dsh-instruction-memory 1.0.13 → 1.0.14
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.md +62 -14
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
dsh plugin --profile web add dsh-instruction-memory
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
宿主版本必须落在[兼容性](#兼容性)声明的范围内。范围之外**宿主会拒绝安装/启动**(1.0.14 起,
|
|
16
|
+
因为 `peerDependencies` 已声明);确需强行安装可用 `dsh plugin allow-version` 授予该精确版本的
|
|
17
|
+
豁免,风险自负。
|
|
18
|
+
|
|
15
19
|
装完重启 DSH,设置页会出现「指令记忆」入口。卸载:
|
|
16
20
|
|
|
17
21
|
```sh
|
|
@@ -36,7 +40,7 @@ dsh plugin --profile web remove dsh-instruction-memory
|
|
|
36
40
|
| `contract-test.mjs` | 契约测试:驱动真实路由,验证两半之间的响应格式 |
|
|
37
41
|
| `verify.mjs` | 装载验证:按 DSH 的方式加载两半 |
|
|
38
42
|
| `smoke-test.mjs` | 注入渲染逻辑的单元测试 |
|
|
39
|
-
| `host-range-test.mjs` | 宿主版本范围契约测试:固定矩阵 × 两种 semver
|
|
43
|
+
| `host-range-test.mjs` | 宿主版本范围契约测试:固定矩阵 × 两种 semver 判定模式,并把 `peerDependencies`(**被执行的那个**)、`dsh.engines.dsh`、`dsh.compatibility.dsh` 三处声明锁到同一个生成值 |
|
|
40
44
|
| `docs/demo.html` | 离线演示页:桩掉 DSH 外壳、加载真实 Client 半渲染设置页(不随 npm 包发布) |
|
|
41
45
|
|
|
42
46
|
## 生效方式
|
|
@@ -167,7 +171,17 @@ DNS 重绑定恰好推翻了它**:`evil.com` 解析到 `127.0.0.1` 之后,
|
|
|
167
171
|
|
|
168
172
|
## 兼容性
|
|
169
173
|
|
|
170
|
-
|
|
174
|
+
同一串范围写在**三处**,而**只有一处会被宿主强制执行**——这一点以前写错过,现在按实测更正:
|
|
175
|
+
|
|
176
|
+
| 位置 | 谁读它 | 作用 |
|
|
177
|
+
| --- | --- | --- |
|
|
178
|
+
| **`peerDependencies`**(`@deepseek-ai/dsh-system-prompt`) | **宿主**:`evaluatePluginCompatibility()`(`dsh-app-boot/lib/index.js`),在**安装**与 **profile 启动**时执行 | **真正的门禁**。不满足即拒绝(或要求显式授予精确版本豁免:`dsh plugin allow-version`)。门禁把 peer 的**范围值**与宿主版本(`dsh --version`)比较,peer 的**包名不参与解析**,只用来点名报错 |
|
|
179
|
+
| `dsh.engines.dsh` | 插件市场(第三方,服务端读取) | 市场卡片上的兼容性判定与展示 |
|
|
180
|
+
| `dsh.compatibility.dsh` | 未找到读取方(官方文档与 DSH 树内均无) | 仅作人类可读的重复声明 |
|
|
181
|
+
|
|
182
|
+
**1.0.14 之前这里只有后两处,没有 `peerDependencies`**——而宿主的门禁在读到缺失的 `peerDependencies` 时会直接 `return undefined`(`if (!Object.hasOwn(fields, "peerDependencies")) return void 0`),也就是**跳过检查**。换句话说,范围之外的宿主在此之前可以装上而**没有任何拦截或警告**;那串范围当时只是市场元数据,不是门禁。1.0.14 补上 peer 之后,它才真正生效。
|
|
183
|
+
|
|
184
|
+
同一串范围(三处逐字节一致,由测试锁定):
|
|
171
185
|
|
|
172
186
|
```
|
|
173
187
|
>=0.1.3-alpha.2 <0.1.4 || >=0.1.4-0 <0.1.5-0 || >=0.1.5-alpha.1 <0.1.6-0 || >=0.1.6-alpha.0 <0.1.7-0 || >=0.1.7-alpha.0 <0.2.0-0 || >=0.2.0-0
|
|
@@ -177,15 +191,19 @@ DNS 重绑定恰好推翻了它**:`evil.com` 解析到 `127.0.0.1` 之后,
|
|
|
177
191
|
|
|
178
192
|
| 等级 | 证明什么 | 覆盖 |
|
|
179
193
|
| --- | --- | --- |
|
|
180
|
-
| ① **真实启动** | 在该宿主版本上真的把 DSH 跑起来:插件装载、注入真的进入**组装后的提示**、插件 HTTP 路由可应答、客户端设置页模块被下发(Windows / Node 22) | `0.1.3-alpha.2` · `0.1.5-alpha.1` · `0.1.5-alpha.2` · `0.1.5-rc.1` · `0.1.5-rc.2` |
|
|
181
|
-
| ② **契约核验** | 抓该版本**真实发布的源码**,逐个核验本插件实际用到的每个符号:`systemPrompt.section()`、`assemble()` 是否求值**函数型** `text`、`FILE_REFERENCE=900` / `TOOL_BASH=1000` 仍在(决定 order 950 是否空档)、重名注册是否抛错、`webServer.register()` / `get host()`、`ctx.inject()` / `ctx.effect()`、`dsh.client.inject` 两包在该版本是否存在且声明了 `dsh.client` | 声明范围接住的**全部
|
|
194
|
+
| ① **真实启动** | 在该宿主版本上真的把 DSH 跑起来:插件装载、注入真的进入**组装后的提示**、插件 HTTP 路由可应答、客户端设置页模块被下发(Windows / Node 22) | `0.1.3-alpha.2` · `0.1.5-alpha.1` · `0.1.5-alpha.2` · `0.1.5-rc.1` · `0.1.5-rc.2` · **`0.2.0-rc.1`** ⁽*⁾ |
|
|
195
|
+
| ② **契约核验** | 抓该版本**真实发布的源码**,逐个核验本插件实际用到的每个符号:`systemPrompt.section()`、`assemble()` 是否求值**函数型** `text`、`FILE_REFERENCE=900` / `TOOL_BASH=1000` 仍在(决定 order 950 是否空档)、重名注册是否抛错、`webServer.register()` / `get host()`、`ctx.inject()` / `ctx.effect()`、`dsh.client.inject` 两包在该版本是否存在且声明了 `dsh.client` | 声明范围接住的**全部 13 个已发布版本**(`0.1.3-alpha.2` → `0.2.0-rc.1`) |
|
|
182
196
|
| ③ **真实执行** | 把插件**真的挂载**进该版本的 `@deepseek-ai/cordis`,跑装载 / 路由注册 / 卸载共 9 项断言 | cordis `4.0.2` 与 `4.0.4`(各 9/9) |
|
|
183
197
|
|
|
184
|
-
|
|
198
|
+
⁽*⁾ **`0.2.0-rc.1` 的①档有一条要说明**:插件装载、注入进入组装后的提示、HTTP 路由可应答三项**均已实测**(路由 `HTTP 200`;`injection.registered=true`、`chars=437`、**`pulls=38`**——即 0.2.0-rc.1 的 agent loop 真的求值了 38 次函数型 `text`)。第四项"客户端模块被下发"**没有直接抓取**:首页需要鉴权(`/` 返回 `401`),我无法取到 `window.__DSH_BOOT__`。这一项的支撑是间接但强的两条:① `dsh-client-modules` 在合成阶段对 `dsh.client` 声明做硬校验,不合格会抛 `ClientPackageCompositionError` 直接导致启动失败——宿主正常启动即说明声明通过了 0.2.0-rc.1 的校验;② 本插件用到的三个客户端契约包(`-slots` / `-renderer` / `-settings`)相对升级前真正在跑的 `0.1.7-rc.2` **逐字节未变**。**未做人工视觉确认**(没有打开设置页看)。
|
|
199
|
+
|
|
200
|
+
此外 `host-range-test.mjs` 的固定矩阵覆盖 `0.1.6-alpha.2`、`0.1.7-rc.2` 与 `0.2.0-rc.1`,并会**读取本机实际安装的宿主版本**做实时断言。
|
|
185
201
|
|
|
186
202
|
**关于 1.0.10 新增的 `ctx.inject`。** 这是新版唯一的硬依赖增量:`inject` 去掉了 `webServer`,设置页路由改为非阻塞的 `ctx.inject(['webServer'], …)` 子 fiber(原因见上)。为此逐个核验了 **cordis 全部 6 个已发布版本**(`4.0.1-rc.1` → `4.0.4`)——**每一个都具备 `ctx.inject`**,因此声明范围内不存在因它而失效的宿主版本。
|
|
187
203
|
|
|
188
|
-
**关于声明范围是否"超范围承诺"。** 已对全部 **
|
|
204
|
+
**关于声明范围是否"超范围承诺"。** 已对全部 **28 个**已发布宿主版本穷举核验:范围内 **13 个**版本的 API 面**全部齐备,超范围承诺 0 项**。范围外的 15 个版本(`0.0.1-rc.1` → `0.1.2-rc.1`)API 面**同样齐备**,但它们**从未真实启动验证过**,所以下限维持不动、不向外放宽——不把没验证过的东西写进声明。
|
|
205
|
+
|
|
206
|
+
**`0.2.0-rc.1` 的核验口径**(2026-09-29 增补):基准取 npm 上**真实发布的 `0.1.7-rc.2`**(升级前本机真正在跑的版本),逐文件 SHA256 与 `0.2.0-rc.1` 比对。本插件的 6 个耦合点里 **6 个逐字节未变**(`dsh-system-prompt` 4/4、`dsh-client-ui-slots` 4/4、`-renderer` 12/12、`-settings` 11/11、`dsh-host-webserver` 3/3、`dsh-client-modules` 10/10);变动的只有 `dsh-agent-loop`(注入通路 `preStep` / `assemble` 逐行等同)与 `dsh-app-boot`(兼容门禁函数逐字节等同)。方法带**阴性对照**:同法比对 `0.1.6-alpha.2` 得到的哈希**不同**,证明这套比对确实能检出变化,而不是恒真。
|
|
189
207
|
|
|
190
208
|
**一个运维上值得知道的事实。** 早期 DSH 用 caret 范围声明同族依赖(如 `^0.1.5-alpha.2`),范围会随时间"往前漂":**今天**安装旧版 DSH,npm 在 `includePrerelease` 语义下会把同族子包解析到**当前最新的 `0.1.x`**,而不是当年那份(实测 7/10 个采样版本会漂移,3 个因精确锁定不会)。这不影响本插件的结论——漂移目标同样在已核验范围内——但"今天装出来的树"与"当年装出来的树"可能不同。
|
|
191
209
|
|
|
@@ -199,10 +217,25 @@ major.minor.patch 且自身带预发布标签的比较符"。这条规则是**
|
|
|
199
217
|
- **每段的上界不能省**:省略会被上一段的比较符"续接"。例如单写 `>=0.1.5-alpha.1`(不封顶),
|
|
200
218
|
在把 `0.1.3` 当 token 时会放行 `0.1.3-alpha.0/1`。
|
|
201
219
|
|
|
202
|
-
⚠️
|
|
203
|
-
`0.1.8-rc.1` 这类版本 tuple 与所有比较符都不同,在 npm
|
|
220
|
+
⚠️ **一个必须知道的上限(注意它是"模式相关"的,别当成普适结论):未声明的未来 minor 的预发布版本,在 npm 的默认语义下无法被任何范围覆盖。**
|
|
221
|
+
`0.1.8-rc.1` 这类版本 tuple 与所有比较符都不同,在 **npm 默认语义**下**永远匹配不到**——与
|
|
204
222
|
`^0.1.0` 无法匹配 `0.1.8-rc.1` 是同一个限制。正式版(`0.1.8`、`0.2.0`、`1.0.0` 等)不受影响。
|
|
205
223
|
|
|
224
|
+
**但在 `includePrerelease: true` 下这条上限不成立。** 实测同一串范围:`0.1.8-rc.1` 在默认语义下 `false`、
|
|
225
|
+
在 `includePrerelease: true` 下 **`true`**(已用 DSH 自带的 semver 7.8.5 验证)。而这个区别是**有后果**的,
|
|
226
|
+
因为两条消费路径用的模式不同:
|
|
227
|
+
|
|
228
|
+
| 消费方 | 模式 | `0.1.8-rc.1` 会被放行吗 |
|
|
229
|
+
| --- | --- | --- |
|
|
230
|
+
| npm / pnpm 解析 `peerDependencies`(**包管理器**) | 默认 | **否** |
|
|
231
|
+
| **宿主门禁** `evaluatePluginCompatibility` | **`includePrerelease: true`**(`dsh-app-boot` L300) | **是** |
|
|
232
|
+
| 插件市场(第三方,服务端) | `includePrerelease: true` | **是** |
|
|
233
|
+
|
|
234
|
+
也就是说:对**包管理器**而言那个上限成立,对**宿主门禁**而言它其实已经被宽松模式接住了。
|
|
235
|
+
所以"未声明的新 minor 预发布版会不会被拒"**不能只看一句话**,要问清楚是哪种模式。
|
|
236
|
+
(`host-range-test.mjs` 里那条 `0.1.8-rc.1 is unreachable` 的断言取的是**默认模式**,其用例名
|
|
237
|
+
因此容易被误读成普适结论——这一点已在 1.0.14 的核验里记录。)
|
|
238
|
+
|
|
206
239
|
**这个限制无法用代码消除,但它的后果已经被消掉了。** 范围现在是**生成出来的**:
|
|
207
240
|
`host-range-test.mjs` 顶部的 `COVERED_LINES` 是唯一事实来源,package.json 里那串长字符串必须
|
|
208
241
|
逐字节等于由它生成的结果(有专门的漂移断言),所以手改长串导致"枚举漏了一段"这类错误不可能
|
|
@@ -234,14 +267,29 @@ FAIL LIVE GUARD: the installed host 0.1.8-rc.1 is admitted by both modes -> ..
|
|
|
234
267
|
两次都因为插件市场传入 `includePrerelease: true` 而侥幸放行,但任何标准 semver 判定
|
|
235
268
|
(`npm` / `pnpm` 的依赖解析)都会拒绝。现在 `host-range-test.mjs` 同时具备固定矩阵与实时守卫。
|
|
236
269
|
|
|
237
|
-
**未验证范围**:macOS / Linux、`headless` 与 `tui` profile
|
|
270
|
+
**未验证范围**:macOS / Linux、`headless` 与 `tui` profile,以及**除上表等级①那几个之外的任何版本的真实启动**,均未实测。
|
|
238
271
|
等级②只证明"该版本里有这些 API",**不证明端到端可用**。
|
|
239
272
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
273
|
+
**关于"市场读哪个字段"这条的证据等级。** 这里说的是**插件市场(第三方)**的行为,不是 `dsh` 自身:
|
|
274
|
+
市场从已发布的 npm manifest 读 `engines.dsh`(顶层优先)或 `dsh.engines.dsh`,与 `@deepseek-ai/dsh*` 的
|
|
275
|
+
`peerDependencies`(若有)**求交**,再用 `semver` + `includePrerelease: true` 与宿主版本比较,据此在卡片上
|
|
276
|
+
显示兼容性;`dsh.compatibility.dsh` **不是**市场读取的那个字段。
|
|
277
|
+
|
|
278
|
+
需要如实说明它的**来源等级**:这一条**在官方文档里没有**,树内也没有可核验的市场客户端
|
|
279
|
+
(`dshmarket` / `alldsh` 均为第三方,读取发生在服务端)。它的依据是一份独立的第三方实证记录
|
|
280
|
+
——本机安装的 `dsh-vibe-math@2.3.16` 在其 `dsh.compatNote` 里逐字写明了上述读取路径与"自用的
|
|
281
|
+
`dsh.compatibility.dshReleases` 市场不读"。所以请把它当作**第三方实证**,不要当成官方保证。
|
|
282
|
+
(1.0.14 之前这段把它与官方事实并列陈述,措辞已按证据分级修正。)
|
|
283
|
+
|
|
284
|
+
**范围之外的宿主会发生什么(1.0.14 起变了)。** 在此之前,本插件没有 `peerDependencies`,宿主门禁
|
|
285
|
+
直接跳过检查,范围外宿主**可以装上且没有警告**。1.0.14 起 peer 生效:
|
|
286
|
+
|
|
287
|
+
- **宿主**(`dsh plugin add` / profile 启动)会拒绝,除非用户显式授予该精确版本的豁免
|
|
288
|
+
(`dsh plugin allow-version`),这正是 DSH 设计的正常流程;
|
|
289
|
+
- **市场**会把"确认不兼容"的条目隐藏并拒绝安装/更新("未声明"或"无法确认"的条目照常显示)。
|
|
290
|
+
|
|
291
|
+
`host-range-test.mjs` 会断言 `peerDependencies` 与另外两处字段**逐字节一致**,并断言 peer 只声明这一个包名——
|
|
292
|
+
三处任一被手改都会在测试里失败。
|
|
245
293
|
|
|
246
294
|
## 发布(维护者)
|
|
247
295
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-instruction-memory",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "User-only instruction memory for DSH: long-term instructions maintained in the settings UI and auto-injected into every conversation — the model has no write access. 指令记忆:只由用户在设置页维护的长期指令,自动注入此后每轮对话;模型没有任何写入口。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -47,6 +47,9 @@
|
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=20"
|
|
49
49
|
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@deepseek-ai/dsh-system-prompt": ">=0.1.3-alpha.2 <0.1.4 || >=0.1.4-0 <0.1.5-0 || >=0.1.5-alpha.1 <0.1.6-0 || >=0.1.6-alpha.0 <0.1.7-0 || >=0.1.7-alpha.0 <0.2.0-0 || >=0.2.0-0"
|
|
52
|
+
},
|
|
50
53
|
"publishConfig": {
|
|
51
54
|
"access": "public"
|
|
52
55
|
},
|