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) <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-05-07 13:46:21 -07:00
parent 257d0de444
commit 2ea8e20f51
No known key found for this signature in database
4 changed files with 7 additions and 1 deletions

View file

@ -21,6 +21,7 @@ export interface Stage {
duration: string;
nodeId: string;
visit: number;
startedAt: string | null;
}
export const statusConfig: Record<StageState, { icon: ComponentType<{ className?: string }>; color: string }> = {

View file

@ -12,6 +12,7 @@ function makeStage(nodeId: string, visit: number, status: StageState): Stage {
visit,
status,
duration: "--",
startedAt: null,
};
}

View file

@ -42,6 +42,7 @@ export function mapRunStagesToSidebarStages(
duration: stage.duration_secs != null
? formatDurationSecs(stage.duration_secs)
: "--",
startedAt: stage.started_at ?? null,
}));
}

View file

@ -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 (
<div className="-mr-4 -mt-6 flex min-h-0 flex-1 sm:-mr-6 lg:-mr-8">