cmux NEXT: a link or terminal opened on the right goes to the pane that already holds its kind
Leo, 2026-10-31, of a link from a chat that opened in a new lower-right browser pane under the browser pane already on the right:
"imo in this case, just open it on the existing. you only need the rightmost botom auto split when there's a terminal that gets opened when there's already a browser, and vice versa"
This builds on #28989 (the right column's lower-pane split) and keeps that split for everything but this case.
The rule
RightColumnPlacement.decide now also gets the kind being opened (Kind: .terminal or .browser, the two Leo named) and which kinds each pane in the right column holds:
| On the chat's right | Opening | Before | After |
|---|---|---|---|
| nothing | anything | split right | split right (unchanged) |
| a browser pane | a link / browser | split below it | a tab in that browser pane |
| a browser pane | a terminal | split below it | split below it (the kind differs) |
| a terminal pane | a terminal | split below it | a tab in that terminal pane |
| a terminal pane | a link / browser | split below it | split below it |
| browser over terminal | a link | a tab in the lower (terminal) pane | a tab in the browser pane |
| browser over terminal | a terminal | a tab in the lower pane | a tab in the lower (terminal) pane |
When several panes hold the kind, the lowest one gets the tab. The width floors only ever turned a split into a tab, so they don't change here.
Paths
- Links:
LinkOpener.openWeb(a chat's links, a terminal's Cmd-click, Home, pages) and a browser page's Cmd-click (BrowserPageRequests.openOnRight) open as.browser. Its reuse check (select a tab already showing the page) uses the same target. - Folders:
LinkOpener.openFolderopens as.terminal. - The docked chat's strip column (
MainPaneLayout,LinkOpenPlacement.inColumn) follows the same rule. - Unchanged (no kind): chats, subagents, side sessions, Session Info sessions, transcript cards and file pages. Leo named only terminals and browsers.
Not in this PR: a terminal or browser picked on a New Tab page in the chat dock (NewTabPage+Open.openBeside). #28544 rewrites that call and is landing. A follow-up passes the pick's kind there once #28544 has landed.
Tests
RightColumnPlacementTests.aBrowserOrTerminalGoesToThePaneThatAlreadyHoldsItsKind: same kind gets a tab and a different kind splits below, for each kind. With both kinds on the right, each open goes to its own pane. A narrow column and an empty right side behave as before. An open with no kind behaves as before.LinkOpenPlacementTests.aLinkGoesToTheBrowserPaneAlreadyOnTheRight: the same rule throughLinkOpenPlacement.targetand the docked chat'sinColumn.- The existing lower-split tests (open with no kind) are unchanged and still pass.
Spec: leo-workspace design/pane-placement.md gets a "Same kind goes to its pane (2026-10-31)" section.
Risk: a behaviour change in where a link or folder opens when the right column already holds a pane of that kind. No new timers, observers or animation loops.
Screenshots: none (Leo, 2026-10-31: "WE DONT NEED FUCKIGN SCREENSHOTS JUST LET ME TRY THE SHIT OUT").
Agent session: agent session
š¤ Generated with Claude Code