---
name: team
description: 使用 Claude Code 原生团队工具，在共享任务列表上协调 N 个代理协同工作
aliases: []
level: 4
---

# Team 技能

生成 N 个协同代理，在共享任务列表上工作，并使用 Claude Code 的原生团队工具。它用内置的团队管理、代理间消息传递和任务依赖替代了旧版 `/swarm` 技能（基于 SQLite）——不需要任何外部依赖。

`swarm` 兼容别名已在 #1131 中移除。

## 用法

```
/oh-my-claudecode:team N:agent-type "task description"
/oh-my-claudecode:team "task description"
/oh-my-claudecode:team ralph "task description"
```

### 参数

- **N** - 队友代理数量（1-20）。可选；默认会根据任务拆解自动调整规模。
- **agent-type** - 在 `team-exec` 阶段生成的 OMC 代理类型（例如 executor、debugger、designer、codex、gemini）。可选；默认按阶段感知路由。使用 `codex` 可生成 Codex CLI worker，使用 `gemini` 可生成 Gemini CLI worker（要求对应 CLI 已安装）。详见下文“Stage Agent Routing”。
- **task** - 要拆解并分发给队友的高层任务
- **ralph** - 可选修饰符。出现时，会将团队流水线包裹进 Ralph 的持久化循环中（失败重试、完成前由 architect 验证）。详见下文“Team + Ralph Composition”。

### 示例

```bash
/team 5:executor "fix all TypeScript errors across the project"
/team 3:debugger "fix build errors in src/"
/team 4:designer "implement responsive layouts for all page components"
/team "refactor the auth module with security review"
/team ralph "build a complete REST API for user management"
# With Codex CLI workers (requires: npm install -g @openai/codex)
/team 2:codex "review architecture and suggest improvements"
# With Gemini CLI workers (requires: npm install -g @google/gemini-cli)
/team 2:gemini "redesign the UI components"
# Mixed: Codex for backend analysis, Gemini for frontend (use /ccg instead for this)
```

## 架构

```
User: "/team 3:executor fix all TypeScript errors"
              |
              v
      [TEAM ORCHESTRATOR (Lead)]
              |
              +-- TeamCreate("fix-ts-errors")
              |       -> lead becomes team-lead@fix-ts-errors
              |
              +-- Analyze & decompose task into subtasks
              |       -> explore/architect produces subtask list
              |
              +-- TaskCreate x N (one per subtask)
              |       -> tasks #1, #2, #3 with dependencies
              |
              +-- TaskUpdate x N (pre-assign owners)
              |       -> task #1 owner=worker-1, etc.
              |
              +-- Task(team_name="fix-ts-errors", name="worker-1") x 3
              |       -> spawns teammates into the team
              |
              +-- Monitor loop
              |       <- SendMessage from teammates (auto-delivered)
              |       -> TaskList polling for progress
              |       -> SendMessage to unblock/coordinate
              |
              +-- Completion
                      -> SendMessage(shutdown_request) to each teammate
                      <- SendMessage(shutdown_response, approve: true)
                      -> TeamDelete("fix-ts-errors")
                      -> rm .omc/state/team-state.json
```

**存储布局（由 Claude Code 管理）：**
```
~/.claude/
  teams/fix-ts-errors/
    config.json          # Team metadata + members array
  tasks/fix-ts-errors/
    .lock                # File lock for concurrent access
    1.json               # Subtask #1
    2.json               # Subtask #2 (may be internal)
    3.json               # Subtask #3
    ...
```

## 分阶段流水线（Canonical Team Runtime）

Team 执行遵循如下分阶段流水线：

`team-plan -> team-prd -> team-exec -> team-verify -> team-fix (loop)`

### 阶段代理路由

流水线的每个阶段都会使用**专门代理**——不只是 executor。lead 会根据阶段和任务特征选择代理。

| Stage | Required Agents | Optional Agents | Selection Criteria |
|-------|----------------|-----------------|-------------------|
| **team-plan** | `explore` (haiku), `planner` (opus) | `analyst` (opus), `architect` (opus) | 需求不清晰时使用 `analyst`。系统边界复杂时使用 `architect`。 |
| **team-prd** | `analyst` (opus) | `critic` (opus) | 使用 `critic` 质疑和校验范围。 |
| **team-exec** | `executor` (sonnet) | `executor` (opus), `debugger` (sonnet), `designer` (sonnet), `writer` (haiku), `test-engineer` (sonnet) | 根据子任务类型匹配代理。复杂自治工作使用 `executor` (model=opus)，UI 用 `designer`，编译问题用 `debugger`，文档用 `writer`，测试创建用 `test-engineer`。 |
| **team-verify** | `verifier` (sonnet) | `test-engineer` (sonnet), `security-reviewer` (sonnet), `code-reviewer` (opus) | 始终运行 `verifier`。auth/crypto 变更增加 `security-reviewer`。超过 20 个文件或架构性变更增加 `code-reviewer`。`code-reviewer` 也负责 style/formatting 检查。 |
| **team-fix** | `executor` (sonnet) | `debugger` (sonnet), `executor` (opus) | 类型/构建错误和回归定位使用 `debugger`。复杂多文件修复使用 `executor` (model=opus)。 |

**路由规则：**

1. **每个阶段由 lead 选择代理，而不是用户。** 用户传入的 `N:agent-type` 参数只会覆盖 `team-exec` 阶段的 worker 类型。其他所有阶段都使用与阶段相匹配的专门代理。
2. **专门代理是对 executor 代理的补充。** 分析/评审路由给 architect/critic Claude 代理，UI 工作路由给 designer 代理。Tmux CLI worker 是一次性执行单元，不参与团队通信。
3. **成本模式影响模型层级。** 在降级模式下：`opus` 代理降为 `sonnet`，`sonnet` 在质量允许时降为 `haiku`。`team-verify` 至少始终使用 `sonnet`。
4. **风险级别会升级评审强度。** 涉及安全或变更超过 20 个文件时，`team-verify` 必须包含 `security-reviewer` + `code-reviewer` (opus)。

### 阶段进入/退出条件

- **team-plan**
  - Entry: 解析 Team 调用并启动编排。
  - Agents: `explore` 扫描代码库，`planner` 创建任务图；复杂任务可选 `analyst`/`architect`。
  - Exit: 拆解完成，并准备好可执行的任务图。
- **team-prd**
  - Entry: 范围模糊或缺少验收标准。
  - Agents: `analyst` 提取需求，可选 `critic`。
  - Exit: 验收标准和边界都已明确。
- **team-exec**
  - Entry: `TeamCreate`、`TaskCreate`、任务分配和 worker 生成全部完成。
  - Agents: 按子任务生成合适类型的专门 worker（见路由表）。
  - Exit: 当前轮次中的执行任务到达终态。
- **team-verify**
  - Entry: 执行轮次结束。
  - Agents: `verifier` + 与任务匹配的评审代理（见路由表）。
  - Exit (pass): 验证关卡通过，且没有必须继续跟进的事项。
  - Exit (fail): 生成修复任务，并将控制流移交给 `team-fix`。
- **team-fix**
  - Entry: 验证发现缺陷、回归或未满足的标准。
  - Agents: 根据缺陷类型使用 `executor`/`debugger`。
  - Exit: 修复完成，流程返回 `team-exec`，之后进入 `team-verify`。

### Verify/Fix 循环与停止条件

持续执行 `team-exec -> team-verify -> team-fix`，直到：
1. 验证通过，且没有剩余必须修复的任务；或
2. 工作达到带有证据的显式终态：blocked/failed。

`team-fix` 有最大尝试次数上限。如果修复尝试超过配置上限，则切换到终态 `failed`（不会无限循环）。

### 阶段交接约定

在阶段之间切换时，重要上下文——已做出的决策、被否决的方案、识别出的风险——通常只存在于 lead 的会话历史中。如果 lead 的上下文被压缩，或代理重启，这些信息就会丢失。

**每个完成的阶段在切换前都必须生成交接文档。**

lead 将交接文档写入 `.omc/handoffs/<stage-name>.md`。

#### 交接格式

```markdown
## Handoff: <current-stage> → <next-stage>
- **Decided**: [key decisions made in this stage]
- **Rejected**: [alternatives considered and why they were rejected]
- **Risks**: [identified risks for the next stage]
- **Files**: [key files created or modified]
- **Remaining**: [items left for the next stage to handle]
```

#### 交接规则

1. **lead 在生成下一阶段代理之前，必须先读取上一阶段的交接文档。** 交接内容会包含在下一阶段代理的生成提示词里，确保代理带着完整上下文开始工作。
2. **交接文档是累积的。** verify 阶段可以读取之前所有交接（plan → prd → exec），从而拿到完整的决策历史。
3. **团队取消时，交接文档仍会保留** 在 `.omc/handoffs/` 中，以便会话恢复。它们不会被 `TeamDelete` 删除。
4. **交接文档应保持轻量。** 最多 10-20 行。它们记录决策及其理由，而不是完整规范（完整规范应保存在如 `DESIGN.md` 这类交付文件中）。

#### 示例

```markdown
## Handoff: team-plan → team-exec
- **Decided**: Microservice architecture with 3 services (auth, api, worker). PostgreSQL for persistence. JWT for auth tokens.
- **Rejected**: Monolith (scaling concerns), MongoDB (team expertise is SQL), session cookies (API-first design).
- **Risks**: Worker service needs Redis for job queue — not yet provisioned. Auth service has no rate limiting in initial design.
- **Files**: DESIGN.md, TEST_STRATEGY.md
- **Remaining**: Database migration scripts, CI/CD pipeline config, Redis provisioning.
```

### 恢复与取消语义

- **Resume:** 使用分阶段状态 + 实时任务状态，从最后一个非终态阶段重新启动。读取 `.omc/handoffs/` 以恢复阶段切换上下文。
- **Cancel:** `/oh-my-claudecode:cancel` 会请求队友关闭，等待响应（尽力而为），将阶段标记为 `cancelled` 且 `active=false`，记录取消元数据，然后根据策略删除团队资源并清理/保留 Team 状态。`.omc/handoffs/` 中的交接文件会保留，以便可能的恢复。
- 终态包括 `complete`、`failed` 和 `cancelled`。

## 工作流

### 阶段 1：解析输入

- 提取 **N**（代理数量），校验范围为 1-20
- 提取 **agent-type**，校验其是否映射到已知 OMC 子代理
- 提取 **task** 描述

### 阶段 2：分析与拆解

使用 `explore` 或 `architect`（通过 MCP 或代理）分析代码库，并将任务拆解为 N 个子任务：

- 每个子任务都应当是**文件作用域**或**模块作用域**，以避免冲突
- 子任务必须彼此独立，或具有清晰的依赖顺序
- 每个子任务都需要简洁的 `subject` 和详细的 `description`
- 识别子任务之间的依赖关系（例如“shared types 必须先于 consumers 修复”）

### 阶段 3：创建团队

调用 `TeamCreate`，使用从任务派生出的 slug：

```json
{
  "team_name": "fix-ts-errors",
  "description": "Fix all TypeScript errors across the project"
}
```

**响应：**
```json
{
  "team_name": "fix-ts-errors",
  "team_file_path": "~/.claude/teams/fix-ts-errors/config.json",
  "lead_agent_id": "team-lead@fix-ts-errors"
}
```

当前会话会成为团队 lead（`team-lead@fix-ts-errors`）。

使用 `state_write` MCP 工具写入 OMC 状态，以便进行正确的会话级持久化：

```
state_write(mode="team", active=true, current_phase="team-plan", state={
  "team_name": "fix-ts-errors",
  "agent_count": 3,
  "agent_types": "executor",
  "task": "fix all TypeScript errors",
  "fix_loop_count": 0,
  "max_fix_loops": 3,
  "linked_ralph": false,
  "stage_history": "team-plan"
})
```

> **Note:** MCP `state_write` 工具会将所有值都以字符串形式传输。读取状态时，消费者必须将 `agent_count`、`fix_loop_count`、`max_fix_loops` 转为数字，将 `linked_ralph` 转为布尔值。

**状态 schema 字段：**

| Field | Type | Description |
|-------|------|-------------|
| `active` | boolean | Team 模式是否处于激活状态 |
| `current_phase` | string | 当前流水线阶段：`team-plan`、`team-prd`、`team-exec`、`team-verify`、`team-fix` |
| `team_name` | string | 团队的 slug 名称 |
| `agent_count` | number | worker 代理数量 |
| `agent_types` | string | 在 team-exec 中使用的代理类型，逗号分隔 |
| `task` | string | 原始任务描述 |
| `fix_loop_count` | number | 当前修复迭代计数 |
| `max_fix_loops` | number | 失败前允许的最大修复迭代次数（默认：3） |
| `linked_ralph` | boolean | 团队是否链接到 ralph 持久化循环 |
| `stage_history` | string | 带时间戳的阶段切换记录，逗号分隔 |

**每次阶段切换都更新状态：**

```
state_write(mode="team", current_phase="team-exec", state={
  "stage_history": "team-plan:2026-02-07T12:00:00Z,team-prd:2026-02-07T12:01:00Z,team-exec:2026-02-07T12:02:00Z"
})
```

**读取状态以检测是否需要恢复：**

```
state_read(mode="team")
```

如果 `active=true` 且 `current_phase` 不是终态，则应从最后一个未完成阶段恢复，而不是创建一个新团队。

### 阶段 4：创建任务

为每个子任务调用 `TaskCreate`。创建后使用带 `addBlockedBy` 的 `TaskUpdate` 设置依赖关系。

```json
// TaskCreate for subtask 1
{
  "subject": "Fix type errors in src/auth/",
  "description": "Fix all TypeScript errors in src/auth/login.ts, src/auth/session.ts, and src/auth/types.ts. Run tsc --noEmit to verify.",
  "activeForm": "Fixing auth type errors"
}
```

**响应会保存一个任务文件（例如 `1.json`）：**
```json
{
  "id": "1",
  "subject": "Fix type errors in src/auth/",
  "description": "Fix all TypeScript errors in src/auth/login.ts...",
  "activeForm": "Fixing auth type errors",
  "owner": "",
  "status": "pending",
  "blocks": [],
  "blockedBy": []
}
```

对于有依赖的任务，在创建后使用 `TaskUpdate`：

```json
// Task #3 depends on task #1 (shared types must be fixed first)
{
  "taskId": "3",
  "addBlockedBy": ["1"]
}
```

**由 lead 预先分配 owner**，以避免竞争条件（这里不存在原子式领取）：

```json
// Assign task #1 to worker-1
{
  "taskId": "1",
  "owner": "worker-1"
}
```

### 阶段 5：生成队友

使用带 `team_name` 和 `name` 参数的 `Task` 生成 N 个队友。每个队友都会获得团队 worker 前导提示（见下文）以及其特定分配内容。

```json
{
  "subagent_type": "oh-my-claudecode:executor",
  "team_name": "fix-ts-errors",
  "name": "worker-1",
  "prompt": "<worker-preamble + assigned tasks>"
}
```

**响应：**
```json
{
  "agent_id": "worker-1@fix-ts-errors",
  "name": "worker-1",
  "team_name": "fix-ts-errors"
}
```

**副作用：**
- 队友会被加入 `config.json` 的 members 数组
- 会自动创建一个**内部任务**（带 `metadata._internal: true`）以追踪代理生命周期
- 内部任务会出现在 `TaskList` 输出中——统计真实任务数量时要过滤掉它们

**IMPORTANT:** 并行生成所有队友（它们是后台代理）。不要等待一个完成后再生成下一个。

### 阶段 6：监控

lead 编排器通过两个通道监控进度：

1. **入站消息** —— 队友完成任务或需要帮助时，会向 `team-lead` 发送 `SendMessage`。这些消息会自动作为新的会话轮次到达（无需轮询）。

2. **TaskList 轮询** —— 定期调用 `TaskList` 检查整体进度：
   ```
   #1 [completed] Fix type errors in src/auth/ (worker-1)
   #3 [in_progress] Fix type errors in src/api/ (worker-2)
   #5 [pending] Fix type errors in src/utils/ (worker-3)
   ```
   格式：`#ID [status] subject (owner)`

**lead 可以采取的协调动作：**

- **为队友解除阻塞：** 发送带指导或缺失上下文的 `message`
- **重新分配工作：** 如果某个队友提前完成，可用 `TaskUpdate` 将待处理任务分配给它，并通过 `SendMessage` 通知
- **处理失败：** 如果某个队友报告失败，则重新分配任务或生成替代者

#### 任务看门狗策略

监控卡住或失败的队友：

- **Max in-progress age**：如果任务在 `in_progress` 状态停留超过 5 分钟且没有消息，则发送状态检查
- **Suspected dead worker**：无消息 + 卡住任务超过 10 分钟 → 将任务重新分配给其他 worker
- **Reassign threshold**：如果某个 worker 失败了 2 个以上任务，则停止给它分配新任务

### 阶段 6.5：阶段切换（状态持久化）

每次阶段切换时，都更新 OMC 状态：

```
// Entering team-exec after planning
state_write(mode="team", current_phase="team-exec", state={
  "stage_history": "team-plan:T1,team-prd:T2,team-exec:T3"
})

// Entering team-verify after execution
state_write(mode="team", current_phase="team-verify")

// Entering team-fix after verify failure
state_write(mode="team", current_phase="team-fix", state={
  "fix_loop_count": 1
})
```

这样可以实现：
- **Resume**：如果 lead 崩溃，`state_read(mode="team")` 会显示最近阶段和团队名称，以便恢复
- **Cancel**：cancel 技能读取 `current_phase`，以了解需要什么清理工作
- **Ralph integration**：Ralph 可以读取团队状态，以判断流水线是否完成或失败

### 阶段 7：完成

当所有真实任务（非内部任务）都已完成或失败时：

1. **验证结果** —— 通过 `TaskList` 检查所有子任务都被标记为 `completed`
2. **关闭队友** —— 向每个活跃队友发送 `shutdown_request`：
   ```json
   {
     "type": "shutdown_request",
     "recipient": "worker-1",
     "content": "All work complete, shutting down team"
   }
   ```
3. **等待响应** —— 每个队友都会返回 `shutdown_response(approve: true)` 并终止
4. **删除团队** —— 调用 `TeamDelete` 清理：
   ```json
   { "team_name": "fix-ts-errors" }
   ```
   响应：
   ```json
   {
     "success": true,
     "message": "Cleaned up directories and worktrees for team \"fix-ts-errors\"",
     "team_name": "fix-ts-errors"
   }
   ```
5. **清理 OMC 状态** —— 删除 `.omc/state/team-state.json`
6. **汇报摘要** —— 向用户展示结果

## 代理前导提示

在生成队友时，将这段前导提示包含进 prompt 中，以建立工作协议。请根据每个队友的具体任务分配进行适配。

```
You are a TEAM WORKER in team "{team_name}". Your name is "{worker_name}".
You report to the team lead ("team-lead").
You are not the leader and must not perform leader orchestration actions.

== WORK PROTOCOL ==

1. CLAIM: Call TaskList to see your assigned tasks (owner = "{worker_name}").
   Pick the first task with status "pending" that is assigned to you.
   Call TaskUpdate to set status "in_progress":
   {"taskId": "ID", "status": "in_progress", "owner": "{worker_name}"}

2. WORK: Execute the task using your tools (Read, Write, Edit, Bash).
   Do NOT spawn sub-agents. Do NOT delegate. Work directly.

3. COMPLETE: When done, mark the task completed:
   {"taskId": "ID", "status": "completed"}

4. REPORT: Notify the lead via SendMessage:
   {"type": "message", "recipient": "team-lead", "content": "Completed task #ID: <summary of what was done>", "summary": "Task #ID complete"}

5. NEXT: Check TaskList for more assigned tasks. If you have more pending tasks, go to step 1.
   If no more tasks are assigned to you, notify the lead:
   {"type": "message", "recipient": "team-lead", "content": "All assigned tasks complete. Standing by.", "summary": "All tasks done, standing by"}

6. SHUTDOWN: When you receive a shutdown_request, respond with:
   {"type": "shutdown_response", "request_id": "<from the request>", "approve": true}

== BLOCKED TASKS ==
If a task has blockedBy dependencies, skip it until those tasks are completed.
Check TaskList periodically to see if blockers have been resolved.

== ERRORS ==
If you cannot complete a task, report the failure to the lead:
{"type": "message", "recipient": "team-lead", "content": "FAILED task #ID: <reason>", "summary": "Task #ID failed"}
Do NOT mark the task as completed. Leave it in_progress so the lead can reassign.

== RULES ==
- NEVER spawn sub-agents or use the Task tool
- NEVER run tmux pane/session orchestration commands (for example `tmux split-window`, `tmux new-session`)
- NEVER run team spawning/orchestration skills or commands (for example `$team`, `$ultrawork`, `$autopilot`, `$ralph`, `omc team ...`, `omx team ...`)
- ALWAYS use absolute file paths
- ALWAYS report progress via SendMessage to "team-lead"
- Use SendMessage with type "message" only -- never "broadcast"
```

### Agent-Type Prompt Injection（worker 专用附加说明）

在组合队友提示词时，根据 worker 类型附加一小段说明：

- `claude_worker`：强调严格执行 TaskList/TaskUpdate/SendMessage 循环，且不能运行编排命令。
- `codex_worker`：强调 CLI API 生命周期（`omc team api ... --json`）以及带 stderr 的显式失败 ACK。
- `gemini_worker`：强调有边界的文件所有权，以及每完成一个子步骤后的里程碑 ACK。

这段附加说明必须保留核心规则：**worker = 仅执行者，绝不能充当 leader/orchestrator**。

## 通信模式

### 队友到 Lead（任务完成报告）

```json
{
  "type": "message",
  "recipient": "team-lead",
  "content": "Completed task #1: Fixed 3 type errors in src/auth/login.ts and 2 in src/auth/session.ts. All files pass tsc --noEmit.",
  "summary": "Task #1 complete"
}
```

### Lead 到队友（重新分配或指导）

```json
{
  "type": "message",
  "recipient": "worker-2",
  "content": "Task #3 is now unblocked. Also pick up task #5 which was originally assigned to worker-1.",
  "summary": "New task assignment"
}
```

### 广播（谨慎使用——会发送 N 条独立消息）

```json
{
  "type": "broadcast",
  "content": "STOP: shared types in src/types/index.ts have changed. Pull latest before continuing.",
  "summary": "Shared types changed"
}
```

### 关闭协议（BLOCKING）

**CRITICAL: 步骤必须严格按顺序执行。确认关闭之前，绝不能调用 `TeamDelete`。**

**Step 1: 验证完成状态**
```
Call TaskList — verify all real tasks (non-internal) are completed or failed.
```

**Step 2: 向每个队友请求关闭**

**Lead sends:**
```json
{
  "type": "shutdown_request",
  "recipient": "worker-1",
  "content": "All work complete, shutting down team"
}
```

**Step 3: 等待响应（BLOCKING）**
- 每个队友最多等待 30s 获取 `shutdown_response`
- 记录哪些队友已确认，哪些超时
- 如果某个队友在 30s 内没有响应：记录 warning，并标记为 unresponsive

**Teammate receives and responds:**
```json
{
  "type": "shutdown_response",
  "request_id": "shutdown-1770428632375@worker-1",
  "approve": true
}
```

批准之后：
- 队友进程终止
- 队友会自动从 `config.json` 的 members 数组中移除
- 该队友对应的内部任务完成

**Step 4: TeamDelete —— 仅在所有队友都已确认或超时后执行**
```json
{ "team_name": "fix-ts-errors" }
```

**Step 5: 孤儿进程扫描**

检查在 `TeamDelete` 之后仍存活的代理进程：
```bash
node "${CLAUDE_PLUGIN_ROOT}/scripts/cleanup-orphans.mjs" --team-name fix-ts-errors
```

这会扫描那些名称匹配该团队、但其配置已不存在的进程，并终止它们（SIGTERM → 等待 5s → SIGKILL）。支持 `--dry-run` 以便检查。

**关闭序列是 BLOCKING 的：** 在所有队友满足以下任一条件之前，不要继续执行 `TeamDelete`：
- 已确认关闭（`shutdown_response` 且 `approve: true`），或
- 超时（30s 无响应）

**IMPORTANT:** `request_id` 由队友收到的 shutdown request 消息提供。队友必须提取它并原样传回。不要伪造 request ID。

## CLI Workers（Codex 和 Gemini）

team 技能支持**混合执行**：将 Claude 代理队友与外部 CLI worker（Codex CLI 和 Gemini CLI）结合起来。两类 worker 都可以进行代码修改——它们的差异在于能力和成本。这些都是独立 CLI 工具，而不是 MCP server。

### 执行模式

任务在拆解时会被打上执行模式标签：

| Execution Mode | Provider | Capabilities |
|---------------|----------|-------------|
| `claude_worker` | Claude agent | 完整的 Claude Code 工具访问能力（Read/Write/Edit/Bash/Task）。最适合需要 Claude 推理能力和迭代式工具使用的任务。 |
| `codex_worker` | Codex CLI (tmux pane) | 在 `working_directory` 中拥有完整文件系统访问权限。通过 tmux pane 自主运行。最适合代码评审、安全分析、重构、架构工作。需要 `npm install -g @openai/codex`。 |
| `gemini_worker` | Gemini CLI (tmux pane) | 在 `working_directory` 中拥有完整文件系统访问权限。通过 tmux pane 自主运行。最适合 UI/设计工作、文档工作以及大上下文任务。需要 `npm install -g @google/gemini-cli`。 |

### CLI Workers 如何运行

Tmux CLI worker 在专用 tmux pane 中运行，并拥有文件系统访问权限。它们是**自治执行者**，而不只是分析者：

1. lead 将任务说明写入一个 prompt 文件
2. lead 启动一个 tmux CLI worker，并将 `working_directory` 设为项目根目录
3. worker 在工作目录中读取文件、修改代码、运行命令
4. 结果/摘要被写入一个输出文件
5. lead 读取输出，标记任务完成，并将结果传递给依赖任务

**与 Claude 队友的关键区别：**
- CLI worker 通过 tmux 运行，而不是通过 Claude Code 的工具系统
- 它们不能使用 TaskList/TaskUpdate/SendMessage（没有 team 感知能力）
- 它们作为一次性自治作业运行，而不是持久存在的队友
- 它们的生命周期由 lead 管理（生成、监控、收集结果）

### 何时路由到哪里

| Task Type | Best Route | Why |
|-----------|-----------|-----|
| 迭代式多步骤工作 | Claude 队友 | 需要通过工具驱动的迭代 + 团队通信 |
| 代码评审 / 安全审计 | CLI worker 或专门代理 | 可自治执行，擅长结构化分析 |
| 架构分析 / 规划 | architect Claude 代理 | 具备强分析推理能力，并可访问代码库 |
| 重构（边界清晰） | CLI worker 或 executor 代理 | 可自治执行，擅长结构化变换 |
| UI/frontend 实现 | designer Claude 代理 | 具备设计专长和框架惯用法 |
| 大规模文档工作 | writer Claude 代理 | 具备写作专长，且能利用大上下文保持一致性 |
| Build/test 迭代循环 | Claude 队友 | 需要 Bash 工具和迭代修复循环 |
| 需要团队协作的任务 | Claude 队友 | 需要 SendMessage 做状态更新 |

### 示例：带 CLI Workers 的混合团队

```
/team 3:executor "refactor auth module with security review"

Task decomposition:
#1 [codex_worker] Security review of current auth code -> output to .omc/research/auth-security.md
#2 [codex_worker] Refactor auth/login.ts and auth/session.ts (uses #1 findings)
#3 [claude_worker:designer] Redesign auth UI components (login form, session indicator)
#4 [claude_worker] Update auth tests + fix integration issues
#5 [gemini_worker] Final code review of all changes
```

lead 会先运行 #1（Codex 安全分析），然后并行运行 #2 和 #3（Codex 重构后端，designer 代理重设前端），随后运行 #4（Claude 队友负责测试迭代），最后运行 #5（Gemini 做最终评审）。

### 预分析（可选）

对于大型且模糊的任务，可以在创建团队前先做分析：

1. 用任务描述 + 代码库上下文生成 `Task(subagent_type="oh-my-claudecode:planner", ...)`
2. 用分析结果产出更好的任务拆解
3. 使用丰富后的上下文创建团队和任务

当任务范围不清晰，并且在提交具体拆解方案前先借助外部推理会更有帮助时，这种做法特别有用。

## 监控增强：Outbox 自动摄取

lead 可以使用 outbox reader 工具主动摄取来自 CLI worker 的 outbox 消息，从而以事件驱动方式监控，而不只依赖 `SendMessage` 投递。

### Outbox Reader Functions

**`readNewOutboxMessages(teamName, workerName)`** —— 使用字节偏移游标读取单个 worker 的新 outbox 消息。每次调用都会推进游标，因此后续调用只会返回自上次读取以来写入的消息。其模式与 `readNewInboxMessages()` 的 inbox 游标一致。

**`readAllTeamOutboxMessages(teamName)`** —— 读取团队中**所有** worker 的新 outbox 消息。返回形如 `{ workerName, messages }` 的数组，并跳过没有新消息的 worker。适合在监控循环中批量轮询。

**`resetOutboxCursor(teamName, workerName)`** —— 将某个 worker 的 outbox 游标重置回字节 0。适用于 lead 重启后重新读取历史消息，或用于调试。

### 在监控阶段使用 `getTeamStatus()`

`getTeamStatus(teamName, workingDirectory, heartbeatMaxAgeMs?)` 函数提供一个统一快照，整合了：

- **Worker registration** —— 哪些 MCP worker 已注册（来自 shadow registry / config.json）
- **Heartbeat freshness** —— 基于 heartbeat age 判断每个 worker 是否存活
- **Task progress** —— 每个 worker 以及整个团队的任务计数（pending、in_progress、completed）
- **Current task** —— 每个 worker 当前正在执行哪个任务
- **Recent outbox messages** —— 自上次状态检查以来的新消息

监控循环中的示例用法：

```typescript
const status = getTeamStatus('fix-ts-errors', workingDirectory);

for (const worker of status.workers) {
  if (!worker.isAlive) {
    // Worker is dead -- reassign its in-progress tasks
  }
  for (const msg of worker.recentMessages) {
    if (msg.type === 'task_complete') {
      // Mark task complete, unblock dependents
    } else if (msg.type === 'task_failed') {
      // Handle failure, possibly retry or reassign
    } else if (msg.type === 'error') {
      // Log error, check if worker needs intervention
    }
  }
}

if (status.taskSummary.pending === 0 && status.taskSummary.inProgress === 0) {
  // All work done -- proceed to shutdown
}
```

### 基于 Outbox 消息的事件动作

| Message Type | Action |
|-------------|--------|
| `task_complete` | 将任务标记为完成，检查被阻塞任务是否已解除阻塞，并通知依赖 worker |
| `task_failed` | 增加 failure sidecar 计数，并决定是重试、重新分配还是跳过 |
| `idle` | worker 没有已分配任务——分配待处理工作或开始关闭 |
| `error` | 记录错误，并检查 heartbeat 中的 `consecutiveErrors` 是否达到隔离阈值 |
| `shutdown_ack` | worker 已确认关闭——可以安全地从团队中移除 |
| `heartbeat` | 更新存活状态跟踪（与 heartbeat 文件有重复，但对延迟监控仍有用） |

这种方式补充了现有基于 `SendMessage` 的通信机制，为无法使用 Claude Code 团队消息工具的 MCP worker 提供了一种拉取式机制。

## 错误处理

### 队友任务失败

1. 队友通过 `SendMessage` 向 lead 报告失败
2. lead 决定：重试（将同一任务重新分配给同一个或不同 worker）或跳过
3. 如需重新分配：使用 `TaskUpdate` 设置新 owner，然后通过 `SendMessage` 通知新 owner

### 队友卡住（无消息）

1. lead 通过 `TaskList` 检测到——任务在 `in_progress` 中卡住过久
2. lead 向队友发送 `SendMessage` 询问状态
3. 如果没有响应，则视为该队友已失效
4. 使用 `TaskUpdate` 将任务重新分配给其他 worker

### 依赖被阻塞

1. 如果一个阻塞任务失败，lead 必须决定是否：
   - 重试这个 blocker
   - 移除依赖（使用修改后 `blockedBy` 的 `TaskUpdate`）
   - 完全跳过被阻塞任务
2. 通过 `SendMessage` 将决策传达给受影响的队友

### 队友崩溃

1. 该队友对应的内部任务会显示异常状态
2. 队友会从 `config.json` 的 members 中消失
3. lead 将无人接手的任务重新分配给剩余 worker
4. 如有需要，使用 `Task(team_name, name)` 生成替代队友

## Team + Ralph 组合

当用户调用 `/team ralph`、说出 "team ralph"，或同时触发这两个关键词时，team 模式会把自己包裹进 Ralph 的持久化循环。这样可以获得：

- **Team orchestration** —— 带有按阶段专门代理的多代理分阶段流水线
- **Ralph persistence** —— 失败重试、完成前进行 architect 验证、迭代追踪

### 激活方式

Team+Ralph 会在以下情况激活：
1. 用户调用 `/team ralph "task"` 或 `/oh-my-claudecode:team ralph "task"`
2. 关键词检测器在提示词中同时发现 `team` 和 `ralph`
3. Hook 在 team 上下文中检测到 `MAGIC KEYWORD: RALPH`

### 状态关联

两种模式都会写入各自的状态文件，并带有交叉引用：

```
// Team state (via state_write)
state_write(mode="team", active=true, current_phase="team-plan", state={
  "team_name": "build-rest-api",
  "linked_ralph": true,
  "task": "build a complete REST API"
})

// Ralph state (via state_write)
state_write(mode="ralph", active=true, iteration=1, max_iterations=10, current_phase="execution", state={
  "linked_team": true,
  "team_name": "build-rest-api"
})
```

### 执行流程

1. Ralph 外层循环启动（第 1 次迭代）
2. Team 流水线运行：`team-plan -> team-prd -> team-exec -> team-verify`
3. 如果 `team-verify` 通过：Ralph 运行 architect 验证（最低 STANDARD 层级）
4. 如果 architect 批准：两种模式都完成，并运行 `/oh-my-claudecode:cancel`
5. 如果 `team-verify` 失败，或 architect 拒绝：team 进入 `team-fix`，然后循环回到 `team-exec -> team-verify`
6. 如果修复循环超过 `max_fix_loops`：Ralph 增加迭代计数，并重试整个流水线
7. 如果 Ralph 超过 `max_iterations`：进入终态 `failed`

### 取消

取消任意一种模式，都会同时取消两者：
- **取消 Ralph（已链接）：** 先取消 Team（优雅关闭所有队友），再清理 Ralph 状态
- **取消 Team（已链接）：** 清理 Team，标记 Ralph 当前迭代已取消，并停止循环

详见下方“Cancellation”章节。

## 幂等恢复

如果 lead 在运行中途崩溃，team 技能应检测现有状态并恢复：

1. 检查 `~/.claude/teams/` 中是否存在与任务 slug 匹配的团队
2. 如果存在，读取 `config.json` 以发现活跃成员
3. 进入监控模式恢复，而不是创建重复团队
4. 调用 `TaskList` 确定当前进度
5. 从监控阶段继续

这样可以避免重复团队，并允许在 lead 故障后进行平滑恢复。

## 对比：Team vs Legacy Swarm

| Aspect | Team (Native) | Swarm (Legacy SQLite) |
|--------|--------------|----------------------|
| **Storage** | `~/.claude/teams/` 和 `~/.claude/tasks/` 中的 JSON 文件 | `.omc/state/swarm.db` 中的 SQLite |
| **Dependencies** | 不需要 `better-sqlite3` | 需要 `better-sqlite3` npm 包 |
| **Task claiming** | `TaskUpdate(owner + in_progress)` —— 由 lead 预分配 | SQLite IMMEDIATE transaction —— 原子性 |
| **Race conditions** | 若两个代理领取同一任务则可能发生（通过预分配缓解） | 无（SQLite transaction） |
| **Communication** | `SendMessage`（私信、广播、关闭） | 无（即发即忘型代理） |
| **Task dependencies** | 内置 `blocks` / `blockedBy` 数组 | 不支持 |
| **Heartbeat** | Claude Code 自动发送 idle 通知 | 手动 heartbeat 表 + 轮询 |
| **Shutdown** | 优雅的请求/响应协议 | 基于信号的终止 |
| **Agent lifecycle** | 通过内部任务 + config members 自动追踪 | 通过 heartbeat 表手动追踪 |
| **Progress visibility** | `TaskList` 显示实时状态和 owner | 对 tasks 表执行 SQL 查询 |
| **Conflict prevention** | owner 字段（由 lead 分配） | 基于租约和超时的领取机制 |
| **Crash recovery** | lead 通过缺失消息检测并重新分配 | 5 分钟租约超时后自动释放 |
| **State cleanup** | `TeamDelete` 删除一切 | 手动 `rm` SQLite 数据库 |

**何时使用 Team 而不是 Swarm：** 所有新工作都应优先使用 `/team`。它使用 Claude Code 的内置基础设施，不需要外部依赖，支持代理间通信，并且具备任务依赖管理能力。

## Cancellation

`/oh-my-claudecode:cancel` 技能负责团队清理：

1. 通过 `state_read(mode="team")` 读取 team 状态，获取 `team_name` 和 `linked_ralph`
2. 向所有活跃队友发送 `shutdown_request`（来自 `config.json` members）
3. 等待每个队友返回 `shutdown_response`（每个成员超时 15s）
4. 调用 `TeamDelete` 删除团队和任务目录
5. 通过 `state_clear(mode="team")` 清理状态
6. 如果 `linked_ralph` 为 true，也要清理 ralph：`state_clear(mode="ralph")`

### 关联模式取消（Team + Ralph）

当 team 与 ralph 关联时，取消遵循依赖顺序：

- **从 Ralph 上下文触发取消：** 先取消 Team（优雅关闭所有队友），再清理 Ralph 状态。这样可以保证 worker 在持久化循环退出前先被停止。
- **从 Team 上下文触发取消：** 清理 Team 状态，然后将 Ralph 标记为已取消。Ralph 的 stop hook 会检测到 team 缺失并停止迭代。
- **Force cancel (`--force`)：** 通过 `state_clear` 无条件清理 `team` 和 `ralph` 状态。

如果队友无响应，`TeamDelete` 可能失败。在这种情况下，cancel 技能应短暂等待后重试，或提示用户手动清理 `~/.claude/teams/{team_name}/` 和 `~/.claude/tasks/{team_name}/`。

## Runtime V2（事件驱动）

当设置 `OMC_RUNTIME_V2=1` 时，team runtime 将使用事件驱动架构，而不是旧版基于 `done.json` 轮询的 watchdog：

- **No done.json**：任务完成通过 CLI API 生命周期切换（claim-task、transition-task-status）检测
- **Snapshot-based monitoring**：每个轮询周期都会获取任务和 worker 的时间点快照，计算差异并发出事件
- **Event log**：所有团队事件都会追加到 `.omc/state/team/{teamName}/events.jsonl`
- **Worker status files**：worker 将状态写入 `.omc/state/team/{teamName}/workers/{name}/status.json`
- **Preserved**：sentinel gate（阻止过早完成）、circuit breaker（死 worker 检测）、failure sidecar

v2 runtime 通过 feature flag 控制，可按会话启用。旧版 v1 runtime 仍然是默认值。

## 动态伸缩

当设置 `OMC_TEAM_SCALING_ENABLED=1` 时，team 支持在会话中途伸缩：

- **scale_up**：向正在运行的团队添加 worker（遵守 `max_workers` 限制）
- **scale_down**：优雅移除空闲 worker（worker 会先完成当前任务，再被移除）
- 基于文件的伸缩锁可防止并发伸缩操作
- 单调递增的 worker 索引计数器可确保跨伸缩事件的 worker 名称唯一

## 配置

通过 `.omc-config.json` 提供可选设置：

```json
{
  "team": {
    "maxAgents": 20,
    "defaultAgentType": "executor",
    "monitorIntervalMs": 30000,
    "shutdownTimeoutMs": 15000
  }
}
```

- **maxAgents** - 队友最大数量（默认：20）
- **defaultAgentType** - 未指定时的默认代理类型（默认：`executor`）
- **monitorIntervalMs** - 轮询 `TaskList` 的频率（默认：30s）
- **shutdownTimeoutMs** - 等待关闭响应的时长（默认：15s）

> **Note:** Team 成员没有硬编码的默认模型。每个队友都是独立的 Claude Code 会话，会继承用户已配置的模型。由于队友还能生成自己的子代理，因此会话模型承担的是编排层角色，而子代理则可以使用任意模型层级。

## 状态清理

成功完成时：

1. `TeamDelete` 负责处理所有 Claude Code 状态：
   - 删除 `~/.claude/teams/{team_name}/`（配置）
   - 删除 `~/.claude/tasks/{team_name}/`（所有任务文件 + lock）
2. 通过 MCP 工具清理 OMC 状态：
   ```
   state_clear(mode="team")
   ```
   如果与 Ralph 关联：
   ```
   state_clear(mode="ralph")
   ```
3. 或运行 `/oh-my-claudecode:cancel`，它会自动处理所有清理工作。

**IMPORTANT:** 只有在所有队友都关闭之后，才能调用 `TeamDelete`。如果配置中仍存在活跃成员（lead 之外），`TeamDelete` 会失败。

## Git Worktree 集成

MCP worker 可以在隔离的 git worktree 中运行，以避免并发 worker 之间的文件冲突。

### 工作方式

1. **创建 worktree**：在生成 worker 之前，调用 `createWorkerWorktree(teamName, workerName, repoRoot)`，在 `.omc/worktrees/{team}/{worker}` 创建隔离 worktree，并使用分支 `omc-team/{teamName}/{workerName}`。

2. **worker 隔离**：将 worktree 路径作为 `BridgeConfig` 中的 `workingDirectory` 传入。worker 只在自己的 worktree 中运行。

3. **合并协调**：worker 完成任务后，使用 `checkMergeConflicts()` 验证分支能否干净合并，再使用 `mergeWorkerBranch()` 通过 `--no-ff` 进行合并，以获得清晰历史。

4. **团队清理**：团队关闭时，调用 `cleanupTeamWorktrees(teamName, repoRoot)` 删除所有 worktree 及其分支。

### API 参考

| Function | Description |
|----------|-------------|
| `createWorkerWorktree(teamName, workerName, repoRoot, baseBranch?)` | 创建隔离 worktree |
| `removeWorkerWorktree(teamName, workerName, repoRoot)` | 删除 worktree 及其分支 |
| `listTeamWorktrees(teamName, repoRoot)` | 列出团队的所有 worktree |
| `cleanupTeamWorktrees(teamName, repoRoot)` | 删除团队的所有 worktree |
| `checkMergeConflicts(workerBranch, baseBranch, repoRoot)` | 非破坏性冲突检查 |
| `mergeWorkerBranch(workerBranch, baseBranch, repoRoot)` | 合并 worker 分支（`--no-ff`） |
| `mergeAllWorkerBranches(teamName, repoRoot, baseBranch?)` | 合并所有已完成的 worker |

### 重要说明

- `tmux-session.ts` 中的 `createSession()` **不**负责创建 worktree——worktree 生命周期通过 `git-worktree.ts` 单独管理
- worktree **不会**在单个 worker 关闭时被清理——只会在团队关闭时清理，以便进行事后检查
- 分支名称通过 `sanitizeName()` 清洗，以防注入
- 所有路径都会验证，防止目录遍历

## 注意事项

1. **内部任务会污染 `TaskList`** —— 当生成队友时，系统会自动创建一个带 `metadata._internal: true` 的内部任务。它们会出现在 `TaskList` 输出中。统计真实任务进度时要过滤掉它们。内部任务的 subject 就是该队友的名字。

2. **没有原子式领取** —— 与 SQLite swarm 不同，`TaskUpdate` 没有事务保证。两个队友可能同时竞争同一任务。**缓解措施：** lead 应在生成队友前通过 `TaskUpdate(taskId, owner)` 预先分配 owner。队友只应处理分配给自己的任务。

3. **任务 ID 是字符串** —— ID 是自动递增的字符串（"1"、"2"、"3"），不是整数。传入 `taskId` 字段时始终要使用字符串值。

4. **`TeamDelete` 要求团队为空** —— 调用 `TeamDelete` 前，所有队友都必须先关闭。lead（唯一剩余成员）不在此检查范围内。

5. **消息会自动投递** —— 队友消息会作为新的会话轮次送达 lead。入站消息不需要轮询或检查 inbox。不过，如果 lead 正在处理中（mid-turn），消息会排队，直到该轮结束时才投递。

6. **队友提示词会存储在配置中** —— 完整 prompt 文本会保存在 `config.json` 的 members 数组中。不要在队友 prompt 中放入秘密或敏感数据。

7. **关闭后成员会自动移除** —— 队友同意关闭并终止后，会自动从 `config.json` 中移除。不要重新读取 config 并期望还能找到已关闭的队友。

8. **`shutdown_response` 需要 `request_id`** —— 队友必须从收到的 shutdown request JSON 中提取 `request_id` 并原样传回。其格式为 `shutdown-{timestamp}@{worker-name}`。伪造该 ID 会导致关闭静默失败。

9. **Team 名称必须是合法 slug** —— 只能使用小写字母、数字和连字符。应从任务描述中派生（例如 `"fix TypeScript errors"` 变成 `"fix-ts-errors"`）。

10. **Broadcast 成本较高** —— 每次广播都会向每个队友分别发送一条消息。默认使用 `message`（私信）。只有在确实是团队级关键告警时才使用广播。

11. **CLI worker 是一次性执行，不是持久队友** —— Tmux CLI worker 拥有完整文件系统访问权限，并且**可以**修改代码。但它们作为一次性自治作业运行——不能使用 TaskList/TaskUpdate/SendMessage。lead 必须管理它们的生命周期：写入 `prompt_file`、生成 CLI worker、读取 `output_file`、标记任务完成。它们不像 Claude 队友那样参与团队通信。
