# Claude Code Agent Teams — Reference > Experimental feature (Feb 2026). Enable per-session via env var. > Updated with experiment findings from 2026-02-12. ## Enabling ```bash # Environment variable (set before starting Claude Code) CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 # In .claude/settings.local.json (case-scoped) { "env": { "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1" } } # Note: "teammateMode" is NOT a valid settings key (validation rejects it). # Display mode defaults to "in-process". For tmux, pass --teammate-mode flag via CLI. ``` ## Filesystem Paths (Verified) | Resource | Path | |----------|------| | Team config | `~/.claude/teams/{team-name}/config.json` | | Teammate inboxes | `~/.claude/teams/{team-name}/inboxes/{name}.json` | | Shared tasks | `~/.claude/tasks/{team-name}/` | | Teammate transcripts | `~/.claude/projects/{hash}/{leadSessionId}/subagents/agent-{id}.jsonl` | Note: Teammate transcripts appear in the **standard subagent directory** under the lead's session, NOT as separate top-level sessions. ### config.json format (verified) ```json { "name": "research-watchers", "description": "Team description...", "createdAt": 1770875105373, "leadAgentId": "team-lead@research-watchers", "leadSessionId": "461daa80-94ec-4e5e-a1bb-0518f78311bc", "members": [ { "agentId": "team-lead@research-watchers", "name": "team-lead", "agentType": "team-lead", "model": "claude-opus-4-6", "joinedAt": 1770875105373, "tmuxPaneId": "", "cwd": "/path/to/project", "subscriptions": [] }, { "agentId": "fs-researcher@research-watchers", "name": "fs-researcher", "agentType": "general-purpose", "model": "claude-opus-4-6", "prompt": "Full spawn prompt...", "color": "blue", "planModeRequired": false, "joinedAt": 1770875126680, "tmuxPaneId": "in-process", "cwd": "/path/to/project", "subscriptions": [], "backendType": "in-process" } ] } ``` Key fields: `agentId` format is `{name}@{teamName}`, `leadSessionId` links to Codeman session, `backendType` indicates display mode, `color` for UI theming. ### Task file format (verified) ```json { "id": "1", "subject": "Research Node.js fs.watch on Linux vs macOS", "description": "Full description...", "activeForm": "Researching Node.js fs.watch Linux vs macOS", "status": "in_progress", "blocks": [], "blockedBy": [], "owner": "fs-researcher" } ``` Internal teammate tracking tasks have `"metadata": { "_internal": true }`. Task states: `pending` → `in_progress` → `completed`. File locking via `.lock.lock` directory (mkdir-based atomic lock). ### Inbox message format (verified) ```json [ { "from": "team-lead", "text": "{\"type\":\"task_assignment\",\"taskId\":\"1\",\"subject\":\"...\",\"assignedBy\":\"team-lead\",\"timestamp\":\"...\"}", "timestamp": "2026-02-12T05:45:18.176Z", "read": false } ] ``` `text` is double-encoded JSON. Message types: `task_assignment`, `shutdown_request`, `shutdown_response`. File locking via `.json.lock` directory. ## Communication Model (CORRECTED) **Hybrid: tool + filesystem.** The `SendMessage` tool writes to filesystem inbox files at `~/.claude/teams/{name}/inboxes/{teammate}.json`. Each teammate AND the lead has an inbox JSON file. Messages are JSON arrays with `from`, `text` (double-encoded JSON), `timestamp`, `read` fields. Message types observed: - **task_assignment**: Lead assigns task to teammate - **shutdown_request**: Lead asks teammate to shut down - **shutdown_response**: Teammate confirms shutdown - (Also: `message`, `broadcast`, `plan_approval_response` per docs) **Implication:** We can intercept messages by watching inbox files AND potentially inject messages by writing to them (respecting `.json.lock` directory locking). ## Process Model (CORRECTED) **Teammates are IN-PROCESS THREADS, not separate OS processes.** In `in-process` mode (the default), all teammates run as threads within the single `claude` process. Only 1 claude process exists per Codeman session, regardless of team size. This means: - No separate PIDs to track per teammate - All teammates share the lead's environment variables - Lower resource overhead than separate processes - Subagent transcript files still created (for progress tracking) ## Display Modes | Mode | Trigger | UI | Requirement | |------|---------|-----|------------| | **in-process** (default) | Default | Shift+Up/Down to switch, Ctrl+T for tasks | Any terminal | | **tmux** | `--teammate-mode tmux` | Split panes | tmux installed | | **iTerm2** | Auto-detected | Native split panes | iTerm2 + `it2` CLI | **For Codeman: use `in-process` only.** Codeman manages its own tmux sessions externally. **In-process UI elements:** - Status bar: `@main @teammate1 @teammate2 ...` with `shift+↑ to expand` - Task list: Checkboxes with assignments `(@teammate-name)` - Hint: `ctrl+t to show teammates` ## Hooks Two new hook types for quality gates (verified in settings schema): ### TeammateIdle Fires when a teammate is about to go idle. - Exit code 0: Allow idle (normal) - Exit code 2: Send feedback back, keep teammate working ### TaskCompleted Fires when a task is being marked complete. - Exit code 0: Allow completion - Exit code 2: Prevent completion, send feedback These are configured in `.claude/settings.local.json` alongside existing Codeman hooks. ## Subagent-Watcher Compatibility (Verified) **Teammates appear as standard subagents.** They create transcript files at: ``` ~/.claude/projects/{hash}/{leadSessionId}/subagents/agent-{id}.jsonl ``` Codeman's existing `subagent-watcher.ts` discovers them automatically. They appear in `/api/subagents` with status "active". **Distinguishing teammates from regular subagents:** - Description field starts with `