fix(dashboard): show shell elapsed line only past a 10s threshold - #8847
Conversation
Design Review (Fable 5) — ✅ PASSDesign-level review of Design-Verdict: PASS Threshold-gating the elapsed row fixes the [DESIGN-REVIEWED] e34e89e |
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
First Principles Review (Fable 5) — ✅ PASSPremise-level review of All checks complete. The one pre-existing consumer of the First-Principles-Verdict: PASS Removes the reported wall of frozen "0s" rows by deleting the sticky latch and gating on real elapsed time; every rider is CI-gate-derived or repo convention. What this change shipsIntent: stop every quick shell call from leaving a permanent, meaningless "0s" status row in the transcript. FIX.
The clock anchoring the PR leans on ( [FIRST-PRINCIPLES-REVIEWED] e34e89e |
Opus 4.8 Review — ✅ no blocking findingsReviewed Review detailsThe only shipped-code change is the one-line render edit in I verified CANDIDATE 1's mechanism against the code: But this fails the bar for a reported defect. The text appears solely on an element that is simultaneously fading to No grounded Step 2 finding surfaced. No findings. [OPUS-REVIEWED] e34e89e Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
UX Review (Fable 5) — 🟡 CONCERNSUX-level review of I have everything I need. The change is purely the shell "Running · Ns" status line: it now waits 10 s to appear and vanishes on completion (previously it froze into the elapsed total). The blind read shows the reader correctly understood the timer, the counting, and the done state — but explicitly flagged that the elapsed total disappears on completion and they couldn't tell whether that was deliberate or lost information. All introduced states are covered by the five stills plus the committed GIF, and the removal animates (height ease pinned by test), so there are no evidence gaps and no block predicates. UX-Verdict: CONCERNS The threshold works and reads cleanly, but completing a long command now deletes the one number the user was watching: its duration. Watch
[UX-REVIEWED] e34e89e |
9751565 to
007fbd8
Compare
…, drop it on completion Since #7916 the 'Running · Ns' line under a shell tool pill was sticky within the turn: it appeared on start and froze into an elapsed total on completion, leaving a permanent (often '0s') line under every shell call. Gate the line on elapsedSeconds >= SHELL_ACTIVITY_MIN_SECS (10) and only while live, so short calls add and remove no line while long ones collapse once at the end. Replaces the sticky latch/frozen-label branch; tests renamed to ToolCallLine.shellActivityThreshold.test.tsx; shared scene extracted to website/scripts/lib/tool-row-scene.mjs.
007fbd8 to
e34e89e
Compare
|
Disposition: fixed (in
Agreed — both call sites ( |
|
Disposition: fixed (in
Agreed — both constants are referenced only inside |
|
Disposition: rebutted — deliberate product decision; the code stays as shipped.
The observation is accurate — the total does vanish on completion — and that is the design this PR states in its title ("drop it on completion") and Summary, not an oversight. Reasoning:
The collapse is animated (height eases to zero, pinned by |
Summary
The "Running · Ns" status line under a shell tool pill now waits until the command has run for 10 seconds before it appears, and is removed the moment the command completes.
Since #7916 the line was sticky within the turn: it appeared when the shell tool started and, on completion, froze into the elapsed total instead of collapsing. That kept the transcript height monotonic above a bottom-pinned reader, but it left a permanent line under every shell call in the turn — and because the elapsed clock only ticks once a second and freezes at its last tick, a
greporgit showthat returned in 40 ms showed a meaningless0s(zh-CN:0秒). A turn with a dozen quick shell calls became a wall of0秒rows.The threshold is what preserves the point of #7916 rather than reverting it: a short call now adds no line and removes none, so the per-tool step above a pinned reader is gone for the common case, and the one collapse that remains happens only at the end of a command that genuinely ran long — which is the only command a reader was watching the clock on anyway.
Changes
website/src/pages/chat/ToolCallLine.tsx—SHELL_ACTIVITY_MIN_SECS = 10;showShellActivityisliveShellActivity && elapsedSeconds >= threshold. The sticky latch (shellActivityShownRef) and the frozen-label branch are removed; the label is alwaysRunning · Nsbecause the line now only exists while the command is live. The clock stays anchored to the tool's own start (execution_started_at, then the logts), so a row that re-mounts mid-command (virtualizer, reload) 25 s in shows the line immediately rather than waiting another ten ticks.website/src/test/ToolCallLine.shellActivityThreshold.test.tsx(replacesToolCallLine.stickyActivity.test.tsx) — hidden under the threshold; appears on the tick that reaches 10 s with the live total; shows at once when mounted past the threshold; removed on completion; never shown for a tool already done at mount.website/src/test/ToolCallLine.test.tsx— the row-slide test is back to pinning the collapse (eases to zero, then unmounts).website/scripts/capture-shell-elapsed-threshold.mjs— self-checking Playwright harness against the built SPA: every still below is asserted against the DOM ([data-testid="shell-activity"]count and text) before it is written.website/scripts/lib/tool-row-scene.mjs— the mid-turn shell-tool scene and page boot shared by this harness andcapture-tool-row-slide.mjs(which is migrated onto it, behaviour unchanged).Evidence
Captured against the built SPA, real time (500 ms per frame). The GIF is cropped to the transcript column; the corner stamp is seconds since the tool started.
Running · 11sRunning · 13sVerification
npx tsc -b,npx eslinton the touched files,npx jscpd .(0 clones),npm run i18n:check,check-unit-literals.mjs— all green locally.temp-screenshots/shell-elapsed-threshold/assertions.json).Pattern harvest
Rule candidate: review-prompt
Pattern: per-item status chrome (elapsed row, spinner text) rendered unconditionally on every tool call instead of gated on the signal being worth showing — a UI review prompt can ask "does this row earn its place for the common short case?"
0srow under every call). A threshold that suppresses the row for the common short case keeps the stability win without the noise — prefer conditioning the extra chrome on the signal being worth it over showing it unconditionally.execution_started_at, then logts), never to mount time, so a row re-mounting mid-command (virtualizer, reload) reflects real elapsed rather than restarting the count.scripts/lib/tool-row-scene.mjs) when a second capture script needs the same page/boot setup, so jscpd stays at 0 clones and the two harnesses cannot drift.