@dsh-workbench/core 0.1.16 → 0.1.18
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/client.js +665 -127
- package/dist/board.css +31 -0
- package/dist/client/client.body.js +665 -127
- package/dist/client/index.js +665 -127
- package/dist/host/index.js +1510 -263
- package/dist/types/app/client.d.ts +124 -27
- package/dist/types/app/layouts/market/add-module-text.d.ts +2 -0
- package/dist/types/app/layouts/market/use-add-module.d.ts +4 -3
- package/dist/types/app/layouts/market/use-module-versions.d.ts +2 -0
- package/dist/types/app/layouts/rightbar/MarketView.d.ts +3 -1
- package/dist/types/app/layouts/rightbar/__tests__/market-rows-plugins.test.d.ts +1 -0
- package/dist/types/app/layouts/rightbar/market-freshness.d.ts +1 -0
- package/dist/types/app/layouts/rightbar/market-mock.d.ts +9 -0
- package/dist/types/app/layouts/rightbar/market-plugin-rows.d.ts +8 -0
- package/dist/types/app/layouts/rightbar/market-rows.d.ts +14 -3
- package/dist/types/app/layouts/rightbar/registry.d.ts +0 -1
- package/dist/types/app/units/__tests__/manifests.test.d.ts +1 -0
- package/dist/types/app/units/fixture-unit-mock.d.ts +3 -3
- package/dist/types/app/units/host.d.ts +2 -2
- package/dist/types/app/units/manifests.d.ts +5 -0
- package/dist/types/app/units/registry.d.ts +10 -2
- package/dist/types/modules/panels/__tests__/market-env.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/market-plugin.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/market-route.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/plugin-actions.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/plugin-ledger.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/plugin-section.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/scope.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/service-release.test.d.ts +1 -0
- package/dist/types/modules/panels/index.d.ts +2 -2
- package/dist/types/modules/panels/model/config.d.ts +27 -9
- package/dist/types/modules/panels/model/market-dispatch.d.ts +9 -0
- package/dist/types/modules/panels/model/market-env.d.ts +20 -0
- package/dist/types/modules/panels/model/market-route.d.ts +26 -0
- package/dist/types/modules/panels/model/market-types.d.ts +71 -0
- package/dist/types/modules/panels/model/market.d.ts +7 -66
- package/dist/types/modules/panels/model/plugin-actions.d.ts +50 -0
- package/dist/types/modules/panels/model/plugin-ledger.d.ts +22 -0
- package/dist/types/modules/panels/model/plugin-name.d.ts +8 -0
- package/dist/types/modules/panels/model/plugin-name.test.d.ts +1 -0
- package/dist/types/modules/panels/model/plugin-section.d.ts +13 -0
- package/dist/types/modules/panels/model/service.d.ts +8 -6
- package/dist/types/shared/api/bundle-install.d.ts +8 -1
- package/dist/types/shared/api/host/__tests__/registry-declaration.test.d.ts +1 -0
- package/dist/types/shared/api/host/__tests__/unit-roster-facts.test.d.ts +1 -0
- package/dist/types/shared/api/host/bundle-routes.d.ts +1 -0
- package/dist/types/shared/api/host/installed-module.d.ts +7 -0
- package/dist/types/shared/api/host/mount-units.d.ts +5 -3
- package/dist/types/shared/api/host/package-content.d.ts +6 -0
- package/dist/types/shared/api/host/package-content.test.d.ts +1 -0
- package/dist/types/shared/api/host/package-kind.d.ts +21 -0
- package/dist/types/shared/api/host/package-kind.test.d.ts +1 -0
- package/dist/types/shared/api/host/package-route.d.ts +23 -0
- package/dist/types/shared/api/host/package-route.test.d.ts +1 -0
- package/dist/types/shared/api/host/registry-declaration.d.ts +23 -0
- package/dist/types/shared/api/host/unit-registry.d.ts +33 -4
- package/dist/types/shared/api/host/unit-roster-facts.d.ts +5 -0
- package/dist/types/shared/api/installed-plugins.d.ts +12 -0
- package/dist/types/shared/api/unit-manifests.d.ts +5 -0
- package/dist/types/shared/api/unit-manifests.test.d.ts +1 -0
- package/dist/types/shared/hooks/bundle-queries.d.ts +2 -0
- package/dist/types/shared/hooks/use-facts.d.ts +1 -0
- package/package.json +2 -2
- package/skills/workbench-module-diy/BUILD.md +5 -5
- package/skills/workbench-module-diy/DESIGN.md +7 -1
- package/skills/workbench-module-diy/REVIEW.md +4 -3
- package/skills/workbench-module-diy/TOOLING.md +2 -2
- package/skills/workbench-module-diy/TOOLS.md +13 -3
|
@@ -419,6 +419,133 @@ function probeKeyOf(error) {
|
|
|
419
419
|
if (error === void 0) return null;
|
|
420
420
|
return error.code === "" ? "unknown" : error.code;
|
|
421
421
|
}
|
|
422
|
+
var SUPPORTED_API_VERSIONS = [1];
|
|
423
|
+
var DECLARATION_KEYS = [
|
|
424
|
+
"apiVersion",
|
|
425
|
+
"unit",
|
|
426
|
+
"card",
|
|
427
|
+
"tools",
|
|
428
|
+
"host",
|
|
429
|
+
"env"
|
|
430
|
+
];
|
|
431
|
+
var DECLARATION_REQUIRED_KEYS = [
|
|
432
|
+
"apiVersion",
|
|
433
|
+
"unit",
|
|
434
|
+
"card",
|
|
435
|
+
"tools",
|
|
436
|
+
"host"
|
|
437
|
+
];
|
|
438
|
+
var CARD_KEYS = ["titleKey", "order"];
|
|
439
|
+
var TOOL_KEYS = [
|
|
440
|
+
"name",
|
|
441
|
+
"writes",
|
|
442
|
+
"key"
|
|
443
|
+
];
|
|
444
|
+
var TOOL_KEY_SHAPE = /^[a-z][a-zA-Z0-9]*$/;
|
|
445
|
+
var HOST_KEYS = ["inject", "optional"];
|
|
446
|
+
function text(value) {
|
|
447
|
+
return typeof value === "string" ? value.trim() : "";
|
|
448
|
+
}
|
|
449
|
+
function isRecord(value) {
|
|
450
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
451
|
+
}
|
|
452
|
+
function outsideKeys(value, allowed) {
|
|
453
|
+
return Object.keys(value).filter((key) => !allowed.includes(key));
|
|
454
|
+
}
|
|
455
|
+
function listOf(keys) {
|
|
456
|
+
return keys.map((key) => JSON.stringify(key)).join(" / ");
|
|
457
|
+
}
|
|
458
|
+
function stringArrayProblems(at, value) {
|
|
459
|
+
if (!Array.isArray(value)) return [`${at} 要是一串字符串,现在是 ${JSON.stringify(value)}`];
|
|
460
|
+
return value.flatMap((item, index) => text(item) === "" ? [`${at}[${index}] 不是非空字符串:${JSON.stringify(item)}`] : []);
|
|
461
|
+
}
|
|
462
|
+
function declarationProblemsOf(subject, raw) {
|
|
463
|
+
if (!isRecord(raw)) return [`${subject}: dsh.workbench 不是一个对象 —— ${JSON.stringify(raw)}`];
|
|
464
|
+
const version = raw.apiVersion;
|
|
465
|
+
if (version === void 0) return [`${subject}: dsh.workbench 没有 apiVersion —— 协议从 v1 起,写 \`"apiVersion": 1\`。缺它 = 外壳不认这个模块(ADR-0038 §2.3)`];
|
|
466
|
+
if (!Number.isInteger(version) || !SUPPORTED_API_VERSIONS.includes(version)) return [`${subject}: dsh.workbench.apiVersion 是 ${JSON.stringify(version)},这里只认 ${SUPPORTED_API_VERSIONS.join(" / ")}(要整数)`];
|
|
467
|
+
const problems = [];
|
|
468
|
+
const unknown = outsideKeys(raw, DECLARATION_KEYS);
|
|
469
|
+
if (unknown.length > 0) problems.push(`${subject}: dsh.workbench 里有协议 v1 不认识的键 ${listOf(unknown)} —— 只有 ${listOf(DECLARATION_KEYS)}。(拼错的键会被外壳**静默忽略**:那句声明等于没写)`);
|
|
470
|
+
for (const key of DECLARATION_REQUIRED_KEYS) if (raw[key] === void 0) problems.push(`${subject}: dsh.workbench 缺 ${key}` + (key === "card" ? "(这个模块没有卡片就写 `\"card\": null`)" : ""));
|
|
471
|
+
const card = raw.card;
|
|
472
|
+
if (card !== void 0 && card !== null) {
|
|
473
|
+
if (!isRecord(card)) problems.push(`${subject}: dsh.workbench.card 要么是对象、要么是 null,现在是 ${JSON.stringify(card)}`);
|
|
474
|
+
else {
|
|
475
|
+
const extra = outsideKeys(card, CARD_KEYS);
|
|
476
|
+
if (extra.length > 0) problems.push(`${subject}: dsh.workbench.card 里有不认的键 ${listOf(extra)} —— card 只有 ${listOf(CARD_KEYS)}(卡片默认显不显示由运行期的面板配置决定,清单里没有这一位)`);
|
|
477
|
+
if (text(card.titleKey) === "") problems.push(`${subject}: dsh.workbench.card.titleKey 要是非空字符串(面板那一格的文案键)`);
|
|
478
|
+
if (typeof card.order !== "number" || !Number.isFinite(card.order)) problems.push(`${subject}: dsh.workbench.card.order 要是数字,现在是 ${JSON.stringify(card.order)}`);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
const tools = raw.tools;
|
|
482
|
+
if (tools !== void 0) {
|
|
483
|
+
if (!Array.isArray(tools)) problems.push(`${subject}: dsh.workbench.tools 要是一串声明,现在是 ${JSON.stringify(tools)}`);
|
|
484
|
+
else {
|
|
485
|
+
const seen = /* @__PURE__ */ new Set();
|
|
486
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
487
|
+
tools.forEach((tool, index) => {
|
|
488
|
+
const at = `dsh.workbench.tools[${index}]`;
|
|
489
|
+
if (!isRecord(tool)) {
|
|
490
|
+
problems.push(`${subject}: ${at} 要是对象,现在是 ${JSON.stringify(tool)}`);
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
const extra = outsideKeys(tool, TOOL_KEYS);
|
|
494
|
+
if (extra.length > 0) problems.push(`${subject}: ${at} 里有不认的键 ${listOf(extra)} —— tools 只有 ${listOf(TOOL_KEYS)}`);
|
|
495
|
+
const name = text(tool.name);
|
|
496
|
+
if (name === "") problems.push(`${subject}: ${at}.name 要是非空字符串`);
|
|
497
|
+
else if (seen.has(name)) problems.push(`${subject}: ${at}.name「${name}」与前面那条撞了 —— 工具名会进 dsh 的工具表,不许重`);
|
|
498
|
+
else seen.add(name);
|
|
499
|
+
if (typeof tool.writes !== "boolean") problems.push(`${subject}: ${at}.writes 要是 true / false(它是"这会写"的唯一声明,缺了审批无从认领)`);
|
|
500
|
+
if (tool.key !== void 0) {
|
|
501
|
+
const key = text(tool.key);
|
|
502
|
+
if (!TOOL_KEY_SHAPE.test(key)) problems.push(`${subject}: ${at}.key 要是 lowerCamelCase 的标识符(如 \`sync\` / \`podLogs\`),现在是 ${JSON.stringify(tool.key)} —— 它会变成生成物里的键名,所以不引号、不许带点或横线`);
|
|
503
|
+
else if (seenKeys.has(key)) problems.push(`${subject}: ${at}.key「${key}」与前面那条撞了 —— 生成物里的键只能有一个`);
|
|
504
|
+
else seenKeys.add(key);
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
const host = raw.host;
|
|
510
|
+
if (host !== void 0) {
|
|
511
|
+
if (!isRecord(host)) problems.push(`${subject}: dsh.workbench.host 要是对象,现在是 ${JSON.stringify(host)}`);
|
|
512
|
+
else {
|
|
513
|
+
const extra = outsideKeys(host, HOST_KEYS);
|
|
514
|
+
if (extra.length > 0) problems.push(`${subject}: dsh.workbench.host 里有不认的键 ${listOf(extra)} —— host 只有 ${listOf(HOST_KEYS)}`);
|
|
515
|
+
if (host.inject === void 0) problems.push(`${subject}: dsh.workbench.host.inject 没写 —— 它声明这个模块要外壳的哪几个服务,外壳靠它判"能不能挂"。一个都不要也要写 \`"inject": []\``);
|
|
516
|
+
else problems.push(...stringArrayProblems(`${subject}: dsh.workbench.host.inject`, host.inject));
|
|
517
|
+
if (host.optional !== void 0) problems.push(...stringArrayProblems(`${subject}: dsh.workbench.host.optional`, host.optional));
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
if (raw.env !== void 0 && !isRecord(raw.env)) problems.push(`${subject}: dsh.workbench.env 要是对象(command / plugins / libs)—— 语义由门禁的 env 判据查,这里只查形状`);
|
|
521
|
+
return problems;
|
|
522
|
+
}
|
|
523
|
+
function readDeclaration(subject, raw) {
|
|
524
|
+
const problems = declarationProblemsOf(subject, raw);
|
|
525
|
+
if (problems.length > 0) return { problems };
|
|
526
|
+
const declaration = raw;
|
|
527
|
+
const card = declaration.card;
|
|
528
|
+
return {
|
|
529
|
+
declaration,
|
|
530
|
+
problems: [],
|
|
531
|
+
manifest: {
|
|
532
|
+
id: text(declaration.unit),
|
|
533
|
+
card: card === null ? null : {
|
|
534
|
+
titleKey: text(card.titleKey),
|
|
535
|
+
order: card.order
|
|
536
|
+
},
|
|
537
|
+
tools: declaration.tools.map((tool) => ({
|
|
538
|
+
name: text(tool.name),
|
|
539
|
+
writes: tool.writes
|
|
540
|
+
})),
|
|
541
|
+
host: {
|
|
542
|
+
inject: [...declaration.host.inject ?? []],
|
|
543
|
+
...declaration.host.optional === void 0 ? {} : { optional: [...declaration.host.optional] }
|
|
544
|
+
},
|
|
545
|
+
...declaration.env === void 0 ? {} : { env: declaration.env }
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
}
|
|
422
549
|
//#endregion
|
|
423
550
|
//#region ../shared/dist/config/constants.js
|
|
424
551
|
var PLUGIN_ID = "@dsh-workbench/core";
|
|
@@ -606,7 +733,7 @@ function ApprovalDetail(props) {
|
|
|
606
733
|
if (owner?.approval !== void 0) {
|
|
607
734
|
const Render = owner.approval.render;
|
|
608
735
|
return h(CardBoundary, {
|
|
609
|
-
unit: owner.
|
|
736
|
+
unit: owner.unit,
|
|
610
737
|
resetKey: props.callId ?? "",
|
|
611
738
|
t
|
|
612
739
|
}, h(Render, {
|
|
@@ -1107,7 +1234,7 @@ var en = {
|
|
|
1107
1234
|
"panels.market.missing": "not installed",
|
|
1108
1235
|
"panels.market.unchecked": "unknown",
|
|
1109
1236
|
"panels.market.checking": "checking",
|
|
1110
|
-
"panels.market.sectionInstalled": "Installed",
|
|
1237
|
+
"panels.market.sectionInstalled": "Installed modules",
|
|
1111
1238
|
"panels.market.sectionPending": "Not installed",
|
|
1112
1239
|
"panels.market.sectionShared": "Shared dependencies",
|
|
1113
1240
|
"panels.market.sharedUsedBy": "Used by {modules}",
|
|
@@ -1135,11 +1262,19 @@ var en = {
|
|
|
1135
1262
|
"panels.market.noSource": "This module declares no install method — install it yourself",
|
|
1136
1263
|
"panels.market.badSource": "The install method is incomplete — install it yourself",
|
|
1137
1264
|
"panels.market.empty": "No modules available",
|
|
1138
|
-
"panels.market.
|
|
1139
|
-
"panels.market.sectionLocal": "Linked locally",
|
|
1265
|
+
"panels.market.sectionLocal": "Local modules",
|
|
1140
1266
|
"panels.market.sectionUnlisted": "Not from the market",
|
|
1267
|
+
"panels.market.sectionPlugins": "Installed opencli plugins",
|
|
1141
1268
|
"panels.market.moduleOutdated": "update available",
|
|
1269
|
+
"panels.market.moduleRefused": "This module was built for an older version of the workbench, so it does not work here. Update it, or uninstall.",
|
|
1270
|
+
"panels.market.moduleRefusedDetail": "Why it cannot be used: {reason}",
|
|
1142
1271
|
"panels.market.moduleRestartHint": "installed but not active — restart dsh once to bring it up",
|
|
1272
|
+
"panels.market.pluginKeptInUse": "Files kept for now: {names} still uses it.",
|
|
1273
|
+
"panels.market.pluginKeptUnsure": "Files kept for now: some modules on this machine do not say what they use, so it is unclear who needs it.",
|
|
1274
|
+
"panels.market.pluginKeptHeld": "Files kept: this one is yours, and a module letting go will not remove it.",
|
|
1275
|
+
"panels.market.pluginKeptUnnamed": "Files kept for now: this one cannot be identified as a plugin, so it is unclear who needs it.",
|
|
1276
|
+
"panels.market.pluginAlsoKnownAs": "Its package is {pkg} (updates and uninstall use that)",
|
|
1277
|
+
"panels.market.pluginBroken": "This install is broken: it cannot be identified as a plugin. Uninstall it, or install it again by package name above.",
|
|
1143
1278
|
"panels.market.restartNeeded": "The new version is installed — restart once to pick it up.",
|
|
1144
1279
|
"panels.market.foot": "After installing, enable it in the panel page of that project.",
|
|
1145
1280
|
"panels.market.recheck": "Check for updates",
|
|
@@ -1187,7 +1322,11 @@ var en = {
|
|
|
1187
1322
|
"panels.market.add.problemInstalled": "This module is already installed",
|
|
1188
1323
|
"panels.market.add.problemNotFound": "No such module found",
|
|
1189
1324
|
"panels.market.add.problemNotPackage": "That path does not exist or is not a valid module package",
|
|
1190
|
-
"panels.market.add.problemNotBundle": "This package
|
|
1325
|
+
"panels.market.add.problemNotBundle": "This package cannot be installed here: {reason}. If it is actually an opencli plugin, use its package name (for example opencli-plugin-cmdb) or a local folder — a git URL or tarball does not reveal what it is.",
|
|
1326
|
+
"panels.market.add.problemNotWorkbenchModule": "This package does not match the workbench you are running, so installing it would not work. Pick another version, or ask the module author.",
|
|
1327
|
+
"panels.market.add.problemNotModuleOrPlugin": "This package is neither a workbench module nor an opencli plugin, so installing it would do nothing. Pick another version, or ask the package author.",
|
|
1328
|
+
"panels.market.add.failureNotModuleOrPlugin": "This package is neither a workbench module nor an opencli plugin, so installing it would do nothing",
|
|
1329
|
+
"panels.market.add.installedPlugin": "Installed: the opencli plugin {name}",
|
|
1191
1330
|
"panels.market.add.problemNetwork": "Cannot reach the module source; check the network and retry",
|
|
1192
1331
|
"panels.market.add.problemUnknown": "Cannot fetch module information: {reason}",
|
|
1193
1332
|
"panels.market.add.failureNetwork": "The network connection failed",
|
|
@@ -1218,6 +1357,7 @@ var en = {
|
|
|
1218
1357
|
"panels.market.add.registryPnpm": "pnpm's own registry",
|
|
1219
1358
|
"panels.market.add.check": "Check",
|
|
1220
1359
|
"panels.market.add.checking": "Checking…",
|
|
1360
|
+
"panels.market.add.classifying": "Working out what it is…",
|
|
1221
1361
|
"panels.market.add.change": "Edit",
|
|
1222
1362
|
"panels.market.add.previewTitle": "About to install",
|
|
1223
1363
|
"panels.market.add.fieldName": "Package",
|
|
@@ -1422,7 +1562,7 @@ var zh = {
|
|
|
1422
1562
|
"panels.market.missing": "未装",
|
|
1423
1563
|
"panels.market.unchecked": "状态未知",
|
|
1424
1564
|
"panels.market.checking": "检测中",
|
|
1425
|
-
"panels.market.sectionInstalled": "
|
|
1565
|
+
"panels.market.sectionInstalled": "已安装模块",
|
|
1426
1566
|
"panels.market.sectionPending": "未安装",
|
|
1427
1567
|
"panels.market.sectionShared": "共用依赖",
|
|
1428
1568
|
"panels.market.sharedUsedBy": "供 {modules} 使用",
|
|
@@ -1450,11 +1590,19 @@ var zh = {
|
|
|
1450
1590
|
"panels.market.noSource": "这个模块没声明怎么装,只能自己动手",
|
|
1451
1591
|
"panels.market.badSource": "安装方式没写全,只能自己动手",
|
|
1452
1592
|
"panels.market.empty": "暂无可用模块",
|
|
1453
|
-
"panels.market.
|
|
1454
|
-
"panels.market.sectionLocal": "本地装的",
|
|
1593
|
+
"panels.market.sectionLocal": "本地模块",
|
|
1455
1594
|
"panels.market.sectionUnlisted": "不是从市场装的",
|
|
1595
|
+
"panels.market.sectionPlugins": "已安装 opencli 插件",
|
|
1456
1596
|
"panels.market.moduleOutdated": "有新版",
|
|
1597
|
+
"panels.market.moduleRefused": "这个模块是给旧版本的工作台写的,现在用不了。更新它,或者卸载。",
|
|
1598
|
+
"panels.market.moduleRefusedDetail": "装不上的原因:{reason}",
|
|
1457
1599
|
"panels.market.moduleRestartHint": "装好了但还没生效 —— 重启一次 dsh 就会出来",
|
|
1600
|
+
"panels.market.pluginKeptInUse": "文件先留着:{names} 还要用它。",
|
|
1601
|
+
"panels.market.pluginKeptUnsure": "文件先留着:这台机器上还有模块看不出用了什么,说不准谁在用它。",
|
|
1602
|
+
"panels.market.pluginKeptHeld": "文件留着:你自己装的那一份,模块放手不动它。",
|
|
1603
|
+
"panels.market.pluginKeptUnnamed": "文件先留着:看不出这是哪个插件,说不准谁在用它。",
|
|
1604
|
+
"panels.market.pluginAlsoKnownAs": "包名是 {pkg}(更新与卸载按它来)",
|
|
1605
|
+
"panels.market.pluginBroken": "这份装坏了:看不出它是个插件。可以卸载,或者去上面按包名再装一次。",
|
|
1458
1606
|
"panels.market.restartNeeded": "新版装好了,重启一次才生效。",
|
|
1459
1607
|
"panels.market.foot": "装好后到那个项目的面板页勾选它,模块才会出现。",
|
|
1460
1608
|
"panels.market.recheck": "重新检查更新",
|
|
@@ -1502,7 +1650,11 @@ var zh = {
|
|
|
1502
1650
|
"panels.market.add.problemInstalled": "该模块已安装",
|
|
1503
1651
|
"panels.market.add.problemNotFound": "未找到相关模块",
|
|
1504
1652
|
"panels.market.add.problemNotPackage": "该路径不存在或不是有效的模块包",
|
|
1505
|
-
"panels.market.add.problemNotBundle": "
|
|
1653
|
+
"panels.market.add.problemNotBundle": "这个包装不进这里:{reason}。要是它其实是个 opencli 插件,请改用包名(例如 opencli-plugin-cmdb)或者本地目录 —— 从 git 地址和 tarball 判断不出它是什么。",
|
|
1654
|
+
"panels.market.add.problemNotWorkbenchModule": "这个包跟现在的工作台对不上,装上也用不了。换一个版本,或者找这个模块的作者。",
|
|
1655
|
+
"panels.market.add.problemNotModuleOrPlugin": "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上。换一个版本,或者找这个包的作者。",
|
|
1656
|
+
"panels.market.add.failureNotModuleOrPlugin": "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上",
|
|
1657
|
+
"panels.market.add.installedPlugin": "装上了:opencli 插件 {name}",
|
|
1506
1658
|
"panels.market.add.problemNetwork": "无法连接模块源,请检查网络后重试",
|
|
1507
1659
|
"panels.market.add.problemUnknown": "无法获取模块信息:{reason}",
|
|
1508
1660
|
"panels.market.add.failureNetwork": "网络连接失败",
|
|
@@ -1533,6 +1685,7 @@ var zh = {
|
|
|
1533
1685
|
"panels.market.add.registryPnpm": "pnpm 自己配的源",
|
|
1534
1686
|
"panels.market.add.check": "预检",
|
|
1535
1687
|
"panels.market.add.checking": "正在预检…",
|
|
1688
|
+
"panels.market.add.classifying": "判定中…",
|
|
1536
1689
|
"panels.market.add.change": "改一下",
|
|
1537
1690
|
"panels.market.add.previewTitle": "将要安装",
|
|
1538
1691
|
"panels.market.add.fieldName": "包名",
|
|
@@ -1809,6 +1962,8 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1809
1962
|
CenteredState: () => CenteredState,
|
|
1810
1963
|
ChoiceGroup: () => ChoiceGroup,
|
|
1811
1964
|
Component: () => Component,
|
|
1965
|
+
DECLARATION_KEYS: () => DECLARATION_KEYS,
|
|
1966
|
+
DECLARATION_REQUIRED_KEYS: () => DECLARATION_REQUIRED_KEYS,
|
|
1812
1967
|
DEFAULT_WORKSPACE_TITLE: () => DEFAULT_WORKSPACE_TITLE,
|
|
1813
1968
|
EVENTS_PATH: () => EVENTS_PATH,
|
|
1814
1969
|
EmptyState: () => EmptyState,
|
|
@@ -1847,6 +2002,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1847
2002
|
STORAGE_KEY_PROJECT: () => STORAGE_KEY_PROJECT,
|
|
1848
2003
|
STORAGE_KEY_RIGHTBAR: () => STORAGE_KEY_RIGHTBAR,
|
|
1849
2004
|
STORAGE_KEY_RIGHTBAR_COLUMN: () => STORAGE_KEY_RIGHTBAR_COLUMN,
|
|
2005
|
+
SUPPORTED_API_VERSIONS: () => SUPPORTED_API_VERSIONS,
|
|
1850
2006
|
SaveBar: () => SaveBar,
|
|
1851
2007
|
SettingsSection: () => SettingsSection,
|
|
1852
2008
|
SkeletonRows: () => SkeletonRows,
|
|
@@ -1857,6 +2013,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1857
2013
|
VERSION_CHECK_TIMEOUT_MS: () => VERSION_CHECK_TIMEOUT_MS,
|
|
1858
2014
|
VERSION_CHECK_TTL_MS: () => VERSION_CHECK_TTL_MS,
|
|
1859
2015
|
WARM_TIMEOUT_MS: () => WARM_TIMEOUT_MS,
|
|
2016
|
+
WORKBENCH_API_VERSION: () => 1,
|
|
1860
2017
|
apiGet: () => apiGet,
|
|
1861
2018
|
apiPost: () => apiPost,
|
|
1862
2019
|
blockerActionLabel: () => blockerActionLabel,
|
|
@@ -1866,6 +2023,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1866
2023
|
buildMarker: () => buildMarker,
|
|
1867
2024
|
createFactChannel: () => createFactChannel,
|
|
1868
2025
|
cx: () => cx,
|
|
2026
|
+
declarationProblemsOf: () => declarationProblemsOf,
|
|
1869
2027
|
decodeRef: () => decodeRef,
|
|
1870
2028
|
dictionaries: () => dictionaries,
|
|
1871
2029
|
en: () => en,
|
|
@@ -1889,6 +2047,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1889
2047
|
parseMarkers: () => parseMarkers,
|
|
1890
2048
|
probeKeyOf: () => probeKeyOf,
|
|
1891
2049
|
quoteShellArg: () => quoteShellArg,
|
|
2050
|
+
readDeclaration: () => readDeclaration,
|
|
1892
2051
|
readFlag: () => readFlag,
|
|
1893
2052
|
readText: () => readText,
|
|
1894
2053
|
relativeTime: () => relativeTime,
|
|
@@ -2001,6 +2160,7 @@ function createAdaptiveTransport() {
|
|
|
2001
2160
|
//#endregion
|
|
2002
2161
|
//#region src/shared/hooks/use-facts.ts
|
|
2003
2162
|
var use_facts_exports = /* @__PURE__ */ __exportAll({
|
|
2163
|
+
subscribeFactRevision: () => subscribeFactRevision,
|
|
2004
2164
|
useFactInvalidate: () => useFactInvalidate,
|
|
2005
2165
|
useFactRevision: () => useFactRevision
|
|
2006
2166
|
});
|
|
@@ -2008,6 +2168,9 @@ var channel = createFactChannel({ transport: createAdaptiveTransport() });
|
|
|
2008
2168
|
function useFactRevision(fact) {
|
|
2009
2169
|
return useSyncExternalStore(useCallback((listener) => channel.subscribe(fact, listener), [fact]), useCallback(() => channel.revisionOf(fact), [fact]));
|
|
2010
2170
|
}
|
|
2171
|
+
function subscribeFactRevision(fact, listener) {
|
|
2172
|
+
return channel.subscribe(fact, listener);
|
|
2173
|
+
}
|
|
2011
2174
|
function useFactInvalidate() {
|
|
2012
2175
|
return useCallback((fact) => channel.refresh(fact), []);
|
|
2013
2176
|
}
|
|
@@ -2235,6 +2398,9 @@ function panelRowName(label, hint, t) {
|
|
|
2235
2398
|
//#endregion
|
|
2236
2399
|
//#region src/app/layouts/rightbar/market-freshness.ts
|
|
2237
2400
|
var MARKET_STALE_MS = VERSION_CHECK_TTL_MS;
|
|
2401
|
+
function marketSettled(freshness, installedRead) {
|
|
2402
|
+
return freshness.loaded && installedRead !== false;
|
|
2403
|
+
}
|
|
2238
2404
|
function shouldProbeOnEnter(input) {
|
|
2239
2405
|
if (input.checkedAt === null) return true;
|
|
2240
2406
|
return input.now - input.checkedAt >= input.staleMs;
|
|
@@ -2532,8 +2698,7 @@ function buildMarketMocks(roster) {
|
|
|
2532
2698
|
...mine,
|
|
2533
2699
|
card: {
|
|
2534
2700
|
titleKey: "一个名字特别特别长的模块用来验证省略号会不会把按钮挤下去",
|
|
2535
|
-
order: 10
|
|
2536
|
-
enabledByDefault: true
|
|
2701
|
+
order: 10
|
|
2537
2702
|
}
|
|
2538
2703
|
}],
|
|
2539
2704
|
capabilities: probe$1(id, "ok"),
|
|
@@ -2637,6 +2802,24 @@ function buildMarketMocks(roster) {
|
|
|
2637
2802
|
installedActions: ["update-bundle", "remove-bundle"]
|
|
2638
2803
|
}
|
|
2639
2804
|
},
|
|
2805
|
+
{
|
|
2806
|
+
id: "installed-client-refused",
|
|
2807
|
+
label: "本机装了,但浏览器这半没挂上(拒因由客户端报告)",
|
|
2808
|
+
manifests: [found],
|
|
2809
|
+
capabilities: {},
|
|
2810
|
+
installed: [{
|
|
2811
|
+
unit: id,
|
|
2812
|
+
pkg: "@dsh-workbench/module-one",
|
|
2813
|
+
installed: "0.1.2",
|
|
2814
|
+
clientRefused: [`宿主没有担保 unit「${id}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]
|
|
2815
|
+
}],
|
|
2816
|
+
expect: {
|
|
2817
|
+
rows: 0,
|
|
2818
|
+
installed: 1,
|
|
2819
|
+
installedActions: ["remove-bundle"],
|
|
2820
|
+
installedNote: true
|
|
2821
|
+
}
|
|
2822
|
+
},
|
|
2640
2823
|
{
|
|
2641
2824
|
id: "installed-confirm",
|
|
2642
2825
|
label: "卸载本机模块(Modal 确认,标题带模块名)",
|
|
@@ -2685,6 +2868,94 @@ function buildMarketMocks(roster) {
|
|
|
2685
2868
|
actions: ["uninstall"]
|
|
2686
2869
|
}
|
|
2687
2870
|
},
|
|
2871
|
+
{
|
|
2872
|
+
id: "plugin-outdated",
|
|
2873
|
+
label: "用户装的 opencli 插件:有新版(给更新 / 卸载)",
|
|
2874
|
+
manifests: [],
|
|
2875
|
+
capabilities: {},
|
|
2876
|
+
plugins: [{
|
|
2877
|
+
pkg: "opencli-plugin-cmdb",
|
|
2878
|
+
name: "cmdb",
|
|
2879
|
+
installed: "1.0.24",
|
|
2880
|
+
latest: "1.0.25"
|
|
2881
|
+
}],
|
|
2882
|
+
expect: {
|
|
2883
|
+
rows: 0,
|
|
2884
|
+
plugins: 1,
|
|
2885
|
+
pluginActions: ["update-plugin", "uninstall-plugin"]
|
|
2886
|
+
}
|
|
2887
|
+
},
|
|
2888
|
+
{
|
|
2889
|
+
id: "plugin-local",
|
|
2890
|
+
label: "本地目录装的 opencli 插件:没有版本源,只给卸载",
|
|
2891
|
+
manifests: [],
|
|
2892
|
+
capabilities: {},
|
|
2893
|
+
plugins: [{
|
|
2894
|
+
pkg: "/Users/me/my-local-plugin",
|
|
2895
|
+
name: "my-local-plugin",
|
|
2896
|
+
local: true
|
|
2897
|
+
}],
|
|
2898
|
+
expect: {
|
|
2899
|
+
rows: 0,
|
|
2900
|
+
plugins: 1,
|
|
2901
|
+
pluginActions: ["uninstall-plugin"],
|
|
2902
|
+
pluginNote: false
|
|
2903
|
+
}
|
|
2904
|
+
},
|
|
2905
|
+
{
|
|
2906
|
+
id: "plugin-alias",
|
|
2907
|
+
label: "插件名 ≠ 包名:行上两个都写出来(更新 / 卸载按包名)",
|
|
2908
|
+
manifests: [],
|
|
2909
|
+
capabilities: {},
|
|
2910
|
+
plugins: [{
|
|
2911
|
+
pkg: "opencli-plugin-cmdb",
|
|
2912
|
+
name: "cmdb",
|
|
2913
|
+
installed: "1.0.24",
|
|
2914
|
+
latest: "1.0.25"
|
|
2915
|
+
}],
|
|
2916
|
+
expect: {
|
|
2917
|
+
rows: 0,
|
|
2918
|
+
plugins: 1,
|
|
2919
|
+
pluginActions: ["update-plugin", "uninstall-plugin"],
|
|
2920
|
+
pluginNoteKey: "panels.market.pluginAlsoKnownAs"
|
|
2921
|
+
}
|
|
2922
|
+
},
|
|
2923
|
+
{
|
|
2924
|
+
id: "plugin-broken",
|
|
2925
|
+
label: "装坏了的那一份(目录在但看不出是个插件):行上直说,给卸载与指路",
|
|
2926
|
+
manifests: [],
|
|
2927
|
+
capabilities: {},
|
|
2928
|
+
plugins: [{
|
|
2929
|
+
pkg: "opencli-plugin-cmdb",
|
|
2930
|
+
name: "cmdb",
|
|
2931
|
+
installed: "1.0.24",
|
|
2932
|
+
broken: true
|
|
2933
|
+
}],
|
|
2934
|
+
expect: {
|
|
2935
|
+
rows: 0,
|
|
2936
|
+
plugins: 1,
|
|
2937
|
+
pluginActions: ["uninstall-plugin"],
|
|
2938
|
+
pluginNoteKey: "panels.market.pluginBroken"
|
|
2939
|
+
}
|
|
2940
|
+
},
|
|
2941
|
+
{
|
|
2942
|
+
id: "plugin-kept",
|
|
2943
|
+
label: "卸掉用户装的插件,但还有模块在用:文件先留着(行上给一句为什么)",
|
|
2944
|
+
manifests: [],
|
|
2945
|
+
capabilities: {},
|
|
2946
|
+
plugins: [{
|
|
2947
|
+
pkg: "opencli-plugin-cmdb",
|
|
2948
|
+
name: "cmdb",
|
|
2949
|
+
installed: "1.0.24"
|
|
2950
|
+
}],
|
|
2951
|
+
notice: "文件先留着:cmdb、argocd 还要用它。",
|
|
2952
|
+
expect: {
|
|
2953
|
+
rows: 0,
|
|
2954
|
+
plugins: 1,
|
|
2955
|
+
pluginActions: ["uninstall-plugin"],
|
|
2956
|
+
notice: true
|
|
2957
|
+
}
|
|
2958
|
+
},
|
|
2688
2959
|
{
|
|
2689
2960
|
id: "empty",
|
|
2690
2961
|
label: "市场空态",
|
|
@@ -2742,7 +3013,6 @@ function createBoardRegistry() {
|
|
|
2742
3013
|
};
|
|
2743
3014
|
},
|
|
2744
3015
|
all: () => sorted,
|
|
2745
|
-
visible: () => sorted.filter((module) => module.enabledByDefault),
|
|
2746
3016
|
byId: (id) => index.get(id),
|
|
2747
3017
|
stepOwner: (kind) => steps.get(kind),
|
|
2748
3018
|
subscribe(listener) {
|
|
@@ -2754,20 +3024,21 @@ function createBoardRegistry() {
|
|
|
2754
3024
|
}
|
|
2755
3025
|
//#endregion
|
|
2756
3026
|
//#region src/app/units/registry.ts
|
|
2757
|
-
function toBoardModule(face) {
|
|
3027
|
+
function toBoardModule(face, manifest) {
|
|
2758
3028
|
return {
|
|
2759
|
-
id:
|
|
2760
|
-
titleKey:
|
|
2761
|
-
order:
|
|
2762
|
-
enabledByDefault: face.manifest.card?.enabledByDefault ?? false,
|
|
3029
|
+
id: manifest.id,
|
|
3030
|
+
titleKey: manifest.card?.titleKey ?? manifest.id,
|
|
3031
|
+
order: manifest.card?.order ?? 100,
|
|
2763
3032
|
View: face.card,
|
|
2764
3033
|
...face.steps === void 0 ? {} : { steps: face.steps }
|
|
2765
3034
|
};
|
|
2766
3035
|
}
|
|
2767
|
-
function createClientUnitRegistry() {
|
|
2768
|
-
const
|
|
3036
|
+
function createClientUnitRegistry(options = {}) {
|
|
3037
|
+
const registrations = [];
|
|
3038
|
+
const refusals = [];
|
|
2769
3039
|
const listeners = /* @__PURE__ */ new Set();
|
|
2770
3040
|
const board = createBoardRegistry();
|
|
3041
|
+
let known = /* @__PURE__ */ new Map();
|
|
2771
3042
|
let revision = 0;
|
|
2772
3043
|
let manifestsCache;
|
|
2773
3044
|
function notify() {
|
|
@@ -2778,28 +3049,86 @@ function createClientUnitRegistry() {
|
|
|
2778
3049
|
console.warn(`[dsh-workbench] 套件注册的订阅者报错(不影响其它订阅者与这次注册):${String(error)}`);
|
|
2779
3050
|
}
|
|
2780
3051
|
}
|
|
3052
|
+
function warnRefusal(unit, reasons) {
|
|
3053
|
+
refusals.push({
|
|
3054
|
+
unit,
|
|
3055
|
+
reasons
|
|
3056
|
+
});
|
|
3057
|
+
console.warn(`[dsh-workbench] ${unit === "" ? "这个模块" : unit} 的卡片没挂上:${reasons.join(";")}`);
|
|
3058
|
+
}
|
|
3059
|
+
function takeBackRefusal(unit) {
|
|
3060
|
+
for (let at = refusals.length - 1; at >= 0; at -= 1) if (refusals[at]?.unit === unit) refusals.splice(at, 1);
|
|
3061
|
+
}
|
|
3062
|
+
function attach(entry) {
|
|
3063
|
+
const manifest = known.get(entry.unit);
|
|
3064
|
+
if (manifest === void 0) return false;
|
|
3065
|
+
entry.mounted = {
|
|
3066
|
+
manifest,
|
|
3067
|
+
unmount: board.register(toBoardModule(entry.face, manifest))
|
|
3068
|
+
};
|
|
3069
|
+
takeBackRefusal(entry.unit);
|
|
3070
|
+
return true;
|
|
3071
|
+
}
|
|
3072
|
+
function detach(entry) {
|
|
3073
|
+
entry.mounted?.unmount();
|
|
3074
|
+
entry.mounted = null;
|
|
3075
|
+
}
|
|
2781
3076
|
return {
|
|
2782
3077
|
register(face) {
|
|
2783
|
-
const
|
|
2784
|
-
if (
|
|
2785
|
-
|
|
2786
|
-
|
|
3078
|
+
const unit = typeof face?.unit === "string" ? face.unit.trim() : "";
|
|
3079
|
+
if (unit === "") {
|
|
3080
|
+
warnRefusal("", ["registerUnit({ unit, card }) 里的 unit 是空的 —— U1b 之前的旧形状是 registerUnit({ manifest, card });现在清单由外壳从**已装清单**读出来、按 unit 交给浏览器(ADR-0038 §2.2)"]);
|
|
3081
|
+
notify();
|
|
3082
|
+
return () => {};
|
|
3083
|
+
}
|
|
3084
|
+
if (registrations.some((entry) => entry.unit === unit)) throw new Error(`套件 id 重复:${unit}(id 会进持久化配置,不能撞)`);
|
|
3085
|
+
const entry = {
|
|
3086
|
+
face,
|
|
3087
|
+
unit,
|
|
3088
|
+
mounted: null
|
|
3089
|
+
};
|
|
3090
|
+
registrations.push(entry);
|
|
2787
3091
|
manifestsCache = void 0;
|
|
3092
|
+
if (!attach(entry)) {
|
|
3093
|
+
warnRefusal(unit, [`宿主没有担保 unit「${unit}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]);
|
|
3094
|
+
options.onUnknownUnit?.(unit);
|
|
3095
|
+
}
|
|
2788
3096
|
notify();
|
|
2789
3097
|
return () => {
|
|
2790
|
-
const at =
|
|
3098
|
+
const at = registrations.indexOf(entry);
|
|
2791
3099
|
if (at < 0) return;
|
|
2792
|
-
|
|
3100
|
+
registrations.splice(at, 1);
|
|
3101
|
+
detach(entry);
|
|
3102
|
+
takeBackRefusal(unit);
|
|
2793
3103
|
manifestsCache = void 0;
|
|
2794
|
-
unregisterBoard();
|
|
2795
3104
|
notify();
|
|
2796
3105
|
};
|
|
2797
3106
|
},
|
|
2798
|
-
all: () =>
|
|
3107
|
+
all: () => registrations.map((entry) => entry.face),
|
|
2799
3108
|
manifests: () => {
|
|
2800
|
-
manifestsCache ??=
|
|
3109
|
+
manifestsCache ??= registrations.flatMap((entry) => entry.mounted === null ? [] : [entry.mounted.manifest]);
|
|
2801
3110
|
return manifestsCache;
|
|
2802
3111
|
},
|
|
3112
|
+
refusals: () => refusals,
|
|
3113
|
+
setManifests(manifests) {
|
|
3114
|
+
known = new Map(manifests.map((manifest) => [manifest.id, manifest]));
|
|
3115
|
+
let changed = false;
|
|
3116
|
+
for (const entry of registrations) {
|
|
3117
|
+
const next = known.get(entry.unit);
|
|
3118
|
+
if (entry.mounted === null) {
|
|
3119
|
+
if (next !== void 0 && attach(entry)) changed = true;
|
|
3120
|
+
continue;
|
|
3121
|
+
}
|
|
3122
|
+
if (next === void 0) {
|
|
3123
|
+
detach(entry);
|
|
3124
|
+
warnRefusal(entry.unit, [`宿主不再担保 unit「${entry.unit}」的清单(模块被卸了?)—— 这张卡片先摘下来`]);
|
|
3125
|
+
changed = true;
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
if (!changed) return;
|
|
3129
|
+
manifestsCache = void 0;
|
|
3130
|
+
notify();
|
|
3131
|
+
},
|
|
2803
3132
|
board,
|
|
2804
3133
|
subscribe(listener) {
|
|
2805
3134
|
listeners.add(listener);
|
|
@@ -2834,11 +3163,9 @@ var messages = {
|
|
|
2834
3163
|
};
|
|
2835
3164
|
var manifest = {
|
|
2836
3165
|
id: FIXTURE_UNIT_ID,
|
|
2837
|
-
kind: "board",
|
|
2838
3166
|
card: {
|
|
2839
3167
|
titleKey: KEY.cardTitle,
|
|
2840
|
-
order: 900
|
|
2841
|
-
enabledByDefault: true
|
|
3168
|
+
order: 900
|
|
2842
3169
|
},
|
|
2843
3170
|
tools: [],
|
|
2844
3171
|
host: { inject: [] }
|
|
@@ -2861,6 +3188,7 @@ function FixtureCard({ t, onRefresh }) {
|
|
|
2861
3188
|
}))));
|
|
2862
3189
|
}
|
|
2863
3190
|
var FIXTURE_FACE = {
|
|
3191
|
+
unit: FIXTURE_UNIT_ID,
|
|
2864
3192
|
manifest,
|
|
2865
3193
|
messages,
|
|
2866
3194
|
card: FixtureCard
|
|
@@ -2881,11 +3209,9 @@ var crashMessages = {
|
|
|
2881
3209
|
};
|
|
2882
3210
|
var crashManifest = {
|
|
2883
3211
|
id: CRASH_UNIT_ID,
|
|
2884
|
-
kind: "board",
|
|
2885
3212
|
card: {
|
|
2886
3213
|
titleKey: CRASH_KEY.cardTitle,
|
|
2887
|
-
order: 899
|
|
2888
|
-
enabledByDefault: true
|
|
3214
|
+
order: 899
|
|
2889
3215
|
},
|
|
2890
3216
|
tools: [],
|
|
2891
3217
|
host: { inject: [] }
|
|
@@ -2894,6 +3220,7 @@ function CrashingCard() {
|
|
|
2894
3220
|
throw new Error("夹具:这张卡片按 wbCrash=1 故意渲染失败(守「一张卡片崩溃不带走面板」)");
|
|
2895
3221
|
}
|
|
2896
3222
|
var CRASH_FACE = {
|
|
3223
|
+
unit: CRASH_UNIT_ID,
|
|
2897
3224
|
manifest: crashManifest,
|
|
2898
3225
|
messages: crashMessages,
|
|
2899
3226
|
card: CrashingCard
|
|
@@ -2906,8 +3233,8 @@ function fixtureRoster(roster) {
|
|
|
2906
3233
|
return hasCard(roster) ? roster : SAMPLE_ROSTER;
|
|
2907
3234
|
}
|
|
2908
3235
|
function fixtureSeed(roster, all, crash = false) {
|
|
2909
|
-
const base = hasCard(roster) ? all : [toBoardModule(FIXTURE_FACE)];
|
|
2910
|
-
return crash ? [toBoardModule(CRASH_FACE), ...base] : base;
|
|
3236
|
+
const base = hasCard(roster) ? all : [toBoardModule(FIXTURE_FACE, FIXTURE_FACE.manifest)];
|
|
3237
|
+
return crash ? [toBoardModule(CRASH_FACE, CRASH_FACE.manifest), ...base] : base;
|
|
2911
3238
|
}
|
|
2912
3239
|
//#endregion
|
|
2913
3240
|
//#region src/app/layouts/rightbar/market-rows.ts
|
|
@@ -2927,6 +3254,25 @@ var MARKET_DOT = {
|
|
|
2927
3254
|
unchecked: "idle",
|
|
2928
3255
|
unknown: "idle"
|
|
2929
3256
|
};
|
|
3257
|
+
function marketRowTitle(row, t) {
|
|
3258
|
+
return row.label ?? t(row.titleKey);
|
|
3259
|
+
}
|
|
3260
|
+
function withClientRefusals(modules, refusals) {
|
|
3261
|
+
if (refusals.length === 0) return modules;
|
|
3262
|
+
const byUnit = new Map(refusals.map((one) => [one.unit, one.reasons]));
|
|
3263
|
+
return modules.map((module) => {
|
|
3264
|
+
const reasons = byUnit.get(module.unit);
|
|
3265
|
+
return reasons === void 0 ? module : {
|
|
3266
|
+
...module,
|
|
3267
|
+
clientRefused: reasons
|
|
3268
|
+
};
|
|
3269
|
+
});
|
|
3270
|
+
}
|
|
3271
|
+
function refusalReasons(host, client) {
|
|
3272
|
+
const reported = host ?? [];
|
|
3273
|
+
if (reported.length > 0) return reported;
|
|
3274
|
+
return [...new Set(client ?? [])];
|
|
3275
|
+
}
|
|
2930
3276
|
function mergeTitles(known, manifests) {
|
|
2931
3277
|
let next = null;
|
|
2932
3278
|
for (const manifest of manifests) {
|
|
@@ -2945,11 +3291,16 @@ function installedRows(modules, manifests, listed, known) {
|
|
|
2945
3291
|
const latest = module.latest;
|
|
2946
3292
|
const outdated = latest !== void 0 && latest !== module.installed;
|
|
2947
3293
|
const loaded = titles.has(module.unit);
|
|
3294
|
+
const refused = refusalReasons(module.refused, module.clientRefused);
|
|
2948
3295
|
rows.push({
|
|
2949
3296
|
id: module.unit,
|
|
2950
3297
|
titleKey: titles.get(module.unit) ?? known?.get(module.unit) ?? module.pkg,
|
|
2951
3298
|
state: outdated ? "outdated" : "installed",
|
|
2952
|
-
...loaded ? {} : { hint: "panels.market.moduleRestartHint" },
|
|
3299
|
+
...loaded || refused.length > 0 ? {} : { hint: "panels.market.moduleRestartHint" },
|
|
3300
|
+
...refused.length === 0 ? {} : { note: {
|
|
3301
|
+
key: "panels.market.moduleRefused",
|
|
3302
|
+
params: { reason: refused.join(";") }
|
|
3303
|
+
} },
|
|
2953
3304
|
...module.local === true ? { local: true } : {},
|
|
2954
3305
|
pkg: module.pkg,
|
|
2955
3306
|
canInstall: false,
|
|
@@ -2968,6 +3319,7 @@ function installedRows(modules, manifests, listed, known) {
|
|
|
2968
3319
|
return rows;
|
|
2969
3320
|
}
|
|
2970
3321
|
function marketActions$1(row) {
|
|
3322
|
+
if (row.plugin === true) return [...row.canUpdate ? ["update-plugin"] : [], ...row.canUninstall ? ["uninstall-plugin"] : []];
|
|
2971
3323
|
return [
|
|
2972
3324
|
...row.canInstall ? ["install"] : [],
|
|
2973
3325
|
...row.moduleUpdate === void 0 ? row.canUpdate ? ["update"] : [] : ["update-bundle"],
|
|
@@ -2991,7 +3343,7 @@ function envNameOf(source) {
|
|
|
2991
3343
|
if (source.kind === "npm") return source.registryEnv;
|
|
2992
3344
|
return "";
|
|
2993
3345
|
}
|
|
2994
|
-
function noteOf(state, install, manifest) {
|
|
3346
|
+
function noteOf$1(state, install, manifest) {
|
|
2995
3347
|
if (state === "installed") return void 0;
|
|
2996
3348
|
if (install === "env-missing") return {
|
|
2997
3349
|
key: "panels.market.needEnv",
|
|
@@ -3050,7 +3402,7 @@ function marketRows(manifests, capabilities, updates = {}) {
|
|
|
3050
3402
|
const capability = capabilities?.[manifest.id];
|
|
3051
3403
|
const install = capability?.install;
|
|
3052
3404
|
const state = capabilities === null ? "checking" : stateOf(capability);
|
|
3053
|
-
const note = noteOf(state, install, manifest);
|
|
3405
|
+
const note = noteOf$1(state, install, manifest);
|
|
3054
3406
|
const onMachine = isOnMachine(state);
|
|
3055
3407
|
const reAdopt = capability?.released === true && install === void 0;
|
|
3056
3408
|
const entry = updates[manifest.id];
|
|
@@ -3222,6 +3574,60 @@ function useHostWrite(options) {
|
|
|
3222
3574
|
};
|
|
3223
3575
|
}
|
|
3224
3576
|
//#endregion
|
|
3577
|
+
//#region src/app/layouts/rightbar/market-plugin-rows.ts
|
|
3578
|
+
function installedPluginKept(value) {
|
|
3579
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
3580
|
+
const kept = value.kept;
|
|
3581
|
+
if (typeof kept !== "object" || kept === null) return void 0;
|
|
3582
|
+
const kind = kept.kind;
|
|
3583
|
+
if (kind === "held") return { key: "panels.market.pluginKeptHeld" };
|
|
3584
|
+
if (kind === "unnamed") return { key: "panels.market.pluginKeptUnnamed" };
|
|
3585
|
+
if (kind === "unsure") return { key: "panels.market.pluginKeptUnsure" };
|
|
3586
|
+
if (kind !== "claimed") return void 0;
|
|
3587
|
+
const raw = kept.by;
|
|
3588
|
+
const names = Array.isArray(raw) ? raw.filter((item) => typeof item === "string") : [];
|
|
3589
|
+
return names.length === 0 ? { key: "panels.market.pluginKeptUnsure" } : {
|
|
3590
|
+
key: "panels.market.pluginKeptInUse",
|
|
3591
|
+
names
|
|
3592
|
+
};
|
|
3593
|
+
}
|
|
3594
|
+
function noteOf(plugin) {
|
|
3595
|
+
if (plugin.broken === true) return {
|
|
3596
|
+
key: "panels.market.pluginBroken",
|
|
3597
|
+
params: {}
|
|
3598
|
+
};
|
|
3599
|
+
if (plugin.local === true) return void 0;
|
|
3600
|
+
if (plugin.name !== void 0 && plugin.name !== plugin.pkg) return {
|
|
3601
|
+
key: "panels.market.pluginAlsoKnownAs",
|
|
3602
|
+
params: { pkg: plugin.pkg }
|
|
3603
|
+
};
|
|
3604
|
+
}
|
|
3605
|
+
function installedPluginRows(plugins) {
|
|
3606
|
+
return plugins.map((plugin) => {
|
|
3607
|
+
const name = plugin.name ?? plugin.pkg;
|
|
3608
|
+
const outdated = plugin.installed !== void 0 && plugin.latest !== void 0 && plugin.latest !== plugin.installed;
|
|
3609
|
+
const note = noteOf(plugin);
|
|
3610
|
+
return {
|
|
3611
|
+
id: `plugin:${plugin.pkg}`,
|
|
3612
|
+
titleKey: plugin.pkg,
|
|
3613
|
+
label: name,
|
|
3614
|
+
plugin: true,
|
|
3615
|
+
state: outdated ? "outdated" : "installed",
|
|
3616
|
+
canInstall: false,
|
|
3617
|
+
canUpdate: outdated,
|
|
3618
|
+
canUninstall: true,
|
|
3619
|
+
...plugin.local === true ? { local: true } : {},
|
|
3620
|
+
...plugin.broken === true ? { broken: true } : {},
|
|
3621
|
+
...note === void 0 ? {} : { note },
|
|
3622
|
+
pkg: plugin.pkg,
|
|
3623
|
+
...plugin.installed === void 0 ? {} : { version: {
|
|
3624
|
+
installed: plugin.installed,
|
|
3625
|
+
...plugin.latest === void 0 ? {} : { latest: plugin.latest }
|
|
3626
|
+
} }
|
|
3627
|
+
};
|
|
3628
|
+
});
|
|
3629
|
+
}
|
|
3630
|
+
//#endregion
|
|
3225
3631
|
//#region src/app/layouts/market/add-module-text.ts
|
|
3226
3632
|
var GUIDE_ITEMS = [
|
|
3227
3633
|
{
|
|
@@ -3340,17 +3746,23 @@ var PROBLEM_KEYS = {
|
|
|
3340
3746
|
"not-found": "panels.market.add.problemNotFound",
|
|
3341
3747
|
"not-a-package": "panels.market.add.problemNotPackage",
|
|
3342
3748
|
"not-a-bundle": "panels.market.add.problemNotBundle",
|
|
3749
|
+
"not-a-workbench-module": "panels.market.add.problemNotWorkbenchModule",
|
|
3750
|
+
"not-a-module-or-plugin": "panels.market.add.problemNotModuleOrPlugin",
|
|
3343
3751
|
network: "panels.market.add.problemNetwork",
|
|
3344
3752
|
unknown: "panels.market.add.problemUnknown"
|
|
3345
3753
|
};
|
|
3346
3754
|
function problemKey(problem) {
|
|
3347
3755
|
return PROBLEM_KEYS[problem] ?? PROBLEM_KEYS.unknown;
|
|
3348
3756
|
}
|
|
3757
|
+
function heldWizardPhase(phase, classifying) {
|
|
3758
|
+
return classifying && (phase === "preview" || phase === "idle") ? "inspecting" : phase;
|
|
3759
|
+
}
|
|
3349
3760
|
var FAILURE_KEYS = {
|
|
3350
3761
|
network: "panels.market.add.failureNetwork",
|
|
3351
3762
|
"spec-host": "panels.market.add.failureNetworkHost",
|
|
3352
3763
|
"not-found": "panels.market.add.failureNotFound",
|
|
3353
3764
|
"no-matching-version": "panels.market.add.failureNoMatchingVersion",
|
|
3765
|
+
"not-a-module-or-plugin": "panels.market.add.failureNotModuleOrPlugin",
|
|
3354
3766
|
"disk-full": "panels.market.add.failureDiskFull",
|
|
3355
3767
|
permission: "panels.market.add.failurePermission",
|
|
3356
3768
|
"build-blocked": "panels.market.add.failureBuildBlocked",
|
|
@@ -3455,7 +3867,9 @@ var PROGRESS_KEY = {
|
|
|
3455
3867
|
"update-bundle": "panels.market.updating",
|
|
3456
3868
|
"remove-bundle": "panels.market.uninstalling",
|
|
3457
3869
|
uninstall: "panels.market.uninstalling",
|
|
3458
|
-
"update-dependency": "panels.market.updating"
|
|
3870
|
+
"update-dependency": "panels.market.updating",
|
|
3871
|
+
"update-plugin": "panels.market.updating",
|
|
3872
|
+
"uninstall-plugin": "panels.market.uninstalling"
|
|
3459
3873
|
};
|
|
3460
3874
|
var ACTION_LABEL_KEY = {
|
|
3461
3875
|
install: "panels.market.install",
|
|
@@ -3463,7 +3877,9 @@ var ACTION_LABEL_KEY = {
|
|
|
3463
3877
|
"update-bundle": "panels.market.update",
|
|
3464
3878
|
"remove-bundle": "panels.market.uninstall",
|
|
3465
3879
|
uninstall: "panels.market.uninstall",
|
|
3466
|
-
"update-dependency": "panels.market.update"
|
|
3880
|
+
"update-dependency": "panels.market.update",
|
|
3881
|
+
"update-plugin": "panels.market.update",
|
|
3882
|
+
"uninstall-plugin": "panels.market.uninstall"
|
|
3467
3883
|
};
|
|
3468
3884
|
//#endregion
|
|
3469
3885
|
//#region src/app/layouts/rightbar/SharedSection.tsx
|
|
@@ -3525,7 +3941,11 @@ function PanelFoot({ text, size = "sm", children }) {
|
|
|
3525
3941
|
}
|
|
3526
3942
|
//#endregion
|
|
3527
3943
|
//#region src/app/layouts/rightbar/MarketView.tsx
|
|
3528
|
-
var CONFIRM_UNINSTALL = [
|
|
3944
|
+
var CONFIRM_UNINSTALL = [
|
|
3945
|
+
"uninstall",
|
|
3946
|
+
"remove-bundle",
|
|
3947
|
+
"uninstall-plugin"
|
|
3948
|
+
];
|
|
3529
3949
|
var CONFIRM_REMOVE = ["remove-bundle"];
|
|
3530
3950
|
function MarketLine({ t, row, pending, failure, onAct }) {
|
|
3531
3951
|
const running = pending !== null && pending.id === row.id ? pending : null;
|
|
@@ -3535,7 +3955,7 @@ function MarketLine({ t, row, pending, failure, onAct }) {
|
|
|
3535
3955
|
return /* @__PURE__ */ h("li", { className: MarketPage_module_default.marketRow }, /* @__PURE__ */ h("span", {
|
|
3536
3956
|
className: MarketPage_module_default.marketIcon,
|
|
3537
3957
|
"aria-hidden": "true"
|
|
3538
|
-
}, /* @__PURE__ */ h(IconModules, { size: 18 })), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketMain }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketName },
|
|
3958
|
+
}, /* @__PURE__ */ h(IconModules, { size: 18 })), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketMain }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketName }, marketRowTitle(row, t), row.version === void 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketVersion }, row.version.installed !== void 0 && row.version.latest !== void 0 && row.version.installed !== row.version.latest ? t("panels.market.versionArrow", {
|
|
3539
3959
|
from: row.version.installed,
|
|
3540
3960
|
to: row.version.latest
|
|
3541
3961
|
}) : row.version.installed ?? row.version.latest ?? "")), /* @__PURE__ */ h("span", {
|
|
@@ -3560,11 +3980,14 @@ function MarketLine({ t, row, pending, failure, onAct }) {
|
|
|
3560
3980
|
variant: action === "install" ? "primary" : "outline",
|
|
3561
3981
|
className: danger ? "wb-dangerAction" : void 0,
|
|
3562
3982
|
icon: danger ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineRegular, { size: 13 }) : void 0,
|
|
3563
|
-
"aria-label": danger ? t("panels.market.uninstallLabel", { name:
|
|
3983
|
+
"aria-label": danger ? t("panels.market.uninstallLabel", { name: marketRowTitle(row, t) }) : void 0,
|
|
3564
3984
|
disabled: locked,
|
|
3565
3985
|
onClick: () => onAct(action)
|
|
3566
3986
|
}, t(ACTION_LABEL_KEY[action]));
|
|
3567
|
-
}))), row.note === void 0 ? null : /* @__PURE__ */ h("div", {
|
|
3987
|
+
}))), row.note === void 0 ? null : /* @__PURE__ */ h("div", {
|
|
3988
|
+
className: MarketPage_module_default.marketNote,
|
|
3989
|
+
title: row.note.params.reason === void 0 ? void 0 : t("panels.market.moduleRefusedDetail", row.note.params)
|
|
3990
|
+
}, t(row.note.key, row.note.params)), failure === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketFailure }, failure));
|
|
3568
3991
|
}
|
|
3569
3992
|
function ConfirmUninstall({ t, name, onConfirm, onCancel }) {
|
|
3570
3993
|
const [acknowledged, setAcknowledged] = useState(false);
|
|
@@ -3593,7 +4016,48 @@ function MarketSection({ t, titleKey, rows, pending, failureOf, act, confirmActi
|
|
|
3593
4016
|
onAct: (action) => confirmActions.includes(action) ? onConfirming(row.id) : void act(row.id, action)
|
|
3594
4017
|
}))));
|
|
3595
4018
|
}
|
|
3596
|
-
function
|
|
4019
|
+
function MarketBody({ t, shown, pluginList, installedList, shared, pending, failed, notice, act, onConfirming }) {
|
|
4020
|
+
const failureOf = (id) => failed?.id === id ? failed.message : null;
|
|
4021
|
+
return /* @__PURE__ */ h(Fragment, null, notice === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketNote }, notice), marketSections(shown).map((section) => /* @__PURE__ */ h(MarketSection, {
|
|
4022
|
+
key: section.id,
|
|
4023
|
+
t,
|
|
4024
|
+
titleKey: section.titleKey,
|
|
4025
|
+
rows: section.rows,
|
|
4026
|
+
pending,
|
|
4027
|
+
failureOf,
|
|
4028
|
+
act,
|
|
4029
|
+
confirmActions: CONFIRM_UNINSTALL,
|
|
4030
|
+
onConfirming
|
|
4031
|
+
})), /* @__PURE__ */ h(MarketSection, {
|
|
4032
|
+
t,
|
|
4033
|
+
titleKey: "panels.market.sectionPlugins",
|
|
4034
|
+
rows: pluginList,
|
|
4035
|
+
pending,
|
|
4036
|
+
failureOf,
|
|
4037
|
+
act,
|
|
4038
|
+
confirmActions: CONFIRM_UNINSTALL,
|
|
4039
|
+
onConfirming
|
|
4040
|
+
}), /* @__PURE__ */ h(MarketSection, {
|
|
4041
|
+
t,
|
|
4042
|
+
titleKey: installedList.length > 0 && installedList.every((row) => row.local === true) ? "panels.market.sectionLocal" : "panels.market.sectionUnlisted",
|
|
4043
|
+
rows: installedList,
|
|
4044
|
+
pending,
|
|
4045
|
+
failureOf,
|
|
4046
|
+
act,
|
|
4047
|
+
confirmActions: CONFIRM_REMOVE,
|
|
4048
|
+
onConfirming
|
|
4049
|
+
}), /* @__PURE__ */ h(PanelFoot, {
|
|
4050
|
+
size: "md",
|
|
4051
|
+
text: t("panels.market.foot")
|
|
4052
|
+
}), /* @__PURE__ */ h(SharedSection, {
|
|
4053
|
+
t,
|
|
4054
|
+
rows: shared,
|
|
4055
|
+
pending,
|
|
4056
|
+
failureOf,
|
|
4057
|
+
act
|
|
4058
|
+
}));
|
|
4059
|
+
}
|
|
4060
|
+
function MarketView({ t, manifests, capabilities, freshness, onChanged, updates, installed, installedRead, plugins, settling, mock }) {
|
|
3597
4061
|
const [titles, setTitles] = useState(/* @__PURE__ */ new Map());
|
|
3598
4062
|
useEffect(() => {
|
|
3599
4063
|
if (mock === void 0) setTitles((known) => mergeTitles(known, manifests));
|
|
@@ -3610,6 +4074,7 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3610
4074
|
});
|
|
3611
4075
|
const [confirming, setConfirming] = useState(mock?.confirming ?? null);
|
|
3612
4076
|
const [failed, setFailed] = useState(mock?.failure ?? null);
|
|
4077
|
+
const [notice, setNotice] = useState(mock?.notice ?? null);
|
|
3613
4078
|
const removing = pending !== null && pending.action === "remove-bundle" && failed?.id !== pending.id ? pending.id : null;
|
|
3614
4079
|
const installedList = installedRows((mock?.installed ?? installed ?? []).filter((module) => !(settling?.has(module.unit) ?? false) && module.unit !== removing), catalog, new Set(rows.map((row) => row.id)), titles);
|
|
3615
4080
|
const pendingRow = removing === null || pending === null || rows.some((row) => row.id === removing) ? void 0 : {
|
|
@@ -3623,7 +4088,12 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3623
4088
|
...pending.version === void 0 ? {} : { version: { installed: pending.version } }
|
|
3624
4089
|
};
|
|
3625
4090
|
const shown = pendingRow === void 0 ? rows : [...rows, pendingRow];
|
|
3626
|
-
const
|
|
4091
|
+
const pluginList = installedPluginRows(mock?.plugins ?? plugins ?? []);
|
|
4092
|
+
const rowById = new Map([
|
|
4093
|
+
...shown,
|
|
4094
|
+
...installedList,
|
|
4095
|
+
...pluginList
|
|
4096
|
+
].map((row) => [row.id, row]));
|
|
3627
4097
|
const confirmingRow = confirming === null ? void 0 : rowById.get(confirming);
|
|
3628
4098
|
const act = async (id, action) => {
|
|
3629
4099
|
if (mock !== void 0) return;
|
|
@@ -3637,13 +4107,15 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3637
4107
|
});
|
|
3638
4108
|
setConfirming(null);
|
|
3639
4109
|
setFailed(null);
|
|
4110
|
+
if (action !== "uninstall-plugin") setNotice(null);
|
|
3640
4111
|
const dependency = action === "update-dependency";
|
|
4112
|
+
const byName = action === "remove-bundle" || action === "update-plugin" || action === "uninstall-plugin";
|
|
3641
4113
|
const outcome = await provision.send(dependency ? {
|
|
3642
4114
|
action,
|
|
3643
4115
|
id
|
|
3644
|
-
} :
|
|
4116
|
+
} : byName ? {
|
|
3645
4117
|
action,
|
|
3646
|
-
name:
|
|
4118
|
+
name: row?.pkg ?? ""
|
|
3647
4119
|
} : {
|
|
3648
4120
|
action,
|
|
3649
4121
|
unit: id
|
|
@@ -3657,6 +4129,10 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3657
4129
|
});
|
|
3658
4130
|
return;
|
|
3659
4131
|
}
|
|
4132
|
+
if (action === "uninstall-plugin") {
|
|
4133
|
+
const kept = installedPluginKept(outcome.value);
|
|
4134
|
+
setNotice(kept === void 0 ? null : t(kept.key, kept.names === void 0 ? {} : { names: kept.names.join(t("panels.market.listSeparator")) }));
|
|
4135
|
+
}
|
|
3660
4136
|
const reason = changeFailure(changeOf(outcome.value), t);
|
|
3661
4137
|
onChanged();
|
|
3662
4138
|
if (reason !== void 0) setFailed({
|
|
@@ -3664,46 +4140,32 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3664
4140
|
message: t("panels.market.failed", { reason })
|
|
3665
4141
|
});
|
|
3666
4142
|
};
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
4143
|
+
const settled = marketSettled(freshness, installedRead);
|
|
4144
|
+
const nothing = shown.length === 0 && installedList.length === 0 && pluginList.length === 0;
|
|
4145
|
+
if (!settled || (settling?.size ?? 0) > 0 && shown.length === 0 && installedList.length === 0) return /* @__PURE__ */ h(MarketChecking, { t });
|
|
4146
|
+
if (nothing) return /* @__PURE__ */ h(MarketEmpty, { t });
|
|
4147
|
+
return /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(MarketBody, {
|
|
3671
4148
|
t,
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
act,
|
|
3677
|
-
confirmActions: CONFIRM_UNINSTALL,
|
|
3678
|
-
onConfirming: setConfirming
|
|
3679
|
-
})), /* @__PURE__ */ h(MarketSection, {
|
|
3680
|
-
t,
|
|
3681
|
-
titleKey: installedList.length > 0 && installedList.every((row) => row.local === true) ? "panels.market.sectionLocal" : "panels.market.sectionUnlisted",
|
|
3682
|
-
rows: installedList,
|
|
4149
|
+
shown,
|
|
4150
|
+
pluginList,
|
|
4151
|
+
installedList,
|
|
4152
|
+
shared,
|
|
3683
4153
|
pending,
|
|
3684
|
-
|
|
4154
|
+
failed,
|
|
4155
|
+
notice,
|
|
3685
4156
|
act,
|
|
3686
|
-
confirmActions: CONFIRM_REMOVE,
|
|
3687
4157
|
onConfirming: setConfirming
|
|
3688
|
-
}), /* @__PURE__ */ h(PanelFoot, {
|
|
3689
|
-
size: "md",
|
|
3690
|
-
text: t("panels.market.foot")
|
|
3691
|
-
}), /* @__PURE__ */ h(SharedSection, {
|
|
3692
|
-
t,
|
|
3693
|
-
rows: shared,
|
|
3694
|
-
pending,
|
|
3695
|
-
failureOf: (id) => failed?.id === id ? failed.message : null,
|
|
3696
|
-
act
|
|
3697
4158
|
}), /* @__PURE__ */ h(ConfirmUninstall, {
|
|
3698
4159
|
key: confirming ?? "",
|
|
3699
4160
|
t,
|
|
3700
|
-
name: confirmingRow === void 0 ? null :
|
|
4161
|
+
name: confirmingRow === void 0 ? null : marketRowTitle(confirmingRow, t),
|
|
3701
4162
|
onCancel: () => setConfirming(null),
|
|
3702
4163
|
onConfirm: () => {
|
|
3703
4164
|
const id = confirming;
|
|
3704
4165
|
setConfirming(null);
|
|
3705
4166
|
if (id === null) return;
|
|
3706
|
-
|
|
4167
|
+
const row = rowById.get(id);
|
|
4168
|
+
act(id, row?.plugin === true ? "uninstall-plugin" : row?.pkg === void 0 ? "uninstall" : "remove-bundle");
|
|
3707
4169
|
}
|
|
3708
4170
|
}));
|
|
3709
4171
|
}
|
|
@@ -3713,6 +4175,9 @@ var BUNDLE_REGISTRIES_ROUTE = "bundle-registries";
|
|
|
3713
4175
|
var BUNDLE_INSPECT_ROUTE = "bundle-inspect";
|
|
3714
4176
|
var MODULE_VERSIONS_ROUTE = "module-versions";
|
|
3715
4177
|
//#endregion
|
|
4178
|
+
//#region src/shared/api/installed-plugins.ts
|
|
4179
|
+
var INSTALLED_PLUGINS_ROUTE = "panels/plugins";
|
|
4180
|
+
//#endregion
|
|
3716
4181
|
//#region src/shared/hooks/bundle-queries.ts
|
|
3717
4182
|
function readBundleRegistries() {
|
|
3718
4183
|
return apiGet(BUNDLE_REGISTRIES_ROUTE);
|
|
@@ -3726,10 +4191,14 @@ function readBundleInspection(spec, registry) {
|
|
|
3726
4191
|
function readModuleVersions(force = false) {
|
|
3727
4192
|
return apiGet(MODULE_VERSIONS_ROUTE, force ? { force: "1" } : void 0);
|
|
3728
4193
|
}
|
|
4194
|
+
function readInstalledPlugins(force = false) {
|
|
4195
|
+
return apiGet(INSTALLED_PLUGINS_ROUTE, force ? { force: "1" } : void 0);
|
|
4196
|
+
}
|
|
3729
4197
|
//#endregion
|
|
3730
4198
|
//#region src/app/layouts/market/use-module-versions.ts
|
|
3731
4199
|
var state = {
|
|
3732
4200
|
modules: null,
|
|
4201
|
+
plugins: null,
|
|
3733
4202
|
read: false,
|
|
3734
4203
|
checkedAt: null
|
|
3735
4204
|
};
|
|
@@ -3754,10 +4223,13 @@ function runModuleVersionsRead(force = false) {
|
|
|
3754
4223
|
if (inFlight !== null && inFlight.force === force) return inFlight.promise;
|
|
3755
4224
|
const seq = readSeq += 1;
|
|
3756
4225
|
if (force) newestForceSeq = seq;
|
|
3757
|
-
const promise = readModuleVersions(force).catch(() => null).then((
|
|
4226
|
+
const promise = Promise.all([readModuleVersions(force), readInstalledPlugins(force)]).catch(() => null).then((responses) => {
|
|
3758
4227
|
if (!force && seq < newestForceSeq) return;
|
|
4228
|
+
const versions = responses?.[0];
|
|
4229
|
+
const plugins = responses?.[1];
|
|
3759
4230
|
publish({
|
|
3760
|
-
modules:
|
|
4231
|
+
modules: versions?.ok === true ? versions.modules : state.modules,
|
|
4232
|
+
plugins: plugins?.ok === true ? plugins.plugins : state.plugins,
|
|
3761
4233
|
read: true,
|
|
3762
4234
|
checkedAt: Date.now()
|
|
3763
4235
|
});
|
|
@@ -3789,6 +4261,7 @@ function useModuleVersions() {
|
|
|
3789
4261
|
}, []);
|
|
3790
4262
|
return {
|
|
3791
4263
|
modules: value.modules,
|
|
4264
|
+
plugins: value.plugins,
|
|
3792
4265
|
read: value.read,
|
|
3793
4266
|
checkedAt: value.checkedAt,
|
|
3794
4267
|
reload
|
|
@@ -4007,7 +4480,7 @@ function AddModulePending({ t, kind }) {
|
|
|
4007
4480
|
})), /* @__PURE__ */ h("h2", {
|
|
4008
4481
|
className: AddModule_module_default.pendingTitle,
|
|
4009
4482
|
role: "status"
|
|
4010
|
-
}, kind === "inspecting" ? t("panels.market.add.
|
|
4483
|
+
}, kind === "inspecting" ? t("panels.market.add.classifying") : t("panels.market.add.installingTitle"))));
|
|
4011
4484
|
}
|
|
4012
4485
|
function AddModulePreview({ t, state }) {
|
|
4013
4486
|
const preview = state.preview;
|
|
@@ -4025,6 +4498,7 @@ function AddModuleResult({ t, state }) {
|
|
|
4025
4498
|
const restart = outcome.change.application === "restart-required";
|
|
4026
4499
|
const cancelled = outcome.change.application === "cancelled";
|
|
4027
4500
|
const notModule = outcome.supply.state === "not-a-module";
|
|
4501
|
+
const plugin = outcome.plugin;
|
|
4028
4502
|
const name = outcome.module.kind === "module" ? outcome.module.unit : outcome.module.pkg;
|
|
4029
4503
|
return /* @__PURE__ */ h("div", { className: AddModule_module_default.body }, /* @__PURE__ */ h("div", { className: AddModule_module_default.hero }, /* @__PURE__ */ h("span", {
|
|
4030
4504
|
className: AddModule_module_default.heroIcon,
|
|
@@ -4036,7 +4510,7 @@ function AddModuleResult({ t, state }) {
|
|
|
4036
4510
|
}) : /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconCheckCircleFillRegular, { size: 28 })), /* @__PURE__ */ h("h2", {
|
|
4037
4511
|
className: AddModule_module_default.wizardTitle,
|
|
4038
4512
|
role: failed ? "alert" : "status"
|
|
4039
|
-
}, failed ? t("panels.market.add.failedTitle") : cancelled ? t("panels.market.add.cancelledTitle") : t("panels.market.add.installedTitle"))), /* @__PURE__ */ h("div", { className: AddModule_module_default.subject }, /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectName }, outcome.module.pkg), name === outcome.module.pkg ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, name), outcome.module.version === void 0 ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, t("panels.market.add.installVersion", { version: outcome.module.version }))), failed ? /* @__PURE__ */ h("p", {
|
|
4513
|
+
}, failed ? t("panels.market.add.failedTitle") : cancelled ? t("panels.market.add.cancelledTitle") : t("panels.market.add.installedTitle"))), /* @__PURE__ */ h("div", { className: AddModule_module_default.subject }, /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectName }, outcome.module.pkg), name === outcome.module.pkg ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, name), outcome.module.version === void 0 ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, t("panels.market.add.installVersion", { version: outcome.module.version }))), plugin !== void 0 ? /* @__PURE__ */ h("p", { className: AddModule_module_default.result }, t("panels.market.add.installedPlugin", { name: plugin.name ?? plugin.pkg })) : failed ? /* @__PURE__ */ h("p", {
|
|
4040
4514
|
className: AddModule_module_default.resultWarn,
|
|
4041
4515
|
role: "alert"
|
|
4042
4516
|
}, t("panels.market.add.failed", { reason })) : restart ? /* @__PURE__ */ h("p", { className: AddModule_module_default.resultWarn }, t("panels.market.add.doneRestart")) : cancelled || notModule ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.result }, t("panels.market.add.tookEffect")), builds.length === 0 ? null : /* @__PURE__ */ h("div", { className: AddModule_module_default.approval }, /* @__PURE__ */ h("p", { className: AddModule_module_default.approvalTitle }, t("panels.market.add.approveTitle")), /* @__PURE__ */ h("p", { className: AddModule_module_default.approvalText }, t("panels.market.add.approveHint", { packages: builds.join("、") })), /* @__PURE__ */ h("p", { className: AddModule_module_default.approvalCaution }, t("panels.market.add.approveCaution"))), supply === void 0 || outcome.supply.state !== "failed" && (failed || cancelled) ? null : /* @__PURE__ */ h("p", { className: supplyTone(outcome.supply.state) }, t(supply, { reason: outcome.supply.reason ?? "" })), state.failure === null ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.problem }, state.failure), outcome.change.errorDetail === void 0 ? null : /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h("p", { className: AddModule_module_default.detailLabel }, t("panels.market.add.details")), /* @__PURE__ */ h("p", { className: AddModule_module_default.detail }, outcome.change.errorDetail)));
|
|
@@ -4107,6 +4581,7 @@ var ADD_MODULE_MOCKS = [
|
|
|
4107
4581
|
refused("not-found"),
|
|
4108
4582
|
refused("not-a-package"),
|
|
4109
4583
|
refused("not-a-bundle"),
|
|
4584
|
+
refused("not-a-module-or-plugin", "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上"),
|
|
4110
4585
|
refused("network", "getaddrinfo ENOTFOUND registry.example.com"),
|
|
4111
4586
|
refused("unknown", "pnpm 的返回码是 1"),
|
|
4112
4587
|
{
|
|
@@ -4188,6 +4663,25 @@ var ADD_MODULE_MOCKS = [
|
|
|
4188
4663
|
spec: "@dsh-workbench/module-hello",
|
|
4189
4664
|
outcome: outcome({})
|
|
4190
4665
|
},
|
|
4666
|
+
{
|
|
4667
|
+
id: "done-plugin",
|
|
4668
|
+
label: "装好了(opencli 插件)",
|
|
4669
|
+
phase: "result",
|
|
4670
|
+
spec: "opencli-plugin-cmdb",
|
|
4671
|
+
outcome: {
|
|
4672
|
+
change: change({ target: "opencli-plugin-cmdb" }),
|
|
4673
|
+
module: {
|
|
4674
|
+
kind: "unknown",
|
|
4675
|
+
pkg: "opencli-plugin-cmdb"
|
|
4676
|
+
},
|
|
4677
|
+
supply: { state: "no-needs" },
|
|
4678
|
+
plugin: {
|
|
4679
|
+
kind: "opencli-plugin",
|
|
4680
|
+
pkg: "opencli-plugin-cmdb",
|
|
4681
|
+
name: "cmdb"
|
|
4682
|
+
}
|
|
4683
|
+
}
|
|
4684
|
+
},
|
|
4191
4685
|
{
|
|
4192
4686
|
id: "done-restart",
|
|
4193
4687
|
label: "装好了(要重启)",
|
|
@@ -4282,6 +4776,42 @@ function stateOfMock(base, mock) {
|
|
|
4282
4776
|
};
|
|
4283
4777
|
}
|
|
4284
4778
|
//#endregion
|
|
4779
|
+
//#region src/shared/hooks/use-visible-busy.ts
|
|
4780
|
+
var use_visible_busy_exports = /* @__PURE__ */ __exportAll({
|
|
4781
|
+
busyView: () => busyView,
|
|
4782
|
+
heldPhase: () => heldPhase,
|
|
4783
|
+
useVisibleBusy: () => useVisibleBusy
|
|
4784
|
+
});
|
|
4785
|
+
function heldPhase(phase, refreshing) {
|
|
4786
|
+
return refreshing && phase === "ready" ? "loading" : phase;
|
|
4787
|
+
}
|
|
4788
|
+
function busyView(active, visible) {
|
|
4789
|
+
return {
|
|
4790
|
+
busy: visible,
|
|
4791
|
+
settling: visible && !active
|
|
4792
|
+
};
|
|
4793
|
+
}
|
|
4794
|
+
function useVisibleBusy(active, floorMs) {
|
|
4795
|
+
const [visible, setVisible] = useState(active);
|
|
4796
|
+
const since = useRef(null);
|
|
4797
|
+
useEffect(() => {
|
|
4798
|
+
if (active) {
|
|
4799
|
+
if (since.current === null) since.current = Date.now();
|
|
4800
|
+
setVisible(true);
|
|
4801
|
+
return;
|
|
4802
|
+
}
|
|
4803
|
+
const held = holdBusy(since.current, Date.now(), floorMs);
|
|
4804
|
+
since.current = null;
|
|
4805
|
+
if (!held.visible) {
|
|
4806
|
+
setVisible(false);
|
|
4807
|
+
return;
|
|
4808
|
+
}
|
|
4809
|
+
const timer = setTimeout(() => setVisible(false), held.releaseInMs);
|
|
4810
|
+
return () => clearTimeout(timer);
|
|
4811
|
+
}, [active, floorMs]);
|
|
4812
|
+
return busyView(active, visible);
|
|
4813
|
+
}
|
|
4814
|
+
//#endregion
|
|
4285
4815
|
//#region src/app/layouts/market/use-add-module.ts
|
|
4286
4816
|
function newRequestId() {
|
|
4287
4817
|
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -4304,6 +4834,7 @@ function useAddModule(options) {
|
|
|
4304
4834
|
const [failure, setFailure] = useState(null);
|
|
4305
4835
|
const generationRef = useRef(0);
|
|
4306
4836
|
const requestIdRef = useRef("");
|
|
4837
|
+
const { busy: classifying } = useVisibleBusy(phase === "inspecting", 500);
|
|
4307
4838
|
const write = useHostWrite({
|
|
4308
4839
|
channel: "provision",
|
|
4309
4840
|
networkText: failedText
|
|
@@ -4401,7 +4932,8 @@ function useAddModule(options) {
|
|
|
4401
4932
|
setOutcome({
|
|
4402
4933
|
change: value.change,
|
|
4403
4934
|
module: value.module,
|
|
4404
|
-
supply: value.supply
|
|
4935
|
+
supply: value.supply,
|
|
4936
|
+
...value.plugin === void 0 ? {} : { plugin: value.plugin }
|
|
4405
4937
|
});
|
|
4406
4938
|
setPhase("result");
|
|
4407
4939
|
if (value.change.application === "applied" || value.change.application === "restart-required") onInstalled();
|
|
@@ -4446,7 +4978,7 @@ function useAddModule(options) {
|
|
|
4446
4978
|
custom,
|
|
4447
4979
|
registryOpen,
|
|
4448
4980
|
guideOpen,
|
|
4449
|
-
phase,
|
|
4981
|
+
phase: heldWizardPhase(phase, classifying),
|
|
4450
4982
|
choices,
|
|
4451
4983
|
problem,
|
|
4452
4984
|
preview,
|
|
@@ -4604,10 +5136,10 @@ function makeMarketEntryIcon(units) {
|
|
|
4604
5136
|
function MarketPanel({ t, units }) {
|
|
4605
5137
|
const manifests = useLiveManifests(units);
|
|
4606
5138
|
const { capabilities, checkedAt, checking, forceProbe, reload: reloadCapability } = useCapabilityMap(0);
|
|
4607
|
-
const { modules, read: installedRead, reload: reloadVersions } = useModuleVersions();
|
|
5139
|
+
const { modules, plugins, read: installedRead, reload: reloadVersions } = useModuleVersions();
|
|
4608
5140
|
const [adding, setAdding] = useState(false);
|
|
4609
5141
|
const updates = useMemo(() => marketUpdatesOf(modules), [modules]);
|
|
4610
|
-
const installed = modules
|
|
5142
|
+
const installed = modules === null ? void 0 : withClientRefusals(modules, units.refusals());
|
|
4611
5143
|
const reload = useCallback(() => {
|
|
4612
5144
|
reloadCapability();
|
|
4613
5145
|
reloadVersions();
|
|
@@ -4664,11 +5196,14 @@ function MarketPanel({ t, units }) {
|
|
|
4664
5196
|
});
|
|
4665
5197
|
const mock = fixturePick.enabled ? fixturePick.current : void 0;
|
|
4666
5198
|
const mockNonce = fixturePick.nonce;
|
|
5199
|
+
const shownFreshness = mock === void 0 ? freshness : mock.loaded === false ? pendingFreshness : MOCK_FRESHNESS;
|
|
5200
|
+
const shownRead = mock === void 0 ? installedRead : mock.installedRead ?? true;
|
|
5201
|
+
const busy = !marketSettled(shownFreshness, shownRead) || shownFreshness.checking;
|
|
4667
5202
|
return /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketPage }, /* @__PURE__ */ h("header", { className: MarketPage_module_default.marketPageHead }, /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("h1", { className: MarketPage_module_default.marketPageTitle }, t("panels.tab.market")), /* @__PURE__ */ h("p", { className: MarketPage_module_default.marketPageIntro }, t("panels.market.lead"))), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketPageTools }, /* @__PURE__ */ h(Tip, { label: t("panels.market.recheck") }, /* @__PURE__ */ h("button", {
|
|
4668
5203
|
type: "button",
|
|
4669
|
-
className: `${MarketPage_module_default.marketIconButton}${checking ? ` ${MarketPage_module_default.marketIconButtonSpinning}` : ""}`,
|
|
5204
|
+
className: `${MarketPage_module_default.marketIconButton}${shownFreshness.checking ? ` ${MarketPage_module_default.marketIconButtonSpinning}` : ""}`,
|
|
4670
5205
|
"aria-label": t("panels.market.checkUpdates"),
|
|
4671
|
-
disabled:
|
|
5206
|
+
disabled: busy,
|
|
4672
5207
|
onClick: () => {
|
|
4673
5208
|
forceProbe();
|
|
4674
5209
|
reloadVersions({ force: true });
|
|
@@ -4681,6 +5216,7 @@ function MarketPanel({ t, units }) {
|
|
|
4681
5216
|
size: "sm",
|
|
4682
5217
|
className: MarketPage_module_default.marketAddButton,
|
|
4683
5218
|
icon: /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: 13 }),
|
|
5219
|
+
disabled: busy,
|
|
4684
5220
|
onClick: () => setAdding(true)
|
|
4685
5221
|
}, t("panels.market.add.open")))), fixturePick.enabled ? /* @__PURE__ */ h(MockStrip, {
|
|
4686
5222
|
mocks: marketMocks,
|
|
@@ -4691,11 +5227,12 @@ function MarketPanel({ t, units }) {
|
|
|
4691
5227
|
t,
|
|
4692
5228
|
manifests,
|
|
4693
5229
|
capabilities,
|
|
4694
|
-
freshness:
|
|
5230
|
+
freshness: shownFreshness,
|
|
4695
5231
|
onChanged: reload,
|
|
4696
5232
|
updates,
|
|
4697
5233
|
installed,
|
|
4698
|
-
installedRead:
|
|
5234
|
+
installedRead: shownRead,
|
|
5235
|
+
plugins,
|
|
4699
5236
|
settling: mock === void 0 ? settling : void 0,
|
|
4700
5237
|
mock
|
|
4701
5238
|
}), /* @__PURE__ */ h(AddModuleDialog, {
|
|
@@ -4751,6 +5288,41 @@ var CLIENT_UNITS = [];
|
|
|
4751
5288
|
function assembleClientUnits(registry) {
|
|
4752
5289
|
for (const face of CLIENT_UNITS) registry.register(face);
|
|
4753
5290
|
}
|
|
5291
|
+
//#endregion
|
|
5292
|
+
//#region src/shared/api/unit-manifests.ts
|
|
5293
|
+
var UNIT_MANIFESTS_ROUTE = "unit-manifests";
|
|
5294
|
+
//#endregion
|
|
5295
|
+
//#region src/app/units/manifests.ts
|
|
5296
|
+
function createUnitManifestLoader(options = {}) {
|
|
5297
|
+
let inFlight = false;
|
|
5298
|
+
let queued = false;
|
|
5299
|
+
let watching = false;
|
|
5300
|
+
const subscribeFacts = options.subscribeFacts ?? subscribeFactRevision;
|
|
5301
|
+
const load = async (registry) => {
|
|
5302
|
+
if (inFlight) {
|
|
5303
|
+
queued = true;
|
|
5304
|
+
return;
|
|
5305
|
+
}
|
|
5306
|
+
inFlight = true;
|
|
5307
|
+
try {
|
|
5308
|
+
const response = await apiGet(UNIT_MANIFESTS_ROUTE).catch(() => null);
|
|
5309
|
+
if (response?.ok === true && Array.isArray(response.manifests)) registry.setManifests(response.manifests);
|
|
5310
|
+
} finally {
|
|
5311
|
+
inFlight = false;
|
|
5312
|
+
if (queued) {
|
|
5313
|
+
queued = false;
|
|
5314
|
+
load(registry);
|
|
5315
|
+
}
|
|
5316
|
+
}
|
|
5317
|
+
};
|
|
5318
|
+
return (registry) => {
|
|
5319
|
+
if (!watching) {
|
|
5320
|
+
watching = true;
|
|
5321
|
+
subscribeFacts(factOfRoute(UNIT_MANIFESTS_ROUTE), () => void load(registry));
|
|
5322
|
+
}
|
|
5323
|
+
load(registry);
|
|
5324
|
+
};
|
|
5325
|
+
}
|
|
4754
5326
|
var BootGate_module_default = {
|
|
4755
5327
|
actions: "_actions_jlw8j_1",
|
|
4756
5328
|
progress: "_progress_jlw8j_2",
|
|
@@ -7428,42 +8000,6 @@ function useLongTask(options) {
|
|
|
7428
8000
|
return { runs };
|
|
7429
8001
|
}
|
|
7430
8002
|
//#endregion
|
|
7431
|
-
//#region src/shared/hooks/use-visible-busy.ts
|
|
7432
|
-
var use_visible_busy_exports = /* @__PURE__ */ __exportAll({
|
|
7433
|
-
busyView: () => busyView,
|
|
7434
|
-
heldPhase: () => heldPhase,
|
|
7435
|
-
useVisibleBusy: () => useVisibleBusy
|
|
7436
|
-
});
|
|
7437
|
-
function heldPhase(phase, refreshing) {
|
|
7438
|
-
return refreshing && phase === "ready" ? "loading" : phase;
|
|
7439
|
-
}
|
|
7440
|
-
function busyView(active, visible) {
|
|
7441
|
-
return {
|
|
7442
|
-
busy: visible,
|
|
7443
|
-
settling: visible && !active
|
|
7444
|
-
};
|
|
7445
|
-
}
|
|
7446
|
-
function useVisibleBusy(active, floorMs) {
|
|
7447
|
-
const [visible, setVisible] = useState(active);
|
|
7448
|
-
const since = useRef(null);
|
|
7449
|
-
useEffect(() => {
|
|
7450
|
-
if (active) {
|
|
7451
|
-
if (since.current === null) since.current = Date.now();
|
|
7452
|
-
setVisible(true);
|
|
7453
|
-
return;
|
|
7454
|
-
}
|
|
7455
|
-
const held = holdBusy(since.current, Date.now(), floorMs);
|
|
7456
|
-
since.current = null;
|
|
7457
|
-
if (!held.visible) {
|
|
7458
|
-
setVisible(false);
|
|
7459
|
-
return;
|
|
7460
|
-
}
|
|
7461
|
-
const timer = setTimeout(() => setVisible(false), held.releaseInMs);
|
|
7462
|
-
return () => clearTimeout(timer);
|
|
7463
|
-
}, [active, floorMs]);
|
|
7464
|
-
return busyView(active, visible);
|
|
7465
|
-
}
|
|
7466
|
-
//#endregion
|
|
7467
8003
|
//#region src/shared/hooks/use-unit-board.ts
|
|
7468
8004
|
var use_unit_board_exports = /* @__PURE__ */ __exportAll({ useUnitBoard: () => useUnitBoard });
|
|
7469
8005
|
function useUnitBoard(options) {
|
|
@@ -7677,7 +8213,7 @@ var kit = {
|
|
|
7677
8213
|
};
|
|
7678
8214
|
function messagesOf(units) {
|
|
7679
8215
|
return units.map((face) => ({
|
|
7680
|
-
unit: face.
|
|
8216
|
+
unit: face.unit,
|
|
7681
8217
|
...face.messages === void 0 ? {} : { messages: face.messages }
|
|
7682
8218
|
}));
|
|
7683
8219
|
}
|
|
@@ -7718,12 +8254,14 @@ function apply(ctx) {
|
|
|
7718
8254
|
}
|
|
7719
8255
|
}
|
|
7720
8256
|
function mount(ctx) {
|
|
7721
|
-
const
|
|
8257
|
+
const loadUnitManifests = createUnitManifestLoader();
|
|
8258
|
+
const units = createClientUnitRegistry({ onUnknownUnit: () => loadUnitManifests(units) });
|
|
7722
8259
|
ctx.provide(UNITS_SERVICE, {
|
|
7723
8260
|
registerUnit: (face) => units.register(face),
|
|
7724
8261
|
manifests: () => units.manifests()
|
|
7725
8262
|
});
|
|
7726
8263
|
assembleClientUnits(units);
|
|
8264
|
+
loadUnitManifests(units);
|
|
7727
8265
|
const store = rightbarStore;
|
|
7728
8266
|
const observable = {
|
|
7729
8267
|
getSnapshot: () => store.getSnapshot(),
|