fix(acpmux, agent pane): Ctrl-B works in the cmux model router's chats; acpmux says which chats it moves
Ctrl-B now works in chats from the cmux model-router profile. Before, the pane decided which chats get Ctrl-B from the harness's name (claude or claude-*), but acpmux accepts _acpmux/process/background for any Claude Code (claude-stdio) harness. Two things went wrong:
- The router profile runs Claude Code under the name
cmux, so it got no Ctrl-B. - An ACP agent that a user's config named
claude-*showed the hint, and acpmux then refused the request.
What changed
- acpmux: every session summary now has
backgroundsWork. acpmux computes it with the same checkprocess/backgrounduses (backgrounds_workinhub/processes.rs: the profile's kind is claude-stdio). So the summary and the request always agree. - The spec (
spec/acpmux-protocol.json) and the generatedtypes.tsare regenerated.docs/background-processes.mdnow says clients offer Ctrl-B from this field, not from the name. - Pane:
backgroundsWork()reads the summary's field, plus the existing no-peer and not-Cloud checks. If the summary doesn't have the field (an older acpmux), the chat gets no Ctrl-B. For another harness, a peer's chat, or a Cloud chat, the hint stays hidden and Ctrl-B stays the composer's, as before. - Gallery:
agent-pane.background-hintgains aroutervariant (hint shown) and aclaudeAcpvariant (no hint). The sharedchat()fixture sets the field for Claude chats, so other gallery entries don't change.
Why a summary field: steering already works this way (a capability the session summary reports, which clients read). It also lets the client stop guessing harness names. The other option, initialize's operations list, applies to the whole connection, not to one chat.
Changelog
Fixed: Ctrl-B moves running work to the background in chats from the cmux model router, and the Ctrl-B hint no longer shows in ACP chats that only have a Claude-like name.
Tests: red on the base, green on the head
The tests are committed alone first (763316662ea), and the fix follows (88f6549ed18). Everything ran on cmux16.
cargo test -p acpmux --test hub_integration a_chats_summary_says_whether_ctrl_b_moves_its_work- Base + tests: FAILED.
backgroundsWorkisNullwherefalseis expected. - Head: ok.
- Base + tests: FAILED.
bun test test/run-in-background.test.ts- Base + tests: 2 fail. The
cmuxchat gotfalse, and theclaude-acpchat gottrue. - Head: pass.
- Base + tests: 2 fail. The
CMUX_BROWSER_TESTS=1 bun test test/agent-pane-ctrl-b-background.test.ts- Base + tests: 2 fail. "the model router's chat … shows the hint and moves its work" and "an ACP agent named claude-acp shows no hint and keeps Ctrl-B".
- Head: all pass.
Observed / Not run
Observed on cmux16 at the head (1bc4ff07a83, after merging feat-cmux-next at 1369f27dcd3):
- Rust:
- all 38
processeshub tests pass (the new one, Ctrl-B, the Codex processes) protocol_ir_is_currentpassescargo fmt --checkis cleanclippy -p acpmux --all-targets(run before the merge) reports only three warnings, all outside this change and all on the base:sort_by_keyin cmux-worktree-care,cmp_ownedin steer_now_tests, anddouble_ended_iterator_lastin tests/prompt_images.rs
- all 38
- Webviews:
vp checkfinds no warnings, lint errors or type errors- the other check scripts pass, and
acpmux-protocol:checkreports the generated code is current bun run checkstops atcheck:switch-fetches, which is red on 1369f27dcd3 too (composer/keptAttachments.ts:134)- the run-in-background unit tests pass.
ui-rulesfails on CopyButton.tsx:43-44, which is red on 1369f27dcd3 too - the browser Ctrl-B test passes (12 tests), including the base's new notice tests
Before the merge, on 3020a012c47 plus this change, bun run check showed 0 errors. Its two warnings are in HistoryPage.tsx and test/sidebar-rail-css.test.tsx, neither touched here.
Four acpmux tests fail the same way on 3020a012c47 with and without this change, so they are base reds:
- lib:
protocol_registry_names_every_served_method - lib:
care_a_stopped_daemon_s_sessions_are_use_not_open - hub_integration:
session_offers::an_offered_chat_is_a_chip_only_… - hub_integration:
transfer_guard::a_chat_with_no_asking_mode_moves_…
Not run:
- the full acpmux suite on Linux or Windows (CI covers those)
- a live router chat in a tagged build
No capture: this is a webview-only change. The browser test and the agent-pane.background-hint gallery variants cover it.
🤖 Generated with Claude Code
Agent session: cosmic-gray
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fixes Ctrl-B in chats from the cmux model router profile. The pane previously decided which chats offer Ctrl-B from the harness name (claude or claude-*), but acpmux accepts background requests for any Claude Code (claude-stdio) harness. So the cmux router profile got no Ctrl-B, while an ACP agent named claude-* showed the hint and got refused.
Every session summary now reports backgroundsWork, computed with the same check that _acpmux/process/background uses. The pane reads this field instead of guessing from the harness name.
- Across both
cmuxand the agent pane, a chat'sbackgroundsWorkcomes from the summary, so the hint and the request always agree. - An acpmux that does not report the field (older version) gets no Ctrl-B.
- Tests cover the
cmuxrouter chat (hint shown, work moves) and an ACP agent namedclaude-acp(no hint, Ctrl-B refused).