dsh-plugin-marketplace 0.2.4 → 0.2.6
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 +4 -0
- package/README.zh.md +4 -0
- package/client.js +9 -6
- package/index.js +22 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
**GitHub**: [Scorp1o117/dsh-plugin-marketplace](https://github.com/Scorp1o117/dsh-plugin-marketplace) · **npm**: [dsh-plugin-marketplace](https://www.npmjs.com/package/dsh-plugin-marketplace)
|
|
6
6
|
|
|
7
|
+
[](https://github.com/Scorp1o117/dsh-enhancement-suite) [](https://www.npmjs.com/package/dsh-enhancement-suite)
|
|
8
|
+
|
|
9
|
+
Part of the [DeepSeek Harness Enhancement Suite](https://github.com/Scorp1o117/dsh-enhancement-suite) — Vision · Soul/Persona · Long-term Memory · Plugin Marketplace.
|
|
10
|
+
|
|
7
11
|
A **plugin marketplace** inside the DeepSeek Harness Web UI: browse
|
|
8
12
|
[github.com/topics/dsh-plugin](https://github.com/topics/dsh-plugin) right
|
|
9
13
|
from the settings page — no terminal needed.
|
package/README.zh.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
**GitHub**: [Scorp1o117/dsh-plugin-marketplace](https://github.com/Scorp1o117/dsh-plugin-marketplace) · **npm**: [dsh-plugin-marketplace](https://www.npmjs.com/package/dsh-plugin-marketplace) · [English](README.md)
|
|
4
4
|
|
|
5
|
+
[](https://github.com/Scorp1o117/dsh-enhancement-suite) [](https://www.npmjs.com/package/dsh-enhancement-suite)
|
|
6
|
+
|
|
7
|
+
属于 [DeepSeek Harness Enhancement Suite](https://github.com/Scorp1o117/dsh-enhancement-suite) —— Vision · Soul/Persona · 长期记忆 · 插件市场。
|
|
8
|
+
|
|
5
9
|
在 DeepSeek Harness **Web UI 里内置的插件市场**:直接在设置页浏览
|
|
6
10
|
[github.com/topics/dsh-plugin](https://github.com/topics/dsh-plugin),无需打开终端。
|
|
7
11
|
|
package/client.js
CHANGED
|
@@ -207,7 +207,10 @@ window.__ModuleLoader__.load({
|
|
|
207
207
|
var st = props.installState; // {status, message, pkg} from the settings scope
|
|
208
208
|
var active = st && st.pkg === installName;
|
|
209
209
|
var status = active ? st.status : "idle";
|
|
210
|
-
var explainState = props.explainState; // {status, text} from the settings scope
|
|
210
|
+
var explainState = props.explainState; // {status, text, repo} from the settings scope
|
|
211
|
+
// The settings field is namespace-global and persists across sessions,
|
|
212
|
+
// so only show it when it belongs to the plugin currently open.
|
|
213
|
+
var explainMine = !!explainState && explainState.repo === p.fullName;
|
|
211
214
|
var [confirming, setConfirming] = react.useState(false);
|
|
212
215
|
var statusNode = null;
|
|
213
216
|
if (status === "running") {
|
|
@@ -264,14 +267,14 @@ window.__ModuleLoader__.load({
|
|
|
264
267
|
h("div", { className: "__mp_translateRow" },
|
|
265
268
|
h("button", { type: "button", className: "__mp_translateBtn",
|
|
266
269
|
style: { marginTop: "8px", padding: "4px 10px", fontSize: "12px", cursor: "pointer", background: "var(--dsw-alias-bg-hover, #21262d)", color: "var(--dsw-alias-label-primary, #e6edf3)", border: "1px solid var(--dsw-alias-border, #30363d)", borderRadius: "6px" },
|
|
267
|
-
disabled:
|
|
270
|
+
disabled: explainMine && explainState.status === "running",
|
|
268
271
|
onClick: function () { props.onExplain(p.fullName, p.desc, props.readme || ""); }
|
|
269
272
|
}, props.t("aiExplain")),
|
|
270
273
|
h("div", { id: "__mp_translateOut", style: { fontSize: "12px", lineHeight: "1.6", color: "var(--dsw-alias-label-secondary, #8b949e)", whiteSpace: "pre-wrap", wordBreak: "break-word", marginTop: "8px", borderTop: "1px solid var(--dsw-alias-border, #21262d)", paddingTop: "8px" } },
|
|
271
|
-
props.explainError ? h("span", { style: { color: "var(--dsw-alias-state-danger-text, #f85149)" } }, props.explainError)
|
|
272
|
-
:
|
|
273
|
-
:
|
|
274
|
-
:
|
|
274
|
+
explainMine && props.explainError ? h("span", { style: { color: "var(--dsw-alias-state-danger-text, #f85149)" } }, props.explainError)
|
|
275
|
+
: explainMine && explainState.status === "running" ? props.t("aiExplaining")
|
|
276
|
+
: explainMine && explainState.status === "error" ? props.t("aiExplainErr").replace("{msg}", explainState.text || "unknown")
|
|
277
|
+
: explainMine && explainState.status === "ok" ? explainState.text
|
|
275
278
|
: ""
|
|
276
279
|
)
|
|
277
280
|
)
|
package/index.js
CHANGED
|
@@ -49,6 +49,8 @@ const Config = z.object({
|
|
|
49
49
|
aiExplainResult: z.object({
|
|
50
50
|
status: z.string().default("idle"), // idle | running | ok | error
|
|
51
51
|
text: z.string().default(""),
|
|
52
|
+
/** repo this result belongs to ("owner/name"); client gates display on it. */
|
|
53
|
+
repo: z.string().default(""),
|
|
52
54
|
ts: z.number().default(0),
|
|
53
55
|
}),
|
|
54
56
|
});
|
|
@@ -135,15 +137,24 @@ function apply(ctx, config) {
|
|
|
135
137
|
* Bundle plugins (already in `dsh.profile.bundles`, or whose installed
|
|
136
138
|
* package declares `dsh.bundle.patch`) are mounted by their own bundle
|
|
137
139
|
* layer — adding a manual row would create a duplicate loader entry and
|
|
138
|
-
* abort boot
|
|
140
|
+
* abort boot. A STALE manual row left by an earlier non-bundle version is
|
|
141
|
+
* removed instead, so reinstalling a bundle plugin never breaks boot.
|
|
139
142
|
*/
|
|
140
143
|
function ensureMounted(pkg, profile) {
|
|
141
144
|
const dshHome = process.env.DSH_HOME || join(os.homedir(), ".dsh");
|
|
142
145
|
const patchPath = join(dshHome, "profiles", profile, "cordis.patch.yml");
|
|
143
146
|
if (!existsSync(patchPath)) return " (patch file not found; mount manually)";
|
|
144
147
|
const bundles = profileManifest(profile)?.dsh?.profile?.bundles ?? [];
|
|
145
|
-
if (bundles.includes(pkg)
|
|
146
|
-
|
|
148
|
+
if (bundles.includes(pkg) || isBundlePackage(pkg, profile)) {
|
|
149
|
+
// Bundle layer auto-mounts; remove any stale manual row (pre-bundle).
|
|
150
|
+
const src = readFileSync(patchPath, "utf8");
|
|
151
|
+
const cleaned = src.replace(new RegExp(`[ \\t]*- id: [^\\n]*\\n[ \\t]*name: ['"]${pkg.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}['"]\\n?`, "g"), "");
|
|
152
|
+
if (cleaned !== src) {
|
|
153
|
+
writeFileSync(patchPath, cleaned, "utf8");
|
|
154
|
+
return " (removed stale manual mount row; bundle layer auto-mounts)";
|
|
155
|
+
}
|
|
156
|
+
return bundles.includes(pkg) ? " (already mounted via dsh.profile.bundles)" : " (bundle plugin: auto-mounted via its own dsh.bundle layer)";
|
|
157
|
+
}
|
|
147
158
|
const id = pkg.replace(/^@[^/]+\//, "").replace(/[^a-z0-9-]/g, "-") || pkg;
|
|
148
159
|
let src = readFileSync(patchPath, "utf8");
|
|
149
160
|
if (src.includes(`name: '${pkg}'`) || src.includes(`name: "${pkg}"`)) return " (already mounted)";
|
|
@@ -218,12 +229,12 @@ function apply(ctx, config) {
|
|
|
218
229
|
}
|
|
219
230
|
|
|
220
231
|
/** Write the AI-explain result report (and clear the consumed request). */
|
|
221
|
-
async function reportExplain(status, text) {
|
|
232
|
+
async function reportExplain(status, text, repo) {
|
|
222
233
|
const settings = ctx.get("settings");
|
|
223
234
|
if (!settings) return;
|
|
224
235
|
const ts = Date.now();
|
|
225
236
|
await settings.update(NS, {
|
|
226
|
-
aiExplainResult: { status, text, ts },
|
|
237
|
+
aiExplainResult: { status, text, repo: repo || "", ts },
|
|
227
238
|
aiExplain: { repo: "", desc: "", readme: "", ts: 0 },
|
|
228
239
|
}).catch((error) => {
|
|
229
240
|
ctx.logger.warn(`[plugin-marketplace] explain state write failed: ${String(error)}`);
|
|
@@ -236,14 +247,16 @@ function apply(ctx, config) {
|
|
|
236
247
|
* settings-backed message channel as the install flow.
|
|
237
248
|
*/
|
|
238
249
|
async function maybeRunExplain() {
|
|
250
|
+
let repo = "";
|
|
239
251
|
try {
|
|
240
252
|
const cfg = current();
|
|
241
253
|
const req = cfg?.aiExplain;
|
|
242
254
|
if (!req || !req.repo || req.ts === lastExplainTs || req.ts === 0) return;
|
|
243
255
|
lastExplainTs = req.ts;
|
|
256
|
+
repo = String(req.repo);
|
|
244
257
|
const llm = ctx.llm;
|
|
245
258
|
if (!llm) {
|
|
246
|
-
await reportExplain("error", "LLM service unavailable; configure a model in Settings → Models.");
|
|
259
|
+
await reportExplain("error", "LLM service unavailable; configure a model in Settings → Models.", repo);
|
|
247
260
|
return;
|
|
248
261
|
}
|
|
249
262
|
// Route through the deployment's default model when one is configured.
|
|
@@ -252,7 +265,6 @@ function apply(ctx, config) {
|
|
|
252
265
|
const defaults = ctx.agentDefaultModel?.currentSelection?.();
|
|
253
266
|
if (defaults?.provider && defaults?.model) route = defaults;
|
|
254
267
|
} catch { /* no default model service; fall back to the adapter default */ }
|
|
255
|
-
const repo = String(req.repo);
|
|
256
268
|
const desc = String(req.desc || "").trim();
|
|
257
269
|
const readme = String(req.readme || "").trim().slice(0, 1500);
|
|
258
270
|
const prompt =
|
|
@@ -260,7 +272,7 @@ function apply(ctx, config) {
|
|
|
260
272
|
(desc ? `简介:${desc}\n` : "") +
|
|
261
273
|
(readme ? `README 摘要:\n${readme}\n` : "") +
|
|
262
274
|
`\n请用简体中文、3~5 句话直接告诉我这个插件大概是干嘛的(核心用途、解决什么问题、适合谁)。不要复述仓库名,不要罗列安装步骤。`;
|
|
263
|
-
await reportExplain("running", "");
|
|
275
|
+
await reportExplain("running", "", repo);
|
|
264
276
|
ctx.logger.info(`[plugin-marketplace] explaining ${repo} (model=${route ? `${route.provider}/${route.model}` : "default"})…`);
|
|
265
277
|
const messages = [createUserMessage({
|
|
266
278
|
content: [{ type: "text", text: prompt }],
|
|
@@ -284,10 +296,10 @@ function apply(ctx, config) {
|
|
|
284
296
|
.join(" ")
|
|
285
297
|
.trim();
|
|
286
298
|
if (!text) throw new Error("model produced no text");
|
|
287
|
-
await reportExplain("ok", text);
|
|
299
|
+
await reportExplain("ok", text, repo);
|
|
288
300
|
} catch (error) {
|
|
289
301
|
ctx.logger.warn(`[plugin-marketplace] explain flow failed: ${String(error)}`);
|
|
290
|
-
await reportExplain("error", String(error instanceof Error ? error.message : error));
|
|
302
|
+
await reportExplain("error", String(error instanceof Error ? error.message : error), repo);
|
|
291
303
|
}
|
|
292
304
|
}
|
|
293
305
|
}
|