名称: cas
描述: 运行一个仅支持 v2 的 Node JSONL 代理,该代理会启动 codex app-server 并暴露一个自动化友好的流 API。在需要以编程方式驱动应用服务器(自动化/编排/会话挖掘)时使用,允许子代理向活跃会话发送更新或代码补丁,自动处理审批,以确定性超时转发服务器请求,通过 thread/* 挖掘会话,引导活动轮次 (turn/steer),或运行 N 个并行实例(每个实例是一个代理 + 一个 app-server 子进程)。
cas (应用服务器控制)
概述
Cas 附带一个小型 Node 代理 (scripts/cas_proxy.mjs),该代理:
- 启动
codex app-server。 - 执行必需的交握 (
initialize->initialized),使用experimentalApi: true和可选的optOutNotificationMethods。 - 通过 stdio 读写 JSONL。
- 自动接受 v2 审批请求。
- 将 v2 服务器请求转发给编排器。
- 拒绝已弃用的旧版审批请求 (
execCommandApproval,applyPatchApproval)。 - 在超时时确定性地使转发请求失败(默认
30000毫秒)。 - 发出无损的、自动化友好的事件流(包括原始应用服务器消息加上派生的路由键)。
此技能假设 codex 在 PATH 中可用,且不需要访问任何仓库源代码树。
快速开始
CODEX_SKILLS_HOME="${CODEX_HOME:-$HOME/.codex}"
CLAUDE_SKILLS_HOME="${CLAUDE_HOME:-$HOME/.claude}"
CAS_SCRIPTS_DIR="$CODEX_SKILLS_HOME/skills/cas/scripts"
[ -d "$CAS_SCRIPTS_DIR" ] || CAS_SCRIPTS_DIR="$CLAUDE_SKILLS_HOME/skills/cas/scripts"
run_cas_tool() {
local subcommand="${1:-}"
if [ -z "$subcommand" ]; then
echo "用法: run_cas_tool <smoke-check|instance-runner> [参数...]" >&2
return 2
fi
shift || true
local bin=""
local marker=""
local fallback=""
case "$subcommand" in
smoke-check)
bin="cas_smoke_check"
marker="cas_smoke_check.zig"
fallback="$CAS_SCRIPTS_DIR/cas_smoke_check.mjs"
;;
instance-runner)
bin="cas_instance_runner"
marker="cas_instance_runner.zig"
fallback="$CAS_SCRIPTS_DIR/cas_instance_runner.mjs"
;;
*)
echo "未知的 cas 子命令: $subcommand" >&2
return 2
;;
esac
if command -v "$bin" >/dev/null 2>&1 && "$bin" --help 2>&1 | grep -q "$marker"; then
"$bin" "$@"
return
fi
if [ "$(uname -s)" = "Darwin" ] && command -v brew >/dev/null 2>&1; then
if ! brew install tkersey/tap/cas; then
echo "brew install tkersey/tap/cas 失败; 拒绝静默回退。" >&2
return 1
fi
if command -v "$bin" >/dev/null 2>&1 && "$bin" --help 2>&1 | grep -q "$marker"; then
"$bin" "$@"
return
fi
echo "brew install tkersey/tap/cas 未产生兼容的 $bin 二进制文件。" >&2
return 1
fi
if [ -f "$fallback" ]; then
node "$fallback" "$@"
return
fi
echo "cas 二进制缺失且回退脚本未找到: $fallback" >&2
return 1
}
run_cas_tool smoke-check --cwd /path/to/workspace --json
术语 (实例)
- 一个“实例”是一个
cas_proxy进程加上其启动的 app-server 子进程。 - 每个实例有自己的 JSONL 流和自己的
sessionId。 - “N 实例”意味着 N 个并行代理+app-server 对;它不是在一个实例中的 N 个线程/轮次。
- 隔离提示:对于多实例运行,如果不想实例共享状态,请首选每个实例的
--state-file(或运行器的--state-file-dir)。
触发线索
- “实例” / “多实例” / “并行会话”
- 应用服务器控制 (JSONL 代理, JSON-RPC 方法)
- 会话挖掘 (线程/轮次清单, 导出/索引)
- 引导/恢复 (
turn/steer,thread/resume)
工作流程
-
启动代理。
- 从 cas 技能目录运行
node scripts/cas_proxy.mjs(或通过脚本路径解析:CODEX_SKILLS_HOME="${CODEX_HOME:-$HOME/.codex}"; CLAUDE_SKILLS_HOME="${CLAUDE_HOME:-$HOME/.claude}"; CAS_PROXY="$CODEX_SKILLS_HOME/skills/cas/scripts/cas_proxy.mjs"; [ -f "$CAS_PROXY" ] || CAS_PROXY="$CLAUDE_SKILLS_HOME/skills/cas/scripts/cas_proxy.mjs"; node "$CAS_PROXY")。 - 可选:传递
--cwd /path/to/workspace以控制 app-server 运行的位置。默认情况下,状态写入~/.codex/cas/state/<workspace-hash>.json。 - 可选:传递
--state-file PATH以覆盖默认状态位置。 - 可选:通过
--server-request-timeout-ms <N>(0 禁用超时)调整转发请求的快速失败行为。 - 可选:控制 v2 审批自动响应(适用于安全的多实例工作器):
--exec-approval auto|accept|acceptForSession|decline|cancel--file-approval auto|accept|acceptForSession|decline|cancel--read-only(同时拒绝执行和文件审批的简写)
- 可选:传递一个或多个
--opt-out-notification-method METHOD标志以抑制连接中已知的嘈杂通知。 - 等待
cas/ready事件。
对于并行 N 实例,首选实例运行器:
run_cas_tool instance-runner --cwd /path/to/workspace --instances N
- 从 cas 技能目录运行
-
通过向代理发送请求来驱动 app-server。
- 向代理 stdin 发送
cas/request消息(方法 + 参数)。 - 代理分配请求 ID(除非您提供),转发给 app-server,并发出
cas/fromServer响应。 - 可选冒烟检查:运行
run_cas_tool smoke-check --cwd /path/to/workspace。
- 向代理 stdin 发送
-
流式和路由通知。
- 消费
cas/fromServer事件并通过threadId/turnId/itemId路由。 - 将代理流视为真相来源;原始消息始终包含在
msg下。
- 消费
-
处理转发的服务器请求。
- 仅当 cas 发出
cas/serverRequest时回复(这些是 cas 未自动处理的服务器请求)。 - 使用相同的
id响应cas/respond。 - 如果您的响应对于类型化 v2 请求格式错误,cas 会发送确定性 JSON-RPC 错误上游,而不是挂起。
- 如果您未及时回复,cas 发出
cas/serverRequestTimeout并使该请求上游失败。 - 审批会自动接受(包括尽力执行策略修改)且不会阻塞您。
- 仅当 cas 发出
-
挖掘会话(可选)。
- 使用
thread/list(游标分页 + 可选的modelProviders/sourceKinds/archived/cwd过滤器)和thread/read(可选includeTurns:true)构建您自己的索引。 - 服务器不是搜索引擎;提取数据并在外部索引。
- 使用
专用 API 助手
当您想要类型化意图而不是原始方法字符串时,使用 scripts/cas_client.mjs 便利包装器:
resumeThread(params)->thread/resumesteerTurn(params)->turn/steerlistExperimentalFeatures(params)->experimentalFeature/list
动态工具 (可选)
如果您选择动态工具,请通过 dynamicTools 在 thread/start 上注册它们(实验性 API 表面)。
当服务器发出 cas/serverRequest 时:
- 对于
method: "item/tool/call",在编排器中运行工具并用cas/respond回复。 - 对于
method: "item/tool/requestUserInput"(实验性),收集答案并返回{ answers: ... }。 - 对于
method: "account/chatgptAuthTokens/refresh",返回刷新令牌或确定性错误。
代理 I/O 契约 (stdin/stdout)
代理本身通过 stdio 讲 JSONL。
stdin -> cas
cas/request发送 JSON-RPC 请求到codex app-server:
{
"type": "cas/request",
"clientRequestId": "任意字符串",
"method": "thread/start",
"params": { "cwd": "/path", "experimentalRawEvents": false }
}
cas/respond回答由 cas 转发的服务器发起的请求:
{
"type": "cas/respond",
"id": 123,
"result": {
"contentItems": [{ "type": "inputText", "text": "..." }],
"success": true
}
}
cas/send转发原始 JSON-RPC 消息到codex app-server(高级逃逸出口):
{
"type": "cas/send",
"msg": { "method": "thread/list", "id": "raw-1", "params": { "cursor": null } }
}
cas/state/get发出当前代理状态。cas/stats/get发出统计快照(运行时间, 队列深度, 计数)。cas/exit关闭代理。
stdout <- cas
cas/ready表示代理完成交握。cas/fromServer为每个来自codex app-server的 JSON 消息发出。cas/toServer为每个发送到codex app-server的 JSON 消息发出(包括自动审批和交握)。cas/serverRequest为需要编排器响应的服务器发起的请求(工具调用, 认证刷新等)发出。cas/serverRequestTimeout在转发的服务器请求因超时失败时发出。cas/stats和cas/ioPaused/cas/ioResumed帮助您监控背压。
所有事件包括:
seq(单调)ts(自纪元以来的毫秒)sessionId(每个代理实例唯一)- 当存在时派生键
threadId/turnId/itemId msg(原始应用服务器消息; 无损)
规范模式来源
使用您安装的 codex 二进制文件生成与您的版本匹配的模式:
codex app-server generate-ts --out DIR
codex app-server generate-json-schema --out DIR
# 如果您需要实验性方法/字段(例如动态工具),包括:
codex app-server generate-ts --experimental --out DIR
codex app-server generate-json-schema --experimental --out DIR
本地参考
阅读 references/codex_app_server_contract.md 以获取控制地图和推荐的路由/响应策略。
资源
references/
实现期间的快速查找控制笔记。
scripts/
可运行的 Node 代理用于编排。
包含:
scripts/cas_proxy.mjs(代理)scripts/cas_client.mjs(JS 包装器:启动代理 + request() + 事件流)scripts/budget_governor.mjs(助手:速率限制 -> 每窗口步调 + 更严格层级钳位)scripts/cas_rate_limits.mjs(CLI: 打印归一化的account/rateLimits/read快照)scripts/cas_example_orchestrator.mjs(示例编排脚本)scripts/cas_instance_runner.mjs(在许多并行 cas 会话/实例中运行一个方法)scripts/cas_smoke_check.mjs(冒烟检查experimentalFeature/list,thread/resume,turn/steer)
Zig CLI 的运行时引导策略镜像 seq:首选已安装的二进制文件;在 macOS 上使用 brew 时,将 brew install tkersey/tap/cas 失败(或不兼容二进制文件)视为硬错误;否则回退到本地 Node 脚本。