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.
Files changed (140) hide show
  1. package/.node-version +1 -0
  2. package/.nvmrc +1 -0
  3. package/.tmp-npm-cache/_cacache/content-v2/sha512/43/27/5e000b8b9c56a6ccc66f709485499f4304e2cb1982582ba571321c07b3ef56fcabd2c671898cc8003365a0485b6fd8e73e7b17b073cec0f7d1628c1a99df +0 -0
  4. package/.tmp-npm-cache/_cacache/content-v2/sha512/51/cf/4301295d74559ed494bae160d54d8741077f89faebb311882ac065019246951e7b53f3dcb913793c42b331e14c7070c4810c3cdc27a427d103a7db4614e0 +0 -0
  5. package/.tmp-npm-cache/_cacache/content-v2/sha512/c3/4d/d68a454a916e74c2617f586fbf770981b33811d667c2547eb0e9fc21938f4ee7e98f1ceee4bde8ad8815b5f6efe21b60eee798837d68f51a3340d7e5bb7a +0 -0
  6. package/.tmp-npm-cache/_cacache/content-v2/sha512/fe/40/2abfbefc96299e8bf714aa91d62607190ae299e102cf5933db2e2904640d65d25d67dbbb6fa2ddc92a17f00b9dbfdf2e37487f67d96ec36c64a285b59a7d +0 -0
  7. package/.tmp-npm-cache/_cacache/index-v5/27/fe/81a3de6ce7ae3d1e41a3421de20c5629998c4ee5d0ffe2037630f03b03b2 +4 -0
  8. package/.tmp-npm-cache/_cacache/index-v5/65/22/dd66711f62681fce09aabb2357a2907b4a0c778ac5227c4baf9603fd86e8 +4 -0
  9. package/.tmp-npm-cache/_update-notifier-last-checked +0 -0
  10. package/AGENTS.md +15 -0
  11. package/CLAUDE.md +3 -0
  12. package/LICENSE +21 -21
  13. package/README.en.md +304 -0
  14. package/README.md +299 -295
  15. package/SECURITY.md +31 -0
  16. package/{public → client}/index.html +12 -13
  17. package/client/package.json +29 -0
  18. package/client/src/App.tsx +123 -0
  19. package/client/src/activity.ts +5 -0
  20. package/client/src/api.ts +130 -0
  21. package/client/src/attention.tsx +157 -0
  22. package/client/src/components/FileExplorer.tsx +156 -0
  23. package/client/src/components/FileViewer.tsx +194 -0
  24. package/client/src/components/SessionRow.tsx +108 -0
  25. package/client/src/components/SessionTree.tsx +197 -0
  26. package/client/src/components/SettingsButton.tsx +122 -0
  27. package/client/src/components/Sidebar.tsx +96 -0
  28. package/client/src/components/StatusBanner.tsx +31 -0
  29. package/client/src/components/TargetGroup.tsx +275 -0
  30. package/client/src/components/TerminalPanel.tsx +192 -0
  31. package/client/src/folders.ts +245 -0
  32. package/client/src/hooks/useTerminal.ts +67 -0
  33. package/client/src/hooks/useTmuxSocket.ts +65 -0
  34. package/client/src/i18n.ts +213 -0
  35. package/client/src/main.tsx +17 -0
  36. package/client/src/settings.tsx +87 -0
  37. package/client/src/styles.css +723 -0
  38. package/client/src/types.ts +93 -0
  39. package/client/src/util.ts +65 -0
  40. package/client/tsconfig.json +13 -0
  41. package/client/vite.config.ts +15 -0
  42. package/fig/fig1.png +0 -0
  43. package/package.json +28 -61
  44. package/scripts/prepack.mjs +35 -0
  45. package/{bin → server/bin}/tmuxes.js +36 -36
  46. package/server/package.json +61 -0
  47. package/server/src/agentHooks.ts +120 -0
  48. package/server/src/agentOutput.ts +36 -0
  49. package/server/src/agentState.ts +70 -0
  50. package/server/src/config.ts +31 -0
  51. package/server/src/exe.ts +34 -0
  52. package/server/src/exec.ts +61 -0
  53. package/server/src/files.ts +330 -0
  54. package/server/src/foldersStore.ts +114 -0
  55. package/server/src/index.ts +114 -0
  56. package/server/src/logger.ts +16 -0
  57. package/{dist/monitor.js → server/src/monitor.ts} +10 -9
  58. package/server/src/openBrowser.ts +28 -0
  59. package/{dist/platform.js → server/src/platform.ts} +4 -5
  60. package/server/src/rest/router.ts +290 -0
  61. package/server/src/targetCommand.ts +79 -0
  62. package/server/src/targets.ts +152 -0
  63. package/server/src/tmux/builder.ts +198 -0
  64. package/server/src/tmux/formats.ts +95 -0
  65. package/server/src/tmux/sessions.ts +204 -0
  66. package/server/src/validate.ts +79 -0
  67. package/server/src/windowsSsh.ts +239 -0
  68. package/server/src/winshell/manager.ts +296 -0
  69. package/server/src/ws/protocol.ts +15 -0
  70. package/server/src/ws/sshState.ts +36 -0
  71. package/server/src/ws/terminalSession.ts +207 -0
  72. package/server/src/ws/wsServer.ts +153 -0
  73. package/server/src/wsl.ts +38 -0
  74. package/server/test/agentHooks.test.ts +66 -0
  75. package/server/test/agentOutput.test.ts +26 -0
  76. package/server/test/agentState.test.ts +24 -0
  77. package/server/test/builder.test.ts +162 -0
  78. package/server/test/files.test.ts +81 -0
  79. package/server/test/formats.test.ts +123 -0
  80. package/server/test/monitor.test.ts +25 -0
  81. package/server/test/validate.test.ts +71 -0
  82. package/server/test/wsl.test.ts +18 -0
  83. package/server/tsconfig.json +9 -0
  84. package/server/vitest.config.ts +12 -0
  85. package/start.cmd +30 -0
  86. package/start.command +20 -0
  87. package/start.sh +20 -0
  88. package/tsconfig.base.json +19 -0
  89. package/dist/agentHooks.js +0 -91
  90. package/dist/agentHooks.js.map +0 -1
  91. package/dist/agentOutput.js +0 -30
  92. package/dist/agentOutput.js.map +0 -1
  93. package/dist/agentState.js +0 -45
  94. package/dist/agentState.js.map +0 -1
  95. package/dist/config.js +0 -32
  96. package/dist/config.js.map +0 -1
  97. package/dist/exe.js +0 -37
  98. package/dist/exe.js.map +0 -1
  99. package/dist/exec.js +0 -43
  100. package/dist/exec.js.map +0 -1
  101. package/dist/files.js +0 -243
  102. package/dist/files.js.map +0 -1
  103. package/dist/foldersStore.js +0 -103
  104. package/dist/foldersStore.js.map +0 -1
  105. package/dist/index.js +0 -117
  106. package/dist/index.js.map +0 -1
  107. package/dist/logger.js +0 -16
  108. package/dist/logger.js.map +0 -1
  109. package/dist/monitor.js.map +0 -1
  110. package/dist/openBrowser.js +0 -31
  111. package/dist/openBrowser.js.map +0 -1
  112. package/dist/platform.js.map +0 -1
  113. package/dist/rest/router.js +0 -190
  114. package/dist/rest/router.js.map +0 -1
  115. package/dist/targetCommand.js +0 -41
  116. package/dist/targetCommand.js.map +0 -1
  117. package/dist/targets.js +0 -131
  118. package/dist/targets.js.map +0 -1
  119. package/dist/tmux/builder.js +0 -173
  120. package/dist/tmux/builder.js.map +0 -1
  121. package/dist/tmux/formats.js +0 -61
  122. package/dist/tmux/formats.js.map +0 -1
  123. package/dist/tmux/sessions.js +0 -157
  124. package/dist/tmux/sessions.js.map +0 -1
  125. package/dist/validate.js +0 -65
  126. package/dist/validate.js.map +0 -1
  127. package/dist/winshell/manager.js +0 -267
  128. package/dist/winshell/manager.js.map +0 -1
  129. package/dist/ws/protocol.js +0 -4
  130. package/dist/ws/protocol.js.map +0 -1
  131. package/dist/ws/sshState.js +0 -35
  132. package/dist/ws/sshState.js.map +0 -1
  133. package/dist/ws/terminalSession.js +0 -204
  134. package/dist/ws/terminalSession.js.map +0 -1
  135. package/dist/ws/wsServer.js +0 -151
  136. package/dist/ws/wsServer.js.map +0 -1
  137. package/dist/wsl.js +0 -35
  138. package/dist/wsl.js.map +0 -1
  139. package/public/assets/index-BpVrfoZw.js +0 -44
  140. package/public/assets/index-D_X5SnGx.css +0 -1
package/.node-version ADDED
@@ -0,0 +1 @@
1
+ 22.22.2
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ 22.22.2
@@ -0,0 +1,4 @@
1
+
2
+ 5c935bb4c4229cc76bb37916a45d2ba3190210e6 {"key":"pacote:tarball:file:F:/code/tmuxes","integrity":"sha512-QydeAAuLnFamzMZvcJSFSZ9DBOLLGYJYK6VxMhwHs+9W/KvSxnGJjMgAM2WgSFtv2Oc+exewc87A99FijBqZ3w==","time":1780714893051,"size":419815}
3
+ 34271a8f330d5b161da4a2e30264963dc8f279a1 {"key":"pacote:tarball:file:F:/code/tmuxes","integrity":"sha512-/kAqv778limei/cUqpHWJgcZCuKZ4QLPWTPbLikEZA1l0l1n27tvot3JKhfwC52/3y43SH9n2W7DbGSihbWafQ==","time":1780714962636,"size":840264}
4
+ b1ce6b3d2d3aa0248c74f77637f5ba0704fb9dee {"key":"pacote:tarball:file:F:/code/tmuxes","integrity":"sha512-Uc9DASlddFWe1JS64WDVTYdBB3+J+uuzEYgqwGUBkkaVHntT89y5E3k8QrMx4UxwcMSBDDzcJ6Qn0QOn20YU4A==","time":1780715028867,"size":1681047}
@@ -0,0 +1,4 @@
1
+
2
+ 268b8f60e56e5c458e9e45905f57dad595fb681a {"key":"pacote:tarball:file:F:/code/tmuxes/server","integrity":"sha512-w03WikVKkW50wmF/WG+/dwmBszgR1mfCVH6w6fwhk49O5+mPHO7kveitiBW19u/iG2Du55iDfWj1GjNA1+W7eg==","time":1780714730282,"size":219374}
3
+ 8329a242f2276a169b56e417c304244e69949a87 {"key":"pacote:tarball:file:F:/code/tmuxes/server","integrity":"sha512-w03WikVKkW50wmF/WG+/dwmBszgR1mfCVH6w6fwhk49O5+mPHO7kveitiBW19u/iG2Du55iDfWj1GjNA1+W7eg==","time":1780714751284,"size":219374}
4
+ 57fe957b4dfd81411a667ff6c83913ced8841f7e {"key":"pacote:tarball:file:F:/code/tmuxes/server","integrity":"sha512-w03WikVKkW50wmF/WG+/dwmBszgR1mfCVH6w6fwhk49O5+mPHO7kveitiBW19u/iG2Du55iDfWj1GjNA1+W7eg==","time":1780714753967,"size":219374}
File without changes
package/AGENTS.md ADDED
@@ -0,0 +1,15 @@
1
+ # Agent Notes
2
+
3
+ - Keep `README.md` and `README.en.md` synchronized. When changing user-facing README content, update both language versions in the same change unless there is an explicit reason not to.
4
+ - Keep install commands, feature descriptions, requirements, FAQ entries, and changelog items aligned across both README files.
5
+ - `server/README.md` is the packaged README copy. If the root `README.md` changes and the package copy is kept in git, sync it too or run the prepack flow that copies it.
6
+ - If a README change intentionally applies to only one language, mention that explicitly in the final summary.
7
+
8
+ ## SSH Safety Constraints
9
+
10
+ - Do not add SSH port scanning, periodic SSH connectivity probes, or repeated SSH login attempts against cluster/HPC targets. Repeated SSH handshakes may be classified by remote administrators as scanning or brute-force behavior.
11
+ - Do not reintroduce short forced SSH keepalive defaults such as `ServerAliveInterval=30`, and do not add any 10-minute-or-less periodic SSH reconnect/scan loop.
12
+ - SSH management commands for remote targets should reuse a long-lived OpenSSH connection through `ControlMaster`/`ControlPath`/`ControlPersist` where the platform supports it, instead of opening a new SSH connection for every refresh.
13
+ - If a shared SSH connection is interrupted, automatic recovery may try exactly one reconnect. Authentication failures must not be retried automatically.
14
+ - After the single reconnect attempt fails, pause automatic SSH polling for that target, surface a clear frontend warning, and require the user to click a manual reconnect button before trying again.
15
+ - Any future change that touches SSH polling, target refresh, file browsing over SSH, terminal reconnect, or OpenSSH argument construction must be checked against these constraints before commit and release.
package/CLAUDE.md ADDED
@@ -0,0 +1,3 @@
1
+ # Claude Notes
2
+
3
+ Read `AGENTS.md` before making changes in this repository. In particular, README updates must keep `README.md` and `README.en.md` synchronized.
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.en.md ADDED
@@ -0,0 +1,304 @@
1
+ <div align="center">
2
+
3
+ # 🖥️ tmuxes
4
+
5
+ [简体中文](./README.md) | **English**
6
+
7
+ ### One browser tab to run, watch, and wrangle a whole swarm of CLI coding agents.
8
+
9
+ **Claude Code · Codex · OpenCode · Hermes** — each in its own tmux session,
10
+ live across **Local · SSH · WSL**, with a file browser of every agent's working directory.
11
+
12
+ 🔔 **When Claude Code / Codex finishes, stops abnormally, or needs a decision, your browser pings you**: red/green sidebar status dots, done/decision/error badges, a sound, and a flashing tab title when you're away. No more babysitting panes to see whether it is still running.
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>🔒 localhost-only · ⚡ one-click launch · 🔔 agent-hook notifications · 🪟 reaches into WSL on Windows · 🧩 zero config</sub>
26
+
27
+ </div>
28
+
29
+ ---
30
+
31
+ > **Why?** Modern coding agents are long-running terminal processes. Run a few at once and you're juggling
32
+ > panes, SSH windows, and "wait, which box was that on?". **tmuxes** puts all of them behind one clean web UI:
33
+ > spin up a session, drop it in a folder, watch it work, peek at the files it's editing — local or remote, same view.
34
+
35
+ ## ✨ Highlights
36
+
37
+ | | |
38
+ |---|---|
39
+ | 🧠 **Built for agents** | Every agent gets its own tmux session. Create one (with an initial command like `claude` or `codex`), select it, and the right pane becomes a **fully interactive live terminal**. |
40
+ | 🔔 **Done / decision / error notifications** | Sessions created with an initial `claude` or `codex` command automatically get official lifecycle hooks. You can also open an empty session, `cd` to the target directory, then click the terminal's top-right `claude` / `codex` button to launch a hooked agent there. Expanded targets sync every 5 seconds: a red dot means running, a green dot means finished, stopped abnormally, or waiting for your decision, and badges tell those cases apart. |
41
+ | 🌐 **Local · SSH · WSL · native Windows** | One sidebar lists your local machine, your `~/.ssh/config` hosts, your WSL distros (on Windows), and native PowerShell / cmd sessions (on Windows) — all side by side. |
42
+ | 🗂️ **Folder tree** | Organize sessions into **drag-and-drop folders** like a file explorer. Persists locally, per target. |
43
+ | 📂 **Live file browser + editor** | The bottom of the sidebar follows each session's **working directory** — click a code file to split the terminal and **read or edit** it inline (save, undo/redo). |
44
+ | 🔁 **True multi-client sync** | Powered by native `tmux attach`: open the same session in two tabs and they mirror each other, keystroke for keystroke. |
45
+ | ⚙️ **Tweakable** | Adjustable font sizes for the sidebar, terminal, and file viewer — applied live, saved across reloads. |
46
+ | 🚀 **One click** | Double-click `start.cmd` / `start.command` / `start.sh` → it builds, launches, and opens your browser. |
47
+
48
+ ## 🖼️ What it looks like
49
+
50
+ <div align="center">
51
+ <img src="https://raw.githubusercontent.com/f1974939505/tmuxes/main/fig/fig1.png" alt="tmuxes screenshot — one tab to run a swarm of CLI agents" width="900">
52
+ </div>
53
+
54
+ ## 🏗️ Architecture
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, terminal via [`@xterm/xterm`](https://www.npmjs.com/package/@xterm/xterm).
66
+ - **`server/`** — Node + Express + `ws` + `node-pty`. A small REST API runs short-lived tmux *management* commands; a single WebSocket endpoint streams the interactive *attach*.
67
+
68
+ > **No native tmux on Windows?** No problem. The server runs natively (node-pty uses ConPTY) and reaches tmux **inside your WSL distros** via `wsl.exe`. On Linux/macOS it talks to local tmux directly. Remote hosts use the **system `ssh` binary**, reusing your existing `~/.ssh` keys / `ssh-agent` — **no passwords are ever stored.**
69
+
70
+ ## 📦 Install from npm
71
+
72
+ This little thing is still fresh and growing fast, so there may be a few bugs and fixes may ship quickly; use `@latest` to pick up the newest build.
73
+
74
+ ```bash
75
+ # One-shot (no clone, opens the browser):
76
+ npx tmuxes@latest
77
+
78
+ # Or install globally and use the `tmuxes` command:
79
+ npm install -g tmuxes
80
+ tmuxes # → http://127.0.0.1:7420
81
+
82
+ # Flags:
83
+ tmuxes --port 8080 --no-open
84
+ ```
85
+
86
+ > Needs **tmux** on the machine/host you connect to. On **Linux**, `node-pty` compiles from source (`build-essential` + `python3`); **Windows / macOS** ship prebuilt binaries — truly one-click. See Requirements below.
87
+
88
+ ## 🚀 One-click from source (for development)
89
+
90
+ <table>
91
+ <tr><th>OS</th><th>Do this</th></tr>
92
+ <tr><td><b>🪟 Windows 11</b></td><td>Double-click <b><code>start.cmd</code></b> (or run it in Windows Terminal). Installs deps, builds, starts the server, and opens <code>http://127.0.0.1:7420</code>. Your WSL distros appear in the sidebar.</td></tr>
93
+ <tr><td><b>🍎 macOS</b></td><td>Double-click <b><code>start.command</code></b> in Finder <sub>(first time: right-click → Open to bypass Gatekeeper)</sub>.</td></tr>
94
+ <tr><td><b>🐧 Linux</b></td><td>Run <b><code>./start.sh</code></b>.</td></tr>
95
+ </table>
96
+
97
+ ## 🔧 Manual run
98
+
99
+ ```bash
100
+ npm install # node-pty: prebuilt on Win/macOS, compiles from source on Linux
101
+
102
+ # Development — Vite dev server + API with hot reload:
103
+ npm run dev # → http://localhost:5173
104
+
105
+ # Production — build the client, serve everything from one process:
106
+ npm run build
107
+ npm start # → http://localhost:7420 (set TMUXES_OPEN=1 to auto-open the browser)
108
+ ```
109
+
110
+ ## 🔔 Launch Hooked Claude Code / Codex
111
+
112
+ tmuxes currently auto-wires official lifecycle hooks for **Claude Code (`claude`)** and **Codex (`codex`)**, so it can tell whether the agent is running, finished, stopped abnormally, or waiting for your decision.
113
+
114
+ Two launch paths:
115
+
116
+ 1. Create a session with `claude` or `codex` as the initial command.
117
+ 2. Create an empty session, `cd /your/project` in the terminal, then click the terminal's top-right `claude` / `codex` button.
118
+
119
+ Status meanings:
120
+
121
+ - Red dot: the agent is running.
122
+ - Green dot: the agent finished, stopped abnormally, is waiting for your decision, or this session has no agent hook.
123
+ - `done` badge: the current turn finished.
124
+ - `decision` badge: the agent is waiting for permission or user input.
125
+ - `error` badge: the agent stopped abnormally, for example when Codex disconnects without firing a stop hook. During the 5-second sync for expanded targets, tmuxes scans the tail of running agent panes and corrects these cases into an alert state.
126
+
127
+ Note: the top-right buttons send a hooked `claude` / `codex` command into the current tmux pane. Do not click them while another program in that pane is waiting for input. Bare `cc` is often the system C compiler, so tmuxes does not treat it as Claude Code by default. Native Windows shells have no tmux session option, so this hook status is not supported there.
128
+
129
+ ## 🧩 Targets
130
+
131
+ - **Local** *(Linux/macOS)* — your machine's tmux. Not shown on Windows.
132
+ - **Native Windows shells** *(Windows)* — PowerShell / cmd spawned directly via ConPTY (auto-detects `pwsh` → `powershell` → `cmd` → Git Bash); pick the shell when creating. Sessions live as long as the server process (survive refresh / reconnect / multi-tab; lost on server restart). They have no tmux working directory, so the file browser is hidden for them.
133
+ - **WSL distros** *(Windows)* — auto-discovered via `wsl.exe -l -q`; one target per distro. tmux must be installed inside the distro.
134
+ - **SSH hosts** — discovered from your `~/.ssh/config` `Host` entries (wildcards skipped). Add extras explicitly:
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
+ Key/agent auth must already work from a normal shell. For a brand-new host, accept its host key once in a regular terminal first. To avoid repeated SSH handshakes for short management calls, Unix-like platforms keep reusing one long-lived OpenSSH connection with `ControlMaster` / `ControlPersist`; native Windows keeps an app-owned long-lived SSH management connection instead of using Windows OpenSSH mux sockets, avoiding `getsockname failed: Not a socket`. tmuxes no longer forces `ServerAliveInterval`, so add keepalives to your own `~/.ssh/config` only when your site allows them. If the shared/management connection is interrupted, tmuxes rebuilds it and retries once; if that still fails, the frontend shows a warning and pauses automatic polling for that SSH target. Click `Reconnect` to try again manually.
142
+
143
+ ## 💻 Requirements
144
+
145
+ All platforms need **Node 22.12+** (the project version files pin 22.22.2) and **npm 10+**. The rest:
146
+
147
+ <details>
148
+ <summary><b>🪟 Windows 11</b></summary>
149
+
150
+ - WSL2 with at least one distro, and **tmux installed inside it** (`sudo apt install tmux`).
151
+ - The built-in OpenSSH client covers SSH targets.
152
+ - node-pty ships a **prebuilt Windows binary** — no compiler needed.
153
+
154
+ </details>
155
+
156
+ <details>
157
+ <summary><b>🍎 macOS</b></summary>
158
+
159
+ - `tmux` on `PATH` (`brew install tmux`).
160
+ - node-pty ships a **prebuilt darwin binary**.
161
+ - Launching from Finder and tmux isn't found? Make sure Homebrew's bin dir is on the GUI `PATH`.
162
+
163
+ </details>
164
+
165
+ <details>
166
+ <summary><b>🐧 Linux</b></summary>
167
+
168
+ - `tmux`, plus a C/C++ toolchain + Python 3 for node-pty (**no Linux prebuilt — it compiles on install**):
169
+ ```bash
170
+ sudo apt-get install -y build-essential python3 tmux
171
+ ```
172
+ - WSL gotcha: `node-gyp` uses whatever `python3` is on `PATH`. If a broken conda Python breaks the build:
173
+ ```bash
174
+ npm config set python /usr/bin/python3
175
+ ```
176
+
177
+ </details>
178
+
179
+ <details>
180
+ <summary><b>Run the server inside WSL instead (alternative)</b></summary>
181
+
182
+ On Windows you can also run the whole server *inside* WSL (like Linux) and just open the browser on Windows — WSL2 forwards `localhost`. The native-Windows + `wsl.exe` setup is what the one-click launcher uses, so it also covers SSH targets and multiple distros in one place.
183
+
184
+ </details>
185
+
186
+ ## 🔒 Security
187
+
188
+ > ⚠️ **tmuxes grants full shell access to anything that can reach it.** It is a single-user, localhost dev tool.
189
+
190
+ By design it:
191
+
192
+ - binds to **`127.0.0.1` only** — the bind address is not configurable at runtime,
193
+ - has **no authentication**,
194
+ - **never spawns a shell** (argv arrays + `shell:false`) and allowlist-validates every input,
195
+ - rejects WebSocket upgrades whose `Origin` isn't localhost (anti DNS-rebind),
196
+ - scopes the file browser/editor to the selected tmux session's current working directory.
197
+
198
+ **Do not** reverse-proxy, tunnel, port-forward, or expose it on `0.0.0.0`. Any local user on the machine can use it.
199
+
200
+ ## 🧪 Tests
201
+
202
+ ```bash
203
+ npm test # vitest: input validation, list parsing, ssh/tmux/wsl argv shapes
204
+ ```
205
+
206
+ ## 🐧 tmux cheat sheet
207
+
208
+ > tmux's "prefix" key is **`Ctrl+b`** by default (written `C-b` below) — press it, release, then press the next key.
209
+ > In a web terminal the thing you'll reach for most is **scroll / copy mode** (scroll back through output, copy text).
210
+
211
+ ### Scroll & copy (most used)
212
+
213
+ | Action | Keys |
214
+ |---|---|
215
+ | Enter copy / scroll mode | `C-b` then `[` |
216
+ | Scroll in that mode | `↑ ↓`, `PageUp` / `PageDown` |
217
+ | Select → copy | `Space` to start → move cursor → `Enter` to copy |
218
+ | Paste it back | `C-b` then `]` |
219
+ | Search in that mode | `C-s` forward / `C-r` backward (emacs-style default) |
220
+ | Quit copy / scroll mode | `q` |
221
+ | **Enable mouse wheel** (scroll + select with the mouse) | run `tmux set -g mouse on`, or put it in `~/.tmux.conf` |
222
+ | **Hold Shift for the mouse** (bypass tmux mouse mode) | Hold `Shift`, drag to select → browser right-click "Copy"; right-click "Paste" |
223
+
224
+ > Tip: once `mouse on` is set, the mouse belongs to tmux; to use the browser's native **drag-select + right-click copy/paste**, hold `Shift` while dragging / right-clicking.
225
+ >
226
+ > Tip: in tmuxes, you can **create / select / rename / kill sessions** directly from the UI; no tmux commands needed for those. Scrolling through history, copying text, and splitting panes are tmux features, so use the shortcuts above for them.
227
+
228
+
229
+ ## ❓ FAQ
230
+
231
+ <details>
232
+ <summary><b>On one cluster, Chinese (or other non-ASCII) text in tmux shows up as underscores <code>_</code>?</b></summary>
233
+
234
+ That machine's login locale isn't UTF-8 (common on HPC login nodes — `LANG=C` / `POSIX`), so tmux runs in **non-UTF-8 mode** and renders each multibyte character as `_`. Fix it **on that machine**:
235
+
236
+ 1. Set a UTF-8 locale — check what's available, then add it to `~/.bashrc` / `~/.zshrc`:
237
+ ```bash
238
+ locale -a | grep -i utf # see which exist (C.UTF-8 / en_US.UTF-8 / zh_CN.UTF-8 …)
239
+ echo 'export LANG=C.UTF-8' >> ~/.bashrc # use a real one from the list above
240
+ ```
241
+ 2. Restart that machine's tmux server so sessions are recreated under UTF-8:
242
+ ```bash
243
+ tmux kill-server
244
+ ```
245
+ 3. Reconnect / create a session from tmuxes.
246
+
247
+ > ⚠️ A pane's UTF-8 mode is fixed **when it's created** — changing the locale **without restarting the server** won't fix already-broken sessions; they must be recreated.
248
+
249
+ </details>
250
+
251
+ ## 📋 Changelog
252
+
253
+ ### 0.1.9
254
+ - **fix: native Windows SSH management commands now use an app-owned long-lived connection.** Avoids Windows OpenSSH `ControlMaster` mux socket failures (`getsockname failed: Not a socket`) while preventing short management calls from repeatedly opening SSH connections.
255
+ - **improve: file browser remote directory refresh is now coalesced.** One remote call reads the pane cwd, validates scope, and lists the directory, reducing SSH management traffic.
256
+
257
+ ### 0.1.8
258
+ - **docs: add the missing 0.1.7 changelog and republish npm package.** Ensures the npm page and repository README both document the SSH long-connection / reconnect behavior.
259
+
260
+ ### 0.1.7
261
+ - **improve: SSH targets now reuse a long-lived connection.** Unix-like platforms use OpenSSH `ControlMaster` / `ControlPersist` so short management commands do not repeatedly create new SSH connections.
262
+ - **change: tmuxes no longer forces `ServerAliveInterval=30`.** Add keepalives to your own `~/.ssh/config` only when your site allows them.
263
+ - **fix: SSH interruptions retry once and then notify the user.** If the shared connection breaks, tmuxes removes the stale control socket and retries once directly; if that still fails, automatic polling pauses and the frontend shows a `Reconnect` button.
264
+
265
+ ### 0.1.6
266
+ - **fix: Codex stream disconnects no longer leave the red dot stuck.** When Codex prints `stream disconnected before completion` but does not fire a stop hook, the 5-second sync for expanded targets scans the tail of running agent panes, writes back an `error` alert, and restores the dot to green.
267
+ - **improve: Claude Code `StopFailure` is now classified as an abnormal stop.** Normal `Stop` / `SessionEnd` events still show `done`; failed stops show `error`.
268
+
269
+ ### 0.1.5
270
+ - **fix: Claude Code launch now uses the `claude` command.** Bare `cc` is the system C compiler in many Linux/SSH environments, so tmuxes no longer treats it as Claude Code by default; the top-right buttons are now `claude` / `codex`.
271
+ - **change: project Node version is standardized on 22.** Added `.nvmrc` / `.node-version`, and package engines now require Node `>=22.12.0 <23`.
272
+
273
+ ### 0.1.4
274
+ - **improve: notifications now use official Claude Code / Codex lifecycle hooks.** Sessions created with an initial `claude` or `codex` command get hooks injected automatically; you can also open an empty session, `cd` to the target directory, then click the top-right `claude` / `codex` button to launch a hooked agent there. tmuxes syncs their tmux session option every 5 seconds. A red dot means running, a green dot means finished or waiting for a decision, and badges distinguish done vs. decision alerts.
275
+
276
+ ### 0.1.3
277
+ - **fix (Windows)**: `Ctrl+C` actually stops the server now. The previous fix was buggy (the readline bridge never entered terminal mode, so it was a no-op), and node-pty's ConPTY backend breaks the host's `CTRL_C_EVENT → SIGINT` path. We now **read the raw Ctrl+C byte (0x03) straight from the console**, bypassing the broken signal machinery. `Ctrl+Break` still works too.
278
+ - **change: native browser right-click restored.** The terminal no longer suppresses the context menu. To use the browser's native **drag-select + right-click copy/paste**, hold `Shift` while dragging / right-clicking (bypasses tmux mouse mode).
279
+
280
+ ### 0.1.2
281
+ - **New: active-to-quiet notifications.** Zero-config monitoring of every session: when a session's terminal screen stops changing, you get a **sidebar status dot + sound + background tab-title flash**. Toggle notifications and sound in Settings.
282
+
283
+ ### 0.1.1
284
+ - **fix (Windows)**: `Ctrl+C` now correctly stops the server. ConPTY child processes (node-pty) were consuming the `CTRL_C_EVENT` before it reached the host node process; fixed by bridging SIGINT via `readline` directly from the console input layer.
285
+ - **fix (terminal)**: Right-click now works in tmux mouse mode. The browser's native context menu is suppressed inside the terminal area so right-click events flow through xterm → tmux. Requires `set -g mouse on` in tmux.
286
+
287
+ ### 0.1.0
288
+ - Initial release.
289
+
290
+ <div align="center">
291
+ <sub>Built with React, TypeScript, node-pty &amp; xterm.js — plus a lot of tmux. Happy babysitting. 🤖</sub>
292
+ </div>
293
+
294
+ ## 🧑‍🔬 About the author
295
+
296
+ > Hey, I'm the human behind this thing 👋
297
+ >
298
+ > A theoretical-physics PhD student at **USTC** (University of Science and Technology of China), spending my days wrestling with an **interpretable many-body-field-theory of Fermi superfluidity** (the stuff we use to study and explain high-Tc superconductivity), plus a small mountain of **high-performance numerical code** ⚛️.
299
+ >
300
+ > This tool started life as a self-rescue mission — if I'm going to babysit a swarm of CLI agents all day, they might as well have a proper command deck 😎.
301
+ >
302
+ > If any of that sounds fun (physics or code — either works), or you'd like to hack on this project together, come say hi 📮
303
+ >
304
+ > **📧 junruwu@mail.ustc.edu.cn**