@crazyhappyone/dsh-tui 0.1.0-alpha.5 → 0.1.0-alpha.51
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/CHANGELOG.md +85 -0
- package/README.i18n.yaml +2 -2
- package/README.md +139 -20
- package/README.zh.md +137 -19
- package/assets/screenshots/dsh-tui-hello.png +0 -0
- package/assets/screenshots/dsh-tui-settings.png +0 -0
- package/bin/dsh-tui.js +18 -3
- package/cordis.patch.yml +116 -22
- package/dist/index.js +70260 -47119
- package/dist/schedule.js +36041 -0
- package/dist/settings.js +961 -0
- package/dist/startup.js +16 -11
- package/dist/zen-proxy.js +1048 -0
- package/package.json +82 -8
- package/presets/base-disable.patch.yml +82 -0
- package/presets/cordis.patch.yml +136 -0
- package/presets/minimal.patch.yml +78 -0
- package/presets/ptc.patch.yml +134 -0
- package/presets/registry.patch.yml +12 -0
- package/presets/standard.patch.yml +128 -0
- package/src/launcher.js +209 -75
- package/assets/screenshots/dsh-tui-home.png +0 -0
- package/tui/README.md +0 -126
- package/tui/README.zh.md +0 -126
- package/tui/cordis.patch.yml +0 -73
package/README.zh.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "DeepSeek Harness
|
|
2
|
+
description: "DeepSeek Harness 终端界面:一个 dsh 插件 bundle 及其 launcher。"
|
|
3
3
|
kind: "package-group"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -13,10 +13,31 @@ kind: "package-group"
|
|
|
13
13
|
|
|
14
14
|
## 概述
|
|
15
15
|
|
|
16
|
-
`@crazyhappyone/dsh-tui`
|
|
16
|
+
`@crazyhappyone/dsh-tui` 是 DeepSeek Harness(dsh)的终端界面,以 dsh **插件 bundle** 加 `dsh-tui` launcher 的形式发布。包声明了 `dsh.bundle`,因此 dsh 会像安装其他插件一样把它装进 profile;launcher 只负责自动完成这一安装并启动 profile。本仓库拥有插件源码(`tui/`、`tui-render/`)。Agent、会话、工具、持久化、provider、权限与 profile 组装仍由 DSH 拥有。
|
|
17
|
+
|
|
18
|
+
## 0.1.0-alpha.51 版本
|
|
19
|
+
|
|
20
|
+
本预发布版面向 DSH `0.2.1-rc.2`,修复实时输出穿插到输入区、滚轮逐行追赶,减少历史渲染开销,并加入设置多级导航。同时修复失败流式文本残留、SSH 登录提示和 `/cd` 后的文件路径问题(#14–#16)。完整变更与验证边界见 [changelog](CHANGELOG.md#010-alpha51--2026-10-21)。
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
npm install --global @crazyhappyone/dsh-tui@next
|
|
24
|
+
dsh-tui probe
|
|
25
|
+
dsh-tui
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
轻量模式和源码模式现在默认使用 `$DSH_HOME/profiles/`(通常为 `~/.dsh/profiles/`)下的官方 `deepseek-tui` profile。`/model` 读取 `ctx.llm`,模型选择调用 DSH 的 `agentDefaultModel`;本 bundle 不读取私有模型配置,也不复制其他 profile 的 provider。Magpie 会写入已有的 `profiles/*/cordis.patch.yml`;若在新 profile 创建前已接入 Magpie,创建后刷新其 DSH 接入/模型目录,再重启 TUI。
|
|
29
|
+
|
|
30
|
+
旧版轻量模式使用 `tui`,源码模式使用 `deepseek-tui`。两个目录均保留,不自动删除或迁移。继续使用原轻量 profile 可运行 `dsh-tui --profile tui`。使用其他已挂载 TUI 的官方 profile 时传入 `--profile NAME`;两种模式的安装和启动都会使用同一个指定目标。各 profile 仍由 DSH 独立配置;只写入 `web` 的 provider 不会自动变成全局配置。
|
|
31
|
+
|
|
32
|
+
正在运行的源码链接安装可通过 `/reload` 加载新构建,但会保留进程原先选中的 profile。若从 `tui` 切换到 `deepseek-tui`,需退出后重新启动,或显式指定 profile。恢复的 Goal 需执行 `/goal resume` 才会自动续跑。
|
|
33
|
+
|
|
34
|
+
`/settings` 现在支持多级浏览。Enter 进入分类、namespace、Provider、model 或字段;←/Esc 返回上一层;`/` 搜索;`i` 编辑对象 JSON;Space 切换支持的值。保存后停留当前位置,继续使用 DSH 官方 settings/credentials 服务。本次 PTY 对照中,9 行滚动到达目标从 168.07 ms 降至 17.93 ms;2,812 个有正文快照的比较帧未发现正文不一致或越界。这是合成数据的 PTY 实测,不是硬件延迟保证。数据与边界见[修复验证](docs/performance-audit-2026-10-21/fix-verification.md)。
|
|
17
35
|
|
|
18
36
|
## 目录
|
|
19
37
|
|
|
38
|
+
- [版本与升级](#010-alpha51-版本)
|
|
39
|
+
- [Changelog](CHANGELOG.md)
|
|
40
|
+
- [终端能力](#终端能力)
|
|
20
41
|
- [截图](#screenshots)
|
|
21
42
|
- [安装 launcher](#install-the-launcher)
|
|
22
43
|
- [运行与更新](#run-and-update)
|
|
@@ -33,9 +54,9 @@ kind: "package-group"
|
|
|
33
54
|
<a id="screenshots"></a>
|
|
34
55
|
## 截图
|
|
35
56
|
|
|
36
|
-
|
|
57
|
+
交互式设置面板(`/settings`):
|
|
37
58
|
|
|
38
|
-

|
|
39
60
|
|
|
40
61
|
发送 `你好` 后:
|
|
41
62
|
|
|
@@ -51,7 +72,7 @@ kind: "package-group"
|
|
|
51
72
|
`dsh-tui` 支持两种运行模式:
|
|
52
73
|
|
|
53
74
|
### 模式 A:轻量模式(推荐,零 Clone 秒开)
|
|
54
|
-
|
|
75
|
+
全局安装官方引擎与 TUI launcher:
|
|
55
76
|
|
|
56
77
|
```text
|
|
57
78
|
npm install --global @deepseek-ai/dsh
|
|
@@ -60,7 +81,18 @@ dsh-tui probe
|
|
|
60
81
|
dsh-tui
|
|
61
82
|
```
|
|
62
83
|
|
|
63
|
-
|
|
84
|
+
首次启动会执行 `dsh plugin --profile deepseek-tui add <包目录>`,把本包链接进 `deepseek-tui` profile,排在 `@deepseek-ai/dsh-base` 之后;之后的启动检测到已安装,直接执行 `dsh --profile deepseek-tui`。不使用 launcher 时,也可以手动执行同样的两条 dsh 命令:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
dsh plugin --profile deepseek-tui add @crazyhappyone/dsh-tui@next
|
|
88
|
+
dsh --profile deepseek-tui
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
在 dsh 0.2 中以 bundle 方式安装是必需的:`/settings` 的修改写入 profile 自己的 patch 层,该层在 bundle 层之后生效;而 `--patch` overlay 位于 profile 层之后,dsh 会拒绝对此类 overlay 所拥有的行写入设置。
|
|
92
|
+
|
|
93
|
+
探测顺序为绝对路径 `DSH_BIN`、PATH、npm/pnpm 全局包、工作目录和 launcher 目录可解析的本地包;每个探测子进程限时十秒,以覆盖冷启动。显式 `DSH_BIN` 失败时不会选择其他安装。包内 bin 使用 launcher 的 Node 执行。
|
|
94
|
+
|
|
95
|
+
本 bundle 面向 dsh `0.2` 发布线(基于 `0.2.1-rc.2` 构建,并在 `0.2.1-alpha.2` 上验证)。包把 `@deepseek-ai/dsh` `>=0.2.0-rc.2 <0.3.0` 声明为可选 peer,因此手动安装时由 dsh 自身的插件兼容性检查把关;launcher 会拒绝其他引擎发布线并给出确切的安装命令,设置 `DSH_TUI_SKIP_ENGINE_CHECK=1` 可跳过 launcher 的检查。
|
|
64
96
|
|
|
65
97
|
### 模式 B:源码模式(开发者调试)
|
|
66
98
|
若需对 TUI 或 DSH 底层代码进行修改与调试:
|
|
@@ -110,13 +142,13 @@ dsh-tui update
|
|
|
110
142
|
<a id="configure-the-source-runtime"></a>
|
|
111
143
|
## 配置源码运行时
|
|
112
144
|
|
|
113
|
-
|
|
145
|
+
默认使用官方公开仓库的 `dsh-v0.2.1-rc.2` tag。源码模式会将本插件链接到现有 `deepseek-tui` profile,保留用户 patch;缺少 Typert 运行时产物时先调用上游生成器。随后通过 `pnpm exec node` 启动源码 CLI,不运行每次都会安装整个工作区的 `predsh` 钩子。
|
|
114
146
|
|
|
115
147
|
| 环境变量 | 默认值 | 用途 |
|
|
116
148
|
|---|---|---|
|
|
117
149
|
| `DSH_TUI_RUNTIME_DIR` | `~/.local/share/dsh-tui/runtime` | 仅供 launcher 使用的专用 clone |
|
|
118
|
-
| `DSH_TUI_SOURCE_URL` | `https://github.com/
|
|
119
|
-
| `DSH_TUI_SOURCE_REF` | `
|
|
150
|
+
| `DSH_TUI_SOURCE_URL` | `https://github.com/deepseek-ai/deepseek-harness.git` | `update` clone 和 fetch 的 Git remote |
|
|
151
|
+
| `DSH_TUI_SOURCE_REF` | `dsh-v0.2.1-rc.2` | `update` fetch 的 branch 或 ref |
|
|
120
152
|
| `DSH_TUI_PNPM` | `pnpm` | 安装和启动所用的 pnpm executable |
|
|
121
153
|
|
|
122
154
|
所有值都不得为空,运行时目录必须是绝对路径。Launcher 会拒绝 symbolic-link runtime path,也会拒绝不是 Git checkout 的现有目录。Child command 接收参数数组,不使用 shell interpolation。
|
|
@@ -128,15 +160,68 @@ dsh-tui update
|
|
|
128
160
|
<a id="relationship-to-dsh"></a>
|
|
129
161
|
## 与 DSH 的关系
|
|
130
162
|
|
|
131
|
-
TUI 是
|
|
163
|
+
TUI 是 dsh 插件 bundle,不是 fork,也不是独立的 agent 运行时:
|
|
132
164
|
|
|
133
165
|
```text
|
|
134
|
-
@deepseek-ai/dsh-base
|
|
135
|
-
└─ @
|
|
136
|
-
|
|
166
|
+
@deepseek-ai/dsh-base dsh 核心 bundle(agent、会话、工具)
|
|
167
|
+
└─ @crazyhappyone/dsh-tui 本 bundle:cordis.patch.yml + dist/*
|
|
168
|
+
├─ tui-startup (./startup) 命令行 provider(任务、--resume、--cwd)
|
|
169
|
+
├─ tui (./settings) /settings 中可编辑的 TUI 偏好(volatile)
|
|
170
|
+
├─ tui-runtime (./runtime) 终端生命周期与控制器
|
|
171
|
+
├─ schedule (./schedule) 官方定时服务与共享会话激活
|
|
172
|
+
└─ zen-proxy (./zen-proxy) 可选的 OpenCode Zen 请求头代理
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
各行通过包的 `exports` 引用插件,因此设置修改会在 profile patch 中记录可移植的行名。本 bundle 还插入已发布的 dsh 插件 `session-stats`、`message-feedback`、`tool-ask-user`、`workspace-changes`、`tool-schedule`、`time-context`、`tool-present`,以及用于账号登录回调的回环 `webserver`,并覆盖 `system-prompt`、`tools`、`session-query-sqlite` 与 `session-title-llm`。
|
|
176
|
+
|
|
177
|
+
### 定时提醒与用户提问
|
|
178
|
+
|
|
179
|
+
模型可使用官方 `schedule_create`、`schedule_list`、`schedule_update`、`schedule_delete` 工具。`/schedules` 跨会话列出提醒:↑↓ 或 PgUp/PgDn 选择、Enter 查看完整提示词、再次 Enter 打开所属会话、`r` 刷新、`d` 请求取消确认(`y` 确认,`n` 或 Esc 保留)。切换到其他会话后,投递仍恢复原会话。任务跨重启持久化;计时器仅在当前进程运行时工作,关闭期间到期的任务在下次启动时处理。投递回执表示已持久写入 inbox,不表示模型已完成回答。适配层打包固定 DSH 构建版本的官方定时服务和会话激活助手;升级上游后需重跑集成检查。
|
|
180
|
+
|
|
181
|
+
用户提问支持整批逐题作答、多选和自定义文本。Space 切换多选项;`c` 打开自定义编辑器;Enter 保存文本、提交选项。无选项的问题直接进入编辑器。Tab 打开完整问题与回答供滚动阅读,Tab 或 Esc 返回编辑。编辑器内 Esc 丢弃本次编辑(纯文本问题则取消提问);选项页 Esc 取消整次请求。粘贴的多行回答保留原文,不改变聊天草稿。
|
|
182
|
+
|
|
183
|
+
凭据编辑器及 `/key`、`/login` 的密钥参数显示圆点遮罩,凭据引用名保持可见。遮罩只影响显示:编辑和提交保留原值,取消后恢复聊天草稿。
|
|
184
|
+
|
|
185
|
+
### 时间上下文、交付文件与图片粘贴
|
|
186
|
+
|
|
187
|
+
官方 `time-context` 插件在准备模型步骤时提供当前时间和进程所在时区,十分钟后刷新。这类模型上下文不会增加人类对话中的消息行。
|
|
188
|
+
|
|
189
|
+
模型可用官方 `present` 工具显式交付现有文件,每次最多八个。`/deliveries` 列出当前会话已记录的交付文件:↑↓ 选择、Enter 预览 UTF-8 文本、`o` 请求本机系统应用打开所选文件、Esc 返回。PDF、Office、图片等二进制格式显示文件信息,并通过系统应用查看。文本读取默认限制为 1 MiB。已完成回合也会显示交付路径与说明;记录可随会话恢复,但文件必须仍存在且可访问。
|
|
190
|
+
|
|
191
|
+
剪贴板图片粘贴在 macOS 使用 `pngpaste -`([安装:`brew install pngpaste`](https://github.com/jcsalterego/pngpaste)),Wayland 使用 `wl-paste`,X11 使用 `xclip`。缺少助手时显示明确错误;读取默认五秒超时,关闭 TUI 时取消,并保留既有图片大小限制与校验。macOS 命令和子进程行为已在 Linux 上自动验证,macOS 实机验证仍待完成。
|
|
192
|
+
|
|
193
|
+
### DeepSeek 账号、模型与工作目录
|
|
194
|
+
|
|
195
|
+
- 当 dsh 挂载 `deepseek-account` 服务时,`/login` 打开 DeepSeek 账号页:Enter 发起浏览器登录,`o` 重新打开授权链接,`c` 取消;登录后页面显示账号资料与余额。浏览器回调到本 bundle 的 `webserver` 行,监听 `127.0.0.1` 上由系统分配的端口。通过 SSH 使用时,页面显示 `ssh -L` 端口转发命令而不打开浏览器;在 `webserver` 行固定 `port` 可让转发保持稳定。关闭重开页面会继续已有登录并恢复转发提示;按 `o` 才显式打开链接。未挂载账号服务时,`/login` 与 `/key` 打开 API 密钥编辑器。
|
|
196
|
+
- `/logout` 确认后退出登录,已保存的 API 密钥保留。
|
|
197
|
+
- `/model` 在 `deepseek-account` 与 `deepseek-official` 目录为空时列出它们,并注明使模型可用的步骤(`/login` 或 `/key`),且拒绝选中此类行。
|
|
198
|
+
- `/cd [路径]` 在 dsh 0.2.1 及以后版本查看或切换会话工作目录。顶栏、`@` 提及与 `/files` 随之切换,文件面板输入的相对路径也以当前会话目录为基准;模型会收到变更通知;已有 shell 保留各自的目录。
|
|
199
|
+
- `/plugins` 将官方 bundle 单独分组。文件尚未安装的官方目录条目标记为可安装,按 Space 打开其精确安装目标的安装预览。
|
|
200
|
+
|
|
201
|
+
### OpenCode Zen 免费模型
|
|
202
|
+
|
|
203
|
+
打包后的 patch 挂载了 `zen-proxy`(vendored 自
|
|
204
|
+
[zhangyang-crazy-one/dsh-zen-proxy](https://github.com/zhangyang-crazy-one/dsh-zen-proxy),
|
|
205
|
+
fork 自 [Yee-h/dsh-zen-proxy](https://github.com/Yee-h/dsh-zen-proxy)):进程内 localhost
|
|
206
|
+
代理,注入 Zen 要求的 OpenCode 官方客户端头(`User-Agent`、
|
|
207
|
+
`x-opencode-client/session/request/project`)。没有它,Zen 会返回
|
|
208
|
+
`400 MissingSessionID` / `429 FreeUsageLimitError`,因为 dsh 始终发送自己的
|
|
209
|
+
attribution `User-Agent`。
|
|
210
|
+
|
|
211
|
+
使用方法:通过 TUI `/settings` provider 表单(或 profile 的 `cordis.patch.yml`)
|
|
212
|
+
添加一个指向该代理的 provider,并把密钥放在 credentials 中:
|
|
213
|
+
|
|
214
|
+
```yaml
|
|
215
|
+
- id: llm-pi-ai
|
|
216
|
+
config:
|
|
217
|
+
providers:
|
|
218
|
+
opencode:
|
|
219
|
+
api: openai-completions
|
|
220
|
+
baseURL: http://127.0.0.1:4097/v1
|
|
221
|
+
apiKeyEnv: OPENCODE_API_KEY
|
|
137
222
|
```
|
|
138
223
|
|
|
139
|
-
|
|
224
|
+
代理只监听 `127.0.0.1:4097`;在 profile 的 `cordis.patch.yml` 中加入 `- id: zen-proxy` 并设置 `disabled: true` 即可关闭。
|
|
140
225
|
|
|
141
226
|
-----
|
|
142
227
|
|
|
@@ -145,7 +230,8 @@ TUI 是 DSH profile 层,而不是独立的 agent 运行时:
|
|
|
145
230
|
|
|
146
231
|
| 包 | DSH 形态 | 职责 |
|
|
147
232
|
|---|---|---|
|
|
148
|
-
| [`tui/`](tui/README.zh.md) |
|
|
233
|
+
| [`tui/`](tui/README.zh.md) | 运行时、启动与设置插件 | 在 `dsh-base` 上组合终端层、拥有 live 终端会话,并将用户动作映射到 DSH 服务 |
|
|
234
|
+
| [`plugins/zen-proxy/`](https://github.com/zhangyang-crazy-one/dsh-zen-proxy) | Vendored 插件(打包为 `dist/zen-proxy.js`) | 进程内 OpenAI 兼容代理,注入 OpenCode Zen 客户端头;在 `cordis.patch.yml` 中挂载 |
|
|
149
235
|
| [`tui-render/`](tui-render/README.zh.md) | Library | 通过 Ink 投影控制器状态,但不拥有 agent、持久化或模型请求 |
|
|
150
236
|
|
|
151
237
|
-----
|
|
@@ -153,9 +239,20 @@ TUI 是 DSH profile 层,而不是独立的 agent 运行时:
|
|
|
153
239
|
<a id="development-workflow"></a>
|
|
154
240
|
## 开发工作流
|
|
155
241
|
|
|
156
|
-
|
|
242
|
+
`tui/` 与 `tui-render/` 基于上游 dsh checkout 编译,版本为 `src/launcher.js` 中 `COMPATIBLE_DSH_VERSION` 指定的 tag:
|
|
157
243
|
|
|
158
|
-
|
|
244
|
+
```text
|
|
245
|
+
git clone --branch dsh-v0.2.1-rc.2 https://github.com/deepseek-ai/deepseek-harness ../deepseek-harness
|
|
246
|
+
(cd ../deepseek-harness && pnpm install)
|
|
247
|
+
npm run build # 或 DSH_SOURCE=/path/to/checkout npm run build
|
|
248
|
+
(cd ../deepseek-harness && pnpm install) # 链接挂载后的插件开发依赖
|
|
249
|
+
npm run dev:setup # 同样支持 DSH_SOURCE;生成类型声明并链接编辑器依赖
|
|
250
|
+
npm run typecheck # 严格检查源码和测试
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
`npm run build` 把插件包与 `cordis.patch.yml` 复制进 checkout 的 `packages/tui/` workspace,用 esbuild 打包 `dist/index.js`、`dist/startup.js`、`dist/settings.js`、`dist/schedule.js` 与 `dist/zen-proxy.js`,并逐个检查导入。插件测试在 checkout 中运行 `npx vitest run packages/tui`,launcher 测试在本仓库运行 `npm test`;发布前运行 `npm run pack:check`。通过 packed tarball 或 `dsh plugin --profile <name> add <本目录>` 测试安装。
|
|
254
|
+
|
|
255
|
+
本地 `tsconfig.json` 用于独立插件仓库的编辑器检查;构建时使用 `tsconfig.workspace.json` 作为 checkout 中的包配置,保留上游项目引用。`dev:setup` 构建依赖类型声明并链接整个 `node_modules` 目录,保留 pnpm 的相对链接。更新上游或公开类型后重新执行 build 和 setup;编辑器若仍显示旧的缺失模块错误,需要重载 TypeScript 项目。
|
|
159
256
|
|
|
160
257
|
-----
|
|
161
258
|
|
|
@@ -178,21 +275,42 @@ npx --yes npm@11 trust github @crazyhappyone/dsh-tui \
|
|
|
178
275
|
每次发布时,先提升 `package.json` 版本,等待 CI 通过并合并,然后创建 tag 与 package version 一致的 GitHub Release:
|
|
179
276
|
|
|
180
277
|
```text
|
|
181
|
-
gh release create v0.1.0-alpha.
|
|
278
|
+
gh release create v0.1.0-alpha.50 --prerelease --notes-file docs/releases/v0.1.0-alpha.50.md
|
|
182
279
|
```
|
|
183
280
|
|
|
184
281
|
`Publish npm` workflow 会在发布前再次运行测试与 packed-package 验证。不要重新运行旧的 release tag:npm version 不可覆盖。提升到 stable 必须使用新版本并发布 non-prerelease GitHub Release。
|
|
185
282
|
|
|
186
283
|
-----
|
|
187
284
|
|
|
285
|
+
## 终端能力
|
|
286
|
+
|
|
287
|
+
`/timeline` 浏览逐条 Session 事件、真实工具/token/时长与完整 JSON;`/attachments` 列出类型化图片/文件引用并打开本地副本;`/review` 读取逐文件官方 diff。`/files` 对已展开目录合并自动刷新,并保留手工 `r` 刷新。
|
|
288
|
+
|
|
289
|
+
`/settings` 使用 Tab/Shift+Tab 切换分组,持久化 `tui.theme=dark|light`。`/keys` 列出各场景按键;`/bind ACTION Ctrl+X`、`/bind ACTION default`、`/unbind ACTION` 修改输入区快捷键并检查冲突。Shift+方向键/Home/End 按字素选择,输入/粘贴替换选区,Ctrl+Y 复制普通选区;凭据选区禁止复制。审批、提问及计划评审中可用 Alt+H 打开只读帮助。
|
|
290
|
+
|
|
291
|
+
`/agents` 支持 `c` 续聊(Enter 排队、Ctrl+Enter 引导)、`s` 请求停止、`v` 在 100 列以上并排查看。窄终端保留单面板。人工控制保留目录给出的准确直接父会话地址;Stop 回执不表示执行已经停止。
|
|
292
|
+
|
|
293
|
+
`/preset` 浏览 standard/PTC/minimal/cordis 声明,`/preset ID` 在首轮前选择隔离组合;开始对话后保持锁定。`/market QUERY` 检索已配置索引,`i` 进入插件管理器预览及确认,`n/p` 翻页。`/inspect` 浏览官方 Host provider,`/inspect host PROVIDER METHOD JSON` 查询具体契约。`/focus` 隐藏中间工具卡片,不修改模型工具或会话日志。外部语言包可调用 `registerTuiLocale`;围栏代码采用有界的按语言词法高亮。
|
|
294
|
+
|
|
295
|
+
Goal 页脚区分自动续跑和需要 `/goal resume` 恢复的停止状态。后台开启的回合会更新运行状态及 Ctrl+C 取消路径。更新正在运行的源码安装后使用 `/reload`;恢复的 Goal 需显式 `/goal resume` 重新授权续跑。
|
|
296
|
+
|
|
297
|
+
验证及平台边界见 [P1/P2 验收记录](docs/p1-p2-verification-2026-10-20.md)。
|
|
298
|
+
|
|
299
|
+
-----
|
|
300
|
+
|
|
188
301
|
<a id="known-limitations"></a>
|
|
189
302
|
## 已知限制
|
|
190
303
|
|
|
191
|
-
-
|
|
304
|
+
- **第三方插件需匹配引擎版本** — 旧认证插件如果只声明兼容 dsh 0.1.x,会被 dsh 0.2 拒绝加载;launcher 不自动授予版本豁免。
|
|
192
305
|
- **需要源码工具链** — 初始化运行时需要 Git、pnpm 与 DSH 支持的 Node 版本。
|
|
193
306
|
- **不自动解决冲突** — dirty 或 non-fast-forward runtime history 需要显式人工操作或新的运行时目录。
|
|
194
307
|
- **运行时更新不是 launcher 更新** — `dsh-tui update` 刷新 DSH 源码与依赖;npm 更新 launcher package。
|
|
195
308
|
- **集成分支拥有发布就绪状态** — launcher 成功不能替代 DSH 分支的行为、snapshot、build 或 hygiene 检查。
|
|
309
|
+
- **源码模式也使用本插件** — 配置的 checkout 必须与本 bundle 的 dsh 版本兼容。历史 profile 中的 `@deepseek-ai/dsh-tui` 旧 bundle 应替换为 `@crazyhappyone/dsh-tui`;迁移前备份 profile,并保留用户设置。
|
|
310
|
+
- **提醒需要进程运行** — `/schedules` 使用官方服务及持久化原会话;重启可恢复待投递提醒,关闭进程期间不运行计时器。
|
|
311
|
+
- **终端能力边界** — 图片及 PDF/Office 文档使用元数据/文本或系统打开。Ink 没有 IME composition 事件,预编辑由终端原生处理。`INK_SCREEN_READER=true` 使用普通输出流,关闭鼠标捕获、备用屏幕及动画;真实 IME/屏幕阅读器设备和 macOS 剪贴板尚未验证。
|
|
312
|
+
- **账号登录需要可访问的 Platform** — 主机无法访问 `platform.deepseek.com` 时登录报告 `no-response`(服务无响应),此时请使用 `/key`。
|
|
313
|
+
- **dsh 0.2 不支持物理删除会话** — 0.2 的会话持久化以归档代替删除,而 TUI 组合未挂载 workspace 归档服务,因此会话列表会提示无法删除。
|
|
196
314
|
|
|
197
315
|
<a id="dev-note"></a>
|
|
198
316
|
## 开发备注
|
|
Binary file
|
|
Binary file
|
package/bin/dsh-tui.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/** Command-line entry for the dsh-tui source-runtime launcher. */
|
|
3
3
|
|
|
4
|
-
import { lstatSync, mkdirSync, readFileSync
|
|
4
|
+
import { lstatSync, mkdirSync, readFileSync } from 'node:fs'
|
|
5
5
|
import { constants, homedir } from 'node:os'
|
|
6
6
|
import { fileURLToPath } from 'node:url'
|
|
7
7
|
import { spawnSync } from 'node:child_process'
|
|
8
|
+
import { createRequire } from 'node:module'
|
|
9
|
+
import { join } from 'node:path'
|
|
8
10
|
import { parseLauncherInvocation, resolveLauncherSettings, runLauncher } from '../src/launcher.js'
|
|
9
11
|
|
|
10
12
|
function inspectPath(path) {
|
|
@@ -28,7 +30,11 @@ function run(command, args, options = {}) {
|
|
|
28
30
|
env: process.env,
|
|
29
31
|
maxBuffer: capture ? 16 * 1024 * 1024 : undefined,
|
|
30
32
|
shell: false,
|
|
31
|
-
|
|
33
|
+
timeout: options.timeoutMs,
|
|
34
|
+
killSignal: 'SIGKILL',
|
|
35
|
+
stdio: options.stdio === 'inherit' ? 'inherit'
|
|
36
|
+
: options.stdio === 'output' ? ['ignore', 'inherit', 'inherit']
|
|
37
|
+
: capture ? ['ignore', 'pipe', 'pipe'] : 'inherit',
|
|
32
38
|
})
|
|
33
39
|
if (result.error !== undefined) {
|
|
34
40
|
return { status: 1, stdout: '', stderr: result.error.message }
|
|
@@ -61,10 +67,19 @@ try {
|
|
|
61
67
|
packageVersion: manifest.version,
|
|
62
68
|
env: process.env,
|
|
63
69
|
adapters: {
|
|
70
|
+
nodeExecutable: process.execPath,
|
|
71
|
+
currentDirectory: process.cwd(),
|
|
72
|
+
resolveDshPackage(directory) {
|
|
73
|
+
try {
|
|
74
|
+
return createRequire(join(directory, 'package.json')).resolve('@deepseek-ai/dsh/package.json')
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (error.code === 'MODULE_NOT_FOUND') return undefined
|
|
77
|
+
throw error
|
|
78
|
+
}
|
|
79
|
+
},
|
|
64
80
|
inspectPath,
|
|
65
81
|
makeDirectory: path => mkdirSync(path, { recursive: true, mode: 0o700 }),
|
|
66
82
|
readText: path => readFileSync(path, 'utf8'),
|
|
67
|
-
writeText: (path, content) => writeFileSync(path, content, 'utf8'),
|
|
68
83
|
run,
|
|
69
84
|
writeOut: text => process.stdout.write(text),
|
|
70
85
|
writeError: text => process.stderr.write(text),
|
package/cordis.patch.yml
CHANGED
|
@@ -1,30 +1,35 @@
|
|
|
1
|
-
#
|
|
1
|
+
# yaml-language-server: $schema=none
|
|
2
|
+
# The dsh-tui bundle layer: a terminal surface over @deepseek-ai/dsh-base.
|
|
2
3
|
# It mounts no Host, HTTP server, Web runtime, or browser plugin. An ordinary
|
|
3
|
-
# provider plugin parses --resume/--cwd and the task positional
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
4
|
+
# provider plugin parses --resume/--cwd and the task positional; the terminal
|
|
5
|
+
# driver then creates an Agent through the core registry. The UI displays one
|
|
6
|
+
# Session; scheduled reminders can activate other Sessions in the same process.
|
|
7
|
+
#
|
|
8
|
+
# Install it as a bundle so user settings (written to the profile layer)
|
|
9
|
+
# apply after this layer:
|
|
10
|
+
# dsh plugin --profile tui add @crazyhappyone/dsh-tui
|
|
11
|
+
# dsh --profile tui
|
|
12
|
+
# Rows target the dsh 0.2 Loader and name plugins through this package's
|
|
13
|
+
# exports, so profile-layer edits record a portable row name.
|
|
8
14
|
|
|
15
|
+
# The working directory reaches the model through the runtime-context
|
|
16
|
+
# message; dsh 0.2.1 registers no cwd prompt variable.
|
|
9
17
|
- id: system-prompt
|
|
10
18
|
config:
|
|
11
|
-
|
|
12
|
-
You are a coding agent powered by the {{model}} model.
|
|
13
|
-
You are interacting with the user through the
|
|
19
|
+
personaPrefix: >-
|
|
20
|
+
You are a coding agent powered by the {{model}} model.
|
|
21
|
+
You are interacting with the user through the dsh-tui
|
|
22
|
+
terminal interface.
|
|
14
23
|
|
|
15
|
-
#
|
|
16
|
-
#
|
|
24
|
+
# HMR stays disabled. Profile and home patch edits apply on the next
|
|
25
|
+
# process start; /reload restarts the terminal with the current session.
|
|
17
26
|
- id: hmr
|
|
18
27
|
disabled: true
|
|
19
28
|
|
|
20
29
|
- id: tools
|
|
21
30
|
config:
|
|
22
31
|
# Keep the same temporary process-wide Code Mode opt-in as the Web surface.
|
|
23
|
-
mode:
|
|
24
|
-
|
|
25
|
-
- id: approval
|
|
26
|
-
config:
|
|
27
|
-
policy: !!js "(process.env.DSH_PERMISSION_MODE ?? 'workspace-write') === 'danger-full-access' ? 'never' : 'ask'"
|
|
32
|
+
mode: native
|
|
28
33
|
|
|
29
34
|
# Full-text session search stays disabled until the first Ctrl+K search (the
|
|
30
35
|
# base row's `openAt: never`). The TUI has no browser-latency concern, so the
|
|
@@ -34,23 +39,107 @@
|
|
|
34
39
|
path: ':memory:'
|
|
35
40
|
openAt: first-search
|
|
36
41
|
|
|
42
|
+
# The first-prompt title gets the whole first prompt, not the base 4 KiB.
|
|
43
|
+
- id: session-title-llm
|
|
44
|
+
config:
|
|
45
|
+
targetWords: 5
|
|
46
|
+
targetCjkCharacters: 10
|
|
47
|
+
maxInputBytes: 16384
|
|
48
|
+
maxOutputTokens: 64
|
|
49
|
+
timeoutMs: 60000
|
|
50
|
+
|
|
37
51
|
- insert:
|
|
52
|
+
# Official task storage/runtime over the terminal's shared cold-Session
|
|
53
|
+
# activation owner. No browser Session API or upload transport is mounted.
|
|
54
|
+
- id: schedule
|
|
55
|
+
name: '@crazyhappyone/dsh-tui/schedule'
|
|
56
|
+
|
|
57
|
+
- id: tool-schedule
|
|
58
|
+
name: '@deepseek-ai/dsh-tool-schedule'
|
|
59
|
+
|
|
60
|
+
# Durable current-time context uses the process time zone and refreshes
|
|
61
|
+
# at most once per ten minutes, matching the official provider defaults.
|
|
62
|
+
- id: time-context
|
|
63
|
+
name: '@deepseek-ai/dsh-time-context'
|
|
64
|
+
config:
|
|
65
|
+
refreshIntervalMs: 600000
|
|
66
|
+
|
|
67
|
+
# Explicit file deliveries stay in the owning Session log.
|
|
68
|
+
- id: tool-present
|
|
69
|
+
name: '@deepseek-ai/dsh-tool-present'
|
|
70
|
+
config:
|
|
71
|
+
maxFiles: 8
|
|
72
|
+
|
|
73
|
+
# Per-round token/duration stats for the terminal status line.
|
|
74
|
+
- id: session-stats
|
|
75
|
+
name: "@deepseek-ai/dsh-session-stats"
|
|
76
|
+
|
|
77
|
+
# Base owns the shared storage/domain/projection-cache stack. This layer
|
|
78
|
+
# contributes only the TUI-facing feedback consumer over that stack.
|
|
79
|
+
- id: message-feedback
|
|
80
|
+
name: "@deepseek-ai/dsh-message-feedback"
|
|
81
|
+
config:
|
|
82
|
+
maxNoteBytes: 8192
|
|
83
|
+
|
|
84
|
+
- id: tool-ask-user
|
|
85
|
+
name: "@deepseek-ai/dsh-tool-ask-user"
|
|
86
|
+
|
|
38
87
|
- id: tui-startup
|
|
39
|
-
name: "
|
|
88
|
+
name: "@crazyhappyone/dsh-tui/startup"
|
|
89
|
+
|
|
90
|
+
# TUI presentation preferences (locale, Enter behavior, notifications,
|
|
91
|
+
# scrollbar, thinking visibility). Every field is volatile, so /settings
|
|
92
|
+
# edits land in the profile layer and apply without a remount.
|
|
93
|
+
- id: tui
|
|
94
|
+
name: "@crazyhappyone/dsh-tui/settings"
|
|
95
|
+
|
|
96
|
+
# In-process OpenCode Zen header proxy (vendored from
|
|
97
|
+
# zhangyang-crazy-one/dsh-zen-proxy, MIT). Listens on localhost
|
|
98
|
+
# only; point an opencode provider baseURL at
|
|
99
|
+
# http://127.0.0.1:4097/v1 to reach the Zen free tier.
|
|
100
|
+
# Remove this row to disable the listener.
|
|
101
|
+
- id: zen-proxy
|
|
102
|
+
name: "@crazyhappyone/dsh-tui/zen-proxy"
|
|
103
|
+
config:
|
|
104
|
+
host: 127.0.0.1
|
|
105
|
+
port: 4097
|
|
106
|
+
|
|
107
|
+
# Loopback route carrier for the DeepSeek account browser callback
|
|
108
|
+
# (/login). Port 0 takes a free port from the OS; pin a port here when
|
|
109
|
+
# an SSH session forwards it. Only routes registered by mounted plugins
|
|
110
|
+
# are served, and the address must stay a loopback literal.
|
|
111
|
+
- id: webserver
|
|
112
|
+
name: '@deepseek-ai/dsh-host-webserver'
|
|
113
|
+
config:
|
|
114
|
+
host: 127.0.0.1
|
|
115
|
+
port: 0
|
|
116
|
+
|
|
117
|
+
# Records each top-level turn's changed files from git working-tree
|
|
118
|
+
# snapshots; the TUI projects a bounded transcript card from Host
|
|
119
|
+
# summaries. Bounds match the plugin Config defaults.
|
|
120
|
+
- id: workspace-changes
|
|
121
|
+
name: '@deepseek-ai/dsh-workspace-changes'
|
|
122
|
+
config:
|
|
123
|
+
timeoutMs: 30000
|
|
124
|
+
outputMaxBytes: 8388608
|
|
125
|
+
maxFiles: 500
|
|
126
|
+
maxFileBytes: 2097152
|
|
127
|
+
diffTimeoutMs: 100
|
|
40
128
|
|
|
41
129
|
# Reads its task from the ordinary tuiStartup provider.
|
|
42
130
|
- id: tui-runtime
|
|
43
|
-
name: "
|
|
131
|
+
name: "@crazyhappyone/dsh-tui/runtime"
|
|
44
132
|
inject: [tuiStartup]
|
|
45
133
|
config:
|
|
46
134
|
task: !!js ctx.tuiStartup.task
|
|
47
135
|
resume: !!js ctx.tuiStartup.resume
|
|
48
136
|
cwd: !!js ctx.tuiStartup.cwd
|
|
137
|
+
model: !!js ctx.tuiStartup.model
|
|
49
138
|
frameStats: !!js ctx.tuiStartup.frameStats
|
|
50
|
-
# Render policy (overscan
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
#
|
|
139
|
+
# Render policy (overscan, stream pacing, scroll pacing, cache).
|
|
140
|
+
# The values mirror the runtime Config schema defaults so the
|
|
141
|
+
# deployment layer owns the tunables; override in the profile patch
|
|
142
|
+
# to retune without touching the plugin.
|
|
54
143
|
renderPolicy:
|
|
55
144
|
transcriptOverscan: 16
|
|
56
145
|
stream:
|
|
@@ -71,3 +160,8 @@
|
|
|
71
160
|
cache:
|
|
72
161
|
maxRows: 4096
|
|
73
162
|
maxBytes: 4194304
|
|
163
|
+
|
|
164
|
+
# Terminal marketplace catalog uses the Host service; installs retain plugin-manager approval.
|
|
165
|
+
- insert:
|
|
166
|
+
- id: plugin-market
|
|
167
|
+
name: "@deepseek-ai/dsh-plugin-market"
|