# 升级指南
本文件按"宿主版本轴"记录升级步骤与注意事项。**先读与你自己相关的那一段**:
> ## ⚠️ v0.4.2 / v0.4.3 存在崩溃级回归,请升级到 v0.4.4
>
> 那两版的终端通知(OSC 9 / 777)在**非 TTY** 场景会把转义序列写进输出流:
> 终端显示乱码,且终端对序列的设备属性应答无人读取,滞留字节污染 nvim RPC 流,
> 表现为**会话跑一会儿就异常退出**(日志里可能是 `nvim_buf_set_lines:
> 'replacement string' item contains newlines` 或 `write EPIPE`)。
> v0.4.4 增加了 `stdout_is_tty()` 守卫(只覆盖非 TTY 场景);**v0.4.5 起该功能
> 与 `/bell` 命令已整体移除** —— 插件所在 nvim 为 `--embed`,其 stdout 是 RPC
> socket,从 Lua 侧没有任何通道能到达终端。
> **git/tag 依赖怎么升级(实测结论,2026-09-16)**:`pnpm update` 与
> `update --latest` **都不会**推进 `github:owner/repo#tag` —— `--latest` 只重写
> npm semver 范围,不改 git ref。唯一有效的是**用 `add` 带新 ref 重写**:
> `dsh plugin --profile
add "owner/repo#vX.Y.Z"`(TUI 内:
> `/plugin update owner/repo#vX.Y.Z`)。`update` 只对 npm 依赖有意义。
| 你的现状 | 读这一节 |
|---|---|
| nvim-tui v0.5.1(宿主 0.2.1-rc.4) | [v0.5.1 → v0.5.2(schedule 修复;宿主不变)](#v051--v052schedule-修复宿主不变) |
| nvim-tui v0.5.0(宿主 0.2.1-rc.2) | [v0.5.0 → v0.5.1(宿主前移 rc.2 → rc.4;零代码改动)](#v050--v051宿主前移-rc2--rc4零代码改动) |
| nvim-tui v0.4.14(宿主 0.2.1-rc.2) | [v0.4.14 → v0.5.0(功能批次,宿主不变;零破坏)](#v0414--v050功能批次宿主不变零破坏) |
| nvim-tui v0.4.12(宿主 0.2.0-rc.2) | [v0.4.12 → v0.4.14(**宿主 0.2.0-rc.2 → 0.2.1-rc.2**;新增 /cwd;兼容判定改 engines.dsh)](#v0412--v0414宿主-020-rc2--021-rc2新增-cwd兼容判定改-enginesdsh) |
| nvim-tui v0.4.11(宿主 0.2.0-rc.2) | [v0.4.11 → v0.4.12(功能与修复,**宿主不变**;零破坏)](#v0411--v0412功能与修复宿主不变零破坏) |
| nvim-tui v0.4.10(宿主 0.2.0-rc.2) | [v0.4.10 → v0.4.11(功能新增,**宿主不变**;零破坏)](#v0410--v0411功能新增宿主不変零破坏) |
| nvim-tui v0.4.9(宿主 0.2.0-rc.1) | [v0.4.9 → v0.4.10(**宿主 0.2.0-rc.1 → 0.2.0-rc.2**,锚点前移)](#v049--v0410宿主-020-rc1--020-rc2) |
| nvim-tui v0.4.8(宿主 0.1.7-rc.2) | [v0.4.8 → v0.4.9(**宿主 0.1.7-rc.2 → 0.2.0-rc.1**,锚点前移)](#v048--v049宿主-017-rc2--020-rc1) |
| nvim-tui v0.4.7(宿主 0.1.7-rc.1) | [v0.4.7 → v0.4.8(**宿主 0.1.7-rc.1 → 0.1.7-rc.2**,锚点前移)](#v047--v048宿主-017-rc1--017-rc2) |
| nvim-tui v0.4.6(宿主 0.1.5-rc.2) | [v0.4.6 → v0.4.7(**宿主 0.1.5-rc.2 → 0.1.7-rc.1**,含破坏性适配)](#v046--v047宿主-015-rc2--017-rc1) |
| nvim-tui v0.4.5(宿主 0.1.5-rc.2) | [v0.4.5 → v0.4.6(发布物修正 + 门禁加固,零破坏)](#v045--v046发布物修正--门禁加固零破坏) |
| nvim-tui v0.4.4(宿主 0.1.5-rc.2) | [v0.4.4 → v0.4.5(移除 /bell 与终端通知,零破坏)](#v044--v045移除-bell-与终端通知零破坏) |
| nvim-tui v0.4.3(宿主 0.1.5-rc.2) | [v0.4.3 → v0.4.4(**崩溃修复**,零破坏)](#v043--v044崩溃修复零破坏) |
| nvim-tui v0.4.2(宿主 0.1.5-rc.2) | [v0.4.2 → v0.4.3(插件升级,零破坏)](#v042--v043插件升级零破坏) |
| nvim-tui v0.4.1(宿主 0.1.5-rc.2) | [v0.4.1 → v0.4.2(插件升级,零破坏)](#v041--v042插件升级零破坏) |
| nvim-tui v0.4.0(宿主 0.1.5-rc.1 或 rc.2) | [v0.4.0 → v0.4.1(插件升级,零破坏)](#v040--v041插件升级零破坏) |
| nvim-tui 已适配 0.1.5(宿主 0.1.5-rc.1) | [宿主 0.1.5-rc.1 → 0.1.5-rc.2(零破坏)](#宿主-015-rc1--015-rc2零破坏) |
| nvim-tui ≤ v0.3.4(宿主 0.1.2-rc.1) | [v0.3.4 → v0.4.0(含宿主 0.1.2-rc.1 → 0.1.5-rc.1)](#v034--v040含宿主-012-rc1--015-rc1) |
| nvim-tui v0.4.0 已升(宿主仍 0.1.2-rc.1) | 同上(宿主段落必读:peer 锚点已改为 `^0.1.5-rc.1`) |
| 仅升级宿主 dsh(插件版本不变) | 见下方历史小节 |
---
## v0.5.1 → v0.5.2(schedule 修复;宿主不变)
> **结论先行**:宿主不变(仍为 0.2.1-rc.4),只修 TUI 组合里
> `dsh-schedule` 永久 pending 的问题。已装过 `/deps install` 的 profile
> 不需要重装 schedule 行。
```bash
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.5.2"
dsh --profile
```
### 根因
`dsh-schedule` 的 `static inject` 包含 `sessionController`,投递时调用
`resolveAgent(sessionId)`。这个服务由 Web/API 组合提供
(`dsh-api-session-controller` + API gateway + client connection +
file-upload),TUI profile 没有它,所以 loader 一直显示:
```
schedule (@deepseek-ai/dsh-schedule): pending (waiting for service: sessionController)
```
### 修复
TUI 启动时提供一个窄适配器,只实现 `resolveAgent`:
- live 会话 → 直接返回 Agent;
- 非 live 会话 → 走 `ensureLiveSession()` 后台恢复(不切换当前聊天);
- 恢复失败 → 返回 `{ error }` 让 schedule 重试。
不挂 `dsh-api-session-controller`,避免把整套 Web 栈装进 TUI。
### 验证
隔离 profile(rc4 + schedule 行)启动后,探针确认 `app.svc('schedule')` 已
激活;`npm run smoke` 覆盖 live session 解析。schedule 的**真实投递**仍建议
在带凭据的真实终端创建一条 1 分钟后的提醒验证一次。
## v0.5.0 → v0.5.1(宿主前移 0.2.1-rc.2 → 0.2.1-rc.4;零代码改动)
> **结论先行**:本版只把依赖/类型锚点前移到 **dsh 0.2.1-rc.4**,TUI 运行时代码
> 没有改动。`engines.dsh` 仍是 `>=0.2.0-rc.2 <0.2.2`,因此 rc.2 / rc.3 / rc.4
> 都仍在兼容范围内(rc4 的 `evaluatePluginCompatibility()` 实测三者均通过)。
```bash
npm i -g @deepseek-ai/dsh@0.2.1-rc.4
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.5.1"
dsh --profile
```
### 这次改了什么
- 15 个 `@deepseek-ai/dsh-*` peer/dev 依赖:`0.2.1-rc.2` → `0.2.1-rc.4`。
- `@deepseek-ai/cordis`:`~4.0.4` → `~4.0.5`(rc4 的 peer 要求)。
- 移除 `@deepseek-ai/dsh-invariants`:rc.4 未发布该包,rc4 的 `dsh-agent` /
`dsh-tools` 也不再把它列为 peer;它只是 rc.2 时代遗留的 devDependency。
- 重新生成 lock,无 rc.2 残留;README 兼容矩阵补充 rc.3 / rc.4。
- **没有命令、UI、事件或配置行为变化**;v0.5.0 的功能/限制说明继续适用。
### 为什么是零破坏
rc.3 的官方变更是 Web 侧栏“更多”菜单与未发送草稿修复;rc.4 只修复 ACP 模式
诊断输出混入 stdout。二者都不在 TUI 的调用路径上。实际 diff 验证:本插件消费的
8 个核心包 + 11 个可选 host 包的 `lib/`(含 `.d.ts`)在 rc.2 与 rc.4 之间**没有
差异**,只有 `package.json` 版本号变化;`tsc` 对着 rc.4 真实类型通过。
### 可选宿主行
与 v0.5.0 相同:`/schedule`、`/terminal`、`/changes` 宿主快照等仍需
`/deps install`;rc.4 的 `dsh-schedule` / `dsh-terminal` / `dsh-terminal-bash`
等包仍存在。
### 验证与限制
- `npm run build` / `check` / `smoke` 在 rc.4 类型面上全绿。
- 用隔离 DSH_HOME + 本地 dsh 0.2.1-rc.4 实际启动:插件行激活,TUI 渲染 prompt
并创建 session。
- **完整真机 e2e 未完成**:隔离 home 没有 API key,host 报
`MISSING_CREDENTIAL`;这不是插件兼容失败。真实终端带凭据可复跑
`npm run e2e`。
- 0.2.2 / 0.3.0 仍未验证,故 `engines.dsh` 上界保持 `<0.2.2`。
## v0.4.14 → v0.5.0(功能批次,宿主不变;零破坏)
> **结论先行**:宿主**不变**(仍为 0.2.1-rc.2;`engines.dsh` 仍为
> `>=0.2.0-rc.2 <0.2.2`),无需升级 dsh。本版是 7 个能力面的功能批次,
> 无破坏性 API 变更;有几处**行为变化**需要知道,见下。
```bash
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.5.0"
dsh --profile
```
### 新增能力(命令数 68 → 77)
- **审批/提问**:审批浮窗显示 `callId` 对应的工具参数与本地化 `displayReason`;
提问支持 `` 自定义文本(plan review 的反馈可用)。
- **交付物/改动**:消费 `deliverables/presented`;`/changes` 优先用宿主
`workspace/changes` 快照并支持 hunk 对比(`/deps` 新增 `workspace-changes` 行)。
- **导出/反馈**:`/export log` 导出 canonical JSONL;`/feedback` 会话级分类反馈。
- **设置/账号**:`/settings form` 表单化写入、`/settings key` 打开凭证文件、
`/account` 状态/余额/浏览器登录(服务名修正为 `deepseekAccount`)。
- **定时提醒/终端**:`/schedule` 与 `/terminal`(nvim PTY 控制台 +
`/terminal shell` 原生 `:terminal`)。
- **PTC/CLI**:PTC 子调用嵌套渲染、image offload 提示、`--resume/--continue/
--model/--permission/--help/--version`。
- **文件/大纲/检查**:`/files`(netrw)、`/preview`、`/upload`、`/outline`、
`/cordis`、`/mcp tools|config|resources`。
### 行为变化(非破坏)
- `/export` 无路径时默认写到**会话 cwd**(此前是进程 cwd);显式路径不变。
- `/feedback` 现在是 TUI 原生命令(覆盖同名官方命令):支持分类/文本;直接
`/feedback <文本>` 仍等价于记录一条无分类反馈。
- `activeSessionCwd` 优先读 `workingDirectory` 服务:`/cwd` 后 `/files`、
`/preview`、`/upload`、`/deliverables` 的相对路径会跟随新目录(这是修复,
但会让此前依赖旧 header 的脚本看到不同结果)。
- `/settings` 新增 `form` / `key` 子命令;原 `edit` / `set` 保持。
- CLI 现在会解析 app 参数;dsh launcher 的 `--patch` 等 flag 会先被剥离。
### 可选宿主行(首次使用前)
`/schedule`、`/terminal`、`/changes` 宿主快照等依赖可选行,先执行:
```bash
/deps install
```
- `/schedule`:`dsh-schedule`
- `/terminal`:`dsh-terminal` + `dsh-terminal-bash`
- `/changes` 宿主快照:`dsh-workspace-changes`
- `/files` 使用 nvim 自带 netrw(用户配置禁用时提示改用 `/dir`)
### 验证与限制
- `npm run build` / `check` / `smoke` 全绿;77 个命令与 `docs/COMMANDS.md` 一致。
- 真机 e2e **未完成**:当前沙箱禁止写 `~/.dsh/profiles//cordis.yml`
(EPERM),属 workspace-write 限制;真实终端可跑 `npm run e2e`。
- `/schedule`、`/terminal` 的真实宿主服务需先 `/deps install` 并重启/HMR;
`/account login` 浏览器 OAuth 未真机验证;`/preview` 图片/PDF 走系统打开;
`/cordis`、`/mcp config` 为只读检查;新增文案的 en 字典尚未逐条补齐。
## v0.4.12 → v0.4.14(宿主 0.2.0-rc.2 → 0.2.1-rc.2;新增 /cwd;兼容判定改 engines.dsh)
> **结论先行**:宿主需升到 **0.2.1-rc.2**。本版把兼容判定从精确 peer 换成范围,
> **一个插件版本可跨多个宿主**(v0.4.13 未单独发布,内容并入本版)。
```bash
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.4.14"
```
### 新增 `/cwd`
`/cwd` 显示会话工作目录,`/cwd <路径>` 切换(相对路径按 `cd` 语义解析)。
走 dsh 0.2.1 的 `workingDirectory` 服务,**只改本会话目录,不动已有进程与权限**。
宿主没有该服务时会明确提示"不支持",而不是报失败。
### 兼容判定改用 `engines.dsh`
0.2.1 起宿主**优先看 `engines.dsh`**,声明后 `peerDependencies` 被忽略。
故声明 `>=0.2.0-rc.2 <0.2.2`:用宿主自己的 `evaluatePluginCompatibility()` 实测,
0.2.0-rc.2 / 0.2.1-rc.1 / 0.2.1-rc.2 **全部兼容**,0.2.2 及 0.3.0 **故意不收**
(未验证过的版本不声明兼容)。
### 未接入
`DeepSeek Search & Fetch`(宿主/适配器层,插件类型面无导出)、`/compact`(本插件早有)、
`PluginRecord` / `LlmCallControls`(可选能力,不接入不影响正确性)。
### 升级步骤
```bash
npm i -g @deepseek-ai/dsh@0.2.1-rc.2
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.4.14"
dsh --profile
```
(0.2.1-rc.2 在 `next` 上,`latest` 仍是 0.2.0-rc.2。)
### 为什么是零破坏
官方 notes 只有两条(V4.1-Flash-1017、Search/Fetch),但类型面有 38 个文件变化,故以代码 diff
为准:`dsh-llm` peer **无变化**;`dsh-agent` 去掉 `invariants`;`dsh-tools` 新增
`dsh-working-directory`(随宿主安装)。**`content.d.ts`(`MessageSourceMap`)哈希完全相同**,
`/todo` 守卫的 `source.kind` 不受影响;我们导入的全部符号均仍在;`tsc` 对着 0.2.1-rc.2 的
真实 `.d.ts` **通过**。
### 未接入的新功能
`DeepSeek Search & Fetch` 在插件可达的类型面里**没有对应导出**(宿主/适配器层能力);
`V4.1-Flash-1017` 是模型 id,价格表有 `/flash/i` 兜底匹配。**TUI 侧没有可接的钩子。**
### ⚠️ 升级后会连带跳过锚在旧版的插件
本机实测 **9 个插件被跳过**(`dsh-memory` / `dsh-knowledge-base` / `dsh-audit-trail` /
`dsh-evidence-gate` / `dsh-orchestrator` / `dsh-quality-gate` / `dsh-role-guard` /
`dsh-spec-gate` / `dsh-test-design-gate`)。两处易误判:
1. 报错字段是 **`requirements`**(不再是 `peerDependencies`)—— 用旧字样 grep 会漏;
2. 即使写范围(`>=0.2.0-rc…`)**也仍被跳过** —— prerelease 的范围**不跨 rc**。
## v0.4.11 → v0.4.12(功能与修复,宿主不变;零破坏)
> **结论先行**:宿主锚点**不变**(仍是 0.2.0-rc.2),无需升级宿主。
```bash
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.4.12"
dsh --profile
```
### 新增:`/models` 显示图像能力标记
`🖼` = 宿主报告支持图像 / `?` = 宿主没有该模型的模态信息 / 无标记 = 仅文本。
三态而非布尔:`?`(没查到)与"仅文本"(查到了但不支持)是**两种不同的失败**,排查方向完全不同。
### 修复:`/diff` 的四个独立问题
对照此前开在**标签页**里,而插件强制 `showtabline=0` —— 打开了却没有任何视觉提示。
现改为**两个并排的独立浮窗**(浮窗不能被 `vsplit`,实测会得到一条 136×2 的细缝),
并补上两栏**只读**(复用 `lock_popup_buffer`)与**打开即普通模式**(交出焦点后按真实
``;`:stopinsert` 在焦点切换后会静默失效,本仓已有文档)。
### 已知限制
两个独立浮窗**无法用 `scrollbind` 联动**(浮窗不在标签页布局内),`]c`/`[c` 跳改动时同步,
**自由滚动长文件时可能错位**。
## v0.4.10 → v0.4.11(功能新增,宿主不变;零破坏)
> **结论先行**:宿主锚点**不变**(仍是 0.2.0-rc.2),无需升级宿主。本版只是功能与修复。
```bash
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.4.11"
dsh --profile
```
### 新增:官方命令注册表接入
任何插件通过 `ctx.commands`(`@deepseek-ai/dsh-commands`,由 `dsh-base` 装配)注册的命令,
现在**在 TUI 里能补全、能执行**:输入 `/` 即出现在补全框,提交时会先问这张表。
`/commands` 可列出注册表。
**参数补全的边界**:官方描述符只提供自由文本 `input.hint`(无结构化文法),所以
**显示"该填什么",但不弹参数选择框** —— 要做只能由官方侧声明枚举,或在 TUI 里硬编码
某个插件的子命令(那会把插件知识塞进 TUI,不建议)。
### 修复
- 官方合并**不再被永久跳过**:启动时无活跃会话会把这次合并记为"欠着",在会话就绪后偿还。
- `/changes` 选中按 Enter 不再无反应(跨命令派发少了前导斜杠)。
## v0.4.9 → v0.4.10(宿主 0.2.0-rc.1 → 0.2.0-rc.2)
> **结论先行**:**代码零改动**,只是锚点前移。rc.2 现为 `latest`。
```bash
npm i -g @deepseek-ai/dsh@0.2.0-rc.2
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.4.10"
dsh --profile
```
### 为什么是零破坏
双版本 tarball diff:`dsh-agent` / `dsh-llm` / `dsh-tools` / `dsh-session` 的
**peer 键集合差异 0 行**、`lib/types` **逐文件 0 个不同**。rc.2 的改动全在宿主与
Web/桌面侧。
### 两条官方变更与本项目的关系
- **模型目录更新到 pi-ai 0.87.1,部分旧模型 ID 被移除**:实测本机未触发任何
`unknown/invalid model` 错误;若你保存过已移除的模型 ID,用 `/model` 重选即可。
- **实验性异步问答模式**:仅 Web/桌面侧,未出现在插件可达的服务面,TUI 无需接入。
### ⚠️ 另有两个插件需前移锚点
`dsh-memory@0.2.2`(精确锚 `0.2.0-rc.1`)与 `dsh-chat-interaction@0.2.0`
(`^0.2.0-rc.1` —— **prerelease 的 caret 不跨 rc**,故 rc.2 也不匹配)。
## v0.4.8 → v0.4.9(宿主 0.1.7-rc.2 → 0.2.0-rc.1)
> **结论先行**:**代码零改动**只是锚点前移(外加一项结果未知的呈现改进)。
> 0.2.0-rc.1 在 `next` dist-tag 上,`latest` 仍是 0.1.7-rc.2。
### 升级步骤
```bash
npm i -g @deepseek-ai/dsh@0.2.0-rc.1
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.4.9"
dsh --profile
```
### 为什么这次是零破坏
双版本 tarball diff:`dsh-agent` / `dsh-llm` / `dsh-tools` 的类型面**各 0 文件不同**,
peer **键集合完全相同**;`dsh-session` 仅**新增**一个类型导出 `ToolCallRecovery`。
### 本版同时改进:工具结果未知的呈现
0.2.0 修复了"工具调度异常后对话无法继续",并明确**结果未知的操作要先核实副作用、
不盲目重试**。本版据此把 `TOOL_OUTCOME_UNKNOWN` 从普通失败里区分出来(`⚠` + 先核实提示),
因为它可能**已经生效** —— 标成 `✗` 会诱导重跑一件已经发生过的事。
### ⚠️ 另外两个插件也需要前移
实测 `dsh-memory@0.2.1`(精确锚 `0.1.7-rc.2`)与 `dsh-chat-interaction@0.1.8`
(范围未含 0.2.0)会被 0.2.0-rc.1 跳过,两者都要各自发布新锚点。
## v0.4.7 → v0.4.8(宿主 0.1.7-rc.1 → 0.1.7-rc.2)
> **结论先行**:**代码零改动**,只是 peer 锚点前移。rc.2 已成为 `latest`。
> 但 peer 是**精确版本**,所以 v0.4.8 与 rc.1 宿主**不匹配** —— 请宿主与本插件一起升。
### 升级步骤
```bash
# 1) 先升宿主(rc.2 现在是 latest)
npm i -g @deepseek-ai/dsh@latest
# 2) 再升插件
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.4.8"
# 3) 重启
dsh --profile
```
### 为什么这次是零破坏
双版本 tarball diff 逐包比对 `lib/types` 与 `peerDependencies`:
- `dsh-agent`:类型面**完全一致**
- `dsh-llm`:**纯新增**(`ACCOUNT_QUOTA_EXCEEDED_CODE` / `projectToolUpdates` /
`ToolUpdate` / `ToolHistory` / `ProjectedToolUpdates`,以及可选字段 `toolUpdate`)
- `dsh-tools`:**纯新增**(审批决策的可选 `displayReason`)
无移除、无签名变更。peers 本身逐字节相同,所以只有锚点字符串变了。
### ⚠️ rc.2 会跳过锚在 rc.1 的插件
升级宿主后,profile 里**每个锚定 `0.1.7-rc.1` 的插件都会被整个跳过**:
```
dsh: skipping profile bundle "dsh-memory": Error: Plugin dsh-memory@0.2.0 is
incompatible with dsh 0.1.7-rc.2: peerDependencies {…}
```
**这不是本插件的问题** —— 是 peer 精确锚点与 rc.2 兼容性检查共同作用的结果。
排查方法:把启动 stderr 抓下来看 `skipping profile bundle` 那几行,逐个项目前移锚点。
若你暂时不想动这些插件,可以**留在 v0.4.7 + rc.1**(那一组是自洽的)。
## v0.4.6 → v0.4.7(宿主 0.1.5-rc.2 → 0.1.7-rc.1)
> **结论先行**:这是**跨宿主版本**的升级,**不是**零破坏。插件与宿主必须一起动,
> 且升级后**必须重启**。若你暂时不想动宿主,**请留在 v0.4.6**(它锚定 0.1.5-rc.2)。
### 升级步骤
```bash
# 1) 先升宿主(0.1.7-rc.1 在 next dist-tag 上)
npm i -g @deepseek-ai/dsh@0.1.7-rc.1
# 2) 再升插件(git 依赖用 add 带新 tag,update/--latest 推不动 git ref)
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.4.7"
# 3) 重启
dsh --profile
```
### 为什么是破坏性的:锚点语义变了
0.1.5 时期 peer 是**区间**(`^0.1.5-rc.2`),于是 rc.1 与 rc.2 可互换。
0.1.7 的 peer 改成**精确版本**:
```
"@deepseek-ai/dsh-agent": "0.1.7-rc.1" ← 无 ^
```
本插件随之精确锚定,**不能再跨 rc 混用**。若插件声明 0.1.7-rc.1 而宿主仍是
0.1.5-rc.2,peer 不匹配,且类型面已按 0.1.7 校验,运行可能报错。
### 本次适配的三处改动
1. **`source.kind` 的 `'plugin'` 被官方移除**(真破坏性变更)。
`MessageSourceMap` 改为「每个生产者在自己的模块里声明自己的 kind」,
官方注释明确 *there is no shared catch-all `plugin` kind*。
本插件按官方范例(`dsh-tools` 的 `tool-registry`)用 module augmentation
自建 `'nvim-tui-todo-guard'`,并交叉 `ContextFormed` 以保留
`form: 'notice'` + `summary`(渲染层靠这对字段把注入内容折叠成一行 dim notice,
而不是伪装成用户输入)。
2. **PTC 服务改名**:`dsh-code-runtime*` 止于 0.1.5-rc.3,0.1.7 换成
`dsh-ptc-runtime`(服务名 `ctx.codeRuntime` → `ctx.ptcRuntime`)。
服务清单**双列两代**,因此 0.1.5 与 0.1.7 宿主都能正确报告 `/deps` 状态。
3. **peer 锚点精确化** + devDependencies 补齐 0.1.7 新增的 peer 集
(`dsh-workspace` / `dsh-sandbox(-policy)` / `dsh-ptc-runtime` /
`dsh-scope` / `dsh-session(-projection)` / `dsh-system-prompt` /
`dsh-typert-protocol` / `dsh-invariants` / `dsh-util-values` /
`dsh-user-approval` / `cordis ~4.0.4`)。本地装需 `--legacy-peer-deps`
(这些包互相 peer 依赖同一精确版本,npm 严格解析无解;运行时由宿主提供)。
### 本版修复:startup 警告不再画到输入框
升到 0.1.7 后,`dsh: warning: 1 entry did not activate` 会出现在**输入框那一行**并把
光标顶到状态栏上。根因:`dsh` 进程自己持有终端(`fd0/1/2 → /dev/ttysNNN`),
而插件跑在它 spawn 的 `nvim --embed` 里(fd 全是 unix socket);宿主用
`process.stderr.write` 写激活诊断,裸字节直接落到我们正在画的终端上(这些字节
**不在任何 buffer 里**,只在终端字节层)。
本版在**模块顶层**接管 `process.stderr.write`(警告来自 dsh 重写 `cordis.yml`
触发的 reload,发生在插件求值之后,故顶层足够早),缓冲后**回放进聊天区**。
**诊断不丢**;`DSH_NVIM_TUI_HOST_STDERR=raw` 可关闭接管。
> 你仍会看到那行警告 —— 但它现在**在聊天区**(带 `· `前缀),而不是画在输入框上。
### 本版未做的适配(有意)
0.1.7 的新功能 —— MCP 资源发现与 URI 模板、headless `--json`、插件管理页、
侧边栏预览等 —— **绝大多数是宿主/Web 侧实现**。TUI 通过既有服务面
(如 `tools.schemas()`,签名未变)自然获得,**不需要 TUI 侧改动**。
Agent Team 面板、Word/Excel 预览、语音转写等为 Web 专有,TUI 不涉及。
### 验证
- 类型面:`check`(含 arch-check / app-ops-check)/ `smoke` / `i18n`
对着 0.1.7-rc.1 的真实类型面全绿(`tsc --noEmit` 0 错)。
- **真机 e2e**:隔离 `DSH_HOME` 内装 0.1.7-rc.1 宿主 + link 本插件,headless 跑通
(`EXIT=0`、dump 正常、版本横幅 / history replay / turn 开合 / 状态栏渲染均正确)。
## v0.4.5 → v0.4.6(发布物修正 + 门禁加固,零破坏)
> **结论先行**:只升插件即可,不需要动宿主、不需要改 `cordis.patch.yml`。
> peer 锚点仍为 `^0.1.5-rc.2`。**若你已装 v0.4.5 可不必升级**(残留文件无人引用,
> 不影响运行);**新装请用本版**。
### 升级步骤
```bash
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.4.6"
dsh --profile # 重启生效
```
### 本版修正
- v0.4.5 的包里残留了两个已删除功能的编译产物
(`lib/commands/commands/bell.{js,d.ts}`)—— 因为 `lib/` 既提交进 git
也随包发布,而 **tsc 不会清理已删源文件的产物**。本版已清除。
- 为此在 `check-arch` 增加第 9 条规则:`lib/` 下每个产物都必须有对应源文件,
否则门禁失败。以后这类残留不会再流到发布物。
## v0.4.4 → v0.4.5(移除 /bell 与终端通知,零破坏)
> **结论先行**:只升插件即可,**不需要动宿主、不需要改 `cordis.patch.yml`**。
> peer 锚点仍为 `^0.1.5-rc.2`(本版未改)。
### 升级步骤
```bash
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.4.5"
# TUI 内等价命令:/plugin update kovey/dsh-nvim-tui#v0.4.5
dsh --profile # 重启生效
```
### 本版变更
- **`/bell` 命令已删除**,响铃与终端通知(OSC 9 / 777)功能一并移除。
原因:插件所在的 nvim 以 `--embed` 启动,其 `fd 0/1/2` 是 nvim↔宿主的 unix
socket(`vim.uv.guess_handle(1)` 报 `"pipe"`),**从 Lua 侧没有任何通道能到达
终端** —— 写转义不但无效,还会摧毁终端显示(v0.4.2 的真实事故:表现为「TUI
窗口消失」但进程没死)。若你之前配置过 `/bell`,该设置不再有任何作用。
- 命令总数 47 → 46。`/help` 与补全里不再出现 `/bell`。
- **`check-arch` 规则 3c 修复两处盲区**(只遍历已登记文件、正则漏 `W()` 写法)。
修好后暴露出 7 处此前静默的跨域写,已按既有模式显式登记归属。这对使用者无行为
影响,但意味着以后命令层的架构违规不会再被门禁放过。
### 若你在 v0.4.2 / v0.4.3 上遇到过显示异常
那些版本的终端通知会向 RPC 通道写转义序列并透传到终端,导致显示被摧毁、乱码
(`64;1;2;4;6;17;18;21;22c` 这类设备属性应答滞留回显)。升级到本版即可根治
(功能已不存在)。
## v0.4.3 → v0.4.4(崩溃修复,零破坏)
> **结论先行**:只升插件即可,**不需要动宿主、不需要改 `cordis.patch.yml`**。
> peer 锚点仍为 `^0.1.5-rc.2`(本版未改)。**这是崩溃修复,建议尽快升级。**
### 升级步骤
```bash
# git 依赖:用 add 带新 tag 重写 ref(update/--latest 推不动 git ref)
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.4.4"
# TUI 内等价命令:/plugin update kovey/dsh-nvim-tui#v0.4.4
dsh --profile # 重启生效
```
### 本版修复
- **非 TTY 不再发射转义序列**(v0.4.2 引入的回归)。原 `raw()` 无条件往 `io.stdout`
写 OSC/BEL,未检查 stdout 是否为终端;在管道 / headless / 重定向场景泄漏出去的
序列会让终端产生**无人读取的设备属性应答**,滞留字节污染 nvim RPC 流,导致会话
异常退出。现加 `stdout_is_tty()` 守卫,两侧保守(探测失败即拒绝发射)。
- 若你曾在终端见到类似 `64;1;2;4;6;17;18;21;22c` 的乱码,那正是该应答 —— 升级后
不再出现。
### 排查提示
该崩溃**不会留下有用的错误日志**(字节层即被打断,`uncaughtException` 上下文不足)。
若以后再遇到「会话莫名退出」,优先看**终端里的乱码**而不是日志。
## v0.4.2 → v0.4.3(插件升级,零破坏)
> **结论先行**:只升插件即可,**不需要动宿主、不需要改 `cordis.patch.yml`**。
> peer 锚点仍是 `^0.1.5-rc.2`(本版未改)。
### 升级步骤
```bash
# git 依赖:必须用 add 带新 tag 重写 ref(见文首说明;update/--latest 都推不动)
dsh plugin --profile nvim-tui add "kovey/dsh-nvim-tui#v0.4.3"
# TUI 内等价命令:/plugin update kovey/dsh-nvim-tui#v0.4.3
dsh --profile nvim-tui # 重启生效
```
### 本版新增
- **`/plugin update`**:补齐安装的对称操作。此前 `/plugin` 只有 install/remove,
目录外插件在 TUI 里没有更新入口。npm 依赖用 `update [--latest]`;
**git/tag 依赖用 `update `**(内部路由到 `add`)。
- `/market update-all` 现在会**点名哪些 git/tag 依赖未被推进** —— 它跑的
`pnpm update` 不带 `--latest`,对 git 依赖无效,此前会让人误以为「全部已更新」。
### 本版修复
- **更正了本文档此前 9 处关于 git 依赖升级的错误说法**(原写「必须带 `--latest`」)。
实测:`update --latest` 对 `github:…#tag` **无效**(只重写 npm semver 范围),
且它会**成功退出却什么都不改**。唯一有效的是 `add` 带新 ref。
## v0.4.1 → v0.4.2(插件升级,零破坏)
> **结论先行**:只升插件即可,**不需要动宿主、不需要改 `cordis.patch.yml`**。
> peer 锚点仍是 `^0.1.5-rc.2`(本版未改),宿主 0.1.5-rc.2 无需变动。
### 升级步骤
```bash
# git 依赖:必须用 add 带新 tag 重写 ref(update/--latest 都推不动 git ref —— 已实测)
dsh plugin --profile nvim-tui add "kovey/dsh-nvim-tui#v0.4.2"
# TUI 内等价命令:/plugin update kovey/dsh-nvim-tui#v0.4.2
dsh --profile nvim-tui # 重启生效
```
> 本版改动了 Lua 侧模块(含 `rpc.lua`、新增 `goto_file.lua`)与 nvim 启动期
> 预加载列表,**必须重启**才能生效 —— 运行中的实例不会热加载。
### 本版新增
- **鲸鱼重做**:从**官方 logo 矢量路径**离线光栅化(不再是手绘网格),按窗口宽度
分 24/32/48 列三档,含呼吸浮动 + 喷气动效。
- **待办清单闭环**:新增回合收尾闸,未完成项会真正走完「实时更新 → 落盘 → 清槽」;
并修掉状态栏徽标在清单结束后不清的缺陷。
- **审批历史** `/approvals`:本会话的批准/拒绝记录,**按会话落盘、重启后仍在**。
- **会话日志健康检查**:`/doctor` 现在会点名曾有日志故障的会话(依据 host 留下的
`.corrupt-backup`),并给出可执行的出路(`/fork` / `/export`)。
- **从转录行跳到文件**:`f` / `gF` 打开光标所在行引用的文件(支持 `:LINE`)。
### 本版修复
- **响铃无声**:`R.bell()` 原先用 `vim.api.nvim_out_write`,该 API 把文本当 **UI
消息**派发、不写 fd,因此响铃自写下起就是无声的。(**后续处置**:该功能连同其
OSC 通知已在 v0.4.5 整体移除 —— 插件所在的 nvim 以 `--embed` 运行,stdout 是
RPC socket 而非终端,任何原始转义都到不了 tty,反而破坏显示。)
- **审批点缺提醒**:`/bell` 的两个调用点(回合结束、审批请求)此前只接了一个。
### 已知问题(不影响升级)
- **终端级完成通知(OSC 9 / 777)在本机实测无效**:插件所在的 nvim 以 `--embed`
启动,其 stdout 是与宿主通信的管道,字节到不了终端。`/bell` 的响铃同样受影响。
代码已放在正确方向(`io.stdout`),但接通需由持有 tty 的进程发射,**本版未完成**。
已在 `rpc.lua` 标注 `NOT WORKING — UNRESOLVED`,不重复试错。
## v0.4.0 → v0.4.1(插件升级,零破坏)
> **结论先行**:只升插件即可,**不需要动宿主、不需要改 `cordis.patch.yml`**。
> peer 锚点从 `^0.1.5-rc.1` 改为 `^0.1.5-rc.2`,而该区间**仍接受
> 0.1.5-rc.1**(下界 rc.2、上界 `<0.2.0`),所以 rc.1 与 rc.2 宿主都可用。
### 升级步骤
```bash
# git 依赖:用 add 带新 tag 重写 ref
dsh plugin --profile nvim-tui add "kovey/dsh-nvim-tui#v0.4.1"
dsh --profile nvim-tui # 重启生效
```
### 本版新增
- **`/plugin` 命令(新)**:市场目录之外的插件直装入口:
`/plugin install `(npm 包名 / `owner/repo` / git URL)、
`/plugin remove `、`/plugin list`。`/market` 只覆盖精选目录里的
2140+ 插件,小众/私有插件搜不到时用这条。
命令**不在** `TUI_COMMAND_WHITELIST` 内,agent 侧无法调用它。
### 本版修复
- **`/deps install` 不再全量跳过**:安装根探测补上 dsh 自带的 store
(`/node_modules/@deepseek-ai/*`)与共享 store
(`$DSH_HOME/profiles/node_modules`),并修掉一处候选根层级错误
(旧写法展开成 `…/node_modules/node_modules/…`,永不命中)。
另把「定位不到安装根」与「包确实不存在」区分开,提示不再误导。
- **e2e 无凭证时不再假报 PASS**:判定排除用户回显与注入上下文,并补中文
`未检测到 API key` 标记(此前只认英文,中文宿主漏判)。
同时修掉一处反向缺陷:以 `· ` 项目符号作答的正常回合曾被整段误判为
「无助手内容」而 FAIL。
### 从源码开发时
```bash
npm run check # tsc 双 tsconfig + 架构/域操作门禁
npm run smoke # 无头冒烟(含 e2e 判定与安装根候选的回归断言)
npm run e2e -- "你好" # 真机 e2e(需凭证:本机 API key 在 ~/.zshrc,需先 source)
npm run i18n:report # i18n 漂移报告
```
---
## 宿主 0.1.5-rc.1 → 0.1.5-rc.2(零破坏)
> **结论先行**:这次宿主升级**不需要任何插件代码改动**。rc.1 与 rc.2 的
> 发布包**运行时代码与类型面逐字节相同**,差异只有版本号与 peer 区间。
### 为什么是零破坏(核实方法可复现)
按仓库既有约定("双版本 tarball diff + scratch 宿主真机 e2e")逐层核对:
```bash
# 1) 取两版全部 15 个 @deepseek-ai 包的 tarball
# https://registry.npmjs.org/@deepseek-ai//-/-.tgz
# 2) 逐文件 sha256 比对
```
核对结果(15 个包 / 212 个文件):
| 项 | 结果 |
|---|---|
| 文件内容逐字节相同 | **197** |
| 仅版本号变动(均为 `package.json`) | **15** |
| 运行时代码 / `lib/types/*.d.ts` 差异 | **0** |
| 仅单侧存在的文件 | **0** |
`package.json` 的差异也只是 `version` 字段与内部 peer/依赖区间
(`^0.1.5-rc.1` → `^0.1.5-rc.2`);忽略键序后**全部内容等价**,无依赖增删。
官方侧同样印证:release notes 只列两项 **web UI** 体验优化(消息反馈弹窗
确认、交付文件卡片排版与图标),commit 区间 `dsh-v0.1.5-rc.1...dsh-v0.1.5-rc.2`
仅 4 个提交,非 `package.json` 的改动全部落在 `apps/web/tests/*` 与
`packages/client/*`(Web 客户端 React 组件,不随 npm 包发布)。
### 升级步骤
```bash
# 1) 升级宿主(rc.2 目前挂在 next dist-tag 上)
npm i -g @deepseek-ai/dsh@next
dsh --version # 期望 0.1.5-rc.2
# 2) 依赖树对齐(仅从源码开发时需要)
cd <本仓库> && npm install # peer 锚点已改为 ^0.1.5-rc.2
```
> ⚠️ **`rc.2` 是预发布版,不是稳定版**。npm 的 `latest` dist-tag 仍停在
> `0.1.0-rc.6`,`0.1.5-rc.2` 只挂在 `next` 上 —— 安装时必须显式 `@next`,
> 否则会装到旧的 `latest`。
### 兼容性说明
- **peer 区间**:`^0.1.5-rc.2` 本身**仍接受** `0.1.5-rc.1`(以及 rc.3、
最终 0.1.5)—— 语义化版本里 `^0.1.5-rc.N` 的下界是 `0.1.5-rc.N`,
上界是 `<0.2.0`。因此 rc.1 宿主不会被这次锚点变更拒之门外。
- **无需回滚预案**:两版代码同构,升/降级只影响宿主版本号本身。
- **会话日志**:rc.2 **没有**引入新的日志格式变更,V3 迁移结论与 rc.1 相同。
---
## v0.3.4 → v0.4.0(含宿主 0.1.2-rc.1 → 0.1.5-rc.1)
> **版本说明**:原计划的 `v0.3.5` 未单独打标签发布,其内容并入 v0.4.0。
> v0.4.0 的 peer 依赖锚点是 **`^0.1.5-rc.1`**:与 0.1.2-rc.1 宿主**不混用**
> (0.1.2 宿主请留在 v0.3.4)。
### 必须做的三步
```bash
# 1) 升级宿主(next dist-tag 当前即 0.1.5-rc.1)
npm i -g @deepseek-ai/dsh@next
dsh --version # 期望 0.1.5-rc.1
# 2) 升级插件到 v0.4.0(git 依赖用 add 带 tag,见文首说明)
dsh plugin --profile nvim-tui add "kovey/dsh-nvim-tui#v0.4.0"
# 3) 依赖树对齐(v0.4.0 起 devDependency/lockfile 也锚定 0.1.5-rc.1;
# 只有从源码开发才需要)
cd <本仓库> && rm -rf node_modules package-lock.json && npm install
dsh --profile nvim-tui # 重启生效(HMR 不足以换掉 peer 依赖)
```
### 行为变化(升级后你会看到)
- **会话日志迁移到 V3**:宿主首次启动会迁移既有日志;`nvim-tui` 的历史/恢复/
分叉消费面已随迁(旧日志仍可读,但**不要**用旧版插件读新日志)。
- **默认模型换代**:新会话默认 `deepseek-flash`(自带 image 模态);识图候选
优先 `deepseek-flash`,并对目录中任意 image 模态模型兜底。
- **`/rewind` 在新宿主降级**:0.1.5-rc.1 移除了 `session.truncate`,命令改为
明确提示不可用;规避方式:`/fork` 派生新会话,或留在 0.1.2 宿主。
- **待办清单纪律默认开启**:每个 agent 作用域注入常驻 system-prompt 段落 +
`agent/pre-step` 逐步提醒(每回合最多 3 条)。关闭方式:
`config.todoGuard: false` 或环境变量 `DSH_NVIM_TUI_TODO_GUARD=0`。
- **`/difficulty` 更严格**:档位模型切换前会做目录(`listModels`)与
`reasoningEffort` 兼容校验,不匹配时跳过并提示,而不是让回合报适配器错误。
- **`/theme`、`/density` 偏好持久化**到 `$DSH_HOME/dsh-nvim-tui-state.json`
(与"上次活跃会话"同一文件);`/theme default` 现在会真正清除上一预设。
- **`/deps install` 真正可用**:此前因安装根解析错误而**恒为空操作**(宿主包在
dsh 安装根的 `node_modules` 下,旧实现只查 profile 根);同时 `pnpm` 版本探测
修复。装配后按运行 profile 写入,等待热重载,必要时自动重启。
- **`/locale zh|en` 双向**:en 模式覆盖已补全(628 键 / 0 未翻译 / 0 死键),
且切回中文可用(此前在 en 启动后无法还原)。
### 从源码开发时新增的门禁
```bash
npm run check # src + scripts 双 tsconfig(TypeScript 严格性已拉满)+ 架构/域操作门禁
npm run smoke # 无头冒烟(含 0.1.5 双宿主兼容断言)
npm run i18n:report # i18n 漂移报告(死键 / 未翻译 / 未包装字面量)
```
TypeScript 严格性:`strict` + `noUnusedLocals/Parameters` +
`noUncheckedIndexedAccess` + `noPropertyAccessFromIndexSignature` +
`exactOptionalPropertyTypes` + `verbatimModuleSyntax` + `noImplicitOverride` +
`noFallthroughCasesInSwitch` + `noImplicitReturns` + `allowUnreachableCode:false`。
宿主边界用**条件展开**表达"缺省 ≠ 显式 undefined"。
### 宿主侧破坏性变更(插件已适配,供排查用)
- **`ctx.sessions` 服务移除**:live 会话存储并入 `ctx.agents`(`agents.get/list`
返回的 Agent 携带 `.session`)。TUI 注入面改为 `['agents','agentDefaultModel']`
并自建 sessions 适配器。
- **Session 生命周期 / V3 日志**:`sessionPersistence` 改为 `list()`(快照
`{header,revision,…}`)+ `open(id,'read').read()` 的 SessionHandle 模型;
surface replace 拼写改为 `startSeq/endSeq`;新增 `system/message` 事件。
TUI 的会话历史 / 子代理冷读 / 自愈修复全部随迁。
- **subagents 续聊**:符号键 `queueSubagentPrompt` 移除,改为公开
`subagents.prompt({requestId, parentSessionId, childSessionId,
mode:'continuable', delivery:'queue'|'steer', content}, signal)`
(旧宿主仍走符号键路径兼容)。
- **默认模型换代**:新会话默认 `deepseek-flash`(DeepSeek-V41-Flash,自带
image 模态)。
```bash
npm i -g @deepseek-ai/dsh@next # next dist-tag 现为 0.1.5-rc.2(rc.1 亦可)
dsh --version # 应输出 0.1.5-rc.2(运行中的进程需重启生效)
# 插件侧(git 依赖):dsh plugin --profile add "kovey/dsh-nvim-tui#"
```
> 当前 `next` dist-tag 已从 0.1.5-rc.1 前进到 **0.1.5-rc.2**;两者对本插件
> 等价(逐字节同代码),rc.2 的锚点更新见文首
> [宿主 0.1.5-rc.1 → 0.1.5-rc.2](#宿主-015-rc1--015-rc2零破坏)。
> 会话日志由宿主自动迁移到 V3 格式(旧文件保留);升级后的会话不支持降级
> 读取,回退宿主版本前请先导出需要保留的会话。
---
---
# 历史指南:dsh 0.1.2-alpha.5 → 0.1.2-rc.1
dsh-nvim-tui v0.2.14 将 peer 依赖锚点抬升至 **`^0.1.2-rc.1`**。升级前已做
全量 API 核对:rc.1 与 alpha.5 的类型面**逐文件零差异**(dsh-agent /
dsh-llm / dsh-tools / dsh-session 等 14 个包的 lib/types 全部 diff 为空),
TUI 消费的宿主服务方法(jobs.onJobsChanged/onJobDone、subagents.listChildren、
workspaceRegistry、agentPresets、permissionPresets、fileReferences、settings、
sessionQuery、messageFeedback put/list/delete、goals get/create/pause/resume/
complete/clear、tools.schemas、pluginInventory.list、agentDefaultModel
currentSelection/saveSelection 等)逐一在 rc.1 定义中存在且签名一致。
真机验证:rc.1 宿主冷启动零错误 + 真实模型 e2e 回合 PASS。
升级步骤:
```bash
npm i -g @deepseek-ai/dsh@next # next dist-tag 即 0.1.2-rc.1
dsh --version # 应输出 0.1.2-rc.1(运行中的进程需重启生效)
# 插件侧(git 依赖):dsh plugin --profile add "kovey/dsh-nvim-tui#"
```
---
# 历史指南:dsh 0.1.2-alpha.4 → 0.1.2-alpha.5
dsh-nvim-tui v0.2.14 将 peer 依赖锚点抬升至 **`^0.1.2-alpha.5`**。本次升级
对 TUI 消费面**零破坏**(alpha.5 的 SessionSeq 移除 `Session.events` 等破坏
性变更在 v0.2.12 已适配完成),主要收益:
- **损坏会话日志官方修复**:持久化扫描器遇到 seq gap 时保留连续前缀并
持久化截断修复(不再硬失败)——TUI 的历史恢复本地兜底已随之移除;
- 官方识图模型目录(`deepseek-v4-flash-vision-exp`,text+image)进入
dsh-llm-deepseek 默认目录,TUI 图片消息自动切换该模型处理;
- jobs 服务补齐 `onJobsChanged`/`onJobDone` 观察者(状态栏后台任务徽章)。
升级步骤:
```bash
npm i -g @deepseek-ai/dsh@alpha
dsh --version # 应输出 0.1.2-alpha.5(运行中的进程需重启生效)
# 插件侧(git 依赖):dsh plugin --profile add "kovey/dsh-nvim-tui#"
```
---
# 历史指南:dsh 0.1.2-alpha.3 → 0.1.2-alpha.4
> **修正(v0.2.12 之后)**:下文"无破坏性变化 / nvim-tui 消费面零改动适配"
> 的结论有误——alpha.4 的 SessionSeq 品牌化重构同时移除了 `Session.events`
> 公共属性,v0.2.12 在恢复旧会话时会抛
> `TypeError: Cannot read properties of undefined (reading 'length')`,
> `/fork` 亦失效。已修复:历史恢复等 7 处消费改走 `snapshotEvents()`
> (alpha.3 `events` 兜底),`/fork` 重写为 alpha.4 官方种子契约
> (`seed` + `inheritedEventCount` + `meta.isSeeded`),真机恢复旧会话
> 验证通过。升级插件请用含该修复的版本。
dsh-nvim-tui v0.2.12 全面适配 DeepSeek Harness **v0.1.2-alpha.4**。逐包 diff
结论:
- **父子代理双向通信(核心变化)**:`followup`(父→子)与 `reportFrom`
(子→父,alpha.3 的 `subagent-report` source + `SubagentReportOptions`
已被移除)合并为通用 **`sendMessage(sender, targetId, …)`**——相邻 Agent
互发消息,Steer 语义(运行中目标在最近步界接收、空闲目标起新回合);
source 统一为 `agent-message`;`queuePrompt` 供宿主侧人类消息入队。
标准子代理提示词改为指示子代理 `send_message({ agent_id, message })`
把结果发回父代理(父代理不自动接收子代理转录/工具输出/推理)。
- **SessionSeq 品牌化重构**:session 事件序列号全线改为 branded number
(`SessionSeq`/`SessionLogOffset`/`OptionalSessionSeq`),`seedLength` →
`isSeeded` + `inheritedEventCount`,且 `Session.events` 公共属性被移除
(改用 `snapshotEvents()` / `ownEvents()` / `eventAt()`)。nvim-tui 的
历史恢复 / 分叉消费面需相应适配(见 CHANGELOG 未发布条目)。
- 其余家族包为配套重构(invariant 模块归并、typert host 调整)。
**无破坏性变化**(nvim-tui 消费面零改动适配);peer 依赖锚点抬升至
`^0.1.2-alpha.4`,版本横幅 0.2.12。新增功能面:子代理消息高亮渲染 +
子代理文件修改实时 diff 同步到父聊天区(见 CHANGELOG)。
## 升级步骤
```bash
# 1. 升级宿主
npm i -g @deepseek-ai/dsh@alpha
dsh --version # 应输出 0.1.2-alpha.4(首次启动 profile 时共享 store
# 自动抬升到 alpha.4;运行中的进程需重启生效)
# 2. 更新 nvim-tui 插件
dsh plugin --profile nvim-tui add "kovey/dsh-nvim-tui#"
# 或固定版本
dsh plugin --profile nvim-tui add "kovey/dsh-nvim-tui#v0.2.12"
# 3. cordis.patch.yml 无需改动——alpha.4 未新增/删除 loader entry,
# alpha.3 时代的装配行(含 web-app 5 服务补全)原样可用。
```
## 验证
```bash
cd <仓库>
npm run check && npm run build && npm run smoke
npm run e2e -- "请只回复两个字:就绪"
```
**判定标准**:e2e 输出 `E2E PASS`,dump 内 `── turn ──` 与 `── turn end ──`
之间有真实助手回复(alpha.4 真机实测通过)。
**回滚**:`npm i -g @deepseek-ai/dsh@0.1.2-alpha.3`,插件退回
`kovey/dsh-nvim-tui#v0.2.11`。
---
# 历史指南:dsh 0.1.2-alpha.2 → 0.1.2-alpha.3
dsh-nvim-tui v0.2.11 全面适配 DeepSeek Harness **v0.1.2-alpha.3**。alpha.3 是
全家族(40+ 包)的**协同版本号抬升**,逐包 diff 结论:
- **19 个核心包**(dsh-agent / dsh-llm / dsh-tools / dsh-session /
dsh-user-approval / dsh-code-runtime / dsh-scope / dsh-system-prompt /
dsh-typert-protocol / dsh-typert-registry / dsh-brand / dsh-timeout /
dsh-util-crypto / dsh-util-values …)`lib/` **与 alpha.2 逐字节相同**,仅
package.json 版本号与依赖范围抬升;
- **dsh-session-projection**:行为微调——change feed 只在某单元 raw view
按 `Object.is` 变化时通知(原来是每次 state 引用变化都通知,语义收敛,
纯去重、非破坏)。nvim-tui 只读 `stateOf()`,不受影响;
- **dsh-attachment**:新增浏览器上传 API `admitPromptContent` +
`PromptContentPart` / `AdmittedPromptContentPart` 类型(纯增量)。
nvim-tui 用到的 `saveImage()` 未变;
- **dsh-invariants**:仅 README 修订。
**结论:无破坏性变化**,nvim-tui 源码零改动即可适配——本次变更只有 peer
依赖锚点抬升(`^0.1.2-alpha.2` → `^0.1.2-alpha.3`)、版本横幅(0.2.11)
与真机验证。
## 升级步骤
```bash
# 1. 升级宿主(alpha dist-tag 当前即 0.1.2-alpha.3)
npm i -g @deepseek-ai/dsh@alpha
dsh --version # 应输出 0.1.2-alpha.3
# 首次启动任意 profile 时 boot 会把共享 store(~/.dsh/profiles/node_modules)
# 抬升到 alpha.3;正在运行的 dsh 进程仍在内存里跑旧代码,需重启才生效。
# 2. 更新 nvim-tui 插件(发布版)
dsh plugin --profile nvim-tui add "kovey/dsh-nvim-tui#"
# 或固定版本
dsh plugin --profile nvim-tui add "kovey/dsh-nvim-tui#v0.2.11"
# 3. 无需修正 cordis.patch.yml —— alpha.3 未新增/删除 loader entry,
# 旧 profile 的 patch 原样可用(与 alpha.2→alpha.3 的零破坏结论一致)。
```
## 4. 推荐:profile 装配补全(激活 TUI 已有功能)
v0.2.11 的功能对比核查确认 5 个官方宿主服务是 **dsh-web-app bundle 独有**、
nvim-tui 宿主组合(dsh-base + dsh-nvim-tui)未装配的——runner 的消费面早已
实现,缺装配时对应功能空转。在 profile 的 cordis.patch.yml 追加即可(依赖
全部落在 dsh-base 已有的 storage / sessionQuery / sessionProjection 上,
无需额外行;包本体在共享 store 里已随宿主安装):
```yaml
# /fb 消息反馈(此前提示"服务未装配")
- insert:
- id: message-feedback
name: '@deepseek-ai/dsh-message-feedback'
config:
maxNoteBytes: 8192
# @ 提及的跨会话引用(此前静默失效)
- id: session-reference
name: '@deepseek-ai/dsh-session-reference'
# 状态栏 TTFT / tok-s 统计(此前投影单元不存在,永不显示)
- id: session-stats
name: '@deepseek-ai/dsh-session-stats'
# PTC 预设的 run_code 执行 seam(此前 /preset ptc 挂起不可用)
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
# 子代理独立模型选择设置
- id: subagent-model-selection-settings
name: '@deepseek-ai/dsh-tool-subagent/model-selection-settings'
```
装配后 headless 启动一次验证(alpha.2 起 boot 把 pending 条目视为致命错误,
能正常启动即证明全部激活)。
## 验证
```bash
cd <仓库>
npm run check && npm run build && npm run smoke
npm run e2e -- "请只回复两个字:就绪" # 真机:全局 dsh (alpha.3) + nvim-tui profile
```
**判定标准**:e2e 输出 `E2E PASS`,dump 里 `── turn ──` 与 `── turn end ──`
之间有真实助手回复(alpha.3 真机实测通过)。
**回滚**:`npm i -g @deepseek-ai/dsh@0.1.2-alpha.2`,插件退回
`kovey/dsh-nvim-tui#v0.2.10`。
---
# 历史指南:dsh 0.1.1-rc.2 → 0.1.2-alpha.2
dsh-nvim-tui v0.2.7 全面适配 DeepSeek Harness **v0.1.2-alpha.2**。本指南覆盖
宿主升级、插件更新、profile patch 修正、第三方插件兼容、验证与回滚的全部步骤
(每一步均经真实环境实测)。以下内容保留作历史参考。
> **v0.2.8 重要更新(会话卡死 400 insufficient tool messages)**:见
> [§0. v0.2.8:修复工具调度器崩溃与已毒化会话的自愈](#0-v028修复工具调度器崩溃与已毒化会话的自愈)。
> 升级到 v0.2.8 后按该节清理 profile 中残留的第二份 `@deepseek-ai/dsh-tools`。
>
> **v0.2.9 补充**:崩溃后又发过消息的会话(历史中间夹杂用户消息)在
> v0.2.8 下仍会 400——v0.2.9 改为按 surface 位置外科修复(就地改写悬空
> tool-calls 的 assistant 消息并中和错位结果),直接升级到 ≥ v0.2.9 再
> 打开旧会话即可自愈。
## 0. v0.2.8:修复工具调度器崩溃与已毒化会话的自愈
**症状**:agent 调用工具(如 bash)后回合崩于
`Cannot read properties of undefined (reading 'prepare')`,此后该会话**每一
轮**都被 API 以 `An assistant message with 'tool_calls' must be followed by
tool messages responding to each 'tool_call_id'. (insufficient tool messages
following tool_calls message)` 400 拒绝,会话永久卡死。
**根因**:v0.2.7 及更早把 `@deepseek-ai/dsh-tools` 声明为**普通依赖**。pnpm
安装时把它 hoist 进 profile 的 `node_modules`,与宿主自带的 dsh-tools 形成
两份物理拷贝;loader 从 profile 解析 `tools` bundle entry → `tools` 服务用
插件副本构造,`dsh-agent-loop`(宿主副本)持有的 scheduler unique symbol
对不上 → 工具派发在 tool/call 已落盘后崩溃 → 悬空 tool_call 让历史永远
重放一条没有 tool 结果的消息 → API 永久 400(宿主编排层已知问题,社区
#1337/#1633/#1665/#1677/#1697/#1959 同签名)。
**修复**:
1. 插件升级到 **v0.2.8+**(dsh-tools 改为 optional peerDependency,不再把
第二份拷贝带进 profile):
```bash
dsh plugin --profile add "kovey/dsh-nvim-tui#"
# 或固定版本
dsh plugin --profile add "kovey/dsh-nvim-tui#v0.2.8"
```
2. 清理旧版本残留的第二份拷贝(升级后仍会留在 profile 里):
```bash
cd ~/.dsh/profiles/
pnpm why @deepseek-ai/dsh-tools # 确认谁在引入副本(应为"无"或仅宿主)
pnpm dedupe # 收敛重复版本
# 若 dedupe 后仍存在 node_modules/@deepseek-ai/dsh-tools 实体目录(非
# 指向宿主的软链),删除后重装:rm -rf node_modules && pnpm install
```
验证(`tui` profile 实测命令):profile 的
`node_modules/@deepseek-ai/dsh-tools` 应为**指向宿主安装的软链**
(`~/.dsh/profiles/node_modules/…` 的共享 fallback),而不是 pnpm 装出的
实体目录。
3. **旧会话自愈(无需重建)**:v0.2.8 打开会话时自动扫描并补写悬空
tool_call 的合成错误结果(`TOOL_OUTCOME_UNKNOWN`),毒化历史重新配对,
原会话继续可用;回合内再次崩溃时也会在回合末自动补写并提示根因。
## 版本对应(peer 范围不混用)
| dsh-nvim-tui | 宿主 dsh | peer 依赖范围 |
|---|---|---|
| **v0.2.7+** | **0.1.2-alpha.2**(npm `alpha` dist-tag) | `^0.1.2-alpha.2` |
| ≤ v0.2.6 | 0.1.1-rc.2(npm `latest`) | `^0.1.1-rc.2` |
> ⚠️ 不要混用:v0.2.7 的 user-questions 走 `user-questions/request` waterfall
> 事件(rc.2 宿主没有该事件,问答会静默失效);`permission.current` 的传参
> 也不同(session vs events)。升级必须**宿主与插件同时**切换。
## 1. 升级宿主 dsh
```bash
npm i -g @deepseek-ai/dsh@alpha
dsh --version # 应输出 0.1.2-alpha.2
```
- alpha.2 修复了 Node 24.0–24.11.1 的启动/HMR 问题。
- 正在运行的 dsh 进程(含 `dsh web` GUI)仍在内存里跑旧代码,需**重启**
才生效。
## 2. 更新 nvim-tui 插件
```bash
# 直链开发 profile(依赖为 "dsh-nvim-tui": "link:<仓库路径>")
git -C <仓库> pull && cd <仓库> && npm install && npm run build
# profile 直链 lib/,无需重装依赖
# 发布版(git 依赖必须带 --latest,否则 pnpm 不重新解析分支 HEAD)
dsh plugin --profile nvim-tui add "kovey/dsh-nvim-tui#"
# 或固定版本(git ref 语法,@version 会被 pnpm 当作别名报错)
dsh plugin --profile nvim-tui add "kovey/dsh-nvim-tui#v0.2.7"
```
## 3. 修正 profile 的 cordis.patch.yml
alpha.2 有两处组合层面的破坏性变化,旧 profile 的 patch 会启动失败或功能失效:
### 3.1 删除重复的 storage 行(启动崩溃)
alpha.2 的 **dsh-base 已自带 `storage` / `storage-json` / `storage-domain`**
三行。旧 patch 里照搬 dsh-web-app 配方的这四行(storage 三件套 + workspace)
会报 `duplicate loader entry id: storage`,整个 profile 起不来。
只保留 `workspace` 行(它依赖的 storageDomain 与 sessionPersistence 均由
dsh-base 提供):
```yaml
# dsh 0.1.2-alpha.2 起 dsh-base 已自带 storage/storage-json/storage-domain
# 三行,patch 不得再重复 insert;workspace 行保留即可。
- insert:
- id: workspace
name: '@deepseek-ai/dsh-workspace'
```
### 3.2 删除失效的 shipped 预设根(/preset 功能)
旧注释「profile-boot 会自动追加 `dsh/config/agent-presets`」已过时——alpha.2
起 shipped 预设**随 `@deepseek-ai/dsh-agent-presets` 包自带**
(`includeShippedRoot` 默认开启,先于任何配置根)。patch 里显式写的
`roots: [{ path: '/config/agent-presets/', trust: system }]`
指向的目录在 alpha.2 已不存在,整个 `roots` 配置应删除:
```yaml
- insert:
- id: agent-presets
name: '@deepseek-ai/dsh-agent-presets'
config:
default: standard
```
### 3.3 pending entry 致命化:补齐依赖行(启动崩溃)
alpha.2 的 boot 把「未激活(pending)的 loader entry」视为**致命错误**
(`plugin tree failed to load: 1 entry did not activate`),旧版本里
pending 插件只是静默不可用。典型症状:
```
Error: dsh: plugin tree failed to load: dsh: 1 entry did not activate
dsh-workspaces-adapter: pending (waiting for service: workspaceRegistry)
```
bundles 里有 `dsh-workspaces-adapter` 的 profile,patch 必须补上它依赖的
`workspace` 行(dsh-base alpha.2 已自带 storage 三件套与
sessionPersistence,只加这一行即可):
```yaml
- insert:
- id: workspace
name: '@deepseek-ai/dsh-workspace'
```
排查方法:headless 启动一次(`DSH_NVIM_TUI_HEADLESS=1 dsh --profile `),
日志里 `pending (waiting for service: X)` 指向缺哪个服务,就按同样方式补
提供 X 的官方行(行名可在 `dsh --profile
--dump-config` 的
`@deepseek-ai/dsh-base` 段里查)。
## 4. 第三方插件兼容性
按启动日志逐条排查 `does not provide an export named ...`:
- **dsh-context**:`< 0.38.5` 的版本 import 了 dsh-settings 已移除的
`settingsNamespace` 导出 → `SyntaxError`。profile 的 package.json 改为
`"dsh-context": "^0.38.5"` 后 `pnpm install --no-frozen-lockfile` 重装。
- 其他插件同理:报缺失导出就查该插件是否有适配 0.1.2 的新版本;没有则
暂时从 bundles 移除该插件再逐次加回。
## 5. 验证
```bash
cd <仓库>
npm run check && npm run build && npm run smoke
npm run e2e -- "请只回复两个字:就绪" # 默认走 PATH 的 dsh + nvim-tui profile
```
**判定标准**:e2e 输出 `E2E PASS`,且 dump 里出现真实助手回复(`── turn ──`
与 `── turn end ──` 之间有回复文本,不是 `⚠` 错误行)。
**安全试跑**(不污染真实 `~/.dsh`,升级宿主前先验证代码兼容性):
```bash
# 1. scratch 安装 alpha 宿主
npm i --prefix /tmp/dsh-alpha @deepseek-ai/dsh@alpha
# 2. scratch DSH_HOME + 最小测试 profile
mkdir -p /tmp/dsh-a2-home/profiles/nvim-tui-a2
# profile/package.json:
# { "name": "dsh-profile-nvim-tui-a2", "private": true,
# "dependencies": { "dsh-nvim-tui": "link:<仓库绝对路径>" },
# "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "dsh-nvim-tui"] } } }
# profile 内再放 pnpm-workspace.yaml (packages: ['.']) 并 pnpm install
cp ~/.dsh/settings.yaml /tmp/dsh-a2-home/settings.yaml # 复用模型配置
# 3. 用覆盖项跑 e2e
DSH_HOME=/tmp/dsh-a2-home \
DSH_BIN=/tmp/dsh-alpha/node_modules/.bin/dsh \
DSH_NVIM_TUI_PROFILE=nvim-tui-a2 \
npm run e2e -- "请只回复两个字:就绪"
```
(`DSH_BIN` / `DSH_NVIM_TUI_PROFILE` 是 v0.2.7 起 e2e 脚本支持的覆盖项;
macOS 没有 `timeout` 命令,e2e 超时用 `DSH_NVIM_TUI_E2E_TIMEOUT` 控制。)
## 6. 回滚
```bash
npm i -g @deepseek-ai/dsh@0.1.1-rc.2
dsh plugin --profile nvim-tui add "kovey/dsh-nvim-tui#v0.2.6"
```
并恢复 cordis.patch.yml 中被删除的行(storage 三件套 + 旧 shipped 预设根
roots 配置),重启 dsh 进程。
## /rewind 的宿主能力说明(v0.3.2+)
`/rewind`(回退到某条消息)依赖宿主 `dsh-session` 的 `session.truncate`
原语;当前宿主编排层未公开该符号,因此命令会提示「会话截断不可用」并
建议 `/fork` 派生替代。若宿主未来公开 truncate,本插件无需改动即自动
启用该路径(代码已按能力探测降级)。