AI 编程 Agent 越开越多,怎么在手机上仍看得住终端?run-kit 把 tmux 变成远程控制台
Claude Code、Codex 或其他编程 Agent 真正跑起来后,问题往往不在“能不能再开一个”,而在“我现在到底该看哪一个”。一个窗格在跑测试,另一个等权限确认,第三个已经完成却没人收尾;离开电脑后,这些状态又重新藏回了工作站里的 tmux。
run-kit 是一个 MIT 许可证的开源终端控制台。它不试图成为另一个 Agent 编排器:核心是把既有 tmux 会话和窗格变成浏览器可访问的界面,并提供面向工作树的启动流程。这个边界很重要——无论窗格里运行的是 Agent、构建、REPL、SSH 还是 htop,run-kit 都只把它当作终端;因此不必依赖某一家 Agent 的私有协议,也不需要额外数据库保存状态。
先解决“观察面”,不要先重写 Agent
很多“多 Agent 面板”会分析模型输出、接管任务分派,甚至要求改造整个工作流。run-kit 的切入点更轻:状态从 tmux 和文件系统读取,浏览器只是一个远程控制台。你仍然按熟悉的方式在本机开 tmux、运行 CLI;只是多了一个能从笔记本或手机浏览器查看和操作窗格的入口。
这特别适合以下场景:
- 一台开发机上同时有多个代码库、多个长任务;
- 需要短暂离开桌面,但想知道 Agent 是否卡在提问或权限确认;
- 用 Git worktree 并行处理独立任务,希望每个工作区都有可见的终端;
- 希望远程查看构建和测试日志,却不把终端历史交给第三方托管服务。
在实际工作流里,远程可见性最好服务于可复现的工程状态,而不是制造另一个“全知全能”的总控台。例如,给每项并行任务保留明确的分支名、worktree 目录、测试命令与日志入口;在 Board 中把“正在改代码”“等待人工决策”“正在跑验证”分开。这样手机上看到一个窗格时,能立刻判断它属于哪条交付路径,而不必依赖模型的自然语言摘要来猜测上下文。
另一个常见误区是把浏览器控制台当成无人值守权限。即使能从远端输入命令,生产环境变更、凭据访问和合并操作仍应沿用原本的审批、最小权限与审计机制。run-kit 让终端更容易抵达,并没有改变命令本身的影响范围;把高风险操作留在受控流程中,才能避免“随时可看”演变为“随时可误操作”。
它不是远程执行平台,也不会替你判断一个 Agent 的改动是否正确。把这种“可观测与访问层”同 Agent 的权限、评审和测试门禁分开,能避免一个仪表盘拥有过多职责。
从 tmux 到浏览器的最小路径
项目提供的推荐安装方式会安装整个 shll 工具集;run-kit 依赖同工具集中的 wt 来支持 worktree 流程。完成安装后,可以先启动本地面板:
curl -fsSL https://shll.ai/install | sh run-kit daemon start open http://localhost:3000
在 tmux 中启动一个会话后,run-kit riff 会创建供 Agent 使用的工作区;README 说明此流程需要 wt 在 PATH 中,且机器上已经有可用的 Agent CLI。遇到依赖、tmux 或环境问题时,不要猜配置,先运行项目提供的诊断命令:
tmux new -s work run-kit doctor run-kit riff
这里有两个容易混淆的点。第一,riff 是启动工作区的辅助流程,并不意味着 run-kit 只能运行 Agent;任何现有 tmux pane 都能出现在控制台。第二,面板的状态来自运行中的 tmux,因此它不是跨重启的作业队列:终端断开不会杀死会话,但 daemon 终止或机器重启后,内存中的会话与回滚缓冲本身不会被它“永久保存”。需要可靠任务恢复时,仍应使用 Git、CI、日志和可重放的脚本。
让“等待人”成为可见信号
对于 Agent,最有价值的状态通常不是“正在输出 token”,而是“它需要你”。run-kit 的可选 agent-setup 会为 Claude Code 的用户级配置写入由项目管理的 hooks;这些 hook 在生命周期事件发生时,把 active、waiting 或 idle 状态写到 tmux pane option。面板据此展示:任务正在进行、正等待权限/回答,还是已经完成。
run-kit agent-setup # 需要移除项目写入的条目时: run-kit agent-setup --uninstall
安装前应先看命令展示的配置差异。尤其在共享开发机或已有自定义 hooks 的环境中,hook 是会影响开发流程的配置,而不是纯 UI 偏好。项目说明该命令会在写入前询问确认,并且重新执行会更新它自己管理的条目;不过,Agent 已经启动的会话通常需要重启,才会读取新的 hook 配置。
这种设计也提示一个实践原则:把“Agent 需要人工”定义为单独状态,而不是把所有静默都当作故障。比如测试运行十分钟与等待一个权限弹窗,在远程浏览器里看起来都可能没有新输出;有了 waiting 状态,才知道何时值得拿起手机干预。
多窗格不是列表:用 Board 看并行任务
当项目从“看一个会话”进入“看一组会话”,run-kit 的 Board 提供跨 tmux server 的窗格看板。可以把窗口固定到具名 Board;同一 Board 会并排渲染这些窗格,手机上则以单窗格滑动方式呈现。固定关系写在 tmux 的 window option 中,因此不是某个浏览器 tab 私有的临时列表。
一个实用的分组方式是按交付风险而非按模型分组:一个 Board 放迁移与部署日志,另一个放代码审查和测试,第三个才放实验性 Agent。这样即使某个模型 CLI 更换,关注的仍是“哪一组任务可能需要我”,而不是某个供应商的界面。
远程访问先收窄网络边界
在局域网外访问本地终端,便利和风险会同时上升。README 给出的移动端方案是通过 Tailscale 的 HTTPS 服务暴露本地 :3000,而不是直接把开发机端口公开到互联网:
tailscale serve --bg http://localhost:3000
随后在 tailnet 内用 HTTPS 地址打开面板。这样做的原因不只是在手机上“能访问”:浏览器的剪贴板等能力需要安全上下文,而终端控制台本身也不应成为无认证的公网入口。部署前还应核对 Tailscale 的设备与 ACL;不要因为 run-kit 默认只监听本地就顺手改成公网绑定。
run-kit 还提供本地服务转发的通知命令,适合让脚本在部署完成或任务结束时提醒已订阅的浏览器:
run-kit notify "deploy finished" --title "CI"
项目将该命令设计为 fail-silent:本地服务不可达时不会阻塞调用脚本。这适合作为“提醒增强”,但不应作为 CI 成功与否的唯一记录;真正的结果仍应由 CI 状态、日志和制品保存来判断。
用现有运维习惯把它纳入日常
把 run-kit 引入团队前,可以先写一张很小的运行约定:哪些 tmux session 是个人实验,哪些对应共享环境;哪些 Board 可以被远程访问;每种任务完成时应留下什么证据。一个简单做法是让每个 worktree 的首条 pane 标题包含分支或工单标识,并把测试命令、服务地址写进仓库的开发文档。这样在远程面板上看到失败输出时,能快速回到正确目录复现,而不是在手机上直接做高风险修复。
还要把生命周期拆开看。tmux 负责让进程在客户端断开后继续运行;run-kit 负责显示与进入这些会话;Git worktree 负责把并行修改隔离;CI 和代码评审负责判定交付是否可靠。它们彼此配合,但没有任何一个组件替代其余部分。尤其是长期任务,应该把关键进展写入提交、Issue 或外部日志,而不是只留在某个仍可能被清理的 scrollback 中。
如果团队已经使用 Tailscale,也建议先限制在少量已登记设备和私有 tailnet 内测试移动访问,再根据实际需要设计 ACL。远程终端的价值在于缩短“看到问题—回到工作站处理”的路径,而不是把开发机扩展成随处可用的公共跳板。访问边界越清晰,面板越能放心地承担日常观察工作。
适合谁,不适合谁
如果你想要的是集中托管的任务队列、自动重试、成本统计或模型路由,run-kit 并非替代品;它不调度 Agent,也不解析其输出。反过来,如果你的工作已经扎根于 tmux,而痛点是并行工作树和远程可见性,它的低侵入性反而是优势:先保持现有终端习惯,再把“看得到、点得进、知道何时等待人”补上。
最稳妥的落地顺序是先在本机启动 daemon,观察一个非关键 tmux 会话;确认 doctor 的结果和 worktree 依赖;再为单台个人设备启用 Tailscale HTTPS;最后才考虑启用 Agent 生命周期 hooks。把访问面、Agent 状态与代码质量门禁分层,远程控制台才会成为并行开发的减压器,而不是新的不透明控制面。