fix(workspaces): launch the agent before the setup terminal
What
On the non-chained workspace-creation path, dispatch the agent before creating the setup terminal.
Why
The agent and the setup script are independent on that path — that is what "not chaining" means — but the setup terminal was created first and so took the earlier createdAt. Every client's tab order follows creation order, so opening a freshly created workspace put a setup shell in the first slot with the agent behind it.
Only waitForSetupBeforeAgents chains the two into a single terminal, and that is desktop-only, off by default (DEFAULT_WAIT_FOR_SETUP_BEFORE_AGENT = false), and behind an Experimental setting. So everything else — desktop's default, the CLI, MCP, automations, and mobile — got the setup shell in front. It reads worst on mobile, where the tab strip sorts oldest-first and the first tab is the one you land on.
Scope
Creation order only. Both terminals still run concurrently, the response shape is unchanged, and the chained path is untouched (earlyAgentsResult stays null there, so the existing dispatch runs exactly as before).
Desktop's pane layout is unaffected: it is built from the create result's arrays (appendLaunchesToPaneLayout), not from createdAt. Two desktop dropdowns that sort createdAt descending (BackgroundTerminalsButton, TerminalSessionDropdown) show the two rows swapped; the background one filters to unattached sessions, so after a create it is unaffected in practice.
Verification
- host-service typecheck, biome, and the full suite (1439 pass / 0 fail).
- Behaviour checked with a throwaway integration test (not committed) that creates a workspace with a setup script and an agent, then compares the two sessions'
createdAt:- with the change: agent created 7ms before setup
- reverted: agent created 7ms after setup, assertion fails
Follow-ups (not in this PR)
- Desktop orders its own tabs
[...terminalLaunches, ...agentLaunches], so it also puts the setup tab first. One-line fix, but visible to every desktop user — deliberately left out. - A
launched_agent_idcolumn onterminal_sessionswould let a tab show its agent immediately instead of reading "Terminal" until the first lifecycle hook lands (and again after the agent exits). Cosmetic, independent of ordering.
https://claude.ai/code/session_01U1PCJWKGgvDQk7NZn7VFCj
Summary by cubic
On the non-chained workspace-creation path, the agent now launches before the setup terminal, so the agent's session takes the first tab slot. Tab order follows createdAt, so previously the setup shell landed in the first slot with the agent behind it — worst on mobile, where the first tab is what you land on.
- Both terminals still run concurrently, and the response shape is unchanged.
- The chained path (
waitForSetupBeforeAgents, desktop-only, off by default) is untouched. - Desktop's pane layout is unaffected because it's built from create-result arrays, not
createdAt.
Summary by CodeRabbit
- Bug Fixes
- Improved workspace creation so independent agents launch promptly.
- Preserved the expected tab order during workspace setup.
- Prevented duplicate agent launches when setup chaining is enabled.
- Improved handling when setup chaining is unavailable or not requested.