一个人同时带三四个编码 Agent 的时候,最先崩掉的不是模型,而是你的注意力:谁卡在等审批、谁刚跑完、谁报错了,全靠切窗口逐个看一遍。tmux 能把窗格平铺得很整齐,但它不理解窗格里那个进程正在想什么;各家 Agent 自己做 Web 控制台,又把人从终端里拉出去。tuios 的做法是把「知道你的 Agent 在干什么」做成终端窗口管理器本身的能力:它在窗格里检测出 Claude Code、Codex、Gemini CLI 等命令行 harness,把 working、needs_input、done、errored 这些状态渲染到标题栏与侧栏,再把所有等待你处理的事项收进一个统一收件箱。本教程从装好命令行开始,一路走到「同一条提示分发给多个 Agent 并行跑」的舰队模式与脚本化控制。文中命令以官方站点 tuios.dev 当前版本为准(写稿时版本号为 v0.10.1)。
Step 1:装上它,跑起来,先记住八个键
tuios 是一个用 Go 写成的终端多路复用器加窗口管理器,MIT 协议,官方为 Linux、macOS、Windows、FreeBSD、OpenBSD 都提供了预编译包,Homebrew、AUR、Nix、Docker 与 go install 路线齐备。装好之后直接运行 tuios,它会顺手拉起后台 daemon 并把你接入一个会话——这一步很关键,正是因为会话由 daemon 而不是由你的终端窗口持有,你关掉终端窗口之后窗格里的进程还活着,回头还能从这台或另一台机器上重新挂回去。不想引入常驻进程时,可以用独立模式跑一次性的会话,代价是失去 detach 之后的持久性。
# 安装(四条路线任选)
brew install tuios # Homebrew(macOS / Linux)
curl -fsSL https://raw.githubusercontent.com/Gaurav-Gosain/tuios/main/install.sh | bash
go install github.com/Gaurav-Gosain/tuios/cmd/tuios@latest
nix run github:Gaurav-Gosain/tuios
# 跑起来:自动拉起 daemon 并接入会话
tuios
# 独立模式(不要常驻 daemon 时用)
tuios --standalone
# 之后要升级
tuios update
官方给出的「够用一天」的八个键位是:n 新建窗格、i 或回车进入终端模式、Ctrl+B 然后 Esc 回到窗口模式、t 切换平铺、Ctrl+P 命令面板、Ctrl+B 然后 d 脱离但保持运行、? 帮助,外加 Ctrl+B i 打开收件箱。记不住也没关系,Ctrl+P 命令面板能模糊搜到几乎所有动作,这是它比传统多路复用器友好的地方。想先看效果再决定要不要装,官方还提供了浏览器里的 WASM 版学习环境。
# 键位速查(前缀键默认为 Ctrl+B)
tuios # 启动并接入会话
Ctrl+B d # 脱离,会话继续跑
Ctrl+B i # 打开统一收件箱
Ctrl+P # 命令面板(记不住键位时的万能出口)
tuios keybinds list # 列出全部键位
# 想先体验?浏览器里就有 WASM 版:
# https://tuios.dev/learn
版本陷阱:项目仍在 0.x 迭代,daemon 通信协议在大版本之间会变——官方在发布说明里明确要求升级后重启 daemon,否则新版客户端连旧版 daemon 会出现莫名的行为不一致。升级流程请固定为:装新二进制 → 结束旧 daemon → 重新运行 tuios。另外 tmux 深度用户要接受一个现实:它的配置是 TOML 而不是 tmux.conf,内置的 tmux 垫片只解决「工具兼容」(让 Claude Code 的 agent teams 之类依赖 tmux 命令的照常工作),不会迁移你的肌肉记忆。
Step 2:把 Agent 状态点亮——装集成
tuios 判定一个窗格里「这个进程在干什么」有七种证据来源,按可信度从高到低依次是:Agent 主动上报(用 tuios set-agent-state 命令,也是仅有的能可靠说出「在等人」的来源)、程序打印的 OSC 7501 状态报文、daemon 读 Agent harness 写的记录文件、Agent 打印的转义序列、屏幕文字匹配规则、前台进程识别,以及「刚才还在工作现在沉默了」这种卡死推断。其中低可信来源不能覆盖高可信来源的结论,只有屏幕规则在看到权限弹窗时,可以在过期的「工作中」声明之上标出「在等人」。没有装集成时,daemon 仍然每两秒扫一次前台进程,内置二十四种 Agent 命令行的清单,能识别并穿透 sh -c、timeout、npx、uvx、mise exec 这类包装层——但纯进程识别只能告诉你「这里有个 Agent」,说不出它在等你。
# 给单个 harness 装集成
tuios integration install claude-code # 也支持 codex / gemini-cli / opencode / kilo / amp …
# 一键给本机所有已装 harness 装上
tuios integration install --all
# 排集成的状态(installed / out of date / not installed / cannot read)
tuios integration status
tuios doctor agents
# 卸载只会移除 tuios 自己写进去的内容
tuios integration uninstall claude-code
装好之后,窗格里就有六种状态了:none(不是 Agent 或没有上报)、working(工作中,显示实心圆点)、needs_input(被人挡住了,等你处理)、idle(没在干也没被挡)、done(跑完了但你还没看过,看过之后就变回 idle)、errored(出错停住了)、unknown(有 Agent 但没人说它在干什么)。其中 needs_input 与 errored 是两种需要你出手的状态,脚本接口会把它们统一报成「需要你」(needs_you),你不必分别处理。
# 看单个窗格与整个会话的状态
tuios get-agent-state -w build # 追加 --json 拿到结构化字段
tuios list-agents # 本会话所有 Agent 窗格
tuios list-agents --all # 含未被识别为 Agent 的窗格
tuios list-agents --all-hosts # 跨所有已登记机器
# 阻塞等待某个 Agent 需要人(适合写进外层脚本)
tuios wait-for agent-state -s work --until needs_input
tuios wait-for agent-state -w build --until idle,done --timeout 600000
# 自己的脚本也可以主动上报状态
tuios set-agent-state working -m "running the test suite"
tuios set-agent-state needs_input -m "waiting for approval to push"
tuios set-agent-state none # 清除
状态不一定准,别拿它当审批凭证:如果你只靠进程识别没装集成,needs_input 多半不会出现,界面上看起来一片岁月静好,实际窗格里的 Agent 可能已经在授权弹窗上卡了十分钟。装完集成后用 tuios integration status 确认是 installed 而不是 out of date,再开始依赖这些状态做判断。
Step 3:一个收件箱装下所有「等你」
这是并行跑多个 Agent 时最值钱的一个设计。Ctrl+B i 打开的收件箱里,汇总了每一个会话里所有正等着你处理的事项:等待批准的工具调用、Agent 主动问人的问题、抛出来的错误,以及已经跑完但你还没去看的那轮对话。你可以就地答复、延后处理(snooze)或者直接忽略,误操作还能撤销。对「一次开五个 Agent 处理五个仓库」的场景来说,这把「逐个切窗口敲批准」压缩成了「在一个列表里连按几次回车」。
# 收件箱入口
Ctrl+B i # 列出所有等待处理项
Ctrl+B A # 打开 Agents 设置页(安装/更新/卸载集成)
# 命令行侧等价能力
tuios list-agents # 谁需要你
tuios wait-for agent-state --until needs_input # 等到有人需要你
# 让 Agent 自己查询和应答(需 --mcp 或 --mcp-write)
tuios --skill inbox # 给 Agent 看的对应操作指南
有意思的是它的安全边界。官方把「回答一个被挂起的审批」「回答 ask-human 提问」「忽略或延后某个收件箱条目」「以你的名义写一条评审意见或排队回复」这几件事定义为只能由真人完成:即便窗格里的进程持有 nonce,通过这些通道发出的请求也会被拒绝;用 send-keys 敲进去的答复同样不被收件箱接受。换句话说,你可以让 Agent 帮你观察与整理,但不能让 Agent 替自己批自己的高风险操作——这条边界值得在团队规范里照抄。
别把「批」这件事也外包出去:受保护输入的设计就是在提醒你——把答复 Agent 提问的能力交出去,等于把「允许执行危险操作」的权限交出去。可以自动化的是「发现谁在等我、把人叫过来」,不该自动化的是「替我按那个批准键」。
Step 4:舰队模式——同一条提示发给多个 Agent
如果你不确定哪个模型或哪家 harness 更适合手头这个任务,舰队模式是最实用的验证方式:把同一句提示分发给多个 Agent,让它们各自在独立的 git worktree 里动手,跑完再比谁的结果好。独立 worktree 是关键——多个 Agent 在同一份工作区里改同样的文件,后果通常是互相覆盖到面目全非。有了各自的沙箱目录,它们真正物理隔离,你可以放心让三家同时开工,之后只把优胜者的分支合回去。
# 把同一条提示分发给多个 Agent(各自独立 git worktree)
tuios fan "给这个函数补齐边界用例的单测" \
--agents claude-code,codex,gemini-cli # 具体参数名以 tuios fan --help 为准
# 开了 --mcp-write 之后,Agent 侧也有对应工具
# send_text / send_keys / ask_agent / respond / fan
# 给 Agent 看的分步指南
tuios --skill fleet
Step 5:会话持久化与跨机器接管
因为会话由 daemon 持有,你可以 Ctrl+B d 脱离本地终端、合上笔记本,过一会儿用同一台机器或其他机器重新挂回去,窗格里的 Agent 与它正在跑的任务都还在。跨机器这一步靠 SSH:先用 tuios hosts add 把远端机器登记一次,之后就能在这个客户端里直接挂到那台机器的会话上,或者只把某个窗格跑在远端。这对「白天在办公室看、晚上在家接着看」的长任务非常实用。
# 登记一台远端机器(一次)
tuios hosts add work-box --ssh [email protected]
# 之后直接接管
tuios attach -t work-box:main # 基础命名形态以 tuios attach --help 为准
tuios list-agents --all-hosts # 跨机器查看谁需要你
# 只看会话
tuios ls
tuios attach -d <name> # 接管并把其他客户端挤下线
跨机即跨权限:登记远端主机意味着这台机器上正在跑的 Agent(以及它们拿到的凭证)可以从你的客户端被操作。只登记你信得过的机器,SSH 走密钥且收敛可登录范围;在共享机器上跑着高权限 Agent 的会话不要开放远程接管。
Step 6:把窗格变成可编排的资源
最后一层是给自动化留的门:除了图形界面,tuios 提供了 send-keys、capture-pane、wait-for 等子命令与一套 JSON 控制协议,还能录制回放一整段操作(tape)。配合 Step 2 里的 wait-for agent-state,你就能写出「拉起三个窗格 → 各发一条任务 → 阻塞等到有人需要审批 → 通知我」这种外层编排脚本,把多 Agent 协作从「手动看管」升级成「有反馈信号的流水线」。再往前一步,你自己的脚本也可以用 set-agent-state 主动上报状态,让 CI 任务在界面上跟 Agent 一样有 working、needs_input、done 的生命周期。
#!/usr/bin/env bash
set -euo pipefail
# 建会话 → 开三个窗格 → 各派一个 Agent
tuios new-session -s triage
tuios new-window -s triage -n lint "claude '修 lint 报错'"
tuios new-window -s triage -n test "codex '补全测试'"
tuios new-window -s triage -n docs "gemini '更新文档'"
# 阻塞等待:谁需要人,谁就先浮出来
tuios wait-for agent-state -s triage --until needs_input
notify-send "tuios: 有 Agent 在等你审批"
# 读取窗格内容做快照归档
tuios capture-pane -t triage:test > /tmp/test-run.log
仍然是一条新赛道:项目处在 0.x,API、配置项与子命令拼写都可能随版本调整,别把关键生产流水线一次性押上去。稳妥路线是先在次要项目上并行跑一两周,确认升级成本和团队习惯都能接受,再考虑作为日常主力;同时对 0.x 软件的固有风险保持预期——它可能很快变好,也可能很快变样。
常见问题速查
| 现象 | 原因与处理 |
|---|---|
| 窗格里明明有 Agent,状态栏却是空的 | 没装集成;跑 tuios integration install --all 后重启对应 Agent |
| integration status 显示 out of date | 旧版装过,重跑 tuios integration install <harness> 更新;opencode 还需重启客户端 |
| 升级后界面行为错乱 | daemon 协议变了;装完新二进制要重启 daemon 再运行 tuios |
| 界面字符缺了一半、图形不显示 | 终端太老;换 Ghostty / Kitty / WezTerm,或加 --ascii-only 退到纯字符模式 |
| 多个 Agent 互相覆盖改动 | 别让它们共享工作区;用舰队模式的独立 git worktree 再合并优胜分支 |
| 收件箱里的审批项无法用 send-keys 通过 | 设计如此——答复属于受保护输入,只能由真人在客户端完成 |
| 看不到 tuios fan 子命令 | 版本差异,先用 tuios --help 与 tuios fan --help 确认,必要时升级到最新版 |