跳至正文
浏览章节

无头运行

用 --print 在管道上跑一个回合、三种输出格式、stdin 上的宿主协议,以及 JSON-RPC 服务器。

一个回合,一个退出码

--print 跑一个回合然后退出。还是同一个二进制、同一个内核;不同的只有界面。

bingo --print "summarise the changes in src/"

不给提示词参数时,整个 stdin 就是提示词:

git diff | bingo --print "review this diff"
cat prompt.txt | bingo --print

只要 stdin 或 stdout 不是终端,即使没有 --print,bingo 也会无头运行——被重定向的 一次运行绝不会去抢屏幕。

退出码

码含义
0回合完成
1回合失败、提交被拒,或会话在它底下关闭了
130回合被打断

输出格式

--output-format 说的是 stdout 上放什么。

text         prose on stdout, everything else on stderr  (default)
json         one bingo Frame per line on stdout, nothing else
stream-json  Claude Code's envelope, one object per line  (ADR-0007)

text 是给人或给 shell 管道用的:stdout 上只有答案,别无他物。错误和通知走 stderr——有人在读时是散文,程序在读时是 [error] code=… msg=…。

json 是 bingo 自己的事件流,序列化之后的样子。每一行是内核发布时那个样子的一个 Frame,所以宿主可以用其他每个界面都在用的那个 reducer 去折叠它们。如果你是在 bingo 之上而不是围着它做东西,这就是该解析的格式——见 事件流。

stream-json 是给那些已经在驱动 claude -p --output-format stream-json 的宿主 用的兼容编码器。它是同一批帧的有损投影,绝不是第二套事件模型:先是一行 system/init,回合运行期间是 assistant 和 user 行,最后一行 result 带着 is_error、num_turns、duration_ms 和 usage。bingo 填不了的字段会被略去而不是 编造,而 result 行的成本是 0.0,因为这里没有任何东西给一个回合定价。

驱动多个回合:宿主协议

--input-format stream-json 把 stdin 变成 Claude Code 的宿主协议:一行一个 JSON 对象,一句提示一个回合,直到 stdin 关闭且每一句提示都被回答。

bingo --print --input-format stream-json --output-format stream-json

一行提示长这样:

{"type":"user","message":{"role":"user","content":"read src/lib.rs"},"parent_tool_use_id":null}

控制请求走同一条路。{"type":"control_request",…,"request": {"subtype":"interrupt"}} 停下正在跑的回合,并以一个 control_response 作答。这个 界面无法履行的 subtype 会得到一个错误而不是沉默,所以宿主绝不会等一个不会来的回复。

--input-format stream-json 是无头协议,需要 --print。少了它,这次运行会被拒绝, 理由是 --input-format stream-json is a headless protocol: it needs --print。

回答权限提问

键盘前没有人时,一个没人能回答的问题会被拒绝:bingo 带着理由否决它,或者在这个问题 没有否决可给时取消它。回合诚实地继续或失败;它绝不挂住。

--permission-prompt-tool stdio 则把这些问题交给协议另一端的宿主。一个 can_use_tool 请求带着工具名和它的输入发出去,由宿主的 control_response 决定——只有 宿主明明白白放行了,工具才会跑。错误响应、缺失的裁决和不认识的裁决,一律算否决。

bingo --print --input-format stream-json --permission-prompt-tool stdio

它需要一条协议来接收答复。单独给出时,这次运行会被拒绝,理由是 --permission-prompt-tool needs --input-format stream-json: there is no other way for an answer to arrive。

更钝的那些工具在无头下照样能用:--permission-mode、 --allowed-tools 'Bash(git status:*)' 和 --dangerously-skip-permissions。 见设置与权限。

在管道上要紧的其他 flag

flag它做什么
--max-turns <N>跑够这么多轮模型之后停下这个回合
--cwd <path>会话的工作目录
--session-id <id>给会话命名的一个不透明的键,给按它路由的宿主用
--continue / --resume <id>重新打开一个会话,而不是新开一个
--settings <path>压在用户层、项目层和本地层之上的又一个设置文件
--mcp-config <path>一个 JSON 文件,它的 mcpServers 会为这次运行加进来
--provider / --model为这次运行挑提供方和模型

JSON-RPC 服务器

对于 GUI、IDE,或任何驱动会话的时间长于一个回合的东西,bingo serve 在 NDJSON 上说 JSON-RPC 2.0(ADR-0007)。

bingo serve --stdio

一个客户端,一行一条消息,在 stdin 和 stdout 上。stdout 上除了 JSON-RPC 消息什么 都没有;每一条诊断都走 stderr。这些方法与内核自己的宿主 API 一一对应——先 initialize,然后 session/open、session/submit、session/answer 和其余的——而事件 作为 event 通知到达,原样携带一个 Frame。写操作立刻返回 {};结果稍后作为一个 IntentAck 事件到达,它的 intent 就是客户端生成的那个 id。

--stdio 是今天仅有的传输方式,不给它是一个错误: serve needs a transport: --stdio is the one there is。

完整的方法列表和已提交的 schema 在 Schema 与协议。