openclaw/acpx

GitHub: openclaw/acpx

acpx 是 ACP(Agent Client Protocol)的无头 CLI 客户端,让 AI 编码 Agent 通过结构化协议进行持久化、可并行的多会话通信,取代脆弱的 PTY 抓取方式。

Stars: 2864 | Forks: 279

acpx banner

# acpx [![npm version](https://img.shields.io/npm/v/acpx.svg)](https://www.npmjs.com/package/acpx) [![npm downloads](https://img.shields.io/npm/dm/acpx.svg)](https://www.npmjs.com/package/acpx) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/34a22c9d82195043.svg)](https://github.com/openclaw/acpx/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Node.js](https://img.shields.io/node/v/acpx.svg)](https://nodejs.org) 你的 agent 们会爱上 acpx! 🤖❤️ 它们讨厌不得不从 PTY 会话中抓取字符 😤 `acpx` 是 [Agent Client Protocol (ACP)](https://agentclientprotocol.com) 的无头(headless)CLI 客户端,因此 AI agent 和编排器(orchestrator)可以通过结构化的协议进行通信,而不是抓取 PTY。 为 Pi、OpenClaw ACP、Codex、Claude 和其他兼容 ACP 的 agent 提供统一的命令入口。专为通过命令行进行的 agent 间通信而构建。 - **持久会话**:支持跨调用存留的多轮对话,按代码仓库区分作用域 - **命名会话**:在同一个代码仓库中运行并行工作流(`-s backend`,`-s frontend`) - **Prompt 排队**:在一个 prompt 运行时提交新的 prompt,它们会按顺序执行 - **协作取消命令**:`cancel` 通过队列 IPC 发送 ACP `session/cancel`,而不会破坏会话状态 - **软关闭生命周期**:关闭会话但不从磁盘删除历史记录 - **队列所有者 TTL**:短暂保持队列所有者存活以备后续 prompt(`--ttl`) - **即发即弃**:`--no-wait` 将 prompt 加入队列并立即返回 - **优雅取消**:`Ctrl+C` 在强制终止作为后备方案之前发送 ACP `session/cancel` - **会话控制**:使用 `set-mode` 和 `set ` 来执行 `session/set_mode` 和 `session/set_config_option` - **崩溃重连**:自动检测死掉的 agent 进程,并自动恢复或重新加载会话 - **从文件/stdin 读取 Prompt**:使用 `--file ` 或通过管道 stdin 提供 prompt 内容 - **配置文件**:通过 `acpx config show|init` 管理全局及项目级的 JSON 配置 - **会话检查/历史**:`sessions show` 和 `sessions history --limit ` - **会话导出/导入**:在机器之间迁移便携式会话存档 - **本地状态检查**:`status` 报告 running/idle/dead/no-session 状态、PID、运行时长和上一个 prompt - **客户端方法**:稳定的 `fs/*` 和 `terminal/*` 处理器,支持权限控制和 cwd 沙箱化 - **认证握手**:通过环境变量/配置凭证提供稳定的 `authenticate` 支持 - **结构化输出**:输出类型化的 ACP 消息(thinking、tool calls、diffs),而不是抓取 ANSI 字符流 - **任意 ACP agent**:内置注册表 + `--agent` 逃生舱,用于自定义服务器 - **单次执行模式**:使用 `exec` 执行无状态的即发即弃任务 - **跨 agent 对比**:`acpx compare pi openclaw codex 'fix the bug'` 针对多个兼容 ACP 的 agent 运行相同的单次 prompt,并并排汇总耗时、token 使用量、权限和最终输出 - **实验性 flows**:`flow run ` 运行 TypeScript 工作流模块处理多个 prompt - **运行时拥有的 flow 动作**:基于 shell 的动作步骤可以在 agent 轮次之外准备工作区和其他确定性机制 - **Flow 工作区隔离**:`acp` 节点可以针对明确的单步 cwd,因此 flow 可以将 agent 的工作保留在一次性 worktree 中 ``` $ acpx codex sessions new $ acpx codex "find the flaky test and fix it" [thinking] Investigating test suite for flaky failures [tool] Run npm test -- --reporter=verbose (running) [tool] Run npm test -- --reporter=verbose (completed) output: ✓ auth.login (0.8s) ✗ checkout.submit (timed out after 5000ms) ✓ cart.add (0.3s) [thinking] Found it — checkout.submit has a race condition in the async setup [tool] Edit src/checkout.test.ts (completed) output: Success. Updated 1 file. [tool] Run npm test -- checkout.submit (completed) output: ✓ checkout.submit (0.4s) Fixed: added `await` to the setup hook in checkout.submit. The test was reading stale state from the previous run. [done] end_turn ``` ## 快速设置 —— 向你的 agent 介绍 acpx 复制下方的代码块并将其粘贴到你的 Pi、OpenClaw、Claude Code 或类似的 agent 框架中。它会安装 acpx,读取技能参考文档,并了解如何在未来的所有编码 agent 任务中使用 ACP。 ``` I want you to use acpx to run coding agents over the Agent Client Protocol (ACP) instead of scraping PTY sessions. Please do the following: 1. Install acpx globally (recommended) or use npx: npm install -g acpx@latest Or without installing: npx acpx@latest 2. For Pi or OpenClaw, use the reference URL below. For Codex-style skill installation, install the acpx skill so you have the full reference available: npx acpx@latest --skill install acpx --agent codex --scope user Use --agent claude for Claude Code. For another harness not listed by --skill install --help, use the reference URL below instead. 3. Read the acpx skill reference so you know every command, flag, and workflow pattern: https://raw.githubusercontent.com/openclaw/acpx/main/skills/acpx/SKILL.md 4. If you need the full CLI reference with all options and examples: https://raw.githubusercontent.com/openclaw/acpx/main/docs/CLI.md From now on, when you need to delegate work to a coding agent, use acpx instead of spawning raw terminal sessions. For example: npx acpx@latest codex "fix the failing tests" npx acpx@latest claude "refactor the auth module" npx acpx@latest codex exec "one-shot: summarize this repo" ``` ## 安装 ``` npm install -g acpx@latest ``` 或者不安装直接运行: ``` npx acpx@latest codex "fix the tests" ``` 无论哪种方式,会话状态都存放在 `~/.acpx/` 中。全局安装会快一点,但 `npx acpx@latest` 也能正常工作。 ## Agent 前置条件 `acpx` 会在首次使用时通过 `npx` 自动下载 ACP 适配器。你不需要手动安装适配器包。 唯一的前置条件是你想要使用的底层编码 agent: - `acpx pi` -> Pi Coding Agent: https://github.com/mariozechner/pi - `acpx openclaw` -> OpenClaw ACP bridge: https://github.com/openclaw/openclaw - `acpx codex` -> Codex CLI: https://codex.openai.com - `acpx claude` -> Claude Code: https://claude.ai/code 更多内置 agent 的文档位于 [agents/README.md](agents/README.md)。 ## 使用示例 ``` acpx codex sessions new # create a session (explicit) for this project dir acpx codex 'fix the tests' # implicit prompt (routes via directory-walk) acpx codex prompt 'fix the tests' # explicit prompt subcommand echo 'fix flaky tests' | acpx codex # prompt from stdin acpx codex --file prompt.md # prompt from file acpx codex --file - "extra context" # explicit stdin + appended args acpx codex --no-wait 'draft test migration plan' # enqueue without waiting if session is busy acpx codex cancel # cooperative cancel of in-flight prompt acpx codex set-mode auto # session/set_mode (adapter-defined mode id) acpx codex set model 'gpt-5.2[high]' # adapter-advertised model control acpx exec 'summarize this repo' # default agent shortcut (codex) acpx codex exec 'what does this repo do?' # one-shot, no saved session acpx codex sessions new --name api # create named session acpx codex -s api 'implement token pagination' # prompt in named session acpx codex sessions new --name docs # create another named session acpx codex -s docs 'rewrite API docs' # parallel work in another named session acpx codex sessions # list sessions for codex command acpx codex sessions list # explicit list acpx codex sessions show # inspect cwd session metadata acpx codex sessions history # show recent turn history acpx codex sessions new # create fresh cwd-scoped default session acpx codex sessions new --name api # create fresh named session acpx codex sessions ensure # return existing scoped session or create one acpx codex sessions ensure --name api # ensure named scoped session acpx codex sessions close # close cwd-scoped default session acpx codex sessions close api # close cwd-scoped named session acpx codex status # local process status for current session acpx config show # show resolved config (global + project) acpx config init # create ~/.acpx/config.json template ``` 主要落地框架示例: ``` acpx pi 'review recent changes' acpx openclaw exec 'summarize active session state' # built-in OpenClaw ACP bridge acpx codex 'fix the failing typecheck' acpx claude 'refactor auth middleware' # built-in claude agent ``` 其他受支持的框架及其具体说明记录在 [agents/README.md](agents/README.md) 中。 ``` acpx my-agent 'review this patch' # unknown name -> raw command acpx --agent './bin/dev-acp --profile ci' 'run checks' # --agent escape hatch ``` ## 实际场景 ``` # 在专用 session 中审查 PR 并自动批准 permissions acpx --cwd ~/repos/shop --approve-all codex -s pr-842 \ 'Review PR #842 for regressions and propose a minimal fix' # 为同一个 repo 保持并行 streams acpx codex -s bugfix 'isolate flaky checkout test' acpx codex -s release 'draft release notes from recent commits' ``` ## 实践中的全局选项 ``` acpx --approve-all codex 'apply the patch and run tests' acpx --approve-reads codex 'inspect repo structure and suggest plan' # default mode acpx --deny-all codex 'explain what you can do without tool access' acpx --non-interactive-permissions fail codex 'fail instead of deny in non-TTY' acpx --policy '{"escalate":["execute"],"defaultAction":"deny"}' --format json codex exec 'ask before shell' acpx --cwd ~/repos/backend codex 'review recent auth changes' acpx --format text codex 'summarize your findings' acpx --format json codex exec 'review changed files' acpx --format json --json-strict codex exec 'machine-safe JSON only' acpx flow run ./my-flow.ts --input-file ./flow-input.json acpx --timeout 1800 flow run ./my-flow.ts acpx --format quiet codex 'final recommendation only' acpx --suppress-reads codex exec 'show tool activity without dumping file bodies' acpx --timeout 90 codex 'investigate intermittent test timeout' acpx --ttl 30 codex 'keep queue owner alive for quick follow-ups' acpx --verbose codex 'debug why adapter startup is failing' ``` ## Flows `acpx flow run ` 通过 `acpx/flows` 运行时执行 TypeScript flow 模块,并将运行状态持久化存储在 `~/.acpx/flows/runs/` 下。 Flows 适用于单个 prompt 不足以完成的多步骤 ACP 工作: - `acp` 步骤将模型形状的工作保留在 ACP 中 - `decision()` 和 `decisionEdge()` 封装受限选择的 ACP 分支,而无需添加新的节点类型 - `action` 步骤处理确定性机制,如 shell 命令或 GitHub 调用 - `compute` 步骤执行本地路由或重塑 - `checkpoint` 步骤为运行时之外的事件暂停 源码树中包含了 flow 示例,位于 [examples/flows/README.md](examples/flows/README.md): - 诸如 `echo`、`branch`、`shell`、`workdir` 和 `two-turn` 等小示例 - 位于 [examples/flows/pr-triage/README.md](examples/flows/pr-triage/README.md) 下的一个更大的 PR 分类示例 - 位于 [examples/flows/replay-viewer/README.md](examples/flows/replay-viewer/README.md) 的重放查看器,用于在浏览器中检查已保存的运行包 运行示例: ``` acpx flow run ./my-flow.ts --input-file ./flow-input.json acpx flow run examples/flows/branch.flow.ts \ --input-json '{"task":"FIX: add a regression test for the reconnect bug"}' acpx flow run examples/flows/pr-triage/pr-triage.flow.ts \ --input-json '{"repo":"openclaw/acpx","prNumber":150}' ``` PR 分类示例仅作为一个工作流示例。如果你针对在线代码仓库运行它, 它可以评论或关闭真实的 GitHub PR。 ## 配置文件 `acpx` 以下列顺序读取配置(后者优先级更高): 1. 全局:`~/.acpx/config.json` 2. 项目:`/.acpxrc.json` CLI 参数始终优先于配置值。 支持的键: ``` { "defaultAgent": "codex", "defaultPermissions": "approve-all", "nonInteractivePermissions": "deny", "authPolicy": "skip", "ttl": 300, "timeout": null, "format": "text", "agents": { "my-custom": { "command": "./bin/my-acp-server", "args": ["acp"] } }, "auth": { "my_auth_method_id": "credential-value" } } ``` 使用 `acpx config show` 查看解析后的结果,使用 `acpx config init` 创建全局模板。 对于 ACP `authenticate` 握手,可以使用配置中的 `auth` 条目,或者使用明确的 `ACPX_AUTH_` 环境变量,例如 `ACPX_AUTH_OPENAI_API_KEY`。 现有的提供商环境变量(如 `OPENAI_API_KEY`)仍会被传递给 子 agent,但它们自身不会触发 ACP auth-method 选择。 ## 输出格式 ``` # text(默认):包含 tool 更新的人类可读 stream acpx codex 'review this PR' # json:NDJSON 事件,适用于自动化 acpx --format json codex exec 'review this PR' \ | jq -r 'select(.type=="tool_call") | [.status, .title] | @tsv' # json-strict:抑制非 JSON 的 stderr 输出(需要 --format json) acpx --format json --json-strict codex exec 'review this PR' # quiet:仅输出最终的 assistant 文本 acpx --format quiet codex 'give me a 3-line summary' # 抑制 read payloads,同时保留选定的输出格式 acpx --suppress-reads codex exec 'inspect the repo and report tool usage' ``` - `text`:人类可读的流,包含助手文本和工具更新 - `json`:用于自动化的原始 ACP NDJSON 流 - `quiet`:仅输出最终的助手文本 - `--suppress-reads`:在 `text` 和 `json` 输出中,将原始读取文件的内容替换为 `[read output suppressed]` JSON 事件包含用于关联的稳定信封: ``` { "eventVersion": 1, "sessionId": "abc123", "requestId": "req-42", "seq": 7, "stream": "prompt", "type": "tool_call" } ``` 会话控制 JSON payload(`sessions new|ensure`,`status`)始终包含 `acpxRecordId` 和 `acpxSessionId`。它们仅在适配器暴露提供商原生会话 ID 时包含 `agentSessionId`。text/quiet 的会话 ID 是 本地 acpx 记录 ID;不要假设它可以被传递给原生提供商 CLI, 除非存在 `agentSessionId`。 ## 内置 agent 和自定义服务器 内置项: | Agent | Adapter | Wraps | | ------------ | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | `pi` | [pi-acp](https://github.com/svkozak/pi-acp) | [Pi Coding Agent](https://github.com/mariozechner/pi) | | `openclaw` | native (`openclaw acp`) | [OpenClaw ACP bridge](https://github.com/openclaw/openclaw) | | `codex` | [codex-acp](https://github.com/agentclientprotocol/codex-acp) | [Codex CLI](https://codex.openai.com) | | `claude` | [claude-agent-acp](https://github.com/agentclientprotocol/claude-agent-acp) | [Claude Code](https://claude.ai/code) | | `gemini` | native (`gemini --acp`) | [Gemini CLI](https://github.com/google/gemini-cli) | | `cursor` | native (`cursor-agent acp`) | [Cursor CLI](https://cursor.com/docs/cli/acp) | | `copilot` | native (`copilot --acp --stdio`) | [GitHub Copilot CLI](https://docs.github.com/copilot/how-tos/copilot-chat/use-copilot-chat-in-the-command-line) | | `droid` | native (`droid exec --output-format acp`) | [Factory Droid](https://www.factory.ai) | | `fast-agent` | `uvx fast-agent-mcp acp` | [fast-agent](https://fast-agent.ai) | | `iflow` | native (`iflow --experimental-acp`) | [iFlow CLI](https://github.com/iflow-ai/iflow-cli) | | `kilocode` | `npx -y @kilocode/cli acp` | [Kilocode](https://kilocode.ai) | | `kimi` | native (`kimi acp`) | [Kimi CLI](https://github.com/MoonshotAI/kimi-cli) | | `kiro` | native (`kiro-cli-chat acp`) | [Kiro CLI](https://kiro.dev) | | `mux` | `npx -y mux@^0.27.0 acp` | [Mux](https://mux.coder.com) | | `opencode` | `npx -y opencode-ai acp` | [OpenCode](https://opencode.ai) | | `qoder` | native (`qodercli --acp`) | [Qoder CLI](https://docs.qoder.com/cli/acp) | | `qwen` | native (`qwen --acp`) | [Qwen Code](https://github.com/QwenLM/qwen-code) | | `trae` | native (`traecli acp serve`) | [Trae CLI](https://docs.trae.cn/cli) | `factory-droid` 和 `factorydroid` 也会解析为内置的 `droid` 适配器。 更多内置 agent 文档位于 [agents/README.md](agents/README.md)。 使用 `--agent` 作为自定义 ACP 服务器的逃生舱: ``` acpx --agent ./my-custom-acp-server 'do something' ``` 对于仓库本地的 OpenClaw 检出,请在配置中覆盖内置命令,以便 `acpx openclaw ...` 直接生成 ACP 桥接,而不会产生 `pnpm` 包装器噪音: ``` { "agents": { "openclaw": { "command": "env OPENCLAW_HIDE_BANNER=1 OPENCLAW_SUPPRESS_NOTES=1 node scripts/run-node.mjs acp --url ws://127.0.0.1:18789 --token-file ~/.openclaw/gateway.token --session agent:main:main" } } } ``` ## 会话行为 - Prompt 命令需要现有的已保存会话记录(通过 `sessions new` 或 `sessions ensure` 创建)。 - Prompt 通过从 `cwd`(或 `--cwd`)向上遍历到最近的 git 根目录(包含自身)进行路由,并选择匹配 `(agent command, dir, optional name)` 的最近活动会话。 - 如果找不到 git 根目录,prompt 将仅匹配完全一致的 `cwd` 会话(不进行父目录遍历)。 - `-s ` 在该目录遍历期间选择一个并行的命名会话。 - `sessions new [--name ]` 为该作用域创建一个新的会话,并软关闭前一个会话。 - `sessions ensure [--name ]` 是幂等的:它返回现有的作用域会话,或者在缺失时创建一个。 - `sessions close [name]` 会软关闭会话:队列所有者/进程被终止,记录以 `closed: true` 保留。 - `sessions list` 在可用时使用 agent 端的 ACP `session/list;使用 `--cursor`、`--filter-cwd` 或 `--local` 进行分页、cwd 过滤或 检查保存的记录。 - 针对当前作用域的自动恢复将跳过标记为关闭的会话。 - Prompt 提交是按会话感知队列的。如果某个 prompt 已经在运行,新的 prompt 将被排队,并由正在运行的 `acpx` 进程处理。 - 队列所有者使用空闲 TTL(默认为 300 秒)。`--ttl ` 可覆盖它;`--ttl 0` 使所有者无限期存活。 - `--no-wait` 将内容提交到该队列并立即返回。 - `cancel` 向正在运行的队列所有者进程发送协作式的 `session/cancel`,并在没有运行 prompt 时返回成功(`nothing to cancel`)。 - `set-mode` 和 `set` 在激活时通过队列所有者 IPC 进行路由,否则它们会直接重新连接以应用 `session/set_mode` 和 `session/set_config_option`。 - `set-mode` 的 `` 值由适配器定义;适配器会拒绝不支持的值(通常为 `Invalid params`)。 - `exec` 始终是一次性执行的,不会复用已保存的会话。 - 会话元数据存储在 `~/.acpx/sessions/` 下。 - 每个成功的 prompt 都会将轻量级的轮次历史预览(`role`、`timestamp`、`textPreview`)附加到会话元数据中。 - 在正在运行的轮次中按 `Ctrl+C` 会发送 ACP `session/cancel`,并在必要时强制终止之前短暂等待 `stopReason=cancelled`。 - 如果已保存的会话 pid 在下一个 prompt 时已经死亡,`acpx` 会重新生成 agent,在播报时尝试 `session/resume`,或者尝试 `session/load`,如果重连失败则透明地回退到 `session/new`。 ## 完整 CLI 参考 参见 [docs/CLI.md](docs/CLI.md)。 ## License MIT
标签:ACP协议, AI智能体, GNU通用公共许可证, MITM代理, Node.js, 会话管理, 客户端, 文档结构分析, 暗色界面, 自动化攻击