cmux mcp: `current` is the agent's own place; new terminals and links open beside its chat

Merged
LA
12d ago
+897-9

Problem

Two bugs, one cause: when an agent named no place, the call went to the daemon's notion of "here", not to the agent's chat.

  1. A cmux_exec script that split workspace: "current" split another workspace. The daemon reads current as its active object, and that is neither the chat's workspace nor always the one the app shows. In one live check these were three different workspaces.
  2. A workspace agent (Chief TUI + fast iteration) asked to "open it to the right" opened the Chief TUI in Home. tab_create_terminal with no pane went to the daemon's active pane, and workspace_open_url with no workspace defaults to the home workspace.

Change

  • current in cmux mcp serve is the calling chat's own workspace, screen, pane, or tab. The server asks the app on each call (system.identify), so a moved chat is followed. focused is new: it means what the app shows (snapshot.get). Under another object, current keeps the daemon's meaning (the active child). A caller the app cannot place fails with caller.unresolved, not with a guess. A client with no caller identity, or a call to another session, keeps the old behavior. (cli/mcp/caller_scope.rs)
  • Beside the chat (cli/beside.rs, one rule for the CLI and MCP): an agent's terminal that names no workspace, screen, or pane goes to the column right of its chat. With no such column, a split right of the chat makes one (viewport_width 0.66) and the tab gets its name. An MCP link with no workspace goes to the app's browser.open_split, so the existing beside_caller rule places it. A person's terminal (no CMUX_AGENT_SESSION) and a named place keep their target.
  • The cmux-workspace skill gets these rules and a section on larger layouts beside a chat: dock the chat left, a column per task, splits for views read together, and widths.

Evidence

  • cargo test -p cmux-tui --lib -- cli::mcp cli::beside: 107 passed (16 new). Four cli::app and remote_cli tests fail in my shell with and without this change (they read the agent env).
  • Dogfood with the branch binary against cmux NIGHTLY:
    • current resolved to the chat's screen while the app showed another workspace. focused resolved to the shown one.
    • As the Chief TUI agent: tab_create_terminal with no place made a column in its own workspace (Home tab count 15 → 15), a second call reused it, and cmux tab create terminal from the CLI used it too. A link went to beside_caller in its own workspace. A person's terminal with no agent env stayed in its old pane.
    • Splitting the docked chat is refused by the daemon (dock-column-agent-chat), as it should be.
    • Built 3 layouts (3 columns with splits, a 2×2 grid, a browser column) only through current, then closed them.
    • Cost: about 97 ms for a current call, against 75 ms by id (one app round trip).

Not done

  • The CLI's own current still means the daemon's active object. Moving caller resolution into the daemon would make the CLI and MCP agree.
  • app_column_dock_left refuses the chat pane with "not shown in any window" while it is shown. Not fixed here.

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