@noob-stupid/dsh-plugin-console 0.3.26 → 0.3.28
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 +61 -351
- package/README.zh.md +57 -321
- package/lib/client.js +162 -8
- package/lib/index.js +348 -36
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -104,6 +104,21 @@ window.__ModuleLoader__.load({
|
|
|
104
104
|
pendingCompatTag: "待适配",
|
|
105
105
|
pendingCompatHint: "框架升级后被强制禁用:先点「检测更新」,如有新版按钮会变为「更新并适配」,点击后更新完成自动校验通过即解锁启用",
|
|
106
106
|
updateAndAdapt: "更新并适配",
|
|
107
|
+
familyTag: "全家桶",
|
|
108
|
+
familySubs: "子包",
|
|
109
|
+
familyUnlockAll: "一键启用已适配",
|
|
110
|
+
familyUnlockAllTip: "对全家桶内所有源码扫描通过(已适配)的子包批量解锁启用;未通过的保持禁用",
|
|
111
|
+
familyUnlockAllConfirm: "将对全家桶内所有已适配(源码扫描通过)的子包一键解锁启用?未通过的将保持禁用。",
|
|
112
|
+
familyUnlockAllDone: "已批量适配解锁",
|
|
113
|
+
familyExpand: "展开",
|
|
114
|
+
familyCollapse: "收起",
|
|
115
|
+
familyUpdate: "全家桶版本检测",
|
|
116
|
+
familyCheckUpdate: "批量检测更新",
|
|
117
|
+
adaptUnlockBtn: "已适配,立即解锁",
|
|
118
|
+
adaptUnlockHint: "已安装版本经源码扫描确认适配当前框架:立即移除禁用块并解锁启用",
|
|
119
|
+
adaptUnlockDone: "已适配解锁:刷新后该行可正常启用",
|
|
120
|
+
migrateTip: "项目已迁移(适配当前框架)",
|
|
121
|
+
migrateBtn: "迁移并适配",
|
|
107
122
|
aiEmpowerFrameworkCheck: "框架适配检测",
|
|
108
123
|
userForcedTag: "补丁强制启用",
|
|
109
124
|
protectedTag: "受保护",
|
|
@@ -404,6 +419,21 @@ window.__ModuleLoader__.load({
|
|
|
404
419
|
pendingCompatTag: "Pending adapt",
|
|
405
420
|
pendingCompatHint: "Force-disabled after framework upgrade: click Check update first; if a newer version exists the button becomes Update & adapt - click it and it unlocks automatically after the compat check",
|
|
406
421
|
updateAndAdapt: "Update & adapt",
|
|
422
|
+
familyTag: "Family bundle",
|
|
423
|
+
familySubs: "sub packages",
|
|
424
|
+
familyUnlockAll: "Unlock all adapted",
|
|
425
|
+
familyUnlockAllTip: "Batch-unlock every sub package in this family whose source scan passed; failed ones stay disabled",
|
|
426
|
+
familyUnlockAllConfirm: "Unlock all adapted (source-scan passed) sub packages in this family? Failed ones stay disabled.",
|
|
427
|
+
familyUnlockAllDone: "Family batch unlock done",
|
|
428
|
+
familyExpand: "Expand",
|
|
429
|
+
familyCollapse: "Collapse",
|
|
430
|
+
familyUpdate: "Family version check",
|
|
431
|
+
familyCheckUpdate: "Check all",
|
|
432
|
+
adaptUnlockBtn: "Adapted - unlock now",
|
|
433
|
+
adaptUnlockHint: "Installed version passed the source scan for the current framework: unlock immediately",
|
|
434
|
+
adaptUnlockDone: "Unlocked: refresh and the row is enabled",
|
|
435
|
+
migrateTip: "Project migrated (adapted to the current framework)",
|
|
436
|
+
migrateBtn: "Migrate & adapt",
|
|
407
437
|
aiEmpowerFrameworkCheck: "Framework compat check",
|
|
408
438
|
userForcedTag: "Forced on by patch",
|
|
409
439
|
protectedTag: "Protected",
|
|
@@ -971,10 +1001,12 @@ window.__ModuleLoader__.load({
|
|
|
971
1001
|
function PluginConsoleTab({ t }) {
|
|
972
1002
|
const [state, setState] = react.useState({ status: "loading" });
|
|
973
1003
|
const [busy, setBusy] = react.useState(null);
|
|
1004
|
+
const [adaptUnlocking, setAdaptUnlocking] = react.useState(null);
|
|
974
1005
|
const [message, setMessage] = react.useState(null);
|
|
975
1006
|
const [reloadHint, setReloadHint] = react.useState(false);
|
|
976
1007
|
const [restartHint, setRestartHint] = react.useState(false);
|
|
977
1008
|
const [jobs, setJobs] = react.useState({});
|
|
1009
|
+
const [familyCollapsed, setFamilyCollapsed] = react.useState({});
|
|
978
1010
|
const [query, setQuery] = react.useState(() => {
|
|
979
1011
|
try { return localStorage.getItem("pc-market-query") ?? ""; } catch { return ""; }
|
|
980
1012
|
});
|
|
@@ -2239,13 +2271,31 @@ window.__ModuleLoader__.load({
|
|
|
2239
2271
|
: ((searchSourcesList !== null ? searchSourcesList.find((s) => s.id === source)?.name : undefined) ?? source);
|
|
2240
2272
|
const extraIds = new Set((state.status === "ready" ? state.data.patch?.inserts ?? [] : []));
|
|
2241
2273
|
const extraCount = state.status === "ready" ? state.data.entries.filter((entry) => entry.extra === true || extraIds.has(entry.rowId)).length : 0;
|
|
2242
|
-
const
|
|
2274
|
+
const pkgRootOf = (m) => { const mm = String(m ?? ""); const x = mm.match(/^(@[^/]+\/[^/]+)(?:\/.*)?$/u); return x ? x[1] : mm; };
|
|
2275
|
+
const filteredEntries = state.status === "ready"
|
|
2243
2276
|
? state.data.entries.filter((entry) => {
|
|
2244
2277
|
if (extraOnly && !(entry.extra === true || extraIds.has(entry.rowId))) return false;
|
|
2245
2278
|
if (installedQueryNorm === "") return true;
|
|
2246
2279
|
return [entry.moduleName, entry.entryId, entry.rowId]
|
|
2247
2280
|
.some((value) => String(value ?? "").toLowerCase().includes(installedQueryNorm));
|
|
2248
|
-
})
|
|
2281
|
+
})
|
|
2282
|
+
: [];
|
|
2283
|
+
// 聚合包分组:仅「同根包 + 子路径导出」(web-all 0.3.14 式,moduleName=pkg/sub)→ 全家桶组;
|
|
2284
|
+
// 经典多子包聚合(每子包独立名)不归组。组头与子包卡片一律置于列表【最底部】。
|
|
2285
|
+
const famRootOf = (entry) => {
|
|
2286
|
+
const m = String(entry.moduleName ?? "");
|
|
2287
|
+
if (m.startsWith("@deepseek-ai/")) return null;
|
|
2288
|
+
return pkgRootOf(m);
|
|
2289
|
+
};
|
|
2290
|
+
const familyCounts = new Map();
|
|
2291
|
+
for (const entry of (state.status === "ready" ? state.data.entries : [])) {
|
|
2292
|
+
const root = famRootOf(entry);
|
|
2293
|
+
if (root === null) continue;
|
|
2294
|
+
familyCounts.set(root, (familyCounts.get(root) ?? 0) + 1);
|
|
2295
|
+
}
|
|
2296
|
+
const familyCards = filteredEntries.map((entry) => {
|
|
2297
|
+
const familyRoot = String(entry.moduleName ?? "").startsWith("@deepseek-ai/") ? null : pkgRootOf(entry.moduleName);
|
|
2298
|
+
void familyRoot;
|
|
2249
2299
|
const open = details !== null && details.entryId === entry.entryId;
|
|
2250
2300
|
let detailPanel = null;
|
|
2251
2301
|
if (open) {
|
|
@@ -2258,10 +2308,13 @@ window.__ModuleLoader__.load({
|
|
|
2258
2308
|
} else {
|
|
2259
2309
|
const meta = details.data.meta;
|
|
2260
2310
|
const readme = details.data.readme;
|
|
2311
|
+
const compatInfo = state.status === "ready" && state.data.compatPending
|
|
2312
|
+
? (state.data.compatPending.pending ?? []).find((p) => p.rowId === entry.rowId) ?? null
|
|
2313
|
+
: null;
|
|
2261
2314
|
detailPanel = el("div", { className: styles.detail },
|
|
2262
2315
|
meta !== null ? el("p", { className: styles.desc }, meta.description ?? t("noDetail")) : null,
|
|
2263
2316
|
entry.pendingCompat === true
|
|
2264
|
-
? el("p", { className: styles.status, "data-pending": "true" }, t("pendingCompatHint"))
|
|
2317
|
+
? el("p", { className: styles.status, "data-pending": "true" }, t("pendingCompatHint") + (compatInfo && compatInfo.checkNote ? ";已知校验:" + compatInfo.checkNote : ""))
|
|
2265
2318
|
: null,
|
|
2266
2319
|
meta !== null && meta.version ? el("div", { className: styles.rowTop },
|
|
2267
2320
|
el("p", { className: styles.status }, t("versionLabel") + ":" + meta.version),
|
|
@@ -2276,7 +2329,38 @@ window.__ModuleLoader__.load({
|
|
|
2276
2329
|
className: styles.toggle,
|
|
2277
2330
|
title: t("aiEmpowerTitle"),
|
|
2278
2331
|
onClick: () => openAiFor(String(entry.moduleName ?? entry.repo ?? "")),
|
|
2279
|
-
}, t("aiEmpowerLabel"))
|
|
2332
|
+
}, t("aiEmpowerLabel")),
|
|
2333
|
+
entry.pendingCompat === true
|
|
2334
|
+
? el("button", {
|
|
2335
|
+
type: "button",
|
|
2336
|
+
className: styles.toggle,
|
|
2337
|
+
"data-pending": "true",
|
|
2338
|
+
title: t("adaptUnlockHint"),
|
|
2339
|
+
disabled: installing === entry.moduleName || adaptUnlocking === entry.entryId,
|
|
2340
|
+
onClick: () => {
|
|
2341
|
+
setAdaptUnlocking(entry.entryId);
|
|
2342
|
+
call("/plugin-console/adapt-unlock", { rowId: entry.rowId }).then(
|
|
2343
|
+
() => {
|
|
2344
|
+
setAdaptUnlocking(null);
|
|
2345
|
+
setMessage(t("adaptUnlockDone"));
|
|
2346
|
+
window.setTimeout(() => window.location.reload(), 1200);
|
|
2347
|
+
},
|
|
2348
|
+
(error) => { setAdaptUnlocking(null); setMessage(t("failed") + ":" + friendlyGithubError(error).message); },
|
|
2349
|
+
);
|
|
2350
|
+
},
|
|
2351
|
+
}, adaptUnlocking === entry.entryId ? t("loadingPhase") : t("adaptUnlockBtn"))
|
|
2352
|
+
: null) : null,
|
|
2353
|
+
updateCheck !== null && updateCheck.status === "ready" && updateCheck.migrate && updateCheck.migrate.compatible
|
|
2354
|
+
? el("div", null,
|
|
2355
|
+
el("div", { className: styles.rowTop },
|
|
2356
|
+
el("p", { className: styles.status }, t("migrateTip") + ":" + String(updateCheck.migrate.to ?? "") + (updateCheck.migrate.latest ? " v" + updateCheck.migrate.latest : "")),
|
|
2357
|
+
el("button", {
|
|
2358
|
+
type: "button",
|
|
2359
|
+
className: styles.toggle,
|
|
2360
|
+
disabled: installing === entry.moduleName,
|
|
2361
|
+
onClick: () => startJob("", updateCheck.migrate.to, "github", "plugin", false),
|
|
2362
|
+
}, installing === entry.moduleName ? t("installing") : t("migrateBtn"))))
|
|
2363
|
+
: null,
|
|
2280
2364
|
updateCheck !== null && updateCheck.status === "ready"
|
|
2281
2365
|
? (updateCheck.error
|
|
2282
2366
|
? el("p", { className: styles.status, "data-error": "true" }, t("updateCheckFailed") + ":" + updateCheck.error)
|
|
@@ -2314,7 +2398,13 @@ window.__ModuleLoader__.load({
|
|
|
2314
2398
|
}
|
|
2315
2399
|
return el("li", { key: entry.entryId, className: styles.row },
|
|
2316
2400
|
el("div", { className: styles.rowTop },
|
|
2317
|
-
el("strong", { className: styles.name, title: entry.moduleName },
|
|
2401
|
+
el("strong", { className: styles.name, title: entry.moduleName }, (() => {
|
|
2402
|
+
const famRoot = famRootOf(entry);
|
|
2403
|
+
const mn = String(entry.moduleName ?? "");
|
|
2404
|
+
return famRoot !== null && (familyCounts.get(famRoot) ?? 0) > 1 && mn.startsWith(famRoot + "/")
|
|
2405
|
+
? mn.slice(famRoot.length + 1)
|
|
2406
|
+
: moduleShortName(entry.moduleName);
|
|
2407
|
+
})()),
|
|
2318
2408
|
el("span", { className: styles.tag, "data-enabled": entry.enabled ? "true" : "false" },
|
|
2319
2409
|
t(entry.enabled ? "enabledTag" : "disabledTag")),
|
|
2320
2410
|
entry.extra === true ? el("span", { className: styles.tag, "data-user": "true" }, t("extraTag")) : null,
|
|
@@ -2360,7 +2450,7 @@ window.__ModuleLoader__.load({
|
|
|
2360
2450
|
setMessage(t("deleteBundleNote") + ":" + (data.packageName ?? "") + (data.uninstallError ? "(包卸载警告:" + data.uninstallError + ")" : ""));
|
|
2361
2451
|
setRestartHint(true);
|
|
2362
2452
|
} else {
|
|
2363
|
-
setMessage(t("deleteNote") + ":" + (data.packageName ?? "") + (data.uninstallError ? "(包卸载警告:" + data.uninstallError + ")" : ""));
|
|
2453
|
+
setMessage(t("deleteNote") + ":" + (data.packageName ?? "") + (data.note ? ";" + data.note : "") + (data.uninstallError ? "(包卸载警告:" + data.uninstallError + ")" : ""));
|
|
2364
2454
|
setTimeout(refresh, 1500);
|
|
2365
2455
|
}
|
|
2366
2456
|
},
|
|
@@ -2388,8 +2478,72 @@ window.__ModuleLoader__.load({
|
|
|
2388
2478
|
),
|
|
2389
2479
|
detailPanel,
|
|
2390
2480
|
);
|
|
2391
|
-
})
|
|
2392
|
-
|
|
2481
|
+
});
|
|
2482
|
+
// 全家桶组头:聚合包(同根包 ≥2 行)合并展示为一个「web 包」卡片
|
|
2483
|
+
const familyHeaders = [];
|
|
2484
|
+
const familySeen = new Set();
|
|
2485
|
+
for (const entry of filteredEntries) {
|
|
2486
|
+
const root = famRootOf(entry);
|
|
2487
|
+
if (root === null || (familyCounts.get(root) ?? 0) <= 1 || familySeen.has(root)) continue;
|
|
2488
|
+
familySeen.add(root);
|
|
2489
|
+
familyHeaders.push(el("div", { key: "family-" + root, className: styles.detail, style: { border: "1px solid var(--dsw-alias-state-business-primary)", borderRadius: 10, padding: "8px 12px", gridColumn: "1 / -1" } },
|
|
2490
|
+
el("div", { className: styles.rowTop, style: { alignItems: "center" } },
|
|
2491
|
+
el("strong", { className: styles.name, style: { flex: "0 1 auto", minWidth: 0, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }, title: root }, root.replace(/^@[^/]+\//u, "").replace(/^dsh-/u, "")),
|
|
2492
|
+
el("span", { className: styles.tag, "data-user": "true" }, t("familyTag") + " · " + (familyCounts.get(root) ?? 0) + " " + t("familySubs")),
|
|
2493
|
+
el("button", {
|
|
2494
|
+
type: "button",
|
|
2495
|
+
className: styles.toggle,
|
|
2496
|
+
style: { whiteSpace: "nowrap", flexShrink: 0 },
|
|
2497
|
+
onClick: () => setFamilyCollapsed((prev) => ({ ...prev, [root]: prev[root] !== true })),
|
|
2498
|
+
}, familyCollapsed[root] === true ? "▸ " + t("familyExpand") : "▾ " + t("familyCollapse")),
|
|
2499
|
+
el("button", {
|
|
2500
|
+
type: "button",
|
|
2501
|
+
className: styles.toggle,
|
|
2502
|
+
style: { whiteSpace: "nowrap", flexShrink: 0 },
|
|
2503
|
+
onClick: () => {
|
|
2504
|
+
setMessage(t("checkingUpdate"));
|
|
2505
|
+
call("/plugin-console/check-update", { packageName: root }).then(
|
|
2506
|
+
(d) => setMessage(t("familyUpdate") + ":" + root + " " + (d?.latest ?? "?") + (d?.migrate && d.migrate.compatible ? " → " + d.migrate.to + " v" + d.migrate.latest : "") + (d?.error ? "(" + d.error + ")" : "")),
|
|
2507
|
+
(e) => setMessage(t("failed") + ":" + friendlyGithubError(e).message),
|
|
2508
|
+
);
|
|
2509
|
+
},
|
|
2510
|
+
}, t("familyCheckUpdate")),
|
|
2511
|
+
el("button", {
|
|
2512
|
+
type: "button",
|
|
2513
|
+
className: styles.toggle,
|
|
2514
|
+
style: { whiteSpace: "nowrap", flexShrink: 0 },
|
|
2515
|
+
title: t("familyUnlockAllTip"),
|
|
2516
|
+
onClick: () => {
|
|
2517
|
+
if (!window.confirm(t("familyUnlockAllConfirm"))) return;
|
|
2518
|
+
call("/plugin-console/adapt-unlock-all", { root }).then(
|
|
2519
|
+
(d) => {
|
|
2520
|
+
setMessage(t("familyUnlockAllDone") + ":" + (d.unlocked ?? []).length + " 行" + (Array.isArray(d.kept) && d.kept.length > 0 ? ";保留 " + d.kept.length + " 行(未通过校验)" : ""));
|
|
2521
|
+
window.setTimeout(() => window.location.reload(), 1500);
|
|
2522
|
+
},
|
|
2523
|
+
(e) => setMessage(t("failed") + ":" + friendlyGithubError(e).message),
|
|
2524
|
+
);
|
|
2525
|
+
},
|
|
2526
|
+
}, t("familyUnlockAll")))
|
|
2527
|
+
));
|
|
2528
|
+
}
|
|
2529
|
+
// 组头放到最底部:普通条目在前,全家桶(组头+子包卡片)整体在后
|
|
2530
|
+
const nonFamilyCards = [];
|
|
2531
|
+
const familySections = new Map();
|
|
2532
|
+
familyCards.forEach((card, i) => {
|
|
2533
|
+
const e = filteredEntries[i];
|
|
2534
|
+
if (e === undefined) { nonFamilyCards.push(card); return; }
|
|
2535
|
+
const root = famRootOf(e);
|
|
2536
|
+
if (root === null || (familyCounts.get(root) ?? 0) <= 1) { nonFamilyCards.push(card); return; }
|
|
2537
|
+
if (!familySections.has(root)) familySections.set(root, { head: familyHeaders.find((h) => h && h.key === "family-" + root) ?? null, cards: [] });
|
|
2538
|
+
familySections.get(root).cards.push(card);
|
|
2539
|
+
});
|
|
2540
|
+
const familySectionEls = [];
|
|
2541
|
+
for (const [, section] of familySections) {
|
|
2542
|
+
if (section.head !== null) familySectionEls.push(section.head);
|
|
2543
|
+
const root = section.head !== null ? section.head.key.slice("family-".length) : null;
|
|
2544
|
+
if (root === null || familyCollapsed[root] !== true) familySectionEls.push(...section.cards);
|
|
2545
|
+
}
|
|
2546
|
+
const rows = state.status === "ready" ? [...nonFamilyCards, ...familySectionEls] : [];
|
|
2393
2547
|
const marketShown = market === null || market.status !== "ready"
|
|
2394
2548
|
? []
|
|
2395
2549
|
: officialOnly
|