@hyzyn/dsh-tty 0.22.0-rc.2 → 0.22.1

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.en.md CHANGED
@@ -36,7 +36,9 @@ After installing, restart `dsh web`; a “Terminal” entry appears in the sideb
36
36
  reads `retainedBy.mainView > 0` to find the current session — trusting only the legacy field leaves
37
37
  the cwd empty and new tabs fall back to the host’s start directory;
38
38
  - Supports TUIs such as vim / htop / less (TERM is injected as `xterm-256color`);
39
- - Panel size changes are resized automatically (xterm fit → native PTY resize);
39
+ - Panel size changes are resized automatically (xterm fit → native PTY resize); **inactive tabs do not
40
+ follow** — each keeps its own last valid size (D79: when the container is invisible or the probe is
41
+ degenerate, no resize frame is sent at all);
40
42
  - **Ctrl+F searches inside the terminal** (Enter next / Shift+Enter previous / Esc closes only the search
41
43
  box), links in the output are clickable, and the toolbar offers clear / copy selection / paste;
42
44
  - **Reconnect on disconnect (0.3.0)**: after an abnormal disconnect such as a page refresh or a network
@@ -112,7 +114,7 @@ The plugin injects sixteen tools into the agent (with the same power as the bash
112
114
  | Tool | Purpose |
113
115
  | --- | --- |
114
116
  | `tty_list` | List terminal sessions (sid / kind (`local\|ssh`) / target / pid / **cwd tracked live as you `cd`** / activity time; tmux persistent sessions carry a `persist` marker; sessions the agent opened carry `owner: 'agent'`). **Includes sessions whose process has exited but which are still inside their read-only retention window** (`exited:true` + exit code/signal, see below) |
115
- | `tty_open` | **Open a terminal session yourself** (0.20.0): a local shell, or a command via `command` (dev server / watch; it runs as **a whole piece of shell code** — `cd x && cmd`, `a; b`, even a multi-line script, and it is *not* subject to the “single line ≤2000” client rule below — D78), with optional tmux persistence via `persistName`. The session **shows up in the user’s terminal panel** as an ordinary tab the user can see and take over — never a hidden session |
117
+ | `tty_open` | **Open a terminal session yourself** (0.20.0): a local shell, or a command via `command` (dev server / watch; it runs as **a whole piece of code in the host shell’s syntax** — on a POSIX shell `cd x && cmd`, `a; b` and multi-line scripts work, while **Windows cmd / PowerShell use their own syntax**; the current shell and syntax are restated every turn in the systemPrompt terminal line; it is *not* subject to the “single line ≤2000” client rule below — D78), with optional tmux persistence via `persistName`. The session **shows up in the user’s terminal panel** as an ordinary tab the user can see and take over — never a hidden session |
116
118
  | `tty_close` | Close a session opened by `tty_open` (0.20.0). **Only the agent’s own sessions may be closed**: a tab the user opened is refused, so the agent never ends a terminal the user is working in. It also works on an **exited session that is still in read-only retention** — that is its release entry point (by default it is retained **until explicitly closed**, never on a timer) |
117
119
  | `tty_stats` | Read live host metrics for a session’s machine (0.20.0): CPU / memory / disk / TCP connections / network rates / temperature / uptime. Local sessions report the host; SSH sessions report that remote host over a separate non-PTY channel that never touches the terminal. Check it before deploying or load-testing |
118
120
  | `tty_capture` | Read recent output (last N lines, ANSI stripped by default, `raw:true` for the raw stream); **`last:true` returns only the output + exit code of the previous completed command** (shell integration markers, see the next section); when a command is **in flight** (just sent, completion marker not in yet) it returns `inProgress:true` without the stale result, so the previous command is never mistaken for this one (0.19.0) |
@@ -867,7 +869,7 @@ ctx.inject(['ttyPanel'], (c) => {
867
869
  | C→S | `{t:'spawn', sid?, cols?, rows?, cwd?, persist?, persistName?, command?}` | Create a session; sid defaults to one generated by the host and cwd to the configured fallback; `persist` + a stable `persistName` (0.10.0) = tmux persistent session (`dsh-<name>`, requires persistence=tmux); `command` (0.14.0) = run a single command directly (no persistence) |
868
870
  | C→S | `{t:'ssh', sid?, cols?, rows?, name? \| host, username, …, persist?, persistName?}` | Create an SSH session (native ssh2); `name` references a connection-book entry as the base, and inline `host/port/username/auth/keyPath/passphrase/password/agentForward` can override it field by field; `persist` has the same semantics as spawn (remote tmux hosting) |
869
871
  | C→S | `{t:'input', sid?, d}` | Key/paste data |
870
- | C→S | `{t:'resize', sid?, cols, rows}` | Panel size change |
872
+ | C→S | `{t:'resize', sid?, cols, rows}` | Panel size change. **The client only sends it when the container is visible and the size is trustworthy** (D79: hidden tab / detached element / minimized panel send nothing, so the PTY keeps its last valid size); the host clamp is only a safety floor, and non-numeric values (including `null`) fall back to 80×24 instead of being clamped to the floor |
871
873
  | C→S | `{t:'refresh', sid?}` | Force a redraw (0.10.1): the host runs `refresh-client` on a tmux session (the client resets to clear stale scrollback and then asks for a fresh redraw; a no-op for non-tmux sessions) |
872
874
  | C→S | `{t:'kill', sid?}` | Close a session (orphan sessions can also be killed across connections, to prevent leaks) |
873
875
  | C→S | `{t:'sessions'}` | List a global session snapshot (`attachable` marks the reattachable ones) |
@@ -962,7 +964,10 @@ verify things like “is there still a white panel after switching light/dark th
962
964
  - **Resize is an internal coupling**: DSH’s `spawnTerminal` handle does not expose resize, so the plugin
963
965
  passes through `(handle).terminal.resize(cols, rows)` directly (node-pty’s native API, reachable in the
964
966
  same process). If a DSH upgrade changes the internals, since 0.3.0 it warns once and degrades to a fixed
965
- size instead of throwing on every frame.
967
+ size instead of throwing on every frame. **D79 addendum**: the check is now an explicit
968
+ `typeof terminal.resize === 'function'` — the old `handle.terminal?.resize?.(…)` only reached the warning
969
+ branch when resize *threw*, so a DSH that renamed or removed `handle.terminal` would neither resize nor
970
+ warn (the promise was empty and debugging had no lead at all).
966
971
  - **TERM is injected through a `-c` wrapper layer (POSIX only)**: DSH hardcodes node-pty `name:"dumb"`, and in
967
972
  node-pty name takes precedence over env.TERM, so the shell is started as
968
973
  `sh -c 'export TERM=...; exec "$shell"'` (transparent to the user; the TERM /
package/README.md CHANGED
@@ -36,7 +36,8 @@ dsh plugin --profile web add link:$(pwd)/packages/tty # 仓库开发调试
36
36
  workspace 域),客户端改看 `retainedBy.mainView > 0` 认当前会话——只认老字段会让
37
37
  cwd 恒为空、新标签回落宿主启动目录;
38
38
  - 支持 vim / htop / less 等 TUI(TERM 已注入为 `xterm-256color`);
39
- - 面板大小变化自动 resize(xterm fit → PTY 原生 resize);
39
+ - 面板大小变化自动 resize(xterm fit → PTY 原生 resize);**非活动标签不跟手**——它保留自己
40
+ 最后一次有效尺寸(D79:容器不可见、或探测结果退化时,尺寸帧一律不发);
40
41
  - **Ctrl+F 终端内搜索**(Enter 下一个 / Shift+Enter 上一个 / Esc 只关搜索框),
41
42
  输出中的链接可点击,工具栏提供 清屏 / 复制选中 / 粘贴;
42
43
  - **断线自动重连(0.3.0)**:刷新页面、网络抖动等异常断开后,会话在宿主
@@ -104,7 +105,7 @@ dsh plugin --profile web add link:$(pwd)/packages/tty # 仓库开发调试
104
105
  | 工具 | 作用 |
105
106
  | --- | --- |
106
107
  | `tty_list` | 列出终端会话(sid / kind(local\|ssh)/ target / pid / **cwd 实时跟随 cd** / 活动时间;tmux 持久会话带 `persist` 标记;agent 自己开的带 `owner: 'agent'`)。**含进程已退出但仍在只读保留期内的会话**(`exited:true` + 退出码/信号,见下节) |
107
- | `tty_open` | **自己开一个终端会话**(0.20.0):本地 shell,或 `command` 直接跑一条命令(dev server / watch;**按整段 shell 代码执行**——`cd x && cmd`、`a; b`、多行脚本都可以,且不受下面「命令标签单行 ≤2000」那条客户端约束,D78),`persistName` 可要 tmux 持久化。**开出来的会话出现在用户的终端面板里**(普通标签、用户可见可接管),不做隐形会话 |
108
+ | `tty_open` | **自己开一个终端会话**(0.20.0):本地 shell,或 `command` 直接跑一条命令(dev server / watch;**按宿主 shell 的语法整段执行**——POSIX shell 上 `cd x && cmd`、`a; b`、多行脚本都可以;**Windows 的 cmd / PowerShell 则按它们自己的语法**,当前 shell 与语法每轮都写在 systemPrompt 的终端一行里;不受下面「命令标签单行 ≤2000」那条客户端约束,D78),`persistName` 可要 tmux 持久化。**开出来的会话出现在用户的终端面板里**(普通标签、用户可见可接管),不做隐形会话 |
108
109
  | `tty_close` | 关掉一个由 `tty_open` 开的会话(0.20.0)。**只允许关 agent 自己开的**:用户在面板里开的标签会被拒绝——agent 不越权结束用户正在用的终端。对**已退出但仍只读保留着**的会话同样可用——那是它的释放入口(默认**保留到显式关闭**,不按时间释放) |
109
110
  | `tty_stats` | 读会话所在机器的实时指标(0.20.0):CPU / 内存 / 磁盘 / TCP 连接数 / 网速 / 温度 / 在线时长。本地会话取宿主机;SSH 会话取那台远程主机(另开一段非 PTY 通道,不影响终端)。部署、压测前先看它 |
110
111
  | `tty_capture` | 读取近期输出(尾部 N 行,默认清洗 ANSI,`raw:true` 取原始流);**`last:true` 只返回上一条已完成命令的输出 + 退出码**(shell 集成标记,见下节);命令**在途**时(刚发送、完成标记未到)返回 `inProgress:true` 且不带旧结果——避免把上一条的输出当成这一条(0.19.0) |
@@ -802,7 +803,7 @@ ctx.inject(['ttyPanel'], (c) => {
802
803
  | C→S | `{t:'spawn', sid?, cols?, rows?, cwd?, persist?, persistName?, command?}` | 创建会话;sid 缺省由宿主生成,cwd 缺省用配置兜底;`persist` + 稳定 `persistName`(0.10.0)= tmux 持久会话(`dsh-<名>`,需 persistence=tmux);`command`(0.14.0)= 直接跑一条命令(不做持久化) |
803
804
  | C→S | `{t:'ssh', sid?, cols?, rows?, name? \| host, username, …, persist?, persistName?}` | 创建 SSH 会话(ssh2 原生);`name` 引用连接簿条目作基底,内联 `host/port/username/auth/keyPath/passphrase/password/agentForward` 可逐项覆盖;`persist` 语义同 spawn(远程 tmux 托管) |
804
805
  | C→S | `{t:'input', sid?, d}` | 按键/粘贴数据 |
805
- | C→S | `{t:'resize', sid?, cols, rows}` | 面板尺寸变化 |
806
+ | C→S | `{t:'resize', sid?, cols, rows}` | 面板尺寸变化。**客户端只在容器可见且尺寸可信时发**(D79:隐藏标签 / 未挂载 / 面板最小化一律不发,PTY 保留上一次有效尺寸);宿主的夹紧只做安全下限,非数值(含 `null`)按非法值回落 80×24 而不是夹到下限 |
806
807
  | C→S | `{t:'refresh', sid?}` | 强制重画(0.10.1):宿主对 tmux 会话执行 `refresh-client`(客户端 reset 清残 scrollback 后请现场重画;非 tmux 会话 no-op) |
807
808
  | C→S | `{t:'kill', sid?}` | 关闭会话(孤儿会话也允许跨连接 kill,防泄漏) |
808
809
  | C→S | `{t:'sessions'}` | 列出全局会话快照(`attachable` 标记可重连者) |
@@ -891,7 +892,9 @@ node scripts/preview.mjs --theme=light # 浅色主题
891
892
  - **resize 为内部耦合**:DSH 的 `spawnTerminal` handle 未暴露 resize,
892
893
  插件直接透传 `(handle).terminal.resize(cols, rows)`(node-pty 原生 API,
893
894
  同进程可达)。DSH 升级若改内部结构,0.3.0 起会警告一次并退化为固定尺寸,
894
- 不再逐帧抛错。
895
+ 不再逐帧抛错;**D79 补**:这里的判据是显式看 `typeof terminal.resize === 'function'`
896
+ ——老写法 `handle.terminal?.resize?.(…)` 只在**抛错**时才进警告分支,DSH 若把
897
+ `handle.terminal` 改名 / 移除,既不 resize 也不警告(承诺落空、排查无线索)。
895
898
  - **TERM 注入用 `-c` 包装层(仅 POSIX)**:DSH 硬编码 node-pty `name:"dumb"`,而
896
899
  node-pty 里 name 优先于 env.TERM,因此 shell 以
897
900
  `sh -c 'export TERM=...; exec "$shell"'` 方式启动(对用户透明;TERM /