一份讲完所有事:怎么跑起来、怎么看会话列表、怎么在手机上操作终端,以及怎么开启 可选功能——会话恢复、锁屏通知、语音输入。
tmux-next 是一个很小的 tmux 网页客户端。它把你机器上跑着的 tmux 会话列出来,让你在 浏览器里打开任意一个。写它是为了在手机上随时看一眼编码 agent(Claude Code、opencode 或 pi)——但没有任何东西是 agent 专属的:任何 tmux 会话都能用。
底层是 tmux 的 control mode,不是屏幕录制。浏览器用 xterm.js 渲染单个 pane; 每次连接挂一个一次性的 grouped session,断开时销毁。重连会从 tmux 重新抓取整个屏幕—— 没有回放、没有缓冲,尺寸也总是对的。
需要 tmux 3.2 以上、Bun 1.0 以上,以及 macOS 或 Linux。
bunx tmux-next
它监听 http://127.0.0.1:7682/,列出本机的所有 tmux 会话。命令行选项:
# 端口和地址 bunx tmux-next --port 9000 --host 127.0.0.1 # 帮助 / 版本 bunx tmux-next --help bunx tmux-next --version
从手机访问需要在前面加一层——它自己没有登录,设计上就该只绑 localhost。 Tailscale 指引是最简单的私有方案; Caddy 指引把它放到公网域名后面、加一层真正的登录。
能访问到它的人,就能在你机器上执行命令——它给出去的是一个 shell。 别把它绑到公网接口就完事。看文末的注意安全。
会话列表、制品和通知历史是三个并列的页面。页头左侧的分段控件在它们之间切换;右侧的
图标依次是铃铛(通知订阅)、齿轮(语言和配色)和 +(新建会话)。
每个会话卡片显示:
点卡片打开会话。卡片上的 ⋯ 按钮打开操作菜单:置顶(保持在
最上面,刷新也不丢)和 结束会话——这会把里面跑着的进程杀掉,所以先要
你确认。
顶部栏有会话名(点它可以改名)、连接状态,以及结束按钮。
底部工具条放着手机键盘没有的键。最下面一行一直在—— Esc Tab ⇧Tab ↑ ↓ ⏎——点 ▴ 展开上面的 两行:Ctrl、^C、左右方向键,以及工具:
滚动:在屏幕上拖动,滚的是程序自己的历史,就像鼠标滚轮一样。不理会鼠标 的程序会自动退回到 PgUp/PgDn。
断线:连接会自动重连,屏幕从 tmux 重建。里面跑的东西从头到尾没被打断—— 它活在 tmux 里,不活在页面上。
点页头 +。新建页面有几个部分:
PATH 上的 agent 会显示为划掉,而不是让你选。~ 逐层往下,可以筛选,也可以当场新建文件夹。
目录在 URL 里,所以返回键按原路一层层往回走,new.html?dir=/some/project
还能存成链接。PROJ-1088。
agent 生成了要看的东西——图表、示意图、HTML 报告——把它丢进
~/.tmux-next/gallery/,就会出现在制品页里:图片网格展示,
HTML 和 SVG 就地沙箱渲染,每个文件都能下载。不用把文件倒腾到别的机器。
把任务交给 agent,人去做别的事,回头才发现它早就停了。Web Push 补上这个空档:手机收到 系统通知——锁着屏、页面关着都行——点一下就跳到那个会话。
需要两件事:
三种时刻会推送:会话结束、agent 打完一轮在等你、agent 需要你确认。agent 自己发的话 原样透传,不翻译。
要求和限制。浏览器只在 HTTPS(或 localhost)
下才给通知权限——走反向代理访问就满足。在 iPhone 上要先「添加到主屏幕」,
再从那个图标订阅:iOS 只给装成 PWA 的应用推送(iOS 16.4+)。每个会话每 30 秒最多一条推送
(会话结束除外)。所有数据都存在本机——~/.tmux-next/vapid.json 放密钥对,
订阅在 ~/.tmux-next/push-subscriptions/——触发推送的接口也只接受本机连接。
每条推送都会记在通知历史页里,手机上一划没了的,在这里还能找到。
tmux server 挂了——重启、崩溃——里面的会话就没了。但 agent 的记录在磁盘上,对话可以重建。 装上配套 hook,tmux-next 就会主动提出帮你恢复:
bunx tmux-next hook
它把 hook 脚本放进 ~/.claude/hooks/,在 ~/.claude/settings.json
里注册——先备份、幂等、绝不覆盖你已有的配置。需要 jq(通知还需要
curl)。之后每个新开在 tmux 里的 agent 都会把 {name, id, cwd}
记到 ~/.tmux-next/sessions/——在磁盘上,tmux server 死了也还在。
tmux 重启后,列表顶部出现「N 个上次的会话可恢复」。点恢复,每个会话就地重建——
tmux new-session 在记录的目录里,用 agent 自己的参数续上(claude --resume
<uuid>、pi --session <uuid>、opencode --session
<ses_…>)——对话就回来了。只有装 hook 之后新开的会话算数;你通过
应用主动结束的会话不会拿来恢复。
升级包之后,重跑一遍 bunx tmux-next hook。
脚本是复制进 ~/.claude/hooks/ 的,npm 没法原地更新——而旧 hook 会
静默失效,把恢复和通知一起带走。服务启动时会检查并打印一行,如果装上的副本和它带的
不一样。
每次 hook 调用都会记到 ~/.tmux-next/hook-events.jsonl——来了哪种事件、是不是
子 agent 发的、归到哪个会话、有没有推送。绝不含消息文本。
TMUX_NEXT_HOOK_LOG=off 就什么都不记。
在手机上念提示词比打快多了。它是可选的,配了 key 才开(识别走火山引擎,费用记你账上):
bunx tmux-next asr <key>
key 存在 ~/.tmux-next/asr.json(权限 0600),内容是单个 JSON 对象——
{ "key": "…", "resourceId": "volc.bigasr.auc_turbo" }。
resourceId 指定识别模型;默认值就对了,除非你知道要换。这个文件也可以手改——
想把同一个 key 指向更新的模型,改一个字段就行,不用重跑命令。
不用重启:服务端每次请求都现读这个文件,写好后刷新终端页,工具条里就会出现麦克风。 换 key 就重跑命令(或重写文件);想关掉语音输入,删掉这个文件。点麦克风,面板占据键盘的 位置——只能有一个;录音按钮开/停,没有时长限制。
说出来的话攒成一份可编辑的草稿,而不是一句句直接进终端——说话是一阵一阵的: 说一句、看看落下来什么、改掉识别错的人名、再说下一句。一次发送把整份草稿 发出去并按回车;面板留着说下一句。点进草稿可以选择下一句插入的位置;选中一段再说话, 会像打字一样替换掉它。
音频到服务器就直接转发上游——绝不下盘——key 也从不离开这台机器。录音需要安全上下文,
所以要走 HTTPS 反向代理访问,别用网络上的裸 http://。
齿轮打开一个小面板:语言(中文或英文——首次访问按浏览器的语言猜)和 配色(四套预设:Tokyo Night、Catppuccin Mocha、One Dark、Nord,选之前 先给你看色板和样例)。两个都立即生效,不用刷新。
语言和配色按机器存(~/.tmux-next/language.json、
~/.tmux-next/theme.json),手机和桌面一致。字号是唯一按设备存的——
屏幕多大和机器长什么样是两回事。
终端工具条的按键也在这里:设置 → 调整顺序决定每个键放哪——常显行、编辑行 (Ctrl、^C、方向键)、工具行(图片、粘贴、复制、字号)。按键按真实排列展开成三行方块(和 工具条本身一样),按住某个键在整块面板上任意拖动(跨行也行),其他键让开——跟整理手机主屏 图标同一个手势。角标显示它在当前设备上的点击次数,按证据排而不是靠猜。排列按设备保存,和 字号一样;▴ 展开键永远固定在常显行最前。恢复默认把工具条还原成出厂顺序。
tmux-next 故意没有自己的登录。能访问到它的人就能 attach 每个会话、随便 敲命令——它给出去的是一个 shell,所以请像对待 SSH 一样对待访问: