MVP Debugger UI (#2888)

This commit is contained in:
Jonathan Dobson
2025-07-07 22:30:33 -04:00
committed by GitHub
parent d63053835f
commit acbdb15265
65 changed files with 2071 additions and 1022 deletions

View File

@@ -1,6 +1,6 @@
import { Status } from "@/api/types";
import { useEffect, useState, useRef, useCallback } from "react";
import { HandIcon, PlayIcon } from "@radix-ui/react-icons";
import { HandIcon, StopIcon } from "@radix-ui/react-icons";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { statusIsNotFinalized } from "@/routes/tasks/types";
@@ -317,13 +317,15 @@ function BrowserStream({
<div className="overlay-container">
<div className="overlay">
<Button
// className="take-control"
className={cn("take-control", { hide: userIsControlling })}
className={cn(
"take-control absolute bottom-[-1rem] left-[1rem]",
{ hide: userIsControlling },
)}
type="button"
onClick={() => setUserIsControlling(true)}
>
<HandIcon className="mr-2 h-4 w-4" />
take control
interact
</Button>
<div className="absolute bottom-[-1rem] right-[1rem]">
<Button
@@ -333,8 +335,8 @@ function BrowserStream({
type="button"
onClick={() => setUserIsControlling(false)}
>
<PlayIcon className="mr-2 h-4 w-4" />
run agent
<StopIcon className="mr-2 h-4 w-4" />
stop interacting
</Button>
</div>
</div>

View File

@@ -0,0 +1,54 @@
import { useEffect, useState } from "react";
interface HMS {
hour: number;
minute: number;
second: number;
}
interface Props {
startAt?: HMS;
}
function Timer({ startAt }: Props) {
const [time, setTime] = useState<HMS>({
hour: 0,
minute: 0,
second: 0,
});
useEffect(() => {
const start = performance.now();
const loop = () => {
const elapsed = performance.now() - start;
let seconds = Math.floor(elapsed / 1000);
let minutes = Math.floor(seconds / 60);
let hours = Math.floor(minutes / 60);
seconds = seconds % 60;
minutes = minutes % 60;
hours = hours % 24;
setTime(() => ({
hour: hours + (startAt?.hour ?? 0),
minute: minutes + (startAt?.minute ?? 0),
second: seconds + (startAt?.second ?? 0),
}));
rAF = requestAnimationFrame(loop);
};
let rAF = requestAnimationFrame(loop);
return () => cancelAnimationFrame(rAF);
}, [startAt]);
return (
<div>
{String(time.hour).padStart(2, "0")}:
{String(time.minute).padStart(2, "0")}:
{String(time.second).padStart(2, "0")}
</div>
);
}
export { Timer };