tmuxes 0.1.10 → 0.1.11
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/LICENSE +21 -21
- package/README.md +283 -296
- package/bin/tmuxes.js +36 -36
- package/package.json +61 -61
- package/public/index.html +11 -11
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 tmuxes contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tmuxes contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,303 +1,290 @@
|
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
#
|
|
76
|
-
npx tmuxes@latest
|
|
77
|
-
|
|
78
|
-
#
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
tmuxes
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
npm
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
-
|
|
132
|
-
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
+
建议直接用 `@latest`,这样能拿到最新的修复包。`tmuxes` 是单用户本机工具,启动后只监听 `127.0.0.1`。
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# 先验证 npm 包入口:
|
|
76
|
+
npx --yes tmuxes@latest --help
|
|
77
|
+
|
|
78
|
+
# 一键运行(无需克隆,默认自动开浏览器):
|
|
79
|
+
npx --yes tmuxes@latest
|
|
80
|
+
|
|
81
|
+
# 或全局安装后用 tmuxes 命令:
|
|
82
|
+
npm install -g tmuxes
|
|
83
|
+
tmuxes # → http://127.0.0.1:7420
|
|
84
|
+
|
|
85
|
+
# 常用参数:
|
|
86
|
+
tmuxes --port 8080 --no-open
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
如果 Windows 上 `npx` 失败,先确认:
|
|
90
|
+
|
|
91
|
+
- `node -v` 是 **22.12+ 且 <23**,`npm -v` 是 **10+**。
|
|
92
|
+
- 使用的是官方 npm registry,且没有旧缓存污染;必要时先跑 `npm cache verify` 再重试。
|
|
93
|
+
- 你要连接的机器/主机上已经装好 **tmux**。Linux 上 `node-pty` 需要现场编译,先装 `build-essential` + `python3`;Windows / macOS 使用预编译二进制。
|
|
94
|
+
|
|
95
|
+
## 🚀 从源码一键启动(开发用)
|
|
96
|
+
|
|
97
|
+
<table>
|
|
98
|
+
<tr><th>系统</th><th>怎么做</th></tr>
|
|
99
|
+
<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>
|
|
100
|
+
<tr><td><b>🍎 macOS</b></td><td>在访达里双击 <b><code>start.command</code></b> <sub>(首次:右键 → 打开,绕过 Gatekeeper)</sub>。</td></tr>
|
|
101
|
+
<tr><td><b>🐧 Linux</b></td><td>运行 <b><code>./start.sh</code></b>。</td></tr>
|
|
102
|
+
</table>
|
|
103
|
+
|
|
104
|
+
## 🔧 手动运行
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npm install # node-pty:Win/macOS 有预编译,Linux 从源码编译
|
|
108
|
+
|
|
109
|
+
# 开发 —— Vite 开发服务器 + API,带热更新:
|
|
110
|
+
npm run dev # → http://localhost:5173
|
|
111
|
+
|
|
112
|
+
# 生产 —— 构建客户端,由单进程统一服务:
|
|
113
|
+
npm run build
|
|
114
|
+
npm start # → http://localhost:7420 (设 TMUXES_OPEN=1 可自动打开浏览器)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## 🔔 启动带 hook 的 Claude Code / Codex
|
|
118
|
+
|
|
119
|
+
tmuxes 目前会给 **Claude Code (`claude`)** 和 **Codex (`codex`)** 自动接入官方 lifecycle hooks,用来判断 agent 是正在运行、已经结束、异常停止,还是正在等你做决策。
|
|
120
|
+
|
|
121
|
+
两种用法:
|
|
122
|
+
|
|
123
|
+
1. 新建 session 时,在初始命令里直接填 `claude` 或 `codex`。
|
|
124
|
+
2. 先新建空 session,进入后在终端里 `cd /你的目标目录`,再点终端右上角的 `claude` / `codex` 按钮。
|
|
125
|
+
|
|
126
|
+
状态含义:
|
|
127
|
+
|
|
128
|
+
- 红点:agent 正在运行。
|
|
129
|
+
- 绿点:agent 已结束、异常停止、正在等你决策,或这个 session 没接入 agent hook。
|
|
130
|
+
- `结束` badge:本轮运行结束。
|
|
131
|
+
- `决策` badge:agent 正在等待权限确认或用户输入。
|
|
132
|
+
- `错误` badge:agent 异常停止,例如 Codex 断流但没有触发 stop hook。tmuxes 会在已展开目标的 5 秒同步里扫描 running agent 的 pane 尾部并把这类错误纠正为提醒状态。
|
|
133
|
+
|
|
134
|
+
注意:右上角按钮本质上是向当前 tmux pane 发送一条带 hook 的 `claude` / `codex` 命令。不要在当前 pane 里已有程序正在接收输入时点击它。裸 `cc` 常常是系统 C 编译器,tmuxes 不会默认把它当作 Claude Code。原生 Windows shell 没有 tmux session option,因此不支持这套 hook 状态。
|
|
135
|
+
|
|
136
|
+
## 🧩 目标(Targets)
|
|
137
|
+
|
|
138
|
+
- **本地** *(Linux/macOS)* —— 你机器上的 tmux。Windows 上不显示。
|
|
139
|
+
- **Windows 本机终端** *(Windows)* —— 服务端用 ConPTY 直接开 PowerShell / cmd 等本机 shell(自动探测 `pwsh` → `powershell` → `cmd` → Git Bash),新建时可在下拉里选 shell。会话随**服务端进程**存活(刷新 / 重连 / 多标签都不丢,重启服务端会丢);这类会话没有 tmux 工作目录,故隐藏底部文件浏览器。
|
|
140
|
+
- **WSL 发行版** *(Windows)* —— 通过 `wsl.exe -l -q` 自动发现;每个发行版一个目标。发行版里必须装了 tmux。
|
|
141
|
+
- **SSH 主机** —— 从你的 `~/.ssh/config` 的 `Host` 条目里发现(跳过通配符)。也可显式添加:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
TMUXES_HOSTS="alice@web1,bob@db2:2222" npm run dev # Linux / macOS
|
|
145
|
+
set TMUXES_HOSTS=alice@web1,bob@db2:2222 && npm run dev # Windows cmd
|
|
146
|
+
```
|
|
147
|
+
|
|
141
148
|
密钥 / 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
|
-
|
|
149
|
+
|
|
150
|
+
## 💻 环境要求
|
|
151
|
+
|
|
152
|
+
所有平台都需要 **Node 22.12+**(项目版本文件固定为 22.22.2)和 **npm 10+**。其余:
|
|
153
|
+
|
|
154
|
+
<details>
|
|
155
|
+
<summary><b>🪟 Windows 11</b></summary>
|
|
156
|
+
|
|
157
|
+
- WSL2 且至少一个发行版,并在其中装好 **tmux**(`sudo apt install tmux`)。
|
|
158
|
+
- 内置的 OpenSSH 客户端覆盖 SSH 目标。
|
|
159
|
+
- node-pty 提供**预编译 Windows 二进制** —— 不需要编译器。
|
|
160
|
+
|
|
161
|
+
</details>
|
|
162
|
+
|
|
163
|
+
<details>
|
|
164
|
+
<summary><b>🍎 macOS</b></summary>
|
|
165
|
+
|
|
166
|
+
- `tmux` 在 `PATH` 上(`brew install tmux`)。
|
|
167
|
+
- node-pty 提供**预编译 darwin 二进制**。
|
|
168
|
+
- 从访达启动却找不到 tmux?确保 Homebrew 的 bin 目录在 GUI 的 `PATH` 里。
|
|
169
|
+
|
|
170
|
+
</details>
|
|
171
|
+
|
|
172
|
+
<details>
|
|
173
|
+
<summary><b>🐧 Linux</b></summary>
|
|
174
|
+
|
|
175
|
+
- `tmux`,外加给 node-pty 的 C/C++ 工具链 + Python 3(**没有 Linux 预编译 —— 安装时现场编译**):
|
|
176
|
+
```bash
|
|
177
|
+
sudo apt-get install -y build-essential python3 tmux
|
|
178
|
+
```
|
|
179
|
+
- WSL 小坑:`node-gyp` 会用 `PATH` 上的任意 `python3`。如果坏掉的 conda Python 把构建搞挂了:
|
|
180
|
+
```bash
|
|
181
|
+
npm config set python /usr/bin/python3
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
</details>
|
|
185
|
+
|
|
186
|
+
<details>
|
|
187
|
+
<summary><b>(备选)把服务端跑在 WSL 内部</b></summary>
|
|
188
|
+
|
|
189
|
+
在 Windows 上,你也可以把整个服务端跑在 WSL **内部**(像 Linux 一样),然后在 Windows 上开浏览器 —— WSL2 会转发 `localhost`。一键启动脚本用的是「原生 Windows + `wsl.exe`」方案,这样能在一个地方同时覆盖 SSH 目标和多个发行版。
|
|
190
|
+
|
|
191
|
+
</details>
|
|
192
|
+
|
|
193
|
+
## 🔒 安全
|
|
194
|
+
|
|
195
|
+
> ⚠️ **tmuxes 会把完整的 shell 访问权交给任何能连上它的人。** 它是一个单用户、仅本机的开发工具。
|
|
196
|
+
|
|
197
|
+
设计上它:
|
|
198
|
+
|
|
199
|
+
- 只绑定 **`127.0.0.1`** —— 绑定地址在运行时不可配置,
|
|
200
|
+
- **没有任何认证**,
|
|
201
|
+
- **从不起 shell**(argv 数组 + `shell:false`),并对每个输入做白名单校验,
|
|
202
|
+
- 拒绝 `Origin` 非 localhost 的 WebSocket 升级(防 DNS-rebind),
|
|
203
|
+
- 把文件浏览器 / 编辑器限制在所选 tmux 会话的**当前工作目录**之内。
|
|
204
|
+
|
|
205
|
+
**请勿**对它做反向代理、隧道、端口转发,或暴露到 `0.0.0.0`。机器上任何本地用户都能用它。
|
|
206
|
+
|
|
207
|
+
## 🧪 测试
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
npm test # vitest:输入校验、列表解析、ssh/tmux/wsl 的 argv 形状
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## 🐧 tmux 速查表
|
|
214
|
+
|
|
215
|
+
> tmux 的「前缀键」默认是 **`Ctrl+b`**(下面记作 `C-b`)—— 先按它,松开,再按后面的键。
|
|
216
|
+
> 在网页终端里**最常用的是滚动 / 复制模式**(往上看历史输出、复制文字)。
|
|
217
|
+
|
|
218
|
+
### 滚动 & 复制(最常用)
|
|
219
|
+
|
|
220
|
+
| 操作 | 按键 |
|
|
221
|
+
|---|---|
|
|
222
|
+
| 进入复制 / 滚动模式 | `C-b` 然后 `[` |
|
|
223
|
+
| 在模式里上下翻 | `↑ ↓`、`PageUp` / `PageDown` |
|
|
224
|
+
| 开始选择 → 复制 | `Space` 定起点 → 移动光标选中 → `Enter` 复制 |
|
|
225
|
+
| 把复制的内容粘回来 | `C-b` 然后 `]` |
|
|
226
|
+
| 在模式里搜索 | `C-s` 向前 / `C-r` 向后(默认 emacs 风格) |
|
|
227
|
+
| 退出复制 / 滚动模式 | `q` |
|
|
228
|
+
| **开鼠标滚轮**(直接滚轮翻 + 鼠标选) | 执行 `tmux set -g mouse on`,或写进 `~/.tmux.conf` |
|
|
229
|
+
| **按住 Shift 用鼠标**(绕过 tmux 鼠标模式) | 按住 `Shift` 拖动选中文字 → 浏览器右键「复制」;右键「粘贴」 |
|
|
230
|
+
|
|
231
|
+
> 提示:开了 `mouse on` 后鼠标归 tmux 管;想用浏览器原生的**框选 + 右键复制粘贴**,**按住 `Shift`** 再拖动 / 右键即可。
|
|
232
|
+
>
|
|
233
|
+
> 提示:在 tmuxes 里**新建 / 选择 / 重命名 / 杀会话**直接点 UI 就行,不用记命令;但**往上滚看历史、复制文字、拆面板**这些是 tmux 自己的功能,得用上面的快捷键。
|
|
234
|
+
|
|
235
|
+
## ❓ 常见问题
|
|
236
|
+
|
|
237
|
+
<details>
|
|
238
|
+
<summary><b>某个集群里 tmux 的中文(或其它非 ASCII 字符)全变成了下划线 <code>_</code>?</b></summary>
|
|
239
|
+
|
|
240
|
+
那台机器的登录 locale 不是 UTF-8(HPC 登录节点很常见,`LANG=C` / `POSIX`),于是 tmux 进入**非 UTF-8 模式**,把每个多字节字符用 `_` 占位。**在那台机器上**修:
|
|
241
|
+
|
|
242
|
+
1. 设一个 UTF-8 locale —— 先看哪些可用,再写进 `~/.bashrc` / `~/.zshrc`:
|
|
243
|
+
```bash
|
|
244
|
+
locale -a | grep -i utf # 看有哪些(C.UTF-8 / en_US.UTF-8 / zh_CN.UTF-8 …)
|
|
245
|
+
echo 'export LANG=C.UTF-8' >> ~/.bashrc # 换成上面真实存在的那个
|
|
246
|
+
```
|
|
247
|
+
2. 重启该机器上的 tmux 服务,让会话以 UTF-8 重新创建:
|
|
248
|
+
```bash
|
|
249
|
+
tmux kill-server
|
|
250
|
+
```
|
|
251
|
+
3. 回到 tmuxes 重新连接 / 新建会话即可。
|
|
252
|
+
|
|
253
|
+
> ⚠️ pane 的 UTF-8 模式在**创建时**就定死了 —— 只改 locale **不重启 server** 的话,已经变成下划线的旧会话不会自动恢复,必须重建。
|
|
254
|
+
|
|
255
|
+
</details>
|
|
256
|
+
|
|
250
257
|
## 📋 更新日志
|
|
251
258
|
|
|
259
|
+
### 0.1.11
|
|
260
|
+
- **文档 / 发布规范**:补齐 npm 发布检查流程,明确只发布 `server` workspace,发布前后都要验证 `npx` / `npm exec` 入口和本机启动 smoke test。
|
|
261
|
+
- **安全约束**:发布流程不得提交或粘贴 `.npmrc` token、`NPM_TOKEN`、SSH 私钥、一次性验证码或任何个人凭据。
|
|
262
|
+
- **README 重整**:安装说明加入 `npx --help` 验证、Windows 排错提示,并压缩早期版本更新。
|
|
263
|
+
|
|
264
|
+
### 0.1.10
|
|
265
|
+
- **发布修正**:重新发布 npm `latest` 包,确认线上 `tmuxes` bin、前端 `public` 资源和 `npx tmuxes@latest` 入口可用。
|
|
266
|
+
|
|
252
267
|
### 0.1.9
|
|
253
268
|
- **修复: Windows SSH 原生管理命令改用应用层长连接**。避免 Windows OpenSSH `ControlMaster` mux socket 的 `getsockname failed: Not a socket`,同时避免短命管理命令反复新建 SSH 连接。
|
|
254
269
|
- **改进: 文件浏览器合并远端目录刷新**。一次远端调用同时读取 pane 工作目录、校验路径并列目录,减少 SSH 管理流量。
|
|
255
270
|
|
|
256
|
-
### 0.1.8
|
|
257
|
-
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
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**
|
|
271
|
+
### 0.1.0 - 0.1.8
|
|
272
|
+
- **早期功能成型**:完成本地 / SSH / WSL / Windows shell 目标、tmux attach 多端同步、拖拽文件夹树、工作目录文件浏览与编辑。
|
|
273
|
+
- **agent 提醒演进**:从活动转静止提醒升级到 Claude Code / Codex 官方 lifecycle hooks,支持结束、决策和异常停止状态。
|
|
274
|
+
- **Windows / SSH 稳定性**:修复 ConPTY 下 `Ctrl+C` 退出、恢复浏览器原生右键,并将 SSH 管理命令改为长期复用连接且中断后只自动重试一次。
|
|
275
|
+
|
|
276
|
+
<div align="center">
|
|
277
|
+
<sub>用 React、TypeScript、node-pty & xterm.js 打造 —— 外加大量 tmux。盯娃愉快。🤖</sub>
|
|
278
|
+
</div>
|
|
279
|
+
|
|
280
|
+
## 🧑🔬 关于作者
|
|
281
|
+
|
|
282
|
+
> 嗨,我是这个项目的作者 👋
|
|
283
|
+
>
|
|
284
|
+
> 中国科学技术大学(USTC)理论物理在读博士,白天的日常是和**多体场论可解释的费米超流理论**(这玩意是用来研究和解释高温超导的),还有一大坨**高性能数值计算**代码贴身肉搏 ⚛️。
|
|
285
|
+
>
|
|
286
|
+
> 这个小工具其实是被一堆 agent 终端搞到头大之后的「自救产物」—— 既然每天都要盯一群 CLI agent 干活,那干脆给它们造个顺手的指挥台 😎。
|
|
287
|
+
>
|
|
288
|
+
> 如果你也对这些感兴趣(物理也好、代码也好),或者想一起折腾这个开源项目,随时来找我玩 📮
|
|
289
|
+
>
|
|
290
|
+
> **📧 junruwu@mail.ustc.edu.cn**
|
package/bin/tmuxes.js
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// tmuxes — web UI to manage tmux sessions (local / SSH / WSL).
|
|
3
|
-
// Parses a couple of flags, sets the env the server reads, then launches it.
|
|
4
|
-
|
|
5
|
-
const args = process.argv.slice(2);
|
|
6
|
-
|
|
7
|
-
if (args.includes('--help') || args.includes('-h')) {
|
|
8
|
-
console.log(`tmuxes — one browser tab to run and supervise tmux sessions (local · SSH · WSL)
|
|
9
|
-
|
|
10
|
-
Usage:
|
|
11
|
-
tmuxes [options]
|
|
12
|
-
|
|
13
|
-
Options:
|
|
14
|
-
--port <n> Port to listen on (default 7420, env TMUXES_PORT)
|
|
15
|
-
--no-open Do not open the browser
|
|
16
|
-
-h, --help Show this help
|
|
17
|
-
|
|
18
|
-
Binds to 127.0.0.1 only (no-auth local UI). Then open http://127.0.0.1:7420
|
|
19
|
-
(opens automatically unless --no-open). Requires tmux on the host you connect to.`);
|
|
20
|
-
process.exit(0);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function flag(name) {
|
|
24
|
-
const i = args.indexOf(name);
|
|
25
|
-
return i >= 0 ? args[i + 1] : undefined;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const port = flag('--port');
|
|
29
|
-
if (port) process.env.TMUXES_PORT = port;
|
|
30
|
-
|
|
31
|
-
// Open the browser by default (the "one-click run" experience), unless the
|
|
32
|
-
// user opted out or already set TMUXES_OPEN.
|
|
33
|
-
if (!args.includes('--no-open') && process.env.TMUXES_OPEN === undefined) {
|
|
34
|
-
process.env.TMUXES_OPEN = '1';
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
await import('../dist/index.js');
|
|
2
|
+
// tmuxes — web UI to manage tmux sessions (local / SSH / WSL).
|
|
3
|
+
// Parses a couple of flags, sets the env the server reads, then launches it.
|
|
4
|
+
|
|
5
|
+
const args = process.argv.slice(2);
|
|
6
|
+
|
|
7
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
8
|
+
console.log(`tmuxes — one browser tab to run and supervise tmux sessions (local · SSH · WSL)
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
tmuxes [options]
|
|
12
|
+
|
|
13
|
+
Options:
|
|
14
|
+
--port <n> Port to listen on (default 7420, env TMUXES_PORT)
|
|
15
|
+
--no-open Do not open the browser
|
|
16
|
+
-h, --help Show this help
|
|
17
|
+
|
|
18
|
+
Binds to 127.0.0.1 only (no-auth local UI). Then open http://127.0.0.1:7420
|
|
19
|
+
(opens automatically unless --no-open). Requires tmux on the host you connect to.`);
|
|
20
|
+
process.exit(0);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function flag(name) {
|
|
24
|
+
const i = args.indexOf(name);
|
|
25
|
+
return i >= 0 ? args[i + 1] : undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const port = flag('--port');
|
|
29
|
+
if (port) process.env.TMUXES_PORT = port;
|
|
30
|
+
|
|
31
|
+
// Open the browser by default (the "one-click run" experience), unless the
|
|
32
|
+
// user opted out or already set TMUXES_OPEN.
|
|
33
|
+
if (!args.includes('--no-open') && process.env.TMUXES_OPEN === undefined) {
|
|
34
|
+
process.env.TMUXES_OPEN = '1';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
await import('../dist/index.js');
|
package/package.json
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "tmuxes",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Web UI to run and supervise many CLI coding agents in tmux — local, SSH, and WSL.",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"tmux",
|
|
7
|
-
"terminal",
|
|
8
|
-
"xterm",
|
|
9
|
-
"ssh",
|
|
10
|
-
"wsl",
|
|
11
|
-
"web-terminal",
|
|
12
|
-
"node-pty",
|
|
13
|
-
"cli-agents"
|
|
14
|
-
],
|
|
15
|
-
"license": "MIT",
|
|
16
|
-
"author": "f1974939505 (https://github.com/f1974939505)",
|
|
17
|
-
"homepage": "https://github.com/f1974939505/tmuxes#readme",
|
|
18
|
-
"repository": {
|
|
19
|
-
"type": "git",
|
|
20
|
-
"url": "git+https://github.com/f1974939505/tmuxes.git",
|
|
21
|
-
"directory": "server"
|
|
22
|
-
},
|
|
23
|
-
"bugs": {
|
|
24
|
-
"url": "https://github.com/f1974939505/tmuxes/issues"
|
|
25
|
-
},
|
|
26
|
-
"type": "module",
|
|
27
|
-
"main": "dist/index.js",
|
|
28
|
-
"bin": {
|
|
29
|
-
"tmuxes": "bin/tmuxes.js"
|
|
30
|
-
},
|
|
31
|
-
"engines": {
|
|
32
|
-
"node": ">=22.12.0 <23"
|
|
33
|
-
},
|
|
34
|
-
"files": [
|
|
35
|
-
"dist",
|
|
36
|
-
"public",
|
|
37
|
-
"bin",
|
|
38
|
-
"README.md",
|
|
39
|
-
"LICENSE"
|
|
40
|
-
],
|
|
41
|
-
"scripts": {
|
|
42
|
-
"dev": "tsx watch src/index.ts",
|
|
43
|
-
"build": "tsc -p tsconfig.json",
|
|
44
|
-
"start": "node dist/index.js",
|
|
45
|
-
"test": "vitest run",
|
|
46
|
-
"prepack": "node ../scripts/prepack.mjs"
|
|
47
|
-
},
|
|
48
|
-
"dependencies": {
|
|
49
|
-
"express": "^5.2.1",
|
|
50
|
-
"node-pty": "1.1.0",
|
|
51
|
-
"ws": "^8.21.0"
|
|
52
|
-
},
|
|
53
|
-
"devDependencies": {
|
|
54
|
-
"@types/express": "^5.0.0",
|
|
55
|
-
"@types/node": "^22.10.0",
|
|
56
|
-
"@types/ws": "^8.5.13",
|
|
57
|
-
"tsx": "^4.19.2",
|
|
58
|
-
"typescript": "^5.7.2",
|
|
59
|
-
"vitest": "^2.1.8"
|
|
60
|
-
}
|
|
61
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "tmuxes",
|
|
3
|
+
"version": "0.1.11",
|
|
4
|
+
"description": "Web UI to run and supervise many CLI coding agents in tmux — local, SSH, and WSL.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"tmux",
|
|
7
|
+
"terminal",
|
|
8
|
+
"xterm",
|
|
9
|
+
"ssh",
|
|
10
|
+
"wsl",
|
|
11
|
+
"web-terminal",
|
|
12
|
+
"node-pty",
|
|
13
|
+
"cli-agents"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "f1974939505 (https://github.com/f1974939505)",
|
|
17
|
+
"homepage": "https://github.com/f1974939505/tmuxes#readme",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/f1974939505/tmuxes.git",
|
|
21
|
+
"directory": "server"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/f1974939505/tmuxes/issues"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"main": "dist/index.js",
|
|
28
|
+
"bin": {
|
|
29
|
+
"tmuxes": "bin/tmuxes.js"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=22.12.0 <23"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"public",
|
|
37
|
+
"bin",
|
|
38
|
+
"README.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"dev": "tsx watch src/index.ts",
|
|
43
|
+
"build": "tsc -p tsconfig.json",
|
|
44
|
+
"start": "node dist/index.js",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"prepack": "node ../scripts/prepack.mjs"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"express": "^5.2.1",
|
|
50
|
+
"node-pty": "1.1.0",
|
|
51
|
+
"ws": "^8.21.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/express": "^5.0.0",
|
|
55
|
+
"@types/node": "^22.10.0",
|
|
56
|
+
"@types/ws": "^8.5.13",
|
|
57
|
+
"tsx": "^4.19.2",
|
|
58
|
+
"typescript": "^5.7.2",
|
|
59
|
+
"vitest": "^2.1.8"
|
|
60
|
+
}
|
|
61
|
+
}
|
package/public/index.html
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>tmuxes</title>
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>tmuxes</title>
|
|
7
7
|
<script type="module" crossorigin src="/assets/index-Dl69CPyt.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-D_X5SnGx.css">
|
|
9
|
-
</head>
|
|
10
|
-
<body>
|
|
11
|
-
<div id="root"></div>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|