From 9edcf0c0080b7d3a2a9ec5d22e0fb6f24d2223b4 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 2 Mar 2026 16:25:20 -0500 Subject: [PATCH] fix: compute elapsed time and cost dynamically for running tasks (#33) Co-Authored-By: Claude Opus 4.6 --- src/__tests__/scheduler.test.ts | 1 + src/scheduler.ts | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/__tests__/scheduler.test.ts b/src/__tests__/scheduler.test.ts index 2081439..2815f2b 100644 --- a/src/__tests__/scheduler.test.ts +++ b/src/__tests__/scheduler.test.ts @@ -20,6 +20,7 @@ function makePool(): WorktreePool { function makeRunner(): AgentRunner { return { run: async (task: Task) => { task.status = "success"; task.durationMs = 100; return task; }, + getRunningTasks: () => [], } as unknown as AgentRunner; } diff --git a/src/scheduler.ts b/src/scheduler.ts index 36acd05..81f1327 100644 --- a/src/scheduler.ts +++ b/src/scheduler.ts @@ -85,11 +85,29 @@ export class Scheduler { } getTask(id: string): Task | undefined { - return this.tasks.get(id) ?? this.store.get(id) ?? undefined; + const task = this.tasks.get(id) ?? this.store.get(id) ?? undefined; + if (task?.status === "running" && task.startedAt) { + task.durationMs = Date.now() - new Date(task.startedAt).getTime(); + const runningInfo = this.runner.getRunningTasks(); + const live = runningInfo.find(r => r.id === task.id); + if (live) task.costUsd = live.costUsd; + } + return task; } listTasks(): Task[] { - return [...this.tasks.values()]; + const tasks = [...this.tasks.values()]; + const now = Date.now(); + const runningInfo = this.runner.getRunningTasks(); + const runningMap = new Map(runningInfo.map(r => [r.id, r])); + for (const t of tasks) { + if (t.status === "running" && t.startedAt) { + t.durationMs = now - new Date(t.startedAt).getTime(); + const live = runningMap.get(t.id); + if (live) t.costUsd = live.costUsd; + } + } + return tasks; } getQueuePosition(taskId: string): number {