cmux NEXT: anything opened on the right goes to the lower pane when the right already holds something
Leo, 2026-10-30:
"subagent stuff... or anything we expect to open on "the right"... if there's already a thing on the right, there should be logic for just putting it on the lower pane of the right. that kinda split."
Earlier, 2026-10-28 (the spec, leo-workspace design/pane-placement.md):
"I mean the right top pane, and then you split to the bottom once so that you get the three items. But you want four items. I don't know what the fourth item should go."
Stacked on #27789. This PR's own diff is ef884b554e8f..HEAD. It stays a draft until #27789 lands.
The rule
One function, RightColumnPlacement.decide (CmuxNextAgentPane), decides every open on the right of a pane. Its input is the right column the window actually shows (RightColumn.measure, from the pane geometry):
| What's on the right of the source | Where the new item goes |
|---|---|
| nothing | a new split right of the source |
| one pane (diff, terminal, browser, session, anything) | a new split below it; that pane keeps what it shows |
| two or more panes | a tab in the lowest pane, never a third split |
- No split leaves the chat under 480 pt or the right column under 420 pt; that open becomes a tab instead.
- Closing the lower pane's last tab removes the pane, so the split collapses back, and the next open splits below again.
Paths routed through it
-
Transcript subagent / Task cards (
AgentSubagentPanes): #27789's placement function, now shared and reading the window's geometry instead of the tracker's own list. -
Side chats,
/btw, Session Info sessions, transcript session cards (AgentSidePanes;chat.sideChatandchat.offer.open). -
Links opened to the right, and chats opened from Needs you (
LinkOpener/LinkOpenPlacement): new.splitBelowtarget for a source that takes tabs.openWeb's reuse of a page already open on the right,openFolderandDurableTabLink's fallback handle it. -
Main-pane layout (ux-owner, 2026-10-30, on Leo's "anything we expect to open on 'the right'"): the strip column right of the docked chat is its right side, so the same lower split applies (
LinkOpenPlacement.inColumn,openOnRight). With nothing on its right yet, main-pane layout still makes the column by its own rule.
Unchanged: Home's pinned dock (a different surface, not named) keeps the link rule: the pane on its right, else a column beside the dock.
Overlap
This overlaps #26582 (RightPanePlacement, the general document/session policy, owned by another lane), which doesn't touch these paths yet. This PR doesn't take its type or touch its branch. Every path here calls one pure function, so it can fold into that policy later.
Tests (one per path)
RightColumnPlacementTests: the rule itself, narrow floors, and close-collapses-then-splits-again.AgentSubagentPanesPlacementTests: with the right side occupied, the first subagent splits below it and the second is a tab there; closing collapses; a 4th subagent is a tab, never a third split.AgentSideSessionPaneTests: side sessions split right, then once below, then become tabs in the lower pane; with the right side occupied they split below it; closing the lower pane's tabs collapses it and the next open splits again.LinkOpenPlacementTests: with the right side measured, a link beside a pane splits below it, a full column takes a tab in its lower pane, narrow columns take a tab, and the main-pane strip column gets the same lower split.
Spec: leo-workspace design/pane-placement.md gains "Something already on the right (2026-10-30)" (lane/ux-pane-placement-lower).
Screenshots
Before/after: pending a fleet capture (requested from ux-owner for the media tour). They'll be added before this leaves draft.
Risk: a behaviour change in where the 2nd+ item opens on the right, for all of these paths. No new timers, observers or animation loops.
Agent session: agent session
š¤ Generated with Claude Code