cmux NEXT composer: the mode menu is the harness's own (Claude Code's Mode menu, Codex's approval menu); the button shows symbol + name, tight rows
Leo saw an invented Normal / Auto / Full access mode menu: padded, solid, with a fat pill around "Full access ⌄". Claude Code's and Codex's own menus look nothing like it.
Now the menu is the harness's own menu for the mode ids it reports (webviews/src/agent-session/acpmux/harnessModes.ts):
- Claude: heading "Mode", then Auto with a Recommended badge, Manual, Accept edits, Plan and Bypass permissions, each with Claude Code's description and number keys 1 to 5. There is no icon column, as in Claude Code's menu. Plan is a row here, because Claude Code's menu lists it.
- Codex: heading "How should actions be approved?", then Ask for approval (hand), Approve for me (terminal in a shield) and Full access (shield with "!"), each with Codex's description. Approve for me appears once the bridge reports
auto-review. The bridge's ownask/read-onlypolicy modes are not part of Codex's menu and are not listed. - Any other harness, or an adapter that reports none of these ids, shows exactly what it reports, unchanged.
- The mode button shows the mode's symbol plus its name (the plain footer used to hide the symbol). It has no pill at rest; hover is the soft tint only.
- Rows are tighter: a 4 px row inset plus the popup's 4 px puts the text about 8 pt from the menu's edge. The menu sizes to its longest row, it stays glass, and the check uses the theme's lit accent (
--agent-lit-glyph), never system blue or orange. - One
AccessMenuserves both the chat composer and the New Tab composer. - The two menu strings that are cmux's, not the harness's (the Recommended badge and Codex's heading), are pane strings:
picker.modeRecommendedandpicker.codexApprovalHeadinginLocalizable.xcstrings, in all 21 locales (needs_reviewexcept English).
The acpmux side (Claude chats report Claude Code's own ids, names and descriptions, acceptEdits included) landed in #23777 (35f14d98). This PR maps the ids to Claude Code's labels whatever names arrive, so older daemons show the right menu too.
The invented list came from acpmux's claude_stdio::MODES (("default","Normal") … ("bypassPermissions","Full access")), added in 8bafb2c (#16174). "Full access" was kept by 8a96bfa (cx-wx93i).
Gallery: agent-pane.composer variants access-menu (Claude, Bypass permissions checked) and access-menu-codex (Codex, Full access checked).
Changelog
- Fixed: The composer's mode menu now lists the harness's own modes with their own labels, descriptions, order and icons (Claude: Auto, Manual, Accept edits, Plan, Bypass permissions; Codex: Ask for approval, Approve for me, Full access). The mode button shows the mode's symbol and name, and menu rows are tighter.
Regression test
cd webviews && bun test test/mode-menu-harness-modes.test.tsx (huge-blue)
- red on base (test commit 137c297 on ae0085b): 0 pass, 5 fail (no "Mode" heading, Normal/Full access rows, no symbol, plain footer hid the symbol, padded rows and text-colored check)
- green on head: 6 pass (the sixth case was added in review)
Observed / Not run
- Observed (huge-blue, after merging feat-cmux-next):
bunx tsc --noEmitpasses, andbunx vp checkreports no lint or type errors. Unit tests (mode-menu-harness-modes, access-chip-refused-mode, access-chip-pending-warning, new-tab-composer-first-frame, lit-glyph-css, agent-options-menu, composer-menu-width, popup-surface, popup-one-hairline): 28 pass. Browser tests withCMUX_BROWSER_TESTS=1(Chromium and WebKit): agent-pane-mode-keys 2/2, quiet-access-chip 4/4, composer-claude-split 18/18, agent-pane-start-mode-chip 4/4, agent-pane-switch-frames 3/3. Fixtures and expectations in those tests are updated to the harness's own names. - Browser tests with
CMUX_BROWSER_TESTS=1on the merged head, each file run alone: composer-footer-essentials 3/3, agent-pane-mode-keys 2/2, quiet-access-chip 4/4, composer-claude-split 18/18, composer-footer-plain 19/19, agent-pane-start-mode-chip 4/4, agent-pane-switch-frames 3/3. Unit tests: mode-menu-harness-modes 6/6 (now including Codex on the bridge's real four ids), access-chip-refused-mode, access-chip-pending-warning, new-tab-composer-first-frame and popup-surface all pass. tsc andvp checkare clean, and so is check-xcstrings-keys. - Base red, not this PR's:
test/lit-glyph-css.test.tsfails on feat-cmux-next for.acpmux-fast[aria-pressed="true"] { color: var(--agent-accent) }(from #23742). - Not run: gallery-play and the Mac app.
No capture: webview-only change; gallery compare to follow in a comment.
Leo-ask: ask-45c7e2e017
Leo-ask: ask-f8d7fe1c14
Agent session: cosmic-gray
🤖 Generated with Claude Code