dsh-code 1.0.6 → 1.0.7
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 +60 -9
- package/README.md +60 -9
- package/bin/deepseek.mjs +86 -1
- package/cordis.patch.yml +88 -0
- package/lib/index.mjs +1002 -94
- package/lib/session-query.mjs +149 -0
- package/lib/types/app.d.ts +9 -2
- package/lib/types/index.d.ts +27 -0
- package/lib/types/kernel-panels.d.ts +23 -0
- package/lib/types/render/editor.d.ts +4 -3
- package/lib/types/render/ime-cursor.d.ts +60 -0
- package/lib/types/render/projection.d.ts +35 -0
- package/lib/types/render/status.d.ts +1 -1
- package/lib/types/session-query.d.ts +92 -0
- package/lib/types/terminal-title.d.ts +58 -0
- package/lib/types/update-panel.d.ts +49 -0
- package/lib/types/update.d.ts +66 -0
- package/package.json +228 -89
- package/src/app.ts +252 -69
- package/src/index.ts +129 -11
- package/src/internals.ts +5 -0
- package/src/kernel-panels.ts +89 -3
- package/src/render/editor.ts +5 -4
- package/src/render/ime-cursor.ts +147 -0
- package/src/render/projection.ts +144 -3
- package/src/render/status.ts +18 -4
- package/src/session-query.ts +235 -0
- package/src/terminal-title.ts +173 -0
- package/src/update-panel.ts +246 -0
- package/src/update.ts +110 -0
package/README.en.md
CHANGED
|
@@ -23,21 +23,21 @@ DeepSeek Harness registers models, tools, storage, policies, and interfaces as p
|
|
|
23
23
|
|
|
24
24
|
## 2. Quick start
|
|
25
25
|
|
|
26
|
-
Requires Node `^22.19 || >=24` and the preview `dsh` CLI (current release line: `@deepseek-ai/dsh@0.1.5-rc.
|
|
26
|
+
Requires Node `^22.19 || >=24` and the preview `dsh` CLI (current release line: `@deepseek-ai/dsh@0.1.5-rc.2`). You can still enter the TUI, browse sessions, and use non-model features without configuring a model; press `Tab` in `/model` to manage API keys, OAuth, device-code sign-in, endpoints, and models.
|
|
27
27
|
|
|
28
28
|
### 1. Install and update
|
|
29
29
|
|
|
30
30
|
Use the same commands for the initial installation and subsequent updates:
|
|
31
31
|
|
|
32
32
|
```sh
|
|
33
|
-
npm install -g @deepseek-ai/dsh@0.1.5-rc.
|
|
33
|
+
npm install -g @deepseek-ai/dsh@0.1.5-rc.2 dsh-code@1.0.7
|
|
34
34
|
npm install -g pnpm
|
|
35
|
-
dsh plugin --profile cli add dsh-code@1.0.
|
|
35
|
+
dsh plugin --profile cli add dsh-code@1.0.7
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
> Note: pnpm ignores packages published less than 24 hours ago, so use the exact version `dsh-code@1.0.
|
|
38
|
+
> Note: pnpm ignores packages published less than 24 hours ago, so use the exact version `dsh-code@1.0.7` on release day; the version may be omitted after 24 hours. npm installation is not affected.
|
|
39
39
|
>
|
|
40
|
-
> Version alignment: dsh-code targets dsh `0.1.5-rc.
|
|
40
|
+
> Version alignment: dsh-code targets dsh `0.1.5-rc.2`, with every Harness dependency pinned exactly to `0.1.5-rc.2`. Keep the global dsh CLI and dsh-code aligned instead of mixing release candidates; the legacy `code` preset id maps to its renamed `ptc` automatically.
|
|
41
41
|
|
|
42
42
|
### 2. Launch commands
|
|
43
43
|
|
|
@@ -64,7 +64,7 @@ DSH-Code brings DSH Agents, models, tools, and durable sessions directly into th
|
|
|
64
64
|
- Create sessions with `/new`, or restore existing sessions with `/resume` and `--continue`
|
|
65
65
|
- Create a new work branch from a historical point with `/fork` while preserving the original session
|
|
66
66
|
- Search history by current directory, update time, and session scope
|
|
67
|
-
- Recall input history with Up/Down, or search previous prompts with `/history`
|
|
67
|
+
- Recall input history with Up/Down (typed slash commands included), or search previous prompts and commands with `/history`
|
|
68
68
|
- Use persistent titles, Markdown export, context occupancy, token, cache, TTFT, and elapsed-time metrics
|
|
69
69
|
- Restore the session's Agent Preset and model selection when resuming it
|
|
70
70
|
|
|
@@ -134,7 +134,7 @@ The following built-in commands are available inside the TUI. Additional Harness
|
|
|
134
134
|
| `/delete [id\|prefix]` | Delete a session and its subagent sessions |
|
|
135
135
|
| `/title <text>` | Change the current session title |
|
|
136
136
|
| `/export [path]` | Export the current session as Markdown |
|
|
137
|
-
| `/history` | Search and reuse previously submitted prompts |
|
|
137
|
+
| `/history` | Search and reuse previously submitted prompts and slash commands |
|
|
138
138
|
| `/clear` | Clear the current terminal display without deleting the durable session |
|
|
139
139
|
|
|
140
140
|
#### Agents, models, and permissions
|
|
@@ -156,6 +156,7 @@ The following built-in commands are available inside the TUI. Additional Harness
|
|
|
156
156
|
| `/todos` | View the complete todo list for the current session |
|
|
157
157
|
| `/agents` | View subagent sessions created by the current session |
|
|
158
158
|
| `/jobs` | View background jobs and their runtime status |
|
|
159
|
+
| `/schedule` | Inspect active reminders (created through the model's schedule tools; read-only, overdue first) |
|
|
159
160
|
| `/copy` | Copy the latest complete assistant response |
|
|
160
161
|
|
|
161
162
|
#### Extensions, display, and exit
|
|
@@ -163,6 +164,7 @@ The following built-in commands are available inside the TUI. Additional Harness
|
|
|
163
164
|
| Command | Purpose |
|
|
164
165
|
| --- | --- |
|
|
165
166
|
| `/plugin [query]` | Inspect loaded extensions and their status |
|
|
167
|
+
| `/update` | One aligned upgrade: pins the global Harness host to the line the target release declares in its peers, moves dsh-code, the host, and profile companion plugins together, shows the full plan and refusal reasons before confirming, and prompts a restart when done |
|
|
166
168
|
| `/statusline` | Select the items displayed in the status bar |
|
|
167
169
|
| `/vscode-keys` | Pass Ctrl+R through VS Code-family terminals (idempotent user-level keybindings.json write) |
|
|
168
170
|
| `/theme` | Switch the terminal color theme |
|
|
@@ -204,7 +206,56 @@ DSH-Code reads the live Harness registries instead of maintaining a separate loc
|
|
|
204
206
|
|
|
205
207
|
`/plugin` provides a read-only view of the current Cordis loader state.
|
|
206
208
|
|
|
207
|
-
### 2.
|
|
209
|
+
### 2. Bundled and optional official plugins
|
|
210
|
+
|
|
211
|
+
The following official plugins ship with DSH-Code and are enabled in the composition by default:
|
|
212
|
+
|
|
213
|
+
- **Session search**: the model gets five read-only tools — `session_search`, `session_event_search`, `session_trace`, `session_event_trace`, `session_event_read` — over prior session logs (the index builds lazily on the first search; cross-session access is scoped by exact working directory; on Node 22 the first search prints a one-time `node:sqlite` experimental warning, which is expected).
|
|
214
|
+
- **Reminders**: `schedule` provides durable, restart-surviving reminders (created through the `schedule_create` / `schedule_list` / `schedule_delete` tools); the `/schedule` panel shows them read-only with overdue rows first. `time-context` injects a clock reading for the model (throttled to 30s).
|
|
215
|
+
- **Clock for reminders**: `time-context` injects the current time for the model (throttled to 30s), so phrasings like "remind me at 5 pm" work.
|
|
216
|
+
|
|
217
|
+
The following official plugins are installed but opt-in (append rows in the user layer `~/.dsh/profiles/cli/cordis.patch.yml`, or install as noted):
|
|
218
|
+
|
|
219
|
+
- **MCP servers** (`@deepseek-ai/dsh-mcp-client`, one row per server; tools register as `mcp__<server>__<tool>`):
|
|
220
|
+
|
|
221
|
+
```yaml
|
|
222
|
+
- insert:
|
|
223
|
+
- id: mcp-memory
|
|
224
|
+
name: '@deepseek-ai/dsh-mcp-client'
|
|
225
|
+
config:
|
|
226
|
+
transport: stdio
|
|
227
|
+
serverName: memory
|
|
228
|
+
command: mcp-server-memory
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
(HTTP transports use `transport: streamable-http` plus `url`; an unreachable server degrades to a reconnect loop and never breaks startup.)
|
|
232
|
+
- **Claude Code / Codex hooks bridges** (`@deepseek-ai/dsh-hooks-claude-code` / `-codex`): run existing hooks configurations at the interception seams; a missing hooks file is a silent no-op:
|
|
233
|
+
|
|
234
|
+
```yaml
|
|
235
|
+
- insert:
|
|
236
|
+
- id: hooks-claude
|
|
237
|
+
name: '@deepseek-ai/dsh-hooks-claude-code'
|
|
238
|
+
config:
|
|
239
|
+
configPath: C:/Users/you/.claude/hooks.json
|
|
240
|
+
```
|
|
241
|
+
- **LSP navigation**: the composition carries `lsp` / `lsp-stdio` / `tool-lsp` rows in a disabled state — language-server binaries resolve at mount, and a missing binary would fail the whole composition boot. Flip the three rows to `disabled: false` in the user layer and configure `lsp-stdio` `servers` (extension to language to server command); the model then gets the `lsp` tool (goToDefinition / findReferences / goToImplementation / hover).
|
|
242
|
+
- **Persistent terminals**: the PTY service and platform backends (pwsh dialect on Windows, bash on POSIX) mount by default, but the six model tools `terminal_open` / `terminal_send` / `terminal_read` / `terminal_signal` / `terminal_close` / `terminal_list` ship DISABLED — enabling them grants shell capability to every session, which the preset layer is supposed to gate, so deployments opt in explicitly. Enable in the user layer:
|
|
243
|
+
```yaml
|
|
244
|
+
- id: tool-terminal
|
|
245
|
+
disabled: false
|
|
246
|
+
```
|
|
247
|
+
(Background sends appear in the /jobs panel.)
|
|
248
|
+
- **tmux pane context** (`@deepseek-ai/dsh-tmux-context`): injects the current tmux pane into the model context when running inside tmux (`config: { refreshIntervalMs: 60000 }`); outside tmux every step degrades to a harmless no-op:
|
|
249
|
+
```yaml
|
|
250
|
+
- insert:
|
|
251
|
+
- id: tmux-context
|
|
252
|
+
name: '@deepseek-ai/dsh-tmux-context'
|
|
253
|
+
config:
|
|
254
|
+
refreshIntervalMs: 60000
|
|
255
|
+
```
|
|
256
|
+
- **External CLI delegation**: `dsh plugin --profile cli add @deepseek-ai/dsh-subagent-claude-code` (or `-codex`) installs the dormant provider; following the upstream contract, copy the preset and enable the `tool-subagent-claude-code` / `tool-subagent-codex` row to let the model delegate tasks to the claude / codex CLIs.
|
|
257
|
+
|
|
258
|
+
### 3. Session-scoped Agent Presets
|
|
208
259
|
|
|
209
260
|
The Host owns the shared infrastructure—registries, persistence, session queries, permissions, and sandbox policies—while each session receives an isolated Agent scope composed by an **Agent Preset**:
|
|
210
261
|
|
|
@@ -216,7 +267,7 @@ The Host owns the shared infrastructure—registries, persistence, session queri
|
|
|
216
267
|
|
|
217
268
|
Use `/mode` before the first turn, or start directly with `--mode <preset>`. The selected Preset is written to the session and restored when the session resumes.
|
|
218
269
|
|
|
219
|
-
###
|
|
270
|
+
### 4. Session history and recovery
|
|
220
271
|
|
|
221
272
|
Prompts, streaming chunks, tool calls and results, model selections, plan state, permissions, titles, and Preset selections are all projected from durable Session events. Session recovery, export, history inspection, context metrics, and terminal replay use the same record.
|
|
222
273
|
|
package/README.md
CHANGED
|
@@ -25,21 +25,21 @@ DeepSeek Harness 将模型、工具、存储、策略和界面作为插件,通
|
|
|
25
25
|
|
|
26
26
|
## 二、快速开始
|
|
27
27
|
|
|
28
|
-
需要 Node `^22.19 || >=24` 和预览版 `dsh` CLI(当前版本线:`@deepseek-ai/dsh@0.1.5-rc.
|
|
28
|
+
需要 Node `^22.19 || >=24` 和预览版 `dsh` CLI(当前版本线:`@deepseek-ai/dsh@0.1.5-rc.2`)。未配置模型时仍可进入 TUI、查看会话和使用非模型功能;在 `/model` 中按 Tab 进入供应商管理,配置 API key、OAuth 与设备码登录。
|
|
29
29
|
|
|
30
30
|
### 1. 安装与更新
|
|
31
31
|
|
|
32
32
|
初次安装和更新使用同一组指令:
|
|
33
33
|
|
|
34
34
|
```sh
|
|
35
|
-
npm install -g @deepseek-ai/dsh@0.1.5-rc.
|
|
35
|
+
npm install -g @deepseek-ai/dsh@0.1.5-rc.2 dsh-code@1.0.7
|
|
36
36
|
npm install -g pnpm
|
|
37
|
-
dsh plugin --profile cli add dsh-code@1.0.
|
|
37
|
+
dsh plugin --profile cli add dsh-code@1.0.7
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
> 提示:pnpm 会忽略发布不足 24 小时的包,因此发布首日请使用精确版本 `dsh-code@1.0.
|
|
40
|
+
> 提示:pnpm 会忽略发布不足 24 小时的包,因此发布首日请使用精确版本 `dsh-code@1.0.7`;24 小时后可省略版本号。npm 安装不受此限制。
|
|
41
41
|
>
|
|
42
|
-
> 版本对齐:dsh-code 面向 dsh `0.1.5-rc.
|
|
42
|
+
> 版本对齐:dsh-code 面向 dsh `0.1.5-rc.2` 构建,全部 Harness 依赖均精确锁定为 `0.1.5-rc.2`。已安装的用户运行 `deepseek update --apply` 即可按同一条版本线一起升级全局宿主与 cli profile 中的插件,本地开发挂载(`link:`)不受影响。
|
|
43
43
|
>
|
|
44
44
|
> 升级说明:旧会话与旧参数中记录的 `code` 预设会自动映射到上游已改名的 `ptc`,无需手动迁移。会话日志读取端随上游升级到格式 v3:旧格式日志在读取时由内核自动迁移,磁盘上的原始文件保持不变。
|
|
45
45
|
|
|
@@ -68,7 +68,7 @@ DSH-Code 的重点是让 DSH 的 Agent、模型、工具和持久会话可以直
|
|
|
68
68
|
- 使用 `/new` 新建会话,或通过 `/resume`、`--continue` 恢复已有会话
|
|
69
69
|
- 使用 `/fork` 从历史节点创建新的工作分支,同时保留原会话
|
|
70
70
|
- 按当前目录、更新时间和会话范围搜索历史记录
|
|
71
|
-
- 使用 Up/Down
|
|
71
|
+
- 使用 Up/Down 召回输入历史(含 / 指令),或通过 `/history` 搜索过去的提示词与指令
|
|
72
72
|
- 支持持久标题、Markdown 导出、上下文占用、token、缓存、TTFT 和耗时统计
|
|
73
73
|
- 恢复会话时同步恢复该会话使用的 Agent Preset 和模型选择
|
|
74
74
|
|
|
@@ -142,7 +142,7 @@ dsh --profile cli --session my-id # 使用指定 id 新建会话
|
|
|
142
142
|
| `/delete [id\|前缀]` | 删除指定会话及其 subagent 会话 |
|
|
143
143
|
| `/title <text>` | 修改当前会话标题 |
|
|
144
144
|
| `/export [path]` | 将当前会话导出为 Markdown |
|
|
145
|
-
| `/history` |
|
|
145
|
+
| `/history` | 搜索并复用过去提交的提示词与 / 指令 |
|
|
146
146
|
| `/clear` | 清空当前终端显示,不删除持久会话 |
|
|
147
147
|
|
|
148
148
|
#### Agent、模型与权限
|
|
@@ -164,6 +164,7 @@ dsh --profile cli --session my-id # 使用指定 id 新建会话
|
|
|
164
164
|
| `/todos` | 查看当前会话的完整 todo 列表 |
|
|
165
165
|
| `/agents` | 查看当前会话创建的 subagent 会话 |
|
|
166
166
|
| `/jobs` | 查看后台任务及其运行状态 |
|
|
167
|
+
| `/schedule` | 查看活动提醒(模型经 schedule 工具创建/取消,面板只读展示,逾期优先) |
|
|
167
168
|
| `/copy` | 复制最近一条完整助手回复 |
|
|
168
169
|
|
|
169
170
|
#### 扩展、显示与退出
|
|
@@ -171,6 +172,7 @@ dsh --profile cli --session my-id # 使用指定 id 新建会话
|
|
|
171
172
|
| 命令 | 用途 |
|
|
172
173
|
| --- | --- |
|
|
173
174
|
| `/plugin [query]` | 查看已加载扩展及其状态 |
|
|
175
|
+
| `/update` | 一键对齐升级:按目标版本的 peers 锁定宿主 Harness 线,同步升级 dsh-code、全局宿主与 profile 内伴生插件,升级前展示完整计划与拒绝条件,完成后提示重启生效 |
|
|
174
176
|
| `/statusline` | 选择状态栏显示的项目 |
|
|
175
177
|
| `/vscode-keys` | 将 Ctrl+R 放行进 VS Code 系终端(幂等写入用户级 keybindings.json) |
|
|
176
178
|
| `/theme` | 切换终端配色主题 |
|
|
@@ -212,7 +214,56 @@ DSH-Code 读取 Harness 的实时注册表,不在本地维护另一套副本
|
|
|
212
214
|
|
|
213
215
|
`/plugin` 提供当前 Cordis loader 状态的只读视图。
|
|
214
216
|
|
|
215
|
-
### 2.
|
|
217
|
+
### 2. 内置扩展与可选官方插件
|
|
218
|
+
|
|
219
|
+
以下官方插件已随 DSH-Code 一起安装并在组合中默认启用:
|
|
220
|
+
|
|
221
|
+
- **会话检索**:模型获得 `session_search` / `session_event_search` / `session_trace` / `session_event_trace` / `session_event_read` 五个只读工具,可检索历史会话内容(首次搜索时才构建索引,按工作目录精确匹配授权;Node 22 上首次搜索会当场打印一次 `node:sqlite` 实验性警告,属正常现象)。
|
|
222
|
+
- **定时提醒**:`schedule` 提供跨重启的持久提醒(`schedule_create` / `schedule_list` / `schedule_delete` 工具创建),`/schedule` 面板只读展示、逾期条目置顶标红;`time-context` 为模型注入时钟读数(30 秒节流)。
|
|
223
|
+
- **提醒的时钟读数**:`time-context` 为模型注入当前时间(30 秒节流),「下午五点提醒我」这类表述因此可用。
|
|
224
|
+
|
|
225
|
+
以下官方插件已安装但需按需启用(在用户层 `~/.dsh/profiles/cli/cordis.patch.yml` 追加行,或按说明安装):
|
|
226
|
+
|
|
227
|
+
- **MCP 服务器**(`@deepseek-ai/dsh-mcp-client`,每个服务器一行,工具注册为 `mcp__<server>__<tool>`):
|
|
228
|
+
|
|
229
|
+
```yaml
|
|
230
|
+
- insert:
|
|
231
|
+
- id: mcp-memory
|
|
232
|
+
name: '@deepseek-ai/dsh-mcp-client'
|
|
233
|
+
config:
|
|
234
|
+
transport: stdio
|
|
235
|
+
serverName: memory
|
|
236
|
+
command: mcp-server-memory
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
(HTTP 传输改用 `transport: streamable-http` + `url`;服务器不可达时安全降级为重连循环,不影响启动。)
|
|
240
|
+
- **Claude Code / Codex hooks 桥**(`@deepseek-ai/dsh-hooks-claude-code` / `-codex`):在拦截缝上运行既有 hooks 配置;hooks 文件缺失时静默不生效:
|
|
241
|
+
|
|
242
|
+
```yaml
|
|
243
|
+
- insert:
|
|
244
|
+
- id: hooks-claude
|
|
245
|
+
name: '@deepseek-ai/dsh-hooks-claude-code'
|
|
246
|
+
config:
|
|
247
|
+
configPath: C:/Users/you/.claude/hooks.json
|
|
248
|
+
```
|
|
249
|
+
- **LSP 导航**:组合里预置了 `lsp` / `lsp-stdio` / `tool-lsp` 三行(禁用状态——语言服务器二进制在挂载期解析,缺失会让整个组合启动失败)。在用户层将三行 `disabled: false` 并为 `lsp-stdio` 配置 `servers`(扩展名到语言再到服务器命令),模型即获得 `lsp` 工具(goToDefinition / findReferences / goToImplementation / hover)。
|
|
250
|
+
- **持久终端**:PTY 服务与平台后端(Windows 走 pwsh 方言、POSIX 走 bash)已默认挂载,但六个模型工具 `terminal_open` / `terminal_send` / `terminal_read` / `terminal_signal` / `terminal_close` / `terminal_list` 出厂禁用——启用等于向所有会话放开 shell 能力,与 preset 把关原则一致,由部署显式决定。在用户层开启:
|
|
251
|
+
```yaml
|
|
252
|
+
- id: tool-terminal
|
|
253
|
+
disabled: false
|
|
254
|
+
```
|
|
255
|
+
(后台发送会出现在 /jobs 面板。)
|
|
256
|
+
- **tmux 面板上下文**(`@deepseek-ai/dsh-tmux-context`):在 tmux 内运行时把当前面板内容注入模型上下文(`config: { refreshIntervalMs: 60000 }`);不在 tmux 内时逐步为无害空操作:
|
|
257
|
+
```yaml
|
|
258
|
+
- insert:
|
|
259
|
+
- id: tmux-context
|
|
260
|
+
name: '@deepseek-ai/dsh-tmux-context'
|
|
261
|
+
config:
|
|
262
|
+
refreshIntervalMs: 60000
|
|
263
|
+
```
|
|
264
|
+
- **外部 CLI 委托**:`dsh plugin --profile cli add @deepseek-ai/dsh-subagent-claude-code`(或 `-codex`)安装休眠 provider,再按上游契约复制预设并启用 `tool-subagent-claude-code` / `tool-subagent-codex` 行,模型即可把任务委托给 claude / codex CLI。
|
|
265
|
+
|
|
266
|
+
### 3. 会话级 Agent Preset
|
|
216
267
|
|
|
217
268
|
Host 持有共享基础设施——注册表、持久化、会话查询、权限和 sandbox 策略;每个会话则获得一个隔离的 Agent scope,并由 **Agent Preset** 进行组合:
|
|
218
269
|
|
|
@@ -224,7 +275,7 @@ Host 持有共享基础设施——注册表、持久化、会话查询、权限
|
|
|
224
275
|
|
|
225
276
|
在第一次 turn 之前使用 `/mode`,或通过 `--mode <preset>` 直接启动。选中的 preset 会写入会话,并在恢复时还原。
|
|
226
277
|
|
|
227
|
-
###
|
|
278
|
+
### 4. 会话记录与恢复
|
|
228
279
|
|
|
229
280
|
提示词、工具调用与结果、模型选择、plan 状态、权限、标题和 preset 选择都由持久 Session 事件投影得到;会话恢复、导出、历史检查、上下文统计和终端重放使用同一份记录。实时流式文本经进程内流帧呈现,落盘日志只保留装配完成的回复(内嵌计时流),两者在重放时得到同一视图。
|
|
230
281
|
|
package/bin/deepseek.mjs
CHANGED
|
@@ -8,7 +8,8 @@ import { dirname, join, resolve } from 'node:path'
|
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
9
9
|
|
|
10
10
|
const packageRequire = createRequire(import.meta.url)
|
|
11
|
-
|
|
11
|
+
/** This launcher's release version (exported for probes and tests). */
|
|
12
|
+
export const packageVersion = packageRequire('../package.json').version
|
|
12
13
|
|
|
13
14
|
/** Arguments required to boot DSH-Code's conventional profile. */
|
|
14
15
|
export const profileArgs = (args = []) => ['--profile', 'cli', ...args]
|
|
@@ -115,6 +116,22 @@ export function harnessLineFromPeers(peers) {
|
|
|
115
116
|
return undefined
|
|
116
117
|
}
|
|
117
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Refusal reason when a local-checkout profile would pair an older local
|
|
121
|
+
* build with the newer global host this upgrade installs, or undefined when
|
|
122
|
+
* the upgrade may proceed (no checkout mounted, or the checkout already
|
|
123
|
+
* matches the release). The caller prints the lines verbatim.
|
|
124
|
+
*/
|
|
125
|
+
export function localCheckoutRefusal(mounted, latestCode, codeSpec) {
|
|
126
|
+
if (mounted === undefined || mounted === latestCode) return undefined
|
|
127
|
+
return [
|
|
128
|
+
`dsh-code: the cli profile mounts a local checkout of dsh-code ${mounted}, while this upgrade would install ${latestCode} globally`,
|
|
129
|
+
'dsh-code: upgrading the host beside an older local checkout pairs incompatible code; refusing to install',
|
|
130
|
+
'dsh-code: update the checkout first (git pull, pnpm install, pnpm build), or switch the profile to the published package:',
|
|
131
|
+
`dsh-code: dsh plugin --profile cli remove dsh-code && dsh plugin --profile cli add ${codeSpec}`,
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
|
|
118
135
|
/**
|
|
119
136
|
* Decide what `update --apply` installs. The global DSH launcher is pinned
|
|
120
137
|
* to the harness line the target dsh-code release declares in its peers,
|
|
@@ -384,6 +401,57 @@ function printUpdateStatus() {
|
|
|
384
401
|
console.log('Run `deepseek update --apply` to upgrade the global packages and the cli profile together.')
|
|
385
402
|
}
|
|
386
403
|
|
|
404
|
+
/**
|
|
405
|
+
* The structured form of the update status for machine consumers
|
|
406
|
+
* (`update --json`, consumed by the TUI /update panel): what is running,
|
|
407
|
+
* what npm serves, the exact steps `update --apply` would run, and every
|
|
408
|
+
* refusal that would stop it. One JSON object on stdout; `null` marks an
|
|
409
|
+
* unreadable value so the payload shape stays constant.
|
|
410
|
+
*/
|
|
411
|
+
export function buildUpdateStatus({
|
|
412
|
+
view = viewJson,
|
|
413
|
+
installedDsh = installedDshVersion,
|
|
414
|
+
readSpec = profileDependencySpec,
|
|
415
|
+
readMounted = profileMountedVersion,
|
|
416
|
+
readPlugins = profilePluginDependencies,
|
|
417
|
+
} = {}) {
|
|
418
|
+
const codeLatest = view(['dsh-code', 'version'])
|
|
419
|
+
const installed = installedDsh()
|
|
420
|
+
const spec = readSpec()
|
|
421
|
+
const mounted = readMounted()
|
|
422
|
+
const peers = codeLatest === undefined ? undefined : view([`dsh-code@${codeLatest}`, 'peerDependencies'])
|
|
423
|
+
const plan = updatePlan({
|
|
424
|
+
latestCode: codeLatest ?? 'unknown',
|
|
425
|
+
peers,
|
|
426
|
+
profileSpec: spec,
|
|
427
|
+
profilePlugins: readPlugins(),
|
|
428
|
+
})
|
|
429
|
+
const registry = codeLatest === undefined ? 'could not read the latest dsh-code version from npm' : undefined
|
|
430
|
+
// The same refusals applyUpdate enforces, precomputed so a caller can
|
|
431
|
+
// show them BEFORE any confirmation instead of failing mid-flight.
|
|
432
|
+
const downgrade = plan.line !== undefined && installed !== undefined && compareHarnessLines(plan.line, installed) < 0
|
|
433
|
+
const localCheckout = plan.profileStep ? undefined : localCheckoutRefusal(mounted, codeLatest, plan.codeSpec)
|
|
434
|
+
const hostOnLine = installed !== undefined && (plan.line === undefined || compareHarnessLines(installed, plan.line) === 0)
|
|
435
|
+
const upToDate = registry === undefined
|
|
436
|
+
&& codeLatest === packageVersion
|
|
437
|
+
&& !downgrade
|
|
438
|
+
&& localCheckout === undefined
|
|
439
|
+
&& hostOnLine
|
|
440
|
+
&& plan.pluginSpecs.length === 0
|
|
441
|
+
&& (mounted === undefined || mounted === codeLatest)
|
|
442
|
+
return {
|
|
443
|
+
code: { running: packageVersion, latest: codeLatest ?? null },
|
|
444
|
+
host: { installed: installed ?? null, targetLine: plan.line ?? null },
|
|
445
|
+
profile: { spec: spec ?? null, mounted: mounted ?? null, localCheckout: !plan.profileStep },
|
|
446
|
+
plan: { dshSpec: plan.dshSpec, codeSpec: plan.codeSpec, pluginSpecs: plan.pluginSpecs },
|
|
447
|
+
// JSON.stringify drops undefined members; every unreadable value must
|
|
448
|
+
// serialize as an explicit null so machine consumers never see a missing
|
|
449
|
+
// key drift into a truthy comparison.
|
|
450
|
+
blockers: { registry: registry ?? null, downgrade, localCheckout: localCheckout ?? null },
|
|
451
|
+
upToDate,
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
387
455
|
/**
|
|
388
456
|
* Upgrade the global launcher and the cli profile plugin together. The
|
|
389
457
|
* global install is pinned to the harness line the new dsh-code release
|
|
@@ -424,6 +492,19 @@ async function applyUpdate({
|
|
|
424
492
|
process.exitCode = 1
|
|
425
493
|
return
|
|
426
494
|
}
|
|
495
|
+
// Local-checkout guard: a link/file-mounted profile runs the checkout's
|
|
496
|
+
// own build, and this command would upgrade the global host beside it.
|
|
497
|
+
// When the checkout is older than the release being installed, upgrading
|
|
498
|
+
// pairs a new host with old local code — the terminal breaks on the next
|
|
499
|
+
// launch. Refuse until the checkout is updated or unmounted.
|
|
500
|
+
if (!plan.profileStep) {
|
|
501
|
+
const refusal = localCheckoutRefusal(profileMountedVersion(), latestCode, plan.codeSpec)
|
|
502
|
+
if (refusal !== undefined) {
|
|
503
|
+
for (const line of refusal) console.error(line)
|
|
504
|
+
process.exitCode = 1
|
|
505
|
+
return
|
|
506
|
+
}
|
|
507
|
+
}
|
|
427
508
|
const steps = [{ command: npm.command, args: [...npm.args, 'install', '-g', plan.dshSpec, plan.codeSpec], label: 'npm install' }]
|
|
428
509
|
if (plan.profileStep) {
|
|
429
510
|
const command = resolveCommand(['plugin', '--profile', 'cli', 'add', plan.codeSpec])
|
|
@@ -490,6 +571,10 @@ export function launchOperation(args = process.argv.slice(2)) {
|
|
|
490
571
|
return launchChild(command.command, command.args)
|
|
491
572
|
}
|
|
492
573
|
if (operation === 'update') {
|
|
574
|
+
if (args.includes('--json')) {
|
|
575
|
+
console.log(JSON.stringify(buildUpdateStatus()))
|
|
576
|
+
return true
|
|
577
|
+
}
|
|
493
578
|
if (args.includes('--apply')) {
|
|
494
579
|
void applyUpdate()
|
|
495
580
|
return true
|
package/cordis.patch.yml
CHANGED
|
@@ -24,6 +24,17 @@
|
|
|
24
24
|
config:
|
|
25
25
|
mode: !!js process.env.DSH_TOOLS_MODE
|
|
26
26
|
|
|
27
|
+
# The base row keeps full-text search off entirely (openAt: never) so nothing
|
|
28
|
+
# imports node:sqlite at boot; the terminal replaces it with the bundle's
|
|
29
|
+
# skip-tolerant subclass below. An override row cannot retarget a row's
|
|
30
|
+
# MODULE (name is only honored on inserts), so the base row is disabled and
|
|
31
|
+
# an equivalent row mounts the subclass: the derived index opens lazily on
|
|
32
|
+
# the first search (no startup cost, no Node 22 experimental warning), and
|
|
33
|
+
# one unreadable source (a pre-release artifact the frozen codecs reject)
|
|
34
|
+
# is skipped with a warning instead of failing every cross-session search.
|
|
35
|
+
- id: session-query-sqlite
|
|
36
|
+
disabled: true
|
|
37
|
+
|
|
27
38
|
# Agent-plane rows are mounted by the selected preset. Keep this list aligned
|
|
28
39
|
# with the upstream Web bundle so two sessions can use different compositions
|
|
29
40
|
# without leaking model-facing registrations through the host layer.
|
|
@@ -132,6 +143,83 @@
|
|
|
132
143
|
- id: authorization
|
|
133
144
|
name: '@deepseek-ai/dsh-authorization'
|
|
134
145
|
|
|
146
|
+
# The bundle's skip-tolerant session-query engine replacing the disabled
|
|
147
|
+
# base row above: same SQLite FTS5 service, observation loop patched to
|
|
148
|
+
# skip unreadable sources instead of failing every search.
|
|
149
|
+
- id: session-query-skip
|
|
150
|
+
name: 'dsh-code/session-query'
|
|
151
|
+
config:
|
|
152
|
+
path: ':memory:'
|
|
153
|
+
openAt: first-search
|
|
154
|
+
|
|
155
|
+
# Model-facing session-log search/trace/read tools over the sessionQuery
|
|
156
|
+
# service (read-only, workspace-scoped by exact cwd). A host-plane mount
|
|
157
|
+
# is deployment-global: every preset session sees the five tools. Kept
|
|
158
|
+
# ENABLED deliberately — read-only search leaks no capability — but note
|
|
159
|
+
# it does reach minimal-preset sessions too.
|
|
160
|
+
- id: tool-session-query
|
|
161
|
+
name: '@deepseek-ai/dsh-tool-session-query'
|
|
162
|
+
|
|
163
|
+
# Durable reminders: the schedule service arms per-root timers, injects
|
|
164
|
+
# due prompts as plugin-source user messages, and writes schedule/change
|
|
165
|
+
# events the projection folds into the /schedule panel. time-context
|
|
166
|
+
# gives the model a clock reading so 'at' times are phrased against the
|
|
167
|
+
# actual time; the 30s throttle bounds durable snapshot growth.
|
|
168
|
+
- id: schedule
|
|
169
|
+
name: '@deepseek-ai/dsh-schedule'
|
|
170
|
+
|
|
171
|
+
- id: time-context
|
|
172
|
+
name: '@deepseek-ai/dsh-time-context'
|
|
173
|
+
config:
|
|
174
|
+
refreshIntervalMs: 30000
|
|
175
|
+
|
|
176
|
+
# Persistent PTY plumbing: the owner-scoped registry and the one backend
|
|
177
|
+
# package in both dialects (pwsh is the Windows/ConPTY path, bash covers
|
|
178
|
+
# POSIX) mount as host SERVICES — no model-facing surface, so they break
|
|
179
|
+
# no preset boundary. The six terminal_* TOOLS ship DISABLED like LSP:
|
|
180
|
+
# enabling them at the host plane would hand every preset (including the
|
|
181
|
+
# shell-restricted minimal one) raw shell capability, the exact leak the
|
|
182
|
+
# disables above exist to prevent. Flip tool-terminal to disabled: false
|
|
183
|
+
# in the PROFILE layer to opt the deployment into PTY tools.
|
|
184
|
+
- id: pty
|
|
185
|
+
name: '@deepseek-ai/dsh-terminal'
|
|
186
|
+
|
|
187
|
+
- id: terminal-pwsh
|
|
188
|
+
name: '@deepseek-ai/dsh-terminal-bash'
|
|
189
|
+
disabled: !!js process.platform !== 'win32'
|
|
190
|
+
config:
|
|
191
|
+
shellDialect: pwsh
|
|
192
|
+
|
|
193
|
+
- id: terminal-bash
|
|
194
|
+
name: '@deepseek-ai/dsh-terminal-bash'
|
|
195
|
+
disabled: !!js process.platform === 'win32'
|
|
196
|
+
|
|
197
|
+
- id: tool-terminal
|
|
198
|
+
name: '@deepseek-ai/dsh-tool-terminal'
|
|
199
|
+
disabled: true
|
|
200
|
+
|
|
201
|
+
# LSP navigation ships DISABLED: lsp-stdio resolves every server command
|
|
202
|
+
# at mount and a missing binary would fail the whole composition boot.
|
|
203
|
+
# Enable in the PROFILE layer with real servers, e.g.:
|
|
204
|
+
# lsp / lsp-stdio / tool-lsp rows with disabled: false and
|
|
205
|
+
# lsp-stdio config.servers mapping extensions to server commands.
|
|
206
|
+
- id: lsp
|
|
207
|
+
name: '@deepseek-ai/dsh-lsp'
|
|
208
|
+
disabled: true
|
|
209
|
+
|
|
210
|
+
- id: lsp-stdio
|
|
211
|
+
name: '@deepseek-ai/dsh-lsp-stdio'
|
|
212
|
+
disabled: true
|
|
213
|
+
|
|
214
|
+
- id: tool-lsp
|
|
215
|
+
name: '@deepseek-ai/dsh-tool-lsp'
|
|
216
|
+
disabled: true
|
|
217
|
+
|
|
218
|
+
# MCP servers (dsh-mcp-client) and hooks bridges (dsh-hooks-claude-code /
|
|
219
|
+
# -codex) take per-instance config (server transports, hooks.json paths),
|
|
220
|
+
# so they mount as rows in the USER profile layer, not here; the packages
|
|
221
|
+
# ship as peers so those rows resolve. README documents the row shapes.
|
|
222
|
+
|
|
135
223
|
- id: tui-startup
|
|
136
224
|
name: 'dsh-code/startup'
|
|
137
225
|
|