tmuxes 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.node-version +1 -0
- package/.nvmrc +1 -0
- package/.tmp-npm-cache/_cacache/content-v2/sha512/43/27/5e000b8b9c56a6ccc66f709485499f4304e2cb1982582ba571321c07b3ef56fcabd2c671898cc8003365a0485b6fd8e73e7b17b073cec0f7d1628c1a99df +0 -0
- package/.tmp-npm-cache/_cacache/content-v2/sha512/51/cf/4301295d74559ed494bae160d54d8741077f89faebb311882ac065019246951e7b53f3dcb913793c42b331e14c7070c4810c3cdc27a427d103a7db4614e0 +0 -0
- package/.tmp-npm-cache/_cacache/content-v2/sha512/c3/4d/d68a454a916e74c2617f586fbf770981b33811d667c2547eb0e9fc21938f4ee7e98f1ceee4bde8ad8815b5f6efe21b60eee798837d68f51a3340d7e5bb7a +0 -0
- package/.tmp-npm-cache/_cacache/content-v2/sha512/fe/40/2abfbefc96299e8bf714aa91d62607190ae299e102cf5933db2e2904640d65d25d67dbbb6fa2ddc92a17f00b9dbfdf2e37487f67d96ec36c64a285b59a7d +0 -0
- package/.tmp-npm-cache/_cacache/index-v5/27/fe/81a3de6ce7ae3d1e41a3421de20c5629998c4ee5d0ffe2037630f03b03b2 +4 -0
- package/.tmp-npm-cache/_cacache/index-v5/65/22/dd66711f62681fce09aabb2357a2907b4a0c778ac5227c4baf9603fd86e8 +4 -0
- package/.tmp-npm-cache/_update-notifier-last-checked +0 -0
- package/AGENTS.md +15 -0
- package/CLAUDE.md +3 -0
- package/LICENSE +21 -21
- package/README.en.md +304 -0
- package/README.md +299 -295
- package/SECURITY.md +31 -0
- package/{public → client}/index.html +12 -13
- package/client/package.json +29 -0
- package/client/src/App.tsx +123 -0
- package/client/src/activity.ts +5 -0
- package/client/src/api.ts +130 -0
- package/client/src/attention.tsx +157 -0
- package/client/src/components/FileExplorer.tsx +156 -0
- package/client/src/components/FileViewer.tsx +194 -0
- package/client/src/components/SessionRow.tsx +108 -0
- package/client/src/components/SessionTree.tsx +197 -0
- package/client/src/components/SettingsButton.tsx +122 -0
- package/client/src/components/Sidebar.tsx +96 -0
- package/client/src/components/StatusBanner.tsx +31 -0
- package/client/src/components/TargetGroup.tsx +275 -0
- package/client/src/components/TerminalPanel.tsx +192 -0
- package/client/src/folders.ts +245 -0
- package/client/src/hooks/useTerminal.ts +67 -0
- package/client/src/hooks/useTmuxSocket.ts +65 -0
- package/client/src/i18n.ts +213 -0
- package/client/src/main.tsx +17 -0
- package/client/src/settings.tsx +87 -0
- package/client/src/styles.css +723 -0
- package/client/src/types.ts +93 -0
- package/client/src/util.ts +65 -0
- package/client/tsconfig.json +13 -0
- package/client/vite.config.ts +15 -0
- package/fig/fig1.png +0 -0
- package/package.json +28 -61
- package/scripts/prepack.mjs +35 -0
- package/{bin → server/bin}/tmuxes.js +36 -36
- package/server/package.json +61 -0
- package/server/src/agentHooks.ts +120 -0
- package/server/src/agentOutput.ts +36 -0
- package/server/src/agentState.ts +70 -0
- package/server/src/config.ts +31 -0
- package/server/src/exe.ts +34 -0
- package/server/src/exec.ts +61 -0
- package/server/src/files.ts +330 -0
- package/server/src/foldersStore.ts +114 -0
- package/server/src/index.ts +114 -0
- package/server/src/logger.ts +16 -0
- package/{dist/monitor.js → server/src/monitor.ts} +10 -9
- package/server/src/openBrowser.ts +28 -0
- package/{dist/platform.js → server/src/platform.ts} +4 -5
- package/server/src/rest/router.ts +290 -0
- package/server/src/targetCommand.ts +79 -0
- package/server/src/targets.ts +152 -0
- package/server/src/tmux/builder.ts +198 -0
- package/server/src/tmux/formats.ts +95 -0
- package/server/src/tmux/sessions.ts +204 -0
- package/server/src/validate.ts +79 -0
- package/server/src/windowsSsh.ts +239 -0
- package/server/src/winshell/manager.ts +296 -0
- package/server/src/ws/protocol.ts +15 -0
- package/server/src/ws/sshState.ts +36 -0
- package/server/src/ws/terminalSession.ts +207 -0
- package/server/src/ws/wsServer.ts +153 -0
- package/server/src/wsl.ts +38 -0
- package/server/test/agentHooks.test.ts +66 -0
- package/server/test/agentOutput.test.ts +26 -0
- package/server/test/agentState.test.ts +24 -0
- package/server/test/builder.test.ts +162 -0
- package/server/test/files.test.ts +81 -0
- package/server/test/formats.test.ts +123 -0
- package/server/test/monitor.test.ts +25 -0
- package/server/test/validate.test.ts +71 -0
- package/server/test/wsl.test.ts +18 -0
- package/server/tsconfig.json +9 -0
- package/server/vitest.config.ts +12 -0
- package/start.cmd +30 -0
- package/start.command +20 -0
- package/start.sh +20 -0
- package/tsconfig.base.json +19 -0
- package/dist/agentHooks.js +0 -91
- package/dist/agentHooks.js.map +0 -1
- package/dist/agentOutput.js +0 -30
- package/dist/agentOutput.js.map +0 -1
- package/dist/agentState.js +0 -45
- package/dist/agentState.js.map +0 -1
- package/dist/config.js +0 -32
- package/dist/config.js.map +0 -1
- package/dist/exe.js +0 -37
- package/dist/exe.js.map +0 -1
- package/dist/exec.js +0 -43
- package/dist/exec.js.map +0 -1
- package/dist/files.js +0 -243
- package/dist/files.js.map +0 -1
- package/dist/foldersStore.js +0 -103
- package/dist/foldersStore.js.map +0 -1
- package/dist/index.js +0 -117
- package/dist/index.js.map +0 -1
- package/dist/logger.js +0 -16
- package/dist/logger.js.map +0 -1
- package/dist/monitor.js.map +0 -1
- package/dist/openBrowser.js +0 -31
- package/dist/openBrowser.js.map +0 -1
- package/dist/platform.js.map +0 -1
- package/dist/rest/router.js +0 -190
- package/dist/rest/router.js.map +0 -1
- package/dist/targetCommand.js +0 -41
- package/dist/targetCommand.js.map +0 -1
- package/dist/targets.js +0 -131
- package/dist/targets.js.map +0 -1
- package/dist/tmux/builder.js +0 -173
- package/dist/tmux/builder.js.map +0 -1
- package/dist/tmux/formats.js +0 -61
- package/dist/tmux/formats.js.map +0 -1
- package/dist/tmux/sessions.js +0 -157
- package/dist/tmux/sessions.js.map +0 -1
- package/dist/validate.js +0 -65
- package/dist/validate.js.map +0 -1
- package/dist/winshell/manager.js +0 -267
- package/dist/winshell/manager.js.map +0 -1
- package/dist/ws/protocol.js +0 -4
- package/dist/ws/protocol.js.map +0 -1
- package/dist/ws/sshState.js +0 -35
- package/dist/ws/sshState.js.map +0 -1
- package/dist/ws/terminalSession.js +0 -204
- package/dist/ws/terminalSession.js.map +0 -1
- package/dist/ws/wsServer.js +0 -151
- package/dist/ws/wsServer.js.map +0 -1
- package/dist/wsl.js +0 -35
- package/dist/wsl.js.map +0 -1
- package/public/assets/index-BpVrfoZw.js +0 -44
- package/public/assets/index-D_X5SnGx.css +0 -1
package/README.md
CHANGED
|
@@ -1,299 +1,303 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
|
|
3
|
-
# 🖥️ tmuxes
|
|
4
|
-
|
|
5
|
-
**简体中文** | [English](./README.en.md)
|
|
6
|
-
|
|
7
|
-
### 一个浏览器标签页,掌控一整群 CLI coding agent。
|
|
8
|
-
|
|
9
|
-
**Claude Code · Codex · OpenCode · Hermes** —— 每个 agent 独占一个 tmux 会话,
|
|
10
|
-
横跨 **本地 · SSH · WSL**,还自带每个 agent 工作目录的文件浏览器。
|
|
11
|
-
|
|
12
|
-
🔔 **Claude Code / Codex 结束运行、异常停止或需要决策时,浏览器会自动提醒你** —— 侧边栏红/绿状态点 +「结束 / 决策 / 错误」提示 + 提示音 + 后台标签页标题闪烁。再也不用挨个窗格去盯「它还在跑吗」。
|
|
13
|
-
|
|
14
|
-
<p>
|
|
15
|
-
<a href="https://www.npmjs.com/package/tmuxes"><img alt="npm version" src="https://img.shields.io/npm/v/tmuxes?style=flat-square&logo=npm&color=CB3837"></a>
|
|
16
|
-
<img alt="platform" src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows%2011-2b2b2b?style=flat-square">
|
|
17
|
-
<img alt="React" src="https://img.shields.io/badge/React-19-61DAFB?style=flat-square&logo=react&logoColor=black">
|
|
18
|
-
<img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-5-3178C6?style=flat-square&logo=typescript&logoColor=white">
|
|
19
|
-
<img alt="Node.js" src="https://img.shields.io/badge/Node.js-22-339933?style=flat-square&logo=nodedotjs&logoColor=white">
|
|
20
|
-
<img alt="Vite" src="https://img.shields.io/badge/Vite-8-646CFF?style=flat-square&logo=vite&logoColor=white">
|
|
21
|
-
<img alt="tmux" src="https://img.shields.io/badge/tmux-3.x-1BB91F?style=flat-square&logo=tmux&logoColor=white">
|
|
22
|
-
<img alt="xterm.js" src="https://img.shields.io/badge/xterm.js-6-1f6feb?style=flat-square">
|
|
23
|
-
</p>
|
|
24
|
-
|
|
25
|
-
<sub>🔒 仅本机 · ⚡ 一键启动 · 🔔 agent hook 提醒 · 🪟 Windows 上直通 WSL · 🧩 零配置</sub>
|
|
26
|
-
|
|
27
|
-
</div>
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
> **为什么做这个?** 现代编码 agent 都是常驻的终端进程。同时跑好几个,你就开始在一堆窗格、SSH 窗口之间手忙脚乱:
|
|
32
|
-
> 「等等,刚那个是在哪台机器上来着?」**tmuxes** 把它们全塞进一个清爽的网页 UI:
|
|
33
|
-
> 开一个会话、丢进文件夹、看它干活、顺手瞄一眼它正在改的文件 —— 本地还是远程,都是同一个视图。
|
|
34
|
-
|
|
35
|
-
## ✨ 特性亮点
|
|
36
|
-
|
|
37
|
-
| | |
|
|
38
|
-
|---|---|
|
|
39
|
-
| 🧠 **为 agent 而生** | 每个 agent 独占一个 tmux 会话。新建时可带初始命令(比如 `claude` 或 `codex`),选中后右侧就是一个**完全可交互的实时终端**。 |
|
|
40
|
-
| 🔔 **结束 / 决策 / 错误提醒** | 新建会话时初始命令是 `claude` 或 `codex` 会自动接入官方 lifecycle hooks。也可以先进入空 session `cd` 到目标目录,再点终端右上角的 `claude` / `codex` 按钮启动带 hook 的 agent。已展开目标每 5 秒同步一次:红点表示 agent 正在运行,绿点表示已结束、异常停止或正在等你决策;结束运行、需要决策和异常停止会显示不同提示。 |
|
|
41
|
-
| 🌐 **本地 · SSH · WSL · 原生 Windows** | 一个侧边栏同时列出你的本机、`~/.ssh/config` 里的主机、(Windows 上)你的 WSL 发行版,以及(Windows)原生 PowerShell / cmd 会话 —— 全部并排排开。 |
|
|
42
|
-
| 🗂️ **文件夹树** | 像资源管理器一样,把会话拖进**可拖拽的文件夹**里整理。按目标分别持久化到本地。 |
|
|
43
|
-
| 📂 **实时文件浏览 + 编辑** | 侧边栏底部跟随每个会话的**工作目录** —— 点一个代码文件就能把终端一分为二,在下面**直接读和改**(可保存、撤销/重做)。 |
|
|
44
|
-
| 🔁 **真·多端同步** | 基于原生 `tmux attach`:同一个会话开两个标签页,逐键同步、互为镜像。 |
|
|
45
|
-
| ⚙️ **可调** | 侧边栏、终端、文件查看器的字号都能调,**实时生效**、刷新后仍保留。 |
|
|
46
|
-
| 🚀 **一键启动** | 双击 `start.cmd` / `start.command` / `start.sh` → 自动构建、启动、打开浏览器。 |
|
|
47
|
-
|
|
48
|
-
## 🖼️ 长这样
|
|
49
|
-
|
|
50
|
-
<div align="center">
|
|
51
|
-
<img src="https://raw.githubusercontent.com/f1974939505/tmuxes/main/fig/fig1.png" alt="tmuxes 截图 —— 一个标签页掌控一群 CLI agent" width="900">
|
|
52
|
-
</div>
|
|
53
|
-
|
|
54
|
-
## 🏗️ 架构
|
|
55
|
-
|
|
56
|
-
```text
|
|
57
|
-
REST (create · list · rename · kill · cwd · files)
|
|
58
|
-
┌────────────┐ ┌──────────────────────┐ ┌──────────────────────────────────┐
|
|
59
|
-
│ Browser │──▶│ Node · Express · ws │──pty──▶│ tmux (Linux/macOS)│
|
|
60
|
-
│ xterm.js │◀──│ node-pty │──pty──▶│ ssh -tt user@host → tmux (remote)│
|
|
61
|
-
└────────────┘ └──────────────────────┘──pty──▶│ wsl.exe -d <distro> → tmux (Windows)│
|
|
62
|
-
▲ binary bytes ⇄ WebSocket ⇄ JSON control └──────────────────────────────────┘
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
- **`client/`** —— React + Vite + TypeScript,终端基于 [`@xterm/xterm`](https://www.npmjs.com/package/@xterm/xterm)。
|
|
66
|
-
- **`server/`** —— Node + Express + `ws` + `node-pty`。一个小型 REST API 跑短命的 tmux *管理*命令;单个 WebSocket 端点负责交互式 *attach* 的流式传输。
|
|
67
|
-
|
|
68
|
-
> **Windows 上没有原生 tmux?** 没问题。服务端原生运行(node-pty 用 ConPTY),通过 `wsl.exe` 直通你 WSL 发行版里的 tmux。Linux/macOS 上则直接和本地 tmux 通信。远程主机用系统 `ssh` 二进制,复用你已有的 `~/.ssh` 密钥 / `ssh-agent` —— **绝不存储任何密码。**
|
|
69
|
-
|
|
70
|
-
## 📦 用 npm 安装
|
|
71
|
-
|
|
72
|
-
刚刚开用的小家伙还在快速长身体,可能偶尔有 bug,修复更新也会比较快;建议用 `@latest` 总是拿到最新版本。
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
# 一键运行(无需克隆,自动开浏览器):
|
|
76
|
-
npx tmuxes@latest
|
|
77
|
-
|
|
78
|
-
# 或全局安装后用 tmuxes 命令:
|
|
79
|
-
npm install -g tmuxes
|
|
80
|
-
tmuxes # → http://127.0.0.1:7420
|
|
81
|
-
|
|
82
|
-
# 常用参数:
|
|
83
|
-
tmuxes --port 8080 --no-open
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
> 前提:你要连的机器/主机上装了 **tmux**。**Linux** 上 `node-pty` 需现场编译(装 `build-essential` + `python3`);**Windows / macOS** 有预编译二进制,真·一键。详见下方「环境要求」。
|
|
87
|
-
|
|
88
|
-
## 🚀 从源码一键启动(开发用)
|
|
89
|
-
|
|
90
|
-
<table>
|
|
91
|
-
<tr><th>系统</th><th>怎么做</th></tr>
|
|
92
|
-
<tr><td><b>🪟 Windows 11</b></td><td>双击 <b><code>start.cmd</code></b>(或在 Windows Terminal 里运行)。自动装依赖、构建、启动服务,并打开 <code>http://127.0.0.1:7420</code>。你的 WSL 发行版会出现在侧边栏。</td></tr>
|
|
93
|
-
<tr><td><b>🍎 macOS</b></td><td>在访达里双击 <b><code>start.command</code></b> <sub>(首次:右键 → 打开,绕过 Gatekeeper)</sub>。</td></tr>
|
|
94
|
-
<tr><td><b>🐧 Linux</b></td><td>运行 <b><code>./start.sh</code></b>。</td></tr>
|
|
95
|
-
</table>
|
|
96
|
-
|
|
97
|
-
## 🔧 手动运行
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
npm install # node-pty:Win/macOS 有预编译,Linux 从源码编译
|
|
101
|
-
|
|
102
|
-
# 开发 —— Vite 开发服务器 + API,带热更新:
|
|
103
|
-
npm run dev # → http://localhost:5173
|
|
104
|
-
|
|
105
|
-
# 生产 —— 构建客户端,由单进程统一服务:
|
|
106
|
-
npm run build
|
|
107
|
-
npm start # → http://localhost:7420 (设 TMUXES_OPEN=1 可自动打开浏览器)
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## 🔔 启动带 hook 的 Claude Code / Codex
|
|
111
|
-
|
|
112
|
-
tmuxes 目前会给 **Claude Code (`claude`)** 和 **Codex (`codex`)** 自动接入官方 lifecycle hooks,用来判断 agent 是正在运行、已经结束、异常停止,还是正在等你做决策。
|
|
113
|
-
|
|
114
|
-
两种用法:
|
|
115
|
-
|
|
116
|
-
1. 新建 session 时,在初始命令里直接填 `claude` 或 `codex`。
|
|
117
|
-
2. 先新建空 session,进入后在终端里 `cd /你的目标目录`,再点终端右上角的 `claude` / `codex` 按钮。
|
|
118
|
-
|
|
119
|
-
状态含义:
|
|
120
|
-
|
|
121
|
-
- 红点:agent 正在运行。
|
|
122
|
-
- 绿点:agent 已结束、异常停止、正在等你决策,或这个 session 没接入 agent hook。
|
|
123
|
-
- `结束` badge:本轮运行结束。
|
|
124
|
-
- `决策` badge:agent 正在等待权限确认或用户输入。
|
|
125
|
-
- `错误` badge:agent 异常停止,例如 Codex 断流但没有触发 stop hook。tmuxes 会在已展开目标的 5 秒同步里扫描 running agent 的 pane 尾部并把这类错误纠正为提醒状态。
|
|
126
|
-
|
|
127
|
-
注意:右上角按钮本质上是向当前 tmux pane 发送一条带 hook 的 `claude` / `codex` 命令。不要在当前 pane 里已有程序正在接收输入时点击它。裸 `cc` 常常是系统 C 编译器,tmuxes 不会默认把它当作 Claude Code。原生 Windows shell 没有 tmux session option,因此不支持这套 hook 状态。
|
|
128
|
-
|
|
129
|
-
## 🧩 目标(Targets)
|
|
130
|
-
|
|
131
|
-
- **本地** *(Linux/macOS)* —— 你机器上的 tmux。Windows 上不显示。
|
|
132
|
-
- **Windows 本机终端** *(Windows)* —— 服务端用 ConPTY 直接开 PowerShell / cmd 等本机 shell(自动探测 `pwsh` → `powershell` → `cmd` → Git Bash),新建时可在下拉里选 shell。会话随**服务端进程**存活(刷新 / 重连 / 多标签都不丢,重启服务端会丢);这类会话没有 tmux 工作目录,故隐藏底部文件浏览器。
|
|
133
|
-
- **WSL 发行版** *(Windows)* —— 通过 `wsl.exe -l -q` 自动发现;每个发行版一个目标。发行版里必须装了 tmux。
|
|
134
|
-
- **SSH 主机** —— 从你的 `~/.ssh/config` 的 `Host` 条目里发现(跳过通配符)。也可显式添加:
|
|
135
|
-
|
|
136
|
-
```bash
|
|
137
|
-
TMUXES_HOSTS="alice@web1,bob@db2:2222" npm run dev # Linux / macOS
|
|
138
|
-
set TMUXES_HOSTS=alice@web1,bob@db2:2222 && npm run dev # Windows cmd
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
密钥 / agent 认证必须在普通 shell 里已经能用。全新主机请先在普通终端里接受一次它的 host key。为避免短命管理命令反复新建 SSH 连接,类 Unix 平台会通过 OpenSSH `ControlMaster` / `ControlPersist` 长期复用同一条 SSH
|
|
142
|
-
|
|
143
|
-
## 💻 环境要求
|
|
144
|
-
|
|
145
|
-
所有平台都需要 **Node 22.12+**(项目版本文件固定为 22.22.2)和 **npm 10+**。其余:
|
|
146
|
-
|
|
147
|
-
<details>
|
|
148
|
-
<summary><b>🪟 Windows 11</b></summary>
|
|
149
|
-
|
|
150
|
-
- WSL2 且至少一个发行版,并在其中装好 **tmux**(`sudo apt install tmux`)。
|
|
151
|
-
- 内置的 OpenSSH 客户端覆盖 SSH 目标。
|
|
152
|
-
- node-pty 提供**预编译 Windows 二进制** —— 不需要编译器。
|
|
153
|
-
|
|
154
|
-
</details>
|
|
155
|
-
|
|
156
|
-
<details>
|
|
157
|
-
<summary><b>🍎 macOS</b></summary>
|
|
158
|
-
|
|
159
|
-
- `tmux` 在 `PATH` 上(`brew install tmux`)。
|
|
160
|
-
- node-pty 提供**预编译 darwin 二进制**。
|
|
161
|
-
- 从访达启动却找不到 tmux?确保 Homebrew 的 bin 目录在 GUI 的 `PATH` 里。
|
|
162
|
-
|
|
163
|
-
</details>
|
|
164
|
-
|
|
165
|
-
<details>
|
|
166
|
-
<summary><b>🐧 Linux</b></summary>
|
|
167
|
-
|
|
168
|
-
- `tmux`,外加给 node-pty 的 C/C++ 工具链 + Python 3(**没有 Linux 预编译 —— 安装时现场编译**):
|
|
169
|
-
```bash
|
|
170
|
-
sudo apt-get install -y build-essential python3 tmux
|
|
171
|
-
```
|
|
172
|
-
- WSL 小坑:`node-gyp` 会用 `PATH` 上的任意 `python3`。如果坏掉的 conda Python 把构建搞挂了:
|
|
173
|
-
```bash
|
|
174
|
-
npm config set python /usr/bin/python3
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
</details>
|
|
178
|
-
|
|
179
|
-
<details>
|
|
180
|
-
<summary><b>(备选)把服务端跑在 WSL 内部</b></summary>
|
|
181
|
-
|
|
182
|
-
在 Windows 上,你也可以把整个服务端跑在 WSL **内部**(像 Linux 一样),然后在 Windows 上开浏览器 —— WSL2 会转发 `localhost`。一键启动脚本用的是「原生 Windows + `wsl.exe`」方案,这样能在一个地方同时覆盖 SSH 目标和多个发行版。
|
|
183
|
-
|
|
184
|
-
</details>
|
|
185
|
-
|
|
186
|
-
## 🔒 安全
|
|
187
|
-
|
|
188
|
-
> ⚠️ **tmuxes 会把完整的 shell 访问权交给任何能连上它的人。** 它是一个单用户、仅本机的开发工具。
|
|
189
|
-
|
|
190
|
-
设计上它:
|
|
191
|
-
|
|
192
|
-
- 只绑定 **`127.0.0.1`** —— 绑定地址在运行时不可配置,
|
|
193
|
-
- **没有任何认证**,
|
|
194
|
-
- **从不起 shell**(argv 数组 + `shell:false`),并对每个输入做白名单校验,
|
|
195
|
-
- 拒绝 `Origin` 非 localhost 的 WebSocket 升级(防 DNS-rebind),
|
|
196
|
-
- 把文件浏览器 / 编辑器限制在所选 tmux 会话的**当前工作目录**之内。
|
|
197
|
-
|
|
198
|
-
**请勿**对它做反向代理、隧道、端口转发,或暴露到 `0.0.0.0`。机器上任何本地用户都能用它。
|
|
199
|
-
|
|
200
|
-
## 🧪 测试
|
|
201
|
-
|
|
202
|
-
```bash
|
|
203
|
-
npm test # vitest:输入校验、列表解析、ssh/tmux/wsl 的 argv 形状
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## 🐧 tmux 速查表
|
|
207
|
-
|
|
208
|
-
> tmux 的「前缀键」默认是 **`Ctrl+b`**(下面记作 `C-b`)—— 先按它,松开,再按后面的键。
|
|
209
|
-
> 在网页终端里**最常用的是滚动 / 复制模式**(往上看历史输出、复制文字)。
|
|
210
|
-
|
|
211
|
-
### 滚动 & 复制(最常用)
|
|
212
|
-
|
|
213
|
-
| 操作 | 按键 |
|
|
214
|
-
|---|---|
|
|
215
|
-
| 进入复制 / 滚动模式 | `C-b` 然后 `[` |
|
|
216
|
-
| 在模式里上下翻 | `↑ ↓`、`PageUp` / `PageDown` |
|
|
217
|
-
| 开始选择 → 复制 | `Space` 定起点 → 移动光标选中 → `Enter` 复制 |
|
|
218
|
-
| 把复制的内容粘回来 | `C-b` 然后 `]` |
|
|
219
|
-
| 在模式里搜索 | `C-s` 向前 / `C-r` 向后(默认 emacs 风格) |
|
|
220
|
-
| 退出复制 / 滚动模式 | `q` |
|
|
221
|
-
| **开鼠标滚轮**(直接滚轮翻 + 鼠标选) | 执行 `tmux set -g mouse on`,或写进 `~/.tmux.conf` |
|
|
222
|
-
| **按住 Shift 用鼠标**(绕过 tmux 鼠标模式) | 按住 `Shift` 拖动选中文字 → 浏览器右键「复制」;右键「粘贴」 |
|
|
223
|
-
|
|
224
|
-
> 提示:开了 `mouse on` 后鼠标归 tmux 管;想用浏览器原生的**框选 + 右键复制粘贴**,**按住 `Shift`** 再拖动 / 右键即可。
|
|
225
|
-
>
|
|
226
|
-
> 提示:在 tmuxes 里**新建 / 选择 / 重命名 / 杀会话**直接点 UI 就行,不用记命令;但**往上滚看历史、复制文字、拆面板**这些是 tmux 自己的功能,得用上面的快捷键。
|
|
227
|
-
|
|
228
|
-
## ❓ 常见问题
|
|
229
|
-
|
|
230
|
-
<details>
|
|
231
|
-
<summary><b>某个集群里 tmux 的中文(或其它非 ASCII 字符)全变成了下划线 <code>_</code>?</b></summary>
|
|
232
|
-
|
|
233
|
-
那台机器的登录 locale 不是 UTF-8(HPC 登录节点很常见,`LANG=C` / `POSIX`),于是 tmux 进入**非 UTF-8 模式**,把每个多字节字符用 `_` 占位。**在那台机器上**修:
|
|
234
|
-
|
|
235
|
-
1. 设一个 UTF-8 locale —— 先看哪些可用,再写进 `~/.bashrc` / `~/.zshrc`:
|
|
236
|
-
```bash
|
|
237
|
-
locale -a | grep -i utf # 看有哪些(C.UTF-8 / en_US.UTF-8 / zh_CN.UTF-8 …)
|
|
238
|
-
echo 'export LANG=C.UTF-8' >> ~/.bashrc # 换成上面真实存在的那个
|
|
239
|
-
```
|
|
240
|
-
2. 重启该机器上的 tmux 服务,让会话以 UTF-8 重新创建:
|
|
241
|
-
```bash
|
|
242
|
-
tmux kill-server
|
|
243
|
-
```
|
|
244
|
-
3. 回到 tmuxes 重新连接 / 新建会话即可。
|
|
245
|
-
|
|
246
|
-
> ⚠️ pane 的 UTF-8 模式在**创建时**就定死了 —— 只改 locale **不重启 server** 的话,已经变成下划线的旧会话不会自动恢复,必须重建。
|
|
247
|
-
|
|
248
|
-
</details>
|
|
249
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# 🖥️ tmuxes
|
|
4
|
+
|
|
5
|
+
**简体中文** | [English](./README.en.md)
|
|
6
|
+
|
|
7
|
+
### 一个浏览器标签页,掌控一整群 CLI coding agent。
|
|
8
|
+
|
|
9
|
+
**Claude Code · Codex · OpenCode · Hermes** —— 每个 agent 独占一个 tmux 会话,
|
|
10
|
+
横跨 **本地 · SSH · WSL**,还自带每个 agent 工作目录的文件浏览器。
|
|
11
|
+
|
|
12
|
+
🔔 **Claude Code / Codex 结束运行、异常停止或需要决策时,浏览器会自动提醒你** —— 侧边栏红/绿状态点 +「结束 / 决策 / 错误」提示 + 提示音 + 后台标签页标题闪烁。再也不用挨个窗格去盯「它还在跑吗」。
|
|
13
|
+
|
|
14
|
+
<p>
|
|
15
|
+
<a href="https://www.npmjs.com/package/tmuxes"><img alt="npm version" src="https://img.shields.io/npm/v/tmuxes?style=flat-square&logo=npm&color=CB3837"></a>
|
|
16
|
+
<img alt="platform" src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows%2011-2b2b2b?style=flat-square">
|
|
17
|
+
<img alt="React" src="https://img.shields.io/badge/React-19-61DAFB?style=flat-square&logo=react&logoColor=black">
|
|
18
|
+
<img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-5-3178C6?style=flat-square&logo=typescript&logoColor=white">
|
|
19
|
+
<img alt="Node.js" src="https://img.shields.io/badge/Node.js-22-339933?style=flat-square&logo=nodedotjs&logoColor=white">
|
|
20
|
+
<img alt="Vite" src="https://img.shields.io/badge/Vite-8-646CFF?style=flat-square&logo=vite&logoColor=white">
|
|
21
|
+
<img alt="tmux" src="https://img.shields.io/badge/tmux-3.x-1BB91F?style=flat-square&logo=tmux&logoColor=white">
|
|
22
|
+
<img alt="xterm.js" src="https://img.shields.io/badge/xterm.js-6-1f6feb?style=flat-square">
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
<sub>🔒 仅本机 · ⚡ 一键启动 · 🔔 agent hook 提醒 · 🪟 Windows 上直通 WSL · 🧩 零配置</sub>
|
|
26
|
+
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
> **为什么做这个?** 现代编码 agent 都是常驻的终端进程。同时跑好几个,你就开始在一堆窗格、SSH 窗口之间手忙脚乱:
|
|
32
|
+
> 「等等,刚那个是在哪台机器上来着?」**tmuxes** 把它们全塞进一个清爽的网页 UI:
|
|
33
|
+
> 开一个会话、丢进文件夹、看它干活、顺手瞄一眼它正在改的文件 —— 本地还是远程,都是同一个视图。
|
|
34
|
+
|
|
35
|
+
## ✨ 特性亮点
|
|
36
|
+
|
|
37
|
+
| | |
|
|
38
|
+
|---|---|
|
|
39
|
+
| 🧠 **为 agent 而生** | 每个 agent 独占一个 tmux 会话。新建时可带初始命令(比如 `claude` 或 `codex`),选中后右侧就是一个**完全可交互的实时终端**。 |
|
|
40
|
+
| 🔔 **结束 / 决策 / 错误提醒** | 新建会话时初始命令是 `claude` 或 `codex` 会自动接入官方 lifecycle hooks。也可以先进入空 session `cd` 到目标目录,再点终端右上角的 `claude` / `codex` 按钮启动带 hook 的 agent。已展开目标每 5 秒同步一次:红点表示 agent 正在运行,绿点表示已结束、异常停止或正在等你决策;结束运行、需要决策和异常停止会显示不同提示。 |
|
|
41
|
+
| 🌐 **本地 · SSH · WSL · 原生 Windows** | 一个侧边栏同时列出你的本机、`~/.ssh/config` 里的主机、(Windows 上)你的 WSL 发行版,以及(Windows)原生 PowerShell / cmd 会话 —— 全部并排排开。 |
|
|
42
|
+
| 🗂️ **文件夹树** | 像资源管理器一样,把会话拖进**可拖拽的文件夹**里整理。按目标分别持久化到本地。 |
|
|
43
|
+
| 📂 **实时文件浏览 + 编辑** | 侧边栏底部跟随每个会话的**工作目录** —— 点一个代码文件就能把终端一分为二,在下面**直接读和改**(可保存、撤销/重做)。 |
|
|
44
|
+
| 🔁 **真·多端同步** | 基于原生 `tmux attach`:同一个会话开两个标签页,逐键同步、互为镜像。 |
|
|
45
|
+
| ⚙️ **可调** | 侧边栏、终端、文件查看器的字号都能调,**实时生效**、刷新后仍保留。 |
|
|
46
|
+
| 🚀 **一键启动** | 双击 `start.cmd` / `start.command` / `start.sh` → 自动构建、启动、打开浏览器。 |
|
|
47
|
+
|
|
48
|
+
## 🖼️ 长这样
|
|
49
|
+
|
|
50
|
+
<div align="center">
|
|
51
|
+
<img src="https://raw.githubusercontent.com/f1974939505/tmuxes/main/fig/fig1.png" alt="tmuxes 截图 —— 一个标签页掌控一群 CLI agent" width="900">
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
## 🏗️ 架构
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
REST (create · list · rename · kill · cwd · files)
|
|
58
|
+
┌────────────┐ ┌──────────────────────┐ ┌──────────────────────────────────┐
|
|
59
|
+
│ Browser │──▶│ Node · Express · ws │──pty──▶│ tmux (Linux/macOS)│
|
|
60
|
+
│ xterm.js │◀──│ node-pty │──pty──▶│ ssh -tt user@host → tmux (remote)│
|
|
61
|
+
└────────────┘ └──────────────────────┘──pty──▶│ wsl.exe -d <distro> → tmux (Windows)│
|
|
62
|
+
▲ binary bytes ⇄ WebSocket ⇄ JSON control └──────────────────────────────────┘
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
- **`client/`** —— React + Vite + TypeScript,终端基于 [`@xterm/xterm`](https://www.npmjs.com/package/@xterm/xterm)。
|
|
66
|
+
- **`server/`** —— Node + Express + `ws` + `node-pty`。一个小型 REST API 跑短命的 tmux *管理*命令;单个 WebSocket 端点负责交互式 *attach* 的流式传输。
|
|
67
|
+
|
|
68
|
+
> **Windows 上没有原生 tmux?** 没问题。服务端原生运行(node-pty 用 ConPTY),通过 `wsl.exe` 直通你 WSL 发行版里的 tmux。Linux/macOS 上则直接和本地 tmux 通信。远程主机用系统 `ssh` 二进制,复用你已有的 `~/.ssh` 密钥 / `ssh-agent` —— **绝不存储任何密码。**
|
|
69
|
+
|
|
70
|
+
## 📦 用 npm 安装
|
|
71
|
+
|
|
72
|
+
刚刚开用的小家伙还在快速长身体,可能偶尔有 bug,修复更新也会比较快;建议用 `@latest` 总是拿到最新版本。
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# 一键运行(无需克隆,自动开浏览器):
|
|
76
|
+
npx tmuxes@latest
|
|
77
|
+
|
|
78
|
+
# 或全局安装后用 tmuxes 命令:
|
|
79
|
+
npm install -g tmuxes
|
|
80
|
+
tmuxes # → http://127.0.0.1:7420
|
|
81
|
+
|
|
82
|
+
# 常用参数:
|
|
83
|
+
tmuxes --port 8080 --no-open
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> 前提:你要连的机器/主机上装了 **tmux**。**Linux** 上 `node-pty` 需现场编译(装 `build-essential` + `python3`);**Windows / macOS** 有预编译二进制,真·一键。详见下方「环境要求」。
|
|
87
|
+
|
|
88
|
+
## 🚀 从源码一键启动(开发用)
|
|
89
|
+
|
|
90
|
+
<table>
|
|
91
|
+
<tr><th>系统</th><th>怎么做</th></tr>
|
|
92
|
+
<tr><td><b>🪟 Windows 11</b></td><td>双击 <b><code>start.cmd</code></b>(或在 Windows Terminal 里运行)。自动装依赖、构建、启动服务,并打开 <code>http://127.0.0.1:7420</code>。你的 WSL 发行版会出现在侧边栏。</td></tr>
|
|
93
|
+
<tr><td><b>🍎 macOS</b></td><td>在访达里双击 <b><code>start.command</code></b> <sub>(首次:右键 → 打开,绕过 Gatekeeper)</sub>。</td></tr>
|
|
94
|
+
<tr><td><b>🐧 Linux</b></td><td>运行 <b><code>./start.sh</code></b>。</td></tr>
|
|
95
|
+
</table>
|
|
96
|
+
|
|
97
|
+
## 🔧 手动运行
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
npm install # node-pty:Win/macOS 有预编译,Linux 从源码编译
|
|
101
|
+
|
|
102
|
+
# 开发 —— Vite 开发服务器 + API,带热更新:
|
|
103
|
+
npm run dev # → http://localhost:5173
|
|
104
|
+
|
|
105
|
+
# 生产 —— 构建客户端,由单进程统一服务:
|
|
106
|
+
npm run build
|
|
107
|
+
npm start # → http://localhost:7420 (设 TMUXES_OPEN=1 可自动打开浏览器)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 🔔 启动带 hook 的 Claude Code / Codex
|
|
111
|
+
|
|
112
|
+
tmuxes 目前会给 **Claude Code (`claude`)** 和 **Codex (`codex`)** 自动接入官方 lifecycle hooks,用来判断 agent 是正在运行、已经结束、异常停止,还是正在等你做决策。
|
|
113
|
+
|
|
114
|
+
两种用法:
|
|
115
|
+
|
|
116
|
+
1. 新建 session 时,在初始命令里直接填 `claude` 或 `codex`。
|
|
117
|
+
2. 先新建空 session,进入后在终端里 `cd /你的目标目录`,再点终端右上角的 `claude` / `codex` 按钮。
|
|
118
|
+
|
|
119
|
+
状态含义:
|
|
120
|
+
|
|
121
|
+
- 红点:agent 正在运行。
|
|
122
|
+
- 绿点:agent 已结束、异常停止、正在等你决策,或这个 session 没接入 agent hook。
|
|
123
|
+
- `结束` badge:本轮运行结束。
|
|
124
|
+
- `决策` badge:agent 正在等待权限确认或用户输入。
|
|
125
|
+
- `错误` badge:agent 异常停止,例如 Codex 断流但没有触发 stop hook。tmuxes 会在已展开目标的 5 秒同步里扫描 running agent 的 pane 尾部并把这类错误纠正为提醒状态。
|
|
126
|
+
|
|
127
|
+
注意:右上角按钮本质上是向当前 tmux pane 发送一条带 hook 的 `claude` / `codex` 命令。不要在当前 pane 里已有程序正在接收输入时点击它。裸 `cc` 常常是系统 C 编译器,tmuxes 不会默认把它当作 Claude Code。原生 Windows shell 没有 tmux session option,因此不支持这套 hook 状态。
|
|
128
|
+
|
|
129
|
+
## 🧩 目标(Targets)
|
|
130
|
+
|
|
131
|
+
- **本地** *(Linux/macOS)* —— 你机器上的 tmux。Windows 上不显示。
|
|
132
|
+
- **Windows 本机终端** *(Windows)* —— 服务端用 ConPTY 直接开 PowerShell / cmd 等本机 shell(自动探测 `pwsh` → `powershell` → `cmd` → Git Bash),新建时可在下拉里选 shell。会话随**服务端进程**存活(刷新 / 重连 / 多标签都不丢,重启服务端会丢);这类会话没有 tmux 工作目录,故隐藏底部文件浏览器。
|
|
133
|
+
- **WSL 发行版** *(Windows)* —— 通过 `wsl.exe -l -q` 自动发现;每个发行版一个目标。发行版里必须装了 tmux。
|
|
134
|
+
- **SSH 主机** —— 从你的 `~/.ssh/config` 的 `Host` 条目里发现(跳过通配符)。也可显式添加:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
TMUXES_HOSTS="alice@web1,bob@db2:2222" npm run dev # Linux / macOS
|
|
138
|
+
set TMUXES_HOSTS=alice@web1,bob@db2:2222 && npm run dev # Windows cmd
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
密钥 / agent 认证必须在普通 shell 里已经能用。全新主机请先在普通终端里接受一次它的 host key。为避免短命管理命令反复新建 SSH 连接,类 Unix 平台会通过 OpenSSH `ControlMaster` / `ControlPersist` 长期复用同一条 SSH 连接;原生 Windows 则由 tmuxes 维护一条应用层 SSH 管理长连接,不使用 Windows OpenSSH mux socket,避免 `getsockname failed: Not a socket`。tmuxes 不再强制设置 `ServerAliveInterval`,如需保活请按所在平台规则写进你自己的 `~/.ssh/config`。如果复用 / 管理连接中断,tmuxes 会自动重建并重试一次;仍失败时会在前端页面提示并暂停该 SSH 目标的自动轮询,点击 `Reconnect` 可手动再试一次。
|
|
142
|
+
|
|
143
|
+
## 💻 环境要求
|
|
144
|
+
|
|
145
|
+
所有平台都需要 **Node 22.12+**(项目版本文件固定为 22.22.2)和 **npm 10+**。其余:
|
|
146
|
+
|
|
147
|
+
<details>
|
|
148
|
+
<summary><b>🪟 Windows 11</b></summary>
|
|
149
|
+
|
|
150
|
+
- WSL2 且至少一个发行版,并在其中装好 **tmux**(`sudo apt install tmux`)。
|
|
151
|
+
- 内置的 OpenSSH 客户端覆盖 SSH 目标。
|
|
152
|
+
- node-pty 提供**预编译 Windows 二进制** —— 不需要编译器。
|
|
153
|
+
|
|
154
|
+
</details>
|
|
155
|
+
|
|
156
|
+
<details>
|
|
157
|
+
<summary><b>🍎 macOS</b></summary>
|
|
158
|
+
|
|
159
|
+
- `tmux` 在 `PATH` 上(`brew install tmux`)。
|
|
160
|
+
- node-pty 提供**预编译 darwin 二进制**。
|
|
161
|
+
- 从访达启动却找不到 tmux?确保 Homebrew 的 bin 目录在 GUI 的 `PATH` 里。
|
|
162
|
+
|
|
163
|
+
</details>
|
|
164
|
+
|
|
165
|
+
<details>
|
|
166
|
+
<summary><b>🐧 Linux</b></summary>
|
|
167
|
+
|
|
168
|
+
- `tmux`,外加给 node-pty 的 C/C++ 工具链 + Python 3(**没有 Linux 预编译 —— 安装时现场编译**):
|
|
169
|
+
```bash
|
|
170
|
+
sudo apt-get install -y build-essential python3 tmux
|
|
171
|
+
```
|
|
172
|
+
- WSL 小坑:`node-gyp` 会用 `PATH` 上的任意 `python3`。如果坏掉的 conda Python 把构建搞挂了:
|
|
173
|
+
```bash
|
|
174
|
+
npm config set python /usr/bin/python3
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
</details>
|
|
178
|
+
|
|
179
|
+
<details>
|
|
180
|
+
<summary><b>(备选)把服务端跑在 WSL 内部</b></summary>
|
|
181
|
+
|
|
182
|
+
在 Windows 上,你也可以把整个服务端跑在 WSL **内部**(像 Linux 一样),然后在 Windows 上开浏览器 —— WSL2 会转发 `localhost`。一键启动脚本用的是「原生 Windows + `wsl.exe`」方案,这样能在一个地方同时覆盖 SSH 目标和多个发行版。
|
|
183
|
+
|
|
184
|
+
</details>
|
|
185
|
+
|
|
186
|
+
## 🔒 安全
|
|
187
|
+
|
|
188
|
+
> ⚠️ **tmuxes 会把完整的 shell 访问权交给任何能连上它的人。** 它是一个单用户、仅本机的开发工具。
|
|
189
|
+
|
|
190
|
+
设计上它:
|
|
191
|
+
|
|
192
|
+
- 只绑定 **`127.0.0.1`** —— 绑定地址在运行时不可配置,
|
|
193
|
+
- **没有任何认证**,
|
|
194
|
+
- **从不起 shell**(argv 数组 + `shell:false`),并对每个输入做白名单校验,
|
|
195
|
+
- 拒绝 `Origin` 非 localhost 的 WebSocket 升级(防 DNS-rebind),
|
|
196
|
+
- 把文件浏览器 / 编辑器限制在所选 tmux 会话的**当前工作目录**之内。
|
|
197
|
+
|
|
198
|
+
**请勿**对它做反向代理、隧道、端口转发,或暴露到 `0.0.0.0`。机器上任何本地用户都能用它。
|
|
199
|
+
|
|
200
|
+
## 🧪 测试
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
npm test # vitest:输入校验、列表解析、ssh/tmux/wsl 的 argv 形状
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## 🐧 tmux 速查表
|
|
207
|
+
|
|
208
|
+
> tmux 的「前缀键」默认是 **`Ctrl+b`**(下面记作 `C-b`)—— 先按它,松开,再按后面的键。
|
|
209
|
+
> 在网页终端里**最常用的是滚动 / 复制模式**(往上看历史输出、复制文字)。
|
|
210
|
+
|
|
211
|
+
### 滚动 & 复制(最常用)
|
|
212
|
+
|
|
213
|
+
| 操作 | 按键 |
|
|
214
|
+
|---|---|
|
|
215
|
+
| 进入复制 / 滚动模式 | `C-b` 然后 `[` |
|
|
216
|
+
| 在模式里上下翻 | `↑ ↓`、`PageUp` / `PageDown` |
|
|
217
|
+
| 开始选择 → 复制 | `Space` 定起点 → 移动光标选中 → `Enter` 复制 |
|
|
218
|
+
| 把复制的内容粘回来 | `C-b` 然后 `]` |
|
|
219
|
+
| 在模式里搜索 | `C-s` 向前 / `C-r` 向后(默认 emacs 风格) |
|
|
220
|
+
| 退出复制 / 滚动模式 | `q` |
|
|
221
|
+
| **开鼠标滚轮**(直接滚轮翻 + 鼠标选) | 执行 `tmux set -g mouse on`,或写进 `~/.tmux.conf` |
|
|
222
|
+
| **按住 Shift 用鼠标**(绕过 tmux 鼠标模式) | 按住 `Shift` 拖动选中文字 → 浏览器右键「复制」;右键「粘贴」 |
|
|
223
|
+
|
|
224
|
+
> 提示:开了 `mouse on` 后鼠标归 tmux 管;想用浏览器原生的**框选 + 右键复制粘贴**,**按住 `Shift`** 再拖动 / 右键即可。
|
|
225
|
+
>
|
|
226
|
+
> 提示:在 tmuxes 里**新建 / 选择 / 重命名 / 杀会话**直接点 UI 就行,不用记命令;但**往上滚看历史、复制文字、拆面板**这些是 tmux 自己的功能,得用上面的快捷键。
|
|
227
|
+
|
|
228
|
+
## ❓ 常见问题
|
|
229
|
+
|
|
230
|
+
<details>
|
|
231
|
+
<summary><b>某个集群里 tmux 的中文(或其它非 ASCII 字符)全变成了下划线 <code>_</code>?</b></summary>
|
|
232
|
+
|
|
233
|
+
那台机器的登录 locale 不是 UTF-8(HPC 登录节点很常见,`LANG=C` / `POSIX`),于是 tmux 进入**非 UTF-8 模式**,把每个多字节字符用 `_` 占位。**在那台机器上**修:
|
|
234
|
+
|
|
235
|
+
1. 设一个 UTF-8 locale —— 先看哪些可用,再写进 `~/.bashrc` / `~/.zshrc`:
|
|
236
|
+
```bash
|
|
237
|
+
locale -a | grep -i utf # 看有哪些(C.UTF-8 / en_US.UTF-8 / zh_CN.UTF-8 …)
|
|
238
|
+
echo 'export LANG=C.UTF-8' >> ~/.bashrc # 换成上面真实存在的那个
|
|
239
|
+
```
|
|
240
|
+
2. 重启该机器上的 tmux 服务,让会话以 UTF-8 重新创建:
|
|
241
|
+
```bash
|
|
242
|
+
tmux kill-server
|
|
243
|
+
```
|
|
244
|
+
3. 回到 tmuxes 重新连接 / 新建会话即可。
|
|
245
|
+
|
|
246
|
+
> ⚠️ pane 的 UTF-8 模式在**创建时**就定死了 —— 只改 locale **不重启 server** 的话,已经变成下划线的旧会话不会自动恢复,必须重建。
|
|
247
|
+
|
|
248
|
+
</details>
|
|
249
|
+
|
|
250
250
|
## 📋 更新日志
|
|
251
251
|
|
|
252
|
+
### 0.1.9
|
|
253
|
+
- **修复: Windows SSH 原生管理命令改用应用层长连接**。避免 Windows OpenSSH `ControlMaster` mux socket 的 `getsockname failed: Not a socket`,同时避免短命管理命令反复新建 SSH 连接。
|
|
254
|
+
- **改进: 文件浏览器合并远端目录刷新**。一次远端调用同时读取 pane 工作目录、校验路径并列目录,减少 SSH 管理流量。
|
|
255
|
+
|
|
252
256
|
### 0.1.8
|
|
253
257
|
- **文档:补齐 0.1.7 更新日志并重新发布 npm 包**。确保 npm 页面和仓库 README 都包含 SSH 长连接 / 重连策略说明。
|
|
254
|
-
|
|
255
|
-
### 0.1.7
|
|
256
|
-
- **改进:SSH 目标改为长期复用连接**。类 Unix 平台通过 OpenSSH `ControlMaster` / `ControlPersist` 复用同一条 SSH 连接,避免短命管理命令反复新建连接。
|
|
257
|
-
- **变更:不再强制 `ServerAliveInterval=30`**。tmuxes 不再主动设置 30 秒 SSH 保活;如需保活,请按所在平台规则写进自己的 `~/.ssh/config`。
|
|
258
|
-
- **修复:SSH 中断只重试一次并提示用户**。复用连接中断时会清理旧 control socket 并直连重试一次;仍失败则暂停自动轮询,在前端显示错误并提供 `Reconnect` 手动重连按钮。
|
|
259
|
-
|
|
260
|
-
### 0.1.6
|
|
261
|
-
- **修复:Codex 断流后红灯不恢复**。当 Codex 输出 `stream disconnected before completion` 但没有触发 stop hook 时,已展开目标的 5 秒同步会扫描 running agent 的 pane 尾部,写回 `错误` 提醒并把红点恢复为绿点。
|
|
262
|
-
- **改进:Claude Code `StopFailure` 归类为异常停止**。正常 `Stop` / `SessionEnd` 仍显示 `结束`,失败停止显示 `错误`。
|
|
263
|
-
|
|
264
|
-
### 0.1.5
|
|
265
|
-
- **修复:Claude Code 启动改用 `claude` 命令**。裸 `cc` 在很多 Linux/SSH 环境里是系统 C 编译器,不再默认识别为 Claude Code,右上角按钮也改为 `claude` / `codex`。
|
|
266
|
-
- **变更:项目 Node 版本统一到 22**。新增 `.nvmrc` / `.node-version`,并将 package engines 统一为 Node `>=22.12.0 <23`。
|
|
267
|
-
|
|
268
|
-
### 0.1.4
|
|
269
|
-
- **改进:提醒改为 Claude Code / Codex 官方 lifecycle hooks**。新建会话时初始命令是 `claude` 或 `codex` 会自动注入 hooks;也可以先进入空 session `cd` 到目标目录,再点右上角 `claude` / `codex` 按钮启动带 hook 的 agent。tmuxes 每 5 秒读取 tmux session option 同步状态。红点表示正在运行,绿点表示已结束或需要决策,并分别显示「结束 / 决策」提示。
|
|
270
|
-
|
|
271
|
-
### 0.1.3
|
|
272
|
-
- **修复 (Windows)**:`Ctrl+C` 现在真的能停掉服务了。之前的修复有 bug(readline 没进入终端模式,信号桥接形同虚设),而且 node-pty 的 ConPTY 会破坏宿主进程的 `CTRL_C_EVENT → SIGINT` 通路。改为**直接从控制台读取 `Ctrl+C` 原始字节(0x03)**,绕开被破坏的信号机制。`Ctrl+Break` 同样可用。
|
|
273
|
-
- **变更:恢复浏览器原生右键**。终端区域不再拦截右键菜单。想用浏览器原生**框选 + 右键复制粘贴**,**按住 `Shift`** 拖动 / 右键即可(绕过 tmux 鼠标模式)。
|
|
274
|
-
|
|
275
|
-
### 0.1.2
|
|
276
|
-
- **新增:活动转静止提醒**。零配置监测每个会话——session 终端画面从持续变化转为静止后,通过**侧边栏状态点 + 提示音 + 后台标签页标题闪烁**提醒你。设置面板可开关提醒与提示音。
|
|
277
|
-
|
|
278
|
-
### 0.1.1
|
|
279
|
-
- **修复 (Windows)**:`Ctrl+C` 现在可以正常终止服务端进程。node-pty 的 ConPTY 子进程会拦截 `CTRL_C_EVENT` 导致 SIGINT 无法到达宿主 node;通过 `readline` 从控制台输入层直接桥接 SIGINT 修复此问题。
|
|
280
|
-
- **修复 (终端)**:鼠标右键现在可以在 tmux 鼠标模式里正常使用。浏览器原生右键菜单在终端区域被禁用,右键事件直接传入 xterm → tmux。需要在 tmux 里开启 `set -g mouse on`。
|
|
281
|
-
|
|
282
|
-
### 0.1.0
|
|
283
|
-
- 初次发布。
|
|
284
|
-
|
|
285
|
-
<div align="center">
|
|
286
|
-
<sub>用 React、TypeScript、node-pty & xterm.js 打造 —— 外加大量 tmux。盯娃愉快。🤖</sub>
|
|
287
|
-
</div>
|
|
288
|
-
|
|
289
|
-
## 🧑🔬 关于作者
|
|
290
|
-
|
|
291
|
-
> 嗨,我是这个项目的作者 👋
|
|
292
|
-
>
|
|
293
|
-
> 中国科学技术大学(USTC)理论物理在读博士,白天的日常是和**多体场论可解释的费米超流理论**(这玩意是用来研究和解释高温超导的),还有一大坨**高性能数值计算**代码贴身肉搏 ⚛️。
|
|
294
|
-
>
|
|
295
|
-
> 这个小工具其实是被一堆 agent 终端搞到头大之后的「自救产物」—— 既然每天都要盯一群 CLI agent 干活,那干脆给它们造个顺手的指挥台 😎。
|
|
296
|
-
>
|
|
297
|
-
> 如果你也对这些感兴趣(物理也好、代码也好),或者想一起折腾这个开源项目,随时来找我玩 📮
|
|
298
|
-
>
|
|
299
|
-
> **📧 junruwu@mail.ustc.edu.cn**
|
|
258
|
+
|
|
259
|
+
### 0.1.7
|
|
260
|
+
- **改进:SSH 目标改为长期复用连接**。类 Unix 平台通过 OpenSSH `ControlMaster` / `ControlPersist` 复用同一条 SSH 连接,避免短命管理命令反复新建连接。
|
|
261
|
+
- **变更:不再强制 `ServerAliveInterval=30`**。tmuxes 不再主动设置 30 秒 SSH 保活;如需保活,请按所在平台规则写进自己的 `~/.ssh/config`。
|
|
262
|
+
- **修复:SSH 中断只重试一次并提示用户**。复用连接中断时会清理旧 control socket 并直连重试一次;仍失败则暂停自动轮询,在前端显示错误并提供 `Reconnect` 手动重连按钮。
|
|
263
|
+
|
|
264
|
+
### 0.1.6
|
|
265
|
+
- **修复:Codex 断流后红灯不恢复**。当 Codex 输出 `stream disconnected before completion` 但没有触发 stop hook 时,已展开目标的 5 秒同步会扫描 running agent 的 pane 尾部,写回 `错误` 提醒并把红点恢复为绿点。
|
|
266
|
+
- **改进:Claude Code `StopFailure` 归类为异常停止**。正常 `Stop` / `SessionEnd` 仍显示 `结束`,失败停止显示 `错误`。
|
|
267
|
+
|
|
268
|
+
### 0.1.5
|
|
269
|
+
- **修复:Claude Code 启动改用 `claude` 命令**。裸 `cc` 在很多 Linux/SSH 环境里是系统 C 编译器,不再默认识别为 Claude Code,右上角按钮也改为 `claude` / `codex`。
|
|
270
|
+
- **变更:项目 Node 版本统一到 22**。新增 `.nvmrc` / `.node-version`,并将 package engines 统一为 Node `>=22.12.0 <23`。
|
|
271
|
+
|
|
272
|
+
### 0.1.4
|
|
273
|
+
- **改进:提醒改为 Claude Code / Codex 官方 lifecycle hooks**。新建会话时初始命令是 `claude` 或 `codex` 会自动注入 hooks;也可以先进入空 session `cd` 到目标目录,再点右上角 `claude` / `codex` 按钮启动带 hook 的 agent。tmuxes 每 5 秒读取 tmux session option 同步状态。红点表示正在运行,绿点表示已结束或需要决策,并分别显示「结束 / 决策」提示。
|
|
274
|
+
|
|
275
|
+
### 0.1.3
|
|
276
|
+
- **修复 (Windows)**:`Ctrl+C` 现在真的能停掉服务了。之前的修复有 bug(readline 没进入终端模式,信号桥接形同虚设),而且 node-pty 的 ConPTY 会破坏宿主进程的 `CTRL_C_EVENT → SIGINT` 通路。改为**直接从控制台读取 `Ctrl+C` 原始字节(0x03)**,绕开被破坏的信号机制。`Ctrl+Break` 同样可用。
|
|
277
|
+
- **变更:恢复浏览器原生右键**。终端区域不再拦截右键菜单。想用浏览器原生**框选 + 右键复制粘贴**,**按住 `Shift`** 拖动 / 右键即可(绕过 tmux 鼠标模式)。
|
|
278
|
+
|
|
279
|
+
### 0.1.2
|
|
280
|
+
- **新增:活动转静止提醒**。零配置监测每个会话——session 终端画面从持续变化转为静止后,通过**侧边栏状态点 + 提示音 + 后台标签页标题闪烁**提醒你。设置面板可开关提醒与提示音。
|
|
281
|
+
|
|
282
|
+
### 0.1.1
|
|
283
|
+
- **修复 (Windows)**:`Ctrl+C` 现在可以正常终止服务端进程。node-pty 的 ConPTY 子进程会拦截 `CTRL_C_EVENT` 导致 SIGINT 无法到达宿主 node;通过 `readline` 从控制台输入层直接桥接 SIGINT 修复此问题。
|
|
284
|
+
- **修复 (终端)**:鼠标右键现在可以在 tmux 鼠标模式里正常使用。浏览器原生右键菜单在终端区域被禁用,右键事件直接传入 xterm → tmux。需要在 tmux 里开启 `set -g mouse on`。
|
|
285
|
+
|
|
286
|
+
### 0.1.0
|
|
287
|
+
- 初次发布。
|
|
288
|
+
|
|
289
|
+
<div align="center">
|
|
290
|
+
<sub>用 React、TypeScript、node-pty & xterm.js 打造 —— 外加大量 tmux。盯娃愉快。🤖</sub>
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
## 🧑🔬 关于作者
|
|
294
|
+
|
|
295
|
+
> 嗨,我是这个项目的作者 👋
|
|
296
|
+
>
|
|
297
|
+
> 中国科学技术大学(USTC)理论物理在读博士,白天的日常是和**多体场论可解释的费米超流理论**(这玩意是用来研究和解释高温超导的),还有一大坨**高性能数值计算**代码贴身肉搏 ⚛️。
|
|
298
|
+
>
|
|
299
|
+
> 这个小工具其实是被一堆 agent 终端搞到头大之后的「自救产物」—— 既然每天都要盯一群 CLI agent 干活,那干脆给它们造个顺手的指挥台 😎。
|
|
300
|
+
>
|
|
301
|
+
> 如果你也对这些感兴趣(物理也好、代码也好),或者想一起折腾这个开源项目,随时来找我玩 📮
|
|
302
|
+
>
|
|
303
|
+
> **📧 junruwu@mail.ustc.edu.cn**
|