cmux NEXT Home: a Chief's avatar shows thinking, tool running, waiting on you and done

Merged
TE
2d ago
+354-77

Leo, 2026-11-03, relayed by Chief: "Chief avatar dot states. Replace the Chief avatar's bounce with per-state animations like the Codex status dot: thinking, tool running, waiting on you, done."

Who built the bounce

git log -S on the avatar loop: the bounce (Float, a bob of the whole avatar, faster while working) came in with #30534 (2026-11-01, one of our own lanes, from Leo's "i also want them animated like how chatgpt animates their dots"). #33395 (2026-11-03, our lane) already removed it after Leo's "don't bounce the circle", replacing it with Ring/Glow/Tilt looks for four states: idle, working, waiting (an unread reply) and failed. #33534 then stopped every idle loop. So no bounce is left on base. What was still missing is the four states Leo named: thinking and tool running were one "working" state, and "waiting" meant an unread reply rather than the Chief waiting on you.

What changes

A Chief's avatar in the Home list and the pinned grid now shows six states. The avatar itself never moves off its place.

StateWhenRing (default)
idlenothing to showat rest, nothing runs
thinkingits turn runs in the model (run.activity is Thinking or Writing the reply)a quarter arc in the accent runs round the edge, 1.6 s a turn (unchanged from #33395's working)
tool runningits turn runs a tool (any other activity line, e.g. "Running swift test")a ring of 12 accent dots turns slowly round the edge, 3.2 s a turn
waiting on youits newest message asks a question still pending, or an approval not yet decideda still orange ring
doneits turn ended and the reply is unreada small green check badge on the lower trailing edge (40% of the avatar), still
faileda send faileda still red ring (unchanged)

Only thinking and tool running loop. Waiting, done, failed and idle run nothing once their cue has played, so there is no CPU or wakeup at idle.

Cues (each at most 240 ms): a turn ending (thinking or tool → anything) pops the avatar 4%; a failure shakes it; waiting with no turn seen fades its ring in; done with no turn seen grows its badge in. Thinking ↔ tool is the same turn, so it plays no cue.

The references come from cmux-design-references: cmux/live/chief-pill-proportions and cmux/live/status-icon-edge (the Chief card's done mark, a small green check disc at the leading edge), cmux/live/status-attention-ring (the attention ring for waiting), codex-mobile/live/agents-sheet-active-completed (a running spinner for active work, plain "Done" for completed) and superset/web/agent-status-transition (running → green completion dot).

Data

  • HomeLiveActivity.isTool (CmuxHomeCore): a line not among modelLines (Thinking, Writing the reply, Working, the lines optchat-chief's run.rs sets for the model) names a tool call. HomeTurnProgress.notSteps now reads the same set instead of its own copy.
  • HomeStore.toolRuns: the conversations whose running run is in a tool. publishLive updates it and rebuilds the rows only when a run moves between the model and a tool, never per token (O(1) per token: one Set lookup).
  • InboxRow.isRunningTool and InboxRow.waitsOnPerson(me:) (a pending question part or an undecided approval part on the newest message from someone else) feed HomeSidebarItem.chiefIsInTool / chiefWaitsOnYou, and HomeSidebarView.avatarState maps them in this order: failed, tool, thinking, waiting, done, idle.

Versions (gallery)

ChiefAvatarMotionGalleryTests draws every style in all six states, plus two cues (tool → done, idle → failed), eight frames each, to Packages/Shared/CmuxMessagesLab/.build/chief-avatar-motion-gallery.png:

  • Ring (default): the table above.
  • Glow: a glow behind the shape. Thinking adds a sweeping glint, tool adds Ring's dots, waiting glows orange, done shows Ring's badge, failed glows red.
  • Tilt: thinking rocks the head ±4°. Everything else is Ring's.
  • Still: nothing.

I picked Ring. Each of the four named states reads differently at row size: an arc vs dots for the two running states (shape, not just speed), a coloured ring for waiting, and a mark rather than a ring for done. That way done never reads as "still running". Debug Settings > Home > Chief avatar motion still switches styles.

What it does not touch

  • The agent working-state Spinner and the sidebar/tab working dot are unchanged. This is the Chief's own avatar in Home's list only.
  • The Chief pet (CmuxNextChiefPetWiring, Floating/ChiefPet) is unchanged.
  • None of the changed files is on the rulebook's Chief code list (CmuxNextApp/Chief/, CmuxNextHomeEngine/HomeChiefSettings*, optchat-chief, ...). They live in MessagesLab's sidebar, CmuxHomeCore's store and CmuxNextHome's sidebar model and view. cc @lawrencecchen, the most frequent recent author of these paths, for awareness.

Stop conditions and cleanup

These are unchanged from #33395, and the new looks follow them. Every loop and cue is removed under Reduce Motion, calm mode, speed off and Home's motion switch (avatarLoopGate), when the window is not key or is hidden or minimized, when a row goes back to the pool (SidebarAvatarMotion.stop also removes the badge layer), and with style Still. Under Reduce Motion the tool dots and the thinking arc stand still, so the state still reads. No timer or display link is added: each look is Core Animation on the avatar layer and at most three named sublayers (ring, glint, badge).

Performance

  • Per token: one Set.contains in publishLive. Rows rebuild only on a model ↔ tool change of a run.
  • Per configure: unchanged (one look comparison and a frame fit, O(1) per visible row).
  • No same-harness before/after frame numbers: the new loop is render-server only, like the arc it sits beside.

Tests

  • ChiefAvatarMotionTests (MessagesLab), extended: tool shows dots that turn slower than the arc, with no cue between thinking and tool; waiting is a still orange ring; done is a small green badge with no ring and no loop; done with no turn seen grows its badge in; only thinking and tool loop in any style; no style moves the avatar.
  • ChiefAvatarStateTests (CmuxHomeCore, new): a run's activity moves toolRuns in and out; the model lines are not tools; a pending question or an undecided approval waits on the person, while an answered or decided one, a plain reply, or my own message does not.

Observed / Not run

  • Observed: python3 scripts/cmux-next/prepush-gate.py: no new violations. Fleet compile and the MessagesLab / CmuxHomeCore suites: results in a comment below.
  • Not run: a DEV build watching the list live. Leo tries the build.

Spec: design/motion-and-polish.md (240 ms cue cap, every loop stops). Prior art: #30534 (the bounce), #33395 and #33534 (the looks this extends), #32861 (lucasr1b, open, Still by default; untouched here).

No capture: the looks are in the gallery sheet; Leo tries the build.

Changelog

Changed: A Chief's avatar in Home shows whether the Chief is thinking, running a tool, waiting on you or done, each with its own look.

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

Home’s Chief avatar now distinguishes model thinking, tool use, questions awaiting a response, and unread completed replies.

  • Thinking shows a rotating arc; tool activity shows slower-moving dots.
  • Open questions and pending approvals show an orange ring; unread replies show a green check.
  • Only thinking and tool activity animate continuously; other states stay still.