3.4 KiB
3.4 KiB
id, title, status, wave, depends_on, plan, spec
| id | title | status | wave | depends_on | plan | spec |
|---|---|---|---|---|---|---|
| 01-duration-helper | Duration helper with unit tests | done | 1 | plan.md | ../../specs/ui/requirements/prompt-turn-duration.md |
Task 01: Duration helper with unit tests
- Acceptance:
messageTurnDurationSeconds(message: Message, turn: Turn | null): number | nullis exported fromapps/web/lib/prompt-history.ts.- It returns
nullunless the message is a user prompt (author_type === "user") WITH a non-emptyturn_idAND a turn that is the message's own (turn.id === message.turn_idANDturn.session_id === message.session_id, mirroring the panel's compositesession_id:idresolution inturnCompletionByPrompt) whosecompleted_atparses;Math.floor-floors the elapsed(completed_at − created_at)to whole seconds and clamps at0. Unparseable timestamps yieldnull, neverNaN. Table-test theturn_idguard and the identity mismatch explicitly (user message with NOturn_id→null; user message withturn_id: ""(empty string) plus a completed passed turn →null— presence/type checks alone must not accept an empty id;turn.id≠message.turn_id→null;turn.session_id≠message.session_id→null). - Table-driven unit tests in
apps/web/lib/prompt-history.test.tscover every spec scenario for the helper, including an explicit regression case for the intentional divergence from the panel: two user messages sharing one completed turn return two different durations (eachcompleted_at − own created_at), a user message with noturn_idreturnsnulleven when a completed turn is passed in, and a mismatchedturn.id/turn.session_idreturnsnulleven when the passed turn is completed. - The helper doc comment states that only the panel's timestamp parsing/floor/clamp arithmetic is shared — the panel's "earlier of turn completion and next prompt" bound does not apply (see plan's bound clarification).
- Verification:
cd apps/web && pnpm vitest run lib/prompt-history.test.ts - Files likely touched:
apps/web/lib/prompt-history.ts(add export; reuse privateepochNanoseconds)apps/web/lib/prompt-history.test.ts(newdescribeblock)
- Dependencies: None.
- Parallelism: sequential.
- Inputs:
- Spec:
docs/specs/ui/requirements/prompt-turn-duration.md—Whatduration rule, allScenarios. - Plan:
docs/plans/prompt-turn-duration/plan.md— Frontend "Duration helper", Tests table. - Pattern:
buildPromptHistoryEntriesinapps/web/lib/prompt-history.tsshows the shared arithmetic for the completion bound (completion ns minus prompt ns,BigInt(1_000_000_000)division, clampBigInt(0)) — reuse only that arithmetic andepochNanoseconds; do NOT apply the panel's next-prompt bound;formatPromptDuration(already exported, same file) stays as the formatter. Turntype:apps/web/lib/types/http.ts—completed_at?: stringis optional.
- Spec:
- Output contract: summary; files changed; tests run with counts; blockers/risks; update task status and
plan.mdcheckbox.
Results
- TDD red:
cd apps/web && pnpm vitest run lib/prompt-history.test.tsfailed as expected: 5 assertions receivednullbeforemessageTurnDurationSecondsexisted. - Verification:
cd apps/web && pnpm vitest run lib/prompt-history.test.tspassed: 1 file, 39 tests. - Generated artifacts: none. Cleanup: no generated artifacts to remove.