你在 5 台服务器上跑着 AI 编码会话。它们会停下来问「这条 rm -rf 能跑吗」——
而你在地铁上,SSH 不在手边。
WebAgents 把这些会话收进一个统一的管控台:一个收件箱、一个「批准 / 拒绝」、一条随时能接管的对话流。
Demo 跑的就是生产代码本身,只是数据源换成了编造的演示数据——它连一个 API 请求都不会发出去。

这不是一个"AI 编程工具"。它是你和一群 AI 之间的控制面。
Claude Code 遇到危险命令会停下来等授权。你不在,它就一直等着。一个会话卡住,后面排的活全停。
5 台机、十几个项目。哪台在跑?哪个在等你?你得挨个 SSH 上去看——如果你手边有电脑的话。
终端里起的会话,网页上看不到;网页上起的,回到终端接不上。你被绑在某一端。
六个能力。每一个都能在上面的 Demo 里点开看。
所有服务器的会话一屏尽览。六态模型:运行中 / 等待审批 / 等待输入 / 空闲 / 已完成 / 出错——一眼看出谁在等你。
四类待办统一收口:审批(危险命令)、计划(改动前确认)、提问(AI 在征询)、验收(回合产生了文件变更)。手机推送直达。
Claude Code 与 Codex 并列。两套完全不同的协议(SDK / app-server RPC),在上层收敛成同一个会话模型、同一个审批流。
终端里 claude 起的会话,Web 上只读追踪 + 一键接管;Web 上起的会话,也能释放到终端继续用 --resume 接。同一份会话,两端都能拿。
浏览器里的真 PTY(tmux 支撑 + 手写 WebSocket + xterm.js)。跨 agent 重启持久——部署完回来,你的 vim 还开着。
跨服务器执行历史(按回合组织,不是一行行日志)、agent 重启事件簿(带「当时被杀掉了哪些会话」)、数据层健康看板。
下面五张全部截自 Demo 站点,你可以自己点进去翻。




一个 hub,N 个 agent。远端不开任何入站端口。
这一节是我认为这个项目最值得看的部分。
不是"我有多少功能",而是"它在真实的多机生产环境里坏过哪些次,以及每一次留下了什么"。
下面每一条都是线上真实发生过、并且付出过代价的。
onerror 永不触发、readyState 恒为 OPEN —— 而兜底轮询的判据是「CLOSED 才回退」,那个条件永远等不到。服务端本来有心跳,但发的是 SSE 注释行 : ping ——浏览器根本不把它暴露给 JS。等于装了心跳,线没接。event: ping + 前端心跳看门狗(会话本该活跃却 45s 无字节 → 主动重建)+ visibilitychange 切回前台立刻补拉。看门狗不要求对端配合——"活跃却静默"本身就够,所以对着还没升级的旧 agent 也能自愈。systemctl restart 一下,正在执行的那一回合被拦腰截断——tool_result 已落盘、assistant 的下一回合永远不会来,会话冻在半途,前端把这条悬空的 tool_use 永久渲染成「正在执行 305 秒」。bootId,hub 据此识别重启并记下「当时被杀掉了哪些会话」——那份名单只有重启前那一拍轮询里有,事后再也拿不到。touch、一次 rsync -a、一个备份工具扫过去——会话就被锁死,而用户面前一条出路都没有。canForce,导致「强制接管」按钮永不出现。一台机做 hub,其余机各放一个 agent。
# 1. 主控机:构建前端 + 起 hub cd web && npm ci && npm run build systemctl enable --now web-agents-hub # 2. 每台被管服务器:放一个 agent(零依赖,只是几个 .js) bash server/deploy-agent.sh root@your-node # ↑ 部署前会先查该机有没有正在跑的会话,有就拒绝——不会把你的活干断 # 3. hub 侧建 SSH 隧道接入(远端不用开任何入站端口) systemctl enable --now web-agents-tunnel@your-node