Repository navigation
cmux NEXT: agent work breathes a calm accent dot instead of a spinner on every row - #22826
Conversation
…nning Leo 2026-10-20, on seventeen running sessions each with a spinner: "isn't this mildly ugly? What are the alternatives?" Agent work now draws a small dot in the theme accent that breathes once every 2.4 s on the shared clock, so many working rows breathe as one. It applies everywhere the status indicator draws work (sidebar rows, switcher, tabs, hover cards) and on the agent pane's running transcript rows (compaction, tool groups, MCP calls, command and shell rows). Loading (a page, a command, a harness check) keeps its spinner. Reduce Motion and the static look hold the dot still. Debug Settings "Working look" (status.working) keeps the alternatives: Shimmer (a still dot; on web pages a light band crosses the row's words) and Spinner (the old turning arc). Web pages get it as data-working-look. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c2a-ee5f-7111-b18b-d14161ef8c3c&host=huge-blue
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Probably yours: CI failed on
Failures:
Matched log linesNot re-run automatically: Written by red: web / Web status; base red: the same failure on the base 89f97db; does not block
Agents: Tour of |
|
Bead |
|
Found 24 test failures on Blacksmith runners: Failures
...and 14 more test failures. View all on Blacksmith
|
…edit-count colors Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c2a-ee5f-7111-b18b-d14161ef8c3c&host=huge-blue
|
owner: 01a15c2a-ee5f-7111-b18b-d14161ef8c3c |
|
Red check classification for 07af590: all three |
…name has room A working workspace row draws "4m" (whole minutes, "1h 3m") dim beside its working dot, only while the name still fits whole; a narrow sidebar keeps the row as it was, and a row with its own trailing text (an age, a status line) keeps that. The text changes on the minute through a DemandTimer. The hover card already shows the time to the second. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c2a-ee5f-7111-b18b-d14161ef8c3c&host=huge-blue
Review of the previous commit: with the default corner badge, a working
row almost always has an age ("3:14 PM") in the trailing text slot, so the
running time never showed. While the agent works, the running time now
replaces the age (a one-line status keeps its place). The minute tick arms
only while the time shows or its first minute runs, cancels on reuse, and
restarts when the start time changes. Tests give the fixture an age.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c2a-ee5f-7111-b18b-d14161ef8c3c&host=huge-blue
Re-review: a parked row returning to its own workspace keeps its content, so configure skips and never set the cleared start again; the trailing slot stayed empty. Reuse now only cancels the tick and lays out again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c2a-ee5f-7111-b18b-d14161ef8c3c&host=huge-blue
|
owner: 01a15c2a-ee5f-7111-b18b-d14161ef8c3c |
|
Reds seen on bf8eeed are base reds; this PR touches none of their files:
Since then: cc6f9d3, 0521835 and 9f8ef27 add the wide-row elapsed time. The independent review passed on 9f8ef27 after two rounds of fixes (the badge age hid it; a pooled row lost it). I'm merging once the cmux-next Swift jobs pass. |
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
…king-look # Conflicts: # Packages/macOS/CmuxNext/Sources/CmuxNextDesign/StatusIndicator/StatusIndicatorLayer.swift
…king-look # Conflicts: # Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/WorkspaceRowView.swift
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
|
WorkspaceRowElapsedTests (from #22826) crashed the test process with signal 11 on the fleet: each test closed a window it still held while isReleasedWhenClosed was true, so the window was released twice. The windows now set isReleasedWhenClosed = false, as the other window tests do, and the suite runs serialized. Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c2a-ee5f-7111-b18b-d14161ef8c3c&host=huge-blue Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
WorkspaceRowElapsedTests (from #22826) crashed the test process with signal 11 on the fleet: each test closed a window it still held while isReleasedWhenClosed was true, so the window was released twice. The windows now set isReleasedWhenClosed = false, as the other window tests do, and the suite runs serialized. Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c2a-ee5f-7111-b18b-d14161ef8c3c&host=huge-blue Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
Shipped in:
|
Leo 2026-10-21: "WHO BROUGHT BACK THE DONE AND THE TIMERS". #22826 (2026-10-20) drew how long a row's agent had worked ("10m") beside its working mark, in place of the row's age, with a minute tick per row. The row drops the running time, its label, its tick and WorkspaceRowView+Elapsed; a working row keeps its age as before #22826. The hover card still shows the time to the second. Test: SidebarRowNoDoneTests.aWorkingRowShowsNoRunningTime renders a row whose agent has worked ten minutes and fails if any label shows a running time. WorkspaceRowElapsedTests (the timer's own tests) goes with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16040-fd0b-7dd0-9487-1a3a198d9f5c&host=cosmic-gray
…r row blinks (#23776) Leo 2026-10-21: "WHO BROUGHT BACK BLINKING ICONS? WE SAID NO BLINKING. WE SAID SPINNER." #22826 (2026-10-20) made the breathing accent dot the default working look (Debug Settings status.working), so every working row's mark faded in and out. The spinner is the default again; the breathing and still dots stay as Debug choices. Test: SidebarRowNoBlinkTests fails if any status mark a row can draw at the defaults pulses, breathes or waves, or if a drawn mark's layers carry a repeating opacity animation; running must spin. Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16040-fd0b-7dd0-9487-1a3a198d9f5c&host=cosmic-gray Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…act checks) Leo, on a #22826 card: no state word and no pill. The state is the pull request glyph's colour alone, as Claude draws it (open green, merged purple, closed red, draft grey); the word stays as the glyph's accessible name. Open and Open in are quiet borderless buttons with a hover background, the card is tighter (8px/10px inset, 6px rows, no divider), a web card's address sits under its title only when it says more than the host, and "+N −M" has no dotted underline. An open pull request's checks are a compact "✓ 90 ✗ 10" (◷ for running ones) with base's "(N already on base)" note, the ✗ muted when every red is also red on base; a finished pull request shows no checks line and no conflicts. The card stays on the tooltip's glass tokens. This also clears the agent-pane-no-capsules red: the 999px state pill is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a1602e-25ea-7611-8c79-d16df0c4058f&host=cosmic-gray
Leo 2026-10-21: "WHO BROUGHT BACK THE DONE AND THE TIMERS". #22826 (2026-10-20) drew how long a row's agent had worked ("10m") beside its working mark, in place of the row's age, with a minute tick per row. The row drops the running time, its label, its tick and WorkspaceRowView+Elapsed; a working row keeps its age as before #22826. The hover card still shows the time to the second. Test: SidebarRowNoDoneTests.aWorkingRowShowsNoRunningTime renders a row whose agent has worked ten minutes and fails if any label shows a running time. WorkspaceRowElapsedTests (the timer's own tests) goes with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16040-fd0b-7dd0-9487-1a3a198d9f5c&host=cosmic-gray
Leo 2026-10-21: "WHO BROUGHT BACK THE DONE AND THE TIMERS". #22826 (2026-10-20) drew how long a row's agent had worked ("10m") beside its working mark, in place of the row's age, with a minute tick per row. The row drops the running time, its label, its tick and WorkspaceRowView+Elapsed; a working row keeps its age as before #22826. The hover card still shows the time to the second. Test: SidebarRowNoDoneTests.aWorkingRowShowsNoRunningTime renders a row whose agent has worked ten minutes and fails if any label shows a running time. WorkspaceRowElapsedTests (the timer's own tests) goes with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16040-fd0b-7dd0-9487-1a3a198d9f5c&host=cosmic-gray
…hover card with state pills (#23746) * cmux NEXT agent chat: tests that a link chip never grows when its title loads (red) [#22896](…/pull/22896) grew inline into "#22896 · cmux-next updates: …" once the page title came in, reflowing the paragraph. These fail on the base: the chip's text and icon must not change after metadata arrives. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a1602e-25ea-7611-8c79-d16df0c4058f&host=cosmic-gray * cmux NEXT agent chat: a link chip's text and icon are fixed when it first draws A pull request chip no longer appends its title (cv-chip__title), and a bare address no longer swaps to the site's title and favicon once cmux learns them. Both now show only in the hover card, so a hover or a late lookup never widens the chip and reflows the reply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a1602e-25ea-7611-8c79-d16df0c4058f&host=cosmic-gray * cmux NEXT agent chat: a tighter link hover card with state pills and base-red checks Leo: "the styling/layout/spacing could be a bit better". The card's head is one compact row: the favicon or GitHub mark inline beside the title (a pull request's own title, cut to two lines), then Open and Open in. A pull request card drops the github.com address footer; a web link keeps its masked address under the title. One 12px inset and 8px between rows. The state is a pill tinted in its colour (open green, merged purple, closed red). Checks whose failures all fail on the base branch read muted "N failing (base)"; some of them read "N failing, M on base". The pr.inspect answer gains an optional failingOnBase, which the host does not send yet. Gallery: merged-with-base-reds and closed pull request states. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a1602e-25ea-7611-8c79-d16df0c4058f&host=cosmic-gray * cmux NEXT agent chat: a quieter pull request card (glyph colour, compact checks) Leo, on a #22826 card: no state word and no pill. The state is the pull request glyph's colour alone, as Claude draws it (open green, merged purple, closed red, draft grey); the word stays as the glyph's accessible name. Open and Open in are quiet borderless buttons with a hover background, the card is tighter (8px/10px inset, 6px rows, no divider), a web card's address sits under its title only when it says more than the host, and "+N −M" has no dotted underline. An open pull request's checks are a compact "✓ 90 ✗ 10" (◷ for running ones) with base's "(N already on base)" note, the ✗ muted when every red is also red on base; a finished pull request shows no checks line and no conflicts. The card stays on the tooltip's glass tokens. This also clears the agent-pane-no-capsules red: the 999px state pill is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a1602e-25ea-7611-8c79-d16df0c4058f&host=cosmic-gray * Hover card test checks the liquid glass the card now uses Base #23477 moved the link card onto .ui-glass, so the card rule sets no fill; the test now pins the ui-glass class and the glass token fallback instead of the old tooltip background. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a1602e-25ea-7611-8c79-d16df0c4058f&host=cosmic-gray --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Leo 2026-10-21: "WHO BROUGHT BACK THE DONE AND THE TIMERS". #22826 (2026-10-20) drew how long a row's agent had worked ("10m") beside its working mark, in place of the row's age, with a minute tick per row. The row drops the running time, its label, its tick and WorkspaceRowView+Elapsed; a working row keeps its age as before #22826. The hover card still shows the time to the second. Test: SidebarRowNoDoneTests.aWorkingRowShowsNoRunningTime renders a row whose agent has worked ten minutes and fails if any label shows a running time. WorkspaceRowElapsedTests (the timer's own tests) goes with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16040-fd0b-7dd0-9487-1a3a198d9f5c&host=cosmic-gray
Leo 2026-10-21: "WHO BROUGHT BACK THE DONE AND THE TIMERS". #22826 (2026-10-20) drew how long a row's agent had worked ("10m") beside its working mark, in place of the row's age, with a minute tick per row. The row drops the running time, its label, its tick and WorkspaceRowView+Elapsed; a working row keeps its age as before #22826. The hover card still shows the time to the second. Test: SidebarRowNoDoneTests.aWorkingRowShowsNoRunningTime renders a row whose agent has worked ten minutes and fails if any label shows a running time. WorkspaceRowElapsedTests (the timer's own tests) goes with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16040-fd0b-7dd0-9487-1a3a198d9f5c&host=cosmic-gray
…3870) * cmux-next: delete the breathing working dot; agent work is the spinner everywhere Follows #23776, which made the spinner the default again. #22826 had added StatusWorkingLook.breathe (a breathing accent dot for agent work) as the default. Leo: "who brought back the blinkers!? we had spinners properly going", "we need to GUARANTEE the breathing dot doesn't come back". Deleted: StatusWorkingLook.breathe, StatusIndicatorPlan.Animation.breathe and its animation key and layer handling, MotionGate.breathAnimation, MotionLoop.breath (tunable default and minimum period), StatusIndicatorConfig.breathLow, the "Breathing Dot" title and its catalog entry; on the web the cmux-breathe keyframes, --cmux-breath-period and the breathe rules. A page with no data-working-look, or any value but shimmer (an old "breathe" included), now draws the spinner. The Apps page's loading skeleton keeps its pulse under its own name (cmux-skeleton-pulse). A stored status.working = "breathe" decodes to nothing and reads as the default, the spinner; tested, along with the payload sent to web pages. Tests: NoBreathingDotTests (every look, every host path that draws work, drawn into the real layer with loops running, plus a source guard over CmuxNextDesign) and static-status-loops.test.ts (each look, no attribute, an old breathe pushed through the theme bootstrap: no working mark loops its opacity; a stylesheet guard). Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16040-fd0b-7dd0-9487-1a3a198d9f5c&host=cosmic-gray Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(agent chat): keep working and jump indicators calm Agent-Session: https://cmux.com/deeplink/agent?harness=codex&session=01a16bc5-12cc-7800-88fd-75e6a391e3dd&host=big-red * test(status): preserve explicit dot choices and guard spinner defaults Agent-Session: https://cmux.com/deeplink/agent?harness=codex&session=01a16bc5-12cc-7800-88fd-75e6a391e3dd&host=big-red * fix(agent chat): use spinners unless a dot was explicitly selected Agent-Session: https://cmux.com/deeplink/agent?harness=codex&session=01a16bc5-12cc-7800-88fd-75e6a391e3dd&host=big-red * fix(web): shrink token debt after removing jump pulse Agent-Session: https://cmux.com/deeplink/agent?harness=codex&session=01a16bc5-12cc-7800-88fd-75e6a391e3dd&host=big-red * fix(agent-pane): construct tray after its callbacks initialize Agent-Session: https://cmux.com/deeplink/agent?harness=codex&session=01a16bc5-12cc-7800-88fd-75e6a391e3dd&host=big-red * fix(ci): ignore vp warning summaries in either order Agent-Session: https://cmux.com/deeplink/agent?harness=codex&session=01a16bc5-12cc-7800-88fd-75e6a391e3dd&host=big-red --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Leo (2026-10-20), on a list of ~17 running sessions with a grey spinner on each row: "Can you think of anything better than just having these spinners? After a certain point, isn't this mildly ugly? What are the alternatives?"
Part 2 of the activity-indicators lane. Part 1, the frozen transcript spinners, was #22786 (merged).
What changes
Palette.accentFill: the text color, or the hueappearance.accentnames; never Claude orange) that breathes once every 2.4 s. It runs on the shared clock, so a list of working rows breathes as one instead of 17 rings turning.status.working) keeps the alternatives:data-working-look, through both WebTheme and the agent pane theme.breath(2.4 s, Debug-tunable, never under 1 s). Web:cmux-breatheandcmux-shimmerkeyframes in desktop.css, kept in phase byui/spinnerClock.ts.The options (Linux gallery,
agent-pane.working-look, dark)These are the agent pane's running rows; the "Compacting the conversation…" row carries the working mark. The native sidebar, switcher and tabs draw the same plan with the native indicator layer; there's no native capture here (no Mac build on this host).
Reduce Motion / Static: the dot holds at full strength.
Why Breathing Dot is the default: one small accent dot per row, breathing slowly and in step, reads as calm "still working" even across 17 rows. Shimmer moves more of the screen (every running row's words), and a spinner on each row is the noise Leo pointed at. Shimmer is a good fit for a single row (it's what "Thinking" already does), so it stays as an option.
Changelog
Changed: A working agent shows a calm breathing dot in your accent color instead of a spinner; Debug Settings keeps Shimmer and Spinner.
Tests
StatusWorkingLookTests(CmuxNextDesign): breathe is the default; each look's plan; a still or hidden row keeps the dot; loading and known progress keep their marks; the breath is slower than the waiting pulse.test/static-status-loops.test.ts(browser): each look runs exactly its own loop on agent work, a loading spinner still turns, and Static and Reduce Motion stop all of them.spinnerTurns.test.tsx: running rows mark themselves as agent work; a loading spinner never takes the dot.Observed / Not run
bun run check(clean), andbun teston conversation, started, gallery and the spinner clock (82 pass). WithCMUX_BROWSER_TESTS=1: static-status-loops, agent-pane-plan and spinner-clock (18 pass). Gallery tests: 43 pass.prepush-gateran on push.activitySince). Elapsed time on a wide row is not in this PR; it needs native layout and a capture, so it comes as a follow-up.StatusWorkingLookTests. No Mac compiles on this host, so those run on CI.Agent session: huge-blue
🤖 Generated with Claude Code