fix(cli): relay init keeps the machine-wide active workspace
Problem
relay init saved its workspace via persistWorkspaceSession({ name, workspaceKey }), which always calls switchWorkspace(name). On a machine already using another workspace (e.g. active = "ghsub-live" read by a fleet node's start script), running relay init in any project silently moved the whole machine to the new local workspace.
Change
persistWorkspaceSessiongainsactivate?: 'always' | 'if-none'(default'always') and reportskeptActiveWorkspacewhen it leaves another workspace active.'if-none'activates only when there is no active workspace, the active name has no saved entry, or the active workspace is the one being (re)selected.relay inituses'if-none'on every path: local (default),--hosted,--url/--key, and the guided wizard (all go throughsetupServer). The workspace is still saved under its name and bound to the project (.agentworkforce/relay/workspace-key.json). When another workspace stays active, init prints:
This project now uses workspace "local"; "ghsub-live" stays active machine-wide. To make "local" the default everywhere, run: relay workspace switch local- Other callers are unchanged:
workspace join/create/switch/restoreand MCPcreate_workspaceare explicit selections that are meant to switch;local-agentand MCP rebind pass no name.
Resolution after init
Verified on main: resolveWorkspaceSelection checks --workspace-key → env → project pin → global active, and agent register, message ... (resolveWorkspaceTransport) and relay mcp (resolveWorkspaceSessionKey) all use it. So no resolver change was needed; a new test runs relay init then relay agent register alice and asserts the transport is the local key at http://127.0.0.1:8787 with source project, while active stays ghsub-live.
Tests
workspace-session.test.ts:if-noneon fresh machine (active set), different active (kept, project pinned, resolves to new key), re-selecting the active workspace, dangling active name.init.test.ts: fresh machine → active set; existing different active → unchanged + message; re-run → idempotent;--hosted;--url/--key; guided flow; init thenagent registeruses the project workspace.npx vitest run packages/cli: 2432 passed.npx tsc --noEmit -p packages/cli: clean.
End-to-end (isolated AGENT_RELAY_HOME / AGENT_RELAY_INSTALL_DIR)
Pre-seeded workspaces.json with active: "ghsub-live" (dummy key). Built relay init --yes --tools none --port 8799: downloaded engine, started server, printed the kept-active line; active stayed ghsub-live, local added, project workspace-key.json == local key. relay agent register alice / bob, relay message dm send bob ... --as alice, relay message inbox check --as bob showed the unread DM. Re-running init left the store unchanged; relay init --stop stopped the server.
🤖 Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Agent Relay sessions