夜雨聆风学习资料网

ARTICLE · 1106460

tuios:开了 6 个 agent,哪个在等你回话

tuios:开了 6 个 agent,哪个在等你回话
Go 日榜上的 tuios 是个 tmux 替代品,但它真正想解决的是另一件事:终端里挂着一排 agent,你得知道谁在干活、谁卡住了、谁在等你按 y。

/ / NEWS / /

哪个在等你

问个具体的问题。

你现在 tmux 里开了 6 个 pane,每个跑一个 Claude Code 或 Codex。其中一个已经停在权限确认上 20 分钟了,在等你按 y。

是哪一个?

我的答案通常是:不知道,挨个切过去看。切到第四个发现它早就停了,前面白等的 20 分钟就这么没了。

tmux 不知道 pane 里跑的是 agent,它只知道那是一个进程在往屏幕上写字。agent 在思考还是在等人,对 tmux 来说没区别。

今天 Go 日榜上的 tuios 就是冲这个问题来的。仓库 README 第一句:

A terminal window manager that knows what your agents are doing.

单日 +215,总星 4,314,MIT。9 月 27 日发 0.8.0,不到两天又发 0.8.1,一个以安全修复为主的版本。我没装,这篇是读仓库文档和 release notes 读出来的,HEAD 是 317daeb。

6 个 pane,只有一个在等你

/ / NEWS / /

先是一个 tmux 替代品

抛开 agent 的部分,tuios 本身是个完整的终端复用器。Go 写的,基于 Charm 那套 Bubble Tea v2 和 Lipgloss v2,.go 文件加起来 49 万多行(含测试)。

tmux 用户会熟悉的东西它都有:daemon 模式、detach / attach、会话重启后恢复。前缀键默认也是 Ctrl+B。

tmux 没有的它也做了一堆:BSP 平铺、niri 风格的横向滚动布局、vim 式的模态操作、Ctrl+P 命令面板。它支持 kitty 图形协议,README 里说 mpv --vo=kitty 能在 pane 里放视频。渲染是事件驱动的,空闲时 CPU 接近零。

装起来一行:

brew install tuios

这些是地基。真正让它上榜的,是地基上面那层。

/ / NEWS / /

五种状态,一张排名表

tuios 给每个跑 agent 的 pane 标一个状态,常用的是五种:

  • working
    :在干活
  • needs_input
    :在等你
  • idle
    :闲着
  • done
    :这一轮做完了
  • errored
    :出错了

另外还有 none 和 unknown 两个兜底状态,后者的意思是"有 agent,但不知道它在干嘛"。

状态画在 pane 标题上,同时在右侧的侧栏(文档叫 rail)列一行。文档特意说了一句,状态用形状表示,不只靠颜色。色弱的人也能分得清,这个细节挺少见。

状态从哪来?最靠谱的是 agent 自己报。tuios integration install 能给 19 个 harness 装上报告钩子,Claude Code、Codex、Gemini CLI、opencode 都在里面:

tuios integration install claude-code tuios doctor agents

没装钩子的 pane,tuios 会退而求其次:读 agent 自己写的会话记录,看终端发出来的转义序列,用规则匹配屏幕上的字,看前台进程是谁,看多久没输出。

六个来源,谁说了算?代码里是一张排名:report > transcript > osc > screen > detect > stall。低排名的一般盖不掉高排名的,屏幕规则再怎么匹配,也改不了 agent 自己报上来的状态。唯一的例外是屏幕上看到了 needs_input,而 agent 报的状态已经过时,这时屏幕规则可以覆盖。

我觉得这个项目写得最好的一段,是解释为什么用排名不用打分:

a score invites adding weak signals together until they clear a threshold, which is how a directory name in a script path once came to count as an agent.

打分制会诱惑你把一堆弱信号加起来,凑够阈值就算数。他们就被这么坑过:脚本路径里有个目录名,被算成了 agent。

换成排名之后,弱信号永远是弱信号,十个弱信号加起来也还是弱。这是踩过坑才会写的设计,不是拍脑袋拍出来的。

五种状态和来源排名

/ / NEWS / /

Inbox:所有"等你"的东西收到一个地方

标出状态只是第一步。6 个 pane 标了 6 个图标,你还是得扫一眼。

tuios 的第二步是 Inbox。Ctrl+B i 打开,里面是所有会话、所有机器上等你处理的东西:权限确认、agent 问你的问题、agent 之间的邮件、报错、做完的回合。Ctrl+B o 直接跳到最老的那条。

最省事的是能在 Inbox 里直接回答,不用切到那个 pane。按 space 打开那条提示,数字键选选项,a 批准,d 拒绝。另外还有一种更彻底的:在配置里打开 [agents.approvals],让 harness 把审批挂起、整个交给 Inbox,用 1 / 2 / 3 答(允许一次 / 总是允许 / 拒绝):

[agents.approvals] enabled = ["claude-code"]

回到开头那个问题:哪个 agent 在等你?现在答案是按 Ctrl+B o。

还能配一个 hook,agent 进入 needs_input 时推到手机上。人不在电脑前也能知道哪个卡住了。

Inbox 把等你的事排成一列

/ / NEWS / /

agent 之间写信

tuios 还给 agent 之间开了个通信口子,四个命令:

  • tuios send-agent-message
    :往某个 pane 的收件箱投一封信,不碰它的键盘
  • tuios read-agent-messages
    :读信
  • tuios ask-agent
    :直接问一个 agent,等它回答
  • tuios ask-human
    :往你的 Inbox 里塞一道选择题,等你答

agent 互相发消息,最怕的是一个被 prompt 注入的 agent 去指挥另一个。tuios 的防法写得很具体:

  • agent 读到的每封信都被当成不可信数据圈起来,发件人字段只算"声称"
  • pane 不能冒充 human 发信,你本人的回复会带 verified_human 标记
  • pane 不能给自己发信,互相追问成环会被拒,发信频率有限制
  • ask-agent
     遇到正在 needs_input 的 pane 直接拒绝,返回 agent_blocked

最后一条很细。一个 agent 正停在权限确认上,另一个 agent 这时往它输入框里打字,打进去的就不是问题,是对权限确认的回答。

信只存在内存里,每个会话 256 条,daemon 一重启就没了。别拿它当持久化的消息队列用。

agent 之间的信,被圈起来当数据

/ / NEWS / /

fan:一个 prompt 扔给一队 agent

tuios fan 是批量开 agent 的命令:

tuios fan 3 --agent 'claude,codex' 'fix the flaky test in auth_test.go'

开 3 个 git worktree,每个里面起一个 agent,哪个先到输入提示符就先把 prompt 打进去。--agent 可以混着写,3 个会轮流分配成 Claude、Codex、Claude。

跑完之后怎么挑,它也准备了命令:

  • tuios fan compare
    :所有尝试并排看,带改动和最后一次检查结果
  • tuios fan verify SESSION -- CMD
    :同一条测试命令在每个 worktree 里跑一遍
  • tuios fan diff A B
    :两个尝试到底哪里不一样
  • tuios fan keep
    :留一个,删掉其他的,没提交的改动不会丢

还有个很实际的处理:agent 第一次启动常常卡在"选主题""登录"之类的首次运行选项上,prompt 打不进去。tuios 等 30 秒,把它变成一道 Inbox 问题丢给你。

用 Claude Code agent teams 的也有办法。agent teams 默认走 tmux 开队友的 pane,tuios 里没有 tmux,所以它做了个垫片:

tuios tmux-shim -- env CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 claude

Claude Code 看到 TMUX 环境变量,以为自己在 tmux 里,开出来的每个队友其实都是 tuios pane,带状态,进 Inbox。

fan 出三个 worktree,再挑一个留下

/ / NEWS / /

0.8.1:两天后补的安全版

0.8.0 发出去不到两天,0.8.1 就来了。release notes 第一句直接说这是 a security release,顺带也捎了几个新功能。

安全部分管三块:远程访问、pane 权限、pane 输出。我最关心中间那块,也就是"一个 pane 能通过 tuios 做什么"。tuios 有一套 pane 权限,叫 grants,分 read / write / fan / respond / admin 五档。0.8.1 里几条比较硬的:

  • 没有 respond 权限的 pane,不能往另一个正在等 prompt 的 pane 里打字。有 admin 也不行。
  • send-keys
     打进来的按键,Inbox 不认它是回答
  • 配置文件里放宽权限的改动不会立刻生效,要到 tuios 外面跑一次 tuios config apply(或者重启 daemon);收紧的改动立刻生效
  • ssh 相关:带 command= 之类选项的公钥直接拒,ProxyCommand、端口转发这些 ssh 选项也拒

第三条的思路值得抄。agent 在 pane 里能改文件,当然也能改 tuios 的配置文件。如果改完配置立刻生效,agent 就能自己给自己提权。要求在 tuios 之外手动 apply,等于把"放权"这个动作从 agent 够得着的地方挪走了。

放宽要人来,收紧随时可以,这个不对称是对的。

放宽要在外面盖章,收紧立即生效

/ / NEWS / /

写在最后

tuios 的 agent 文档有三千多行。一个终端复用器,光讲 agent 的部分就写了这么长,能看出作者的重心早就不在"复用终端"上了。

它有没有可能替代 tmux?对只开一两个 shell 的人,没必要,tmux 用了十几年,肌肉记忆比什么都值钱。对一天到晚同时挂五六个 agent 的人,值得装上试一个下午。

我比较在意的反而是那段"排名不打分"。现在各种 agent 工具都在做状态检测,多数用的是一堆启发式规则加权。tuios 说它被一个目录名坑过,所以改了设计。

其他家呢?是没被坑过,还是被坑了没发现。

相关学习资料