cmux NEXT: Ctrl-B runs work in the background; Summary shows live background tasks

Merged
TE
16d ago
+3184-372

Leo asked "where is ctrl/cmd b here? where is the background showing?" The case: a turn runs 3 commands while many acpmux child sessions and background commands are live, yet the Summary panel shows Outputs, Subagents and Sources all as "None".

What changes

  • Ctrl-B moves running work to the background in a local Claude Code chat, like Claude Code's own Ctrl-B.
    • Ctrl-B works anywhere in the chat, the composer included, while the current turn runs a command or a foreground subagent in the foreground. A subagent draws no tool row, so a running one counts by itself. Ctrl-B sends acpmux's new _acpmux/process/background, which sends Claude Code's background_tasks control request.
    • A running command's row shows a dim "⌃B to run in background" hint. It fades in after 1.5 s when motion is on, so quick commands don't flash it. A call still waiting for permission shows no hint and doesn't take Ctrl-B.
    • With nothing running, Ctrl-B stays the composer's (move the caret back one character). The page leaves Ctrl-B alone in these chats, which never show the hint:
      • Codex and other harnesses, which acpmux refuses.
      • A peer's chat and a Cloud chat, whose processes this acpmux can't move.
    • ⌘B stays the left sidebar's (toggleLeftSidebar), so only Ctrl-B ships.
  • acpmux _acpmux/process/background {sessionId, toolCallId?} → {backgrounded}:
    • Claude only. Web and Peer connections are refused, like process/kill.
    • Shells it moved report origin: "user_backgrounded".
    • CLI: acpmux process background SESSION [--tool-call ID].
    • The spec and generated TS are regenerated. Base's IR was stale and lacked worktree/*, so those methods also show in this diff.
  • The summary card shows live background work:
    • Running commands come from acpmux's process registry, merged with the transcript's commands by toolCallId. Running ones list first, with elapsed time and Stop. Finished ones fold into one row.
    • Child acpmux chats started with -m parent show under Subagents with their state, and open on click.
    • Header counts include both.
  • Empty sections collapse. No more "None" rows. An empty card shows one quiet line, and "Attach files or folders" stays reachable.
  • The turn line, and a row after the turn:
    • While the turn runs, its line counts registry commands and running chats.
    • When the turn ends with work still running, one row says "Running in background · N commands · M sessions" and opens the summary card.

Shortcut-rule deviation

Ctrl-B is handled in the chat page, not as an ActionDescriptor/keybinding. It follows the pattern of Esc-stop (escapeStop.ts): an in-chat key that copies Claude Code's own key. It is live only while foreground work runs, so it doesn't take the composer's Ctrl-B the rest of the time.

Changelog

  • Added: cmux NEXT: Ctrl-B moves a Claude Code chat's running command or subagent to the background. The chat summary lists running background commands and started chats live, instead of empty "None" sections.

Observed

  • acpmux on cmux16:
    • cargo test -p acpmux --test hub_integration process: 36 passed, 6 of them new.
    • --lib claude_stdio: 40 passed. --lib cli::process: 14 passed. protocol_ir_is_current passes.
    • cargo fmt --check is clean.
    • clippy has only 2 lints, both red on base too: unnecessary_sort_by in cmux-worktree-care and cmp_owned in steer_now_tests.
    • The other failures in the full suites fail on base too.
  • webviews on cmux16 at db2f72c5517, with base merged in:
    • bun run check: 0 errors, formatting, type scale and layers all clean. It still exits 1 on one lint warning, in base's HistoryPage.tsx.
    • Unit tests pass: run-in-background, summary-background-work, session-rail-tasks, transcript-working-line, pane-english, ui-rules, escape-stop and gallery-coverage.
    • The tooltip-rules test flags only lines in files this PR doesn't touch (SavedEnvironmentPanel, RailChanges, PendingSteer, StatsPage).
  • prepush-gate.py: no new violations.
  • CI reds at 4409bd43436 that are not this PR's: defaults-snapshot (stale CmuxNextSettings exports from base) and the Guard status wrapper. The release-notary red was this PR's highlight, which lacked a docs link; it is fixed in db2f72c5517.
  • Gallery before/after: https://cmux-lawrences-mac-mini.tail137216.ts.net:18796/compare/bg-tasks-ctrl-b/ (entry agent-pane.background-hint, plus the summary card entries).

Not run

  • The Playwright tests (agent-pane-ctrl-b-background, agent-pane-background-tasks, agent-pane-subagents-tab, agent-pane-working-counts) skip on cmux16, which has no browser engines. CI's react-apps job runs them.

Follow-ups

  • A failed Ctrl-B shows no notice yet.
  • If Claude never answers background_tasks, its shells stay marked as asked.
  • In a chat the registry can't list, a background task whose end was never seen keeps the "Running in background" row.

Leo-ask: ask-75cd16a7d1

🤖 Generated with Claude Code
Agent session: cosmic-gray