@noob-stupid/dsh-plugin-console 0.3.67 → 0.4.1
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/lib/client.js +126 -31
- package/lib/index.js +60 -9687
- package/lib/server/domain/ai-run.js +479 -0
- package/lib/server/domain/ai.js +246 -0
- package/lib/server/domain/compat.js +474 -0
- package/lib/server/domain/components.js +108 -0
- package/lib/server/domain/dep-source.js +122 -0
- package/lib/server/domain/format-contract.js +265 -0
- package/lib/server/domain/format-scan.js +434 -0
- package/lib/server/domain/framework.js +393 -0
- package/lib/server/domain/install-job.js +561 -0
- package/lib/server/domain/install.js +599 -0
- package/lib/server/domain/jobs.js +28 -0
- package/lib/server/domain/market.js +409 -0
- package/lib/server/domain/patch.js +203 -0
- package/lib/server/domain/presets.js +93 -0
- package/lib/server/domain/quarantine.js +224 -0
- package/lib/server/domain/release-source.js +504 -0
- package/lib/server/domain/repoland.js +119 -0
- package/lib/server/domain/revoke.js +184 -0
- package/lib/server/domain/runtime.js +118 -0
- package/lib/server/domain/selfupdate.js +319 -0
- package/lib/server/domain/skills.js +234 -0
- package/lib/server/domain/sources.js +297 -0
- package/lib/server/domain/suite.js +220 -0
- package/lib/server/infra/exec.js +98 -0
- package/lib/server/infra/fsx.js +163 -0
- package/lib/server/infra/fw-integrity-check.js +37 -0
- package/lib/server/infra/http.js +373 -0
- package/lib/server/infra/httpd.js +51 -0
- package/lib/server/infra/mask.js +19 -0
- package/lib/server/infra/paths.js +177 -0
- package/lib/server/infra/semver.js +168 -0
- package/lib/server/routes/ai.js +172 -0
- package/lib/server/routes/components.js +254 -0
- package/lib/server/routes/framework-preflight.js +160 -0
- package/lib/server/routes/framework-upgrade.js +679 -0
- package/lib/server/routes/framework.js +544 -0
- package/lib/server/routes/github-login.js +198 -0
- package/lib/server/routes/index.js +128 -0
- package/lib/server/routes/install.js +116 -0
- package/lib/server/routes/market.js +415 -0
- package/lib/server/routes/plugins.js +562 -0
- package/lib/server/routes/skills.js +107 -0
- package/lib/server/routes/sources.js +437 -0
- package/lib/server/routes/state.js +125 -0
- package/lib/server/state.js +22 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -276,7 +276,7 @@ window.__ModuleLoader__.load({
|
|
|
276
276
|
aiFallbackLabel: "AI 兜底",
|
|
277
277
|
aiEmpowerLabel: "AI 赋能",
|
|
278
278
|
aiEmpowerTitle: "AI 赋能:读文档自动规划并部署组件;识别到服务器类组件后自动加启动/停止按钮",
|
|
279
|
-
aiEmpowerSrcTitle: "输入要部署的组件(npm 包名或 GitHub 仓库,如 Noob-stupid/dsh-plugin-hub 或 @noob-stupid/dsh-plugin-console)",
|
|
279
|
+
aiEmpowerSrcTitle: "输入要部署的组件(npm 包名或 GitHub 仓库,如 Noob-stupid/dsh-plugin-gating-hub 或 @noob-stupid/dsh-plugin-console)",
|
|
280
280
|
aiEmpowerPlanTitle: "AI 赋能部署计划",
|
|
281
281
|
aiEmpowerType: "类型",
|
|
282
282
|
aiEmpowerTypeMapping: { "pure-plugin": "纯插件", "service": "服务器组件", "config-only": "仅配置" },
|
|
@@ -475,6 +475,20 @@ window.__ModuleLoader__.load({
|
|
|
475
475
|
frameworkUpgradeTarget: "升级目标",
|
|
476
476
|
frameworkUpgradePick: "选择要升级到的版本(列出所有比当前新的版本,含预发布;latest 为稳定版)",
|
|
477
477
|
frameworkUpgradeMore: "展开全部可选版本({n})",
|
|
478
|
+
// 升级前契约预检(2026-09-24 事故:v4 消息格式变更让运行期生产方全部失效)
|
|
479
|
+
fwPreflightBtn: "升级预检",
|
|
480
|
+
fwPreflightTitle: "升级前契约预检:抓目标版本的会话格式契约(迁移边),扫描 agent-presets 与已装插件里的旧形状消息来源;可一键适配并自动备份(.bak-preflight-*)",
|
|
481
|
+
fwPreflightRunning: "预检中…",
|
|
482
|
+
fwPreflightClean: "预检通过:本地生产方没有会触发格式校验的旧写法",
|
|
483
|
+
fwPreflightFound: "预检发现 {n} 处必须适配(另有 {m} 处提示)",
|
|
484
|
+
fwPreflightContract: "会话格式契约:{summary}",
|
|
485
|
+
fwPreflightNoContract: "契约未知:{err}(已降级为内置规则扫描)",
|
|
486
|
+
fwPreflightPatch: "一键适配(自动备份)",
|
|
487
|
+
fwPreflightApplyConfirm: "将修改本地文件(每个文件自动备份为 .bak-preflight-*),继续?",
|
|
488
|
+
fwPreflightPatched: "已适配 {n} 处,备份 {b} 个文件",
|
|
489
|
+
fwPreflightRemaining: "适配后仍有 {n} 处需人工处理(预检不会自动改)",
|
|
490
|
+
fwPreflightNeedManual: "需人工处理:{why}",
|
|
491
|
+
fwPreflightScanned: "已扫描 {n} 个生产方文件(预设 + 插件)",
|
|
478
492
|
frameworkUpgradeFold: "收起版本列表",
|
|
479
493
|
frameworkUpgradeChannelStable: "稳定版",
|
|
480
494
|
frameworkUpgradeChannelPre: "预发布",
|
|
@@ -887,6 +901,20 @@ window.__ModuleLoader__.load({
|
|
|
887
901
|
frameworkUpgradeTarget: "Upgrade target",
|
|
888
902
|
frameworkUpgradePick: "Pick a version to upgrade to (every version newer than the current one, pre-releases included; latest = stable channel)",
|
|
889
903
|
frameworkUpgradeMore: "Show all available versions ({n})",
|
|
904
|
+
// Pre-upgrade contract preflight (2026-09-24 incident: v4 message-format change broke every runtime producer)
|
|
905
|
+
fwPreflightBtn: "Pre-upgrade preflight",
|
|
906
|
+
fwPreflightTitle: "Pre-upgrade contract preflight: fetch the target session-format contract (migration edges) and scan agent-presets + installed plugins for legacy message sources; one click adapts with .bak-preflight-* backups",
|
|
907
|
+
fwPreflightRunning: "Preflighting…",
|
|
908
|
+
fwPreflightClean: "Preflight passed: no legacy producer shape that would fail format validation",
|
|
909
|
+
fwPreflightFound: "Preflight found {n} blockers to adapt ({m} advisories)",
|
|
910
|
+
fwPreflightContract: "Session-format contract: {summary}",
|
|
911
|
+
fwPreflightNoContract: "Contract unknown: {err} (degraded to built-in rules)",
|
|
912
|
+
fwPreflightPatch: "Adapt now (auto backup)",
|
|
913
|
+
fwPreflightApplyConfirm: "This will modify local files (each backed up as .bak-preflight-*). Continue?",
|
|
914
|
+
fwPreflightPatched: "Adapted {n} spot(s), backed up {b} file(s)",
|
|
915
|
+
fwPreflightRemaining: "{n} spot(s) still need manual work (preflight never auto-fixes those)",
|
|
916
|
+
fwPreflightNeedManual: "Needs manual work: {why}",
|
|
917
|
+
fwPreflightScanned: "Scanned {n} producer file(s) (presets + plugins)",
|
|
890
918
|
frameworkUpgradeFold: "Collapse version list",
|
|
891
919
|
frameworkUpgradeChannelStable: "stable",
|
|
892
920
|
frameworkUpgradeChannelPre: "pre-release",
|
|
@@ -1392,6 +1420,10 @@ window.__ModuleLoader__.load({
|
|
|
1392
1420
|
? fwSelectedVersion
|
|
1393
1421
|
: (fwCheck && fwCheck.tagDefault) || (fwCheck && fwCheck.target) || (fwVersions[0] ? fwVersions[0].version : null);
|
|
1394
1422
|
const fwChannelLabel = (v) => (v && v.isLatest === true ? t("frameworkUpgradeChannelStable") + " · latest" : (v && typeof v.channel === "string" && v.channel !== "" ? t("frameworkUpgradeChannelPre") + " · " + v.channel : t("frameworkUpgradeChannelPre")));
|
|
1423
|
+
// 升级前契约预检(Step 1+2):report=只读预检结论,patch=一键适配结果;两者分开放,
|
|
1424
|
+
// 免得把「扫描结论」和「已经改过什么」混成一团(用户要能分辨「该不该升级」与「改了什么」)
|
|
1425
|
+
const [fwPreflightBusy, setFwPreflightBusy] = react.useState(false);
|
|
1426
|
+
const [fwPreflight, setFwPreflight] = react.useState(null);
|
|
1395
1427
|
// 面板里的状态刷新:**无视**「终态已关闭」标记——卡片可以被永久关掉,面板必须永远能查到真相
|
|
1396
1428
|
const fwStatusRefresh = () => {
|
|
1397
1429
|
call("/plugin-console/framework-upgrade-status").then(
|
|
@@ -1411,6 +1443,24 @@ window.__ModuleLoader__.load({
|
|
|
1411
1443
|
(error) => { setFwCheckBusy(false); setMessage(t("failed") + ":" + friendlyGithubError(error).message); },
|
|
1412
1444
|
);
|
|
1413
1445
|
};
|
|
1446
|
+
// 升级前契约预检:先只读预检(抓目标版本会话格式契约 + 扫本地生产方),
|
|
1447
|
+
// 再按需一键适配(服务端逐文件备份 .bak-preflight-*,名单外文件一律拒绝写入)。
|
|
1448
|
+
// 为什么必须独立于「框架升级」按钮:包级适配门看不到运行期契约破坏(2026-09-24 事故)。
|
|
1449
|
+
const fwPreflightRun = (apply) => {
|
|
1450
|
+
const targetVersion = fwSelected ?? fwCheck?.target ?? null;
|
|
1451
|
+
if (apply === true && !window.confirm(t("fwPreflightApplyConfirm"))) return;
|
|
1452
|
+
setFwPreflightBusy(true);
|
|
1453
|
+
const path = apply === true ? "/plugin-console/framework-preflight-patch" : "/plugin-console/framework-preflight";
|
|
1454
|
+
const payload = apply === true ? { targetVersion, mode: "apply" } : { targetVersion };
|
|
1455
|
+
call(path, payload).then(
|
|
1456
|
+
(data) => {
|
|
1457
|
+
setFwPreflightBusy(false);
|
|
1458
|
+
setFwPreflight((prev) => (apply === true ? { report: (prev && prev.report) ?? null, patch: data } : { report: data, patch: null }));
|
|
1459
|
+
},
|
|
1460
|
+
(error) => { setFwPreflightBusy(false); setMessage(t("failed") + ":" + friendlyGithubError(error).message); },
|
|
1461
|
+
);
|
|
1462
|
+
};
|
|
1463
|
+
const fwShortPath = (p) => String(p ?? "").replace(/\\/gu, "/").split("/").slice(-3).join("/");
|
|
1414
1464
|
const doFrameworkRollback = () => {
|
|
1415
1465
|
setFrameworkUpgrading(true);
|
|
1416
1466
|
call("/plugin-console/framework-rollback", {}).then(
|
|
@@ -2832,7 +2882,9 @@ window.__ModuleLoader__.load({
|
|
|
2832
2882
|
return;
|
|
2833
2883
|
}
|
|
2834
2884
|
if ((item.subpackagePath || item.npmPackage === true) && typeof item.packageName === "string" && item.packageName !== "") {
|
|
2835
|
-
// monorepo
|
|
2885
|
+
// monorepo 子包 / npm 包名命中:搜索结果带 packageName,按 npm 包名安装
|
|
2886
|
+
//(npm 包名反查命中的条目没有 subpackagePath,只有 packageName + npmPackage,
|
|
2887
|
+
// 不改这一行就会退化成"按仓库装",装到的不是用户输入的那个包 —— 2026-09-20)
|
|
2836
2888
|
startJob(item.fullName, item.packageName, item.source ?? "github");
|
|
2837
2889
|
return;
|
|
2838
2890
|
}
|
|
@@ -3663,8 +3715,47 @@ window.__ModuleLoader__.load({
|
|
|
3663
3715
|
: null,
|
|
3664
3716
|
frameworkStatus.message ? el("p", { className: styles.status, "data-error": frameworkStatus.status === "failed" ? "true" : undefined }, frameworkStatus.message) : null)
|
|
3665
3717
|
: el("p", { className: styles.status }, t("fwPanelNoRecord")),
|
|
3718
|
+
// ③.0 升级预检报告(只读结论 + 一键适配结果)——放在升级按钮之前,
|
|
3719
|
+
// 让「先预检、再升级」成为默认路径
|
|
3720
|
+
fwPreflight !== null
|
|
3721
|
+
? el("div", { style: { flexDirection: "column", gap: 6, display: "flex", border: "1px solid var(--dsw-alias-border-l2)", borderRadius: 8, padding: 8 } },
|
|
3722
|
+
el("strong", { className: styles.name },
|
|
3723
|
+
t("fwPreflightBtn")
|
|
3724
|
+
+ (fwPreflight.report?.scan ? "(" + t("fwPreflightScanned").replace("{n}", String(fwPreflight.report.scan.filesScanned)) + ")" : "")),
|
|
3725
|
+
fwPreflight.report === null || fwPreflight.report === undefined
|
|
3726
|
+
? null
|
|
3727
|
+
: (fwPreflight.report.contract !== null && fwPreflight.report.contract !== undefined
|
|
3728
|
+
? el("p", { className: styles.status }, t("fwPreflightContract").replace("{summary}", String(fwPreflight.report.contractSummary ?? "")))
|
|
3729
|
+
: el("p", { className: styles.message, "data-warn": "true" }, t("fwPreflightNoContract").replace("{err}", String(fwPreflight.report.contractError ?? "?")))),
|
|
3730
|
+
fwPreflight.report === null || fwPreflight.report === undefined
|
|
3731
|
+
? null
|
|
3732
|
+
: (fwPreflight.report.scan.ok === true
|
|
3733
|
+
? el("p", { className: styles.status }, "✓ " + t("fwPreflightClean"))
|
|
3734
|
+
: el("p", { className: styles.message, "data-error": "true" }, t("fwPreflightFound").replace("{n}", String(fwPreflight.report.scan.blockers)).replace("{m}", String(fwPreflight.report.scan.warnings)))),
|
|
3735
|
+
fwPreflight.report === null || fwPreflight.report === undefined
|
|
3736
|
+
? null
|
|
3737
|
+
: el("div", { style: { flexDirection: "column", gap: 2, display: "flex", maxHeight: 160, overflowY: "auto" } },
|
|
3738
|
+
(fwPreflight.report.scan.findings ?? []).slice(0, 10).map((f, idx) => el("p", { key: idx, className: styles.status },
|
|
3739
|
+
"• " + fwShortPath(f.file) + ":" + f.line + " — " + f.rule
|
|
3740
|
+
+ (f.fixable === true ? "" : "(" + t("fwPreflightNeedManual").replace("{why}", String(f.reason ?? f.note ?? "?")) + ")")
|
|
3741
|
+
+ (f.after ? " → " + f.after : "")))),
|
|
3742
|
+
fwPreflight.patch !== null && fwPreflight.patch !== undefined
|
|
3743
|
+
? el("p", { className: styles.status, "data-pending": "true" },
|
|
3744
|
+
t("fwPreflightPatched").replace("{n}", String((fwPreflight.patch.changes ?? []).length)).replace("{b}", String((fwPreflight.patch.backups ?? []).length)))
|
|
3745
|
+
: null,
|
|
3746
|
+
fwPreflight.patch !== null && fwPreflight.patch !== undefined && (fwPreflight.patch.remaining?.blockers ?? 0) > 0
|
|
3747
|
+
? el("p", { className: styles.message, "data-warn": "true" }, t("fwPreflightRemaining").replace("{n}", String(fwPreflight.patch.remaining.blockers)))
|
|
3748
|
+
: null,
|
|
3749
|
+
el("div", { className: styles.rowTop },
|
|
3750
|
+
fwPreflight.report !== null && fwPreflight.report !== undefined && fwPreflight.report.scan.blockers > 0
|
|
3751
|
+
? el("button", { type: "button", className: styles.toggle, disabled: fwPreflightBusy, onClick: () => fwPreflightRun(true) }, t("fwPreflightPatch"))
|
|
3752
|
+
: null,
|
|
3753
|
+
el("button", { type: "button", className: styles.toggle, disabled: fwPreflightBusy, onClick: () => fwPreflightRun(false) }, fwPreflightBusy ? t("fwPreflightRunning") : t("fwPreflightBtn")),
|
|
3754
|
+
el("button", { type: "button", className: styles.toggle, onClick: () => setFwPreflight(null) }, t("closeModal"))))
|
|
3755
|
+
: null,
|
|
3666
3756
|
// ③ 操作:升级(两步确认)/ 回滚 / 重启 / 重新检查
|
|
3667
3757
|
el("div", { className: styles.rowTop, style: { flexWrap: "wrap" } },
|
|
3758
|
+
el("button", { type: "button", className: styles.toggle, disabled: fwPreflightBusy, title: t("fwPreflightTitle"), onClick: () => fwPreflightRun(false) }, fwPreflightBusy ? t("fwPreflightRunning") : t("fwPreflightBtn")),
|
|
3668
3759
|
fwCheck?.target
|
|
3669
3760
|
? (fwConfirmPanel
|
|
3670
3761
|
? el("div", { style: { flexDirection: "column", gap: 8, display: "flex", flexBasis: "100%" } },
|
|
@@ -3716,34 +3807,36 @@ window.__ModuleLoader__.load({
|
|
|
3716
3807
|
el("p", { className: styles.message }, t("compatGateHint")),
|
|
3717
3808
|
el("p", { className: styles.status, "data-pending": gatePendingCount > 0 ? "true" : undefined },
|
|
3718
3809
|
gatePendingCount > 0 ? t("gatePendingInfo").replace("{n}", String(gatePendingCount)) : t("gatePendingNone")),
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
(
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
?
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
:
|
|
3746
|
-
|
|
3810
|
+
el("p", { className: styles.status, "data-pending": gatePendingCount > 0 ? "true" : undefined },
|
|
3811
|
+
gatePendingCount > 0 ? t("gatePendingInfo").replace("{n}", String(gatePendingCount)) : t("gatePendingNone")),
|
|
3812
|
+
// 明细清单(2026-09-24 用户要求:面板要能看到是哪些插件,有列表数据)
|
|
3813
|
+
gateRows !== null && gateRows.pendingCount + gateRows.adoptedCount > 0
|
|
3814
|
+
? el("div", { style: { flexDirection: "column", gap: 6, display: "flex" } },
|
|
3815
|
+
el("strong", { className: styles.name }, t("gateListPending").replace("{n}", String(gateRows.pendingCount))),
|
|
3816
|
+
gateRows.pending.length === 0
|
|
3817
|
+
? el("p", { className: styles.status }, t("gatePendingNone"))
|
|
3818
|
+
: null,
|
|
3819
|
+
(gateShowAll ? gateRows.pending : gateRows.pending.slice(0, 8)).map((r) => el("div", {
|
|
3820
|
+
key: "p-" + String(r.rowId),
|
|
3821
|
+
style: { flexDirection: "column", gap: 2, display: "flex", padding: "4px 0" },
|
|
3822
|
+
},
|
|
3823
|
+
el("span", { className: styles.name }, (r.enabled === false ? "⛔ " : "• ") + String(r.name) + (r.version ? " v" + r.version : "")),
|
|
3824
|
+
el("span", { className: styles.status }, t("gateRowReason").replace("{reason}", String(r.note ?? "—"))),
|
|
3825
|
+
el("span", { className: styles.status },
|
|
3826
|
+
(r.source === "boot-quarantine" ? t("gateRowFromBoot") : t("gateRowFromUpgrade"))
|
|
3827
|
+
+ (r.forcedAt ? t("gateRowAt").replace("{t}", gateTime(r.forcedAt)) : "")
|
|
3828
|
+
+ (r.adoptable ? t("gateRowAdoptable") : "")))),
|
|
3829
|
+
gateRows.pendingCount > 8
|
|
3830
|
+
? el("button", { type: "button", className: styles.toggle, onClick: () => setGateShowAll((v) => !v) },
|
|
3831
|
+
gateShowAll ? t("gateListFold") : t("gateListMore").replace("{n}", String(gateRows.pendingCount)))
|
|
3832
|
+
: null,
|
|
3833
|
+
gateRows.adoptedCount > 0
|
|
3834
|
+
? el("div", { style: { flexDirection: "column", gap: 2, display: "flex" } },
|
|
3835
|
+
el("strong", { className: styles.name }, t("gateListAdopted").replace("{n}", String(gateRows.adoptedCount))),
|
|
3836
|
+
gateRows.adopted.slice(0, 8).map((r) => el("span", { key: "a-" + String(r.rowId), className: styles.status },
|
|
3837
|
+
"✓ " + String(r.name) + (r.version ? " v" + r.version : "") + (r.adoptedAt ? " · " + gateTime(r.adoptedAt) : ""))))
|
|
3838
|
+
: null)
|
|
3839
|
+
: null)))
|
|
3747
3840
|
: null,
|
|
3748
3841
|
aiOpen
|
|
3749
3842
|
? el("div", { className: styles.modalBackdrop },
|
|
@@ -3860,7 +3953,9 @@ window.__ModuleLoader__.load({
|
|
|
3860
3953
|
setMessage(t("cleanResiduals") + "…");
|
|
3861
3954
|
call("/plugin-console/clean-residuals", {}).then(
|
|
3862
3955
|
(data) => {
|
|
3863
|
-
|
|
3956
|
+
const keptCount = Array.isArray(data && data.kept) ? data.kept.length : 0;
|
|
3957
|
+
const keptNote = keptCount > 0 ? ";保留在用插件 " + keptCount + " 个" : "";
|
|
3958
|
+
if (data && data.ok === true) setMessage(t("cleanResiduals") + ":" + (data.count === 0 ? "无残余" : "已清理 " + data.count + " 项") + keptNote);
|
|
3864
3959
|
},
|
|
3865
3960
|
(error) => setMessage(t("failed") + ":" + friendlyGithubError(error).message),
|
|
3866
3961
|
);
|