cmux NEXT Needs you: a jump opens the waiting chat on the right, in the chat's side pane
Leo, 2026-10-22, on #23849's Needs you jump, which opened the waiting chat as a tab after the coordinator's: "just do more on the side? the right pane has so much... or just do a split on the right...". The team rule from the same day: "DEFAULT ON THE RIGHT".
Change. chat.asks.open (AgentPaneAskOpen) still focuses the tab that already shows the waiting chat. When there is none, it opens the chat on the chat's right the way a link does (LinkOpener, layout.linkPlacement, through a new openRight header hook). It never opens in a new tab in the chat's own pane.
- A pane is already on the chat's right, a plain split's terminal included: a tab there, selected and focused.
- No pane there: a new split on the right.
- The chat is its screen's main pane: a tab in the column on its right (
MainPaneLayout), as before. - Nothing opens there (no window, or the pane on the right belongs to another machine, which never gets a chat of this Mac's acpmux): the chat's side pane (
AgentSidePanes, where New side chat and/btwopen), as in the first version of this PR.
The side pane alone missed one case. It reuses only a pane it made itself, so a chat in a plain split (chat | terminal) with no side chat open got a third split instead of a tab in the pane already on its right. projects-d7 found that gap.
With layout.linkPlacement set to same-pane, the jump follows that setting the way links do.
Tests (red first). AgentPaneAskOpenTests:
- A jump opens
directional-motionon the right and never callsopenSideoropenTab. - A second jump focuses the tab that shows the chat.
- When nothing opens on the right, the side pane takes it.
- A jump to the chat itself, a peer's chat, a remote chat, or from a pane with no chat opens nothing.
- Webview: comments only;
agent-pane-needs-you.test.tsxalready pinschat.asks.open.
The app wiring reuses LinkOpener.open with openTab(in:session:select:), the pattern ChatsOpenCoordinator uses for a New Tab page's chat. Placement itself is LinkOpener's existing, tested logic, so there is no capture.
No capture: the change is where a Needs-you jump opens a chat (a tab in the pane on the right, else a split), and no capture scene or tour clicks a jump. AgentPaneAskOpenTests pins the order (shown tab, then the right pane, then the side pane), and placement is LinkOpener's existing tested logic.
š¤ Generated with Claude Code
Current exact-head verification
- Rebased onto current
feat-cmux-next(f2c7e19bd074a3); exact pushed head:64b1c7c12f20a3928dbcd5fb96d58bdd8660c9f3. - Independent Codex gpt-6-astra xhigh review: SHIP at the exact head. It inspected right-side LinkOpener placement, local-daemon/session guards, side-pane fallback, mirror readiness and cancellation; no concrete P0āP2 findings. Static review only; supplied tests and CI were not rerun by the reviewer.
- Superseded-head changed suites passed:
AgentPaneAskOpenTestsandTabMirrorPlacementTests. The old broad Swift red was in untouched base suites (AcpmuxDaemonSummaryTests,ProcessLauncherTests, sidebar movement/pinned-row tests and ScreenReplace), and old gallery health/Guard status were base/harness reds. - Local prepush gate passes with no new violations.
- Exact-head fleet Release compile passed: job122460243922. The status validates repository/head, recipe version2 and
release-onone, and reports the app compiled and linked in SwiftPM Release (-Onone). - Exact-head app compile also passed: job122461025870, fleet job
e005190f4fef0d45da581112, with an actual compile pass (106 s); this is not the skipped advisory test-compile plan. - Exact-head changed native suites passed in Swift job122462122599:
AgentPaneAskOpenTestsandTabMirrorPlacementTests, six tests / two suites. The later broad pass explicitly excludes those suites and ends in the existing SwiftPM-helper harness failure (unexpected signal code5, no final summary), after starting3,386 unrelated tests; no changed-suite failure was reported. No rerun was dispatched. - Exact-head focused web tests passed: run40576655546, 25 tests / 108 assertions / zero failures. Source
64b1c7c12f20a3928dbcd5fb96d58bdd8660c9f3, tree55f8e2b2bf493f9d5ea644f56dbfcb4bc611bca2(snapshotc9a6baf4cb946e1c9e19ee4e621165740f486a80). - Unrelated check reds classified from completed job logs: gallery health(3) reports zero broken states but the untouched
streaming-text#jump-during-streamfixture takes17,348ms against its2,000ms budget. Release-notary tests fail in untouchedtests/test_nightly_sparkle_key.shandtests/test_nightly_legacy_publish_linux.pyagainst unchanged.github/workflows/nightly.yml. These four files are byte-identical to basef2c7e19bd074a3cd363709c6771a65ddd9b245e2; Guard status aggregates the same release-notary failure.
Agent session: agent session