dsh-plugin-upgrade 2.0.1 → 2.0.2

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-zh.md CHANGED
@@ -3,16 +3,18 @@
3
3
  # ⬆️ dsh-plugin-upgrade
4
4
  - **1024 商店通道**:先 `npm i -g dsh1024`,再执行 `dsh1024 plugin --profile web add dsh-plugin-upgrade`(计入 [deepseek1024.com](https://deepseek1024.com) 安装排行)。
5
5
  [![Gitee](https://img.shields.io/badge/Gitee-mirror-c71d23?logo=gitee)](https://gitee.com/perrylink/dsh-plugin-upgrade)
6
+ [![dshfind](https://dshfind.com/api/badge/PerryLink/dsh-plugin-upgrade?metric=downloads&lang=zh)](https://dshfind.com/zh/plugins/PerryLink/dsh-plugin-upgrade?ref=badge)
6
7
 
7
- **DeepSeek Harness 插件升级技能(已合并、版本锁定)——`0.1.3-alpha.1` → `0.1.5-rc.1`,由两条闭合的 leg 承载。**
8
+ **DeepSeek Harness 插件升级技能——一个包、一份走廊索引、两条闭合的走廊:`0.1.3-alpha.1` → `0.1.5-rc.1`(`legAB`)与 `0.1.5-rc.2` → `0.1.6-alpha.2`(`legC`)。**
8
9
 
9
- *leg A `0.1.3-alpha.1` → `0.1.5-alpha.1`,leg B `0.1.5-alpha.1` → `0.1.5-rc.1`:一张走廊卡加一个零依赖接缝扫描器,覆盖合并后的 20 条接缝目录,让「静默不挂载的 client 半边」不再被误当成「typecheck 绿了」。*
10
+ *扫描器自行路由:它读取目标仓库声明的 dsh 区间(或接受 `--span`),然后套用那条走廊自己的、证据绑定的目录——`legAB` 的 20 条接缝(leg A `0.1.3-alpha.1` → `0.1.5-alpha.1` 加 leg B `0.1.5-alpha.1` → `0.1.5-rc.1`)或 `legC` 的 5 条接缝(`E1`–`E5`)。只有一个入口,因此「静默停止挂载的 client 半边」永远不会被误当成「typecheck 绿了」。*
10
11
 
11
- > **官方仓库。** 这是 dsh-plugin-upgrade 唯一的官方仓库,由 PerryLink 维护。它取代两个版本锁定的包 `dsh-plugin-upgrade`(leg A)与 `dsh-plugin-upgrade-rc1`(leg B)。其他账号下的同名仓库与本项目无关。
12
+ > **官方仓库。** 这是 dsh-plugin-upgrade 唯一的官方仓库,由 PerryLink 维护。它取代两个已退役的版本锁定包 `dsh-plugin-upgrade`(leg A)与 `dsh-plugin-upgrade-rc1`(leg B),并且 `0.1.5-rc.2` → `0.1.6-alpha.2` 走廊(leg C)就是并入本包的——`dsh-plugin-upgrade-016` 这个名字从未上过 registry。其他账号下的同名仓库与本项目无关。
12
13
 
13
14
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
14
15
  [![DSH plugin](https://img.shields.io/badge/dsh--plugin-✅-green)](https://github.com/topics/dsh-plugin)
15
16
  [![dsh-doctor](https://raw.githubusercontent.com/PerryLink/dsh-plugin-doctor/main/badges/PerryLink__dsh-plugin-upgrade.svg)](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
17
+ [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-zh.svg)](https://dsh.market/)
16
18
  [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
17
19
  [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-plugin-upgrade/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-plugin-upgrade/actions)
18
20
  [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-plugin-upgrade?label=version)](https://github.com/PerryLink/dsh-plugin-upgrade/releases)
@@ -29,21 +31,22 @@
29
31
 
30
32
  | 面 | 状态 |
31
33
  |---|---|
32
- | 宿主 | DeepSeek Harness `0.1.5-rc.1`(tag `dsh-v0.1.5-rc.1` = `183f08e9c6dd`;leg A→B 交接点 `dsh-v0.1.5-alpha.1` = `5dda764ed3aa`;走廊起点 `0.1.3-alpha.1`)。peer 区间 `@deepseek-ai/dsh-skill >=0.1.2-rc.1 <0.2.0 \|\| >=0.1.5-alpha.1 <0.2.0`、`@deepseek-ai/cordis ^4.0.2`、`@deepseek-ai/schemastery ^3.18.2`。 |
34
+ | 宿主 | DeepSeek Harness `0.1.5-rc.1`(tag `dsh-v0.1.7-alpha.2` = `183f08e9c6dd`;leg A→B 交接点 `dsh-v0.1.7-alpha.2` = `5dda764ed3aa`;走廊起点 `0.1.3-alpha.1`),以及 `legC` 对应的 DeepSeek Harness `0.1.6-alpha.2`(tag `dsh-v0.1.7-alpha.2`)。peer 区间 `@deepseek-ai/dsh-skill >=0.1.2-rc.1 <0.2.0 \|\| >=0.1.5-alpha.1 <0.2.0 \|\| >=0.1.6-0 <0.2.0 \|\| >=0.1.7-0 <0.2.0`、`@deepseek-ai/cordis ^4.0.2`、`@deepseek-ai/schemastery ^3.18.2`。 |
33
35
  | Node | `^22.19.0 \|\| >=24.0.0` |
34
36
  | 平台 | 有 Node 即可;扫描器只读文件系统,与平台无关 |
35
37
  | 模型 | 纯文本模型完全支持;技能就是一段 Markdown,不要求工具或视觉能力 |
36
- | 范围 | **两条闭合的 leg,一个跨度**:leg A `0.1.3-alpha.1` → `0.1.5-alpha.1`,加上 leg B `0.1.5-alpha.1` → `0.1.5-rc.1`。走廊永不加宽:`0.1.5-rc.1` 之后的一跳就是一个新包。 |
37
- | Legs | 两条 leg 都在本包内:leg A 保留 `S1`–`S10` + `M1` 接缝,leg B 保留 `C1`、`C2`、`C4`、`C5`、`H1`–`H4`、`P1`——各自带有自己的证据、卡片章节、夹具与回滚路径。没有需要另装的姊妹包。 |
38
+ | 走廊索引 | 一个包、一个入口。`lib/route.mjs` 持有全部闭合走廊,CLI 根据目标仓库声明的区间(`engines.dsh`、`@deepseek-ai/dsh*` 各范围)路由到匹配的那一条;`--span legAB\|legC` 可覆盖猜测,未声明区间时回退到较旧的走廊。两份目录从不合并:每条走廊保留自己的接缝数组、卡片、证据、夹具与一致性门禁。 |
39
+ | 范围 | **两条闭合的走廊**:`legAB` = `0.1.3-alpha.1` → `0.1.5-rc.1`(leg A + leg B),`legC` = `0.1.5-rc.2` → `0.1.6-alpha.2`。走廊永不加宽:新增接缝的一跳就是一条新走廊——一张新卡加一行新索引,而不是一个新包。 |
40
+ | Legs | 每条 leg 都在本包内:leg A 保留 `S1`–`S10` + `M1` 接缝,leg B 保留 `C1`、`C2`、`C4`、`C5`、`H1`–`H4`、`P1`,leg C 保留 `E1`–`E5`——各自带有自己的证据、卡片章节、夹具与回滚路径。没有需要另装的姊妹包。 |
38
41
  | `C3` | 已弃用:leg B 的卡把「类型线陈旧导致的假绿」写作 `C3`,而这与 leg A 的 `M1` 是同一个缺陷。合并一事记录在卡上;`--seams C3` 匹配不到任何东西。 |
39
42
  | 前身包 | 请勿在同一个 profile 中同时挂载已退役的 `dsh-plugin-upgrade`:两者都会注册 agent skill `plugin-upgrade`,第二次挂载会因 skill 名冲突而失败。该包在 npm 上已标记 deprecated、其仓库已退役;本包已取代它的两条腿。 |
40
43
 
41
44
  ## 你得到什么
42
45
 
43
- 两半,一套接缝目录:
46
+ 两半,每条走廊一套接缝目录:
44
47
 
45
48
  - **一个随包发布的 agent 技能(`plugin-upgrade`)** —— 合并后的走廊卡,以及「修-验」循环。正文先把调用者路由到与它 peer 区间相符的那条 leg;只有任务真正需要时模型才会加载它,本包不贡献任何系统提示词段落,也不注册工具。
46
- - **一个零依赖 CLI(`dsh-plugin-upgrade-scan`)** —— 按 `file:line` 报告合并后二十条接缝(`S3`、`S8`、`S9`、`M1`、`S4`、`S5`、`S6`、`S7`、`S2`、`S1`、`S10`、`C1`、`C2`、`P1`、`C4`、`C5`、`H1`、`H2`、`H4`、`H3`)的事实,全部于 2026-09-09(leg A)与 2026-09-10(leg B)从 harness 的 tag 区间重新读取。命中 error 级即退出码 `1`,可直接接进 CI。
49
+ - **一个零依赖 CLI(`dsh-plugin-upgrade-scan`)** —— 解析出走廊,并按 `file:line` 报告那条走廊接缝的事实:`legAB` 的二十条(`S3`、`S8`、`S9`、`M1`、`S4`、`S5`、`S6`、`S7`、`S2`、`S1`、`S10`、`C1`、`C2`、`P1`、`C4`、`C5`、`H1`、`H2`、`H4`、`H3`)于 2026-09-09(leg A)与 2026-09-10(leg B)从 harness 的 tag 区间重新读取,或 `legC` 的五条(`E1`–`E5`)在 `dsh-v0.1.7-alpha.1` 上测得(2026-09-19)。命中 error 级即退出码 `1`,可直接接进 CI。
47
50
 
48
51
  它要消灭的失效模式是:**这一跨度的破坏大多是静默的,而且两端都静默。** 类型线可能陈旧,于是仓库是对着**旧目录**编译的(接缝 `M1`);而裸 `conversation` client slot 被删除且没有别名,`ctx.slots.inject()` 又只在 declaration 存在时才执行回调——于是仍然指向它的 client 半边停止挂载,没有报错、没有日志、构建也不会失败(接缝 `C1`)。有三类破坏能穿过 `typecheck` + `test`:
49
52
 
@@ -66,8 +69,8 @@ dsh --profile web --dump-config | grep -A3 'id: dsh-plugin-upgrade'
66
69
  npx dsh-plugin-upgrade-scan --repo ../my-plugin
67
70
  ```
68
71
 
69
- 然后让 agent 使用 `plugin-upgrade` 技能,或自己按卡驱动循环:
70
- `skills/plugin-upgrade/references/v0.1.3-alpha.1-to-v0.1.5-rc.1.md`(leg A 是 §1,leg B 是 §2,合并后的接缝索引是 §3)。
72
+ 然后让 agent 使用 `plugin-upgrade` 技能,或自己用与你区间相符的卡驱动循环:
73
+ `skills/plugin-upgrade/references/v0.1.3-alpha.1-to-v0.1.5-rc.1.md`(`legAB`——leg A 是 §1,leg B 是 §2,合并后的接缝索引是 §3)或 `skills/plugin-upgrade/references/v0.1.5-rc.2-to-v0.1.6-alpha.2.md`(`legC`)。扫描器会替你选走廊;当声明的区间有歧义时,加上 `--span legC`。
71
74
 
72
75
  ## 安装与卸载
73
76
 
@@ -107,19 +110,20 @@ dsh plugin --profile web remove dsh-plugin-upgrade # 卸载(可逆)
107
110
  **CLI** —— `dsh-plugin-upgrade-scan`:
108
111
 
109
112
  ```sh
110
- dsh-plugin-upgrade-scan [--repo <path>] [--json <out.json>] [--seams S3,C1,P1] [--quiet]
113
+ dsh-plugin-upgrade-scan [--repo <path>] [--span legAB|legC|<span>] [--json <out.json>] [--seams S3,C1,P1] [--quiet]
111
114
  ```
112
115
 
113
116
  | 参数 | 含义 |
114
117
  |---|---|
115
- | `--repo <path>` | 要扫描的仓库(默认当前目录)。 |
118
+ | `--repo <path>` | 要扫描的仓库(默认当前目录)。它声明的 dsh 区间决定走哪条走廊。 |
119
+ | `--span legAB\|legC\|<span>` | 不再根据声明的区间猜测,而是强制指定走廊。未知区间回退到 `legAB`。 |
116
120
  | `--json <out.json>` | 同时写出机器可读报告(`repo`、`scannedAt`、`files`、`hits[]`、`bySeam`)。 |
117
- | `--seams S3,C1,P1` | 只跑合并目录中的指定接缝。 |
121
+ | `--seams S3,C1,P1` | 只跑解析出的那条走廊目录中的指定接缝(接缝 id 从不在走廊之间共享)。 |
118
122
  | `--quiet` | 不打印人类可读渲染(与 `--json` 搭配)。 |
119
123
 
120
124
  退出码:`0` 无 error 级命中 · `1` 至少一个 error 级命中 · `2` 用法或扫描失败。扫描干净是**必要非充分**条件——出口标准是真实宿主冒烟,**加上**日志写入器(leg A)的恢复往返,以及 client 半边(leg B)的真实浏览器断言。
121
125
 
122
- ## 二十条接缝
126
+ ## 二十条 `legAB` 接缝
123
127
 
124
128
  顺序遵循 `lib/scan.mjs` 中的目录(先 leg A,后 leg B),这也是 `test/card.test.mjs` 把卡钉住的顺序。
125
129
 
@@ -148,9 +152,23 @@ dsh-plugin-upgrade-scan [--repo <path>] [--json <out.json>] [--seams S3,C1,P1] [
148
152
 
149
153
  `S7`、`S2`、`S1`、`S10`、`C4`、`C5`、`H1`、`H2` 与 `H4` 刻意保持提示级:它们都有合法命中(已经用了新 API 的仓、一份文档快照、插件自己的模型 id 表、Node 的 `ChildProcess.pid`),所以扫描器把它们作为人工复核线索,而不是失败。`M1` 与 `P1` 是**结构化**检查——它们解析 `package.json` 与 `tsconfig*.json`,而不是匹配文本——而 `H3` 是**仅卡片(card-only)**:有文档、参与 id 一致性校验,且刻意没有检测器(`CARD_ONLY = ['H3']`)。
150
154
 
155
+ ## 五条 `legC` 接缝(`0.1.5-rc.2` → `0.1.6-alpha.2`)
156
+
157
+ 顺序遵循 `lib/scan-0.1.6.mjs` 中的目录,这也是 `test/card.test.mjs` 把 `legC` 卡钉住的顺序。这里每条接缝都是 `error`,且每条都会被检测到(`CARD_ONLY = []`)。
158
+
159
+ | Id | 级别 | 通往 `0.1.6-alpha.2` 的路上变了什么 |
160
+ |---|---|---|
161
+ | `E1` | error | `agent/created` 监听器是串行派发的:抛异常的监听器——或做了慢工作的监听器——会直接阻塞 agent 创建。把同步工作包进 `try`/`catch`,其余用 `queueMicrotask`/`setImmediate` 或你自己的队列延后。 |
162
+ | `E2` | error | 异步 `apply()` 的第一个 `await` 出现在注册之前:此后注册的任何东西都落进卸载窗口并抛 `INACTIVE_EFFECT`,而旧的闭包仍在运行。把一切注册都放在第一个 `await` 之前、放进同一个 `ctx.effect()` 里。 |
163
+ | `E3` | error | 被删除的 slot/state 键:`settings.plugin.item` 变成 keyed→list 的 `plugins.item`,`SessionListState.current` 消失——设置卡会**静默**消失(`spec === undefined` 提前返回),而 `current` 的类型断言照旧编译,功能却已死。 |
164
+ | `E4` | error | 被删除的 client API:`sessions.open` / `openSubagent` / `clear` 变成 `retain` / `using` / `retainInfo`。 |
165
+ | `E5` | error | 被删除的模型字面量:`deepseek-v4-flash*` 与 `deepseek-v4-vision-exp`。默认模型目录从 4 缩到 2,未编入目录的 id 以纯文本方式透传。 |
166
+
167
+ 与 `legAB` 相同的纪律同样适用:扫描干净是必要而非充分条件。`legC` 的破坏是静默的或仅运行时的(已发布的类型线掩盖了那些删除),所以出口标准仍是在临时 `DSH_HOME` 上的真实宿主冒烟,外加适用情况下的日志写入器往返与真实浏览器断言。
168
+
151
169
  ## 本包不覆盖什么
152
170
 
153
- - **`0.1.5-rc.1` 之后的一跳。** 合并跨度按构造终止于 rc.1:harness 从 `0.1.5-rc.1` 到 `0.1.5-rc.2` 的一跳没有新增任何面向插件的接缝(本包自己的 dev/test 钉版与 CI 探针跑在 `0.1.5-rc.2` 线上,因此目录是对着最新已发布类型校验的)。之后任何新增接缝的东西都是**一个新包**——一张会漂移的卡比没有卡更糟。
171
+ - **越过本包任何一条走廊的一跳。** `legAB` 按构造终止于 `0.1.5-rc.1`:harness 从 `0.1.5-rc.1` 到 `0.1.5-rc.2` 的一跳没有新增任何面向插件的接缝(本包自己的 dev/test 钉版现已跑到 `0.1.7-alpha.2` 线,因此目录是对着那些已发布类型校验的;compat workflow 的探针仍锚定 `0.1.6-alpha.2`),而 `legC` 覆盖 `0.1.5-rc.2` → `0.1.6-alpha.2`。之后任何新增接缝的一跳都**不**被覆盖:走廊是闭合的,加宽一张卡比新增一张卡更糟。它会得到一张新卡和一行新索引——而不是一个新包。
154
172
  - **`0.1.1` → `0.1.2` 这一跳。** 请使用社区收敛技能。
155
173
  - **跨 leg 重述。** leg A 拥有会话格式接缝(`assistant/message.stream`、`SessionHandleReadResult`、`EpochHeader.system`、`ctx.agent`、`Inbox`、`SystemPrompt.persona`、V3 日志 generation),leg B 不重述它们——leg B 区间内 `packages/core/session/src` 的全部 diff 只有两个新增的事件类型字面量与一行注释。每条 leg 的卡片章节保留自己的范围声明。
156
174
  - **DSH 面向用户的升级路径。** 本包升级的是**插件源码**,不是用户的 harness 安装。
@@ -175,15 +193,15 @@ npm run check:readmes # 五语 README 一致性
175
193
  npm pack
176
194
  ```
177
195
 
178
- 扫描器**每条 leg 各有一对**合成夹具:`fixtures/leg-a-bad-repo`(leg A 的会话/配置接缝,故意包含全部 error 级接缝)配 `fixtures/leg-a-good-repo`(已适配),以及 `fixtures/bad-repo`(leg B 的 client slot 接缝)配 `fixtures/good-repo`(已适配)——再外加拿一个已钉 `0.1.5-rc.1` 的家族仓做 live negative,所以目录里的回归会在这个测试套件里失败,而不是在下游用户那里。`test/card.test.mjs` 断言合并后的卡片索引与 `lib/scan.mjs` 命名的**正好**是同样二十个接缝 id、同样的级别,并且 `CARD_ONLY` 正好是 `['H3']`——把「证据绑定」规则变成机器门禁。
196
+ 扫描器**每条 `legAB` leg 各有一对**合成夹具:`fixtures/leg-a-bad-repo`(leg A 的会话/配置接缝,故意包含全部 error 级接缝)配 `fixtures/leg-a-good-repo`(已适配),以及 `fixtures/bad-repo`(leg B 的 client slot 接缝)配 `fixtures/good-repo`(已适配)——再外加拿一个已钉 `0.1.5-rc.1` 的家族仓做 live negative,所以目录里的回归会在这个测试套件里失败,而不是在下游用户那里。`test/card.test.mjs` 断言每张卡的索引与它自己的目录(`legAB` 用 `lib/scan.mjs`,`legC` 用 `lib/scan-0.1.6.mjs`)命名的**正好**是同样的接缝 id、同样的级别,`legAB` 的 `CARD_ONLY` 正好是 `['H3']` 而 `legC` 的是空,并且两份目录不共享任何接缝 id——把「证据绑定」规则变成机器门禁,每条走廊各一道。
179
197
 
180
198
  ## 主题标签
181
199
 
182
200
  `dsh`、`dsh-plugin`、`deepseek-harness`、`deepseek`、`cordis`、`plugin-upgrade`、`migration`、`skill`、`version-card`、`scanner`、`client-slots`(与 `package.json` keywords 一致;`dsh-plugin` 是生态的可见性通道)。
183
201
 
184
- ## PerryLink DSH 插件家族
202
+ ## PerryLink DSH Plugin Family
185
203
 
186
- 这是 [PerryLink](https://github.com/PerryLink) 维护的 [40 个 DeepSeek Harness 插件](https://github.com/PerryLink) 之一。如果它能帮到你,其他的也会:
204
+ This project is one of the **45 DeepSeek Harness plugins** maintained by [PerryLink](https://github.com/PerryLink). If this one helps you, the others likely will too:
187
205
 
188
206
  | Plugin | One-liner |
189
207
  |---|---|
@@ -193,48 +211,46 @@ npm pack
193
211
  | **[dsh-budget](https://github.com/PerryLink/dsh-budget)** | Cost governance for DeepSeek Harness: budgets, carbon, and latency in one panel. | |
194
212
  | **[dsh-catalog](https://github.com/PerryLink/dsh-catalog)** | DSH Desktop Market standard catalog source for the PerryLink family | |
195
213
  | **[dsh-cert-mcp](https://github.com/PerryLink/dsh-cert-mcp)** | Read-only MCP server exposing the certification registry: grades, snapshots and five-dimension evidence | |
196
- | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | Unified session + workspace + config checkpoints with one-shot `/rewind` | |
197
- | **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | Migrate Claude Code, Codex, OpenCode and Hermes sessions, memories and skills into DSH | |
214
+ | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | Claude Code /rewind-equivalent: snapshots, session forks, one-shot restore | |
215
+ | **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | Migrate Claude Code sessions, memory, skills and CLAUDE.md into DSH | |
198
216
  | **[dsh-click](https://github.com/PerryLink/dsh-click)** | Cross-platform native desktop control for DeepSeek Harness — Windows first. | |
199
217
  | **[dsh-composer-history](https://github.com/PerryLink/dsh-composer-history)** | Terminal-style input history for the web composer: arrows, Ctrl+R search | |
200
- | **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | Deterministic dataset profiling, cleaning and citation verification | |
218
+ | **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | Dataset quality checks and citation cross-checks (the optional numeric bridge consumed here) | |
201
219
  | **[dsh-defend](https://github.com/PerryLink/dsh-defend)** | Prompt-injection, jailbreak, and secret-leak defense for DeepSeek Harness. | |
202
220
  | **[dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck)** | Engineering-discipline guard: requirements grill, test gates, adversary review | |
203
221
  | **[dsh-draw](https://github.com/PerryLink/dsh-draw)** | Unified static-image generation routing for DeepSeek Harness. | |
204
- | **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | Read-only performance diagnostics: load, spill, compaction and cache hit rate | |
205
- | **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | Chinese mutual-fund research with sealed, traceable source snapshots | |
206
- | **[dsh-github](https://github.com/PerryLink/dsh-github)** | GitHub PR/issue/CI integration with every write approval-gated | |
207
- | **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | Industry and company research pack: chain map, policy timeline, company cards | |
208
- | **[dsh-kit](https://github.com/PerryLink/dsh-kit)** | One-command starter pack that installs the core family | |
209
- | **[dsh-library](https://github.com/PerryLink/dsh-library)** | Local document knowledge base with hybrid search and citation-aware injection | |
210
- | **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | Local Ollama model discovery and task-based routing with cloud fallback | |
211
- | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | LSP diagnostics, formatting, completion, code actions, symbols and rename | |
212
- | **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | PII masking at the model boundary with a host-side restore table | |
213
- | **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | MCP management console: `/mcp` command, Settings tab and trial calls | |
214
- | **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | Approval-gated cross-session memory protocol (`ctx.memory` + SQLite) | |
215
- | **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | OpenTelemetry and Langfuse telemetry export from the session event stream | |
216
- | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | Runtime-switchable model output styles | |
217
- | **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | Declarative allow/deny/ask rules plus a process-level network policy | |
222
+ | **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | Read-only performance diagnostics for DeepSeek Harness. | |
223
+ | **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | Deterministic research reports for Chinese public mutual funds | |
224
+ | **[dsh-github](https://github.com/PerryLink/dsh-github)** | GitHub PR/issues integration for DSH, every write gated by approval | |
225
+ | **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | Industry research orchestration that seals its deliverables through this plugin's `ctx.researchReport.assemble` | |
226
+ | **[dsh-laya](https://github.com/PerryLink/dsh-laya)** | Laya typed decisions (`noul`/`choice`/`score`) as a first-class Cordis service and model-visible tools | |
227
+ | **[dsh-library](https://github.com/PerryLink/dsh-library)** | Local document knowledge base for DeepSeek Harness. | |
228
+ | **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | Local-model (Ollama) integration for DeepSeek Harness. | |
229
+ | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | LSP diagnostics, formatting, completion, code actions and rename over language servers | |
230
+ | **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | PII masking middleware: anonymize at the model boundary, restore at the display layer | |
231
+ | **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | Read-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors | |
232
+ | **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool | |
233
+ | **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | OpenTelemetry and Langfuse observability exporter for DeepSeek Harness. | |
234
+ | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | Claude Code outputStyles-equivalent runtime style switching | |
235
+ | **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | Claude Code-style declarative allow/deny/ask permission rules with audit | |
218
236
  | **[dsh-plugin-certification](https://github.com/PerryLink/dsh-plugin-certification)** | Community certification registry with repro-checkable grades and badges | |
219
237
  | **[dsh-plugin-doctor](https://github.com/PerryLink/dsh-plugin-doctor)** | Zero-dependency static + sandbox smoke detector for DSH plugins | |
220
- | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | Plugin-dev knowledge base, agent skill and the `dsh-plugin-dev` CLI toolchain | |
238
+ | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | Plugin-development knowledge base as an on-demand agent skill | |
221
239
  | **[dsh-plugin-kit](https://github.com/PerryLink/dsh-plugin-kit)** | Shared zero-runtime-dependency toolkit for the PerryLink DSH plugins | |
222
- | **[dsh-plugin-portal](https://github.com/PerryLink/dsh-plugin-portal)** | Zero-dependency static portal rendering the whole plugin family as one page | |
223
- | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | Multi-channel approval/question bridge: WeChat, Telegram, Feishu + a session console | |
224
- | **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | Verifiable research reports: evidence ledger, manifest seal, per-claim verdicts | |
225
- | **[dsh-score](https://github.com/PerryLink/dsh-score)** | Multi-dimensional plugin quality scoring with an evidence-backed leaderboard | |
226
- | **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | Pin sessions and workspaces in the Web sidebar with per-pin colors | |
227
- | **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | Git-backed cross-device session synchronization with keep-both merges | |
228
- | **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | Security-audit skill pack plus the `plugin_vet` supply-chain gate | |
229
- | **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | Voice-first session loop: speech-to-text input and text-to-speech replies | |
240
+ | **[dsh-plugin-upgrade](https://github.com/PerryLink/dsh-plugin-upgrade)** | One-package, one-corridor-index plugin upgrade skill: routes a repository to the matching closed corridor card | |
241
+ | **[dsh-plugin-upgrade-015](https://github.com/PerryLink/dsh-plugin-upgrade-015)** | Merged `0.1.3-alpha.1` → `0.1.5-rc.1` upgrade corridor card plus a zero-dependency seam scanner | |
242
+ | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | Multi-channel approval/question bridge: WeChat/Telegram/Feishu, session console | |
243
+ | **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | Verifiable research-report engine: content-addressed evidence ledger and sealed versions | |
244
+ | **[dsh-score](https://github.com/PerryLink/dsh-score)** | Multi-dimensional quality scoring for DeepSeek Harness plugins. | |
245
+ | **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | Pin sessions in the Web sidebar with durable ordering | |
246
+ | **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | Cross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store. | |
247
+ | **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | Security-audit skill pack: secret scan, dependency and supply-chain review | |
248
+ | **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | Voice-first session loop for DeepSeek Harness: talk to it, hear it answer. | |
230
249
  | **[dsh-team-rooms](https://github.com/PerryLink/dsh-team-rooms)** | Cross-session team rooms: shared message bus, task board and timeline | |
231
- | **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | Isolated install-and-smoke test drives with a pass/fail matrix | |
232
- | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | TickTick/Dida365 task bridge: session-header panel plus eleven agent tools | |
233
- | **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | Vendor parameter translation and deterministic JSON repair | |
234
- | **[dsh-wechat](https://github.com/pan17/dsh-wechat)** | WeChat ↔ DSH bridge (Tencent iLink bot) developed with [pan17](https://github.com/pan17/dsh-wechat), who hosts the repo | |
235
- | **[dsh-personal-directive](https://github.com/PerryLink/dsh-personal-directive)** | Personal directive injector with a top-bar toggle (fork of liucai2026/dsh-personal-directive) | |
250
+ | **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | Isolated install-and-smoke test drives for DeepSeek Harness plugins. | |
251
+ | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | TickTick/Dida365 task bridge: session-header panel + 11 tools | |
252
+ | **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | Vendor parameter translation and deterministic JSON repair for DeepSeek Harness. | |
236
253
 
237
- 属于 PerryLink DSH 插件家族——40+ 个仓库,覆盖会话、记忆、权限、交付、可观测性与开发者工具。目录见 [perrylink-dsh-catalog.perrylink.workers.dev](https://perrylink-dsh-catalog.perrylink.workers.dev) 或 [`dsh-plugin` 主题](https://github.com/topics/dsh-plugin)。
238
254
 
239
255
  ## 许可证
240
256
 
package/README.md CHANGED
@@ -3,16 +3,19 @@
3
3
  # ⬆️ dsh-plugin-upgrade
4
4
  - **1024 store channel**: `npm i -g dsh1024` once, then `dsh1024 plugin --profile web add dsh-plugin-upgrade` (counts toward the [deepseek1024.com](https://deepseek1024.com) install ranking).
5
5
  [![Gitee](https://img.shields.io/badge/Gitee-mirror-c71d23?logo=gitee)](https://gitee.com/perrylink/dsh-plugin-upgrade)
6
+ [![dshfind](https://dshfind.com/api/badge/PerryLink/dsh-plugin-upgrade?metric=downloads)](https://dshfind.com/plugins/PerryLink/dsh-plugin-upgrade?ref=badge)
7
+ [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/PerryLink/dsh-plugin-upgrade/badge)](https://api.securityscorecards.dev/projects/github.com/PerryLink/dsh-plugin-upgrade)
6
8
 
7
- **Merged, version-locked plugin upgrade skill for DeepSeek Harness — `0.1.3-alpha.1` → `0.1.5-rc.1`, carried as two closed legs.**
9
+ **Plugin upgrade skill for DeepSeek Harness — one package, one corridor index, two closed corridors: `0.1.3-alpha.1` → `0.1.5-rc.1` (`legAB`) and `0.1.5-rc.2` → `0.1.6-alpha.2` (`legC`).**
8
10
 
9
- *Leg A `0.1.3-alpha.1` → `0.1.5-alpha.1`, leg B `0.1.5-alpha.1` → `0.1.5-rc.1`: one corridor card plus one zero-dependency seam scanner over the merged 20-seam catalog, so a client half that stopped mounting silently is never mistaken for "typecheck is green".*
11
+ *The scanner routes itself: it reads the target repository's declared dsh band (or takes `--span`), then applies that corridor's own evidence-bound catalog — `legAB`'s 20 seams (leg A `0.1.3-alpha.1` → `0.1.5-alpha.1` plus leg B `0.1.5-alpha.1` → `0.1.5-rc.1`) or `legC`'s 5 seams (`E1`–`E5`). One entry point, so a client half that stopped mounting silently is never mistaken for "typecheck is green".*
10
12
 
11
- > **Official repository.** This is the only official repository of dsh-plugin-upgrade, maintained by PerryLink. It supersedes the two version-locked packages `dsh-plugin-upgrade` (leg A) and `dsh-plugin-upgrade-rc1` (leg B). Same-name repositories under other accounts are not affiliated.
13
+ > **Official repository.** This is the only official repository of dsh-plugin-upgrade, maintained by PerryLink. It supersedes the retired version-locked packages `dsh-plugin-upgrade` (leg A) and `dsh-plugin-upgrade-rc1` (leg B), and it is the package the `0.1.5-rc.2` → `0.1.6-alpha.2` corridor (leg C) was folded into — the `dsh-plugin-upgrade-016` name never reached the registry. Same-name repositories under other accounts are not affiliated.
12
14
 
13
15
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
14
16
  [![DSH plugin](https://img.shields.io/badge/dsh--plugin-✅-green)](https://github.com/topics/dsh-plugin)
15
17
  [![dsh-doctor](https://raw.githubusercontent.com/PerryLink/dsh-plugin-doctor/main/badges/PerryLink__dsh-plugin-upgrade.svg)](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
18
+ [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-en.svg)](https://dsh.market/)
16
19
  [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
17
20
  [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-plugin-upgrade/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-plugin-upgrade/actions)
18
21
  [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-plugin-upgrade?label=version)](https://github.com/PerryLink/dsh-plugin-upgrade/releases)
@@ -29,21 +32,22 @@
29
32
 
30
33
  | Surface | Status |
31
34
  |---|---|
32
- | Harness | DeepSeek Harness `0.1.5-rc.1` (tag `dsh-v0.1.5-rc.1` = `183f08e9c6dd`; leg A→B handoff `dsh-v0.1.5-alpha.1` = `5dda764ed3aa`; corridor start `0.1.3-alpha.1`). Peer band `@deepseek-ai/dsh-skill >=0.1.2-rc.1 <0.2.0 \|\| >=0.1.5-alpha.1 <0.2.0`, `@deepseek-ai/cordis ^4.0.2`, `@deepseek-ai/schemastery ^3.18.2`. |
35
+ | Harness | DeepSeek Harness `0.1.5-rc.1` (tag `dsh-v0.1.7-alpha.2` = `183f08e9c6dd`; leg A→B handoff `dsh-v0.1.7-alpha.2` = `5dda764ed3aa`; corridor start `0.1.3-alpha.1`) and, for `legC`, DeepSeek Harness `0.1.6-alpha.2` (tag `dsh-v0.1.7-alpha.2`). Peer band `@deepseek-ai/dsh-skill >=0.1.2-rc.1 <0.2.0 \|\| >=0.1.5-alpha.1 <0.2.0 \|\| >=0.1.6-0 <0.2.0 \|\| >=0.1.7-0 <0.2.0`, `@deepseek-ai/cordis ^4.0.2`, `@deepseek-ai/schemastery ^3.18.2`. |
33
36
  | Node | `^22.19.0 \|\| >=24.0.0` |
34
37
  | Platforms | Anywhere Node runs; the scanner is filesystem-only and platform-neutral |
35
38
  | Model | Text-only models fully supported; the skill is a Markdown body, no tool or vision requirement |
36
- | Scope | **Two closed legs, one span**: leg A `0.1.3-alpha.1` → `0.1.5-alpha.1` plus leg B `0.1.5-alpha.1` → `0.1.5-rc.1`. A corridor never widens: a hop after `0.1.5-rc.1` is a new package. |
37
- | Legs | Both legs live in this package: leg A keeps the `S1`–`S10` + `M1` seams, leg B keeps `C1`, `C2`, `C4`, `C5`, `H1`–`H4`, `P1` — each with its own evidence, card section, fixtures and rollback path. There is no sibling package to install. |
39
+ | Corridor index | One package, one entry point. `lib/route.mjs` holds the closed corridors and the CLI routes to the matching one from the target repo's declared band (`engines.dsh`, the `@deepseek-ai/dsh*` ranges); `--span legAB\|legC` overrides the guess and an undeclared band falls back to the older corridor. The two catalogs are never merged: each corridor keeps its own seam array, card, evidence, fixtures and parity gate. |
40
+ | Scope | **Two closed corridors**: `legAB` = `0.1.3-alpha.1` → `0.1.5-rc.1` (leg A + leg B), `legC` = `0.1.5-rc.2` → `0.1.6-alpha.2`. A corridor never widens: a hop that adds a seam is a new corridor — a new card and a new index row, not a new package. |
41
+ | Legs | Every leg lives in this package: leg A keeps the `S1`–`S10` + `M1` seams, leg B keeps `C1`, `C2`, `C4`, `C5`, `H1`–`H4`, `P1`, and leg C keeps `E1`–`E5` — each with its own evidence, card section, fixtures and rollback path. There is no sibling package to install. |
38
42
  | `C3` | Retired: leg B's card spelled the stale-type-line false green `C3`, which is the same defect as leg A's `M1`. The fold is recorded on the card; `--seams C3` matches nothing. |
39
43
  | Sibling | Do not mount the retired `dsh-plugin-upgrade` in the same profile: both register the agent skill `plugin-upgrade`, so the second mount collides on the skill name. That package is deprecated on npm and its repository is retired; this package replaces both of its legs. |
40
44
 
41
45
  ## What you get
42
46
 
43
- Two halves, one seam catalog:
47
+ Two halves, one seam catalog per corridor:
44
48
 
45
- - **A bundled agent skill (`plugin-upgrade`)** — the merged corridor card and a fix-and-verify loop. The body first routes the caller to the leg that matches its peer band; the model loads it only when a task actually needs it, and the package contributes no system-prompt paragraph and no tool.
46
- - **A zero-dependency CLI (`dsh-plugin-upgrade-scan`)** — reports `file:line` facts for the merged twenty seams (`S3`, `S8`, `S9`, `M1`, `S4`, `S5`, `S6`, `S7`, `S2`, `S1`, `S10`, `C1`, `C2`, `P1`, `C4`, `C5`, `H1`, `H2`, `H4`, `H3`) re-read from the harness tag ranges on 2026-09-09 (leg A) and 2026-09-10 (leg B). Exit `1` on any error-severity hit, so it drops straight into CI.
49
+ - **A bundled agent skill (`plugin-upgrade`)** — the corridor cards and a fix-and-verify loop. The body first routes the caller to the corridor that matches its peer band; the model loads it only when a task actually needs it, and the package contributes no system-prompt paragraph and no tool.
50
+ - **A zero-dependency CLI (`dsh-plugin-upgrade-scan`)** — resolves the corridor and reports `file:line` facts for that corridor's seams: `legAB`'s twenty (`S3`, `S8`, `S9`, `M1`, `S4`, `S5`, `S6`, `S7`, `S2`, `S1`, `S10`, `C1`, `C2`, `P1`, `C4`, `C5`, `H1`, `H2`, `H4`, `H3`) re-read from the harness tag ranges on 2026-09-09 (leg A) and 2026-09-10 (leg B), or `legC`'s five (`E1`–`E5`) measured on `dsh-v0.1.7-alpha.1` (2026-09-19). Exit `1` on any error-severity hit, so it drops straight into CI.
47
51
 
48
52
  The point is the failure mode this corridor exists to kill: **this span's breakage is mostly silent, from both ends.** The type line can be stale, so the repo compiles against the **old** catalog (seam `M1`), and the bare `conversation` client slot was deleted with no alias while `ctx.slots.inject()` only runs its callback when the declaration exists — so a client half that still targets it stops mounting with no error, no log line and no failed build (seam `C1`). Three classes of breakage survive `typecheck` + `test`:
49
53
 
@@ -66,8 +70,7 @@ dsh --profile web --dump-config | grep -A3 'id: dsh-plugin-upgrade'
66
70
  npx dsh-plugin-upgrade-scan --repo ../my-plugin
67
71
  ```
68
72
 
69
- Then ask the agent to use the `plugin-upgrade` skill, or drive the loop yourself with the card at
70
- `skills/plugin-upgrade/references/v0.1.3-alpha.1-to-v0.1.5-rc.1.md` (leg A is §1, leg B is §2, the merged seam index is §3).
73
+ Then ask the agent to use the `plugin-upgrade` skill, or drive the loop yourself with the card that matches your band: `skills/plugin-upgrade/references/v0.1.3-alpha.1-to-v0.1.5-rc.1.md` (`legAB` — leg A is §1, leg B is §2, the merged seam index is §3) or `skills/plugin-upgrade/references/v0.1.5-rc.2-to-v0.1.6-alpha.2.md` (`legC`). The scanner picks the corridor for you; add `--span legC` when the declared band is ambiguous.
71
74
 
72
75
  ## Install & uninstall
73
76
 
@@ -107,19 +110,20 @@ The plugin mounts loud: a missing `SKILL.md`, an empty body, or a frontmatter wi
107
110
  **CLI** — `dsh-plugin-upgrade-scan`:
108
111
 
109
112
  ```sh
110
- dsh-plugin-upgrade-scan [--repo <path>] [--json <out.json>] [--seams S3,C1,P1] [--quiet]
113
+ dsh-plugin-upgrade-scan [--repo <path>] [--span legAB|legC|<span>] [--json <out.json>] [--seams S3,C1,P1] [--quiet]
111
114
  ```
112
115
 
113
116
  | Flag | Meaning |
114
117
  |---|---|
115
- | `--repo <path>` | Repository to scan (default: cwd). |
118
+ | `--repo <path>` | Repository to scan (default: cwd). Its declared dsh band chooses the corridor. |
119
+ | `--span legAB\|legC\|<span>` | Force a corridor instead of guessing from the declared band. An unknown band falls back to `legAB`. |
116
120
  | `--json <out.json>` | Also write the machine-readable report (`repo`, `scannedAt`, `files`, `hits[]`, `bySeam`). |
117
- | `--seams S3,C1,P1` | Restrict to specific seams of the merged catalog. |
121
+ | `--seams S3,C1,P1` | Restrict to specific seams of the resolved corridor's catalog (ids are never shared between corridors). |
118
122
  | `--quiet` | Suppress the human rendering (pair with `--json`). |
119
123
 
120
124
  Exit codes: `0` no error-severity hit · `1` at least one error-severity hit · `2` usage or scan failure. A clean scan is necessary but not sufficient — the exit criterion is a real-host smoke, plus a resume round-trip for log writers (leg A) and a real browser assertion for the client half (leg B).
121
125
 
122
- ## The twenty seams
126
+ ## The twenty `legAB` seams
123
127
 
124
128
  Order follows the catalog in `lib/scan.mjs` (leg A first, then leg B), which is also the order `test/card.test.mjs` pins the card to.
125
129
 
@@ -148,9 +152,23 @@ Order follows the catalog in `lib/scan.mjs` (leg A first, then leg B), which is
148
152
 
149
153
  `S7`, `S2`, `S1`, `S10`, `C4`, `C5`, `H1`, `H2` and `H4` are deliberately advisory: they have legitimate matches (a repo that already uses the new API, a documentation snapshot, a plugin's own model-id table, a Node `ChildProcess.pid`), so the scanner reports them as leads for manual review rather than failures. `M1` and `P1` are **structured** checks — they resolve `package.json` and `tsconfig*.json` instead of matching text — and `H3` is **card-only**: documented, id-parity checked, and deliberately without a detector (`CARD_ONLY = ['H3']`).
150
154
 
155
+ ## The five `legC` seams (`0.1.5-rc.2` → `0.1.6-alpha.2`)
156
+
157
+ Order follows the catalog in `lib/scan-0.1.6.mjs`, which is also the order `test/card.test.mjs` pins the `legC` card to. Every seam here is `error` and every one is detected (`CARD_ONLY = []`).
158
+
159
+ | Id | Severity | What changed on the way to `0.1.6-alpha.2` |
160
+ |---|---|---|
161
+ | `E1` | error | `agent/created` listeners are dispatched serially: a listener that throws — or that does slow work — blocks agent creation outright. Wrap synchronous work in `try`/`catch` and defer the rest with `queueMicrotask`/`setImmediate` or your own queue. |
162
+ | `E2` | error | An async `apply()` whose first `await` precedes its registrations: anything registered afterwards lands in the unload window and throws `INACTIVE_EFFECT`, while the old closure keeps running. Register everything before the first `await`, inside one `ctx.effect()`. |
163
+ | `E3` | error | Deleted slot/state keys: `settings.plugin.item` became the keyed→list `plugins.item`, and `SessionListState.current` is gone — a settings card disappears **silently** (`spec === undefined` early return), and `current` casts keep compiling while the feature is dead. |
164
+ | `E4` | error | Deleted client API: `sessions.open` / `openSubagent` / `clear` became `retain` / `using` / `retainInfo`. |
165
+ | `E5` | error | Deleted model literals: `deepseek-v4-flash*` and `deepseek-v4-vision-exp`. The default model catalog shrank from 4 to 2, and an uncatalogued id passes through as text-only. |
166
+
167
+ The same discipline applies as for `legAB`: a clean scan is necessary, not sufficient. `legC` breakage is silent or runtime-only (the published type line hides the deletions), so the exit criterion stays a real-host smoke on a temp `DSH_HOME`, plus the log-writer round-trip and the real-browser assertion where they apply.
168
+
151
169
  ## What this does not cover
152
170
 
153
- - **A hop after `0.1.5-rc.1`.** The merged span ends at rc.1 by construction: the harness hop `0.1.5-rc.1` → `0.1.5-rc.2` added no plugin-facing seam (this package's own dev/test pin and CI probe run on the `0.1.5-rc.2` line so the catalog is verified against the newest published types). Anything that adds a seam later is a **new package** — a card that drifts is worse than no card.
171
+ - **A hop past every corridor here.** `legAB` ends at `0.1.5-rc.1` by construction: the harness hop `0.1.5-rc.1` → `0.1.5-rc.2` added no plugin-facing seam (this package's own dev/test pin now runs on the `0.1.7-alpha.2` line, so the catalog is verified against those published types; the compat workflow's probe still anchors `0.1.6-alpha.2`), and `legC` covers `0.1.5-rc.2` → `0.1.6-alpha.2`. A later hop that adds a seam is **not** covered: a corridor is closed, and widening a card is worse than adding one. It gets a new card and a new index row — not a new package.
154
172
  - **The `0.1.1` → `0.1.2` hop.** Use the community convergence skill.
155
173
  - **Restating across legs.** Leg A owns the session-format seams (`assistant/message.stream`, `SessionHandleReadResult`, `EpochHeader.system`, `ctx.agent`, `Inbox`, `SystemPrompt.persona`, the V3 log generation) and leg B does not restate them — the whole `packages/core/session/src` diff in leg B's range is two added event-type literals and one comment line. Each leg's card section keeps its own scope statement.
156
174
  - **The DSH user-facing upgrade path.** This package upgrades *plugin source code*, not a user's harness installation.
@@ -175,7 +193,7 @@ npm run check:readmes # five-language README consistency
175
193
  npm pack
176
194
  ```
177
195
 
178
- The scanner has a synthetic fixture pair **per leg**: `fixtures/leg-a-bad-repo` (leg A's session/config seams, every error seam present on purpose) with `fixtures/leg-a-good-repo` (adapted), and `fixtures/bad-repo` (leg B's client-slot seams) with `fixtures/good-repo` (adapted) — plus a live negative on a family repository already pinned to `0.1.5-rc.1`, so a regression in the catalog fails the suite rather than a downstream user. `test/card.test.mjs` asserts that the merged card index and `lib/scan.mjs` name **exactly** the same twenty seam ids with the same severities, and that `CARD_ONLY` is exactly `['H3']` — the evidence-binding rule as a machine gate.
196
+ The scanner has a synthetic fixture pair **per `legAB` leg**: `fixtures/leg-a-bad-repo` (leg A's session/config seams, every error seam present on purpose) with `fixtures/leg-a-good-repo` (adapted), and `fixtures/bad-repo` (leg B's client-slot seams) with `fixtures/good-repo` (adapted) — plus a live negative on a family repository already pinned to `0.1.5-rc.1`, so a regression in the catalog fails the suite rather than a downstream user. `test/card.test.mjs` asserts that each card's index and its own catalog (`lib/scan.mjs` for `legAB`, `lib/scan-0.1.6.mjs` for `legC`) name **exactly** the same seam ids with the same severities, that `legAB`'s `CARD_ONLY` is exactly `['H3']` while `legC`'s is empty, and that the two catalogs share no seam id — the evidence-binding rule as a machine gate, per corridor.
179
197
 
180
198
  ## Topics
181
199
 
@@ -183,7 +201,7 @@ The scanner has a synthetic fixture pair **per leg**: `fixtures/leg-a-bad-repo`
183
201
 
184
202
  ## PerryLink DSH Plugin Family
185
203
 
186
- This project is one of the [40 DeepSeek Harness plugins](https://github.com/PerryLink) maintained by [PerryLink](https://github.com/PerryLink). If this one helps you, the others likely will too:
204
+ This project is one of the **45 DeepSeek Harness plugins** maintained by [PerryLink](https://github.com/PerryLink). If this one helps you, the others likely will too:
187
205
 
188
206
  | Plugin | One-liner |
189
207
  |---|---|
@@ -193,48 +211,46 @@ This project is one of the [40 DeepSeek Harness plugins](https://github.com/Perr
193
211
  | **[dsh-budget](https://github.com/PerryLink/dsh-budget)** | Cost governance for DeepSeek Harness: budgets, carbon, and latency in one panel. | |
194
212
  | **[dsh-catalog](https://github.com/PerryLink/dsh-catalog)** | DSH Desktop Market standard catalog source for the PerryLink family | |
195
213
  | **[dsh-cert-mcp](https://github.com/PerryLink/dsh-cert-mcp)** | Read-only MCP server exposing the certification registry: grades, snapshots and five-dimension evidence | |
196
- | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | Unified session + workspace + config checkpoints with one-shot `/rewind` | |
197
- | **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | Migrate Claude Code, Codex, OpenCode and Hermes sessions, memories and skills into DSH | |
214
+ | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | Claude Code /rewind-equivalent: snapshots, session forks, one-shot restore | |
215
+ | **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | Migrate Claude Code sessions, memory, skills and CLAUDE.md into DSH | |
198
216
  | **[dsh-click](https://github.com/PerryLink/dsh-click)** | Cross-platform native desktop control for DeepSeek Harness — Windows first. | |
199
217
  | **[dsh-composer-history](https://github.com/PerryLink/dsh-composer-history)** | Terminal-style input history for the web composer: arrows, Ctrl+R search | |
200
- | **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | Deterministic dataset profiling, cleaning and citation verification | |
218
+ | **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | Dataset quality checks and citation cross-checks (the optional numeric bridge consumed here) | |
201
219
  | **[dsh-defend](https://github.com/PerryLink/dsh-defend)** | Prompt-injection, jailbreak, and secret-leak defense for DeepSeek Harness. | |
202
220
  | **[dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck)** | Engineering-discipline guard: requirements grill, test gates, adversary review | |
203
221
  | **[dsh-draw](https://github.com/PerryLink/dsh-draw)** | Unified static-image generation routing for DeepSeek Harness. | |
204
- | **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | Read-only performance diagnostics: load, spill, compaction and cache hit rate | |
205
- | **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | Chinese mutual-fund research with sealed, traceable source snapshots | |
206
- | **[dsh-github](https://github.com/PerryLink/dsh-github)** | GitHub PR/issue/CI integration with every write approval-gated | |
207
- | **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | Industry and company research pack: chain map, policy timeline, company cards | |
208
- | **[dsh-kit](https://github.com/PerryLink/dsh-kit)** | One-command starter pack that installs the core family | |
209
- | **[dsh-library](https://github.com/PerryLink/dsh-library)** | Local document knowledge base with hybrid search and citation-aware injection | |
210
- | **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | Local Ollama model discovery and task-based routing with cloud fallback | |
211
- | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | LSP diagnostics, formatting, completion, code actions, symbols and rename | |
212
- | **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | PII masking at the model boundary with a host-side restore table | |
213
- | **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | MCP management console: `/mcp` command, Settings tab and trial calls | |
214
- | **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | Approval-gated cross-session memory protocol (`ctx.memory` + SQLite) | |
215
- | **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | OpenTelemetry and Langfuse telemetry export from the session event stream | |
216
- | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | Runtime-switchable model output styles | |
217
- | **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | Declarative allow/deny/ask rules plus a process-level network policy | |
222
+ | **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | Read-only performance diagnostics for DeepSeek Harness. | |
223
+ | **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | Deterministic research reports for Chinese public mutual funds | |
224
+ | **[dsh-github](https://github.com/PerryLink/dsh-github)** | GitHub PR/issues integration for DSH, every write gated by approval | |
225
+ | **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | Industry research orchestration that seals its deliverables through this plugin's `ctx.researchReport.assemble` | |
226
+ | **[dsh-laya](https://github.com/PerryLink/dsh-laya)** | Laya typed decisions (`noul`/`choice`/`score`) as a first-class Cordis service and model-visible tools | |
227
+ | **[dsh-library](https://github.com/PerryLink/dsh-library)** | Local document knowledge base for DeepSeek Harness. | |
228
+ | **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | Local-model (Ollama) integration for DeepSeek Harness. | |
229
+ | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | LSP diagnostics, formatting, completion, code actions and rename over language servers | |
230
+ | **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | PII masking middleware: anonymize at the model boundary, restore at the display layer | |
231
+ | **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | Read-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors | |
232
+ | **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool | |
233
+ | **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | OpenTelemetry and Langfuse observability exporter for DeepSeek Harness. | |
234
+ | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | Claude Code outputStyles-equivalent runtime style switching | |
235
+ | **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | Claude Code-style declarative allow/deny/ask permission rules with audit | |
218
236
  | **[dsh-plugin-certification](https://github.com/PerryLink/dsh-plugin-certification)** | Community certification registry with repro-checkable grades and badges | |
219
237
  | **[dsh-plugin-doctor](https://github.com/PerryLink/dsh-plugin-doctor)** | Zero-dependency static + sandbox smoke detector for DSH plugins | |
220
- | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | Plugin-dev knowledge base, agent skill and the `dsh-plugin-dev` CLI toolchain | |
238
+ | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | Plugin-development knowledge base as an on-demand agent skill | |
221
239
  | **[dsh-plugin-kit](https://github.com/PerryLink/dsh-plugin-kit)** | Shared zero-runtime-dependency toolkit for the PerryLink DSH plugins | |
222
- | **[dsh-plugin-portal](https://github.com/PerryLink/dsh-plugin-portal)** | Zero-dependency static portal rendering the whole plugin family as one page | |
223
- | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | Multi-channel approval/question bridge: WeChat, Telegram, Feishu + a session console | |
224
- | **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | Verifiable research reports: evidence ledger, manifest seal, per-claim verdicts | |
225
- | **[dsh-score](https://github.com/PerryLink/dsh-score)** | Multi-dimensional plugin quality scoring with an evidence-backed leaderboard | |
226
- | **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | Pin sessions and workspaces in the Web sidebar with per-pin colors | |
227
- | **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | Git-backed cross-device session synchronization with keep-both merges | |
228
- | **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | Security-audit skill pack plus the `plugin_vet` supply-chain gate | |
229
- | **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | Voice-first session loop: speech-to-text input and text-to-speech replies | |
240
+ | **[dsh-plugin-upgrade](https://github.com/PerryLink/dsh-plugin-upgrade)** | One-package, one-corridor-index plugin upgrade skill: routes a repository to the matching closed corridor card | |
241
+ | **[dsh-plugin-upgrade-015](https://github.com/PerryLink/dsh-plugin-upgrade-015)** | Merged `0.1.3-alpha.1` → `0.1.5-rc.1` upgrade corridor card plus a zero-dependency seam scanner | |
242
+ | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | Multi-channel approval/question bridge: WeChat/Telegram/Feishu, session console | |
243
+ | **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | Verifiable research-report engine: content-addressed evidence ledger and sealed versions | |
244
+ | **[dsh-score](https://github.com/PerryLink/dsh-score)** | Multi-dimensional quality scoring for DeepSeek Harness plugins. | |
245
+ | **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | Pin sessions in the Web sidebar with durable ordering | |
246
+ | **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | Cross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store. | |
247
+ | **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | Security-audit skill pack: secret scan, dependency and supply-chain review | |
248
+ | **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | Voice-first session loop for DeepSeek Harness: talk to it, hear it answer. | |
230
249
  | **[dsh-team-rooms](https://github.com/PerryLink/dsh-team-rooms)** | Cross-session team rooms: shared message bus, task board and timeline | |
231
- | **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | Isolated install-and-smoke test drives with a pass/fail matrix | |
232
- | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | TickTick/Dida365 task bridge: session-header panel plus eleven agent tools | |
233
- | **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | Vendor parameter translation and deterministic JSON repair | |
234
- | **[dsh-wechat](https://github.com/pan17/dsh-wechat)** | WeChat ↔ DSH bridge (Tencent iLink bot) developed with [pan17](https://github.com/pan17/dsh-wechat), who hosts the repo | |
235
- | **[dsh-personal-directive](https://github.com/PerryLink/dsh-personal-directive)** | Personal directive injector with a top-bar toggle (fork of liucai2026/dsh-personal-directive) | |
250
+ | **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | Isolated install-and-smoke test drives for DeepSeek Harness plugins. | |
251
+ | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | TickTick/Dida365 task bridge: session-header panel + 11 tools | |
252
+ | **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | Vendor parameter translation and deterministic JSON repair for DeepSeek Harness. | |
236
253
 
237
- Part of the PerryLink DSH plugin family — 40+ repositories covering sessions, memory, permissions, delivery, observability and developer tooling. Browse the catalog at [perrylink-dsh-catalog.perrylink.workers.dev](https://perrylink-dsh-catalog.perrylink.workers.dev) or the [`dsh-plugin` topic](https://github.com/topics/dsh-plugin).
238
254
 
239
255
  ## License
240
256
 
@@ -10,9 +10,9 @@ of them is copied into the published artifact.
10
10
  | Package | Range | Role | License |
11
11
  |---|---|---|---|
12
12
  | `@deepseek-ai/cordis` | `^4.0.2` (peer) | Plugin runtime (Context, effect, inject) | Apache-2.0 |
13
- | `@deepseek-ai/dsh-skill` | `>=0.1.2-rc.1 <0.2.0 \|\| >=0.1.5-alpha.1 <0.2.0` (peer) | `skills` service and `SkillRegistry` used by the tests | Apache-2.0 |
13
+ | `@deepseek-ai/dsh-skill` | `>=0.1.2-rc.1 <0.2.0 \|\| >=0.1.5-alpha.1 <0.2.0 \|\| >=0.1.6-0 <0.2.0 \|\| >=0.1.7-0 <0.2.0` (peer) | `skills` service and `SkillRegistry` used by the tests | Apache-2.0 |
14
14
  | `@deepseek-ai/schemastery` | `^3.18.2` (peer) | `Config` schema | Apache-2.0 |
15
- | `@deepseek-ai/dsh-skill` | `0.1.5-rc.2` (dev) | Real-registry mount test against the published `0.1.5-rc.2` line (the newest published types verify the same merged seam catalog) | Apache-2.0 |
15
+ | `@deepseek-ai/dsh-skill` | `0.1.7-alpha.2` (dev) | Real-registry mount test against the published `0.1.7-alpha.2` line (the newest published types verify the same merged seam catalog) | Apache-2.0 |
16
16
 
17
17
  The scanner (`lib/scan.mjs`) and the CLI import only Node.js built-ins (`node:fs`,
18
18
  `node:path`) and therefore add no transitive install-time dependency of their own.
package/lib/route.mjs CHANGED
@@ -39,7 +39,11 @@ export const CORRIDORS = [
39
39
  },
40
40
  ]
41
41
 
42
- /** Accepts a corridor id ('legC'), a full span, or a bare mention of a line. */
42
+ /**
43
+ * Accepts a corridor id ('legC'), a full span, or a bare mention of a line.
44
+ * @param {string} id - the `--span` value, a corridor id, or a bare line mention.
45
+ * @returns {Corridor | undefined} the matching corridor, or undefined when nothing matches.
46
+ */
43
47
  export function corridorById(id) {
44
48
  if (typeof id !== 'string' || id.length === 0) return undefined
45
49
  const wanted = id.trim().toLowerCase()
@@ -90,7 +94,11 @@ export function resolveCorridor(input = {}) {
90
94
  return CORRIDORS.find(c => c.id === 'legAB')
91
95
  }
92
96
 
93
- /** Reads `--span <value>` out of an argv array without touching the other flags. */
97
+ /**
98
+ * Reads `--span <value>` out of an argv array without touching the other flags.
99
+ * @param {string[]} argv - the raw CLI argument list (no `node`/script prefix).
100
+ * @returns {string | undefined} the span value, or undefined when the flag is absent.
101
+ */
94
102
  export function spanFromArgv(argv) {
95
103
  const index = argv.findIndex(a => a === '--span')
96
104
  if (index >= 0 && typeof argv[index + 1] === 'string' && !argv[index + 1].startsWith('--')) return argv[index + 1]
@@ -98,7 +106,11 @@ export function spanFromArgv(argv) {
98
106
  return inline ? inline.slice('--span='.length) : undefined
99
107
  }
100
108
 
101
- /** Reads `--repo <value>` (or `--repo=<value>`) out of an argv array. */
109
+ /**
110
+ * Reads `--repo <value>` (or `--repo=<value>`) out of an argv array.
111
+ * @param {string[]} argv - the raw CLI argument list (no `node`/script prefix).
112
+ * @returns {string | undefined} the repo path, or undefined when the flag is absent.
113
+ */
102
114
  export function repoFromArgv(argv) {
103
115
  const index = argv.findIndex(a => a === '--repo')
104
116
  if (index >= 0 && typeof argv[index + 1] === 'string') return argv[index + 1]
@@ -106,7 +118,11 @@ export function repoFromArgv(argv) {
106
118
  return inline ? inline.slice('--repo='.length) : undefined
107
119
  }
108
120
 
109
- /** Loads the catalog module the corridor points at. */
121
+ /**
122
+ * Loads the catalog module the corridor points at.
123
+ * @param {Corridor} corridor - the corridor whose `catalog` path is imported.
124
+ * @returns {Promise<any>} the catalog module namespace (`main`, `SEAMS`, `render`, …). `any` is the honest type here: the specifier is a runtime string, so the namespace shape is not knowable statically.
125
+ */
110
126
  export async function loadCatalog(corridor) {
111
127
  return import(new URL(corridor.catalog, import.meta.url).href)
112
128
  }