cmux NEXT Needs you: a jump opens the waiting chat on the right, in the chat's side pane

Merged
TE
9d ago
+150-27

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 /btw open), 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-motion on the right and never calls openSide or openTab.
  • 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.tsx already pins chat.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: AgentPaneAskOpenTests and TabMirrorPlacementTests. 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: AgentPaneAskOpenTests and TabMirrorPlacementTests, 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, tree 55f8e2b2bf493f9d5ea644f56dbfcb4bc611bca2 (snapshot c9a6baf4cb946e1c9e19ee4e621165740f486a80).
  • Unrelated check reds classified from completed job logs: gallery health(3) reports zero broken states but the untouched streaming-text#jump-during-stream fixture takes17,348ms against its2,000ms budget. Release-notary tests fail in untouched tests/test_nightly_sparkle_key.sh and tests/test_nightly_legacy_publish_linux.py against unchanged .github/workflows/nightly.yml. These four files are byte-identical to base f2c7e19bd074a3cd363709c6771a65ddd9b245e2; Guard status aggregates the same release-notary failure.

Agent session: agent session