A workspace isn't limited to a single agent. You can attach additional agents — of the same kind or different kinds — to one workspace. Every agent runs as its own session but they all share the same git worktree and branch, and they can message each other. This is useful for, say, running a second Claude as a dedicated reviewer alongside the one doing the work, or pitting claude and codex at the same problem in the same tree.

Every workspace starts with exactly one agent — the primary, chosen at creation time by --agent or the coding_agent setting (see Coding agents). Everything below is about adding more on top of that.

Adding and removing agents

In the TUI, press Ctrl-x a while a workspace is selected to open the agents panel. It lists the agents already attached (the primary is tagged (primary)) and an "add" picker of the four kinds:

KeyAction
/Move through the add picker
EnterAdd the highlighted kind
aAdd one of every kind at once
xRemove the most-recently-added (non-primary) agent
EscClose the panel

Newly added agents spawn immediately with the workspace's context injected. The primary can't be removed from the panel — it lives for the life of the workspace.

From the CLI, the equivalent of the panel's "add" is:

wsx agent add <kind>     # kind = claude | pi | hermes | codex

This runs against the current workspace — the one whose worktree you're in, or the one named by $WSX_WORKSPACE_ID (see identity below). It prints the new agent's label, e.g. added claude#2.

Switching focus between agents

When a workspace has more than one agent, the attached view grows a footer agents row listing each agent with a single-letter switch key:

agents:  ▎claude q   ▎codex w   ▎pi r

Press the key (q, w, r, …) to point the focused pane at that agent's session, or click the pill. The keys are drawn from a fixed pool — q w r y i o p s h j — assigned in display order (primary first). A workspace with more than ten agents renders the rest keyless, but they stay clickable. The row only appears once a second agent exists; a single-agent workspace looks exactly as before.

Because agents share the worktree, switching focus is just changing which session your keystrokes go to — there's no branch-swapping or checkout involved.

Inter-agent messaging

Agents in the same workspace can send each other messages:

wsx agent send <label> <message…>

<label> is an agent's footer/list label (claude, claude#2, codex, …). The rest of the line is the message body. Delivery is asynchronous: the message is queued and injected into the target's session on the next tick, prefixed with a banner so the recipient knows where it came from:

[message from claude#2]
…your message body…

If the sender is the wsx CLI itself (not another agent — i.e. $WSX_AGENT_INSTANCE_ID is unset), the banner is just [message]. If the target agent isn't running yet, wsx spawns it first, then delivers. Sending to a label that doesn't exist in the workspace errors with a hint to run wsx agent list.

Since all agents write to the same files, prefer messaging to hand off work rather than editing the same paths in parallel.

Listing agents

wsx agent list

Prints one agent per line — its instance id and label, with (primary) appended for the primary — for the current workspace:

1  claude  (primary)
2  claude#2
4  codex

The leading number is the agent's instance id — the same value wsx injects as $WSX_AGENT_INSTANCE_ID into that agent's session.

Agent identity and labels

Each agent instance has a label derived from its kind and its ordinal within that kind: the first of a kind is the bare name (claude), and each subsequent one of the same kind gets a #N suffix (claude#2, claude#3). The same rule produces the labels shown in the footer row, in wsx agent list, and in message banners.

When wsx spawns an agent it injects two environment variables into that session, so the agent (or scripts it runs) can address the multi-agent CLI without guessing:

VariableValue
WSX_WORKSPACE_IDThe workspace this agent belongs to
WSX_AGENT_INSTANCE_IDThis specific agent instance

wsx agent commands resolve the "current" workspace from $WSX_WORKSPACE_ID first, falling back to matching the current directory against known worktrees — so the commands work both from inside an agent session and from a plain shell in the worktree. wsx agent send uses $WSX_AGENT_INSTANCE_ID to stamp the [message from …] sender on outgoing messages.