@noob-stupid/dsh-plugin-console 0.3.27 → 0.3.28
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 +61 -354
- package/README.zh.md +57 -326
- package/lib/index.js +31 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,139 +18,23 @@
|
|
|
18
18
|
[](https://github.com/Noob-stupid/dsh-plugin-hub/releases)[](https://www.dsh.so/artifact/dsh-plugin-hub)
|
|
19
19
|
[](https://www.dsh.so/artifact/dsh-plugin-hub)
|
|
20
20
|
|
|
21
|
+
> Manage all your DeepSeek Harness plugins in one panel: one-click enable/disable,
|
|
22
|
+
> a 500+ plugin & skill marketplace with one-click install, and one-click framework
|
|
23
|
+
> upgrade with auto-rollback.
|
|
21
24
|
|
|
25
|
+
## Why DSH Plugin Hub
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
> (`dsh.migrate.to`), softened dependency-strict judgment, pending hints moved into details.
|
|
33
|
-
> **Safe sub-package delete**: deleting a bundle sub-row disables only that row and keeps the bundle —
|
|
34
|
-
> fixing the incident where deleting one sub-package removed the whole family bundle.
|
|
35
|
-
>
|
|
36
|
-
> **Install:**
|
|
37
|
-
> ```bash
|
|
38
|
-
> npm i -g @noob-stupid/dsh-plugin-console
|
|
39
|
-
> # or in DSH: dsh plugin --profile web add @noob-stupid/dsh-plugin-console
|
|
40
|
-
> ```
|
|
41
|
-
> **Try it:** Plugin Console → family card at the bottom → 「批量检测更新 / 一键启用已适配」.
|
|
42
|
-
>
|
|
43
|
-
> Feedback: [GitHub Issues](https://github.com/Noob-stupid/dsh-plugin-hub/issues).
|
|
44
|
-
A **plugin management panel** for the DeepSeek Harness (DSH) Web GUI: one-click
|
|
45
|
-
enable/disable of installed plugins, a **multi-source plugin marketplace**
|
|
46
|
-
(GitHub / Gitee / custom sources) with one-click install, an **auto-collected
|
|
47
|
-
static plugin & skill index** refreshed by CI every 6 hours, skill install/disable,
|
|
48
|
-
suite one-click assembly, and **one-click framework upgrade** (online install with
|
|
49
|
-
auto-rollback).
|
|
50
|
-
|
|
51
|
-
> ## 🎯 One-click framework upgrade (v0.3.13 highlight)
|
|
52
|
-
>
|
|
53
|
-
> Open the "Plugin Console" panel → **Plugin Marketplace** → the
|
|
54
|
-
> `deepseek-ai/deepseek-harness` card → click **"Framework Upgrade → vX"**:
|
|
55
|
-
> **backup config & framework (rollback point) → online install (service stays up) →
|
|
56
|
-
> version verification → auto-rollback on failure → auto-restart**.
|
|
57
|
-
>
|
|
58
|
-
> After upgrade, framework packages are **auto-relinked** (fixes pnpm top-level link
|
|
59
|
-
> staleness that caused mixed versions, e.g. an old model plugin missing vision models).
|
|
60
|
-
> Tested: 0.1.0-rc.8 → **0.1.1-rc.2** end-to-end automatic, rollback-safe.
|
|
61
|
-
|
|
62
|
-
<!-- TOC -->
|
|
63
|
-
- [Highlights](#highlights)
|
|
64
|
-
- [One-click install](#one-click-install)
|
|
65
|
-
- [Usage](#usage)
|
|
66
|
-
- [Features](#features)
|
|
67
|
-
- [How it works](#how-it-works)
|
|
68
|
-
- [Compatibility](#compatibility)
|
|
69
|
-
- [Project layout](#project-layout)
|
|
70
|
-
- [HTTP endpoints](#http-endpoints)
|
|
71
|
-
- [Local AI fallback & consent dialog](#local-ai-fallback--consent-dialog)
|
|
72
|
-
- [Framework patch (cordis.patch.yml parse tolerance)](#framework-patch-cordispatchyml-parse-tolerance)
|
|
73
|
-
- [Security](#security)
|
|
74
|
-
- [Disclaimer](#disclaimer)
|
|
75
|
-
- [Known limitations](#known-limitations)
|
|
76
|
-
- [Help](#help)
|
|
77
|
-
- [Ecosystem & discoverability](#ecosystem--discoverability)
|
|
78
|
-
- [Support](#support)
|
|
79
|
-
- [Changelog](#changelog)
|
|
80
|
-
- [License](#license)
|
|
81
|
-
<!-- /TOC -->
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## Highlights
|
|
86
|
-
|
|
87
|
-
| | Benefit | Detail |
|
|
88
|
-
|---|---|---|
|
|
89
|
-
| 🤖 | **AI Empower (v0.3.24)** | Give the console a package name or GitHub repo — the local AI reads docs, drafts a **deployment plan** (install / write config / start service / health check) and executes it safely after your confirmation; server-type components get an automatic control card |
|
|
90
|
-
| 🛡️ | **Framework upgrade safety & adapt gate (v0.3.25)** | Force-disables plugins incompatible with the new framework (enable locked; 「Check update → Update & adapt」auto-verifies and unlocks); full-tree checkpoint before upgrade, automatic rollback on relaunch failure, one-click rollback to the previous version |
|
|
91
|
-
| 🏠 | **Family-bundle cards & safety (v0.3.27)** | Same-root subpath exports group into one family card (collapse/expand, batch check-update, one-click unlock-adapted, known-check preview); never-crash safety (pre-enable import probe + patch auto-heal + exports fallback); adapt-gate source-scan hard criterion & migrate detection; deleting a bundle sub-row disables only that row |
|
|
92
|
-
| 🚀 | **Server component cards** | Left-side floating card auto-aligned to the main panel: start / stop / status / **open Web UI** buttons, multi-server dropdown, collapsible |
|
|
93
|
-
| 🧩 | **Plugin & skill hub** | Auto-collected index of `dsh-plugin` topic repos (**500+** by stars) plus a **Skills tab** (`agent-skills` ∪ `claude-skills` ∪ `dsh-skill`, up to 300) — browse, search, one-click install, no GitHub API calls |
|
|
94
|
-
| 🤖 | **Auto-collection CI** | GitHub Actions reruns `build-index` every 6 hours (manual trigger available); authors just add the `dsh-plugin` / `agent-skills` / `claude-skills` / `dsh-skill` topic — no application needed |
|
|
95
|
-
| ⚡ | **Instant, rate-limit-free** | The index is served as a static `marketplace/index.json` via jsDelivr CDN (10-min host cache); terminal users make **zero GitHub API calls** |
|
|
96
|
-
| 🔄 | **Version detection & one-click update** | Semver-based; installed entries match npm `dist-tags.latest` / `beta`; subpackage mismatch warnings prevent mixed-version breakage |
|
|
97
|
-
| 🔀 | **Multi-source** | GitHub / Gitee (direct-repo mode) / custom search sources (URL template + header auth + private http); `⊞` merges GitHub + all custom sources in parallel |
|
|
98
|
-
| 🔒 | **Safe by default** | Loopback-only routes; AI fallback behind an explicit cost-consent modal; infrastructure rows are toggle-protected |
|
|
99
|
-
|
|
100
|
-
<details>
|
|
101
|
-
<summary><b>📑 目录 / Table of Contents</b></summary>
|
|
102
|
-
|
|
103
|
-
- [Highlights](#highlights)
|
|
104
|
-
- [AI 赋能与服务器组件控制](#ai-赋能与服务器组件控制)
|
|
105
|
-
- [One-click install](#one-click-install)
|
|
106
|
-
- [Usage](#usage)
|
|
107
|
-
- [Features](#features)
|
|
108
|
-
- [How it works](#how-it-works)
|
|
109
|
-
- [Compatibility](#compatibility)
|
|
110
|
-
- [Project layout](#project-layout)
|
|
111
|
-
- [HTTP endpoints](#http-endpoints)
|
|
112
|
-
- [Security](#security)
|
|
113
|
-
- [Known limitations](#known-limitations)
|
|
114
|
-
- [Help & Ecosystem](#help--ecosystem)
|
|
115
|
-
- [Contributing](#contributing)
|
|
116
|
-
- [Changelog](#changelog)
|
|
117
|
-
- [License](#license)
|
|
118
|
-
</details>
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## AI 赋能与服务器组件控制
|
|
123
|
-
|
|
124
|
-
> **AI Empower** — v0.3.24 正式版核心功能。
|
|
125
|
-
|
|
126
|
-
在插件控制台输入 **npm 包名或 GitHub 仓库**(如 `OpenViking`、`@noob-stupid/dsh-plugin-console`):
|
|
127
|
-
|
|
128
|
-
1. **AI 读文档出计划**:子代理调研 README/docs,产出结构化计划(类型:纯插件 / 服务器组件 / 仅配置;步骤:安装 / 写配置 / 下载 / 启动服务 / 健康检查);
|
|
129
|
-
2. **你确认**(计划在弹窗里逐步骤勾选)——安全护栏:命令/路径白名单、破坏性命令拦截、日志脱敏;
|
|
130
|
-
3. **安全执行**:实时回显日志、可中断、幂等(已装/已下载/服务健康则复用);
|
|
131
|
-
4. **自动生成组件卡片**:服务器类组件注册到组件清单,卡片出现在主面板左侧(启动/停止/状态/【打开】直达 Web UI;多服务器时 ▾ 下拉;打开详情时自动隐藏;可折叠并有状态记忆)。
|
|
132
|
-
|
|
133
|
-
**内置 OpenViking 模板**:输入 `OpenViking` 秒出计划(pip 装 `openviking[local-embed]` → 下载中文嵌入模型 → 写 `ov.conf`(复用 DSH 的 DeepSeek 凭据,支持独立区块覆盖)→ 启动服务器 → 健康检查)。
|
|
134
|
-
|
|
135
|
-
**模型配置**:默认跟随 DSH(`settings.yaml` + `.credentials.yaml`);可建 `~/.dsh/plugin-console/ai-empower.json` 独立覆盖:
|
|
136
|
-
|
|
137
|
-
```json
|
|
138
|
-
{ "vlm": { "provider": "openai", "api_base": "https://api.deepseek.com", "model": "deepseek-v4-flash-vision-exp" }, "api_key": "sk-..." }
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
> **For plugin authors**: add the `dsh-plugin` topic to your repo — the official
|
|
144
|
-
> [topic list](https://github.com/topics/dsh-plugin) is how both the ecosystem and this
|
|
145
|
-
> hub discover you. For skills, add `agent-skills` / `claude-skills` / `dsh-skill`.
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
## One-click install
|
|
150
|
-
|
|
151
|
-
### Option 1: official command (recommended)
|
|
27
|
+
- 🧩 **Plugin & skill hub** — auto-collected index of `dsh-plugin` repos (500+ by
|
|
28
|
+
stars) plus a Skills tab; browse, search, one-click install, **zero GitHub API
|
|
29
|
+
calls** (served via CDN).
|
|
30
|
+
- 🚀 **One-click framework upgrade** — backup → online install (service stays up) →
|
|
31
|
+
verify → **auto-rollback on failure**. Tested end-to-end.
|
|
32
|
+
- 🤖 **AI Empower** — give the console a package name or GitHub repo, the local AI
|
|
33
|
+
reads its docs and drafts a safe, confirmable deployment plan (install / config /
|
|
34
|
+
start / health-check); server components get an automatic control card.
|
|
35
|
+
→ [details](docs/ai-empower.md)
|
|
152
36
|
|
|
153
|
-
|
|
37
|
+
## Install
|
|
154
38
|
|
|
155
39
|
```sh
|
|
156
40
|
# npm release (recommended: prebuilt, no git / build authorization needed)
|
|
@@ -160,14 +44,9 @@ dsh plugin --profile web add @noob-stupid/dsh-plugin-console
|
|
|
160
44
|
dsh plugin --profile web add github:Noob-stupid/dsh-plugin-hub
|
|
161
45
|
```
|
|
162
46
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
```sh
|
|
166
|
-
dsh plugin --profile web remove @noob-stupid/dsh-plugin-console
|
|
167
|
-
dsh plugin --profile web add @noob-stupid/dsh-plugin-console
|
|
168
|
-
```
|
|
47
|
+
Then restart the dsh service → refresh the page → **Settings → Plugins → Plugin Console**.
|
|
169
48
|
|
|
170
|
-
|
|
49
|
+
<details><summary><b>More install options</b> (deploy script / hand it to an AI)</summary>
|
|
171
50
|
|
|
172
51
|
### Option 2: deploy script (fallback when network is restricted)
|
|
173
52
|
|
|
@@ -196,6 +75,45 @@ idempotently appends an enable entry to `cordis.patch.yml`. Afterwards:
|
|
|
196
75
|
|
|
197
76
|
Requires: DSH ≥ 0.1.0-rc.6 (web profile, with `dsh-client-modules` / `dsh-host-plugin-inventory`).
|
|
198
77
|
|
|
78
|
+
</details>
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Highlights
|
|
83
|
+
|
|
84
|
+
| | Benefit | Detail |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| 🤖 | **AI Empower ** | Give the console a package name or GitHub repo — the local AI reads docs, drafts a **deployment plan** (install / write config / start service / health check) and executes it safely after your confirmation; server-type components get an automatic control card |
|
|
87
|
+
| 🛡️ | **Framework upgrade safety & adapt gate ** | Force-disables plugins incompatible with the new framework (enable locked; 「Check update → Update & adapt」auto-verifies and unlocks); full-tree checkpoint before upgrade, automatic rollback on relaunch failure, one-click rollback to the previous version |
|
|
88
|
+
| 🏠 | **Family-bundle cards & safety ** | Same-root subpath exports group into one family card (collapse/expand, batch check-update, one-click unlock-adapted, known-check preview); never-crash safety (pre-enable import probe + patch auto-heal + exports fallback); adapt-gate source-scan hard criterion & migrate detection; deleting a bundle sub-row disables only that row |
|
|
89
|
+
| 🚀 | **Server component cards** | Left-side floating card auto-aligned to the main panel: start / stop / status / **open Web UI** buttons, multi-server dropdown, collapsible |
|
|
90
|
+
| 🧩 | **Plugin & skill hub** | Auto-collected index of `dsh-plugin` topic repos (**500+** by stars) plus a **Skills tab** (`agent-skills` ∪ `claude-skills` ∪ `dsh-skill`, up to 300) — browse, search, one-click install, no GitHub API calls |
|
|
91
|
+
| 🤖 | **Auto-collection CI** | GitHub Actions reruns `build-index` every 6 hours (manual trigger available); authors just add the `dsh-plugin` / `agent-skills` / `claude-skills` / `dsh-skill` topic — no application needed |
|
|
92
|
+
| ⚡ | **Instant, rate-limit-free** | The index is served as a static `marketplace/index.json` via jsDelivr CDN (10-min host cache); terminal users make **zero GitHub API calls** |
|
|
93
|
+
| 🔄 | **Version detection & one-click update** | Semver-based; installed entries match npm `dist-tags.latest` / `beta`; subpackage mismatch warnings prevent mixed-version breakage |
|
|
94
|
+
| 🔀 | **Multi-source** | GitHub / Gitee (direct-repo mode) / custom search sources (URL template + header auth + private http); `⊞` merges GitHub + all custom sources in parallel |
|
|
95
|
+
| 🔒 | **Safe by default** | Loopback-only routes; AI fallback behind an explicit cost-consent modal; infrastructure rows are toggle-protected |
|
|
96
|
+
|
|
97
|
+
<details>
|
|
98
|
+
<summary><b>📑 目录 / Table of Contents</b></summary>
|
|
99
|
+
|
|
100
|
+
- [Highlights](#highlights)
|
|
101
|
+
- [AI 赋能与服务器组件控制](#ai-赋能与服务器组件控制)
|
|
102
|
+
- [One-click install](#one-click-install)
|
|
103
|
+
- [Usage](#usage)
|
|
104
|
+
- [Features](#features)
|
|
105
|
+
- [How it works](#how-it-works)
|
|
106
|
+
- [Compatibility](#compatibility)
|
|
107
|
+
- [Project layout](#project-layout)
|
|
108
|
+
- [HTTP endpoints](#http-endpoints)
|
|
109
|
+
- [Security](#security)
|
|
110
|
+
- [Known limitations](#known-limitations)
|
|
111
|
+
- [Help & Ecosystem](#help--ecosystem)
|
|
112
|
+
- [Contributing](#contributing)
|
|
113
|
+
- [Changelog](#changelog)
|
|
114
|
+
- [License](#license)
|
|
115
|
+
</details>
|
|
116
|
+
|
|
199
117
|
---
|
|
200
118
|
|
|
201
119
|
## Usage
|
|
@@ -253,47 +171,6 @@ Requires: DSH ≥ 0.1.0-rc.6 (web profile, with `dsh-client-modules` / `dsh-host
|
|
|
253
171
|
- **Card dismiss semantics**: terminal states (done/failed) are permanently dismissed on ✕
|
|
254
172
|
(persisted); in-progress dismissal is session-only and the card returns after a refresh.
|
|
255
173
|
|
|
256
|
-
### Framework upgrade safety & plugin adapt gate (v0.3.25)
|
|
257
|
-
|
|
258
|
-
> Origin: the 2026-09-04 DSH `0.1.1-rc.2 → 0.1.2-rc.1` incident — the upgrade script ran in
|
|
259
|
-
> the wrong working directory, overwrote the new CLI into the old `.pnpm` entry, left a
|
|
260
|
-
> mixed-version tree, and the service could not start. This version makes upgrade safety
|
|
261
|
-
> and plugin compatibility detection first-class console mechanisms.
|
|
262
|
-
|
|
263
|
-
**Upgrade safety trio**
|
|
264
|
-
|
|
265
|
-
1. **Framework root detection**: locates the real install root (the top-level `node_modules`
|
|
266
|
-
containing `.pnpm`), fixing the `require.resolve`-returns-`.pnpm`-realpath root cause
|
|
267
|
-
(relink no-op / new package overwriting the old tree); refuses to upgrade when the root
|
|
268
|
-
cannot be identified (service stays running);
|
|
269
|
-
2. **Full-tree checkpoint before upgrade**: mirrors every `@deepseek-ai` version package in
|
|
270
|
-
`.pnpm` + the top-level scope + `lock.yaml`
|
|
271
|
-
(under `~/.dsh/plugin-console/framework-backups/<version>/fw-tree/`);
|
|
272
|
-
3. **Automatic full-tree rollback + retry**: install failure or relaunch failure restores
|
|
273
|
-
the pre-upgrade tree and relaunches automatically — no more "please run it manually"
|
|
274
|
-
dead-ends; after rollback, relink/repair steps are skipped to avoid damaging the
|
|
275
|
-
restored tree a second time.
|
|
276
|
-
|
|
277
|
-
**One-click rollback**: after an upgrade the framework card shows a **「回滚到上一版」** button
|
|
278
|
-
(`/plugin-console/framework-rollback`): stop service → restore full tree → relaunch →
|
|
279
|
-
health check, state visible throughout.
|
|
280
|
-
|
|
281
|
-
**Plugin adapt gate (compatibility detection)**
|
|
282
|
-
|
|
283
|
-
- After an upgrade, plugin entries recorded in `~/.dsh/plugin-console/compat-pending.json`
|
|
284
|
-
are **force-disabled**; the enable button is locked and the server rejects `/toggle` with
|
|
285
|
-
409 (unbypassable). The enabled-button label itself shows「待适配」as the state hint;
|
|
286
|
-
- The **details** panel explains the flow: **Check update → Update & adapt**;
|
|
287
|
-
- **Post-update auto-verification**: scans the latest `package.json` for an explicit
|
|
288
|
-
`dsh.engines.framework` / `engines.dsh` declaration plus `@deepseek-ai/*` dependency
|
|
289
|
-
ranges (built-in zero-dependency semver engine — strict npm prerelease rules for
|
|
290
|
-
dependencies, loose for explicit declarations); if the version changed and no
|
|
291
|
-
incompatibility was found, the `disabled` block is **removed automatically** and the row
|
|
292
|
-
unlocks; aggregator updates validate all synced subpackages too;
|
|
293
|
-
- **AI Empower pre-check**: during planning the server pre-checks the registry's latest
|
|
294
|
-
declaration and adapt-gate hits, injects them into the subagent prompt (the plan must
|
|
295
|
-
explain the conclusion to the user) and marks it on the plan panel (red for incompatible).
|
|
296
|
-
|
|
297
174
|
### Marketplace (multi-source)
|
|
298
175
|
|
|
299
176
|
- **Source switcher**: click the login pill to switch between **GitHub / Gitee / custom
|
|
@@ -343,183 +220,13 @@ The floating "Sources" button (right of the title row, semi-transparent) opens t
|
|
|
343
220
|
|
|
344
221
|
---
|
|
345
222
|
|
|
346
|
-
##
|
|
347
|
-
|
|
348
|
-
### Toggle semantics
|
|
349
|
-
|
|
350
|
-
The DSH web profile is composed of a bundle patch layer plus the user patch layer
|
|
351
|
-
(`$DSH_HOME/profiles/web/cordis.patch.yml`); patches are **per-key overrides**.
|
|
352
|
-
Toggling a plugin just appends/removes two YAML lines:
|
|
353
|
-
|
|
354
|
-
```yaml
|
|
355
|
-
- id: plugin-entry-id
|
|
356
|
-
disabled: true
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
The config watcher (HMR) recomposes within ~1s — no restart needed except for host code.
|
|
360
|
-
|
|
361
|
-
### Install chain
|
|
362
|
-
|
|
363
|
-
```
|
|
364
|
-
configured registries (primary→backup, default npmmirror → npmjs)
|
|
365
|
-
→ curl manual install (node networking blocked: tarball into node_modules)
|
|
366
|
-
→ git channel (GitHub via proxy+direct, Gitee via its platform)
|
|
367
|
-
→ EPERM stale-dir cleanup retry
|
|
368
|
-
→ repository subpackage expansion (aggregate packages first)
|
|
369
|
-
→ local AI fallback (behind an explicit cost-consent modal)
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
Skills install directly by `git clone --depth 1` → copy SKILL.md bundle into
|
|
373
|
-
`~/.dsh/skills/<name>/` (no npm, no patch, no restart).
|
|
374
|
-
|
|
375
|
-
### Data sources
|
|
376
|
-
|
|
377
|
-
```
|
|
378
|
-
GitHub Actions (every 6h, repo token)
|
|
379
|
-
└─ scripts/build-index.cjs: pages topic:dsh-plugin (500 by stars) + skills topics (300)
|
|
380
|
-
└─ commits marketplace/index.json back to main
|
|
381
|
-
└─ host reads it via jsDelivr CDN (10-min cache) → instant market, zero API calls
|
|
382
|
-
└─ live search still uses the GitHub search API (browser-direct + server channel)
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
### Version detection & installed recognition
|
|
386
|
-
|
|
387
|
-
- **Installed recognition**: match installed entries by `repository` field or module name
|
|
388
|
-
against market items (repo name → package name mapping);
|
|
389
|
-
- **Version detection**: `check-update` reads npm `dist-tags.latest` via curl; for aggregate
|
|
390
|
-
packages it also compares subpackage declared vs actual versions (depsOutdated) to prevent
|
|
391
|
-
mixed-version startup conflicts.
|
|
392
|
-
|
|
393
|
-
---
|
|
394
|
-
|
|
395
|
-
## Compatibility
|
|
396
|
-
|
|
397
|
-
- Supports the **DSH 0.1.0 series** (`0.1.0-rc.6` and siblings).
|
|
398
|
-
- The panel reads the running `@deepseek-ai/dsh-web-app` version: after a breaking upgrade
|
|
399
|
-
(0.2 / 1.0) a compatibility warning appears instead of silent failure.
|
|
400
|
-
- **Plugin adapt gate (v0.3.25)**: third-party plugins incompatible with the current
|
|
401
|
-
framework are force-disabled after an upgrade (enable locked); run 「Check update」to
|
|
402
|
-
upgrade the plugin first — it unlocks automatically after the auto-verification passes.
|
|
403
|
-
See 「Framework upgrade safety & plugin adapt gate」.
|
|
404
|
-
- Likely breaking seams: patch semantics, `webServer.register`, loader entry shape,
|
|
405
|
-
`dsh.client` bundle format, `settings.plugins.tab` slot.
|
|
406
|
-
- Deploy scripts do not check versions; the in-panel warning is authoritative.
|
|
407
|
-
|
|
408
|
-
---
|
|
409
|
-
|
|
410
|
-
## Project layout
|
|
411
|
-
|
|
412
|
-
```
|
|
413
|
-
lib/index.js Host plugin (/plugin-console/* routes + patch I/O + multi-source search + install)
|
|
414
|
-
lib/client.js Browser bundle (ModuleLoader format, settings tab)
|
|
415
|
-
scripts/build-index.cjs Index builder (plugins --limit 500 / skills --skills --limit 300)
|
|
416
|
-
scripts/apply-framework-patch.cjs Framework patch (issue #5, idempotent)
|
|
417
|
-
.github/workflows/registry.yml Auto-collection CI (every 6h + manual dispatch)
|
|
418
|
-
marketplace/index.json Generated static index (jsDelivr CDN)
|
|
419
|
-
deploy.ps1 / deploy.sh One-click deploy scripts (Windows / Linux·macOS)
|
|
420
|
-
test-harness.mjs Logic self-test (state/toggle/validation/loopback; search SKIP by network)
|
|
421
|
-
```
|
|
422
|
-
<img width="1878" height="945" alt="image" src="https://github.com/user-attachments/assets/b26f2f19-0ba4-4be7-9ca1-b3fd4c51a7a8" />
|
|
423
|
-
|
|
424
|
-
---
|
|
425
|
-
|
|
426
|
-
## HTTP endpoints
|
|
427
|
-
|
|
428
|
-
| Endpoint | Method | Purpose |
|
|
429
|
-
|---|---|---|
|
|
430
|
-
| `/plugin-console/state` | GET | Plugin list + patch state + compat + running install jobs |
|
|
431
|
-
| `/plugin-console/toggle` | POST | Enable/disable an entry (writes user patch layer) |
|
|
432
|
-
| `/plugin-console/uninstall` | POST | Remove entry + uninstall package (bundle-aware) |
|
|
433
|
-
| `/plugin-console/search` | POST | Multi-source search (github/gitee/custom, `multi` merge) |
|
|
434
|
-
| `/plugin-console/repo` | POST | Repo metadata: package.json, private root, dsh hint, **hasSkill** |
|
|
435
|
-
| `/plugin-console/enrich` | POST | Server-side type markers (official/aggregate/skill) |
|
|
436
|
-
| `/plugin-console/install` | POST | Install (plugin or `kind: skill`), returns a job id |
|
|
437
|
-
| `/plugin-console/install-status` | POST | Poll an install job |
|
|
438
|
-
| `/plugin-console/check-update` | POST | npm latest version + subpackage mismatch check |
|
|
439
|
-
| `/plugin-console/market-index` | POST | Static index (jsDelivr CDN, 10-min cache) |
|
|
440
|
-
| `/plugin-console/skills-installed` | GET | Installed skills under `~/.dsh/skills` |
|
|
441
|
-
| `/plugin-console/sources` | GET/POST | Registry & search-source manager, Gitee OAuth setup |
|
|
442
|
-
| `/plugin-console/gitee-oauth-url` / `gitee-oauth-callback` | GET | Gitee OAuth flow |
|
|
443
|
-
| `/plugin-console/ai-consent` | POST | Approve/cancel the AI-fallback step |
|
|
444
|
-
| `/plugin-console/restart` | POST | Watchdog-safe self-restart (panel button equivalent) |
|
|
445
|
-
| `/plugin-console/framework-upgrade` | POST | One-click framework upgrade (full-tree checkpoint → online install → rollback protection) |
|
|
446
|
-
| `/plugin-console/framework-rollback` | POST | One-click rollback to the previous version (stop → full-tree restore → auto relaunch → health check) |
|
|
447
|
-
| `/plugin-console/self-update` | POST | Update the console itself (latest npm tarball into the profile) |
|
|
448
|
-
| `/plugin-console/ai-empower/plan` / `status` / `run` / `cancel` | POST | AI Empower: plan (with framework compat pre-check) → status polling → confirmed run → cancel |
|
|
449
|
-
| `/plugin-console/components` / `component/start` / `stop` / `status` | GET/POST | Server component registry and start/stop/status |
|
|
450
|
-
|
|
451
|
-
---
|
|
452
|
-
|
|
453
|
-
## Local AI fallback & consent dialog
|
|
454
|
-
|
|
455
|
-
Installation goes through a **deterministic channel chain**:
|
|
456
|
-
`configured sources (primary→backup) → curl manual install → git channel → EPERM cleanup retry
|
|
457
|
-
→ repository subpackage expansion`. Only when all deterministic channels fail does the
|
|
458
|
-
**local AI fallback** take over.
|
|
459
|
-
|
|
460
|
-
**What it is**: a local AI subagent takes over the install — it diagnoses like a human
|
|
461
|
-
(inspects repo structure, finds subpackages/aggregate packages, cleans leftovers), installs
|
|
462
|
-
with the right package manager and writes the config. **Note: this step calls a DeepSeek API
|
|
463
|
-
model and may incur API costs.**
|
|
464
|
-
|
|
465
|
-
**Consent dialog (cost transparency)**:
|
|
466
|
-
|
|
467
|
-
1. After all deterministic channels fail, the task enters "waiting for authorization" and a
|
|
468
|
-
top-most modal appears:
|
|
469
|
-
- explicitly states "will call a DeepSeek API model, may incur API costs"
|
|
470
|
-
- offers **Approve, continue** / **Cancel** (Cancel = zero cost)
|
|
471
|
-
- auto-cancels after 10 minutes
|
|
472
|
-
2. The modal offers **"Don't ask again"** (auto-approve) — restorable at the bottom of the
|
|
473
|
-
marketplace page.
|
|
474
|
-
3. The floating **"AI fallback"** toggle can disable the feature entirely: deterministic
|
|
475
|
-
failures cancel the install, **never calling a model API (zero cost)**.
|
|
476
|
-
|
|
477
|
-
---
|
|
478
|
-
|
|
479
|
-
## Framework patch (cordis.patch.yml parse tolerance)
|
|
480
|
-
|
|
481
|
-
**Problem (issue #5)**: if `cordis.patch.yml` contains a top-level `[]` placeholder plus
|
|
482
|
-
later entries (two YAML root nodes), DSH fails at startup:
|
|
483
|
-
`end of the stream or a document separator is expected`.
|
|
484
|
-
|
|
485
|
-
**Fix location**: `parsePatchList` in the DSH framework `dsh-app-boot` — on parse failure,
|
|
486
|
-
top-level empty-array placeholder lines are dropped (treated as no-op) and parsing retries;
|
|
487
|
-
normal files, pure `[]` files, and indented sub-arrays are unaffected.
|
|
488
|
-
|
|
489
|
-
**Apply** (re-run after every DSH upgrade, which overwrites framework files):
|
|
490
|
-
|
|
491
|
-
```bash
|
|
492
|
-
node scripts/apply-framework-patch.cjs
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
The script locates `dsh-app-boot/lib/index.js` in the npx cache, skips when already patched
|
|
496
|
-
(idempotent), and keeps a `.bak-issue5` backup on first apply.
|
|
497
|
-
|
|
498
|
-
---
|
|
499
|
-
|
|
500
|
-
## Security
|
|
501
|
-
|
|
502
|
-
- All routes are loopback-only;
|
|
503
|
-
- GitHub metadata is used only to discover public plugins; npm installs keep full TLS
|
|
504
|
-
validation against the registry;
|
|
505
|
-
- GitHub search is browser-direct; Gitee/custom source requests and headers (including
|
|
506
|
-
credentials) are handled server-side only and never shipped to the browser;
|
|
507
|
-
- Custom source URLs accept https and local/private http only (127.0.0.1, localhost,
|
|
508
|
-
10.x, 192.168.x, 172.16-31.x, etc.);
|
|
509
|
-
- Skills are plain files (SKILL.md + assets) — installing a skill does **not** execute code;
|
|
510
|
-
the git clone comes from the repo you chose, review the repo before installing.
|
|
511
|
-
|
|
512
|
-
---
|
|
513
|
-
|
|
514
|
-
## Disclaimer
|
|
223
|
+
## Documentation
|
|
515
224
|
|
|
516
|
-
-
|
|
517
|
-
|
|
518
|
-
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
- This hub is provided AS-IS; neither the hub nor its developers are liable for any damage
|
|
522
|
-
(data loss, system damage, privacy leaks) caused by installing or using third-party plugins.
|
|
225
|
+
- [AI Empower 与服务器组件控制](docs/ai-empower.md)
|
|
226
|
+
- [Framework upgrade safety & plugin adapt gate](docs/upgrade-safety-adapt-gate.md)
|
|
227
|
+
- [How it works](docs/how-it-works.md) · [Compatibility](docs/compatibility.md) · [Project layout](docs/project-layout.md)
|
|
228
|
+
- [HTTP endpoints](docs/http-endpoints.md) · [Local AI fallback & consent](docs/ai-fallback.md)
|
|
229
|
+
- [Framework patch (cordis.patch.yml)](docs/framework-patch.md) · [Security & disclaimer](docs/security-disclaimer.md)
|
|
523
230
|
|
|
524
231
|
---
|
|
525
232
|
|
package/README.zh.md
CHANGED
|
@@ -6,145 +6,21 @@
|
|
|
6
6
|
|
|
7
7
|
# DSH 插件中心(dsh-plugin-hub)
|
|
8
8
|
|
|
9
|
-
>
|
|
10
|
-
>
|
|
11
|
-
> **全家桶分组卡片**:同根包子路径导出(如 `@linxin666/dsh-web-all/settings`)自动聚合为一张
|
|
12
|
-
> 全家桶卡片(列表底部)——收起/展开、批量检测更新、**一键启用已适配**、已知校验预览,子卡剥离
|
|
13
|
-
> `web-all/` 前缀。
|
|
14
|
-
> **永不崩安全**:启用前子进程导入探针 + 补丁自动自愈(核心行恢复/缺失模块自动禁用)+
|
|
15
|
-
> exports 回退 `package.json` 解析——记忆插件被误禁用的事故已修复。
|
|
16
|
-
> **适配门强化**:源码扫描硬判据(0.3.6 假通过教训)、迁移检测(`dsh.migrate.to`)、
|
|
17
|
-
> 依赖严格判定软化、待适配提示移入详情。
|
|
18
|
-
> **子包删除安全**:删除聚合包子行仅停用该行、不动 bundle——修复"删一个子包导致整个全家桶消失"的事故。
|
|
19
|
-
>
|
|
20
|
-
> **安装:**
|
|
21
|
-
> ```bash
|
|
22
|
-
> npm i -g @noob-stupid/dsh-plugin-console
|
|
23
|
-
> # 或在 DSH 中:dsh plugin --profile web add @noob-stupid/dsh-plugin-console
|
|
24
|
-
> ```
|
|
25
|
-
> **体验入口:** 插件控制台 → 列表底部全家桶卡片 → 批量检测更新 / 一键启用已适配。
|
|
26
|
-
>
|
|
27
|
-
> 反馈:[GitHub Issues](https://github.com/Noob-stupid/dsh-plugin-hub/issues)。
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
31
|
-
[](https://awesome-dsh-plugin.com)
|
|
32
|
-
[](https://github.com/Noob-stupid/dsh-plugin-hub/stargazers)
|
|
33
|
-
[](LICENSE)
|
|
34
|
-
[](https://github.com/Noob-stupid/dsh-plugin-hub/commits/main)
|
|
35
|
-
[](https://github.com/Noob-stupid/dsh-plugin-hub/actions/workflows/registry.yml)
|
|
36
|
-
[](https://github.com/topics/dsh-plugin)
|
|
37
|
-
[](https://www.npmjs.com/package/@noob-stupid/dsh-plugin-console)
|
|
38
|
-
[](https://www.npmjs.com/package/@noob-stupid/dsh-plugin-console)
|
|
39
|
-
[](https://github.com/Noob-stupid/dsh-plugin-hub/releases)[](https://www.dsh.so/artifact/dsh-plugin-hub)
|
|
40
|
-
[](https://www.dsh.so/artifact/dsh-plugin-hub)
|
|
41
|
-
|
|
42
|
-
给 DeepSeek Harness(DSH)Web 界面加上**插件管理面板**:一键启用/停用已安装插件,
|
|
43
|
-
在**多个搜索源**上浏览 dsh-plugin 插件项目(GitHub / Gitee / 自定义源),一键添加并启用——
|
|
44
|
-
并带一份 **CI 每 6 小时自动收录的静态插件/技能索引**。
|
|
45
|
-
|
|
46
|
-
> ## 🎯 框架一键升级(v0.3.13 亮点)
|
|
47
|
-
>
|
|
48
|
-
> 打开「插件管理」面板 → **插件市场** → `deepseek-ai/deepseek-harness` 卡片 →
|
|
49
|
-
> 点 **「框架升级 → vX」**,一步完成:
|
|
50
|
-
> **备份配置与框架本体(回滚点)→ 在线安装(服务不中断)→ 版本校验 → 失败自动回滚 → 自动重启生效**。
|
|
51
|
-
>
|
|
52
|
-
> 升级后**自动重链框架配套包**(避免 pnpm 顶层链接滞后导致的混版本问题,如模型插件旧版缺失 vision 模型)。
|
|
53
|
-
> 已实测:0.1.0-rc.8 → **0.1.1-rc.2** 全程自动、失败可回滚、升级后可正常使用。
|
|
54
|
-
|
|
55
|
-
<!-- TOC -->
|
|
56
|
-
- [核心优势](#核心优势)
|
|
57
|
-
- [一键部署](#一键部署)
|
|
58
|
-
- [使用方法](#使用方法)
|
|
59
|
-
- [功能](#功能)
|
|
60
|
-
- [原理](#原理)
|
|
61
|
-
- [兼容性策略](#兼容性策略)
|
|
62
|
-
- [项目结构](#项目结构)
|
|
63
|
-
- [HTTP 接口](#http-接口)
|
|
64
|
-
- [AI 兜底安装与授权弹窗](#ai-兜底安装与授权弹窗)
|
|
65
|
-
- [框架层补丁(cordis.patch.yml 解析容错)](#框架层补丁cordispatchyml-解析容错)
|
|
66
|
-
- [安全说明](#安全说明)
|
|
67
|
-
- [免责声明](#免责声明)
|
|
68
|
-
- [已知限制](#已知限制)
|
|
69
|
-
- [帮助 / Help](#帮助--help)
|
|
70
|
-
- [生态与收录](#生态与收录)
|
|
71
|
-
- [支持](#支持)
|
|
72
|
-
- [更新日志](#更新日志)
|
|
73
|
-
- [License](#license)
|
|
74
|
-
<!-- /TOC -->
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## 核心优势
|
|
79
|
-
|
|
80
|
-
| | 优势 | 说明 |
|
|
81
|
-
|---|---|---|
|
|
82
|
-
| 🤖 | **AI 赋能(v0.3.24)** | 输入 npm 包名 / GitHub 仓库,本地 AI 读文档生成**部署计划**(安装/写配置/启动服务/健康检查),你确认后安全执行;服务器类组件自动生成控制卡片 |
|
|
83
|
-
| 🛡️ | **框架升级适配门与安全(v0.3.25)** | 升级后不兼容插件强制禁用(适配门锁定,「检测更新 → 更新并适配 → 自动校验解锁」);升级前全树 checkpoint、拉起失败自动全树回滚、框架卡片一键回滚到上一版 |
|
|
84
|
-
| 🏠 | **全家桶分组卡片与安全(v0.3.27)** | 同根包子路径导出自动聚合为一张全家桶卡片(收起/展开、批量检测更新、一键启用已适配、已知校验预览);永不崩安全(启用前导入探针 + 补丁自愈 + exports 回退);适配门源码扫描硬判据与迁移检测;删除聚合包子行仅停用该行 |
|
|
85
|
-
| 🚀 | **服务器组件卡片** | 左侧浮卡与主面板顶边对齐:启动 / 停止 / 状态 / 【打开】直达 Web UI,多服务器下拉、可折叠(状态记忆) |
|
|
86
|
-
| 🧩 | **插件 + 技能双市场** | 自动收录 `dsh-plugin` topic 仓库(按 star **500+**),另有**技能 tab**(`agent-skills` ∪ `claude-skills` ∪ `dsh-skill`,最多 300)——浏览、搜索、一键安装,零 GitHub API 调用;插件自带技能(如 openviking-memory)只读展示 |
|
|
87
|
-
| 🤖 | **自动收录 CI** | GitHub Actions 每 6 小时自动重跑 `build-index`(也支持手动触发);作者只需给自己的仓库打 `dsh-plugin` / `agent-skills` / `claude-skills` / `dsh-skill` 标签,**无需申请、无需审核** |
|
|
88
|
-
| ⚡ | **秒开、零限流** | 索引以静态 `marketplace/index.json` 提交仓库,经 jsDelivr CDN 分发(宿主 10 分钟缓存)——终端用户**零 GitHub API 调用、零限流** |
|
|
89
|
-
| 🔄 | **版本检测与一键更新** | semver 比较 + beta/next 识别(本地已是测试版最新时不误报);已安装条目自动比对 npm `dist-tags`,聚合包子包版本不配套时给出 depsOutdated 提示 |
|
|
90
|
-
| 🔀 | **多源检索** | GitHub / Gitee(仓库直装模式)/ 自定义搜索源(URL 模板 + 请求头认证 + 私网 http);「⊞」并行合并 GitHub + 全部自定义源 |
|
|
91
|
-
| 🔒 | **安全默认** | 全部路由仅环回;AI 兜底置于明确费用授权弹窗之后;AI 赋能执行器命令/路径白名单;基础设施行禁止开关(受保护) |
|
|
92
|
-
|
|
93
|
-
<details>
|
|
94
|
-
<summary><b>📑 目录</b></summary>
|
|
95
|
-
|
|
96
|
-
- [核心优势](#核心优势)
|
|
97
|
-
- [AI 赋能与服务器组件控制](#ai-赋能与服务器组件控制)
|
|
98
|
-
- [一键部署](#一键部署)
|
|
99
|
-
- [使用方法](#使用方法)
|
|
100
|
-
- [功能](#功能)
|
|
101
|
-
- [原理](#原理)
|
|
102
|
-
- [兼容性策略](#兼容性策略)
|
|
103
|
-
- [项目结构](#项目结构)
|
|
104
|
-
- [HTTP 接口](#http-接口)
|
|
105
|
-
- [安全说明](#安全说明)
|
|
106
|
-
- [已知限制](#已知限制)
|
|
107
|
-
- [帮助 / Help](#帮助--help)
|
|
108
|
-
- [生态与收录](#生态与收录)
|
|
109
|
-
- [参与贡献](#参与贡献)
|
|
110
|
-
- [许可证](#许可证)
|
|
111
|
-
</details>
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
|
|
115
|
-
## AI 赋能与服务器组件控制
|
|
116
|
-
|
|
117
|
-
> **AI 赋能** — v0.3.24 正式版核心功能。
|
|
118
|
-
|
|
119
|
-
在插件控制台输入 **npm 包名或 GitHub 仓库**(如 `OpenViking`、`@noob-stupid/dsh-plugin-console`):
|
|
120
|
-
|
|
121
|
-
1. **AI 读文档出计划**:子代理调研 README/docs,产出结构化计划(类型:纯插件 / 服务器组件 / 仅配置;步骤:安装 / 写配置 / 下载 / 启动服务 / 健康检查);
|
|
122
|
-
2. **你确认**(计划弹窗里逐步骤勾选)——安全护栏:命令/路径白名单、破坏性命令拦截、日志脱敏;
|
|
123
|
-
3. **安全执行**:实时回显日志、可中断、幂等(已装 / 已下载 / 服务健康则复用);
|
|
124
|
-
4. **自动生成组件卡片**:服务器类组件注册到组件清单,卡片出现在主面板左侧(启动/停止/状态/【打开】直达 Web UI;多服务器时 ▾ 下拉;打开详情时自动隐藏;可折叠并有状态记忆)。
|
|
9
|
+
> 一站式管理你的 DeepSeek Harness 插件:一键启用/停用、500+ 插件与技能市场一键安装、
|
|
10
|
+
> 框架一键升级(失败自动回滚)。
|
|
125
11
|
|
|
126
|
-
|
|
12
|
+
## 为什么是 DSH 插件中心
|
|
127
13
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
---
|
|
135
|
-
|
|
136
|
-
> **给插件作者**:给仓库打上 `dsh-plugin` 标签即可被官方 [topic 列表](https://github.com/topics/dsh-plugin)
|
|
137
|
-
> 与本中心自动收录;技能类仓库请打 `agent-skills` / `claude-skills` / `dsh-skill`。
|
|
138
|
-
|
|
139
|
-
---
|
|
14
|
+
- 🧩 **插件 + 技能双市场** — 自动收录 `dsh-plugin` 仓库(按 star **500+**)外加技能 tab;
|
|
15
|
+
浏览、搜索、一键安装,**零 GitHub API 调用**(CDN 分发,秒开零限流)。
|
|
16
|
+
- 🚀 **框架一键升级** — 备份 → 在线安装(服务不中断)→ 校验 → **失败自动回滚**,端到端实测。
|
|
17
|
+
- 🤖 **AI 赋能** — 输入 npm 包名或 GitHub 仓库,本地 AI 读文档生成**部署计划**
|
|
18
|
+
(安装/写配置/启动服务/健康检查),你确认后安全执行;服务器组件自动生成控制卡片。
|
|
19
|
+
→ [详见](docs/ai-empower.zh.md)
|
|
140
20
|
|
|
141
21
|
## 一键部署
|
|
142
22
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
插件声明了 `dsh.bundle` 官方清单,一条命令装好并自动启用:
|
|
146
|
-
|
|
147
|
-
```sh
|
|
23
|
+
```bash
|
|
148
24
|
# npm 发布版(推荐:预构建产物,无需 git / 构建授权)
|
|
149
25
|
dsh plugin --profile web add @noob-stupid/dsh-plugin-console
|
|
150
26
|
|
|
@@ -152,14 +28,9 @@ dsh plugin --profile web add @noob-stupid/dsh-plugin-console
|
|
|
152
28
|
dsh plugin --profile web add github:Noob-stupid/dsh-plugin-hub
|
|
153
29
|
```
|
|
154
30
|
|
|
155
|
-
|
|
31
|
+
然后重启 dsh 服务 → 刷新页面 → **设置 → 插件 → 插件控制台**。
|
|
156
32
|
|
|
157
|
-
|
|
158
|
-
dsh plugin --profile web remove @noob-stupid/dsh-plugin-console
|
|
159
|
-
dsh plugin --profile web add @noob-stupid/dsh-plugin-console
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
然后重启 dsh 服务 → 刷新页面 → 设置 → 插件 → 插件管理。
|
|
33
|
+
<details><summary><b>更多部署方式</b>(部署脚本 / 一句话交给 AI)</summary>
|
|
163
34
|
|
|
164
35
|
### 方式二:部署脚本(网络受限时的兜底)
|
|
165
36
|
|
|
@@ -187,6 +58,45 @@ git clone https://github.com/Noob-stupid/dsh-plugin-hub /tmp/dsh-plugin-console
|
|
|
187
58
|
|
|
188
59
|
要求:DSH ≥ 0.1.0-rc.6(web profile,含 `dsh-client-modules` / `dsh-host-plugin-inventory`)。
|
|
189
60
|
|
|
61
|
+
</details>
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 核心优势
|
|
66
|
+
|
|
67
|
+
| | 优势 | 说明 |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| 🤖 | **AI 赋能** | 输入 npm 包名 / GitHub 仓库,本地 AI 读文档生成**部署计划**(安装/写配置/启动服务/健康检查),你确认后安全执行;服务器类组件自动生成控制卡片 |
|
|
70
|
+
| 🛡️ | **框架升级适配门与安全** | 升级后不兼容插件强制禁用(适配门锁定,「检测更新 → 更新并适配 → 自动校验解锁」);升级前全树 checkpoint、拉起失败自动全树回滚、框架卡片一键回滚到上一版 |
|
|
71
|
+
| 🏠 | **全家桶分组卡片与安全** | 同根包子路径导出自动聚合为一张全家桶卡片(收起/展开、批量检测更新、一键启用已适配、已知校验预览);永不崩安全(启用前导入探针 + 补丁自愈 + exports 回退);适配门源码扫描硬判据与迁移检测;删除聚合包子行仅停用该行 |
|
|
72
|
+
| 🚀 | **服务器组件卡片** | 左侧浮卡与主面板顶边对齐:启动 / 停止 / 状态 / 【打开】直达 Web UI,多服务器下拉、可折叠(状态记忆) |
|
|
73
|
+
| 🧩 | **插件 + 技能双市场** | 自动收录 `dsh-plugin` topic 仓库(按 star **500+**),另有**技能 tab**(`agent-skills` ∪ `claude-skills` ∪ `dsh-skill`,最多 300)——浏览、搜索、一键安装,零 GitHub API 调用;插件自带技能(如 openviking-memory)只读展示 |
|
|
74
|
+
| 🤖 | **自动收录 CI** | GitHub Actions 每 6 小时自动重跑 `build-index`(也支持手动触发);作者只需给自己的仓库打 `dsh-plugin` / `agent-skills` / `claude-skills` / `dsh-skill` 标签,**无需申请、无需审核** |
|
|
75
|
+
| ⚡ | **秒开、零限流** | 索引以静态 `marketplace/index.json` 提交仓库,经 jsDelivr CDN 分发(宿主 10 分钟缓存)——终端用户**零 GitHub API 调用、零限流** |
|
|
76
|
+
| 🔄 | **版本检测与一键更新** | semver 比较 + beta/next 识别(本地已是测试版最新时不误报);已安装条目自动比对 npm `dist-tags`,聚合包子包版本不配套时给出 depsOutdated 提示 |
|
|
77
|
+
| 🔀 | **多源检索** | GitHub / Gitee(仓库直装模式)/ 自定义搜索源(URL 模板 + 请求头认证 + 私网 http);「⊞」并行合并 GitHub + 全部自定义源 |
|
|
78
|
+
| 🔒 | **安全默认** | 全部路由仅环回;AI 兜底置于明确费用授权弹窗之后;AI 赋能执行器命令/路径白名单;基础设施行禁止开关(受保护) |
|
|
79
|
+
|
|
80
|
+
<details>
|
|
81
|
+
<summary><b>📑 目录</b></summary>
|
|
82
|
+
|
|
83
|
+
- [核心优势](#核心优势)
|
|
84
|
+
- [AI 赋能与服务器组件控制](#ai-赋能与服务器组件控制)
|
|
85
|
+
- [一键部署](#一键部署)
|
|
86
|
+
- [使用方法](#使用方法)
|
|
87
|
+
- [功能](#功能)
|
|
88
|
+
- [原理](#原理)
|
|
89
|
+
- [兼容性策略](#兼容性策略)
|
|
90
|
+
- [项目结构](#项目结构)
|
|
91
|
+
- [HTTP 接口](#http-接口)
|
|
92
|
+
- [安全说明](#安全说明)
|
|
93
|
+
- [已知限制](#已知限制)
|
|
94
|
+
- [帮助 / Help](#帮助--help)
|
|
95
|
+
- [生态与收录](#生态与收录)
|
|
96
|
+
- [参与贡献](#参与贡献)
|
|
97
|
+
- [许可证](#许可证)
|
|
98
|
+
</details>
|
|
99
|
+
|
|
190
100
|
---
|
|
191
101
|
|
|
192
102
|
## 使用方法
|
|
@@ -234,37 +144,6 @@ git clone https://github.com/Noob-stupid/dsh-plugin-hub /tmp/dsh-plugin-console
|
|
|
234
144
|
- **卡片关闭语义**:终态(成功/失败)点叉号永久关闭(持久化);进行中点叉号仅本次会话
|
|
235
145
|
隐藏,刷新后恢复显示。
|
|
236
146
|
|
|
237
|
-
### 框架升级适配门与升级安全(v0.3.25)
|
|
238
|
-
|
|
239
|
-
> 缘起:2026-09-04 DSH `0.1.1-rc.2 → 0.1.2-rc.1` 升级事故——升级脚本在错误的工作目录执行,
|
|
240
|
-
> 把新 CLI 原位覆盖进旧 `.pnpm` 目录、依赖树混版本,服务无法拉起。本版本把「升级安全」与
|
|
241
|
-
> 「插件兼容检测」固化为控制台机制。
|
|
242
|
-
|
|
243
|
-
**升级安全三件套**
|
|
244
|
-
|
|
245
|
-
1. **框架安装根识别**:定位真正的框架安装根(含 `.pnpm` 的顶层 `node_modules`),修复
|
|
246
|
-
`require.resolve` 返回 `.pnpm` 内部 realpath 导致的「重链空转 / 新包覆盖旧目录」根因;
|
|
247
|
-
定位不到时**拒绝升级**(不 kill 服务、服务保持运行);
|
|
248
|
-
2. **升级前全树 checkpoint**:镜像 `.pnpm` 全部 `@deepseek-ai` 版本包 + 顶层 scope +
|
|
249
|
-
`lock.yaml`(写入 `~/.dsh/plugin-console/framework-backups/<版本>/fw-tree/`);
|
|
250
|
-
3. **拉起失败自动全树回滚并重试**:安装失败或服务拉起失败都会自动恢复升级前全树并再次拉起,
|
|
251
|
-
不再只留「请手动运行」提示;回滚后跳过重链/修复(避免对已恢复旧树二次破坏)。
|
|
252
|
-
|
|
253
|
-
**一键回滚**:升级后框架卡片出现「回滚到上一版」按钮(`/plugin-console/framework-rollback`):
|
|
254
|
-
停服 → 全树恢复 → 自动拉起 → 健康检测,全程状态可见。
|
|
255
|
-
|
|
256
|
-
**插件适配门(插件检测)**
|
|
257
|
-
|
|
258
|
-
- 升级后写入 `~/.dsh/plugin-console/compat-pending.json` 的插件行被**强制禁用**,启用按钮
|
|
259
|
-
锁定(服务端 `/toggle` 直接 409,无法绕过);行状态以按钮文案「待适配」提示;
|
|
260
|
-
- 「详情」面板给出说明与入口:**检测更新 → 更新并适配**;
|
|
261
|
-
- **更新后自动校验**:扫描最新版 `package.json` 的 `dsh.engines.framework` / `engines.dsh`
|
|
262
|
-
显式声明 + `@deepseek-ai/*` 依赖范围(内置零依赖 semver 判定器:依赖判定遵循 npm
|
|
263
|
-
prerelease 严格规则、声明判定宽松);版本已变化且未判定不兼容 → **自动移除禁用块解锁**;
|
|
264
|
-
聚合包更新连带校验同步的子包;
|
|
265
|
-
- **AI 赋能适配预检**:规划时服务端预检 registry 最新版声明与适配门命中情况,注入子代理
|
|
266
|
-
提示词(要求计划向用户解释适配结论),并在计划面板标注(不兼容标红)。
|
|
267
|
-
|
|
268
147
|
### 插件市场(多搜索源)
|
|
269
148
|
|
|
270
149
|
- **搜索源切换**:点击顶部登录态标识弹出菜单,在 **GitHub / Gitee / 自定义源** 间切换(选择持久化);
|
|
@@ -310,161 +189,13 @@ git clone https://github.com/Noob-stupid/dsh-plugin-hub /tmp/dsh-plugin-console
|
|
|
310
189
|
|
|
311
190
|
---
|
|
312
191
|
|
|
313
|
-
##
|
|
314
|
-
|
|
315
|
-
### 开关语义
|
|
316
|
-
|
|
317
|
-
DSH 的 web profile 由 bundle 补丁层 + 用户补丁层(`$DSH_HOME/profiles/web/cordis.patch.yml`)
|
|
318
|
-
组合而成,补丁是**逐键覆盖**语义。插件开关只是往用户补丁层追加/移除两行 YAML:
|
|
319
|
-
|
|
320
|
-
```yaml
|
|
321
|
-
- id: 插件条目id
|
|
322
|
-
disabled: true
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
配置文件监视器(HMR)会在保存后 1 秒内重组合,无需重启——除宿主代码本身变更外。
|
|
326
|
-
|
|
327
|
-
### 安装链
|
|
328
|
-
|
|
329
|
-
```
|
|
330
|
-
配置的软件源按主→备依次尝试(默认 npmmirror → npmjs)
|
|
331
|
-
→ curl 手动安装 (node 网络黑洞时:curl 下载 tarball 解压进 node_modules)
|
|
332
|
-
→ git 通道 (GitHub 走加速代理+直连,Gitee 走对应平台)
|
|
333
|
-
→ Windows EPERM 陈旧目录自动清理重试
|
|
334
|
-
→ 自动展开仓库子包 (聚合包优先)
|
|
335
|
-
→ 本地 AI 兜底 (置于明确费用授权弹窗之后)
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
技能安装独立走:`git clone --depth 1` → 复制 SKILL.md 资源到 `~/.dsh/skills/<名称>/`
|
|
339
|
-
(不碰 npm、不写补丁、无需重启)。
|
|
340
|
-
|
|
341
|
-
### 数据源
|
|
342
|
-
|
|
343
|
-
```
|
|
344
|
-
GitHub Actions(每 6 小时,仓库自带 token)
|
|
345
|
-
└─ scripts/build-index.cjs:分页拉取 topic:dsh-plugin(按 star 500 个)+ 技能 topic(300 个)
|
|
346
|
-
└─ 提交 marketplace/index.json 回 main
|
|
347
|
-
└─ 宿主经 jsDelivr CDN 读取(10 分钟缓存)→ 市场秒开、零 API 调用
|
|
348
|
-
└─ 实时搜索仍走 GitHub 搜索 API(浏览器直连 + 服务端通道兜底)
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
### 版本检测与已安装识别
|
|
352
|
-
|
|
353
|
-
- **已安装识别**:按已装条目的 `repository` 字段或模块名与市场条目比对(仓库名 → 包名映射);
|
|
354
|
-
- **版本检测**:`check-update` 走 curl 读 npm `dist-tags.latest`;聚合包额外对比子包
|
|
355
|
-
声明版本 vs 本地实际版本(depsOutdated),防止半更新混搭导致启动冲突。
|
|
356
|
-
|
|
357
|
-
---
|
|
358
|
-
|
|
359
|
-
## 兼容性策略
|
|
360
|
-
|
|
361
|
-
- 当前支持 **DSH 0.1.0 系列**(`0.1.0-rc.6` 及同系列版本)。
|
|
362
|
-
- 面板会读取运行中的 `@deepseek-ai/dsh-web-app` 版本:官方发布破坏性升级
|
|
363
|
-
(0.2 / 1.0 等)后,面板顶部会显示兼容性警告并给出本仓库地址,而不是默默失效。
|
|
364
|
-
- **插件适配门(v0.3.25)**:框架升级后不兼容的第三方插件会被**强制禁用**(启用按钮锁定);
|
|
365
|
-
请先「检测更新」升级该插件,更新并通过自动校验后才会解锁——详见
|
|
366
|
-
「框架升级适配门与升级安全」。
|
|
367
|
-
- 官方破坏性更新可能改动的接口:补丁层语义、`webServer.register`、
|
|
368
|
-
加载器条目结构、`dsh.client` bundle 格式、`settings.plugins.tab` 插槽。
|
|
369
|
-
届时随官方版本更新本仓库即可(依赖面已收窄到上述几个点)。
|
|
370
|
-
- 部署脚本不校验版本、直接安装;面板里的警告是权威提示。
|
|
371
|
-
|
|
372
|
-
---
|
|
373
|
-
|
|
374
|
-
## 项目结构
|
|
375
|
-
|
|
376
|
-
```
|
|
377
|
-
lib/index.js 宿主端插件(/plugin-console/* 路由 + 补丁读写 + 多源检索 + 安装)
|
|
378
|
-
lib/client.js 浏览器端 bundle(ModuleLoader 格式,设置页 tab)
|
|
379
|
-
scripts/build-index.cjs 索引构建(插件 --limit 500 / 技能 --skills --limit 300)
|
|
380
|
-
scripts/apply-framework-patch.cjs 框架层补丁(issue #5,幂等,可重复应用)
|
|
381
|
-
.github/workflows/registry.yml 自动收录 CI(每 6 小时 + 手动触发)
|
|
382
|
-
marketplace/index.json 生成的静态索引(jsDelivr CDN 分发)
|
|
383
|
-
deploy.ps1 / deploy.sh 一键部署脚本(Windows / Linux·macOS)
|
|
384
|
-
test-harness.mjs 逻辑自检(state/toggle/校验/环回保护;搜索视网络环境 SKIP)
|
|
385
|
-
test-compat-gate.mjs 适配门单元测试(内置 semver 判定器:声明/依赖兼容规则)
|
|
386
|
-
```
|
|
387
|
-
<img width="1878" height="945" alt="image" src="https://github.com/user-attachments/assets/b26f2f19-0ba4-4be7-9ca1-b3fd4c51a7a8" />
|
|
388
|
-
|
|
389
|
-
---
|
|
390
|
-
|
|
391
|
-
## HTTP 接口
|
|
392
|
-
|
|
393
|
-
| 接口 | 方法 | 说明 |
|
|
394
|
-
|---|---|---|
|
|
395
|
-
| `/plugin-console/state` | GET | 插件清单 + 补丁状态 + 兼容性 + 运行中的安装任务 |
|
|
396
|
-
| `/plugin-console/toggle` | POST | 启用/停用条目(写用户补丁层) |
|
|
397
|
-
| `/plugin-console/uninstall` | POST | 删除条目并卸载包(bundle 感知) |
|
|
398
|
-
| `/plugin-console/search` | POST | 多源搜索(github/gitee/自定义,`multi` 合并) |
|
|
399
|
-
| `/plugin-console/repo` | POST | 仓库元数据:package.json、private 根、dsh 提示、**hasSkill** |
|
|
400
|
-
| `/plugin-console/enrich` | POST | 服务端类型标记(官方/聚合/技能) |
|
|
401
|
-
| `/plugin-console/install` | POST | 安装(插件或 `kind: skill` 技能),返回任务 id |
|
|
402
|
-
| `/plugin-console/install-status` | POST | 轮询安装任务 |
|
|
403
|
-
| `/plugin-console/check-update` | POST | npm 最新版本 + 子包不配套检查 |
|
|
404
|
-
| `/plugin-console/market-index` | POST | 静态索引(jsDelivr CDN,10 分钟缓存) |
|
|
405
|
-
| `/plugin-console/skills-installed` | GET | `~/.dsh/skills` 下已安装技能 |
|
|
406
|
-
| `/plugin-console/sources` | GET/POST | 软件源与搜索源管理、Gitee OAuth 配置 |
|
|
407
|
-
| `/plugin-console/gitee-oauth-url` / `gitee-oauth-callback` | GET | Gitee OAuth 流程 |
|
|
408
|
-
| `/plugin-console/ai-consent` | POST | 同意/取消 AI 兜底步骤 |
|
|
409
|
-
| `/plugin-console/restart` | POST | 自带守护的安全自重启(等同面板按钮) |
|
|
410
|
-
| `/plugin-console/framework-upgrade` | POST | 框架一键升级(全树 checkpoint → 在线安装 → 全树回滚保护) |
|
|
411
|
-
| `/plugin-console/framework-rollback` | POST | 一键回滚到升级前版本(停服 → 全树恢复 → 自动拉起 → 健康检测) |
|
|
412
|
-
| `/plugin-console/self-update` | POST | 控制台自身一键更新(npm 最新 tarball 到当前 profile) |
|
|
413
|
-
| `/plugin-console/ai-empower/plan` / `status` / `run` / `cancel` | POST | AI 赋能:规划(含框架适配预检)→ 状态轮询 → 确认执行 → 取消 |
|
|
414
|
-
| `/plugin-console/components` / `component/start` / `stop` / `status` | GET/POST | 服务器组件清单与启动/停止/状态 |
|
|
415
|
-
|
|
416
|
-
---
|
|
417
|
-
|
|
418
|
-
## AI 兜底安装与授权弹窗
|
|
419
|
-
|
|
420
|
-
安装走**确定性通道链**:`配置源(主→备)→ curl 手动安装 → git 通道 → EPERM 清理重试 → 仓库子包展开`。常规通道全部失败时,才轮到**本地 AI 兜底**。
|
|
421
|
-
|
|
422
|
-
**本地 AI 兜底是什么**:拉起一个本地 AI 子代理接管安装——它会像人工一样诊断(查仓库结构、识别子包/聚合包、清理残留),用正确管理器完成安装并落配置。**注意:这一步会调用 DeepSeek API 模型,可能产生 API 费用。**
|
|
423
|
-
|
|
424
|
-
**授权弹窗逻辑(费用透明)**:
|
|
425
|
-
|
|
426
|
-
1. 常规通道全失败后,任务进入「等待授权」状态,屏幕中央弹出**最上层模态框**:
|
|
427
|
-
- 明确说明"将调用 DeepSeek API 模型,可能产生 API 费用"
|
|
428
|
-
- 提供 **同意,继续** / **取消** 两个按钮(取消 = 零费用)
|
|
429
|
-
- 10 分钟未决定自动取消
|
|
430
|
-
2. 模态框内可勾选 **"以后不再提醒"**(自动同意)——勾选后可随时在**插件市场页面最底部**恢复弹窗提醒
|
|
431
|
-
3. 右上角悬浮的 **"AI 兜底"开关**可彻底关闭该功能:常规通道失败将直接取消安装,**永远不会调用模型 API(零费用)**
|
|
432
|
-
|
|
433
|
-
---
|
|
434
|
-
|
|
435
|
-
## 框架层补丁(cordis.patch.yml 解析容错)
|
|
436
|
-
|
|
437
|
-
**问题(issue #5)**:`cordis.patch.yml` 若含顶格 `[]` 占位符 + 后续条目(两个 YAML 根节点),
|
|
438
|
-
DSH 启动时解析崩溃:`end of the stream or a document separator is expected`。
|
|
439
|
-
|
|
440
|
-
**修复位置**:DSH 框架 `dsh-app-boot` 的 `parsePatchList`——解析失败时自动移除顶格空数组占位行(视为 no-op)后重试;
|
|
441
|
-
正常文件、纯 `[]` 文件、缩进子数组均不受影响。
|
|
442
|
-
|
|
443
|
-
**应用方式**(DSH 升级后需重新执行,升级会覆盖框架文件):
|
|
444
|
-
|
|
445
|
-
```bash
|
|
446
|
-
node scripts/apply-framework-patch.cjs
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
脚本自动定位 npx 缓存中的 `dsh-app-boot/lib/index.js`,检测到已补丁则跳过(幂等),首次应用会保留 `.bak-issue5` 备份。
|
|
450
|
-
|
|
451
|
-
---
|
|
452
|
-
|
|
453
|
-
## 安全说明
|
|
454
|
-
|
|
455
|
-
- 全部路由仅允许环回地址访问;
|
|
456
|
-
- GitHub 元数据只用于发现公开插件,npm 安装走 registry 的完整 TLS 校验;
|
|
457
|
-
- GitHub 源搜索在浏览器内直连;Gitee / 自定义源检索与请求头(含认证信息)仅经服务端处理,不下发浏览器;
|
|
458
|
-
- 自定义源地址仅允许 https 与本机/私网 http(127.0.0.1、localhost、10.x、192.168.x、172.16-31.x 等);
|
|
459
|
-
- 技能是纯文件(SKILL.md + 资源)——安装技能**不会执行任何代码**;git clone 来自你选择的仓库,安装前请自行核验。
|
|
460
|
-
|
|
461
|
-
---
|
|
462
|
-
|
|
463
|
-
## 免责声明
|
|
192
|
+
## 文档
|
|
464
193
|
|
|
465
|
-
-
|
|
466
|
-
-
|
|
467
|
-
-
|
|
194
|
+
- [AI 赋能与服务器组件控制](docs/ai-empower.zh.md)
|
|
195
|
+
- [框架升级适配门与升级安全](docs/upgrade-safety-adapt-gate.zh.md)
|
|
196
|
+
- [原理](docs/how-it-works.zh.md) · [兼容性策略](docs/compatibility.zh.md) · [项目结构](docs/project-layout.zh.md)
|
|
197
|
+
- [HTTP 接口](docs/http-endpoints.zh.md) · [AI 兜底安装与授权弹窗](docs/ai-fallback.zh.md)
|
|
198
|
+
- [安全说明与免责声明](docs/security-disclaimer.zh.md)
|
|
468
199
|
|
|
469
200
|
---
|
|
470
201
|
|
package/lib/index.js
CHANGED
|
@@ -179,26 +179,37 @@ function baseDirOf(baseUrl) {
|
|
|
179
179
|
* (2026-09-04 教训:@openviking/dsh-memory-plugin 因此被 heal 误判模块缺失并自动禁用)——
|
|
180
180
|
* fallback 直接查 node_modules 物理路径。
|
|
181
181
|
*/
|
|
182
|
-
function resolvePackageJson(pkgName, baseDir) {
|
|
182
|
+
function resolvePackageJson(pkgName, baseDir, fallbackBase) {
|
|
183
183
|
const name = packageNameOf(pkgName)
|
|
184
184
|
try {
|
|
185
185
|
return createRequire(join(baseDir, 'package.json')).resolve(`${name}/package.json`)
|
|
186
186
|
} catch {}
|
|
187
187
|
const parts = String(name).split('/')
|
|
188
188
|
const candidate = join(baseDir, 'node_modules', ...parts, 'package.json')
|
|
189
|
-
|
|
189
|
+
if (existsSync(candidate)) return candidate
|
|
190
|
+
// issue #15:npm 全局安装 dsh 时 ctx.baseUrl 落在框架安装树(而非 profile node_modules),
|
|
191
|
+
// 官方 @deepseek-ai/* 恰好可见、第三方插件全部解析失败 → 详情/版本/仓库全空。
|
|
192
|
+
// 回退到 profile 目录(fallbackBase)再试一次。
|
|
193
|
+
if (typeof fallbackBase === 'string' && fallbackBase !== '' && fallbackBase !== baseDir) {
|
|
194
|
+
try {
|
|
195
|
+
return createRequire(join(fallbackBase, 'package.json')).resolve(`${name}/package.json`)
|
|
196
|
+
} catch {}
|
|
197
|
+
const candidate2 = join(fallbackBase, 'node_modules', ...parts, 'package.json')
|
|
198
|
+
if (existsSync(candidate2)) return candidate2
|
|
199
|
+
}
|
|
200
|
+
return null
|
|
190
201
|
}
|
|
191
202
|
|
|
192
203
|
/** 已加载插件的包元信息缓存(安装日期/版本/仓库),60 秒 TTL。 */
|
|
193
204
|
const pkgMetaCache = new Map()
|
|
194
205
|
const PKG_META_TTL = 60000
|
|
195
|
-
function entryPkgMeta(moduleName, baseUrl) {
|
|
206
|
+
function entryPkgMeta(moduleName, baseUrl, profileDir) {
|
|
196
207
|
if (typeof moduleName !== 'string' || moduleName.startsWith('cordis:')) return null
|
|
197
208
|
const hit = pkgMetaCache.get(moduleName)
|
|
198
209
|
if (hit !== undefined && Date.now() - hit.at < PKG_META_TTL) return hit
|
|
199
210
|
const meta = { at: Date.now(), installDate: null, version: null, repository: null }
|
|
200
211
|
try {
|
|
201
|
-
const pkgPath = resolvePackageJson(moduleName, baseDirOf(baseUrl))
|
|
212
|
+
const pkgPath = resolvePackageJson(moduleName, baseDirOf(baseUrl), profileDir ?? null)
|
|
202
213
|
if (pkgPath === null) throw new Error('not found')
|
|
203
214
|
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
|
|
204
215
|
// 安装日期:优先 curl 通道写入的 .dsh-installed-at 标记(真实安装时刻);
|
|
@@ -1061,7 +1072,7 @@ function backupProfileSnapshot(profileDir, version, ctx) {
|
|
|
1061
1072
|
try { copyFileSync(join(profileDir, 'package.json'), join(dir, 'profile-package.json')) } catch {}
|
|
1062
1073
|
try {
|
|
1063
1074
|
const plugins = listEntries(ctx).map((e) => {
|
|
1064
|
-
const meta = entryPkgMeta(e.moduleName, ctx.baseUrl ?? 'file:///')
|
|
1075
|
+
const meta = entryPkgMeta(e.moduleName, ctx.baseUrl ?? 'file:///', profileDirOf(ctx))
|
|
1065
1076
|
return { rowId: e.rowId, moduleName: e.moduleName, enabled: e.enabled, version: meta?.version ?? null, installDate: meta?.installDate ?? null }
|
|
1066
1077
|
})
|
|
1067
1078
|
writeFileSync(join(dir, 'plugins.json'), JSON.stringify(plugins, null, 2), 'utf8')
|
|
@@ -1106,6 +1117,15 @@ function findPatchPath(ctx) {
|
|
|
1106
1117
|
return defaultPatchPath()
|
|
1107
1118
|
}
|
|
1108
1119
|
|
|
1120
|
+
/** profile 根目录(resolvePackageJson 的 fallbackBase 用;失败返回 null)。 */
|
|
1121
|
+
function profileDirOf(ctx) {
|
|
1122
|
+
try {
|
|
1123
|
+
return dirname(findPatchPath(ctx))
|
|
1124
|
+
} catch {
|
|
1125
|
+
return null
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1109
1129
|
/** 读取补丁文件并扫描:停用块与 insert 行的 id。 */
|
|
1110
1130
|
async function readPatchState(patchPath) {
|
|
1111
1131
|
let text = ''
|
|
@@ -1187,10 +1207,10 @@ function summarizeReadme(text) {
|
|
|
1187
1207
|
}
|
|
1188
1208
|
|
|
1189
1209
|
/** 读取一个已加载插件的 package.json 元信息与 README 摘要。 */
|
|
1190
|
-
async function readPluginDetails(moduleName, baseUrl) {
|
|
1210
|
+
async function readPluginDetails(moduleName, baseUrl, profileDir) {
|
|
1191
1211
|
if (typeof moduleName !== 'string' || moduleName.startsWith('cordis:')) return { meta: null, readme: null }
|
|
1192
1212
|
try {
|
|
1193
|
-
const pkgPath = resolvePackageJson(moduleName, baseDirOf(baseUrl))
|
|
1213
|
+
const pkgPath = resolvePackageJson(moduleName, baseDirOf(baseUrl), profileDir ?? null)
|
|
1194
1214
|
if (pkgPath === null) throw new Error('not found')
|
|
1195
1215
|
const pkg = JSON.parse(await readFile(pkgPath, 'utf8'))
|
|
1196
1216
|
const meta = {
|
|
@@ -3877,7 +3897,7 @@ async function runInstallJob(job, ctx) {
|
|
|
3877
3897
|
let ghRepo = typeof job.repo === 'string' && job.repo !== '' && job.repo.includes('/') ? job.repo : null
|
|
3878
3898
|
if (ghRepo === null) {
|
|
3879
3899
|
try {
|
|
3880
|
-
const meta = entryPkgMeta(name, ctx.baseUrl ?? 'file:///')
|
|
3900
|
+
const meta = entryPkgMeta(name, ctx.baseUrl ?? 'file:///', profileDirOf(ctx))
|
|
3881
3901
|
const repoUrl = typeof meta?.repository === 'string' ? meta.repository : (meta?.repository && typeof meta.repository === 'object' ? meta.repository.url : null)
|
|
3882
3902
|
const m = typeof repoUrl === 'string' ? repoUrl.replace(/^git\+/u, '').match(/github\.com[/:]([^/]+\/[^/]+?)(?:\.git)?$/u) : null
|
|
3883
3903
|
if (m) ghRepo = m[1]
|
|
@@ -4110,7 +4130,7 @@ async function handle(ctx, req, res) {
|
|
|
4110
4130
|
}
|
|
4111
4131
|
} catch {}
|
|
4112
4132
|
const entries = listEntries(ctx).map((entry) => {
|
|
4113
|
-
const meta = entryPkgMeta(entry.moduleName, ctx.baseUrl ?? 'file:///')
|
|
4133
|
+
const meta = entryPkgMeta(entry.moduleName, ctx.baseUrl ?? 'file:///', profileDirOf(ctx))
|
|
4114
4134
|
return {
|
|
4115
4135
|
...entry,
|
|
4116
4136
|
userDisabled: patch.disables.includes(entry.rowId),
|
|
@@ -4301,7 +4321,7 @@ async function handle(ctx, req, res) {
|
|
|
4301
4321
|
return
|
|
4302
4322
|
}
|
|
4303
4323
|
const moduleName = entry.options.name
|
|
4304
|
-
const details = await readPluginDetails(moduleName, ctx.baseUrl ?? 'file:///')
|
|
4324
|
+
const details = await readPluginDetails(moduleName, ctx.baseUrl ?? 'file:///', profileDirOf(ctx))
|
|
4305
4325
|
sendJson(res, 200, { ok: true, entryId, rowId: rowIdOf(ctx, entryId), moduleName, ...details })
|
|
4306
4326
|
return
|
|
4307
4327
|
}
|
|
@@ -4985,7 +5005,7 @@ async function handle(ctx, req, res) {
|
|
|
4985
5005
|
// 覆盖 dsh-plugin-console(本面板)这类"源码在 GitHub、npm 上不存在"的宿主插件。
|
|
4986
5006
|
let fallbackError = err instanceof Error ? err.message : String(err)
|
|
4987
5007
|
try {
|
|
4988
|
-
const meta = entryPkgMeta(packageName, ctx.baseUrl ?? 'file:///')
|
|
5008
|
+
const meta = entryPkgMeta(packageName, ctx.baseUrl ?? 'file:///', profileDirOf(ctx))
|
|
4989
5009
|
const repo = typeof meta?.repository === 'string'
|
|
4990
5010
|
? meta.repository.replace(/^git\+/u, '').replace(/\.git$/u, '')
|
|
4991
5011
|
: (meta?.repository && typeof meta.repository === 'object' ? meta.repository.url : null)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noob-stupid/dsh-plugin-console",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.28",
|
|
4
4
|
"description": "DSH plugin management panel & marketplace: one-click enable/disable, multi-source market (GitHub/Gitee/custom), static-index market (500+ plugins / 300 skills), skills, suites, and one-click framework upgrade.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|