dsh-plugin-discovery 1.2.0 → 1.2.5
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 +104 -96
- package/client.js +646 -24
- package/data/recommended.json +1206 -1206
- package/index.js +318 -14
- package/package.json +74 -74
package/index.js
CHANGED
|
@@ -389,6 +389,193 @@ 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
|
+
/** pnpm 11 拦截依赖安装脚本时,失败结果带 pendingBuilds;需用户确认后经 approvedBuilds 重试。 */
|
|
505
|
+
function extractBuildBlock(result) {
|
|
506
|
+
const pendingBuilds = Array.isArray(result?.pendingBuilds)
|
|
507
|
+
? [...new Set(result.pendingBuilds.map((name) => String(name || "").trim()).filter(Boolean))]
|
|
508
|
+
: [];
|
|
509
|
+
const kind = result?.packageResult?.kind || null;
|
|
510
|
+
const code = result?.error?.code || null;
|
|
511
|
+
const blocked =
|
|
512
|
+
kind === "build-blocked" ||
|
|
513
|
+
code === "build-blocked" ||
|
|
514
|
+
/ERR_PNPM_IGNORED_BUILDS|Ignored build scripts/i.test(String(result?.packageResult?.output || ""));
|
|
515
|
+
return {
|
|
516
|
+
pendingBuilds,
|
|
517
|
+
needsBuildApproval: blocked && pendingBuilds.length > 0,
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
function normalizeApprovedBuilds(value) {
|
|
522
|
+
if (!Array.isArray(value)) return [];
|
|
523
|
+
return [...new Set(value.map((name) => String(name || "").trim()).filter(Boolean))];
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/** 安装失败时从精选目录推荐相近/同标签插件,优先给出可替代的当前生态包。 */
|
|
527
|
+
function buildFailureRecommendations(catalog, failedSpec, limit = 4) {
|
|
528
|
+
const failed = String(failedSpec || "").trim();
|
|
529
|
+
const seen = new Set([failed.toLowerCase()]);
|
|
530
|
+
const out = [];
|
|
531
|
+
const pushRow = (row, reason) => {
|
|
532
|
+
const spec = String(row?.spec || "").trim();
|
|
533
|
+
if (!spec || seen.has(spec.toLowerCase())) return;
|
|
534
|
+
seen.add(spec.toLowerCase());
|
|
535
|
+
out.push({
|
|
536
|
+
spec,
|
|
537
|
+
title: row.title || spec,
|
|
538
|
+
description: row.description || "",
|
|
539
|
+
source: "catalog",
|
|
540
|
+
installSpec: spec,
|
|
541
|
+
catalogId: row.id || row.spec,
|
|
542
|
+
reason: reason || "similar",
|
|
543
|
+
featured: row.featured === true,
|
|
544
|
+
rank: typeof row.rank === "number" ? row.rank : 0,
|
|
545
|
+
});
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
const plugins = Array.isArray(catalog?.plugins) ? catalog.plugins : [];
|
|
549
|
+
const failedRow = plugins.find((row) => String(row.spec || "").toLowerCase() === failed.toLowerCase());
|
|
550
|
+
if (failedRow) {
|
|
551
|
+
for (const rel of failedRow.related || []) {
|
|
552
|
+
const hit = plugins.find((row) => String(row.spec || "") === rel || String(row.id || "") === rel);
|
|
553
|
+
if (hit) pushRow(hit, "related");
|
|
554
|
+
if (out.length >= limit) return out;
|
|
555
|
+
}
|
|
556
|
+
for (const tag of failedRow.tags || []) {
|
|
557
|
+
for (const row of plugins) {
|
|
558
|
+
if ((row.tags || []).includes(tag)) pushRow(row, "tag");
|
|
559
|
+
if (out.length >= limit) return out;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
for (const cat of failedRow.categories || []) {
|
|
563
|
+
if (cat === "featured") continue;
|
|
564
|
+
for (const row of plugins) {
|
|
565
|
+
if ((row.categories || []).includes(cat)) pushRow(row, "category");
|
|
566
|
+
if (out.length >= limit) return out;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
for (const spec of suggestCatalogAlternatives(catalog, failed, limit)) {
|
|
572
|
+
const hit = plugins.find((row) => String(row.spec || "") === spec) || { spec, title: spec };
|
|
573
|
+
pushRow(hit, "similar");
|
|
574
|
+
if (out.length >= limit) break;
|
|
575
|
+
}
|
|
576
|
+
return out.slice(0, limit);
|
|
577
|
+
}
|
|
578
|
+
|
|
392
579
|
function mapGithubRepos(items) {
|
|
393
580
|
return (Array.isArray(items) ? items : []).map((repo) => ({
|
|
394
581
|
source: "github",
|
|
@@ -936,6 +1123,9 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
936
1123
|
|
|
937
1124
|
const limit = this.config.maxCandidates;
|
|
938
1125
|
const token = opts.githubToken ?? this.config.githubToken;
|
|
1126
|
+
await this.refreshCatalog({ force: false }).catch(() => {});
|
|
1127
|
+
const catalog = this.getCatalog();
|
|
1128
|
+
const catalogHits = catalogHitsForQuery(catalog, q === "dsh" ? "" : q, limit);
|
|
939
1129
|
let raw = [];
|
|
940
1130
|
try {
|
|
941
1131
|
if (source === "npm" || source === "all") {
|
|
@@ -946,23 +1136,27 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
946
1136
|
}
|
|
947
1137
|
} catch (error) {
|
|
948
1138
|
this.ctx.logger.warn("[plugin-discovery] search failed", error);
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1139
|
+
if (!catalogHits.length) {
|
|
1140
|
+
return {
|
|
1141
|
+
ok: false,
|
|
1142
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1143
|
+
results: [],
|
|
1144
|
+
total: 0,
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
// 在线源失败时仍返回精选命中,避免「搜得到却全空」
|
|
1148
|
+
raw = [];
|
|
955
1149
|
}
|
|
956
1150
|
|
|
957
1151
|
const seen = new Set();
|
|
958
1152
|
const deduped = [];
|
|
959
|
-
for (const row of raw) {
|
|
1153
|
+
for (const row of [...catalogHits, ...raw]) {
|
|
960
1154
|
if (!row.spec || seen.has(row.spec)) continue;
|
|
961
1155
|
seen.add(row.spec);
|
|
962
1156
|
deduped.push({
|
|
963
1157
|
...row,
|
|
964
1158
|
installSpec: row.spec,
|
|
965
|
-
bundle: null,
|
|
1159
|
+
bundle: row.bundle ?? null,
|
|
966
1160
|
});
|
|
967
1161
|
if (deduped.length >= limit) break;
|
|
968
1162
|
}
|
|
@@ -1086,14 +1280,40 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
1086
1280
|
message: `「${existing}」已在 DSH 插件列表中,无需重复安装。请到「插件」页查看。`,
|
|
1087
1281
|
};
|
|
1088
1282
|
}
|
|
1283
|
+
const withInstallHint = (message) => {
|
|
1284
|
+
const text = String(message || "").trim() || "安装失败";
|
|
1285
|
+
const looksNetwork =
|
|
1286
|
+
/ERR_PNPM_META_FETCH_FAIL|fetch failed|ECONNRESET|ETIMEDOUT|ENOTFOUND|network|镜像/i.test(text);
|
|
1287
|
+
if (!looksNetwork) return text;
|
|
1288
|
+
const alts = suggestCatalogAlternatives(this.getCatalog(), trimmed);
|
|
1289
|
+
if (!alts.length) {
|
|
1290
|
+
return `${text}。若持续失败,可改用「分类浏览 / 为你推荐」里的精选包,或稍后重试。`;
|
|
1291
|
+
}
|
|
1292
|
+
return `${text}。可改试精选目录中的相近插件:${alts.join("、")}`;
|
|
1293
|
+
};
|
|
1294
|
+
const approvedBuilds = normalizeApprovedBuilds(opts.approvedBuilds);
|
|
1089
1295
|
try {
|
|
1090
1296
|
const result = await this.ctx.pluginManager.installBundle(trimmed, {
|
|
1091
1297
|
requestId,
|
|
1092
1298
|
enabled: true,
|
|
1299
|
+
...(approvedBuilds.length ? { approvedBuilds } : {}),
|
|
1093
1300
|
});
|
|
1094
1301
|
const packageName = result?.bundle || pre.name || trimmed;
|
|
1095
1302
|
const application = result?.application;
|
|
1096
1303
|
const failed = application === "failed" || application === "cancelled";
|
|
1304
|
+
const rawMessage = failed
|
|
1305
|
+
? formatChangeFailure(result, application || "failed")
|
|
1306
|
+
: `「${packageName}」安装完成(${application || "applied"} / ${result?.stage || "install"})`;
|
|
1307
|
+
const incompat = failed ? extractIncompatibility(result) : {};
|
|
1308
|
+
const buildBlock = failed ? extractBuildBlock(result) : {};
|
|
1309
|
+
const recommendations =
|
|
1310
|
+
failed && (incompat.needsRiskExemption || incompat.code === "incompatible-version")
|
|
1311
|
+
? buildFailureRecommendations(this.getCatalog(), trimmed, 4)
|
|
1312
|
+
: undefined;
|
|
1313
|
+
let message = failed ? withInstallHint(rawMessage) : rawMessage;
|
|
1314
|
+
if (failed && recommendations && recommendations.length) {
|
|
1315
|
+
message = `${message}\n推荐改试:${recommendations.map((row) => row.spec).join("、")}`;
|
|
1316
|
+
}
|
|
1097
1317
|
return {
|
|
1098
1318
|
ok: !failed,
|
|
1099
1319
|
alreadyInstalled: false,
|
|
@@ -1101,15 +1321,71 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
1101
1321
|
requestId,
|
|
1102
1322
|
application,
|
|
1103
1323
|
stage: result?.stage,
|
|
1104
|
-
message
|
|
1105
|
-
|
|
1106
|
-
|
|
1324
|
+
message,
|
|
1325
|
+
detail: failed ? rawMessage : undefined,
|
|
1326
|
+
logPath: failed ? result?.packageResult?.logPath : undefined,
|
|
1327
|
+
code:
|
|
1328
|
+
incompat.code ||
|
|
1329
|
+
(buildBlock.needsBuildApproval ? "build-blocked" : undefined) ||
|
|
1330
|
+
undefined,
|
|
1331
|
+
incompatible: incompat.incompatible || undefined,
|
|
1332
|
+
needsRiskExemption: incompat.needsRiskExemption === true,
|
|
1333
|
+
pendingBuilds: buildBlock.pendingBuilds || undefined,
|
|
1334
|
+
needsBuildApproval: buildBlock.needsBuildApproval === true,
|
|
1335
|
+
approvedBuilds: approvedBuilds.length ? approvedBuilds : result?.approvedBuilds,
|
|
1336
|
+
recommendations,
|
|
1337
|
+
installSpec: trimmed,
|
|
1107
1338
|
result,
|
|
1108
1339
|
};
|
|
1109
1340
|
} catch (error) {
|
|
1110
1341
|
return {
|
|
1111
1342
|
ok: false,
|
|
1112
1343
|
requestId,
|
|
1344
|
+
message: withInstallHint(error instanceof Error ? error.message : String(error)),
|
|
1345
|
+
installSpec: trimmed,
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
/** Typert Remote:参数必须是独立形参,不能解构、不能默认值、不能 rest。 */
|
|
1351
|
+
async grantVersionExemption(packageVersion, runtimeVersion, acceptRisk) {
|
|
1352
|
+
if (!this.config.enabled) {
|
|
1353
|
+
return { ok: false, message: "发现插件已停用" };
|
|
1354
|
+
}
|
|
1355
|
+
const pkg = String(packageVersion == null ? "" : packageVersion).trim();
|
|
1356
|
+
const runtime = String(runtimeVersion == null ? "" : runtimeVersion).trim();
|
|
1357
|
+
const accepted = acceptRisk === true;
|
|
1358
|
+
if (!pkg || !runtime) {
|
|
1359
|
+
return { ok: false, message: "缺少 packageVersion 或 runtimeVersion" };
|
|
1360
|
+
}
|
|
1361
|
+
if (!accepted) {
|
|
1362
|
+
return {
|
|
1363
|
+
ok: false,
|
|
1364
|
+
message: "未确认风险。授予版本豁免必须 acceptRisk=true,并先明确告知可能崩溃或数据丢失。",
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
if (typeof this.ctx.pluginManager?.setVersionExemption !== "function") {
|
|
1368
|
+
return { ok: false, message: "当前 DSH 不支持 setVersionExemption" };
|
|
1369
|
+
}
|
|
1370
|
+
try {
|
|
1371
|
+
const result = await this.ctx.pluginManager.setVersionExemption(pkg, runtime, true, true);
|
|
1372
|
+
const application = result?.application;
|
|
1373
|
+
const failed = application === "failed" || application === "cancelled";
|
|
1374
|
+
return {
|
|
1375
|
+
ok: !failed,
|
|
1376
|
+
packageVersion: pkg,
|
|
1377
|
+
runtimeVersion: runtime,
|
|
1378
|
+
application,
|
|
1379
|
+
message: failed
|
|
1380
|
+
? formatChangeFailure(result, application || "failed")
|
|
1381
|
+
: `已为 ${pkg} 在 DSH ${runtime} 上授予精确版本豁免,可重新安装。`,
|
|
1382
|
+
result,
|
|
1383
|
+
};
|
|
1384
|
+
} catch (error) {
|
|
1385
|
+
return {
|
|
1386
|
+
ok: false,
|
|
1387
|
+
packageVersion: pkg,
|
|
1388
|
+
runtimeVersion: runtime,
|
|
1113
1389
|
message: error instanceof Error ? error.message : String(error),
|
|
1114
1390
|
};
|
|
1115
1391
|
}
|
|
@@ -1124,6 +1400,23 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
1124
1400
|
return { ok: true, settled: null, pending: true, message: "安装仍在进行或已丢失" };
|
|
1125
1401
|
}
|
|
1126
1402
|
const failed = settled.application === "failed" || settled.application === "cancelled";
|
|
1403
|
+
const failText = failed ? formatChangeFailure(settled, settled.application) : "";
|
|
1404
|
+
const incompat = failed ? extractIncompatibility(settled) : {};
|
|
1405
|
+
const buildBlock = failed ? extractBuildBlock(settled) : {};
|
|
1406
|
+
const failedSpec =
|
|
1407
|
+
(Array.isArray(incompat.incompatible) && incompat.incompatible[0]
|
|
1408
|
+
? `${incompat.incompatible[0].name}@${incompat.incompatible[0].version}`
|
|
1409
|
+
: "") || settled.bundle || "";
|
|
1410
|
+
const recommendations =
|
|
1411
|
+
failed && (incompat.needsRiskExemption || incompat.code === "incompatible-version")
|
|
1412
|
+
? buildFailureRecommendations(this.getCatalog(), failedSpec, 4)
|
|
1413
|
+
: undefined;
|
|
1414
|
+
let message = failed
|
|
1415
|
+
? failText
|
|
1416
|
+
: `安装完成(${settled.application} / ${settled.stage})`;
|
|
1417
|
+
if (failed && recommendations && recommendations.length) {
|
|
1418
|
+
message = `${message}\n推荐改试:${recommendations.map((row) => row.spec).join("、")}`;
|
|
1419
|
+
}
|
|
1127
1420
|
return {
|
|
1128
1421
|
ok: !failed,
|
|
1129
1422
|
settled,
|
|
@@ -1131,9 +1424,19 @@ class PluginDiscoveryService extends TypertRemoteService {
|
|
|
1131
1424
|
packageName: settled.bundle,
|
|
1132
1425
|
application: settled.application,
|
|
1133
1426
|
stage: settled.stage,
|
|
1134
|
-
message
|
|
1135
|
-
|
|
1136
|
-
|
|
1427
|
+
message,
|
|
1428
|
+
detail: failed ? failText : undefined,
|
|
1429
|
+
logPath: failed ? settled?.packageResult?.logPath : undefined,
|
|
1430
|
+
code:
|
|
1431
|
+
incompat.code ||
|
|
1432
|
+
(buildBlock.needsBuildApproval ? "build-blocked" : undefined) ||
|
|
1433
|
+
undefined,
|
|
1434
|
+
incompatible: incompat.incompatible || undefined,
|
|
1435
|
+
needsRiskExemption: incompat.needsRiskExemption === true,
|
|
1436
|
+
pendingBuilds: buildBlock.pendingBuilds || undefined,
|
|
1437
|
+
needsBuildApproval: buildBlock.needsBuildApproval === true,
|
|
1438
|
+
recommendations,
|
|
1439
|
+
installSpec: failedSpec || undefined,
|
|
1137
1440
|
};
|
|
1138
1441
|
} catch (error) {
|
|
1139
1442
|
return {
|
|
@@ -1260,6 +1563,7 @@ markRemoteMethod(PluginDiscoveryService.prototype, "checkSelfUpdate");
|
|
|
1260
1563
|
markRemoteMethod(PluginDiscoveryService.prototype, "updateSelf");
|
|
1261
1564
|
markRemoteMethod(PluginDiscoveryService.prototype, "resolve");
|
|
1262
1565
|
markRemoteMethod(PluginDiscoveryService.prototype, "installPlugin");
|
|
1566
|
+
markRemoteMethod(PluginDiscoveryService.prototype, "grantVersionExemption");
|
|
1263
1567
|
markRemoteMethod(PluginDiscoveryService.prototype, "listInstalled");
|
|
1264
1568
|
markRemoteMethod(PluginDiscoveryService.prototype, "waitInstall");
|
|
1265
1569
|
|
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.5",
|
|
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
|
+
}
|