











现在我的 tmux 里常年开着好几个 AI Agent:这个 session 里 Claude Code 在改 bug,那个 session 里 pi 在整理笔记,另一个窗口里还有一个在跑长任务。Agent 干活的时候人可以去做别的事,但问题也随之而来——我得隔一会儿就把窗口挨个切一遍,看看谁跑完了、谁正被权限确认框卡住干等着我。窗口一多,这件事就变得又烦又容易漏。
我真正想要的东西很简单:一眼看到所有 Agent 的状态。在干活的、等我输入的、已经闲下来的,各是哪几个,在哪个 pane 里。
在这之前我试过一些别的办法。比如用 Stop hook 在 Agent 结束时发系统通知,也试过让 Agent 往 IRC 频道里发消息。它们都能用,但都没有解决本质问题:我要知道的是当前状况,而通知只能反映某个时间点的状况。
脱节是这样发生的:通知说「任务完成了」,但如果我当时没有理会,而是后来直接切到对应终端继续发消息,Agent 就又跑起来了——通知列表里躺着的那条「已完成」从此与现实脱节。事件流没有「撤回」和「更新」,它只会越积越多,而我永远无法确定哪条还作数。
IRC 的问题还要多一层:消息要 Agent 自己发,这意味着上报这件事本身要挤占它的上下文——要在提示词里交代清楚、要在恰当的时机想起来发、发的内容还会混进后续对话里,造成上下文污染。为了旁观 Agent 的状态而去打扰 Agent 本身,这个方向从根上就不太对。
所以结论是:我需要的不是事件推送,而是一个随时反映现实的状态视图——它应该从外部观察得来,不依赖 Agent 的自觉,也永远不会过期。
这个需求已经有人解决过了:Herdr(在新标签页打开) 是一个专门为 coding agent 设计的终端运行时,它的侧边栏就能显示每个 pane 里 Agent 的状态。我翻了它的源码,发现状态检测的实现相当讲究,是一套「证据驱动」的机制:
❯,工作时终端标题会出现盲文旋转符。规则带优先级、区域切分和布尔组合,还处理了大量边角情况(比如浏览历史记录的界面要冻结状态,不能误判)。这套机制在实践中被打磨得很成熟,尤其是那些 manifest 规则,全是踩坑踩出来的。
试用下来,Herdr 本身却没能留住我,原因说起来有点微妙:操作手感。它的快捷键和 tmux 不完全一样,长期养成的肌肉记忆时不时就会按错;想完全退出它也不太方便。这类终端复用器是典型的「手感产品」——每天要摸几百次的东西,别扭一点点都会被无限放大。
于是想法就变成了:机制是好机制,但我不需要换一个运行时。Agent 就跑在我现有的 tmux 里,我只需要一个「旁观者」——把 Herdr 的检测机制搬出来,做成一个独立的只读监控器。
技术上这条路出乎意料地顺:Herdr 检测所需的三样输入,tmux 全都有现成的原语可以对应。它读的「终端底部缓冲」就是 tmux capture-pane -p 给出的可见屏幕(而且不受用户在 copy-mode 里翻页的影响);它用的 OSC 终端标题就是 #{pane_title};进程识别从 #{pane_pid} 出发用 macOS 的 proc_pidinfo 一路就能查下去。Herdr 是 Apache-2.0 的,19 份 manifest 规则文件可以原样拿来用,只要自己实现一个语义兼容的规则引擎。
这个项目从头到尾由 Claude Fable 5(Claude Code)完成,整个过程在同一个会话里:
PREFIX 的传统 Makefile。中途还有个意外收获:它跑第一版进程识别时发现我的 tmux pane 里全是识别不出 Agent 的 koshell——我的 shell 包装器会再分配一层嵌套 PTY,Agent 实际运行在内层 tty 上。它当场定位了原因,加了「沿不同 tty 的子进程下钻」的逻辑才解决。这种环境特有的坑,事先做计划时根本想不到。
成品就是 tmux-agent-watch(在新标签页打开):一个 Rust 写的 TUI,每两秒轮询一次,以 session → window → pane 的树状结构只展示包含 Agent 的分支,用红绿灯标注状态——🔴 被卡住等输入、🟢 正在干活、⚪ 空闲。它对 tmux 严格只读(只用 list-panes 和 capture-pane),不改任何 Agent 的配置。检测不准的时候,还有个 --explain %N 模式能打印出引擎看到的屏幕内容和每条规则的求值过程,排查误判非常好用。
对我来说,这件事最有意思的地方在于分工:Herdr 的作者积累了「怎么从屏幕上认出 Agent 状态」这个真正难的知识,开源协议允许这份知识被复用;而把它移植到另一个形态的工程活,一次会话就让 AI 干完了。我出的是需求、四个决策和验收,剩下的——包括读懂别人的源码——都不用自己动手。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。