Transcript: a running tool row shimmers its words, not a spinner at the far edge ("doesn't claude desktop have the thinking shimmer go across stuff")

Merged
TE
3d ago
+465-41

Leo, 2026-11-03, on a running "Monitor" tool row whose spinner sat at the transcript's far right edge, a whole column away from the row's words:

yo what the
this is kinda weird looking
doesn't claude desktop have the thinking shimmer go across stuff

A running tool row now shows that it runs on its own words, as Claude desktop's and ChatGPT's running rows do: a soft light band sweeps across the label while the call runs. Nothing is parked at the row's far edge.

Change

  • ShimmerText.tsx RowShimmer: the row's own words drawn again as an inert, aria-hidden lit copy over them. It reuses the Thinking line's two transform-only loops (cmux-shimmer-band / cmux-shimmer-lit, --cmux-shimmer-period 2.8 s, on the shared clock), so the Thinking line and running rows sweep together and the page paints nothing per frame. The band moves inside a still clip, so the label's box never grows and ToolRow's cut-label disclosure check is unaffected.
  • ToolRow and CommandRow draw it while the call runs, in the foreground or the background. It unmounts when the call ends, so the loop stops with it.
  • BackgroundMark: no spinner while a call runs in the background (this was the mark in Leo's screenshot). Its running state stays screen-reader text; the check, "Failed" and "Stopped" still show once it ends. The now-unused grouped / showActivity props are gone.
  • A running row's words rest at --cv-text-dim (a step under a finished row, as ChatGPT's in-flight row is) and the band lights them to --cv-text. Reduce Motion, data-cmux-motion off or reduced, and the static status look keep the dimmed words still, with no animation.
  • Not touched: the agent working-state mark (sidebar, tabs, subagent tray), which stays a spinner; tool group and run summary lines; Thinking; compaction. The "Monitor"/"TaskStop" raw names are already handled by #32738.

Gallery

agent-pane.tool-row-shimmer uses the real rows (a finished TaskStop, a background Monitor, a running read and command, a finished read) in six arms: shipped (the Thinking line's 40% band and 2.8 s clock, lit to the text colour), narrow (48 px band), wide (70%), quick (1.8 s), accent (the Thinking line's accent tint), and still (Reduce Motion). I chose shipped: it matches the references' few-letters-wide soft band in neutral text colour, and it stays in step with the Thinking line. The arms were captured mid-sweep in dark and light and compared with the references; captures are kept private.

References used (cmux-design-references): chatgpt/web/status-work-grouped-tool-rows, chatgpt/web/status-work-working-for-timer, claude/live/status-thinking-line-token-counts, and Leo's own cmux/live/transcript-running-tool-row-detached-spinner.

Design spec: leo-workspace design/chat-transcript.md (tool groups' spinner section), updated in a leo-workspace PR to match.

Measurements (same harness, test/browser/tool-row-shimmer.html, Chromium)

metricbefore (base 4fbe098)after
painted marks right of a running background row's words1 (spinner)0
spinners on running tool rows10
running rows whose words shimmer0 of 33 of 3
animations on a running row1 (spin)2 (band + lit, transform only)
animations on a finished row / under Reduce Motion or the motion gate0 / 10 / 0
running words' colour (dark)same as finished (white @ 0.58)--cv-text-dim

Tests

  • New test/tool-row-shimmer-browser.test.ts (red/green): no spinner and no painted mark right of a running row's words; each running row's lit copy is its own words and runs cmux-shimmer-band; the words' box doesn't grow; a finished row has no shimmer; Reduce Motion and data-cmux-motion reduced and off run no animation and keep the words dimmed. Committed first: 4 fail on base (spinner: monitor), 4 pass on head.
  • BackgroundMark.test.tsx now asserts no spinner and an inert shimmer while running, and none once it finishes.
  • Ran on the fleet: the new test, tool-row-column-browser, transcript-row-spinners, BackgroundMark, agent-pane-background-tasks, transcript-collapsed-tool-runs: all pass.

Observed / Not run

  • Observed: the fleet Chromium runs above, and gallery captures of every arm mid-sweep in dark and light.
  • Not run: WebKit; a DEV build in the app.

Risk: low. The change is confined to the transcript's tool row components and their CSS. A running row's words are a step dimmer, and the band is CSS-only.

Changelog

  • Running tool calls in the agent chat shimmer across their own label, as in Claude desktop, instead of showing a spinner at the far edge of the transcript.

Agent session: agent session

🤖 Generated with Claude Code


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Running tool rows in the agent transcript now shimmer across their own label instead of showing a spinner at the far edge, matching Claude desktop and ChatGPT.

  • Adds a RowShimmer overlay that reuses the Thinking line's existing band animation, so running rows sweep in step with it.
  • Removes the spinner from BackgroundMark while a background call runs; the running state stays as screen-reader text only.
  • Running words rest at --cv-text-dim; Reduce Motion or the motion gate keeps them dimmed and still.
  • Adds the agent-pane.tool-row-shimmer gallery and browser tests covering both animated and static states.