Compare commits

...
Author SHA1 Message Date
BaaRai d24e734f19 fix(web): freeze session run duration while the task is paused
Sessions keep state=running in the store during a task-level pause, so the
sessions tab treated them as live and the run duration kept ticking with
Date.now(), visibly advancing time while the task (and its deadline budget)
was frozen. Pass taskPaused down from the detail page and pin the duration
at the last recorded step while paused.

Closes #84
2026-10-21 14:34:31 +02:00
2 changed files with 7 additions and 4 deletions
@@ -478,7 +478,7 @@ function WorkerAssetBadge({ assets }: { assets: IntentAsset[] }) {
);
}
export function SessionsTab({ taskId }: { taskId: string }) {
export function SessionsTab({ taskId, taskPaused = false }: { taskId: string; taskPaused?: boolean }) {
const approvalFocus = useApprovalFocus({ taskId });
const [selectedSessionId, setActiveId] = React.useState(MAIN_ID);
const focusSession = React.useMemo<Session | undefined>(() => {
@@ -1416,6 +1416,9 @@ export function SessionsTab({ taskId }: { taskId: string }) {
// Run duration = span from this session's first step to its last (for a live
// session, "now" so it ticks up — the 1.5s setTick above re-renders it).
// While the TASK is paused nothing time-derived may advance (#84): sessions
// keep state='running' in the store during a pause, so live alone would keep
// ticking and misrepresent the frozen budget. Freeze at the last step instead.
const runDuration = React.useMemo(() => {
let min = Infinity,
max = 0;
@@ -1426,9 +1429,9 @@ export function SessionsTab({ taskId }: { taskId: string }) {
if (t > max) max = t;
}
if (!Number.isFinite(min) || max === 0) return null;
const end = active.live ? Date.now() : max;
const end = active.live && !taskPaused ? Date.now() : max;
return Math.max(0, end - min);
}, [activity, active.live]);
}, [activity, active.live, taskPaused]);
// ---- transcript auto-scroll (open → bottom; stick to bottom unless scrolled up) ----
const contentRef = React.useRef<HTMLDivElement | null>(null);
@@ -420,7 +420,7 @@ function TaskDetailInner() {
{/* Tab content */}
<div className="flex-1 p-4 lg:p-6">
<TabsContent value="sessions" className="mt-0">
<SessionsTab taskId={id} />
<SessionsTab taskId={id} taskPaused={task?.status === "paused"} />
</TabsContent>
<TabsContent value="overview" className="mt-0">
<OverviewTab taskId={id} />