feat(next): centralize right-pane placement policy

Closed
TE
6d ago
+149-1

Lawrence said: "leo view changes is still bad / it should open to the right". Leo then clarified the split behavior: "if a right pane exists, open as a new tab after its ACTIVE tab" for documents, while "A SESSION (subagent, associated session, side chat) gets its own BOTTOM split of that right column the first time"; narrow layouts should tab instead of splitting.

This PR adds the shared, pure RightPanePlacement policy and focused Swift tests. It encodes:

  • no right column creates one (or keeps the item in the chat below 480 pt);
  • documents target the top-right area and sessions target a bottom-right area;
  • first session splits below documents, later sessions append after the active tab;
  • duplicate identities select the existing item anywhere in the right column;
  • split thresholds are 480 pt chat width and 420 pt right-column width.

The policy is intentionally value-based so LinkOpener, AgentBesidePlacement, openBeside, AgentSidePanes, and subagent/session callers can share the same decision without workspace or window jumps. Full native routing and real-app before/after capture are coordinated in the parent PR stack.

Validation: git diff --check; pure Swift placement tests added for every rule, including narrow-window fallbacks, main-pane-compatible area modeling, active-tab anchors, and dedupe.

Related: #26093, #25721

agent-identity footer --repo manaflow-ai/cmux


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Centralizes right-pane placement into a shared, pure RightPanePlacement policy so documents, sessions, and links all make the same split decisions from a caller-supplied pane snapshot.

The policy creates a right column when none exists (keeping the item in the chat below 480 pt), inserts documents above sessions, gives the first session its own lower split, appends later tabs after the active one, deduplicates by identity across the whole column, and falls back to tabbing when the chat or column is too narrow (480 pt chat width, 420 pt right-column width). LinkOpener now follows the right column's active tab instead of the chat's selected tab, preserving insertion order there. Swift tests cover every rule, including narrow-window and active-tab anchor fallbacks. Related: #26093, #25721.