@hyzyn/dsh-tty 0.5.0 → 0.9.0
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 +93 -15
- package/client.js +38 -38
- package/lib/index.d.ts +7 -1
- package/lib/index.js +712 -25
- package/lib/index.js.map +1 -1
- package/lib/sftp.d.ts +110 -0
- package/lib/sftp.js +449 -0
- package/lib/sftp.js.map +1 -0
- package/lib/shell-integration.js +51 -11
- package/lib/shell-integration.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,16 @@ xterm.js 全交互终端(node-pty 真实 PTY,WebGL 渲染器加速),支
|
|
|
9
9
|
(OSC 133/7)**——agent 能按「命令」粒度读写终端(`tty_capture{last}` /
|
|
10
10
|
`tty_expect`),并支持 **agent forwarding**、**~/.ssh/config 导入** 等深化
|
|
11
11
|
能力;0.5.0 起内置**端口转发管理**——连接簿条目配隧道(-L/-R 两向),宿主
|
|
12
|
-
|
|
12
|
+
自持连接、断线自动重连、状态徽标(见下文);0.6.0 起 **bash 3.2(macOS
|
|
13
|
+
自带)补全命令开始标记**(DEBUG trap 兜底,`tty_capture{last}` /
|
|
14
|
+
`tty_expect` 早停恢复可用),设置卡片 **Shell 路径可选可输入**;0.7.0 起内置
|
|
15
|
+
**SFTP 文件传输**——SSH 连接的远程目录浏览与上传/下载/新建目录/重命名/删除
|
|
16
|
+
(面板「文件浏览」对话框 + agent `sftp_*` 工具,见下文);0.8.0 起面板支持
|
|
17
|
+
**拖拽上传**(文件与文件夹直接拖入,递归展开目录结构逐级上传),agent 侧
|
|
18
|
+
补齐**管理闭环**:`sftp_mkdir`(parents 逐级补齐)/ `sftp_rename`(跨目录
|
|
19
|
+
移动)/ `sftp_remove`(递归删除)/ `sftp_tree`(限深递归列举);0.9.0 起
|
|
20
|
+
**SFTP 界面可选双栏风格**(左本机 / 右远程、行内直传,宿主服务端对拷),
|
|
21
|
+
面板头部压缩为「标签行 + SSH 连接栏」两行。
|
|
13
22
|
|
|
14
23
|

|
|
15
24
|
|
|
@@ -53,7 +62,7 @@ dsh plugin --profile web add link:$(pwd)/packages/tty # 仓库开发调试
|
|
|
53
62
|
|
|
54
63
|
## agent 工具(P1)
|
|
55
64
|
|
|
56
|
-
插件向 agent
|
|
65
|
+
插件向 agent 注入十三个工具(与 bash 工具同权,操作实时显示在用户终端里):
|
|
57
66
|
|
|
58
67
|
| 工具 | 作用 |
|
|
59
68
|
| --- | --- |
|
|
@@ -62,6 +71,14 @@ dsh plugin --profile web add link:$(pwd)/packages/tty # 仓库开发调试
|
|
|
62
71
|
| `tty_screen` | 读取**当前可见屏幕**的渲染结果(xterm-headless 虚拟屏,纯文本)——能真正读懂 vim / htop / 菜单等 TUI 界面 |
|
|
63
72
|
| `tty_expect` | 用正则**等待后续输出**中的就绪信号(dev server URL、构建完成等);超时不抛错(`matched:false` + 尾部输出),命令提前结束也会带退出码早停 |
|
|
64
73
|
| `tty_send` | 向指定会话发送按键/文本(如 dev server 的 q 键、菜单选择) |
|
|
74
|
+
| `sftp_list` | 列出 SSH 远程目录内容(名称/类型/大小/修改时间,目录在前);`book` 为连接簿条目名,`path` 缺省为登录 home |
|
|
75
|
+
| `sftp_read` | 读取远程**文本**文件(默认 ≤256KB 可调至 1MB,超出截断;含 NUL 字节按二进制拒绝) |
|
|
76
|
+
| `sftp_write` | 写远程文本文件(默认覆盖,`append:true` 追加;单次 ≤1MB) |
|
|
77
|
+
| `sftp_mkdir` | 创建远程目录;`parents:true` 逐级补齐缺失父目录(等效 `mkdir -p`,自底向上创建,已存在目录幂等跳过) |
|
|
78
|
+
| `sftp_rename` | 重命名/移动远程文件或目录(`to` 与 `from` 不同目录即移动;不覆盖已存在的目标) |
|
|
79
|
+
| `sftp_remove` | 删除远程文件/目录;目录默认 rmdir(非空明确报错),`recursive:true` 整树删除(不可恢复) |
|
|
80
|
+
| `sftp_tree` | 递归列举远程目录结构(深度优先、目录优先;`maxDepth` 1~8 / `maxEntries` 1~2000 限流,超限 `truncated:true`;symlink 不跟随防环) |
|
|
81
|
+
| `tunnel_list` | 列出端口转发隧道及其实时状态(活跃/连接中/错误/停止、规则、连接数) |
|
|
65
82
|
|
|
66
83
|
典型 agent 流程(推荐):`tty_send` 启动长任务 → `tty_expect` 等就绪标记 →
|
|
67
84
|
`tty_capture{last:true}` 拿单条命令结果。此外 `systemPrompt` 里注册了动态
|
|
@@ -74,8 +91,14 @@ spawn 时经既有的 `-c` 包装层按 shell 类型注入钩子(对用户透
|
|
|
74
91
|
|
|
75
92
|
- **zsh**:`ZDOTDIR` 指向临时桩目录(VS Code 同款方案),桩文件先 source
|
|
76
93
|
用户原 rc 再追加 `precmd`/`preexec` 钩子;
|
|
77
|
-
- **bash**:`--rcfile` 桩(先 source `~/.bashrc
|
|
78
|
-
|
|
94
|
+
- **bash**:`--rcfile` 桩(先 source `~/.bashrc`);命令开始标记按版本二选一:
|
|
95
|
+
bash ≥ 4.4 走 `PS0`;bash < 4.4(macOS 自带 3.2)无 PS0,用 **DEBUG trap
|
|
96
|
+
兜底**(handler 按 `$BASH_COMMAND` 过滤掉 PROMPT_COMMAND 机制自身的
|
|
97
|
+
fire,避免幻影标记把用户输出切出捕获区间;bash 3.2 的
|
|
98
|
+
`trap - DEBUG` 在 handler 内卸载不生效,故按「永久武装 + 过滤」设计)。
|
|
99
|
+
副作用:循环体等复合命令的内部命令会多发 B 标记,仅影响
|
|
100
|
+
`tty_capture{last}` 对这类命令的截取起点,D/退出码与 `tty_expect` 不受影响;
|
|
101
|
+
PROMPT_COMMAND 挂钩兼容字符串与数组(bash 5.1+)两种形态;
|
|
79
102
|
- 标记语义:`133;A` prompt 开始 / `133;B` 命令开始 / `133;D;<exit>` 命令
|
|
80
103
|
结束带退出码 / `OSC 7 file://…` cwd 上报(`tty_list.cwd` 跟随 `cd`,
|
|
81
104
|
SSH 会话则上报远程路径);
|
|
@@ -104,6 +127,42 @@ SSH 会话同表调度:`tty_list` 里 `kind: 'ssh'` 的条目按 `target`
|
|
|
104
127
|
`tunnel_list` 工具查询状态;
|
|
105
128
|
- TOFU 与终端会话共享同一份 hostKeys 钉扎;端口不占用 maxSessions 名额。
|
|
106
129
|
|
|
130
|
+
## SFTP 文件传输(0.7.0,0.8.0/0.9.0 增强)
|
|
131
|
+
|
|
132
|
+
不动终端、不占会话名额,直接对 SSH 连接做远程文件操作(`ssh2` 的 sftp
|
|
133
|
+
subsystem,宿主半体 `src/sftp.ts`):
|
|
134
|
+
|
|
135
|
+

|
|
136
|
+
|
|
137
|
+

|
|
138
|
+
|
|
139
|
+
- **入口**:① 标签栏「+」菜单的连接簿条目带 📂(按该条目打开文件浏览);
|
|
140
|
+
② SSH 连接对话框填好主机/认证后点「文件浏览」(不落连接簿也能浏览);
|
|
141
|
+
- **操作**:目录浏览(路径框回车跳转、`..(上级目录)`、单击文件即下载)、
|
|
142
|
+
**上传**(多选文件,XHR 流式 + 进度百分比;0.8.0 起支持**拖拽**——文件与
|
|
143
|
+
文件夹直接拖入对话框,文件夹经 `webkitGetAsEntry` 递归展开逐个上传,目录
|
|
144
|
+
用 mkdir parents 逐级补齐)、**下载**(POST → 浏览器 Blob
|
|
145
|
+
→ `<a download>`)、**新建目录**、**重命名**(行内编辑器)、**删除**
|
|
146
|
+
(🗑 二次点击确认,目录带 `recursive` 整目录删除);
|
|
147
|
+
- **连接管理**:懒连接池——首次操作才建 SSH 连接,空闲 120 秒自动回收,
|
|
148
|
+
断开后下次操作自动重连;连接簿条目在每次(重)连接时实时解析(改密码
|
|
149
|
+
后自动用新凭证);TOFU 与终端会话/隧道共用同一份 `hostKeys` 钉扎,指纹
|
|
150
|
+
变同样拒绝;SFTP 不计入 `maxSessions` 名额;
|
|
151
|
+
- **传输通道**:`POST /api/dsh-tty/sftp/list|mkdir|rename|remove|download|
|
|
152
|
+
upload`(全部 loopback 围栏)。连接规格经 JSON 体(连接簿名或内联字段,
|
|
153
|
+
与 WS ssh 帧同语义「条目作基底 + 内联逐项覆盖」)或 upload 的
|
|
154
|
+
`x-dsh-sftp-meta` 头(base64url)携带——**凭证不进 URL/查询串**;上传下载
|
|
155
|
+
均为流式 pipe,不整文件进内存;
|
|
156
|
+
- **agent 工具**:`sftp_list` / `sftp_read` / `sftp_write` / `sftp_mkdir` /
|
|
157
|
+
`sftp_rename` / `sftp_remove` / `sftp_tree`(见上表)——只收
|
|
158
|
+
`book` 连接簿条目名,**不接受内联凭证**(agent 上下文不进明文密钥);
|
|
159
|
+
- **双栏风格(0.9.0 可选,配置 `sftpStyle`)**:左本机 / 右远程两栏——本机
|
|
160
|
+
侧浏览与文件操作走新增的 `/api/dsh-tty/local-fs` 路由(list/mkdir/rename/
|
|
161
|
+
remove,loopback 围栏);行内 `⇨ / ⇦` 把条目对拷到对面栏的当前目录
|
|
162
|
+
(`/api/dsh-tty/local-fs/transfer` 由宿主服务端把两个路径流式直传,目录
|
|
163
|
+
递归、同名覆盖,**字节不经过浏览器**);单窗体风格照旧,设置卡片切换,
|
|
164
|
+
重新打开 SFTP 生效。
|
|
165
|
+
|
|
107
166
|
## SSH 连接(方案 C)
|
|
108
167
|
|
|
109
168
|
0.2.0 起标签栏「+」变为一键菜单,除本地终端外还能开 **SSH 标签页**:宿主
|
|
@@ -112,8 +171,9 @@ SSH 会话同表调度:`tty_list` 里 `kind: 'ssh'` 的条目按 `target`
|
|
|
112
171
|
关闭、输出缓冲、背压与 agent 工具全部复用同一套调度。
|
|
113
172
|
|
|
114
173
|
- **「+」菜单三个入口**:本地终端 / **SSH 连接簿**(配置里保存过的条目,
|
|
115
|
-
显示 `user@host[:port] · auth`,**条目带 ✎
|
|
116
|
-
(表单手填 host / port / username / auth
|
|
174
|
+
显示 `user@host[:port] · auth`,**条目带 📂 文件浏览与 ✎ 编辑**)/ SSH 连接…
|
|
175
|
+
(表单手填 host / port / username / auth,连接前可勾选保存,对话框底部
|
|
176
|
+
「文件浏览」可跳过终端直接以当前信息打开 SFTP);
|
|
117
177
|
- **连接簿**:SSH 连接对话框勾选「保存到连接簿」即存为条目(同名覆盖,
|
|
118
178
|
名称留空用主机名);「+」菜单条目的 ✎ 与设置卡片里的 **编辑** 都走同一
|
|
119
179
|
编辑表单(行内改 host/port/username/auth/私钥/密码/agent forwarding,
|
|
@@ -160,7 +220,7 @@ SSH 会话同表调度:`tty_list` 里 `kind: 'ssh'` 的条目按 `target`
|
|
|
160
220
|
| `enabled` | true | 关闭整个插件(需重启生效) |
|
|
161
221
|
| `announceToAgent` | true | 是否向 agent 公告终端面板能力(systemPrompt 注入) |
|
|
162
222
|
| `maxSessions` | 4 | 并发 PTY 会话上限(1~16) |
|
|
163
|
-
| `shell` | `$SHELL` | shell
|
|
223
|
+
| `shell` | `$SHELL` | shell 路径;设置卡片可选可输入(下拉候选来自 `/etc/shells` + `$SHELL` + 常见安装路径,仅列存在且可执行者,`$SHELL` 优先),也可手输任意路径 |
|
|
164
224
|
| `term` | `xterm-256color` | TERM 值 |
|
|
165
225
|
| `colorTerm` | `truecolor` | COLORTERM 值 |
|
|
166
226
|
| `cwd` | 宿主启动目录 | 兜底工作目录(客户端当前会话 cwd 优先) |
|
|
@@ -169,6 +229,7 @@ SSH 会话同表调度:`tty_list` 里 `kind: 'ssh'` 的条目按 `target`
|
|
|
169
229
|
| `hostKeys` | `[]` | SSH 主机指纹记录(TOFU,自动维护):条目 `{host, port, fingerprint}`;按 host:port 唯一,首次连接自动追加,指纹变更拒绝连接;设置卡片可删除重置 |
|
|
170
230
|
| `shellIntegration` | true | 注入 OSC 133/7 shell 集成(命令边界标记 + cwd 上报;`tty_capture{last}` 依赖它);zsh/bash 支持,其他 shell 自动跳过;出兼容问题时可关闭 |
|
|
171
231
|
| `tunnels` | `[]` | 端口转发隧道:条目 `{name, bookName, direction=local\|remote, localPort?, remoteHost?, remotePort?, localTargetHost?, localTargetPort?, enabled}`;`bookName` 引用连接簿条目提供主机与认证;卡片「端口转发」区块可视化维护 |
|
|
232
|
+
| `sftpStyle` | `dialog` | SFTP 文件浏览界面风格:`dialog` 单窗体(远程目录 + 上传/下载/拖拽)/ `dual` 双栏(左本机 / 右远程,行内 `⇨/⇦` 宿主服务端直传);重新打开 SFTP 生效 |
|
|
172
233
|
|
|
173
234
|
## 帧协议(/api/dsh-tty/ws,JSON 文本帧;v3 = 单连接多会话 + 断线重连)
|
|
174
235
|
|
|
@@ -233,11 +294,13 @@ pnpm --filter @hyzyn/dsh-tty ssh-smoke # SSH 冒烟:内存 SSH server(ssh
|
|
|
233
294
|
内保活可重连,宿主进程重启则所有会话结束;超期后未重连的会话由回收器
|
|
234
295
|
结束,输出缓冲(尾部 256KB)之外的滚动历史无法恢复。
|
|
235
296
|
- **shell 集成仅 zsh / bash**:其他 shell 自动跳过(`tty_capture{last}` 会
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
297
|
+
明确报错而非错报)。bash < 4.4 走 DEBUG trap 兜底:循环体等复合命令的
|
|
298
|
+
内部命令会多发 B 标记,`tty_capture{last}` 对这类命令只截取最后一个内部
|
|
299
|
+
命令之后的输出(退出码与 `tty_expect` 不受影响)。用户 rc 若覆盖
|
|
300
|
+
`PROMPT_COMMAND`/钩子数组,集成可能失效——可关闭 `shellIntegration` 或
|
|
301
|
+
反馈补丁兼容。
|
|
240
302
|
- **端口转发边界**:本地监听固定 127.0.0.1(不暴露局域网);remote 方向服务端监听还受服务端 sshd `GatewayPorts` 限制;隧道的 SSH 连接与终端会话独立,均走 TOFU 钉扎与连接簿认证;隧道规格变更(端口/目标/启停)经「保存」热生效,热改连接簿凭证则在下次重连时生效。
|
|
303
|
+
- **SFTP 边界**:文件权限 = 对应 SSH 账号的终端权限(无额外沙箱/chroot);下载经浏览器内存(超大文件建议终端 `scp`/`rsync`);agent 工具 `sftp_read` ≤1MB 且拒绝二进制、`sftp_write` 单次 ≤1MB(大内容走面板上传或终端);`sftp_*` 工具只收连接簿条目名,内联凭证仅供面板对话框使用。
|
|
241
304
|
- **SSH host key 为 TOFU 钉扎**:首次连接自动记录 sha256 指纹(trust on
|
|
242
305
|
first use),之后指纹一致放行、变更拒绝——不再是无条件放行的
|
|
243
306
|
accept-and-log。注意 TOFU 的固有边界:首次连接若已遭遇 MITM 则记录的
|
|
@@ -276,7 +339,13 @@ pnpm --filter @hyzyn/dsh-tty ssh-smoke # SSH 冒烟:内存 SSH server(ssh
|
|
|
276
339
|
├─ 本地路径:ctx.get('subprocess').spawnTerminal({ argv: shell -c 包装层, cwd })
|
|
277
340
|
├─ 辅助路由:/api/dsh-tty/ssh-config(~/.ssh/config 导入候选)、
|
|
278
341
|
│ /api/dsh-tty/env-vars(env 插件托管变量名)、/api/dsh-tty/known-hosts
|
|
279
|
-
│ (TOFU 指纹预填充,src/known-hosts.ts 解析含 hashed
|
|
342
|
+
│ (TOFU 指纹预填充,src/known-hosts.ts 解析含 hashed 条目)、
|
|
343
|
+
│ /api/dsh-tty/shells(Shell 路径候选)——均 loopback 围栏
|
|
344
|
+
├─ SFTP(src/sftp.ts,0.7.0):懒连接池(空闲 120s 回收、断开按需重连、
|
|
345
|
+
│ TOFU 共用)→ POST /api/dsh-tty/sftp/list|mkdir|rename|remove|download|
|
|
346
|
+
│ upload(spec 走体/头,凭证不进 URL;上传下载流式 pipe)+
|
|
347
|
+
│ sftp_list/read/write/mkdir/rename/remove/tree 工具(只收连接簿名;
|
|
348
|
+
│ mkdir 支持 parents 自底向上逐级补齐,tree 限深限数递归列举)
|
|
280
349
|
├─ 端口转发(src/tunnels.ts):宿主自持隧道(-L/-R 双向),断线退避重连、
|
|
281
350
|
│ TOFU 共用、连接计数;GET /api/dsh-tty/tunnels 实时状态 + tunnel_list 工具
|
|
282
351
|
└─ 帧协议:spawn|ssh / input / resize / kill / sessions / attach
|
|
@@ -290,12 +359,21 @@ SSH 路径 (src/ssh.ts,方案 C)
|
|
|
290
359
|
背压一并透传到 channel —— 之后与本地 PTY 无差别调度
|
|
291
360
|
```
|
|
292
361
|
|
|
293
|
-
M0 探针、集成测试(B1~
|
|
362
|
+
M0 探针、集成测试(B1~B24 共 58 项断言)与真实实例冒烟(live / TUI)在
|
|
294
363
|
真实 DSH 服务组合上验证过:TERM 注入、resize 透传、sid 冲突、并发上限、
|
|
295
364
|
loopback 围栏、多会话数据隔离、cwd 跟随与校验、配置热生效(settings/updated)、
|
|
296
365
|
kill→exit 全链路、断线保活 + sessions/attach 重连回放、tty_screen 虚拟屏、
|
|
297
366
|
tty_capture ANSI 清洗、shell 集成(capture{last} + exitCode、OSC 7 cwd
|
|
298
|
-
跟随)、tty_expect 匹配与超时、~/.ssh/config 解析器、端口转发(双隧道 active + forwardOut 往返 + reconcile
|
|
367
|
+
跟随)、tty_expect 匹配与超时、~/.ssh/config 解析器、端口转发(双隧道 active + forwardOut 往返 + reconcile 清理)、
|
|
368
|
+
shells 候选路由、bash 3.2 shell 集成(DEBUG trap 兜底:capture{last} +
|
|
369
|
+
exitCode、tty_expect 命令结束早停)、SFTP 文件传输(list/mkdir/upload/
|
|
370
|
+
download/remove 路由 + sftp_* 工具,test-sshd 内存 sshd 端到端)、SFTP 管理
|
|
371
|
+
闭环(agent sftp_mkdir/-rename/-remove/-tree:parents 补齐、tree 限深截断、
|
|
372
|
+
跨目录移动、非空删除拒绝与递归删除)。SSH 路径由 `ssh-smoke`
|
|
299
373
|
(内存 SSH server × 真实 `spawnSsh`)验证:password 认证建链与 prompt、
|
|
300
374
|
命令往返、pty-req 初始尺寸与 resize(window-change)、terminate /
|
|
301
|
-
exit-status 全链路,以及 TOFU 指纹记录(S7)与指纹变更拒绝连接(S8
|
|
375
|
+
exit-status 全链路,以及 TOFU 指纹记录(S7)与指纹变更拒绝连接(S8);
|
|
376
|
+
SFTP 由 ssh-smoke S9(test-sshd 的 sftp subsystem × 真实 SftpManager)覆盖:
|
|
377
|
+
目录列表与 realpath home、上传覆盖+追加、下载(stat size 作 content-length)、
|
|
378
|
+
mkdir/rename/非递归删除拒绝/递归删除、TOFU 指纹变更拒绝;S9g 覆盖 mkdir
|
|
379
|
+
`parents` 自底向上逐级补齐(幂等)与 `tree` 限深截断/全量。
|