[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CW1W8ZZM1A366XVGHXTTCX":3,"skill-same:01M6CW1W8ZZM1A366XVGHXTTCX":69},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":25,"publishedAt":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":13,"repositoryHtmlUrl":52,"repositoryHomepageUrl":6,"ownerHtmlUrl":53,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":54,"install":55,"resources":68},"01M6CW1W8ZZM1A366XVGHXTTCX","agent-dispatch-use",null,"AgentDispatch 使用指南。教导 AI Agent 如何启动 Server、配置 Client Node、将各种 Agent 作为 Worker 挂载到分发集群、提交任务并监听状态。触发方式：用户提及 \"\u002Fonboard\"、\"how to use dispatch\"、\"快速上手\"、\"set up agentdispatch\"、\"挂载 Agent\"、\"mount worker\" 等关键词时激活。","blackplume233\u002FAgentDispatch","blackplume233","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F32346887?v=4","01M6CW1PP6XWA3JMVYH3T45R5P","01M6CW1PTFMF173PDVR9CQ8H31",1,"MIT","https:\u002F\u002Fgithub.com\u002Fblackplume233\u002FAgentDispatch\u002Fblob\u002Fmaster\u002F.agents\u002Fskills\u002Fagent-dispatch-use\u002FSKILL.md",[17,22],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],"agent dispatch use","dispatch","use","关键词","up","write","read","node","grep","ai agent","mount","挂载","onboard","how","shell","SET","server","2026-11-10 10:12:30",false,"---\nname: agent-dispatch-use\ndescription: 'AgentDispatch 使用指南。教导 AI Agent 如何启动 Server、配置 Client Node、将各种 Agent 作为 Worker 挂载到分发集群、提交任务并监听状态。触发方式：用户提及 \"\u002Fonboard\"、\"how to use dispatch\"、\"快速上手\"、\"set up agentdispatch\"、\"挂载 Agent\"、\"mount worker\" 等关键词时激活。'\nlicense: MIT\nallowed-tools: Shell, Read, Write, Glob, Grep\n---\n\n# AgentDispatch 使用指南\n\n## 概述\n\nAgentDispatch 是一个 AI Agent 任务分发平台。核心架构将任务**创建**与**执行**完全解耦：\n\n| 组件 | 职责 |\n|------|------|\n| **Server** | 中心化 REST API 服务，管理任务队列、客户端注册、文件持久化、SSE 推送 |\n| **Client Node** | 执行节点，轮询 Server 获取任务，调度和管理本地 Worker Agent 集群 |\n| **Worker Agent** | 通过 ACP (Agent Client Protocol) 执行具体任务的 AI Agent |\n| **Manager Agent** | 可选的 AI 调度顾问，通过 ACP 向 Client Node 提供分发建议 |\n| **CLI** | `dispatch` 命令行工具，Worker 通过它上报进度、提交产物 |\n\n```\n                            ┌────────────────────────┐\n  任务提交方                 │     Server (:9800)      │\n  (curl \u002F SDK \u002F Dashboard)─→│  REST API + FileStore   │\n                            │  SSE Stream + Auth      │\n                            └────────┬───────────────┘\n                                     │ HTTP (poll\u002Fclaim\u002Fprogress\u002Fcomplete)\n                            ┌────────▼───────────────┐\n                            │     Client Node         │\n                            │  Dispatcher (tag\u002Fmgr)   │\n                            │  AcpController          │\n                            │  WorkerManager          │\n                            │  IPC Server             │\n                            └──┬─────┬─────┬─────────┘\n                   ACP(stdio)  │     │     │  ACP(stdio)\n                     ┌─────────▼┐ ┌──▼──┐ ┌▼──────────┐\n                     │ Worker-01│ │Wk-02│ │Manager Agt │\n                     │(claude)  │ │(gpt)│ │(调度顾问)   │\n                     └──────────┘ └─────┘ └───────────┘\n```\n\n**核心设计理念**：任何支持 ACP 协议（JSON-RPC 2.0 over stdio）的 AI Agent 都可以作为 Worker 挂载到 Client Node 上。\n\n---\n\n## Part 1: 启动 Server\n\n### 1.1 前置条件\n\n- Node.js >= 20.0.0\n- pnpm >= 9.x\n\n### 1.2 安装与构建\n\n```bash\npnpm install\npnpm build\n```\n\n### 1.3 零配置启动\n\n```bash\nnode packages\u002Fserver\u002Fdist\u002Findex.js\n# Server 默认监听 0.0.0.0:9800，数据存储在 .\u002Fdata\u002F\n```\n\n### 1.4 自定义配置\n\n**环境变量方式**（推荐用于快速测试）：\n\n```bash\nDISPATCH_SERVER_PORT=8080 \\\nDISPATCH_DATA_DIR=.\u002Fmy-data \\\nDISPATCH_LOG_LEVEL=debug \\\nDISPATCH_AUTH_ENABLED=true \\\nDISPATCH_AUTH_TOKENS=\"tok_client_abc123,tok_operator_xyz:operator\" \\\nnode packages\u002Fserver\u002Fdist\u002Findex.js\n```\n\n**配置文件方式**（`server.config.json`）：\n\n```json\n{\n  \"host\": \"0.0.0.0\",\n  \"port\": 9800,\n  \"dataDir\": \".\u002Fdata\",\n  \"logLevel\": \"info\",\n  \"auth\": {\n    \"enabled\": true,\n    \"users\": [{ \"username\": \"admin\", \"password\": \"your-password\" }],\n    \"tokens\": [\n      \"tok_client_abc123\",\n      { \"token\": \"tok_operator_xyz\", \"role\": \"operator\" }\n    ]\n  }\n}\n```\n\n### 1.5 验证\n\n```bash\ncurl http:\u002F\u002Flocalhost:9800\u002Fhealth\n# {\"status\":\"ok\",\"version\":\"0.0.1\",\"authEnabled\":false}\n```\n\n### 1.6 环境变量一览\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `DISPATCH_SERVER_HOST` | `0.0.0.0` | 监听地址 |\n| `DISPATCH_SERVER_PORT` | `9800` | 监听端口 |\n| `DISPATCH_DATA_DIR` | `.\u002Fdata` | 数据目录 |\n| `DISPATCH_LOG_LEVEL` | `info` | 日志级别 (debug\u002Finfo\u002Fwarn\u002Ferror) |\n| `DISPATCH_AUTH_ENABLED` | `false` | 启用鉴权 |\n| `DISPATCH_AUTH_TOKENS` | — | 静态 Token 列表（逗号分隔，`:role` 后缀可选） |\n\n---\n\n## Part 2: 配置 Client Node\n\n### 2.1 最小可用配置\n\n在工作目录创建 `client.config.json`：\n\n```json\n{\n  \"name\": \"my-node\",\n  \"serverUrl\": \"http:\u002F\u002Flocalhost:9800\",\n  \"tags\": [\"code-review\"],\n  \"dispatchMode\": \"tag-auto\",\n  \"autoDispatch\": {\n    \"rules\": [\n      { \"taskTags\": [\"code-review\"], \"targetAgentId\": \"worker-01\", \"priority\": 10 }\n    ],\n    \"fallbackAction\": \"skip\"\n  },\n  \"agents\": [\n    {\n      \"id\": \"worker-01\",\n      \"type\": \"worker\",\n      \"command\": \"claude-agent-acp\",\n      \"workDir\": \"\u002Fpath\u002Fto\u002Fworkspace\"\n    }\n  ]\n}\n```\n\n### 2.2 完整配置结构\n\n```json\n{\n  \"name\": \"production-node\",\n  \"serverUrl\": \"http:\u002F\u002Fyour-server:9800\",\n  \"token\": \"tok_client_abc123\",\n  \"tags\": [\"code-review\", \"documentation\", \"testing\"],\n  \"dispatchMode\": \"hybrid\",\n  \"polling\": { \"interval\": 10000 },\n  \"heartbeat\": { \"interval\": 30000 },\n  \"ipc\": { \"path\": \"\" },\n  \"autoDispatch\": {\n    \"rules\": [\n      { \"taskTags\": [\"code-review\"], \"targetAgentId\": \"claude-worker\", \"priority\": 10 },\n      { \"taskTags\": [\"documentation\"], \"targetCapabilities\": [\"writing\"], \"priority\": 5 },\n      { \"taskTags\": [\"testing\"], \"targetAgentId\": \"test-worker\", \"priority\": 8 }\n    ],\n    \"fallbackAction\": \"skip\"\n  },\n  \"logging\": {\n    \"dir\": \".\u002Flogs\",\n    \"rotateDaily\": true,\n    \"retainDays\": 30,\n    \"httpLog\": true,\n    \"auditLog\": true,\n    \"agentLog\": true\n  },\n  \"agents\": []\n}\n```\n\n### 2.3 关键字段说明\n\n| 字段 | 必填 | 说明 |\n|------|------|------|\n| `name` | 是 | 节点唯一标识，Server 按此区分客户端 |\n| `serverUrl` | 是 | Server HTTP 地址 |\n| `token` | 启用 auth 时 | Server 分配的 API Token |\n| `tags` | 是 | 节点能处理的任务标签集合 |\n| `dispatchMode` | 是 | 分发策略：`tag-auto` \u002F `manager` \u002F `hybrid` |\n| `autoDispatch.rules` | tag-auto\u002Fhybrid | 按 task tag 匹配 Worker 的规则列表 |\n| `autoDispatch.fallbackAction` | 否 | 无规则匹配时行为：`skip`（默认）\u002F `queue-local` |\n\n### 2.4 分发模式\n\n| 模式 | 工作方式 | 需要 Manager |\n|------|---------|:-----------:|\n| `tag-auto` | 规则引擎按 task tag 匹配 Worker，按 priority 排序 | 否 |\n| `manager` | 每个待分配任务都咨询 Manager Agent，由 AI 决定路由 | 是 |\n| `hybrid` | Manager 在线时用 AI 调度，离线时回退到 tag-auto 规则 | 可选 |\n\n### 2.5 分发规则详解\n\n```json\n{\n  \"taskTags\": [\"backend\", \"api\"],\n  \"targetAgentId\": \"worker-backend\",\n  \"targetCapabilities\": [\"typescript\", \"node\"],\n  \"priority\": 10\n}\n```\n\n| 字段 | 说明 |\n|------|------|\n| `taskTags` | AND 逻辑 — 任务必须包含所有指定 tag 才匹配 |\n| `targetAgentId` | 精确指定 Worker ID |\n| `targetCapabilities` | 按能力匹配 — 选择拥有这些 capabilities 的空闲 Worker |\n| `priority` | 数值越大越优先（多条规则匹配时取最高优先级） |\n\n### 2.6 启动 Client Node\n\n```bash\nnode packages\u002Fclient-node\u002Fdist\u002Fmain.js\n# 或指定配置文件\nDISPATCH_NODE_CONFIG=.\u002Fmy-config.json node packages\u002Fclient-node\u002Fdist\u002Fmain.js\n```\n\nCLI 方式：\n\n```bash\ndispatch start --config .\u002Fclient.config.json\ndispatch start --config .\u002Fclient.config.json --foreground\n```\n\n---\n\n## Part 3: 将 Agent 作为 Worker 挂载（重点）\n\n这是 AgentDispatch 的核心操作——将一个 AI Agent 注册为 Worker，使其能自动接收并执行分发来的任务。\n\n### 3.1 Agent 挂载原理\n\n```\n┌──────────────────────────────────────────────────────────────┐\n│                     Client Node                               │\n│                                                               │\n│  1. Dispatcher 决定: task → worker-01                         │\n│  2. HTTP claim → Server                                       │\n│  3. AcpController.launchAgent():                              │\n│     a. 创建 AgentProcess (spawn 子进程)                        │\n│     b. 注入 DISPATCH_TOKEN + DISPATCH_IPC_PATH                │\n│     c. 通过 stdin\u002Fstdout 建立 ACP JSON-RPC 连接               │\n│     d. 发送 initialize (声明 capabilities)                     │\n│     e. TaskWorkflowRunner 发送 task prompt                    │\n│  4. Worker 执行任务，通过 dispatch CLI 上报进度                  │\n│  5. Worker 完成 → 产物打包 → dispatch worker complete          │\n│  6. AcpController 收集结果 → 上传 Server → 标记 completed      │\n│                                                               │\n│  ┌─────────────────┐  stdio (ACP)  ┌──────────────────┐      │\n│  │  AcpController   │←────────────→│  Worker Process   │      │\n│  │  DispatchAcpClient│              │  (ACP Agent 进程)  │      │\n│  └─────────────────┘               └──────────────────┘      │\n└──────────────────────────────────────────────────────────────┘\n```\n\n### 3.2 AgentConfig 完整字段\n\n每个 Worker 在 `client.config.json` 的 `agents` 数组中注册：\n\n```typescript\ninterface AgentConfig {\n  id: string;                    \u002F\u002F 唯一标识（必填）\n  type: 'manager' | 'worker';   \u002F\u002F 角色（必填）\n  command: string;               \u002F\u002F 启动命令（必填）\n  args?: string[];               \u002F\u002F 额外启动参数\n  workDir: string;               \u002F\u002F 工作目录（必填）\n  capabilities?: string[];       \u002F\u002F 能力标签（用于 dispatch 匹配）\n  autoClaimTags?: string[];      \u002F\u002F 自动认领的任务标签\n  allowMultiProcess?: boolean;   \u002F\u002F 是否允许并行多任务（默认 false）\n  promptTemplate?: string;       \u002F\u002F 自定义 prompt 模板路径\n  acpCapabilities?: {\n    fs?: {\n      readTextFile?: boolean;    \u002F\u002F 允许 Agent 读文件\n      writeTextFile?: boolean;   \u002F\u002F 允许 Agent 写文件\n    };\n    terminal?: boolean;          \u002F\u002F 允许 Agent 使用终端\n  };\n  permissionPolicy?: 'auto-allow' | 'auto-deny' | 'prompt';\n}\n```\n\n### 3.3 关键字段深度说明\n\n#### `command` — Agent 启动命令\n\n第一个 token 是可执行文件，后续 token 是默认参数。`args` 中的参数会追加到末尾。\n\n```json\n{ \"command\": \"claude-agent-acp\", \"args\": [\"--model\", \"sonnet\"] }\n\u002F\u002F 实际执行: claude-agent-acp --model sonnet\n```\n\n**要求**：`command` 启动的进程必须通过 **stdin\u002Fstdout** 进行 ACP 协议通信（JSON-RPC 2.0, newline-delimited JSON）。stderr 用于日志输出，不参与协议。\n\n> **注意**：并非所有 AI Agent CLI 都原生支持 ACP。部分 Agent（如 Claude、Codex）需要通过适配器。\n> 详见 [ACP 兼容 Agent 列表](https:\u002F\u002Fagentclientprotocol.com\u002Fget-started\u002Fagents)。\n\n#### `workDir` — Agent 工作目录\n\nAgent 进程以此目录为 `cwd` 启动。Client Node 会在其中创建：\n\n```\n{workDir}\u002F\n├── .dispatch\u002F\n│   ├── input\u002F{taskIdPrefix}\u002F    ← 下载的任务附件\n│   └── output\u002F{taskIdPrefix}\u002F   ← Agent 应将产物放在这里\n│       ├── artifact.zip         ← 产物压缩包\n│       └── result.json          ← 结构化结果\n└── ... (Agent 自身的文件)\n```\n\n#### `capabilities` — 能力标签\n\n与分发规则的 `targetCapabilities` 配合使用：\n\n```json\n\u002F\u002F 规则: 需要 [\"typescript\", \"testing\"] 能力的 Worker\n{ \"taskTags\": [\"unit-test\"], \"targetCapabilities\": [\"typescript\", \"testing\"] }\n\n\u002F\u002F Worker: 声明自己具备这些能力\n{ \"id\": \"test-bot\", \"capabilities\": [\"typescript\", \"testing\", \"jest\"] }\n\u002F\u002F ✓ 匹配成功（Worker 具备规则要求的所有能力）\n```\n\n#### `acpCapabilities` — ACP 能力声明\n\n在 ACP `initialize` 阶段向 Agent 声明 Client 提供的能力：\n\n```json\n{\n  \"acpCapabilities\": {\n    \"fs\": { \"readTextFile\": true, \"writeTextFile\": true },\n    \"terminal\": true\n  }\n}\n```\n\n| 能力 | 说明 |\n|------|------|\n| `fs.readTextFile` | Agent 可通过 ACP 请求读取 Client 端文件 |\n| `fs.writeTextFile` | Agent 可通过 ACP 请求写入 Client 端文件 |\n| `terminal` | Agent 可通过 ACP 请求执行终端命令 |\n\n#### `permissionPolicy` — 权限策略\n\n当 Agent 通过 ACP 请求使用工具（文件读写、终端）时的审批策略：\n\n| 值 | 行为 |\n|----|------|\n| `auto-allow` | 自动批准所有请求（默认，适合可信 Agent） |\n| `auto-deny` | 自动拒绝所有请求（最安全） |\n| `prompt` | 需要人工审批（当前未完整实现） |\n\n### 3.4 Worker 生命周期\n\n```\n                          Client Node 启动\n                               │\n                    Worker 注册 (config.agents)\n                               │\n                          status: idle\n                               │\n              ┌────────────────▼────────────────┐\n              │   Dispatcher 匹配到合适的任务     │\n              │   HTTP claim → Server             │\n              └────────────────┬────────────────┘\n                               │\n              ┌────────────────▼────────────────┐\n              │   AcpController.launchAgent()    │\n              │   1. spawn(command, {cwd:workDir})│\n              │   2. env += DISPATCH_TOKEN        │\n              │   3. env += DISPATCH_IPC_PATH     │\n              │   4. ACP initialize()             │\n              │   5. ACP prompt(taskContent)       │\n              └────────────────┬────────────────┘\n                               │\n                        status: busy\n                               │\n              ┌────────────────▼────────────────┐\n              │  Worker 执行任务                   │\n              │  - dispatch worker progress ...   │\n              │  - dispatch worker log ...        │\n              │  - 产出 artifact.zip + result.json │\n              │  - dispatch worker complete ...   │\n              └────────────────┬────────────────┘\n                               │\n                   ┌───────────┴───────────┐\n                   ▼                       ▼\n            完成 (completed)         失败 (failed)\n                   │                       │\n            status: idle             auto restart?\n                   │                  (指数退避)\n                   ▼                       │\n            等待下一个任务              status: idle\n```\n\n#### 进程环境变量注入\n\nWorker 进程启动时自动获得两个关键环境变量：\n\n| 变量 | 值 | 用途 |\n|------|-----|------|\n| `DISPATCH_TOKEN` | `wt_\u003Cuuid>` | 临时 Worker Token，仅在本次任务生命周期内有效，任务结束自动撤销 |\n| `DISPATCH_IPC_PATH` | Unix socket \u002F named pipe 路径 | 连接 Client Node IPC Server，用于 `dispatch` CLI 通信 |\n\n#### 自动重启机制\n\nWorker 进程异常退出时（exit code ≠ 0）：\n\n1. 状态标记为 `crashed`\n2. 如有正在执行的任务，自动释放回 `pending`\n3. 如重启次数未超限（默认 3 次），启用指数退避重启：\n   - 第 1 次: 2 秒后\n   - 第 2 次: 4 秒后\n   - 第 3 次: 8 秒后（上限 30 秒）\n4. 重启后状态回到 `idle`，可继续接收新任务\n\n### 3.5 Worker 通过 CLI 与系统交互\n\nWorker 在任务执行过程中使用 `dispatch` CLI：\n\n```bash\n# 上报进度（首次上报触发 claimed → in_progress 转换）\ndispatch worker progress \u003CtaskId> --percent 30 --message \"分析代码中...\"\n\n# 追加工作日志\ndispatch worker log \u003CtaskId> --message \"发现 3 个潜在安全问题\"\n\n# 完成任务（提交产物）\ndispatch worker complete \u003CtaskId> \\\n  --zip .\u002Foutput\u002Fartifact.zip \\\n  --result .\u002Foutput\u002Fresult.json\n\n# 报告失败\ndispatch worker fail \u003CtaskId> --reason \"无法访问代码仓库\"\n\n# 查询当前任务状态\ndispatch worker status \u003CtaskId>\n\n# 心跳（长时间无进度更新时使用）\ndispatch worker heartbeat \u003CtaskId>\n```\n\n### 3.6 ACP 任务分发流程\n\nClient Node 通过 ACP 向 Worker 发送任务时，使用 **TaskWorkflowRunner** 执行多轮对话：\n\n**Pass 1: InitialTaskPass** — 构建任务 prompt，包含：\n- 任务标题、描述、优先级、标签、元数据\n- 附件路径（如有下载）\n- 产物输出目录和格式要求\n- CLI 命令参考\n\n**Pass 2: ArtifactEnforcementPass** — 任务完成后检查产物：\n- 验证 `artifact.zip` 和 `result.json` 是否存在\n- 如产物缺失，向 Agent 发送补救 prompt，要求补充\n- 最终验证通过后才标记任务完成\n\n---\n\n## Part 4: 挂载不同类型的 Agent\n\n> **前提**：并非所有 AI Agent CLI 都原生支持 ACP 协议。部分需要通过**适配器**桥接。\n> 完整列表参见 [ACP 兼容 Agent](https:\u002F\u002Fagentclientprotocol.com\u002Fget-started\u002Fagents)。\n\n### 4.0 ACP 兼容 Agent 参考表\n\n| Agent | ACP 支持 | command | args | 安装方式 |\n|-------|---------|---------|------|---------|\n| **Claude Agent** | 适配器 | `claude-agent-acp` | — | `npm i -g @zed-industries\u002Fclaude-agent-acp` |\n| **Codex CLI** | 适配器 | `codex-acp` | — | `npm i -g @zed-industries\u002Fcodex-acp` |\n| **Gemini CLI** | 原生 | `gemini` | `[\"--experimental-acp\"]` | `npm i -g @google\u002Fgemini-cli` |\n| **Goose** | 原生 | `goose` | `[\"acp\"]` | [block.github.io\u002Fgoose](https:\u002F\u002Fblock.github.io\u002Fgoose\u002Fdocs\u002Fguides\u002Facp-clients) |\n| **OpenCode** | 原生 | `opencode` | `[\"acp\"]` | [open-code.ai](https:\u002F\u002Fopen-code.ai\u002Fdocs\u002Fen\u002Facp) |\n| **Kiro CLI** | 原生 | `kiro` | `[\"acp\"]` | [kiro.dev\u002Fcli](https:\u002F\u002Fkiro.dev\u002Fcli\u002F) |\n| **Kimi CLI** | 原生 | `kimi` | `[\"acp\"]` | [github.com\u002FMoonshotAI\u002Fkimi-cli](https:\u002F\u002Fgithub.com\u002FMoonshotAI\u002Fkimi-cli) |\n| **Augment Code** | 原生 | `auggie` | `[\"--acp\"]` | [docs.augmentcode.com\u002Fcli\u002Facp](https:\u002F\u002Fdocs.augmentcode.com\u002Fcli\u002Facp\u002Fagent) |\n| **Cline** | 原生 | `cline` | `[\"--acp\"]` | [docs.cline.bot](https:\u002F\u002Fdocs.cline.bot\u002Fcline-cli\u002Facp-editor-integrations) |\n| **Qwen Code** | 原生 | `qwen` | `[\"--acp\"]` | `npm i -g @qwen-code\u002Fqwen-code` |\n| **Mistral Vibe** | 原生 | `vibe-acp` | — | [github.com\u002Fmistralai\u002Fmistral-vibe](https:\u002F\u002Fgithub.com\u002Fmistralai\u002Fmistral-vibe\u002Fblob\u002Fmain\u002Fdocs\u002Facp-setup.md) |\n| **OpenHands** | 原生 | `openhands` | `[\"acp\"]` | [docs.openhands.dev](https:\u002F\u002Fdocs.openhands.dev\u002Fopenhands\u002Fusage\u002Frun-openhands\u002Facp) |\n| **GitHub Copilot** | 公测 | — | — | [github.com\u002Ffeatures\u002Fcopilot](https:\u002F\u002Fgithub.com\u002Ffeatures\u002Fcopilot) |\n| **Pi** | 适配器 | `pi-acp` | — | [github.com\u002Fsvkozak\u002Fpi-acp](https:\u002F\u002Fgithub.com\u002Fsvkozak\u002Fpi-acp) |\n| 自定义 Agent | 需自行实现 | `node .\u002Fagent.mjs` | — | 使用 ACP SDK（TypeScript\u002FPython\u002FRust\u002FKotlin） |\n\n> **重要**：很多 Agent CLI 的\"普通模式\"是交互式终端，不等于 ACP 模式。必须使用上表中对应的 `args` 参数才能进入 ACP stdio 通信模式。\n\nACP SDK 库：\n- TypeScript: `@anthropic-ai\u002Fagent-client-protocol` — [文档](https:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Ftypescript)\n- Python: `agent-client-protocol` — [文档](https:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Fpython)\n- Rust: — [文档](https:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Frust)\n- Kotlin: — [文档](https:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Fkotlin)\n\n### 4.1 挂载 Claude Agent\n\nClaude Code **不原生支持 ACP**，需通过 Zed 官方的 [`claude-agent-acp`](https:\u002F\u002Fgithub.com\u002Fzed-industries\u002Fclaude-agent-acp) 适配器桥接。\n\n**安装适配器**：\n\n```bash\nnpm install -g @zed-industries\u002Fclaude-agent-acp\n```\n\n**配置**：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"claude-reviewer\",\n      \"type\": \"worker\",\n      \"command\": \"claude-agent-acp\",\n      \"args\": [\"--model\", \"sonnet\"],\n      \"workDir\": \"\u002Fworkspace\u002Fclaude-reviewer\",\n      \"capabilities\": [\"code-review\", \"security-audit\", \"typescript\"],\n      \"acpCapabilities\": {\n        \"fs\": { \"readTextFile\": true, \"writeTextFile\": true },\n        \"terminal\": true\n      },\n      \"permissionPolicy\": \"auto-allow\"\n    }\n  ]\n}\n```\n\n> 适配器通过 Claude Agent SDK 调用 Claude，需要设置 `ANTHROPIC_API_KEY` 环境变量。\n> 也可下载[预编译二进制](https:\u002F\u002Fgithub.com\u002Fzed-industries\u002Fclaude-agent-acp\u002Freleases)，无需 Node.js。\n\n### 4.2 挂载 Codex Agent\n\nOpenAI Codex CLI 同样需通过 [`codex-acp`](https:\u002F\u002Fgithub.com\u002Fzed-industries\u002Fcodex-acp) 适配器：\n\n```bash\nnpm install -g @zed-industries\u002Fcodex-acp\n```\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"codex-worker\",\n      \"type\": \"worker\",\n      \"command\": \"codex-acp\",\n      \"workDir\": \"\u002Fworkspace\u002Fcodex-worker\",\n      \"capabilities\": [\"code-generation\", \"refactor\"],\n      \"permissionPolicy\": \"auto-allow\"\n    }\n  ]\n}\n```\n\n> 需要设置 `OPENAI_API_KEY` 或 `CODEX_API_KEY` 环境变量。\n\n### 4.3 挂载原生 ACP Agent（Gemini、Goose、OpenCode 等）\n\n部分 Agent CLI 内置 ACP 协议支持，但通常需要特定的子命令或标志才能进入 ACP 模式（而非交互终端模式）。\n\n**Gemini CLI**（需 `--experimental-acp` 标志）：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"gemini-worker\",\n      \"type\": \"worker\",\n      \"command\": \"gemini\",\n      \"args\": [\"--experimental-acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Fgemini-worker\",\n      \"capabilities\": [\"code-generation\", \"analysis\"],\n      \"permissionPolicy\": \"auto-allow\"\n    }\n  ]\n}\n```\n\n**Goose**（需 `acp` 子命令）：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"goose-worker\",\n      \"type\": \"worker\",\n      \"command\": \"goose\",\n      \"args\": [\"acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Fgoose-worker\",\n      \"capabilities\": [\"general\"],\n      \"permissionPolicy\": \"auto-allow\"\n    }\n  ]\n}\n```\n\n**OpenCode**（需 `acp` 子命令）：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"opencode-worker\",\n      \"type\": \"worker\",\n      \"command\": \"opencode\",\n      \"args\": [\"acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Fopencode-worker\",\n      \"capabilities\": [\"code-generation\", \"refactor\"]\n    }\n  ]\n}\n```\n\n### 4.4 挂载自定义 ACP Agent\n\n任何实现了 ACP 协议的程序都可以作为 Worker。ACP 协议要求：\n\n- 通过 **stdin** 接收 JSON-RPC 2.0 消息（换行分隔 NDJSON）\n- 通过 **stdout** 发送 JSON-RPC 2.0 响应（换行分隔 NDJSON）\n- stderr 用于日志（不参与协议通信）\n\n**Python ACP Agent 示例**：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"python-analyzer\",\n      \"type\": \"worker\",\n      \"command\": \"python\",\n      \"args\": [\".\u002Fmy_agent.py\"],\n      \"workDir\": \"\u002Fworkspace\u002Fpython-agent\",\n      \"capabilities\": [\"data-analysis\", \"python\"],\n      \"acpCapabilities\": {\n        \"fs\": { \"readTextFile\": true }\n      }\n    }\n  ]\n}\n```\n\n**Node.js ACP Agent**：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"node-agent\",\n      \"type\": \"worker\",\n      \"command\": \"node\",\n      \"args\": [\".\u002Fagent.mjs\"],\n      \"workDir\": \"\u002Fworkspace\u002Fnode-agent\",\n      \"capabilities\": [\"web-scraping\", \"api-testing\"]\n    }\n  ]\n}\n```\n\n### 4.5 挂载 Manager Agent（调度顾问）\n\nManager Agent 不执行任务，而是为 Client Node 提供分发建议：\n\n```json\n{\n  \"dispatchMode\": \"manager\",\n  \"agents\": [\n    {\n      \"id\": \"dispatch-manager\",\n      \"type\": \"manager\",\n      \"command\": \"claude-agent-acp\",\n      \"workDir\": \"\u002Fworkspace\u002Fmanager\",\n      \"acpCapabilities\": {\n        \"fs\": { \"readTextFile\": true, \"writeTextFile\": false },\n        \"terminal\": false\n      }\n    },\n    {\n      \"id\": \"worker-backend\",\n      \"type\": \"worker\",\n      \"command\": \"claude-agent-acp\",\n      \"workDir\": \"\u002Fworkspace\u002Fbackend\",\n      \"capabilities\": [\"backend\", \"api\", \"database\"]\n    },\n    {\n      \"id\": \"worker-frontend\",\n      \"type\": \"worker\",\n      \"command\": \"gemini\",\n      \"args\": [\"--experimental-acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Ffrontend\",\n      \"capabilities\": [\"frontend\", \"react\", \"css\"]\n    }\n  ]\n}\n```\n\nManager 收到的咨询 prompt 包含：任务信息 + 所有可用 Worker 的 ID、能力和状态。Manager 返回 JSON 格式的 `DispatchAdvice`：\n\n```json\n{\n  \"recommendedAgentId\": \"worker-backend\",\n  \"confidence\": 0.9,\n  \"reason\": \"This task involves API endpoint implementation, best suited for the backend worker.\"\n}\n```\n\n### 4.6 多 Worker 集群配置\n\n一个 Client Node 可以挂载多个 Worker，形成专业化分工。不同 Worker 可以使用不同的 Agent：\n\n```json\n{\n  \"name\": \"team-alpha\",\n  \"serverUrl\": \"http:\u002F\u002Fdispatch-server:9800\",\n  \"token\": \"tok_team_alpha\",\n  \"tags\": [\"code-review\", \"testing\", \"docs\", \"refactor\"],\n  \"dispatchMode\": \"hybrid\",\n  \"autoDispatch\": {\n    \"rules\": [\n      { \"taskTags\": [\"code-review\"], \"targetAgentId\": \"reviewer\", \"priority\": 10 },\n      { \"taskTags\": [\"testing\"], \"targetAgentId\": \"tester\", \"priority\": 10 },\n      { \"taskTags\": [\"docs\"], \"targetAgentId\": \"writer\", \"priority\": 5 },\n      { \"taskTags\": [\"refactor\"], \"targetCapabilities\": [\"typescript\"], \"priority\": 8 }\n    ],\n    \"fallbackAction\": \"skip\"\n  },\n  \"agents\": [\n    {\n      \"id\": \"manager\",\n      \"type\": \"manager\",\n      \"command\": \"claude-agent-acp\",\n      \"workDir\": \"\u002Fworkspace\u002Fmanager\"\n    },\n    {\n      \"id\": \"reviewer\",\n      \"type\": \"worker\",\n      \"command\": \"claude-agent-acp\",\n      \"workDir\": \"\u002Fworkspace\u002Freviewer\",\n      \"capabilities\": [\"code-review\", \"security\", \"typescript\", \"python\"]\n    },\n    {\n      \"id\": \"tester\",\n      \"type\": \"worker\",\n      \"command\": \"gemini\",\n      \"args\": [\"--experimental-acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Ftester\",\n      \"capabilities\": [\"testing\", \"typescript\", \"jest\", \"playwright\"]\n    },\n    {\n      \"id\": \"writer\",\n      \"type\": \"worker\",\n      \"command\": \"goose\",\n      \"args\": [\"acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Fwriter\",\n      \"capabilities\": [\"writing\", \"documentation\", \"markdown\"]\n    }\n  ]\n}\n```\n\n### 4.7 Worker 挂载检查清单\n\n挂载新 Worker 前确认以下事项：\n\n| 检查项 | 说明 |\n|--------|------|\n| Agent 支持 ACP 协议 | 原生支持或已安装适配器（参见 4.0 参考表） |\n| `command` 可直接执行 | 在 shell 中运行 `command` 能成功启动（已 `npm i -g` 或在 PATH 中） |\n| API Key 已配置 | 如 `ANTHROPIC_API_KEY`、`OPENAI_API_KEY` 等环境变量已设置 |\n| `workDir` 存在且有写权限 | Client Node 需要在其中创建 `.dispatch\u002F` 目录 |\n| `id` 全局唯一 | 同一 Client Node 下所有 Agent ID 不能重复 |\n| `capabilities` 与规则匹配 | 至少有一条 `autoDispatch.rules` 能路由到此 Worker |\n| 网络可达 | Worker 能通过 IPC 路径连接 Client Node |\n\n---\n\n## Part 5: 提交任务并监听状态\n\n### 5.1 创建任务\n\n**JSON 请求**：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer tok_client_abc123\" \\\n  -d '{\n    \"title\": \"Review PR #42\",\n    \"description\": \"Review the pull request for security issues and code quality.\",\n    \"tags\": [\"code-review\"],\n    \"priority\": \"high\",\n    \"metadata\": { \"repo\": \"my-org\u002Fmy-repo\", \"pr\": 42 }\n  }'\n```\n\n**带附件（multipart）**：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks \\\n  -H \"Authorization: Bearer tok_client_abc123\" \\\n  -F 'data={\"title\":\"Analyze dataset\",\"tags\":[\"data-analysis\"],\"priority\":\"normal\"}' \\\n  -F 'files=@.\u002Fdataset.csv' \\\n  -F 'files=@.\u002Fconfig.yaml'\n```\n\n### 5.2 查询任务\n\n```bash\ncurl http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks                  # 所有活跃任务\ncurl \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks?status=pending\"  # 按状态\ncurl \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks?tag=code-review\" # 按标签\ncurl \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks?page=1&limit=10\" # 分页\ncurl http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\u002F{taskId}          # 单个任务\n```\n\n### 5.3 SSE 流式监听（推荐）\n\n```bash\ncurl -N \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\u002F{taskId}\u002Fstream?interval=1000&logs=true\"\n```\n\n| 事件 | 说明 | 数据 |\n|------|------|------|\n| `task` | 状态\u002F进度变化 | `{ id, status, progress, progressMessage, claimedBy, updatedAt }` |\n| `logs` | 新交互日志 | `InteractionLogEntry[]` |\n| `done` | 到达终态 | `{ taskId, finalStatus }` |\n| `error` | 轮询出错 | `{ message }` |\n\n**TypeScript 示例**：\n\n```typescript\nfunction watchTask(serverUrl: string, taskId: string): Promise\u003Cstring> {\n  return new Promise((resolve, reject) => {\n    const url = `${serverUrl}\u002Fapi\u002Fv1\u002Ftasks\u002F${taskId}\u002Fstream?interval=1000&logs=true`;\n    const es = new EventSource(url);\n\n    es.addEventListener('task', (e) => {\n      const data = JSON.parse(e.data);\n      console.log(`[${data.status}] ${data.progressMessage ?? ''}`);\n    });\n\n    es.addEventListener('logs', (e) => {\n      for (const entry of JSON.parse(e.data)) {\n        console.log(`  [${entry.type}] ${entry.content.slice(0, 80)}`);\n      }\n    });\n\n    es.addEventListener('done', (e) => {\n      const data = JSON.parse(e.data);\n      es.close();\n      resolve(data.finalStatus);\n    });\n\n    es.addEventListener('error', () => { es.close(); reject(new Error('SSE error')); });\n  });\n}\n```\n\n---\n\n## Part 6: 任务状态机\n\n```\npending ──→ claimed ──→ in_progress ──→ completed\n   │                        │\n   │                        └──→ failed ──→ (release) ──→ pending\n   │\n   └──→ cancelled\n```\n\n| 状态 | 触发 | 说明 |\n|------|------|------|\n| `pending` | 创建任务 \u002F release | 等待被领取 |\n| `claimed` | Worker claim | 已分配给 Worker，尚未开始 |\n| `in_progress` | 首次 progress 上报 | 正在执行中 |\n| `completed` | 产物上传成功 | 终态 |\n| `failed` | Worker 报告失败 | 可通过 release 回到 pending |\n| `cancelled` | 手动取消 | 终态 |\n\n---\n\n## Part 7: Token 鉴权\n\n| 角色 | 用途 | 权限 |\n|------|------|------|\n| `admin` | Dashboard 登录 | 完全权限 |\n| `client` | Client Node \u002F Worker | 完全权限（包括 claim\u002Fcomplete） |\n| `operator` | 外部集成 | 创建\u002F删除\u002F查看任务；**禁止** claim\u002Frelease\u002Fprogress\u002Fcomplete\u002Fcancel |\n\n```bash\n# 登录获取 session token\ncurl -X POST http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Fauth\u002Flogin \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"username\":\"admin\",\"password\":\"your-password\"}'\n\n# 使用 static token\ncurl -H \"Authorization: Bearer tok_client_abc123\" http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\n```\n\n---\n\n## Part 8: 端到端示例\n\n### 8.1 最简单的完整流程\n\n```bash\n#!\u002Fbin\u002Fbash\n# 1. 启动 Server\nDISPATCH_DATA_DIR=\u002Ftmp\u002Fdispatch-demo node packages\u002Fserver\u002Fdist\u002Findex.js &\nsleep 2\n\n# 2. 提交任务\nTASK_ID=$(curl -s -X POST http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"title\":\"Demo\",\"tags\":[\"demo\"],\"priority\":\"normal\"}' | jq -r '.id')\necho \"Task: $TASK_ID\"\n\n# 3. 监听（后台）\ncurl -sN \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\u002F$TASK_ID\u002Fstream?interval=1000\" &\n\n# 4. 模拟 Worker: claim → progress → complete\ncurl -s -X POST \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\u002F$TASK_ID\u002Fclaim\" \\\n  -H \"Content-Type: application\u002Fjson\" -d '{\"clientId\":\"node-01\",\"agentId\":\"worker-01\"}'\n\ncurl -s -X POST \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\u002F$TASK_ID\u002Fprogress\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"clientId\":\"node-01\",\"agentId\":\"worker-01\",\"progress\":50,\"message\":\"Working...\"}'\n\n# 5. 清理\nkill %2 2>\u002Fdev\u002Fnull; kill %1 2>\u002Fdev\u002Fnull\n```\n\n### 8.2 单 Worker 自动化完整部署\n\n```bash\n#!\u002Fbin\u002Fbash\n# 1. 启动 Server\nDISPATCH_DATA_DIR=.\u002Fdata node packages\u002Fserver\u002Fdist\u002Findex.js &\nsleep 2\n\n# 2. 安装 ACP 适配器（以 Claude 为例；若用 Gemini 等原生 ACP Agent 可跳过）\nnpm install -g @zed-industries\u002Fclaude-agent-acp\n\n# 3. 准备 Worker 工作目录\nmkdir -p \u002Fworkspace\u002Fclaude-worker\n\n# 4. 创建 client.config.json\ncat > client.config.json \u003C\u003CEOF\n{\n  \"name\": \"single-worker-node\",\n  \"serverUrl\": \"http:\u002F\u002Flocalhost:9800\",\n  \"tags\": [\"general\"],\n  \"dispatchMode\": \"tag-auto\",\n  \"autoDispatch\": {\n    \"rules\": [{ \"taskTags\": [\"general\"], \"targetAgentId\": \"claude\", \"priority\": 1 }]\n  },\n  \"agents\": [{\n    \"id\": \"claude\",\n    \"type\": \"worker\",\n    \"command\": \"claude-agent-acp\",\n    \"workDir\": \"\u002Fworkspace\u002Fclaude-worker\",\n    \"capabilities\": [\"general\"],\n    \"acpCapabilities\": { \"fs\": { \"readTextFile\": true, \"writeTextFile\": true }, \"terminal\": true },\n    \"permissionPolicy\": \"auto-allow\"\n  }]\n}\nEOF\n\n# 5. 启动 Client Node（Worker 自动就绪）\nnode packages\u002Fclient-node\u002Fdist\u002Fmain.js &\nsleep 3\n\n# 6. 提交任务 → Worker 自动领取并执行\ncurl -X POST http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"title\":\"Write unit tests for auth module\",\"tags\":[\"general\"],\"priority\":\"normal\"}'\n\necho \"Task submitted. Worker will pick it up automatically.\"\n```\n\n---\n\n## Part 9: 生产部署注意事项\n\n部署 AgentDispatch 到远程服务器时，请注意以下关键事项。完整详情和排查步骤参见 [故障排查指南](..\u002F..\u002Fdocs\u002Fguide\u002Ftroubleshooting.md)。\n\n| 主题 | 要点 |\n|------|------|\n| **进程管理** | 使用 pm2 \u002F systemd \u002F Docker，避免 `nohup` |\n| **远程 Dashboard** | 设置 `VITE_API_URL=http:\u002F\u002F\u003Cserver-ip>:9800`；详见 [配置指南](..\u002F..\u002Fdocs\u002Fguide\u002Fconfiguration.md#dashboard-远程访问) |\n| **嵌套 Claude 会话** | 用包装脚本 `unset CLAUDECODE` 后再启动 Worker |\n| **inotify（Linux）** | 增加 `max_user_instances` 到 8192+ |\n| **CORS** | Server 已内置支持；反向代理不要重复添加 CORS 头 |\n| **部署检查清单** | 见 [troubleshooting.md — Deployment Checklist](..\u002F..\u002Fdocs\u002Fguide\u002Ftroubleshooting.md#deployment-checklist) |\n\n---\n\n## REST API 快速参考\n\n### 任务管理\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks` | 创建任务 |\n| `GET` | `\u002Fapi\u002Fv1\u002Ftasks` | 列出活跃任务（?status=&tag=&page=&limit=） |\n| `GET` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id` | 获取单个任务 |\n| `PATCH` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id` | 更新任务 |\n| `DELETE` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id` | 删除任务 |\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Fclaim` | 领取任务 |\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Frelease` | 释放任务 |\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Fprogress` | 上报进度 |\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Fcomplete` | 完成任务（multipart） |\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Fcancel` | 取消任务 |\n| `GET` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Fstream` | SSE 流式监听 |\n| `GET\u002FPOST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Flogs` | 交互日志 |\n\n### 客户端管理\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `POST` | `\u002Fapi\u002Fv1\u002Fclients\u002Fregister` | 注册 |\n| `GET` | `\u002Fapi\u002Fv1\u002Fclients` | 列表 |\n| `GET` | `\u002Fapi\u002Fv1\u002Fclients\u002F:id` | 详情 |\n| `DELETE` | `\u002Fapi\u002Fv1\u002Fclients\u002F:id` | 注销 |\n| `POST` | `\u002Fapi\u002Fv1\u002Fclients\u002F:id\u002Fheartbeat` | 心跳 |\n\n### 鉴权\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `POST` | `\u002Fapi\u002Fv1\u002Fauth\u002Flogin` | 登录 |\n| `POST` | `\u002Fapi\u002Fv1\u002Fauth\u002Flogout` | 登出 |\n| `GET` | `\u002Fapi\u002Fv1\u002Fauth\u002Fme` | 验证 Token |\n| `GET` | `\u002Fhealth` | 健康检查（无需鉴权） |\n\n---\n\n## 常见错误码\n\n| 错误码 | HTTP | 说明 |\n|--------|------|------|\n| `TASK_NOT_FOUND` | 404 | 任务不存在 |\n| `TASK_ALREADY_CLAIMED` | 409 | 任务已被其他 Worker 领取，或非 owner 操作 |\n| `TASK_INVALID_TRANSITION` | 400 | 当前状态不允许此操作 |\n| `UNAUTHORIZED` | 401 | Token 缺失或无效 |\n| `FORBIDDEN` | 403 | 角色权限不足 |\n| `VALIDATION_ERROR` | 400 | 请求参数校验失败 |\n| `ARTIFACT_MISSING_ZIP` | 400 | 完成任务时缺少 zip |\n| `ARTIFACT_MISSING_RESULT` | 400 | 完成任务时缺少 result.json |\n\n---\n\n## 数据目录结构\n\n```\n{dataDir}\u002F\n├── tasks\u002F           # 活跃任务 (.json + .md)\n├── tasks-archive\u002F   # 归档任务\n├── attachments\u002F     # 任务输入附件\n├── artifacts\u002F       # 任务产物 (zip + result.json)\n├── clients\u002F         # 客户端注册信息\n└── logs\u002F\n    ├── tasks\u002F       # 按任务 ID 的交互日志 (.jsonl)\n    ├── clients\u002F     # 按客户端 ID 的日志\n    └── server-*.jsonl  # Server 主日志\n```\n","# AgentDispatch 使用指南\n\n## 概述\n\nAgentDispatch 是一个 AI Agent 任务分发平台。核心架构将任务**创建**与**执行**完全解耦：\n\n| 组件 | 职责 |\n|------|------|\n| **Server** | 中心化 REST API 服务，管理任务队列、客户端注册、文件持久化、SSE 推送 |\n| **Client Node** | 执行节点，轮询 Server 获取任务，调度和管理本地 Worker Agent 集群 |\n| **Worker Agent** | 通过 ACP (Agent Client Protocol) 执行具体任务的 AI Agent |\n| **Manager Agent** | 可选的 AI 调度顾问，通过 ACP 向 Client Node 提供分发建议 |\n| **CLI** | `dispatch` 命令行工具，Worker 通过它上报进度、提交产物 |\n\n```\n                            ┌────────────────────────┐\n  任务提交方                 │     Server (:9800)      │\n  (curl \u002F SDK \u002F Dashboard)─→│  REST API + FileStore   │\n                            │  SSE Stream + Auth      │\n                            └────────┬───────────────┘\n                                     │ HTTP (poll\u002Fclaim\u002Fprogress\u002Fcomplete)\n                            ┌────────▼───────────────┐\n                            │     Client Node         │\n                            │  Dispatcher (tag\u002Fmgr)   │\n                            │  AcpController          │\n                            │  WorkerManager          │\n                            │  IPC Server             │\n                            └──┬─────┬─────┬─────────┘\n                   ACP(stdio)  │     │     │  ACP(stdio)\n                     ┌─────────▼┐ ┌──▼──┐ ┌▼──────────┐\n                     │ Worker-01│ │Wk-02│ │Manager Agt │\n                     │(claude)  │ │(gpt)│ │(调度顾问)   │\n                     └──────────┘ └─────┘ └───────────┘\n```\n\n**核心设计理念**：任何支持 ACP 协议（JSON-RPC 2.0 over stdio）的 AI Agent 都可以作为 Worker 挂载到 Client Node 上。\n\n---\n\n## Part 1: 启动 Server\n\n### 1.1 前置条件\n\n- Node.js >= 20.0.0\n- pnpm >= 9.x\n\n### 1.2 安装与构建\n\n```bash\npnpm install\npnpm build\n```\n\n### 1.3 零配置启动\n\n```bash\nnode packages\u002Fserver\u002Fdist\u002Findex.js\n# Server 默认监听 0.0.0.0:9800，数据存储在 .\u002Fdata\u002F\n```\n\n### 1.4 自定义配置\n\n**环境变量方式**（推荐用于快速测试）：\n\n```bash\nDISPATCH_SERVER_PORT=8080 \\\nDISPATCH_DATA_DIR=.\u002Fmy-data \\\nDISPATCH_LOG_LEVEL=debug \\\nDISPATCH_AUTH_ENABLED=true \\\nDISPATCH_AUTH_TOKENS=\"tok_client_abc123,tok_operator_xyz:operator\" \\\nnode packages\u002Fserver\u002Fdist\u002Findex.js\n```\n\n**配置文件方式**（`server.config.json`）：\n\n```json\n{\n  \"host\": \"0.0.0.0\",\n  \"port\": 9800,\n  \"dataDir\": \".\u002Fdata\",\n  \"logLevel\": \"info\",\n  \"auth\": {\n    \"enabled\": true,\n    \"users\": [{ \"username\": \"admin\", \"password\": \"your-password\" }],\n    \"tokens\": [\n      \"tok_client_abc123\",\n      { \"token\": \"tok_operator_xyz\", \"role\": \"operator\" }\n    ]\n  }\n}\n```\n\n### 1.5 验证\n\n```bash\ncurl http:\u002F\u002Flocalhost:9800\u002Fhealth\n# {\"status\":\"ok\",\"version\":\"0.0.1\",\"authEnabled\":false}\n```\n\n### 1.6 环境变量一览\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `DISPATCH_SERVER_HOST` | `0.0.0.0` | 监听地址 |\n| `DISPATCH_SERVER_PORT` | `9800` | 监听端口 |\n| `DISPATCH_DATA_DIR` | `.\u002Fdata` | 数据目录 |\n| `DISPATCH_LOG_LEVEL` | `info` | 日志级别 (debug\u002Finfo\u002Fwarn\u002Ferror) |\n| `DISPATCH_AUTH_ENABLED` | `false` | 启用鉴权 |\n| `DISPATCH_AUTH_TOKENS` | — | 静态 Token 列表（逗号分隔，`:role` 后缀可选） |\n\n---\n\n## Part 2: 配置 Client Node\n\n### 2.1 最小可用配置\n\n在工作目录创建 `client.config.json`：\n\n```json\n{\n  \"name\": \"my-node\",\n  \"serverUrl\": \"http:\u002F\u002Flocalhost:9800\",\n  \"tags\": [\"code-review\"],\n  \"dispatchMode\": \"tag-auto\",\n  \"autoDispatch\": {\n    \"rules\": [\n      { \"taskTags\": [\"code-review\"], \"targetAgentId\": \"worker-01\", \"priority\": 10 }\n    ],\n    \"fallbackAction\": \"skip\"\n  },\n  \"agents\": [\n    {\n      \"id\": \"worker-01\",\n      \"type\": \"worker\",\n      \"command\": \"claude-agent-acp\",\n      \"workDir\": \"\u002Fpath\u002Fto\u002Fworkspace\"\n    }\n  ]\n}\n```\n\n### 2.2 完整配置结构\n\n```json\n{\n  \"name\": \"production-node\",\n  \"serverUrl\": \"http:\u002F\u002Fyour-server:9800\",\n  \"token\": \"tok_client_abc123\",\n  \"tags\": [\"code-review\", \"documentation\", \"testing\"],\n  \"dispatchMode\": \"hybrid\",\n  \"polling\": { \"interval\": 10000 },\n  \"heartbeat\": { \"interval\": 30000 },\n  \"ipc\": { \"path\": \"\" },\n  \"autoDispatch\": {\n    \"rules\": [\n      { \"taskTags\": [\"code-review\"], \"targetAgentId\": \"claude-worker\", \"priority\": 10 },\n      { \"taskTags\": [\"documentation\"], \"targetCapabilities\": [\"writing\"], \"priority\": 5 },\n      { \"taskTags\": [\"testing\"], \"targetAgentId\": \"test-worker\", \"priority\": 8 }\n    ],\n    \"fallbackAction\": \"skip\"\n  },\n  \"logging\": {\n    \"dir\": \".\u002Flogs\",\n    \"rotateDaily\": true,\n    \"retainDays\": 30,\n    \"httpLog\": true,\n    \"auditLog\": true,\n    \"agentLog\": true\n  },\n  \"agents\": []\n}\n```\n\n### 2.3 关键字段说明\n\n| 字段 | 必填 | 说明 |\n|------|------|------|\n| `name` | 是 | 节点唯一标识，Server 按此区分客户端 |\n| `serverUrl` | 是 | Server HTTP 地址 |\n| `token` | 启用 auth 时 | Server 分配的 API Token |\n| `tags` | 是 | 节点能处理的任务标签集合 |\n| `dispatchMode` | 是 | 分发策略：`tag-auto` \u002F `manager` \u002F `hybrid` |\n| `autoDispatch.rules` | tag-auto\u002Fhybrid | 按 task tag 匹配 Worker 的规则列表 |\n| `autoDispatch.fallbackAction` | 否 | 无规则匹配时行为：`skip`（默认）\u002F `queue-local` |\n\n### 2.4 分发模式\n\n| 模式 | 工作方式 | 需要 Manager |\n|------|---------|:-----------:|\n| `tag-auto` | 规则引擎按 task tag 匹配 Worker，按 priority 排序 | 否 |\n| `manager` | 每个待分配任务都咨询 Manager Agent，由 AI 决定路由 | 是 |\n| `hybrid` | Manager 在线时用 AI 调度，离线时回退到 tag-auto 规则 | 可选 |\n\n### 2.5 分发规则详解\n\n```json\n{\n  \"taskTags\": [\"backend\", \"api\"],\n  \"targetAgentId\": \"worker-backend\",\n  \"targetCapabilities\": [\"typescript\", \"node\"],\n  \"priority\": 10\n}\n```\n\n| 字段 | 说明 |\n|------|------|\n| `taskTags` | AND 逻辑 — 任务必须包含所有指定 tag 才匹配 |\n| `targetAgentId` | 精确指定 Worker ID |\n| `targetCapabilities` | 按能力匹配 — 选择拥有这些 capabilities 的空闲 Worker |\n| `priority` | 数值越大越优先（多条规则匹配时取最高优先级） |\n\n### 2.6 启动 Client Node\n\n```bash\nnode packages\u002Fclient-node\u002Fdist\u002Fmain.js\n# 或指定配置文件\nDISPATCH_NODE_CONFIG=.\u002Fmy-config.json node packages\u002Fclient-node\u002Fdist\u002Fmain.js\n```\n\nCLI 方式：\n\n```bash\ndispatch start --config .\u002Fclient.config.json\ndispatch start --config .\u002Fclient.config.json --foreground\n```\n\n---\n\n## Part 3: 将 Agent 作为 Worker 挂载（重点）\n\n这是 AgentDispatch 的核心操作——将一个 AI Agent 注册为 Worker，使其能自动接收并执行分发来的任务。\n\n### 3.1 Agent 挂载原理\n\n```\n┌──────────────────────────────────────────────────────────────┐\n│                     Client Node                               │\n│                                                               │\n│  1. Dispatcher 决定: task → worker-01                         │\n│  2. HTTP claim → Server                                       │\n│  3. AcpController.launchAgent():                              │\n│     a. 创建 AgentProcess (spawn 子进程)                        │\n│     b. 注入 DISPATCH_TOKEN + DISPATCH_IPC_PATH                │\n│     c. 通过 stdin\u002Fstdout 建立 ACP JSON-RPC 连接               │\n│     d. 发送 initialize (声明 capabilities)                     │\n│     e. TaskWorkflowRunner 发送 task prompt                    │\n│  4. Worker 执行任务，通过 dispatch CLI 上报进度                  │\n│  5. Worker 完成 → 产物打包 → dispatch worker complete          │\n│  6. AcpController 收集结果 → 上传 Server → 标记 completed      │\n│                                                               │\n│  ┌─────────────────┐  stdio (ACP)  ┌──────────────────┐      │\n│  │  AcpController   │←────────────→│  Worker Process   │      │\n│  │  DispatchAcpClient│              │  (ACP Agent 进程)  │      │\n│  └─────────────────┘               └──────────────────┘      │\n└──────────────────────────────────────────────────────────────┘\n```\n\n### 3.2 AgentConfig 完整字段\n\n每个 Worker 在 `client.config.json` 的 `agents` 数组中注册：\n\n```typescript\ninterface AgentConfig {\n  id: string;                    \u002F\u002F 唯一标识（必填）\n  type: 'manager' | 'worker';   \u002F\u002F 角色（必填）\n  command: string;               \u002F\u002F 启动命令（必填）\n  args?: string[];               \u002F\u002F 额外启动参数\n  workDir: string;               \u002F\u002F 工作目录（必填）\n  capabilities?: string[];       \u002F\u002F 能力标签（用于 dispatch 匹配）\n  autoClaimTags?: string[];      \u002F\u002F 自动认领的任务标签\n  allowMultiProcess?: boolean;   \u002F\u002F 是否允许并行多任务（默认 false）\n  promptTemplate?: string;       \u002F\u002F 自定义 prompt 模板路径\n  acpCapabilities?: {\n    fs?: {\n      readTextFile?: boolean;    \u002F\u002F 允许 Agent 读文件\n      writeTextFile?: boolean;   \u002F\u002F 允许 Agent 写文件\n    };\n    terminal?: boolean;          \u002F\u002F 允许 Agent 使用终端\n  };\n  permissionPolicy?: 'auto-allow' | 'auto-deny' | 'prompt';\n}\n```\n\n### 3.3 关键字段深度说明\n\n#### `command` — Agent 启动命令\n\n第一个 token 是可执行文件，后续 token 是默认参数。`args` 中的参数会追加到末尾。\n\n```json\n{ \"command\": \"claude-agent-acp\", \"args\": [\"--model\", \"sonnet\"] }\n\u002F\u002F 实际执行: claude-agent-acp --model sonnet\n```\n\n**要求**：`command` 启动的进程必须通过 **stdin\u002Fstdout** 进行 ACP 协议通信（JSON-RPC 2.0, newline-delimited JSON）。stderr 用于日志输出，不参与协议。\n\n> **注意**：并非所有 AI Agent CLI 都原生支持 ACP。部分 Agent（如 Claude、Codex）需要通过适配器。\n> 详见 [ACP 兼容 Agent 列表](https:\u002F\u002Fagentclientprotocol.com\u002Fget-started\u002Fagents)。\n\n#### `workDir` — Agent 工作目录\n\nAgent 进程以此目录为 `cwd` 启动。Client Node 会在其中创建：\n\n```\n{workDir}\u002F\n├── .dispatch\u002F\n│   ├── input\u002F{taskIdPrefix}\u002F    ← 下载的任务附件\n│   └── output\u002F{taskIdPrefix}\u002F   ← Agent 应将产物放在这里\n│       ├── artifact.zip         ← 产物压缩包\n│       └── result.json          ← 结构化结果\n└── ... (Agent 自身的文件)\n```\n\n#### `capabilities` — 能力标签\n\n与分发规则的 `targetCapabilities` 配合使用：\n\n```json\n\u002F\u002F 规则: 需要 [\"typescript\", \"testing\"] 能力的 Worker\n{ \"taskTags\": [\"unit-test\"], \"targetCapabilities\": [\"typescript\", \"testing\"] }\n\n\u002F\u002F Worker: 声明自己具备这些能力\n{ \"id\": \"test-bot\", \"capabilities\": [\"typescript\", \"testing\", \"jest\"] }\n\u002F\u002F ✓ 匹配成功（Worker 具备规则要求的所有能力）\n```\n\n#### `acpCapabilities` — ACP 能力声明\n\n在 ACP `initialize` 阶段向 Agent 声明 Client 提供的能力：\n\n```json\n{\n  \"acpCapabilities\": {\n    \"fs\": { \"readTextFile\": true, \"writeTextFile\": true },\n    \"terminal\": true\n  }\n}\n```\n\n| 能力 | 说明 |\n|------|------|\n| `fs.readTextFile` | Agent 可通过 ACP 请求读取 Client 端文件 |\n| `fs.writeTextFile` | Agent 可通过 ACP 请求写入 Client 端文件 |\n| `terminal` | Agent 可通过 ACP 请求执行终端命令 |\n\n#### `permissionPolicy` — 权限策略\n\n当 Agent 通过 ACP 请求使用工具（文件读写、终端）时的审批策略：\n\n| 值 | 行为 |\n|----|------|\n| `auto-allow` | 自动批准所有请求（默认，适合可信 Agent） |\n| `auto-deny` | 自动拒绝所有请求（最安全） |\n| `prompt` | 需要人工审批（当前未完整实现） |\n\n### 3.4 Worker 生命周期\n\n```\n                          Client Node 启动\n                               │\n                    Worker 注册 (config.agents)\n                               │\n                          status: idle\n                               │\n              ┌────────────────▼────────────────┐\n              │   Dispatcher 匹配到合适的任务     │\n              │   HTTP claim → Server             │\n              └────────────────┬────────────────┘\n                               │\n              ┌────────────────▼────────────────┐\n              │   AcpController.launchAgent()    │\n              │   1. spawn(command, {cwd:workDir})│\n              │   2. env += DISPATCH_TOKEN        │\n              │   3. env += DISPATCH_IPC_PATH     │\n              │   4. ACP initialize()             │\n              │   5. ACP prompt(taskContent)       │\n              └────────────────┬────────────────┘\n                               │\n                        status: busy\n                               │\n              ┌────────────────▼────────────────┐\n              │  Worker 执行任务                   │\n              │  - dispatch worker progress ...   │\n              │  - dispatch worker log ...        │\n              │  - 产出 artifact.zip + result.json │\n              │  - dispatch worker complete ...   │\n              └────────────────┬────────────────┘\n                               │\n                   ┌───────────┴───────────┐\n                   ▼                       ▼\n            完成 (completed)         失败 (failed)\n                   │                       │\n            status: idle             auto restart?\n                   │                  (指数退避)\n                   ▼                       │\n            等待下一个任务              status: idle\n```\n\n#### 进程环境变量注入\n\nWorker 进程启动时自动获得两个关键环境变量：\n\n| 变量 | 值 | 用途 |\n|------|-----|------|\n| `DISPATCH_TOKEN` | `wt_\u003Cuuid>` | 临时 Worker Token，仅在本次任务生命周期内有效，任务结束自动撤销 |\n| `DISPATCH_IPC_PATH` | Unix socket \u002F named pipe 路径 | 连接 Client Node IPC Server，用于 `dispatch` CLI 通信 |\n\n#### 自动重启机制\n\nWorker 进程异常退出时（exit code ≠ 0）：\n\n1. 状态标记为 `crashed`\n2. 如有正在执行的任务，自动释放回 `pending`\n3. 如重启次数未超限（默认 3 次），启用指数退避重启：\n   - 第 1 次: 2 秒后\n   - 第 2 次: 4 秒后\n   - 第 3 次: 8 秒后（上限 30 秒）\n4. 重启后状态回到 `idle`，可继续接收新任务\n\n### 3.5 Worker 通过 CLI 与系统交互\n\nWorker 在任务执行过程中使用 `dispatch` CLI：\n\n```bash\n# 上报进度（首次上报触发 claimed → in_progress 转换）\ndispatch worker progress \u003CtaskId> --percent 30 --message \"分析代码中...\"\n\n# 追加工作日志\ndispatch worker log \u003CtaskId> --message \"发现 3 个潜在安全问题\"\n\n# 完成任务（提交产物）\ndispatch worker complete \u003CtaskId> \\\n  --zip .\u002Foutput\u002Fartifact.zip \\\n  --result .\u002Foutput\u002Fresult.json\n\n# 报告失败\ndispatch worker fail \u003CtaskId> --reason \"无法访问代码仓库\"\n\n# 查询当前任务状态\ndispatch worker status \u003CtaskId>\n\n# 心跳（长时间无进度更新时使用）\ndispatch worker heartbeat \u003CtaskId>\n```\n\n### 3.6 ACP 任务分发流程\n\nClient Node 通过 ACP 向 Worker 发送任务时，使用 **TaskWorkflowRunner** 执行多轮对话：\n\n**Pass 1: InitialTaskPass** — 构建任务 prompt，包含：\n- 任务标题、描述、优先级、标签、元数据\n- 附件路径（如有下载）\n- 产物输出目录和格式要求\n- CLI 命令参考\n\n**Pass 2: ArtifactEnforcementPass** — 任务完成后检查产物：\n- 验证 `artifact.zip` 和 `result.json` 是否存在\n- 如产物缺失，向 Agent 发送补救 prompt，要求补充\n- 最终验证通过后才标记任务完成\n\n---\n\n## Part 4: 挂载不同类型的 Agent\n\n> **前提**：并非所有 AI Agent CLI 都原生支持 ACP 协议。部分需要通过**适配器**桥接。\n> 完整列表参见 [ACP 兼容 Agent](https:\u002F\u002Fagentclientprotocol.com\u002Fget-started\u002Fagents)。\n\n### 4.0 ACP 兼容 Agent 参考表\n\n| Agent | ACP 支持 | command | args | 安装方式 |\n|-------|---------|---------|------|---------|\n| **Claude Agent** | 适配器 | `claude-agent-acp` | — | `npm i -g @zed-industries\u002Fclaude-agent-acp` |\n| **Codex CLI** | 适配器 | `codex-acp` | — | `npm i -g @zed-industries\u002Fcodex-acp` |\n| **Gemini CLI** | 原生 | `gemini` | `[\"--experimental-acp\"]` | `npm i -g @google\u002Fgemini-cli` |\n| **Goose** | 原生 | `goose` | `[\"acp\"]` | [block.github.io\u002Fgoose](https:\u002F\u002Fblock.github.io\u002Fgoose\u002Fdocs\u002Fguides\u002Facp-clients) |\n| **OpenCode** | 原生 | `opencode` | `[\"acp\"]` | [open-code.ai](https:\u002F\u002Fopen-code.ai\u002Fdocs\u002Fen\u002Facp) |\n| **Kiro CLI** | 原生 | `kiro` | `[\"acp\"]` | [kiro.dev\u002Fcli](https:\u002F\u002Fkiro.dev\u002Fcli\u002F) |\n| **Kimi CLI** | 原生 | `kimi` | `[\"acp\"]` | [github.com\u002FMoonshotAI\u002Fkimi-cli](https:\u002F\u002Fgithub.com\u002FMoonshotAI\u002Fkimi-cli) |\n| **Augment Code** | 原生 | `auggie` | `[\"--acp\"]` | [docs.augmentcode.com\u002Fcli\u002Facp](https:\u002F\u002Fdocs.augmentcode.com\u002Fcli\u002Facp\u002Fagent) |\n| **Cline** | 原生 | `cline` | `[\"--acp\"]` | [docs.cline.bot](https:\u002F\u002Fdocs.cline.bot\u002Fcline-cli\u002Facp-editor-integrations) |\n| **Qwen Code** | 原生 | `qwen` | `[\"--acp\"]` | `npm i -g @qwen-code\u002Fqwen-code` |\n| **Mistral Vibe** | 原生 | `vibe-acp` | — | [github.com\u002Fmistralai\u002Fmistral-vibe](https:\u002F\u002Fgithub.com\u002Fmistralai\u002Fmistral-vibe\u002Fblob\u002Fmain\u002Fdocs\u002Facp-setup.md) |\n| **OpenHands** | 原生 | `openhands` | `[\"acp\"]` | [docs.openhands.dev](https:\u002F\u002Fdocs.openhands.dev\u002Fopenhands\u002Fusage\u002Frun-openhands\u002Facp) |\n| **GitHub Copilot** | 公测 | — | — | [github.com\u002Ffeatures\u002Fcopilot](https:\u002F\u002Fgithub.com\u002Ffeatures\u002Fcopilot) |\n| **Pi** | 适配器 | `pi-acp` | — | [github.com\u002Fsvkozak\u002Fpi-acp](https:\u002F\u002Fgithub.com\u002Fsvkozak\u002Fpi-acp) |\n| 自定义 Agent | 需自行实现 | `node .\u002Fagent.mjs` | — | 使用 ACP SDK（TypeScript\u002FPython\u002FRust\u002FKotlin） |\n\n> **重要**：很多 Agent CLI 的\"普通模式\"是交互式终端，不等于 ACP 模式。必须使用上表中对应的 `args` 参数才能进入 ACP stdio 通信模式。\n\nACP SDK 库：\n- TypeScript: `@anthropic-ai\u002Fagent-client-protocol` — [文档](https:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Ftypescript)\n- Python: `agent-client-protocol` — [文档](https:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Fpython)\n- Rust: — [文档](https:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Frust)\n- Kotlin: — [文档](https:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Fkotlin)\n\n### 4.1 挂载 Claude Agent\n\nClaude Code **不原生支持 ACP**，需通过 Zed 官方的 [`claude-agent-acp`](https:\u002F\u002Fgithub.com\u002Fzed-industries\u002Fclaude-agent-acp) 适配器桥接。\n\n**安装适配器**：\n\n```bash\nnpm install -g @zed-industries\u002Fclaude-agent-acp\n```\n\n**配置**：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"claude-reviewer\",\n      \"type\": \"worker\",\n      \"command\": \"claude-agent-acp\",\n      \"args\": [\"--model\", \"sonnet\"],\n      \"workDir\": \"\u002Fworkspace\u002Fclaude-reviewer\",\n      \"capabilities\": [\"code-review\", \"security-audit\", \"typescript\"],\n      \"acpCapabilities\": {\n        \"fs\": { \"readTextFile\": true, \"writeTextFile\": true },\n        \"terminal\": true\n      },\n      \"permissionPolicy\": \"auto-allow\"\n    }\n  ]\n}\n```\n\n> 适配器通过 Claude Agent SDK 调用 Claude，需要设置 `ANTHROPIC_API_KEY` 环境变量。\n> 也可下载[预编译二进制](https:\u002F\u002Fgithub.com\u002Fzed-industries\u002Fclaude-agent-acp\u002Freleases)，无需 Node.js。\n\n### 4.2 挂载 Codex Agent\n\nOpenAI Codex CLI 同样需通过 [`codex-acp`](https:\u002F\u002Fgithub.com\u002Fzed-industries\u002Fcodex-acp) 适配器：\n\n```bash\nnpm install -g @zed-industries\u002Fcodex-acp\n```\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"codex-worker\",\n      \"type\": \"worker\",\n      \"command\": \"codex-acp\",\n      \"workDir\": \"\u002Fworkspace\u002Fcodex-worker\",\n      \"capabilities\": [\"code-generation\", \"refactor\"],\n      \"permissionPolicy\": \"auto-allow\"\n    }\n  ]\n}\n```\n\n> 需要设置 `OPENAI_API_KEY` 或 `CODEX_API_KEY` 环境变量。\n\n### 4.3 挂载原生 ACP Agent（Gemini、Goose、OpenCode 等）\n\n部分 Agent CLI 内置 ACP 协议支持，但通常需要特定的子命令或标志才能进入 ACP 模式（而非交互终端模式）。\n\n**Gemini CLI**（需 `--experimental-acp` 标志）：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"gemini-worker\",\n      \"type\": \"worker\",\n      \"command\": \"gemini\",\n      \"args\": [\"--experimental-acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Fgemini-worker\",\n      \"capabilities\": [\"code-generation\", \"analysis\"],\n      \"permissionPolicy\": \"auto-allow\"\n    }\n  ]\n}\n```\n\n**Goose**（需 `acp` 子命令）：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"goose-worker\",\n      \"type\": \"worker\",\n      \"command\": \"goose\",\n      \"args\": [\"acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Fgoose-worker\",\n      \"capabilities\": [\"general\"],\n      \"permissionPolicy\": \"auto-allow\"\n    }\n  ]\n}\n```\n\n**OpenCode**（需 `acp` 子命令）：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"opencode-worker\",\n      \"type\": \"worker\",\n      \"command\": \"opencode\",\n      \"args\": [\"acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Fopencode-worker\",\n      \"capabilities\": [\"code-generation\", \"refactor\"]\n    }\n  ]\n}\n```\n\n### 4.4 挂载自定义 ACP Agent\n\n任何实现了 ACP 协议的程序都可以作为 Worker。ACP 协议要求：\n\n- 通过 **stdin** 接收 JSON-RPC 2.0 消息（换行分隔 NDJSON）\n- 通过 **stdout** 发送 JSON-RPC 2.0 响应（换行分隔 NDJSON）\n- stderr 用于日志（不参与协议通信）\n\n**Python ACP Agent 示例**：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"python-analyzer\",\n      \"type\": \"worker\",\n      \"command\": \"python\",\n      \"args\": [\".\u002Fmy_agent.py\"],\n      \"workDir\": \"\u002Fworkspace\u002Fpython-agent\",\n      \"capabilities\": [\"data-analysis\", \"python\"],\n      \"acpCapabilities\": {\n        \"fs\": { \"readTextFile\": true }\n      }\n    }\n  ]\n}\n```\n\n**Node.js ACP Agent**：\n\n```json\n{\n  \"agents\": [\n    {\n      \"id\": \"node-agent\",\n      \"type\": \"worker\",\n      \"command\": \"node\",\n      \"args\": [\".\u002Fagent.mjs\"],\n      \"workDir\": \"\u002Fworkspace\u002Fnode-agent\",\n      \"capabilities\": [\"web-scraping\", \"api-testing\"]\n    }\n  ]\n}\n```\n\n### 4.5 挂载 Manager Agent（调度顾问）\n\nManager Agent 不执行任务，而是为 Client Node 提供分发建议：\n\n```json\n{\n  \"dispatchMode\": \"manager\",\n  \"agents\": [\n    {\n      \"id\": \"dispatch-manager\",\n      \"type\": \"manager\",\n      \"command\": \"claude-agent-acp\",\n      \"workDir\": \"\u002Fworkspace\u002Fmanager\",\n      \"acpCapabilities\": {\n        \"fs\": { \"readTextFile\": true, \"writeTextFile\": false },\n        \"terminal\": false\n      }\n    },\n    {\n      \"id\": \"worker-backend\",\n      \"type\": \"worker\",\n      \"command\": \"claude-agent-acp\",\n      \"workDir\": \"\u002Fworkspace\u002Fbackend\",\n      \"capabilities\": [\"backend\", \"api\", \"database\"]\n    },\n    {\n      \"id\": \"worker-frontend\",\n      \"type\": \"worker\",\n      \"command\": \"gemini\",\n      \"args\": [\"--experimental-acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Ffrontend\",\n      \"capabilities\": [\"frontend\", \"react\", \"css\"]\n    }\n  ]\n}\n```\n\nManager 收到的咨询 prompt 包含：任务信息 + 所有可用 Worker 的 ID、能力和状态。Manager 返回 JSON 格式的 `DispatchAdvice`：\n\n```json\n{\n  \"recommendedAgentId\": \"worker-backend\",\n  \"confidence\": 0.9,\n  \"reason\": \"This task involves API endpoint implementation, best suited for the backend worker.\"\n}\n```\n\n### 4.6 多 Worker 集群配置\n\n一个 Client Node 可以挂载多个 Worker，形成专业化分工。不同 Worker 可以使用不同的 Agent：\n\n```json\n{\n  \"name\": \"team-alpha\",\n  \"serverUrl\": \"http:\u002F\u002Fdispatch-server:9800\",\n  \"token\": \"tok_team_alpha\",\n  \"tags\": [\"code-review\", \"testing\", \"docs\", \"refactor\"],\n  \"dispatchMode\": \"hybrid\",\n  \"autoDispatch\": {\n    \"rules\": [\n      { \"taskTags\": [\"code-review\"], \"targetAgentId\": \"reviewer\", \"priority\": 10 },\n      { \"taskTags\": [\"testing\"], \"targetAgentId\": \"tester\", \"priority\": 10 },\n      { \"taskTags\": [\"docs\"], \"targetAgentId\": \"writer\", \"priority\": 5 },\n      { \"taskTags\": [\"refactor\"], \"targetCapabilities\": [\"typescript\"], \"priority\": 8 }\n    ],\n    \"fallbackAction\": \"skip\"\n  },\n  \"agents\": [\n    {\n      \"id\": \"manager\",\n      \"type\": \"manager\",\n      \"command\": \"claude-agent-acp\",\n      \"workDir\": \"\u002Fworkspace\u002Fmanager\"\n    },\n    {\n      \"id\": \"reviewer\",\n      \"type\": \"worker\",\n      \"command\": \"claude-agent-acp\",\n      \"workDir\": \"\u002Fworkspace\u002Freviewer\",\n      \"capabilities\": [\"code-review\", \"security\", \"typescript\", \"python\"]\n    },\n    {\n      \"id\": \"tester\",\n      \"type\": \"worker\",\n      \"command\": \"gemini\",\n      \"args\": [\"--experimental-acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Ftester\",\n      \"capabilities\": [\"testing\", \"typescript\", \"jest\", \"playwright\"]\n    },\n    {\n      \"id\": \"writer\",\n      \"type\": \"worker\",\n      \"command\": \"goose\",\n      \"args\": [\"acp\"],\n      \"workDir\": \"\u002Fworkspace\u002Fwriter\",\n      \"capabilities\": [\"writing\", \"documentation\", \"markdown\"]\n    }\n  ]\n}\n```\n\n### 4.7 Worker 挂载检查清单\n\n挂载新 Worker 前确认以下事项：\n\n| 检查项 | 说明 |\n|--------|------|\n| Agent 支持 ACP 协议 | 原生支持或已安装适配器（参见 4.0 参考表） |\n| `command` 可直接执行 | 在 shell 中运行 `command` 能成功启动（已 `npm i -g` 或在 PATH 中） |\n| API Key 已配置 | 如 `ANTHROPIC_API_KEY`、`OPENAI_API_KEY` 等环境变量已设置 |\n| `workDir` 存在且有写权限 | Client Node 需要在其中创建 `.dispatch\u002F` 目录 |\n| `id` 全局唯一 | 同一 Client Node 下所有 Agent ID 不能重复 |\n| `capabilities` 与规则匹配 | 至少有一条 `autoDispatch.rules` 能路由到此 Worker |\n| 网络可达 | Worker 能通过 IPC 路径连接 Client Node |\n\n---\n\n## Part 5: 提交任务并监听状态\n\n### 5.1 创建任务\n\n**JSON 请求**：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer tok_client_abc123\" \\\n  -d '{\n    \"title\": \"Review PR #42\",\n    \"description\": \"Review the pull request for security issues and code quality.\",\n    \"tags\": [\"code-review\"],\n    \"priority\": \"high\",\n    \"metadata\": { \"repo\": \"my-org\u002Fmy-repo\", \"pr\": 42 }\n  }'\n```\n\n**带附件（multipart）**：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks \\\n  -H \"Authorization: Bearer tok_client_abc123\" \\\n  -F 'data={\"title\":\"Analyze dataset\",\"tags\":[\"data-analysis\"],\"priority\":\"normal\"}' \\\n  -F 'files=@.\u002Fdataset.csv' \\\n  -F 'files=@.\u002Fconfig.yaml'\n```\n\n### 5.2 查询任务\n\n```bash\ncurl http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks                  # 所有活跃任务\ncurl \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks?status=pending\"  # 按状态\ncurl \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks?tag=code-review\" # 按标签\ncurl \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks?page=1&limit=10\" # 分页\ncurl http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\u002F{taskId}          # 单个任务\n```\n\n### 5.3 SSE 流式监听（推荐）\n\n```bash\ncurl -N \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\u002F{taskId}\u002Fstream?interval=1000&logs=true\"\n```\n\n| 事件 | 说明 | 数据 |\n|------|------|------|\n| `task` | 状态\u002F进度变化 | `{ id, status, progress, progressMessage, claimedBy, updatedAt }` |\n| `logs` | 新交互日志 | `InteractionLogEntry[]` |\n| `done` | 到达终态 | `{ taskId, finalStatus }` |\n| `error` | 轮询出错 | `{ message }` |\n\n**TypeScript 示例**：\n\n```typescript\nfunction watchTask(serverUrl: string, taskId: string): Promise\u003Cstring> {\n  return new Promise((resolve, reject) => {\n    const url = `${serverUrl}\u002Fapi\u002Fv1\u002Ftasks\u002F${taskId}\u002Fstream?interval=1000&logs=true`;\n    const es = new EventSource(url);\n\n    es.addEventListener('task', (e) => {\n      const data = JSON.parse(e.data);\n      console.log(`[${data.status}] ${data.progressMessage ?? ''}`);\n    });\n\n    es.addEventListener('logs', (e) => {\n      for (const entry of JSON.parse(e.data)) {\n        console.log(`  [${entry.type}] ${entry.content.slice(0, 80)}`);\n      }\n    });\n\n    es.addEventListener('done', (e) => {\n      const data = JSON.parse(e.data);\n      es.close();\n      resolve(data.finalStatus);\n    });\n\n    es.addEventListener('error', () => { es.close(); reject(new Error('SSE error')); });\n  });\n}\n```\n\n---\n\n## Part 6: 任务状态机\n\n```\npending ──→ claimed ──→ in_progress ──→ completed\n   │                        │\n   │                        └──→ failed ──→ (release) ──→ pending\n   │\n   └──→ cancelled\n```\n\n| 状态 | 触发 | 说明 |\n|------|------|------|\n| `pending` | 创建任务 \u002F release | 等待被领取 |\n| `claimed` | Worker claim | 已分配给 Worker，尚未开始 |\n| `in_progress` | 首次 progress 上报 | 正在执行中 |\n| `completed` | 产物上传成功 | 终态 |\n| `failed` | Worker 报告失败 | 可通过 release 回到 pending |\n| `cancelled` | 手动取消 | 终态 |\n\n---\n\n## Part 7: Token 鉴权\n\n| 角色 | 用途 | 权限 |\n|------|------|------|\n| `admin` | Dashboard 登录 | 完全权限 |\n| `client` | Client Node \u002F Worker | 完全权限（包括 claim\u002Fcomplete） |\n| `operator` | 外部集成 | 创建\u002F删除\u002F查看任务；**禁止** claim\u002Frelease\u002Fprogress\u002Fcomplete\u002Fcancel |\n\n```bash\n# 登录获取 session token\ncurl -X POST http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Fauth\u002Flogin \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"username\":\"admin\",\"password\":\"your-password\"}'\n\n# 使用 static token\ncurl -H \"Authorization: Bearer tok_client_abc123\" http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\n```\n\n---\n\n## Part 8: 端到端示例\n\n### 8.1 最简单的完整流程\n\n```bash\n#!\u002Fbin\u002Fbash\n# 1. 启动 Server\nDISPATCH_DATA_DIR=\u002Ftmp\u002Fdispatch-demo node packages\u002Fserver\u002Fdist\u002Findex.js &\nsleep 2\n\n# 2. 提交任务\nTASK_ID=$(curl -s -X POST http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"title\":\"Demo\",\"tags\":[\"demo\"],\"priority\":\"normal\"}' | jq -r '.id')\necho \"Task: $TASK_ID\"\n\n# 3. 监听（后台）\ncurl -sN \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\u002F$TASK_ID\u002Fstream?interval=1000\" &\n\n# 4. 模拟 Worker: claim → progress → complete\ncurl -s -X POST \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\u002F$TASK_ID\u002Fclaim\" \\\n  -H \"Content-Type: application\u002Fjson\" -d '{\"clientId\":\"node-01\",\"agentId\":\"worker-01\"}'\n\ncurl -s -X POST \"http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks\u002F$TASK_ID\u002Fprogress\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"clientId\":\"node-01\",\"agentId\":\"worker-01\",\"progress\":50,\"message\":\"Working...\"}'\n\n# 5. 清理\nkill %2 2>\u002Fdev\u002Fnull; kill %1 2>\u002Fdev\u002Fnull\n```\n\n### 8.2 单 Worker 自动化完整部署\n\n```bash\n#!\u002Fbin\u002Fbash\n# 1. 启动 Server\nDISPATCH_DATA_DIR=.\u002Fdata node packages\u002Fserver\u002Fdist\u002Findex.js &\nsleep 2\n\n# 2. 安装 ACP 适配器（以 Claude 为例；若用 Gemini 等原生 ACP Agent 可跳过）\nnpm install -g @zed-industries\u002Fclaude-agent-acp\n\n# 3. 准备 Worker 工作目录\nmkdir -p \u002Fworkspace\u002Fclaude-worker\n\n# 4. 创建 client.config.json\ncat > client.config.json \u003C\u003CEOF\n{\n  \"name\": \"single-worker-node\",\n  \"serverUrl\": \"http:\u002F\u002Flocalhost:9800\",\n  \"tags\": [\"general\"],\n  \"dispatchMode\": \"tag-auto\",\n  \"autoDispatch\": {\n    \"rules\": [{ \"taskTags\": [\"general\"], \"targetAgentId\": \"claude\", \"priority\": 1 }]\n  },\n  \"agents\": [{\n    \"id\": \"claude\",\n    \"type\": \"worker\",\n    \"command\": \"claude-agent-acp\",\n    \"workDir\": \"\u002Fworkspace\u002Fclaude-worker\",\n    \"capabilities\": [\"general\"],\n    \"acpCapabilities\": { \"fs\": { \"readTextFile\": true, \"writeTextFile\": true }, \"terminal\": true },\n    \"permissionPolicy\": \"auto-allow\"\n  }]\n}\nEOF\n\n# 5. 启动 Client Node（Worker 自动就绪）\nnode packages\u002Fclient-node\u002Fdist\u002Fmain.js &\nsleep 3\n\n# 6. 提交任务 → Worker 自动领取并执行\ncurl -X POST http:\u002F\u002Flocalhost:9800\u002Fapi\u002Fv1\u002Ftasks \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"title\":\"Write unit tests for auth module\",\"tags\":[\"general\"],\"priority\":\"normal\"}'\n\necho \"Task submitted. Worker will pick it up automatically.\"\n```\n\n---\n\n## Part 9: 生产部署注意事项\n\n部署 AgentDispatch 到远程服务器时，请注意以下关键事项。完整详情和排查步骤参见 [故障排查指南](..\u002F..\u002Fdocs\u002Fguide\u002Ftroubleshooting.md)。\n\n| 主题 | 要点 |\n|------|------|\n| **进程管理** | 使用 pm2 \u002F systemd \u002F Docker，避免 `nohup` |\n| **远程 Dashboard** | 设置 `VITE_API_URL=http:\u002F\u002F\u003Cserver-ip>:9800`；详见 [配置指南](..\u002F..\u002Fdocs\u002Fguide\u002Fconfiguration.md#dashboard-远程访问) |\n| **嵌套 Claude 会话** | 用包装脚本 `unset CLAUDECODE` 后再启动 Worker |\n| **inotify（Linux）** | 增加 `max_user_instances` 到 8192+ |\n| **CORS** | Server 已内置支持；反向代理不要重复添加 CORS 头 |\n| **部署检查清单** | 见 [troubleshooting.md — Deployment Checklist](..\u002F..\u002Fdocs\u002Fguide\u002Ftroubleshooting.md#deployment-checklist) |\n\n---\n\n## REST API 快速参考\n\n### 任务管理\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks` | 创建任务 |\n| `GET` | `\u002Fapi\u002Fv1\u002Ftasks` | 列出活跃任务（?status=&tag=&page=&limit=） |\n| `GET` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id` | 获取单个任务 |\n| `PATCH` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id` | 更新任务 |\n| `DELETE` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id` | 删除任务 |\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Fclaim` | 领取任务 |\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Frelease` | 释放任务 |\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Fprogress` | 上报进度 |\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Fcomplete` | 完成任务（multipart） |\n| `POST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Fcancel` | 取消任务 |\n| `GET` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Fstream` | SSE 流式监听 |\n| `GET\u002FPOST` | `\u002Fapi\u002Fv1\u002Ftasks\u002F:id\u002Flogs` | 交互日志 |\n\n### 客户端管理\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `POST` | `\u002Fapi\u002Fv1\u002Fclients\u002Fregister` | 注册 |\n| `GET` | `\u002Fapi\u002Fv1\u002Fclients` | 列表 |\n| `GET` | `\u002Fapi\u002Fv1\u002Fclients\u002F:id` | 详情 |\n| `DELETE` | `\u002Fapi\u002Fv1\u002Fclients\u002F:id` | 注销 |\n| `POST` | `\u002Fapi\u002Fv1\u002Fclients\u002F:id\u002Fheartbeat` | 心跳 |\n\n### 鉴权\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `POST` | `\u002Fapi\u002Fv1\u002Fauth\u002Flogin` | 登录 |\n| `POST` | `\u002Fapi\u002Fv1\u002Fauth\u002Flogout` | 登出 |\n| `GET` | `\u002Fapi\u002Fv1\u002Fauth\u002Fme` | 验证 Token |\n| `GET` | `\u002Fhealth` | 健康检查（无需鉴权） |\n\n---\n\n## 常见错误码\n\n| 错误码 | HTTP | 说明 |\n|--------|------|------|\n| `TASK_NOT_FOUND` | 404 | 任务不存在 |\n| `TASK_ALREADY_CLAIMED` | 409 | 任务已被其他 Worker 领取，或非 owner 操作 |\n| `TASK_INVALID_TRANSITION` | 400 | 当前状态不允许此操作 |\n| `UNAUTHORIZED` | 401 | Token 缺失或无效 |\n| `FORBIDDEN` | 403 | 角色权限不足 |\n| `VALIDATION_ERROR` | 400 | 请求参数校验失败 |\n| `ARTIFACT_MISSING_ZIP` | 400 | 完成任务时缺少 zip |\n| `ARTIFACT_MISSING_RESULT` | 400 | 完成任务时缺少 result.json |\n\n---\n\n## 数据目录结构\n\n```\n{dataDir}\u002F\n├── tasks\u002F           # 活跃任务 (.json + .md)\n├── tasks-archive\u002F   # 归档任务\n├── attachments\u002F     # 任务输入附件\n├── artifacts\u002F       # 任务产物 (zip + result.json)\n├── clients\u002F         # 客户端注册信息\n└── logs\u002F\n    ├── tasks\u002F       # 按任务 ID 的交互日志 (.jsonl)\n    ├── clients\u002F     # 按客户端 ID 的日志\n    └── server-*.jsonl  # Server 主日志\n```\n",{"name":5,"license":14,"description":7,"allowed-tools":48},"Shell, Read, Write, Glob, Grep","master","3a92278a00caef2314e2008a9f50b810363a3d86",".agents\u002Fskills\u002Fagent-dispatch-use","https:\u002F\u002Fgithub.com\u002Fblackplume233\u002FAgentDispatch","https:\u002F\u002Fgithub.com\u002Fblackplume233","2026-03-03 22:11:55",{"source":8,"skillName":5,"commands":56,"prompt":66,"zipAvailable":67},[57,60,63],{"tool":58,"command":59},"npx","npx skills add blackplume233\u002FAgentDispatch --skill agent-dispatch-use",{"tool":61,"command":62},"bunx","bunx skills add blackplume233\u002FAgentDispatch --skill agent-dispatch-use",{"tool":64,"command":65},"pnpm","pnpm dlx skills add blackplume233\u002FAgentDispatch --skill agent-dispatch-use","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fblackplume233\u002FAgentDispatch\u002Fblob\u002Fmaster\u002F.agents\u002Fskills\u002Fagent-dispatch-use\u002FSKILL.md",true,[],[70,91,107,120,136,150],{"skillNo":71,"name":72,"nameZh":6,"description":73,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":79,"publishedAt":43},"01M6CW3A862TC4XFPS14SVG8M3","qa-monitor","QA 持续监测 SubAgent。监听 git HEAD 变化，每有新 ship（commit）自动触发完整回归测试，无变化时进入可配置间隔的休眠轮询。触发方式：用户提及 \"\u002Fqa-watch\"、\"QA 监测\"、\"continuous QA\"、\"watch ship\" 等关键词时激活。","https:\u002F\u002Fgithub.com\u002Fblackplume233\u002FAgentDispatch\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fqa-monitor\u002FSKILL.md",[76],{"categoryNo":77,"categoryName":78,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量",[80,81,82,83,84,85,40,86,87,29,34,32,31,88,89,90],"monitor","qa","qa monitor","testing","commit","git","ship","subagent","engineer","issue","task",{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":99,"publishedAt":43},"01M6CW36KDT33XESRJE4EQZEZ3","qa-engineer","QA 测试工程师 SubAgent。模拟真实用户通过 CLI\u002FREST API 与 AgentDispatch 交互，智能判断输出和产物是否合理，黑盒为主白盒为辅，发现问题自动创建 Issue。触发方式：用户提及 \"\u002Fqa\"、\"QA run\"、\"QA test\"、\"运行测试场景\" 等关键词时激活。","https:\u002F\u002Fgithub.com\u002Fblackplume233\u002FAgentDispatch\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fqa-engineer\u002FSKILL.md",[97,98],{"categoryNo":77,"categoryName":78,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},[81,88,100,83,101,102,103,104,105,40,106,87,29,34,32,31,89,90],"qa engineer","cli","test","run","REST","api","qa test",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":113,"publishedAt":43},"01M6CW34K4423W6Z48RE8SP860","pr-watcher","PR 轮询守护 SubAgent。持续监控 GitHub 上的 Open PR，自动调用 pr-handler 逐一处理，连续 N 轮无新可处理 PR 后退出。触发方式：用户提及 \"\u002Fwatch-prs\"、\"轮询 PR\"、\"watch prs\" 等关键词时激活。","https:\u002F\u002Fgithub.com\u002Fblackplume233\u002FAgentDispatch\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fpr-watcher\u002FSKILL.md",[],[114,115,116,117,40,118,87,119,29,34,32,31,90],"pr","pr watcher","github","open pr","open","连续",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":43},"01M6CW321GNCF2EKY9NQC2WJ9S","pr-handler","PR Gatekeeper SubAgent。自动化处理 Multi-Agent Pipeline 产出的 Draft PR：验证代码质量 → 本地合并 → 更新 Spec → Ship 交付。触发方式：用户提及 \"\u002Fhandle-pr\"、\"处理 PR\"、\"review pr\"、\"合并 PR\" 等关键词时激活。","https:\u002F\u002Fgithub.com\u002Fblackplume233\u002FAgentDispatch\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fpr-handler\u002FSKILL.md",[],[114,127,128,129,130,131,132,40,86,87,29,133,34,134,32,31,89,90,135],"pr handler","review","spec","review pr","pipeline","gatekeeper","multi-agent","draft pr","draft",{"skillNo":137,"name":138,"nameZh":6,"description":139,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":140,"categories":141,"keywords":142,"publishedAt":43},"01M6CW2ZQTW1TV0CMSVAKQ7B9S","issue-manager","GitHub-first Issue 管理 SubAgent。Issue 编号和内容以 GitHub Issues 为准，本地 .trellis\u002Fissues\u002F 为 Obsidian 兼容缓存。触发方式：用户提及 \"\u002Fissue\"、\"创建 issue\"、\"create issue\"、\"新建问题\"、\"提 bug\" 等关键词时激活。","https:\u002F\u002Fgithub.com\u002Fblackplume233\u002FAgentDispatch\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fissue-manager\u002FSKILL.md",[],[89,143,116,144,145,146,147,148,40,87,29,34,32,31,149],"issue manager","obsidian","create","github issues","issues","first","bug",{"skillNo":151,"name":152,"nameZh":6,"description":153,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":154,"categories":155,"keywords":156,"publishedAt":43},"01M6CW2WXEYST8AVQWP3BM0B43","git-commit","Execute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions \"\u002Fcommit\". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type\u002Fscope\u002Fdescription overrides, (4) Intelligent file staging for logical grouping","https:\u002F\u002Fgithub.com\u002Fblackplume233\u002FAgentDispatch\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fgit-commit\u002FSKILL.md",[],[84,157,85,145,158,159,160,161,162,163,164,165,166,167,28,168,169,170,171,172],"git commit","commit message","file","messages","conventional commit","analysis","Bash","commit messages","interactive","user","execute","diff","auto","commit changes","grouping","message"]