# Multi-agent teams

> Run Claude Code, Codex and other agents side by side, coordinating through tmux-ide team groups, a shared status bus, direct messages and wait commands.

tmux-ide lets agents in different panes work as a team, even when they are
different tools. A Claude Code lead can hand work to a Codex pane and wait for
it to finish, using the same `send`, `wait`, `events` and `team` commands
documented elsewhere.

Every agent is a process in a tmux pane, so coordination works with any agent.
Claude Code reports its status through the integration hooks. Other agents
report it with a one-line pane option, or the fallback detector recognizes them.

## The coordination primitives


### A shared status bus

Every agent publishes its state, and the whole fleet can read it. The fleet
rollup is one JSON call, transitions stream as they happen, and any single pane's
verdict is one command:

```bash
tmux-ide team --json               # fleet rollup: each session's + window's agent status
tmux-ide events --follow           # live stream of session-status transitions (JSONL)
tmux-ide agent explain %2 --json   # one pane's status (+ exactly why it was classified that way)
```

`team --json` includes a per-pane `agents` array; `events` reports session-level
transitions. `agent explain <pane>` shows how one pane was classified.

Any agent joins the bus by self-reporting — no integration required:

```bash
tmux set-option -p @agent_state "working:$(date +%s)"   # working | blocked | done | idle
```

Claude Code does this automatically once you run
`tmux-ide integration install claude`. For Codex, cursor-agent, or any other
tool, either drop that one line into the agent's own lifecycle or rely on the
fallback detector (process-tree + screen manifests). See
[Agent detection](/docs/agent-detection).

### Send a task to another agent

`tmux-ide send` types a message straight into another agent's prompt — so agent A
can hand agent B a task. Target a pane by ID (`%2`), title, role, or
`@ide_name`:

```bash
tmux-ide send %2 "Implement POST /login per the spec in docs/auth.md, then run the tests"
tmux-ide send API --no-enter "draft: "        # stage text without submitting
echo "long instructions…" | tmux-ide send %2  # pipe from stdin
```

Messages over 150 characters are written to a dispatch file under
`.tasks/dispatch/` in the project, and the target is told to read it. That avoids paste-mode
problems in agent interfaces.

`send` is the quick, human-style way to message an agent. When you need exact
pane identity across servers, attributed senders and retry-safe handles, use
[agent automation](/docs/automation) instead.

### Wait for a teammate

Block until a teammate reaches a state or produces output. Exit codes make it
scriptable (`0` = matched, `1` = timed out):

```bash
tmux-ide wait output %2 --match "tests passed" --timeout 300000   # wait on a pane
tmux-ide wait agent-status api --status done --timeout 600000     # wait on a session
```

See [Wait for an agent in scripts](/docs/notifications-events#wait-for-an-agent-in-scripts)
for every option.

### Inspect and isolate

```bash
tmux-ide agent explain %3     # why is the UI pane blocked? see exactly how it was classified
tmux-ide worktree create feature/login   # give a teammate an isolated checkout + session
```

## Worked example: a Claude Code lead dispatching to Codex

Picture a Claude Code agent running as the **lead** in pane `%0`, with a Codex
agent in `%2`. The lead can drive the whole loop from its own shell:

```bash
# 1. Read the fleet rollup, then check the codex pane specifically
tmux-ide team --json | jq '.projects[].sessions[] | {name, status}'
tmux-ide agent explain %2 --json | jq -r .classification

# 2. Hand the codex pane a task
tmux-ide send %2 "Add a /health endpoint returning {ok:true}, then run: npm test"

# 3. Block until codex reports the tests passing
tmux-ide wait output %2 --match "Tests:.*passed" --timeout 300000 \
  && echo "codex finished — reviewing its diff"

# 4. Re-read that pane's verdict before assigning the next task
tmux-ide agent explain %2 --json | jq -r .classification
```

Step 2 puts text into Codex's prompt exactly as if the lead had typed it. Step 3
watches Codex's own output. Steps 1 and 4 read the shared bus. None of it is
Claude-specific — swap `%2` for a cursor-agent or `aider` pane and the same
commands hold. To wait on a whole session, such as a worktree running one agent,
use `tmux-ide wait agent-status <session> --status done` instead of
`wait output`.

## The lead-agent pattern

The pattern that ties it together:

* A **lead** — a human watching Home, or a lead agent — assigns work with
  `send` and worktrees.
* **Teammates** report status (automatically for Claude Code, via the pane option
  for anything else).
* The **`done`/`blocked` state and its notification** are the handoff signal:
  the lead reacts the moment a teammate finishes or gets stuck, instead of
  polling.

The status bus, messaging and waits are plain CLI commands with `--json` output
and exit codes. Use the same pattern from scripts, a lead agent's tool calls or a
Makefile.

## A mixed fleet

In the app, Home and the sidebar list each agent with its state, and Attention
(`F7`) jumps to the ones that need you. In a [tmux chrome](/docs/the-dock)
session the same fleet looks like this (illustrative):

```
 mixed-fleet   ●working                          [ ⌂ home ^b h ]  [ ⧉ switch ^b j ]
┌──────────────────────────────┬──────────────────────────────┐
│ Lead (claude)          %0    │ API (codex)            %2    │
│ claude · working   ●working  │ codex  · done      ●done     │
├──────────────────────────────┼──────────────────────────────┤
│ UI (cursor-agent)      %3    │ Shell                  %4    │
│ cursor · blocked   ●blocked  │ $                            │
└──────────────────────────────┴──────────────────────────────┘
```

One glance tells the lead (human or agent): the API agent is `done`, the UI
agent is `blocked` and needs attention. That state is the handoff signal.

## Group panes into a named team

A team is a presentation group of existing tmux panes. It can contain Claude,
Codex, other agents, and supporting terminals. Grouping does not start an
orchestrator or change how a harness manages its own teammates.

Assign existing panes on the same tmux server to a named group:

```bash
tmux-ide team assign %2 "Release crew" --json
tmux-ide team assign %5 "Release crew" --json
tmux-ide team unassign %5 --json
```

Use `--socket-name NAME` or `--socket-path /absolute/socket` to select another
server explicitly. Run these commands on the machine that owns the panes.
The same team name deliberately selects the same explicit group on that server;
equal names on different machines or servers stay separate. These commands
require exact pane IDs and do not send terminal input.

Home and the sidebar keep members together and display their team alongside the
existing machine/session context. Home search also matches team names. A manual
assignment takes precedence over discovered grouping. Removing it allows native
team discovery to apply again. Member names still use the shared name resolver,
including any manual pane-name override.

Assignments are pane-local: they survive moving a pane between windows or
sessions and restarting the daemon. Replacing the pane process clears the
assignment from the displayed inventory; assign the new process explicitly.
Assignments do not restore deleted panes or join groups across machines.

### Native Claude teams

Teammates from [Claude Code agent teams](/docs/claude-code-agent-teams) that run in
their own tmux panes are grouped automatically — see the next section.

## Claude Code agent teams

With Claude Code agent teams, a Claude Code lead spawns Claude Code teammates,
and in tmux each teammate gets its own split pane. tmux-ide shows those
teammates by name, grouped under their team, with live status; see
[Claude Code agent teams](/docs/claude-code-agent-teams) for setup and limits.

## See also

* [Agent detection](/docs/agent-detection) — the status every teammate publishes
* [Claude Code agent teams](/docs/claude-code-agent-teams) — setup, what tmux-ide shows and its limits
* [Notifications and events](/docs/notifications-events) — the toast/stream side of the handoff
* [Worktrees](/docs/worktrees) — an isolated checkout per teammate
* [Agent automation](/docs/automation) — scoped, attributed pane reads and sends over CLI, MCP and SDK
* [CLI reference](/docs/commands) — `send`, `wait`, `team`, `events` in full
