[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CW1RY53NTVRCJRK0SWGWRB":3,"skill-same:01M6CW1RY53NTVRCJRK0SWGWRB":62},{"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":22,"publishedAt":36,"linkOnly":37,"markdownContent":38,"markdownBody":39,"frontMatter":40,"refName":42,"commitSha":43,"skillDirectory":44,"forksCount":13,"repositoryHtmlUrl":45,"repositoryHomepageUrl":6,"ownerHtmlUrl":46,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":47,"install":48,"resources":61},"01M6CW1RY53NTVRCJRK0SWGWRB","acp-dev-guide",null,"ACP (Agent Client Protocol) 开发指南。提供协议规范、SDK 接口、Agent 兼容性等完整参考，指导开发者实现 ACP Agent 或 Client。触发方式：用户提及 \"\u002Facp-dev\"、\"ACP 开发\"、\"实现 ACP Agent\"、\"ACP SDK\"、\"Agent Client Protocol\" 等关键词时激活。","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\u002Facp-dev-guide\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[23,24,25,26,27,28,29,30,31,32,33,34,35],"acp","dev","guide","acp dev guide","sdk","agent client protocol","protocol","shell","关键词","grep","read","write","webfetch","2026-11-10 10:12:30",false,"---\nname: acp-dev-guide\ndescription: 'ACP (Agent Client Protocol) 开发指南。提供协议规范、SDK 接口、Agent 兼容性等完整参考，指导开发者实现 ACP Agent 或 Client。触发方式：用户提及 \"\u002Facp-dev\"、\"ACP 开发\"、\"实现 ACP Agent\"、\"ACP SDK\"、\"Agent Client Protocol\" 等关键词时激活。'\nlicense: MIT\nallowed-tools: Shell, Read, Write, Glob, Grep, WebFetch\n---\n\n# ACP (Agent Client Protocol) 开发指南\n\n## 1. 协议概述\n\nACP 是一个标准化协议，定义了 **Client**（代码编辑器\u002FIDE）与 **Agent**（AI 编码助手）之间的通信方式。类似于 LSP 对语言服务器的标准化作用，ACP 让任何兼容的 Agent 都能接入任何兼容的 Client。\n\n**协议特性**：\n- 基于 **JSON-RPC 2.0**\n- 传输层：**stdio**（主要）、Streamable HTTP（草案）\n- 消息类型：Method（请求-响应）、Notification（单向通知）\n- 所有文件路径必须是**绝对路径**，行号从 **1** 开始\n\n**角色定义**：\n\n| 角色 | 职责 | 示例 |\n|------|------|------|\n| **Client** | 管理环境、处理用户交互、控制资源访问 | Zed、JetBrains IDE、VS Code、Neovim、AgentDispatch ClientNode |\n| **Agent** | 使用 AI 自主修改代码，通常作为 Client 的子进程运行 | Claude Agent、Gemini CLI、Goose、自定义 Agent |\n\n---\n\n## 2. 官方文档与资源\n\n### 2.1 核心文档\n\n| 文档 | URL |\n|------|-----|\n| **ACP 官网** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002F> |\n| **协议概览** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Foverview> |\n| **初始化** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Finitialization> |\n| **Session 管理** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fsession-setup> |\n| **Prompt Turn 生命周期** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fprompt-turn> |\n| **文件系统操作** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Ffile-system> |\n| **终端操作** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fterminals> |\n| **Tool Calls** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Ftool-calls> |\n| **Session 模式** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fsession-modes> |\n| **内容类型** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fcontent> |\n| **Slash Commands** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fslash-commands> |\n| **协议扩展性** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fextensibility> |\n| **传输层** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Ftransports> |\n| **JSON Schema** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fschema> |\n\n### 2.2 生态系统\n\n| 资源 | URL |\n|------|-----|\n| **兼容 Agent 列表** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fget-started\u002Fagents> |\n| **兼容 Client 列表** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fget-started\u002Fclients> |\n| **ACP Registry** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fget-started\u002Fregistry> |\n| **LLMs.txt 索引** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fllms.txt> |\n\n---\n\n## 3. SDK 获取与安装\n\n### 3.1 TypeScript SDK\n\n```bash\nnpm install @agentclientprotocol\u002Fsdk\n```\n\n| 资源 | URL |\n|------|-----|\n| NPM 包 | \u003Chttps:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@agentclientprotocol\u002Fsdk> |\n| GitHub | \u003Chttps:\u002F\u002Fgithub.com\u002Fagentclientprotocol\u002Ftypescript-sdk> |\n| API 文档 | \u003Chttps:\u002F\u002Fagentclientprotocol.github.io\u002Ftypescript-sdk> |\n| 示例代码 | \u003Chttps:\u002F\u002Fgithub.com\u002Fagentclientprotocol\u002Ftypescript-sdk\u002Ftree\u002Fmain\u002Fsrc\u002Fexamples> |\n| 生产参考（Gemini CLI） | \u003Chttps:\u002F\u002Fgithub.com\u002Fgoogle-gemini\u002Fgemini-cli\u002Fblob\u002Fmain\u002Fpackages\u002Fcli\u002Fsrc\u002Fzed-integration\u002FzedIntegration.ts> |\n\n**核心类**：\n\n| 类 | 用途 |\n|----|------|\n| `AgentSideConnection` | **构建 Agent** — 提供 Agent 侧的 ACP 连接，实现 Client 接口 |\n| `ClientSideConnection` | **构建 Client** — 提供 Client 侧的 ACP 连接，实现 Agent 接口 |\n| `TerminalHandle` | 终端操作句柄（由 `createTerminal` 返回） |\n| `ndJsonStream` | 将 stdin\u002Fstdout 包装为 NDJSON 双向流 |\n\n### 3.2 Python SDK\n\n```bash\npip install agent-client-protocol\n# 或\nuv add agent-client-protocol\n```\n\n| 资源 | URL |\n|------|-----|\n| PyPI | \u003Chttps:\u002F\u002Fpypi.org\u002Fproject\u002Fagent-client-protocol\u002F> |\n| GitHub | \u003Chttps:\u002F\u002Fgithub.com\u002Fagentclientprotocol\u002Fpython-sdk> |\n| API 文档 | \u003Chttps:\u002F\u002Fagentclientprotocol.github.io\u002Fpython-sdk\u002F> |\n| 示例代码 | \u003Chttps:\u002F\u002Fgithub.com\u002Fagentclientprotocol\u002Fpython-sdk\u002Ftree\u002Fmain\u002Fexamples> |\n\n**核心类\u002F函数**：\n\n| 类\u002F函数 | 用途 |\n|--------|------|\n| `Agent` (基类) | **构建 Agent** — 子类化并实现 `prompt()` 等方法 |\n| `Client` (接口) | **构建 Client** — 实现 `request_permission()`、`session_update()` |\n| `run_agent()` | 启动 Agent 并监听 stdio |\n| `spawn_agent_process()` | 作为 Client 启动 Agent 子进程 |\n| `spawn_client_process()` | 作为 Agent 启动 Client 子进程 |\n| `text_block()` | 构建文本内容块 |\n| `start_tool_call()` | 构建 tool call 开始通知 |\n| `update_tool_call()` | 构建 tool call 更新通知 |\n\n### 3.3 其他 SDK\n\n| 语言 | 文档 |\n|------|------|\n| Rust | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Frust> |\n| Kotlin | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Fkotlin> |\n| 社区贡献 | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Fcommunity> |\n\n---\n\n## 4. 协议方法完整参考\n\n### 4.1 Agent 实现的方法（Client → Agent）\n\n#### 必选方法\n\n| 方法 | 说明 |\n|------|------|\n| `initialize` | 协商协议版本和能力 |\n| `session\u002Fnew` | 创建新会话 |\n| `session\u002Fprompt` | 发送用户消息 |\n\n#### 可选方法\n\n| 方法 | 前提条件 | 说明 |\n|------|---------|------|\n| `session\u002Fload` | Agent 声明 `loadSession` 能力 | 恢复已有会话 |\n| `session\u002Fset_mode` | — | 切换 Agent 工作模式 |\n| `authenticate` | Agent 声明 `authMethods` | 认证 |\n\n#### 通知（Client → Agent，无响应）\n\n| 通知 | 说明 |\n|------|------|\n| `session\u002Fcancel` | 取消当前 prompt turn |\n\n### 4.2 Client 实现的方法（Agent → Client）\n\n#### 必选方法\n\n| 方法 | 说明 |\n|------|------|\n| `session\u002Frequest_permission` | 请求用户授权 tool call |\n\n#### 可选方法（取决于 Client 声明的能力）\n\n| 方法 | 前提条件 | 说明 |\n|------|---------|------|\n| `fs\u002Fread_text_file` | `clientCapabilities.fs.readTextFile` | 读取文件内容 |\n| `fs\u002Fwrite_text_file` | `clientCapabilities.fs.writeTextFile` | 写入文件内容 |\n| `terminal\u002Fcreate` | `clientCapabilities.terminal` | 创建终端 |\n| `terminal\u002Foutput` | `clientCapabilities.terminal` | 获取终端输出 |\n| `terminal\u002Frelease` | `clientCapabilities.terminal` | 释放终端 |\n| `terminal\u002Fwait_for_exit` | `clientCapabilities.terminal` | 等待终端命令退出 |\n| `terminal\u002Fkill` | `clientCapabilities.terminal` | 杀死终端进程 |\n\n#### 通知（Agent → Client，无响应）\n\n| 通知 | 说明 |\n|------|------|\n| `session\u002Fupdate` | 会话更新（消息块、tool call、计划、命令列表、模式变更） |\n\n### 4.3 Capability 协商\n\n**Client Capabilities**（Client 在 `initialize` 请求中声明）：\n\n```typescript\ninterface ClientCapabilities {\n  fs?: {\n    readTextFile?: boolean;   \u002F\u002F 允许 Agent 读文件\n    writeTextFile?: boolean;  \u002F\u002F 允许 Agent 写文件\n  };\n  terminal?: boolean;         \u002F\u002F 允许 Agent 创建\u002F管理终端\n}\n```\n\n**Agent Capabilities**（Agent 在 `initialize` 响应中声明）：\n\n```typescript\ninterface AgentCapabilities {\n  loadSession?: boolean;        \u002F\u002F 支持恢复会话\n  promptCapabilities?: {\n    image?: boolean;            \u002F\u002F 支持图片内容\n    audio?: boolean;            \u002F\u002F 支持音频内容\n    embeddedContext?: boolean;  \u002F\u002F 支持嵌入式上下文\n  };\n  mcp?: {\n    http?: boolean;             \u002F\u002F 支持 HTTP 传输的 MCP\n    sse?: boolean;              \u002F\u002F 支持 SSE 传输的 MCP（已弃用）\n  };\n}\n```\n\n---\n\n## 5. 消息流完整生命周期\n\n### 5.1 初始化\n\n```\nClient → Agent:  initialize { protocolVersion, clientCapabilities, clientInfo }\nAgent → Client:  initialize response { protocolVersion, agentCapabilities, agentInfo, authMethods }\n```\n\n### 5.2 创建会话\n\n```\nClient → Agent:  session\u002Fnew { cwd, mcpServers }\nAgent → Client:  response { sessionId }\n```\n\n### 5.3 Prompt Turn 循环\n\n```\nClient → Agent:  session\u002Fprompt { sessionId, prompt: ContentBlock[] }\n\n  ┌─ Agent 处理循环 ─────────────────────────────────┐\n  │                                                    │\n  │  Agent → Client: session\u002Fupdate (plan)             │\n  │  Agent → Client: session\u002Fupdate (agent_message)    │\n  │                                                    │\n  │  if tool call:                                     │\n  │    Agent → Client: session\u002Fupdate (tool_call)      │\n  │    Agent → Client: request_permission (可选)        │\n  │    Client → Agent: permission response             │\n  │    Agent → Client: session\u002Fupdate (in_progress)    │\n  │    Agent → Client: session\u002Fupdate (completed)      │\n  │    → 将结果送回 LLM，继续循环                         │\n  │                                                    │\n  │  if cancelled:                                     │\n  │    Client → Agent: session\u002Fcancel                  │\n  │    Agent → Client: prompt response (cancelled)     │\n  │                                                    │\n  └────────────────────────────────────────────────────┘\n\nAgent → Client:  session\u002Fprompt response { stopReason }\n```\n\n**StopReason 类型**：\n\n| 值 | 含义 |\n|----|------|\n| `end_turn` | LLM 正常完成 |\n| `max_tokens` | 达到 token 上限 |\n| `max_model_requests` | 达到模型请求次数上限 |\n| `refused` | Agent 拒绝继续 |\n| `cancelled` | Client 取消 |\n\n### 5.4 session\u002Fupdate 通知类型\n\n| sessionUpdate 值 | 含义 |\n|------------------|------|\n| `agent_message_chunk` | Agent 消息文本块（流式） |\n| `user_message_chunk` | 用户消息块（会话恢复时） |\n| `tool_call` | 新的 tool call |\n| `tool_call_update` | tool call 状态更新 |\n| `plan` | Agent 执行计划 |\n| `commands_update` | 可用 slash commands 更新 |\n| `mode_change` | Agent 模式变更 |\n\n---\n\n## 6. 实现 ACP Agent（TypeScript）\n\n### 6.1 最小 Agent\n\n```typescript\nimport { AgentSideConnection, ndJsonStream, PROTOCOL_VERSION } from '@agentclientprotocol\u002Fsdk';\nimport type { Agent, StopReason } from '@agentclientprotocol\u002Fsdk';\n\nconst stream = ndJsonStream(process.stdin, process.stdout);\n\nconst connection = new AgentSideConnection(\n  (conn): Agent => ({\n    initialize: async (params) => ({\n      protocolVersion: PROTOCOL_VERSION,\n      agentCapabilities: {},\n      agentInfo: { name: 'my-agent', version: '1.0.0' },\n      authMethods: [],\n    }),\n\n    newSession: async (params) => ({\n      sessionId: `sess_${Date.now()}`,\n    }),\n\n    prompt: async (params) => {\n      const text = params.prompt\n        .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n        .map((b) => b.text)\n        .join('\\n');\n\n      await conn.sessionUpdate({\n        sessionId: params.sessionId,\n        update: {\n          sessionUpdate: 'agent_message_chunk',\n          content: { type: 'text', text: `Echo: ${text}` },\n        },\n      });\n\n      return { stopReason: 'end_turn' as StopReason };\n    },\n  }),\n  stream,\n);\n\nawait connection.closed;\n```\n\n### 6.2 使用 Client 能力（读写文件、终端）\n\n```typescript\nprompt: async (params) => {\n  \u002F\u002F 读文件（仅当 Client 声明了 fs.readTextFile）\n  const file = await conn.readTextFile({\n    sessionId: params.sessionId,\n    path: '\u002Fabsolute\u002Fpath\u002Fto\u002Ffile.ts',\n  });\n\n  \u002F\u002F 写文件（仅当 Client 声明了 fs.writeTextFile）\n  await conn.writeTextFile({\n    sessionId: params.sessionId,\n    path: '\u002Fabsolute\u002Fpath\u002Fto\u002Foutput.ts',\n    content: '\u002F\u002F generated code',\n  });\n\n  \u002F\u002F 创建终端（仅当 Client 声明了 terminal）\n  const terminal = await conn.createTerminal({\n    sessionId: params.sessionId,\n    command: 'npm',\n    args: ['test'],\n    cwd: '\u002Fproject\u002Froot',\n  });\n  const output = await terminal.waitForExit();\n\n  \u002F\u002F 请求用户授权\n  const permission = await conn.requestPermission({\n    sessionId: params.sessionId,\n    toolCall: { toolCallId: 'call_001' },\n    options: [\n      { optionId: 'allow', name: 'Allow', kind: 'allow_once' },\n      { optionId: 'reject', name: 'Reject', kind: 'reject_once' },\n    ],\n  });\n\n  return { stopReason: 'end_turn' };\n}\n```\n\n---\n\n## 7. 实现 ACP Agent（Python）\n\n### 7.1 最小 Agent\n\n```python\nimport asyncio\nfrom acp import Agent, PromptResponse, run_agent\n\nclass EchoAgent(Agent):\n    async def initialize(self, protocol_version, client_capabilities, **kw):\n        return {\n            \"protocolVersion\": 1,\n            \"agentCapabilities\": {},\n            \"agentInfo\": {\"name\": \"echo-agent\", \"version\": \"1.0.0\"},\n            \"authMethods\": [],\n        }\n\n    async def new_session(self, cwd, mcp_servers=None, **kw):\n        return {\"sessionId\": f\"sess_{id(self)}\"}\n\n    async def prompt(self, prompt, session_id, **kw) -> PromptResponse:\n        text = \" \".join(b[\"text\"] for b in prompt if b.get(\"type\") == \"text\")\n        await self.connection.session_update(\n            session_id=session_id,\n            update={\n                \"sessionUpdate\": \"agent_message_chunk\",\n                \"content\": {\"type\": \"text\", \"text\": f\"Echo: {text}\"},\n            },\n        )\n        return PromptResponse(stop_reason=\"end_turn\")\n\nif __name__ == \"__main__\":\n    asyncio.run(run_agent(EchoAgent()))\n```\n\n### 7.2 作为 Client 启动 Agent\n\n```python\nimport asyncio\nfrom acp import spawn_agent_process, text_block\nfrom acp.interfaces import Client\n\nclass MyClient(Client):\n    async def request_permission(self, options, session_id, tool_call, **kw):\n        return {\"outcome\": {\"outcome\": \"selected\", \"optionId\": options[0][\"optionId\"]}}\n\n    async def session_update(self, session_id, update, **kw):\n        print(f\"[{session_id}] {update}\")\n\nasync def main():\n    async with spawn_agent_process(\n        MyClient(), \"gemini\", \"--experimental-acp\"\n    ) as (conn, proc):\n        await conn.initialize(protocol_version=1)\n        session = await conn.new_session(cwd=\"\u002Fmy\u002Fproject\", mcp_servers=[])\n        result = await conn.prompt(\n            session_id=session.session_id,\n            prompt=[text_block(\"Explain this codebase\")],\n        )\n        print(f\"Stop reason: {result.stop_reason}\")\n\nasyncio.run(main())\n```\n\n---\n\n## 8. 实现 ACP Client（TypeScript）\n\nAgentDispatch 的 ClientNode 就是一个 ACP Client 的实现。核心步骤：\n\n```typescript\nimport { ClientSideConnection, ndJsonStream, PROTOCOL_VERSION } from '@agentclientprotocol\u002Fsdk';\nimport { spawn } from 'node:child_process';\n\n\u002F\u002F 1. 启动 Agent 子进程\nconst proc = spawn('gemini', ['--experimental-acp'], {\n  stdio: ['pipe', 'pipe', 'pipe'],\n  cwd: '\u002Fproject\u002Froot',\n});\n\n\u002F\u002F 2. 建立 ACP 连接\nconst stream = ndJsonStream(proc.stdout, proc.stdin);\nconst connection = new ClientSideConnection(\n  (_agent) => ({\n    \u002F\u002F Client 实现的方法\n    requestPermission: async (params) => ({\n      outcome: { outcome: 'selected', optionId: params.options[0].optionId },\n    }),\n    readTextFile: async (params) => ({\n      content: await fs.readFile(params.path, 'utf-8'),\n    }),\n    writeTextFile: async (params) => {\n      await fs.writeFile(params.path, params.content, 'utf-8');\n      return null;\n    },\n    sessionUpdate: async (params) => {\n      console.log('Update:', JSON.stringify(params.update));\n    },\n  }),\n  stream,\n);\n\n\u002F\u002F 3. 初始化\nconst initResult = await connection.initialize({\n  protocolVersion: PROTOCOL_VERSION,\n  clientCapabilities: {\n    fs: { readTextFile: true, writeTextFile: true },\n    terminal: true,\n  },\n  clientInfo: { name: 'my-client', version: '1.0.0' },\n});\n\n\u002F\u002F 4. 创建会话\nconst session = await connection.newSession({\n  cwd: '\u002Fproject\u002Froot',\n  mcpServers: [],\n});\n\n\u002F\u002F 5. 发送 prompt\nconst result = await connection.prompt({\n  sessionId: session.sessionId,\n  prompt: [{ type: 'text', text: 'Review the code in src\u002F' }],\n});\n```\n\n---\n\n## 9. 常用 Agent 的 ACP 支持形态\n\n> **核心规律**：几乎所有 Agent CLI 的默认模式是交互式终端，需要特定子命令\u002F标志才能进入 ACP stdio 模式。\n\n### 9.1 分类总览\n\n| 类型 | 特征 | 代表 |\n|------|------|------|\n| **子命令风格** | `command acp` 启动 ACP 模式 | Goose、OpenCode、Kiro、Kimi、OpenHands |\n| **标志风格** | `command --acp` 启动 ACP 模式 | Cline、Augment(auggie)、Qwen Code(qwen)、Gemini(--experimental-acp) |\n| **独立适配器** | 适配器二进制本身就是 ACP 模式 | claude-agent-acp、codex-acp、vibe-acp、pi-acp |\n\n### 9.2 完整命令参考\n\n| Agent | 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\"]` | [MoonshotAI\u002Fkimi-cli](https:\u002F\u002Fgithub.com\u002FMoonshotAI\u002Fkimi-cli) |\n| **Augment Code** | `auggie` | `[\"--acp\"]` | [docs.augmentcode.com](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` | — | [mistralai\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\n### 9.3 常见错误\n\n```jsonc\n\u002F\u002F ❌ 错误 — 启动交互终端，不是 ACP\n{ \"command\": \"gemini\" }\n{ \"command\": \"cline\" }\n\n\u002F\u002F ✅ 正确 — 进入 ACP stdio 模式\n{ \"command\": \"gemini\", \"args\": [\"--experimental-acp\"] }\n{ \"command\": \"cline\",  \"args\": [\"--acp\"] }\n```\n\n---\n\n## 10. 调试与测试\n\n### 10.1 手动测试 ACP Agent\n\n通过管道直接向 Agent 发送 JSON-RPC 消息：\n\n```bash\necho '{\"jsonrpc\":\"2.0\",\"id\":0,\"method\":\"initialize\",\"params\":{\"protocolVersion\":1,\"clientCapabilities\":{\"fs\":{\"readTextFile\":true,\"writeTextFile\":true},\"terminal\":true},\"clientInfo\":{\"name\":\"test\",\"version\":\"0.1.0\"}}}' | gemini --experimental-acp\n```\n\n### 10.2 使用 acpx CLI 测试\n\n[acpx](https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Facpx) 是一个通用 ACP CLI 客户端：\n\n```bash\nnpx acpx gemini --experimental-acp\n```\n\n### 10.3 在 Zed 中验证\n\n在 `~\u002F.config\u002Fzed\u002Fsettings.json` 中添加自定义 Agent：\n\n```json\n{\n  \"agent_servers\": {\n    \"My Agent\": {\n      \"type\": \"custom\",\n      \"command\": \"node\",\n      \"args\": [\".\u002Fdist\u002Fmy-agent.js\"]\n    }\n  }\n}\n```\n\n---\n\n## 11. 协议 JSON Schema\n\n完整的协议 JSON Schema 可从以下地址获取：\n\n- \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fschema>\n- \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fapi-reference\u002Fopenapi.json>\n\nTypeScript SDK 中的类型定义直接从 Schema 生成，可作为实现参考。\n\n---\n\n## 12. 开发检查清单\n\n实现新的 ACP Agent 或 Client 前，确认以下事项：\n\n| 检查项 | 说明 |\n|--------|------|\n| stdio 通信 | 通过 stdin\u002Fstdout 使用 NDJSON 格式的 JSON-RPC 2.0 |\n| stderr 仅用于日志 | stdout 不能混入非 JSON-RPC 内容 |\n| `initialize` 握手 | 必须实现版本协商和能力交换 |\n| `session\u002Fnew` | 必须返回唯一 sessionId |\n| `session\u002Fprompt` | 必须处理 prompt 并返回 StopReason |\n| `session\u002Fcancel` | 必须优雅处理取消，返回 `cancelled` stop reason |\n| 能力检查 | 调用 Client 方法前必须检查对应 capability |\n| 绝对路径 | 所有文件路径必须是绝对路径 |\n| 行号从 1 开始 | 不是 0-based |\n","# ACP (Agent Client Protocol) 开发指南\n\n## 1. 协议概述\n\nACP 是一个标准化协议，定义了 **Client**（代码编辑器\u002FIDE）与 **Agent**（AI 编码助手）之间的通信方式。类似于 LSP 对语言服务器的标准化作用，ACP 让任何兼容的 Agent 都能接入任何兼容的 Client。\n\n**协议特性**：\n- 基于 **JSON-RPC 2.0**\n- 传输层：**stdio**（主要）、Streamable HTTP（草案）\n- 消息类型：Method（请求-响应）、Notification（单向通知）\n- 所有文件路径必须是**绝对路径**，行号从 **1** 开始\n\n**角色定义**：\n\n| 角色 | 职责 | 示例 |\n|------|------|------|\n| **Client** | 管理环境、处理用户交互、控制资源访问 | Zed、JetBrains IDE、VS Code、Neovim、AgentDispatch ClientNode |\n| **Agent** | 使用 AI 自主修改代码，通常作为 Client 的子进程运行 | Claude Agent、Gemini CLI、Goose、自定义 Agent |\n\n---\n\n## 2. 官方文档与资源\n\n### 2.1 核心文档\n\n| 文档 | URL |\n|------|-----|\n| **ACP 官网** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002F> |\n| **协议概览** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Foverview> |\n| **初始化** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Finitialization> |\n| **Session 管理** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fsession-setup> |\n| **Prompt Turn 生命周期** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fprompt-turn> |\n| **文件系统操作** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Ffile-system> |\n| **终端操作** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fterminals> |\n| **Tool Calls** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Ftool-calls> |\n| **Session 模式** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fsession-modes> |\n| **内容类型** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fcontent> |\n| **Slash Commands** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fslash-commands> |\n| **协议扩展性** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fextensibility> |\n| **传输层** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Ftransports> |\n| **JSON Schema** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fschema> |\n\n### 2.2 生态系统\n\n| 资源 | URL |\n|------|-----|\n| **兼容 Agent 列表** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fget-started\u002Fagents> |\n| **兼容 Client 列表** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fget-started\u002Fclients> |\n| **ACP Registry** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fget-started\u002Fregistry> |\n| **LLMs.txt 索引** | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fllms.txt> |\n\n---\n\n## 3. SDK 获取与安装\n\n### 3.1 TypeScript SDK\n\n```bash\nnpm install @agentclientprotocol\u002Fsdk\n```\n\n| 资源 | URL |\n|------|-----|\n| NPM 包 | \u003Chttps:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@agentclientprotocol\u002Fsdk> |\n| GitHub | \u003Chttps:\u002F\u002Fgithub.com\u002Fagentclientprotocol\u002Ftypescript-sdk> |\n| API 文档 | \u003Chttps:\u002F\u002Fagentclientprotocol.github.io\u002Ftypescript-sdk> |\n| 示例代码 | \u003Chttps:\u002F\u002Fgithub.com\u002Fagentclientprotocol\u002Ftypescript-sdk\u002Ftree\u002Fmain\u002Fsrc\u002Fexamples> |\n| 生产参考（Gemini CLI） | \u003Chttps:\u002F\u002Fgithub.com\u002Fgoogle-gemini\u002Fgemini-cli\u002Fblob\u002Fmain\u002Fpackages\u002Fcli\u002Fsrc\u002Fzed-integration\u002FzedIntegration.ts> |\n\n**核心类**：\n\n| 类 | 用途 |\n|----|------|\n| `AgentSideConnection` | **构建 Agent** — 提供 Agent 侧的 ACP 连接，实现 Client 接口 |\n| `ClientSideConnection` | **构建 Client** — 提供 Client 侧的 ACP 连接，实现 Agent 接口 |\n| `TerminalHandle` | 终端操作句柄（由 `createTerminal` 返回） |\n| `ndJsonStream` | 将 stdin\u002Fstdout 包装为 NDJSON 双向流 |\n\n### 3.2 Python SDK\n\n```bash\npip install agent-client-protocol\n# 或\nuv add agent-client-protocol\n```\n\n| 资源 | URL |\n|------|-----|\n| PyPI | \u003Chttps:\u002F\u002Fpypi.org\u002Fproject\u002Fagent-client-protocol\u002F> |\n| GitHub | \u003Chttps:\u002F\u002Fgithub.com\u002Fagentclientprotocol\u002Fpython-sdk> |\n| API 文档 | \u003Chttps:\u002F\u002Fagentclientprotocol.github.io\u002Fpython-sdk\u002F> |\n| 示例代码 | \u003Chttps:\u002F\u002Fgithub.com\u002Fagentclientprotocol\u002Fpython-sdk\u002Ftree\u002Fmain\u002Fexamples> |\n\n**核心类\u002F函数**：\n\n| 类\u002F函数 | 用途 |\n|--------|------|\n| `Agent` (基类) | **构建 Agent** — 子类化并实现 `prompt()` 等方法 |\n| `Client` (接口) | **构建 Client** — 实现 `request_permission()`、`session_update()` |\n| `run_agent()` | 启动 Agent 并监听 stdio |\n| `spawn_agent_process()` | 作为 Client 启动 Agent 子进程 |\n| `spawn_client_process()` | 作为 Agent 启动 Client 子进程 |\n| `text_block()` | 构建文本内容块 |\n| `start_tool_call()` | 构建 tool call 开始通知 |\n| `update_tool_call()` | 构建 tool call 更新通知 |\n\n### 3.3 其他 SDK\n\n| 语言 | 文档 |\n|------|------|\n| Rust | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Frust> |\n| Kotlin | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Fkotlin> |\n| 社区贡献 | \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Flibraries\u002Fcommunity> |\n\n---\n\n## 4. 协议方法完整参考\n\n### 4.1 Agent 实现的方法（Client → Agent）\n\n#### 必选方法\n\n| 方法 | 说明 |\n|------|------|\n| `initialize` | 协商协议版本和能力 |\n| `session\u002Fnew` | 创建新会话 |\n| `session\u002Fprompt` | 发送用户消息 |\n\n#### 可选方法\n\n| 方法 | 前提条件 | 说明 |\n|------|---------|------|\n| `session\u002Fload` | Agent 声明 `loadSession` 能力 | 恢复已有会话 |\n| `session\u002Fset_mode` | — | 切换 Agent 工作模式 |\n| `authenticate` | Agent 声明 `authMethods` | 认证 |\n\n#### 通知（Client → Agent，无响应）\n\n| 通知 | 说明 |\n|------|------|\n| `session\u002Fcancel` | 取消当前 prompt turn |\n\n### 4.2 Client 实现的方法（Agent → Client）\n\n#### 必选方法\n\n| 方法 | 说明 |\n|------|------|\n| `session\u002Frequest_permission` | 请求用户授权 tool call |\n\n#### 可选方法（取决于 Client 声明的能力）\n\n| 方法 | 前提条件 | 说明 |\n|------|---------|------|\n| `fs\u002Fread_text_file` | `clientCapabilities.fs.readTextFile` | 读取文件内容 |\n| `fs\u002Fwrite_text_file` | `clientCapabilities.fs.writeTextFile` | 写入文件内容 |\n| `terminal\u002Fcreate` | `clientCapabilities.terminal` | 创建终端 |\n| `terminal\u002Foutput` | `clientCapabilities.terminal` | 获取终端输出 |\n| `terminal\u002Frelease` | `clientCapabilities.terminal` | 释放终端 |\n| `terminal\u002Fwait_for_exit` | `clientCapabilities.terminal` | 等待终端命令退出 |\n| `terminal\u002Fkill` | `clientCapabilities.terminal` | 杀死终端进程 |\n\n#### 通知（Agent → Client，无响应）\n\n| 通知 | 说明 |\n|------|------|\n| `session\u002Fupdate` | 会话更新（消息块、tool call、计划、命令列表、模式变更） |\n\n### 4.3 Capability 协商\n\n**Client Capabilities**（Client 在 `initialize` 请求中声明）：\n\n```typescript\ninterface ClientCapabilities {\n  fs?: {\n    readTextFile?: boolean;   \u002F\u002F 允许 Agent 读文件\n    writeTextFile?: boolean;  \u002F\u002F 允许 Agent 写文件\n  };\n  terminal?: boolean;         \u002F\u002F 允许 Agent 创建\u002F管理终端\n}\n```\n\n**Agent Capabilities**（Agent 在 `initialize` 响应中声明）：\n\n```typescript\ninterface AgentCapabilities {\n  loadSession?: boolean;        \u002F\u002F 支持恢复会话\n  promptCapabilities?: {\n    image?: boolean;            \u002F\u002F 支持图片内容\n    audio?: boolean;            \u002F\u002F 支持音频内容\n    embeddedContext?: boolean;  \u002F\u002F 支持嵌入式上下文\n  };\n  mcp?: {\n    http?: boolean;             \u002F\u002F 支持 HTTP 传输的 MCP\n    sse?: boolean;              \u002F\u002F 支持 SSE 传输的 MCP（已弃用）\n  };\n}\n```\n\n---\n\n## 5. 消息流完整生命周期\n\n### 5.1 初始化\n\n```\nClient → Agent:  initialize { protocolVersion, clientCapabilities, clientInfo }\nAgent → Client:  initialize response { protocolVersion, agentCapabilities, agentInfo, authMethods }\n```\n\n### 5.2 创建会话\n\n```\nClient → Agent:  session\u002Fnew { cwd, mcpServers }\nAgent → Client:  response { sessionId }\n```\n\n### 5.3 Prompt Turn 循环\n\n```\nClient → Agent:  session\u002Fprompt { sessionId, prompt: ContentBlock[] }\n\n  ┌─ Agent 处理循环 ─────────────────────────────────┐\n  │                                                    │\n  │  Agent → Client: session\u002Fupdate (plan)             │\n  │  Agent → Client: session\u002Fupdate (agent_message)    │\n  │                                                    │\n  │  if tool call:                                     │\n  │    Agent → Client: session\u002Fupdate (tool_call)      │\n  │    Agent → Client: request_permission (可选)        │\n  │    Client → Agent: permission response             │\n  │    Agent → Client: session\u002Fupdate (in_progress)    │\n  │    Agent → Client: session\u002Fupdate (completed)      │\n  │    → 将结果送回 LLM，继续循环                         │\n  │                                                    │\n  │  if cancelled:                                     │\n  │    Client → Agent: session\u002Fcancel                  │\n  │    Agent → Client: prompt response (cancelled)     │\n  │                                                    │\n  └────────────────────────────────────────────────────┘\n\nAgent → Client:  session\u002Fprompt response { stopReason }\n```\n\n**StopReason 类型**：\n\n| 值 | 含义 |\n|----|------|\n| `end_turn` | LLM 正常完成 |\n| `max_tokens` | 达到 token 上限 |\n| `max_model_requests` | 达到模型请求次数上限 |\n| `refused` | Agent 拒绝继续 |\n| `cancelled` | Client 取消 |\n\n### 5.4 session\u002Fupdate 通知类型\n\n| sessionUpdate 值 | 含义 |\n|------------------|------|\n| `agent_message_chunk` | Agent 消息文本块（流式） |\n| `user_message_chunk` | 用户消息块（会话恢复时） |\n| `tool_call` | 新的 tool call |\n| `tool_call_update` | tool call 状态更新 |\n| `plan` | Agent 执行计划 |\n| `commands_update` | 可用 slash commands 更新 |\n| `mode_change` | Agent 模式变更 |\n\n---\n\n## 6. 实现 ACP Agent（TypeScript）\n\n### 6.1 最小 Agent\n\n```typescript\nimport { AgentSideConnection, ndJsonStream, PROTOCOL_VERSION } from '@agentclientprotocol\u002Fsdk';\nimport type { Agent, StopReason } from '@agentclientprotocol\u002Fsdk';\n\nconst stream = ndJsonStream(process.stdin, process.stdout);\n\nconst connection = new AgentSideConnection(\n  (conn): Agent => ({\n    initialize: async (params) => ({\n      protocolVersion: PROTOCOL_VERSION,\n      agentCapabilities: {},\n      agentInfo: { name: 'my-agent', version: '1.0.0' },\n      authMethods: [],\n    }),\n\n    newSession: async (params) => ({\n      sessionId: `sess_${Date.now()}`,\n    }),\n\n    prompt: async (params) => {\n      const text = params.prompt\n        .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n        .map((b) => b.text)\n        .join('\\n');\n\n      await conn.sessionUpdate({\n        sessionId: params.sessionId,\n        update: {\n          sessionUpdate: 'agent_message_chunk',\n          content: { type: 'text', text: `Echo: ${text}` },\n        },\n      });\n\n      return { stopReason: 'end_turn' as StopReason };\n    },\n  }),\n  stream,\n);\n\nawait connection.closed;\n```\n\n### 6.2 使用 Client 能力（读写文件、终端）\n\n```typescript\nprompt: async (params) => {\n  \u002F\u002F 读文件（仅当 Client 声明了 fs.readTextFile）\n  const file = await conn.readTextFile({\n    sessionId: params.sessionId,\n    path: '\u002Fabsolute\u002Fpath\u002Fto\u002Ffile.ts',\n  });\n\n  \u002F\u002F 写文件（仅当 Client 声明了 fs.writeTextFile）\n  await conn.writeTextFile({\n    sessionId: params.sessionId,\n    path: '\u002Fabsolute\u002Fpath\u002Fto\u002Foutput.ts',\n    content: '\u002F\u002F generated code',\n  });\n\n  \u002F\u002F 创建终端（仅当 Client 声明了 terminal）\n  const terminal = await conn.createTerminal({\n    sessionId: params.sessionId,\n    command: 'npm',\n    args: ['test'],\n    cwd: '\u002Fproject\u002Froot',\n  });\n  const output = await terminal.waitForExit();\n\n  \u002F\u002F 请求用户授权\n  const permission = await conn.requestPermission({\n    sessionId: params.sessionId,\n    toolCall: { toolCallId: 'call_001' },\n    options: [\n      { optionId: 'allow', name: 'Allow', kind: 'allow_once' },\n      { optionId: 'reject', name: 'Reject', kind: 'reject_once' },\n    ],\n  });\n\n  return { stopReason: 'end_turn' };\n}\n```\n\n---\n\n## 7. 实现 ACP Agent（Python）\n\n### 7.1 最小 Agent\n\n```python\nimport asyncio\nfrom acp import Agent, PromptResponse, run_agent\n\nclass EchoAgent(Agent):\n    async def initialize(self, protocol_version, client_capabilities, **kw):\n        return {\n            \"protocolVersion\": 1,\n            \"agentCapabilities\": {},\n            \"agentInfo\": {\"name\": \"echo-agent\", \"version\": \"1.0.0\"},\n            \"authMethods\": [],\n        }\n\n    async def new_session(self, cwd, mcp_servers=None, **kw):\n        return {\"sessionId\": f\"sess_{id(self)}\"}\n\n    async def prompt(self, prompt, session_id, **kw) -> PromptResponse:\n        text = \" \".join(b[\"text\"] for b in prompt if b.get(\"type\") == \"text\")\n        await self.connection.session_update(\n            session_id=session_id,\n            update={\n                \"sessionUpdate\": \"agent_message_chunk\",\n                \"content\": {\"type\": \"text\", \"text\": f\"Echo: {text}\"},\n            },\n        )\n        return PromptResponse(stop_reason=\"end_turn\")\n\nif __name__ == \"__main__\":\n    asyncio.run(run_agent(EchoAgent()))\n```\n\n### 7.2 作为 Client 启动 Agent\n\n```python\nimport asyncio\nfrom acp import spawn_agent_process, text_block\nfrom acp.interfaces import Client\n\nclass MyClient(Client):\n    async def request_permission(self, options, session_id, tool_call, **kw):\n        return {\"outcome\": {\"outcome\": \"selected\", \"optionId\": options[0][\"optionId\"]}}\n\n    async def session_update(self, session_id, update, **kw):\n        print(f\"[{session_id}] {update}\")\n\nasync def main():\n    async with spawn_agent_process(\n        MyClient(), \"gemini\", \"--experimental-acp\"\n    ) as (conn, proc):\n        await conn.initialize(protocol_version=1)\n        session = await conn.new_session(cwd=\"\u002Fmy\u002Fproject\", mcp_servers=[])\n        result = await conn.prompt(\n            session_id=session.session_id,\n            prompt=[text_block(\"Explain this codebase\")],\n        )\n        print(f\"Stop reason: {result.stop_reason}\")\n\nasyncio.run(main())\n```\n\n---\n\n## 8. 实现 ACP Client（TypeScript）\n\nAgentDispatch 的 ClientNode 就是一个 ACP Client 的实现。核心步骤：\n\n```typescript\nimport { ClientSideConnection, ndJsonStream, PROTOCOL_VERSION } from '@agentclientprotocol\u002Fsdk';\nimport { spawn } from 'node:child_process';\n\n\u002F\u002F 1. 启动 Agent 子进程\nconst proc = spawn('gemini', ['--experimental-acp'], {\n  stdio: ['pipe', 'pipe', 'pipe'],\n  cwd: '\u002Fproject\u002Froot',\n});\n\n\u002F\u002F 2. 建立 ACP 连接\nconst stream = ndJsonStream(proc.stdout, proc.stdin);\nconst connection = new ClientSideConnection(\n  (_agent) => ({\n    \u002F\u002F Client 实现的方法\n    requestPermission: async (params) => ({\n      outcome: { outcome: 'selected', optionId: params.options[0].optionId },\n    }),\n    readTextFile: async (params) => ({\n      content: await fs.readFile(params.path, 'utf-8'),\n    }),\n    writeTextFile: async (params) => {\n      await fs.writeFile(params.path, params.content, 'utf-8');\n      return null;\n    },\n    sessionUpdate: async (params) => {\n      console.log('Update:', JSON.stringify(params.update));\n    },\n  }),\n  stream,\n);\n\n\u002F\u002F 3. 初始化\nconst initResult = await connection.initialize({\n  protocolVersion: PROTOCOL_VERSION,\n  clientCapabilities: {\n    fs: { readTextFile: true, writeTextFile: true },\n    terminal: true,\n  },\n  clientInfo: { name: 'my-client', version: '1.0.0' },\n});\n\n\u002F\u002F 4. 创建会话\nconst session = await connection.newSession({\n  cwd: '\u002Fproject\u002Froot',\n  mcpServers: [],\n});\n\n\u002F\u002F 5. 发送 prompt\nconst result = await connection.prompt({\n  sessionId: session.sessionId,\n  prompt: [{ type: 'text', text: 'Review the code in src\u002F' }],\n});\n```\n\n---\n\n## 9. 常用 Agent 的 ACP 支持形态\n\n> **核心规律**：几乎所有 Agent CLI 的默认模式是交互式终端，需要特定子命令\u002F标志才能进入 ACP stdio 模式。\n\n### 9.1 分类总览\n\n| 类型 | 特征 | 代表 |\n|------|------|------|\n| **子命令风格** | `command acp` 启动 ACP 模式 | Goose、OpenCode、Kiro、Kimi、OpenHands |\n| **标志风格** | `command --acp` 启动 ACP 模式 | Cline、Augment(auggie)、Qwen Code(qwen)、Gemini(--experimental-acp) |\n| **独立适配器** | 适配器二进制本身就是 ACP 模式 | claude-agent-acp、codex-acp、vibe-acp、pi-acp |\n\n### 9.2 完整命令参考\n\n| Agent | 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\"]` | [MoonshotAI\u002Fkimi-cli](https:\u002F\u002Fgithub.com\u002FMoonshotAI\u002Fkimi-cli) |\n| **Augment Code** | `auggie` | `[\"--acp\"]` | [docs.augmentcode.com](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` | — | [mistralai\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\n### 9.3 常见错误\n\n```jsonc\n\u002F\u002F ❌ 错误 — 启动交互终端，不是 ACP\n{ \"command\": \"gemini\" }\n{ \"command\": \"cline\" }\n\n\u002F\u002F ✅ 正确 — 进入 ACP stdio 模式\n{ \"command\": \"gemini\", \"args\": [\"--experimental-acp\"] }\n{ \"command\": \"cline\",  \"args\": [\"--acp\"] }\n```\n\n---\n\n## 10. 调试与测试\n\n### 10.1 手动测试 ACP Agent\n\n通过管道直接向 Agent 发送 JSON-RPC 消息：\n\n```bash\necho '{\"jsonrpc\":\"2.0\",\"id\":0,\"method\":\"initialize\",\"params\":{\"protocolVersion\":1,\"clientCapabilities\":{\"fs\":{\"readTextFile\":true,\"writeTextFile\":true},\"terminal\":true},\"clientInfo\":{\"name\":\"test\",\"version\":\"0.1.0\"}}}' | gemini --experimental-acp\n```\n\n### 10.2 使用 acpx CLI 测试\n\n[acpx](https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Facpx) 是一个通用 ACP CLI 客户端：\n\n```bash\nnpx acpx gemini --experimental-acp\n```\n\n### 10.3 在 Zed 中验证\n\n在 `~\u002F.config\u002Fzed\u002Fsettings.json` 中添加自定义 Agent：\n\n```json\n{\n  \"agent_servers\": {\n    \"My Agent\": {\n      \"type\": \"custom\",\n      \"command\": \"node\",\n      \"args\": [\".\u002Fdist\u002Fmy-agent.js\"]\n    }\n  }\n}\n```\n\n---\n\n## 11. 协议 JSON Schema\n\n完整的协议 JSON Schema 可从以下地址获取：\n\n- \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fprotocol\u002Fschema>\n- \u003Chttps:\u002F\u002Fagentclientprotocol.com\u002Fapi-reference\u002Fopenapi.json>\n\nTypeScript SDK 中的类型定义直接从 Schema 生成，可作为实现参考。\n\n---\n\n## 12. 开发检查清单\n\n实现新的 ACP Agent 或 Client 前，确认以下事项：\n\n| 检查项 | 说明 |\n|--------|------|\n| stdio 通信 | 通过 stdin\u002Fstdout 使用 NDJSON 格式的 JSON-RPC 2.0 |\n| stderr 仅用于日志 | stdout 不能混入非 JSON-RPC 内容 |\n| `initialize` 握手 | 必须实现版本协商和能力交换 |\n| `session\u002Fnew` | 必须返回唯一 sessionId |\n| `session\u002Fprompt` | 必须处理 prompt 并返回 StopReason |\n| `session\u002Fcancel` | 必须优雅处理取消，返回 `cancelled` stop reason |\n| 能力检查 | 调用 Client 方法前必须检查对应 capability |\n| 绝对路径 | 所有文件路径必须是绝对路径 |\n| 行号从 1 开始 | 不是 0-based |\n",{"name":5,"license":14,"description":7,"allowed-tools":41},"Shell, Read, Write, Glob, Grep, WebFetch","master","3a92278a00caef2314e2008a9f50b810363a3d86",".agents\u002Fskills\u002Facp-dev-guide","https:\u002F\u002Fgithub.com\u002Fblackplume233\u002FAgentDispatch","https:\u002F\u002Fgithub.com\u002Fblackplume233","2026-03-03 22:11:55",{"source":8,"skillName":5,"commands":49,"prompt":59,"zipAvailable":60},[50,53,56],{"tool":51,"command":52},"npx","npx skills add blackplume233\u002FAgentDispatch --skill acp-dev-guide",{"tool":54,"command":55},"bunx","bunx skills add blackplume233\u002FAgentDispatch --skill acp-dev-guide",{"tool":57,"command":58},"pnpm","pnpm dlx skills add blackplume233\u002FAgentDispatch --skill acp-dev-guide","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fblackplume233\u002FAgentDispatch\u002Fblob\u002Fmaster\u002F.agents\u002Fskills\u002Facp-dev-guide\u002FSKILL.md",true,[],[63,84,102,115,131,145],{"skillNo":64,"name":65,"nameZh":6,"description":66,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":72,"publishedAt":36},"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",[69],{"categoryNo":70,"categoryName":71,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量",[73,74,75,76,77,78,30,79,80,31,32,33,34,81,82,83],"monitor","qa","qa monitor","testing","commit","git","ship","subagent","engineer","issue","task",{"skillNo":85,"name":86,"nameZh":6,"description":87,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":94,"publishedAt":36},"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",[90,91],{"categoryNo":70,"categoryName":71,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":92,"categoryName":93,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口",[74,81,95,76,96,97,98,99,100,30,101,80,31,32,33,34,82,83],"qa engineer","cli","test","run","REST","api","qa test",{"skillNo":103,"name":104,"nameZh":6,"description":105,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":106,"categories":107,"keywords":108,"publishedAt":36},"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",[],[109,110,111,112,30,113,80,114,31,32,33,34,83],"pr","pr watcher","github","open pr","open","连续",{"skillNo":116,"name":117,"nameZh":6,"description":118,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":119,"categories":120,"keywords":121,"publishedAt":36},"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",[],[109,122,123,124,125,126,127,30,79,80,31,128,32,129,33,34,82,83,130],"pr handler","review","spec","review pr","pipeline","gatekeeper","multi-agent","draft pr","draft",{"skillNo":132,"name":133,"nameZh":6,"description":134,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":135,"categories":136,"keywords":137,"publishedAt":36},"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",[],[82,138,111,139,140,141,142,143,30,80,31,32,33,34,144],"issue manager","obsidian","create","github issues","issues","first","bug",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":149,"categories":150,"keywords":151,"publishedAt":36},"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",[],[77,152,78,140,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168],"git commit","commit message","file","messages","conventional commit","analysis","Bash","commit messages","interactive","user","execute","use","diff","auto","commit changes","grouping","message"]