fix(cmux-next): pending New Tab access chip is a live menu at the start mode

Merged
TE
17d ago
+88-8

Problem

A New Tab chat that has not reported its modes yet shows its access mode (the start mode acpmux answered) as an inert pending chip, so you can't change it before the first send.

Change

  • While the chat is pending, the start mode shows as a real access menu. The rows come from the harness's last mode catalog, the checked row is acpmux's start mode, and a pick goes through the normal chat.mode setter.
  • The checked row is never the mode the harness's last chat showed. An earlier head of this PR read the profile's last current mode, so a chat starting in full access could show "Ask before edits". There is now a test for that.
  • A borrowed answer (another folder's) still shows the unnamed inert chip, as before.

Scope was cut at the base merge (2026-10-19). The spacing, checkmark-column and pill-outline changes are dropped, because later base work chose differently: #21645, #21744 and #21816 changed the same rules. The regenerated protocol files are also dropped.

Validation

  • bun test test/access-chip-pending-warning.test.tsx (jsdom) discriminates: 2 of its 8 tests ("first frame" and "names acpmux's start mode") fail with the base ComposerPickers.tsx/App.tsx, and all 8 pass at this head. It drives ComposerPickers with holdsModePick set directly.
  • CMUX_BROWSER_TESTS=1 bun test test/agent-pane-start-mode-chip.test.ts passes, but its new assertions also pass with base sources (they cover a shown harness switch, where the live access menu already draws), so they are not coverage of this change.
  • Not covered by a test: the New Tab gate (holdsModePick in DefaultComposerChips) and a pending-menu pick reaching session/set_mode after the first send. A review traced that path by hand: chat.new {deferred} runs before chat.mode, pickMode holds the mode with its gesture ticket, and run() applies it when the chat opens.
  • After merging feat-cmux-next (73740a8e2d8): bun test over the access-chip, model-picker, New Tab and markdown-link tests: 103 pass, 11 skip (browser lane), 0 fail. bun run typecheck clean.

Known follow-ups (low): the menu has only the checked row when the harness has never reported its modes; a held New Tab pick doesn't refresh other pending chats' kept start mode until acpmux announces the change; holdsModePick reads window.cmuxAcpmuxActions during render.

🤖 Generated with Claude Code