# 90-dsh 升级项目:0.1.2-rc.1 → 0.1.5-rc.1(2026-09-14 立项) - 日期:2026-09-14 | 状态:🔄 **进行中**(阶段 1 通过 / 阶段 2 进行中 / 阶段 3–4 未开始) - 触发:用户原话 ——「**先把项目的 dsh 升级到这个版本**」→ 追加「**确认执行 迟早要跟进官方的版本,不可能一直用现在这个版本**」 - 依据流程:**档案 07 §三**(版本升级流程五阶段;其红线第一条 =「**不得直接在现网执行升级**」) > **TL;DR** > 目标版本 = **`0.1.5-rc.1`**(npm `latest`;用户材料里插件 peer 也是 `^0.1.5-rc.1`,三方自洽)。 > **已在 test106 隔离完成阶段 1**(起 profile 成功、默认 53 个客户端插件)。 > **阶段 2 关键结论:0.1.2→0.1.5 在 profile 布局 / CLI / lib 形态上同构,破坏面比预期小**(详见评估表); > **我们自己的 univer 0.2.28 在 0.1.5 上:装得上(pnpm peer 容忍)、启动无报错、客户端 inject 差集为空** ⇒ 运行时可用。 > 唯一**结构性差异**:`__DSH_BOOT__` 由顶层数组改为 **`{rev, entries[], batches[]}`**。 > **生产(bt-server)本次零改动。** --- ## 一、版本判定(无需猜测,证据三方自洽) | 证据 | 值 | |---|---| | npm `dist-tags` | **`latest` = 0.1.5-rc.1**(`next` = 0.1.5-rc.2、`alpha` = 0.1.5-alpha.2) | | 用户材料里插件的 peer 范围 | `^0.1.5-rc.1`(如 `dsh-client-ui-sidebar-documentpreview` 系) | | test106 机器上已装 | `/usr/lib/node_modules/@deepseek-ai/dsh` = **0.1.5-rc.1** | (版本时间线:0.1.2-rc.1 = 09-03 → 0.1.3-alpha.2 = 09-07 → 0.1.5-alpha.1/2 = 09-08/09 → **0.1.5-rc.1/2 = 09-10**) ## 二、阶段 1 · 隔离升级测试(✅ 通过) - 环境:**test106**(OpenCloudOS 9.6 / **glibc 2.38** / node 22.23.2 / npm 10.9.8);**未跑平台**(无 `dshs`、无 `/var/lib/dshs`) - 隔离方式:`HOME=DSH_HOME=/opt/upgrade-smoke/home`、`--port 41999` ⇒ **不影响任何现有环境** - 结果:**profile 启动成功**;页面需 **token 换 cookie**(`dsh-auth-*`)后 200(27.7 KB) - 记录与复跑命令:test106 `/opt/upgrade-smoke/测试记录.md` ## 三、阶段 2 · 影响评估(🔄 进行中) ### 3.1 同构项(**风险低**,实测) | 面 | 0.1.2-rc.1(生产) | 0.1.5-rc.1 | 判定 | |---|---|---|---| | `profile/package.json` 结构 | `dsh.profile.{bundles, patchReload}` | **同** | ✅ 平台解析路径不变 | | profile 位置 | `/profiles/web` | **同** | ✅ | | `cordis.patch.yml` | 顶层数组 + `- insert: - id/name` | **同**(注释仍写 "top-level YAML array… insert lists;`!!js` 允许") | ✅ 我们的角色补丁 / bundle patch 写法兼容 | | `lib` 形态 | 带 hash 单文件(`dump-config-*.js`/`plugin-*.js`)+ `lib/bin.js` | **同** | ✅ 平台若按 `lib/bin.js` 调 CLI 不受影响 | | `dsh` 可执行 | `/usr/local/bin/dsh → …/lib/bin.js` 软链 | **同**(test106 在 `/usr/lib`) | ✅ 档案 88 的"解软链探测"继续有效 | | CLI 顶层 | `--profile` / `--patch` / `-V` | **同**,且**新增 `dsh plugin` 子命令** | ✅ 新增不破坏既有 | ### 3.2 差异项(**需处置**,实测) | # | 差异 | 影响 | 处置 | |---|---|---|---| | 1 | **`__DSH_BOOT__` 结构变更**:0.1.2 顶层数组/`modules` → 0.1.5 **`{rev, entries[], batches[]}`** | 客户端消费方 + **我们的判据脚本**(按旧结构解析会误判"行不存在" —— 本次就误判过一次) | 更新判据脚本解析;**平台代码需核是否解析它** | | 2 | **`dsh plugin add` 在带 `pnpm-workspace.yaml` 的 profile 上失败**(`ERR_PNPM_ADDING_TO_ROOT`) | 仅影响使用该新子命令的人;**平台投放通道不受影响**(平台自调 `pnpm add -w`) | 记录;必要时平台侧改调 `-w` | | 3 | 包总数 **213 → 240**(+27);默认客户端插件 **46 → 53** | 新增能力(见 3.3);也可能带来**新的默认启用项与角色补丁冲突** | 逐项核角色补丁 6 个禁用项在 0.1.5 是否仍存在(`ui-cordis`/`hmr` 初查仍在 ✓) | | 4 | 我们**已装插件**的 peer 精确锁 `0.1.2-rc.1`(univer fork ×7 包、`@softspark/dsh-file-preview`) | 平台**兼容预检**会判 `incompatible`(`dep-range`)而拒绝投放;**但运行时实测可用**(见 3.4) | univer fork 放宽 peer 范围(`0.1.2-rc.1 \|\| 0.1.5-rc.1`)后重编 → 新版本;`file-preview` 可直接**退役** | | 5 | 0.1.5 的 `dsh-client-ui-sidebar-documentpreview` **默认下发**(inject 已满足) | 与已装的 `@softspark/dsh-file-preview` **功能重叠** | 退役后者(少一个第三方依赖) | ### 3.3 升级收益(实测) | 收益 | 证据 | |---|---| | **原生侧栏文档预览**(Markdown / 代码 / 纯文本 / PDF / HTML / 图片) | `dsh-client-ui-sidebar-documentpreview` 在 53 个默认客户端插件里,inject = `api-gateway` / `api-workspace-files` / `sidebar-right` / `ui-layout` / `ui-session`(**全部满足**) | | **Office 预览有官方扩展点** | `documentPreviews` 注册表存在于该包(`ctx.documentPreviews.register(...)`)⇒ 可自研注册 xlsx/docx 渲染器 | | better-sidebar 那批插件变可用 | `dsh-client-ui-sidebar-right` ✅ 默认下发(0.1.2 无 ⇒ 之前是硬拦路虎) | | 产出文件 chips 机制不变 | `dsh-client-ui-deliverables` ✅ 仍在(服务器上仍只能走"预览","用默认应用打开"依旧 `nativeUnavailable`) | ### 3.4 我们插件的实测装载(**最关键的硬数据**) 在 0.1.5-rc.1 隔离 profile 里装 `dsh-univer-office@0.2.28`(`pnpm add -w file:…` + 写入 `dsh.profile.bundles`): | 检查 | 结果 | |---|---| | 安装 | ✅ 成功(pnpm 9 对 peer 冲突**容忍**,未失败) | | 启动 | ✅ 无报错(日志仅 `dsh web: …?token=…`) | | **客户端半边** | ✅ 页面清单**出现** `dsh-univer-office`(相对干净 profile 的**新增项就是它**) | | **inject 差集(老坑判据)** | ✅ **6 个 inject 全满足,差集为空** ⇒ **不会静默挂起** | ⇒ **结论:univer 在 0.1.5 上运行时可用**;阻塞点只在**平台兼容预检的 peer 范围**(属可修的声明问题)。 ## 四、阶段 3(差异修复)待办清单 1. **univer fork**:放宽 7 个 peer 范围 → 重编 → 出 0.2.29(同时把 `dsh.client.inject` 保持在"页面实测可满足"的集合内); 2. **判据脚本 / 平台代码**:适配 `__DSH_BOOT__` 新结构(核平台是否有解析点); 3. **角色补丁**:逐项核 6 个禁用项包名在 0.1.5 的存在性(缺则补/改名); 4. **清理**:`@softspark/dsh-file-preview` 退役(被原生取代); 5. **DB / sessions / 平台自研插件**:尚未核(下一轮重点:`dshs.db` schema、session zstd 格式、`@dsh-local/*` 的官方 API 依赖面)。 ## 五、阶段 4(整体更新)—— **需用户确认** - 影响:**全体用户**(全局 dsh + 全部 profile + 全部实例重启) - 前置:阶段 2 剩余项核完 + 阶段 3 修复完成 + 在 test106 跑通完整回归 - 回滚:`/opt/dsh/backups/` + profile 快照(档案 07 §三 阶段 5) ## 六、本次的纪律说明(**生产零改动**) - 全程**未触碰生产**(bt-server):只做只读比对 + 在 test106 隔离目录内操作; - test106 上为测试**装了 pnpm@9**(测试机,与生产无关); - 冒烟进程均已停止;隔离目录保留(含测试记录)供下一轮继续。 --- ## 追加(2026-09-14 20:0x · 阶段 2 收尾 + 阶段 3 首项完成 + **一处自我更正**) ### 一、⚠️ **更正 3.2 差异项第 1 条**(重要,防误导后续修复) 原文写的「`__DSH_BOOT__` 结构变更:0.1.2 顶层数组 → 0.1.5 `{rev, entries[], batches[]}`」**是错的**。 **实测证据**:在**生产(0.1.2-rc.1)**页面上按 `entries` 解析**成功**——顶层键同样是 **`['rev','entries','batches']`**,行数 47。 ⇒ **两版的 boot 结构同构**;我先前的"差异"来自**我自己的解析正则过时**(只在新结构上试通过),不是版本差异。 ⇒ **"结构性差异"归零**:0.1.2 → 0.1.5 在 **profile 布局 / patch / CLI / lib 形态 / boot 结构**上**全部同构**。 ### 二、阶段 2 收尾(剩余未知项已核完) | 待核项 | 结论 | |---|---| | **角色补丁 6 个禁用项包名**在 0.1.5 是否存在 | ✅ **6/6 全部存在**(`ui-settings-models` / `-settings-plugins` / `-settings-plugin-inventory` / `ui-cordis` / `dsh-client-hmr` / `dsh-host-directory-picker-auto`)⇒ **角色补丁不用改** | | 平台自研插件的 client inject 在 0.1.5 是否可满足 | ✅ `business-plugins` / `portal-entry` 只 inject `dsh-client-ui-settings-general`(在 ✓)、`workspace-scoped-picker` inject `[]` ⇒ **不会挂** | | `dsh-plugin-mcn-suite` | ⚠️ inject 含 **`@deepseek-ai/dsh-client-runtime`**(0.1.2 与 0.1.5 **都没有**)⇒ 它的浏览器半边**本来就挂**(**既有问题**,与升级无关) | ### 三、阶段 3 · 首项完成:**univer fork 放宽 peer → 0.2.29(已投放)** - 改动:7 个 `@deepseek-ai/dsh-*` peer 由 `0.1.1-rc.2 || 0.1.2-rc.1` **追加 `|| 0.1.5-rc.1`**(原先**不是**精确锁 —— 早先被预检拒的是 `@huiliyi37/dsh-office`,记混过一次); - 构建:`pnpm pack` → `dsh-univer-office-0.2.29.tgz`(md5 `4f6ace5924649c86ff2c463c5d8b5264`); - **投放并验证**:admin 导入候选池 ⇒ **`compat.level = ok`**(放宽后的范围被认可,将来 0.1.5 也会 ok)⇒ 停用/启用 ⇒ 实装 **0.2.29** ⇒ 页面 univer 行 **inject 差集 = 无** ⇒ 实例 active; - 对现有 0.1.2 生产**零行为变化**(只改声明)。 ### 四、阶段 3 剩余待办 | # | 项 | 状态 | |---|---|---| | 1 | univer fork 放宽 peer → 0.2.29 | ✅ **完成并投放** | | 2 | `__DSH_BOOT__` 适配 | ✅ **无需适配**(两版同构;更正后归零) | | 3 | 角色补丁 6 项核对 | ✅ **无需改动**(6/6 存在) | | 4 | `@softspark/dsh-file-preview` 退役 | ⏳ **等阶段 4 之后**(现在退役 = 生产失去预览能力,因为 0.1.2 无原生预览)—— **顺序纪律** | | 5 | `dshs.db` schema / session zstd 格式 / `@dsh-local/*` **host 侧** API 依赖面 | ⏳ 未核(下一轮) | --- ## 追加(2026-09-14 19:5x · **阶段 3 完成 + 阶段 4 执行成功 —— 项目收口**) ### 一、阶段 3 完整隔离回归(✅ 全绿) 在 test106 隔离 profile 里装**平台全部 5 个插件**(business-plugins 0.3.13 / portal-entry 0.5.2 / workspace-scoped-picker 0.1.5 / `@softspark/dsh-file-preview` 2.0.0 / univer 0.2.28)+ 对齐生产角色补丁: | 检查 | 结果 | |---|---| | 启动 | ✅ **0 错误行** | | 页面 | ✅ 200(28.9 KB),客户端插件 **57** | | 5 个插件 inject 差集 | ✅ **全部为"无"**(含 picker) | ⚠️ **过程中两次自我纠错(都是"我的配置不全",不是 0.1.5 兼容问题)**: 1. `workspace-scoped-picker` 首轮**不在页面清单** ⇒ 根因是它的 `cordis.patch.yml` **有意为空**(注释写明「本包的行由 **profile 层单点插入**」,避免 duplicate id 崩溃循环),而我只写了 `bundles` 没写行; 2. 补行后**启动失败**:`service "directoryPicker" has been registered` —— 我们的 picker 与官方 `dsh-host-directory-picker-auto/browse` 抢同名服务;**生产是靠角色补丁把官方那条 `disabled: true` 避让的**,而我的隔离 profile 漏了这条。 ⇒ 补齐后全绿;**并因此验证了一条关键前提:0.1.5 里官方那个行 `id: directory-picker` / 包名与生产角色补丁一致**,⇒ 平台重建补丁仍有效。 ### 二、阶段 4 · 整体更新(✅ 执行成功) **前置全部就位**:备份 400 MB(`/opt/dsh/backups/upgrade-0.1.5-20260914/`:全局 dsh 0.1.2-rc.1 + 2 个 profile 快照 + DB + **回滚.md**)· 隔离回归全绿 · univer 0.2.29 peer 已放宽。 | 步骤 | 结果 | |---|---| | 升级全局 dsh | ✅ `npm i -g @deepseek-ai/dsh@0.1.5-rc.1`(added 23 / removed 25 / changed 499),`dsh --version` = **0.1.5-rc.1** | | 重启平台 | ✅ `dshs` **active** | | 平台 API | ✅ `/api/auth/me`、`/api/plugins/business`、`/api/me/model-providers`、`/api/dsh/status` **全 200** | | 实例 | ✅ scope active;实例内 dsh = **0.1.5-rc.1**;实例页 200(62.9 KB) | | **收益到位** | ✅ 客户端插件 **47 → 54**,含 **`dsh-client-ui-sidebar-documentpreview`**(原生侧栏预览)· `sidebar-right` · `deliverables` | | 平台 5 插件 | ✅ 全部 inject 差集"无"(含 picker) | ### 三、遗留与观察项 | # | 项 | 处置 | |---|---|---| | 1 | `@softspark/dsh-file-preview` 退役 | ⏸ **暂不退役**(与原生预览功能重叠但无害;**同一窗口不做两件事**,观察一天再定) | | 2 | 备份目录 400 MB | 保留至观察期结束(确认稳定后可删) | | 3 | test106 隔离环境 | 保留 `/opt/upgrade-smoke/`(含测试记录)+ 测试机装了 `pnpm@9`(与生产无关) | | 4 | mcn-suite 浏览器半边pre-existing 挂起 | **既有问题**,不在本次范围 | | 5 | 回滚材料 | `/opt/dsh/backups/upgrade-0.1.5-20260914/回滚.md`(含逐条命令) | ### 四、项目状态 **✅ 阶段 1–4 全部完成**(档案 07 流程走完);**回滚预案仍在位**;后续按官方节奏跟进(下次升级同样走这五阶段)。