carry of #28175: cmux: add first-class space CLI commands

Merged
TE
5d ago
+414-12

Carry of #28175 (its owner's session is gone). It keeps that PR's six commits with their authorship, merges feat-cmux-next in, and fixes the two findings of the review that blocked it at edcac1e.

Leo, 2026-10-30, as quoted on #28175: "oh also spaces warrant good commnds too" / "good intuitive stuff".

Summary

What #28175 adds: first-class cmux space verbs.

  • cmux space list reads the daemon's room listing.
  • cmux space new <name>, switch <name>, rename <old> <new>, close <name>, move workspace <workspace> <space> and move tab <tab> <space> run the app's catalog actions. The CLI and MCP go through the same registry.
  • A new catalog action tab.moveToSpace (cmux tab move-to-space, palette and MCP app_tab_move_to_space) is the tab twin of Move Workspace to Space.
  • cmux space --help and the root help list the scope (English and Japanese).

Fixed in this carry:

  • P1, Move Tab to Space moved every sibling tab. The old code pinned the tab's whole workspace to the space. Now only the tab moves (Packages/macOS/CmuxNext/Sources/CmuxNextApp/Handlers/TabHandlers+More.swift, moveToSpace, lines 63-79):
    • A tab alone in its workspace takes that workspace with it: a pin in the home session, as Move Workspace to Space does.
    • A tab with siblings moves to a new workspace through TabMoves.toNewWorkspace, the path Move Tab to New Workspace uses. That new workspace is then pinned to the space, and the siblings stay where they were.
    • Home's own tab is refused. So is a workspace already pinned to that space.
    • The action is .waiting(.daemonEcho), since a space pin has no store intent.
  • P2, cmux space rename --name Office targeted a space named --name. The positional forms now match only the words before the first option, the same way the generic <noun> <verb> route reads them. Options after the positional words reach the action. Flag forms fall through to the catalog route unchanged. The space forms moved to cmux-tui/crates/cmux-tui/src/cli/app/space.rs.
  • tab.moveToSpace had no tab-menu placement and no exemption. It is now exempt from the tab right-click menu as pointerMenuTrim: that menu's Move folder already has Move Tab to Workspace…, and a list of spaces there would bloat it. It stays in the palette, CLI and MCP.
  • Generated exports listing the new action are updated by hand to match what the generators write: plans/cmux-next/action-surfaces.json; the plans/cmux-next/actions.md counts (1282 actions, palette 1229, CLI verbs 757, MCP 675, tab 106, pointerMenuTrim 15); and web/data/next-docs/*.generated.json, written by bun web/scripts/export-next-docs.ts. The PR autofix regenerates the action exports on the fleet if anything differs.
  • plans/cmux-next/arch-ratchet.json: one app_lines exception for this handler's lines. The handler needs App-only types (TabMoves, WindowProfiles, AppServices, AppActionContext), so it can't live in a package. The reviewer judged this justified.

Testing

  • Red test first: space_flags_are_not_positional_names and space_positional_forms_keep_trailing_options in cmux-tui/crates/cmux-tui/src/cli/app/tests.rs. Commit 9c09857 adds them before the fix.
  • Rust, through cmux-ci on this PR at 32b3929 (run 41161031549): cargo test -p cmux-tui cli:: exits 0. With the P2 fix reverted, space_flags_are_not_positional_names and space_positional_forms_keep_trailing_options fail.
  • The original #28175 test space_mutations_use_the_catalog_actions_and_name_targets was red at its own head: run_action leaves out args when an action takes none. The tests now read a missing args as {}.
  • Swift: the fleet test-compile of this PR passed (run 41156732209 at e8d51c7; the commit after it changes only Rust tests).

Observed / Not run

  • Observed: scripts/cmux-next/check-state-roots.sh ok; scripts/cmux-next/check-no-godfiles.sh --only rust ok; prepush-gate.py passes with the ratchet exception.
  • Not run: a tagged build with a live cmux space move tab across two spaces. Only the reviewer's read and the compile cover the Swift handler.

Changelog

Added: cmux space list|new|switch|rename|close|move commands and a Move Tab to Space action

Proof

No capture: CLI verbs and a palette/CLI-only action; no right-click menu or other native UI changes.

Supersedes #28175.

Agent session: agent session

🤖 Generated with Claude Code