nova-cli-fifo-worker v0.1.0

零轮询
FIFO 通知机制

Claude Code 如何瞬间感知 Codex 和 OpenCode 任务完成 — 不浪费一个 token。

向下滚动开始学习
01

等待的困境

当你让 Claude Code 调度外部 CLI 工具时,总得有人等着。问题是:怎么等?

组件之间的对话
C
Claude Code
Codex,帮我分析一下那个 API 的响应类型。
X
Codex
收到!稍等一下...
C
Claude Code
好了吗?...好了吗?...好了吗?
X
Codex
刚做完!但你一直在问我...
💡
核心问题:Claude Code、Codex、OpenCode 是独立的进程,它们不共享内存,也没有内置的「我做完了」信号。那 Claude Code 怎么知道助手们什么时候完成?
02

三代方案的演进

就像从信箱演进到即时通讯。

🔄
第一代:轮询
每 2 秒检查一次文件。就像每隔 2 分钟跑去看一次信箱有没有信。
while [ ! -f done.txt ]; do sleep 2 # 浪费时间 done
延迟: 1-2s | 额外 token: 0 | 不优雅
🤖
第二代:Agent 包装
用 Claude Agent 包装 Codex/OpenCode。原生推送,但你要付一个 Haiku 的钱来跑一条 bash 命令。
Agent({ prompt: "run codex...", model: "haiku" # 浪费 ~2000 token })
延迟: ~0ms | 额外 token: 2000+ | 太贵
🚀
第三代:FIFO
命名管道,读取端阻塞直到写入端发送数据。像气动传输管 — 即时送达,零能耗。
mkfifo /tmp/signal # 创建管道 cat /tmp/signal # 阻塞直到有数据
延迟: ~0ms | 额外 token: 0 | 完美
03

FIFO:气动传输管

FIFO 是一种特殊文件,像气动传输管一样连接两个进程。

Claude Code
cat /tmp/fifo
⏸️
OS 内核
阻塞读取端
⬅️
Codex/OpenCode
echo > /tmp/fifo
点击「下一步」查看 FIFO 工作原理
代码 mkfifo /tmp/fifo-codex-task1 # 读取端(Claude Code) cat /tmp/fifo-codex-task1 # ^^ 在这里阻塞,CPU 占用为 0 # 写入端(Codex hook) echo "done" > /tmp/fifo-codex-task1 # ^^ 立即唤醒读取端
白话解释 创建一根叫「fifo-codex-task1」的气动管 Claude Code 把耳朵贴在管子上 安静地等待,什么都不做,什么都不消耗 ...时间流逝,Codex 在干活... Codex 对着管子喊「搞定了!」 Claude Code 瞬间听到,继续工作
📐
关键洞察:不同于轮询(反复消耗 CPU 检查)或 Agent 包装(消耗 token),FIFO 利用 OS 内核来完成等待。完全免费。
04

谁往管道里喊话?

每个 CLI 都有自己的 hook 系统。两者都写入同一个 FIFO。

X
Codex
~/.codex/hooks.json
使用 JSON 配置,监听 Stop 事件:
{ "hooks": { "Stop": [{ "hooks": [{ "type": "command", "command": "echo DONE > $FIFO" }] }] } }
O
OpenCode
~/.config/opencode/plugins/
使用 TypeScript 插件,监听 session.idle 事件:
export const Plugin = async () => ({ event: async ({ event }) => { if (event.type === "session.idle") writeFileSync(fifo, signal) } })
💡
不同的门,同一个信箱。Codex 用 JSON 配置,OpenCode 用 TypeScript 插件 — 但两者都将相同格式的 JSON 信号写入同一个 FIFO。Claude Code 不在乎是谁写的。
05

完整流程

观看基于 FIFO 的 Worker 通知的完整生命周期。

mkfifo
cat fifo
(后台)
tmux 分屏
Codex 执行
Stop hook
写入 FIFO
收到通知!
点击追踪信号传递路径
脚本 # 第 1 步:创建管道 WORKER=task1 mkfifo /tmp/fifo-codex-$WORKER # 第 2 步:后台监听 cat /tmp/fifo-codex-$WORKER # 第 3 步:tmux 分屏启动 tmux split-window -h -p 40 \ "CODEX_WORKER_ID=$WORKER \ codex exec 'prompt'; sleep 30" # 第 4 步:Hook 触发 → FIFO 写入 # 第 5 步:cat 返回 → 收到通知!
发生了什么 为「task1」创建一根通信管道 在管道上开始监听 (后台运行,零消耗) 在右侧打开一个新的 tmux 面板 在那里启动 Codex,带上 Worker ID 用户可以实时看到 Codex 在工作 Codex 完成 → 它的 Stop hook 触发 信号通过管道传递 Claude Code 瞬间唤醒 → 读取结果
06

扩展:并发多 Worker

每个 Worker 有自己的管道。就像前台接待员有多条电话线。

并发 Worker 编排
C
Claude Code(指挥)
我需要同时做三件事。创建管道中...
X
Codex Worker A
正在分析 API 类型... 🔍
O
OpenCode Worker B
正在检查测试覆盖率... 🧪
O
OpenCode Worker C
正在检查文档时效性... 📝
X
Codex Worker A
搞定!信号已通过管道发送 ✅
O
OpenCode Worker C
完成!我的管道信号也发了 ✅
O
OpenCode Worker B
我也好了!三根管道全部送达 ✅
C
Claude Code(指挥)
三个信号全收到。开始汇总结果... 🎯
# 为每个 worker 创建管道 for W in codex-a opencode-b opencode-c; do mkfifo /tmp/fifo-$W # run_in_background: cat /tmp/fifo-$W done # 每个 worker 独立完成 # 每个写入各自的 FIFO # Claude Code 分别收到通知
07

检验你的理解

Q1:为什么 FIFO 比让 Claude Code 每 2 秒轮询一次文件更好?
没错!OS 内核会让读取进程休眠。数据到达时,内核将其唤醒。等待期间零 CPU 消耗 — 这就是阻塞 I/O 的魔力。
不太对。关键优势不在于速度或磁盘 — 而是 OS 内核代替你等待,不需要 CPU 周期或轮询循环。
Q2:一个 Codex Worker 刚完成任务。什么触发了 FIFO 写入?
对!每个 CLI 使用自己的原生 hook 系统。Codex 的 Stop 事件(在 hooks.json 中)触发一条命令写入 FIFO。通知来自 CLI 自身。
通知来自 CLI 内部。Codex 有一个「Stop」hook 事件,在任务完成时触发 — 这个 hook 负责写入 FIFO。
Q3:你需要 Codex 和 OpenCode 并发运行。要创建几个 FIFO?
每个 Worker 有自己的 FIFO(如 /tmp/fifo-codex-a、/tmp/fifo-opencode-b)。Claude Code 独立监听每一个,这样可以追踪哪个 Worker 完成了。
每个 Worker 需要自己的 FIFO!共享会导致竞态条件。就像多条电话线 — 每个来电者一条。
08

完整架构

方案额外 LLM Token延迟依赖
轮询(while sleep)01-2 秒tmux
Agent 包装(Haiku)~2000+~0ms
FIFO(本方案)0~0mstmux + hook
🏗️
技术栈
信号
FIFO
展示
tmux
Codex Hook
Stop
OpenCode Hook
session.idle
监听器
run_in_background

零轮询。零 token。瞬时通知。

nova-cli-fifo-worker v0.1.0 — Built with Claude Code