cmux NEXT composer: the footer starts with the harness, its icon and name

Merged
TE
14d ago
+732-37

In progress: the fleet runs of the regression test (red and green) are still queued. Their results will be added to this description.

Leo asked "why is there no harness at the left". The quiet row under the agent pane's composer box showed only the mode ("Full access ⌄") on the left, and "Opus 5.5" plus the context ring on the right. Nothing said which harness the chat runs.

Now the row starts with the harness, the way Claude Code's footer starts with the project:

  • What it shows. The harness's brand mark (the same AgentMark the model menu's rail and the session rows draw) and its name: Claude Code, Codex, or a profile's own name. The mode follows it, and the model button and the ring stay on the right.
  • How it looks. Quiet text in the row's muted ink, with no capsule.
  • What a click does. A chat that can still switch harness (New Tab, or a chat with no message yet) gets the row's soft pill on hover, and a click opens the model button's menu. That menu's harness rail is the composer's existing harness switcher, so no second switcher is added. Once a chat has a message its harness is fixed (ComposerPickers locked, Leo 2026-10-13), so the item there is plain text: no button, no hover pill.
  • During a switch. While a switch to another harness is starting, the item names the target harness, as the model chip does.
  • Narrow rows. composerRowFit.ts gains a harness unit. In a narrow row its name goes after effort's short name and before the model's family (step harnessMark, 460 px). Its mark always stays, and the row's fit then puts the name in the tooltip. At 410 px the row reads: the mark, the mode's glyph, "Opus Med", then the ring.
  • No harness installed. When acpmux lists no harness, the row names none: the model button's place says Add harness, and nothing else. The chips' fallback (the model catalog's first harness) is never shown as the chat's harness.
  • Scope. Only the quiet row draws the item: ComposerHarness renders nothing outside ComposerFoot (InQuietRow). The other footer look and the New Tab card's pickers already lead with the model's mark. AccessMenu is untouched (#23831 changes it).

Root cause: there was no harness unit at all. ComposerFoot (webviews/src/agent-session/acpmux/ComposerFoot.tsx:10) renders only Chips (ComposerPickers.tsx:688, ModelPicker, PendingMode, AccessMenu, the plan toggle and AgentOptionsMenu) and the ring. The quiet row came from #22285, which moved the mode, model and effort out of the box. The model chip's mark was the only thing that named the harness, and the plain look hides that mark at rest (composerLocation.css:535-539, .agent-mark { display: none } above 370 px).

Overlap: composer-look-model-quiet (no PR yet) changes composerRowFit.ts so the quiet row fits on its measured room. This PR only adds the unit and its step. Once that lands, the new 460 px container query should take the same :not(.acpmux-composer-foot) as the others. That branch already conflicts with feat-cmux-next in composerLocation.css around line 563, independent of this PR.

Gallery: agent-pane.composer variants footer-harness (Claude), footer-harness-codex and footer-harness-new-chat (the play clicks the item and the menu opens).

Changelog

  • Added: The agent composer's footer starts with the chat's harness, its icon and name (Claude Code, Codex, …). In a chat that can still switch harness, clicking it opens the harness menu.

Regression test

CMUX_BROWSER_TESTS=1 bun test test/composer-footer-harness.test.ts (webviews/; it also covers the no-harness New Tab, the new chat's harness rail, and the 410 px order), plus test/composer-row-fit.test.ts and test/composer-fit-steps.test.ts, on the fleet (cmux-ci run scripts/ci/run-webviews-tests.sh):

  • red on base (test commit ffed6f389e4 on 0b71d5ea640): pending
  • green on head (32fa728d2ab, the fix plus the weight check): pending
  • neighbors on head (40f62d1f450): composer-claude-split (updated for the new first item), composer-footer-plain, composer-quiet-chips, composer-row-steps, composer-footer-essentials: pending

Observed / Not run

  • Observed: cmux-ci compile-check --app passed at 32fa728 (job 0cec30b3158698ec3e130ee7, 58 s); the PR's other commits change only tests. The gallery frames from the compare build (cmux-lawrence) read: Claude "Claude Code · Full access … Opus 5.5", Codex "Codex · Full access … GPT-6 Astra", a new chat "Claude Code … Opus 5.5" with the item as a button. At 410 px only the mark shows, followed by the mode's glyph, "Opus" and the ring. The name and the mode's label are regular weight, 13 px, the row's muted ink.
  • Pending: the fleet runs above.
  • Not run: the Mac app. bun run check locally (cosmic-gray's guard sends tsc to the fleet); CI's web lint covers it.

No capture: webview-only change; gallery compare https://cmux-lawrences-mac-mini.tail137216.ts.net:18796/compare/composer-look-footer-harness/?entry=agent-pane.composer (tailnet).

Leo-ask: ask-98ecbe7758

Agent session: cosmic-gray

🤖 Generated with Claude Code