ARTICLE · 1294990
同时开五个 AI 编程助手,你怎么知道谁在等你
我们现在开发经常会多个 agent 同时运行,比如:你手上三个活儿并行,一个要重构认证模块,一个要修 CI 上的偶发失败,一个要给新接口补文档。于是你开了五个终端窗口,分别扔给 Claude Code、Codex、Gemini CLI。
一般情况下我们看进度:来回切窗口,看哪个在等你。
窗口 1 在跑测试,窗口 2 弹了个权限确认你没看见,已经卡了四分钟,窗口 3 早干完了但你不知道,窗口 4 报错了退出,窗口 5 在等你回答一个问题。
你上班的八小时里,有相当一部分花在「轮询」上。你变成了一个调度器,而且还是性能很差的那种。
TUIOS 想解决的正是这个问题。它不是又一个 tmux 换皮,而是一个把 Agent 的状态当一等公民的终端窗口管理器。
这个项目 6k+ star,MIT 协议,Go 写的,一年前建的仓,最近的版本号是 0.11.0。
TUIOS 的 GitHub 仓库首页
它到底是什么
一句话:一个知道面板里在跑什么的终端多路复用器。
如果你用过 tmux 或 zellij,基础能力它都有:平铺分屏、九个工作区、会话常驻、detach 之后继续跑。这些是及格线,不是卖点。
真正不一样的是三件事:
第一,每个面板有 Agent 状态。 面板里跑的是 Claude Code、Codex 还是你自己的 htop,它会分类;如果是 Agent,它还会告诉你这个 Agent 现在是「在干活」「在等你」「干完了」还是「出错了」。
第二,所有「在等你」的事汇成一个收件箱。 跨会话、跨机器,Ctrl+B i 一处看完,还能原地回答,不用切到那个面板。
第三,Agent 之间能互相发消息。 这点后面细说,它是这个项目最有争议也最有想象力的部分。
用起来的感觉大概是:以前你有五个终端,现在你有五个 Agent 的下属,加一个它们向你的汇报界面。
状态是怎么「知道」的
这是整个项目技术上最有意思的地方。
一个终端模拟器,原则上只能看到字节流。它不知道这些字符是 vim 画的还是 Claude Code 画的,更不知道程序内部是不是正在等一个人输入 y。
TUIOS 的解法是:不信任何单一来源,而是排一个可信度座次。
七级可信度:谁说的话更算数
从最可信到最不可信:
① report —— Agent 自己上报。 这是最准的来源,也是唯一能可靠说出「我在等你批准」的来源。实现方式是装 hook:tuios integration install claude-code 会往 Claude Code 自己的配置文件里加几条钩子,Agent 在关键时刻调用 tuios agent-hook,把状态告诉 TUIOS。
文档写得很克制:安装器只添加条目,保留文件里其他所有内容,并且第一次修改前会存一份 .tuios.bak;遇到解析不了的文件会拒绝写入,而不是重写。
② program —— 程序自己打印 OSC 7501。 任何程序(不只是 Agent)都能用这个转义序列报告自己的状态:
bash tuios status blocked --kind permission --app deploy --msg 'Approve deploy to production?'
这样连一个部署脚本、一次 brew 升级,都能出现在侧栏和收件箱里,跟 Agent 一个待遇。
③ transcript —— 读会话记录。 有些 Agent 框架会把对话写进文件,守护进程直接去读。
④ osc —— 终端转义序列。 比如 OSC 9;4 的进度条:设了进度条就算「干活中」,清掉算「空闲」,错误态算「出错」。
⑤ screen —— 屏幕规则。 匹配面板底部的文字。这条存在的理由是:Agent 停在权限弹窗上的时候,往往什么都不打印——没输出、没标题、没进度。唯一的证据就是屏幕上的那几行字。
Codex 的规则清单就是去读标题里的 Action Required。Crush 的权限弹窗是个带边框的方框,规则会要求所有字符串都在同一个方框内才匹配,避免把对话记录里引用的同样文字误判成弹窗。
⑥ detect —— 进程识别。 每两秒看一次前台进程,认 24 种 Agent CLI 的清单,还会穿过 sh -c、timeout、npx、uvx、mise exec 这些包装。你想加自己的,扔个 TOML 文件到 ~/.config/tuios/harnesses/ 就行。
⑦ stall —— 停顿计时。 本来报「干活中」,然后 30 秒没动静,守护进程最后看一眼屏幕,没有规则命中就降级成「不知道」。
座次的规则很硬:只能覆盖同级或更低级,绝不能盖掉更高级的。
所以屏幕规则不会去覆盖 Agent 自己的说法。唯一例外是——屏幕规则看到权限弹窗时,可以盖过一条过期的「干活中」,弹窗消失后旧说法自动回来。
这条设计对应的工程现实是:一个面板同一时刻可能有六个来源各说各话,不给优先级,状态就会来回跳,最后没人信。宁可承认不知道,也不要让低可信来源假装知道。
文档里有一句话我觉得最实在:「检测能判断 Agent 存在,但它说不出 Agent 是不是在等你。」
状态长什么样
七个状态,六个形状:
TUIOS 官方截图:四个平铺面板,每个标题带状态标记,右侧栏列出 Agent 状态
● 干活中、▲ 等你、○ 空闲、■ 完成、× 出错、□ 不知道。
这里有个细节值得单独说:它是用不同形状,不是同一个形状换颜色。
理由很直接:黑白截图、投影仪、色弱用户、SSH 到一台配色很怪的终端——这些场景下颜色都会失效,形状不会。项目还在旁边留了一列 ASCII,给 --ascii-only 的用户用,是 *、!、o、#、x、?。
这类决定看着小,但它说明作者真的在用户的实际环境里跑过,而不是在自己的 iTerm2 里调色调得很爽就发布了。
收件箱:把「轮询」变成「收件」
状态是内部机制,收件箱才是你每天真正用的东西。
收件箱:所有 Agent 的等待汇到一处
这是 TUIOS 官方界面的样子:
TUIOS 官方截图:收件箱界面
列表按「在等你」的紧急程度排,每条带面板名、它要什么、等了多久。有这几类:批准请求、问题、计划、邮件、报错、待看的完成轮次。
处理方式很干脆:空格打开弹窗原文,a 批准,d 拒绝,1-9 选那个选项,R 带理由拒绝。不用切到那个面板去。
有两个设计我要专门拎出来。
第一,批准前先把弹窗再读一遍。 在你按下批准键之前,守护进程会重新读一次那个弹窗,如果内容变了就拒绝这个操作。两个人同时答同一题,先答的算。
这条防的是什么?防的是「你看了 A,实际批准了 B」。在多 Agent 并发的场景里,弹窗内容在你移开视线的几秒内变化,是完全可能的。
第二,危险命令要按两次。
有一份内置的风险规则,会去匹配 shell 命令的每一段,穿透 sudo、env、sh -c、$( )、反引号、eval 这些包装。命中就不只是按一下的事:
rm -r 带 -f、git push --force、git reset --hard、git clean -f、curl 管道进 shell、sudo、dd of=、mkfs、chmod -R 777、DROP TABLE、terraform apply/destroy、kubectl delete、npm publish……
还有一条覆盖面很大的:写出工作目录之外的任何文件。
命中之后,1 和 2 需要同一键在三秒内按第二次才生效,第一次按下什么都不发,并告诉你这个提示什么时候失效。
项目自己的定性是:这是减速带,不是沙箱。 把 rm 藏进变量里、写个别名、套层脚本,规则就过了。真正的边界还是 Agent 框架自己的权限系统。这些规则只保证「允许一个危险操作需要两次刻意的按键」。
我欣赏这个尺度感。安全工具最怕的是宣称自己解决了问题,结果用户以为有了护栏就不再看了。
Agent 互相发消息,以及一次真实的翻车
项目里有个功能叫 fleet:tuios fan 会把同一个提示词同时扔给几个不同的 Agent,各自在自己的 git worktree 里干活,最多 8 路,然后你可以对比结果。
配上 tuios send-agent-message 和 tuios ask-agent,Agent 之间能互相发消息、互相提问,一个 Agent 等另一个 Agent 的答复。
这是这个项目最有想象力的地方,也是它踩过最狠的坑。
v0.11.0 修了一个权限绕过漏洞,编号 GHSA-78rj-pghh-vh42。
漏洞原理:一个面板替另一个 Agent 按了同意
漏洞链路是这样的:
在默认配置 agents.permissions mode = 「open」 下,每个面板都自带 admin 权限。当时还剩下的唯一一道防线,是一条「禁止往正在等提示的面板里打字」的检查。
但这条检查看的是目标面板的状态。而「设置 Agent 状态」是另一个动词,它没有限制成「只能设自己的面板」。
于是两步就够了:
第一步,把目标面板的状态从 needs_input 改成 working——这样那道拒绝打字的检查就不触发了。
第二步,往里打 1 和 Enter——批准了那个权限弹窗。
公告的原话:一个被提示词注入的 Agent,可以静默批准同一守护进程上任意其他 Agent 的权限提示,全程没有人在场。
修复方式也很干净:把 set-agent-state 也绑到调用者自己的面板上,跟受限连接早就在用的 scopeSelf 规则对齐。
我觉得这个漏洞比项目本身更值得读。传统终端里不存在这个问题,因为终端里根本没有「多个程序互相知道对方在等什么」这个层。一旦你引入了跨进程的 Agent 协作,就同时引入了一个进程可以冒充另一个进程的通道。
而默认配置给每个面板 admin,这个选择在单 Agent 场景下很省事,在多 Agent 场景下就是漏洞的温床。这个教训不只属于 TUIOS。
架构:为什么关掉窗口 Agent 不会死
架构:守护进程拿住 PTY,客户端只是屏幕
TUIOS 默认跑成守护进程模式。守护进程持有所有 PTY 和终端模拟器,客户端通过 Unix socket 接进来,只是负责画。
这个拆分带来的直接好处是:detach 之后什么都没停。 你 Ctrl+B d 回家,第二天在公司 SSH 进来 attach,五个 Agent 还在原地,只有你不在的时候它们干了什么需要你补看。
它也支持多客户端看同一个会话——本地终端、SSH、浏览器(tuios-web)同时接上,看到的是同一份状态。
线协议这块有个细节体现出作者的洁癖:
单帧最大 16 MB;嵌套超过 1024 层直接拒;类型定义超过 1024 个拒;布局超过 16383 个节点拒;超限的帧跳过不读,这样连接还能保持同步,不会因为一个坏帧就断掉。
同一条规则也适用于跨机联邦的对端守护进程。翻译一下:一个被投毒的守护进程,或者一台对端机器,撑不爆客户端的内存。
技术栈是 Go + Bubble Tea v2 + Lipgloss v2,用的是 Model-View-Update。终端模拟器是自研纯 Go 实现,没有 cgo,所以 go install 和交叉编译直接能用——这是它敢往 Linux、macOS、Windows、FreeBSD、OpenBSD 都发预编译包的前提。另外还有一套用 libghostty-vt 的构建,两套模拟器用差分测试喂同样的字节流比对结果。
渲染是事件驱动的:PTY 读协程有数据了才通知渲染,没有固定频率的空转。空闲时几乎不耗 CPU,这对一个要常驻一整天的工具很重要。
怎么装,怎么开始
bash brew install tuios
也可以用 AUR、Nix、go install、Docker,或者直接下载预编译包。第一次跑会建一个叫 session-0 的会话。
进去之后是窗口管理模式:按键用来操作窗口,不发给 shell。按 n 开一个面板,按 i 进终端模式,这时按键才发给程序。按 Alt+Esc 回窗口管理模式。
这里有个设计我觉得对:单独按 Esc 仍然是发给程序的,所以 vim 这类全屏程序不会因为你想退出一层模式就跟着退。
常用键:
n 新面板(窗口模式) Ctrl+B 然后 d detach Alt+1..9 切工作区 Ctrl+P 命令面板,搜所有动作 Ctrl+B i 收件箱 Ctrl+B o 跳到最老的一条待办 Ctrl+B ? 帮助忘了键怎么办?Ctrl+B 按下去停在半空等半秒,会弹出一个面板列出这个前缀接下来能接什么键。这个交互比翻文档快多了。
要跑 Agent 并让它报状态,装集成:
bash tuios integration install claude-code tuios integration install --all tuios doctor agents
十二个框架能上报状态(Claude Code、Codex、Copilot、Cursor Agent、Gemini CLI、opencode、Kilo、Amp、Kimi Code CLI、Pi、oh-my-pi、Qwen Code),另外七个只上报会话 id,用来崩溃恢复时续上对话。
不想装集成也行:TUIOS 会退回用进程识别和屏幕规则,能判断有没有 Agent、大概在不在干活,但判断不了「它在等你」。
如果你只是想要一个 tmux 替代品,配置里 [agents] enabled = false 一次关掉所有 Agent 功能。
值不值得换
我先说三个不适合的情况。
你只用一个大模型、一次只跑一个任务。 那收件箱是空的,状态列是装饰,你付的所有复杂度都没有回报,直接用 tmux 就完了。
你的工作流深度绑定 tmux 的脚本。 TUIOS 有个 tmux 兼容层,能让那些驱动 tmux 的工具(比如 Claude Code 的 agent teams)在 TUIOS 里跑,但那是补丁不是原生。真重度依赖 tmux 生态,迁移成本不低。
你在 Windows 上用。 有预编译包,但项目的主场明显是 macOS 和 Linux,文档里 macOS 的 Alt 键、Docker Desktop 的坑都占了大量篇幅。
再说适合的。
同时跑两三个以上 Agent 的人。 这是唯一能真正解决问题的人群。状态列和收件箱把「轮询」这件事从你的工作流里删掉了,这是实打实的时间。
需要在多台机器上调度 Agent 的人。tuios hosts 加 SSH 联邦,tuios attach --host build 能把另一台机器上的会话画在本地,收件箱里也能看到那边的等待项。这个能力在 tmux 上要自己搭一堆东西。
喜欢折腾终端外观的人。 主题编辑器、keybind 预设(tmux/screen/zellij 三套,切过去键位就是你熟悉的)、kitty 图形协议、sixel、九种工作区、BSP/master-stack/横向无限三种布局。这块做得相当厚。
几个得提前知道的:
它还很年轻。 v0.11.0,一个月内发了十几个版本,功能面在快速扩张。仓库 31 个未关闭 issue,最近的一个权限漏洞影响 v0.10.1 及以前——用之前先确认版本,低于 0.11.0 的建议直接升级。
默认权限配置偏宽松。agents.permissions 默认是 open,每个面板都是 admin。如果你要多 Agent 协作,认真看一下 grants 相关的文档,别默认它替你考虑了安全。
装 hook 会改你的配置文件。 它会备份、会拒绝写入解析不了的文件、卸载时只删自己写的条目——这些做得不错,但它确实在改 Claude Code 这些工具自己的配置文件,你心里要有数。
我的判断
TUIOS 的价值不在于它是「更好的 tmux」。它的屏幕渲染、鼠标交互、键位密度都做得很好,但那是一堆终端项目在卷的事。
它真正抓住的是一个新出现的问题:当 AI Agent 变成你日常并行工作的对象之后,终端这个工具从「管理进程」变成了「管理协作者」。
而管理协作者需要的不是更好的分屏,是状态可见性和收敛的待办入口。谁在干活、谁卡住了、谁需要我做一个决定——这三件事解决了,你才敢并行开更多 Agent。
那个七级可信度座次表,我觉得是整份文档里最有工程味的一页。它承认了一件事:你不可能可靠地知道一个黑盒进程在想什么,所以只能让所有可能的信号源都进来,然后给它们排定优先级,并且明确标出「不知道」。
这比假装自己能看透 Agent 要诚实得多,也实用得多。
项目地址 https://github.com/Gaurav-Gosain/tuios 官网与在线体验(浏览器里跑真应用) https://tuios.dev https://tuios.dev/learn














































































