From 2ea8e20f519125c738476a8121b7674e42bb612a Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Thu, 7 May 2026 13:46:21 -0700 Subject: [PATCH] feat(web): time stage transcript events from the stage's own start The Transcript view is filtered to a single stage, so measure each event's elapsed time from that stage's started_at instead of the run's created_at. The previous behavior folded the run's initialization wait (sandbox build, clone, devcontainer setup) into every per-stage timestamp. Falls back to RunSummary.start_time and then created_at for stages or runs that never ran. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/fabro-web/app/components/stage-sidebar.tsx | 1 + apps/fabro-web/app/lib/stage-sidebar.test.ts | 1 + apps/fabro-web/app/lib/stage-sidebar.ts | 1 + apps/fabro-web/app/routes/run-stages.tsx | 5 ++++- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/fabro-web/app/components/stage-sidebar.tsx b/apps/fabro-web/app/components/stage-sidebar.tsx index e2cfe88f8..0799a9ada 100644 --- a/apps/fabro-web/app/components/stage-sidebar.tsx +++ b/apps/fabro-web/app/components/stage-sidebar.tsx @@ -21,6 +21,7 @@ export interface Stage { duration: string; nodeId: string; visit: number; + startedAt: string | null; } export const statusConfig: Record; color: string }> = { diff --git a/apps/fabro-web/app/lib/stage-sidebar.test.ts b/apps/fabro-web/app/lib/stage-sidebar.test.ts index 9e8891645..662c67999 100644 --- a/apps/fabro-web/app/lib/stage-sidebar.test.ts +++ b/apps/fabro-web/app/lib/stage-sidebar.test.ts @@ -12,6 +12,7 @@ function makeStage(nodeId: string, visit: number, status: StageState): Stage { visit, status, duration: "--", + startedAt: null, }; } diff --git a/apps/fabro-web/app/lib/stage-sidebar.ts b/apps/fabro-web/app/lib/stage-sidebar.ts index 84a5de2de..825888073 100644 --- a/apps/fabro-web/app/lib/stage-sidebar.ts +++ b/apps/fabro-web/app/lib/stage-sidebar.ts @@ -42,6 +42,7 @@ export function mapRunStagesToSidebarStages( duration: stage.duration_secs != null ? formatDurationSecs(stage.duration_secs) : "--", + startedAt: stage.started_at ?? null, })); } diff --git a/apps/fabro-web/app/routes/run-stages.tsx b/apps/fabro-web/app/routes/run-stages.tsx index 70b7daf03..3a68a26e7 100644 --- a/apps/fabro-web/app/routes/run-stages.tsx +++ b/apps/fabro-web/app/routes/run-stages.tsx @@ -907,7 +907,10 @@ export default function RunStages() { ); } - const runStart = runQuery.data?.created_at; + const runStart = + selectedStage.startedAt ?? + runQuery.data?.start_time ?? + runQuery.data?.created_at; return (