fix(cmux-next): the first new terminal a script opens from Home after launch opens beside it, not refused (FC-1)

Merged
LA
5d ago
+66-11

Summary

The first New Terminal Tab after launch from a script, the CLI or MCP, aimed at Home's dock, now opens in a column right of the dock. Before, the daemon refused it.

FC-1 (fuzz catalog): about 6 s after launch, the first-5s bench's newSurface (action.run, origin script) on Home's focused dock failed in 4 of 5 launches (6 of 7 tries) with "new-tab: the daemon refused the new tab". A person's Ctrl-` in the same launches opened a terminal in 20 of 20 rounds.

Cause (confirmed in the bench: diagnostic job 461a988b39553e691602fe76, first-5s bench at 7189677d2a00, the app's unified log at the refused base terminal):

[com.cmuxterm.app.next:app.daemon] new-tab rejected: new-tab failed: dock-column-pinned: the pinned column takes no other tab (allow_tabs is off) [dock-column-pinned]

The code path:

  • HomeDock pins Home's dock in its dock move. It lets the dock take tabs (allow_tabs, column.update) only in a later, separate step (HomeDock.allowTabs). A person can also close the dock to tabs.
  • While allow_tabs is off, HomeDockOpens.opensBeside is false. So TabLifecycle.newTerminal sent a script's terminal into the dock itself.
  • cmux-tui refuses every tab in a pinned column that takes no tabs (ensure_pane_takes_tabs, dock-column-pinned, cmux-tui/crates/cmux-tui-core/src/mux/pinned_columns.rs).
  • A person's Ctrl-goes throughChatColumnPlacement.openTool` and opens beside the dock, so it was never refused.

Fix: in TabLifecycle.newTerminal, a terminal aimed at a pinned dock that takes no tabs opens in a new column right of the dock. A shown dock uses ChatColumnPlacement.openBesideDock, as a person's terminal from Home's lone dock does. A dock that no window shows uses new-pane-right. Home's dock opens nothing in itself, whoever asks (home-chief-pane.md H1, H5).

#30503 (landed) makes such a refusal name its real cause. This PR removes the refusal for this case. A follow-up PR makes Home's dock take tabs as soon as the tree has its ids (HomeDock.allowTabs waited for the next connection).

Changelog

  • Fixed: The first new terminal tab a script or the CLI opens from Home right after launch now opens beside Home instead of failing.

Testing

Regression test: HomeClosedDockNewTerminalTests (CmuxNextAppTests, same-tree cmux-tui). It shows Home's docked page, closes the dock to tabs (allow_tabs: false, the state between the pin and allow_tabs), then runs newSurface from a script and from the CLI. It expects no failure and a real terminal in a column right of the dock.

  • Red at 22c089222fb (test only, on top of #30503's commits), display worker cmux14 (gui-session-v1), CMUX_TEST_REQUIRE_GUI=1: step 68b2502b96ac9dffeb24dc8e failed with 4 issues, for .script and .cli: failures → ["new-tab: new-tab failed: dock-column-pinned: the pinned column takes no other tab (allow_tabs is off) [dock-column-pinned]"], and no terminal right of the dock.
  • Green at 27ee8cf1cc67, display worker cmux13s (gui-session-v1), CMUX_TEST_REQUIRE_GUI=1: step 15ddbf30f9705fa344a82e9d passed HomeClosedDockNewTerminalTests (1 test, 2 cases) and the existing HomeDockOpensTests (10 of 10).
  • The head f1848f383cf is 27ee8cf1cc67 merged with feat-cmux-next (which has #30503); the PR diff against feat is only this fix and its test.
  • Compile: cmux-ci compile-check --app --package CmuxNext --recipe-version 2 job 5be6112a1469fed96f234ecf passed at 27ee8cf1cc67 (CmuxNext, app, cmux-tui); job 17a409d80f452ddf8a1e7a6d at the head f1848f383cf.

Observed / Not run

  • Observed: the red and green display steps and the compile-check above, and prepush-gate.py with no new violations.
  • Observed: the diagnostic bench 461a988b39553e691602fe76 (without this fix) logged the dock-column-pinned refusal above on its first base terminal, and all 3 tries were refused.
  • Not run: the full CmuxNext suite and a dogfood build.
  • Not run: the first-5s bench with this fix (ref cp-scratch/fc1-newtab-diag-fix 109b27a3a43e); the display test above runs the same path.
  • Follow-up (separate PR): HomeDock.allowTabs returns with no retry when the tree has no resource ids for the dock yet, so allow_tabs can stay off for the whole launch.

No capture: only where a script's new terminal opens changes; the column right of Home already shows for a person's new terminal.

perf claim: none


Summary by cubic

Fixes the first new terminal tab that a script, CLI, or MCP opens from Home right after launch being refused by the daemon; it now opens in a column right of Home's dock.

Bug Fixes

  • Home's dock is pinned before it starts taking tabs (allow_tabs), so a tab aimed at it previously hit the dock-column-pinned refusal.
  • TabLifecycle.newTerminal now routes such a terminal beside the dock, matching where a person's new terminal opens.
  • A dock that no window shows uses new-pane-right instead.
  • Adds HomeClosedDockNewTerminalTests covering script and CLI origins.