dsh-update-status 0.1.7 → 0.1.9

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 CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
  All notable changes to this project are documented here.
4
4
 
5
+ ## 0.1.9 — 2026-09-26
6
+
7
+ Verified DeepSeek Harness: `0.1.7-rc.2` (the latest release candidate, and what npm's `next` dist-tag publishes), also `0.1.7-rc.1` and `0.1.7-alpha.2`. Full bilingual release notes: [`docs/releases/v0.1.9.md`](docs/releases/v0.1.9.md).
8
+
9
+ A load-failure fix: on some machines the plugin disappeared entirely after upgrading DSH and then the plugin, with nothing in the panel to explain it. No migration is needed, and the verified DSH list is unchanged.
10
+
11
+ - **`@deepseek-ai/schemastery` is resolved explicitly instead of imported by bare specifier.** The host half used to `import z from '@deepseek-ai/schemastery'`, which Node resolves *from the importing file*, so any copy left inside the plugin's install directory won over the copy DSH ships. That is not theoretical: an unmanaged dev `node_modules` (copied in by a local-directory install, which pnpm never removes) pinned `3.18.2`, which has no `volatile()`, and `lib/index.js` threw `TypeError: …volatile is not a function` while it was being imported — the whole host half was gone before any plugin code ran. `src/host/schemastery.ts` now resolves the peer itself, platform copies first (the running DSH installation, then the profile peer farm at `$DSH_HOME/profiles/node_modules`, then the profile tree), and only then falls back to Node's walk. The first candidate that actually exposes `volatile()` wins, and the capability is verified rather than assumed.
12
+ - **A missing `volatile()` degrades the form instead of killing the plugin.** When only a stale copy is reachable the plugin still loads: `Config` is built with ordinary fields, the Host logs the resolution, and the panel shows a new `stale-schemastery` warning (severity `notice`, so the chip never repaints) naming the version, the resolved path and the exact directory to remove. Only a total miss — no schemastery anywhere, which means the plugin is not running inside a working DSH installation — still throws, and it names every candidate it tried.
13
+ - **The regression is locked three ways.** `tests/host/schemastery.spec.ts` drives the resolver with injected candidates (platform copy beats a shadowing copy; a stale-only environment loads and reports; unresolvable candidates are skipped; the default order is platform-first, plugin-local last) and adds a source guard that fails if any file under `src/` takes a *value* import of the peer again. `tests/guards/shadowed-peer.mjs` (wired into `pnpm run verify`, CI and both release workflows, after the build) loads the **built** entry with a fake `3.18.2` planted beside it, asserting it still loads and that, with a platform copy present, the platform copy wins.
14
+ - **Already-broken installs still need one manual step.** A machine already running `0.1.6`–`0.1.8` with an unmanaged leftover copy cannot load any newer version either — the failure happens before plugin code runs. Remove the leftover copy and restart DSH first; from this version on, upgrading is the whole fix.
15
+ - **Tests: 116 passing** (up from 98) across 15 files.
16
+ - **Unchanged**: the status read, the RPC channel, the client rendering path, the sidebar chip, the detail panel, the LAN fallback and the profile-patch preference model. The three preferences are still the only volatile fields.
17
+
18
+ ## 0.1.8 — 2026-09-25
19
+
20
+ Verified DeepSeek Harness: `0.1.7-rc.2` (the latest release candidate, and what npm's `next` dist-tag publishes), also `0.1.7-rc.1` and `0.1.7-alpha.2`. Full bilingual release notes: [`docs/releases/v0.1.8.md`](docs/releases/v0.1.8.md).
21
+
22
+ A version-matrix release with **zero code change**: DSH moved from `0.1.7-rc.1` to `0.1.7-rc.2`, and nothing this plugin binds to changed shape. No migration is needed from `0.1.7`.
23
+
24
+ - **`0.1.7-rc.2` joins the verified list.** `VERIFIED_DSH_VERSIONS` in `src/shared/types.ts` and `package.json`'s `dsh.compatibility.dshReleases` both gain it, keeping `0.1.7-alpha.2` and `0.1.7-rc.1`; `tests/shared/compatibility.spec.ts` keeps the two lists identical and proves the `dsh.engines.dsh` / `@deepseek-ai/dsh-settings` peer ranges admit every listed release.
25
+ - **The user-visible effect.** `0.1.7-rc.2` is what npm's `next` dist-tag publishes, and the old list stopped at `0.1.7-rc.1`, so following `next` produced a `preview-unverified` advisory (`notice` level, never repaints the chip). The running version and the channel row now read verified, and that advisory is gone. Generated upgrade commands and installation guidance are untouched.
26
+ - **rc.1 → rc.2 interface audit, all 7 bound packages.** `dsh-settings`, `dsh-client-ui-settings`, `dsh-client-ui-settings-general`, `dsh-client-ui-sidebar`, `dsh-client-ui-layout`, `dsh-client-connection` and `dsh-api-remotes` were diffed across the two releases. Every difference is additive shortcut plumbing: `settingsOpen` / `settingsShortcut` on the settings slot context, `shortcuts` on the sidebar shell context, `useShortcuts` on `SidebarRoot` / `HeaderLeadingControls`, `panelInfo` on the layout service, a `shortcuts.layout` locale namespace, a `shortcut.open` label, and a `dsh-schedule/remote` type re-export. Nothing this plugin uses was removed or reshaped: the `ctx.configForms` form face, `remote.settings`' `settings.describe` / `settings.mutate`, the `/api/dsh-update-status.*` Connection RPC routes and the four slots (`sidebar.brand.name`, `sidebar.footer.action`, `shell.overlay`, `settings.section`) are all unchanged.
27
+ - **Live load check on rc.2.** With a disposable `DSH_HOME`, this repository was installed into a web profile with `link:` and `dsh --profile web --dump-config` composed the `dsh-update-status` entry with no compatibility refusal — rc.2's profile-load gate accepts the bundle.
28
+ - **Tests: 98 passing** (unchanged — this release adds no behaviour to lock). The audit and the live load check are the new evidence; the panel/chip end-to-end interaction was **not** re-run on rc.2, and the `0.1.6` live adaptation conclusion still stands.
29
+ - **Unchanged**: the Host half, the client half, the RPC channel, the status read, the sidebar chip, the detail panel, the LAN (non-loopback) fallback and the profile-patch preference model.
30
+
5
31
  ## 0.1.7 — 2026-09-24
6
32
 
7
33
  Verified DeepSeek Harness: `0.1.7-rc.1` (the latest release candidate) and `0.1.7-alpha.2`. Full bilingual release notes: [`docs/releases/v0.1.7.md`](docs/releases/v0.1.7.md).
package/README.md CHANGED
@@ -53,7 +53,7 @@ Requirements:
53
53
 
54
54
  - DeepSeek Harness with the Web profile
55
55
  - Node.js 20 or newer
56
- - Verified DSH releases: `0.1.7-rc.1` (latest RC) and `0.1.7-alpha.2`
56
+ - Verified DSH releases: `0.1.7-rc.2` (latest RC), `0.1.7-rc.1` and `0.1.7-alpha.2`
57
57
 
58
58
  With an installed `dsh` command:
59
59
 
@@ -148,13 +148,15 @@ If you want DSH's stock policy instead (a non-loopback page never persists setti
148
148
 
149
149
  ## Compatibility
150
150
 
151
- Current release: plugin **`0.1.7`** is verified against DeepSeek Harness **`0.1.7-rc.1`** (the latest release candidate) and **`0.1.7-alpha.2`**.
151
+ Current release: plugin **`0.1.9`** is verified against DeepSeek Harness **`0.1.7-rc.2`** (the latest release candidate), **`0.1.7-rc.1`** and **`0.1.7-alpha.2`**.
152
152
 
153
153
  ### Which plugin version goes with which DeepSeek Harness version
154
154
 
155
155
  | Plugin | Verified DeepSeek Harness | On npm | What that version is |
156
156
  | --- | --- | --- | --- |
157
- | **`0.1.7`** | `0.1.7-rc.1`, `0.1.7-alpha.2` | `latest` | Runtime warnings become language-neutral codes rendered by the client, so the English UI is fully English; dev toolchain bumped |
157
+ | **`0.1.9`** | `0.1.7-rc.2`, `0.1.7-rc.1`, `0.1.7-alpha.2` | `latest` | Resolves `@deepseek-ai/schemastery` explicitly so a stale copy left in the install directory can no longer shadow the copy DSH ships and take the host half down; a missing `volatile()` now degrades the settings form with a `stale-schemastery` notice instead of throwing |
158
+ | `0.1.8` | `0.1.7-rc.2`, `0.1.7-rc.1`, `0.1.7-alpha.2` | published | Version-matrix release: adds the running `0.1.7-rc.2` to the verified list after auditing the rc.1 → rc.2 interface delta; zero code change |
159
+ | `0.1.7` | `0.1.7-rc.1`, `0.1.7-alpha.2` | published | Runtime warnings become language-neutral codes rendered by the client, so the English UI is fully English; dev toolchain bumped |
158
160
  | `0.1.6` | `0.1.7-rc.1`, `0.1.7-alpha.2` | published | Adapts to DSH 0.1.7: the preferences ARE the plugin entry's volatile `Config` (a form namespace is the Loader entry id), the official client channel is `ctx.configForms`, and `@deepseek-ai/schemastery` is a peer |
159
161
  | `0.1.5` | `0.1.6-alpha.2`, `0.1.6-alpha.1`, `0.1.5-rc.1` | published | One dot carries every state (green up to date, grey checking, amber breathing update), neutral grey chip surface in both themes, and advisory notices no longer repaint the chip |
160
162
  | `0.1.4` | `0.1.6-alpha.1`, `0.1.5-rc.1` | published | Fixes the unselectable "channel you are running"; preference writes locked by tests |
@@ -163,12 +165,14 @@ Current release: plugin **`0.1.7`** is verified against DeepSeek Harness **`0.1.
163
165
  | `0.1.1` | `0.1.5-rc.1` | published | The previous npm `latest`; the plugin is inert on LAN/non-loopback pages |
164
166
  | `0.1.0` | `0.1.2-rc.1` | published | First release |
165
167
 
166
- - **`0.1.6` and `0.1.7` support the DSH `0.1.7` line only.** DSH `0.1.7` removed the runtime `ctx.settings.register(...)` API and the `ctx.settingsScope` client service this plugin was built on, so those are the only releases whose preferences work there. On an older DSH — including `0.1.6-alpha.2` — stay on plugin **`0.1.5`**.
168
+ - **`0.1.6` through `0.1.9` support the DSH `0.1.7` line only.** DSH `0.1.7` removed the runtime `ctx.settings.register(...)` API and the `ctx.settingsScope` client service this plugin was built on, so those are the only releases whose preferences work there. On an older DSH — including `0.1.6-alpha.2` — stay on plugin **`0.1.5`**.
167
169
  - **Verified DeepSeek Harness** is the exact DSH release that plugin build was tested against. The list has one source of truth in two places — `VERIFIED_DSH_VERSIONS` in [`src/shared/types.ts`](src/shared/types.ts) and `dsh.compatibility.dshReleases` in [`package.json`](package.json) — and a test keeps them identical. A release that is not on the list is not declared compatible: verify it manually first, and if it turns out incompatible, disable or uninstall the plugin rather than patching DSH core. A release that is merely *not listed yet* is reported as **unverified**: that is an advisory in the panel only, and it never repaints the chip — an operator who upgrades DSH ahead of this plugin keeps a normal chip.
168
170
  - **On npm** is what `dsh plugin --profile web add dsh-update-status@latest` actually installs. A version that exists in this repository but not on npm is a development state, not a release.
169
171
  - Match them explicitly when it matters:
170
172
 
171
173
  ```sh
174
+ dsh plugin --profile web add dsh-update-status@0.1.9 # DSH 0.1.7-rc.2, 0.1.7-rc.1 or 0.1.7-alpha.2
175
+ dsh plugin --profile web add dsh-update-status@0.1.8 # DSH 0.1.7-rc.2, 0.1.7-rc.1 or 0.1.7-alpha.2
172
176
  dsh plugin --profile web add dsh-update-status@0.1.7 # DSH 0.1.7-rc.1 or 0.1.7-alpha.2
173
177
  dsh plugin --profile web add dsh-update-status@0.1.6 # DSH 0.1.7-rc.1 or 0.1.7-alpha.2
174
178
  dsh plugin --profile web add dsh-update-status@0.1.5 # DSH 0.1.6-alpha.2, 0.1.6-alpha.1 or 0.1.5-rc.1
@@ -177,9 +181,9 @@ Current release: plugin **`0.1.7`** is verified against DeepSeek Harness **`0.1.
177
181
  ```
178
182
 
179
183
  - Two declarations make the `0.1.7` line load at all, and a test keeps them honest:
180
- - `dsh.engines.dsh` and `peerDependencies['@deepseek-ai/dsh-settings']` both declare `>=0.1.7-alpha.2 <0.2.0`, which admits both verified releases. The lower bound names the alpha on purpose — under node-semver's default prerelease rule a range like `>=0.1.6-0 <0.2.0` does **not** admit `0.1.7-alpha.2`. DSH `0.1.7-rc.1` also refuses an incompatible bundle at profile load, so a range that excluded the running release would silently drop the plugin.
184
+ - `dsh.engines.dsh` and `peerDependencies['@deepseek-ai/dsh-settings']` both declare `>=0.1.7-alpha.2 <0.2.0`, which admits all three verified releases. The lower bound names the alpha on purpose — under node-semver's default prerelease rule a range like `>=0.1.6-0 <0.2.0` does **not** admit `0.1.7-alpha.2`. DSH `0.1.7-rc.2` also refuses an incompatible bundle at profile load, so a range that excluded the running release would silently drop the plugin.
181
185
  - `@deepseek-ai/schemastery` is a **peer**, not a plain dependency: DSH 0.1.7 resolves only a linked plugin's peer dependencies from the running installation, so a `link:` install of this directory would otherwise fail to import the Host half.
182
- - Per-release notes — what changed, who is affected, what to do — are hand-written in Chinese and English and become the GitHub Release body: [`v0.1.7`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.7.md) · [`v0.1.6`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.6.md) · [`v0.1.5`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.5.md) · [`v0.1.4`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.4.md) · [`v0.1.3`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.3.md) (covers the never-published `0.1.2`).
186
+ - Per-release notes — what changed, who is affected, what to do — are hand-written in Chinese and English and become the GitHub Release body: [`v0.1.9`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.9.md) · [`v0.1.8`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.8.md) · [`v0.1.7`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.7.md) · [`v0.1.6`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.6.md) · [`v0.1.5`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.5.md) · [`v0.1.4`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.4.md) · [`v0.1.3`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.3.md) (covers the never-published `0.1.2`).
183
187
 
184
188
  ## Configuration
185
189
 
@@ -221,6 +225,13 @@ The Host caches one registry response, 360 minutes by default, and only a normal
221
225
  **Nothing reaches the npm registry.**
222
226
  The plugin reports the failure and still shows the locally detected running version. Registry access is HTTPS-only to `registry.npmjs.org`; a proxy or offline host produces that warning rather than a wrong version.
223
227
 
228
+ **The plugin disappeared after an upgrade, and the host log says `volatile is not a function`.**
229
+ Up to `0.1.5` this plugin declared `@deepseek-ai/schemastery` as a regular dependency. From `0.1.6` it is a **peer that DSH provides**, and the `volatile()` DSH adds to it is what turns the three preferences into this entry's settings form. If a copy of that package is left inside the plugin's own install directory — a dev `node_modules` copied in by a local-directory install, which pnpm never removes — Node used to resolve that stale copy, and the missing method threw while the host half was being imported, so the plugin disappeared before it could report anything at all. Newer builds resolve the platform copy explicitly and load either way, and when only a stale copy is reachable the panel shows a `stale-schemastery` notice naming the directory. Remove the leftover copy and restart DSH:
230
+
231
+ ```sh
232
+ rm -rf ~/.dsh/profiles/<profile>/node_modules/dsh-update-status/node_modules
233
+ ```
234
+
224
235
  ## Security boundary
225
236
 
226
237
  - Registry access is limited to HTTPS `registry.npmjs.org`; redirects are rejected.
package/README.zh.md CHANGED
@@ -53,7 +53,7 @@
53
53
 
54
54
  - 带 Web profile 的 DeepSeek Harness
55
55
  - Node.js 20 或更新版本
56
- - 已验证的 DSH 版本:`0.1.7-rc.1`(最新 RC)与 `0.1.7-alpha.2`
56
+ - 已验证的 DSH 版本:`0.1.7-rc.2`(最新 RC)、`0.1.7-rc.1` 与 `0.1.7-alpha.2`
57
57
 
58
58
  已经安装 `dsh` 命令:
59
59
 
@@ -148,13 +148,15 @@ DSH 对来源不是 loopback(`localhost` / `127.0.0.1`)的页面会关闭 Ho
148
148
 
149
149
  ## 兼容性
150
150
 
151
- 当前发布:插件 **`0.1.7`** 已针对 DeepSeek Harness **`0.1.7-rc.1`**(最新候选版本)与 **`0.1.7-alpha.2`** 验证。
151
+ 当前发布:插件 **`0.1.9`** 已针对 DeepSeek Harness **`0.1.7-rc.2`**(最新候选版本)、**`0.1.7-rc.1`** 与 **`0.1.7-alpha.2`** 验证。
152
152
 
153
153
  ### 插件版本与 DeepSeek Harness 版本的对应关系
154
154
 
155
155
  | 插件版本 | 已验证的 DeepSeek Harness | npm 发布状态 | 该版本是什么 |
156
156
  | --- | --- | --- | --- |
157
- | **`0.1.7`** | `0.1.7-rc.1`、`0.1.7-alpha.2` | `latest` | 运行期告警改为语言中立的代码、由客户端按界面语言渲染,英文界面不再混入中文;dev 工具链升级 |
157
+ | **`0.1.9`** | `0.1.7-rc.2`、`0.1.7-rc.1`、`0.1.7-alpha.2` | `latest` | 显式解析 `@deepseek-ai/schemastery`,安装目录里残留的旧副本不再能遮蔽 DSH 自带的那份、把宿主半整个带走;缺少 `volatile()` 时改为降级设置表单并给出 `stale-schemastery` 提示,而不是抛错 |
158
+ | `0.1.8` | `0.1.7-rc.2`、`0.1.7-rc.1`、`0.1.7-alpha.2` | 已发布 | 版本矩阵发布:核对 rc.1 → rc.2 接口差异后,把正在运行的 `0.1.7-rc.2` 加入已验证清单;代码零改动 |
159
+ | `0.1.7` | `0.1.7-rc.1`、`0.1.7-alpha.2` | 已发布 | 运行期告警改为语言中立的代码、由客户端按界面语言渲染,英文界面不再混入中文;dev 工具链升级 |
158
160
  | `0.1.6` | `0.1.7-rc.1`、`0.1.7-alpha.2` | 已发布 | 适配 DSH 0.1.7:偏好设置就是插件条目的 volatile `Config`(设置表单命名空间 = loader 条目 id),官方客户端通道改为 `ctx.configForms`,`@deepseek-ai/schemastery` 改为 peer |
159
161
  | `0.1.5` | `0.1.6-alpha.2`、`0.1.6-alpha.1`、`0.1.5-rc.1` | 已发布 | 一颗圆点承载全部状态(绿=已是最新、灰=检查中、橙=有新版本)、两套主题都用中性灰底框、提示性告警不再重绘芯片 |
160
162
  | `0.1.4` | `0.1.6-alpha.1`、`0.1.5-rc.1` | 已发布 | 修复「正在运行的通道不可选」;偏好写入路径补齐回归测试 |
@@ -163,12 +165,14 @@ DSH 对来源不是 loopback(`localhost` / `127.0.0.1`)的页面会关闭 Ho
163
165
  | `0.1.1` | `0.1.5-rc.1` | 已发布 | 此前 npm 上的 `latest`;局域网/非回环页面下插件整体不可用 |
164
166
  | `0.1.0` | `0.1.2-rc.1` | 已发布 | 首个版本 |
165
167
 
166
- - **`0.1.6` 与 `0.1.7` 只支持 DSH `0.1.7` 线。** DSH `0.1.7` 移除了本插件赖以工作的运行时 `ctx.settings.register(...)` API 与 `ctx.settingsScope` 客户端服务,因此该版本线上只有它们俩的偏好设置能工作;仍在更早的 DSH(含 `0.1.6-alpha.2`)上时,请继续使用插件 **`0.1.5`**。
168
+ - **`0.1.6` 至 `0.1.9` 只支持 DSH `0.1.7` 线。** DSH `0.1.7` 移除了本插件赖以工作的运行时 `ctx.settings.register(...)` API 与 `ctx.settingsScope` 客户端服务,因此该版本线上只有它们的偏好设置能工作;仍在更早的 DSH(含 `0.1.6-alpha.2`)上时,请继续使用插件 **`0.1.5`**。
167
169
  - **已验证的 DeepSeek Harness** 是该插件构建实际测试过的确切 DSH 版本。这份清单只有两个存放处——[`src/shared/types.ts`](src/shared/types.ts) 的 `VERIFIED_DSH_VERSIONS` 与 [`package.json`](package.json) 的 `dsh.compatibility.dshReleases`——并有测试保证两者一致。未列出的 DSH 版本不会被宣称为兼容:请先人工验证;确认不兼容时请禁用或卸载插件,不要修改 DSH 核心。若只是**尚未列入**,插件会标为「尚未验证兼容」:这是**只出现在面板里**的提示,绝不会重绘芯片——DSH 升级快于插件时,芯片依然保持正常外观。
168
170
  - **npm 发布状态** 是 `dsh plugin --profile web add dsh-update-status@latest` 实际会装到的版本。只存在于本仓库、尚未发布到 npm 的版本属于开发状态,不是发布版本。
169
171
  - 需要精确对应时显式指定版本:
170
172
 
171
173
  ```sh
174
+ dsh plugin --profile web add dsh-update-status@0.1.9 # DSH 0.1.7-rc.2、0.1.7-rc.1 或 0.1.7-alpha.2
175
+ dsh plugin --profile web add dsh-update-status@0.1.8 # DSH 0.1.7-rc.2、0.1.7-rc.1 或 0.1.7-alpha.2
172
176
  dsh plugin --profile web add dsh-update-status@0.1.7 # DSH 0.1.7-rc.1 或 0.1.7-alpha.2
173
177
  dsh plugin --profile web add dsh-update-status@0.1.6 # DSH 0.1.7-rc.1 或 0.1.7-alpha.2
174
178
  dsh plugin --profile web add dsh-update-status@0.1.5 # DSH 0.1.6-alpha.2、0.1.6-alpha.1 或 0.1.5-rc.1
@@ -177,9 +181,9 @@ DSH 对来源不是 loopback(`localhost` / `127.0.0.1`)的页面会关闭 Ho
177
181
  ```
178
182
 
179
183
  - 有两处声明让 `0.1.7` 线能正常加载,并由测试守住:
180
- - `dsh.engines.dsh` 与 `peerDependencies['@deepseek-ai/dsh-settings']` 都声明 `>=0.1.7-alpha.2 <0.2.0`,两个已验证版本都在范围内。下界特意写成这个 alpha:按 node-semver 默认的预发布规则,`>=0.1.6-0 <0.2.0` 这样的范围**并不接纳** `0.1.7-alpha.2`。另外 DSH `0.1.7-rc.1` 会在 profile 加载时拒绝不兼容的 bundle,范围若排除正在运行的版本,插件会被静默丢弃。
184
+ - `dsh.engines.dsh` 与 `peerDependencies['@deepseek-ai/dsh-settings']` 都声明 `>=0.1.7-alpha.2 <0.2.0`,三个已验证版本都在范围内。下界特意写成这个 alpha:按 node-semver 默认的预发布规则,`>=0.1.6-0 <0.2.0` 这样的范围**并不接纳** `0.1.7-alpha.2`。另外 DSH `0.1.7-rc.2` 会在 profile 加载时拒绝不兼容的 bundle,范围若排除正在运行的版本,插件会被静默丢弃。
181
185
  - `@deepseek-ai/schemastery` 是 **peer**,不是普通依赖:DSH 0.1.7 只从运行安装解析 link 插件的 peer 依赖,否则 `link:` 安装会连 Host 半边都 import 失败。
182
- - 每个版本的中英文详细说明(改了什么、影响谁、需要做什么)手写后直接作为 GitHub Release 正文:[`v0.1.7`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.7.md) · [`v0.1.6`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.6.md) · [`v0.1.5`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.5.md) · [`v0.1.4`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.4.md) · [`v0.1.3`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.3.md)(含从未发布的 `0.1.2`)。
186
+ - 每个版本的中英文详细说明(改了什么、影响谁、需要做什么)手写后直接作为 GitHub Release 正文:[`v0.1.9`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.9.md) · [`v0.1.8`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.8.md) · [`v0.1.7`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.7.md) · [`v0.1.6`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.6.md) · [`v0.1.5`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.5.md) · [`v0.1.4`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.4.md) · [`v0.1.3`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.3.md)(含从未发布的 `0.1.2`)。
183
187
 
184
188
  ## 配置
185
189
 
@@ -221,6 +225,13 @@ Host 会缓存一次 registry 响应,默认 360 分钟,且只有普通读取
221
225
  **完全连不上 npm registry。**
222
226
  插件会报告失败,并仍然显示本地检测到的运行版本。registry 访问只允许 HTTPS 的 `registry.npmjs.org`;代理或离线环境会给出这条警告,而不是编造一个版本号。
223
227
 
228
+ **升级之后插件整个消失了,宿主日志里是 `volatile is not a function`。**
229
+ `0.1.5` 及更早版本把 `@deepseek-ai/schemastery` 声明为普通依赖;从 `0.1.6` 起它是**由 DSH 提供的 peer**,而 DSH 给它加的 `volatile()` 正是把三个偏好变成这个条目设置表单的机制。如果该包的一份旧副本被留在插件自己的安装目录里(用本地目录安装时被一起拷进来的 dev `node_modules`,pnpm 永远不会清理),Node 就会解析到那份旧副本,缺失的方法在宿主半 import 阶段直接抛错,插件在来得及报告任何信息之前就消失了。新版本改为显式解析平台那份,两种情况都能加载;只找得到旧副本时,面板会给出 `stale-schemastery` 提示并指出该删除哪个目录。删除残留目录后重启 DSH:
230
+
231
+ ```sh
232
+ rm -rf ~/.dsh/profiles/<profile>/node_modules/dsh-update-status/node_modules
233
+ ```
234
+
224
235
  ## 安全边界
225
236
 
226
237
  - registry 访问只允许 HTTPS `registry.npmjs.org`,并拒绝重定向。
package/lib/client.js CHANGED
@@ -277,6 +277,14 @@ window.__ModuleLoader__.load({
277
277
  zh: "{channel} 是预览通道,版本 {version} 尚未验证与本插件兼容。",
278
278
  en: "{channel} is a preview channel; version {version} has not been verified as compatible with this plugin."
279
279
  },
280
+ "warning.staleSchemastery": {
281
+ zh: "本插件解析到的 @deepseek-ai/schemastery(版本 {version})来自 {path},不是 DSH 自带的那份,偏好字段无法标记为 volatile。请删除该残留目录并重启 DSH:rm -rf {nodeModulesDir}",
282
+ en: "This plugin resolved @deepseek-ai/schemastery {version} from {path} instead of the copy DSH provides, so preference fields cannot be marked volatile. Remove the stale directory and restart DSH: rm -rf {nodeModulesDir}"
283
+ },
284
+ "warning.staleSchemasteryNoPath": {
285
+ zh: "本插件解析到的 @deepseek-ai/schemastery(版本 {version})来自 {path},不是 DSH 自带的那份,偏好字段无法标记为 volatile。请删除该处残留的 @deepseek-ai/schemastery 目录并重启 DSH。",
286
+ en: "This plugin resolved @deepseek-ai/schemastery {version} from {path} instead of the copy DSH provides, so preference fields cannot be marked volatile. Remove the stale @deepseek-ai/schemastery directory there and restart DSH."
287
+ },
280
288
  "guidance.sourceCheckout": {
281
289
  zh: "请更新 DSH 源码 checkout、安装依赖并重新构建;本插件无法从 GUI 原地替换。",
282
290
  en: "Update the DSH source checkout, install its dependencies, and rebuild it; this plugin cannot replace it in place from the GUI."
@@ -383,6 +391,16 @@ window.__ModuleLoader__.load({
383
391
  channel: warning.channel,
384
392
  version: warning.version
385
393
  }, language);
394
+ case "stale-schemastery": {
395
+ const params = {
396
+ version: warning.version ?? "—",
397
+ path: warning.path
398
+ };
399
+ return warning.nodeModulesDir === null ? t("warning.staleSchemasteryNoPath", params, language) : t("warning.staleSchemastery", {
400
+ ...params,
401
+ nodeModulesDir: warning.nodeModulesDir
402
+ }, language);
403
+ }
386
404
  }
387
405
  }
388
406
  /** Prefer structured warnings, but keep the Host string for mixed-version clients. */
@@ -1028,6 +1046,17 @@ window.__ModuleLoader__.load({
1028
1046
  channel: record.channel,
1029
1047
  version: record.version
1030
1048
  };
1049
+ if (record.code === "stale-schemastery") {
1050
+ const version = record.version === null ? null : stringOrNull(record.version);
1051
+ const nodeModulesDir = record.nodeModulesDir === null ? null : stringOrNull(record.nodeModulesDir);
1052
+ const path = stringOrNull(record.path);
1053
+ if (path !== null && (record.version === null || version !== null) && (record.nodeModulesDir === null || nodeModulesDir !== null)) return {
1054
+ code: record.code,
1055
+ version,
1056
+ path,
1057
+ nodeModulesDir
1058
+ };
1059
+ }
1031
1060
  }
1032
1061
  /** Reject malformed RPC output before it reaches a slot component. */
1033
1062
  function updateStatusOf(value) {