@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 +72 -10
- package/README.zh.md +63 -5
- package/lib/client.js +85 -53
- package/lib/server/domain/auto-disable.js +226 -0
- package/lib/server/domain/auto-preflight-run.js +184 -0
- package/lib/server/domain/auto-preflight.js +345 -0
- package/lib/server/domain/compat-state.js +57 -8
- package/lib/server/domain/compat.js +10 -60
- package/lib/server/domain/patch-yaml-check.js +151 -0
- package/lib/server/domain/peer-veto.js +103 -0
- package/lib/server/domain/safe-boot.js +520 -0
- package/lib/server/domain/settings-api-scan.js +251 -0
- package/lib/server/routes/compat.js +240 -11
- package/lib/server/routes/framework-preflight.js +14 -1
- package/lib/server/routes/index.js +4 -0
- package/lib/server/routes/plugins.js +3 -1
- package/lib/server/routes/safe-boot.js +139 -0
- package/lib/server/routes/state.js +17 -3
- package/package.json +1 -1
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
|
+

|
|
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://github.com/deepseek-ai/deepseek-harness)
|
|
14
46
|
[](https://awesome-dsh-plugin.com)
|
|
15
47
|
[](https://github.com/Noob-stupid/dsh-plugin-gating-hub/stargazers)
|
|
@@ -22,13 +54,11 @@
|
|
|
22
54
|
[](https://github.com/Noob-stupid/dsh-plugin-gating-hub/releases)[](https://www.dsh.so/artifact/dsh-plugin-hub)
|
|
23
55
|
[](https://www.dsh.so/artifact/dsh-plugin-hub)
|
|
24
56
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
>
|
|
28
|
-
>
|
|
29
|
-
>
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
+

|
|
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`**,无需任何变通。
|