dsh-m 0.2.0 → 0.2.1
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.en.md +12 -6
- package/README.md +12 -6
- package/docs/DESIGN.md +1 -1
- package/lib/cli.js +15 -2
- package/lib/client.js +6 -6
- package/lib/core/registry.js +5 -2
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -12,14 +12,20 @@ A DeepSeek Harness (DSH) plugin marketplace with a customizable registry: **brow
|
|
|
12
12
|
|
|
13
13
|
## Quick start
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
**Paste this whole block to your agent to install:**
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
Install and enable the DSH plugin dsh-m:
|
|
19
|
+
1. Run `dsh plugin --profile web add dsh-m`
|
|
20
|
+
2. Restart DSH Web to load the plugin (on this machine: `systemctl --user restart dsh-web.service`; or restart it your usual way)
|
|
21
|
+
3. Poll `curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3080` until it returns 200 again
|
|
22
|
+
4. Run `curl -s -X POST http://127.0.0.1:3080/dshm -H 'content-type: application/json' -d '{"method":"ping"}'` and confirm the reply has `plugin: dsh-m`
|
|
23
|
+
5. Then remind me to refresh the page and click "Plugin Marketplace" at the bottom of the sidebar
|
|
17
24
|
```
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
2. Refresh the page and click "**Plugin Marketplace**" at the bottom of the sidebar.
|
|
26
|
+
> `npm install -g dsh-m` installs only the `dshm` CLI (terminal management) — it does **not** register the plugin into the web profile; it can coexist with the plugin install above.
|
|
21
27
|
|
|
22
|
-
The default registry includes DSH Skins,
|
|
28
|
+
The default registry includes DSH Skins, ModSearch, the Lark / QQ / Weixin / WeCom / DingTalk channel bridges, and dsh-m itself.
|
|
23
29
|
|
|
24
30
|
## Panel
|
|
25
31
|
|
|
@@ -58,7 +64,7 @@ When the registry is unavailable, `registry` / `search` / `outdated` print the c
|
|
|
58
64
|
|
|
59
65
|
## Registry
|
|
60
66
|
|
|
61
|
-
`registry.json` is hand-curated and
|
|
67
|
+
`registry.json` is hand-curated and fetched at runtime in order: **GitHub raw (`@main`) → GitHub mirror (jsDelivr CDN, backup line) → local 60-min TTL cache → bundled snapshot** — listing updates are decoupled from plugin releases. To add or amend a listing, edit `registry.json` and open a PR; CI validates the strict schema, npm/GitHub existence, duplicate ids and URL reachability.
|
|
62
68
|
|
|
63
69
|
**Custom registry (overrides the official one)**: the Settings tab supports a single custom registry address that **replaces** the default registry (no merging):
|
|
64
70
|
|
package/README.md
CHANGED
|
@@ -12,14 +12,20 @@
|
|
|
12
12
|
|
|
13
13
|
## 30 秒上手
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
**把下面整段贴给 agent 即可完成安装**:
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
安装并启用 DSH 插件 dsh-m:
|
|
19
|
+
1. 执行 `dsh plugin --profile web add dsh-m`
|
|
20
|
+
2. 重启 DSH Web 使插件加载(本机:`systemctl --user restart dsh-web.service`;或按你的部署方式重启)
|
|
21
|
+
3. 轮询 `curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3080`,直到恢复 200
|
|
22
|
+
4. 执行 `curl -s -X POST http://127.0.0.1:3080/dshm -H 'content-type: application/json' -d '{"method":"ping"}'`,确认返回 `plugin: dsh-m`
|
|
23
|
+
5. 完成后提醒我刷新页面,点击侧栏底部的「插件市场」
|
|
17
24
|
```
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
2. 刷新页面,点击侧栏底部的「**插件市场**」。
|
|
26
|
+
> `npm install -g dsh-m` 只安装 `dshm` CLI(终端管理用),**不会**把插件注册进 web profile;与上面插件安装不冲突,可并存。
|
|
21
27
|
|
|
22
|
-
默认收录清单里的插件包括:DSH Skins、
|
|
28
|
+
默认收录清单里的插件包括:DSH Skins、ModSearch、Lark / QQ / 微信 / 企业微信 / 钉钉通道桥,以及 dsh-m 自身。
|
|
23
29
|
|
|
24
30
|
## 界面(侧栏「插件市场」)
|
|
25
31
|
|
|
@@ -58,7 +64,7 @@ dshm restart --yes
|
|
|
58
64
|
|
|
59
65
|
## 收录清单(registry)
|
|
60
66
|
|
|
61
|
-
`registry.json` 手工 curated
|
|
67
|
+
`registry.json` 手工 curated,运行时按 **GitHub 原始文件(raw @main)→ GitHub 镜像(jsDelivr CDN,备用线路)→ 本地 60 分钟 TTL 缓存 → 包内快照** 的顺序获取——收录更新与插件发版**解耦**,push 后最多等一个缓存周期(可在设置页强制刷新)。收录 / 修订直接改 `registry.json` 发 PR,CI 自动校验:严格 schema、npm 包与 GitHub 仓库存在性、重复 id、URL 可达性。
|
|
62
68
|
|
|
63
69
|
**自定义收录清单(可覆盖官方清单)**:设置页支持单一自定义 registry 地址,**整体覆盖**默认清单(不合并):
|
|
64
70
|
|
package/docs/DESIGN.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
### 2.1 载体与分发(v1.1 可自定义 registry 定稿)
|
|
17
17
|
- repo 内**单文件 `registry.json`**,手工 curated,版本号**不写死**(运行时实查 npm/GitHub)。
|
|
18
|
-
- **默认源**获取顺序:raw.githubusercontent `@main` → jsDelivr `@main` → 默认 TTL 缓存 → npm
|
|
18
|
+
- **默认源**获取顺序:raw.githubusercontent `@main` → jsDelivr `@main` → 默认 TTL 缓存 → npm 包内快照兜底。jsDelivr 是 GitHub 内容的免费 CDN 镜像,仅作 raw 拉取失败时的**备用线路**(覆盖大陆可达性与 GitHub 故障;CDN 缓存可能滞后数小时,可用 purge.jsdelivr.net 手动清理)。收录更新与插件发版**解耦**。
|
|
19
19
|
- **自定义覆盖源(单一地址,整体覆盖,不合并)**:`registryUrl` 为空 = 官方默认清单;非空 = 一个 HTTPS URL(或 loopback HTTP,仅本机管理员信任边界,不承诺 DNS rebinding 防护)或 DSH Web 主机上的本地普通文件(绝对路径 / `file://`,`realpath` + `O_NOFOLLOW` 同 fd 读取与复核,严格 UTF-8,2 MiB 原始字节上限)。自定义源失败只回退**该源自己的缓存**,绝不静默改用官方清单;无可缓存数据时返回空清单 + 不可用状态。
|
|
20
20
|
- **「新增插件」流程**:设置页下载默认 `registry.json` → 用户自行编辑副本 → 填入副本地址「校验并应用」。副本是独立快照,不自动同步官方新条目。
|
|
21
21
|
- **严格 v1 schema**:顶层只允许 `version/plugins`,条目只允许 `id/name/description/category/tags/source/npm/github/homepage/icon`;未知字段、非法 ID/npm/GitHub/URL、重复 ID/tag、字段超限、`plugins` 超过 1,000 条均拒绝整份清单(不截断、不部分加载);超过 200 条提示性能边界。
|
package/lib/cli.js
CHANGED
|
@@ -51,6 +51,19 @@ function requireYes(flags, action) {
|
|
|
51
51
|
function sourceLabel(s) {
|
|
52
52
|
return { npm: 'npm', github: 'github', link: '本地 link', file: '本地 file', unknown: '未知' }[s] || s;
|
|
53
53
|
}
|
|
54
|
+
/** registry 来源的用户友好名称(CLI 本地终端可见)。 */
|
|
55
|
+
function registrySourceLabel(s) {
|
|
56
|
+
return {
|
|
57
|
+
'default-raw': 'GitHub 原始文件(@main)',
|
|
58
|
+
'default-jsdelivr': 'GitHub 镜像(备用)',
|
|
59
|
+
'default-cache': '默认清单缓存',
|
|
60
|
+
bundled: '包内快照(兜底)',
|
|
61
|
+
'custom-url': '自定义 URL 源',
|
|
62
|
+
'custom-file': '本地文件源',
|
|
63
|
+
'custom-cache': '自定义源(缓存)',
|
|
64
|
+
'custom-unavailable': '自定义源(不可用)',
|
|
65
|
+
}[s] || s;
|
|
66
|
+
}
|
|
54
67
|
function addressLines(state) {
|
|
55
68
|
return [
|
|
56
69
|
`配置地址:${state.configuredAddress === '' ? '(默认官方清单)' : state.configuredAddress}`,
|
|
@@ -138,7 +151,7 @@ async function runCliDispatch(argv, deps, io) {
|
|
|
138
151
|
out(` ${it.description}`);
|
|
139
152
|
}
|
|
140
153
|
const s = result.registryState;
|
|
141
|
-
out(`\n来源:${s.source}${s.stale ? '(缓存)' : ''} · 更新:${s.fetchedAt ?? '—'} · 共 ${result.total} 条`);
|
|
154
|
+
out(`\n来源:${registrySourceLabel(s.source)}${s.stale ? '(缓存)' : ''} · 更新:${s.fetchedAt ?? '—'} · 共 ${result.total} 条`);
|
|
142
155
|
return 0;
|
|
143
156
|
}
|
|
144
157
|
case 'list': {
|
|
@@ -188,7 +201,7 @@ async function runCliDispatch(argv, deps, io) {
|
|
|
188
201
|
err(line);
|
|
189
202
|
return 1;
|
|
190
203
|
}
|
|
191
|
-
out(`来源:${loaded.source} · 更新时间:${loaded.fetchedAt ?? '—'} · 条目:${loaded.count}`);
|
|
204
|
+
out(`来源:${registrySourceLabel(loaded.source)} · 更新时间:${loaded.fetchedAt ?? '—'} · 条目:${loaded.count}`);
|
|
192
205
|
for (const line of addressLines(loaded))
|
|
193
206
|
out(line);
|
|
194
207
|
for (const e of loaded.registry.plugins) {
|
package/lib/client.js
CHANGED
|
@@ -196,12 +196,12 @@ var ZH = {
|
|
|
196
196
|
"settings.about": "\u5173\u4E8E",
|
|
197
197
|
"settings.about.text": "\u4E2A\u4EBA DSH \u63D2\u4EF6\u5E02\u573A\uFF1A\u6536\u5F55\u3001\u5B89\u88C5\u3001\u5378\u8F7D\u3001\u5347\u7EA7\u5168\u90E8\u672C\u673A\u5B8C\u6210\uFF1B\u6536\u5F55\u6E05\u5355\u652F\u6301\u81EA\u5B9A\u4E49\u8986\u76D6\uFF0C\u5E94\u7528\u5373\u65F6\u751F\u6548\u3002",
|
|
198
198
|
"src.override": "\u81EA\u5B9A\u4E49\u6E90",
|
|
199
|
-
"src.jsdelivr": "
|
|
199
|
+
"src.jsdelivr": "GitHub \u955C\u50CF\uFF08\u5907\u7528\uFF09",
|
|
200
200
|
"src.raw": "raw.githubusercontent\uFF08@main\uFF09",
|
|
201
201
|
"src.cache": "\u672C\u5730\u7F13\u5B58",
|
|
202
202
|
"src.bundled": "\u5305\u5185\u5FEB\u7167\uFF08\u515C\u5E95\uFF09",
|
|
203
|
-
"src.default.raw": "
|
|
204
|
-
"src.default.jsdelivr": "
|
|
203
|
+
"src.default.raw": "GitHub \u539F\u59CB\u6587\u4EF6\uFF08@main\uFF09",
|
|
204
|
+
"src.default.jsdelivr": "GitHub \u955C\u50CF\uFF08\u5907\u7528\uFF09",
|
|
205
205
|
"src.default.cache": "\u9ED8\u8BA4\u6E05\u5355\u7F13\u5B58",
|
|
206
206
|
"src.custom.url": "\u81EA\u5B9A\u4E49 URL \u6E90",
|
|
207
207
|
"src.custom.file": "\u672C\u5730\u6587\u4EF6\u6E90",
|
|
@@ -365,12 +365,12 @@ var EN = {
|
|
|
365
365
|
"settings.about": "About",
|
|
366
366
|
"settings.about.text": "A personal DSH plugin marketplace \u2014 browse, install, uninstall and upgrade, all local; registry overrides apply live.",
|
|
367
367
|
"src.override": "Custom source",
|
|
368
|
-
"src.jsdelivr": "
|
|
368
|
+
"src.jsdelivr": "GitHub mirror (backup)",
|
|
369
369
|
"src.raw": "raw.githubusercontent (@main)",
|
|
370
370
|
"src.cache": "Local cache",
|
|
371
371
|
"src.bundled": "Bundled snapshot (fallback)",
|
|
372
|
-
"src.default.raw": "raw
|
|
373
|
-
"src.default.jsdelivr": "
|
|
372
|
+
"src.default.raw": "GitHub raw (@main)",
|
|
373
|
+
"src.default.jsdelivr": "GitHub mirror (backup)",
|
|
374
374
|
"src.default.cache": "Default registry cache",
|
|
375
375
|
"src.custom.url": "Custom URL source",
|
|
376
376
|
"src.custom.file": "Local file source",
|
package/lib/core/registry.js
CHANGED
|
@@ -479,8 +479,11 @@ function buildState(params) {
|
|
|
479
479
|
};
|
|
480
480
|
}
|
|
481
481
|
const REPO = 'iasiv5/dsh-m';
|
|
482
|
-
//
|
|
483
|
-
//
|
|
482
|
+
// 默认源两条网络线路(用户可见名称为「GitHub 镜像(备用)」,无需理解 jsDelivr 是什么):
|
|
483
|
+
// - raw.githubusercontent:GitHub 原始文件,准实时,永远优先;
|
|
484
|
+
// - jsDelivr(cdn.jsdelivr.net,GitHub 内容的免费 CDN 镜像):仅当 raw 拉不到时启用——
|
|
485
|
+
// 覆盖大陆可达性与 GitHub 故障两类场景,代价是 CDN 缓存可能滞后数小时
|
|
486
|
+
// (可用 purge.jsdelivr.net 手动清缓存)。再往下还有本地缓存与包内快照兜底。
|
|
484
487
|
const DEFAULT_URLS = [
|
|
485
488
|
{ source: 'default-raw', url: `https://raw.githubusercontent.com/${REPO}/main/registry.json` },
|
|
486
489
|
{ source: 'default-jsdelivr', url: `https://cdn.jsdelivr.net/gh/${REPO}@main/registry.json` },
|