dsh-ssh-tui 0.7.0 → 0.7.2
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 +90 -7
- package/README.md +58 -7
- package/lib/approval-cache.js +12 -9
- package/lib/approval-cache.js.map +1 -1
- package/lib/color-depth.js +26 -5
- package/lib/color-depth.js.map +1 -1
- package/lib/diag.js +60 -17
- package/lib/diag.js.map +1 -1
- package/lib/dialogs.js.map +1 -1
- package/lib/display-sock.js +68 -10
- package/lib/display-sock.js.map +1 -1
- package/lib/footer.js +35 -7
- package/lib/footer.js.map +1 -1
- package/lib/gateway-protocol.js +202 -0
- package/lib/gateway-protocol.js.map +1 -0
- package/lib/i18n/en.js +63 -41
- package/lib/i18n/en.js.map +1 -1
- package/lib/i18n/zh.js +63 -41
- package/lib/i18n/zh.js.map +1 -1
- package/lib/index.js +99 -23
- package/lib/index.js.map +1 -1
- package/lib/job-label.js +99 -17
- package/lib/job-label.js.map +1 -1
- package/lib/plan.js +269 -17
- package/lib/plan.js.map +1 -1
- package/lib/platform.js +88 -0
- package/lib/platform.js.map +1 -0
- package/lib/provider-catalog.js +3 -0
- package/lib/provider-catalog.js.map +1 -1
- package/lib/route-memory.js +8 -1
- package/lib/route-memory.js.map +1 -1
- package/lib/session-list.js +18 -1
- package/lib/session-list.js.map +1 -1
- package/lib/session-lock.js +75 -23
- package/lib/session-lock.js.map +1 -1
- package/lib/session-route.js +331 -0
- package/lib/session-route.js.map +1 -0
- package/lib/subagent-model.js +79 -1
- package/lib/subagent-model.js.map +1 -1
- package/lib/term-text.js +7 -4
- package/lib/term-text.js.map +1 -1
- package/lib/tool-present.js +46 -14
- package/lib/tool-present.js.map +1 -1
- package/lib/tui.js +1796 -274
- package/lib/tui.js.map +1 -1
- package/lib/types/color-depth.d.ts +4 -4
- package/lib/types/diag.d.ts +11 -0
- package/lib/types/dialogs.d.ts +4 -0
- package/lib/types/display-sock.d.ts +52 -1
- package/lib/types/footer.d.ts +18 -4
- package/lib/types/gateway-protocol.d.ts +88 -0
- package/lib/types/job-label.d.ts +38 -7
- package/lib/types/plan.d.ts +94 -4
- package/lib/types/platform.d.ts +50 -0
- package/lib/types/route-memory.d.ts +17 -22
- package/lib/types/session-list.d.ts +5 -0
- package/lib/types/session-lock.d.ts +9 -0
- package/lib/types/session-route.d.ts +191 -0
- package/lib/types/subagent-model.d.ts +53 -0
- package/lib/types/term-text.d.ts +3 -2
- package/lib/types/tool-present.d.ts +2 -17
- package/lib/types/transcript-types.d.ts +44 -1
- package/lib/types/tui.d.ts +292 -2
- package/lib/types/update-check.d.ts +42 -1
- package/lib/update-check.js +31 -2
- package/lib/update-check.js.map +1 -1
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -14,6 +14,9 @@ If you mostly work over SSH — a jump host, a test box, a keyboard-only
|
|
|
14
14
|
session — start here. A local desktop terminal with themes and layout
|
|
15
15
|
you already like can stay as it is.
|
|
16
16
|
|
|
17
|
+
A SuperGrok / X Premium subscription goes through the standalone plugin
|
|
18
|
+
[dsh-llm-xai-oauth](https://github.com/cyjyyd/dsh-llm-xai-oauth) (headless, web, or this TUI). It reuses a local grok-bridge token; no xAI API key.
|
|
19
|
+
|
|
17
20
|
Listed on the [dshfind plugin directory](https://dshfind.com/en/plugins/cyjyyd/dsh-ssh-tui):
|
|
18
21
|
|
|
19
22
|
[](https://dshfind.com/en/plugins/cyjyyd/dsh-ssh-tui?ref=badge)
|
|
@@ -89,11 +92,11 @@ The recommended install is the command at the top of this README:
|
|
|
89
92
|
profile dependency, and appends this package to `dsh.profile.bundles`
|
|
90
93
|
because the manifest declares `dsh.bundle`.
|
|
91
94
|
|
|
92
|
-
Optional:
|
|
95
|
+
Optional: put a SuperGrok subscription on dsh (standalone plugin, this TUI is not required):
|
|
93
96
|
|
|
94
97
|
```sh
|
|
95
|
-
dsh plugin --profile tui add dsh-llm-xai-oauth
|
|
96
|
-
dsh plugin --profile headless add dsh-llm-xai-oauth
|
|
98
|
+
dsh plugin --profile tui add dsh-llm-xai-oauth@latest
|
|
99
|
+
dsh plugin --profile headless add dsh-llm-xai-oauth@latest
|
|
97
100
|
```
|
|
98
101
|
|
|
99
102
|
SuperGrok access tokens last about an hour. The TUI refreshes a due token on open, and `/usage` force-refreshes once after HTTP 401. If dsh is not running overnight, install the companion refresher or the next session starts with 401:
|
|
@@ -246,14 +249,24 @@ On first launch (when no API key is configured) the TUI opens a setup wizard:
|
|
|
246
249
|
1. choose a provider template, matching the official Models page:
|
|
247
250
|
- DeepSeek official;
|
|
248
251
|
- OpenCode Go (`opencode.ai/zen/go/v1`, Responses protocol);
|
|
252
|
+
- OpenCode Go · Completions (same gateway on its chat route; Zen's model list
|
|
253
|
+
does not publish which route a model speaks, so pick this row for one that
|
|
254
|
+
only answers `/chat/completions`);
|
|
249
255
|
- Command Code (`api.commandcode.ai`, Completions protocol, with its own quota);
|
|
256
|
+
- Command Code · Responses (same gateway and key on its Responses route; the
|
|
257
|
+
gateway lists 55 of 71 models on both routes, 8 on Completions only, and the
|
|
258
|
+
Claude family on Messages only — pick the row that matches your model);
|
|
250
259
|
- custom OpenAI-compatible gateway (Completions);
|
|
251
260
|
- custom OpenAI Responses gateway;
|
|
252
261
|
- Anthropic Messages-compatible gateway;
|
|
253
262
|
2. for custom providers, enter a lowercase Provider ID (permanent), base URL,
|
|
254
263
|
API key (masked while typing), and one or more model IDs — each step has a
|
|
255
264
|
sensible template default. On the models step, press `Ctrl+F` to fetch the
|
|
256
|
-
current model list straight from the provider endpoint
|
|
265
|
+
current model list straight from the provider endpoint, then press Enter to
|
|
266
|
+
open a checklist of what was fetched (the template's models are pre-checked:
|
|
267
|
+
the listing offers candidates, it does not configure them all for you). When
|
|
268
|
+
more than one model is kept, a second step picks which one this session
|
|
269
|
+
should run; typing a model list instead skips both questions;
|
|
257
270
|
3. confirm and save.
|
|
258
271
|
|
|
259
272
|
The wizard sizes each model's context window automatically: the endpoint
|
|
@@ -288,6 +301,17 @@ dsh --profile tui
|
|
|
288
301
|
|
|
289
302
|
`--provider <id> --model <id>` remains available as a temporary override.
|
|
290
303
|
|
|
304
|
+
**One gateway is one provider.** `llm-pi-ai` stores the wire protocol on the
|
|
305
|
+
provider entry (one protocol per route), so a gateway whose catalogue spans
|
|
306
|
+
protocols is kept as sibling rows — `command-code`,
|
|
307
|
+
`command-code-completions`, `command-code-messages`. `/provider`, `/model` and
|
|
308
|
+
`/submodel` present those as a single supplier: the model list is the union of
|
|
309
|
+
the rows, a pick is filed on the row that can actually speak its protocol
|
|
310
|
+
(taken from the gateway's own `supported_endpoints`, else from where the model
|
|
311
|
+
is already configured), and the remembered choice is keyed by the gateway's id
|
|
312
|
+
so the next `/provider` still shows one row. Command Code and OpenCode Go are
|
|
313
|
+
both such gateways.
|
|
314
|
+
|
|
291
315
|
You can reopen the wizard at any time with:
|
|
292
316
|
|
|
293
317
|
```sh
|
|
@@ -316,8 +340,9 @@ You can reopen the wizard at any time with:
|
|
|
316
340
|
line endings.
|
|
317
341
|
- **Subagent route**: the identity row always carries `sub:<model>` — the route every child
|
|
318
342
|
inherits — with the effort in parentheses when `/subeffort` set one, e.g.
|
|
319
|
-
`sub:grok-4.5(xhigh)`.
|
|
320
|
-
|
|
343
|
+
`sub:grok-4.5(xhigh)`. While the child is on the parent's own provider the chip keeps the
|
|
344
|
+
row's mute; only a `/submodel` pin onto a *different* provider colours it and prefixes the
|
|
345
|
+
provider (`sub:xai/grok-4.5`). The full route is in the header and `/status`.
|
|
321
346
|
|
|
322
347
|
## Usage
|
|
323
348
|
|
|
@@ -395,6 +420,44 @@ default. Both commands are remembered under `ssh-tui-subagent` in
|
|
|
395
420
|
releases selected continuable children using the harness 0.1.1
|
|
396
421
|
`drainContinuableChildren` capability.
|
|
397
422
|
|
|
423
|
+
### Each session keeps its own route (`$DSH_HOME/tui-session-routes.json`)
|
|
424
|
+
|
|
425
|
+
The settings above are the **software-level default**: a new session starts
|
|
426
|
+
there. What a session actually ran on — the parent provider/model/effort plus
|
|
427
|
+
the subagent route, including a child pinned to another supplier — is recorded
|
|
428
|
+
separately, and `--resume` applies it automatically with one line saying so:
|
|
429
|
+
|
|
430
|
+
```
|
|
431
|
+
Resumed on this session's recorded route: xai/grok-4.6 (xhigh) · subagent deepseek-official/deepseek-v4-flash
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
This is what cross-provider children made necessary: under one global default,
|
|
435
|
+
session A can run its children on DeepSeek while session B runs them on xAI, and
|
|
436
|
+
a resume that only knew the software default would mix the two up. The rules:
|
|
437
|
+
|
|
438
|
+
- a **new session** is unaffected — it still starts from `settings.yaml`;
|
|
439
|
+
- on **resume** the record beats the default, but an explicit `--provider` /
|
|
440
|
+
`--model` flag still wins: that is what this launch asked for;
|
|
441
|
+
- a restored subagent route applies to **that session only** and is not written
|
|
442
|
+
back to `ssh-tui-subagent`, so one resume cannot change the default for every
|
|
443
|
+
later session;
|
|
444
|
+
- the record is written when a route settles (`/model`, `/provider`,
|
|
445
|
+
`/submodel`, `/subeffort`, `/setup`) and at the start of every turn, which
|
|
446
|
+
catches a preset or a hand-edited `settings.yaml`; nothing is written when
|
|
447
|
+
nothing changed;
|
|
448
|
+
- the newest 200 sessions are kept and older ones fall out; an unreadable file
|
|
449
|
+
reads as "no record" and the default applies;
|
|
450
|
+
- when the **recorded provider no longer exists** (removed or renamed), the whole
|
|
451
|
+
record is dropped and the launch falls back to the app-level defaults — model,
|
|
452
|
+
effort and subagent together — saying which supplier it fell back from. A
|
|
453
|
+
removed *child* pin is narrower: the parent route stays and the children fall
|
|
454
|
+
back to the app-level subagent setting. If not even the default can be routed
|
|
455
|
+
to, an error names it, lists what is available, and points at `/setup` and
|
|
456
|
+
`/provider`. Availability is judged permissively (the four built-ins, the
|
|
457
|
+
adapter list, a configured `llm-pi-ai` profile): calling a dead route alive
|
|
458
|
+
costs the harness's own error, calling a live one dead would silently lose the
|
|
459
|
+
session's route.
|
|
460
|
+
|
|
398
461
|
Each subagent is its own collapsible card. One or many children start collapsed,
|
|
399
462
|
so the parent transcript stays readable; `Enter`, click, empty-input `↑`/`↓`,
|
|
400
463
|
and `Ctrl+R` expand or collapse them independently. Running cards show a spinner,
|
|
@@ -579,6 +642,10 @@ Find your symptom; each answer is what to do, not a change log.
|
|
|
579
642
|
- **Windows: `host display socket did not appear`** — upgrade
|
|
580
643
|
(`dsh plugin --profile tui add dsh-ssh-tui@latest`); older builds waited 15 seconds and
|
|
581
644
|
timed out on the named pipe. If it still fails, attach `/diag` to an issue.
|
|
645
|
+
- **Windows: the in-app update reports `spawn dsh ENOENT`** — an older updater spawned a
|
|
646
|
+
bare `dsh`, which on Windows is a `dsh.cmd` shim. Run the same upgrade once from the
|
|
647
|
+
command line (`dsh plugin --profile tui add dsh-ssh-tui@latest`); the in-app update works
|
|
648
|
+
from then on.
|
|
582
649
|
- **pnpm refuses to run the build script of a git dependency** — add the key pnpm prints to
|
|
583
650
|
`allowBuilds` in the profile's `pnpm-workspace.yaml`, then reinstall.
|
|
584
651
|
- **After an upgrade `/mode` reports a missing service, or the preset tools vanish** — run
|
|
@@ -606,6 +673,10 @@ Find your symptom; each answer is what to do, not a change log.
|
|
|
606
673
|
|
|
607
674
|
### Display and terminal
|
|
608
675
|
|
|
676
|
+
- **Windows: no colour at all, just black and white** — 0.7.0 read the unset `TERM` of a
|
|
677
|
+
Windows session as "no terminal". Pin the palette to recover it:
|
|
678
|
+
`set DSH_TUI_COLOR_DEPTH=8` (or `256` / `truecolor`); `/diag` prints the resolved palette
|
|
679
|
+
and the hints behind it.
|
|
609
680
|
- **Colours look wrong, or a diff is one solid block you cannot read** — pin the palette
|
|
610
681
|
with `DSH_TUI_COLOR_DEPTH=truecolor|256|8|none`. At `256` a diff is dark grey with green
|
|
611
682
|
or red text; at `none` there is no colour at all, but `+`/`-`, `●`, `⚠` and `✖` remain —
|
|
@@ -636,11 +707,17 @@ Find your symptom; each answer is what to do, not a change log.
|
|
|
636
707
|
its remaining share and reset time. Threshold alerts still fire on the tightest window.
|
|
637
708
|
- **The model name has no provider prefix** — the status line shows the model alone
|
|
638
709
|
(`provider/model` is truncated to the model); the full route is in the header and
|
|
639
|
-
`/status`, and a `sub:` chip shows the child's model the same way
|
|
710
|
+
`/status`, and a `sub:` chip shows the child's model the same way — unless `/submodel`
|
|
711
|
+
pinned another provider, which adds a `provider/` prefix and an accent.
|
|
640
712
|
- **The subagent model is not what you want** — `/submodel` picks the model, `/subeffort`
|
|
641
713
|
the reasoning effort, `/status` shows the current pair.
|
|
642
714
|
- **No `tok/s`** — that turn had no measurable model tokens; a step with only a first-token
|
|
643
715
|
time shows `首字 1.2s`.
|
|
716
|
+
- **The footer is stuck on "compacting" and `/compact` says one is already running** — the Host
|
|
717
|
+
exited mid-compaction, so the log has a `compaction/start` with no `end` and the resumed card
|
|
718
|
+
stays on "running" forever. Restart and resume the same session: the replay settles every such
|
|
719
|
+
compaction as interrupted, which frees the footer and the command again. Before 0.7.2 the same
|
|
720
|
+
restart still helps (the stale card is never written back to the log).
|
|
644
721
|
- **The plan strip asked for leftover todos only once** — that is deliberate: one reminder
|
|
645
722
|
per open list, so a turn end never spawns another turn forever. To see it again, complete
|
|
646
723
|
the list and start a new one.
|
|
@@ -669,6 +746,12 @@ Find your symptom; each answer is what to do, not a change log.
|
|
|
669
746
|
|
|
670
747
|
## Development
|
|
671
748
|
|
|
749
|
+
Platform-sensitive changes (environment variables, child processes, paths, terminal
|
|
750
|
+
capability) have their own note: [docs/platform.md](docs/platform.md). The rule is to put the
|
|
751
|
+
platform decision in an injectable pure function and assert the Windows branch in a test, so
|
|
752
|
+
it reddens on Linux too; `tests/platform-guards.test.mjs` statically rejects a new bare
|
|
753
|
+
`spawn('name')`, and CI's `test-windows` leg runs the same suite on a real Windows runner.
|
|
754
|
+
|
|
672
755
|
```text
|
|
673
756
|
src/picker.ts launch history picker (9-row page, uncapped list, filter)
|
|
674
757
|
src/tui.ts SshTui (re-exports leaf helpers)
|
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ English: [README.en.md](README.en.md)
|
|
|
13
13
|
如果你主要在 SSH 里写代码——公司跳板、测试机、只有键盘的会话——可以从这里开始。
|
|
14
14
|
本机桌面终端若更在意主题和布局,也可以继续用你已经习惯的界面。
|
|
15
15
|
|
|
16
|
-
SuperGrok / X Premium
|
|
16
|
+
已经在付 SuperGrok / X Premium 的话,用独立插件 [dsh-llm-xai-oauth](https://github.com/cyjyyd/dsh-llm-xai-oauth) 把订阅接进 dsh(headless / web / 本 TUI 都能用),复用本机 grok-bridge token,不需要 xAI API Key。
|
|
17
17
|
|
|
18
18
|
本插件已被 [dshfind 插件目录](https://dshfind.com/zh/plugins/cyjyyd/dsh-ssh-tui) 收录:
|
|
19
19
|
|
|
@@ -68,7 +68,8 @@ dsh --profile tui
|
|
|
68
68
|
- 输入框下方两行底栏:第一行链路芯片 + 按宽度丢组的会话数字(轮次、入/出 token、速度);
|
|
69
69
|
第二行只留一个活动词(运行中 / 工具 N / 子代理 N / 压缩中…),身份收到右侧(含 `目录:srv`;点击打印完整工作目录);
|
|
70
70
|
身份里始终带 `sub:<子代理模型>`(如 `sub:grok-4.5(xhigh)`):`/submodel` 选模型、`/subeffort` 选档位(带括号后缀);
|
|
71
|
-
|
|
71
|
+
子代理跟随主模型时它就是身份行的暗色;只有 `/submodel` 钉到**别的提供商**才变色并补上 `提供商/` 前缀
|
|
72
|
+
(如 `sub:xai/grok-4.5`)——完整路由在顶栏与 `/status`;
|
|
72
73
|
- 恢复旧会话会切到该会话记录的工作目录;新建会话用启动时的当前目录;
|
|
73
74
|
- 历史会话启动选择器:`dsh --profile tui --resume`(或 `resume`)先选会话再进入;
|
|
74
75
|
- 终端窗口标题栏:运行中旋转图标 + `运行中 · 工具 N`,完成后 `✓ 已完成`,并响
|
|
@@ -110,11 +111,11 @@ dsh --profile tui
|
|
|
110
111
|
|
|
111
112
|
推荐安装就是文首那条 `dsh plugin --profile tui add dsh-ssh-tui@latest`。CLI 会从 npm 拉包、写入 profile 依赖,并把本插件加入 `dsh.profile.bundles`(因为包内声明了 `dsh.bundle`)。
|
|
112
113
|
|
|
113
|
-
|
|
114
|
+
可选:把 SuperGrok 订阅接进 dsh(独立插件,不依赖本 TUI):
|
|
114
115
|
|
|
115
116
|
```bash
|
|
116
|
-
dsh plugin --profile tui add dsh-llm-xai-oauth
|
|
117
|
-
dsh plugin --profile headless add dsh-llm-xai-oauth
|
|
117
|
+
dsh plugin --profile tui add dsh-llm-xai-oauth@latest
|
|
118
|
+
dsh plugin --profile headless add dsh-llm-xai-oauth@latest
|
|
118
119
|
```
|
|
119
120
|
|
|
120
121
|
SuperGrok 的 access token 大约 1 小时过期。TUI 打开时会刷新即将过期的 token,`/usage` 遇到 401 也会再刷一次。机器长时间不开 dsh 时,请另开刷新进程,否则一打开就是 401:
|
|
@@ -339,6 +340,14 @@ preset 保留它 `preset.yml` 里的名字不翻译。`/mode <id|名字>` 直接
|
|
|
339
340
|
每个提供商上次的模型和思考强度会分开记住。`/setup` 只新增或更新当前这条
|
|
340
341
|
API Key 提供商,不会冲掉其它路由。SuperGrok / X Premium 走本机 OAuth,不需要填 Key。
|
|
341
342
|
|
|
343
|
+
**一个网关就是一个提供商。** `llm-pi-ai` 把线路协议记在 provider 上(一条 route 只能
|
|
344
|
+
一种协议),所以目录跨协议的网关在 `settings.yaml` 里本来会拆成 `command-code` /
|
|
345
|
+
`command-code-completions` / `command-code-messages` 这样的兄弟行。`/provider`、
|
|
346
|
+
`/model`、`/submodel` 把它们**当成一家**列出:模型列表取各行并集,选中后自动落到
|
|
347
|
+
真正能发该协议的那一行(依据网关自己公布的 `supported_endpoints`;公布不了就沿用
|
|
348
|
+
它已经配置在的那行),而记住你上次选择的键是网关注 id——所以下次打开仍然只有一行。
|
|
349
|
+
Command Code 与 OpenCode Go 都是这种网关。
|
|
350
|
+
|
|
342
351
|
子代理默认跟随父会话的提供方,并尽量选同一家的轻量模型:按父会话所选模型名
|
|
343
352
|
近似匹配,`flash` 结尾的优先——DeepSeek 用 `deepseek-v4-flash`,xAI 用
|
|
344
353
|
`grok-4.5`。`/model` 或 `/provider` 换提供商(OAuth / API Key 都一样)时会
|
|
@@ -402,13 +411,43 @@ web 端与 TUI 共用同一份设置。`/model` 换提供商后**下一步请求
|
|
|
402
411
|
每个提供商上次的模型和思考强度记在 `ssh-tui-routes` 里,切回 SuperGrok / 官方 / Go 时会预填。
|
|
403
412
|
`/setup` 只更新当前这条提供商(模型列表会合并),不会删掉其它路由的 Key 和模型。
|
|
404
413
|
|
|
414
|
+
### 会话自己的路由(`$DSH_HOME/tui-session-routes.json`)
|
|
415
|
+
|
|
416
|
+
上面那份是**软件级默认值**:新会话从这里起步。而每个会话实际用过的路由(父会话的提供商/模型/强度,
|
|
417
|
+
加上子代理那条——包括钉死到别的提供商的情况)会单独记在 `tui-session-routes.json` 里,
|
|
418
|
+
`--resume` 时**自动按记录恢复**,并在转录区打一行说明:
|
|
419
|
+
|
|
420
|
+
```
|
|
421
|
+
已按本会话记录恢复路由:xai/grok-4.6 (xhigh) · 子代理 deepseek-official/deepseek-v4-flash
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
这就是跨提供商子代理需要会话级存储的原因:同一个软件默认值下,A 会话可能让自己的子代理跑在
|
|
425
|
+
DeepSeek 上、B 会话跑在 xAI 上;只记软件级默认值的话,resume 之后两个会话会互相污染。
|
|
426
|
+
规则:
|
|
427
|
+
|
|
428
|
+
- **新会话**不受影响,仍从 `settings.yaml` 的默认值起步;
|
|
429
|
+
- **resume** 时记录优先于默认值,但 **CLI 显式给的 `--provider` / `--model` 仍然最高**——
|
|
430
|
+
那是这次启动的明确要求;
|
|
431
|
+
- 恢复的子代理路由**只作用于当前会话**,不会写回 `ssh-tui-subagent`(否则一次 resume 会改掉
|
|
432
|
+
以后所有新会话的默认子代理);
|
|
433
|
+
- 记录在路由定下来时写(`/model`、`/provider`、`/submodel`、`/subeffort`、`/setup`)以及每轮开始时
|
|
434
|
+
(这样 preset 或手改 settings.yaml 换掉的模型也能被记住);没变化就不写;
|
|
435
|
+
- 只保留最近 200 个会话的记录,老的自然淘汰;文件坏了就当作没有记录,退回默认值。
|
|
436
|
+
- 记录里的**提供商已被删掉/改名**时:整条会话记录作废,回退到应用级默认(模型、强度、子代理一起回退),
|
|
437
|
+
并在启动时说明从哪家退下来的;只有**子代理单独钉死的那家**不可用时,父路由照旧、子代理退回应用级设置。
|
|
438
|
+
连默认提供商都不可用时会打一行错误:报出是哪家、列出可用的提供商,并指向 `/setup` 与 `/provider`。
|
|
439
|
+
判断"可用"取宽松口径(内建四家 + 适配器列表 + 已配置的 `llm-pi-ai` 档案):误判成可用只是报一条
|
|
440
|
+
Harness 自己的错误,误判成不可用则会悄悄丢掉会话路由。
|
|
441
|
+
|
|
405
442
|
对 OpenCode 和其他第三方提供商,`/model` 会先调用提供商的端点
|
|
406
443
|
(`GET {baseURL}/models`)获取实时模型列表;端点不可达时回退到已配置的
|
|
407
444
|
模型列表。若选中的模型尚未写入提供商配置,会自动追加到
|
|
408
445
|
`llm-pi-ai.providers.<id>.models`,保证 Harness 可以正常调用。
|
|
409
446
|
|
|
410
447
|
首次配置向导的自定义/OpenCode 提供商步骤中,输入模型 ID 前可按
|
|
411
|
-
`Ctrl+F`
|
|
448
|
+
`Ctrl+F` 直接从端点拉取模型列表,免去手动输入。拉完按回车打开**勾选列表**:
|
|
449
|
+
模板模型默认勾上,端点列出的只是候选,不会替你全写进配置;勾了多个时再问一次
|
|
450
|
+
「本次会话用哪个模型」。想直接手写模型 ID 列表,输入并回车即可跳过这两步。
|
|
412
451
|
|
|
413
452
|
向导会尽量自动填好上下文窗口:先读端点 `/models` 的容量字段,查不到再按模型名
|
|
414
453
|
去内置 pi-ai 目录匹配(会剥离提供商写进模型名的思考档位后缀 `-high` / `-low` /
|
|
@@ -513,6 +552,10 @@ npm run typecheck
|
|
|
513
552
|
npm run build
|
|
514
553
|
```
|
|
515
554
|
|
|
555
|
+
改到环境变量、子进程、路径或终端能力时,先读 [docs/platform.md](docs/platform.md):平台判断要写成可注入的纯函数并在用例里
|
|
556
|
+
显式跑 Windows 分支(`tests/platform-guards.test.mjs` 会静态拦住新的裸名 `spawn`),真实 Windows 由 CI 的
|
|
557
|
+
`test-windows` 腿覆盖。
|
|
558
|
+
|
|
516
559
|
## 常见问题(QA)
|
|
517
560
|
|
|
518
561
|
按现象查;每条只讲怎么办,不讲版本历史。
|
|
@@ -522,6 +565,8 @@ npm run build
|
|
|
522
565
|
- **`dsh-ssh-tui: both stdin and stdout must be TTYs`**:必须在真实终端 / SSH 会话里启动;管道、CI、`&` 后台都不行。
|
|
523
566
|
- **Windows 报 `host display socket did not appear`**:升级到最新版:
|
|
524
567
|
`dsh plugin --profile tui add dsh-ssh-tui@latest`。仍失败请附 `/diag` 输出提 issue。
|
|
568
|
+
- **Windows 上应用内更新报 `spawn dsh ENOENT`**:旧的更新器直接 `spawn dsh`,而 Windows 上装的是 `dsh.cmd` 垫片;
|
|
569
|
+
在命令行跑一次同样的升级即可(`dsh plugin --profile tui add dsh-ssh-tui@latest`),之后应用内更新正常。
|
|
525
570
|
- **pnpm 拒绝 git 依赖的构建脚本**:把 pnpm 打印的 key 加进 profile 的 `pnpm-workspace.yaml` 的 `allowBuilds`,再重装。
|
|
526
571
|
- **升级后 `/mode` 报「服务不可用」、preset 工具消失**:敲 `/doctor`。它逐项判定部署组合(补丁能否解析、
|
|
527
572
|
名单与 code-runtime 是否组合、有没有行被挂载两次、dsh 版本是否在兼容表内、是否装着两份 `@deepseek-ai/dsh-scope`),
|
|
@@ -540,6 +585,8 @@ npm run build
|
|
|
540
585
|
|
|
541
586
|
### 显示与终端
|
|
542
587
|
|
|
588
|
+
- **Windows 下完全没有颜色(只有黑白)**:0.7.0 在 Windows 上把"未设置 `TERM`"误判为无终端。指定色深即可恢复:
|
|
589
|
+
`set DSH_TUI_COLOR_DEPTH=8`(或 `256` / `truecolor`),也可以先看 `/diag` 的**配色**一行确认判定结果。
|
|
543
590
|
- **颜色不对,或 diff 整块一个颜色、看不清字**:显式指定色深 `DSH_TUI_COLOR_DEPTH=truecolor|256|8|none`。
|
|
544
591
|
`256` 下 diff 是深灰底 + 绿/红字;`none` 完全没有颜色,但 `+`/`-`、`●`、`⚠`、`✖` 仍在,状态不只靠颜色表达。
|
|
545
592
|
- **中文 / emoji 挤压相邻字符**:换一款覆盖这些字形的等宽字体(如 Noto Sans Mono CJK)。程序按 2 格预算这些符号
|
|
@@ -558,9 +605,13 @@ npm run build
|
|
|
558
605
|
- **`5Hr` / `1Wk` / `1Mo` 是什么**:该数值所属的额度窗口。默认显示**最小窗口**(5 小时 → 周 → 月),
|
|
559
606
|
`/quota` 列出全部窗口、剩余比例与重置时间。告警仍按"最紧的那个窗口"触发。
|
|
560
607
|
- **状态栏模型名没有提供商前缀**:状态行只显示模型名(`provider/model` 会截断成模型名),完整路由在顶栏与 `/status`;
|
|
561
|
-
`sub:`
|
|
608
|
+
`sub:` 子代理同样只显示模型名;只有钉到别的提供商时才补 `提供商/` 前缀并变色。
|
|
562
609
|
- **看不到子代理模型 / 想换子代理**:`/submodel` 选模型、`/subeffort` 选思考档位,`/status` 查看当前值。
|
|
563
610
|
- **没有 `tok/s`**:该轮没有可统计的模型 token;只有首字耗时时显示 `首字 1.2s`。
|
|
611
|
+
- **底栏一直显示「压缩中」,`/compact` 还说已有压缩在进行**:Host 在压缩过程中退出,日志里只剩
|
|
612
|
+
`compaction/start` 没有 `end`,恢复会话时那张卡片会一直停在"运行中"。重新启动(`--resume` 同一会话)
|
|
613
|
+
即可:重放会把这类没有结束事件的压缩结算成「压缩被中断」,底栏随之恢复,`/compact` 也能再用。
|
|
614
|
+
升级到 0.7.2 之前遇到时,重启同样有效(旧卡片不会写回日志)。
|
|
564
615
|
- **计划条只提醒一次"补待办"**:有意如此——一条待办列表只问一次,避免每轮结束都开一个新回合。
|
|
565
616
|
想再次触发,先把列表全部标成完成,再新开一列待办。
|
|
566
617
|
|
package/lib/approval-cache.js
CHANGED
|
@@ -25,19 +25,22 @@
|
|
|
25
25
|
* the review result there depends entirely on a script the key cannot see.
|
|
26
26
|
* @module dsh-ssh-tui/approval-cache
|
|
27
27
|
*/
|
|
28
|
+
import { createHash } from 'node:crypto';
|
|
28
29
|
import { isOpaqueInterpreterCommand } from './auto-approval.js';
|
|
29
30
|
/** How long one remembered verdict stays usable. */
|
|
30
31
|
export const DEFAULT_VERDICT_TTL_MS = 10 * 60 * 1000;
|
|
31
32
|
/** How many verdicts are remembered at once; the least recently used go first. */
|
|
32
33
|
export const DEFAULT_VERDICT_CAPACITY = 32;
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Identity digest for a reviewed request.
|
|
36
|
+
*
|
|
37
|
+
* A 32-bit FNV-1a used to be enough to *look* unique in a 32-slot map, but a
|
|
38
|
+
* collision here reuses someone else's verdict — `npm publish --tag next`
|
|
39
|
+
* answering as yesterday's `npm publish`. SHA-1 truncated to 16 hex is still
|
|
40
|
+
* short in the map and not a birthday problem at this capacity.
|
|
41
|
+
*/
|
|
42
|
+
function identityDigest(text) {
|
|
43
|
+
return createHash('sha1').update(text).digest('hex').slice(0, 16);
|
|
41
44
|
}
|
|
42
45
|
/** Whitespace-insensitive form of a command, so spacing alone cannot miss. */
|
|
43
46
|
export function canonicalCommand(command) {
|
|
@@ -64,7 +67,7 @@ export function cacheableShape(input) {
|
|
|
64
67
|
* @returns a stable, collision-resistant digest.
|
|
65
68
|
*/
|
|
66
69
|
export function verdictKey(input) {
|
|
67
|
-
return
|
|
70
|
+
return identityDigest([
|
|
68
71
|
input.toolName,
|
|
69
72
|
canonicalCommand(input.command),
|
|
70
73
|
input.args ?? '',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval-cache.js","sourceRoot":"","sources":["../src/approval-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAA;AAG/D,oDAAoD;AACpD,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AACpD,kFAAkF;AAClF,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAA;AA2B1C
|
|
1
|
+
{"version":3,"file":"approval-cache.js","sourceRoot":"","sources":["../src/approval-cache.ts"],"names":[],"mappings":"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"}
|
package/lib/color-depth.js
CHANGED
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
* Decide the palette from the environment.
|
|
17
17
|
*
|
|
18
18
|
* `DSH_TUI_COLOR_DEPTH` wins outright so a user can correct a wrong guess.
|
|
19
|
-
* Otherwise: no colour at all when `NO_COLOR` is set or `TERM`
|
|
20
|
-
*
|
|
19
|
+
* Otherwise: no colour at all when `NO_COLOR` is set or `TERM` is `dumb`
|
|
20
|
+
* (or empty on POSIX); truecolor when `COLORTERM` says so; 256 for a
|
|
21
21
|
* `*256color` terminal and for tmux/screen (their default palette is 256 and
|
|
22
|
-
* they translate truecolor poorly); 8 for everything else.
|
|
22
|
+
* they translate truecolor poorly); 8 for Linux/VT consoles and everything else.
|
|
23
23
|
* @param env - the environment to read (tests pass their own).
|
|
24
24
|
* @returns the palette to paint with.
|
|
25
25
|
*/
|
|
26
|
-
export function colorDepth(env = process.env) {
|
|
26
|
+
export function colorDepth(env = process.env, platform = process.platform) {
|
|
27
27
|
const forced = (env.DSH_TUI_COLOR_DEPTH ?? '').trim().toLowerCase();
|
|
28
28
|
if (forced === 'truecolor' || forced === '24bit' || forced === '16m')
|
|
29
29
|
return 'truecolor';
|
|
@@ -37,8 +37,24 @@ export function colorDepth(env = process.env) {
|
|
|
37
37
|
if (noColor !== '')
|
|
38
38
|
return 'none';
|
|
39
39
|
const term = (env.TERM ?? '').trim().toLowerCase();
|
|
40
|
-
|
|
40
|
+
// What an empty TERM means depends on the platform. On POSIX it is the pipe /
|
|
41
|
+
// CI case and there is nothing to paint with. On Windows it is simply the
|
|
42
|
+
// normal state — PowerShell, ConHost and Windows Terminal all leave TERM unset
|
|
43
|
+
// — and reading it as "no colour" is what turned a Windows session black and
|
|
44
|
+
// white. The explicit markers below still decide the palette there.
|
|
45
|
+
if (term === '') {
|
|
46
|
+
if (platform !== 'win32')
|
|
47
|
+
return 'none';
|
|
48
|
+
}
|
|
49
|
+
else if (term === 'dumb') {
|
|
41
50
|
return 'none';
|
|
51
|
+
}
|
|
52
|
+
else if (term === 'linux' || term === 'vt100' || term === 'vt220') {
|
|
53
|
+
// Linux virtual consoles (tty1 on a headless box) and classic VT
|
|
54
|
+
// emulators advertise these names and still paint the 8/16-colour
|
|
55
|
+
// palette. OSC 8 hyperlinks stay off (see osc8Enabled); colour does not.
|
|
56
|
+
return '8';
|
|
57
|
+
}
|
|
42
58
|
const colorTerm = (env.COLORTERM ?? '').trim().toLowerCase();
|
|
43
59
|
if (colorTerm === 'truecolor' || colorTerm === '24bit')
|
|
44
60
|
return 'truecolor';
|
|
@@ -46,6 +62,11 @@ export function colorDepth(env = process.env) {
|
|
|
46
62
|
return '256';
|
|
47
63
|
if (term.startsWith('screen') || term.startsWith('tmux'))
|
|
48
64
|
return '256';
|
|
65
|
+
// Windows Terminal sets WT_SESSION and paints 24-bit colour; a plain Windows
|
|
66
|
+
// console falls through to the 16-colour palette, which still carries the
|
|
67
|
+
// diff colours (and `DSH_TUI_COLOR_DEPTH` overrides either way).
|
|
68
|
+
if (platform === 'win32' && (env.WT_SESSION ?? '').trim() !== '')
|
|
69
|
+
return 'truecolor';
|
|
49
70
|
return '8';
|
|
50
71
|
}
|
|
51
72
|
/** The 16 standard colours, as the RGB a terminal roughly paints them with. */
|
package/lib/color-depth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color-depth.js","sourceRoot":"","sources":["../src/color-depth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,
|
|
1
|
+
{"version":3,"file":"color-depth.js","sourceRoot":"","sources":["../src/color-depth.ts"],"names":[],"mappings":"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"}
|
package/lib/diag.js
CHANGED
|
@@ -16,24 +16,30 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { readFile, readdir, stat } from 'node:fs/promises';
|
|
18
18
|
import { join } from 'node:path';
|
|
19
|
+
import { colorDepth } from './color-depth.js';
|
|
19
20
|
import { t } from './i18n/index.js';
|
|
20
|
-
import { displaySockExists, isPipePath, resolveDshHome, sessionErrPath, sessionSockPath, } from './display-sock.js';
|
|
21
|
-
import { inspectLiveHost, sessionLockDisabled, sessionLockPath } from './session-lock.js';
|
|
21
|
+
import { displaySockExists, isPipePath, legacySessionErrPath, resolveDshHome, sessionErrPath, sessionSockLookupPaths, sessionSockPath, } from './display-sock.js';
|
|
22
|
+
import { inspectLiveHost, sessionLockDisabled, sessionLockLookupPaths, sessionLockPath } from './session-lock.js';
|
|
22
23
|
import { sessionIndexPath } from './session-index.js';
|
|
23
24
|
/** How much of a Host stderr log the report carries. */
|
|
24
25
|
export const DIAG_ERR_TAIL_BYTES = 2000;
|
|
25
26
|
/** Tail of a Host stderr log, or undefined when there is nothing to read. */
|
|
26
27
|
export async function readErrTail(sessionId, dshHome = resolveDshHome()) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
const paths = [sessionErrPath(sessionId, dshHome), legacySessionErrPath(sessionId, dshHome)]
|
|
29
|
+
.filter((path) => path !== undefined);
|
|
30
|
+
for (const path of paths) {
|
|
31
|
+
try {
|
|
32
|
+
const raw = await readFile(path, 'utf8');
|
|
33
|
+
const trimmed = raw.trim();
|
|
34
|
+
if (trimmed === '')
|
|
35
|
+
continue;
|
|
36
|
+
return trimmed.length <= DIAG_ERR_TAIL_BYTES ? trimmed : `…${trimmed.slice(-DIAG_ERR_TAIL_BYTES)}`;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Missing at this name; try the 0.7.1 leftover next.
|
|
40
|
+
}
|
|
36
41
|
}
|
|
42
|
+
return undefined;
|
|
37
43
|
}
|
|
38
44
|
/**
|
|
39
45
|
* Why `--resume` would behave the way it does, as an ordered chain of verdicts.
|
|
@@ -97,6 +103,18 @@ export function formatDiag(snapshot) {
|
|
|
97
103
|
node: snapshot.nodeVersion,
|
|
98
104
|
}));
|
|
99
105
|
lines.push(t('diag.rowPlatform', { platform: snapshot.platform }));
|
|
106
|
+
// Optional so a caller that builds its own snapshot (a library user, an older
|
|
107
|
+
// test) still renders; an absent palette is reported as unknown, not thrown.
|
|
108
|
+
if (snapshot.color !== undefined) {
|
|
109
|
+
lines.push(t('diag.rowColor', {
|
|
110
|
+
depth: snapshot.color.depth,
|
|
111
|
+
term: snapshot.color.term === undefined || snapshot.color.term === '' ? t('diag.colorUnset') : snapshot.color.term,
|
|
112
|
+
colorTerm: snapshot.color.colorTerm === undefined || snapshot.color.colorTerm === ''
|
|
113
|
+
? t('diag.colorUnset')
|
|
114
|
+
: snapshot.color.colorTerm,
|
|
115
|
+
wt: snapshot.color.windowsTerminal ? yes : no,
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
100
118
|
lines.push(t('diag.rowSession', { session: snapshot.sessionId }));
|
|
101
119
|
lines.push(t('diag.rowRole', {
|
|
102
120
|
role: snapshot.hostProcess ? t('diag.roleHost') : t('diag.roleLauncher'),
|
|
@@ -167,10 +185,26 @@ export async function collectDiag(options) {
|
|
|
167
185
|
const dshHome = options.dshHome ?? resolveDshHome();
|
|
168
186
|
const sockPath = sessionSockPath(options.sessionId, dshHome);
|
|
169
187
|
const lockPath = sessionLockPath(options.sessionId, dshHome);
|
|
170
|
-
const
|
|
188
|
+
const sockLookup = sessionSockLookupPaths(options.sessionId, dshHome);
|
|
189
|
+
const lockLookup = sessionLockLookupPaths(options.sessionId, dshHome);
|
|
190
|
+
let reachable = false;
|
|
191
|
+
let reachableSock = sockPath;
|
|
192
|
+
for (const candidate of sockLookup) {
|
|
193
|
+
if (await displaySockExists(candidate)) {
|
|
194
|
+
reachable = true;
|
|
195
|
+
reachableSock = candidate;
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
171
199
|
let sockFilePresent;
|
|
172
200
|
if (!isPipePath(sockPath)) {
|
|
173
|
-
sockFilePresent =
|
|
201
|
+
sockFilePresent = false;
|
|
202
|
+
for (const candidate of sockLookup) {
|
|
203
|
+
if (await stat(candidate).then(() => true).catch(() => false)) {
|
|
204
|
+
sockFilePresent = true;
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
174
208
|
}
|
|
175
209
|
const live = await inspectLiveHost(options.sessionId, dshHome).catch(() => undefined);
|
|
176
210
|
const host = live === undefined
|
|
@@ -189,8 +223,10 @@ export async function collectDiag(options) {
|
|
|
189
223
|
// `inspectLiveHost` steals a dead lock, so a lock file that exists while the
|
|
190
224
|
// inspection found nothing is the stale case.
|
|
191
225
|
if (host.kind === 'none') {
|
|
192
|
-
|
|
193
|
-
|
|
226
|
+
for (const candidate of lockLookup) {
|
|
227
|
+
const raw = await readFile(candidate, 'utf8').then(text => text, () => undefined);
|
|
228
|
+
if (raw === undefined)
|
|
229
|
+
continue;
|
|
194
230
|
try {
|
|
195
231
|
const parsed = JSON.parse(raw);
|
|
196
232
|
host.kind = 'stale';
|
|
@@ -200,7 +236,8 @@ export async function collectDiag(options) {
|
|
|
200
236
|
host.state = parsed.state;
|
|
201
237
|
if (typeof parsed.agentStatus === 'string')
|
|
202
238
|
host.agentStatus = parsed.agentStatus;
|
|
203
|
-
host.lockPath =
|
|
239
|
+
host.lockPath = candidate;
|
|
240
|
+
break;
|
|
204
241
|
}
|
|
205
242
|
catch {
|
|
206
243
|
// An unreadable lock is reported as no lock.
|
|
@@ -216,11 +253,17 @@ export async function collectDiag(options) {
|
|
|
216
253
|
hostVersion: options.hostVersion,
|
|
217
254
|
nodeVersion: process.version,
|
|
218
255
|
platform: `${process.platform} ${process.arch}`,
|
|
256
|
+
color: options.color ?? {
|
|
257
|
+
depth: String(colorDepth(process.env)),
|
|
258
|
+
...((process.env.TERM ?? '') === '' ? {} : { term: process.env.TERM }),
|
|
259
|
+
...((process.env.COLORTERM ?? '') === '' ? {} : { colorTerm: process.env.COLORTERM }),
|
|
260
|
+
windowsTerminal: (process.env.WT_SESSION ?? '') !== '',
|
|
261
|
+
},
|
|
219
262
|
sessionId: options.sessionId,
|
|
220
263
|
hostProcess: options.hostProcess,
|
|
221
264
|
locksDisabled: sessionLockDisabled(),
|
|
222
265
|
dshHome,
|
|
223
|
-
sockPath,
|
|
266
|
+
sockPath: reachable ? reachableSock : sockPath,
|
|
224
267
|
sockReachable: reachable,
|
|
225
268
|
...(sockFilePresent === undefined ? {} : { sockFilePresent }),
|
|
226
269
|
host,
|