cmux-tui: move-tab-to-column takes the new column's pane id from the caller (tab-column-client-pane-v1)

Merged
TE
2d ago
+452-93

Leo (2026-11-03): "it's so slow to open and close idk if there's some sort of threading issue but it's nigh instant for claude and codex so we nede to be at least as fast".

leo-named-fix. This is the daemon half. The app half follows in a second PR.

What

When a person opens a tab from a lone agent chat (Cmd-T, a New Tab pick, a folder), the chat docks left. Its pane keeps the new tab (ChatColumnPlacement.route .dockChat, which sends move-tab-to-column with dock and respawn). Until the daemon replies, the screen shows nothing new. To show the dock and the new tab's stand-in in the click's frame, the app needs the daemon's new column pane to replace its provisional one by id. split-client-keys-v1 already does this for split.

move-tab-to-column now takes an optional pane_id (pane_ and 32 lowercase hex digits), with or without respawn, behind the new capability tab-column-client-pane-v1:

  • The new column's pane takes that public id.
  • A malformed id is a bad request.
  • An id that a live or deleted resource already has is refused with pane_id_exists, and nothing moves.
  • Without pane_id, nothing changes.

Spec: cmux-tui/spec/commands.md, sdk-schema.json and api-compat.surface.json. SDK bindings were regenerated (bindings/codegen/generate.py --write), and the Rust bindings test names pane_id as missing.

Tests

cmux-tui-core server::split_respawn_tests::a_column_move_takes_the_callers_pane_id covers three cases:

  • the capability is advertised;
  • a malformed id is refused and moves nothing;
  • a keyed dock with respawn gives the column pane the minted id, and a second move with the same id is refused with pane_id_exists.

Performance

metricbeforeafterdeltaharness or run link
dock respawn, click to the dock showingdaemon round tripunchanged in this PRnonethe app half measures it

There's no user-visible change on its own: this is an additive request field behind a new capability.

Risk

risk:normal. Additive, opt-in field. Clients that don't send pane_id are unaffected.

Changelog

none

Agent session: agent session

🤖 Generated with Claude Code


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


Summary by cubic

Adds an optional pane_id to move-tab-to-column so the daemon's new column pane carries a caller-minted public id, letting the app replace its provisional pane by id when a lone agent chat docks left on a new tab. This is the daemon half; the app half follows, so there's no user-visible change on its own.

Changes

  • A malformed id is a bad request and moves nothing; an id a live or deleted resource has is refused with pane_id_exists.
  • With respawn, a used id is refused before the fresh tab is made, so a refusal consumes no terminal id the caller would retry with.
  • Without pane_id, behavior is unchanged.
  • The new field sits behind the tab-column-client-pane-v1 capability, advertised by the daemon.
  • Spec, SDK schema, api-compat surface, and all language bindings regenerated; tests cover the capability advertisement, malformed ids, a keyed dock with respawn, and used-id refusal.