@dsh-workbench/core 0.1.18 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/client.js +2241 -955
  2. package/dist/client/client.body.js +2241 -955
  3. package/dist/client/index.js +2242 -956
  4. package/dist/host/index.js +1840 -332
  5. package/dist/types/app/client.d.ts +225 -81
  6. package/dist/types/app/layouts/__tests__/async-feedback.test.d.ts +1 -0
  7. package/dist/types/app/layouts/market/__tests__/add-module-stages.test.d.ts +1 -0
  8. package/dist/types/app/layouts/market/add-module-text.d.ts +16 -1
  9. package/dist/types/app/layouts/market/use-add-module.d.ts +3 -8
  10. package/dist/types/app/layouts/market/use-module-versions.d.ts +2 -1
  11. package/dist/types/app/layouts/rightbar/MarketView.d.ts +7 -1
  12. package/dist/types/app/layouts/rightbar/ModulesPage.d.ts +4 -2
  13. package/dist/types/app/layouts/rightbar/PanelGroupRows.d.ts +10 -0
  14. package/dist/types/app/layouts/rightbar/PanelModules.d.ts +2 -2
  15. package/dist/types/app/layouts/rightbar/PanelRowControls.d.ts +13 -0
  16. package/dist/types/app/layouts/rightbar/__tests__/market-catalog.test.d.ts +1 -0
  17. package/dist/types/app/layouts/rightbar/__tests__/market-dots.test.d.ts +1 -0
  18. package/dist/types/app/layouts/rightbar/__tests__/market-row-icon.test.d.ts +1 -0
  19. package/dist/types/app/layouts/rightbar/__tests__/market-section-icon.test.d.ts +1 -0
  20. package/dist/types/app/layouts/rightbar/__tests__/market-state-rules.test.d.ts +1 -0
  21. package/dist/types/app/layouts/rightbar/__tests__/market-workbench.test.d.ts +1 -0
  22. package/dist/types/app/layouts/rightbar/__tests__/panel-dismiss.test.d.ts +1 -0
  23. package/dist/types/app/layouts/rightbar/__tests__/panel-drag-target.test.d.ts +1 -0
  24. package/dist/types/app/layouts/rightbar/__tests__/panel-plugin-rows.test.d.ts +1 -0
  25. package/dist/types/app/layouts/rightbar/__tests__/panel-scope-ui.test.d.ts +1 -0
  26. package/dist/types/app/layouts/rightbar/__tests__/panel-write.test.d.ts +1 -0
  27. package/dist/types/app/layouts/rightbar/board-selection.d.ts +20 -0
  28. package/dist/types/app/layouts/rightbar/dsh-borrow.d.ts +15 -0
  29. package/dist/types/app/layouts/rightbar/dsh-borrow.test.d.ts +1 -0
  30. package/dist/types/app/layouts/rightbar/dsh-surface.d.ts +11 -0
  31. package/dist/types/app/layouts/rightbar/dsh-surface.test.d.ts +1 -0
  32. package/dist/types/app/layouts/rightbar/market-act.d.ts +21 -0
  33. package/dist/types/app/layouts/rightbar/market-installed-mock.d.ts +9 -0
  34. package/dist/types/app/layouts/rightbar/market-mock-types.d.ts +58 -0
  35. package/dist/types/app/layouts/rightbar/market-mock.d.ts +2 -43
  36. package/dist/types/app/layouts/rightbar/market-plugin-rows.d.ts +3 -1
  37. package/dist/types/app/layouts/rightbar/market-row-icon.d.ts +7 -0
  38. package/dist/types/app/layouts/rightbar/market-row-types.d.ts +37 -0
  39. package/dist/types/app/layouts/rightbar/market-rows.d.ts +13 -53
  40. package/dist/types/app/layouts/rightbar/market-section-icon.d.ts +3 -0
  41. package/dist/types/app/layouts/rightbar/market-section.d.ts +18 -0
  42. package/dist/types/app/layouts/rightbar/market-shared-rows.d.ts +21 -0
  43. package/dist/types/app/layouts/rightbar/market-view-text.d.ts +7 -1
  44. package/dist/types/app/layouts/rightbar/market-workbench-row.d.ts +5 -0
  45. package/dist/types/app/layouts/rightbar/panel-dismiss.d.ts +2 -0
  46. package/dist/types/app/layouts/rightbar/panel-mock.d.ts +3 -2
  47. package/dist/types/app/layouts/rightbar/panel-write.d.ts +15 -0
  48. package/dist/types/app/layouts/rightbar/use-drag-listeners.d.ts +6 -0
  49. package/dist/types/app/layouts/rightbar/use-panels.d.ts +15 -1
  50. package/dist/types/app/layouts/sidebar/__tests__/session-row-ui.test.d.ts +1 -0
  51. package/dist/types/app/units/registry.d.ts +5 -2
  52. package/dist/types/modules/panels/__tests__/diy-harness.d.ts +19 -0
  53. package/dist/types/modules/panels/__tests__/diy-report.test.d.ts +1 -0
  54. package/dist/types/modules/panels/__tests__/diy-tools-health.test.d.ts +1 -0
  55. package/dist/types/modules/panels/__tests__/diy-tools-panel.test.d.ts +1 -0
  56. package/dist/types/modules/panels/__tests__/plugin-panel-market-parity.test.d.ts +1 -0
  57. package/dist/types/modules/panels/__tests__/plugin-panel.test.d.ts +1 -0
  58. package/dist/types/modules/panels/__tests__/plugin-tool-units.test.d.ts +1 -0
  59. package/dist/types/modules/panels/__tests__/scope-machine.test.d.ts +1 -0
  60. package/dist/types/modules/panels/__tests__/scope-support.d.ts +51 -0
  61. package/dist/types/modules/panels/model/config.d.ts +23 -3
  62. package/dist/types/modules/panels/model/diy-report.d.ts +63 -0
  63. package/dist/types/modules/panels/model/market-dispatch.d.ts +4 -0
  64. package/dist/types/modules/panels/model/market-registry.d.ts +12 -0
  65. package/dist/types/modules/panels/model/market-registry.test.d.ts +1 -0
  66. package/dist/types/modules/panels/model/market-types.d.ts +1 -0
  67. package/dist/types/modules/panels/model/market.d.ts +3 -2
  68. package/dist/types/modules/panels/model/plugin-panel.d.ts +3 -0
  69. package/dist/types/modules/panels/model/prefs.d.ts +3 -1
  70. package/dist/types/modules/panels/model/service.d.ts +5 -1
  71. package/dist/types/shared/api/bundle-install.d.ts +15 -1
  72. package/dist/types/shared/api/host/__tests__/approval-note-injection.test.d.ts +1 -0
  73. package/dist/types/shared/api/host/__tests__/panel-state-route.test.d.ts +1 -0
  74. package/dist/types/shared/api/host/__tests__/plugin-catalog.test.d.ts +1 -0
  75. package/dist/types/shared/api/host/__tests__/plugin-login-hint.test.d.ts +1 -0
  76. package/dist/types/shared/api/host/__tests__/plugin-tools.test.d.ts +1 -0
  77. package/dist/types/shared/api/host/bundle-inspect-kind.test.d.ts +1 -0
  78. package/dist/types/shared/api/host/bundle-routes-self.test.d.ts +1 -0
  79. package/dist/types/shared/api/host/installed-module.d.ts +12 -0
  80. package/dist/types/shared/api/host/mount-units.d.ts +1 -0
  81. package/dist/types/shared/api/host/plugin-catalog.d.ts +60 -0
  82. package/dist/types/shared/api/host/plugin-login-hint.d.ts +2 -0
  83. package/dist/types/shared/api/host/plugin-tools.d.ts +10 -0
  84. package/dist/types/shared/api/host/plugin-units.d.ts +47 -0
  85. package/dist/types/shared/api/host/unit-registry.d.ts +9 -0
  86. package/dist/types/shared/api/unit-manifests.d.ts +1 -0
  87. package/dist/types/shared/components/PanelFoot.d.ts +1 -1
  88. package/dist/types/shared/hooks/panel-state-report.d.ts +13 -0
  89. package/dist/types/shared/hooks/panel-state-report.test.d.ts +1 -0
  90. package/docs/HANDOFF.md +7 -0
  91. package/package.json +2 -2
  92. package/preset/diy.patch.yml +5 -26
  93. package/skills/workbench-module-diy/REVIEW.md +22 -0
  94. package/skills/workbench-module-diy/SKILL.md +3 -1
  95. package/skills/workbench-module-diy/TOOLING.md +2 -0
@@ -1,4 +1,4 @@
1
- import { Button, CodeBlock, DisclosureRow, IconCheckCircleFillRegular, IconCheckOutlineRegular, IconChevronDownOutlineRegular, IconCodeOutlineRegular, IconEditOutlineRegular, IconEllipsisOutlineRegular, IconFlatListOutlineRegular, IconFolderCloseRegular, IconFolderOpenRegular, IconInfoOutlineRegular, IconNewChatOutlineRegular, IconPanelLeftOutlineRegular, IconPinOutlineRegular, IconPlusOutlineRegular, IconRefreshOutlineRegular, IconRightUpOutlineRegular, IconSearchOutlineRegular, IconSettingsOutlineRegular, IconTrashOutlineRegular, IconWarningOutlineRegular, Menu, Modal, RiskConfirmation, StateDot, Switch, Tag, TextShimmer, Tooltip, useAnchoredPosition, useDismissOnOutsidePointer, writeClipboard } from "@deepseek-ai/dsh-client-ui-primitives";
1
+ import { Button, CodeBlock, DisclosureRow, IconArchiveOutlineRegular, IconCheckCircleFillRegular, IconCheckOutlineRegular, IconChevronDownOutlineRegular, IconCodeOutlineRegular, IconCordisPluginOutlineRegular, IconDownloadOutlineRegular, IconEditOutlineRegular, IconEllipsisOutlineRegular, IconFlatListOutlineRegular, IconFolderCloseRegular, IconFolderOpenRegular, IconInfoOutlineRegular, IconLinkOutlineRegular, IconNewChatOutlineRegular, IconPanelLeftOutlineRegular, IconPinOutlineRegular, IconPlusOutlineRegular, IconRefreshOutlineRegular, IconRightUpOutlineRegular, IconSearchOutlineRegular, IconSettingsOutlineRegular, IconTrashOutlineRegular, IconWarningOutlineRegular, Menu, Modal, RiskConfirmation, StateDot, Switch, Tag, TextShimmer, Tooltip, useAnchoredPosition, useDismissOnOutsidePointer, writeClipboard } from "@deepseek-ai/dsh-client-ui-primitives";
2
2
  //#region \0rolldown/runtime.js
3
3
  var __defProp = Object.defineProperty;
4
4
  var __exportAll = (all, no_symbols) => {
@@ -422,6 +422,11 @@ function probeKeyOf(error) {
422
422
  if (error === void 0) return null;
423
423
  return error.code === "" ? "unknown" : error.code;
424
424
  }
425
+ //#endregion
426
+ //#region ../shared/dist/api/unit.js
427
+ function hasEnvSupply(manifest) {
428
+ return (manifest.env?.plugins ?? []).length > 0 || (manifest.env?.libs ?? []).length > 0;
429
+ }
425
430
  var SUPPORTED_API_VERSIONS = [1];
426
431
  var DECLARATION_KEYS = [
427
432
  "apiVersion",
@@ -557,10 +562,13 @@ var PREFS_PREFIX = `${API_PREFIX}/prefs`;
557
562
  var EVENTS_PATH = "/workbench/events";
558
563
  var ACTIONS_PREFIX = `${API_PREFIX}/actions`;
559
564
  var PROVISION_PREFIX = `${API_PREFIX}/provision`;
565
+ var PANEL_STATE_PATH = "panel-state";
566
+ var PANEL_STATE_PREFIX = `${API_PREFIX}/${PANEL_STATE_PATH}`;
560
567
  var OPENCLI_PIN = "1.8.8";
561
568
  var CODING_ISSUES_SERVICE = "workbenchCodingIssues";
562
569
  var PANELS_SERVICE = "workbenchPanels";
563
570
  var UNITS_SERVICE = "workbenchUnits";
571
+ var PANEL_STATE_SERVICE = "workbenchPanelState";
564
572
  var OPENCLI_TIMEOUT_MS = 12e4;
565
573
  var WARM_TIMEOUT_MS = 2e4;
566
574
  var INSTALL_TIMEOUT_MS = 3e5;
@@ -680,7 +688,9 @@ var CardBoundary = class extends Component {
680
688
  return { reason: errorReasonOf(error) };
681
689
  }
682
690
  componentDidCatch(error) {
683
- console.error(`[dsh-workbench] 模块 ${this.props.unit} 渲染失败:${errorReasonOf(error)}`, error);
691
+ const reason = errorReasonOf(error);
692
+ console.error(`[dsh-workbench] 模块 ${this.props.unit} 渲染失败:${reason}`, error);
693
+ this.props.onFailure?.(reason);
684
694
  }
685
695
  componentDidUpdate(previous) {
686
696
  if (previous.resetKey !== this.props.resetKey && this.state.reason !== null) this.setState({ reason: null });
@@ -1090,6 +1100,50 @@ function IconBrandMark({ size = 24 }) {
1090
1100
  strokeLinecap: "round"
1091
1101
  }));
1092
1102
  }
1103
+ function IconOpencli({ size = 16 }) {
1104
+ return h(Shell, {
1105
+ size,
1106
+ viewBox: "0 0 64 64"
1107
+ }, h("defs", null, h("linearGradient", {
1108
+ id: "opencli-mark",
1109
+ x1: "0%",
1110
+ y1: "0%",
1111
+ x2: "100%",
1112
+ y2: "100%"
1113
+ }, h("stop", {
1114
+ offset: "0%",
1115
+ stopColor: "#00e5a0"
1116
+ }), h("stop", {
1117
+ offset: "50%",
1118
+ stopColor: "#00b4d8"
1119
+ }), h("stop", {
1120
+ offset: "100%",
1121
+ stopColor: "#7b61ff"
1122
+ }))), h("rect", {
1123
+ width: 64,
1124
+ height: 64,
1125
+ rx: 14,
1126
+ fill: "#0a0a0f"
1127
+ }), h("text", {
1128
+ x: "50%",
1129
+ y: "54%",
1130
+ dominantBaseline: "middle",
1131
+ textAnchor: "middle",
1132
+ fontFamily: "monospace",
1133
+ fontWeight: 700,
1134
+ fontSize: 28,
1135
+ fill: "url(#opencli-mark)"
1136
+ }, ">_"));
1137
+ }
1138
+ function IconNpm({ size = 16 }) {
1139
+ return h(Shell, {
1140
+ size,
1141
+ viewBox: "0 0 1024 1024"
1142
+ }, h("path", {
1143
+ d: "M64 337.76h896v298.72H512v49.792H312.896v-49.824H64z m49.792 248.928h99.552v-149.376h49.76v149.344h49.792v-199.104H113.792z m248.896-199.136v248.928h99.552v-49.792h99.552v-199.136z m99.552 49.792H512v99.584h-49.792z m149.344-49.792v199.136h99.552v-149.376h49.792v149.344h49.792v-149.344h49.792v149.344h49.792v-199.104z",
1144
+ fill: "#CB3837"
1145
+ }));
1146
+ }
1093
1147
  function IconModules({ size = 16 }) {
1094
1148
  return h("svg", {
1095
1149
  width: size,
@@ -1179,6 +1233,8 @@ var en = {
1179
1233
  "project.none": "No project",
1180
1234
  "project.empty": "No projects yet. Use “Add project” below.",
1181
1235
  "project.add": "Add project…",
1236
+ "project.add.busy": "Creating the workspace…",
1237
+ "project.add.failed": "Creating the workspace failed",
1182
1238
  "project.search.label": "Search workspaces",
1183
1239
  "project.search.placeholder": "Search workspaces (folder / name / path)",
1184
1240
  "project.search.empty": "No workspace matches “{query}”.",
@@ -1212,13 +1268,22 @@ var en = {
1212
1268
  "time.hours": "{n} h ago",
1213
1269
  "time.days": "{n} d ago",
1214
1270
  "panels.title": "Panel modules",
1215
- "panels.reset": "Reset",
1271
+ "panels.groupBoardless": "No-board modules",
1272
+ "panels.groupPlugins": "opencli plugins",
1273
+ "panels.market.defaultHint": "When on, it is on by default in every workspace; you can also turn it off for a single workspace in Panel setup.",
1274
+ "panels.market.defaultLabel": "On by default everywhere",
1275
+ "panels.market.defaultLocked": "Unusable right now — update or uninstall it first",
1276
+ "panels.followAll": "Restore the default everywhere",
1277
+ "panels.followAllConfirmTitle": "Restore the default everywhere?",
1278
+ "panels.followAllConfirmDetail": "Every row changed in this workspace goes back to following the global default.",
1279
+ "panels.followAllConfirmAck": "I understand: to set them up for this workspace again, I will have to change them row by row.",
1280
+ "panels.followAllConfirmYes": "Restore",
1281
+ "panels.followAllConfirmNo": "Cancel",
1216
1282
  "panels.enabled": "enabled in this project",
1217
1283
  "panels.disabled": "not enabled in this project",
1218
1284
  "panels.choose": "Choose modules",
1219
1285
  "panels.buildModule": "Build a module",
1220
1286
  "panels.failed": "Could not save the change. Try again.",
1221
- "panels.hintEffect": "Disabling = the agent cannot reach that data",
1222
1287
  "panels.dragHint": "Drag to reorder",
1223
1288
  "panels.unknownStep": "No suite provides this view",
1224
1289
  "panels.labelWithHint": "{label} ({hint})",
@@ -1232,7 +1297,9 @@ var en = {
1232
1297
  "panels.noneInstalled": "None of these modules has its plugin installed yet",
1233
1298
  "panels.noneInstalledHint": "Once installed they come back here, and you pick which go on the panel.",
1234
1299
  "panels.market.installed": "installed",
1235
- "panels.market.outdated": "needs update",
1300
+ "panels.market.notActive": "not active",
1301
+ "panels.market.notUsable": "unusable",
1302
+ "panels.market.broken": "broken",
1236
1303
  "panels.market.hasNew": "New version",
1237
1304
  "panels.market.missing": "not installed",
1238
1305
  "panels.market.unchecked": "unknown",
@@ -1240,7 +1307,7 @@ var en = {
1240
1307
  "panels.market.sectionInstalled": "Installed modules",
1241
1308
  "panels.market.sectionPending": "Not installed",
1242
1309
  "panels.market.sectionShared": "Shared dependencies",
1243
- "panels.market.sharedUsedBy": "Used by {modules}",
1310
+ "panels.market.sharedUsedBy": "Used by module {modules}",
1244
1311
  "panels.market.listSeparator": ", ",
1245
1312
  "panels.market.sharedMissing": "not installed",
1246
1313
  "panels.market.sharedOutdated": "update available",
@@ -1262,22 +1329,24 @@ var en = {
1262
1329
  "panels.market.confirmNo": "Cancel",
1263
1330
  "panels.market.failed": "Failed: {reason}",
1264
1331
  "panels.market.needEnv": "Set {env} in the terminal that started the workbench first",
1332
+ "panels.market.needCommands": "Missing commands: {commands}",
1333
+ "panels.market.localMark": "local",
1334
+ "panels.market.localHint": "This is your machine’s own copy (not taken from the registry).",
1265
1335
  "panels.market.noSource": "This module declares no install method — install it yourself",
1266
1336
  "panels.market.badSource": "The install method is incomplete — install it yourself",
1267
1337
  "panels.market.empty": "No modules available",
1268
- "panels.market.sectionLocal": "Local modules",
1269
- "panels.market.sectionUnlisted": "Not from the market",
1270
1338
  "panels.market.sectionPlugins": "Installed opencli plugins",
1271
1339
  "panels.market.moduleOutdated": "update available",
1272
- "panels.market.moduleRefused": "This module was built for an older version of the workbench, so it does not work here. Update it, or uninstall.",
1340
+ "panels.market.moduleRefused": "This module does not match this workbench, so it cannot be used for now.",
1273
1341
  "panels.market.moduleRefusedDetail": "Why it cannot be used: {reason}",
1274
- "panels.market.moduleRestartHint": "installed but not active — restart dsh once to bring it up",
1342
+ "panels.market.moduleRestartHint": "restart dsh once to bring it up",
1343
+ "panels.market.workbenchName": "Workbench",
1344
+ "panels.market.workbenchLocal": "This is the copy from your working repository; it does not come from the registry.",
1275
1345
  "panels.market.pluginKeptInUse": "Files kept for now: {names} still uses it.",
1276
1346
  "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.",
1277
1347
  "panels.market.pluginKeptHeld": "Files kept: this one is yours, and a module letting go will not remove it.",
1278
1348
  "panels.market.pluginKeptUnnamed": "Files kept for now: this one cannot be identified as a plugin, so it is unclear who needs it.",
1279
- "panels.market.pluginAlsoKnownAs": "Its package is {pkg} (updates and uninstall use that)",
1280
- "panels.market.pluginBroken": "This install is broken: it cannot be identified as a plugin. Uninstall it, or install it again by package name above.",
1349
+ "panels.market.pluginBroken": "This install is broken: it cannot be identified as a plugin. Uninstall it, or tell the agent to reinstall it by package name with workbench_modules (the install-bundle action).",
1281
1350
  "panels.market.restartNeeded": "The new version is installed — restart once to pick it up.",
1282
1351
  "panels.market.foot": "After installing, enable it in the panel page of that project.",
1283
1352
  "panels.market.recheck": "Check for updates",
@@ -1286,7 +1355,7 @@ var en = {
1286
1355
  "panels.market.justNow": "just now",
1287
1356
  "panels.market.minutesAgo": "{n} min ago",
1288
1357
  "panels.market.hoursAgo": "{n} h ago",
1289
- "panels.market.add.description": "Enter a package name, a Git URL, or a path to a local directory.",
1358
+ "panels.market.add.description": "Enter a module or opencli plugin package name, Git repository URL, or local directory path.",
1290
1359
  "panels.market.add.specPlaceholder": "e.g. @dsh-workbench/module-hello",
1291
1360
  "panels.market.add.guideToggle": "Install guide and examples",
1292
1361
  "panels.market.add.guideHide": "Hide guide",
@@ -1325,11 +1394,13 @@ var en = {
1325
1394
  "panels.market.add.problemInstalled": "This module is already installed",
1326
1395
  "panels.market.add.problemNotFound": "No such module found",
1327
1396
  "panels.market.add.problemNotPackage": "That path does not exist or is not a valid module package",
1328
- "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.",
1397
+ "panels.market.add.problemNotBundle": "This package cannot be installed here: {reason}. This entry recognises workbench modules and opencli plugins by package name, and installs either; but a git URL or a tarball does not reveal what it is — if it is really one of those two, use its package name or a local folder instead.",
1329
1398
  "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.",
1330
1399
  "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.",
1331
1400
  "panels.market.add.failureNotModuleOrPlugin": "This package is neither a workbench module nor an opencli plugin, so installing it would do nothing",
1332
1401
  "panels.market.add.installedPlugin": "Installed: the opencli plugin {name}",
1402
+ "panels.market.add.pluginPreview": "This is an opencli plugin: it goes into the opencli plugin area and works as soon as it is installed — no restart.",
1403
+ "panels.market.add.pluginAlias": "Plugin name: {name}",
1333
1404
  "panels.market.add.problemNetwork": "Cannot reach the module source; check the network and retry",
1334
1405
  "panels.market.add.problemUnknown": "Cannot fetch module information: {reason}",
1335
1406
  "panels.market.add.failureNetwork": "The network connection failed",
@@ -1360,7 +1431,7 @@ var en = {
1360
1431
  "panels.market.add.registryPnpm": "pnpm's own registry",
1361
1432
  "panels.market.add.check": "Check",
1362
1433
  "panels.market.add.checking": "Checking…",
1363
- "panels.market.add.classifying": "Working out what it is…",
1434
+ "panels.market.add.classifying": "Checking…",
1364
1435
  "panels.market.add.change": "Edit",
1365
1436
  "panels.market.add.previewTitle": "About to install",
1366
1437
  "panels.market.add.fieldName": "Package",
@@ -1507,6 +1578,8 @@ var zh = {
1507
1578
  "project.none": "未选择项目",
1508
1579
  "project.empty": "还没有项目。用下面的「添加项目」选一个目录。",
1509
1580
  "project.add": "添加项目…",
1581
+ "project.add.busy": "正在新建工作区…",
1582
+ "project.add.failed": "新建工作区没成功",
1510
1583
  "project.search.label": "搜索工作区",
1511
1584
  "project.search.placeholder": "搜索工作区(目录名 / 中文名 / 路径)",
1512
1585
  "project.search.empty": "没有匹配「{query}」的工作区。",
@@ -1540,13 +1613,22 @@ var zh = {
1540
1613
  "time.hours": "{n} 小时前",
1541
1614
  "time.days": "{n} 天前",
1542
1615
  "panels.title": "面板模块",
1543
- "panels.reset": "恢复默认",
1616
+ "panels.groupBoardless": "无看板模块",
1617
+ "panels.groupPlugins": "opencli 插件",
1618
+ "panels.market.defaultHint": "打开后所有工作区默认开启,也可在工作区面板配置中单独关闭",
1619
+ "panels.market.defaultLabel": "全局默认开启",
1620
+ "panels.market.defaultLocked": "这份现在用不了,先更新或卸载",
1621
+ "panels.followAll": "全部恢复默认",
1622
+ "panels.followAllConfirmTitle": "全部恢复默认?",
1623
+ "panels.followAllConfirmDetail": "这个工作区里改过的每一行都会清掉,之后都跟随全局。",
1624
+ "panels.followAllConfirmAck": "我明白:清掉之后,想再按这个工作区配,得一行一行重新改。",
1625
+ "panels.followAllConfirmYes": "恢复默认",
1626
+ "panels.followAllConfirmNo": "取消",
1544
1627
  "panels.enabled": "这个项目已启用",
1545
1628
  "panels.disabled": "这个项目未启用",
1546
1629
  "panels.choose": "选择模块",
1547
1630
  "panels.buildModule": "造一个模块",
1548
1631
  "panels.failed": "改配置失败了,再试一次。",
1549
- "panels.hintEffect": "停用 = agent 拿不到相关数据",
1550
1632
  "panels.dragHint": "拖动调整顺序",
1551
1633
  "panels.unknownStep": "这一层没有套件提供",
1552
1634
  "panels.labelWithHint": "{label}({hint})",
@@ -1560,7 +1642,9 @@ var zh = {
1560
1642
  "panels.noneInstalled": "这些模块要的插件都还没装",
1561
1643
  "panels.noneInstalledHint": "装好之后它们会回到这里,再由你决定放哪几个上板。",
1562
1644
  "panels.market.installed": "已安装",
1563
- "panels.market.outdated": "要更新",
1645
+ "panels.market.notActive": "未生效",
1646
+ "panels.market.notUsable": "不可用",
1647
+ "panels.market.broken": "装坏了",
1564
1648
  "panels.market.hasNew": "有新版本",
1565
1649
  "panels.market.missing": "未装",
1566
1650
  "panels.market.unchecked": "状态未知",
@@ -1568,7 +1652,7 @@ var zh = {
1568
1652
  "panels.market.sectionInstalled": "已安装模块",
1569
1653
  "panels.market.sectionPending": "未安装",
1570
1654
  "panels.market.sectionShared": "共用依赖",
1571
- "panels.market.sharedUsedBy": "供 {modules} 使用",
1655
+ "panels.market.sharedUsedBy": "供 {modules} 模块使用",
1572
1656
  "panels.market.listSeparator": "、",
1573
1657
  "panels.market.sharedMissing": "未装",
1574
1658
  "panels.market.sharedOutdated": "有新版",
@@ -1590,22 +1674,24 @@ var zh = {
1590
1674
  "panels.market.confirmNo": "取消",
1591
1675
  "panels.market.failed": "没成功:{reason}",
1592
1676
  "panels.market.needEnv": "先在启动工作台的终端里设 {env}",
1677
+ "panels.market.needCommands": "缺这几条命令:{commands}",
1678
+ "panels.market.localMark": "本地",
1679
+ "panels.market.localHint": "本机那份(不从源上取)。",
1593
1680
  "panels.market.noSource": "这个模块没声明怎么装,只能自己动手",
1594
1681
  "panels.market.badSource": "安装方式没写全,只能自己动手",
1595
1682
  "panels.market.empty": "暂无可用模块",
1596
- "panels.market.sectionLocal": "本地模块",
1597
- "panels.market.sectionUnlisted": "不是从市场装的",
1598
1683
  "panels.market.sectionPlugins": "已安装 opencli 插件",
1599
1684
  "panels.market.moduleOutdated": "有新版",
1600
- "panels.market.moduleRefused": "这个模块是给旧版本的工作台写的,现在用不了。更新它,或者卸载。",
1685
+ "panels.market.moduleRefused": "模块版本与工作台不匹配,暂时无法使用",
1601
1686
  "panels.market.moduleRefusedDetail": "装不上的原因:{reason}",
1602
- "panels.market.moduleRestartHint": "装好了但还没生效 —— 重启一次 dsh 就会出来",
1687
+ "panels.market.moduleRestartHint": "重启后生效",
1688
+ "panels.market.workbenchName": "工作台",
1689
+ "panels.market.workbenchLocal": "这份是本仓正在开发的那一份,不从源上取。",
1603
1690
  "panels.market.pluginKeptInUse": "文件先留着:{names} 还要用它。",
1604
1691
  "panels.market.pluginKeptUnsure": "文件先留着:这台机器上还有模块看不出用了什么,说不准谁在用它。",
1605
1692
  "panels.market.pluginKeptHeld": "文件留着:你自己装的那一份,模块放手不动它。",
1606
1693
  "panels.market.pluginKeptUnnamed": "文件先留着:看不出这是哪个插件,说不准谁在用它。",
1607
- "panels.market.pluginAlsoKnownAs": "包名是 {pkg}(更新与卸载按它来)",
1608
- "panels.market.pluginBroken": "这份装坏了:看不出它是个插件。可以卸载,或者去上面按包名再装一次。",
1694
+ "panels.market.pluginBroken": "这份装坏了:看不出它是个插件。可以卸载,或者直接跟 agent 说:用 workbench_modules 的 install-bundle 按包名再装一次。",
1609
1695
  "panels.market.restartNeeded": "新版装好了,重启一次才生效。",
1610
1696
  "panels.market.foot": "装好后到那个项目的面板页勾选它,模块才会出现。",
1611
1697
  "panels.market.recheck": "重新检查更新",
@@ -1614,7 +1700,7 @@ var zh = {
1614
1700
  "panels.market.justNow": "刚刚",
1615
1701
  "panels.market.minutesAgo": "{n} 分钟前",
1616
1702
  "panels.market.hoursAgo": "{n} 小时前",
1617
- "panels.market.add.description": "输入模块的包名、Git 仓库地址或本地目录路径。",
1703
+ "panels.market.add.description": "输入模块或 opencli 插件的包名、Git 仓库地址或本地目录路径。",
1618
1704
  "panels.market.add.specPlaceholder": "例如 @dsh-workbench/module-hello",
1619
1705
  "panels.market.add.guideToggle": "模块安装引导和示例",
1620
1706
  "panels.market.add.guideHide": "收起引导",
@@ -1653,11 +1739,13 @@ var zh = {
1653
1739
  "panels.market.add.problemInstalled": "该模块已安装",
1654
1740
  "panels.market.add.problemNotFound": "未找到相关模块",
1655
1741
  "panels.market.add.problemNotPackage": "该路径不存在或不是有效的模块包",
1656
- "panels.market.add.problemNotBundle": "这个包装不进这里:{reason}。要是它其实是个 opencli 插件,请改用包名(例如 opencli-plugin-cmdb)或者本地目录 —— 从 git 地址和 tarball 判断不出它是什么。",
1742
+ "panels.market.add.problemNotBundle": "这个包装不进这里:{reason}。这个入口按包名认工作台模块和 opencli 插件,两种都能装;但 git 地址和 tarball 判断不出它是什么 —— 要是它其实是这两样之一,请改填包名或本地目录。",
1657
1743
  "panels.market.add.problemNotWorkbenchModule": "这个包跟现在的工作台对不上,装上也用不了。换一个版本,或者找这个模块的作者。",
1658
1744
  "panels.market.add.problemNotModuleOrPlugin": "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上。换一个版本,或者找这个包的作者。",
1659
1745
  "panels.market.add.failureNotModuleOrPlugin": "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上",
1660
1746
  "panels.market.add.installedPlugin": "装上了:opencli 插件 {name}",
1747
+ "panels.market.add.pluginPreview": "这是一份 opencli 插件:装进 opencli 的插件区,装完就能用,不用重启。",
1748
+ "panels.market.add.pluginAlias": "插件名:{name}",
1661
1749
  "panels.market.add.problemNetwork": "无法连接模块源,请检查网络后重试",
1662
1750
  "panels.market.add.problemUnknown": "无法获取模块信息:{reason}",
1663
1751
  "panels.market.add.failureNetwork": "网络连接失败",
@@ -1688,7 +1776,7 @@ var zh = {
1688
1776
  "panels.market.add.registryPnpm": "pnpm 自己配的源",
1689
1777
  "panels.market.add.check": "预检",
1690
1778
  "panels.market.add.checking": "正在预检…",
1691
- "panels.market.add.classifying": "判定中…",
1779
+ "panels.market.add.classifying": "检测中…",
1692
1780
  "panels.market.add.change": "改一下",
1693
1781
  "panels.market.add.previewTitle": "将要安装",
1694
1782
  "panels.market.add.fieldName": "包名",
@@ -1912,6 +2000,203 @@ function holdBusy(since, now, floorMs) {
1912
2000
  releaseInMs: left
1913
2001
  };
1914
2002
  }
2003
+ var PANEL_STATE_CRASH_WINDOW_MS = 6e5;
2004
+ var PANEL_STATE_MAX_TEXT = 2e3;
2005
+ var PHASES = [
2006
+ "idle",
2007
+ "loading",
2008
+ "ready",
2009
+ "error"
2010
+ ];
2011
+ function asRecord(value) {
2012
+ return typeof value === "object" && value !== null ? value : void 0;
2013
+ }
2014
+ function textOf(value, max) {
2015
+ if (typeof value !== "string") return "";
2016
+ const trimmed = value.trim();
2017
+ return trimmed.length > max ? trimmed.slice(0, max) : trimmed;
2018
+ }
2019
+ function atOf(value) {
2020
+ if (typeof value !== "number" || !Number.isFinite(value)) return null;
2021
+ if (value < 0) return null;
2022
+ return Math.trunc(value);
2023
+ }
2024
+ function errorOf(raw) {
2025
+ const record = asRecord(raw);
2026
+ if (record === void 0) return void 0;
2027
+ const code = textOf(record["code"], 120);
2028
+ const message = textOf(record["message"], PANEL_STATE_MAX_TEXT);
2029
+ if (code === "" && message === "") return void 0;
2030
+ return {
2031
+ code: code === "" ? "unknown" : code,
2032
+ message
2033
+ };
2034
+ }
2035
+ function parseCardsReport(payload) {
2036
+ const record = asRecord(payload);
2037
+ if (record === void 0) return {
2038
+ ok: false,
2039
+ message: "请求体要是一个对象"
2040
+ };
2041
+ const workspace = textOf(record["workspace"], PANEL_STATE_MAX_TEXT);
2042
+ if (workspace === "") return {
2043
+ ok: false,
2044
+ message: "workspace 不能是空的 —— 面板按工作区存"
2045
+ };
2046
+ const raw = record["cards"];
2047
+ if (!Array.isArray(raw)) return {
2048
+ ok: false,
2049
+ message: "cards 要是一个数组"
2050
+ };
2051
+ const cards = [];
2052
+ for (const item of raw.slice(0, 32)) {
2053
+ const card = asRecord(item);
2054
+ if (card === void 0) continue;
2055
+ const unit = textOf(card["unit"], 200);
2056
+ const route = textOf(card["route"], 400);
2057
+ const phase = textOf(card["phase"], 20);
2058
+ const at = atOf(card["at"]);
2059
+ if (unit === "" || route === "" || at === null || !PHASES.includes(phase)) continue;
2060
+ const error = errorOf(card["error"]);
2061
+ cards.push({
2062
+ unit,
2063
+ route,
2064
+ phase,
2065
+ at,
2066
+ ...error === void 0 ? {} : { error }
2067
+ });
2068
+ }
2069
+ if (cards.length === 0) return {
2070
+ ok: false,
2071
+ message: "cards 里没有一条能认的(unit / route / phase / at 都要有)"
2072
+ };
2073
+ return {
2074
+ ok: true,
2075
+ value: {
2076
+ workspace,
2077
+ cards
2078
+ }
2079
+ };
2080
+ }
2081
+ function parseCrashReport(payload) {
2082
+ const record = asRecord(payload);
2083
+ if (record === void 0) return {
2084
+ ok: false,
2085
+ message: "请求体要是一个对象"
2086
+ };
2087
+ const workspace = textOf(record["workspace"], PANEL_STATE_MAX_TEXT);
2088
+ const unit = textOf(record["unit"], 200);
2089
+ const reason = textOf(record["reason"], PANEL_STATE_MAX_TEXT);
2090
+ if (workspace === "") return {
2091
+ ok: false,
2092
+ message: "workspace 不能是空的"
2093
+ };
2094
+ if (unit === "") return {
2095
+ ok: false,
2096
+ message: "unit 不能是空的"
2097
+ };
2098
+ if (reason === "") return {
2099
+ ok: false,
2100
+ message: "reason 不能是空的(没有原因的崩溃没法查)"
2101
+ };
2102
+ return {
2103
+ ok: true,
2104
+ value: {
2105
+ workspace,
2106
+ unit,
2107
+ reason,
2108
+ at: atOf(record["at"]) ?? Date.now()
2109
+ }
2110
+ };
2111
+ }
2112
+ function createPanelStateStore() {
2113
+ const workspaces = /* @__PURE__ */ new Map();
2114
+ function trim(entry, max) {
2115
+ while (entry.size > max) {
2116
+ const oldest = entry.keys().next();
2117
+ if (oldest.done === true) return;
2118
+ entry.delete(oldest.value);
2119
+ }
2120
+ }
2121
+ function workspaceEntryOf(workspace) {
2122
+ const existing = workspaces.get(workspace);
2123
+ if (existing !== void 0) return existing;
2124
+ const created = {
2125
+ at: 0,
2126
+ units: /* @__PURE__ */ new Map()
2127
+ };
2128
+ workspaces.set(workspace, created);
2129
+ trim(workspaces, 64);
2130
+ return created;
2131
+ }
2132
+ function unitEntryOf(entry, unit) {
2133
+ const existing = entry.units.get(unit);
2134
+ if (existing !== void 0) return existing;
2135
+ const created = {
2136
+ at: 0,
2137
+ cards: /* @__PURE__ */ new Map()
2138
+ };
2139
+ entry.units.set(unit, created);
2140
+ return created;
2141
+ }
2142
+ return {
2143
+ cards(report) {
2144
+ const entry = workspaceEntryOf(report.workspace);
2145
+ for (const card of report.cards) {
2146
+ const unit = unitEntryOf(entry, card.unit);
2147
+ unit.cards.delete(card.route);
2148
+ unit.cards.set(card.route, card);
2149
+ trim(unit.cards, 12);
2150
+ if (card.at > unit.at) unit.at = card.at;
2151
+ if (card.at > entry.at) entry.at = card.at;
2152
+ }
2153
+ },
2154
+ crash(report) {
2155
+ const entry = workspaceEntryOf(report.workspace);
2156
+ const unit = unitEntryOf(entry, report.unit);
2157
+ const previous = unit.crash;
2158
+ const counted = previous !== void 0 && previous.reason === report.reason && report.at >= previous.at && report.at - previous.at <= 6e5;
2159
+ unit.crash = {
2160
+ unit: report.unit,
2161
+ reason: report.reason,
2162
+ at: report.at,
2163
+ count: counted ? previous.count + 1 : 1
2164
+ };
2165
+ if (report.at > unit.at) unit.at = report.at;
2166
+ if (report.at > entry.at) entry.at = report.at;
2167
+ },
2168
+ snapshot(workspace) {
2169
+ if (workspace === null) return {
2170
+ workspace: null,
2171
+ at: 0,
2172
+ units: []
2173
+ };
2174
+ const entry = workspaces.get(workspace);
2175
+ if (entry === void 0) return {
2176
+ workspace,
2177
+ at: 0,
2178
+ units: []
2179
+ };
2180
+ const units = [...entry.units.entries()].map(([unit, one]) => {
2181
+ const cards = [...one.cards.values()].sort((a, b) => a.route.localeCompare(b.route));
2182
+ const okAt = cards.reduce((best, card) => card.phase === "ready" && (best === null || card.at > best) ? card.at : best, null);
2183
+ return {
2184
+ unit,
2185
+ at: one.at,
2186
+ okAt,
2187
+ cards,
2188
+ ...one.crash === void 0 ? {} : { crash: one.crash }
2189
+ };
2190
+ });
2191
+ units.sort((a, b) => b.at - a.at || a.unit.localeCompare(b.unit));
2192
+ return {
2193
+ workspace,
2194
+ at: entry.at,
2195
+ units
2196
+ };
2197
+ }
2198
+ };
2199
+ }
1915
2200
  //#endregion
1916
2201
  //#region ../shared/dist/lib/text.js
1917
2202
  function quoteShellArg(value) {
@@ -1979,6 +2264,8 @@ var dist_exports = /* @__PURE__ */ __exportAll({
1979
2264
  IconBrandMark: () => IconBrandMark,
1980
2265
  IconConversation: () => IconConversation,
1981
2266
  IconModules: () => IconModules,
2267
+ IconNpm: () => IconNpm,
2268
+ IconOpencli: () => IconOpencli,
1982
2269
  IconPanelScreen: () => IconPanelScreen,
1983
2270
  LOCALES: () => LOCALES,
1984
2271
  LOCALE_NS: () => LOCALE_NS,
@@ -1995,6 +2282,14 @@ var dist_exports = /* @__PURE__ */ __exportAll({
1995
2282
  PANELS_SERVICE: () => PANELS_SERVICE,
1996
2283
  PANEL_LIST_LIMIT: () => 50,
1997
2284
  PANEL_POLL_MS: () => PANEL_POLL_MS,
2285
+ PANEL_STATE_CRASH_WINDOW_MS: () => PANEL_STATE_CRASH_WINDOW_MS,
2286
+ PANEL_STATE_MAX_CARDS: () => 12,
2287
+ PANEL_STATE_MAX_REPORTS: () => 32,
2288
+ PANEL_STATE_MAX_TEXT: () => PANEL_STATE_MAX_TEXT,
2289
+ PANEL_STATE_MAX_UNITS: () => 64,
2290
+ PANEL_STATE_PATH: () => PANEL_STATE_PATH,
2291
+ PANEL_STATE_PREFIX: () => PANEL_STATE_PREFIX,
2292
+ PANEL_STATE_SERVICE: () => PANEL_STATE_SERVICE,
1998
2293
  PLUGIN_ID: () => PLUGIN_ID,
1999
2294
  PREFS_PREFIX: () => PREFS_PREFIX,
2000
2295
  PROBE_TTL_MS: () => PROBE_TTL_MS,
@@ -2025,6 +2320,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2025
2320
  blockerPending: () => blockerPending,
2026
2321
  buildMarker: () => buildMarker,
2027
2322
  createFactChannel: () => createFactChannel,
2323
+ createPanelStateStore: () => createPanelStateStore,
2028
2324
  cx: () => cx,
2029
2325
  declarationProblemsOf: () => declarationProblemsOf,
2030
2326
  decodeRef: () => decodeRef,
@@ -2036,6 +2332,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2036
2332
  factOfRoute: () => factOfRoute,
2037
2333
  gateOf: () => gateOf,
2038
2334
  h: () => h,
2335
+ hasEnvSupply: () => hasEnvSupply,
2039
2336
  holdBusy: () => holdBusy,
2040
2337
  isFactScope: () => isFactScope,
2041
2338
  longTaskDot: () => longTaskDot,
@@ -2044,6 +2341,8 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2044
2341
  markerBody: () => markerBody,
2045
2342
  mergeMessages: () => mergeMessages,
2046
2343
  mergeMessagesSkipping: () => mergeMessagesSkipping,
2344
+ parseCardsReport: () => parseCardsReport,
2345
+ parseCrashReport: () => parseCrashReport,
2047
2346
  parseFactFrame: () => parseFactFrame,
2048
2347
  parseJsonLoose: () => parseJsonLoose,
2049
2348
  parseLocalTimestamp: () => parseLocalTimestamp,
@@ -2417,6 +2716,197 @@ function holdBack(installed, roster, active, previous) {
2417
2716
  return pending.filter((unit) => active.has(unit) || fresh.includes(unit));
2418
2717
  }
2419
2718
  //#endregion
2719
+ //#region src/app/layouts/rightbar/market-installed-mock.ts
2720
+ function installedMocks(input) {
2721
+ const { id, found, mine, probe } = input;
2722
+ return [
2723
+ {
2724
+ id: "no-supply",
2725
+ label: "没有环境依赖的模块(供给是基座命令那种):市场里有它这一行",
2726
+ manifests: [found],
2727
+ capabilities: probe(id, "ok"),
2728
+ installed: [{
2729
+ unit: id,
2730
+ pkg: "@dsh-workbench/module-one",
2731
+ installed: "0.1.2"
2732
+ }],
2733
+ expect: {
2734
+ rows: 1,
2735
+ state: "installed",
2736
+ actions: ["uninstall"],
2737
+ installed: 0,
2738
+ shared: 0
2739
+ }
2740
+ },
2741
+ {
2742
+ id: "no-card",
2743
+ label: "没有卡片的模块(只有基座命令那种):市场里有它这一行,有版本、有「更新」",
2744
+ manifests: [{
2745
+ ...found,
2746
+ card: null
2747
+ }],
2748
+ capabilities: probe(id, "ok"),
2749
+ updates: { [id]: {
2750
+ installed: "0.1.2",
2751
+ latest: "0.2.0"
2752
+ } },
2753
+ installed: [{
2754
+ unit: id,
2755
+ pkg: "@dsh-workbench/module-one",
2756
+ installed: "0.1.2"
2757
+ }],
2758
+ expect: {
2759
+ rows: 1,
2760
+ state: "outdated",
2761
+ actions: ["update-bundle", "uninstall"],
2762
+ version: {
2763
+ installed: "0.1.2",
2764
+ latest: "0.2.0"
2765
+ },
2766
+ installed: 0,
2767
+ shared: 0
2768
+ }
2769
+ },
2770
+ {
2771
+ id: "no-env-installed",
2772
+ label: "本机装着、又没有依赖要探(DIY 本地那份那种):写「已安装」,不是「状态未知」",
2773
+ manifests: [{
2774
+ ...found,
2775
+ env: void 0
2776
+ }],
2777
+ capabilities: {},
2778
+ updates: { [id]: { installed: "0.1.2" } },
2779
+ installed: [{
2780
+ unit: id,
2781
+ pkg: "@dsh-workbench/module-one",
2782
+ installed: "0.1.2"
2783
+ }],
2784
+ expect: {
2785
+ rows: 1,
2786
+ state: "installed",
2787
+ actions: ["uninstall"],
2788
+ version: { installed: "0.1.2" },
2789
+ installed: 0
2790
+ }
2791
+ },
2792
+ {
2793
+ id: "local-no-update",
2794
+ label: "本机那份(link: 装的):有「本地」标记、不给「更新」",
2795
+ manifests: [mine],
2796
+ capabilities: probe(id, "ok", { plugins: [{
2797
+ name: "fixture",
2798
+ status: "ok",
2799
+ missing: []
2800
+ }] }),
2801
+ updates: { [id]: {
2802
+ installed: "0.1.0",
2803
+ local: true
2804
+ } },
2805
+ installed: [{
2806
+ unit: id,
2807
+ pkg: "@dsh-workbench/module-one",
2808
+ installed: "0.1.0",
2809
+ local: true
2810
+ }],
2811
+ expect: {
2812
+ rows: 1,
2813
+ state: "installed",
2814
+ actions: ["uninstall"],
2815
+ local: true,
2816
+ version: { installed: "0.1.0" },
2817
+ installed: 0
2818
+ }
2819
+ },
2820
+ {
2821
+ id: "installed-refused",
2822
+ label: "本机装了,但宿主不认它的声明(行上说得出理由)",
2823
+ manifests: [],
2824
+ capabilities: {},
2825
+ installed: [{
2826
+ unit: id,
2827
+ pkg: "@dsh-workbench/module-one",
2828
+ installed: "0.1.2",
2829
+ refused: ["dsh.workbench 缺 apiVersion —— 协议从 v1 起,写 \"apiVersion\": 1"]
2830
+ }],
2831
+ expect: {
2832
+ rows: 0,
2833
+ installed: 1,
2834
+ installedState: "unusable",
2835
+ installedActions: ["remove-bundle"],
2836
+ installedNote: true
2837
+ }
2838
+ },
2839
+ {
2840
+ id: "installed-pending",
2841
+ label: "本机装了、宿主还没加载它(重启一次就会出来)",
2842
+ manifests: [],
2843
+ capabilities: {},
2844
+ installed: [{
2845
+ unit: id,
2846
+ pkg: "@dsh-workbench/module-one",
2847
+ installed: "0.1.2"
2848
+ }],
2849
+ expect: {
2850
+ rows: 0,
2851
+ installed: 1,
2852
+ installedState: "inactive",
2853
+ installedActions: ["remove-bundle"],
2854
+ installedHint: "panels.market.moduleRestartHint"
2855
+ }
2856
+ },
2857
+ {
2858
+ id: "installed-pending-update",
2859
+ label: "本机装了、还没加载 + 源上有新版(给「更新」,也说明要重启)",
2860
+ manifests: [],
2861
+ capabilities: {},
2862
+ installed: [{
2863
+ unit: id,
2864
+ pkg: "@dsh-workbench/module-one",
2865
+ installed: "0.1.0",
2866
+ latest: "0.1.2"
2867
+ }],
2868
+ expect: {
2869
+ rows: 0,
2870
+ installed: 1,
2871
+ installedState: "outdated",
2872
+ installedActions: ["update-bundle", "remove-bundle"],
2873
+ installedHint: "panels.market.moduleRestartHint"
2874
+ }
2875
+ },
2876
+ {
2877
+ id: "installed-confirm",
2878
+ label: "卸载本机模块(还没加载的那种:Modal 确认,标题是包名)",
2879
+ manifests: [],
2880
+ capabilities: {},
2881
+ installed: [{
2882
+ unit: id,
2883
+ pkg: "@dsh-workbench/module-one",
2884
+ installed: "0.1.2"
2885
+ }],
2886
+ confirming: id,
2887
+ expect: {
2888
+ rows: 0,
2889
+ installed: 1,
2890
+ installedState: "inactive",
2891
+ installedActions: ["remove-bundle"]
2892
+ }
2893
+ },
2894
+ {
2895
+ id: "first-paint",
2896
+ label: "刚进页面(检测中:能力与本机清单都还没结论)",
2897
+ manifests: [mine],
2898
+ capabilities: null,
2899
+ installedRead: false,
2900
+ loaded: false,
2901
+ expect: {
2902
+ rows: 1,
2903
+ state: "checking",
2904
+ actions: []
2905
+ }
2906
+ }
2907
+ ];
2908
+ }
2909
+ //#endregion
2420
2910
  //#region src/app/layouts/rightbar/market-mock.ts
2421
2911
  function installable(manifest) {
2422
2912
  return {
@@ -2527,7 +3017,8 @@ function buildMarketMocks(roster) {
2527
3017
  expect: {
2528
3018
  rows: 1,
2529
3019
  state: "outdated",
2530
- actions: ["update", "uninstall"]
3020
+ actions: ["update", "uninstall"],
3021
+ noteKey: "panels.market.needCommands"
2531
3022
  }
2532
3023
  },
2533
3024
  {
@@ -2772,109 +3263,38 @@ function buildMarketMocks(roster) {
2772
3263
  actions: ["uninstall"]
2773
3264
  }
2774
3265
  },
3266
+ ...installedMocks({
3267
+ id,
3268
+ found,
3269
+ mine,
3270
+ probe: probe$1
3271
+ }),
2775
3272
  {
2776
- id: "installed-half",
2777
- label: "本机装了模块,但它没有环境依赖(供给那半没有它)",
2778
- manifests: [found],
2779
- capabilities: {},
2780
- installed: [{
2781
- unit: id,
2782
- pkg: "@dsh-workbench/module-one",
2783
- installed: "0.1.2"
2784
- }],
3273
+ id: "shared-many",
3274
+ label: "三个模块(同一份安装)",
3275
+ manifests: [
3276
+ mine,
3277
+ twin(mine),
3278
+ {
3279
+ ...twin(mine),
3280
+ id: `${mine.id}-c`
3281
+ }
3282
+ ],
3283
+ capabilities: {
3284
+ ...probe$1(id, "ok"),
3285
+ ...probe$1(secondId, "ok"),
3286
+ ...probe$1(`${mine.id}-c`, "ok")
3287
+ },
2785
3288
  expect: {
2786
- rows: 0,
2787
- installed: 1,
2788
- installedActions: ["remove-bundle"]
3289
+ rows: 3,
3290
+ state: "installed",
3291
+ actions: ["uninstall"]
2789
3292
  }
2790
3293
  },
2791
3294
  {
2792
- id: "installed-half-update",
2793
- label: "本机装了模块 + 源上有新版(给「更新」,装完要重启)",
2794
- manifests: [found],
2795
- capabilities: {},
2796
- installed: [{
2797
- unit: id,
2798
- pkg: "@dsh-workbench/module-one",
2799
- installed: "0.1.0",
2800
- latest: "0.1.2"
2801
- }],
2802
- expect: {
2803
- rows: 0,
2804
- installed: 1,
2805
- installedActions: ["update-bundle", "remove-bundle"]
2806
- }
2807
- },
2808
- {
2809
- id: "installed-client-refused",
2810
- label: "本机装了,但浏览器这半没挂上(拒因由客户端报告)",
2811
- manifests: [found],
2812
- capabilities: {},
2813
- installed: [{
2814
- unit: id,
2815
- pkg: "@dsh-workbench/module-one",
2816
- installed: "0.1.2",
2817
- clientRefused: [`宿主没有担保 unit「${id}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]
2818
- }],
2819
- expect: {
2820
- rows: 0,
2821
- installed: 1,
2822
- installedActions: ["remove-bundle"],
2823
- installedNote: true
2824
- }
2825
- },
2826
- {
2827
- id: "installed-confirm",
2828
- label: "卸载本机模块(Modal 确认,标题带模块名)",
2829
- manifests: [found],
2830
- capabilities: {},
2831
- installed: [{
2832
- unit: id,
2833
- pkg: "@dsh-workbench/module-one",
2834
- installed: "0.1.2"
2835
- }],
2836
- confirming: id,
2837
- expect: {
2838
- rows: 0,
2839
- installed: 1,
2840
- installedActions: ["remove-bundle"]
2841
- }
2842
- },
2843
- {
2844
- id: "first-paint",
2845
- label: "刚进页面(检测中:能力与本机清单都还没结论)",
2846
- manifests: [found],
2847
- capabilities: null,
2848
- installedRead: false,
2849
- loaded: false,
2850
- expect: { rows: 0 }
2851
- },
2852
- {
2853
- id: "shared-many",
2854
- label: "三个模块(同一份安装)",
2855
- manifests: [
2856
- mine,
2857
- twin(mine),
2858
- {
2859
- ...twin(mine),
2860
- id: `${mine.id}-c`
2861
- }
2862
- ],
2863
- capabilities: {
2864
- ...probe$1(id, "ok"),
2865
- ...probe$1(secondId, "ok"),
2866
- ...probe$1(`${mine.id}-c`, "ok")
2867
- },
2868
- expect: {
2869
- rows: 3,
2870
- state: "installed",
2871
- actions: ["uninstall"]
2872
- }
2873
- },
2874
- {
2875
- id: "plugin-outdated",
2876
- label: "用户装的 opencli 插件:有新版(给更新 / 卸载)",
2877
- manifests: [],
3295
+ id: "plugin-outdated",
3296
+ label: "用户装的 opencli 插件:有新版(给更新 / 卸载)",
3297
+ manifests: [],
2878
3298
  capabilities: {},
2879
3299
  plugins: [{
2880
3300
  pkg: "opencli-plugin-cmdb",
@@ -2919,8 +3339,7 @@ function buildMarketMocks(roster) {
2919
3339
  expect: {
2920
3340
  rows: 0,
2921
3341
  plugins: 1,
2922
- pluginActions: ["update-plugin", "uninstall-plugin"],
2923
- pluginNoteKey: "panels.market.pluginAlsoKnownAs"
3342
+ pluginActions: ["update-plugin", "uninstall-plugin"]
2924
3343
  }
2925
3344
  },
2926
3345
  {
@@ -2937,6 +3356,7 @@ function buildMarketMocks(roster) {
2937
3356
  expect: {
2938
3357
  rows: 0,
2939
3358
  plugins: 1,
3359
+ pluginState: "broken",
2940
3360
  pluginActions: ["uninstall-plugin"],
2941
3361
  pluginNoteKey: "panels.market.pluginBroken"
2942
3362
  }
@@ -2959,6 +3379,70 @@ function buildMarketMocks(roster) {
2959
3379
  notice: true
2960
3380
  }
2961
3381
  },
3382
+ {
3383
+ id: "workbench-update",
3384
+ label: "工作台有新版(这一行也给「更新」,装完面板自己换上)",
3385
+ manifests: [],
3386
+ capabilities: {},
3387
+ workbench: {
3388
+ pkg: "@dsh-workbench/core",
3389
+ installed: "0.1.18",
3390
+ latest: "0.1.19"
3391
+ },
3392
+ expect: {
3393
+ rows: 0,
3394
+ workbenchState: "outdated",
3395
+ workbenchActions: ["update-workbench"]
3396
+ }
3397
+ },
3398
+ {
3399
+ id: "workbench-current",
3400
+ label: "工作台已经最新(只显示版本,没有按钮)",
3401
+ manifests: [],
3402
+ capabilities: {},
3403
+ workbench: {
3404
+ pkg: "@dsh-workbench/core",
3405
+ installed: "0.1.19"
3406
+ },
3407
+ expect: {
3408
+ rows: 0,
3409
+ workbenchState: "installed",
3410
+ workbenchActions: []
3411
+ }
3412
+ },
3413
+ {
3414
+ id: "workbench-local",
3415
+ label: "工作台是本仓那份(link: 装的:不给更新,行上说清)",
3416
+ manifests: [],
3417
+ capabilities: {},
3418
+ workbench: {
3419
+ pkg: "@dsh-workbench/core",
3420
+ installed: "0.1.18",
3421
+ latest: "0.1.19",
3422
+ local: true
3423
+ },
3424
+ expect: {
3425
+ rows: 0,
3426
+ workbenchState: "installed",
3427
+ workbenchActions: [],
3428
+ workbenchNoteKey: "panels.market.workbenchLocal"
3429
+ }
3430
+ },
3431
+ {
3432
+ id: "workbench-updated",
3433
+ label: "工作台刚更新完(新版已经在盘上:行上就是新版,没有按钮、也不劝人重启)",
3434
+ manifests: [],
3435
+ capabilities: {},
3436
+ workbench: {
3437
+ pkg: "@dsh-workbench/core",
3438
+ installed: "0.1.19"
3439
+ },
3440
+ expect: {
3441
+ rows: 0,
3442
+ workbenchState: "installed",
3443
+ workbenchActions: []
3444
+ }
3445
+ },
2962
3446
  {
2963
3447
  id: "empty",
2964
3448
  label: "市场空态",
@@ -3028,11 +3512,13 @@ function createBoardRegistry() {
3028
3512
  //#endregion
3029
3513
  //#region src/app/units/registry.ts
3030
3514
  function toBoardModule(face, manifest) {
3515
+ const View = face.card;
3516
+ if (View === void 0) return void 0;
3031
3517
  return {
3032
3518
  id: manifest.id,
3033
3519
  titleKey: manifest.card?.titleKey ?? manifest.id,
3034
3520
  order: manifest.card?.order ?? 100,
3035
- View: face.card,
3521
+ View,
3036
3522
  ...face.steps === void 0 ? {} : { steps: face.steps }
3037
3523
  };
3038
3524
  }
@@ -3042,6 +3528,7 @@ function createClientUnitRegistry(options = {}) {
3042
3528
  const listeners = /* @__PURE__ */ new Set();
3043
3529
  const board = createBoardRegistry();
3044
3530
  let known = /* @__PURE__ */ new Map();
3531
+ let installableIds = null;
3045
3532
  let revision = 0;
3046
3533
  let manifestsCache;
3047
3534
  function notify() {
@@ -3052,9 +3539,10 @@ function createClientUnitRegistry(options = {}) {
3052
3539
  console.warn(`[dsh-workbench] 套件注册的订阅者报错(不影响其它订阅者与这次注册):${String(error)}`);
3053
3540
  }
3054
3541
  }
3055
- function warnRefusal(unit, reasons) {
3542
+ function warnRefusal(unit, kind, reasons) {
3056
3543
  refusals.push({
3057
3544
  unit,
3545
+ kind,
3058
3546
  reasons
3059
3547
  });
3060
3548
  console.warn(`[dsh-workbench] ${unit === "" ? "这个模块" : unit} 的卡片没挂上:${reasons.join(";")}`);
@@ -3065,9 +3553,10 @@ function createClientUnitRegistry(options = {}) {
3065
3553
  function attach(entry) {
3066
3554
  const manifest = known.get(entry.unit);
3067
3555
  if (manifest === void 0) return false;
3556
+ const boardModule = toBoardModule(entry.face, manifest);
3068
3557
  entry.mounted = {
3069
3558
  manifest,
3070
- unmount: board.register(toBoardModule(entry.face, manifest))
3559
+ unmount: boardModule === void 0 ? () => {} : board.register(boardModule)
3071
3560
  };
3072
3561
  takeBackRefusal(entry.unit);
3073
3562
  return true;
@@ -3080,7 +3569,7 @@ function createClientUnitRegistry(options = {}) {
3080
3569
  register(face) {
3081
3570
  const unit = typeof face?.unit === "string" ? face.unit.trim() : "";
3082
3571
  if (unit === "") {
3083
- warnRefusal("", ["registerUnit({ unit, card }) 里的 unit 是空的 —— U1b 之前的旧形状是 registerUnit({ manifest, card });现在清单由外壳从**已装清单**读出来、按 unit 交给浏览器(ADR-0038 §2.2)"]);
3572
+ warnRefusal("", "old-shape", ["registerUnit({ unit, card }) 里的 unit 是空的 —— U1b 之前的旧形状是 registerUnit({ manifest, card });现在清单由外壳从**已装清单**读出来、按 unit 交给浏览器(ADR-0038 §2.2)"]);
3084
3573
  notify();
3085
3574
  return () => {};
3086
3575
  }
@@ -3093,7 +3582,7 @@ function createClientUnitRegistry(options = {}) {
3093
3582
  registrations.push(entry);
3094
3583
  manifestsCache = void 0;
3095
3584
  if (!attach(entry)) {
3096
- warnRefusal(unit, [`宿主没有担保 unit「${unit}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]);
3585
+ warnRefusal(unit, "no-manifest", [`宿主没有担保 unit「${unit}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]);
3097
3586
  options.onUnknownUnit?.(unit);
3098
3587
  }
3099
3588
  notify();
@@ -3113,8 +3602,10 @@ function createClientUnitRegistry(options = {}) {
3113
3602
  return manifestsCache;
3114
3603
  },
3115
3604
  refusals: () => refusals,
3116
- setManifests(manifests) {
3605
+ installable: () => installableIds,
3606
+ setManifests(manifests, installable) {
3117
3607
  known = new Map(manifests.map((manifest) => [manifest.id, manifest]));
3608
+ installableIds = installable === void 0 ? null : new Set(installable);
3118
3609
  let changed = false;
3119
3610
  for (const entry of registrations) {
3120
3611
  const next = known.get(entry.unit);
@@ -3124,7 +3615,7 @@ function createClientUnitRegistry(options = {}) {
3124
3615
  }
3125
3616
  if (next === void 0) {
3126
3617
  detach(entry);
3127
- warnRefusal(entry.unit, [`宿主不再担保 unit「${entry.unit}」的清单(模块被卸了?)—— 这张卡片先摘下来`]);
3618
+ warnRefusal(entry.unit, "withdrawn", [`宿主不再担保 unit「${entry.unit}」的清单(模块被卸了?)—— 这张卡片先摘下来`]);
3128
3619
  changed = true;
3129
3620
  }
3130
3621
  }
@@ -3235,16 +3726,153 @@ function hasCard(roster) {
3235
3726
  function fixtureRoster(roster) {
3236
3727
  return hasCard(roster) ? roster : SAMPLE_ROSTER;
3237
3728
  }
3729
+ function boardModuleOf(face) {
3730
+ const module = toBoardModule(face, face.manifest);
3731
+ return module === void 0 ? [] : [module];
3732
+ }
3238
3733
  function fixtureSeed(roster, all, crash = false) {
3239
- const base = hasCard(roster) ? all : [toBoardModule(FIXTURE_FACE, FIXTURE_FACE.manifest)];
3240
- return crash ? [toBoardModule(CRASH_FACE, CRASH_FACE.manifest), ...base] : base;
3734
+ const base = hasCard(roster) ? all : boardModuleOf(FIXTURE_FACE);
3735
+ return crash ? [...boardModuleOf(CRASH_FACE), ...base] : base;
3736
+ }
3737
+ //#endregion
3738
+ //#region src/app/layouts/rightbar/market-shared-rows.ts
3739
+ var SHARED_STATE_KEY = {
3740
+ checking: "panels.market.checking",
3741
+ installed: "panels.market.sharedOk",
3742
+ outdated: "panels.market.sharedOutdated",
3743
+ unsatisfied: "panels.market.sharedUnsatisfied",
3744
+ missing: "panels.market.sharedMissing",
3745
+ unchecked: "panels.market.unchecked"
3746
+ };
3747
+ var SHARED_DOT = {
3748
+ checking: "ongoing",
3749
+ installed: "done",
3750
+ outdated: "warning",
3751
+ unsatisfied: "warning",
3752
+ missing: "idle",
3753
+ unchecked: "idle"
3754
+ };
3755
+ function sharedActions(row) {
3756
+ return [...row.canUpdate ? ["update-dependency"] : []];
3757
+ }
3758
+ var SHARED_RANK = {
3759
+ checking: -1,
3760
+ unchecked: 0,
3761
+ installed: 1,
3762
+ outdated: 2,
3763
+ unsatisfied: 3,
3764
+ missing: 4
3765
+ };
3766
+ function sharedRows(manifests, capabilities) {
3767
+ const catalog = manifests.filter((manifest) => (manifest.env?.plugins ?? []).length > 0 || (manifest.env?.libs ?? []).length > 0);
3768
+ const byId = new Map(catalog.map((manifest) => [manifest.id, manifest]));
3769
+ const buckets = /* @__PURE__ */ new Map();
3770
+ const bucketOf = (kind, name, label, purpose) => {
3771
+ const id = `${kind}:${name}`;
3772
+ const found = buckets.get(id);
3773
+ if (found !== void 0) return found;
3774
+ const created = {
3775
+ kind,
3776
+ name,
3777
+ label,
3778
+ users: [],
3779
+ states: [],
3780
+ ...purpose === void 0 ? {} : { purpose }
3781
+ };
3782
+ buckets.set(id, created);
3783
+ return created;
3784
+ };
3785
+ for (const manifest of catalog) {
3786
+ const capability = capabilities?.[manifest.id];
3787
+ const released = capability?.released === true;
3788
+ for (const need of manifest.env?.plugins ?? []) {
3789
+ const source = need.installSource;
3790
+ const bucket = bucketOf("plugin", need.name, source?.kind === "npm" ? source.package : need.name);
3791
+ if (released) continue;
3792
+ bucket.users.push(manifest.id);
3793
+ const state = capability?.plugins?.find((item) => item.name === need.name);
3794
+ bucket.states.push(state === void 0 ? "unchecked" : state.status === "ok" ? "installed" : state.status);
3795
+ if (state?.release !== void 0) {
3796
+ bucket.installed ??= state.release.installed;
3797
+ bucket.latest ??= state.release.latest;
3798
+ }
3799
+ bucket.command ??= state?.command;
3800
+ }
3801
+ for (const need of manifest.env?.libs ?? []) {
3802
+ const bucket = bucketOf("lib", need.name, need.name, need.purpose);
3803
+ if (released) continue;
3804
+ bucket.users.push(manifest.id);
3805
+ const state = capability?.libs?.find((item) => item.name === need.name);
3806
+ bucket.states.push(state === void 0 ? "unchecked" : state.status === "ok" ? "installed" : state.status);
3807
+ bucket.installed ??= state?.installed;
3808
+ bucket.latest ??= state?.latest;
3809
+ bucket.command ??= state?.command;
3810
+ }
3811
+ }
3812
+ const rows = [];
3813
+ for (const bucket of buckets.values()) {
3814
+ if (bucket.users.length === 0) continue;
3815
+ const state = capabilities === null ? "checking" : bucket.states.reduce((soFar, item) => SHARED_RANK[item] > SHARED_RANK[soFar] ? item : soFar, "unchecked");
3816
+ const version = bucket.installed === void 0 && bucket.latest === void 0 ? void 0 : {
3817
+ ...bucket.installed === void 0 ? {} : { installed: bucket.installed },
3818
+ ...bucket.latest === void 0 ? {} : { latest: bucket.latest }
3819
+ };
3820
+ const detail = bucket.purpose === void 0 ? void 0 : `${bucket.label} —— ${bucket.purpose}`;
3821
+ rows.push({
3822
+ id: `${bucket.kind}:${bucket.name}`,
3823
+ kind: bucket.kind,
3824
+ label: bucket.label,
3825
+ usedByKeys: bucket.users.map((unit) => byId.get(unit)?.card?.titleKey ?? unit),
3826
+ state,
3827
+ canUpdate: state === "outdated" || state === "unsatisfied",
3828
+ ...version === void 0 ? {} : { version },
3829
+ ...detail === void 0 ? {} : { detail }
3830
+ });
3831
+ }
3832
+ return rows;
3833
+ }
3834
+ //#endregion
3835
+ //#region src/app/layouts/rightbar/market-workbench-row.ts
3836
+ var WORKBENCH_ROW_ID = "workbench:self";
3837
+ var WORKBENCH_TITLE_KEY = "panels.market.workbenchName";
3838
+ function workbenchRow(version) {
3839
+ if (version === null || version === void 0 || version.installed === "") return void 0;
3840
+ const local = version.local === true;
3841
+ const latest = local ? void 0 : version.latest;
3842
+ const update = latest !== void 0 && latest !== version.installed ? {
3843
+ installed: version.installed,
3844
+ latest
3845
+ } : void 0;
3846
+ const note = local ? {
3847
+ key: "panels.market.workbenchLocal",
3848
+ params: {}
3849
+ } : void 0;
3850
+ return {
3851
+ id: WORKBENCH_ROW_ID,
3852
+ titleKey: WORKBENCH_TITLE_KEY,
3853
+ workbench: true,
3854
+ state: update === void 0 ? "installed" : "outdated",
3855
+ canInstall: false,
3856
+ canUpdate: update !== void 0,
3857
+ canUninstall: false,
3858
+ ...note === void 0 ? {} : { note },
3859
+ version: {
3860
+ installed: version.installed,
3861
+ ...latest === void 0 ? {} : { latest }
3862
+ },
3863
+ ...update === void 0 ? {} : { moduleUpdate: update },
3864
+ pkg: version.pkg
3865
+ };
3241
3866
  }
3242
3867
  //#endregion
3243
3868
  //#region src/app/layouts/rightbar/market-rows.ts
3244
3869
  var MARKET_STATE_KEY = {
3245
3870
  checking: "panels.market.checking",
3246
3871
  installed: "panels.market.installed",
3247
- outdated: "panels.market.outdated",
3872
+ inactive: "panels.market.notActive",
3873
+ unusable: "panels.market.notUsable",
3874
+ broken: "panels.market.broken",
3875
+ outdated: "panels.market.moduleOutdated",
3248
3876
  missing: "panels.market.missing",
3249
3877
  unchecked: "panels.market.unchecked",
3250
3878
  unknown: "panels.market.unchecked"
@@ -3252,6 +3880,9 @@ var MARKET_STATE_KEY = {
3252
3880
  var MARKET_DOT = {
3253
3881
  checking: "ongoing",
3254
3882
  installed: "done",
3883
+ inactive: "error",
3884
+ unusable: "error",
3885
+ broken: "error",
3255
3886
  outdated: "warning",
3256
3887
  missing: "idle",
3257
3888
  unchecked: "idle",
@@ -3261,8 +3892,9 @@ function marketRowTitle(row, t) {
3261
3892
  return row.label ?? t(row.titleKey);
3262
3893
  }
3263
3894
  function withClientRefusals(modules, refusals) {
3264
- if (refusals.length === 0) return modules;
3265
- const byUnit = new Map(refusals.map((one) => [one.unit, one.reasons]));
3895
+ const refused = refusals.filter((one) => one.kind !== "no-manifest");
3896
+ if (refused.length === 0) return modules;
3897
+ const byUnit = new Map(refused.map((one) => [one.unit, one.reasons]));
3266
3898
  return modules.map((module) => {
3267
3899
  const reasons = byUnit.get(module.unit);
3268
3900
  return reasons === void 0 ? module : {
@@ -3286,20 +3918,21 @@ function mergeTitles(known, manifests) {
3286
3918
  }
3287
3919
  return next ?? known;
3288
3920
  }
3289
- function installedRows(modules, manifests, listed, known) {
3921
+ function installedRows(modules, manifests, listed, known, defaults = /* @__PURE__ */ new Set(), changed = {}) {
3290
3922
  const titles = new Map(manifests.map((manifest) => [manifest.id, manifest.card?.titleKey]));
3291
3923
  const rows = [];
3292
3924
  for (const module of modules) {
3293
3925
  if (listed.has(module.unit)) continue;
3294
- const latest = module.latest;
3926
+ const latest = module.local === true ? void 0 : module.latest;
3295
3927
  const outdated = latest !== void 0 && latest !== module.installed;
3296
3928
  const loaded = titles.has(module.unit);
3297
3929
  const refused = refusalReasons(module.refused, module.clientRefused);
3930
+ const pending = !loaded && refused.length === 0;
3298
3931
  rows.push({
3299
3932
  id: module.unit,
3300
3933
  titleKey: titles.get(module.unit) ?? known?.get(module.unit) ?? module.pkg,
3301
- state: outdated ? "outdated" : "installed",
3302
- ...loaded || refused.length > 0 ? {} : { hint: "panels.market.moduleRestartHint" },
3934
+ state: outdated ? "outdated" : refused.length > 0 ? "unusable" : pending ? "inactive" : "installed",
3935
+ ...pending ? { hint: "panels.market.moduleRestartHint" } : {},
3303
3936
  ...refused.length === 0 ? {} : { note: {
3304
3937
  key: "panels.market.moduleRefused",
3305
3938
  params: { reason: refused.join(";") }
@@ -3316,12 +3949,19 @@ function installedRows(modules, manifests, listed, known) {
3316
3949
  ...outdated ? { moduleUpdate: {
3317
3950
  installed: module.installed,
3318
3951
  latest
3319
- } } : {}
3952
+ } } : {},
3953
+ defaultShown: defaults.has(module.unit),
3954
+ defaultChanged: changed[module.unit] ?? 0
3320
3955
  });
3321
3956
  }
3322
3957
  return rows;
3323
3958
  }
3959
+ var SWITCH_LOCKED = /* @__PURE__ */ new Set(["unusable", "broken"]);
3960
+ function marketSwitchLocked(row) {
3961
+ return SWITCH_LOCKED.has(row.state);
3962
+ }
3324
3963
  function marketActions$1(row) {
3964
+ if (row.workbench === true) return row.canUpdate ? ["update-workbench"] : [];
3325
3965
  if (row.plugin === true) return [...row.canUpdate ? ["update-plugin"] : [], ...row.canUninstall ? ["uninstall-plugin"] : []];
3326
3966
  return [
3327
3967
  ...row.canInstall ? ["install"] : [],
@@ -3329,8 +3969,8 @@ function marketActions$1(row) {
3329
3969
  ...row.canUninstall ? [row.pkg === void 0 ? "uninstall" : "remove-bundle"] : []
3330
3970
  ];
3331
3971
  }
3332
- function stateOf(capability) {
3333
- if (capability === void 0) return "unknown";
3972
+ function stateOf(capability, manifest, installed) {
3973
+ if (capability === void 0) return installed && !hasEnvSupply(manifest) ? "installed" : "unknown";
3334
3974
  if (capability.released === true) return "missing";
3335
3975
  if (capability.status === "missing-plugin") return "missing";
3336
3976
  if (capability.status === "unchecked") return "unchecked";
@@ -3346,8 +3986,9 @@ function envNameOf(source) {
3346
3986
  if (source.kind === "npm") return source.registryEnv;
3347
3987
  return "";
3348
3988
  }
3349
- function noteOf$1(state, install, manifest) {
3989
+ function noteOf$1(state, capability, manifest) {
3350
3990
  if (state === "installed") return void 0;
3991
+ const install = capability?.install;
3351
3992
  if (install === "env-missing") return {
3352
3993
  key: "panels.market.needEnv",
3353
3994
  params: { env: envNameOf((manifest.env?.plugins ?? []).find((need) => envNameOf(need.installSource) !== "")?.installSource) }
@@ -3360,9 +4001,19 @@ function noteOf$1(state, install, manifest) {
3360
4001
  key: "panels.market.badSource",
3361
4002
  params: {}
3362
4003
  };
4004
+ const missing = capability?.missing ?? [];
4005
+ if (state === "outdated" && missing.length > 0) return {
4006
+ key: "panels.market.needCommands",
4007
+ params: { commands: missing.join("、") },
4008
+ tone: "plain"
4009
+ };
3363
4010
  }
3364
4011
  function isOnMachine(state) {
3365
- return state === "installed" || state === "outdated";
4012
+ return state === "installed" || state === "outdated" || state === "inactive" || state === "unusable" || state === "broken";
4013
+ }
4014
+ function marketCatalog(manifests, installable) {
4015
+ if (installable === void 0 || installable === null) return manifests.filter(hasEnvSupply);
4016
+ return manifests.filter((manifest) => installable.has(manifest.id));
3366
4017
  }
3367
4018
  function liveManifests(manifests, capabilities, installed) {
3368
4019
  if (capabilities === null || installed === null) return manifests;
@@ -3376,14 +4027,19 @@ function marketHasUpdates(rows, shared = []) {
3376
4027
  function marketUpdatesOf(modules) {
3377
4028
  if (modules === null) return {};
3378
4029
  const next = {};
3379
- for (const module of modules) next[module.unit] = {
3380
- installed: module.installed,
3381
- ...module.latest === void 0 ? {} : { latest: module.latest }
3382
- };
4030
+ for (const module of modules) {
4031
+ const local = module.local === true;
4032
+ next[module.unit] = {
4033
+ installed: module.installed,
4034
+ ...local || module.latest === void 0 ? {} : { latest: module.latest },
4035
+ ...local ? { local: true } : {}
4036
+ };
4037
+ }
3383
4038
  return next;
3384
4039
  }
3385
- function marketHintVisible(manifests, capabilities, modules) {
3386
- return marketHasUpdates(marketRows(manifests, capabilities, marketUpdatesOf(modules)), sharedRows(manifests, capabilities));
4040
+ function marketHintVisible(manifests, capabilities, modules, workbench) {
4041
+ const self = workbenchRow(workbench);
4042
+ return marketHasUpdates([...marketRows(manifests, capabilities, marketUpdatesOf(modules)), ...self === void 0 ? [] : [self]], sharedRows(manifests, capabilities));
3387
4043
  }
3388
4044
  function marketSections(rows) {
3389
4045
  const installed = rows.filter((row) => isOnMachine(row.state));
@@ -3398,17 +4054,17 @@ function marketSections(rows) {
3398
4054
  rows: rest
3399
4055
  }]];
3400
4056
  }
3401
- function marketRows(manifests, capabilities, updates = {}) {
3402
- const catalog = manifests.filter((manifest) => (manifest.env?.plugins ?? []).length > 0 || (manifest.env?.libs ?? []).length > 0);
4057
+ function marketRows(manifests, capabilities, updates = {}, defaults = /* @__PURE__ */ new Set(), changed = {}) {
3403
4058
  const rows = [];
3404
- for (const manifest of catalog) {
4059
+ for (const manifest of manifests) {
3405
4060
  const capability = capabilities?.[manifest.id];
3406
4061
  const install = capability?.install;
3407
- const state = capabilities === null ? "checking" : stateOf(capability);
3408
- const note = noteOf$1(state, install, manifest);
4062
+ const entry = updates[manifest.id];
4063
+ const local = entry?.local === true;
4064
+ const state = capabilities === null ? "checking" : stateOf(capability, manifest, entry !== void 0);
4065
+ const note = noteOf$1(state, capability, manifest);
3409
4066
  const onMachine = isOnMachine(state);
3410
4067
  const reAdopt = capability?.released === true && install === void 0;
3411
- const entry = updates[manifest.id];
3412
4068
  const moduleUpdate = entry === void 0 || entry.latest === void 0 || entry.latest === entry.installed ? void 0 : {
3413
4069
  installed: entry.installed,
3414
4070
  latest: entry.latest
@@ -3425,101 +4081,10 @@ function marketRows(manifests, capabilities, updates = {}) {
3425
4081
  ...entry.latest === void 0 ? {} : { latest: entry.latest }
3426
4082
  } },
3427
4083
  ...moduleUpdate === void 0 ? {} : { moduleUpdate },
3428
- ...moduleUpdate === void 0 ? note === void 0 ? {} : { note } : {}
3429
- });
3430
- }
3431
- return rows;
3432
- }
3433
- var SHARED_STATE_KEY = {
3434
- checking: "panels.market.checking",
3435
- installed: "panels.market.sharedOk",
3436
- outdated: "panels.market.sharedOutdated",
3437
- unsatisfied: "panels.market.sharedUnsatisfied",
3438
- missing: "panels.market.sharedMissing",
3439
- unchecked: "panels.market.unchecked"
3440
- };
3441
- var SHARED_DOT = {
3442
- checking: "ongoing",
3443
- installed: "done",
3444
- outdated: "warning",
3445
- unsatisfied: "warning",
3446
- missing: "idle",
3447
- unchecked: "idle"
3448
- };
3449
- function sharedActions(row) {
3450
- return [...row.canUpdate ? ["update-dependency"] : []];
3451
- }
3452
- var SHARED_RANK = {
3453
- checking: -1,
3454
- unchecked: 0,
3455
- installed: 1,
3456
- outdated: 2,
3457
- unsatisfied: 3,
3458
- missing: 4
3459
- };
3460
- function sharedRows(manifests, capabilities) {
3461
- const catalog = manifests.filter((manifest) => (manifest.env?.plugins ?? []).length > 0 || (manifest.env?.libs ?? []).length > 0);
3462
- const byId = new Map(catalog.map((manifest) => [manifest.id, manifest]));
3463
- const buckets = /* @__PURE__ */ new Map();
3464
- const bucketOf = (kind, name, label, purpose) => {
3465
- const id = `${kind}:${name}`;
3466
- const found = buckets.get(id);
3467
- if (found !== void 0) return found;
3468
- const created = {
3469
- kind,
3470
- name,
3471
- label,
3472
- users: [],
3473
- states: [],
3474
- ...purpose === void 0 ? {} : { purpose }
3475
- };
3476
- buckets.set(id, created);
3477
- return created;
3478
- };
3479
- for (const manifest of catalog) {
3480
- const capability = capabilities?.[manifest.id];
3481
- const released = capability?.released === true;
3482
- for (const need of manifest.env?.plugins ?? []) {
3483
- const source = need.installSource;
3484
- const bucket = bucketOf("plugin", need.name, source?.kind === "npm" ? source.package : need.name);
3485
- if (released) continue;
3486
- bucket.users.push(manifest.id);
3487
- const state = capability?.plugins?.find((item) => item.name === need.name);
3488
- bucket.states.push(state === void 0 ? "unchecked" : state.status === "ok" ? "installed" : state.status);
3489
- if (state?.release !== void 0) {
3490
- bucket.installed ??= state.release.installed;
3491
- bucket.latest ??= state.release.latest;
3492
- }
3493
- bucket.command ??= state?.command;
3494
- }
3495
- for (const need of manifest.env?.libs ?? []) {
3496
- const bucket = bucketOf("lib", need.name, need.name, need.purpose);
3497
- if (released) continue;
3498
- bucket.users.push(manifest.id);
3499
- const state = capability?.libs?.find((item) => item.name === need.name);
3500
- bucket.states.push(state === void 0 ? "unchecked" : state.status === "ok" ? "installed" : state.status);
3501
- bucket.installed ??= state?.installed;
3502
- bucket.latest ??= state?.latest;
3503
- bucket.command ??= state?.command;
3504
- }
3505
- }
3506
- const rows = [];
3507
- for (const bucket of buckets.values()) {
3508
- if (bucket.users.length === 0) continue;
3509
- const state = capabilities === null ? "checking" : bucket.states.reduce((soFar, item) => SHARED_RANK[item] > SHARED_RANK[soFar] ? item : soFar, "unchecked");
3510
- const version = bucket.installed === void 0 && bucket.latest === void 0 ? void 0 : {
3511
- ...bucket.installed === void 0 ? {} : { installed: bucket.installed },
3512
- ...bucket.latest === void 0 ? {} : { latest: bucket.latest }
3513
- };
3514
- const detail = bucket.purpose === void 0 ? void 0 : `${bucket.label} —— ${bucket.purpose}`;
3515
- rows.push({
3516
- id: `${bucket.kind}:${bucket.name}`,
3517
- label: bucket.label,
3518
- usedByKeys: bucket.users.map((unit) => byId.get(unit)?.card?.titleKey ?? unit),
3519
- state,
3520
- canUpdate: state === "outdated" || state === "unsatisfied",
3521
- ...version === void 0 ? {} : { version },
3522
- ...detail === void 0 ? {} : { detail }
4084
+ ...moduleUpdate === void 0 ? note === void 0 ? {} : { note } : {},
4085
+ ...local ? { local: true } : {},
4086
+ defaultShown: defaults.has(manifest.id),
4087
+ defaultChanged: changed[manifest.id] ?? 0
3523
4088
  });
3524
4089
  }
3525
4090
  return rows;
@@ -3577,6 +4142,42 @@ function useHostWrite(options) {
3577
4142
  };
3578
4143
  }
3579
4144
  //#endregion
4145
+ //#region src/shared/hooks/use-visible-busy.ts
4146
+ var use_visible_busy_exports = /* @__PURE__ */ __exportAll({
4147
+ busyView: () => busyView,
4148
+ heldPhase: () => heldPhase,
4149
+ useVisibleBusy: () => useVisibleBusy
4150
+ });
4151
+ function heldPhase(phase, refreshing) {
4152
+ return refreshing && phase === "ready" ? "loading" : phase;
4153
+ }
4154
+ function busyView(active, visible) {
4155
+ return {
4156
+ busy: visible,
4157
+ settling: visible && !active
4158
+ };
4159
+ }
4160
+ function useVisibleBusy(active, floorMs) {
4161
+ const [visible, setVisible] = useState(active);
4162
+ const since = useRef(null);
4163
+ useEffect(() => {
4164
+ if (active) {
4165
+ if (since.current === null) since.current = Date.now();
4166
+ setVisible(true);
4167
+ return;
4168
+ }
4169
+ const held = holdBusy(since.current, Date.now(), floorMs);
4170
+ since.current = null;
4171
+ if (!held.visible) {
4172
+ setVisible(false);
4173
+ return;
4174
+ }
4175
+ const timer = setTimeout(() => setVisible(false), held.releaseInMs);
4176
+ return () => clearTimeout(timer);
4177
+ }, [active, floorMs]);
4178
+ return busyView(active, visible);
4179
+ }
4180
+ //#endregion
3580
4181
  //#region src/app/layouts/rightbar/market-plugin-rows.ts
3581
4182
  function installedPluginKept(value) {
3582
4183
  if (typeof value !== "object" || value === null) return void 0;
@@ -3594,34 +4195,40 @@ function installedPluginKept(value) {
3594
4195
  names
3595
4196
  };
3596
4197
  }
4198
+ function installedPluginNotice(value, t) {
4199
+ const kept = installedPluginKept(value);
4200
+ if (kept === void 0) return null;
4201
+ return t(kept.key, kept.names === void 0 ? {} : { names: kept.names.join(t("panels.market.listSeparator")) });
4202
+ }
3597
4203
  function noteOf(plugin) {
3598
4204
  if (plugin.broken === true) return {
3599
4205
  key: "panels.market.pluginBroken",
3600
- params: {}
4206
+ params: {},
4207
+ tone: "alert"
3601
4208
  };
3602
4209
  if (plugin.local === true) return void 0;
3603
- if (plugin.name !== void 0 && plugin.name !== plugin.pkg) return {
3604
- key: "panels.market.pluginAlsoKnownAs",
3605
- params: { pkg: plugin.pkg }
3606
- };
3607
4210
  }
3608
- function installedPluginRows(plugins) {
4211
+ function installedPluginRows(plugins, defaults = /* @__PURE__ */ new Set(), changed = {}) {
3609
4212
  return plugins.map((plugin) => {
4213
+ const id = `plugin:${plugin.pkg}`;
3610
4214
  const name = plugin.name ?? plugin.pkg;
3611
4215
  const outdated = plugin.installed !== void 0 && plugin.latest !== void 0 && plugin.latest !== plugin.installed;
3612
4216
  const note = noteOf(plugin);
3613
4217
  return {
3614
- id: `plugin:${plugin.pkg}`,
4218
+ id,
3615
4219
  titleKey: plugin.pkg,
3616
4220
  label: name,
3617
4221
  plugin: true,
3618
- state: outdated ? "outdated" : "installed",
4222
+ state: outdated ? "outdated" : plugin.broken === true ? "broken" : "installed",
3619
4223
  canInstall: false,
3620
4224
  canUpdate: outdated,
3621
4225
  canUninstall: true,
3622
4226
  ...plugin.local === true ? { local: true } : {},
3623
4227
  ...plugin.broken === true ? { broken: true } : {},
4228
+ defaultShown: defaults.has(id),
4229
+ defaultChanged: changed[id] ?? 0,
3624
4230
  ...note === void 0 ? {} : { note },
4231
+ ...plugin.installed === void 0 ? {} : { versionLabel: `${plugin.pkg}@${plugin.installed}` },
3625
4232
  pkg: plugin.pkg,
3626
4233
  ...plugin.installed === void 0 ? {} : { version: {
3627
4234
  installed: plugin.installed,
@@ -3630,8 +4237,315 @@ function installedPluginRows(plugins) {
3630
4237
  };
3631
4238
  });
3632
4239
  }
4240
+ var MarketPage_module_default = {
4241
+ marketList: "_marketList_csyus_1",
4242
+ marketRow: "_marketRow_csyus_10",
4243
+ marketIcon: "_marketIcon_csyus_20",
4244
+ marketMain: "_marketMain_csyus_32",
4245
+ marketName: "_marketName_csyus_39",
4246
+ marketDesc: "_marketDesc_csyus_48",
4247
+ marketUsedBy: "_marketUsedBy_csyus_59",
4248
+ marketVersion: "_marketVersion_csyus_73",
4249
+ marketLocalTag: "_marketLocalTag_csyus_95",
4250
+ marketEnd: "_marketEnd_csyus_106",
4251
+ marketSwitchSeat: "_marketSwitchSeat_csyus_113",
4252
+ marketActions: "_marketActions_csyus_126",
4253
+ marketUpdateAction: "_marketUpdateAction_csyus_132",
4254
+ marketSelfDivider: "_marketSelfDivider_csyus_138",
4255
+ marketSection: "_marketSection_csyus_143",
4256
+ marketSectionHead: "_marketSectionHead_csyus_150",
4257
+ marketSectionIcon: "_marketSectionIcon_csyus_156",
4258
+ marketSectionTitle: "_marketSectionTitle_csyus_163",
4259
+ marketSectionCount: "_marketSectionCount_csyus_169",
4260
+ marketProgress: "_marketProgress_csyus_176",
4261
+ marketNote: "_marketNote_csyus_186",
4262
+ marketNotePlain: "_marketNotePlain_csyus_193",
4263
+ marketFailure: "_marketFailure_csyus_201",
4264
+ marketEmpty: "_marketEmpty_csyus_208",
4265
+ marketPage: "_marketPage_csyus_213",
4266
+ marketPageHead: "_marketPageHead_csyus_231",
4267
+ marketPageTitle: "_marketPageTitle_csyus_239",
4268
+ marketPageIntro: "_marketPageIntro_csyus_244",
4269
+ marketPageTools: "_marketPageTools_csyus_250",
4270
+ marketIconButton: "_marketIconButton_csyus_259",
4271
+ marketIconWrap: "_marketIconWrap_csyus_284",
4272
+ marketIconButtonSpinning: "_marketIconButtonSpinning_csyus_288",
4273
+ "wb-spin": "_wb-spin_csyus_1",
4274
+ marketAddButton: "_marketAddButton_csyus_292",
4275
+ marketChecking: "_marketChecking_csyus_309",
4276
+ marketEmptyTitle: "_marketEmptyTitle_csyus_317"
4277
+ };
4278
+ //#endregion
4279
+ //#region src/app/layouts/rightbar/MarketStates.tsx
4280
+ function MarketChecking({ t }) {
4281
+ return /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmpty }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketChecking }, /* @__PURE__ */ h(StateDot, {
4282
+ state: "ongoing",
4283
+ size: 14
4284
+ }), t("panels.market.checking")));
4285
+ }
4286
+ function MarketEmpty({ t }) {
4287
+ return /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmpty }, /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmptyTitle }, t("panels.market.empty")));
4288
+ }
4289
+ //#endregion
4290
+ //#region src/app/layouts/rightbar/market-section-icon.ts
4291
+ var SIZE$1 = 14;
4292
+ function marketSectionIcon(kind) {
4293
+ switch (kind) {
4294
+ case "installed": return h(IconModules, { size: SIZE$1 });
4295
+ case "pending": return h(IconDownloadOutlineRegular, { size: SIZE$1 });
4296
+ case "plugins": return h(IconCordisPluginOutlineRegular, { size: SIZE$1 });
4297
+ case "shared": return h(IconLinkOutlineRegular, { size: SIZE$1 });
4298
+ }
4299
+ }
4300
+ //#endregion
4301
+ //#region src/app/layouts/rightbar/market-row-icon.ts
4302
+ var SIZE = 18;
4303
+ function packageIcon(kind) {
4304
+ switch (kind) {
4305
+ case "module": return h(IconArchiveOutlineRegular, { size: SIZE });
4306
+ case "plugin": return h(IconOpencli, { size: SIZE });
4307
+ case "lib": return h(IconNpm, { size: SIZE });
4308
+ case "workbench": return h(IconPanelScreen, { size: SIZE });
4309
+ }
4310
+ }
4311
+ function marketRowKind(row) {
4312
+ if (row.workbench === true) return "workbench";
4313
+ if (row.plugin === true) return "plugin";
4314
+ return "module";
4315
+ }
4316
+ function sharedRowKind(row) {
4317
+ return row.kind === "plugin" ? "plugin" : "lib";
4318
+ }
4319
+ //#endregion
4320
+ //#region src/app/layouts/rightbar/market-view-text.ts
4321
+ var PROGRESS_KEY = {
4322
+ install: "panels.market.installing",
4323
+ update: "panels.market.updating",
4324
+ "update-bundle": "panels.market.updating",
4325
+ "remove-bundle": "panels.market.uninstalling",
4326
+ uninstall: "panels.market.uninstalling",
4327
+ "update-dependency": "panels.market.updating",
4328
+ "update-plugin": "panels.market.updating",
4329
+ "uninstall-plugin": "panels.market.uninstalling",
4330
+ "update-workbench": "panels.market.updating"
4331
+ };
4332
+ var ACTION_LABEL_KEY = {
4333
+ install: "panels.market.install",
4334
+ update: "panels.market.update",
4335
+ "update-bundle": "panels.market.update",
4336
+ "remove-bundle": "panels.market.uninstall",
4337
+ uninstall: "panels.market.uninstall",
4338
+ "update-dependency": "panels.market.update",
4339
+ "update-plugin": "panels.market.update",
4340
+ "uninstall-plugin": "panels.market.uninstall",
4341
+ "update-workbench": "panels.market.update"
4342
+ };
4343
+ function pendingRowOf(input) {
4344
+ const { pending, removing } = input;
4345
+ if (removing === null || pending === null) return void 0;
4346
+ if (input.rows.some((row) => row.id === removing)) return void 0;
4347
+ return {
4348
+ id: removing,
4349
+ titleKey: pending.titleKey ?? input.titles.get(removing) ?? removing,
4350
+ state: "installed",
4351
+ canInstall: false,
4352
+ canUpdate: false,
4353
+ canUninstall: true,
4354
+ ...pending.pkg === void 0 ? {} : { pkg: pending.pkg },
4355
+ ...pending.version === void 0 ? {} : { version: { installed: pending.version } }
4356
+ };
4357
+ }
4358
+ //#endregion
4359
+ //#region src/app/layouts/rightbar/SharedSection.tsx
4360
+ function SharedLine({ t, row, pending, failure, onAct }) {
4361
+ const running = pending !== null && pending.id === row.id ? pending : null;
4362
+ const locked = pending !== null;
4363
+ const actions = sharedActions(row);
4364
+ const stateText = t(SHARED_STATE_KEY[row.state]);
4365
+ const version = row.version;
4366
+ const name = /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketName }, row.label, version === void 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketVersion }, version.installed !== void 0 && version.latest !== void 0 && version.installed !== version.latest ? t("panels.market.versionArrow", {
4367
+ from: version.installed,
4368
+ to: version.latest
4369
+ }) : version.installed ?? version.latest ?? ""));
4370
+ return /* @__PURE__ */ h("li", { className: MarketPage_module_default.marketRow }, /* @__PURE__ */ h("span", {
4371
+ className: MarketPage_module_default.marketIcon,
4372
+ "aria-hidden": "true"
4373
+ }, packageIcon(sharedRowKind(row))), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketMain }, row.detail === void 0 ? name : /* @__PURE__ */ h(Tip, { label: row.detail }, name), /* @__PURE__ */ h("span", {
4374
+ className: MarketPage_module_default.marketDesc,
4375
+ role: "img",
4376
+ "aria-label": stateText
4377
+ }, row.state === "checking" ? /* @__PURE__ */ h(StateDot, {
4378
+ state: "ongoing",
4379
+ size: 14
4380
+ }) : /* @__PURE__ */ h(StateDot, {
4381
+ state: SHARED_DOT[row.state],
4382
+ size: 9
4383
+ }), stateText, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketUsedBy }, t("panels.market.sharedUsedBy", { modules: row.usedByKeys.map((key) => t(key)).join(t("panels.market.listSeparator")) })))), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEnd }, running !== null ? /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketProgress }, /* @__PURE__ */ h(StateDot, {
4384
+ state: "ongoing",
4385
+ size: 14
4386
+ }), t(PROGRESS_KEY[running.action])) : actions.length === 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketActions }, actions.map((action) => /* @__PURE__ */ h(Button, {
4387
+ key: action,
4388
+ type: "button",
4389
+ size: "sm",
4390
+ variant: "outline",
4391
+ disabled: locked,
4392
+ onClick: () => onAct(action)
4393
+ }, t(ACTION_LABEL_KEY[action]))))), failure === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketFailure }, failure));
4394
+ }
4395
+ function SharedSection({ t, rows, pending, failureOf, act }) {
4396
+ if (rows.length === 0) return null;
4397
+ return /* @__PURE__ */ h("section", { className: MarketPage_module_default.marketSection }, /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketSectionHead }, /* @__PURE__ */ h("span", {
4398
+ className: MarketPage_module_default.marketSectionIcon,
4399
+ "aria-hidden": "true"
4400
+ }, marketSectionIcon("shared")), /* @__PURE__ */ h("h2", { className: MarketPage_module_default.marketSectionTitle }, t("panels.market.sectionShared")), /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketSectionCount }, rows.length)), /* @__PURE__ */ h("ul", { className: MarketPage_module_default.marketList }, rows.map((row) => /* @__PURE__ */ h(SharedLine, {
4401
+ key: row.id,
4402
+ t,
4403
+ row,
4404
+ pending,
4405
+ failure: failureOf(row.id),
4406
+ onAct: (action) => void act(row.id, action)
4407
+ }))));
4408
+ }
4409
+ //#endregion
4410
+ //#region src/app/layouts/rightbar/panel-write.ts
4411
+ var PANEL_SETTLE_MS = 4e3;
4412
+ function rowKey(row) {
4413
+ return `${row.id}:${row.shown ? "1" : "0"}:${row.source}`;
4414
+ }
4415
+ function rowKeys(rows) {
4416
+ return rows.map(rowKey).join(",");
4417
+ }
4418
+ function panelBoardSignature(units, plugins, own) {
4419
+ return `${rowKeys(units)}|${rowKeys(plugins)}|${own ? "1" : "0"}`;
4420
+ }
4421
+ function machineBoardSignature(defaults, changed) {
4422
+ const counts = Object.entries(changed).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([id, count]) => `${id}:${String(count)}`);
4423
+ return `${[...defaults].sort().join(",")}|${counts.join(",")}`;
4424
+ }
4425
+ function nextPending(pending, signature) {
4426
+ return pending !== null && pending !== signature ? null : pending;
4427
+ }
4428
+ function useBoardSettle(signature) {
4429
+ const [held, setHeld] = useState(null);
4430
+ useEffect(() => {
4431
+ setHeld((current) => nextPending(current, signature));
4432
+ }, [signature]);
4433
+ useEffect(() => {
4434
+ if (held === null) return void 0;
4435
+ const timer = setTimeout(() => setHeld(null), PANEL_SETTLE_MS);
4436
+ return () => clearTimeout(timer);
4437
+ }, [held]);
4438
+ return {
4439
+ pending: held !== null,
4440
+ begin: () => setHeld(signature),
4441
+ clear: () => setHeld(null)
4442
+ };
4443
+ }
4444
+ //#endregion
4445
+ //#region src/app/layouts/rightbar/market-section.tsx
4446
+ var dangerActions = [
4447
+ "uninstall",
4448
+ "remove-bundle",
4449
+ "uninstall-plugin"
4450
+ ];
4451
+ var updateActions = [
4452
+ "update",
4453
+ "update-bundle",
4454
+ "update-plugin",
4455
+ "update-workbench"
4456
+ ];
4457
+ function MarketLine({ t, row, pending, failure, onAct, onDefault, boardBusy }) {
4458
+ const running = pending !== null && pending.id === row.id ? pending : null;
4459
+ const locked = pending !== null;
4460
+ const quiet = row.workbench === true && row.state === "installed" && row.hint === void 0;
4461
+ const actions = marketActions$1(row);
4462
+ const switchLocked = marketSwitchLocked(row);
4463
+ const stateText = t(MARKET_STATE_KEY[row.state]);
4464
+ return /* @__PURE__ */ h("li", { className: MarketPage_module_default.marketRow }, /* @__PURE__ */ h("span", {
4465
+ className: MarketPage_module_default.marketIcon,
4466
+ "aria-hidden": "true"
4467
+ }, packageIcon(marketRowKind(row))), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketMain }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketName }, marketRowTitle(row, t), row.versionLabel === void 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketVersion }, row.versionLabel), row.version === void 0 || row.versionLabel !== 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", {
4468
+ from: row.version.installed,
4469
+ to: row.version.latest
4470
+ }) : row.version.installed ?? row.version.latest ?? ""), row.local === true ? /* @__PURE__ */ h(Tip, { label: t("panels.market.localHint") }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketLocalTag }, t("panels.market.localMark"))) : null), quiet ? null : /* @__PURE__ */ h("span", {
4471
+ className: MarketPage_module_default.marketDesc,
4472
+ role: "img",
4473
+ "aria-label": stateText
4474
+ }, row.state === "checking" ? /* @__PURE__ */ h(StateDot, {
4475
+ state: "ongoing",
4476
+ size: 14
4477
+ }) : /* @__PURE__ */ h(StateDot, {
4478
+ state: MARKET_DOT[row.state],
4479
+ size: 9
4480
+ }), stateText, row.hint === void 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketUsedBy }, t(row.hint)))), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEnd }, running !== null ? /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketProgress }, /* @__PURE__ */ h(StateDot, {
4481
+ state: "ongoing",
4482
+ size: 14
4483
+ }), t(PROGRESS_KEY[running.action])) : actions.length === 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketActions }, actions.map((action) => {
4484
+ const danger = dangerActions.includes(action);
4485
+ const update = updateActions.includes(action);
4486
+ return /* @__PURE__ */ h(Button, {
4487
+ key: action,
4488
+ type: "button",
4489
+ size: "sm",
4490
+ variant: action === "install" ? "primary" : "outline",
4491
+ className: danger ? "wb-dangerAction" : update ? MarketPage_module_default.marketUpdateAction : void 0,
4492
+ icon: danger ? /* @__PURE__ */ h(IconTrashOutlineRegular, { size: 13 }) : void 0,
4493
+ "aria-label": danger ? t("panels.market.uninstallLabel", { name: marketRowTitle(row, t) }) : void 0,
4494
+ disabled: locked,
4495
+ onClick: () => onAct(action)
4496
+ }, t(ACTION_LABEL_KEY[action]));
4497
+ })), row.defaultShown === void 0 ? null : /* @__PURE__ */ h(Tip, { label: t(switchLocked ? "panels.market.defaultLocked" : "panels.market.defaultHint") }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketSwitchSeat }, /* @__PURE__ */ h(Switch, {
4498
+ checked: row.defaultShown,
4499
+ disabled: boardBusy === true || locked || switchLocked,
4500
+ label: `${marketRowTitle(row, t)} · ${t("panels.market.defaultLabel")}`,
4501
+ onChange: (next) => onDefault?.(next)
4502
+ })))), row.note === void 0 ? null : /* @__PURE__ */ h("div", {
4503
+ className: row.note.tone === "plain" ? MarketPage_module_default.marketNotePlain : MarketPage_module_default.marketNote,
4504
+ title: row.note.params.reason === void 0 ? void 0 : t("panels.market.moduleRefusedDetail", row.note.params)
4505
+ }, t(row.note.key, row.note.params)), failure === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketFailure }, failure));
4506
+ }
4507
+ function MarketSection({ t, titleKey, icon, rows, pending, failureOf, act, confirmActions, onConfirming, onDefault, boardBusy }) {
4508
+ if (rows.length === 0) return null;
4509
+ return /* @__PURE__ */ h("section", { className: MarketPage_module_default.marketSection }, titleKey === void 0 ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketSectionHead }, /* @__PURE__ */ h("span", {
4510
+ className: MarketPage_module_default.marketSectionIcon,
4511
+ "aria-hidden": "true"
4512
+ }, icon), /* @__PURE__ */ h("h2", { className: MarketPage_module_default.marketSectionTitle }, t(titleKey)), rows.length === 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketSectionCount }, rows.length)), rows.length === 0 ? null : /* @__PURE__ */ h("ul", { className: MarketPage_module_default.marketList }, rows.map((row) => /* @__PURE__ */ h(MarketLine, {
4513
+ key: row.id,
4514
+ t,
4515
+ row,
4516
+ pending,
4517
+ failure: failureOf(row.id),
4518
+ onAct: (action) => confirmActions.includes(action) ? onConfirming(row.id) : void act(row.id, action),
4519
+ onDefault: (next) => onDefault?.(row.id, next),
4520
+ boardBusy
4521
+ }))));
4522
+ }
3633
4523
  //#endregion
3634
4524
  //#region src/app/layouts/market/add-module-text.ts
4525
+ function previewOf(inspection, fallback) {
4526
+ if (inspection.status === "plugin") return {
4527
+ kind: "plugin",
4528
+ name: inspection.pkg,
4529
+ version: inspection.version ?? "",
4530
+ description: "",
4531
+ registry: inspection.registry ?? "",
4532
+ ...inspection.pluginName === void 0 ? {} : { pluginName: inspection.pluginName }
4533
+ };
4534
+ return {
4535
+ kind: "module",
4536
+ name: inspection.name ?? fallback,
4537
+ version: inspection.version ?? "",
4538
+ description: inspection.description ?? "",
4539
+ registry: inspection.registry ?? ""
4540
+ };
4541
+ }
4542
+ function resultKindOf(input) {
4543
+ if (input.plugin) return "plugin";
4544
+ if (input.change.application === "failed") return "failed";
4545
+ if (input.change.application === "restart-required") return "restart";
4546
+ if (input.change.application === "cancelled" || input.supplyState === "not-a-module") return "quiet";
4547
+ return "took-effect";
4548
+ }
3635
4549
  var GUIDE_ITEMS = [
3636
4550
  {
3637
4551
  titleKey: "panels.market.add.guideIdTitle",
@@ -3819,128 +4733,60 @@ function changeFailure(change, t) {
3819
4733
  if (change === void 0 || SHIPPED.includes(change.application)) return void 0;
3820
4734
  return failureReason(failureCode(change), change.application, t);
3821
4735
  }
3822
- var MarketPage_module_default = {
3823
- marketList: "_marketList_z6vtq_1",
3824
- marketRow: "_marketRow_z6vtq_10",
3825
- marketIcon: "_marketIcon_z6vtq_20",
3826
- marketMain: "_marketMain_z6vtq_32",
3827
- marketName: "_marketName_z6vtq_39",
3828
- marketDesc: "_marketDesc_z6vtq_48",
3829
- marketUsedBy: "_marketUsedBy_z6vtq_59",
3830
- marketVersion: "_marketVersion_z6vtq_73",
3831
- marketEnd: "_marketEnd_z6vtq_95",
3832
- marketActions: "_marketActions_z6vtq_102",
3833
- marketSection: "_marketSection_z6vtq_108",
3834
- marketSectionHead: "_marketSectionHead_z6vtq_115",
3835
- marketSectionTitle: "_marketSectionTitle_z6vtq_121",
3836
- marketSectionCount: "_marketSectionCount_z6vtq_127",
3837
- marketProgress: "_marketProgress_z6vtq_133",
3838
- marketNote: "_marketNote_z6vtq_143",
3839
- marketFailure: "_marketFailure_z6vtq_150",
3840
- marketEmpty: "_marketEmpty_z6vtq_157",
3841
- marketPage: "_marketPage_z6vtq_162",
3842
- marketPageHead: "_marketPageHead_z6vtq_180",
3843
- marketPageTitle: "_marketPageTitle_z6vtq_188",
3844
- marketPageIntro: "_marketPageIntro_z6vtq_193",
3845
- marketPageTools: "_marketPageTools_z6vtq_199",
3846
- marketIconButton: "_marketIconButton_z6vtq_208",
3847
- marketIconWrap: "_marketIconWrap_z6vtq_233",
3848
- marketIconButtonSpinning: "_marketIconButtonSpinning_z6vtq_237",
3849
- "wb-spin": "_wb-spin_z6vtq_1",
3850
- marketAddButton: "_marketAddButton_z6vtq_241",
3851
- marketChecking: "_marketChecking_z6vtq_258",
3852
- marketEmptyTitle: "_marketEmptyTitle_z6vtq_266"
3853
- };
3854
4736
  //#endregion
3855
- //#region src/app/layouts/rightbar/MarketStates.tsx
3856
- function MarketChecking({ t }) {
3857
- return /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmpty }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketChecking }, /* @__PURE__ */ h(StateDot, {
3858
- state: "ongoing",
3859
- size: 14
3860
- }), t("panels.market.checking")));
3861
- }
3862
- function MarketEmpty({ t }) {
3863
- return /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmpty }, /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmptyTitle }, t("panels.market.empty")));
3864
- }
3865
- //#endregion
3866
- //#region src/app/layouts/rightbar/market-view-text.ts
3867
- var PROGRESS_KEY = {
3868
- install: "panels.market.installing",
3869
- update: "panels.market.updating",
3870
- "update-bundle": "panels.market.updating",
3871
- "remove-bundle": "panels.market.uninstalling",
3872
- uninstall: "panels.market.uninstalling",
3873
- "update-dependency": "panels.market.updating",
3874
- "update-plugin": "panels.market.updating",
3875
- "uninstall-plugin": "panels.market.uninstalling"
3876
- };
3877
- var ACTION_LABEL_KEY = {
3878
- install: "panels.market.install",
3879
- update: "panels.market.update",
3880
- "update-bundle": "panels.market.update",
3881
- "remove-bundle": "panels.market.uninstall",
3882
- uninstall: "panels.market.uninstall",
3883
- "update-dependency": "panels.market.update",
3884
- "update-plugin": "panels.market.update",
3885
- "uninstall-plugin": "panels.market.uninstall"
3886
- };
3887
- //#endregion
3888
- //#region src/app/layouts/rightbar/SharedSection.tsx
3889
- function SharedLine({ t, row, pending, failure, onAct }) {
3890
- const running = pending !== null && pending.id === row.id ? pending : null;
3891
- const locked = pending !== null;
3892
- const actions = sharedActions(row);
3893
- const stateText = t(SHARED_STATE_KEY[row.state]);
3894
- const version = row.version;
3895
- const name = /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketName }, row.label, version === void 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketVersion }, version.installed !== void 0 && version.latest !== void 0 && version.installed !== version.latest ? t("panels.market.versionArrow", {
3896
- from: version.installed,
3897
- to: version.latest
3898
- }) : version.installed ?? version.latest ?? ""));
3899
- return /* @__PURE__ */ h("li", { className: MarketPage_module_default.marketRow }, /* @__PURE__ */ h("span", {
3900
- className: MarketPage_module_default.marketIcon,
3901
- "aria-hidden": "true"
3902
- }, /* @__PURE__ */ h(IconModules, { size: 18 })), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketMain }, row.detail === void 0 ? name : /* @__PURE__ */ h(Tip, { label: row.detail }, name), /* @__PURE__ */ h("span", {
3903
- className: MarketPage_module_default.marketDesc,
3904
- role: "img",
3905
- "aria-label": stateText
3906
- }, row.state === "checking" ? /* @__PURE__ */ h(StateDot, {
3907
- state: "ongoing",
3908
- size: 14
3909
- }) : /* @__PURE__ */ h(StateDot, {
3910
- state: SHARED_DOT[row.state],
3911
- size: 9
3912
- }), stateText, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketUsedBy }, t("panels.market.sharedUsedBy", { modules: row.usedByKeys.map((key) => t(key)).join(t("panels.market.listSeparator")) })))), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEnd }, running !== null ? /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketProgress }, /* @__PURE__ */ h(StateDot, {
3913
- state: "ongoing",
3914
- size: 14
3915
- }), t(PROGRESS_KEY[running.action])) : actions.length === 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketActions }, actions.map((action) => /* @__PURE__ */ h(Button, {
3916
- key: action,
3917
- type: "button",
3918
- size: "sm",
3919
- variant: "outline",
3920
- disabled: locked,
3921
- onClick: () => onAct(action)
3922
- }, t(ACTION_LABEL_KEY[action]))))), failure === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketFailure }, failure));
3923
- }
3924
- function SharedSection({ t, rows, pending, failureOf, act }) {
3925
- if (rows.length === 0) return null;
3926
- return /* @__PURE__ */ h("section", { className: MarketPage_module_default.marketSection }, /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketSectionHead }, /* @__PURE__ */ h("h2", { className: MarketPage_module_default.marketSectionTitle }, t("panels.market.sectionShared")), /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketSectionCount }, rows.length)), /* @__PURE__ */ h("ul", { className: MarketPage_module_default.marketList }, rows.map((row) => /* @__PURE__ */ h(SharedLine, {
3927
- key: row.id,
3928
- t,
3929
- row,
3930
- pending,
3931
- failure: failureOf(row.id),
3932
- onAct: (action) => void act(row.id, action)
3933
- }))));
4737
+ //#region src/app/layouts/rightbar/market-act.ts
4738
+ function marketActOf(options) {
4739
+ const { t, mocked, rowOf, seats, send, onChanged } = options;
4740
+ return async (id, action) => {
4741
+ if (mocked) return;
4742
+ const row = rowOf(id);
4743
+ seats.setPending({
4744
+ id,
4745
+ action,
4746
+ ...row?.titleKey === void 0 ? {} : { titleKey: row.titleKey },
4747
+ ...row?.pkg === void 0 ? {} : { pkg: row.pkg },
4748
+ ...row?.version?.installed === void 0 ? {} : { version: row.version.installed }
4749
+ });
4750
+ seats.setConfirming(null);
4751
+ seats.setFailed(null);
4752
+ if (action !== "uninstall-plugin") seats.setNotice(null);
4753
+ const outcome = await send(action === "update-dependency" ? {
4754
+ action,
4755
+ id
4756
+ } : action === "remove-bundle" || action === "update-plugin" || action === "uninstall-plugin" || action === "update-workbench" ? {
4757
+ action,
4758
+ name: row?.pkg ?? ""
4759
+ } : {
4760
+ action,
4761
+ unit: id
4762
+ });
4763
+ seats.setPending(null);
4764
+ if (!outcome.ok) {
4765
+ onChanged();
4766
+ seats.setFailed({
4767
+ id,
4768
+ message: t("panels.market.failed", { reason: outcome.message })
4769
+ });
4770
+ return;
4771
+ }
4772
+ if (action === "uninstall-plugin") seats.setNotice(installedPluginNotice(outcome.value, t));
4773
+ const reason = changeFailure(changeOf(outcome.value), t);
4774
+ onChanged();
4775
+ if (reason !== void 0) seats.setFailed({
4776
+ id,
4777
+ message: t("panels.market.failed", { reason })
4778
+ });
4779
+ };
3934
4780
  }
3935
4781
  var PanelFoot_module_default = {
3936
- foot: "_foot_1us83_1",
3937
- footText: "_footText_1us83_12",
3938
- footTextMd: "_footTextMd_1us83_17"
4782
+ foot: "_foot_1ud1j_1",
4783
+ footText: "_footText_1ud1j_13",
4784
+ footTextMd: "_footTextMd_1ud1j_18"
3939
4785
  };
3940
4786
  //#endregion
3941
4787
  //#region src/shared/components/PanelFoot.tsx
3942
4788
  function PanelFoot({ text, size = "sm", children }) {
3943
- return /* @__PURE__ */ h("footer", { className: PanelFoot_module_default.foot }, /* @__PURE__ */ h("span", { className: size === "md" ? PanelFoot_module_default.footTextMd : PanelFoot_module_default.footText }, text), children ?? null);
4789
+ return /* @__PURE__ */ h("footer", { className: PanelFoot_module_default.foot }, text === void 0 ? null : /* @__PURE__ */ h("span", { className: size === "md" ? PanelFoot_module_default.footTextMd : PanelFoot_module_default.footText }, text), children ?? null);
3944
4790
  }
3945
4791
  //#endregion
3946
4792
  //#region src/app/layouts/rightbar/MarketView.tsx
@@ -3949,49 +4795,6 @@ var CONFIRM_UNINSTALL = [
3949
4795
  "remove-bundle",
3950
4796
  "uninstall-plugin"
3951
4797
  ];
3952
- var CONFIRM_REMOVE = ["remove-bundle"];
3953
- function MarketLine({ t, row, pending, failure, onAct }) {
3954
- const running = pending !== null && pending.id === row.id ? pending : null;
3955
- const locked = pending !== null;
3956
- const actions = marketActions$1(row);
3957
- const stateText = t(row.moduleUpdate === void 0 ? MARKET_STATE_KEY[row.state] : "panels.market.moduleOutdated");
3958
- return /* @__PURE__ */ h("li", { className: MarketPage_module_default.marketRow }, /* @__PURE__ */ h("span", {
3959
- className: MarketPage_module_default.marketIcon,
3960
- "aria-hidden": "true"
3961
- }, /* @__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", {
3962
- from: row.version.installed,
3963
- to: row.version.latest
3964
- }) : row.version.installed ?? row.version.latest ?? "")), /* @__PURE__ */ h("span", {
3965
- className: MarketPage_module_default.marketDesc,
3966
- role: "img",
3967
- "aria-label": stateText
3968
- }, row.state === "checking" ? /* @__PURE__ */ h(StateDot, {
3969
- state: "ongoing",
3970
- size: 14
3971
- }) : /* @__PURE__ */ h(StateDot, {
3972
- state: MARKET_DOT[row.state],
3973
- size: 9
3974
- }), stateText, row.hint === void 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketUsedBy }, t(row.hint)))), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEnd }, running !== null ? /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketProgress }, /* @__PURE__ */ h(StateDot, {
3975
- state: "ongoing",
3976
- size: 14
3977
- }), t(PROGRESS_KEY[running.action])) : actions.length === 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketActions }, actions.map((action) => {
3978
- const danger = action === "uninstall" || action === "remove-bundle";
3979
- return /* @__PURE__ */ h(Button, {
3980
- key: action,
3981
- type: "button",
3982
- size: "sm",
3983
- variant: action === "install" ? "primary" : "outline",
3984
- className: danger ? "wb-dangerAction" : void 0,
3985
- icon: danger ? /* @__PURE__ */ h(IconTrashOutlineRegular, { size: 13 }) : void 0,
3986
- "aria-label": danger ? t("panels.market.uninstallLabel", { name: marketRowTitle(row, t) }) : void 0,
3987
- disabled: locked,
3988
- onClick: () => onAct(action)
3989
- }, t(ACTION_LABEL_KEY[action]));
3990
- }))), row.note === void 0 ? null : /* @__PURE__ */ h("div", {
3991
- className: MarketPage_module_default.marketNote,
3992
- title: row.note.params.reason === void 0 ? void 0 : t("panels.market.moduleRefusedDetail", row.note.params)
3993
- }, t(row.note.key, row.note.params)), failure === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketFailure }, failure));
3994
- }
3995
4798
  function ConfirmUninstall({ t, name, onConfirm, onCancel }) {
3996
4799
  const [acknowledged, setAcknowledged] = useState(false);
3997
4800
  return /* @__PURE__ */ h(RiskConfirmation, {
@@ -4006,26 +4809,31 @@ function ConfirmUninstall({ t, name, onConfirm, onCancel }) {
4006
4809
  onAcknowledgedChange: setAcknowledged,
4007
4810
  onCancel,
4008
4811
  onConfirm
4009
- });
4010
- }
4011
- function MarketSection({ t, titleKey, rows, pending, failureOf, act, confirmActions, onConfirming }) {
4012
- if (rows.length === 0) return null;
4013
- return /* @__PURE__ */ h("section", { className: MarketPage_module_default.marketSection }, /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketSectionHead }, /* @__PURE__ */ h("h2", { className: MarketPage_module_default.marketSectionTitle }, t(titleKey)), /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketSectionCount }, rows.length)), /* @__PURE__ */ h("ul", { className: MarketPage_module_default.marketList }, rows.map((row) => /* @__PURE__ */ h(MarketLine, {
4014
- key: row.id,
4015
- t,
4016
- row,
4017
- pending,
4018
- failure: failureOf(row.id),
4019
- onAct: (action) => confirmActions.includes(action) ? onConfirming(row.id) : void act(row.id, action)
4020
- }))));
4812
+ });
4021
4813
  }
4022
- function MarketBody({ t, shown, pluginList, installedList, shared, pending, failed, notice, act, onConfirming }) {
4814
+ function MarketBody({ t, self, shown, pluginList, installedList, shared, pending, failed, notice, act, onConfirming, setDefault, boardBusy }) {
4023
4815
  const failureOf = (id) => failed?.id === id ? failed.message : null;
4024
- return /* @__PURE__ */ h(Fragment, null, notice === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketNote }, notice), marketSections(shown).map((section) => /* @__PURE__ */ h(MarketSection, {
4816
+ return /* @__PURE__ */ h(Fragment, null, notice === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketNote }, notice), /* @__PURE__ */ h(MarketSection, {
4817
+ t,
4818
+ rows: self === void 0 ? [] : [self],
4819
+ onDefault: setDefault,
4820
+ boardBusy,
4821
+ pending,
4822
+ failureOf,
4823
+ act,
4824
+ confirmActions: CONFIRM_UNINSTALL,
4825
+ onConfirming
4826
+ }), self === void 0 ? null : /* @__PURE__ */ h("div", {
4827
+ className: MarketPage_module_default.marketSelfDivider,
4828
+ "aria-hidden": "true"
4829
+ }), marketSections([...shown, ...installedList]).map((section) => /* @__PURE__ */ h(MarketSection, {
4025
4830
  key: section.id,
4026
4831
  t,
4027
4832
  titleKey: section.titleKey,
4833
+ icon: marketSectionIcon(section.id === "installed" ? "installed" : "pending"),
4028
4834
  rows: section.rows,
4835
+ onDefault: setDefault,
4836
+ boardBusy,
4029
4837
  pending,
4030
4838
  failureOf,
4031
4839
  act,
@@ -4034,21 +4842,15 @@ function MarketBody({ t, shown, pluginList, installedList, shared, pending, fail
4034
4842
  })), /* @__PURE__ */ h(MarketSection, {
4035
4843
  t,
4036
4844
  titleKey: "panels.market.sectionPlugins",
4845
+ icon: marketSectionIcon("plugins"),
4037
4846
  rows: pluginList,
4847
+ onDefault: setDefault,
4848
+ boardBusy,
4038
4849
  pending,
4039
4850
  failureOf,
4040
4851
  act,
4041
4852
  confirmActions: CONFIRM_UNINSTALL,
4042
4853
  onConfirming
4043
- }), /* @__PURE__ */ h(MarketSection, {
4044
- t,
4045
- titleKey: installedList.length > 0 && installedList.every((row) => row.local === true) ? "panels.market.sectionLocal" : "panels.market.sectionUnlisted",
4046
- rows: installedList,
4047
- pending,
4048
- failureOf,
4049
- act,
4050
- confirmActions: CONFIRM_REMOVE,
4051
- onConfirming
4052
4854
  }), /* @__PURE__ */ h(PanelFoot, {
4053
4855
  size: "md",
4054
4856
  text: t("panels.market.foot")
@@ -4060,95 +4862,91 @@ function MarketBody({ t, shown, pluginList, installedList, shared, pending, fail
4060
4862
  act
4061
4863
  }));
4062
4864
  }
4063
- function MarketView({ t, manifests, capabilities, freshness, onChanged, updates, installed, installedRead, plugins, settling, mock }) {
4865
+ function MarketView({ t, manifests, installable, capabilities, freshness, onChanged, onPending, updates, installed, installedRead, workbench, plugins, settling, mock, defaults = [], changed = {} }) {
4064
4866
  const [titles, setTitles] = useState(/* @__PURE__ */ new Map());
4065
4867
  useEffect(() => {
4066
4868
  if (mock === void 0) setTitles((known) => mergeTitles(known, manifests));
4067
4869
  }, [manifests, mock]);
4068
4870
  const catalog = mock?.manifests ?? manifests;
4871
+ const marketable = mock === void 0 ? marketCatalog(manifests, installable) : catalog;
4069
4872
  const effective = mock === void 0 ? capabilities : mock.capabilities;
4070
- const source = liveManifests(catalog, effective, mock === void 0 && installed !== void 0 ? new Set(installed.map((item) => item.unit)) : null);
4071
- const rows = marketRows(source, effective, mock?.updates ?? updates ?? {});
4873
+ const source = liveManifests(marketable, effective, mock === void 0 && installed !== void 0 ? new Set(installed.map((item) => item.unit)) : null);
4874
+ const byDefault = new Set(defaults);
4875
+ const rows = marketRows(source, effective, mock?.updates ?? updates ?? {}, byDefault, changed);
4072
4876
  const shared = sharedRows(source, effective);
4073
4877
  const [pending, setPending] = useState(mock?.pending ?? null);
4878
+ useEffect(() => {
4879
+ onPending?.(pending !== null);
4880
+ return () => onPending?.(false);
4881
+ }, [pending, onPending]);
4074
4882
  const provision = useHostWrite({
4075
4883
  channel: "provision",
4076
4884
  networkText: t("panels.failed")
4077
4885
  });
4886
+ const boardWrite = useHostWrite({
4887
+ channel: "prefs",
4888
+ resource: "panels",
4889
+ networkText: t("panels.failed")
4890
+ });
4891
+ const [writingDefault, setWritingDefault] = useState(false);
4892
+ const settleDefault = useBoardSettle(machineBoardSignature(defaults, changed));
4893
+ const { busy: boardBusy } = useVisibleBusy(writingDefault || settleDefault.pending, 500);
4894
+ const setDefault = async (id, next) => {
4895
+ if (mock !== void 0) return;
4896
+ setWritingDefault(true);
4897
+ settleDefault.begin();
4898
+ const outcome = await boardWrite.send({
4899
+ action: next ? "show" : "hide",
4900
+ id,
4901
+ scope: "machine"
4902
+ });
4903
+ setWritingDefault(false);
4904
+ if (!outcome.ok) {
4905
+ settleDefault.clear();
4906
+ setNotice(t("panels.failed"));
4907
+ }
4908
+ };
4078
4909
  const [confirming, setConfirming] = useState(mock?.confirming ?? null);
4079
4910
  const [failed, setFailed] = useState(mock?.failure ?? null);
4080
4911
  const [notice, setNotice] = useState(mock?.notice ?? null);
4081
4912
  const removing = pending !== null && pending.action === "remove-bundle" && failed?.id !== pending.id ? pending.id : null;
4082
- 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);
4083
- const pendingRow = removing === null || pending === null || rows.some((row) => row.id === removing) ? void 0 : {
4084
- id: removing,
4085
- titleKey: pending.titleKey ?? titles.get(removing) ?? removing,
4086
- state: "installed",
4087
- canInstall: false,
4088
- canUpdate: false,
4089
- canUninstall: true,
4090
- ...pending.pkg === void 0 ? {} : { pkg: pending.pkg },
4091
- ...pending.version === void 0 ? {} : { version: { installed: pending.version } }
4092
- };
4913
+ 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, byDefault, changed);
4914
+ const pendingRow = pendingRowOf({
4915
+ pending,
4916
+ removing,
4917
+ rows,
4918
+ titles
4919
+ });
4093
4920
  const shown = pendingRow === void 0 ? rows : [...rows, pendingRow];
4094
- const pluginList = installedPluginRows(mock?.plugins ?? plugins ?? []);
4921
+ const self = workbenchRow(mock === void 0 ? workbench : mock.workbench);
4922
+ const pluginList = installedPluginRows(mock?.plugins ?? plugins ?? [], byDefault, changed);
4095
4923
  const rowById = new Map([
4096
4924
  ...shown,
4925
+ ...self === void 0 ? [] : [self],
4097
4926
  ...installedList,
4098
4927
  ...pluginList
4099
4928
  ].map((row) => [row.id, row]));
4100
4929
  const confirmingRow = confirming === null ? void 0 : rowById.get(confirming);
4101
- const act = async (id, action) => {
4102
- if (mock !== void 0) return;
4103
- const row = rowById.get(id);
4104
- setPending({
4105
- id,
4106
- action,
4107
- ...row?.titleKey === void 0 ? {} : { titleKey: row.titleKey },
4108
- ...row?.pkg === void 0 ? {} : { pkg: row.pkg },
4109
- ...row?.version?.installed === void 0 ? {} : { version: row.version.installed }
4110
- });
4111
- setConfirming(null);
4112
- setFailed(null);
4113
- if (action !== "uninstall-plugin") setNotice(null);
4114
- const dependency = action === "update-dependency";
4115
- const byName = action === "remove-bundle" || action === "update-plugin" || action === "uninstall-plugin";
4116
- const outcome = await provision.send(dependency ? {
4117
- action,
4118
- id
4119
- } : byName ? {
4120
- action,
4121
- name: row?.pkg ?? ""
4122
- } : {
4123
- action,
4124
- unit: id
4125
- });
4126
- setPending(null);
4127
- if (!outcome.ok) {
4128
- onChanged();
4129
- setFailed({
4130
- id,
4131
- message: t("panels.market.failed", { reason: outcome.message })
4132
- });
4133
- return;
4134
- }
4135
- if (action === "uninstall-plugin") {
4136
- const kept = installedPluginKept(outcome.value);
4137
- setNotice(kept === void 0 ? null : t(kept.key, kept.names === void 0 ? {} : { names: kept.names.join(t("panels.market.listSeparator")) }));
4138
- }
4139
- const reason = changeFailure(changeOf(outcome.value), t);
4140
- onChanged();
4141
- if (reason !== void 0) setFailed({
4142
- id,
4143
- message: t("panels.market.failed", { reason })
4144
- });
4145
- };
4930
+ const act = marketActOf({
4931
+ t,
4932
+ mocked: mock !== void 0,
4933
+ rowOf: (id) => rowById.get(id),
4934
+ seats: {
4935
+ setPending,
4936
+ setConfirming,
4937
+ setFailed,
4938
+ setNotice
4939
+ },
4940
+ send: (body) => provision.send(body),
4941
+ onChanged
4942
+ });
4146
4943
  const settled = marketSettled(freshness, installedRead);
4147
- const nothing = shown.length === 0 && installedList.length === 0 && pluginList.length === 0;
4944
+ const nothing = shown.length === 0 && self === void 0 && installedList.length === 0 && pluginList.length === 0;
4148
4945
  if (!settled || (settling?.size ?? 0) > 0 && shown.length === 0 && installedList.length === 0) return /* @__PURE__ */ h(MarketChecking, { t });
4149
4946
  if (nothing) return /* @__PURE__ */ h(MarketEmpty, { t });
4150
4947
  return /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(MarketBody, {
4151
4948
  t,
4949
+ self,
4152
4950
  shown,
4153
4951
  pluginList,
4154
4952
  installedList,
@@ -4157,7 +4955,9 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
4157
4955
  failed,
4158
4956
  notice,
4159
4957
  act,
4160
- onConfirming: setConfirming
4958
+ onConfirming: setConfirming,
4959
+ setDefault,
4960
+ boardBusy
4161
4961
  }), /* @__PURE__ */ h(ConfirmUninstall, {
4162
4962
  key: confirming ?? "",
4163
4963
  t,
@@ -4173,6 +4973,182 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
4173
4973
  }));
4174
4974
  }
4175
4975
  //#endregion
4976
+ //#region src/modules/sessions/model/session-node.ts
4977
+ function visiblePendingKind(kind) {
4978
+ switch (kind) {
4979
+ case "approval":
4980
+ case "plan-review":
4981
+ case "question": return kind;
4982
+ default: return;
4983
+ }
4984
+ }
4985
+ function sessionNode(summary, statusById, list, pinnedIds, archivedIds) {
4986
+ const status = statusById.get(summary.id);
4987
+ const catalog = list.projectionsBySession[summary.id]?.values?.subagentCatalog;
4988
+ let runningSubagentCount = 0;
4989
+ for (const child of catalog ?? []) {
4990
+ const childStatus = statusById.get(child.id);
4991
+ const childRow = list.byId[child.id];
4992
+ if ((childStatus?.running ?? childRow?.running) === true) runningSubagentCount += 1;
4993
+ }
4994
+ return {
4995
+ id: summary.id,
4996
+ title: summary.blank ? "" : summary.displayTitle,
4997
+ blank: summary.blank,
4998
+ running: status?.running ?? summary.running,
4999
+ runningSubagentCount,
5000
+ completed: status?.completionUnread === true,
5001
+ pinned: !archivedIds.has(summary.id) && pinnedIds.has(summary.id),
5002
+ updatedAt: summary.updatedAt,
5003
+ pendingInteraction: visiblePendingKind(status?.pendingInteraction?.kind)
5004
+ };
5005
+ }
5006
+ function sessionStatuses(node, t) {
5007
+ const subagents = node.runningSubagentCount > 0 ? {
5008
+ state: "ongoing",
5009
+ label: t(node.runningSubagentCount === 1 ? "status.subagentsRunning.one" : "status.subagentsRunning.other", { n: node.runningSubagentCount })
5010
+ } : void 0;
5011
+ let pending;
5012
+ switch (node.pendingInteraction) {
5013
+ case "approval":
5014
+ pending = {
5015
+ state: "warning",
5016
+ label: t("status.waitingApproval")
5017
+ };
5018
+ break;
5019
+ case "plan-review":
5020
+ pending = {
5021
+ state: "warning",
5022
+ label: t("status.planReview")
5023
+ };
5024
+ break;
5025
+ case "question":
5026
+ pending = {
5027
+ state: "warning",
5028
+ label: t("status.waitingAnswer")
5029
+ };
5030
+ break;
5031
+ default: pending = void 0;
5032
+ }
5033
+ if (pending !== void 0) return subagents === void 0 ? [pending] : [pending, subagents];
5034
+ if (node.running) {
5035
+ const primary = {
5036
+ state: "ongoing",
5037
+ label: t("status.running")
5038
+ };
5039
+ return subagents === void 0 ? [primary] : [primary, subagents];
5040
+ }
5041
+ if (subagents !== void 0) return [subagents];
5042
+ if (node.completed) return [{
5043
+ state: "done",
5044
+ label: t("status.completed")
5045
+ }];
5046
+ return [{
5047
+ state: "idle",
5048
+ label: t("status.idle")
5049
+ }];
5050
+ }
5051
+ function currentSessionId(list, panelActive) {
5052
+ if (panelActive) return void 0;
5053
+ return Object.values(list.byId).find((session) => (session.retainedBy?.mainView ?? 0) > 0)?.id;
5054
+ }
5055
+ function orderSessionRows(rows, pinnedIds, archivedIds) {
5056
+ const placeholders = [];
5057
+ const leading = [];
5058
+ const rest = [];
5059
+ for (const row of rows) if (row.blank) placeholders.push(row);
5060
+ else if (!archivedIds.has(row.id) && pinnedIds.has(row.id)) leading.push(row);
5061
+ else rest.push(row);
5062
+ return [
5063
+ ...placeholders,
5064
+ ...leading,
5065
+ ...rest
5066
+ ];
5067
+ }
5068
+ function workspaceOfSession(workspaces, sessionId) {
5069
+ if (sessionId === void 0) return null;
5070
+ return workspaces.find((workspace) => workspace.sessionIds.includes(sessionId)) ?? null;
5071
+ }
5072
+ function sessionRows(workspaceSessionIds, list, archivedIds, current) {
5073
+ const rows = [];
5074
+ for (const id of workspaceSessionIds) {
5075
+ if (archivedIds.has(id)) continue;
5076
+ const row = list.byId[id];
5077
+ if (row === void 0 || row.origin === "subagent") continue;
5078
+ if (row.blank && row.id !== current) continue;
5079
+ rows.push(row);
5080
+ }
5081
+ return rows;
5082
+ }
5083
+ //#endregion
5084
+ //#region src/app/layouts/project-selection.ts
5085
+ var listeners$1 = /* @__PURE__ */ new Set();
5086
+ function selectedProjectId() {
5087
+ const stored = readText(STORAGE_KEY_PROJECT);
5088
+ return stored === "" ? null : stored;
5089
+ }
5090
+ function selectProject(workspaceId) {
5091
+ writeText(STORAGE_KEY_PROJECT, workspaceId);
5092
+ for (const listener of [...listeners$1]) try {
5093
+ listener();
5094
+ } catch {}
5095
+ }
5096
+ function subscribeProject(listener) {
5097
+ listeners$1.add(listener);
5098
+ return () => {
5099
+ listeners$1.delete(listener);
5100
+ };
5101
+ }
5102
+ //#endregion
5103
+ //#region src/app/layouts/rightbar/use-panels.ts
5104
+ function shouldDropPanels(workspace, previous) {
5105
+ return workspace !== previous;
5106
+ }
5107
+ function useEnabledUnits(refreshToken, workspace) {
5108
+ const [enabled, setEnabled] = useState(null);
5109
+ const lastWorkspace = useRef(workspace);
5110
+ useEffect(() => {
5111
+ let cancelled = false;
5112
+ if (shouldDropPanels(workspace, lastWorkspace.current)) {
5113
+ lastWorkspace.current = workspace;
5114
+ setEnabled(null);
5115
+ }
5116
+ const read = async () => {
5117
+ const response = await apiGet("panels", workspace === null ? {} : { path: workspace }).catch(() => null);
5118
+ if (cancelled) return;
5119
+ if (response?.ok === true && Array.isArray(response.units)) setEnabled({
5120
+ units: response.units,
5121
+ plugins: Array.isArray(response.plugins) ? response.plugins : [],
5122
+ defaults: Array.isArray(response.defaults) ? response.defaults : [],
5123
+ own: response.own === true,
5124
+ changed: response.changed ?? {}
5125
+ });
5126
+ };
5127
+ read();
5128
+ return () => {
5129
+ cancelled = true;
5130
+ };
5131
+ }, [
5132
+ refreshToken,
5133
+ useFactRevision("panels"),
5134
+ workspace
5135
+ ]);
5136
+ return enabled;
5137
+ }
5138
+ function useSelectedProjectId() {
5139
+ const [id, setId] = useState(() => selectedProjectId());
5140
+ useEffect(() => subscribeProject(() => setId(selectedProjectId())), []);
5141
+ return id;
5142
+ }
5143
+ function useBoardWorkspace(workspaces, sessions) {
5144
+ const projectId = useSelectedProjectId();
5145
+ const workspace = workspaces.items.find((item) => item.workspaceId === projectId) ?? workspaceOfSession(workspaces.items, currentSessionId(sessions, false));
5146
+ return {
5147
+ workspace,
5148
+ path: workspace?.path ?? null
5149
+ };
5150
+ }
5151
+ //#endregion
4176
5152
  //#region src/shared/api/bundle-install.ts
4177
5153
  var BUNDLE_REGISTRIES_ROUTE = "bundle-registries";
4178
5154
  var BUNDLE_INSPECT_ROUTE = "bundle-inspect";
@@ -4202,10 +5178,11 @@ function readInstalledPlugins(force = false) {
4202
5178
  var state = {
4203
5179
  modules: null,
4204
5180
  plugins: null,
5181
+ workbench: null,
4205
5182
  read: false,
4206
5183
  checkedAt: null
4207
5184
  };
4208
- var listeners$1 = /* @__PURE__ */ new Set();
5185
+ var listeners = /* @__PURE__ */ new Set();
4209
5186
  var inFlight = null;
4210
5187
  var readSeq = 0;
4211
5188
  var newestForceSeq = -1;
@@ -4213,14 +5190,14 @@ function moduleVersionsValue() {
4213
5190
  return state;
4214
5191
  }
4215
5192
  function subscribeModuleVersions(listener) {
4216
- listeners$1.add(listener);
5193
+ listeners.add(listener);
4217
5194
  return () => {
4218
- listeners$1.delete(listener);
5195
+ listeners.delete(listener);
4219
5196
  };
4220
5197
  }
4221
5198
  function publish(next) {
4222
5199
  state = next;
4223
- for (const listener of [...listeners$1]) listener();
5200
+ for (const listener of [...listeners]) listener();
4224
5201
  }
4225
5202
  function runModuleVersionsRead(force = false) {
4226
5203
  if (inFlight !== null && inFlight.force === force) return inFlight.promise;
@@ -4233,6 +5210,7 @@ function runModuleVersionsRead(force = false) {
4233
5210
  publish({
4234
5211
  modules: versions?.ok === true ? versions.modules : state.modules,
4235
5212
  plugins: plugins?.ok === true ? plugins.plugins : state.plugins,
5213
+ workbench: versions?.ok === true ? versions.workbench ?? null : state.workbench,
4236
5214
  read: true,
4237
5215
  checkedAt: Date.now()
4238
5216
  });
@@ -4265,6 +5243,7 @@ function useModuleVersions() {
4265
5243
  return {
4266
5244
  modules: value.modules,
4267
5245
  plugins: value.plugins,
5246
+ workbench: value.workbench,
4268
5247
  read: value.read,
4269
5248
  checkedAt: value.checkedAt,
4270
5249
  reload
@@ -4489,7 +5468,9 @@ function AddModulePreview({ t, state }) {
4489
5468
  const preview = state.preview;
4490
5469
  if (preview === null) return null;
4491
5470
  const source = preview.registry === "" ? t("panels.market.add.registryDefault") : preview.registry;
4492
- return /* @__PURE__ */ h("div", { className: AddModule_module_default.body }, /* @__PURE__ */ h("div", { className: AddModule_module_default.subject }, /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectName }, preview.name), preview.version === "" ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, t("panels.market.add.installVersion", { version: preview.version })), preview.description === "" ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectDesc }, preview.description), /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, source)));
5471
+ const plugin = preview.kind === "plugin";
5472
+ const pluginName = plugin ? preview.pluginName : void 0;
5473
+ return /* @__PURE__ */ h("div", { className: AddModule_module_default.body }, /* @__PURE__ */ h("div", { className: AddModule_module_default.subject }, /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectName }, preview.name), preview.version === "" ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, t("panels.market.add.installVersion", { version: preview.version })), pluginName === void 0 || pluginName === preview.name ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, t("panels.market.add.pluginAlias", { name: pluginName })), preview.description === "" ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectDesc }, preview.description), /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, source)), plugin ? /* @__PURE__ */ h("p", { className: AddModule_module_default.result }, t("panels.market.add.pluginPreview")) : null);
4493
5474
  }
4494
5475
  function AddModuleResult({ t, state }) {
4495
5476
  const outcome = state.outcome;
@@ -4497,26 +5478,27 @@ function AddModuleResult({ t, state }) {
4497
5478
  const reason = failureReason(failureCode(outcome.change), outcome.change.application, t);
4498
5479
  const supply = supplyKey(outcome.supply.state);
4499
5480
  const builds = state.builds;
4500
- const failed = outcome.change.application === "failed";
4501
- const restart = outcome.change.application === "restart-required";
4502
- const cancelled = outcome.change.application === "cancelled";
4503
- const notModule = outcome.supply.state === "not-a-module";
4504
5481
  const plugin = outcome.plugin;
5482
+ const kind = resultKindOf({
5483
+ change: outcome.change,
5484
+ supplyState: outcome.supply.state,
5485
+ plugin: plugin !== void 0
5486
+ });
4505
5487
  const name = outcome.module.kind === "module" ? outcome.module.unit : outcome.module.pkg;
4506
5488
  return /* @__PURE__ */ h("div", { className: AddModule_module_default.body }, /* @__PURE__ */ h("div", { className: AddModule_module_default.hero }, /* @__PURE__ */ h("span", {
4507
5489
  className: AddModule_module_default.heroIcon,
4508
- "data-state": failed ? "error" : cancelled ? "idle" : "done",
5490
+ "data-state": kind === "failed" ? "error" : kind === "cancelled" ? "idle" : "done",
4509
5491
  "aria-hidden": "true"
4510
- }, failed ? /* @__PURE__ */ h(IconWarningOutlineRegular, { size: 28 }) : cancelled ? /* @__PURE__ */ h(StateDot, {
5492
+ }, kind === "failed" ? /* @__PURE__ */ h(IconWarningOutlineRegular, { size: 28 }) : kind === "cancelled" ? /* @__PURE__ */ h(StateDot, {
4511
5493
  state: "idle",
4512
5494
  size: 28
4513
5495
  }) : /* @__PURE__ */ h(IconCheckCircleFillRegular, { size: 28 })), /* @__PURE__ */ h("h2", {
4514
5496
  className: AddModule_module_default.wizardTitle,
4515
- role: failed ? "alert" : "status"
4516
- }, 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", {
5497
+ role: kind === "failed" ? "alert" : "status"
5498
+ }, kind === "failed" ? t("panels.market.add.failedTitle") : kind === "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 }))), kind === "plugin" && plugin !== void 0 ? /* @__PURE__ */ h("p", { className: AddModule_module_default.result }, t("panels.market.add.installedPlugin", { name: plugin.name ?? plugin.pkg })) : kind === "failed" ? /* @__PURE__ */ h("p", {
4517
5499
  className: AddModule_module_default.resultWarn,
4518
5500
  role: "alert"
4519
- }, 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)));
5501
+ }, t("panels.market.add.failed", { reason })) : kind === "restart" ? /* @__PURE__ */ h("p", { className: AddModule_module_default.resultWarn }, t("panels.market.add.doneRestart")) : kind === "quiet" ? 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" && (kind === "failed" || kind === "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)));
4520
5502
  }
4521
5503
  //#endregion
4522
5504
  //#region src/app/layouts/market/add-module-mock.ts
@@ -4593,6 +5575,7 @@ var ADD_MODULE_MOCKS = [
4593
5575
  phase: "preview",
4594
5576
  spec: "@dsh-workbench/module-hello",
4595
5577
  preview: {
5578
+ kind: "module",
4596
5579
  name: "@dsh-workbench/module-hello",
4597
5580
  version: "0.1.2",
4598
5581
  description: "最小样本模块:一枚「你好」卡片",
@@ -4600,15 +5583,30 @@ var ADD_MODULE_MOCKS = [
4600
5583
  }
4601
5584
  },
4602
5585
  {
4603
- id: "preview-no-source",
4604
- label: "预览(问不出源)",
5586
+ id: "preview-no-source",
5587
+ label: "预览(问不出源)",
5588
+ phase: "preview",
5589
+ spec: "@dsh-workbench/module-hello",
5590
+ preview: {
5591
+ kind: "module",
5592
+ name: "@dsh-workbench/module-hello",
5593
+ version: "",
5594
+ description: "",
5595
+ registry: ""
5596
+ }
5597
+ },
5598
+ {
5599
+ id: "preview-plugin",
5600
+ label: "预览(opencli 插件)",
4605
5601
  phase: "preview",
4606
- spec: "@dsh-workbench/module-hello",
5602
+ spec: "opencli-plugin-grafana",
4607
5603
  preview: {
4608
- name: "@dsh-workbench/module-hello",
4609
- version: "",
5604
+ kind: "plugin",
5605
+ name: "opencli-plugin-grafana",
5606
+ version: "1.0.16",
4610
5607
  description: "",
4611
- registry: ""
5608
+ registry: "registry.npmmirror.com",
5609
+ pluginName: "grafana"
4612
5610
  }
4613
5611
  },
4614
5612
  {
@@ -4779,42 +5777,6 @@ function stateOfMock(base, mock) {
4779
5777
  };
4780
5778
  }
4781
5779
  //#endregion
4782
- //#region src/shared/hooks/use-visible-busy.ts
4783
- var use_visible_busy_exports = /* @__PURE__ */ __exportAll({
4784
- busyView: () => busyView,
4785
- heldPhase: () => heldPhase,
4786
- useVisibleBusy: () => useVisibleBusy
4787
- });
4788
- function heldPhase(phase, refreshing) {
4789
- return refreshing && phase === "ready" ? "loading" : phase;
4790
- }
4791
- function busyView(active, visible) {
4792
- return {
4793
- busy: visible,
4794
- settling: visible && !active
4795
- };
4796
- }
4797
- function useVisibleBusy(active, floorMs) {
4798
- const [visible, setVisible] = useState(active);
4799
- const since = useRef(null);
4800
- useEffect(() => {
4801
- if (active) {
4802
- if (since.current === null) since.current = Date.now();
4803
- setVisible(true);
4804
- return;
4805
- }
4806
- const held = holdBusy(since.current, Date.now(), floorMs);
4807
- since.current = null;
4808
- if (!held.visible) {
4809
- setVisible(false);
4810
- return;
4811
- }
4812
- const timer = setTimeout(() => setVisible(false), held.releaseInMs);
4813
- return () => clearTimeout(timer);
4814
- }, [active, floorMs]);
4815
- return busyView(active, visible);
4816
- }
4817
- //#endregion
4818
5780
  //#region src/app/layouts/market/use-add-module.ts
4819
5781
  function newRequestId() {
4820
5782
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
@@ -4900,12 +5862,7 @@ function useAddModule(options) {
4900
5862
  setPhase("idle");
4901
5863
  return;
4902
5864
  }
4903
- setPreview({
4904
- name: inspection.name ?? wanted,
4905
- version: inspection.version ?? "",
4906
- description: inspection.description ?? "",
4907
- registry: inspection.registry ?? ""
4908
- });
5865
+ setPreview(previewOf(inspection, wanted));
4909
5866
  setPhase("preview");
4910
5867
  });
4911
5868
  }, [spec, registry]);
@@ -4953,14 +5910,21 @@ function useAddModule(options) {
4953
5910
  requestId: requestIdRef.current
4954
5911
  });
4955
5912
  }, [cancel]);
5913
+ const [removing, setRemoving] = useState(false);
4956
5914
  const removeIt = useCallback(() => {
4957
5915
  const pkg = outcome?.module.pkg;
4958
5916
  if (pkg === void 0) return;
5917
+ setRemoving(true);
5918
+ setFailure(null);
4959
5919
  remove.send({
4960
5920
  action: "remove-bundle",
4961
5921
  name: pkg
4962
5922
  }).then((result) => {
4963
- if (!result.ok) return;
5923
+ setRemoving(false);
5924
+ if (!result.ok) {
5925
+ setFailure(result.message);
5926
+ return;
5927
+ }
4964
5928
  onInstalled();
4965
5929
  });
4966
5930
  }, [
@@ -4987,6 +5951,7 @@ function useAddModule(options) {
4987
5951
  preview,
4988
5952
  outcome,
4989
5953
  failure,
5954
+ removing,
4990
5955
  builds: outcome?.change.pendingBuilds ?? [],
4991
5956
  setSpec,
4992
5957
  setChoice: useCallback((next) => {
@@ -5060,8 +6025,13 @@ function AddModuleDialog({ t, open, onClose, onInstalled }) {
5060
6025
  variant: "outline",
5061
6026
  size: "md",
5062
6027
  className: "wb-dangerAction",
6028
+ disabled: state.removing,
6029
+ "aria-busy": state.removing,
5063
6030
  onClick: state.removeIt
5064
- }, t("panels.market.add.remove")) : null, /* @__PURE__ */ h(Button, {
6031
+ }, state.removing ? /* @__PURE__ */ h(StateDot, {
6032
+ state: "ongoing",
6033
+ size: 12
6034
+ }) : null, t(state.removing ? "panels.market.uninstalling" : "panels.market.add.remove")) : null, /* @__PURE__ */ h(Button, {
5065
6035
  type: "button",
5066
6036
  variant: "outline",
5067
6037
  size: "md",
@@ -5123,12 +6093,17 @@ function useLiveManifests(units) {
5123
6093
  useSyncExternalStore(useCallback((listener) => units.subscribe(listener), [units]), useCallback(() => units.version(), [units]));
5124
6094
  return units.manifests();
5125
6095
  }
6096
+ function useInstallableUnits(units) {
6097
+ useSyncExternalStore(useCallback((listener) => units.subscribe(listener), [units]), useCallback(() => units.version(), [units]));
6098
+ return units.installable();
6099
+ }
5126
6100
  function makeMarketEntryIcon(units) {
5127
6101
  return function MarketEntryIcon({ size = 16 }) {
5128
6102
  const manifests = useLiveManifests(units);
6103
+ const installable = useInstallableUnits(units);
5129
6104
  const { capabilities } = useCapabilityMap(0);
5130
- const { modules } = useModuleVersions();
5131
- const hasUpdates = marketHintVisible(manifests, capabilities, modules);
6105
+ const { modules, workbench } = useModuleVersions();
6106
+ const hasUpdates = marketHintVisible(marketCatalog(manifests, installable), capabilities, modules, workbench);
5132
6107
  useEffect(() => {
5133
6108
  publishPanelHint(MARKET_PANEL_ID, hasUpdates ? { labelKey: "panels.market.hasNew" } : null);
5134
6109
  return () => publishPanelHint(MARKET_PANEL_ID, null);
@@ -5138,9 +6113,13 @@ function makeMarketEntryIcon(units) {
5138
6113
  }
5139
6114
  function MarketPanel({ t, units }) {
5140
6115
  const manifests = useLiveManifests(units);
6116
+ const installable = useInstallableUnits(units);
5141
6117
  const { capabilities, checkedAt, checking, forceProbe, reload: reloadCapability } = useCapabilityMap(0);
5142
- const { modules, plugins, read: installedRead, reload: reloadVersions } = useModuleVersions();
6118
+ const { modules, plugins, workbench, read: installedRead, reload: reloadVersions } = useModuleVersions();
6119
+ const machineBoard = useEnabledUnits(0, null);
5143
6120
  const [adding, setAdding] = useState(false);
6121
+ const [acting, setActing] = useState(false);
6122
+ const openAddModule = useCallback(() => setAdding(true), []);
5144
6123
  const updates = useMemo(() => marketUpdatesOf(modules), [modules]);
5145
6124
  const installed = modules === null ? void 0 : withClientRefusals(modules, units.refusals());
5146
6125
  const reload = useCallback(() => {
@@ -5201,7 +6180,7 @@ function MarketPanel({ t, units }) {
5201
6180
  const mockNonce = fixturePick.nonce;
5202
6181
  const shownFreshness = mock === void 0 ? freshness : mock.loaded === false ? pendingFreshness : MOCK_FRESHNESS;
5203
6182
  const shownRead = mock === void 0 ? installedRead : mock.installedRead ?? true;
5204
- const busy = !marketSettled(shownFreshness, shownRead) || shownFreshness.checking;
6183
+ const busy = !marketSettled(shownFreshness, shownRead) || shownFreshness.checking || acting;
5205
6184
  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", {
5206
6185
  type: "button",
5207
6186
  className: `${MarketPage_module_default.marketIconButton}${shownFreshness.checking ? ` ${MarketPage_module_default.marketIconButtonSpinning}` : ""}`,
@@ -5220,7 +6199,7 @@ function MarketPanel({ t, units }) {
5220
6199
  className: MarketPage_module_default.marketAddButton,
5221
6200
  icon: /* @__PURE__ */ h(IconPlusOutlineRegular, { size: 13 }),
5222
6201
  disabled: busy,
5223
- onClick: () => setAdding(true)
6202
+ onClick: openAddModule
5224
6203
  }, t("panels.market.add.open")))), fixturePick.enabled ? /* @__PURE__ */ h(MockStrip, {
5225
6204
  mocks: marketMocks,
5226
6205
  index: fixturePick.index,
@@ -5229,15 +6208,20 @@ function MarketPanel({ t, units }) {
5229
6208
  key: `${mock?.id ?? "real-market"}-${mockNonce}`,
5230
6209
  t,
5231
6210
  manifests,
6211
+ installable,
5232
6212
  capabilities,
5233
6213
  freshness: shownFreshness,
5234
6214
  onChanged: reload,
6215
+ onPending: setActing,
5235
6216
  updates,
5236
6217
  installed,
5237
6218
  installedRead: shownRead,
6219
+ workbench,
5238
6220
  plugins,
5239
6221
  settling: mock === void 0 ? settling : void 0,
5240
- mock
6222
+ mock,
6223
+ defaults: machineBoard?.defaults ?? [],
6224
+ changed: machineBoard?.changed ?? {}
5241
6225
  }), /* @__PURE__ */ h(AddModuleDialog, {
5242
6226
  t,
5243
6227
  open: adding,
@@ -5262,25 +6246,6 @@ function registerMarketPanel(ctx, units) {
5262
6246
  }, MarketPanel));
5263
6247
  }
5264
6248
  //#endregion
5265
- //#region src/app/layouts/project-selection.ts
5266
- var listeners = /* @__PURE__ */ new Set();
5267
- function selectedProjectId() {
5268
- const stored = readText(STORAGE_KEY_PROJECT);
5269
- return stored === "" ? null : stored;
5270
- }
5271
- function selectProject(workspaceId) {
5272
- writeText(STORAGE_KEY_PROJECT, workspaceId);
5273
- for (const listener of [...listeners]) try {
5274
- listener();
5275
- } catch {}
5276
- }
5277
- function subscribeProject(listener) {
5278
- listeners.add(listener);
5279
- return () => {
5280
- listeners.delete(listener);
5281
- };
5282
- }
5283
- //#endregion
5284
6249
  //#region src/shared/api/diy.ts
5285
6250
  var DIY_PRESET_ID = "workbench-diy";
5286
6251
  var WORKSHOP_TITLE = "工作台DIY";
@@ -5309,7 +6274,7 @@ function createUnitManifestLoader(options = {}) {
5309
6274
  inFlight = true;
5310
6275
  try {
5311
6276
  const response = await apiGet(UNIT_MANIFESTS_ROUTE).catch(() => null);
5312
- if (response?.ok === true && Array.isArray(response.manifests)) registry.setManifests(response.manifests);
6277
+ if (response?.ok === true && Array.isArray(response.manifests)) registry.setManifests(response.manifests, Array.isArray(response.installable) ? response.installable : void 0);
5313
6278
  } finally {
5314
6279
  inFlight = false;
5315
6280
  if (queued) {
@@ -6146,6 +7111,131 @@ function createDshColumnSource(read, intervalMs) {
6146
7111
  }
6147
7112
  };
6148
7113
  }
7114
+ //#endregion
7115
+ //#region src/app/layouts/rightbar/dsh-surface.ts
7116
+ var DSH_SEAT_ATTRIBUTE = "data-sidebar-right-session";
7117
+ function dshSeatOnScreen(host) {
7118
+ if (host === void 0) return false;
7119
+ return host.querySelector(`[${DSH_SEAT_ATTRIBUTE}]`) !== null;
7120
+ }
7121
+ function createDshSurfaceWatch(read, onReady, intervalMs) {
7122
+ let timer;
7123
+ const disarm = () => {
7124
+ if (timer === void 0) return;
7125
+ clearInterval(timer);
7126
+ timer = void 0;
7127
+ };
7128
+ const tick = () => {
7129
+ if (!read()) return;
7130
+ disarm();
7131
+ onReady();
7132
+ };
7133
+ return {
7134
+ arm() {
7135
+ if (timer !== void 0) return;
7136
+ timer = setInterval(tick, intervalMs);
7137
+ },
7138
+ disarm
7139
+ };
7140
+ }
7141
+ //#endregion
7142
+ //#region src/app/layouts/rightbar/dsh-borrow.ts
7143
+ function createDshBorrow(host) {
7144
+ let pendingOpen = false;
7145
+ let pendingCall;
7146
+ let unsubscribe;
7147
+ let restore;
7148
+ let shimmed = false;
7149
+ const flush = () => {
7150
+ const official = host.official();
7151
+ if (official === void 0 || !dshSeatOnScreen(document)) return;
7152
+ if (pendingOpen) {
7153
+ pendingOpen = false;
7154
+ if (!official.isExpanded()) official.toggleExpanded();
7155
+ }
7156
+ const call = pendingCall;
7157
+ pendingCall = void 0;
7158
+ call?.();
7159
+ };
7160
+ const watch = createDshSurfaceWatch(() => dshSeatOnScreen(document), flush, 60);
7161
+ const subscribe = () => {
7162
+ const official = host.official();
7163
+ if (official === void 0 || unsubscribe !== void 0) return;
7164
+ unsubscribe = official.mounted.subscribe(() => {
7165
+ watch.arm();
7166
+ flush();
7167
+ });
7168
+ };
7169
+ const enter = (call) => {
7170
+ const official = host.official();
7171
+ if (official === void 0) return false;
7172
+ if (dshSeatOnScreen(document)) {
7173
+ if (!official.isExpanded()) official.toggleExpanded();
7174
+ call?.();
7175
+ return true;
7176
+ }
7177
+ subscribe();
7178
+ watch.arm();
7179
+ host.yieldColumn();
7180
+ pendingOpen = true;
7181
+ if (call !== void 0) pendingCall = call;
7182
+ return false;
7183
+ };
7184
+ const takeSeat = (call) => {
7185
+ shim();
7186
+ if (host.official() === void 0) return;
7187
+ enter(call);
7188
+ };
7189
+ const shim = () => {
7190
+ const official = host.official();
7191
+ if (official === void 0 || shimmed) return;
7192
+ const { openResource, openTab } = official;
7193
+ if (typeof openResource !== "function" || typeof openTab !== "function") return;
7194
+ shimmed = true;
7195
+ official.openResource = (address, options) => takeSeat(() => openResource.call(official, address, options));
7196
+ official.openTab = (kind, options) => takeSeat(() => openTab.call(official, kind, options));
7197
+ restore = () => {
7198
+ official.openResource = openResource;
7199
+ official.openTab = openTab;
7200
+ shimmed = false;
7201
+ };
7202
+ };
7203
+ return {
7204
+ open() {
7205
+ const official = host.official();
7206
+ if (official === void 0) return false;
7207
+ return official.mounted.getSnapshot() === void 0 || official.isExpanded();
7208
+ },
7209
+ use: takeSeat,
7210
+ toggle() {
7211
+ const official = host.official();
7212
+ if (official === void 0) return;
7213
+ if (!dshSeatOnScreen(document)) {
7214
+ pendingOpen = true;
7215
+ watch.arm();
7216
+ return;
7217
+ }
7218
+ official.toggleExpanded();
7219
+ },
7220
+ back() {
7221
+ pendingOpen = false;
7222
+ pendingCall = void 0;
7223
+ watch.disarm();
7224
+ host.reclaimColumn();
7225
+ },
7226
+ start() {
7227
+ shim();
7228
+ subscribe();
7229
+ },
7230
+ dispose() {
7231
+ unsubscribe?.();
7232
+ unsubscribe = void 0;
7233
+ watch.disarm();
7234
+ restore?.();
7235
+ restore = void 0;
7236
+ }
7237
+ };
7238
+ }
6149
7239
  var Breadcrumbs_module_default = {
6150
7240
  stripTabs: "_stripTabs_1dqp4_1",
6151
7241
  tab: "_tab_1dqp4_9",
@@ -6218,20 +7308,29 @@ function BoardMockStrip({ fixtures, show }) {
6218
7308
  });
6219
7309
  }
6220
7310
  var ModulesPage_module_default = {
6221
- trigger: "_trigger_1weg4_1",
6222
- pop: "_pop_1weg4_7",
6223
- head: "_head_1weg4_21",
6224
- title: "_title_1weg4_29",
6225
- reset: "_reset_1weg4_37",
6226
- list: "_list_1weg4_59",
6227
- row: "_row_1weg4_68",
6228
- rowOver: "_rowOver_1weg4_83",
6229
- ghost: "_ghost_1weg4_93",
6230
- grip: "_grip_1weg4_108",
6231
- label: "_label_1weg4_116",
6232
- name: "_name_1weg4_123",
6233
- error: "_error_1weg4_134",
6234
- dep: "_dep_1weg4_142"
7311
+ trigger: "_trigger_15ptp_1",
7312
+ pop: "_pop_15ptp_6",
7313
+ head: "_head_15ptp_20",
7314
+ title: "_title_15ptp_28",
7315
+ rowControls: "_rowControls_15ptp_36",
7316
+ reset: "_reset_15ptp_43",
7317
+ list: "_list_15ptp_65",
7318
+ row: "_row_15ptp_36",
7319
+ rowDragging: "_rowDragging_15ptp_85",
7320
+ rowBlocked: "_rowBlocked_15ptp_89",
7321
+ listDragging: "_listDragging_15ptp_93",
7322
+ rowOff: "_rowOff_15ptp_101",
7323
+ rowOver: "_rowOver_15ptp_109",
7324
+ ghost: "_ghost_15ptp_119",
7325
+ grip: "_grip_15ptp_134",
7326
+ gripDragging: "_gripDragging_15ptp_144",
7327
+ gripBlocked: "_gripBlocked_15ptp_148",
7328
+ label: "_label_15ptp_152",
7329
+ name: "_name_15ptp_159",
7330
+ error: "_error_15ptp_170",
7331
+ dep: "_dep_15ptp_178",
7332
+ group: "_group_15ptp_186",
7333
+ groupTitle: "_groupTitle_15ptp_191"
6235
7334
  };
6236
7335
  //#endregion
6237
7336
  //#region src/app/layouts/rightbar/panel-mock.ts
@@ -6244,6 +7343,32 @@ function row$1(id, titleKey, shown) {
6244
7343
  hasCard: true
6245
7344
  };
6246
7345
  }
7346
+ function noCardRow(id, titleKey) {
7347
+ return {
7348
+ id,
7349
+ titleKey,
7350
+ shown: false,
7351
+ source: "user",
7352
+ hasCard: false
7353
+ };
7354
+ }
7355
+ function plugin(id, pkg, title, shown) {
7356
+ return {
7357
+ id,
7358
+ pkg,
7359
+ title,
7360
+ shown,
7361
+ source: "user"
7362
+ };
7363
+ }
7364
+ var PLUGIN_MOCK = {
7365
+ id: "plugin",
7366
+ label: "opencli 插件行(标出是插件,能开能关)",
7367
+ units: [],
7368
+ plugins: [plugin("plugin:opencli-plugin-cmdb", "opencli-plugin-cmdb", "cmdb", true), plugin("plugin:opencli-plugin-notes", "opencli-plugin-notes", "notes", false)],
7369
+ capabilities: {},
7370
+ expect: { rows: 0 }
7371
+ };
6247
7372
  function probe(unit, status) {
6248
7373
  return { [unit]: {
6249
7374
  unit,
@@ -6261,7 +7386,7 @@ function buildPanelMocks(roster) {
6261
7386
  units: [],
6262
7387
  capabilities: {},
6263
7388
  expect: { rows: 0 }
6264
- }];
7389
+ }, PLUGIN_MOCK];
6265
7390
  const titleKey = found.card?.titleKey ?? found.id;
6266
7391
  const id = found.id;
6267
7392
  const on = row$1(id, titleKey, true);
@@ -6346,6 +7471,20 @@ function buildPanelMocks(roster) {
6346
7471
  on: true
6347
7472
  }
6348
7473
  },
7474
+ {
7475
+ id: "no-card",
7476
+ label: "没看板的模块(只有基座命令那种):也列出来、带「无看板」标签,开关照常能用,只是不参与排序",
7477
+ units: [on, noCardRow(`${id}-c`, `${titleKey}(无看板)`)],
7478
+ capabilities: {
7479
+ ...probe(id, "ok"),
7480
+ ...probe(`${id}-c`, "ok")
7481
+ },
7482
+ expect: {
7483
+ rows: 2,
7484
+ badge: null,
7485
+ on: true
7486
+ }
7487
+ },
6349
7488
  {
6350
7489
  id: "long",
6351
7490
  label: "超长模块名",
@@ -6396,7 +7535,7 @@ function buildPanelMocks(roster) {
6396
7535
  ...probe(`${id}-c`, "ok")
6397
7536
  },
6398
7537
  drag: {
6399
- from: 2,
7538
+ from: 1,
6400
7539
  over: 0,
6401
7540
  at: {
6402
7541
  x: 1230,
@@ -6407,7 +7546,34 @@ function buildPanelMocks(roster) {
6407
7546
  rows: 3,
6408
7547
  on: true
6409
7548
  }
6410
- }
7549
+ },
7550
+ {
7551
+ id: "drag-off",
7552
+ label: "拖到未开启的那一行上:落点不亮(松手也不动)",
7553
+ units: [
7554
+ on,
7555
+ twin,
7556
+ third
7557
+ ],
7558
+ capabilities: {
7559
+ ...probe(id, "ok"),
7560
+ ...probe(`${id}-b`, "ok"),
7561
+ ...probe(`${id}-c`, "ok")
7562
+ },
7563
+ drag: {
7564
+ from: 0,
7565
+ over: null,
7566
+ at: {
7567
+ x: 1230,
7568
+ y: 300
7569
+ }
7570
+ },
7571
+ expect: {
7572
+ rows: 3,
7573
+ on: true
7574
+ }
7575
+ },
7576
+ PLUGIN_MOCK
6411
7577
  ];
6412
7578
  }
6413
7579
  //#endregion
@@ -6420,6 +7586,22 @@ function available(capability) {
6420
7586
  function selectPanelUnits(units, capabilities) {
6421
7587
  return units.filter((unit) => available(capabilities?.[unit.id]));
6422
7588
  }
7589
+ function panelDropTarget(rows, index) {
7590
+ if (index === null) return null;
7591
+ const row = rows[index];
7592
+ return row?.shown === true && row.hasCard !== false ? index : null;
7593
+ }
7594
+ function rowAtPoint(boxes, y) {
7595
+ const last = boxes.length - 1;
7596
+ for (let at = 0; at <= last; at += 1) {
7597
+ const box = boxes[at];
7598
+ const next = boxes[at + 1];
7599
+ if (box === void 0) continue;
7600
+ const end = next === void 0 ? box.bottom : next.top;
7601
+ if (y >= box.top && (next === void 0 ? y <= end : y < end)) return at;
7602
+ }
7603
+ return null;
7604
+ }
6423
7605
  function panelBadgeKey(capability) {
6424
7606
  if (capability === void 0 || capability.status === "ok") return void 0;
6425
7607
  if (capability.status === "failed") return "panels.dep.failed";
@@ -6427,6 +7609,31 @@ function panelBadgeKey(capability) {
6427
7609
  if (capability.status === "missing-commands") return "panels.dep.missingCommands";
6428
7610
  return "panels.dep.unchecked";
6429
7611
  }
7612
+ function moduleRow(unit, capability) {
7613
+ const badge = panelBadgeKey(capability);
7614
+ return {
7615
+ id: unit.id,
7616
+ titleKey: unit.titleKey,
7617
+ plugin: false,
7618
+ hasCard: unit.hasCard,
7619
+ ...badge === void 0 ? {} : { badgeKey: badge },
7620
+ shown: unit.shown,
7621
+ source: unit.source
7622
+ };
7623
+ }
7624
+ function pluginRow(plugin) {
7625
+ return {
7626
+ id: plugin.id,
7627
+ title: plugin.title,
7628
+ plugin: true,
7629
+ shown: plugin.shown,
7630
+ source: plugin.source
7631
+ };
7632
+ }
7633
+ function selectPanelRows(units, plugins, capabilities) {
7634
+ const listed = new Set(plugins.map((plugin) => plugin.id));
7635
+ return [...selectPanelUnits(units, capabilities).filter((unit) => !listed.has(unit.id)).map((unit) => moduleRow(unit, capabilities?.[unit.id])), ...plugins.map(pluginRow)];
7636
+ }
6430
7637
  function selectBoardModules(units, byId, capabilities) {
6431
7638
  if (units === null) return [];
6432
7639
  return units.filter((unit) => unit.shown && available(capabilities?.[unit.id])).map((unit) => byId(unit.id)).filter((module) => module !== void 0);
@@ -6440,49 +7647,106 @@ function aggregateSummaries(summaries) {
6440
7647
  };
6441
7648
  }
6442
7649
  //#endregion
6443
- //#region src/app/layouts/rightbar/ModulesPage.tsx
6444
- var BLANK_DRAG_IMAGE = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
6445
- function ModulesPage({ t, units, workspace, capabilities, loading = false, onOpenMarket, mocked = false, mock }) {
6446
- const [drag, setDrag] = useState(mock?.drag ?? null);
6447
- const [busy, setBusy] = useState(mock?.busy ?? false);
6448
- const [failed, setFailed] = useState(mock?.failed ?? false);
6449
- const rows = selectPanelUnits(units, capabilities);
6450
- const empty = !loading && rows.length === 0;
6451
- const prefWrite = useHostWrite({
6452
- channel: "prefs",
6453
- resource: "panels",
6454
- networkText: t("panels.failed")
7650
+ //#region src/app/layouts/rightbar/PanelRowControls.tsx
7651
+ function PanelRowControls({ t, unit, label, busy, onWrite }) {
7652
+ return /* @__PURE__ */ h("span", { className: ModulesPage_module_default.rowControls }, /* @__PURE__ */ h(Switch, {
7653
+ checked: unit.shown,
7654
+ label: `${label} · ${unit.shown ? t("panels.enabled") : t("panels.disabled")}`,
7655
+ disabled: busy,
7656
+ onChange: (next) => onWrite({
7657
+ action: next ? "show" : "hide",
7658
+ id: unit.id
7659
+ })
7660
+ }));
7661
+ }
7662
+ //#endregion
7663
+ //#region src/app/layouts/rightbar/PanelGroupRows.tsx
7664
+ function PanelGroupRows({ t, rows, titleKey, busy, onWrite }) {
7665
+ if (rows.length === 0) return null;
7666
+ return /* @__PURE__ */ h("div", { className: ModulesPage_module_default.group }, /* @__PURE__ */ h("h3", { className: ModulesPage_module_default.groupTitle }, t(titleKey)), /* @__PURE__ */ h("ul", { className: ModulesPage_module_default.list }, rows.map((row) => {
7667
+ const title = row.title ?? t(row.titleKey ?? row.id);
7668
+ return /* @__PURE__ */ h("li", {
7669
+ key: row.id,
7670
+ className: `${ModulesPage_module_default.row} ${row.shown ? "" : ModulesPage_module_default.rowOff}`
7671
+ }, /* @__PURE__ */ h("span", { "aria-hidden": "true" }), /* @__PURE__ */ h("span", { className: ModulesPage_module_default.label }, /* @__PURE__ */ h("span", { className: ModulesPage_module_default.name }, title), row.badgeKey === void 0 ? null : /* @__PURE__ */ h("span", { className: ModulesPage_module_default.dep }, t(row.badgeKey))), /* @__PURE__ */ h(PanelRowControls, {
7672
+ t,
7673
+ unit: row,
7674
+ label: title,
7675
+ busy,
7676
+ onWrite
7677
+ }));
7678
+ })));
7679
+ }
7680
+ //#endregion
7681
+ //#region src/app/layouts/rightbar/use-drag-listeners.ts
7682
+ function useDragListeners(active, handlers) {
7683
+ const latestRef = useRef(handlers);
7684
+ useEffect(() => {
7685
+ latestRef.current = handlers;
6455
7686
  });
6456
- const write = async (body) => {
6457
- if (mocked) return;
6458
- setBusy(true);
6459
- setFailed(false);
6460
- const outcome = await prefWrite.send({
6461
- ...body,
6462
- ...workspace === null ? {} : { path: workspace }
6463
- });
6464
- setBusy(false);
6465
- if (!outcome.ok) setFailed(true);
6466
- };
6467
- const drop = () => {
6468
- if (drag === null) return;
6469
- const moved = rows[drag.from];
6470
- setDrag(null);
6471
- if (moved === void 0 || drag.from === drag.over) return;
6472
- write({
6473
- action: "move",
6474
- id: moved.id,
6475
- index: drag.over
6476
- });
6477
- };
6478
- const dragging = drag === null ? void 0 : rows[drag.from];
6479
- return /* @__PURE__ */ h(Fragment, null, drag?.at === void 0 || dragging === void 0 ? null : /* @__PURE__ */ h("div", {
6480
- className: ModulesPage_module_default.ghost,
6481
- style: {
6482
- left: `${drag.at.x + 12}px`,
6483
- top: `${drag.at.y - 12}px`
7687
+ useEffect(() => {
7688
+ if (!active) return;
7689
+ const onMove = (event) => latestRef.current.move(event.clientX, event.clientY);
7690
+ const onUp = (event) => latestRef.current.drop(event.clientY);
7691
+ const onCancel = () => latestRef.current.cancel();
7692
+ window.addEventListener("pointermove", onMove);
7693
+ window.addEventListener("pointerup", onUp);
7694
+ window.addEventListener("pointercancel", onCancel);
7695
+ window.addEventListener("blur", onCancel);
7696
+ return () => {
7697
+ window.removeEventListener("pointermove", onMove);
7698
+ window.removeEventListener("pointerup", onUp);
7699
+ window.removeEventListener("pointercancel", onCancel);
7700
+ window.removeEventListener("blur", onCancel);
7701
+ };
7702
+ }, [active]);
7703
+ }
7704
+ //#endregion
7705
+ //#region src/app/layouts/rightbar/ModulesPage.tsx
7706
+ function rowBoxes(list) {
7707
+ return list === null ? [] : Array.from(list.children).map((item) => item.getBoundingClientRect());
7708
+ }
7709
+ function rowClass(row, index, drag) {
7710
+ const parts = [ModulesPage_module_default.row];
7711
+ if (!row.shown) parts.push(ModulesPage_module_default.rowOff);
7712
+ if (drag !== null) parts.push(row.shown ? ModulesPage_module_default.rowDragging : ModulesPage_module_default.rowBlocked);
7713
+ if (drag?.over === index) parts.push(ModulesPage_module_default.rowOver);
7714
+ return parts.join(" ");
7715
+ }
7716
+ function gripClass(drag) {
7717
+ if (drag === null) return ModulesPage_module_default.grip;
7718
+ return `${ModulesPage_module_default.grip} ${drag.over === null ? ModulesPage_module_default.gripBlocked : ModulesPage_module_default.gripDragging}`;
7719
+ }
7720
+ function RowLabel({ t, row }) {
7721
+ return /* @__PURE__ */ h("span", { className: ModulesPage_module_default.label }, /* @__PURE__ */ h("span", { className: ModulesPage_module_default.name }, t(row.titleKey ?? row.id)), row.badgeKey === void 0 ? null : /* @__PURE__ */ h("span", { className: ModulesPage_module_default.dep }, t(row.badgeKey)));
7722
+ }
7723
+ function PanelRowItem({ t, row, index, drag, handlers, tipEpoch, busy, onWrite }) {
7724
+ return /* @__PURE__ */ h("li", { className: rowClass(row, index, drag) }, row.shown && row.hasCard !== false ? /* @__PURE__ */ h(Tip, {
7725
+ key: tipEpoch,
7726
+ label: t("panels.dragHint"),
7727
+ disabled: drag !== null
7728
+ }, /* @__PURE__ */ h("span", {
7729
+ className: gripClass(drag),
7730
+ "aria-hidden": "true",
7731
+ onPointerDown: (event) => {
7732
+ if (event.button !== 0) return;
7733
+ event.preventDefault();
7734
+ event.currentTarget.setPointerCapture(event.pointerId);
7735
+ handlers.begin(index, event.clientX, event.clientY);
6484
7736
  }
6485
- }, t(dragging.titleKey)), empty ? /* @__PURE__ */ h(CenteredState, {
7737
+ }, "⠿")) : /* @__PURE__ */ h("span", { "aria-hidden": "true" }), /* @__PURE__ */ h(RowLabel, {
7738
+ t,
7739
+ row
7740
+ }), /* @__PURE__ */ h(PanelRowControls, {
7741
+ t,
7742
+ unit: row,
7743
+ label: t(row.titleKey ?? row.id),
7744
+ busy,
7745
+ onWrite
7746
+ }));
7747
+ }
7748
+ function PanelEmpty({ t, onOpenMarket }) {
7749
+ return /* @__PURE__ */ h(CenteredState, {
6486
7750
  compact: true,
6487
7751
  icon: null,
6488
7752
  title: t("panels.noneInstalled"),
@@ -6493,60 +7757,178 @@ function ModulesPage({ t, units, workspace, capabilities, loading = false, onOpe
6493
7757
  variant: "outline",
6494
7758
  onClick: onOpenMarket
6495
7759
  }, t("panels.browseMarket"))
6496
- }) : /* @__PURE__ */ h("ul", { className: ModulesPage_module_default.list }, rows.map((unit, index) => {
6497
- const badge = panelBadgeKey(capabilities?.[unit.id]);
6498
- const dep = badge === void 0 ? void 0 : t(badge);
6499
- return /* @__PURE__ */ h("li", {
6500
- className: `${ModulesPage_module_default.row}${drag?.over === index ? ` ${ModulesPage_module_default.rowOver}` : ""}`,
6501
- key: unit.id,
6502
- draggable: true,
6503
- onDragStart: (event) => {
6504
- const blank = new Image();
6505
- blank.src = BLANK_DRAG_IMAGE;
6506
- event.dataTransfer.setDragImage(blank, 0, 0);
6507
- setDrag({
6508
- from: index,
6509
- over: index,
6510
- at: {
6511
- x: event.clientX,
6512
- y: event.clientY
6513
- }
6514
- });
6515
- },
6516
- onDragOver: (event) => {
6517
- event.preventDefault();
6518
- if (drag !== null) setDrag({
6519
- from: drag.from,
6520
- over: index,
6521
- at: {
6522
- x: event.clientX,
6523
- y: event.clientY
6524
- }
6525
- });
6526
- },
6527
- onDragEnd: drop,
6528
- onDrop: (event) => {
6529
- event.preventDefault();
6530
- drop();
7760
+ });
7761
+ }
7762
+ function DragGhost({ label, at }) {
7763
+ return /* @__PURE__ */ h("div", {
7764
+ className: ModulesPage_module_default.ghost,
7765
+ style: {
7766
+ left: `${at.x + 12}px`,
7767
+ top: `${at.y - 12}px`
7768
+ }
7769
+ }, label);
7770
+ }
7771
+ function ResetConfirmation({ t, open, busy, onCancel, onConfirm }) {
7772
+ const [acknowledged, setAcknowledged] = useState(false);
7773
+ const close = (next) => {
7774
+ setAcknowledged(false);
7775
+ next();
7776
+ };
7777
+ return /* @__PURE__ */ h(RiskConfirmation, {
7778
+ open,
7779
+ title: t("panels.followAllConfirmTitle"),
7780
+ description: t("panels.followAllConfirmDetail"),
7781
+ acknowledgeLabel: t("panels.followAllConfirmAck"),
7782
+ cancelLabel: t("panels.followAllConfirmNo"),
7783
+ closeLabel: t("panels.followAllConfirmNo"),
7784
+ confirmLabel: t("panels.followAllConfirmYes"),
7785
+ acknowledged,
7786
+ disabled: busy,
7787
+ onAcknowledgedChange: setAcknowledged,
7788
+ onCancel: () => close(onCancel),
7789
+ onConfirm: () => close(onConfirm)
7790
+ });
7791
+ }
7792
+ function ModulesPage({ t, units, plugins = [], workspace, capabilities, loading = false, onOpenMarket, mocked = false, mock, own = false }) {
7793
+ const [drag, setDrag] = useState(mock?.drag ?? null);
7794
+ const [tipEpoch, setTipEpoch] = useState(0);
7795
+ const [writing, setWriting] = useState(mock?.busy ?? false);
7796
+ const [failed, setFailed] = useState(mock?.failed ?? false);
7797
+ const [confirmingReset, setConfirmingReset] = useState(false);
7798
+ const listRef = useRef(null);
7799
+ const rows = selectPanelRows(units, plugins, capabilities);
7800
+ const modules = rows.filter((row) => !row.plugin);
7801
+ const carded = modules.filter((row) => row.hasCard !== false);
7802
+ const boardless = modules.filter((row) => row.hasCard === false);
7803
+ const pluginRows = rows.filter((row) => row.plugin);
7804
+ const empty = !loading && rows.length === 0;
7805
+ const settle = useBoardSettle(panelBoardSignature(units, plugins, own));
7806
+ const { busy } = useVisibleBusy(writing || settle.pending, 500);
7807
+ const prefWrite = useHostWrite({
7808
+ channel: "prefs",
7809
+ resource: "panels",
7810
+ networkText: t("panels.failed")
7811
+ });
7812
+ const write = async (body) => {
7813
+ if (mocked) return;
7814
+ setWriting(true);
7815
+ setFailed(false);
7816
+ settle.begin();
7817
+ const outcome = await prefWrite.send({
7818
+ ...body,
7819
+ ...workspace === null ? {} : { path: workspace }
7820
+ });
7821
+ setWriting(false);
7822
+ if (!outcome.ok) {
7823
+ settle.clear();
7824
+ setFailed(true);
7825
+ }
7826
+ };
7827
+ const writeRow = (body) => void write(body);
7828
+ const dropTargetAt = (y) => panelDropTarget(carded, rowAtPoint(rowBoxes(listRef.current), y));
7829
+ const beginDrag = (index, x, y) => {
7830
+ if (carded[index]?.shown !== true) return;
7831
+ setDrag({
7832
+ from: index,
7833
+ over: index,
7834
+ at: {
7835
+ x,
7836
+ y
6531
7837
  }
6532
- }, /* @__PURE__ */ h(Tip, { label: t("panels.dragHint") }, /* @__PURE__ */ h("span", {
6533
- className: ModulesPage_module_default.grip,
6534
- "aria-hidden": "true"
6535
- }, "⠿")), /* @__PURE__ */ h("span", { className: ModulesPage_module_default.label }, /* @__PURE__ */ h("span", { className: ModulesPage_module_default.name }, t(unit.titleKey)), dep === void 0 ? null : /* @__PURE__ */ h("span", { className: ModulesPage_module_default.dep }, dep)), /* @__PURE__ */ h(Switch, {
6536
- checked: unit.shown,
6537
- label: `${t(unit.titleKey)} · ${unit.shown ? t("panels.enabled") : t("panels.disabled")}`,
6538
- disabled: busy,
6539
- onChange: (next) => void write({
6540
- action: next ? "show" : "hide",
6541
- id: unit.id
6542
- })
6543
- }));
6544
- })), /* @__PURE__ */ h(PanelFoot, { text: t("panels.hintEffect") }, /* @__PURE__ */ h("button", {
7838
+ });
7839
+ };
7840
+ const trackDrag = (x, y) => {
7841
+ if (drag === null) return;
7842
+ setDrag({
7843
+ from: drag.from,
7844
+ over: dropTargetAt(y),
7845
+ at: {
7846
+ x,
7847
+ y
7848
+ }
7849
+ });
7850
+ };
7851
+ const settleDrag = (y) => {
7852
+ const from = drag?.from;
7853
+ setDrag(null);
7854
+ setTipEpoch((epoch) => epoch + 1);
7855
+ if (from === void 0) return;
7856
+ const moved = carded[from];
7857
+ const over = dropTargetAt(y);
7858
+ if (moved === void 0 || over === null || over === from) return;
7859
+ write({
7860
+ action: "move",
7861
+ id: moved.id,
7862
+ index: over
7863
+ });
7864
+ };
7865
+ const cancelDrag = () => {
7866
+ setDrag(null);
7867
+ setTipEpoch((epoch) => epoch + 1);
7868
+ };
7869
+ const handlers = {
7870
+ begin: beginDrag,
7871
+ move: trackDrag,
7872
+ drop: settleDrag,
7873
+ cancel: cancelDrag
7874
+ };
7875
+ useDragListeners(drag !== null, handlers);
7876
+ const dragged = drag === null ? void 0 : carded[drag.from];
7877
+ return /* @__PURE__ */ h(Fragment, null, drag?.at === void 0 || dragged === void 0 ? null : /* @__PURE__ */ h(DragGhost, {
7878
+ label: t(dragged.titleKey ?? dragged.id),
7879
+ at: drag.at
7880
+ }), empty ? /* @__PURE__ */ h(PanelEmpty, {
7881
+ t,
7882
+ onOpenMarket
7883
+ }) : null, carded.length === 0 ? null : /* @__PURE__ */ h("ul", {
7884
+ ref: listRef,
7885
+ className: `${ModulesPage_module_default.list}${drag === null ? "" : ` ${ModulesPage_module_default.listDragging}`}`
7886
+ }, carded.map((row, index) => /* @__PURE__ */ h(PanelRowItem, {
7887
+ key: row.id,
7888
+ t,
7889
+ row,
7890
+ index,
7891
+ drag,
7892
+ handlers,
7893
+ tipEpoch,
7894
+ busy,
7895
+ onWrite: writeRow
7896
+ }))), /* @__PURE__ */ h(PanelGroupRows, {
7897
+ t,
7898
+ rows: boardless,
7899
+ titleKey: "panels.groupBoardless",
7900
+ busy,
7901
+ onWrite: writeRow
7902
+ }), /* @__PURE__ */ h(PanelGroupRows, {
7903
+ t,
7904
+ rows: pluginRows,
7905
+ titleKey: "panels.groupPlugins",
7906
+ busy,
7907
+ onWrite: writeRow
7908
+ }), own ? /* @__PURE__ */ h(PanelFoot, null, /* @__PURE__ */ h("button", {
6545
7909
  type: "button",
6546
7910
  className: ModulesPage_module_default.reset,
6547
7911
  disabled: busy,
6548
- onClick: () => void write({ action: "reset" })
6549
- }, t("panels.reset"))), failed ? /* @__PURE__ */ h("p", { className: ModulesPage_module_default.error }, t("panels.failed")) : null);
7912
+ onClick: () => setConfirmingReset(true)
7913
+ }, t("panels.followAll"))) : null, /* @__PURE__ */ h(ResetConfirmation, {
7914
+ t,
7915
+ open: confirmingReset,
7916
+ busy,
7917
+ onCancel: () => setConfirmingReset(false),
7918
+ onConfirm: () => {
7919
+ setConfirmingReset(false);
7920
+ write({ action: "reset" });
7921
+ }
7922
+ }), failed ? /* @__PURE__ */ h("p", { className: ModulesPage_module_default.error }, t("panels.failed")) : null);
7923
+ }
7924
+ //#endregion
7925
+ //#region src/app/layouts/rightbar/panel-dismiss.ts
7926
+ function hasOpenModal(scope) {
7927
+ return scope.querySelector("[aria-modal=\"true\"]") !== null;
7928
+ }
7929
+ function dismissPanelByPointer(next, scope, onOpenChange) {
7930
+ if (!next && hasOpenModal(scope)) return;
7931
+ onOpenChange(next);
6550
7932
  }
6551
7933
  //#endregion
6552
7934
  //#region src/app/layouts/rightbar/PanelModules.tsx
@@ -6577,8 +7959,8 @@ function PanelModules({ t, open, onOpenChange, enabledUnits, workspace, refreshT
6577
7959
  });
6578
7960
  const panelMock = fixturePick.enabled ? fixturePick.current : void 0;
6579
7961
  const mockNonce = fixturePick.nonce;
6580
- useDismissOnOutsidePointer(root, open, onOpenChange);
6581
- const units = enabledUnits ?? [];
7962
+ useDismissOnOutsidePointer(root, open, (next) => dismissPanelByPointer(next, document, onOpenChange));
7963
+ const units = enabledUnits?.units ?? [];
6582
7964
  return /* @__PURE__ */ h("div", {
6583
7965
  className: ModulesPage_module_default.trigger,
6584
7966
  ref: root
@@ -6603,8 +7985,10 @@ function PanelModules({ t, open, onOpenChange, enabledUnits, workspace, refreshT
6603
7985
  key: `${panelMock?.id ?? "real-modules"}-${mockNonce}`,
6604
7986
  t,
6605
7987
  units: panelMock?.units ?? units,
7988
+ plugins: panelMock?.plugins ?? enabledUnits?.plugins ?? [],
6606
7989
  capabilities: panelMock === void 0 ? fixturePick.enabled ? null : capabilities : panelMock.capabilities,
6607
7990
  loading: enabledUnits === null,
7991
+ own: enabledUnits?.own === true,
6608
7992
  onOpenMarket,
6609
7993
  mocked: fixturePick.enabled,
6610
7994
  workspace,
@@ -6781,114 +8165,6 @@ function rightbarPresentation(input) {
6781
8165
  };
6782
8166
  }
6783
8167
  //#endregion
6784
- //#region src/modules/sessions/model/session-node.ts
6785
- function visiblePendingKind(kind) {
6786
- switch (kind) {
6787
- case "approval":
6788
- case "plan-review":
6789
- case "question": return kind;
6790
- default: return;
6791
- }
6792
- }
6793
- function sessionNode(summary, statusById, list, pinnedIds, archivedIds) {
6794
- const status = statusById.get(summary.id);
6795
- const catalog = list.projectionsBySession[summary.id]?.values?.subagentCatalog;
6796
- let runningSubagentCount = 0;
6797
- for (const child of catalog ?? []) {
6798
- const childStatus = statusById.get(child.id);
6799
- const childRow = list.byId[child.id];
6800
- if ((childStatus?.running ?? childRow?.running) === true) runningSubagentCount += 1;
6801
- }
6802
- return {
6803
- id: summary.id,
6804
- title: summary.blank ? "" : summary.displayTitle,
6805
- blank: summary.blank,
6806
- running: status?.running ?? summary.running,
6807
- runningSubagentCount,
6808
- completed: status?.completionUnread === true,
6809
- pinned: !archivedIds.has(summary.id) && pinnedIds.has(summary.id),
6810
- updatedAt: summary.updatedAt,
6811
- pendingInteraction: visiblePendingKind(status?.pendingInteraction?.kind)
6812
- };
6813
- }
6814
- function sessionStatuses(node, t) {
6815
- const subagents = node.runningSubagentCount > 0 ? {
6816
- state: "ongoing",
6817
- label: t(node.runningSubagentCount === 1 ? "status.subagentsRunning.one" : "status.subagentsRunning.other", { n: node.runningSubagentCount })
6818
- } : void 0;
6819
- let pending;
6820
- switch (node.pendingInteraction) {
6821
- case "approval":
6822
- pending = {
6823
- state: "warning",
6824
- label: t("status.waitingApproval")
6825
- };
6826
- break;
6827
- case "plan-review":
6828
- pending = {
6829
- state: "warning",
6830
- label: t("status.planReview")
6831
- };
6832
- break;
6833
- case "question":
6834
- pending = {
6835
- state: "warning",
6836
- label: t("status.waitingAnswer")
6837
- };
6838
- break;
6839
- default: pending = void 0;
6840
- }
6841
- if (pending !== void 0) return subagents === void 0 ? [pending] : [pending, subagents];
6842
- if (node.running) {
6843
- const primary = {
6844
- state: "ongoing",
6845
- label: t("status.running")
6846
- };
6847
- return subagents === void 0 ? [primary] : [primary, subagents];
6848
- }
6849
- if (subagents !== void 0) return [subagents];
6850
- if (node.completed) return [{
6851
- state: "done",
6852
- label: t("status.completed")
6853
- }];
6854
- return [{
6855
- state: "idle",
6856
- label: t("status.idle")
6857
- }];
6858
- }
6859
- function currentSessionId(list, panelActive) {
6860
- if (panelActive) return void 0;
6861
- return Object.values(list.byId).find((session) => (session.retainedBy?.mainView ?? 0) > 0)?.id;
6862
- }
6863
- function orderSessionRows(rows, pinnedIds, archivedIds) {
6864
- const placeholders = [];
6865
- const leading = [];
6866
- const rest = [];
6867
- for (const row of rows) if (row.blank) placeholders.push(row);
6868
- else if (!archivedIds.has(row.id) && pinnedIds.has(row.id)) leading.push(row);
6869
- else rest.push(row);
6870
- return [
6871
- ...placeholders,
6872
- ...leading,
6873
- ...rest
6874
- ];
6875
- }
6876
- function workspaceOfSession(workspaces, sessionId) {
6877
- if (sessionId === void 0) return null;
6878
- return workspaces.find((workspace) => workspace.sessionIds.includes(sessionId)) ?? null;
6879
- }
6880
- function sessionRows(workspaceSessionIds, list, archivedIds, current) {
6881
- const rows = [];
6882
- for (const id of workspaceSessionIds) {
6883
- if (archivedIds.has(id)) continue;
6884
- const row = list.byId[id];
6885
- if (row === void 0 || row.origin === "subagent") continue;
6886
- if (row.blank && row.id !== current) continue;
6887
- rows.push(row);
6888
- }
6889
- return rows;
6890
- }
6891
- //#endregion
6892
8168
  //#region src/app/layouts/rightbar/suite-world.ts
6893
8169
  function createSuiteWorld(input) {
6894
8170
  const sessionId = currentSessionId(input.sessions, false);
@@ -6905,47 +8181,52 @@ function createSuiteWorld(input) {
6905
8181
  };
6906
8182
  }
6907
8183
  //#endregion
6908
- //#region src/app/layouts/rightbar/use-panels.ts
6909
- function shouldDropPanels(workspace, previous) {
6910
- return workspace !== previous;
6911
- }
6912
- function useEnabledUnits(refreshToken, workspace) {
6913
- const [enabled, setEnabled] = useState(null);
6914
- const lastWorkspace = useRef(workspace);
6915
- useEffect(() => {
6916
- let cancelled = false;
6917
- if (shouldDropPanels(workspace, lastWorkspace.current)) {
6918
- lastWorkspace.current = workspace;
6919
- setEnabled(null);
6920
- }
6921
- const read = async () => {
6922
- const response = await apiGet("panels", workspace === null ? {} : { path: workspace }).catch(() => null);
6923
- if (cancelled) return;
6924
- if (response?.ok === true && Array.isArray(response.units)) setEnabled(response.units);
6925
- };
6926
- read();
6927
- return () => {
6928
- cancelled = true;
6929
- };
6930
- }, [
6931
- refreshToken,
6932
- useFactRevision("panels"),
6933
- workspace
6934
- ]);
6935
- return enabled;
6936
- }
6937
- function useSelectedProjectId() {
6938
- const [id, setId] = useState(() => selectedProjectId());
6939
- useEffect(() => subscribeProject(() => setId(selectedProjectId())), []);
6940
- return id;
6941
- }
6942
- function useBoardWorkspace(workspaces, sessions) {
6943
- const projectId = useSelectedProjectId();
6944
- const workspace = workspaces.items.find((item) => item.workspaceId === projectId) ?? workspaceOfSession(workspaces.items, currentSessionId(sessions, false));
6945
- return {
6946
- workspace,
6947
- path: workspace?.path ?? null
6948
- };
8184
+ //#region src/shared/hooks/panel-state-report.ts
8185
+ var FLUSH_MS = 400;
8186
+ var workspace = null;
8187
+ var timer = null;
8188
+ var pending = /* @__PURE__ */ new Map();
8189
+ function unitOfRoute(route) {
8190
+ const cut = route.indexOf("/");
8191
+ return cut <= 0 ? null : route.slice(0, cut);
8192
+ }
8193
+ function setPanelWorkspace(path) {
8194
+ if (path === workspace) return;
8195
+ const previous = workspace;
8196
+ workspace = path;
8197
+ if (previous !== null) pending.clear();
8198
+ }
8199
+ function reportPanelRead(input) {
8200
+ pending.set(`${input.unit}\u0000${input.route}`, {
8201
+ unit: input.unit,
8202
+ route: input.route,
8203
+ phase: input.phase,
8204
+ at: Date.now(),
8205
+ ...input.error === void 0 ? {} : { error: input.error }
8206
+ });
8207
+ if (timer !== null) return;
8208
+ timer = setTimeout(flush, FLUSH_MS);
8209
+ }
8210
+ function reportPanelCrash(input) {
8211
+ const target = workspace;
8212
+ if (target === null) return;
8213
+ apiPost(`${PANEL_STATE_PATH}/crash`, {
8214
+ workspace: target,
8215
+ unit: input.unit,
8216
+ reason: input.reason,
8217
+ at: Date.now()
8218
+ }).catch(() => void 0);
8219
+ }
8220
+ function flush() {
8221
+ timer = null;
8222
+ const target = workspace;
8223
+ const cards = [...pending.values()];
8224
+ pending.clear();
8225
+ if (target === null || cards.length === 0) return;
8226
+ apiPost(`${PANEL_STATE_PATH}/cards`, {
8227
+ workspace: target,
8228
+ cards
8229
+ }).catch(() => void 0);
6949
8230
  }
6950
8231
  var Rightbar_module_default = {
6951
8232
  panel: "_panel_135e7_1",
@@ -7000,7 +8281,7 @@ function PanelHeader({ t, trail, onGoTo, titleKeyOf, refreshing, at, refreshEnab
7000
8281
  onClick: onCollapse
7001
8282
  })))));
7002
8283
  }
7003
- function BoardContent({ top, plan, world, board, twoColumns, panelToken, onPanelRefresh, onNavigate, onOpenMarket, onSummary, onOpenModules, buildModule, t }) {
8284
+ function BoardContent({ top, plan, world, board, twoColumns, panelToken, onPanelRefresh, onNavigate, onOpenMarket, onSummary, onOpenModules, onCardFailure, buildModule, t }) {
7004
8285
  if (top.kind !== "board") {
7005
8286
  const owner = board.stepOwner(top.kind);
7006
8287
  if (owner === void 0) return /* @__PURE__ */ h(CenteredState, {
@@ -7012,7 +8293,8 @@ function BoardContent({ top, plan, world, board, twoColumns, panelToken, onPanel
7012
8293
  key,
7013
8294
  unit: owner.id,
7014
8295
  resetKey: `${key}:${panelToken}:${workspacePathOf(world)}`,
7015
- t
8296
+ t,
8297
+ onFailure: (reason) => onCardFailure(owner.id, reason)
7016
8298
  }, /* @__PURE__ */ h(ModuleHost, {
7017
8299
  module: owner,
7018
8300
  step: top.kind,
@@ -7045,7 +8327,8 @@ function BoardContent({ top, plan, world, board, twoColumns, panelToken, onPanel
7045
8327
  key,
7046
8328
  unit: module.id,
7047
8329
  resetKey: `${key}:${panelToken}:${workspacePathOf(world)}`,
7048
- t
8330
+ t,
8331
+ onFailure: (reason) => onCardFailure(module.id, reason)
7049
8332
  }, /* @__PURE__ */ h(ModuleHost, {
7050
8333
  module,
7051
8334
  world,
@@ -7071,13 +8354,14 @@ function Rightbar(props) {
7071
8354
  const { capabilities } = useCapabilityMap(panelToken);
7072
8355
  const board = useBoardWorkspace(workspaces, sessions);
7073
8356
  const boardWorkspace = board.path;
7074
- const enabledUnits = useEnabledUnits(panelToken, boardWorkspace);
8357
+ const panelBoard = useEnabledUnits(panelToken, boardWorkspace);
8358
+ const enabledUnits = panelBoard?.units ?? null;
7075
8359
  const [modulesOpen, setModulesOpen] = useState(false);
7076
8360
  const fixtures = useBoardMock(fixtureRoster(manifests));
7077
8361
  const visibleModules = selectBoardModules(enabledUnits, (id) => modules.byId(id), capabilities);
7078
8362
  const plan = planBoard(fixtures.shape, {
7079
8363
  modules: visibleModules,
7080
- configRead: enabledUnits !== null
8364
+ configRead: panelBoard !== null
7081
8365
  }, fixtureSeed(manifests, modules.all(), crashModeOn(window.location.search)));
7082
8366
  const world = createSuiteWorld({
7083
8367
  workspaces,
@@ -7094,6 +8378,16 @@ function Rightbar(props) {
7094
8378
  [id]: next
7095
8379
  }));
7096
8380
  }, []);
8381
+ const onCardFailure = useCallback((unit, reason) => {
8382
+ reportPanelCrash({
8383
+ unit,
8384
+ reason
8385
+ });
8386
+ }, []);
8387
+ const fixtureMode = mockModeOn(window.location.search) || crashModeOn(window.location.search);
8388
+ useEffect(() => {
8389
+ setPanelWorkspace(fixtureMode ? null : boardWorkspace);
8390
+ }, [boardWorkspace, fixtureMode]);
7097
8391
  const summary = aggregateSummaries(plan.modules.map((entry) => summaries[entry.module.id]).filter((item) => item !== void 0));
7098
8392
  const feedEnabled = plan.modules.length > 0 || plan.reading;
7099
8393
  const shown = state.expanded;
@@ -7138,7 +8432,7 @@ function Rightbar(props) {
7138
8432
  onRefresh: refreshPanel,
7139
8433
  modulesOpen,
7140
8434
  onModulesOpenChange: setModulesOpen,
7141
- enabledUnits,
8435
+ enabledUnits: panelBoard,
7142
8436
  manifests,
7143
8437
  workspace: boardWorkspace,
7144
8438
  refreshToken: panelToken,
@@ -7159,6 +8453,7 @@ function Rightbar(props) {
7159
8453
  onOpenMarket: openMarket,
7160
8454
  onSummary,
7161
8455
  onOpenModules: () => setModulesOpen(true),
8456
+ onCardFailure,
7162
8457
  buildModule: props.buildModule,
7163
8458
  t: props.t
7164
8459
  })));
@@ -7659,10 +8954,7 @@ function SessionLeading({ node, statuses, renderSlot }) {
7659
8954
  if (node.blank) return null;
7660
8955
  const primary = statuses[0];
7661
8956
  if (primary === void 0 || primary.state === "idle") return /* @__PURE__ */ h(Fragment, null, renderSlot("sidebar.session.row.leading", { sessionId: node.id }));
7662
- return /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(StateDot, {
7663
- state: primary.state,
7664
- size: 10
7665
- }), statuses.map((status) => /* @__PURE__ */ h("span", {
8957
+ return /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(StateDot, { state: primary.state }), statuses.map((status) => /* @__PURE__ */ h("span", {
7666
8958
  className: "wb-visuallyHidden",
7667
8959
  key: status.label
7668
8960
  }, status.label)));
@@ -7737,6 +9029,21 @@ function SessionList({ workspace, pinnedIds, archived, panelActive, useSessions,
7737
9029
  function panelLabel(entry) {
7738
9030
  return typeof entry.label === "function" ? entry.label() : entry.label;
7739
9031
  }
9032
+ function addWorkspace(input) {
9033
+ input.add().catch(() => null).then((path) => {
9034
+ if (path === null || path === "") return;
9035
+ input.onBusy(true);
9036
+ input.onFailed(false);
9037
+ input.create(path).catch(() => void 0).then((view) => {
9038
+ input.onBusy(false);
9039
+ if (view?.workspaceId === void 0) {
9040
+ input.onFailed(true);
9041
+ return;
9042
+ }
9043
+ input.onCreated(view.workspaceId);
9044
+ });
9045
+ });
9046
+ }
7740
9047
  function Sidebar(props) {
7741
9048
  const { collapsed, renderSlot, t, useWorkspaces, usePanelInfo } = props;
7742
9049
  const items = useWorkspaces((state) => state.items);
@@ -7746,6 +9053,8 @@ function Sidebar(props) {
7746
9053
  const sessions = props.useSessions((state) => state);
7747
9054
  const [storedId, setStoredId] = useState(() => selectedProjectId());
7748
9055
  const [panelEntries, setPanelEntries] = useState(() => props.listPanels());
9056
+ const [creating, setCreating] = useState(false);
9057
+ const [createFailed, setCreateFailed] = useState(false);
7749
9058
  useEffect(() => props.subscribePanels(() => setPanelEntries(props.listPanels())), [props]);
7750
9059
  useEffect(() => subscribeProject(() => setStoredId(selectedProjectId())), []);
7751
9060
  const current = items.find((workspace) => workspace.workspaceId === storedId) ?? items[0] ?? null;
@@ -7763,11 +9072,12 @@ function Sidebar(props) {
7763
9072
  });
7764
9073
  };
7765
9074
  const addProject = () => {
7766
- props.pickDirectory().then((path) => {
7767
- if (path === null || path === "") return;
7768
- props.createWorkspace(path).then((view) => {
7769
- if (view?.workspaceId !== void 0) pickProject(view.workspaceId);
7770
- });
9075
+ addWorkspace({
9076
+ add: props.pickDirectory,
9077
+ create: props.createWorkspace,
9078
+ onBusy: setCreating,
9079
+ onFailed: setCreateFailed,
9080
+ onCreated: pickProject
7771
9081
  });
7772
9082
  };
7773
9083
  const wide = !collapsed;
@@ -7798,14 +9108,20 @@ function Sidebar(props) {
7798
9108
  size: isWide ? 16 : 18,
7799
9109
  active
7800
9110
  }, { only: id })
7801
- }))), wide ? /* @__PURE__ */ h(ProjectSwitcher, {
9111
+ }))), wide ? /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(ProjectSwitcher, {
7802
9112
  items,
7803
9113
  current,
7804
9114
  onPick: pickProject,
7805
9115
  onAdd: addProject,
7806
9116
  onRename: props.renameWorkspace,
7807
9117
  t
7808
- }) : null, /* @__PURE__ */ h(WorkspaceSection, {
9118
+ }), creating ? /* @__PURE__ */ h("p", {
9119
+ className: "wb-workspaceBusy",
9120
+ role: "status"
9121
+ }, /* @__PURE__ */ h(StateDot, {
9122
+ state: "ongoing",
9123
+ size: 12
9124
+ }), t("project.add.busy")) : null, createFailed ? /* @__PURE__ */ h("p", { className: "wb-workspaceError" }, t("project.add.failed")) : null) : null, /* @__PURE__ */ h(WorkspaceSection, {
7809
9125
  t,
7810
9126
  wide,
7811
9127
  onNewSession: () => {
@@ -7844,7 +9160,7 @@ var palette_default = ":root {\n --wb-static-titlebar-fill: #ffffff8c;\n --wb-
7844
9160
  var scale_default = ":root {\n --wb-dur-0-12: 0.12s;\n --wb-dur-0-15: 0.15s;\n --wb-dur-0-9: 0.9s;\n --wb-dur-1-4: 1.4s;\n --wb-dur-1-5: 1.5s;\n --wb-font-10: 10px;\n --wb-font-11-5: 11.5px;\n --wb-font-12-5: 12.5px;\n --wb-font-17: 17px;\n --wb-font-18: 18px;\n --wb-font-6: 6px;\n --wb-len-0-5: 0.5px;\n --wb-len-1: 1px;\n --wb-len-10: 10px;\n --wb-len-12: 12px;\n --wb-len-120: 120px;\n --wb-len-13: 13px;\n --wb-len-132: 132px;\n --wb-len-14: 14px;\n --wb-len-144: 144px;\n --wb-len-15: 15px;\n --wb-len-16: 16px;\n --wb-len-18: 18px;\n --wb-len-2: 2px;\n --wb-len-20: 20px;\n --wb-len-200: 200px;\n --wb-len-22: 22px;\n --wb-len-220: 220px;\n --wb-len-24: 24px;\n --wb-len-240: 240px;\n --wb-len-26: 26px;\n --wb-len-260: 260px;\n --wb-len-28: 28px;\n --wb-len-3: 3px;\n --wb-len-3-4em: 3.4em;\n --wb-len-30: 30px;\n --wb-len-300: 300px;\n --wb-len-32: 32px;\n --wb-len-320: 320px;\n --wb-len-34: 34px;\n --wb-len-36: 36px;\n --wb-len-360: 360px;\n --wb-len-38: 38px;\n --wb-len-4: 4px;\n --wb-len-440: 440px;\n --wb-len-40: 40px;\n --wb-len-420: 420px;\n --wb-len-42em: 42em;\n --wb-len-44: 44px;\n --wb-len-48: 48px;\n --wb-len-5: 5px;\n --wb-len-52: 52px;\n --wb-len-520: 520px;\n --wb-len-56: 56px;\n --wb-len-560: 560px;\n --wb-len-6: 6px;\n --wb-len-60: 60px;\n --wb-len-64: 64px;\n --wb-len-7: 7px;\n --wb-len-72: 72px;\n --wb-len-8: 8px;\n --wb-len-800: 800px;\n --wb-len-9: 9px;\n --wb-len-96: 96px;\n --wb-len-960: 960px;\n --wb-len-neg-0-5: -0.5px;\n --wb-len-neg-1-5: -1.5px;\n --wb-len-neg-12: -12px;\n --wb-len-neg-2: -2px;\n --wb-len-neg-3: -3px;\n --wb-len-neg-4: -4px;\n --wb-len-neg-6: -6px;\n --wb-len-neg-8: -8px;\n --wb-line-10: 10px;\n --wb-line-13: 13px;\n --wb-line-14: 14px;\n --wb-line-15: 15px;\n --wb-line-16: 16px;\n --wb-line-17: 17px;\n --wb-line-18: 18px;\n --wb-line-19: 19px;\n --wb-line-20: 20px;\n --wb-line-22: 22px;\n --wb-line-24: 24px;\n --wb-radius-14: 14px;\n --wb-radius-2: 2px;\n --wb-radius-6: 6px;\n --wb-radius-pill: 999px;\n --wb-track-brand: .04em;\n --wb-z-1100: 1100;\n --wb-z-10: 10;\n --wb-z-30: 30;\n --wb-z-40: 40;\n --wb-z-top: 2147483000;\n --wb-project-menu-min-width: 0;\n}\n";
7845
9161
  //#endregion
7846
9162
  //#region src/shared/styles/sidebar-app.css?raw
7847
- var sidebar_app_default = ".wb-wsSection {\n position: relative;\n flex: none;\n --dsh-session-list-edge-inset: var(--dsh-sidebar-inline-padding);\n --dsh-session-list-scrollbar-width: 5px;\n --dsh-session-list-scrollbar-offset: 2px;\n margin: 0 var(--dsh-session-list-scrollbar-offset) var(--wb-len-4) 0;\n padding-right: calc( var(--dsh-session-list-edge-inset) - var(--dsh-session-list-scrollbar-width) - var(--dsh-session-list-scrollbar-offset) );\n}.wb-sectionHeader {\n box-sizing: border-box;\n display: flex;\n justify-content: flex-start;\n align-items: center;\n gap: var(--wb-len-4);\n height: var(--wb-len-36);\n flex: none;\n margin-bottom: var(--wb-len-4);\n padding-left: var(--wb-len-8);\n padding-right: var(--wb-len-2);\n border-radius: var(--dsw-radius-md);\n color: var(--dsw-alias-label-tertiary);\n overflow: hidden;\n}.wb-wsNew {\n margin-left: auto;\n}.wb-sectionLabel {\n flex: none;\n min-width: 0;\n max-width: 45%;\n overflow: hidden;\n white-space: nowrap;\n line-height: var(--wb-line-20);\n}.wb-collapsed .wb-wsSection {\n margin: 0 0 var(--wb-len-12);\n padding-right: 0;\n}.wb-collapsed .wb-sectionHeader {\n justify-content: flex-start;\n gap: 0;\n margin-bottom: 0;\n padding-left: 0;\n padding-right: 0;\n}.wb-collapsed .wb-wsNew {\n margin-left: 0;\n}.wb-project {\n position: relative;\n flex: none;\n margin: 0 var(--wb-len-2) var(--wb-len-4);\n}.wb-projectAnchor {\n display: block;\n width: 100%;\n min-width: var(--wb-project-menu-min-width, 0);\n}.wb-projectButton {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--wb-gap-xs);\n width: 100%;\n height: var(--wb-len-34);\n padding: 0 var(--wb-len-8);\n border: none;\n border-radius: var(--dsw-radius-md);\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n text-align: left;\n cursor: pointer;\n user-select: none;\n}.wb-projectButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}.wb-projectButton:focus-visible {\n outline: var(--dsw-focus-ring-width) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}.wb-collapsed .wb-projectButton {\n justify-content: center;\n width: var(--wb-bar-height);\n height: var(--wb-bar-height);\n padding: 0;\n}.wb-collapsed .wb-projectName,\n.wb-collapsed .wb-projectChevron {\n display: none;\n}.wb-projectGlyph {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n color: var(--dsw-alias-label-tertiary);\n}.wb-projectGlyphActive {\n color: var(--dsw-alias-state-business-primary);\n}.wb-projectName {\n flex: 1;\n min-width: 0;\n font-size: var(--wb-font-row);\n line-height: var(--wb-line-20);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}.wb-projectChevron {\n flex: none;\n display: inline-flex;\n color: var(--dsw-alias-label-caption);\n transition: transform var(--wb-dur-0-15) var(--ds-ease-in-out);\n}.wb-projectChevronOpen {\n transform: rotate(180deg);\n}.wb-sessions {\n --dsh-session-list-edge-inset: var(--dsh-sidebar-inline-padding);\n --dsh-session-list-scrollbar-width: 5px;\n --dsh-session-list-scrollbar-offset: 2px;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n margin-left: var(--wb-len-neg-4);\n margin-right: var(--dsh-session-list-scrollbar-offset);\n padding-left: var(--wb-len-4);\n padding-right: calc( var(--dsh-session-list-edge-inset) - var(--dsh-session-list-scrollbar-width) - var(--dsh-session-list-scrollbar-offset) );\n padding-bottom: var(--wb-len-16);\n scrollbar-gutter: stable;\n --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);\n --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);\n}.wb-sessions > * + * {\n margin-top: var(--wb-len-2);\n}.wb-sessionLeading {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n color: var(--dsw-alias-label-tertiary);\n}.wb-sessionPin {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n margin-left: var(--wb-len-6);\n color: var(--dsw-alias-label-caption);\n}.wb-rowActions {\n flex: none;\n display: none;\n align-items: center;\n gap: var(--wb-len-10);\n}.wb-rowActions .wb-iconButton {\n width: var(--wb-len-24);\n height: var(--wb-len-24);\n}.wb-sessionRow:hover .wb-rowActions,\n.wb-sessionRow.wb-menuOpen .wb-rowActions {\n display: inline-flex;\n}.wb-sessionRow:hover .wb-sessionTime,\n.wb-sessionRow.wb-menuOpen .wb-sessionTime,\n.wb-sessionRow:hover .wb-sessionPin,\n.wb-sessionRow.wb-menuOpen .wb-sessionPin {\n display: none;\n}.wb-sessionRow.wb-menuOpen {\n background: var(--dsw-alias-interactive-bg-hover);\n}.wb-rowMenu {\n left: auto;\n right: 0;\n min-width: var(--wb-len-144);\n max-width: var(--wb-len-260);\n}.wb-sessionRow {\n position: relative;\n flex: none;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: 0;\n width: 100%;\n height: var(--wb-len-32);\n padding: 0 var(--wb-len-8);\n border: none;\n border-radius: var(--dsw-radius-md);\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n text-align: left;\n cursor: pointer;\n user-select: none;\n}.wb-sessionRow:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}.wb-sessionRow:focus-visible {\n outline: var(--dsw-focus-ring-width) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}.wb-visuallyHidden {\n clip: rect(0 0 0 0);\n white-space: nowrap;\n width: var(--wb-len-1);\n height: var(--wb-len-1);\n position: absolute;\n overflow: hidden;\n}.wb-sessionTitle {\n flex: 1;\n min-width: 0;\n margin: 0 var(--wb-len-6) 0 var(--wb-len-4);\n font-size: var(--wb-font-row);\n line-height: var(--wb-line-20);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}.wb-sessionTime {\n flex: none;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}.wb-empty {\n padding: var(--wb-len-16) var(--wb-len-12);\n font-size: var(--dsw-font-xs-13-font-size);\n color: var(--dsw-alias-label-tertiary);\n}@media (prefers-reduced-motion: reduce) {\n .wb-projectChevron {\n transition: none;\n }}.wb-sessionRow.wb-selected {\n background: var(--dsw-alias-interactive-bg-hover);\n}.wb-panelTag {\n flex: none;\n margin-left: auto;\n}.wb-panelGlyph {\n position: relative;\n}.wb-panelDot {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n top: var(--wb-len-neg-3);\n right: var(--wb-len-neg-3);\n}button.pXSMma_workspace {\n display: none;\n}";
9163
+ var sidebar_app_default = ".wb-wsSection {\n position: relative;\n flex: none;\n --dsh-session-list-edge-inset: var(--dsh-sidebar-inline-padding);\n --dsh-session-list-scrollbar-width: 5px;\n --dsh-session-list-scrollbar-offset: 2px;\n margin: 0 var(--dsh-session-list-scrollbar-offset) var(--wb-len-4) 0;\n padding-right: calc( var(--dsh-session-list-edge-inset) - var(--dsh-session-list-scrollbar-width) - var(--dsh-session-list-scrollbar-offset) );\n}.wb-sectionHeader {\n box-sizing: border-box;\n display: flex;\n justify-content: flex-start;\n align-items: center;\n gap: var(--wb-len-4);\n height: var(--wb-len-36);\n flex: none;\n margin-bottom: var(--wb-len-4);\n padding-left: var(--wb-len-8);\n padding-right: var(--wb-len-2);\n border-radius: var(--dsw-radius-md);\n color: var(--dsw-alias-label-tertiary);\n overflow: hidden;\n}.wb-wsNew {\n margin-left: auto;\n}.wb-sectionLabel {\n flex: none;\n min-width: 0;\n max-width: 45%;\n overflow: hidden;\n white-space: nowrap;\n line-height: var(--wb-line-20);\n}.wb-collapsed .wb-wsSection {\n margin: 0 0 var(--wb-len-12);\n padding-right: 0;\n}.wb-collapsed .wb-sectionHeader {\n justify-content: flex-start;\n gap: 0;\n margin-bottom: 0;\n padding-left: 0;\n padding-right: 0;\n}.wb-collapsed .wb-wsNew {\n margin-left: 0;\n}.wb-project {\n position: relative;\n flex: none;\n margin: 0 var(--wb-len-2) var(--wb-len-4);\n}.wb-projectAnchor {\n display: block;\n width: 100%;\n min-width: var(--wb-project-menu-min-width, 0);\n}.wb-projectButton {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--wb-gap-xs);\n width: 100%;\n height: var(--wb-len-34);\n padding: 0 var(--wb-len-8);\n border: none;\n border-radius: var(--dsw-radius-md);\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n text-align: left;\n cursor: pointer;\n user-select: none;\n}.wb-projectButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}.wb-projectButton:focus-visible {\n outline: var(--dsw-focus-ring-width) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}.wb-collapsed .wb-projectButton {\n justify-content: center;\n width: var(--wb-bar-height);\n height: var(--wb-bar-height);\n padding: 0;\n}.wb-collapsed .wb-projectName,\n.wb-collapsed .wb-projectChevron {\n display: none;\n}.wb-projectGlyph {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n color: var(--dsw-alias-label-tertiary);\n}.wb-projectGlyphActive {\n color: var(--dsw-alias-state-business-primary);\n}.wb-projectName {\n flex: 1;\n min-width: 0;\n font-size: var(--wb-font-row);\n line-height: var(--wb-line-20);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}.wb-projectChevron {\n flex: none;\n display: inline-flex;\n color: var(--dsw-alias-label-caption);\n transition: transform var(--wb-dur-0-15) var(--ds-ease-in-out);\n}.wb-projectChevronOpen {\n transform: rotate(180deg);\n}.wb-sessions {\n --dsh-session-list-edge-inset: var(--dsh-sidebar-inline-padding);\n --dsh-session-list-scrollbar-width: 5px;\n --dsh-session-list-scrollbar-offset: 2px;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n margin-left: var(--wb-len-neg-4);\n margin-right: var(--dsh-session-list-scrollbar-offset);\n padding-left: var(--wb-len-4);\n padding-right: calc( var(--dsh-session-list-edge-inset) - var(--dsh-session-list-scrollbar-width) - var(--dsh-session-list-scrollbar-offset) );\n padding-bottom: var(--wb-len-16);\n scrollbar-gutter: stable;\n --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);\n --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);\n}.wb-sessions > * + * {\n margin-top: var(--wb-len-2);\n}.wb-sessionLeading {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n color: var(--dsw-alias-label-tertiary);\n}.wb-sessionPin {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n margin-left: var(--wb-len-6);\n color: var(--dsw-alias-label-caption);\n}.wb-rowActions {\n flex: none;\n display: none;\n align-items: center;\n gap: var(--wb-len-10);\n}.wb-rowActions .wb-iconButton {\n width: var(--wb-len-24);\n height: var(--wb-len-24);\n}.wb-sessionRow:hover .wb-rowActions,\n.wb-sessionRow.wb-menuOpen .wb-rowActions {\n display: inline-flex;\n}.wb-sessionRow:hover .wb-sessionTime,\n.wb-sessionRow.wb-menuOpen .wb-sessionTime,\n.wb-sessionRow:hover .wb-sessionPin,\n.wb-sessionRow.wb-menuOpen .wb-sessionPin {\n display: none;\n}.wb-sessionRow.wb-menuOpen {\n background: var(--dsw-alias-interactive-bg-hover);\n}.wb-rowMenu {\n left: auto;\n right: 0;\n min-width: var(--wb-len-144);\n max-width: var(--wb-len-260);\n}.wb-sessionRow {\n position: relative;\n flex: none;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: 0;\n width: 100%;\n height: var(--wb-len-32);\n padding: 0 var(--wb-len-8);\n border: none;\n border-radius: var(--dsw-radius-md);\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n text-align: left;\n cursor: pointer;\n user-select: none;\n}.wb-sessionRow:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}.wb-sessionRow:focus-visible {\n outline: var(--dsw-focus-ring-width) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}.wb-visuallyHidden {\n clip: rect(0 0 0 0);\n white-space: nowrap;\n width: var(--wb-len-1);\n height: var(--wb-len-1);\n position: absolute;\n overflow: hidden;\n}.wb-sessionTitle {\n flex: 1;\n min-width: 0;\n margin: 0 var(--wb-len-6) 0 var(--wb-len-4);\n font-size: var(--wb-font-row);\n line-height: var(--wb-line-20);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}.wb-sessionTime {\n flex: none;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}.wb-workspaceBusy {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin: var(--wb-len-4) var(--wb-len-8) 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}.wb-workspaceError {\n margin: var(--wb-len-4) var(--wb-len-8) 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-state-error-primary);\n}.wb-empty {\n padding: var(--wb-len-16) var(--wb-len-12);\n font-size: var(--dsw-font-xs-13-font-size);\n color: var(--dsw-alias-label-tertiary);\n}@media (prefers-reduced-motion: reduce) {\n .wb-projectChevron {\n transition: none;\n }}.wb-sessionRow.wb-selected {\n background: var(--dsw-alias-interactive-bg-hover);\n}.wb-panelTag {\n flex: none;\n margin-left: auto;\n}.wb-panelGlyph {\n position: relative;\n}.wb-panelDot {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n top: var(--wb-len-neg-3);\n right: var(--wb-len-neg-3);\n}button.pXSMma_workspace {\n display: none;\n}";
7848
9164
  //#endregion
7849
9165
  //#region src/shared/styles/sidebar.css?raw
7850
9166
  var sidebar_default = ".wb-root{--dsh-sidebar-inline-padding:12px;height:100%;padding:var(--wb-len-6) var(--dsh-sidebar-inline-padding);box-sizing:border-box;background:var(--dsw-specific-sidebar-fill);color:var(--dsw-alias-label-primary);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);flex-direction:column;font-size:var(--dsw-font-s-14-font-size);display:flex}[data-platform=darwin] .wb-root{background:0 0}.wb-root.wb-collapsed{padding:var(--wb-len-18) var(--wb-len-10) var(--wb-len-6)}[data-windows-titlebar] .wb-root .wb-logoRow{height:var(--wb-len-40);margin:0;padding:0}[data-windows-titlebar] .wb-toggle{top:calc((var(--dsh-windows-titlebar-height) - var(--wb-len-28)) / 2);z-index:var(--wb-z-30);-webkit-app-region:no-drag;position:fixed;left:var(--wb-len-12)}[data-windows-titlebar] .wb-root.wb-collapsed .wb-logoRow{height:0}[data-windows-titlebar] .wb-root:not(.wb-collapsed) .wb-brand{padding-left:var(--wb-len-4)}[data-windows-titlebar] .wb-brandIdentity{transform:translateY(1px)}[data-windows-titlebar] .wb-brandMark{transform:translate(1px)}[data-windows-titlebar] .wb-brandName{font-weight:400}[data-windows-titlebar] .wb-root.wb-collapsed{padding:0}[data-windows-titlebar] .wb-root:not(.wb-collapsed) .wb-newSession{margin-top:var(--wb-len-8);margin-left:0}[data-windows-titlebar] .wb-collapsed .wb-panelList,[data-windows-titlebar] .wb-collapsed .wb-regionArea,[data-windows-titlebar] .wb-collapsed .wb-footArea{display:none}html[data-windows-titlebar]:has([data-sidebar-collapsed=true]){--dsh-windows-menu-start:84px}[data-windows-titlebar] .wb-collapsed .wb-newSession{top:calc((var(--dsh-windows-titlebar-height) - var(--wb-len-28)) / 2);z-index:var(--wb-z-30);-webkit-app-region:no-drag;border:none;margin:0;padding:0;position:fixed;left:var(--wb-len-48)}[data-windows-titlebar] .wb-railIn .wb-iconButton,[data-windows-titlebar] .wb-railIn .wb-newSession{animation:none}[data-windows-titlebar] .wb-collapsed .wb-toggle,[data-windows-titlebar] .wb-collapsed .wb-newSession{corner-shape:round;width:var(--wb-len-28);height:var(--wb-len-28);color:var(--dsw-alias-label-secondary);border-radius:50%}[data-windows-titlebar] .wb-collapsed .wb-toggle .wb-panelIcon{display:inline-flex}.wb-root.wb-quietBars{--dsh-scrollbar-thumb:transparent;--dsh-scrollbar-thumb-hover:transparent}.wb-fading>*{opacity:0;transition:opacity var(--wb-dur-0-15) var(--ds-ease-in-out)}.wb-wide{animation:wb-wide-in var(--ds-transition-duration) var(--ds-ease-in-out)}@keyframes wb-wide-in{0%{opacity:0}}.wb-railIn .wb-iconButton,.wb-railIn .wb-newSession,.wb-railIn .wb-panelList,.wb-railIn .wb-regionArea{animation:wb-rail-in var(--wb-dur-0-15) var(--ds-ease-in-out) backwards}.wb-railIn .wb-footArea{animation:wb-rail-fade-in var(--wb-dur-0-15) var(--ds-ease-in-out) backwards}@keyframes wb-rail-in{0%{opacity:0;transform:translate(49px)}}@keyframes wb-rail-fade-in{0%{opacity:0}}.wb-topStrip{box-sizing:border-box;height:var(--wb-len-52);margin:var(--wb-len-neg-6) calc(-1 * var(--dsh-sidebar-inline-padding)) 0;flex:none;justify-content:flex-end;align-items:center;padding:0 var(--wb-len-12) var(--wb-len-2);display:flex}[data-fullscreen] .wb-topStrip{justify-content:flex-start}.wb-topStrip+.wb-logoRow{margin-top:var(--wb-len-neg-12)}.wb-logoRow{box-sizing:border-box;flex:none;justify-content:flex-end;align-items:center;gap:var(--wb-len-8);height:var(--wb-len-60);margin-bottom:var(--wb-len-4);padding:var(--wb-len-8) 0 var(--wb-len-8) var(--wb-len-4);display:flex;overflow:hidden}.wb-collapsed .wb-logoRow{justify-content:flex-start;height:var(--wb-len-36);margin-bottom:var(--wb-len-12);padding:0;overflow:visible}.wb-brand{min-width:0;color:inherit;cursor:pointer;background:0 0;border:none;flex:1;align-items:center;padding:0;display:inline-flex;overflow:hidden}[data-platform=darwin] .wb-brand{cursor:default}.wb-brandIdentity{align-items:center;gap:var(--wb-len-8);min-width:0;height:var(--wb-len-24);display:inline-flex}.wb-brandMark{flex:none;justify-content:center;align-items:center;display:inline-flex}.wb-brandName{letter-spacing:var(--wb-track-brand);align-items:center;gap:var(--wb-len-6);min-width:0;height:var(--wb-len-24);font-size:var(--wb-font-18);font-weight:600;line-height:var(--wb-line-24);display:inline-flex}.wb-fallbackBrandName{letter-spacing:0;white-space:nowrap;font-size:var(--wb-font-17)}.wb-localBuildBrand{white-space:nowrap;flex-direction:column;flex:none;justify-content:center;align-items:flex-start;gap:var(--wb-len-1);height:var(--wb-len-24);display:inline-flex}.wb-localBuildTitle{letter-spacing:0;font-size:var(--dsw-font-xxs-12-font-size);line-height:var(--wb-line-13)}.wb-panelIcon{display:inline-flex;align-items:center;justify-content:center}.wb-iconButton{border-radius:var(--dsw-radius-sm);cursor:pointer;width:var(--wb-len-28);height:var(--wb-len-28);color:var(--dsw-alias-label-secondary);background:0 0;border:none;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex;position:relative}.wb-iconButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.wb-iconButton.wb-toggle:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:-2px}.wb-collapsed .wb-iconButton{border-radius:var(--dsw-radius-md);width:var(--wb-len-36);height:var(--wb-len-36)}.wb-collapsed .wb-toggle .wb-panelIcon{display:none}.wb-collapsed .wb-toggle:hover .wb-panelIcon{display:inline}.wb-collapsed .wb-toggle:hover .wb-railMark{display:none}.wb-railMark{justify-content:center;align-items:center;display:inline-flex}.wb-collapsed .wb-iconButton{color:var(--dsw-alias-label-primary)}.wb-buildVersion{height:var(--wb-len-10);color:var(--dsw-alias-label-primary-inverted);background:var(--dsw-alias-label-primary);font-family:var(--ds-font-family-code);white-space:nowrap;border-radius:var(--wb-radius-2);flex:none;align-items:center;padding:0 var(--wb-len-3);font-size:var(--wb-font-6);font-weight:500;line-height:var(--wb-line-10);display:inline-flex}.wb-newSession{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-button-elevated-fill);height:var(--wb-len-38);color:var(--dsw-alias-label-primary);cursor:pointer;flex:none;justify-content:center;align-items:center;gap:0;margin:0 var(--wb-len-2) var(--wb-len-12);padding:var(--wb-len-8) var(--wb-len-12);font-size:var(--dsw-font-s-14-font-size);font-weight:500;line-height:var(--wb-line-22);display:flex;position:relative;overflow:hidden;container-type:inline-size}.wb-newSession:hover{background:var(--dsw-alias-button-floating-hover)}[data-platform=darwin] .wb-newSession{background:var(--wb-static-titlebar-fill)}[data-platform=darwin] .wb-newSession:hover{background:var(--wb-static-titlebar-fill-hover)}[data-platform=darwin] [data-ds-dark-theme] .wb-newSession{background:var(--wb-static-titlebar-fill-dark)}[data-platform=darwin] [data-ds-dark-theme] .wb-newSession:hover{background:var(--wb-static-titlebar-fill-dark-hover)}.wb-collapsed .wb-newSession{background:0 0;border-color:transparent;align-self:flex-start;gap:0;width:var(--wb-len-36);height:var(--wb-len-36);margin:0 0 var(--wb-len-12);padding:0}.wb-collapsed .wb-newSession:hover{background:var(--dsw-alias-interactive-bg-hover)}.wb-newSessionLabel{white-space:nowrap;max-width:var(--wb-len-200);overflow:hidden}.wb-collapsed .wb-newSessionLabel{max-width:0}.wb-newSessionLabelMask{flex:1;min-width:0}.wb-newSession:is(:hover,:focus-visible) .wb-newSessionLabelMask:has(+.wb-newSessionShortcut){overflow:hidden;mask-image:linear-gradient(90deg,var(--wb-static-mask-opaque) calc(100% - var(--wb-len-16)),transparent)}.wb-newSessionContent{justify-content:center;align-items:center;gap:var(--wb-len-6);width:100cqw;display:flex}.wb-newSessionContent>svg{flex:none}.wb-newSessionShortcut{opacity:0;pointer-events:none;flex:none;font-weight:400;display:inline-flex}.wb-newSession:is(:hover,:focus-visible) .wb-newSessionShortcut{opacity:1}.wb-panelList{flex-direction:column;flex:none;gap:var(--wb-len-4);margin-bottom:var(--wb-len-8);display:flex}.wb-panelRow{box-sizing:border-box;border-radius:var(--dsw-radius-md);min-height:var(--wb-len-36);color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;align-items:center;gap:var(--wb-len-8);margin:0 var(--wb-len-2);padding:var(--wb-len-7) var(--wb-len-8);line-height:var(--wb-line-22);display:flex}.wb-panelRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.wb-panelRow.wb-panelActive{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.wb-panelRow:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:-2px}.wb-panelGlyph{flex:none;justify-content:center;align-items:center;display:inline-flex}.wb-panelTitle{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.wb-collapsed .wb-panelList{gap:var(--wb-len-12);margin-bottom:var(--wb-len-12)}.wb-collapsed .wb-panelRow{width:var(--wb-len-36);height:var(--wb-len-36);color:var(--dsw-alias-label-primary);justify-content:center;margin:0;padding:0}.wb-regionArea{min-height:0;margin-left:var(--wb-len-neg-4);margin-right:calc(-1 * var(--dsh-sidebar-inline-padding));flex-direction:column;flex:1;padding-left:var(--wb-len-4);display:flex;overflow:hidden}.wb-collapsed .wb-regionArea{margin-left:0;margin-right:0;padding-left:0}.wb-footArea{flex-direction:column;flex:none;display:flex}.wb-settingsArea,.wb-footerActions{flex:none;width:100%;min-width:0}.wb-footerActions{display:flex}.wb-collapsed .wb-footArea{align-items:center}.wb-collapsed .wb-settingsArea,.wb-collapsed .wb-footerActions{justify-content:center;width:auto;display:flex}@media (prefers-reduced-motion:reduce){.wb-wide,.wb-fading>*,.wb-railIn .wb-iconButton,.wb-railIn .wb-newSession,.wb-railIn .wb-panelList,.wb-railIn .wb-footArea,.wb-railIn .wb-regionArea{transition:none;animation:none}}\n";
@@ -7931,6 +9247,12 @@ function useApiResource(route, query, refreshToken, options = {}) {
7931
9247
  ...prev.at === void 0 ? {} : { at: prev.at }
7932
9248
  } : { phase: "loading" });
7933
9249
  const flight = requestResource(route, queryRef.current, key);
9250
+ const owner = unitOfRoute(route);
9251
+ if (owner !== null) reportPanelRead({
9252
+ unit: owner,
9253
+ route,
9254
+ phase: "loading"
9255
+ });
7934
9256
  flight.task.then((response) => {
7935
9257
  if (cancelled) return;
7936
9258
  if (response.ok) {
@@ -7939,19 +9261,43 @@ function useApiResource(route, query, refreshToken, options = {}) {
7939
9261
  value: response,
7940
9262
  at: Date.now()
7941
9263
  });
9264
+ if (owner !== null) reportPanelRead({
9265
+ unit: owner,
9266
+ route,
9267
+ phase: "ready"
9268
+ });
7942
9269
  return;
7943
9270
  }
7944
9271
  setState({
7945
9272
  phase: "error",
7946
9273
  error: response.error
7947
9274
  });
9275
+ if (owner !== null) reportPanelRead({
9276
+ unit: owner,
9277
+ route,
9278
+ phase: "error",
9279
+ error: {
9280
+ code: response.error.code,
9281
+ message: response.error.message
9282
+ }
9283
+ });
7948
9284
  }).catch((reason) => {
7949
9285
  if (cancelled) return;
9286
+ const message = reason instanceof Error ? reason.message : String(reason);
7950
9287
  setState({
7951
9288
  phase: "error",
7952
9289
  error: {
7953
9290
  code: "network",
7954
- message: reason instanceof Error ? reason.message : String(reason)
9291
+ message
9292
+ }
9293
+ });
9294
+ if (owner !== null) reportPanelRead({
9295
+ unit: owner,
9296
+ route,
9297
+ phase: "error",
9298
+ error: {
9299
+ code: "network",
9300
+ message
7955
9301
  }
7956
9302
  });
7957
9303
  });
@@ -8220,7 +9566,7 @@ function messagesOf(units) {
8220
9566
  ...face.messages === void 0 ? {} : { messages: face.messages }
8221
9567
  }));
8222
9568
  }
8223
- var COMPONENT_CSS_MARKER = "\n.wb-activityBlock {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n padding-top: var(--wb-len-10);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.wb-activityBlock:first-child {\n border-top: none;\n}\n\n.wb-activityBlockHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-8);\n}\n\n.wb-activityLine {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-activityLineText {\n flex: none;\n min-width: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n max-height: var(--wb-len-72);\n overflow-y: auto;\n}\n\n.wb-activityLineAt {\n flex: none;\n margin-left: auto;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-16);\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-activityLine > .wb-activityLineAt,\n.wb-activityLine > .wb-activityLineActions {\n margin-left: auto;\n}\n\n.wb-activityLine > .wb-activityLineAt + .wb-activityLineActions {\n margin-left: 0;\n}\n\n.wb-activityLineActions {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n}\n\n.wb-activityActionFailed {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-note {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-problem {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n.wb-approvalCommand {\n max-width: 100%;\n}\n.wb-approvalPlan {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n}\n.wb-approvalHint {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n.wb-approvalRows {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n margin: 0;\n}\n.wb-approvalRow {\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-8);\n}\n.wb-approvalLabel {\n flex: none;\n width: var(--wb-len-56);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-approvalValue {\n margin: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n overflow-wrap: anywhere;\n}\n.wb-approvalWarn {\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-cardHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n flex: none;\n padding: var(--wb-len-8) var(--wb-len-10) var(--wb-len-8) var(--wb-len-20);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.wb-cardTitle {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n font-weight: 600;\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-cardMeta {\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wb-cardMeta::before {\n content: '\\00b7';\n margin-right: var(--wb-len-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardOpen {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n margin-left: auto;\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-4);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardOpen ~ .wb-cardRefresh {\n margin-left: 0;\n}\n\n.wb-cardOpen:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-cardRefresh {\n margin-left: auto;\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-4);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardRefresh:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-cardRefresh:disabled {\n cursor: default;\n opacity: 1;\n}\n\n.wb-cardGear {\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-3);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardGear:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-cardRefresh.wb-spinning svg {\n animation: wb-spin var(--wb-dur-0-9) linear infinite;\n}\n\n.wb-card {\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-xl);\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n flex: none;\n}\n.wb-cardBody {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n padding: var(--wb-len-12);\n}\n.wb-cardBody > :not([data-wb-bleed]) {\n padding-left: var(--wb-len-8);\n padding-right: var(--wb-len-8);\n}\n\n.wb-choiceMenu {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n padding: var(--wb-len-4);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n background: transparent;\n}\n\n.wb-choiceOption {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-height: var(--wb-len-30);\n padding: var(--wb-len-6) var(--wb-len-8);\n border-radius: var(--dsw-radius-md);\n cursor: pointer;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-choiceOptionOn {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.wb-checkbox {\n position: absolute;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n margin: 0;\n opacity: 0;\n pointer-events: none;\n}\n\n.wb-checkboxBox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n flex: none;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n border: 1px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-xs);\n corner-shape: round;\n color: var(--dsw-alias-label-primary-foreground);\n transition:\n background-color var(--wb-dur-0-12) ease, border-color var(--wb-dur-0-12) ease;\n}\n\n.wb-choiceOption:hover .wb-checkboxBox {\n border-color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-checkbox:checked + .wb-checkboxBox {\n border-color: var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n}\n\n.wb-checkbox:disabled + .wb-checkboxBox {\n opacity: 0.5;\n}\n\n.wb-checkbox:focus-visible + .wb-checkboxBox {\n outline: var(--dsw-focus-ring-width, var(--wb-len-2)) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n\n.wb-choiceOption:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.wb-choiceLabel {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wb-radio {\n appearance: none;\n -webkit-appearance: none;\n flex: none;\n box-sizing: border-box;\n width: var(--wb-len-12);\n height: var(--wb-len-12);\n margin: 0;\n border: 1px solid var(--dsw-alias-border-l3);\n border-radius: 50%;\n corner-shape: round;\n background-color: transparent;\n cursor: pointer;\n transition:\n background-color var(--wb-dur-0-12) ease, border-color var(--wb-dur-0-12) ease;\n}\n\n.wb-radio:not(:checked):hover {\n border-color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-radio:checked {\n border-color: var(--dsw-alias-brand-primary);\n background-image: radial-gradient(\n circle at center,\n var(--dsw-alias-brand-primary) 0 3px,\n transparent 3px\n );\n}\n\n.wb-radio:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n.wb-radio:focus-visible {\n outline: var(--dsw-focus-ring-width, var(--wb-len-2)) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}:where(.wb-link) {\n margin-left: var(--wb-len-2);\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-2);\n font: inherit;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n text-decoration: none;\n white-space: nowrap;\n vertical-align: baseline;\n}\n\n:where(.wb-link:hover) {\n text-decoration: underline;\n}\n\n:where(.wb-link:focus-visible) {\n outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}\n\n.wb-longTask {\n padding-top: var(--wb-len-12);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n.wb-longTaskHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin: 0;\n}\n\n.wb-longTaskLink {\n flex: none;\n}\n\n.wb-longTaskHeadline {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-longTaskProblem {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n.wb-longTaskDump {\n margin: var(--wb-len-2) 0 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-longTaskDump pre {\n margin: var(--wb-len-4) 0 0;\n max-height: var(--wb-len-220);\n overflow: auto;\n}\n.wb-mockStrip {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wb-len-4);\n padding: var(--wb-len-8) var(--wb-len-12);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n flex: none;\n}\n\n.wb-mockNote {\n flex: 1 0 100%;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-14);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-mockChip {\n flex: none;\n padding: var(--wb-len-2) var(--wb-len-7);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--wb-radius-pill);\n corner-shape: round;\n background: transparent;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-14);\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n.wb-mockChip:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-mockChipOn {\n border-color: transparent;\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-label-primary-foreground);\n}\n.wb-centered.wb-centeredCompact {\n flex: none;\n min-height: 0;\n gap: var(--wb-len-8);\n padding: var(--wb-len-20) var(--wb-len-16);\n}\n\n.wb-centered.wb-centeredCompact .wb-centeredHero {\n margin-bottom: var(--wb-len-4);\n}\n\n.wb-skeleton {\n display: flex;\n flex-direction: column;\n}\n\n.wb-skeletonRow {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n padding: var(--wb-len-8);\n border-radius: var(--dsw-radius-md);\n}\n\n.wb-skeletonRow + .wb-skeletonRow::before {\n content: '';\n align-self: stretch;\n height: var(--wb-len-0-5);\n margin: 0 var(--wb-len-8) var(--wb-len-neg-0-5);\n background: var(--dsw-alias-border-l2);\n}\n\n.wb-skeletonBar {\n display: block;\n height: var(--wb-len-13);\n border-radius: var(--dsw-radius-xs);\n background: var(--dsw-alias-bg-skeleton);\n animation: wb-skeleton-pulse var(--wb-dur-1-4) var(--ds-ease-in-out) infinite;\n}\n\n.wb-skeletonBarTitle {\n width: 62%;\n}\n\n.wb-skeletonBarMeta {\n width: 32%;\n height: var(--wb-len-10);\n}\n\n.wb-skeletonRow:nth-child(2n) .wb-skeletonBarTitle {\n width: 74%;\n}\n\n.wb-skeletonRow:nth-child(3n) .wb-skeletonBarTitle {\n width: 52%;\n}\n\n@keyframes wb-skeleton-pulse {\n 50% {\n opacity: 0.45;\n }\n}\n\n.wb-centered {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n gap: var(--wb-len-14);\n flex: 1;\n min-height: var(--wb-len-240);\n padding: 0 var(--wb-len-24) var(--wb-len-24);\n text-align: center;\n}\n\n.wb-centeredHero {\n display: flex;\n margin-bottom: var(--wb-len-16);\n color: var(--dsw-alias-label-dimmed);\n}\n\n.wb-centeredTitle {\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-centeredHint {\n max-width: var(--wb-len-300);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-centeredDetail {\n max-width: var(--wb-len-320);\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-dimmed);\n word-break: break-all;\n}\n\n.wb-centeredAction {\n display: flex;\n justify-content: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-2);\n}\n@media (prefers-reduced-motion: reduce) {\n .wb-skeletonBar {\n animation: none;\n }}\n\n.wb-row:has(> [data-wb-dot]) {\n grid-template-columns: 84px minmax(0, 1fr);\n}\n.wb-rows {\n display: flex;\n flex-direction: column;\n}\n.wb-row {\n display: grid;\n grid-template-columns: 56px minmax(0, 1fr);\n align-items: baseline;\n gap: var(--wb-len-8);\n padding: var(--wb-len-4) 0;\n}\n.wb-row + .wb-row {\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n.wb-rowKey {\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-rowValue {\n min-width: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n overflow-wrap: anywhere;\n}\n\n.wb-formActions {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--wb-len-8);\n}\n.wb-settings {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n padding: var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-1);\n}\n.wb-settingsHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n}\n.wb-settingsTitle {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-stack {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-10);\n min-height: 0;\n}\n\n.wb-stateBlock {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n}\n.wb-stateBlockTitle {\n margin: 0;\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n}\n.wb-stateBlockHint {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-stateBlockActions {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-2);\n}\n.wb-stateBlockResolving {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n.wb-textField {\n box-sizing: border-box;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.wb-textField:focus {\n border-color: var(--dsw-alias-state-business-primary);\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-business-primary);\n}\n\n.wb-textField[aria-invalid='true'] {\n border-color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-textField[aria-invalid='true']:focus {\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-error-primary);\n}\n\n:where(.wb-textField) {\n min-height: var(--wb-len-32);\n padding: var(--wb-len-6) var(--wb-len-12);\n}\n.wb-field {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xs-13-font-size);\n}\n\n.wb-fieldLabel {\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-fieldHint {\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n._marketList_z6vtq_1 {\n list-style: none;\n margin: 0;\n padding: var(--wb-len-6);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n._marketRow_z6vtq_10 {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n align-items: center;\n column-gap: var(--wb-len-14);\n row-gap: var(--wb-len-4);\n padding: var(--wb-len-8);\n border-radius: var(--dsw-radius-lg);\n}\n\n._marketIcon_z6vtq_20 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-40);\n height: var(--wb-len-40);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketMain_z6vtq_32 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n min-width: 0;\n}\n\n._marketName_z6vtq_39 {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n._marketDesc_z6vtq_48 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketUsedBy_z6vtq_59 {\n margin-left: var(--wb-len-8);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n opacity: 0.75;\n}\n\n._marketUsedBy_z6vtq_59::before {\n content: '·';\n margin-right: var(--wb-len-6);\n opacity: 0.8;\n}\n\n._marketName_z6vtq_39 ._marketVersion_z6vtq_73 {\n margin-left: var(--wb-len-6);\n font-size: var(--dsw-font-xxs-12-font-size);\n font-weight: 400;\n line-height: var(--wb-line-18);\n}\n\n._marketVersion_z6vtq_73 {\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-caption);\n}\n\n._marketVersion_z6vtq_73::before {\n content: '';\n display: inline-block;\n width: var(--wb-len-1);\n height: var(--wb-len-10);\n margin: 0 var(--wb-len-8) 0 var(--wb-len-2);\n vertical-align: -1px;\n background: var(--dsw-alias-border-l2);\n}\n\n._marketEnd_z6vtq_95 {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n}\n\n._marketActions_z6vtq_102 {\n flex: none;\n display: flex;\n gap: var(--wb-len-6);\n}\n\n._marketSection_z6vtq_108 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n min-width: 0;\n}\n\n._marketSectionHead_z6vtq_115 {\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-8);\n}\n\n._marketSectionTitle_z6vtq_121 {\n margin: 0;\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n._marketSectionCount_z6vtq_127 {\n font: var(--dsw-font-s-14);\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-caption);\n}\n\n._marketProgress_z6vtq_133 {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-8);\n min-height: var(--wb-len-32);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketNote_z6vtq_143 {\n grid-column: 2 / -1;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-state-warn-primary);\n overflow-wrap: anywhere;\n}\n\n._marketFailure_z6vtq_150 {\n grid-column: 2 / -1;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._marketEmpty_z6vtq_157 {\n padding: var(--wb-len-18) var(--wb-len-16);\n text-align: center;\n}\n\n._marketPage_z6vtq_162 {\n box-sizing: border-box;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-32);\n padding: 0 clamp(var(--wb-len-24), 4vw, var(--wb-len-48)) var(--wb-len-48);\n overflow-x: hidden;\n overflow-y: auto;\n color: var(--dsw-alias-label-primary);\n}\n\n._marketPage_z6vtq_162 > * {\n width: 100%;\n max-width: var(--wb-len-960);\n}\n\n._marketPageHead_z6vtq_180 {\n box-sizing: border-box;\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-16);\n padding-top: var(--wb-len-28);\n}\n\n._marketPageTitle_z6vtq_188 {\n margin: 0;\n font: var(--dsw-font-l-20);\n}\n\n._marketPageIntro_z6vtq_193 {\n margin: var(--wb-len-4) 0 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketPageTools_z6vtq_199 {\n flex: none;\n align-self: center;\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: var(--wb-len-16);\n}\n\n._marketIconButton_z6vtq_208 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-28);\n height: var(--wb-len-28);\n padding: 0;\n border: 0;\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n color: var(--dsw-alias-label-caption);\n cursor: pointer;\n}\n\n._marketIconButton_z6vtq_208:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketIconButton_z6vtq_208:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n._marketIconWrap_z6vtq_233 {\n display: inline-flex;\n}\n\n._marketIconButtonSpinning_z6vtq_237 svg {\n animation: _wb-spin_z6vtq_1 var(--wb-dur-0-9) linear infinite;\n}\n\n._marketAddButton_z6vtq_241 {\n height: var(--wb-len-32);\n padding: 0 var(--wb-len-12);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n border-radius: var(--dsw-radius-md);\n}\n\n._marketEmpty_z6vtq_157 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-64) var(--wb-len-16);\n text-align: center;\n}\n\n._marketChecking_z6vtq_258 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketEmptyTitle_z6vtq_266 {\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n@keyframes _wb-spin_z6vtq_1 {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n._foot_1us83_1 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-8) var(--wb-len-14) var(--wb-len-10);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._footText_1us83_12 {\n flex: 1;\n min-width: 0;\n}\n\n._footTextMd_1us83_17 {\n flex: 1;\n min-width: 0;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n._wide_1coeb_1 {\n justify-content: center;\n width: 100%;\n height: var(--wb-len-40);\n border-radius: var(--dsw-radius-md);\n}\n\n._dialog_1coeb_8 {\n width: min(var(--wb-len-560), 100%);\n max-height: min(var(--wb-len-800), 100%);\n}\n\n._content_1coeb_13 {\n min-height: 0;\n overflow: auto;\n}\n\n._stack_1coeb_18 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n\n._body_1coeb_25 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n\n._field_1coeb_32 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xs-13-font-size);\n}\n\n._input_1coeb_39 {\n width: 100%;\n height: var(--wb-len-40);\n padding: 0 var(--wb-len-14);\n}\n\n._registryField_1coeb_45 {\n height: var(--wb-len-32);\n margin-left: var(--wb-len-26);\n padding: 0 var(--wb-len-10);\n}\n\n._options_1coeb_51 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-8) var(--wb-len-12);\n}\n\n._guideToggle_1coeb_59 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-4);\n align-self: flex-start;\n margin-top: var(--wb-len-4);\n padding: 0;\n border: 0;\n background: transparent;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n._guideToggle_1coeb_59:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n._guideToggle_1coeb_59 svg,\n._registryToggle_1coeb_78 svg {\n transition: transform var(--wb-dur-0-12) ease;\n}\n\n._guideToggle_1coeb_59[aria-expanded='true'] svg,\n._registryToggle_1coeb_78[aria-expanded='true'] svg {\n transform: rotate(180deg);\n}\n\n._registryWrap_1coeb_87 {\n position: relative;\n flex: none;\n}\n\n._registryToggle_1coeb_78 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n height: var(--wb-len-26);\n padding: 0 var(--wb-len-8) 0 var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-2);\n font: inherit;\n font-size: var(--wb-font-12-5);\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n._registryToggle_1coeb_78:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n._registryToggle_1coeb_78:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n._registryToggle_1coeb_78[aria-expanded='true'] {\n border-color: var(--dsw-alias-border-l3);\n background: var(--dsw-alias-bg-layer-3);\n}\n\n._registryChosen_1coeb_121 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n._registry_1coeb_45 {\n position: fixed;\n z-index: var(--wb-z-1100);\n box-sizing: border-box;\n width: min(var(--wb-len-440), 100vw - var(--wb-len-24));\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10) var(--wb-len-12);\n border: 0;\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-alias-bg-layer-2);\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l3);\n box-shadow: var(--dsw-elevation-prominent);\n}\n\n._registryOption_1coeb_143 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n padding: var(--wb-len-8) var(--wb-len-10);\n border: 0.5px solid transparent;\n border-radius: var(--dsw-radius-lg);\n cursor: pointer;\n}\n\nlabel._registryOption_1coeb_143 {\n flex-direction: row;\n align-items: flex-start;\n gap: var(--wb-len-10);\n}\n\n._registryPick_1coeb_159 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-10);\n cursor: pointer;\n}\n\n._registryOption_1coeb_143[data-checked='true'] {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 40%, transparent);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._registryOption_1coeb_143 input[type='radio'] {\n flex: none;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n margin: var(--wb-len-2) 0 0;\n accent-color: var(--dsw-alias-brand-primary);\n}\n\n._registryTitle_1coeb_179 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wb-len-8);\n font: var(--dsw-font-xs-13);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-primary);\n}\n\n._registryHint_1coeb_189 {\n margin-left: var(--wb-len-26);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n overflow-wrap: anywhere;\n}\n\n._inputError_1coeb_197 {\n margin: var(--wb-len-neg-4) 0 0 var(--wb-len-26);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-state-error-primary);\n}\n\n._guide_1coeb_59 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) var(--wb-len-14) var(--wb-len-14);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._guideList_1coeb_214 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n._guideItem_1coeb_223 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) 0;\n}\n\n._guideIndex_1coeb_230 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-20);\n height: var(--wb-len-20);\n border-radius: var(--wb-radius-pill);\n corner-shape: round;\n background: var(--dsw-alias-bg-module-platform);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._guideMain_1coeb_244 {\n display: flex;\n flex-direction: column;\n flex: 1;\n gap: 0;\n min-width: 0;\n}\n\n._guideTitle_1coeb_252 {\n font: var(--dsw-font-s-14);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n._guideHint_1coeb_258 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-caption);\n}\n\n._guideExample_1coeb_264 {\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._guideExample_1coeb_264 code {\n font-family: var(--dsw-font-mono, monospace);\n}\n\n._guideExampleLabel_1coeb_274 {\n color: var(--dsw-alias-label-caption);\n}\n\n._footer_1coeb_278 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-20);\n width: 100%;\n}\n\n._hero_1coeb_285 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) 0 var(--wb-len-4);\n text-align: center;\n}\n\n._heroIcon_1coeb_294 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-44);\n height: var(--wb-len-44);\n color: var(--dsw-alias-label-secondary);\n}\n\n._heroIcon_1coeb_294[data-state='done'] {\n color: var(--dsw-alias-state-success-secondary);\n}\n\n._heroIcon_1coeb_294[data-state='error'] {\n color: var(--dsw-alias-state-warn-label);\n}\n\n._pendingTitle_1coeb_311 {\n margin: 0;\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n._wizardTitle_1coeb_319 {\n margin: 0;\n font-size: var(--wb-font-18);\n line-height: var(--wb-len-26);\n font-weight: 600;\n}\n\n._subject_1coeb_326 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-6);\n padding: var(--wb-len-16);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-lg);\n text-align: center;\n}\n\n._subjectName_1coeb_337 {\n margin: 0;\n font: var(--dsw-font-base-strong-16);\n overflow-wrap: anywhere;\n}\n\n._subjectMeta_1coeb_343,\n._subjectDesc_1coeb_344 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._result_1coeb_351,\n._resultWarn_1coeb_352 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-12);\n border-radius: var(--dsw-radius-md);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-primary);\n}\n\n._resultWarn_1coeb_352 {\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent);\n}\n\n._approval_1coeb_365 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n padding: var(--wb-len-12) var(--wb-len-14);\n border: 0.5px solid var(--dsw-alias-state-warn-primary);\n border-radius: var(--dsw-radius-lg);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 8%, transparent);\n}\n\n._approvalTitle_1coeb_375 {\n margin: 0;\n font: var(--dsw-font-s-14);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._approvalText_1coeb_382 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._approvalCaution_1coeb_388 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n font-weight: 600;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._note_1coeb_395 {\n margin: 0;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._noteWarn_1coeb_402 {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._noteError_1coeb_406 {\n color: var(--dsw-alias-state-error-primary);\n}\n\n._problem_1coeb_410 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._detailLabel_1coeb_417 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-caption);\n}\n\n._detail_1coeb_417 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l1);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-3);\n font-family: var(--dsw-font-mono, monospace);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n._note_1enlz_1 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-8);\n margin: 0;\n padding: var(--wb-len-10) var(--wb-len-12);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-state-warn-tertiary);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n\n._note_1enlz_1 > svg {\n flex: none;\n margin-top: var(--wb-len-2);\n color: var(--dsw-alias-state-warn-primary);\n}\n._actions_jlw8j_1[hidden],\n._progress_jlw8j_2[hidden],\n._commandRow_jlw8j_3[hidden],\n._bridge_jlw8j_4[hidden],\n._raw_jlw8j_5[hidden] {\n display: none;\n}\n\n._gate_jlw8j_9 {\n position: fixed;\n inset: 0;\n z-index: var(--wb-z-top);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--wb-len-24);\n background: var(--dsw-alias-bg-base);\n}\n\n._card_jlw8j_20 {\n width: 100%;\n max-width: var(--wb-len-420);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-16);\n text-align: center;\n}\n\n._card_jlw8j_20:has(._actions_jlw8j_1:not([hidden])),\n._card_jlw8j_20:has(._bridge_jlw8j_4:not([hidden])) {\n max-width: var(--wb-len-520);\n}\n\n._title_jlw8j_35 {\n margin: 0;\n font-size: var(--dsw-font-base-16-font-size);\n line-height: var(--wb-line-24);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._hint_jlw8j_43 {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._steps_jlw8j_50 {\n list-style: none;\n margin: var(--wb-len-6) 0 0;\n padding: 0;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n text-align: left;\n}\n\n._step_jlw8j_50 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-6) var(--wb-len-10);\n border-radius: var(--dsw-radius-sm);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._step_jlw8j_50[data-status='running'] {\n color: var(--dsw-alias-label-primary);\n}\n\n._mark_jlw8j_77 {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-14);\n height: var(--wb-len-14);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n font-variant-numeric: tabular-nums;\n}\n\n._step_jlw8j_50[data-status='ok'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-success-primary);\n}\n\n._step_jlw8j_50[data-status='warn'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._step_jlw8j_50[data-status='failed'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-error-primary);\n}\n\n._label_jlw8j_102 {\n flex: none;\n}\n\n._detail_jlw8j_106 {\n margin-left: auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._progress_jlw8j_2 {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-4);\n max-width: 100%;\n}\n\n._elapsed_jlw8j_124 {\n flex: none;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n font-variant-numeric: tabular-nums;\n}\n\n._error_jlw8j_132 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n max-height: var(--wb-len-120);\n overflow: auto;\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n white-space: pre-wrap;\n word-break: break-all;\n text-align: left;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._commandRow_jlw8j_3 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-4);\n margin: 0 0 var(--wb-len-8);\n padding-right: var(--wb-len-4);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._copy_jlw8j_158 {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-24);\n height: var(--wb-len-24);\n padding: 0;\n border: none;\n border-radius: var(--wb-radius-6);\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._copy_jlw8j_158:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._command_jlw8j_3 {\n flex: 1;\n min-width: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n overflow-wrap: anywhere;\n color: var(--dsw-alias-label-primary);\n}\n\n._buttons_jlw8j_191 {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--wb-len-12);\n}\n\n._mockSlot_jlw8j_198 {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n justify-content: center;\n background: var(--dsw-alias-bg-base);\n}\n\n._button_jlw8j_191 {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: var(--wb-len-28);\n padding: 0 var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n font: inherit;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n\n._button_jlw8j_191:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._button_jlw8j_191:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n._actions_jlw8j_1,\n._bridge_jlw8j_4 {\n box-sizing: border-box;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--wb-len-10);\n margin-top: var(--wb-len-4);\n padding: var(--wb-len-14) var(--wb-len-16);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--wb-radius-14);\n background: var(--dsw-alias-bg-layer-1);\n text-align: left;\n}\n\n._fixTitle_jlw8j_249 {\n margin: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._actions_jlw8j_1 ._hint_jlw8j_43,\n._bridge_jlw8j_4 ._hint_jlw8j_43 {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-19);\n color: var(--dsw-alias-label-secondary);\n}\n\n._actions_jlw8j_1 ._commandRow_jlw8j_3,\n._bridge_jlw8j_4 ._commandRow_jlw8j_3 {\n margin: 0;\n}\n\n._actions_jlw8j_1 ._buttons_jlw8j_191,\n._bridge_jlw8j_4 ._buttons_jlw8j_191 {\n justify-content: flex-start;\n}\n\n._raw_jlw8j_5 {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._rawSummary_jlw8j_282 {\n cursor: pointer;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._actions_jlw8j_1 ._error_jlw8j_132,\n._bridge_jlw8j_4 ._error_jlw8j_132 {\n margin-top: var(--wb-len-6);\n}\n\n._bridgeLines_jlw8j_292 {\n margin: 0;\n padding-left: var(--wb-len-18);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-19);\n color: var(--dsw-alias-label-secondary);\n}\n\n._bridgeLine_jlw8j_292 a {\n display: block;\n margin-top: var(--wb-len-4);\n width: fit-content;\n}\n\n._link_jlw8j_309 {\n color: var(--dsw-alias-label-primary);\n text-decoration: none;\n}\n\n._link_jlw8j_309::after {\n content: '↗';\n margin-left: var(--wb-len-2);\n}\n\n._link_jlw8j_309:hover {\n text-decoration: underline;\n}\n\n._loading_jlw8j_323 {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._loading_jlw8j_323[hidden] {\n display: none;\n}\n\n._loadingMotion_jlw8j_332 {\n transform-origin: center;\n animation: _wb-spin_jlw8j_1 var(--wb-dur-1-5) linear infinite;\n}\n\n._loadingTrack_jlw8j_337,\n._loadingArc_jlw8j_338 {\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n}\n\n._loadingTrack_jlw8j_337 {\n opacity: 0.25;\n}\n\n._loadingArc_jlw8j_338 {\n stroke-dasharray: 12 150;\n animation: _wb-dash_jlw8j_1 var(--wb-dur-1-5) ease-in-out infinite;\n}\n\n@keyframes _wb-spin_jlw8j_1 {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes _wb-dash_jlw8j_1 {\n 0% {\n stroke-dasharray: 12 150;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 24 150;\n stroke-dashoffset: -6;\n }\n to {\n stroke-dasharray: 12 150;\n stroke-dashoffset: 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n ._loadingMotion_jlw8j_332,\n ._loadingArc_jlw8j_338 {\n animation: none;\n }\n}\n._group_1hxis_1 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-2);\n}\n\n._button_1hxis_7 {\n flex: none;\n width: var(--wb-len-28);\n height: var(--wb-len-28);\n padding: 0;\n color: var(--dsw-alias-label-secondary);\n}\n\n._button_1hxis_7:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n._active_1hxis_19 {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._icon_1hxis_23 {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n._icon_1hxis_23 svg {\n display: block;\n width: var(--wb-len-15);\n height: var(--wb-len-15);\n}\n\n._mirror_1hxis_35 {\n transform: scaleX(-1);\n}\n._stripTabs_1dqp4_1 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-4);\n min-width: 0;\n overflow: hidden;\n}\n\n._tab_1dqp4_9 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n flex: none;\n height: var(--wb-len-28);\n padding: 0 var(--wb-len-10);\n border: 0;\n border-radius: var(--dsw-radius-sm);\n background: none;\n font: inherit;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-16);\n max-width: 100%;\n}\n\n._tabActive_1dqp4_25 {\n color: var(--dsw-alias-label-primary);\n}\n\n._tabQuiet_1dqp4_29 {\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._tabQuiet_1dqp4_29:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._tabTitle_1dqp4_39 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._sep_1dqp4_49 {\n flex: none;\n color: var(--dsw-alias-label-dimmed);\n}\n._trigger_1weg4_1 {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n._pop_1weg4_7 {\n position: absolute;\n top: calc(100% + var(--wb-len-8));\n right: 0;\n z-index: var(--wb-z-30);\n width: var(--wb-len-360);\n max-width: calc(100vw - var(--wb-len-48));\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--wb-radius-14);\n background: var(--dsw-alias-bg-layer-2);\n box-shadow: var(--dsw-shadow-lv3);\n overflow: hidden;\n}\n\n._head_1weg4_21 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-10) var(--wb-len-12) var(--wb-len-9) var(--wb-len-14);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n._title_1weg4_29 {\n flex: 1;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._reset_1weg4_37 {\n flex: none;\n padding: var(--wb-len-3) var(--wb-len-8);\n border: none;\n border-radius: var(--wb-radius-6);\n background: transparent;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._reset_1weg4_37:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._reset_1weg4_37:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n._list_1weg4_59 {\n list-style: none;\n margin: 0;\n padding: var(--wb-len-6);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n._row_1weg4_68 {\n position: relative;\n display: grid;\n grid-template-columns: 12px minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-7) var(--wb-len-8);\n border-radius: var(--dsw-radius-sm);\n cursor: grab;\n}\n\n._row_1weg4_68:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._rowOver_1weg4_83::before {\n content: '';\n position: absolute;\n top: var(--wb-len-neg-3);\n left: var(--wb-len-8);\n right: var(--wb-len-8);\n height: var(--wb-len-2);\n background: var(--dsw-alias-brand-primary);\n}\n\n._ghost_1weg4_93 {\n position: fixed;\n z-index: var(--wb-z-40);\n pointer-events: none;\n padding: var(--wb-len-4) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n box-shadow: var(--wb-static-shadow-ghost);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n white-space: nowrap;\n}\n\n._grip_1weg4_108 {\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n text-align: center;\n color: var(--dsw-alias-label-tertiary);\n user-select: none;\n}\n\n._label_1weg4_116 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n}\n\n._name_1weg4_123 {\n min-width: 0;\n flex: 0 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n}\n\n._error_1weg4_134 {\n margin: 0;\n padding: 0 var(--wb-len-14) var(--wb-len-10);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-state-error-primary);\n}\n\n._dep_1weg4_142 {\n flex: none;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n white-space: nowrap;\n}\n._panel_135e7_1 {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: var(--wb-z-10);\n visibility: hidden;\n}\n\n._panel_135e7_1[data-fullscreen] {\n z-index: var(--wb-z-40);\n}\n\n._panel_135e7_1[data-open] {\n visibility: visible;\n}\n\n._columns_135e7_18 {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n align-items: start;\n gap: var(--wb-len-12);\n}\n\n._columns_135e7_18[data-two] {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n\n._column_135e7_18 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n._root_1vd78_1 {\n position: relative;\n flex: none;\n margin: 0 var(--wb-len-2) var(--wb-len-4);\n}\n\n._anchor_1vd78_7 {\n display: block;\n width: 100%;\n}\n\n._menu_1vd78_12 {\n min-width: var(--wb-len-240);\n max-width: var(--wb-len-360);\n}\n\n._trigger_1vd78_17 {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--wb-gap-xs);\n width: 100%;\n height: var(--wb-len-34);\n padding: 0 var(--wb-len-8);\n border: none;\n border-radius: var(--dsw-radius-md);\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n._trigger_1vd78_17:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._trigger_1vd78_17:focus-visible {\n outline: var(--dsw-focus-ring-width) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}\n\n._glyph_1vd78_44 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._glyphActive_1vd78_54 {\n color: var(--dsw-alias-state-business-primary);\n}\n\n._triggerName_1vd78_58 {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-6);\n font-size: var(--wb-font-row);\n line-height: var(--wb-line-20);\n overflow: hidden;\n}\n\n._dir_1vd78_69 {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._name_1vd78_77 {\n flex: 0 1 auto;\n max-width: 50%;\n font-size: var(--dsw-font-xxs-12-font-size);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._triggerName_1vd78_58 ._name_1vd78_77 {\n color: var(--dsw-alias-label-tertiary);\n}\n\n._chevron_1vd78_90 {\n flex: none;\n display: inline-flex;\n color: var(--dsw-alias-label-caption);\n}\n\n._row_1vd78_96 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n width: 100%;\n min-width: 0;\n}\n\n._trailing_1vd78_104 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-20);\n height: var(--wb-len-20);\n margin-inline-start: auto;\n}\n\n._trailing_1vd78_104 ._rowAction_1vd78_114 {\n width: var(--wb-len-20);\n min-width: var(--wb-len-20);\n height: var(--wb-len-20);\n min-height: var(--wb-len-20);\n padding: 0;\n border-radius: var(--dsw-radius-sm);\n}\n\n._row_1vd78_96 ._name_1vd78_77 {\n color: var(--dsw-alias-label-tertiary);\n}\n\n._current_1vd78_127 {\n flex: none;\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-primary);\n}\n\n._field_1vd78_134 {\n display: flex;\n align-items: center;\n gap: var(--wb-gap-xs);\n box-sizing: border-box;\n width: 100%;\n height: var(--wb-len-34);\n padding: 0 var(--wb-len-8);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._field_1vd78_134:focus-within {\n border-color: var(--dsw-alias-state-business-primary);\n}\n\n._searchIcon_1vd78_151 {\n flex: none;\n display: inline-flex;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._field_1vd78_134 ._search_1vd78_151 {\n flex: 1;\n min-width: 0;\n height: var(--wb-len-24);\n border: none;\n background: transparent;\n}\n\n._field_1vd78_134 ._search_1vd78_151:focus {\n border-color: transparent;\n box-shadow: none;\n}\n._dialog_1vye5_1 {\n width: min(var(--wb-len-420), 100%);\n}\n\n._stack_1vye5_5 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n min-width: 0;\n}\n\n._input_1vye5_12 {\n width: 100%;\n height: var(--wb-len-40);\n padding: 0 var(--wb-len-12);\n}\n\n._meta_1vye5_18 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n._blocker_1oaj0_1 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-6);\n padding: var(--wb-len-20) var(--wb-len-16);\n text-align: center;\n}\n\n._icon_1oaj0_10 {\n display: flex;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._title_1oaj0_15 {\n margin: var(--wb-len-2) 0 0;\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._hint_1oaj0_23 {\n margin: 0;\n max-width: var(--wb-len-42em);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n text-wrap: pretty;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 {\n align-items: flex-start;\n gap: var(--wb-len-6);\n padding: var(--wb-len-4) 0 var(--wb-len-2);\n text-align: left;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._title_1oaj0_15 {\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._hint_1oaj0_23 {\n max-width: 100%;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._actions_1oaj0_48 {\n margin-top: var(--wb-len-8);\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._raw_1oaj0_52 {\n margin-top: var(--wb-len-4);\n max-width: 100%;\n}\n\n._actions_1oaj0_48 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-10);\n margin-top: var(--wb-len-6);\n}\n\n._raw_1oaj0_52 {\n margin-top: var(--wb-len-10);\n width: 100%;\n max-width: var(--wb-len-360);\n text-align: left;\n}\n\n._notice_1oaj0_71 {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: start;\n column-gap: var(--wb-len-10);\n margin: 0 0 var(--wb-len-10);\n padding: var(--wb-len-10) var(--wb-len-12);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-left: 2px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._notice_1oaj0_71._noticeFlat_1oaj0_84 {\n margin: 0;\n padding: 0;\n border: 0;\n background: transparent;\n}\n\n._noticeText_1oaj0_91 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-3);\n min-width: 0;\n}\n\n._noticeTitle_1oaj0_98 {\n font-size: var(--wb-font-12-5);\n line-height: var(--wb-line-18);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._noticeHint_1oaj0_105 {\n font-size: var(--wb-font-11-5);\n line-height: var(--wb-line-17);\n color: var(--dsw-alias-label-tertiary);\n overflow-wrap: anywhere;\n}\n\n._noticeActions_1oaj0_112 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin-top: var(--wb-len-neg-2);\n}\n\n._failure_1oaj0_119 {\n margin: var(--wb-len-8) 0 0;\n font-size: var(--wb-font-11-5);\n line-height: var(--wb-line-17);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._failureDetail_1oaj0_127 {\n display: block;\n margin-top: var(--wb-len-2);\n color: var(--dsw-alias-label-tertiary);\n white-space: pre-wrap;\n}\n\n._inlineAction_1oaj0_134 {\n padding: 0;\n border: none;\n background: transparent;\n cursor: pointer;\n}\n\n._inlineAction_1oaj0_134:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n._rawText_1oaj0_146 {\n margin: var(--wb-len-6) 0 0;\n max-width: 100%;\n}\n/*$vite$:1*/";
9569
+ var COMPONENT_CSS_MARKER = "\n.wb-activityBlock {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n padding-top: var(--wb-len-10);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.wb-activityBlock:first-child {\n border-top: none;\n}\n\n.wb-activityBlockHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-8);\n}\n\n.wb-activityLine {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-activityLineText {\n flex: none;\n min-width: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n max-height: var(--wb-len-72);\n overflow-y: auto;\n}\n\n.wb-activityLineAt {\n flex: none;\n margin-left: auto;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-16);\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-activityLine > .wb-activityLineAt,\n.wb-activityLine > .wb-activityLineActions {\n margin-left: auto;\n}\n\n.wb-activityLine > .wb-activityLineAt + .wb-activityLineActions {\n margin-left: 0;\n}\n\n.wb-activityLineActions {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n}\n\n.wb-activityActionFailed {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-note {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-problem {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n.wb-approvalCommand {\n max-width: 100%;\n}\n.wb-approvalPlan {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n}\n.wb-approvalHint {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n.wb-approvalRows {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n margin: 0;\n}\n.wb-approvalRow {\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-8);\n}\n.wb-approvalLabel {\n flex: none;\n width: var(--wb-len-56);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-approvalValue {\n margin: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n overflow-wrap: anywhere;\n}\n.wb-approvalWarn {\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-cardHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n flex: none;\n padding: var(--wb-len-8) var(--wb-len-10) var(--wb-len-8) var(--wb-len-20);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.wb-cardTitle {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n font-weight: 600;\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-cardMeta {\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wb-cardMeta::before {\n content: '\\00b7';\n margin-right: var(--wb-len-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardOpen {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n margin-left: auto;\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-4);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardOpen ~ .wb-cardRefresh {\n margin-left: 0;\n}\n\n.wb-cardOpen:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-cardRefresh {\n margin-left: auto;\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-4);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardRefresh:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-cardRefresh:disabled {\n cursor: default;\n opacity: 1;\n}\n\n.wb-cardGear {\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-3);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardGear:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-cardRefresh.wb-spinning svg {\n animation: wb-spin var(--wb-dur-0-9) linear infinite;\n}\n\n.wb-card {\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-xl);\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n flex: none;\n}\n.wb-cardBody {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n padding: var(--wb-len-12);\n}\n.wb-cardBody > :not([data-wb-bleed]) {\n padding-left: var(--wb-len-8);\n padding-right: var(--wb-len-8);\n}\n\n.wb-choiceMenu {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n padding: var(--wb-len-4);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n background: transparent;\n}\n\n.wb-choiceOption {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-height: var(--wb-len-30);\n padding: var(--wb-len-6) var(--wb-len-8);\n border-radius: var(--dsw-radius-md);\n cursor: pointer;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-choiceOptionOn {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.wb-checkbox {\n position: absolute;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n margin: 0;\n opacity: 0;\n pointer-events: none;\n}\n\n.wb-checkboxBox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n flex: none;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n border: 1px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-xs);\n corner-shape: round;\n color: var(--dsw-alias-label-primary-foreground);\n transition:\n background-color var(--wb-dur-0-12) ease, border-color var(--wb-dur-0-12) ease;\n}\n\n.wb-choiceOption:hover .wb-checkboxBox {\n border-color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-checkbox:checked + .wb-checkboxBox {\n border-color: var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n}\n\n.wb-checkbox:disabled + .wb-checkboxBox {\n opacity: 0.5;\n}\n\n.wb-checkbox:focus-visible + .wb-checkboxBox {\n outline: var(--dsw-focus-ring-width, var(--wb-len-2)) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n\n.wb-choiceOption:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.wb-choiceLabel {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wb-radio {\n appearance: none;\n -webkit-appearance: none;\n flex: none;\n box-sizing: border-box;\n width: var(--wb-len-12);\n height: var(--wb-len-12);\n margin: 0;\n border: 1px solid var(--dsw-alias-border-l3);\n border-radius: 50%;\n corner-shape: round;\n background-color: transparent;\n cursor: pointer;\n transition:\n background-color var(--wb-dur-0-12) ease, border-color var(--wb-dur-0-12) ease;\n}\n\n.wb-radio:not(:checked):hover {\n border-color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-radio:checked {\n border-color: var(--dsw-alias-brand-primary);\n background-image: radial-gradient(\n circle at center,\n var(--dsw-alias-brand-primary) 0 3px,\n transparent 3px\n );\n}\n\n.wb-radio:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n.wb-radio:focus-visible {\n outline: var(--dsw-focus-ring-width, var(--wb-len-2)) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}:where(.wb-link) {\n margin-left: var(--wb-len-2);\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-2);\n font: inherit;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n text-decoration: none;\n white-space: nowrap;\n vertical-align: baseline;\n}\n\n:where(.wb-link:hover) {\n text-decoration: underline;\n}\n\n:where(.wb-link:focus-visible) {\n outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}\n\n.wb-longTask {\n padding-top: var(--wb-len-12);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n.wb-longTaskHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin: 0;\n}\n\n.wb-longTaskLink {\n flex: none;\n}\n\n.wb-longTaskHeadline {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-longTaskProblem {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n.wb-longTaskDump {\n margin: var(--wb-len-2) 0 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-longTaskDump pre {\n margin: var(--wb-len-4) 0 0;\n max-height: var(--wb-len-220);\n overflow: auto;\n}\n.wb-mockStrip {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wb-len-4);\n padding: var(--wb-len-8) var(--wb-len-12);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n flex: none;\n}\n\n.wb-mockNote {\n flex: 1 0 100%;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-14);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-mockChip {\n flex: none;\n padding: var(--wb-len-2) var(--wb-len-7);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--wb-radius-pill);\n corner-shape: round;\n background: transparent;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-14);\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n.wb-mockChip:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-mockChipOn {\n border-color: transparent;\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-label-primary-foreground);\n}\n.wb-centered.wb-centeredCompact {\n flex: none;\n min-height: 0;\n gap: var(--wb-len-8);\n padding: var(--wb-len-20) var(--wb-len-16);\n}\n\n.wb-centered.wb-centeredCompact .wb-centeredHero {\n margin-bottom: var(--wb-len-4);\n}\n\n.wb-skeleton {\n display: flex;\n flex-direction: column;\n}\n\n.wb-skeletonRow {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n padding: var(--wb-len-8);\n border-radius: var(--dsw-radius-md);\n}\n\n.wb-skeletonRow + .wb-skeletonRow::before {\n content: '';\n align-self: stretch;\n height: var(--wb-len-0-5);\n margin: 0 var(--wb-len-8) var(--wb-len-neg-0-5);\n background: var(--dsw-alias-border-l2);\n}\n\n.wb-skeletonBar {\n display: block;\n height: var(--wb-len-13);\n border-radius: var(--dsw-radius-xs);\n background: var(--dsw-alias-bg-skeleton);\n animation: wb-skeleton-pulse var(--wb-dur-1-4) var(--ds-ease-in-out) infinite;\n}\n\n.wb-skeletonBarTitle {\n width: 62%;\n}\n\n.wb-skeletonBarMeta {\n width: 32%;\n height: var(--wb-len-10);\n}\n\n.wb-skeletonRow:nth-child(2n) .wb-skeletonBarTitle {\n width: 74%;\n}\n\n.wb-skeletonRow:nth-child(3n) .wb-skeletonBarTitle {\n width: 52%;\n}\n\n@keyframes wb-skeleton-pulse {\n 50% {\n opacity: 0.45;\n }\n}\n\n.wb-centered {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n gap: var(--wb-len-14);\n flex: 1;\n min-height: var(--wb-len-240);\n padding: 0 var(--wb-len-24) var(--wb-len-24);\n text-align: center;\n}\n\n.wb-centeredHero {\n display: flex;\n margin-bottom: var(--wb-len-16);\n color: var(--dsw-alias-label-dimmed);\n}\n\n.wb-centeredTitle {\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-centeredHint {\n max-width: var(--wb-len-300);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-centeredDetail {\n max-width: var(--wb-len-320);\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-dimmed);\n word-break: break-all;\n}\n\n.wb-centeredAction {\n display: flex;\n justify-content: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-2);\n}\n@media (prefers-reduced-motion: reduce) {\n .wb-skeletonBar {\n animation: none;\n }}\n\n.wb-row:has(> [data-wb-dot]) {\n grid-template-columns: 84px minmax(0, 1fr);\n}\n.wb-rows {\n display: flex;\n flex-direction: column;\n}\n.wb-row {\n display: grid;\n grid-template-columns: 56px minmax(0, 1fr);\n align-items: baseline;\n gap: var(--wb-len-8);\n padding: var(--wb-len-4) 0;\n}\n.wb-row + .wb-row {\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n.wb-rowKey {\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-rowValue {\n min-width: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n overflow-wrap: anywhere;\n}\n\n.wb-formActions {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--wb-len-8);\n}\n.wb-settings {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n padding: var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-1);\n}\n.wb-settingsHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n}\n.wb-settingsTitle {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-stack {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-10);\n min-height: 0;\n}\n\n.wb-stateBlock {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n}\n.wb-stateBlockTitle {\n margin: 0;\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n}\n.wb-stateBlockHint {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-stateBlockActions {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-2);\n}\n.wb-stateBlockResolving {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n.wb-textField {\n box-sizing: border-box;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.wb-textField:focus {\n border-color: var(--dsw-alias-state-business-primary);\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-business-primary);\n}\n\n.wb-textField[aria-invalid='true'] {\n border-color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-textField[aria-invalid='true']:focus {\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-error-primary);\n}\n\n:where(.wb-textField) {\n min-height: var(--wb-len-32);\n padding: var(--wb-len-6) var(--wb-len-12);\n}\n.wb-field {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xs-13-font-size);\n}\n\n.wb-fieldLabel {\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-fieldHint {\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n._marketList_csyus_1 {\n list-style: none;\n margin: 0;\n padding: var(--wb-len-6);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n._marketRow_csyus_10 {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n align-items: center;\n column-gap: var(--wb-len-14);\n row-gap: var(--wb-len-4);\n padding: var(--wb-len-8);\n border-radius: var(--dsw-radius-lg);\n}\n\n._marketIcon_csyus_20 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-40);\n height: var(--wb-len-40);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketMain_csyus_32 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n min-width: 0;\n}\n\n._marketName_csyus_39 {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n._marketDesc_csyus_48 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketUsedBy_csyus_59 {\n margin-left: var(--wb-len-8);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n opacity: 0.75;\n}\n\n._marketUsedBy_csyus_59::before {\n content: '·';\n margin-right: var(--wb-len-6);\n opacity: 0.8;\n}\n\n._marketName_csyus_39 ._marketVersion_csyus_73 {\n margin-left: var(--wb-len-6);\n font-size: var(--dsw-font-xxs-12-font-size);\n font-weight: 400;\n line-height: var(--wb-line-18);\n}\n\n._marketVersion_csyus_73 {\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-caption);\n}\n\n._marketVersion_csyus_73::before {\n content: '';\n display: inline-block;\n width: var(--wb-len-1);\n height: var(--wb-len-10);\n margin: 0 var(--wb-len-8) 0 var(--wb-len-2);\n vertical-align: -1px;\n background: var(--dsw-alias-border-l2);\n}\n\n._marketLocalTag_csyus_95 {\n margin-left: var(--wb-len-8);\n padding: 0 var(--wb-len-6);\n border: var(--wb-len-1) solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-sm);\n font-size: var(--dsw-font-xxs-12-font-size);\n font-weight: 400;\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-caption);\n}\n\n._marketEnd_csyus_106 {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--wb-len-10);\n}\n\n._marketSwitchSeat_csyus_113 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-10);\n}\n\n._marketSwitchSeat_csyus_113::before {\n content: '';\n width: 0;\n height: var(--wb-len-14);\n border-left: 0.5px solid var(--dsw-alias-border-l3);\n}\n\n._marketActions_csyus_126 {\n flex: none;\n display: flex;\n gap: var(--wb-len-6);\n}\n\n._marketUpdateAction_csyus_132 {\n color: var(--dsw-alias-state-warn-primary);\n border-color: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 30%, transparent);\n --dsw-alias-interactive-bg-hover: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 8%, transparent);\n}\n\n._marketSelfDivider_csyus_138 {\n height: 0;\n border-top: 0.5px solid var(--dsw-alias-border-l3);\n}\n\n._marketSection_csyus_143 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n min-width: 0;\n}\n\n._marketSectionHead_csyus_150 {\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-8);\n}\n\n._marketSectionIcon_csyus_156 {\n display: inline-flex;\n align-items: center;\n align-self: center;\n color: var(--dsw-alias-label-caption);\n}\n\n._marketSectionTitle_csyus_163 {\n margin: 0;\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n._marketSectionCount_csyus_169 {\n font: var(--dsw-font-s-14);\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-caption);\n}\n\n\n._marketProgress_csyus_176 {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-8);\n min-height: var(--wb-len-32);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketNote_csyus_186 {\n grid-column: 2 / -1;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-state-warn-primary);\n overflow-wrap: anywhere;\n}\n\n._marketNotePlain_csyus_193 {\n grid-column: 2 / -1;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-caption);\n overflow-wrap: anywhere;\n}\n\n._marketFailure_csyus_201 {\n grid-column: 2 / -1;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._marketEmpty_csyus_208 {\n padding: var(--wb-len-18) var(--wb-len-16);\n text-align: center;\n}\n\n._marketPage_csyus_213 {\n box-sizing: border-box;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-32);\n padding: 0 clamp(var(--wb-len-24), 4vw, var(--wb-len-48)) var(--wb-len-48);\n overflow-x: hidden;\n overflow-y: auto;\n color: var(--dsw-alias-label-primary);\n}\n\n._marketPage_csyus_213 > * {\n width: 100%;\n max-width: var(--wb-len-960);\n}\n\n._marketPageHead_csyus_231 {\n box-sizing: border-box;\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-16);\n padding-top: var(--wb-len-28);\n}\n\n._marketPageTitle_csyus_239 {\n margin: 0;\n font: var(--dsw-font-l-20);\n}\n\n._marketPageIntro_csyus_244 {\n margin: var(--wb-len-4) 0 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketPageTools_csyus_250 {\n flex: none;\n align-self: center;\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: var(--wb-len-16);\n}\n\n._marketIconButton_csyus_259 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-28);\n height: var(--wb-len-28);\n padding: 0;\n border: 0;\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n color: var(--dsw-alias-label-caption);\n cursor: pointer;\n}\n\n._marketIconButton_csyus_259:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketIconButton_csyus_259:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n._marketIconWrap_csyus_284 {\n display: inline-flex;\n}\n\n._marketIconButtonSpinning_csyus_288 svg {\n animation: _wb-spin_csyus_1 var(--wb-dur-0-9) linear infinite;\n}\n\n._marketAddButton_csyus_292 {\n height: var(--wb-len-32);\n padding: 0 var(--wb-len-12);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n border-radius: var(--dsw-radius-md);\n}\n\n._marketEmpty_csyus_208 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-64) var(--wb-len-16);\n text-align: center;\n}\n\n._marketChecking_csyus_309 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketEmptyTitle_csyus_317 {\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n@keyframes _wb-spin_csyus_1 {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n._foot_1ud1j_1 {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--wb-len-8);\n padding: var(--wb-len-8) var(--wb-len-14) var(--wb-len-10);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._footText_1ud1j_13 {\n flex: 1;\n min-width: 0;\n}\n\n._footTextMd_1ud1j_18 {\n flex: 1;\n min-width: 0;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n._wide_1coeb_1 {\n justify-content: center;\n width: 100%;\n height: var(--wb-len-40);\n border-radius: var(--dsw-radius-md);\n}\n\n._dialog_1coeb_8 {\n width: min(var(--wb-len-560), 100%);\n max-height: min(var(--wb-len-800), 100%);\n}\n\n._content_1coeb_13 {\n min-height: 0;\n overflow: auto;\n}\n\n._stack_1coeb_18 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n\n._body_1coeb_25 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n\n._field_1coeb_32 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xs-13-font-size);\n}\n\n._input_1coeb_39 {\n width: 100%;\n height: var(--wb-len-40);\n padding: 0 var(--wb-len-14);\n}\n\n._registryField_1coeb_45 {\n height: var(--wb-len-32);\n margin-left: var(--wb-len-26);\n padding: 0 var(--wb-len-10);\n}\n\n._options_1coeb_51 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-8) var(--wb-len-12);\n}\n\n._guideToggle_1coeb_59 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-4);\n align-self: flex-start;\n margin-top: var(--wb-len-4);\n padding: 0;\n border: 0;\n background: transparent;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n._guideToggle_1coeb_59:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n._guideToggle_1coeb_59 svg,\n._registryToggle_1coeb_78 svg {\n transition: transform var(--wb-dur-0-12) ease;\n}\n\n._guideToggle_1coeb_59[aria-expanded='true'] svg,\n._registryToggle_1coeb_78[aria-expanded='true'] svg {\n transform: rotate(180deg);\n}\n\n._registryWrap_1coeb_87 {\n position: relative;\n flex: none;\n}\n\n._registryToggle_1coeb_78 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n height: var(--wb-len-26);\n padding: 0 var(--wb-len-8) 0 var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-2);\n font: inherit;\n font-size: var(--wb-font-12-5);\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n._registryToggle_1coeb_78:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n._registryToggle_1coeb_78:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n._registryToggle_1coeb_78[aria-expanded='true'] {\n border-color: var(--dsw-alias-border-l3);\n background: var(--dsw-alias-bg-layer-3);\n}\n\n._registryChosen_1coeb_121 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n._registry_1coeb_45 {\n position: fixed;\n z-index: var(--wb-z-1100);\n box-sizing: border-box;\n width: min(var(--wb-len-440), 100vw - var(--wb-len-24));\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10) var(--wb-len-12);\n border: 0;\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-alias-bg-layer-2);\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l3);\n box-shadow: var(--dsw-elevation-prominent);\n}\n\n._registryOption_1coeb_143 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n padding: var(--wb-len-8) var(--wb-len-10);\n border: 0.5px solid transparent;\n border-radius: var(--dsw-radius-lg);\n cursor: pointer;\n}\n\nlabel._registryOption_1coeb_143 {\n flex-direction: row;\n align-items: flex-start;\n gap: var(--wb-len-10);\n}\n\n._registryPick_1coeb_159 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-10);\n cursor: pointer;\n}\n\n._registryOption_1coeb_143[data-checked='true'] {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 40%, transparent);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._registryOption_1coeb_143 input[type='radio'] {\n flex: none;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n margin: var(--wb-len-2) 0 0;\n accent-color: var(--dsw-alias-brand-primary);\n}\n\n._registryTitle_1coeb_179 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wb-len-8);\n font: var(--dsw-font-xs-13);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-primary);\n}\n\n._registryHint_1coeb_189 {\n margin-left: var(--wb-len-26);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n overflow-wrap: anywhere;\n}\n\n._inputError_1coeb_197 {\n margin: var(--wb-len-neg-4) 0 0 var(--wb-len-26);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-state-error-primary);\n}\n\n._guide_1coeb_59 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) var(--wb-len-14) var(--wb-len-14);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._guideList_1coeb_214 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n._guideItem_1coeb_223 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) 0;\n}\n\n._guideIndex_1coeb_230 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-20);\n height: var(--wb-len-20);\n border-radius: var(--wb-radius-pill);\n corner-shape: round;\n background: var(--dsw-alias-bg-module-platform);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._guideMain_1coeb_244 {\n display: flex;\n flex-direction: column;\n flex: 1;\n gap: 0;\n min-width: 0;\n}\n\n._guideTitle_1coeb_252 {\n font: var(--dsw-font-s-14);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n._guideHint_1coeb_258 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-caption);\n}\n\n._guideExample_1coeb_264 {\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._guideExample_1coeb_264 code {\n font-family: var(--dsw-font-mono, monospace);\n}\n\n._guideExampleLabel_1coeb_274 {\n color: var(--dsw-alias-label-caption);\n}\n\n._footer_1coeb_278 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-20);\n width: 100%;\n}\n\n._hero_1coeb_285 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) 0 var(--wb-len-4);\n text-align: center;\n}\n\n._heroIcon_1coeb_294 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-44);\n height: var(--wb-len-44);\n color: var(--dsw-alias-label-secondary);\n}\n\n._heroIcon_1coeb_294[data-state='done'] {\n color: var(--dsw-alias-state-success-secondary);\n}\n\n._heroIcon_1coeb_294[data-state='error'] {\n color: var(--dsw-alias-state-warn-label);\n}\n\n._pendingTitle_1coeb_311 {\n margin: 0;\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n._wizardTitle_1coeb_319 {\n margin: 0;\n font-size: var(--wb-font-18);\n line-height: var(--wb-len-26);\n font-weight: 600;\n}\n\n._subject_1coeb_326 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-6);\n padding: var(--wb-len-16);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-lg);\n text-align: center;\n}\n\n._subjectName_1coeb_337 {\n margin: 0;\n font: var(--dsw-font-base-strong-16);\n overflow-wrap: anywhere;\n}\n\n._subjectMeta_1coeb_343,\n._subjectDesc_1coeb_344 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._result_1coeb_351,\n._resultWarn_1coeb_352 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-12);\n border-radius: var(--dsw-radius-md);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-primary);\n}\n\n._resultWarn_1coeb_352 {\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent);\n}\n\n._approval_1coeb_365 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n padding: var(--wb-len-12) var(--wb-len-14);\n border: 0.5px solid var(--dsw-alias-state-warn-primary);\n border-radius: var(--dsw-radius-lg);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 8%, transparent);\n}\n\n._approvalTitle_1coeb_375 {\n margin: 0;\n font: var(--dsw-font-s-14);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._approvalText_1coeb_382 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._approvalCaution_1coeb_388 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n font-weight: 600;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._note_1coeb_395 {\n margin: 0;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._noteWarn_1coeb_402 {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._noteError_1coeb_406 {\n color: var(--dsw-alias-state-error-primary);\n}\n\n._problem_1coeb_410 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._detailLabel_1coeb_417 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-caption);\n}\n\n._detail_1coeb_417 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l1);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-3);\n font-family: var(--dsw-font-mono, monospace);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n._note_1enlz_1 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-8);\n margin: 0;\n padding: var(--wb-len-10) var(--wb-len-12);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-state-warn-tertiary);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n\n._note_1enlz_1 > svg {\n flex: none;\n margin-top: var(--wb-len-2);\n color: var(--dsw-alias-state-warn-primary);\n}\n._actions_jlw8j_1[hidden],\n._progress_jlw8j_2[hidden],\n._commandRow_jlw8j_3[hidden],\n._bridge_jlw8j_4[hidden],\n._raw_jlw8j_5[hidden] {\n display: none;\n}\n\n._gate_jlw8j_9 {\n position: fixed;\n inset: 0;\n z-index: var(--wb-z-top);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--wb-len-24);\n background: var(--dsw-alias-bg-base);\n}\n\n._card_jlw8j_20 {\n width: 100%;\n max-width: var(--wb-len-420);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-16);\n text-align: center;\n}\n\n._card_jlw8j_20:has(._actions_jlw8j_1:not([hidden])),\n._card_jlw8j_20:has(._bridge_jlw8j_4:not([hidden])) {\n max-width: var(--wb-len-520);\n}\n\n._title_jlw8j_35 {\n margin: 0;\n font-size: var(--dsw-font-base-16-font-size);\n line-height: var(--wb-line-24);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._hint_jlw8j_43 {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._steps_jlw8j_50 {\n list-style: none;\n margin: var(--wb-len-6) 0 0;\n padding: 0;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n text-align: left;\n}\n\n._step_jlw8j_50 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-6) var(--wb-len-10);\n border-radius: var(--dsw-radius-sm);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._step_jlw8j_50[data-status='running'] {\n color: var(--dsw-alias-label-primary);\n}\n\n._mark_jlw8j_77 {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-14);\n height: var(--wb-len-14);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n font-variant-numeric: tabular-nums;\n}\n\n._step_jlw8j_50[data-status='ok'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-success-primary);\n}\n\n._step_jlw8j_50[data-status='warn'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._step_jlw8j_50[data-status='failed'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-error-primary);\n}\n\n._label_jlw8j_102 {\n flex: none;\n}\n\n._detail_jlw8j_106 {\n margin-left: auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._progress_jlw8j_2 {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-4);\n max-width: 100%;\n}\n\n._elapsed_jlw8j_124 {\n flex: none;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n font-variant-numeric: tabular-nums;\n}\n\n._error_jlw8j_132 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n max-height: var(--wb-len-120);\n overflow: auto;\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n white-space: pre-wrap;\n word-break: break-all;\n text-align: left;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._commandRow_jlw8j_3 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-4);\n margin: 0 0 var(--wb-len-8);\n padding-right: var(--wb-len-4);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._copy_jlw8j_158 {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-24);\n height: var(--wb-len-24);\n padding: 0;\n border: none;\n border-radius: var(--wb-radius-6);\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._copy_jlw8j_158:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._command_jlw8j_3 {\n flex: 1;\n min-width: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n overflow-wrap: anywhere;\n color: var(--dsw-alias-label-primary);\n}\n\n._buttons_jlw8j_191 {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--wb-len-12);\n}\n\n._mockSlot_jlw8j_198 {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n justify-content: center;\n background: var(--dsw-alias-bg-base);\n}\n\n._button_jlw8j_191 {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: var(--wb-len-28);\n padding: 0 var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n font: inherit;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n\n._button_jlw8j_191:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._button_jlw8j_191:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n._actions_jlw8j_1,\n._bridge_jlw8j_4 {\n box-sizing: border-box;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--wb-len-10);\n margin-top: var(--wb-len-4);\n padding: var(--wb-len-14) var(--wb-len-16);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--wb-radius-14);\n background: var(--dsw-alias-bg-layer-1);\n text-align: left;\n}\n\n._fixTitle_jlw8j_249 {\n margin: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._actions_jlw8j_1 ._hint_jlw8j_43,\n._bridge_jlw8j_4 ._hint_jlw8j_43 {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-19);\n color: var(--dsw-alias-label-secondary);\n}\n\n._actions_jlw8j_1 ._commandRow_jlw8j_3,\n._bridge_jlw8j_4 ._commandRow_jlw8j_3 {\n margin: 0;\n}\n\n._actions_jlw8j_1 ._buttons_jlw8j_191,\n._bridge_jlw8j_4 ._buttons_jlw8j_191 {\n justify-content: flex-start;\n}\n\n._raw_jlw8j_5 {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._rawSummary_jlw8j_282 {\n cursor: pointer;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._actions_jlw8j_1 ._error_jlw8j_132,\n._bridge_jlw8j_4 ._error_jlw8j_132 {\n margin-top: var(--wb-len-6);\n}\n\n._bridgeLines_jlw8j_292 {\n margin: 0;\n padding-left: var(--wb-len-18);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-19);\n color: var(--dsw-alias-label-secondary);\n}\n\n._bridgeLine_jlw8j_292 a {\n display: block;\n margin-top: var(--wb-len-4);\n width: fit-content;\n}\n\n._link_jlw8j_309 {\n color: var(--dsw-alias-label-primary);\n text-decoration: none;\n}\n\n._link_jlw8j_309::after {\n content: '↗';\n margin-left: var(--wb-len-2);\n}\n\n._link_jlw8j_309:hover {\n text-decoration: underline;\n}\n\n._loading_jlw8j_323 {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._loading_jlw8j_323[hidden] {\n display: none;\n}\n\n._loadingMotion_jlw8j_332 {\n transform-origin: center;\n animation: _wb-spin_jlw8j_1 var(--wb-dur-1-5) linear infinite;\n}\n\n._loadingTrack_jlw8j_337,\n._loadingArc_jlw8j_338 {\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n}\n\n._loadingTrack_jlw8j_337 {\n opacity: 0.25;\n}\n\n._loadingArc_jlw8j_338 {\n stroke-dasharray: 12 150;\n animation: _wb-dash_jlw8j_1 var(--wb-dur-1-5) ease-in-out infinite;\n}\n\n@keyframes _wb-spin_jlw8j_1 {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes _wb-dash_jlw8j_1 {\n 0% {\n stroke-dasharray: 12 150;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 24 150;\n stroke-dashoffset: -6;\n }\n to {\n stroke-dasharray: 12 150;\n stroke-dashoffset: 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n ._loadingMotion_jlw8j_332,\n ._loadingArc_jlw8j_338 {\n animation: none;\n }\n}\n._group_1hxis_1 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-2);\n}\n\n._button_1hxis_7 {\n flex: none;\n width: var(--wb-len-28);\n height: var(--wb-len-28);\n padding: 0;\n color: var(--dsw-alias-label-secondary);\n}\n\n._button_1hxis_7:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n._active_1hxis_19 {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._icon_1hxis_23 {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n._icon_1hxis_23 svg {\n display: block;\n width: var(--wb-len-15);\n height: var(--wb-len-15);\n}\n\n._mirror_1hxis_35 {\n transform: scaleX(-1);\n}\n._stripTabs_1dqp4_1 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-4);\n min-width: 0;\n overflow: hidden;\n}\n\n._tab_1dqp4_9 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n flex: none;\n height: var(--wb-len-28);\n padding: 0 var(--wb-len-10);\n border: 0;\n border-radius: var(--dsw-radius-sm);\n background: none;\n font: inherit;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-16);\n max-width: 100%;\n}\n\n._tabActive_1dqp4_25 {\n color: var(--dsw-alias-label-primary);\n}\n\n._tabQuiet_1dqp4_29 {\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._tabQuiet_1dqp4_29:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._tabTitle_1dqp4_39 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._sep_1dqp4_49 {\n flex: none;\n color: var(--dsw-alias-label-dimmed);\n}\n._trigger_15ptp_1 {\n display: flex;\n align-items: center;\n}\n\n._pop_15ptp_6 {\n position: absolute;\n top: calc(var(--wb-len-38) + var(--wb-len-8));\n right: var(--wb-len-6);\n z-index: var(--wb-z-30);\n width: min(var(--wb-len-360), calc(100% - var(--wb-len-12)));\n max-width: calc(100vw - var(--wb-len-48));\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--wb-radius-14);\n background: var(--dsw-alias-bg-layer-2);\n box-shadow: var(--dsw-shadow-lv3);\n overflow: hidden;\n}\n\n._head_15ptp_20 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-10) var(--wb-len-12) var(--wb-len-9) var(--wb-len-14);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n._title_15ptp_28 {\n flex: 1;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._rowControls_15ptp_36 {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-8);\n}\n\n._reset_15ptp_43 {\n flex: none;\n padding: var(--wb-len-3) var(--wb-len-8);\n border: none;\n border-radius: var(--wb-radius-6);\n background: transparent;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._reset_15ptp_43:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._reset_15ptp_43:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n._list_15ptp_65 {\n list-style: none;\n margin: 0;\n padding: var(--wb-len-6);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n._row_15ptp_36 {\n position: relative;\n display: grid;\n grid-template-columns: 12px minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-7) var(--wb-len-8);\n border-radius: var(--dsw-radius-sm);\n cursor: default;\n}\n\n._rowDragging_15ptp_85 {\n cursor: grabbing;\n}\n\n._rowBlocked_15ptp_89 {\n cursor: not-allowed;\n}\n\n._listDragging_15ptp_93 ._rowControls_15ptp_36 {\n pointer-events: none;\n}\n\n._row_15ptp_36:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._rowOff_15ptp_101 {\n opacity: 0.55;\n}\n\n._rowOff_15ptp_101:hover {\n opacity: 1;\n}\n\n._rowOver_15ptp_109::before {\n content: '';\n position: absolute;\n top: var(--wb-len-neg-3);\n left: var(--wb-len-8);\n right: var(--wb-len-8);\n height: var(--wb-len-2);\n background: var(--dsw-alias-brand-primary);\n}\n\n._ghost_15ptp_119 {\n position: fixed;\n z-index: var(--wb-z-40);\n pointer-events: none;\n padding: var(--wb-len-4) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n box-shadow: var(--wb-static-shadow-ghost);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n white-space: nowrap;\n}\n\n._grip_15ptp_134 {\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n text-align: center;\n color: var(--dsw-alias-label-tertiary);\n user-select: none;\n cursor: grab;\n touch-action: none;\n}\n\n._gripDragging_15ptp_144 {\n cursor: grabbing;\n}\n\n._gripBlocked_15ptp_148 {\n cursor: not-allowed;\n}\n\n._label_15ptp_152 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n}\n\n._name_15ptp_159 {\n min-width: 0;\n flex: 0 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n}\n\n._error_15ptp_170 {\n margin: 0;\n padding: 0 var(--wb-len-14) var(--wb-len-10);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-state-error-primary);\n}\n\n._dep_15ptp_178 {\n flex: none;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n white-space: nowrap;\n}\n\n._group_15ptp_186 {\n padding-top: var(--wb-len-6);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n._groupTitle_15ptp_191 {\n margin: 0;\n padding: var(--wb-len-2) var(--wb-len-8) 0 var(--wb-len-14);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n font-weight: 400;\n color: var(--dsw-alias-label-tertiary);\n}\n._panel_135e7_1 {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: var(--wb-z-10);\n visibility: hidden;\n}\n\n._panel_135e7_1[data-fullscreen] {\n z-index: var(--wb-z-40);\n}\n\n._panel_135e7_1[data-open] {\n visibility: visible;\n}\n\n._columns_135e7_18 {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n align-items: start;\n gap: var(--wb-len-12);\n}\n\n._columns_135e7_18[data-two] {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n\n._column_135e7_18 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n._root_1vd78_1 {\n position: relative;\n flex: none;\n margin: 0 var(--wb-len-2) var(--wb-len-4);\n}\n\n._anchor_1vd78_7 {\n display: block;\n width: 100%;\n}\n\n._menu_1vd78_12 {\n min-width: var(--wb-len-240);\n max-width: var(--wb-len-360);\n}\n\n._trigger_1vd78_17 {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--wb-gap-xs);\n width: 100%;\n height: var(--wb-len-34);\n padding: 0 var(--wb-len-8);\n border: none;\n border-radius: var(--dsw-radius-md);\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n._trigger_1vd78_17:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._trigger_1vd78_17:focus-visible {\n outline: var(--dsw-focus-ring-width) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}\n\n._glyph_1vd78_44 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._glyphActive_1vd78_54 {\n color: var(--dsw-alias-state-business-primary);\n}\n\n._triggerName_1vd78_58 {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-6);\n font-size: var(--wb-font-row);\n line-height: var(--wb-line-20);\n overflow: hidden;\n}\n\n._dir_1vd78_69 {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._name_1vd78_77 {\n flex: 0 1 auto;\n max-width: 50%;\n font-size: var(--dsw-font-xxs-12-font-size);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._triggerName_1vd78_58 ._name_1vd78_77 {\n color: var(--dsw-alias-label-tertiary);\n}\n\n._chevron_1vd78_90 {\n flex: none;\n display: inline-flex;\n color: var(--dsw-alias-label-caption);\n}\n\n._row_1vd78_96 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n width: 100%;\n min-width: 0;\n}\n\n._trailing_1vd78_104 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-20);\n height: var(--wb-len-20);\n margin-inline-start: auto;\n}\n\n._trailing_1vd78_104 ._rowAction_1vd78_114 {\n width: var(--wb-len-20);\n min-width: var(--wb-len-20);\n height: var(--wb-len-20);\n min-height: var(--wb-len-20);\n padding: 0;\n border-radius: var(--dsw-radius-sm);\n}\n\n._row_1vd78_96 ._name_1vd78_77 {\n color: var(--dsw-alias-label-tertiary);\n}\n\n._current_1vd78_127 {\n flex: none;\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-primary);\n}\n\n._field_1vd78_134 {\n display: flex;\n align-items: center;\n gap: var(--wb-gap-xs);\n box-sizing: border-box;\n width: 100%;\n height: var(--wb-len-34);\n padding: 0 var(--wb-len-8);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._field_1vd78_134:focus-within {\n border-color: var(--dsw-alias-state-business-primary);\n}\n\n._searchIcon_1vd78_151 {\n flex: none;\n display: inline-flex;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._field_1vd78_134 ._search_1vd78_151 {\n flex: 1;\n min-width: 0;\n height: var(--wb-len-24);\n border: none;\n background: transparent;\n}\n\n._field_1vd78_134 ._search_1vd78_151:focus {\n border-color: transparent;\n box-shadow: none;\n}\n._dialog_1vye5_1 {\n width: min(var(--wb-len-420), 100%);\n}\n\n._stack_1vye5_5 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n min-width: 0;\n}\n\n._input_1vye5_12 {\n width: 100%;\n height: var(--wb-len-40);\n padding: 0 var(--wb-len-12);\n}\n\n._meta_1vye5_18 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n._blocker_1oaj0_1 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-6);\n padding: var(--wb-len-20) var(--wb-len-16);\n text-align: center;\n}\n\n._icon_1oaj0_10 {\n display: flex;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._title_1oaj0_15 {\n margin: var(--wb-len-2) 0 0;\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._hint_1oaj0_23 {\n margin: 0;\n max-width: var(--wb-len-42em);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n text-wrap: pretty;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 {\n align-items: flex-start;\n gap: var(--wb-len-6);\n padding: var(--wb-len-4) 0 var(--wb-len-2);\n text-align: left;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._title_1oaj0_15 {\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._hint_1oaj0_23 {\n max-width: 100%;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._actions_1oaj0_48 {\n margin-top: var(--wb-len-8);\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._raw_1oaj0_52 {\n margin-top: var(--wb-len-4);\n max-width: 100%;\n}\n\n._actions_1oaj0_48 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-10);\n margin-top: var(--wb-len-6);\n}\n\n._raw_1oaj0_52 {\n margin-top: var(--wb-len-10);\n width: 100%;\n max-width: var(--wb-len-360);\n text-align: left;\n}\n\n._notice_1oaj0_71 {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: start;\n column-gap: var(--wb-len-10);\n margin: 0 0 var(--wb-len-10);\n padding: var(--wb-len-10) var(--wb-len-12);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-left: 2px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._notice_1oaj0_71._noticeFlat_1oaj0_84 {\n margin: 0;\n padding: 0;\n border: 0;\n background: transparent;\n}\n\n._noticeText_1oaj0_91 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-3);\n min-width: 0;\n}\n\n._noticeTitle_1oaj0_98 {\n font-size: var(--wb-font-12-5);\n line-height: var(--wb-line-18);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._noticeHint_1oaj0_105 {\n font-size: var(--wb-font-11-5);\n line-height: var(--wb-line-17);\n color: var(--dsw-alias-label-tertiary);\n overflow-wrap: anywhere;\n}\n\n._noticeActions_1oaj0_112 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin-top: var(--wb-len-neg-2);\n}\n\n._failure_1oaj0_119 {\n margin: var(--wb-len-8) 0 0;\n font-size: var(--wb-font-11-5);\n line-height: var(--wb-line-17);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._failureDetail_1oaj0_127 {\n display: block;\n margin-top: var(--wb-len-2);\n color: var(--dsw-alias-label-tertiary);\n white-space: pre-wrap;\n}\n\n._inlineAction_1oaj0_134 {\n padding: 0;\n border: none;\n background: transparent;\n cursor: pointer;\n}\n\n._inlineAction_1oaj0_134:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n._rawText_1oaj0_146 {\n margin: var(--wb-len-6) 0 0;\n max-width: 100%;\n}\n/*$vite$:1*/";
8224
9570
  function workbenchCss() {
8225
9571
  return `${tokens_default}\n${palette_default}\n${scale_default}\n${sidebar_default}\n${sidebar_app_default}\n${rightbar_default}\n${chrome_default}\n${board_default}\n${motion_default}\n${COMPONENT_CSS_MARKER}`;
8226
9572
  }
@@ -8354,16 +9700,6 @@ function mount(ctx) {
8354
9700
  };
8355
9701
  const rightbarHooks = { hooks: { rightbar: observable } };
8356
9702
  const sidebarRight = () => ctx.get("sidebarRight");
8357
- const dshColumn = createDshColumnSource(() => {
8358
- const official = sidebarRight();
8359
- if (official === void 0) return false;
8360
- return official.mounted.getSnapshot() === void 0 || official.isExpanded();
8361
- }, 400);
8362
- let pendingDshOpen = false;
8363
- let pendingOfficialCall;
8364
- let unsubscribeOfficial;
8365
- let restoreOfficial;
8366
- let officialShimmed = false;
8367
9703
  let workbenchColumnArmed = false;
8368
9704
  let disposeWorkbenchColumn;
8369
9705
  const armWorkbenchColumn = () => {
@@ -8385,87 +9721,37 @@ function mount(ctx) {
8385
9721
  disposeWorkbenchColumn?.();
8386
9722
  disposeWorkbenchColumn = void 0;
8387
9723
  };
8388
- const flushOfficialCall = () => {
8389
- const official = sidebarRight();
8390
- if (official === void 0 || official.mounted.getSnapshot() === void 0) return;
8391
- if (pendingDshOpen) {
8392
- pendingDshOpen = false;
8393
- if (!official.isExpanded()) official.toggleExpanded();
8394
- }
8395
- const call = pendingOfficialCall;
8396
- pendingOfficialCall = void 0;
8397
- call?.();
8398
- };
8399
- const watchOfficial = () => {
8400
- const official = sidebarRight();
8401
- if (official === void 0 || unsubscribeOfficial !== void 0) return;
8402
- unsubscribeOfficial = official.mounted.subscribe(flushOfficialCall);
8403
- };
8404
- const armDshColumn = () => {
8405
- const official = sidebarRight();
8406
- if (official === void 0) return false;
8407
- if (official.mounted.getSnapshot() !== void 0) {
8408
- if (!official.isExpanded()) official.toggleExpanded();
8409
- return true;
8410
- }
8411
- watchOfficial();
8412
- store.setColumn("dsh");
8413
- ctx.layout.closeRightbar();
8414
- releaseWorkbenchColumn();
8415
- pendingDshOpen = true;
8416
- return false;
8417
- };
8418
- const openInDshColumn = (call) => {
8419
- shimOfficialNavigation();
8420
- if (sidebarRight() === void 0) return;
8421
- if (armDshColumn()) {
8422
- call();
8423
- return;
9724
+ const borrow = createDshBorrow({
9725
+ official: sidebarRight,
9726
+ yieldColumn: () => {
9727
+ store.setColumn("dsh");
9728
+ ctx.layout.closeRightbar();
9729
+ releaseWorkbenchColumn();
9730
+ },
9731
+ reclaimColumn: () => {
9732
+ store.setColumn("workbench");
9733
+ armWorkbenchColumn();
9734
+ store.setExpanded(true);
8424
9735
  }
8425
- pendingOfficialCall = call;
8426
- };
8427
- const shimOfficialNavigation = () => {
8428
- const official = sidebarRight();
8429
- if (official === void 0 || officialShimmed) return;
8430
- const { openResource, openTab } = official;
8431
- if (typeof openResource !== "function" || typeof openTab !== "function") return;
8432
- officialShimmed = true;
8433
- official.openResource = (address, options) => openInDshColumn(() => openResource.call(official, address, options));
8434
- official.openTab = (kind, options) => openInDshColumn(() => openTab.call(official, kind, options));
8435
- restoreOfficial = () => {
8436
- official.openResource = openResource;
8437
- official.openTab = openTab;
8438
- officialShimmed = false;
8439
- };
8440
- };
9736
+ });
9737
+ const dshColumn = createDshColumnSource(() => borrow.open(), 400);
8441
9738
  const selectColumn = (column) => {
8442
9739
  if (store.getSnapshot().column === column) {
8443
9740
  if (column === "workbench") {
8444
9741
  rightbarActions.toggleRightbar();
8445
9742
  return;
8446
9743
  }
8447
- const current = sidebarRight();
8448
- if (current === void 0 || current.mounted.getSnapshot() === void 0) return;
8449
- current.toggleExpanded();
9744
+ borrow.toggle();
8450
9745
  return;
8451
9746
  }
8452
9747
  if (column === "workbench") {
8453
- store.setColumn("workbench");
8454
- pendingDshOpen = false;
8455
- armWorkbenchColumn();
8456
- store.setExpanded(true);
9748
+ borrow.back();
8457
9749
  return;
8458
9750
  }
8459
- openInDshColumn(() => {});
8460
- };
8461
- ctx.effect(() => () => {
8462
- unsubscribeOfficial?.();
8463
- unsubscribeOfficial = void 0;
8464
- restoreOfficial?.();
8465
- restoreOfficial = void 0;
8466
- }, "dsh-workbench: 官方椅面订阅与借道");
8467
- shimOfficialNavigation();
8468
- watchOfficial();
9751
+ borrow.use();
9752
+ };
9753
+ ctx.effect(() => () => borrow.dispose(), "dsh-workbench: 官方椅面订阅与借道");
9754
+ borrow.start();
8469
9755
  if (store.getSnapshot().column === "workbench") armWorkbenchColumn();
8470
9756
  ctx.slots.inject("sidebar", () => ctx.slots.register({
8471
9757
  name: "sidebar",