agentrun

agentrun 用一条命令在沙箱里运行 claude-code、codex、pi 和 dsh,支持 macOS、Linux、Cloud Managed 容器和 docker 容器。

Motivation

在脚本或 CI 里让 claude-code、codex、pi 或 dsh 去改代码,每次都要处理同样的事:agent 能写哪些文件、能不能联网、会不会读到你自己的配置和账号;各运行时的参数、输出格式和成败判定各不相同;同一段脚本换到 docker 或 Cloud Managed 容器里,可能因为缺少沙箱工具或登录而失败,报错也看不出原因。

agentrun 把这些事放进一条命令。它在当前环境能提供的沙箱里启动运行时,把运行时的输出转换成同一种事件流,按统一的规则给出退出码;agentrun doctor 在启动前检查环境,失败时说明原因和改法。选哪个模型、失败后是否重试、怎么安装运行时,仍由调用方决定。

脚本或 CI agentrun 沙箱:只写工作目录 · 网络经过滤代理 claude-code codex pi dsh 不读你的运行时配置 doctor 检查环境 · 转换输出 · 判定成败 同一种事件流与退出码 同一条命令在 macOS、Linux、Cloud Managed 容器和 docker 容器里运行

Get Started

给使用 agentrun 的人:怎么安装、怎么调用、出了问题怎么查。

Environment

开发者文档从这一节开始。下图是源代码里各模块的关系,每个页面开头的「代码位置」列出对应的源文件。

命令行 cli.rs会话环境session.rs credential.rs运行框架 run/doctor.rs沙箱sandbox/适配器接口 runtime/过滤代理network/claudecode.rscodex.rspi.rsdsh.rslaunch / translate / failureRecord事件输出output/:aggregate.rs → event.rs → mod.rs(text.rs、rich.rs),用量在 usage.rs
模块关系。运行框架调用会话环境、沙箱与过滤代理做启动前检查,通过适配器接口启动运行时并翻译它的输出;doctor 复用沙箱与过滤代理做检查。四个适配器在 runtime/ 下。

可见性按目录限定:每个目录下的文件都是私有子模块,外部只能用 mod.rs re-export 的项:tests/ 或 main.rs 用到的写 pub use,只有 crate 内其他目录用到的写 pub(crate) use。私有子模块里的项可以保持 pub,能不能从外部访问由 mod.rs 是否 re-export 决定。唯一的例外是 runtime/ 的 claudecode、codex、pi 三个子模块声明为 pub mod,因为每个适配器有自己的集成测试。理由:编译器只对外部访问不到的项报告未使用,可见性按目录限定后,新的死代码才会被报出来。run/ 把 doctor 子命令分派给 doctor.rs,doctor.rs 复用 run/ 的 Caller 与临时目录函数,这一处是有意保留的分派关系。

平台相关的代码按平台分文件:process_tree/ 的 linux.rs 与 macos.rs、sandbox/ 的 bubblewrap.rs 与 seatbelt.rs,同一目录的两个文件提供同一组项,由 mod.rs 按操作系统选择;包裹命令与 Seatbelt 配置在两个平台都编译。理由:单元测试在 Linux 上也能检查 macOS 的包裹参数。

agent 在什么样的环境里运行:会话环境变量、临时目录、凭据与进程,沙箱与网络限制,以及在四种环境里怎么调用。

在四种环境里怎么调用

工具不探测自己运行在哪种环境里。它只看操作系统,并在启动前实际启动一次沙箱来判断沙箱能不能用。理由:按环境探测一旦误判,本机会话就会在没有沙箱的情况下运行;实际启动一次沙箱则能直接回答「能不能隔离」这个问题。

环境沙箱调用方的写法
本机 macOSSeatbelt,系统自带不用写 --sandbox
本机 Linuxbubblewrap(bwrap,claude-code、pi 与 dsh 另需 socat);codex 用它自己的沙箱不用写;没装 bwrap 时 agentrun 报错并给出安装命令
Cloud Managed 容器(Claude 云端、Codex 云端)同本机 Linux,要求容器里装了 bwrap 与 socat,且能创建用户命名空间不用写。在 Claude 云端验证过;Codex 云端没有验证过
docker 容器默认的 docker 容器不能创建用户命名空间,沙箱无法启动启动方写 --sandbox off 或设 AGENTRUN_SANDBOX=off,隔离边界是容器本身

Cloud Managed 容器有两种:Claude 云端只运行 claude-code、pi 与 dsh,Codex 云端只运行 codex 与 pi。工具不区分这两种容器,由启动方选择运行时。

Event and Output

agentrun 输出的统一事件流与三种输出格式。后两页是运行时原始输出的字段参考。

Runtime

怎么调用 agentrun:命令行选项、启动前检查、doctor 与退出码,以及 agentrun 怎么启动每个运行时、怎么判定成败。

Testing and Release

怎么测试 agentrun、四种环境的验收由谁执行、怎么发布。

不支持的功能

以下功能目前没有需求支撑,agentrun 不提供,表中写了现在的替代做法:

功能内容
--skill DIR把技能目录复制到各运行时的技能位置(.claude/skills/、.codex/skills/、.pi/skills/)。替代做法:调用方自己把技能文件放进工作目录,并在提示词里写出路径
配置文件固定的追加目录与运行时可执行文件路径。替代做法:追加目录用 --path,运行时从 PATH 查找
agentrun exec -- <命令>用同样的会话环境、凭据与沙箱启动任意命令,只提供退出码与 start、end 事件。替代做法:任意命令由调用方自己启动
额外的可写目录在工作目录与会话临时目录之外再开放一个可写目录
--allow-host-file从文件读主机列表。替代做法:调用方需要长列表就在脚本里展开成多个 --allow-host
按请求内容过滤网络需要解密 HTTPS。过滤代理只按目标主机与端口判断
命令与 Python 包的黑名单运行时的权限规则只匹配命令文字,容易绕过;沙箱拒绝指定路径只在沙箱运行时生效