cmux-next: chat clicks open beside the chat, one right pane
Bead: cx-1ndnn
In a chat, links, file refs and the Changes diff chip now open in the pane to the right of the chat. The first click makes that pane: a chat alone in its workspace docks left and the page opens right of it, so the chat stays in view. Later clicks add tabs to the same pane, never another split. Clicking something already open there selects its tab. Cmd-click keeps the old behavior: the default browser for links, the chat's own pane for files.
ChatBeside is the one routing entry point. It finds the pane right of the chat, selects a tab there that already shows the entity, or opens the entity there through the existing beside-caller placement (openBrowser, ViewerService.openFile(…, beside:)). Keyboard focus stays in the chat. Anything it can't place (a remote or reconnecting daemon, a file kind the browser previews) falls back to the old open.
Call sites wired:
AgentTabContentopenURL: transcript links, PR chips and links, Open Link. A link click's own modifiers decide Cmd (AgentPaneLinkClick, set around the open indecidePolicyFor).AgentTabContentonOpenFile(tab target): path chips, changed-file rows, project files and instructions.AgentChatSplitToggles: the Changes diff chip targets the beside pane when one exists.
Not wired yet (follow-ups on cx-1ndnn): subagent transcripts, terminals, Cmd for file refs (the page's open-file message needs the click's metaKey), and re-clicking the Changes chip selecting its tab. The opt-in Tile subagents layout builds on this.
No new animation: the dock and the tab use the existing placement.
Testing
| check | before | after |
|---|---|---|
open-beside-realchat-e2e.py: a real chat (acpmux fake harness) | FAIL 0/5 on the test build: links go to the default browser, the file covers the chat | PASS 5/5 (incl. "the chat docks left and the opened pane is in view") |
open-beside-e2e.py: a New Tab page seeded with the links reply | FAIL 1/4 on the test build | PASS 4/4 on the exact fix head |
| same, row "a file already open in the chat's pane still opens beside" (review finding) | FAIL 3/4 on the first fix | PASS 4/4 |
open-beside-realchat-e2e.py after the base merge (24f8b66e: #20659's attach fix, #20635), Mac DEV build | PASS 5/5 |
DEV builds on cua-3/cua-4. The Linux pool shipped a stale web bundle, so those builds were made on Macs (cx-s3k17). Two Opus reviews: the second found nothing blocking; its reconnect finding is fixed (a reconnecting daemon takes the old path).
The real-chat script finds the build's acpmux home under ~/.acpmux/builds/<key> since base's per-build isolation (cx-is1kf.3); before #20659 every chat attach was refused on base (cx-b08ei), so the script could not bind a chat.
Pre-push: crash ratchet, concurrency, god files (nothing grew), system-blue, conventions lint, webviews bun run check.
Proof
The recording below is from window snapshots of real DEV builds at 1500x900, with the composer's machine name blanked. I watched it. Before: nothing opens in the app; at the end the file page fills the chat's pane. After: the chat docks left, /pr/1, /pr/2 and notes.md open as tabs in one pane right of it, and the chat stays in view.
Changelog
- Changed: In cmux NEXT, links and file refs clicked in a chat open in one pane to the right of the chat; Cmd-click keeps the old behavior.
🤖 Generated with Claude Code
Showcase

Full quality: