@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
@@ -1809,6 +1809,7 @@ var en = {
1809
1809
  "panels.dragHint": "Drag to reorder",
1810
1810
  "panels.unknownStep": "No suite provides this view",
1811
1811
  "panels.labelWithHint": "{label} ({hint})",
1812
+ "panels.hintJoin": "; ",
1812
1813
  "panels.dep.failed": "⚠ failed to start",
1813
1814
  "panels.dep.missingPlugin": "⚠ not ready yet",
1814
1815
  "panels.dep.missingCommands": "⚠ needs an update",
@@ -1823,6 +1824,7 @@ var en = {
1823
1824
  "panels.market.notUsable": "unusable",
1824
1825
  "panels.market.broken": "broken",
1825
1826
  "panels.market.hasNew": "New version",
1827
+ "panels.market.hasProblem": "Module problem",
1826
1828
  "panels.market.missing": "not installed",
1827
1829
  "panels.market.unchecked": "unknown",
1828
1830
  "panels.market.checking": "checking",
@@ -2234,6 +2236,7 @@ var zh = {
2234
2236
  "panels.dragHint": "拖动调整顺序",
2235
2237
  "panels.unknownStep": "这一层没有套件提供",
2236
2238
  "panels.labelWithHint": "{label}({hint})",
2239
+ "panels.hintJoin": ";",
2237
2240
  "panels.dep.failed": "⚠ 起不来",
2238
2241
  "panels.dep.missingPlugin": "⚠ 还没装好",
2239
2242
  "panels.dep.missingCommands": "⚠ 需要更新",
@@ -2248,6 +2251,7 @@ var zh = {
2248
2251
  "panels.market.notUsable": "不可用",
2249
2252
  "panels.market.broken": "装坏了",
2250
2253
  "panels.market.hasNew": "有新版本",
2254
+ "panels.market.hasProblem": "模块异常",
2251
2255
  "panels.market.missing": "未装",
2252
2256
  "panels.market.unchecked": "状态未知",
2253
2257
  "panels.market.checking": "检测中",
@@ -3513,8 +3517,15 @@ var devSurface = {
3513
3517
  //#region src/app/layouts/panel-hint.ts
3514
3518
  var hints = /* @__PURE__ */ new Map();
3515
3519
  var listeners$3 = /* @__PURE__ */ new Set();
3520
+ function sameHint(left, right) {
3521
+ if (left === null || right === null) return left === right;
3522
+ if (left.labelKey !== right.labelKey || left.tone !== right.tone) return false;
3523
+ const leftMore = left.moreKeys ?? [];
3524
+ const rightMore = right.moreKeys ?? [];
3525
+ return leftMore.length === rightMore.length && leftMore.every((key, index) => key === rightMore[index]);
3526
+ }
3516
3527
  function publishPanelHint(id, hint) {
3517
- if ((hints.get(id)?.labelKey ?? null) === (hint?.labelKey ?? null)) return;
3528
+ if (sameHint(hints.get(id) ?? null, hint)) return;
3518
3529
  if (hint === null) hints.delete(id);
3519
3530
  else hints.set(id, hint);
3520
3531
  for (const listener of [...listeners$3]) listener();
@@ -3535,7 +3546,7 @@ function panelRowName(label, hint, t) {
3535
3546
  if (hint === null) return label;
3536
3547
  return t("panels.labelWithHint", {
3537
3548
  label,
3538
- hint: t(hint.labelKey)
3549
+ hint: [hint.labelKey, ...hint.moreKeys ?? []].map((key) => t(key)).join(t("panels.hintJoin"))
3539
3550
  });
3540
3551
  }
3541
3552
  //#endregion
@@ -3686,39 +3697,6 @@ function sharedRows(manifests, capabilities) {
3686
3697
  return rows;
3687
3698
  }
3688
3699
  //#endregion
3689
- //#region src/app/layouts/rightbar/market-workbench-row.ts
3690
- var WORKBENCH_ROW_ID = "workbench:self";
3691
- var WORKBENCH_TITLE_KEY = "panels.market.workbenchName";
3692
- function workbenchRow(version) {
3693
- if (version === null || version === void 0 || version.installed === "") return void 0;
3694
- const local = version.local === true;
3695
- const latest = local ? void 0 : version.latest;
3696
- const update = latest !== void 0 && latest !== version.installed ? {
3697
- installed: version.installed,
3698
- latest
3699
- } : void 0;
3700
- const note = local ? {
3701
- key: "panels.market.workbenchLocal",
3702
- params: {}
3703
- } : void 0;
3704
- return {
3705
- id: WORKBENCH_ROW_ID,
3706
- titleKey: WORKBENCH_TITLE_KEY,
3707
- workbench: true,
3708
- state: !local && version.running !== void 0 && version.running !== version.installed ? "pending-restart" : update === void 0 ? "installed" : "outdated",
3709
- canInstall: false,
3710
- canUpdate: update !== void 0,
3711
- canUninstall: false,
3712
- ...note === void 0 ? {} : { note },
3713
- version: {
3714
- installed: version.installed,
3715
- ...latest === void 0 ? {} : { latest }
3716
- },
3717
- ...update === void 0 ? {} : { moduleUpdate: update },
3718
- pkg: version.pkg
3719
- };
3720
- }
3721
- //#endregion
3722
3700
  //#region src/app/layouts/rightbar/market-rows.ts
3723
3701
  var MARKET_STATE_KEY = {
3724
3702
  checking: "panels.market.checking",
@@ -3900,10 +3878,6 @@ function marketUpdatesOf(modules) {
3900
3878
  }
3901
3879
  return next;
3902
3880
  }
3903
- function marketHintVisible(manifests, capabilities, modules, workbench) {
3904
- const self = workbenchRow(workbench);
3905
- return marketHasUpdates([...marketRows(manifests, capabilities, marketUpdatesOf(modules)), ...self === void 0 ? [] : [self]], sharedRows(manifests, capabilities));
3906
- }
3907
3881
  function marketOrder(rows, titleOf) {
3908
3882
  return [...rows].sort((left, right) => {
3909
3883
  const byTitle = titleOf(left).localeCompare(titleOf(right), "zh-Hans-CN");
@@ -3959,6 +3933,152 @@ function marketRows(manifests, capabilities, updates = {}, defaults = /* @__PURE
3959
3933
  return rows;
3960
3934
  }
3961
3935
  //#endregion
3936
+ //#region src/app/layouts/rightbar/market-plugin-rows.ts
3937
+ function installedPluginKept(value) {
3938
+ if (typeof value !== "object" || value === null) return void 0;
3939
+ const kept = value.kept;
3940
+ if (typeof kept !== "object" || kept === null) return void 0;
3941
+ const kind = kept.kind;
3942
+ if (kind === "held") return { key: "panels.market.pluginKeptHeld" };
3943
+ if (kind === "unnamed") return { key: "panels.market.pluginKeptUnnamed" };
3944
+ if (kind === "unsure") return { key: "panels.market.pluginKeptUnsure" };
3945
+ if (kind !== "claimed") return void 0;
3946
+ const raw = kept.by;
3947
+ const names = Array.isArray(raw) ? raw.filter((item) => typeof item === "string") : [];
3948
+ return names.length === 0 ? { key: "panels.market.pluginKeptUnsure" } : {
3949
+ key: "panels.market.pluginKeptInUse",
3950
+ names
3951
+ };
3952
+ }
3953
+ function installedPluginNotice(value, t) {
3954
+ const kept = installedPluginKept(value);
3955
+ if (kept === void 0) return null;
3956
+ return t(kept.key, kept.names === void 0 ? {} : { names: kept.names.join(t("panels.market.listSeparator")) });
3957
+ }
3958
+ function noteOf(plugin) {
3959
+ if (plugin.broken === true) return {
3960
+ key: "panels.market.pluginBroken",
3961
+ params: {},
3962
+ tone: "alert"
3963
+ };
3964
+ if (plugin.local === true) return void 0;
3965
+ }
3966
+ function installedPluginRows(plugins, defaults = /* @__PURE__ */ new Set(), changed = {}) {
3967
+ return plugins.map((plugin) => {
3968
+ const id = `plugin:${plugin.pkg}`;
3969
+ const name = plugin.name ?? plugin.pkg;
3970
+ const outdated = plugin.installed !== void 0 && plugin.latest !== void 0 && plugin.latest !== plugin.installed;
3971
+ const note = noteOf(plugin);
3972
+ return {
3973
+ id,
3974
+ titleKey: plugin.pkg,
3975
+ label: name,
3976
+ plugin: true,
3977
+ state: outdated ? "outdated" : plugin.broken === true ? "broken" : "installed",
3978
+ canInstall: false,
3979
+ canUpdate: outdated,
3980
+ canUninstall: true,
3981
+ ...plugin.local === true ? { local: true } : {},
3982
+ ...plugin.broken === true ? { broken: true } : {},
3983
+ defaultShown: defaults.has(id),
3984
+ defaultChanged: changed[id] ?? 0,
3985
+ ...note === void 0 ? {} : { note },
3986
+ ...plugin.installed === void 0 ? {} : { versionLabel: `${plugin.pkg}@${plugin.installed}` },
3987
+ pkg: plugin.pkg,
3988
+ ...plugin.installed === void 0 ? {} : { version: {
3989
+ installed: plugin.installed,
3990
+ ...plugin.latest === void 0 ? {} : { latest: plugin.latest }
3991
+ } }
3992
+ };
3993
+ });
3994
+ }
3995
+ //#endregion
3996
+ //#region src/app/layouts/rightbar/market-workbench-row.ts
3997
+ var WORKBENCH_ROW_ID = "workbench:self";
3998
+ var WORKBENCH_TITLE_KEY = "panels.market.workbenchName";
3999
+ function workbenchRow(version) {
4000
+ if (version === null || version === void 0 || version.installed === "") return void 0;
4001
+ const local = version.local === true;
4002
+ const latest = local ? void 0 : version.latest;
4003
+ const update = latest !== void 0 && latest !== version.installed ? {
4004
+ installed: version.installed,
4005
+ latest
4006
+ } : void 0;
4007
+ const note = local ? {
4008
+ key: "panels.market.workbenchLocal",
4009
+ params: {}
4010
+ } : void 0;
4011
+ return {
4012
+ id: WORKBENCH_ROW_ID,
4013
+ titleKey: WORKBENCH_TITLE_KEY,
4014
+ workbench: true,
4015
+ state: !local && version.running !== void 0 && version.running !== version.installed ? "pending-restart" : update === void 0 ? "installed" : "outdated",
4016
+ canInstall: false,
4017
+ canUpdate: update !== void 0,
4018
+ canUninstall: false,
4019
+ ...note === void 0 ? {} : { note },
4020
+ version: {
4021
+ installed: version.installed,
4022
+ ...latest === void 0 ? {} : { latest }
4023
+ },
4024
+ ...update === void 0 ? {} : { moduleUpdate: update },
4025
+ pkg: version.pkg
4026
+ };
4027
+ }
4028
+ //#endregion
4029
+ //#region src/app/layouts/rightbar/market-hint.ts
4030
+ var PROBLEM_KEY = "panels.market.hasProblem";
4031
+ var RESTART_KEY = "panels.market.pendingRestart";
4032
+ var UPDATES_KEY = "panels.market.hasNew";
4033
+ function isProblem(row) {
4034
+ return row.broken === true || row.state === "broken" || row.state === "unusable" || row.note?.key === "panels.market.moduleRefused";
4035
+ }
4036
+ function isRestart(row) {
4037
+ return row.state === "inactive" || row.state === "pending-restart";
4038
+ }
4039
+ function awaitsRestart(input) {
4040
+ const loaded = new Set(input.manifests.map((manifest) => manifest.id));
4041
+ return (input.installed ?? []).some((module) => !loaded.has(module.unit) && refusalReasons(module.refused, module.clientRefused).length === 0);
4042
+ }
4043
+ function marketHintOf(input) {
4044
+ const marketable = marketCatalog(input.manifests, input.installable);
4045
+ const catalog = marketRows(marketable, input.capabilities, marketUpdatesOf(input.modules));
4046
+ const listed = new Set(catalog.map((row) => row.id));
4047
+ const self = workbenchRow(input.workbench);
4048
+ const rows = [
4049
+ ...catalog,
4050
+ ...installedRows(input.installed ?? [], input.manifests, listed),
4051
+ ...installedPluginRows(input.plugins ?? []),
4052
+ ...self === void 0 ? [] : [self]
4053
+ ];
4054
+ const problem = rows.some(isProblem);
4055
+ const restart = rows.some(isRestart) || awaitsRestart(input);
4056
+ const updates = marketHasUpdates(rows, sharedRows(marketable, input.capabilities));
4057
+ const more = [];
4058
+ if (problem) {
4059
+ if (restart) more.push(RESTART_KEY);
4060
+ if (updates) more.push(UPDATES_KEY);
4061
+ return {
4062
+ labelKey: PROBLEM_KEY,
4063
+ tone: "danger",
4064
+ ...more.length === 0 ? {} : { moreKeys: more }
4065
+ };
4066
+ }
4067
+ if (restart) {
4068
+ if (updates) more.push(UPDATES_KEY);
4069
+ return {
4070
+ labelKey: RESTART_KEY,
4071
+ tone: "warning",
4072
+ ...more.length === 0 ? {} : { moreKeys: more }
4073
+ };
4074
+ }
4075
+ if (updates) return {
4076
+ labelKey: UPDATES_KEY,
4077
+ tone: "warning"
4078
+ };
4079
+ return null;
4080
+ }
4081
+ //#endregion
3962
4082
  //#region src/shared/hooks/use-host-write.ts
3963
4083
  var use_host_write_exports = /* @__PURE__ */ __exportAll({ useHostWrite: () => useHostWrite });
3964
4084
  function useHostWrite(options) {
@@ -4114,66 +4234,6 @@ function useMarketTransient(input) {
4114
4234
  setNotice
4115
4235
  };
4116
4236
  }
4117
- //#endregion
4118
- //#region src/app/layouts/rightbar/market-plugin-rows.ts
4119
- function installedPluginKept(value) {
4120
- if (typeof value !== "object" || value === null) return void 0;
4121
- const kept = value.kept;
4122
- if (typeof kept !== "object" || kept === null) return void 0;
4123
- const kind = kept.kind;
4124
- if (kind === "held") return { key: "panels.market.pluginKeptHeld" };
4125
- if (kind === "unnamed") return { key: "panels.market.pluginKeptUnnamed" };
4126
- if (kind === "unsure") return { key: "panels.market.pluginKeptUnsure" };
4127
- if (kind !== "claimed") return void 0;
4128
- const raw = kept.by;
4129
- const names = Array.isArray(raw) ? raw.filter((item) => typeof item === "string") : [];
4130
- return names.length === 0 ? { key: "panels.market.pluginKeptUnsure" } : {
4131
- key: "panels.market.pluginKeptInUse",
4132
- names
4133
- };
4134
- }
4135
- function installedPluginNotice(value, t) {
4136
- const kept = installedPluginKept(value);
4137
- if (kept === void 0) return null;
4138
- return t(kept.key, kept.names === void 0 ? {} : { names: kept.names.join(t("panels.market.listSeparator")) });
4139
- }
4140
- function noteOf(plugin) {
4141
- if (plugin.broken === true) return {
4142
- key: "panels.market.pluginBroken",
4143
- params: {},
4144
- tone: "alert"
4145
- };
4146
- if (plugin.local === true) return void 0;
4147
- }
4148
- function installedPluginRows(plugins, defaults = /* @__PURE__ */ new Set(), changed = {}) {
4149
- return plugins.map((plugin) => {
4150
- const id = `plugin:${plugin.pkg}`;
4151
- const name = plugin.name ?? plugin.pkg;
4152
- const outdated = plugin.installed !== void 0 && plugin.latest !== void 0 && plugin.latest !== plugin.installed;
4153
- const note = noteOf(plugin);
4154
- return {
4155
- id,
4156
- titleKey: plugin.pkg,
4157
- label: name,
4158
- plugin: true,
4159
- state: outdated ? "outdated" : plugin.broken === true ? "broken" : "installed",
4160
- canInstall: false,
4161
- canUpdate: outdated,
4162
- canUninstall: true,
4163
- ...plugin.local === true ? { local: true } : {},
4164
- ...plugin.broken === true ? { broken: true } : {},
4165
- defaultShown: defaults.has(id),
4166
- defaultChanged: changed[id] ?? 0,
4167
- ...note === void 0 ? {} : { note },
4168
- ...plugin.installed === void 0 ? {} : { versionLabel: `${plugin.pkg}@${plugin.installed}` },
4169
- pkg: plugin.pkg,
4170
- ...plugin.installed === void 0 ? {} : { version: {
4171
- installed: plugin.installed,
4172
- ...plugin.latest === void 0 ? {} : { latest: plugin.latest }
4173
- } }
4174
- };
4175
- });
4176
- }
4177
4237
  var MarketPage_module_default = {
4178
4238
  marketList: "_marketList_csyus_1",
4179
4239
  marketRow: "_marketRow_csyus_10",
@@ -5171,7 +5231,7 @@ function attentionSessionIdOf(input) {
5171
5231
  let bestRank = -1;
5172
5232
  for (const summary of sessionRows(workspace.sessionIds, input.sessions, input.archivedIds)) {
5173
5233
  const ofSession = attentionOfSession(summary, input.statusById, input.sessions);
5174
- if (ofSession === void 0 || ofSession === "ongoing") continue;
5234
+ if (ofSession === void 0) continue;
5175
5235
  const rank = RANK[ofSession];
5176
5236
  if (best === void 0 || rank > bestRank || rank === bestRank && isLater(summary, best)) {
5177
5237
  best = summary;
@@ -5972,12 +6032,22 @@ function makeMarketEntryIcon(units) {
5972
6032
  const manifests = useLiveManifests(units);
5973
6033
  const installable = useInstallableUnits(units);
5974
6034
  const { capabilities } = useCapabilityMap(0);
5975
- const { modules, workbench } = useModuleVersions();
5976
- const hasUpdates = marketHintVisible(marketCatalog(manifests, installable), capabilities, modules, workbench);
6035
+ const { modules, plugins, workbench } = useModuleVersions();
6036
+ const hint = marketHintOf({
6037
+ manifests,
6038
+ installable,
6039
+ capabilities,
6040
+ modules,
6041
+ installed: modules === null ? void 0 : withClientRefusals(modules, units.refusals()),
6042
+ plugins,
6043
+ workbench
6044
+ });
5977
6045
  useEffect(() => {
5978
- publishPanelHint(MARKET_PANEL_ID, hasUpdates ? { labelKey: "panels.market.hasNew" } : null);
5979
- return () => publishPanelHint(MARKET_PANEL_ID, null);
5980
- }, [hasUpdates]);
6046
+ publishPanelHint(MARKET_PANEL_ID, hint);
6047
+ }, [hint]);
6048
+ useEffect(() => () => {
6049
+ publishPanelHint(MARKET_PANEL_ID, null);
6050
+ }, []);
5981
6051
  return /* @__PURE__ */ h(IconModules, { size });
5982
6052
  };
5983
6053
  }
@@ -9041,10 +9111,10 @@ function PanelRow({ id, label, active, wide, onSelect, fallbackGlyph, renderEntr
9041
9111
  className: "wb-panelGlyph",
9042
9112
  "aria-hidden": "true"
9043
9113
  }, glyph, hint !== null && !wide ? /* @__PURE__ */ h("span", { className: "wb-panelDot" }, /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
9044
- state: "warning",
9114
+ state: hint.tone === "danger" ? "error" : "warning",
9045
9115
  size: 9
9046
9116
  })) : null), wide ? /* @__PURE__ */ h("span", { className: "wb-panelTitle" }, label) : null, hint === null || !wide ? null : /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.Tag, {
9047
- tone: "warning",
9117
+ tone: hint.tone,
9048
9118
  className: "wb-panelTag"
9049
9119
  }, t(hint.labelKey))));
9050
9120
  }