openclaw/acpx
GitHub: openclaw/acpx
acpx 是 ACP(Agent Client Protocol)的无头 CLI 客户端,让 AI 编码 Agent 通过结构化协议进行持久化、可并行的多会话通信,取代脆弱的 PTY 抓取方式。
Stars: 2864 | Forks: 279
# acpx
[](https://www.npmjs.com/package/acpx)
[](https://www.npmjs.com/package/acpx)
[](https://github.com/openclaw/acpx/actions/workflows/ci.yml)
[](https://opensource.org/licenses/MIT)
[](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, 会话管理, 客户端, 文档结构分析, 暗色界面, 自动化攻击