@dsh-workbench/core 0.3.2 → 0.3.3

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.
Files changed (38) hide show
  1. package/client.js +177 -107
  2. package/dist/client/client.body.js +177 -107
  3. package/dist/client/index.js +177 -107
  4. package/dist/host/index.js +829 -1458
  5. package/dist/types/app/client.d.ts +15 -3
  6. package/dist/types/app/layouts/panel-hint.d.ts +3 -0
  7. package/dist/types/app/layouts/rightbar/market-hint.d.ts +16 -0
  8. package/dist/types/app/layouts/rightbar/market-rows.d.ts +2 -3
  9. package/dist/types/modules/panels/model/diy-browser-act.d.ts +2 -39
  10. package/dist/types/modules/panels/model/diy-browser-tools.d.ts +39 -0
  11. package/dist/types/modules/panels/model/diy-browser.d.ts +1 -14
  12. package/dist/types/modules/panels/model/diy-observers.d.ts +11 -0
  13. package/dist/types/modules/panels/model/diy-observers.test.d.ts +1 -0
  14. package/dist/types/modules/panels/model/diy-page.d.ts +1 -0
  15. package/dist/types/modules/panels/model/diy-scripts.d.ts +0 -63
  16. package/dist/types/modules/panels/model/diy-spec.d.ts +5 -0
  17. package/dist/types/modules/panels/model/diy-spec.test.d.ts +1 -0
  18. package/dist/types/modules/panels/unit.d.ts +13 -11
  19. package/dist/types/shared/api/host/diy-recon.d.ts +10 -0
  20. package/package.json +3 -3
  21. package/skills/workbench-module-diy/BUILD.md +37 -16
  22. package/skills/workbench-module-diy/DATASOURCE.md +4 -1
  23. package/skills/workbench-module-diy/DESIGN.md +15 -8
  24. package/skills/workbench-module-diy/KIT.md +2 -0
  25. package/skills/workbench-module-diy/PANEL.md +3 -2
  26. package/skills/workbench-module-diy/REVIEW.md +115 -48
  27. package/skills/workbench-module-diy/SKILL.md +33 -9
  28. package/skills/workbench-module-diy/STEPS.md +1 -1
  29. package/skills/workbench-module-diy/TOOLING.md +6 -3
  30. package/skills/workbench-module-diy/TOOLS.md +90 -204
  31. package/skills/workbench-module-diy/WIRING.md +7 -5
  32. package/skills/workbench-module-diy/WRITES.md +90 -0
  33. package/dist/types/modules/panels/model/diy-act.d.ts +0 -4
  34. package/dist/types/modules/panels/model/diy-look.d.ts +0 -15
  35. package/dist/types/modules/panels/model/diy-net.d.ts +0 -3
  36. /package/dist/types/modules/panels/model/{diy-act.test.d.ts → diy-browser-act.test.d.ts} +0 -0
  37. /package/dist/types/modules/panels/model/{diy-look.test.d.ts → diy-browser-tools-shot.test.d.ts} +0 -0
  38. /package/dist/types/modules/panels/model/{diy-net.test.d.ts → diy-browser-tools.test.d.ts} +0 -0
@@ -1812,6 +1812,7 @@ var en = {
1812
1812
  "panels.dragHint": "Drag to reorder",
1813
1813
  "panels.unknownStep": "No suite provides this view",
1814
1814
  "panels.labelWithHint": "{label} ({hint})",
1815
+ "panels.hintJoin": "; ",
1815
1816
  "panels.dep.failed": "⚠ failed to start",
1816
1817
  "panels.dep.missingPlugin": "⚠ not ready yet",
1817
1818
  "panels.dep.missingCommands": "⚠ needs an update",
@@ -1826,6 +1827,7 @@ var en = {
1826
1827
  "panels.market.notUsable": "unusable",
1827
1828
  "panels.market.broken": "broken",
1828
1829
  "panels.market.hasNew": "New version",
1830
+ "panels.market.hasProblem": "Module problem",
1829
1831
  "panels.market.missing": "not installed",
1830
1832
  "panels.market.unchecked": "unknown",
1831
1833
  "panels.market.checking": "checking",
@@ -2237,6 +2239,7 @@ var zh = {
2237
2239
  "panels.dragHint": "拖动调整顺序",
2238
2240
  "panels.unknownStep": "这一层没有套件提供",
2239
2241
  "panels.labelWithHint": "{label}({hint})",
2242
+ "panels.hintJoin": ";",
2240
2243
  "panels.dep.failed": "⚠ 起不来",
2241
2244
  "panels.dep.missingPlugin": "⚠ 还没装好",
2242
2245
  "panels.dep.missingCommands": "⚠ 需要更新",
@@ -2251,6 +2254,7 @@ var zh = {
2251
2254
  "panels.market.notUsable": "不可用",
2252
2255
  "panels.market.broken": "装坏了",
2253
2256
  "panels.market.hasNew": "有新版本",
2257
+ "panels.market.hasProblem": "模块异常",
2254
2258
  "panels.market.missing": "未装",
2255
2259
  "panels.market.unchecked": "状态未知",
2256
2260
  "panels.market.checking": "检测中",
@@ -3516,8 +3520,15 @@ var devSurface = {
3516
3520
  //#region src/app/layouts/panel-hint.ts
3517
3521
  var hints = /* @__PURE__ */ new Map();
3518
3522
  var listeners$3 = /* @__PURE__ */ new Set();
3523
+ function sameHint(left, right) {
3524
+ if (left === null || right === null) return left === right;
3525
+ if (left.labelKey !== right.labelKey || left.tone !== right.tone) return false;
3526
+ const leftMore = left.moreKeys ?? [];
3527
+ const rightMore = right.moreKeys ?? [];
3528
+ return leftMore.length === rightMore.length && leftMore.every((key, index) => key === rightMore[index]);
3529
+ }
3519
3530
  function publishPanelHint(id, hint) {
3520
- if ((hints.get(id)?.labelKey ?? null) === (hint?.labelKey ?? null)) return;
3531
+ if (sameHint(hints.get(id) ?? null, hint)) return;
3521
3532
  if (hint === null) hints.delete(id);
3522
3533
  else hints.set(id, hint);
3523
3534
  for (const listener of [...listeners$3]) listener();
@@ -3538,7 +3549,7 @@ function panelRowName(label, hint, t) {
3538
3549
  if (hint === null) return label;
3539
3550
  return t("panels.labelWithHint", {
3540
3551
  label,
3541
- hint: t(hint.labelKey)
3552
+ hint: [hint.labelKey, ...hint.moreKeys ?? []].map((key) => t(key)).join(t("panels.hintJoin"))
3542
3553
  });
3543
3554
  }
3544
3555
  //#endregion
@@ -3689,39 +3700,6 @@ function sharedRows(manifests, capabilities) {
3689
3700
  return rows;
3690
3701
  }
3691
3702
  //#endregion
3692
- //#region src/app/layouts/rightbar/market-workbench-row.ts
3693
- var WORKBENCH_ROW_ID = "workbench:self";
3694
- var WORKBENCH_TITLE_KEY = "panels.market.workbenchName";
3695
- function workbenchRow(version) {
3696
- if (version === null || version === void 0 || version.installed === "") return void 0;
3697
- const local = version.local === true;
3698
- const latest = local ? void 0 : version.latest;
3699
- const update = latest !== void 0 && latest !== version.installed ? {
3700
- installed: version.installed,
3701
- latest
3702
- } : void 0;
3703
- const note = local ? {
3704
- key: "panels.market.workbenchLocal",
3705
- params: {}
3706
- } : void 0;
3707
- return {
3708
- id: WORKBENCH_ROW_ID,
3709
- titleKey: WORKBENCH_TITLE_KEY,
3710
- workbench: true,
3711
- state: !local && version.running !== void 0 && version.running !== version.installed ? "pending-restart" : update === void 0 ? "installed" : "outdated",
3712
- canInstall: false,
3713
- canUpdate: update !== void 0,
3714
- canUninstall: false,
3715
- ...note === void 0 ? {} : { note },
3716
- version: {
3717
- installed: version.installed,
3718
- ...latest === void 0 ? {} : { latest }
3719
- },
3720
- ...update === void 0 ? {} : { moduleUpdate: update },
3721
- pkg: version.pkg
3722
- };
3723
- }
3724
- //#endregion
3725
3703
  //#region src/app/layouts/rightbar/market-rows.ts
3726
3704
  var MARKET_STATE_KEY = {
3727
3705
  checking: "panels.market.checking",
@@ -3903,10 +3881,6 @@ function marketUpdatesOf(modules) {
3903
3881
  }
3904
3882
  return next;
3905
3883
  }
3906
- function marketHintVisible(manifests, capabilities, modules, workbench) {
3907
- const self = workbenchRow(workbench);
3908
- return marketHasUpdates([...marketRows(manifests, capabilities, marketUpdatesOf(modules)), ...self === void 0 ? [] : [self]], sharedRows(manifests, capabilities));
3909
- }
3910
3884
  function marketOrder(rows, titleOf) {
3911
3885
  return [...rows].sort((left, right) => {
3912
3886
  const byTitle = titleOf(left).localeCompare(titleOf(right), "zh-Hans-CN");
@@ -3962,6 +3936,152 @@ function marketRows(manifests, capabilities, updates = {}, defaults = /* @__PURE
3962
3936
  return rows;
3963
3937
  }
3964
3938
  //#endregion
3939
+ //#region src/app/layouts/rightbar/market-plugin-rows.ts
3940
+ function installedPluginKept(value) {
3941
+ if (typeof value !== "object" || value === null) return void 0;
3942
+ const kept = value.kept;
3943
+ if (typeof kept !== "object" || kept === null) return void 0;
3944
+ const kind = kept.kind;
3945
+ if (kind === "held") return { key: "panels.market.pluginKeptHeld" };
3946
+ if (kind === "unnamed") return { key: "panels.market.pluginKeptUnnamed" };
3947
+ if (kind === "unsure") return { key: "panels.market.pluginKeptUnsure" };
3948
+ if (kind !== "claimed") return void 0;
3949
+ const raw = kept.by;
3950
+ const names = Array.isArray(raw) ? raw.filter((item) => typeof item === "string") : [];
3951
+ return names.length === 0 ? { key: "panels.market.pluginKeptUnsure" } : {
3952
+ key: "panels.market.pluginKeptInUse",
3953
+ names
3954
+ };
3955
+ }
3956
+ function installedPluginNotice(value, t) {
3957
+ const kept = installedPluginKept(value);
3958
+ if (kept === void 0) return null;
3959
+ return t(kept.key, kept.names === void 0 ? {} : { names: kept.names.join(t("panels.market.listSeparator")) });
3960
+ }
3961
+ function noteOf(plugin) {
3962
+ if (plugin.broken === true) return {
3963
+ key: "panels.market.pluginBroken",
3964
+ params: {},
3965
+ tone: "alert"
3966
+ };
3967
+ if (plugin.local === true) return void 0;
3968
+ }
3969
+ function installedPluginRows(plugins, defaults = /* @__PURE__ */ new Set(), changed = {}) {
3970
+ return plugins.map((plugin) => {
3971
+ const id = `plugin:${plugin.pkg}`;
3972
+ const name = plugin.name ?? plugin.pkg;
3973
+ const outdated = plugin.installed !== void 0 && plugin.latest !== void 0 && plugin.latest !== plugin.installed;
3974
+ const note = noteOf(plugin);
3975
+ return {
3976
+ id,
3977
+ titleKey: plugin.pkg,
3978
+ label: name,
3979
+ plugin: true,
3980
+ state: outdated ? "outdated" : plugin.broken === true ? "broken" : "installed",
3981
+ canInstall: false,
3982
+ canUpdate: outdated,
3983
+ canUninstall: true,
3984
+ ...plugin.local === true ? { local: true } : {},
3985
+ ...plugin.broken === true ? { broken: true } : {},
3986
+ defaultShown: defaults.has(id),
3987
+ defaultChanged: changed[id] ?? 0,
3988
+ ...note === void 0 ? {} : { note },
3989
+ ...plugin.installed === void 0 ? {} : { versionLabel: `${plugin.pkg}@${plugin.installed}` },
3990
+ pkg: plugin.pkg,
3991
+ ...plugin.installed === void 0 ? {} : { version: {
3992
+ installed: plugin.installed,
3993
+ ...plugin.latest === void 0 ? {} : { latest: plugin.latest }
3994
+ } }
3995
+ };
3996
+ });
3997
+ }
3998
+ //#endregion
3999
+ //#region src/app/layouts/rightbar/market-workbench-row.ts
4000
+ var WORKBENCH_ROW_ID = "workbench:self";
4001
+ var WORKBENCH_TITLE_KEY = "panels.market.workbenchName";
4002
+ function workbenchRow(version) {
4003
+ if (version === null || version === void 0 || version.installed === "") return void 0;
4004
+ const local = version.local === true;
4005
+ const latest = local ? void 0 : version.latest;
4006
+ const update = latest !== void 0 && latest !== version.installed ? {
4007
+ installed: version.installed,
4008
+ latest
4009
+ } : void 0;
4010
+ const note = local ? {
4011
+ key: "panels.market.workbenchLocal",
4012
+ params: {}
4013
+ } : void 0;
4014
+ return {
4015
+ id: WORKBENCH_ROW_ID,
4016
+ titleKey: WORKBENCH_TITLE_KEY,
4017
+ workbench: true,
4018
+ state: !local && version.running !== void 0 && version.running !== version.installed ? "pending-restart" : update === void 0 ? "installed" : "outdated",
4019
+ canInstall: false,
4020
+ canUpdate: update !== void 0,
4021
+ canUninstall: false,
4022
+ ...note === void 0 ? {} : { note },
4023
+ version: {
4024
+ installed: version.installed,
4025
+ ...latest === void 0 ? {} : { latest }
4026
+ },
4027
+ ...update === void 0 ? {} : { moduleUpdate: update },
4028
+ pkg: version.pkg
4029
+ };
4030
+ }
4031
+ //#endregion
4032
+ //#region src/app/layouts/rightbar/market-hint.ts
4033
+ var PROBLEM_KEY = "panels.market.hasProblem";
4034
+ var RESTART_KEY = "panels.market.pendingRestart";
4035
+ var UPDATES_KEY = "panels.market.hasNew";
4036
+ function isProblem(row) {
4037
+ return row.broken === true || row.state === "broken" || row.state === "unusable" || row.note?.key === "panels.market.moduleRefused";
4038
+ }
4039
+ function isRestart(row) {
4040
+ return row.state === "inactive" || row.state === "pending-restart";
4041
+ }
4042
+ function awaitsRestart(input) {
4043
+ const loaded = new Set(input.manifests.map((manifest) => manifest.id));
4044
+ return (input.installed ?? []).some((module) => !loaded.has(module.unit) && refusalReasons(module.refused, module.clientRefused).length === 0);
4045
+ }
4046
+ function marketHintOf(input) {
4047
+ const marketable = marketCatalog(input.manifests, input.installable);
4048
+ const catalog = marketRows(marketable, input.capabilities, marketUpdatesOf(input.modules));
4049
+ const listed = new Set(catalog.map((row) => row.id));
4050
+ const self = workbenchRow(input.workbench);
4051
+ const rows = [
4052
+ ...catalog,
4053
+ ...installedRows(input.installed ?? [], input.manifests, listed),
4054
+ ...installedPluginRows(input.plugins ?? []),
4055
+ ...self === void 0 ? [] : [self]
4056
+ ];
4057
+ const problem = rows.some(isProblem);
4058
+ const restart = rows.some(isRestart) || awaitsRestart(input);
4059
+ const updates = marketHasUpdates(rows, sharedRows(marketable, input.capabilities));
4060
+ const more = [];
4061
+ if (problem) {
4062
+ if (restart) more.push(RESTART_KEY);
4063
+ if (updates) more.push(UPDATES_KEY);
4064
+ return {
4065
+ labelKey: PROBLEM_KEY,
4066
+ tone: "danger",
4067
+ ...more.length === 0 ? {} : { moreKeys: more }
4068
+ };
4069
+ }
4070
+ if (restart) {
4071
+ if (updates) more.push(UPDATES_KEY);
4072
+ return {
4073
+ labelKey: RESTART_KEY,
4074
+ tone: "warning",
4075
+ ...more.length === 0 ? {} : { moreKeys: more }
4076
+ };
4077
+ }
4078
+ if (updates) return {
4079
+ labelKey: UPDATES_KEY,
4080
+ tone: "warning"
4081
+ };
4082
+ return null;
4083
+ }
4084
+ //#endregion
3965
4085
  //#region src/shared/hooks/use-host-write.ts
3966
4086
  var use_host_write_exports = /* @__PURE__ */ __exportAll({ useHostWrite: () => useHostWrite });
3967
4087
  function useHostWrite(options) {
@@ -4117,66 +4237,6 @@ function useMarketTransient(input) {
4117
4237
  setNotice
4118
4238
  };
4119
4239
  }
4120
- //#endregion
4121
- //#region src/app/layouts/rightbar/market-plugin-rows.ts
4122
- function installedPluginKept(value) {
4123
- if (typeof value !== "object" || value === null) return void 0;
4124
- const kept = value.kept;
4125
- if (typeof kept !== "object" || kept === null) return void 0;
4126
- const kind = kept.kind;
4127
- if (kind === "held") return { key: "panels.market.pluginKeptHeld" };
4128
- if (kind === "unnamed") return { key: "panels.market.pluginKeptUnnamed" };
4129
- if (kind === "unsure") return { key: "panels.market.pluginKeptUnsure" };
4130
- if (kind !== "claimed") return void 0;
4131
- const raw = kept.by;
4132
- const names = Array.isArray(raw) ? raw.filter((item) => typeof item === "string") : [];
4133
- return names.length === 0 ? { key: "panels.market.pluginKeptUnsure" } : {
4134
- key: "panels.market.pluginKeptInUse",
4135
- names
4136
- };
4137
- }
4138
- function installedPluginNotice(value, t) {
4139
- const kept = installedPluginKept(value);
4140
- if (kept === void 0) return null;
4141
- return t(kept.key, kept.names === void 0 ? {} : { names: kept.names.join(t("panels.market.listSeparator")) });
4142
- }
4143
- function noteOf(plugin) {
4144
- if (plugin.broken === true) return {
4145
- key: "panels.market.pluginBroken",
4146
- params: {},
4147
- tone: "alert"
4148
- };
4149
- if (plugin.local === true) return void 0;
4150
- }
4151
- function installedPluginRows(plugins, defaults = /* @__PURE__ */ new Set(), changed = {}) {
4152
- return plugins.map((plugin) => {
4153
- const id = `plugin:${plugin.pkg}`;
4154
- const name = plugin.name ?? plugin.pkg;
4155
- const outdated = plugin.installed !== void 0 && plugin.latest !== void 0 && plugin.latest !== plugin.installed;
4156
- const note = noteOf(plugin);
4157
- return {
4158
- id,
4159
- titleKey: plugin.pkg,
4160
- label: name,
4161
- plugin: true,
4162
- state: outdated ? "outdated" : plugin.broken === true ? "broken" : "installed",
4163
- canInstall: false,
4164
- canUpdate: outdated,
4165
- canUninstall: true,
4166
- ...plugin.local === true ? { local: true } : {},
4167
- ...plugin.broken === true ? { broken: true } : {},
4168
- defaultShown: defaults.has(id),
4169
- defaultChanged: changed[id] ?? 0,
4170
- ...note === void 0 ? {} : { note },
4171
- ...plugin.installed === void 0 ? {} : { versionLabel: `${plugin.pkg}@${plugin.installed}` },
4172
- pkg: plugin.pkg,
4173
- ...plugin.installed === void 0 ? {} : { version: {
4174
- installed: plugin.installed,
4175
- ...plugin.latest === void 0 ? {} : { latest: plugin.latest }
4176
- } }
4177
- };
4178
- });
4179
- }
4180
4240
  var MarketPage_module_default = {
4181
4241
  marketList: "_marketList_csyus_1",
4182
4242
  marketRow: "_marketRow_csyus_10",
@@ -5174,7 +5234,7 @@ function attentionSessionIdOf(input) {
5174
5234
  let bestRank = -1;
5175
5235
  for (const summary of sessionRows(workspace.sessionIds, input.sessions, input.archivedIds)) {
5176
5236
  const ofSession = attentionOfSession(summary, input.statusById, input.sessions);
5177
- if (ofSession === void 0 || ofSession === "ongoing") continue;
5237
+ if (ofSession === void 0) continue;
5178
5238
  const rank = RANK[ofSession];
5179
5239
  if (best === void 0 || rank > bestRank || rank === bestRank && isLater(summary, best)) {
5180
5240
  best = summary;
@@ -5975,12 +6035,22 @@ function makeMarketEntryIcon(units) {
5975
6035
  const manifests = useLiveManifests(units);
5976
6036
  const installable = useInstallableUnits(units);
5977
6037
  const { capabilities } = useCapabilityMap(0);
5978
- const { modules, workbench } = useModuleVersions();
5979
- const hasUpdates = marketHintVisible(marketCatalog(manifests, installable), capabilities, modules, workbench);
6038
+ const { modules, plugins, workbench } = useModuleVersions();
6039
+ const hint = marketHintOf({
6040
+ manifests,
6041
+ installable,
6042
+ capabilities,
6043
+ modules,
6044
+ installed: modules === null ? void 0 : withClientRefusals(modules, units.refusals()),
6045
+ plugins,
6046
+ workbench
6047
+ });
5980
6048
  useEffect(() => {
5981
- publishPanelHint(MARKET_PANEL_ID, hasUpdates ? { labelKey: "panels.market.hasNew" } : null);
5982
- return () => publishPanelHint(MARKET_PANEL_ID, null);
5983
- }, [hasUpdates]);
6049
+ publishPanelHint(MARKET_PANEL_ID, hint);
6050
+ }, [hint]);
6051
+ useEffect(() => () => {
6052
+ publishPanelHint(MARKET_PANEL_ID, null);
6053
+ }, []);
5984
6054
  return /* @__PURE__ */ h(IconModules, { size });
5985
6055
  };
5986
6056
  }
@@ -9044,10 +9114,10 @@ function PanelRow({ id, label, active, wide, onSelect, fallbackGlyph, renderEntr
9044
9114
  className: "wb-panelGlyph",
9045
9115
  "aria-hidden": "true"
9046
9116
  }, glyph, hint !== null && !wide ? /* @__PURE__ */ h("span", { className: "wb-panelDot" }, /* @__PURE__ */ h(StateDot, {
9047
- state: "warning",
9117
+ state: hint.tone === "danger" ? "error" : "warning",
9048
9118
  size: 9
9049
9119
  })) : null), wide ? /* @__PURE__ */ h("span", { className: "wb-panelTitle" }, label) : null, hint === null || !wide ? null : /* @__PURE__ */ h(Tag, {
9050
- tone: "warning",
9120
+ tone: hint.tone,
9051
9121
  className: "wb-panelTag"
9052
9122
  }, t(hint.labelKey))));
9053
9123
  }