tmuxes 0.1.2 → 0.1.4
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/README.md +58 -26
- package/bin/tmuxes.js +0 -0
- package/dist/agentHooks.js +92 -0
- package/dist/agentHooks.js.map +1 -0
- package/dist/agentState.js +45 -0
- package/dist/agentState.js.map +1 -0
- package/dist/index.js +42 -5
- package/dist/index.js.map +1 -1
- package/dist/monitor.js +0 -0
- package/dist/monitor.js.map +1 -1
- package/dist/rest/router.js +15 -6
- package/dist/rest/router.js.map +1 -1
- package/dist/tmux/formats.js +6 -2
- package/dist/tmux/formats.js.map +1 -1
- package/dist/tmux/sessions.js +39 -9
- package/dist/tmux/sessions.js.map +1 -1
- package/dist/winshell/manager.js +0 -13
- package/dist/winshell/manager.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/{index-n4LbpWeu.css → index-BorZEUXh.css} +1 -1
- package/public/assets/index-F0cL3gdE.js +44 -0
- package/public/index.html +2 -2
- package/dist/attention.js +0 -54
- package/dist/attention.js.map +0 -1
- package/public/assets/index-BmRC6hB0.js +0 -44
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
**Claude Code · Codex · OpenCode · Hermes** —— 每个 agent 独占一个 tmux 会话,
|
|
10
10
|
横跨 **本地 · SSH · WSL**,还自带每个 agent 工作目录的文件浏览器。
|
|
11
11
|
|
|
12
|
-
🔔 **
|
|
12
|
+
🔔 **Claude Code / Codex 结束运行或需要决策时,浏览器会自动提醒你** —— 侧边栏红/绿状态点 +「结束 / 决策」提示 + 提示音 + 后台标签页标题闪烁。再也不用挨个窗格去盯「它还在跑吗」。
|
|
13
13
|
|
|
14
14
|
<p>
|
|
15
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>
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<img alt="xterm.js" src="https://img.shields.io/badge/xterm.js-6-1f6feb?style=flat-square">
|
|
23
23
|
</p>
|
|
24
24
|
|
|
25
|
-
<sub>🔒 仅本机 · ⚡ 一键启动 · 🔔
|
|
25
|
+
<sub>🔒 仅本机 · ⚡ 一键启动 · 🔔 agent hook 提醒 · 🪟 Windows 上直通 WSL · 🧩 零配置</sub>
|
|
26
26
|
|
|
27
27
|
</div>
|
|
28
28
|
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
| | |
|
|
38
38
|
|---|---|
|
|
39
39
|
| 🧠 **为 agent 而生** | 每个 agent 独占一个 tmux 会话。新建时可带初始命令(比如 `claude` 或 `codex`),选中后右侧就是一个**完全可交互的实时终端**。 |
|
|
40
|
-
| 🔔
|
|
40
|
+
| 🔔 **结束 / 决策提醒** | 新建会话时初始命令是 `claude`、`cc` 或 `codex` 会自动接入官方 lifecycle hooks。也可以先进入空 session `cd` 到目标目录,再点终端右上角的 `cc` / `codex` 按钮启动带 hook 的 agent。已展开目标每 5 秒同步一次:红点表示 agent 正在运行,绿点表示已结束或正在等你决策;结束运行和需要决策会显示不同提示。 |
|
|
41
41
|
| 🌐 **本地 · SSH · WSL · 原生 Windows** | 一个侧边栏同时列出你的本机、`~/.ssh/config` 里的主机、(Windows 上)你的 WSL 发行版,以及(Windows)原生 PowerShell / cmd 会话 —— 全部并排排开。 |
|
|
42
42
|
| 🗂️ **文件夹树** | 像资源管理器一样,把会话拖进**可拖拽的文件夹**里整理。按目标分别持久化到本地。 |
|
|
43
43
|
| 📂 **实时文件浏览 + 编辑** | 侧边栏底部跟随每个会话的**工作目录** —— 点一个代码文件就能把终端一分为二,在下面**直接读和改**(可保存、撤销/重做)。 |
|
|
@@ -47,27 +47,9 @@
|
|
|
47
47
|
|
|
48
48
|
## 🖼️ 长这样
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
│ │ │
|
|
54
|
-
│ ▾ Local local │ $ claude "refactor the auth module" │
|
|
55
|
-
│ 📂 frontend │ ⠿ thinking… │
|
|
56
|
-
│ ● agent1 2 win · 3m │ ▸ Editing src/auth/session.ts │
|
|
57
|
-
│ ○ agent2 1 win │ ▸ Running tests… │
|
|
58
|
-
│ 📁 backend │ │
|
|
59
|
-
│ ○ scratch 1 win │ │
|
|
60
|
-
│ ▾ devbox ssh ├───────────────── src/auth/session.ts ─────────┤
|
|
61
|
-
│ ○ build 1 win │ 1 export function createSession(user) { │
|
|
62
|
-
│ ─────────── drag ──────── │ 2 const token = sign(user, KEY) │
|
|
63
|
-
│ WORKING DIRECTORY ↑ ⌂ │ 3 return { token, exp: Date.now() + TTL } │
|
|
64
|
-
│ 📁 src │ 4 } │
|
|
65
|
-
│ 📄 session.ts │ │
|
|
66
|
-
│ 📄 README.md │ │
|
|
67
|
-
│ ⚙ Settings │ │
|
|
68
|
-
└───────────────────────────┴──────────────────────────────────────────────┘
|
|
69
|
-
侧边栏:tmux 树 + 当前目录文件浏览器 终端 ╱ 打开的文件
|
|
70
|
-
```
|
|
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>
|
|
71
53
|
|
|
72
54
|
## 🏗️ 架构
|
|
73
55
|
|
|
@@ -123,6 +105,24 @@ npm run build
|
|
|
123
105
|
npm start # → http://localhost:7420 (设 TMUXES_OPEN=1 可自动打开浏览器)
|
|
124
106
|
```
|
|
125
107
|
|
|
108
|
+
## 🔔 启动带 hook 的 cc / Codex
|
|
109
|
+
|
|
110
|
+
tmuxes 目前会给 **Claude Code (`cc`)** 和 **Codex (`codex`)** 自动接入官方 lifecycle hooks,用来判断 agent 是正在运行、已经结束,还是正在等你做决策。
|
|
111
|
+
|
|
112
|
+
两种用法:
|
|
113
|
+
|
|
114
|
+
1. 新建 session 时,在初始命令里直接填 `cc` 或 `codex`。
|
|
115
|
+
2. 先新建空 session,进入后在终端里 `cd /你的目标目录`,再点终端右上角的 `cc` / `codex` 按钮。
|
|
116
|
+
|
|
117
|
+
状态含义:
|
|
118
|
+
|
|
119
|
+
- 红点:agent 正在运行。
|
|
120
|
+
- 绿点:agent 已结束、正在等你决策,或这个 session 没接入 agent hook。
|
|
121
|
+
- `结束` badge:本轮运行结束。
|
|
122
|
+
- `决策` badge:agent 正在等待权限确认或用户输入。
|
|
123
|
+
|
|
124
|
+
注意:右上角按钮本质上是向当前 tmux pane 发送一条带 hook 的 `cc` / `codex` 命令。不要在当前 pane 里已有程序正在接收输入时点击它。原生 Windows shell 没有 tmux session option,因此不支持这套 hook 状态。
|
|
125
|
+
|
|
126
126
|
## 🧩 目标(Targets)
|
|
127
127
|
|
|
128
128
|
- **本地** *(Linux/macOS)* —— 你机器上的 tmux。Windows 上不显示。
|
|
@@ -216,13 +216,45 @@ npm test # vitest:输入校验、列表解析、ssh/tmux/wsl 的 argv 形状
|
|
|
216
216
|
| 在模式里搜索 | `C-s` 向前 / `C-r` 向后(默认 emacs 风格) |
|
|
217
217
|
| 退出复制 / 滚动模式 | `q` |
|
|
218
218
|
| **开鼠标滚轮**(直接滚轮翻 + 鼠标选) | 执行 `tmux set -g mouse on`,或写进 `~/.tmux.conf` |
|
|
219
|
+
| **按住 Shift 用鼠标**(绕过 tmux 鼠标模式) | 按住 `Shift` 拖动选中文字 → 浏览器右键「复制」;右键「粘贴」 |
|
|
219
220
|
|
|
221
|
+
> 提示:开了 `mouse on` 后鼠标归 tmux 管;想用浏览器原生的**框选 + 右键复制粘贴**,**按住 `Shift`** 再拖动 / 右键即可。
|
|
222
|
+
>
|
|
220
223
|
> 提示:在 tmuxes 里**新建 / 选择 / 重命名 / 杀会话**直接点 UI 就行,不用记命令;但**往上滚看历史、复制文字、拆面板**这些是 tmux 自己的功能,得用上面的快捷键。
|
|
221
224
|
|
|
225
|
+
## ❓ 常见问题
|
|
226
|
+
|
|
227
|
+
<details>
|
|
228
|
+
<summary><b>某个集群里 tmux 的中文(或其它非 ASCII 字符)全变成了下划线 <code>_</code>?</b></summary>
|
|
229
|
+
|
|
230
|
+
那台机器的登录 locale 不是 UTF-8(HPC 登录节点很常见,`LANG=C` / `POSIX`),于是 tmux 进入**非 UTF-8 模式**,把每个多字节字符用 `_` 占位。**在那台机器上**修:
|
|
231
|
+
|
|
232
|
+
1. 设一个 UTF-8 locale —— 先看哪些可用,再写进 `~/.bashrc` / `~/.zshrc`:
|
|
233
|
+
```bash
|
|
234
|
+
locale -a | grep -i utf # 看有哪些(C.UTF-8 / en_US.UTF-8 / zh_CN.UTF-8 …)
|
|
235
|
+
echo 'export LANG=C.UTF-8' >> ~/.bashrc # 换成上面真实存在的那个
|
|
236
|
+
```
|
|
237
|
+
2. 重启该机器上的 tmux 服务,让会话以 UTF-8 重新创建:
|
|
238
|
+
```bash
|
|
239
|
+
tmux kill-server
|
|
240
|
+
```
|
|
241
|
+
3. 回到 tmuxes 重新连接 / 新建会话即可。
|
|
242
|
+
|
|
243
|
+
> ⚠️ pane 的 UTF-8 模式在**创建时**就定死了 —— 只改 locale **不重启 server** 的话,已经变成下划线的旧会话不会自动恢复,必须重建。
|
|
244
|
+
|
|
245
|
+
</details>
|
|
246
|
+
|
|
222
247
|
## 📋 更新日志
|
|
223
248
|
|
|
249
|
+
### 0.1.4
|
|
250
|
+
- **改进:提醒改为 Claude Code / Codex 官方 lifecycle hooks**。新建会话时初始命令是 `claude`、`cc` 或 `codex` 会自动注入 hooks;也可以先进入空 session `cd` 到目标目录,再点右上角 `cc` / `codex` 按钮启动带 hook 的 agent。tmuxes 每 5 秒读取 tmux session option 同步状态。红点表示正在运行,绿点表示已结束或需要决策,并分别显示「结束 / 决策」提示。
|
|
251
|
+
|
|
252
|
+
### 0.1.3
|
|
253
|
+
- **修复 (Windows)**:`Ctrl+C` 现在真的能停掉服务了。之前的修复有 bug(readline 没进入终端模式,信号桥接形同虚设),而且 node-pty 的 ConPTY 会破坏宿主进程的 `CTRL_C_EVENT → SIGINT` 通路。改为**直接从控制台读取 `Ctrl+C` 原始字节(0x03)**,绕开被破坏的信号机制。`Ctrl+Break` 同样可用。
|
|
254
|
+
- **变更:恢复浏览器原生右键**。终端区域不再拦截右键菜单。想用浏览器原生**框选 + 右键复制粘贴**,**按住 `Shift`** 拖动 / 右键即可(绕过 tmux 鼠标模式)。
|
|
255
|
+
|
|
224
256
|
### 0.1.2
|
|
225
|
-
-
|
|
257
|
+
- **新增:活动转静止提醒**。零配置监测每个会话——session 终端画面从持续变化转为静止后,通过**侧边栏状态点 + 提示音 + 后台标签页标题闪烁**提醒你。设置面板可开关提醒与提示音。
|
|
226
258
|
|
|
227
259
|
### 0.1.1
|
|
228
260
|
- **修复 (Windows)**:`Ctrl+C` 现在可以正常终止服务端进程。node-pty 的 ConPTY 子进程会拦截 `CTRL_C_EVENT` 导致 SIGINT 无法到达宿主 node;通过 `readline` 从控制台输入层直接桥接 SIGINT 修复此问题。
|
|
@@ -245,4 +277,4 @@ npm test # vitest:输入校验、列表解析、ssh/tmux/wsl 的 argv 形状
|
|
|
245
277
|
>
|
|
246
278
|
> 如果你也对这些感兴趣(物理也好、代码也好),或者想一起折腾这个开源项目,随时来找我玩 📮
|
|
247
279
|
>
|
|
248
|
-
> **📧 junruwu@mail.ustc.edu.cn**
|
|
280
|
+
> **📧 junruwu@mail.ustc.edu.cn**
|
package/bin/tmuxes.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { agentHookCommand, } from './agentState.js';
|
|
2
|
+
function isDisabled() {
|
|
3
|
+
const v = process.env.TMUXES_NO_AUTOHOOK;
|
|
4
|
+
return v === '1' || v === 'true';
|
|
5
|
+
}
|
|
6
|
+
function baseName(token) {
|
|
7
|
+
return (token.split(/[\\/]/).pop() || '').toLowerCase().replace(/\.(exe|cmd|bat)$/, '');
|
|
8
|
+
}
|
|
9
|
+
export function detectAgentKind(command) {
|
|
10
|
+
if (isDisabled())
|
|
11
|
+
return undefined;
|
|
12
|
+
const trimmed = command.trim();
|
|
13
|
+
if (!trimmed)
|
|
14
|
+
return undefined;
|
|
15
|
+
const m = /^(\S+)(\s+[\s\S]*)?$/.exec(trimmed);
|
|
16
|
+
if (!m)
|
|
17
|
+
return undefined;
|
|
18
|
+
switch (baseName(m[1])) {
|
|
19
|
+
case 'claude':
|
|
20
|
+
case 'cc':
|
|
21
|
+
return 'claude';
|
|
22
|
+
case 'codex':
|
|
23
|
+
return 'codex';
|
|
24
|
+
default:
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function hook(kind, state, reason, event) {
|
|
29
|
+
return { type: 'command', command: agentHookCommand(kind, state, reason, event) };
|
|
30
|
+
}
|
|
31
|
+
function claudeSettings() {
|
|
32
|
+
return JSON.stringify({
|
|
33
|
+
hooks: {
|
|
34
|
+
UserPromptSubmit: [{ hooks: [hook('claude', 'running', '', 'UserPromptSubmit')] }],
|
|
35
|
+
PreToolUse: [{ matcher: '', hooks: [hook('claude', 'running', '', 'PreToolUse')] }],
|
|
36
|
+
PostToolUse: [{ matcher: '', hooks: [hook('claude', 'running', '', 'PostToolUse')] }],
|
|
37
|
+
PermissionRequest: [
|
|
38
|
+
{ matcher: '', hooks: [hook('claude', 'waiting', 'decision', 'PermissionRequest')] },
|
|
39
|
+
],
|
|
40
|
+
Notification: [
|
|
41
|
+
{
|
|
42
|
+
matcher: 'permission_prompt',
|
|
43
|
+
hooks: [hook('claude', 'waiting', 'decision', 'Notification.permission_prompt')],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
matcher: 'elicitation_dialog',
|
|
47
|
+
hooks: [hook('claude', 'waiting', 'decision', 'Notification.elicitation_dialog')],
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
Stop: [{ hooks: [hook('claude', 'idle', 'done', 'Stop')] }],
|
|
51
|
+
StopFailure: [{ hooks: [hook('claude', 'idle', 'done', 'StopFailure')] }],
|
|
52
|
+
SessionEnd: [{ hooks: [hook('claude', 'idle', 'done', 'SessionEnd')] }],
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function tomlString(v) {
|
|
57
|
+
return `"${v.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
58
|
+
}
|
|
59
|
+
function codexHookConfig(event, cmd, opts = {}) {
|
|
60
|
+
const matcher = opts.matcher === undefined ? '' : `matcher=${tomlString(opts.matcher)},`;
|
|
61
|
+
return `hooks.${event}=[{${matcher}hooks=[{type="command",command=${tomlString(cmd)}}]}]`;
|
|
62
|
+
}
|
|
63
|
+
function codexConfigArgs() {
|
|
64
|
+
const configs = [
|
|
65
|
+
codexHookConfig('UserPromptSubmit', agentHookCommand('codex', 'running', '', 'UserPromptSubmit')),
|
|
66
|
+
codexHookConfig('PreToolUse', agentHookCommand('codex', 'running', '', 'PreToolUse'), {
|
|
67
|
+
matcher: '',
|
|
68
|
+
}),
|
|
69
|
+
codexHookConfig('PostToolUse', agentHookCommand('codex', 'running', '', 'PostToolUse'), {
|
|
70
|
+
matcher: '',
|
|
71
|
+
}),
|
|
72
|
+
codexHookConfig('PermissionRequest', agentHookCommand('codex', 'waiting', 'decision', 'PermissionRequest'), { matcher: '' }),
|
|
73
|
+
codexHookConfig('Stop', agentHookCommand('codex', 'idle', 'done', 'Stop')),
|
|
74
|
+
];
|
|
75
|
+
return configs.map((c) => `-c '${c}'`).join(' ');
|
|
76
|
+
}
|
|
77
|
+
export function augmentAgentCommand(command) {
|
|
78
|
+
const kind = detectAgentKind(command);
|
|
79
|
+
if (!kind)
|
|
80
|
+
return { command };
|
|
81
|
+
const trimmed = command.trim();
|
|
82
|
+
const m = /^(\S+)(\s+[\s\S]*)?$/.exec(trimmed);
|
|
83
|
+
if (!m)
|
|
84
|
+
return { command };
|
|
85
|
+
const prog = m[1];
|
|
86
|
+
const rest = m[2] ?? '';
|
|
87
|
+
if (kind === 'claude') {
|
|
88
|
+
return { kind, command: `${prog} --settings '${claudeSettings()}'${rest}` };
|
|
89
|
+
}
|
|
90
|
+
return { kind, command: `${prog} ${codexConfigArgs()}${rest}` };
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=agentHooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentHooks.js","sourceRoot":"","sources":["../src/agentHooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export const AGENT_OPTION = '@tmuxes_agent';
|
|
2
|
+
function isAgentKind(v) {
|
|
3
|
+
return v === 'claude' || v === 'codex';
|
|
4
|
+
}
|
|
5
|
+
function isAgentState(v) {
|
|
6
|
+
return v === 'running' || v === 'waiting' || v === 'idle';
|
|
7
|
+
}
|
|
8
|
+
function isAttentionReason(v) {
|
|
9
|
+
return v === 'decision' || v === 'done';
|
|
10
|
+
}
|
|
11
|
+
function cleanToken(v) {
|
|
12
|
+
return v.replace(/[^A-Za-z0-9_.-]/g, '_');
|
|
13
|
+
}
|
|
14
|
+
export function agentValue(kind, state, reason, event, nonce) {
|
|
15
|
+
return [
|
|
16
|
+
kind,
|
|
17
|
+
state,
|
|
18
|
+
reason,
|
|
19
|
+
cleanToken(event),
|
|
20
|
+
nonce.replace(/:/g, '_'),
|
|
21
|
+
].join(':');
|
|
22
|
+
}
|
|
23
|
+
export function agentInitialValue(kind) {
|
|
24
|
+
return agentValue(kind, 'idle', '', 'launch', String(Date.now()));
|
|
25
|
+
}
|
|
26
|
+
export function agentHookCommand(kind, state, reason, event) {
|
|
27
|
+
return `tmux set-option -q ${AGENT_OPTION} ${agentValue(kind, state, reason, event, '$(date +%s).$$')}`;
|
|
28
|
+
}
|
|
29
|
+
export function parseAgentValue(raw) {
|
|
30
|
+
if (!raw)
|
|
31
|
+
return undefined;
|
|
32
|
+
const [kind, state, reason, event, ...nonceParts] = raw.split(':');
|
|
33
|
+
if (!isAgentKind(kind) || !isAgentState(state))
|
|
34
|
+
return undefined;
|
|
35
|
+
const snap = { agentKind: kind, agentState: state };
|
|
36
|
+
if (isAttentionReason(reason))
|
|
37
|
+
snap.attentionReason = reason;
|
|
38
|
+
if (event)
|
|
39
|
+
snap.agentEvent = event;
|
|
40
|
+
const nonce = nonceParts.join(':');
|
|
41
|
+
if (nonce)
|
|
42
|
+
snap.agentNonce = nonce;
|
|
43
|
+
return snap;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=agentState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentState.js","sourceRoot":"","sources":["../src/agentState.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC;AAE5C,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,OAAO,CAAC;AACzC,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,MAAM,CAAC;AAC5D,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAS;IAClC,OAAO,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,MAAM,CAAC;AAC1C,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,IAAe,EACf,KAAiB,EACjB,MAA4B,EAC5B,KAAa,EACb,KAAa;IAEb,OAAO;QACL,IAAI;QACJ,KAAK;QACL,MAAM;QACN,UAAU,CAAC,KAAK,CAAC;QACjB,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;KACzB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAe;IAC/C,OAAO,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAe,EACf,KAAiB,EACjB,MAA4B,EAC5B,KAAa;IAEb,OAAO,sBAAsB,YAAY,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,EAAE,CAAC;AAC1G,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAuB;IACrD,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACjE,MAAM,IAAI,GAAkB,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACnE,IAAI,iBAAiB,CAAC,MAAM,CAAC;QAAE,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC;IAC7D,IAAI,KAAK;QAAE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IACnC,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,KAAK;QAAE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IACnC,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -46,6 +46,14 @@ function shutdown(signal) {
|
|
|
46
46
|
return;
|
|
47
47
|
shuttingDown = true;
|
|
48
48
|
log.info(`received ${signal}, shutting down`);
|
|
49
|
+
// Restore the console we put into raw mode (Windows Ctrl+C handling).
|
|
50
|
+
try {
|
|
51
|
+
if (process.stdin.isTTY)
|
|
52
|
+
process.stdin.setRawMode(false);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
/* ignore */
|
|
56
|
+
}
|
|
49
57
|
disposeAll();
|
|
50
58
|
winShell.disposeAll();
|
|
51
59
|
server.close(() => process.exit(0));
|
|
@@ -59,11 +67,40 @@ process.on('SIGHUP', () => shutdown('SIGHUP'));
|
|
|
59
67
|
// Windows Ctrl+Break.
|
|
60
68
|
if (process.platform === 'win32')
|
|
61
69
|
process.on('SIGBREAK', () => shutdown('SIGBREAK'));
|
|
62
|
-
// On Windows,
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
// On Windows, node-pty's ConPTY backend breaks the normal CTRL_C_EVENT → SIGINT
|
|
71
|
+
// path for the host process (see microsoft/node-pty#190), so `process.on('SIGINT')`
|
|
72
|
+
// can't be relied on. Instead we read the raw Ctrl+C byte (0x03) straight from the
|
|
73
|
+
// console, set up at startup (before any pty is spawned). This bypasses the signal
|
|
74
|
+
// machinery entirely. Ctrl+Break still works via the SIGBREAK handler above.
|
|
75
|
+
if (process.platform === 'win32') {
|
|
76
|
+
const stdin = process.stdin;
|
|
77
|
+
if (stdin.isTTY) {
|
|
78
|
+
try {
|
|
79
|
+
stdin.setRawMode(true); // deliver keys as bytes; Ctrl+C arrives as 0x03
|
|
80
|
+
stdin.resume();
|
|
81
|
+
stdin.on('data', (buf) => {
|
|
82
|
+
if (buf.includes(0x03))
|
|
83
|
+
shutdown('Ctrl+C');
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Fall back to the readline SIGINT bridge (needs explicit terminal mode).
|
|
88
|
+
readline
|
|
89
|
+
.createInterface({ input: stdin, terminal: true })
|
|
90
|
+
.on('SIGINT', () => shutdown('SIGINT'));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
// stdin isn't a console TTY (e.g. piped) — best-effort bridge.
|
|
95
|
+
try {
|
|
96
|
+
readline
|
|
97
|
+
.createInterface({ input: stdin, terminal: true })
|
|
98
|
+
.on('SIGINT', () => shutdown('SIGINT'));
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
/* nothing more we can do */
|
|
102
|
+
}
|
|
103
|
+
}
|
|
67
104
|
}
|
|
68
105
|
// If the port is already held (e.g. a previous run is still alive), exit with a
|
|
69
106
|
// clear message instead of an unhandled-error stack trace.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACxC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE3B,4EAA4E;AAC5E,4DAA4D;AAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC3G,IAAI,UAAU,EAAE,CAAC;IACf,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IACpC,uFAAuF;IACvF,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QACvE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,IAAI,CAAC,uBAAuB,UAAU,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;AACjC,eAAe,CAAC,MAAM,CAAC,CAAC;AAExB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IAC3C,MAAM,GAAG,GAAG,UAAU,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;IACnD,GAAG,CAAC,IAAI,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;IACvC,4EAA4E;IAC5E,KAAK,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,oCAAoC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtF,iEAAiE;IACjE,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW;QAAE,WAAW,CAAC,GAAG,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,SAAS,QAAQ,CAAC,MAAc;IAC9B,IAAI,YAAY;QAAE,OAAO;IACzB,YAAY,GAAG,IAAI,CAAC;IACpB,GAAG,CAAC,IAAI,CAAC,YAAY,MAAM,iBAAiB,CAAC,CAAC;IAC9C,UAAU,EAAE,CAAC;IACb,QAAQ,CAAC,UAAU,EAAE,CAAC;IACtB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,4CAA4C;IAC5C,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;AAClD,CAAC;AACD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC/C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACjD,6EAA6E;AAC7E,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC/C,sBAAsB;AACtB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;IAAE,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;AAErF,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACxC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE3B,4EAA4E;AAC5E,4DAA4D;AAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC3G,IAAI,UAAU,EAAE,CAAC;IACf,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IACpC,uFAAuF;IACvF,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QACvE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,IAAI,CAAC,uBAAuB,UAAU,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;AACjC,eAAe,CAAC,MAAM,CAAC,CAAC;AAExB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IAC3C,MAAM,GAAG,GAAG,UAAU,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;IACnD,GAAG,CAAC,IAAI,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;IACvC,4EAA4E;IAC5E,KAAK,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,oCAAoC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtF,iEAAiE;IACjE,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW;QAAE,WAAW,CAAC,GAAG,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,SAAS,QAAQ,CAAC,MAAc;IAC9B,IAAI,YAAY;QAAE,OAAO;IACzB,YAAY,GAAG,IAAI,CAAC;IACpB,GAAG,CAAC,IAAI,CAAC,YAAY,MAAM,iBAAiB,CAAC,CAAC;IAC9C,sEAAsE;IACtE,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IACD,UAAU,EAAE,CAAC;IACb,QAAQ,CAAC,UAAU,EAAE,CAAC;IACtB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,4CAA4C;IAC5C,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;AAClD,CAAC;AACD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC/C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACjD,6EAA6E;AAC7E,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC/C,sBAAsB;AACtB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;IAAE,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;AAErF,gFAAgF;AAChF,oFAAoF;AACpF,mFAAmF;AACnF,mFAAmF;AACnF,6EAA6E;AAC7E,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,gDAAgD;YACxE,KAAK,CAAC,MAAM,EAAE,CAAC;YACf,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE;gBAC/B,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC7C,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,0EAA0E;YAC1E,QAAQ;iBACL,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;iBACjD,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;SAAM,CAAC;QACN,+DAA+D;QAC/D,IAAI,CAAC;YACH,QAAQ;iBACL,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;iBACjD,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,4BAA4B;QAC9B,CAAC;IACH,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,2DAA2D;AAC3D,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;IAChD,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAC9B,GAAG,CAAC,KAAK,CACP,QAAQ,MAAM,CAAC,IAAI,iEAAiE;YAClF,6CAA6C,CAChD,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,KAAK,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/monitor.js
CHANGED
|
Binary file
|
package/dist/monitor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"monitor.js","sourceRoot":"","sources":["../src/monitor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"monitor.js","sourceRoot":"","sources":["../src/monitor.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,SAAiB,EAAE,QAAuB;IACjE,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/rest/router.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import { getTarget, isValidTargetId, refreshTargets } from '../targets.js';
|
|
3
3
|
import { isValidSessionName } from '../validate.js';
|
|
4
|
-
import { TmuxError, listSessions, createSession, renameSession, killSession, listWindows,
|
|
4
|
+
import { TmuxError, listSessions, createSession, renameSession, killSession, listWindows, launchAgentInSession, } from '../tmux/sessions.js';
|
|
5
5
|
import { annotate } from '../monitor.js';
|
|
6
6
|
import { getSessionCwd, listDirectory, readFilePreview, resolveScopedPath, writeFile } from '../files.js';
|
|
7
7
|
import { readFolders, writeFolders } from '../foldersStore.js';
|
|
@@ -26,6 +26,11 @@ function requireSessionName(raw) {
|
|
|
26
26
|
throw new TmuxError(400, 'invalid session name');
|
|
27
27
|
return raw;
|
|
28
28
|
}
|
|
29
|
+
function requireLaunchAgent(raw) {
|
|
30
|
+
if (raw === 'cc' || raw === 'codex')
|
|
31
|
+
return raw;
|
|
32
|
+
throw new TmuxError(400, 'invalid agent');
|
|
33
|
+
}
|
|
29
34
|
/** A filesystem path supplied via query. Passed as a single argv element (no
|
|
30
35
|
* shell), so we only sanity-check shape, not contents — this app already
|
|
31
36
|
* grants full shell access on the target by design. */
|
|
@@ -54,11 +59,6 @@ apiRouter.get('/targets/:id/sessions', wrap(async (req, res) => {
|
|
|
54
59
|
const sessions = target.kind === 'winlocal' ? winShell.list() : await listSessions(target);
|
|
55
60
|
res.json({ sessions: annotate(target.id, sessions) });
|
|
56
61
|
}));
|
|
57
|
-
apiRouter.get('/targets/:id/sessions/:name/peek', wrap(async (req, res) => {
|
|
58
|
-
const target = requireTarget(req);
|
|
59
|
-
const name = requireSessionName(req.params.name);
|
|
60
|
-
res.json(target.kind === 'winlocal' ? winShell.peek(name) : await peekSession(target, name));
|
|
61
|
-
}));
|
|
62
62
|
apiRouter.post('/targets/:id/sessions', wrap(async (req, res) => {
|
|
63
63
|
const target = requireTarget(req);
|
|
64
64
|
const body = (req.body ?? {});
|
|
@@ -89,6 +89,15 @@ apiRouter.patch('/targets/:id/sessions/:name', wrap(async (req, res) => {
|
|
|
89
89
|
await renameSession(target, name, newName);
|
|
90
90
|
res.json({ name: newName });
|
|
91
91
|
}));
|
|
92
|
+
apiRouter.post('/targets/:id/sessions/:name/agent', wrap(async (req, res) => {
|
|
93
|
+
const target = requireTarget(req);
|
|
94
|
+
if (target.kind === 'winlocal')
|
|
95
|
+
throw new TmuxError(400, 'agent hooks require a tmux target');
|
|
96
|
+
const name = requireSessionName(req.params.name);
|
|
97
|
+
const agent = requireLaunchAgent((req.body ?? {}).agent);
|
|
98
|
+
await launchAgentInSession(target, name, agent);
|
|
99
|
+
res.json({ ok: true });
|
|
100
|
+
}));
|
|
92
101
|
apiRouter.delete('/targets/:id/sessions/:name', wrap(async (req, res) => {
|
|
93
102
|
const target = requireTarget(req);
|
|
94
103
|
const name = requireSessionName(req.params.name);
|
package/dist/rest/router.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/rest/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkD,MAAM,SAAS,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAe,MAAM,eAAe,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,SAAS,EACT,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,WAAW,EACX,
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/rest/router.ts"],"names":[],"mappings":"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"}
|
package/dist/tmux/formats.js
CHANGED
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
* a printable "|" and place the only free-form field (the name) LAST, then
|
|
6
6
|
* rejoin the remainder — robust even if a name itself contains "|", because
|
|
7
7
|
* the leading numeric fields never do. */
|
|
8
|
+
import { AGENT_OPTION, parseAgentValue } from '../agentState.js';
|
|
8
9
|
const SEP = '|';
|
|
9
10
|
export const SESSION_FORMAT = [
|
|
10
11
|
'#{session_windows}',
|
|
11
12
|
'#{session_attached}',
|
|
12
13
|
'#{session_created}',
|
|
13
|
-
'#{session_activity}', // epoch
|
|
14
|
+
'#{session_activity}', // epoch from tmux; kept for display/debug
|
|
15
|
+
`#{${AGENT_OPTION}}`, // agent hook state: "<kind>:<state>:<reason>:<event>:<nonce>"
|
|
14
16
|
'#{session_name}', // free-form → must be last
|
|
15
17
|
].join(SEP);
|
|
16
18
|
export const WINDOW_FORMAT = [
|
|
@@ -25,12 +27,14 @@ export function parseSessions(stdout) {
|
|
|
25
27
|
.filter((l) => l.length > 0)
|
|
26
28
|
.map((line) => {
|
|
27
29
|
const parts = line.split(SEP);
|
|
30
|
+
const agent = parseAgentValue(parts[4] || '');
|
|
28
31
|
return {
|
|
29
32
|
windows: Number(parts[0]) || 0,
|
|
30
33
|
attached: Number(parts[1]) > 0,
|
|
31
34
|
created: Number(parts[2]) || 0,
|
|
32
35
|
lastActivity: Number(parts[3]) || 0,
|
|
33
|
-
|
|
36
|
+
...agent,
|
|
37
|
+
name: parts.slice(5).join(SEP), // name may legitimately contain "|"
|
|
34
38
|
};
|
|
35
39
|
})
|
|
36
40
|
.filter((s) => s.name);
|
package/dist/tmux/formats.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formats.js","sourceRoot":"","sources":["../../src/tmux/formats.ts"],"names":[],"mappings":"AAAA;;;;;;2CAM2C;AAE3C,MAAM,GAAG,GAAG,GAAG,CAAC;AAEhB,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,oBAAoB;IACpB,qBAAqB;IACrB,oBAAoB;IACpB,qBAAqB,EAAE,
|
|
1
|
+
{"version":3,"file":"formats.js","sourceRoot":"","sources":["../../src/tmux/formats.ts"],"names":[],"mappings":"AAAA;;;;;;2CAM2C;AAE3C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAyD,MAAM,kBAAkB,CAAC;AAExH,MAAM,GAAG,GAAG,GAAG,CAAC;AAEhB,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,oBAAoB;IACpB,qBAAqB;IACrB,oBAAoB;IACpB,qBAAqB,EAAE,0CAA0C;IACjE,KAAK,YAAY,GAAG,EAAE,8DAA8D;IACpF,iBAAiB,EAAE,2BAA2B;CAC/C,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,iBAAiB;IACjB,iBAAiB;IACjB,kBAAkB;IAClB,gBAAgB,EAAE,2BAA2B;CAC9C,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AA6BZ,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SAC3B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC9B,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAC9B,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC9B,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACnC,GAAG,KAAK;YACR,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,oCAAoC;SACrE,CAAC;IACJ,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SAC3B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5B,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAC5B,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;SAC/B,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC;AAED,wEAAwE;AACxE,MAAM,QAAQ,GAAG,oDAAoD,CAAC;AAEtE,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
|
package/dist/tmux/sessions.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { runCommand } from '../exec.js';
|
|
2
2
|
import { managementArgv, newSessionArgv } from './builder.js';
|
|
3
|
+
import { AGENT_OPTION, agentInitialValue, } from '../agentState.js';
|
|
4
|
+
import { augmentAgentCommand } from '../agentHooks.js';
|
|
3
5
|
import { SESSION_FORMAT, WINDOW_FORMAT, parseSessions, parseWindows, isEmptySessionsError, } from './formats.js';
|
|
4
6
|
import { isValidSessionName } from '../validate.js';
|
|
5
|
-
import { classifyTail, lastLines } from '../attention.js';
|
|
6
7
|
/** A management error carrying the HTTP status the router should return. */
|
|
7
8
|
export class TmuxError extends Error {
|
|
8
9
|
status;
|
|
@@ -58,13 +59,49 @@ export async function createSession(target, opts) {
|
|
|
58
59
|
name = r.stdout.trim();
|
|
59
60
|
}
|
|
60
61
|
if (opts.command && opts.command.length > 0) {
|
|
62
|
+
const augmented = augmentAgentCommand(opts.command);
|
|
63
|
+
if (augmented.kind) {
|
|
64
|
+
await run(target, [
|
|
65
|
+
'set-option',
|
|
66
|
+
'-t',
|
|
67
|
+
name,
|
|
68
|
+
'-q',
|
|
69
|
+
AGENT_OPTION,
|
|
70
|
+
agentInitialValue(augmented.kind),
|
|
71
|
+
]);
|
|
72
|
+
}
|
|
61
73
|
// Type the command literally, then press Enter. Two send-keys calls so the
|
|
62
74
|
// command text can never be misparsed as a key name.
|
|
63
|
-
await run(target, ['send-keys', '-t', name, '-l',
|
|
75
|
+
await run(target, ['send-keys', '-t', name, '-l', augmented.command]);
|
|
64
76
|
await run(target, ['send-keys', '-t', name, 'Enter']);
|
|
65
77
|
}
|
|
66
78
|
return { name };
|
|
67
79
|
}
|
|
80
|
+
export async function launchAgentInSession(target, name, agent) {
|
|
81
|
+
const augmented = augmentAgentCommand(agent);
|
|
82
|
+
if (!augmented.kind)
|
|
83
|
+
throw new TmuxError(400, 'unsupported agent');
|
|
84
|
+
const set = await run(target, [
|
|
85
|
+
'set-option',
|
|
86
|
+
'-t',
|
|
87
|
+
name,
|
|
88
|
+
'-q',
|
|
89
|
+
AGENT_OPTION,
|
|
90
|
+
agentInitialValue(augmented.kind),
|
|
91
|
+
]);
|
|
92
|
+
if (set.code !== 0) {
|
|
93
|
+
if (/can't find session|session not found|no server running/i.test(set.stderr)) {
|
|
94
|
+
throw new TmuxError(404, `session "${name}" not found`);
|
|
95
|
+
}
|
|
96
|
+
throw new TmuxError(502, firstStderrLine(set.stderr));
|
|
97
|
+
}
|
|
98
|
+
const send = await run(target, ['send-keys', '-t', name, '-l', augmented.command]);
|
|
99
|
+
if (send.code !== 0)
|
|
100
|
+
throw new TmuxError(502, firstStderrLine(send.stderr));
|
|
101
|
+
const enter = await run(target, ['send-keys', '-t', name, 'Enter']);
|
|
102
|
+
if (enter.code !== 0)
|
|
103
|
+
throw new TmuxError(502, firstStderrLine(enter.stderr));
|
|
104
|
+
}
|
|
68
105
|
export async function renameSession(target, name, newName) {
|
|
69
106
|
if (!isValidSessionName(newName))
|
|
70
107
|
throw new TmuxError(400, 'invalid new session name');
|
|
@@ -88,13 +125,6 @@ export async function killSession(target, name) {
|
|
|
88
125
|
}
|
|
89
126
|
throw new TmuxError(502, firstStderrLine(r.stderr));
|
|
90
127
|
}
|
|
91
|
-
/** Grab the active pane's last lines and classify whether the session is
|
|
92
|
-
* waiting on the user. `capture-pane -p` returns plain text (no escapes). */
|
|
93
|
-
export async function peekSession(target, name) {
|
|
94
|
-
const r = await run(target, ['capture-pane', '-t', name, '-p', '-S', '-12']);
|
|
95
|
-
const tail = r.code === 0 ? r.stdout : '';
|
|
96
|
-
return { reason: classifyTail(tail), tail: lastLines(tail, 6) };
|
|
97
|
-
}
|
|
98
128
|
export async function listWindows(target, name) {
|
|
99
129
|
const r = await run(target, ['list-windows', '-t', name, '-F', WINDOW_FORMAT]);
|
|
100
130
|
if (r.code === 0)
|