dsh-m 0.2.8 → 0.2.10
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/docs/DESIGN.md +19 -5
- package/lib/cli.js +5 -4
- package/lib/client.js +319 -239
- package/lib/core/dsh-cli.js +245 -52
- package/lib/core/host-api.js +38 -6
- package/lib/core/installed.js +89 -38
- package/lib/core/market.js +52 -301
- package/lib/core/npm-integrity.js +139 -13
- package/lib/core/profile-transaction.js +825 -0
- package/lib/host.js +1 -2
- package/lib/tools.js +15 -24
- package/package.json +2 -1
- package/registry.json +33 -0
package/lib/host.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import Schema from '@deepseek-ai/schemastery';
|
|
3
|
-
import { withMutationLock } from './core/market.js';
|
|
4
3
|
import { createApiDispatcher } from './core/host-api.js';
|
|
5
4
|
import { bindLoaderHost } from './core/live-plugin.js';
|
|
6
5
|
import { createRegistryController } from './core/registry-controller.js';
|
|
@@ -36,7 +35,7 @@ export function apply(ctx, config) {
|
|
|
36
35
|
// 本地 API:单路由 + method 分发(防护与状态映射在 core/host-api.ts)
|
|
37
36
|
ctx.inject(['webServer'], (c) => {
|
|
38
37
|
const server = c.webServer;
|
|
39
|
-
const handleApi = createApiDispatcher({ controller, pkg
|
|
38
|
+
const handleApi = createApiDispatcher({ controller, pkg });
|
|
40
39
|
server.register({
|
|
41
40
|
kind: 'exact',
|
|
42
41
|
path: '/dshm',
|
package/lib/tools.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
2
2
|
import { installTimeoutMs } from './core/env.js';
|
|
3
|
-
import { installFromRegistry, listInstalledWithMeta, listMarket, uninstallPlugin, upgradePlugin,
|
|
3
|
+
import { installFromRegistry, listInstalledWithMeta, listMarket, uninstallPlugin, upgradePlugin, } from './core/market.js';
|
|
4
4
|
import { scheduleRestart } from './core/restart.js';
|
|
5
5
|
export const CATEGORY_LABELS = {
|
|
6
6
|
market: '市场',
|
|
@@ -15,18 +15,6 @@ function cloneJson(value) {
|
|
|
15
15
|
function summaryOf(state) {
|
|
16
16
|
return { isDefault: state.isDefault, status: state.status, stale: state.stale };
|
|
17
17
|
}
|
|
18
|
-
function matchInstalledByEntry(entry, installed) {
|
|
19
|
-
return installed.find((it) => {
|
|
20
|
-
if (entry.npm && (it.pkg === entry.npm || it.name === entry.npm))
|
|
21
|
-
return true;
|
|
22
|
-
if (entry.github && it.source === 'github') {
|
|
23
|
-
const m = /^github:([^#]+)/.exec(it.spec);
|
|
24
|
-
if (m && m[1] === entry.github)
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
return false;
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
18
|
export function registerTools(ctx, cfg, deps = {}) {
|
|
31
19
|
const timeoutMs = cfg.timeoutMs ?? 20_000;
|
|
32
20
|
const m = {
|
|
@@ -77,18 +65,18 @@ export function registerTools(ctx, cfg, deps = {}) {
|
|
|
77
65
|
withLatest: false,
|
|
78
66
|
namespace: 'host',
|
|
79
67
|
});
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
68
|
+
// 安装标注唯一来源:listMarket 的单次 profile 快照。
|
|
69
|
+
// 状态不完整且存在可被误标的条目时 fail-closed——不把未知安装状态呈现成未安装;
|
|
70
|
+
// 空结果(registry 不可用/超时/无匹配)无可误标条目,维持优雅空结果。
|
|
71
|
+
if (!result.installedComplete && result.items.length > 0) {
|
|
72
|
+
throw new Error('读取 web profile 安装状态失败,安装标注不可用;请稍后重试');
|
|
73
|
+
}
|
|
86
74
|
return cloneJson({
|
|
87
75
|
query: String(args.query || ''),
|
|
88
76
|
category,
|
|
89
77
|
total: result.total,
|
|
90
78
|
registry: summaryOf(result.registryState),
|
|
91
|
-
items:
|
|
79
|
+
items: result.items.map((e) => ({
|
|
92
80
|
id: e.id,
|
|
93
81
|
name: e.name,
|
|
94
82
|
description: e.description,
|
|
@@ -163,7 +151,7 @@ export function registerTools(ctx, cfg, deps = {}) {
|
|
|
163
151
|
if (!id)
|
|
164
152
|
throw new Error('缺少收录 id');
|
|
165
153
|
const version = typeof args.version === 'string' && args.version.trim() ? args.version.trim() : undefined;
|
|
166
|
-
return cloneJson(await
|
|
154
|
+
return cloneJson(await m.installFromRegistry(id, cfg, { version, namespace: 'host' }));
|
|
167
155
|
},
|
|
168
156
|
}));
|
|
169
157
|
ctx.tools.register(defineTool({
|
|
@@ -188,7 +176,7 @@ export function registerTools(ctx, cfg, deps = {}) {
|
|
|
188
176
|
const target = String(args.pkg || '').trim();
|
|
189
177
|
if (!target)
|
|
190
178
|
throw new Error('缺少 pkg');
|
|
191
|
-
return cloneJson(await
|
|
179
|
+
return cloneJson(await m.uninstallPlugin(target, cfg, { namespace: 'host' }));
|
|
192
180
|
},
|
|
193
181
|
}));
|
|
194
182
|
ctx.tools.register(defineTool({
|
|
@@ -247,7 +235,7 @@ export function registerTools(ctx, cfg, deps = {}) {
|
|
|
247
235
|
const target = String(args.pkg || '').trim();
|
|
248
236
|
if (!target)
|
|
249
237
|
throw new Error('缺少 pkg');
|
|
250
|
-
return cloneJson(await
|
|
238
|
+
return cloneJson(await m.upgradePlugin(target, cfg, { namespace: 'host' }));
|
|
251
239
|
},
|
|
252
240
|
}));
|
|
253
241
|
ctx.tools.register(defineTool({
|
|
@@ -319,7 +307,10 @@ function renderList(out) {
|
|
|
319
307
|
}
|
|
320
308
|
function renderInstall(out) {
|
|
321
309
|
const extra = out.usedAllowAllBuilds ? '注意:该插件执行了构建脚本(已按策略放行)。' : '';
|
|
322
|
-
|
|
310
|
+
const heals = out.healActions?.length
|
|
311
|
+
? `安装过程含 ${out.healActions.length} 步自愈(${out.healActions.map((h) => h.code).join('、')})。`
|
|
312
|
+
: '';
|
|
313
|
+
return `✅ ${out.pkg} 已安装(${out.spec})。${extra}${heals}需要重启 DSH Web 生效——告知用户并询问是否 dshm_restart。不要打印安装命令。`;
|
|
323
314
|
}
|
|
324
315
|
function renderUninstall(out) {
|
|
325
316
|
const parts = [`✅ ${out.pkg} 已卸载。`];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-m",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"description": "DSH Marketplace — 个人自用的 DeepSeek Harness 插件市场:收录、安装、卸载、升级 DSH 插件",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"build": "node scripts/build.mjs",
|
|
46
46
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
47
47
|
"test": "node --test tests/*.test.mjs",
|
|
48
|
+
"pretest": "npm run build",
|
|
48
49
|
"prepare": "npm run build"
|
|
49
50
|
},
|
|
50
51
|
"dsh": {
|
package/registry.json
CHANGED
|
@@ -67,6 +67,39 @@
|
|
|
67
67
|
"github": "liustack/modsearch",
|
|
68
68
|
"homepage": "https://github.com/liustack/modsearch"
|
|
69
69
|
},
|
|
70
|
+
{
|
|
71
|
+
"id": "dsh-docs-panel",
|
|
72
|
+
"name": "DSH Docs Panel",
|
|
73
|
+
"description": "DSH 侧边栏里的「全局文档」:全局 Markdown 笔记,任何工作区随时可读,支持大纲跳转与一键转编辑器。(需先安装 dsh-better-sidebar ≥0.4.0)",
|
|
74
|
+
"category": "ui",
|
|
75
|
+
"tags": ["文档", "Markdown", "侧边栏", "需 better-sidebar"],
|
|
76
|
+
"source": "npm",
|
|
77
|
+
"npm": "dsh-docs-panel",
|
|
78
|
+
"github": "mlosun/dsh-docs-panel",
|
|
79
|
+
"homepage": "https://github.com/mlosun/dsh-docs-panel"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "dsh-server-deck",
|
|
83
|
+
"name": "DSH Server Deck",
|
|
84
|
+
"description": "服务器卡片仪表盘:实时状态/CPU/内存/磁盘 + 趋势记录与可视化(1h/24h/7d/30d),点卡片进入 xterm 交互终端。可选集成 dsh-better-sidebar:装后注册为侧边栏「服务器」页签,装载顺序无关。",
|
|
85
|
+
"category": "tools",
|
|
86
|
+
"tags": ["服务器", "监控", "终端", "推荐 better-sidebar"],
|
|
87
|
+
"source": "npm",
|
|
88
|
+
"npm": "dsh-server-deck",
|
|
89
|
+
"github": "meyaomiao/dsh-server-deck",
|
|
90
|
+
"homepage": "https://github.com/meyaomiao/dsh-server-deck"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "dsh-flowglass",
|
|
94
|
+
"name": "DSH Flowglass",
|
|
95
|
+
"description": "流镜:实时会话流程图插件,把当前会话画成三列泳道,展示工具调用、并行分组与子代理分支,支持逐层钻取。可选集成 dsh-better-sidebar:装后注册为按会话隔离的侧边栏 Tab。",
|
|
96
|
+
"category": "ui",
|
|
97
|
+
"tags": ["可视化", "流程图", "会话", "推荐 better-sidebar"],
|
|
98
|
+
"source": "npm",
|
|
99
|
+
"npm": "dsh-flowglass",
|
|
100
|
+
"github": "Iwctwbh/dsh-flowglass",
|
|
101
|
+
"homepage": "https://github.com/Iwctwbh/dsh-flowglass"
|
|
102
|
+
},
|
|
70
103
|
{
|
|
71
104
|
"id": "dsh-auth",
|
|
72
105
|
"name": "DSH Auth",
|