@noob-stupid/dsh-plugin-console 0.5.31 → 0.5.33

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 CHANGED
@@ -4,12 +4,44 @@
4
4
 
5
5
  ---
6
6
 
7
- <img width="1170" height="609" alt="image" src="https://github.com/user-attachments/assets/b802d606-14ba-4151-9956-ff642ed12b0a" />
8
-
9
7
  # DSH Plugin Gating Hub (dsh-plugin-gating-hub)
10
8
 
11
9
  *Renamed from `dsh-plugin-hub` — old URLs redirect.*
12
10
 
11
+ **Framework-upgrade safety and plugin-version gating for DSH.** A failed upgrade rolls back.
12
+ A framework changed by **any** update channel is still guarded. A version the host cannot
13
+ take is refused, not installed.
14
+
15
+ **Install (npm, one line)**
16
+
17
+ ```sh
18
+ dsh plugin --profile web add @noob-stupid/dsh-plugin-console
19
+ ```
20
+
21
+ Then restart the dsh service → refresh the page → **Settings → Plugins → Plugin Console**.
22
+
23
+ ![Upgrade safety panel, expanded in place](docs/images/upgrade-safety-panel.png)
24
+
25
+ **Three hard guarantees**
26
+
27
+ - 🛡️ **Contract pre-check → rollback point → auto-rollback.** A data-driven **contract pre-check**
28
+ runs first (message contract / dependency API / config schema / removed API / loader contract);
29
+ then config backup + a full-tree **rollback point**. A failed install or relaunch **auto-rolls
30
+ the tree back**, a 「roll back to previous」 button restores the last version, and plugins the
31
+ new framework cannot load are **auto-disabled** — version check catches fake success, 15-min
32
+ timeout + stall detection.
33
+ - 👁️ **Even when another update channel changes the framework.** An **environment fingerprint**
34
+ catches changes made by the official desktop updater or a manual `pnpm`: it auto-runs a
35
+ **read-only pre-flight**, and disables a row **only with hard evidence** (package unresolvable /
36
+ `file://` target gone / named in a boot-failure log). `@deepseek-ai/*` and **protected / core
37
+ rows are never auto-disabled**; each auto-disable writes a one-command recovery record.
38
+ - 🔒 **Plugin install & upgrade gating.** Version/declaration gate (`dsh.engines.framework` /
39
+ `engines.dsh` / `@deepseek-ai/*` ranges, built-in zero-dependency semver), a **repo-size gate**
40
+ on source channels, and explicit handling of **non-registry sources** — a bare version is
41
+ written back only once the registry really resolves it, otherwise the package is materialized
42
+ as `link:`. Install scripts are never auto-authorized, and pnpm's supply-chain gate is never
43
+ bypassed.
44
+
13
45
  [![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)
14
46
  [![Awesome DSH Plugin](https://awesome-dsh-plugin.com/badge.svg)](https://awesome-dsh-plugin.com)
15
47
  [![GitHub stars](https://img.shields.io/github/stars/Noob-stupid/dsh-plugin-gating-hub?style=flat-square&logo=github)](https://github.com/Noob-stupid/dsh-plugin-gating-hub/stargazers)
@@ -22,13 +54,11 @@
22
54
  [![GitHub Release](https://img.shields.io/github/v/release/Noob-stupid/dsh-plugin-gating-hub?style=flat-square)](https://github.com/Noob-stupid/dsh-plugin-gating-hub/releases)[![dsh.so security](https://www.dsh.so/badge/dsh-plugin-hub.svg)](https://www.dsh.so/artifact/dsh-plugin-hub)
23
55
  [![dsh.so install](https://www.dsh.so/badge/install/dsh-plugin-hub.svg)](https://www.dsh.so/artifact/dsh-plugin-hub)
24
56
 
25
- > **Framework upgrade safety & plugin version gating for DeepSeek Harness (DSH)**: one-click
26
- > framework upgrade with **auto-rollback on failure** → **one-click rollback to the previous
27
- > version** after an upgrade → plugins the new framework cannot load are **auto-disabled** →
28
- > the **plugin upgrade gate** refuses a version the host can't take.
29
- > A **built-in multi-source plugin market & index** (500+ plugins / 300+ skills, zero GitHub
30
- > API calls) rides on top as the **discovery layer** — and **every source is swappable**: install
31
- > source (incl. a private intranet registry), search source (URL template + headers), index source
57
+ <img width="1170" height="609" alt="DSH Plugin Gating Hub" src="https://github.com/user-attachments/assets/b802d606-14ba-4151-9956-ff642ed12b0a" />
58
+
59
+ > **Discovery layer on top**: a **built-in multi-source plugin market & index** (500+ plugins /
60
+ > 300+ skills, zero GitHub API calls) — and **every source is swappable**: install source
61
+ > (incl. a private intranet registry), search source (URL template + headers), index source
32
62
  > (self-hosted intranet index), Git source (incl. a local `file://` bare repo), so plugins can be
33
63
  > installed on an **intranet-only or fully offline** machine.
34
64
 
@@ -311,8 +341,40 @@ The mode decides **who leads framework upgrades** — nothing else:
311
341
 
312
342
  - **Observer (default)**: the console only preflights, gates, and guards the rollback point. It does not take over upgrades.
313
343
  - **Managed**: framework upgrade and rollback are owned by this console. It switches to managed automatically when you upgrade through this console, and records the reason.
344
+ - **Switches back to Observer automatically (0.5.32)**: when the **desktop-host shape** is detected (the existing `detectHostShape()` criteria), a mode that was **not set by hand** (`compat-mode.json` `source` is `auto:*`; a missing field counts as `manual`) is switched back to Observer on startup / first status query, with a one-line notice. **Once you switch it by hand it is never changed automatically again**; when it is already Observer nothing is written.
314
345
 
315
346
  **Boot-failure quarantine is not affected by the mode.** When the service cannot start, the console locates the culprit from the boot log and disables it (broken presets are renamed to `.broken-*`; with no clear culprit it falls back to safe mode so the service can start). A console that cannot boot cannot gate anything — so this rescue path always runs.
347
+
348
+ **Auto-disable on confirmed evidence (0.5.32)**: when the fingerprint-triggered auto-preflight, or a
349
+ boot-failure record, provides **confirmed evidence** (the row's package resolves on **none** of the
350
+ resolution bases, a `file://` target truly does not exist, or the boot log names the row), the console
351
+ writes `disabled: true` for those rows **itself** (no click needed). Safety rails: **only rows with
352
+ evidence**; `@deepseek-ai/*` (framework-owned) and protected/core rows are **never** auto-disabled;
353
+ a **safe-boot snapshot is written first**, so any auto-disable is one command away from a rollback;
354
+ when there is nothing to write, **not a single byte is written**; every auto-disable leaves a record in
355
+ `dshHome()/plugin-console/auto-disable.log` (time / row id / evidence / restore command).
356
+
357
+ Prefer "report only, let me click" (enabled by default) — replace `<host:port>` with your instance
358
+ (the default `dsh web` profile listens on `127.0.0.1:3080`):
359
+
360
+ ```bash
361
+ curl -X POST http://<host:port>/plugin-console/compat-ack \
362
+ -H 'Content-Type: application/json' -d '{"autoDisableOnEvidence":false}'
363
+ ```
364
+
365
+ **How to roll an auto-disable back**: the route `POST /plugin-console/safe-boot` with
366
+ `{"action":"restore-last-good"}` (the current state is backed up first), or — when the service will not
367
+ start — from the plugin directory:
368
+
369
+ ```bash
370
+ node scripts/safe-boot.mjs --list # see which snapshots exist
371
+ node scripts/safe-boot.mjs --restore-last-good # restore the newest good snapshot byte-for-byte
372
+ node scripts/safe-boot.mjs --disable-suspects # or: append disabled: true to named rows only (nothing deleted)
373
+ node scripts/safe-boot.mjs --mark-good # mark a snapshot as good (never removed by retention)
374
+ ```
375
+
376
+ Safe-boot snapshots live under `dshHome()/plugin-console/safe-boot/` (**not** in the profile directory),
377
+ keeping the newest 3 plus the one you marked as good.
316
378
  ## Framework compatibility
317
379
 
318
380
  Measured on isolated instances (fresh `DSH_HOME`, real HTTP probes) — **supported: framework ≥ `0.1.5-rc.2`**, no workarounds needed.
@@ -353,7 +415,7 @@ Verification matrix, raw logs and the one framework-side caveat (`0.1.2-rc.1` sh
353
415
 
354
416
  ---
355
417
 
356
- ##帮助
418
+ ## Help & Ecosystem
357
419
 
358
420
  - **Panel missing**: restart dsh → refresh → Settings → Plugins → Plugin Console.
359
421
  - **Toggle does nothing**: infrastructure rows are "Protected" (by design); normal toggles
package/README.zh.md CHANGED
@@ -4,15 +4,41 @@
4
4
 
5
5
  ---
6
6
 
7
- <img width="1170" height="609" alt="image" src="https://github.com/user-attachments/assets/b802d606-14ba-4151-9956-ff642ed12b0a" />
8
-
9
7
  # DSH 插件门控中心(dsh-plugin-gating-hub)
10
8
 
11
9
  *原名 `dsh-plugin-hub`,已改名;旧链接 301 跳转有效。*
12
10
 
13
- > **DSH 框架升级安全与插件升级门控**:一键框架升级(**失败自动回滚**)→ 升级后**一键回滚到
14
- > 上一版** → 新框架带不动的插件**自动禁用** → **插件升级门控**按版本/声明拒绝装不上的插件版本。
15
- > **内置多源插件市场与自定义索引**(500+ 插件 / 300+ 技能,零 GitHub API 调用)作为**发现层**——
11
+ **DSH 的框架升级安全 + 插件升级门控。** 升级失败自动回滚。**别的通道**改了框架也照样守门。
12
+ 宿主带不动的插件版本直接拒绝,不会装上。
13
+
14
+ **安装(npm,一行)**
15
+
16
+ ```sh
17
+ dsh plugin --profile web add @noob-stupid/dsh-plugin-console
18
+ ```
19
+
20
+ 然后重启 dsh 服务 → 刷新页面 → **设置 → 插件 → 插件控制台**。
21
+
22
+ ![「升级安全」面板(就地展开)](docs/images/upgrade-safety-panel.png)
23
+
24
+ **三条最硬的能力**
25
+
26
+ - 🛡️ **升级前契约预检 → 回滚点 → 失败自动回滚。** 先跑数据化的**契约预检**(消息契约 /
27
+ 依赖 API / 配置 schema / 被删 API / 装载器契约),再做配置备份 + 全树**回滚点**;
28
+ 安装或拉起失败即**全树自动回滚**,升级成功后还有「回滚到上一版」按钮,
29
+ 新框架带不动的插件**自动禁用** —— 版本校验防假成功,15 分钟硬超时 + 卡死检测。
30
+ - 👁️ **别的更新通道改了框架,也守门。** **环境指纹**能发现官方桌面端更新器或手动 `pnpm`
31
+ 造成的框架变更:变化即自动跑一次**只读预检**,且**有确证证据才**禁用某行
32
+ (包确证解析不到 / `file://` 目标确实不存在 / 启动失败日志点名);`@deepseek-ai/*`(框架自带)
33
+ 与**受保护 / 核心行永不禁用**,每次自动禁用都留一条可读的恢复命令。
34
+ - 🔒 **插件安装与升级门控。** 版本/声明门控(`dsh.engines.framework` / `engines.dsh` /
35
+ `@deepseek-ai/*` 范围,内置零依赖 semver)+ 源码通道的**体积门禁** + **非 registry 来源**的
36
+ 显式处理(只有在 registry 真能解析到该版本时才写回裸版本号,否则物化成 `link:`);
37
+ 安装脚本**绝不自动放行**,pnpm 的供应链闸**绝不绕过**。
38
+
39
+ <img width="1170" height="609" alt="DSH 插件门控中心" src="https://github.com/user-attachments/assets/b802d606-14ba-4151-9956-ff642ed12b0a" />
40
+
41
+ > **上层还带一个发现层**:**内置多源插件市场与自定义索引**(500+ 插件 / 300+ 技能,零 GitHub API 调用)——
16
42
  > 而且**每一条源都能换成你自己的**:安装源(含内网私有 registry)、搜索源(URL 模板 + 请求头)、
17
43
  > 索引源(内网自建索引)、Git 源(含 `file://` 本地裸仓库),**纯内网 / 断网也能装插件**。
18
44
 
@@ -248,8 +274,40 @@ git clone https://github.com/Noob-stupid/dsh-plugin-gating-hub /tmp/dsh-plugin-c
248
274
 
249
275
  - **观察者(默认)**:只做预检、门控与回滚点守护,不接管框架升级。
250
276
  - **托管**:框架升级与回滚由本控制台负责。**走本控制台升级时会自动切到托管**并记下原因。
277
+ - **自动切回观察者(0.5.32)**:检测到**桌面端宿主形态**(复用既有 `detectHostShape()` 判据)时,
278
+ 若当前模式**不是用户手动设定的**(`compat-mode.json` 的 `source` 为 `auto:*`;缺字段按 `manual` 兼容),
279
+ 启动/首次状态查询会把它自动拨回观察者并给一行提示。**你手动拨过一次之后,它永不自动改**;
280
+ 已经是观察者时零写盘。
251
281
 
252
282
  **启动失败隔离不受模式影响。** 服务起不来时,控制台会从启动日志定位肇事插件并禁用它(预设文件改名 `.broken-*`;找不到明确肇事者则进安全模式先让服务起来)。**起不来的控制台什么都门控不了** —— 所以这条救火链路永远生效。
283
+
284
+ **有确证证据时会自动禁用(0.5.32)**:环境指纹变化触发的自动预检、或启动失败记录给出**确证证据**时
285
+ (行引用的包**在所有解析基准上都解析不到**、`file://` 目标确实不存在、启动失败日志**点名**该行),
286
+ 控制台会**自动**给这些行写 `disabled: true`(不再等你点)。安全栏:**只禁有证据的行**;
287
+ `@deepseek-ai/*`(框架自带)与受保护/核心行**永不自动禁用**;**禁前先写一份"安全启动快照"**,
288
+ 所以任何一次自动禁用都能一条命令回滚;没有可写内容时**一个字节都不写**;每次自动禁用都在
289
+ `dshHome()/plugin-console/auto-disable.log` 留一条记录(时间 / 行 id / 证据 / 恢复命令)。
290
+
291
+ 想改成"只报告、等我自己点"(默认启用)—— `<host:port>` 换成你实例的地址
292
+ (默认 `dsh web` profile 监听 `127.0.0.1:3080`):
293
+
294
+ ```bash
295
+ curl -X POST http://<host:port>/plugin-console/compat-ack \
296
+ -H 'Content-Type: application/json' -d '{"autoDisableOnEvidence":false}'
297
+ ```
298
+
299
+ **怎么恢复(把自动禁用回滚)**:接口 `POST /plugin-console/safe-boot` + `{"action":"restore-last-good"}`
300
+ (改前会再备份一份当前状态);或服务打不开时,在插件目录下跑:
301
+
302
+ ```bash
303
+ node scripts/safe-boot.mjs --list # 先看清有哪些快照
304
+ node scripts/safe-boot.mjs --restore-last-good # 整份逐字节恢复到最近的良好快照
305
+ node scripts/safe-boot.mjs --disable-suspects # 或:只给点名的可疑行追加 disabled: true(不删任何行)
306
+ node scripts/safe-boot.mjs --mark-good # 把某份快照标记为"良好"(永不随保留策略删除)
307
+ ```
308
+
309
+ 安全启动快照落在 `dshHome()/plugin-console/safe-boot/`(**不在** profile 目录里),保留最近 3 份 +
310
+ 永不删你标记为"良好"的那份。
253
311
  ## 框架兼容性
254
312
 
255
313
  在隔离实例(全新 `DSH_HOME` + 真实 HTTP 探针)实测:**支持框架 ≥ `0.1.5-rc.2`**,无需任何变通。