dsh-plugin-discovery 1.2.0 → 1.2.4
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 +103 -96
- package/client.js +496 -21
- package/data/recommended.json +1206 -1206
- package/index.js +281 -14
- package/package.json +74 -74
package/index.js
CHANGED
|
@@ -389,6 +389,171 @@ async function searchNpm(query, limit) {
|
|
|
389
389
|
});
|
|
390
390
|
}
|
|
391
391
|
|
|
392
|
+
/** 在线搜索时把精选目录命中置顶,避免同名冷门包(如 @dsh-ssh/dsh-ssh)盖过已验证的 @linxin666/dsh-ssh。 */
|
|
393
|
+
function catalogHitsForQuery(catalog, query, limit) {
|
|
394
|
+
const rows = filterCatalogPlugins(catalog, {
|
|
395
|
+
category: "",
|
|
396
|
+
query,
|
|
397
|
+
personalize: false,
|
|
398
|
+
installedNames: [],
|
|
399
|
+
});
|
|
400
|
+
return rows.slice(0, Math.max(0, limit)).map((row) => ({
|
|
401
|
+
...mapCatalogPlugin(row),
|
|
402
|
+
reason: "catalog",
|
|
403
|
+
}));
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function suggestCatalogAlternatives(catalog, failedSpec, limit = 3) {
|
|
407
|
+
const failed = String(failedSpec || "").trim().toLowerCase();
|
|
408
|
+
if (!failed) return [];
|
|
409
|
+
const tokens = failed
|
|
410
|
+
.replace(/^@/, "")
|
|
411
|
+
.split(/[/@._-]+/)
|
|
412
|
+
.map((part) => part.trim().toLowerCase())
|
|
413
|
+
.filter((part) => part.length >= 3 && part !== "dsh" && part !== "plugin");
|
|
414
|
+
const uniq = [];
|
|
415
|
+
const seen = new Set([failed]);
|
|
416
|
+
for (const token of tokens.length ? tokens : [failed]) {
|
|
417
|
+
for (const row of catalogHitsForQuery(catalog, token, 8)) {
|
|
418
|
+
const spec = String(row.spec || "").trim();
|
|
419
|
+
if (!spec || seen.has(spec.toLowerCase())) continue;
|
|
420
|
+
seen.add(spec.toLowerCase());
|
|
421
|
+
uniq.push(spec);
|
|
422
|
+
if (uniq.length >= limit) return uniq;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return uniq;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/** ManagementError 没有 message 字段,只有 code / diagnostic;再拼上 packageResult 输出尾部。 */
|
|
429
|
+
function formatChangeFailure(result, fallbackApplication = "failed") {
|
|
430
|
+
const parts = [];
|
|
431
|
+
const err = result?.error;
|
|
432
|
+
if (err && typeof err === "object") {
|
|
433
|
+
if (err.diagnostic) parts.push(String(err.diagnostic).trim());
|
|
434
|
+
if (err.code) parts.push(`错误码:${err.code}`);
|
|
435
|
+
if (Array.isArray(err.incompatible) && err.incompatible.length) {
|
|
436
|
+
const names = err.incompatible
|
|
437
|
+
.map((row) => `${row?.name || "?"}@${row?.version || "?"}`)
|
|
438
|
+
.filter(Boolean);
|
|
439
|
+
if (names.length) parts.push(`不兼容:${names.join("、")}`);
|
|
440
|
+
}
|
|
441
|
+
} else if (typeof err === "string" && err.trim()) {
|
|
442
|
+
parts.push(err.trim());
|
|
443
|
+
} else if (err?.message) {
|
|
444
|
+
parts.push(String(err.message).trim());
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
const pkg = result?.packageResult;
|
|
448
|
+
if (pkg && typeof pkg === "object") {
|
|
449
|
+
if (pkg.kind) parts.push(`失败类型:${pkg.kind}`);
|
|
450
|
+
if (pkg.timedOut) parts.push("安装超时(长时间无输出)");
|
|
451
|
+
if (typeof pkg.exitCode === "number") parts.push(`退出码:${pkg.exitCode}`);
|
|
452
|
+
const output = String(pkg.output || "").trim();
|
|
453
|
+
if (output) {
|
|
454
|
+
const lines = output
|
|
455
|
+
.split(/\r?\n/)
|
|
456
|
+
.map((line) => line.trim())
|
|
457
|
+
.filter(Boolean);
|
|
458
|
+
const tail = lines.slice(-8).join("\n");
|
|
459
|
+
if (tail) parts.push(tail);
|
|
460
|
+
}
|
|
461
|
+
if (pkg.logPath) parts.push(`完整日志:${pkg.logPath}`);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
if (result?.failedAt) parts.push(`失败位置:${result.failedAt}`);
|
|
465
|
+
if (Array.isArray(result?.pendingBuilds) && result.pendingBuilds.length) {
|
|
466
|
+
parts.push(`待批准构建脚本:${result.pendingBuilds.join("、")}`);
|
|
467
|
+
}
|
|
468
|
+
if (Array.isArray(result?.warnings) && result.warnings.length) {
|
|
469
|
+
parts.push(`警告:${result.warnings.slice(0, 3).join(";")}`);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const unique = [];
|
|
473
|
+
const seen = new Set();
|
|
474
|
+
for (const part of parts) {
|
|
475
|
+
const text = String(part || "").trim();
|
|
476
|
+
if (!text || seen.has(text)) continue;
|
|
477
|
+
seen.add(text);
|
|
478
|
+
unique.push(text);
|
|
479
|
+
}
|
|
480
|
+
if (unique.length) return unique.join("\n");
|
|
481
|
+
const application = result?.application || fallbackApplication;
|
|
482
|
+
return `安装失败(${application})。插件管理器未返回 diagnostic / 安装日志。`;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
function extractIncompatibility(result) {
|
|
486
|
+
const code = result?.error?.code || null;
|
|
487
|
+
const incompatible = Array.isArray(result?.error?.incompatible)
|
|
488
|
+
? result.error.incompatible
|
|
489
|
+
.map((row) => ({
|
|
490
|
+
name: String(row?.name || "").trim(),
|
|
491
|
+
version: String(row?.version || "").trim(),
|
|
492
|
+
runtimeVersion: String(row?.runtimeVersion || "").trim(),
|
|
493
|
+
peers: row?.peers && typeof row.peers === "object" ? row.peers : {},
|
|
494
|
+
}))
|
|
495
|
+
.filter((row) => row.name && row.version)
|
|
496
|
+
: [];
|
|
497
|
+
return {
|
|
498
|
+
code,
|
|
499
|
+
incompatible,
|
|
500
|
+
needsRiskExemption: code === "incompatible-version" && incompatible.length > 0,
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/** 安装失败时从精选目录推荐相近/同标签插件,优先给出可替代的当前生态包。 */
|
|
505
|
+
function buildFailureRecommendations(catalog, failedSpec, limit = 4) {
|
|
506
|
+
const failed = String(failedSpec || "").trim();
|
|
507
|
+
const seen = new Set([failed.toLowerCase()]);
|
|
508
|
+
const out = [];
|
|
509
|
+
const pushRow = (row, reason) => {
|
|
510
|
+
const spec = String(row?.spec || "").trim();
|
|
511
|
+
if (!spec || seen.has(spec.toLowerCase())) return;
|
|
512
|
+
seen.add(spec.toLowerCase());
|
|
513
|
+
out.push({
|
|
514
|
+
spec,
|
|
515
|
+
title: row.title || spec,
|
|
516
|
+
description: row.description || "",
|
|
517
|
+
source: "catalog",
|
|
518
|
+
installSpec: spec,
|
|
519
|
+
catalogId: row.id || row.spec,
|
|
520
|
+
reason: reason || "similar",
|
|
521
|
+
featured: row.featured === true,
|
|
522
|
+
rank: typeof row.rank === "number" ? row.rank : 0,
|
|
523
|
+
});
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
const plugins = Array.isArray(catalog?.plugins) ? catalog.plugins : [];
|
|
527
|
+
const failedRow = plugins.find((row) => String(row.spec || "").toLowerCase() === failed.toLowerCase());
|
|
528
|
+
if (failedRow) {
|
|
529
|
+
for (const rel of failedRow.related || []) {
|
|
530
|
+
const hit = plugins.find((row) => String(row.spec || "") === rel || String(row.id || "") === rel);
|
|
531
|
+
if (hit) pushRow(hit, "related");
|
|
532
|
+
if (out.length >= limit) return out;
|
|
533
|
+
}
|
|
534
|
+
for (const tag of failedRow.tags || []) {
|
|
535
|
+
for (const row of plugins) {
|
|
536
|
+
if ((row.tags || []).includes(tag)) pushRow(row, "tag");
|
|
537
|
+
if (out.length >= limit) return out;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
for (const cat of failedRow.categories || []) {
|
|
541
|
+
if (cat === "featured") continue;
|
|
542
|
+
for (const row of plugins) {
|
|
543
|
+
if ((row.categories || []).includes(cat)) pushRow(row, "category");
|
|
544
|
+
if (out.length >= limit) return out;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
for (const spec of suggestCatalogAlternatives(catalog, failed, limit)) {
|
|
550
|
+
const hit = plugins.find((row) => String(row.spec || "") === spec) || { spec, title: spec };
|
|
551
|
+
pushRow(hit, "similar");
|
|
552
|
+
if (out.length >= limit) break;
|
|
553
|
+
}
|
|
554
|
+
return out.slice(0, limit);
|
|
555
|
+
}
|
|
556
|
+
|
|
392
557
|
function mapGithubRepos(items) {
|
|
393
558
|
return (Array.isArray(items) ? items : []).map((repo) => ({
|
|
394
559
|
source: "github",
|
|
@@ -936,6 +1101,9 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
936
1101
|
|
|
937
1102
|
const limit = this.config.maxCandidates;
|
|
938
1103
|
const token = opts.githubToken ?? this.config.githubToken;
|
|
1104
|
+
await this.refreshCatalog({ force: false }).catch(() => {});
|
|
1105
|
+
const catalog = this.getCatalog();
|
|
1106
|
+
const catalogHits = catalogHitsForQuery(catalog, q === "dsh" ? "" : q, limit);
|
|
939
1107
|
let raw = [];
|
|
940
1108
|
try {
|
|
941
1109
|
if (source === "npm" || source === "all") {
|
|
@@ -946,23 +1114,27 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
946
1114
|
}
|
|
947
1115
|
} catch (error) {
|
|
948
1116
|
this.ctx.logger.warn("[plugin-discovery] search failed", error);
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1117
|
+
if (!catalogHits.length) {
|
|
1118
|
+
return {
|
|
1119
|
+
ok: false,
|
|
1120
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1121
|
+
results: [],
|
|
1122
|
+
total: 0,
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
// 在线源失败时仍返回精选命中,避免「搜得到却全空」
|
|
1126
|
+
raw = [];
|
|
955
1127
|
}
|
|
956
1128
|
|
|
957
1129
|
const seen = new Set();
|
|
958
1130
|
const deduped = [];
|
|
959
|
-
for (const row of raw) {
|
|
1131
|
+
for (const row of [...catalogHits, ...raw]) {
|
|
960
1132
|
if (!row.spec || seen.has(row.spec)) continue;
|
|
961
1133
|
seen.add(row.spec);
|
|
962
1134
|
deduped.push({
|
|
963
1135
|
...row,
|
|
964
1136
|
installSpec: row.spec,
|
|
965
|
-
bundle: null,
|
|
1137
|
+
bundle: row.bundle ?? null,
|
|
966
1138
|
});
|
|
967
1139
|
if (deduped.length >= limit) break;
|
|
968
1140
|
}
|
|
@@ -1086,6 +1258,17 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
1086
1258
|
message: `「${existing}」已在 DSH 插件列表中,无需重复安装。请到「插件」页查看。`,
|
|
1087
1259
|
};
|
|
1088
1260
|
}
|
|
1261
|
+
const withInstallHint = (message) => {
|
|
1262
|
+
const text = String(message || "").trim() || "安装失败";
|
|
1263
|
+
const looksNetwork =
|
|
1264
|
+
/ERR_PNPM_META_FETCH_FAIL|fetch failed|ECONNRESET|ETIMEDOUT|ENOTFOUND|network|镜像/i.test(text);
|
|
1265
|
+
if (!looksNetwork) return text;
|
|
1266
|
+
const alts = suggestCatalogAlternatives(this.getCatalog(), trimmed);
|
|
1267
|
+
if (!alts.length) {
|
|
1268
|
+
return `${text}。若持续失败,可改用「分类浏览 / 为你推荐」里的精选包,或稍后重试。`;
|
|
1269
|
+
}
|
|
1270
|
+
return `${text}。可改试精选目录中的相近插件:${alts.join("、")}`;
|
|
1271
|
+
};
|
|
1089
1272
|
try {
|
|
1090
1273
|
const result = await this.ctx.pluginManager.installBundle(trimmed, {
|
|
1091
1274
|
requestId,
|
|
@@ -1094,6 +1277,18 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
1094
1277
|
const packageName = result?.bundle || pre.name || trimmed;
|
|
1095
1278
|
const application = result?.application;
|
|
1096
1279
|
const failed = application === "failed" || application === "cancelled";
|
|
1280
|
+
const rawMessage = failed
|
|
1281
|
+
? formatChangeFailure(result, application || "failed")
|
|
1282
|
+
: `「${packageName}」安装完成(${application || "applied"} / ${result?.stage || "install"})`;
|
|
1283
|
+
const incompat = failed ? extractIncompatibility(result) : {};
|
|
1284
|
+
const recommendations =
|
|
1285
|
+
failed && (incompat.needsRiskExemption || incompat.code === "incompatible-version")
|
|
1286
|
+
? buildFailureRecommendations(this.getCatalog(), trimmed, 4)
|
|
1287
|
+
: undefined;
|
|
1288
|
+
let message = failed ? withInstallHint(rawMessage) : rawMessage;
|
|
1289
|
+
if (failed && recommendations && recommendations.length) {
|
|
1290
|
+
message = `${message}\n推荐改试:${recommendations.map((row) => row.spec).join("、")}`;
|
|
1291
|
+
}
|
|
1097
1292
|
return {
|
|
1098
1293
|
ok: !failed,
|
|
1099
1294
|
alreadyInstalled: false,
|
|
@@ -1101,15 +1296,65 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
1101
1296
|
requestId,
|
|
1102
1297
|
application,
|
|
1103
1298
|
stage: result?.stage,
|
|
1104
|
-
message
|
|
1105
|
-
|
|
1106
|
-
|
|
1299
|
+
message,
|
|
1300
|
+
detail: failed ? rawMessage : undefined,
|
|
1301
|
+
logPath: failed ? result?.packageResult?.logPath : undefined,
|
|
1302
|
+
code: incompat.code || undefined,
|
|
1303
|
+
incompatible: incompat.incompatible || undefined,
|
|
1304
|
+
needsRiskExemption: incompat.needsRiskExemption === true,
|
|
1305
|
+
recommendations,
|
|
1306
|
+
installSpec: trimmed,
|
|
1107
1307
|
result,
|
|
1108
1308
|
};
|
|
1109
1309
|
} catch (error) {
|
|
1110
1310
|
return {
|
|
1111
1311
|
ok: false,
|
|
1112
1312
|
requestId,
|
|
1313
|
+
message: withInstallHint(error instanceof Error ? error.message : String(error)),
|
|
1314
|
+
installSpec: trimmed,
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
/** Typert Remote:参数必须是独立形参,不能解构、不能默认值、不能 rest。 */
|
|
1320
|
+
async grantVersionExemption(packageVersion, runtimeVersion, acceptRisk) {
|
|
1321
|
+
if (!this.config.enabled) {
|
|
1322
|
+
return { ok: false, message: "发现插件已停用" };
|
|
1323
|
+
}
|
|
1324
|
+
const pkg = String(packageVersion == null ? "" : packageVersion).trim();
|
|
1325
|
+
const runtime = String(runtimeVersion == null ? "" : runtimeVersion).trim();
|
|
1326
|
+
const accepted = acceptRisk === true;
|
|
1327
|
+
if (!pkg || !runtime) {
|
|
1328
|
+
return { ok: false, message: "缺少 packageVersion 或 runtimeVersion" };
|
|
1329
|
+
}
|
|
1330
|
+
if (!accepted) {
|
|
1331
|
+
return {
|
|
1332
|
+
ok: false,
|
|
1333
|
+
message: "未确认风险。授予版本豁免必须 acceptRisk=true,并先明确告知可能崩溃或数据丢失。",
|
|
1334
|
+
};
|
|
1335
|
+
}
|
|
1336
|
+
if (typeof this.ctx.pluginManager?.setVersionExemption !== "function") {
|
|
1337
|
+
return { ok: false, message: "当前 DSH 不支持 setVersionExemption" };
|
|
1338
|
+
}
|
|
1339
|
+
try {
|
|
1340
|
+
const result = await this.ctx.pluginManager.setVersionExemption(pkg, runtime, true, true);
|
|
1341
|
+
const application = result?.application;
|
|
1342
|
+
const failed = application === "failed" || application === "cancelled";
|
|
1343
|
+
return {
|
|
1344
|
+
ok: !failed,
|
|
1345
|
+
packageVersion: pkg,
|
|
1346
|
+
runtimeVersion: runtime,
|
|
1347
|
+
application,
|
|
1348
|
+
message: failed
|
|
1349
|
+
? formatChangeFailure(result, application || "failed")
|
|
1350
|
+
: `已为 ${pkg} 在 DSH ${runtime} 上授予精确版本豁免,可重新安装。`,
|
|
1351
|
+
result,
|
|
1352
|
+
};
|
|
1353
|
+
} catch (error) {
|
|
1354
|
+
return {
|
|
1355
|
+
ok: false,
|
|
1356
|
+
packageVersion: pkg,
|
|
1357
|
+
runtimeVersion: runtime,
|
|
1113
1358
|
message: error instanceof Error ? error.message : String(error),
|
|
1114
1359
|
};
|
|
1115
1360
|
}
|
|
@@ -1124,6 +1369,22 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
1124
1369
|
return { ok: true, settled: null, pending: true, message: "安装仍在进行或已丢失" };
|
|
1125
1370
|
}
|
|
1126
1371
|
const failed = settled.application === "failed" || settled.application === "cancelled";
|
|
1372
|
+
const failText = failed ? formatChangeFailure(settled, settled.application) : "";
|
|
1373
|
+
const incompat = failed ? extractIncompatibility(settled) : {};
|
|
1374
|
+
const failedSpec =
|
|
1375
|
+
(Array.isArray(incompat.incompatible) && incompat.incompatible[0]
|
|
1376
|
+
? `${incompat.incompatible[0].name}@${incompat.incompatible[0].version}`
|
|
1377
|
+
: "") || settled.bundle || "";
|
|
1378
|
+
const recommendations =
|
|
1379
|
+
failed && (incompat.needsRiskExemption || incompat.code === "incompatible-version")
|
|
1380
|
+
? buildFailureRecommendations(this.getCatalog(), failedSpec, 4)
|
|
1381
|
+
: undefined;
|
|
1382
|
+
let message = failed
|
|
1383
|
+
? failText
|
|
1384
|
+
: `安装完成(${settled.application} / ${settled.stage})`;
|
|
1385
|
+
if (failed && recommendations && recommendations.length) {
|
|
1386
|
+
message = `${message}\n推荐改试:${recommendations.map((row) => row.spec).join("、")}`;
|
|
1387
|
+
}
|
|
1127
1388
|
return {
|
|
1128
1389
|
ok: !failed,
|
|
1129
1390
|
settled,
|
|
@@ -1131,9 +1392,14 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
1131
1392
|
packageName: settled.bundle,
|
|
1132
1393
|
application: settled.application,
|
|
1133
1394
|
stage: settled.stage,
|
|
1134
|
-
message
|
|
1135
|
-
|
|
1136
|
-
|
|
1395
|
+
message,
|
|
1396
|
+
detail: failed ? failText : undefined,
|
|
1397
|
+
logPath: failed ? settled?.packageResult?.logPath : undefined,
|
|
1398
|
+
code: incompat.code || undefined,
|
|
1399
|
+
incompatible: incompat.incompatible || undefined,
|
|
1400
|
+
needsRiskExemption: incompat.needsRiskExemption === true,
|
|
1401
|
+
recommendations,
|
|
1402
|
+
installSpec: failedSpec || undefined,
|
|
1137
1403
|
};
|
|
1138
1404
|
} catch (error) {
|
|
1139
1405
|
return {
|
|
@@ -1260,6 +1526,7 @@ markRemoteMethod(PluginDiscoveryService.prototype, "checkSelfUpdate");
|
|
|
1260
1526
|
markRemoteMethod(PluginDiscoveryService.prototype, "updateSelf");
|
|
1261
1527
|
markRemoteMethod(PluginDiscoveryService.prototype, "resolve");
|
|
1262
1528
|
markRemoteMethod(PluginDiscoveryService.prototype, "installPlugin");
|
|
1529
|
+
markRemoteMethod(PluginDiscoveryService.prototype, "grantVersionExemption");
|
|
1263
1530
|
markRemoteMethod(PluginDiscoveryService.prototype, "listInstalled");
|
|
1264
1531
|
markRemoteMethod(PluginDiscoveryService.prototype, "waitInstall");
|
|
1265
1532
|
|
package/package.json
CHANGED
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dsh-plugin-discovery",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"description": "Discover and install community DSH bundles from the sidebar: newbie essentials, recommendations, categories, self-update, and npm/GitHub search.",
|
|
6
|
-
"author": "hjhcos",
|
|
7
|
-
"license": "MIT",
|
|
8
|
-
"keywords": [
|
|
9
|
-
"dsh",
|
|
10
|
-
"dsh-plugin",
|
|
11
|
-
"deepseek",
|
|
12
|
-
"deepseek-harness",
|
|
13
|
-
"plugin",
|
|
14
|
-
"bundle",
|
|
15
|
-
"discovery",
|
|
16
|
-
"marketplace",
|
|
17
|
-
"recommend"
|
|
18
|
-
],
|
|
19
|
-
"homepage": "https://github.com/hjhcos/dsh-plugin-discovery#readme",
|
|
20
|
-
"bugs": {
|
|
21
|
-
"url": "https://github.com/hjhcos/dsh-plugin-discovery/issues"
|
|
22
|
-
},
|
|
23
|
-
"repository": {
|
|
24
|
-
"type": "git",
|
|
25
|
-
"url": "git+https://github.com/hjhcos/dsh-plugin-discovery.git"
|
|
26
|
-
},
|
|
27
|
-
"icon": "./icon.svg",
|
|
28
|
-
"exports": {
|
|
29
|
-
".": "./index.js",
|
|
30
|
-
"./client": "./client.js",
|
|
31
|
-
"./package.json": "./package.json",
|
|
32
|
-
"./locale/*.json": "./locale/*.json"
|
|
33
|
-
},
|
|
34
|
-
"files": [
|
|
35
|
-
"index.js",
|
|
36
|
-
"mark-remote.js",
|
|
37
|
-
"client.js",
|
|
38
|
-
"cordis.patch.yml",
|
|
39
|
-
"icon.svg",
|
|
40
|
-
"data",
|
|
41
|
-
"locale",
|
|
42
|
-
"skill",
|
|
43
|
-
"docs",
|
|
44
|
-
"LICENSE",
|
|
45
|
-
"README.md"
|
|
46
|
-
],
|
|
47
|
-
"dependencies": {
|
|
48
|
-
"@deepseek-ai/cordis": "~4.0.4",
|
|
49
|
-
"@deepseek-ai/dsh-tools": "0.2.0-rc.2",
|
|
50
|
-
"@deepseek-ai/dsh-typert-protocol": "0.2.0-rc.2",
|
|
51
|
-
"@deepseek-ai/schemastery": "~3.18.4"
|
|
52
|
-
},
|
|
53
|
-
"peerDependencies": {
|
|
54
|
-
"@deepseek-ai/cordis": "~4.0.4",
|
|
55
|
-
"@deepseek-ai/dsh-tools": "0.2.0-rc.2",
|
|
56
|
-
"@deepseek-ai/dsh-typert-protocol": "0.2.0-rc.2",
|
|
57
|
-
"@deepseek-ai/schemastery": "*"
|
|
58
|
-
},
|
|
59
|
-
"dsh": {
|
|
60
|
-
"bundle": {
|
|
61
|
-
"patch": "./cordis.patch.yml"
|
|
62
|
-
},
|
|
63
|
-
"client": {
|
|
64
|
-
"platform": "web",
|
|
65
|
-
"immediately": false,
|
|
66
|
-
"inject": [
|
|
67
|
-
"@deepseek-ai/dsh-client-ui-sidebar",
|
|
68
|
-
"@deepseek-ai/dsh-client-ui-layout",
|
|
69
|
-
"@deepseek-ai/dsh-client-locale",
|
|
70
|
-
"@deepseek-ai/dsh-api-remotes"
|
|
71
|
-
]
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-plugin-discovery",
|
|
3
|
+
"version": "1.2.4",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Discover and install community DSH bundles from the sidebar: newbie essentials, recommendations, categories, self-update, and npm/GitHub search.",
|
|
6
|
+
"author": "hjhcos",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"dsh",
|
|
10
|
+
"dsh-plugin",
|
|
11
|
+
"deepseek",
|
|
12
|
+
"deepseek-harness",
|
|
13
|
+
"plugin",
|
|
14
|
+
"bundle",
|
|
15
|
+
"discovery",
|
|
16
|
+
"marketplace",
|
|
17
|
+
"recommend"
|
|
18
|
+
],
|
|
19
|
+
"homepage": "https://github.com/hjhcos/dsh-plugin-discovery#readme",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/hjhcos/dsh-plugin-discovery/issues"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/hjhcos/dsh-plugin-discovery.git"
|
|
26
|
+
},
|
|
27
|
+
"icon": "./icon.svg",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": "./index.js",
|
|
30
|
+
"./client": "./client.js",
|
|
31
|
+
"./package.json": "./package.json",
|
|
32
|
+
"./locale/*.json": "./locale/*.json"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"index.js",
|
|
36
|
+
"mark-remote.js",
|
|
37
|
+
"client.js",
|
|
38
|
+
"cordis.patch.yml",
|
|
39
|
+
"icon.svg",
|
|
40
|
+
"data",
|
|
41
|
+
"locale",
|
|
42
|
+
"skill",
|
|
43
|
+
"docs",
|
|
44
|
+
"LICENSE",
|
|
45
|
+
"README.md"
|
|
46
|
+
],
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
49
|
+
"@deepseek-ai/dsh-tools": "0.2.0-rc.2",
|
|
50
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.0-rc.2",
|
|
51
|
+
"@deepseek-ai/schemastery": "~3.18.4"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
55
|
+
"@deepseek-ai/dsh-tools": "0.2.0-rc.2",
|
|
56
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.0-rc.2",
|
|
57
|
+
"@deepseek-ai/schemastery": "*"
|
|
58
|
+
},
|
|
59
|
+
"dsh": {
|
|
60
|
+
"bundle": {
|
|
61
|
+
"patch": "./cordis.patch.yml"
|
|
62
|
+
},
|
|
63
|
+
"client": {
|
|
64
|
+
"platform": "web",
|
|
65
|
+
"immediately": false,
|
|
66
|
+
"inject": [
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-sidebar",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-layout",
|
|
69
|
+
"@deepseek-ai/dsh-client-locale",
|
|
70
|
+
"@deepseek-ai/dsh-api-remotes"
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|