cmux-next: main pane layout, an agent chat's opens land in one column on its right
An agent chat is now its screen's main pane, and nothing opens into it. Links, files and folders a chat opens, and its subagent and side chat panes, become tabs in one column on the chat's right. A chat alone on its screen docks left the first time, so that column slides in beside it. Closing the column's last tab gives the chat its full width back: the daemon folds the dock into a plain pane, which dock_column_flags_cleared_by_a_close_stay_cleared_after_restart covers.
This is on by default as layout.mainPane: "agent-chats", and "off" turns it off. Debug Settings > Panes and Columns > Main pane layout overrides the setting: Follow the setting, On or Off.
How it works
MainPaneLayout.side (CmuxNextLayout) reuses ChatColumnPlacement, the rule a person's new tab from the chat already follows:
- From the chat dock, the new tab goes into the strip pane the person used last.
- From a lone chat, the chat docks left (
.dockChat). - Any other pane keeps today's rules: a strip pane, a terminal, a chat sharing its screen without a dock, a zoomed screen, and Home's pinned dock when it is alone.
The callers:
LinkOpener: links, files and folders from the chat go to the column on its right. Before this, a click in a chat opened a tab inside the chat (#22822).- From a lone chat, the tab opens unselected in the chat's pane, then the chat docks left with the agent chat role (
MainPaneLayout.dockChat). - A folder docks the chat and leaves the folder's terminal in its pane, in one daemon commit (
ChatColumnPlacement.route).
- From a lone chat, the tab opens unselected in the chat's pane, then the chat docks left with the agent chat role (
AgentTabStore.openBeside: subagent panes and side chats open as tabs in that column, not as splits stacked beside the chat.- Agent opens (
beside_caller: browser, diff, process terminal, Files tree) and a person's Cmd-T from the chat already landed there. They're unchanged.
Focus follows the link-focus rule. A person's click focuses the new tab. An agent's open, or an unfocused subagent open, selects its tab in the column without moving keyboard focus (selectWhenReportedKeepingFocus). A lone chat's open reports finished only once the chat is listed in its dock, so a second open right after it is a tab in the same column, not a split. A past chat picked on a New Tab page in the dock still replaces the page in the dock (mainPane: false): chats never become tabs in the right column.
The slide-in uses the existing pane springs. #22949 (directional-motion) holds the chat in place while a lone chat docks for AgentBesidePlacement. Once it lands, MainPaneLayout.dockChat gets the same one-line handOffContent hint.
Changelog
- New: an agent chat stays as the main pane, and what it opens appears as tabs in one column on its right (Settings > General > Main Pane).
Testing
- I ran 5 suites on the fleet at the PR's head:
MainPaneLayoutTests,MainPaneSettingTests,LinkOpenPlacementTests,LinkPlacementSettingTestsandHomeLoneDockTests. All 30 tests passed, at both bf31888 and ea6e682. - The settings exports were regenerated by the PR autofix (run 39588693869).
defaults_guard.py check-stamppasses. prepush-gate.pyfound no new violations, andlint-ios-package-conventions.shpassed.- The independent review is in the PR comments. It found three problems in the first version, all now fixed: agent opens took focus, a quick second open made a split, and resumed chats landed in the right column.
- The tour is
scripts/cmux-next/media/tours/main-pane.json, run under themedia-tourlabel. It shows a lone chat docking for a link, tabs joining the right column, and closing the column giving the chat its full width back.
🤖 Generated with Claude Code
Agent session: cosmic-gray
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
An agent chat now stays as its screen's main pane: links, files, folders, subagent panes, and side chats it opens land as tabs in one column on its right, instead of inside the chat (#22822) or as splits stacked beside it.
- On by default as
layout.mainPane: "agent-chats";"off"restores the previous rules. A Debug Settings override (panes.mainPane: Follow the setting, On, Off) can force either. - A chat alone on its screen docks left the first time so that column slides in beside it; the dock hands off the chat's content so only the new column moves, and cancels the hint if the dock fails. Closing the column's last tab gives the chat its full width back.
- A person's click focuses the new tab; an agent's open selects it without taking focus, and a queued open waits until the chat is in its dock so it lands in the same column.
- A past chat picked on a New Tab page in the dock still replaces the page there; main pane routing applies to terminals, browsers, and links only.
- Settings exports, MDM docs, and localizations were regenerated; tests, a tour, and a release-note highlight with a New Agent Chat try-it action cover the change.