@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
@@ -419,6 +419,11 @@ function probeKeyOf(error) {
419
419
  if (error === void 0) return null;
420
420
  return error.code === "" ? "unknown" : error.code;
421
421
  }
422
+ //#endregion
423
+ //#region ../shared/dist/api/unit.js
424
+ function hasEnvSupply(manifest) {
425
+ return (manifest.env?.plugins ?? []).length > 0 || (manifest.env?.libs ?? []).length > 0;
426
+ }
422
427
  var SUPPORTED_API_VERSIONS = [1];
423
428
  var DECLARATION_KEYS = [
424
429
  "apiVersion",
@@ -554,10 +559,13 @@ var PREFS_PREFIX = `${API_PREFIX}/prefs`;
554
559
  var EVENTS_PATH = "/workbench/events";
555
560
  var ACTIONS_PREFIX = `${API_PREFIX}/actions`;
556
561
  var PROVISION_PREFIX = `${API_PREFIX}/provision`;
562
+ var PANEL_STATE_PATH = "panel-state";
563
+ var PANEL_STATE_PREFIX = `${API_PREFIX}/${PANEL_STATE_PATH}`;
557
564
  var OPENCLI_PIN = "1.8.8";
558
565
  var CODING_ISSUES_SERVICE = "workbenchCodingIssues";
559
566
  var PANELS_SERVICE = "workbenchPanels";
560
567
  var UNITS_SERVICE = "workbenchUnits";
568
+ var PANEL_STATE_SERVICE = "workbenchPanelState";
561
569
  var OPENCLI_TIMEOUT_MS = 12e4;
562
570
  var WARM_TIMEOUT_MS = 2e4;
563
571
  var INSTALL_TIMEOUT_MS = 3e5;
@@ -677,7 +685,9 @@ var CardBoundary = class extends Component {
677
685
  return { reason: errorReasonOf(error) };
678
686
  }
679
687
  componentDidCatch(error) {
680
- console.error(`[dsh-workbench] 模块 ${this.props.unit} 渲染失败:${errorReasonOf(error)}`, error);
688
+ const reason = errorReasonOf(error);
689
+ console.error(`[dsh-workbench] 模块 ${this.props.unit} 渲染失败:${reason}`, error);
690
+ this.props.onFailure?.(reason);
681
691
  }
682
692
  componentDidUpdate(previous) {
683
693
  if (previous.resetKey !== this.props.resetKey && this.state.reason !== null) this.setState({ reason: null });
@@ -1087,6 +1097,50 @@ function IconBrandMark({ size = 24 }) {
1087
1097
  strokeLinecap: "round"
1088
1098
  }));
1089
1099
  }
1100
+ function IconOpencli({ size = 16 }) {
1101
+ return h(Shell, {
1102
+ size,
1103
+ viewBox: "0 0 64 64"
1104
+ }, h("defs", null, h("linearGradient", {
1105
+ id: "opencli-mark",
1106
+ x1: "0%",
1107
+ y1: "0%",
1108
+ x2: "100%",
1109
+ y2: "100%"
1110
+ }, h("stop", {
1111
+ offset: "0%",
1112
+ stopColor: "#00e5a0"
1113
+ }), h("stop", {
1114
+ offset: "50%",
1115
+ stopColor: "#00b4d8"
1116
+ }), h("stop", {
1117
+ offset: "100%",
1118
+ stopColor: "#7b61ff"
1119
+ }))), h("rect", {
1120
+ width: 64,
1121
+ height: 64,
1122
+ rx: 14,
1123
+ fill: "#0a0a0f"
1124
+ }), h("text", {
1125
+ x: "50%",
1126
+ y: "54%",
1127
+ dominantBaseline: "middle",
1128
+ textAnchor: "middle",
1129
+ fontFamily: "monospace",
1130
+ fontWeight: 700,
1131
+ fontSize: 28,
1132
+ fill: "url(#opencli-mark)"
1133
+ }, ">_"));
1134
+ }
1135
+ function IconNpm({ size = 16 }) {
1136
+ return h(Shell, {
1137
+ size,
1138
+ viewBox: "0 0 1024 1024"
1139
+ }, h("path", {
1140
+ 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",
1141
+ fill: "#CB3837"
1142
+ }));
1143
+ }
1090
1144
  function IconModules({ size = 16 }) {
1091
1145
  return h("svg", {
1092
1146
  width: size,
@@ -1176,6 +1230,8 @@ var en = {
1176
1230
  "project.none": "No project",
1177
1231
  "project.empty": "No projects yet. Use “Add project” below.",
1178
1232
  "project.add": "Add project…",
1233
+ "project.add.busy": "Creating the workspace…",
1234
+ "project.add.failed": "Creating the workspace failed",
1179
1235
  "project.search.label": "Search workspaces",
1180
1236
  "project.search.placeholder": "Search workspaces (folder / name / path)",
1181
1237
  "project.search.empty": "No workspace matches “{query}”.",
@@ -1209,13 +1265,22 @@ var en = {
1209
1265
  "time.hours": "{n} h ago",
1210
1266
  "time.days": "{n} d ago",
1211
1267
  "panels.title": "Panel modules",
1212
- "panels.reset": "Reset",
1268
+ "panels.groupBoardless": "No-board modules",
1269
+ "panels.groupPlugins": "opencli plugins",
1270
+ "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.",
1271
+ "panels.market.defaultLabel": "On by default everywhere",
1272
+ "panels.market.defaultLocked": "Unusable right now — update or uninstall it first",
1273
+ "panels.followAll": "Restore the default everywhere",
1274
+ "panels.followAllConfirmTitle": "Restore the default everywhere?",
1275
+ "panels.followAllConfirmDetail": "Every row changed in this workspace goes back to following the global default.",
1276
+ "panels.followAllConfirmAck": "I understand: to set them up for this workspace again, I will have to change them row by row.",
1277
+ "panels.followAllConfirmYes": "Restore",
1278
+ "panels.followAllConfirmNo": "Cancel",
1213
1279
  "panels.enabled": "enabled in this project",
1214
1280
  "panels.disabled": "not enabled in this project",
1215
1281
  "panels.choose": "Choose modules",
1216
1282
  "panels.buildModule": "Build a module",
1217
1283
  "panels.failed": "Could not save the change. Try again.",
1218
- "panels.hintEffect": "Disabling = the agent cannot reach that data",
1219
1284
  "panels.dragHint": "Drag to reorder",
1220
1285
  "panels.unknownStep": "No suite provides this view",
1221
1286
  "panels.labelWithHint": "{label} ({hint})",
@@ -1229,7 +1294,9 @@ var en = {
1229
1294
  "panels.noneInstalled": "None of these modules has its plugin installed yet",
1230
1295
  "panels.noneInstalledHint": "Once installed they come back here, and you pick which go on the panel.",
1231
1296
  "panels.market.installed": "installed",
1232
- "panels.market.outdated": "needs update",
1297
+ "panels.market.notActive": "not active",
1298
+ "panels.market.notUsable": "unusable",
1299
+ "panels.market.broken": "broken",
1233
1300
  "panels.market.hasNew": "New version",
1234
1301
  "panels.market.missing": "not installed",
1235
1302
  "panels.market.unchecked": "unknown",
@@ -1237,7 +1304,7 @@ var en = {
1237
1304
  "panels.market.sectionInstalled": "Installed modules",
1238
1305
  "panels.market.sectionPending": "Not installed",
1239
1306
  "panels.market.sectionShared": "Shared dependencies",
1240
- "panels.market.sharedUsedBy": "Used by {modules}",
1307
+ "panels.market.sharedUsedBy": "Used by module {modules}",
1241
1308
  "panels.market.listSeparator": ", ",
1242
1309
  "panels.market.sharedMissing": "not installed",
1243
1310
  "panels.market.sharedOutdated": "update available",
@@ -1259,22 +1326,24 @@ var en = {
1259
1326
  "panels.market.confirmNo": "Cancel",
1260
1327
  "panels.market.failed": "Failed: {reason}",
1261
1328
  "panels.market.needEnv": "Set {env} in the terminal that started the workbench first",
1329
+ "panels.market.needCommands": "Missing commands: {commands}",
1330
+ "panels.market.localMark": "local",
1331
+ "panels.market.localHint": "This is your machine’s own copy (not taken from the registry).",
1262
1332
  "panels.market.noSource": "This module declares no install method — install it yourself",
1263
1333
  "panels.market.badSource": "The install method is incomplete — install it yourself",
1264
1334
  "panels.market.empty": "No modules available",
1265
- "panels.market.sectionLocal": "Local modules",
1266
- "panels.market.sectionUnlisted": "Not from the market",
1267
1335
  "panels.market.sectionPlugins": "Installed opencli plugins",
1268
1336
  "panels.market.moduleOutdated": "update available",
1269
- "panels.market.moduleRefused": "This module was built for an older version of the workbench, so it does not work here. Update it, or uninstall.",
1337
+ "panels.market.moduleRefused": "This module does not match this workbench, so it cannot be used for now.",
1270
1338
  "panels.market.moduleRefusedDetail": "Why it cannot be used: {reason}",
1271
- "panels.market.moduleRestartHint": "installed but not active — restart dsh once to bring it up",
1339
+ "panels.market.moduleRestartHint": "restart dsh once to bring it up",
1340
+ "panels.market.workbenchName": "Workbench",
1341
+ "panels.market.workbenchLocal": "This is the copy from your working repository; it does not come from the registry.",
1272
1342
  "panels.market.pluginKeptInUse": "Files kept for now: {names} still uses it.",
1273
1343
  "panels.market.pluginKeptUnsure": "Files kept for now: some modules on this machine do not say what they use, so it is unclear who needs it.",
1274
1344
  "panels.market.pluginKeptHeld": "Files kept: this one is yours, and a module letting go will not remove it.",
1275
1345
  "panels.market.pluginKeptUnnamed": "Files kept for now: this one cannot be identified as a plugin, so it is unclear who needs it.",
1276
- "panels.market.pluginAlsoKnownAs": "Its package is {pkg} (updates and uninstall use that)",
1277
- "panels.market.pluginBroken": "This install is broken: it cannot be identified as a plugin. Uninstall it, or install it again by package name above.",
1346
+ "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).",
1278
1347
  "panels.market.restartNeeded": "The new version is installed — restart once to pick it up.",
1279
1348
  "panels.market.foot": "After installing, enable it in the panel page of that project.",
1280
1349
  "panels.market.recheck": "Check for updates",
@@ -1283,7 +1352,7 @@ var en = {
1283
1352
  "panels.market.justNow": "just now",
1284
1353
  "panels.market.minutesAgo": "{n} min ago",
1285
1354
  "panels.market.hoursAgo": "{n} h ago",
1286
- "panels.market.add.description": "Enter a package name, a Git URL, or a path to a local directory.",
1355
+ "panels.market.add.description": "Enter a module or opencli plugin package name, Git repository URL, or local directory path.",
1287
1356
  "panels.market.add.specPlaceholder": "e.g. @dsh-workbench/module-hello",
1288
1357
  "panels.market.add.guideToggle": "Install guide and examples",
1289
1358
  "panels.market.add.guideHide": "Hide guide",
@@ -1322,11 +1391,13 @@ var en = {
1322
1391
  "panels.market.add.problemInstalled": "This module is already installed",
1323
1392
  "panels.market.add.problemNotFound": "No such module found",
1324
1393
  "panels.market.add.problemNotPackage": "That path does not exist or is not a valid module package",
1325
- "panels.market.add.problemNotBundle": "This package cannot be installed here: {reason}. If it is actually an opencli plugin, use its package name (for example opencli-plugin-cmdb) or a local folder — a git URL or tarball does not reveal what it is.",
1394
+ "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.",
1326
1395
  "panels.market.add.problemNotWorkbenchModule": "This package does not match the workbench you are running, so installing it would not work. Pick another version, or ask the module author.",
1327
1396
  "panels.market.add.problemNotModuleOrPlugin": "This package is neither a workbench module nor an opencli plugin, so installing it would do nothing. Pick another version, or ask the package author.",
1328
1397
  "panels.market.add.failureNotModuleOrPlugin": "This package is neither a workbench module nor an opencli plugin, so installing it would do nothing",
1329
1398
  "panels.market.add.installedPlugin": "Installed: the opencli plugin {name}",
1399
+ "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.",
1400
+ "panels.market.add.pluginAlias": "Plugin name: {name}",
1330
1401
  "panels.market.add.problemNetwork": "Cannot reach the module source; check the network and retry",
1331
1402
  "panels.market.add.problemUnknown": "Cannot fetch module information: {reason}",
1332
1403
  "panels.market.add.failureNetwork": "The network connection failed",
@@ -1357,7 +1428,7 @@ var en = {
1357
1428
  "panels.market.add.registryPnpm": "pnpm's own registry",
1358
1429
  "panels.market.add.check": "Check",
1359
1430
  "panels.market.add.checking": "Checking…",
1360
- "panels.market.add.classifying": "Working out what it is…",
1431
+ "panels.market.add.classifying": "Checking…",
1361
1432
  "panels.market.add.change": "Edit",
1362
1433
  "panels.market.add.previewTitle": "About to install",
1363
1434
  "panels.market.add.fieldName": "Package",
@@ -1504,6 +1575,8 @@ var zh = {
1504
1575
  "project.none": "未选择项目",
1505
1576
  "project.empty": "还没有项目。用下面的「添加项目」选一个目录。",
1506
1577
  "project.add": "添加项目…",
1578
+ "project.add.busy": "正在新建工作区…",
1579
+ "project.add.failed": "新建工作区没成功",
1507
1580
  "project.search.label": "搜索工作区",
1508
1581
  "project.search.placeholder": "搜索工作区(目录名 / 中文名 / 路径)",
1509
1582
  "project.search.empty": "没有匹配「{query}」的工作区。",
@@ -1537,13 +1610,22 @@ var zh = {
1537
1610
  "time.hours": "{n} 小时前",
1538
1611
  "time.days": "{n} 天前",
1539
1612
  "panels.title": "面板模块",
1540
- "panels.reset": "恢复默认",
1613
+ "panels.groupBoardless": "无看板模块",
1614
+ "panels.groupPlugins": "opencli 插件",
1615
+ "panels.market.defaultHint": "打开后所有工作区默认开启,也可在工作区面板配置中单独关闭",
1616
+ "panels.market.defaultLabel": "全局默认开启",
1617
+ "panels.market.defaultLocked": "这份现在用不了,先更新或卸载",
1618
+ "panels.followAll": "全部恢复默认",
1619
+ "panels.followAllConfirmTitle": "全部恢复默认?",
1620
+ "panels.followAllConfirmDetail": "这个工作区里改过的每一行都会清掉,之后都跟随全局。",
1621
+ "panels.followAllConfirmAck": "我明白:清掉之后,想再按这个工作区配,得一行一行重新改。",
1622
+ "panels.followAllConfirmYes": "恢复默认",
1623
+ "panels.followAllConfirmNo": "取消",
1541
1624
  "panels.enabled": "这个项目已启用",
1542
1625
  "panels.disabled": "这个项目未启用",
1543
1626
  "panels.choose": "选择模块",
1544
1627
  "panels.buildModule": "造一个模块",
1545
1628
  "panels.failed": "改配置失败了,再试一次。",
1546
- "panels.hintEffect": "停用 = agent 拿不到相关数据",
1547
1629
  "panels.dragHint": "拖动调整顺序",
1548
1630
  "panels.unknownStep": "这一层没有套件提供",
1549
1631
  "panels.labelWithHint": "{label}({hint})",
@@ -1557,7 +1639,9 @@ var zh = {
1557
1639
  "panels.noneInstalled": "这些模块要的插件都还没装",
1558
1640
  "panels.noneInstalledHint": "装好之后它们会回到这里,再由你决定放哪几个上板。",
1559
1641
  "panels.market.installed": "已安装",
1560
- "panels.market.outdated": "要更新",
1642
+ "panels.market.notActive": "未生效",
1643
+ "panels.market.notUsable": "不可用",
1644
+ "panels.market.broken": "装坏了",
1561
1645
  "panels.market.hasNew": "有新版本",
1562
1646
  "panels.market.missing": "未装",
1563
1647
  "panels.market.unchecked": "状态未知",
@@ -1565,7 +1649,7 @@ var zh = {
1565
1649
  "panels.market.sectionInstalled": "已安装模块",
1566
1650
  "panels.market.sectionPending": "未安装",
1567
1651
  "panels.market.sectionShared": "共用依赖",
1568
- "panels.market.sharedUsedBy": "供 {modules} 使用",
1652
+ "panels.market.sharedUsedBy": "供 {modules} 模块使用",
1569
1653
  "panels.market.listSeparator": "、",
1570
1654
  "panels.market.sharedMissing": "未装",
1571
1655
  "panels.market.sharedOutdated": "有新版",
@@ -1587,22 +1671,24 @@ var zh = {
1587
1671
  "panels.market.confirmNo": "取消",
1588
1672
  "panels.market.failed": "没成功:{reason}",
1589
1673
  "panels.market.needEnv": "先在启动工作台的终端里设 {env}",
1674
+ "panels.market.needCommands": "缺这几条命令:{commands}",
1675
+ "panels.market.localMark": "本地",
1676
+ "panels.market.localHint": "本机那份(不从源上取)。",
1590
1677
  "panels.market.noSource": "这个模块没声明怎么装,只能自己动手",
1591
1678
  "panels.market.badSource": "安装方式没写全,只能自己动手",
1592
1679
  "panels.market.empty": "暂无可用模块",
1593
- "panels.market.sectionLocal": "本地模块",
1594
- "panels.market.sectionUnlisted": "不是从市场装的",
1595
1680
  "panels.market.sectionPlugins": "已安装 opencli 插件",
1596
1681
  "panels.market.moduleOutdated": "有新版",
1597
- "panels.market.moduleRefused": "这个模块是给旧版本的工作台写的,现在用不了。更新它,或者卸载。",
1682
+ "panels.market.moduleRefused": "模块版本与工作台不匹配,暂时无法使用",
1598
1683
  "panels.market.moduleRefusedDetail": "装不上的原因:{reason}",
1599
- "panels.market.moduleRestartHint": "装好了但还没生效 —— 重启一次 dsh 就会出来",
1684
+ "panels.market.moduleRestartHint": "重启后生效",
1685
+ "panels.market.workbenchName": "工作台",
1686
+ "panels.market.workbenchLocal": "这份是本仓正在开发的那一份,不从源上取。",
1600
1687
  "panels.market.pluginKeptInUse": "文件先留着:{names} 还要用它。",
1601
1688
  "panels.market.pluginKeptUnsure": "文件先留着:这台机器上还有模块看不出用了什么,说不准谁在用它。",
1602
1689
  "panels.market.pluginKeptHeld": "文件留着:你自己装的那一份,模块放手不动它。",
1603
1690
  "panels.market.pluginKeptUnnamed": "文件先留着:看不出这是哪个插件,说不准谁在用它。",
1604
- "panels.market.pluginAlsoKnownAs": "包名是 {pkg}(更新与卸载按它来)",
1605
- "panels.market.pluginBroken": "这份装坏了:看不出它是个插件。可以卸载,或者去上面按包名再装一次。",
1691
+ "panels.market.pluginBroken": "这份装坏了:看不出它是个插件。可以卸载,或者直接跟 agent 说:用 workbench_modules 的 install-bundle 按包名再装一次。",
1606
1692
  "panels.market.restartNeeded": "新版装好了,重启一次才生效。",
1607
1693
  "panels.market.foot": "装好后到那个项目的面板页勾选它,模块才会出现。",
1608
1694
  "panels.market.recheck": "重新检查更新",
@@ -1611,7 +1697,7 @@ var zh = {
1611
1697
  "panels.market.justNow": "刚刚",
1612
1698
  "panels.market.minutesAgo": "{n} 分钟前",
1613
1699
  "panels.market.hoursAgo": "{n} 小时前",
1614
- "panels.market.add.description": "输入模块的包名、Git 仓库地址或本地目录路径。",
1700
+ "panels.market.add.description": "输入模块或 opencli 插件的包名、Git 仓库地址或本地目录路径。",
1615
1701
  "panels.market.add.specPlaceholder": "例如 @dsh-workbench/module-hello",
1616
1702
  "panels.market.add.guideToggle": "模块安装引导和示例",
1617
1703
  "panels.market.add.guideHide": "收起引导",
@@ -1650,11 +1736,13 @@ var zh = {
1650
1736
  "panels.market.add.problemInstalled": "该模块已安装",
1651
1737
  "panels.market.add.problemNotFound": "未找到相关模块",
1652
1738
  "panels.market.add.problemNotPackage": "该路径不存在或不是有效的模块包",
1653
- "panels.market.add.problemNotBundle": "这个包装不进这里:{reason}。要是它其实是个 opencli 插件,请改用包名(例如 opencli-plugin-cmdb)或者本地目录 —— 从 git 地址和 tarball 判断不出它是什么。",
1739
+ "panels.market.add.problemNotBundle": "这个包装不进这里:{reason}。这个入口按包名认工作台模块和 opencli 插件,两种都能装;但 git 地址和 tarball 判断不出它是什么 —— 要是它其实是这两样之一,请改填包名或本地目录。",
1654
1740
  "panels.market.add.problemNotWorkbenchModule": "这个包跟现在的工作台对不上,装上也用不了。换一个版本,或者找这个模块的作者。",
1655
1741
  "panels.market.add.problemNotModuleOrPlugin": "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上。换一个版本,或者找这个包的作者。",
1656
1742
  "panels.market.add.failureNotModuleOrPlugin": "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上",
1657
1743
  "panels.market.add.installedPlugin": "装上了:opencli 插件 {name}",
1744
+ "panels.market.add.pluginPreview": "这是一份 opencli 插件:装进 opencli 的插件区,装完就能用,不用重启。",
1745
+ "panels.market.add.pluginAlias": "插件名:{name}",
1658
1746
  "panels.market.add.problemNetwork": "无法连接模块源,请检查网络后重试",
1659
1747
  "panels.market.add.problemUnknown": "无法获取模块信息:{reason}",
1660
1748
  "panels.market.add.failureNetwork": "网络连接失败",
@@ -1685,7 +1773,7 @@ var zh = {
1685
1773
  "panels.market.add.registryPnpm": "pnpm 自己配的源",
1686
1774
  "panels.market.add.check": "预检",
1687
1775
  "panels.market.add.checking": "正在预检…",
1688
- "panels.market.add.classifying": "判定中…",
1776
+ "panels.market.add.classifying": "检测中…",
1689
1777
  "panels.market.add.change": "改一下",
1690
1778
  "panels.market.add.previewTitle": "将要安装",
1691
1779
  "panels.market.add.fieldName": "包名",
@@ -1909,6 +1997,203 @@ function holdBusy(since, now, floorMs) {
1909
1997
  releaseInMs: left
1910
1998
  };
1911
1999
  }
2000
+ var PANEL_STATE_CRASH_WINDOW_MS = 6e5;
2001
+ var PANEL_STATE_MAX_TEXT = 2e3;
2002
+ var PHASES = [
2003
+ "idle",
2004
+ "loading",
2005
+ "ready",
2006
+ "error"
2007
+ ];
2008
+ function asRecord(value) {
2009
+ return typeof value === "object" && value !== null ? value : void 0;
2010
+ }
2011
+ function textOf(value, max) {
2012
+ if (typeof value !== "string") return "";
2013
+ const trimmed = value.trim();
2014
+ return trimmed.length > max ? trimmed.slice(0, max) : trimmed;
2015
+ }
2016
+ function atOf(value) {
2017
+ if (typeof value !== "number" || !Number.isFinite(value)) return null;
2018
+ if (value < 0) return null;
2019
+ return Math.trunc(value);
2020
+ }
2021
+ function errorOf(raw) {
2022
+ const record = asRecord(raw);
2023
+ if (record === void 0) return void 0;
2024
+ const code = textOf(record["code"], 120);
2025
+ const message = textOf(record["message"], PANEL_STATE_MAX_TEXT);
2026
+ if (code === "" && message === "") return void 0;
2027
+ return {
2028
+ code: code === "" ? "unknown" : code,
2029
+ message
2030
+ };
2031
+ }
2032
+ function parseCardsReport(payload) {
2033
+ const record = asRecord(payload);
2034
+ if (record === void 0) return {
2035
+ ok: false,
2036
+ message: "请求体要是一个对象"
2037
+ };
2038
+ const workspace = textOf(record["workspace"], PANEL_STATE_MAX_TEXT);
2039
+ if (workspace === "") return {
2040
+ ok: false,
2041
+ message: "workspace 不能是空的 —— 面板按工作区存"
2042
+ };
2043
+ const raw = record["cards"];
2044
+ if (!Array.isArray(raw)) return {
2045
+ ok: false,
2046
+ message: "cards 要是一个数组"
2047
+ };
2048
+ const cards = [];
2049
+ for (const item of raw.slice(0, 32)) {
2050
+ const card = asRecord(item);
2051
+ if (card === void 0) continue;
2052
+ const unit = textOf(card["unit"], 200);
2053
+ const route = textOf(card["route"], 400);
2054
+ const phase = textOf(card["phase"], 20);
2055
+ const at = atOf(card["at"]);
2056
+ if (unit === "" || route === "" || at === null || !PHASES.includes(phase)) continue;
2057
+ const error = errorOf(card["error"]);
2058
+ cards.push({
2059
+ unit,
2060
+ route,
2061
+ phase,
2062
+ at,
2063
+ ...error === void 0 ? {} : { error }
2064
+ });
2065
+ }
2066
+ if (cards.length === 0) return {
2067
+ ok: false,
2068
+ message: "cards 里没有一条能认的(unit / route / phase / at 都要有)"
2069
+ };
2070
+ return {
2071
+ ok: true,
2072
+ value: {
2073
+ workspace,
2074
+ cards
2075
+ }
2076
+ };
2077
+ }
2078
+ function parseCrashReport(payload) {
2079
+ const record = asRecord(payload);
2080
+ if (record === void 0) return {
2081
+ ok: false,
2082
+ message: "请求体要是一个对象"
2083
+ };
2084
+ const workspace = textOf(record["workspace"], PANEL_STATE_MAX_TEXT);
2085
+ const unit = textOf(record["unit"], 200);
2086
+ const reason = textOf(record["reason"], PANEL_STATE_MAX_TEXT);
2087
+ if (workspace === "") return {
2088
+ ok: false,
2089
+ message: "workspace 不能是空的"
2090
+ };
2091
+ if (unit === "") return {
2092
+ ok: false,
2093
+ message: "unit 不能是空的"
2094
+ };
2095
+ if (reason === "") return {
2096
+ ok: false,
2097
+ message: "reason 不能是空的(没有原因的崩溃没法查)"
2098
+ };
2099
+ return {
2100
+ ok: true,
2101
+ value: {
2102
+ workspace,
2103
+ unit,
2104
+ reason,
2105
+ at: atOf(record["at"]) ?? Date.now()
2106
+ }
2107
+ };
2108
+ }
2109
+ function createPanelStateStore() {
2110
+ const workspaces = /* @__PURE__ */ new Map();
2111
+ function trim(entry, max) {
2112
+ while (entry.size > max) {
2113
+ const oldest = entry.keys().next();
2114
+ if (oldest.done === true) return;
2115
+ entry.delete(oldest.value);
2116
+ }
2117
+ }
2118
+ function workspaceEntryOf(workspace) {
2119
+ const existing = workspaces.get(workspace);
2120
+ if (existing !== void 0) return existing;
2121
+ const created = {
2122
+ at: 0,
2123
+ units: /* @__PURE__ */ new Map()
2124
+ };
2125
+ workspaces.set(workspace, created);
2126
+ trim(workspaces, 64);
2127
+ return created;
2128
+ }
2129
+ function unitEntryOf(entry, unit) {
2130
+ const existing = entry.units.get(unit);
2131
+ if (existing !== void 0) return existing;
2132
+ const created = {
2133
+ at: 0,
2134
+ cards: /* @__PURE__ */ new Map()
2135
+ };
2136
+ entry.units.set(unit, created);
2137
+ return created;
2138
+ }
2139
+ return {
2140
+ cards(report) {
2141
+ const entry = workspaceEntryOf(report.workspace);
2142
+ for (const card of report.cards) {
2143
+ const unit = unitEntryOf(entry, card.unit);
2144
+ unit.cards.delete(card.route);
2145
+ unit.cards.set(card.route, card);
2146
+ trim(unit.cards, 12);
2147
+ if (card.at > unit.at) unit.at = card.at;
2148
+ if (card.at > entry.at) entry.at = card.at;
2149
+ }
2150
+ },
2151
+ crash(report) {
2152
+ const entry = workspaceEntryOf(report.workspace);
2153
+ const unit = unitEntryOf(entry, report.unit);
2154
+ const previous = unit.crash;
2155
+ const counted = previous !== void 0 && previous.reason === report.reason && report.at >= previous.at && report.at - previous.at <= 6e5;
2156
+ unit.crash = {
2157
+ unit: report.unit,
2158
+ reason: report.reason,
2159
+ at: report.at,
2160
+ count: counted ? previous.count + 1 : 1
2161
+ };
2162
+ if (report.at > unit.at) unit.at = report.at;
2163
+ if (report.at > entry.at) entry.at = report.at;
2164
+ },
2165
+ snapshot(workspace) {
2166
+ if (workspace === null) return {
2167
+ workspace: null,
2168
+ at: 0,
2169
+ units: []
2170
+ };
2171
+ const entry = workspaces.get(workspace);
2172
+ if (entry === void 0) return {
2173
+ workspace,
2174
+ at: 0,
2175
+ units: []
2176
+ };
2177
+ const units = [...entry.units.entries()].map(([unit, one]) => {
2178
+ const cards = [...one.cards.values()].sort((a, b) => a.route.localeCompare(b.route));
2179
+ const okAt = cards.reduce((best, card) => card.phase === "ready" && (best === null || card.at > best) ? card.at : best, null);
2180
+ return {
2181
+ unit,
2182
+ at: one.at,
2183
+ okAt,
2184
+ cards,
2185
+ ...one.crash === void 0 ? {} : { crash: one.crash }
2186
+ };
2187
+ });
2188
+ units.sort((a, b) => b.at - a.at || a.unit.localeCompare(b.unit));
2189
+ return {
2190
+ workspace,
2191
+ at: entry.at,
2192
+ units
2193
+ };
2194
+ }
2195
+ };
2196
+ }
1912
2197
  //#endregion
1913
2198
  //#region ../shared/dist/lib/text.js
1914
2199
  function quoteShellArg(value) {
@@ -1976,6 +2261,8 @@ var dist_exports = /* @__PURE__ */ __exportAll({
1976
2261
  IconBrandMark: () => IconBrandMark,
1977
2262
  IconConversation: () => IconConversation,
1978
2263
  IconModules: () => IconModules,
2264
+ IconNpm: () => IconNpm,
2265
+ IconOpencli: () => IconOpencli,
1979
2266
  IconPanelScreen: () => IconPanelScreen,
1980
2267
  LOCALES: () => LOCALES,
1981
2268
  LOCALE_NS: () => LOCALE_NS,
@@ -1992,6 +2279,14 @@ var dist_exports = /* @__PURE__ */ __exportAll({
1992
2279
  PANELS_SERVICE: () => PANELS_SERVICE,
1993
2280
  PANEL_LIST_LIMIT: () => 50,
1994
2281
  PANEL_POLL_MS: () => PANEL_POLL_MS,
2282
+ PANEL_STATE_CRASH_WINDOW_MS: () => PANEL_STATE_CRASH_WINDOW_MS,
2283
+ PANEL_STATE_MAX_CARDS: () => 12,
2284
+ PANEL_STATE_MAX_REPORTS: () => 32,
2285
+ PANEL_STATE_MAX_TEXT: () => PANEL_STATE_MAX_TEXT,
2286
+ PANEL_STATE_MAX_UNITS: () => 64,
2287
+ PANEL_STATE_PATH: () => PANEL_STATE_PATH,
2288
+ PANEL_STATE_PREFIX: () => PANEL_STATE_PREFIX,
2289
+ PANEL_STATE_SERVICE: () => PANEL_STATE_SERVICE,
1995
2290
  PLUGIN_ID: () => PLUGIN_ID,
1996
2291
  PREFS_PREFIX: () => PREFS_PREFIX,
1997
2292
  PROBE_TTL_MS: () => PROBE_TTL_MS,
@@ -2022,6 +2317,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2022
2317
  blockerPending: () => blockerPending,
2023
2318
  buildMarker: () => buildMarker,
2024
2319
  createFactChannel: () => createFactChannel,
2320
+ createPanelStateStore: () => createPanelStateStore,
2025
2321
  cx: () => cx,
2026
2322
  declarationProblemsOf: () => declarationProblemsOf,
2027
2323
  decodeRef: () => decodeRef,
@@ -2033,6 +2329,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2033
2329
  factOfRoute: () => factOfRoute,
2034
2330
  gateOf: () => gateOf,
2035
2331
  h: () => h,
2332
+ hasEnvSupply: () => hasEnvSupply,
2036
2333
  holdBusy: () => holdBusy,
2037
2334
  isFactScope: () => isFactScope,
2038
2335
  longTaskDot: () => longTaskDot,
@@ -2041,6 +2338,8 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2041
2338
  markerBody: () => markerBody,
2042
2339
  mergeMessages: () => mergeMessages,
2043
2340
  mergeMessagesSkipping: () => mergeMessagesSkipping,
2341
+ parseCardsReport: () => parseCardsReport,
2342
+ parseCrashReport: () => parseCrashReport,
2044
2343
  parseFactFrame: () => parseFactFrame,
2045
2344
  parseJsonLoose: () => parseJsonLoose,
2046
2345
  parseLocalTimestamp: () => parseLocalTimestamp,
@@ -2414,6 +2713,197 @@ function holdBack(installed, roster, active, previous) {
2414
2713
  return pending.filter((unit) => active.has(unit) || fresh.includes(unit));
2415
2714
  }
2416
2715
  //#endregion
2716
+ //#region src/app/layouts/rightbar/market-installed-mock.ts
2717
+ function installedMocks(input) {
2718
+ const { id, found, mine, probe } = input;
2719
+ return [
2720
+ {
2721
+ id: "no-supply",
2722
+ label: "没有环境依赖的模块(供给是基座命令那种):市场里有它这一行",
2723
+ manifests: [found],
2724
+ capabilities: probe(id, "ok"),
2725
+ installed: [{
2726
+ unit: id,
2727
+ pkg: "@dsh-workbench/module-one",
2728
+ installed: "0.1.2"
2729
+ }],
2730
+ expect: {
2731
+ rows: 1,
2732
+ state: "installed",
2733
+ actions: ["uninstall"],
2734
+ installed: 0,
2735
+ shared: 0
2736
+ }
2737
+ },
2738
+ {
2739
+ id: "no-card",
2740
+ label: "没有卡片的模块(只有基座命令那种):市场里有它这一行,有版本、有「更新」",
2741
+ manifests: [{
2742
+ ...found,
2743
+ card: null
2744
+ }],
2745
+ capabilities: probe(id, "ok"),
2746
+ updates: { [id]: {
2747
+ installed: "0.1.2",
2748
+ latest: "0.2.0"
2749
+ } },
2750
+ installed: [{
2751
+ unit: id,
2752
+ pkg: "@dsh-workbench/module-one",
2753
+ installed: "0.1.2"
2754
+ }],
2755
+ expect: {
2756
+ rows: 1,
2757
+ state: "outdated",
2758
+ actions: ["update-bundle", "uninstall"],
2759
+ version: {
2760
+ installed: "0.1.2",
2761
+ latest: "0.2.0"
2762
+ },
2763
+ installed: 0,
2764
+ shared: 0
2765
+ }
2766
+ },
2767
+ {
2768
+ id: "no-env-installed",
2769
+ label: "本机装着、又没有依赖要探(DIY 本地那份那种):写「已安装」,不是「状态未知」",
2770
+ manifests: [{
2771
+ ...found,
2772
+ env: void 0
2773
+ }],
2774
+ capabilities: {},
2775
+ updates: { [id]: { installed: "0.1.2" } },
2776
+ installed: [{
2777
+ unit: id,
2778
+ pkg: "@dsh-workbench/module-one",
2779
+ installed: "0.1.2"
2780
+ }],
2781
+ expect: {
2782
+ rows: 1,
2783
+ state: "installed",
2784
+ actions: ["uninstall"],
2785
+ version: { installed: "0.1.2" },
2786
+ installed: 0
2787
+ }
2788
+ },
2789
+ {
2790
+ id: "local-no-update",
2791
+ label: "本机那份(link: 装的):有「本地」标记、不给「更新」",
2792
+ manifests: [mine],
2793
+ capabilities: probe(id, "ok", { plugins: [{
2794
+ name: "fixture",
2795
+ status: "ok",
2796
+ missing: []
2797
+ }] }),
2798
+ updates: { [id]: {
2799
+ installed: "0.1.0",
2800
+ local: true
2801
+ } },
2802
+ installed: [{
2803
+ unit: id,
2804
+ pkg: "@dsh-workbench/module-one",
2805
+ installed: "0.1.0",
2806
+ local: true
2807
+ }],
2808
+ expect: {
2809
+ rows: 1,
2810
+ state: "installed",
2811
+ actions: ["uninstall"],
2812
+ local: true,
2813
+ version: { installed: "0.1.0" },
2814
+ installed: 0
2815
+ }
2816
+ },
2817
+ {
2818
+ id: "installed-refused",
2819
+ label: "本机装了,但宿主不认它的声明(行上说得出理由)",
2820
+ manifests: [],
2821
+ capabilities: {},
2822
+ installed: [{
2823
+ unit: id,
2824
+ pkg: "@dsh-workbench/module-one",
2825
+ installed: "0.1.2",
2826
+ refused: ["dsh.workbench 缺 apiVersion —— 协议从 v1 起,写 \"apiVersion\": 1"]
2827
+ }],
2828
+ expect: {
2829
+ rows: 0,
2830
+ installed: 1,
2831
+ installedState: "unusable",
2832
+ installedActions: ["remove-bundle"],
2833
+ installedNote: true
2834
+ }
2835
+ },
2836
+ {
2837
+ id: "installed-pending",
2838
+ label: "本机装了、宿主还没加载它(重启一次就会出来)",
2839
+ manifests: [],
2840
+ capabilities: {},
2841
+ installed: [{
2842
+ unit: id,
2843
+ pkg: "@dsh-workbench/module-one",
2844
+ installed: "0.1.2"
2845
+ }],
2846
+ expect: {
2847
+ rows: 0,
2848
+ installed: 1,
2849
+ installedState: "inactive",
2850
+ installedActions: ["remove-bundle"],
2851
+ installedHint: "panels.market.moduleRestartHint"
2852
+ }
2853
+ },
2854
+ {
2855
+ id: "installed-pending-update",
2856
+ label: "本机装了、还没加载 + 源上有新版(给「更新」,也说明要重启)",
2857
+ manifests: [],
2858
+ capabilities: {},
2859
+ installed: [{
2860
+ unit: id,
2861
+ pkg: "@dsh-workbench/module-one",
2862
+ installed: "0.1.0",
2863
+ latest: "0.1.2"
2864
+ }],
2865
+ expect: {
2866
+ rows: 0,
2867
+ installed: 1,
2868
+ installedState: "outdated",
2869
+ installedActions: ["update-bundle", "remove-bundle"],
2870
+ installedHint: "panels.market.moduleRestartHint"
2871
+ }
2872
+ },
2873
+ {
2874
+ id: "installed-confirm",
2875
+ label: "卸载本机模块(还没加载的那种:Modal 确认,标题是包名)",
2876
+ manifests: [],
2877
+ capabilities: {},
2878
+ installed: [{
2879
+ unit: id,
2880
+ pkg: "@dsh-workbench/module-one",
2881
+ installed: "0.1.2"
2882
+ }],
2883
+ confirming: id,
2884
+ expect: {
2885
+ rows: 0,
2886
+ installed: 1,
2887
+ installedState: "inactive",
2888
+ installedActions: ["remove-bundle"]
2889
+ }
2890
+ },
2891
+ {
2892
+ id: "first-paint",
2893
+ label: "刚进页面(检测中:能力与本机清单都还没结论)",
2894
+ manifests: [mine],
2895
+ capabilities: null,
2896
+ installedRead: false,
2897
+ loaded: false,
2898
+ expect: {
2899
+ rows: 1,
2900
+ state: "checking",
2901
+ actions: []
2902
+ }
2903
+ }
2904
+ ];
2905
+ }
2906
+ //#endregion
2417
2907
  //#region src/app/layouts/rightbar/market-mock.ts
2418
2908
  function installable(manifest) {
2419
2909
  return {
@@ -2524,7 +3014,8 @@ function buildMarketMocks(roster) {
2524
3014
  expect: {
2525
3015
  rows: 1,
2526
3016
  state: "outdated",
2527
- actions: ["update", "uninstall"]
3017
+ actions: ["update", "uninstall"],
3018
+ noteKey: "panels.market.needCommands"
2528
3019
  }
2529
3020
  },
2530
3021
  {
@@ -2769,109 +3260,38 @@ function buildMarketMocks(roster) {
2769
3260
  actions: ["uninstall"]
2770
3261
  }
2771
3262
  },
3263
+ ...installedMocks({
3264
+ id,
3265
+ found,
3266
+ mine,
3267
+ probe: probe$1
3268
+ }),
2772
3269
  {
2773
- id: "installed-half",
2774
- label: "本机装了模块,但它没有环境依赖(供给那半没有它)",
2775
- manifests: [found],
2776
- capabilities: {},
2777
- installed: [{
2778
- unit: id,
2779
- pkg: "@dsh-workbench/module-one",
2780
- installed: "0.1.2"
2781
- }],
3270
+ id: "shared-many",
3271
+ label: "三个模块(同一份安装)",
3272
+ manifests: [
3273
+ mine,
3274
+ twin(mine),
3275
+ {
3276
+ ...twin(mine),
3277
+ id: `${mine.id}-c`
3278
+ }
3279
+ ],
3280
+ capabilities: {
3281
+ ...probe$1(id, "ok"),
3282
+ ...probe$1(secondId, "ok"),
3283
+ ...probe$1(`${mine.id}-c`, "ok")
3284
+ },
2782
3285
  expect: {
2783
- rows: 0,
2784
- installed: 1,
2785
- installedActions: ["remove-bundle"]
3286
+ rows: 3,
3287
+ state: "installed",
3288
+ actions: ["uninstall"]
2786
3289
  }
2787
3290
  },
2788
3291
  {
2789
- id: "installed-half-update",
2790
- label: "本机装了模块 + 源上有新版(给「更新」,装完要重启)",
2791
- manifests: [found],
2792
- capabilities: {},
2793
- installed: [{
2794
- unit: id,
2795
- pkg: "@dsh-workbench/module-one",
2796
- installed: "0.1.0",
2797
- latest: "0.1.2"
2798
- }],
2799
- expect: {
2800
- rows: 0,
2801
- installed: 1,
2802
- installedActions: ["update-bundle", "remove-bundle"]
2803
- }
2804
- },
2805
- {
2806
- id: "installed-client-refused",
2807
- label: "本机装了,但浏览器这半没挂上(拒因由客户端报告)",
2808
- manifests: [found],
2809
- capabilities: {},
2810
- installed: [{
2811
- unit: id,
2812
- pkg: "@dsh-workbench/module-one",
2813
- installed: "0.1.2",
2814
- clientRefused: [`宿主没有担保 unit「${id}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]
2815
- }],
2816
- expect: {
2817
- rows: 0,
2818
- installed: 1,
2819
- installedActions: ["remove-bundle"],
2820
- installedNote: true
2821
- }
2822
- },
2823
- {
2824
- id: "installed-confirm",
2825
- label: "卸载本机模块(Modal 确认,标题带模块名)",
2826
- manifests: [found],
2827
- capabilities: {},
2828
- installed: [{
2829
- unit: id,
2830
- pkg: "@dsh-workbench/module-one",
2831
- installed: "0.1.2"
2832
- }],
2833
- confirming: id,
2834
- expect: {
2835
- rows: 0,
2836
- installed: 1,
2837
- installedActions: ["remove-bundle"]
2838
- }
2839
- },
2840
- {
2841
- id: "first-paint",
2842
- label: "刚进页面(检测中:能力与本机清单都还没结论)",
2843
- manifests: [found],
2844
- capabilities: null,
2845
- installedRead: false,
2846
- loaded: false,
2847
- expect: { rows: 0 }
2848
- },
2849
- {
2850
- id: "shared-many",
2851
- label: "三个模块(同一份安装)",
2852
- manifests: [
2853
- mine,
2854
- twin(mine),
2855
- {
2856
- ...twin(mine),
2857
- id: `${mine.id}-c`
2858
- }
2859
- ],
2860
- capabilities: {
2861
- ...probe$1(id, "ok"),
2862
- ...probe$1(secondId, "ok"),
2863
- ...probe$1(`${mine.id}-c`, "ok")
2864
- },
2865
- expect: {
2866
- rows: 3,
2867
- state: "installed",
2868
- actions: ["uninstall"]
2869
- }
2870
- },
2871
- {
2872
- id: "plugin-outdated",
2873
- label: "用户装的 opencli 插件:有新版(给更新 / 卸载)",
2874
- manifests: [],
3292
+ id: "plugin-outdated",
3293
+ label: "用户装的 opencli 插件:有新版(给更新 / 卸载)",
3294
+ manifests: [],
2875
3295
  capabilities: {},
2876
3296
  plugins: [{
2877
3297
  pkg: "opencli-plugin-cmdb",
@@ -2916,8 +3336,7 @@ function buildMarketMocks(roster) {
2916
3336
  expect: {
2917
3337
  rows: 0,
2918
3338
  plugins: 1,
2919
- pluginActions: ["update-plugin", "uninstall-plugin"],
2920
- pluginNoteKey: "panels.market.pluginAlsoKnownAs"
3339
+ pluginActions: ["update-plugin", "uninstall-plugin"]
2921
3340
  }
2922
3341
  },
2923
3342
  {
@@ -2934,6 +3353,7 @@ function buildMarketMocks(roster) {
2934
3353
  expect: {
2935
3354
  rows: 0,
2936
3355
  plugins: 1,
3356
+ pluginState: "broken",
2937
3357
  pluginActions: ["uninstall-plugin"],
2938
3358
  pluginNoteKey: "panels.market.pluginBroken"
2939
3359
  }
@@ -2956,6 +3376,70 @@ function buildMarketMocks(roster) {
2956
3376
  notice: true
2957
3377
  }
2958
3378
  },
3379
+ {
3380
+ id: "workbench-update",
3381
+ label: "工作台有新版(这一行也给「更新」,装完面板自己换上)",
3382
+ manifests: [],
3383
+ capabilities: {},
3384
+ workbench: {
3385
+ pkg: "@dsh-workbench/core",
3386
+ installed: "0.1.18",
3387
+ latest: "0.1.19"
3388
+ },
3389
+ expect: {
3390
+ rows: 0,
3391
+ workbenchState: "outdated",
3392
+ workbenchActions: ["update-workbench"]
3393
+ }
3394
+ },
3395
+ {
3396
+ id: "workbench-current",
3397
+ label: "工作台已经最新(只显示版本,没有按钮)",
3398
+ manifests: [],
3399
+ capabilities: {},
3400
+ workbench: {
3401
+ pkg: "@dsh-workbench/core",
3402
+ installed: "0.1.19"
3403
+ },
3404
+ expect: {
3405
+ rows: 0,
3406
+ workbenchState: "installed",
3407
+ workbenchActions: []
3408
+ }
3409
+ },
3410
+ {
3411
+ id: "workbench-local",
3412
+ label: "工作台是本仓那份(link: 装的:不给更新,行上说清)",
3413
+ manifests: [],
3414
+ capabilities: {},
3415
+ workbench: {
3416
+ pkg: "@dsh-workbench/core",
3417
+ installed: "0.1.18",
3418
+ latest: "0.1.19",
3419
+ local: true
3420
+ },
3421
+ expect: {
3422
+ rows: 0,
3423
+ workbenchState: "installed",
3424
+ workbenchActions: [],
3425
+ workbenchNoteKey: "panels.market.workbenchLocal"
3426
+ }
3427
+ },
3428
+ {
3429
+ id: "workbench-updated",
3430
+ label: "工作台刚更新完(新版已经在盘上:行上就是新版,没有按钮、也不劝人重启)",
3431
+ manifests: [],
3432
+ capabilities: {},
3433
+ workbench: {
3434
+ pkg: "@dsh-workbench/core",
3435
+ installed: "0.1.19"
3436
+ },
3437
+ expect: {
3438
+ rows: 0,
3439
+ workbenchState: "installed",
3440
+ workbenchActions: []
3441
+ }
3442
+ },
2959
3443
  {
2960
3444
  id: "empty",
2961
3445
  label: "市场空态",
@@ -3025,11 +3509,13 @@ function createBoardRegistry() {
3025
3509
  //#endregion
3026
3510
  //#region src/app/units/registry.ts
3027
3511
  function toBoardModule(face, manifest) {
3512
+ const View = face.card;
3513
+ if (View === void 0) return void 0;
3028
3514
  return {
3029
3515
  id: manifest.id,
3030
3516
  titleKey: manifest.card?.titleKey ?? manifest.id,
3031
3517
  order: manifest.card?.order ?? 100,
3032
- View: face.card,
3518
+ View,
3033
3519
  ...face.steps === void 0 ? {} : { steps: face.steps }
3034
3520
  };
3035
3521
  }
@@ -3039,6 +3525,7 @@ function createClientUnitRegistry(options = {}) {
3039
3525
  const listeners = /* @__PURE__ */ new Set();
3040
3526
  const board = createBoardRegistry();
3041
3527
  let known = /* @__PURE__ */ new Map();
3528
+ let installableIds = null;
3042
3529
  let revision = 0;
3043
3530
  let manifestsCache;
3044
3531
  function notify() {
@@ -3049,9 +3536,10 @@ function createClientUnitRegistry(options = {}) {
3049
3536
  console.warn(`[dsh-workbench] 套件注册的订阅者报错(不影响其它订阅者与这次注册):${String(error)}`);
3050
3537
  }
3051
3538
  }
3052
- function warnRefusal(unit, reasons) {
3539
+ function warnRefusal(unit, kind, reasons) {
3053
3540
  refusals.push({
3054
3541
  unit,
3542
+ kind,
3055
3543
  reasons
3056
3544
  });
3057
3545
  console.warn(`[dsh-workbench] ${unit === "" ? "这个模块" : unit} 的卡片没挂上:${reasons.join(";")}`);
@@ -3062,9 +3550,10 @@ function createClientUnitRegistry(options = {}) {
3062
3550
  function attach(entry) {
3063
3551
  const manifest = known.get(entry.unit);
3064
3552
  if (manifest === void 0) return false;
3553
+ const boardModule = toBoardModule(entry.face, manifest);
3065
3554
  entry.mounted = {
3066
3555
  manifest,
3067
- unmount: board.register(toBoardModule(entry.face, manifest))
3556
+ unmount: boardModule === void 0 ? () => {} : board.register(boardModule)
3068
3557
  };
3069
3558
  takeBackRefusal(entry.unit);
3070
3559
  return true;
@@ -3077,7 +3566,7 @@ function createClientUnitRegistry(options = {}) {
3077
3566
  register(face) {
3078
3567
  const unit = typeof face?.unit === "string" ? face.unit.trim() : "";
3079
3568
  if (unit === "") {
3080
- warnRefusal("", ["registerUnit({ unit, card }) 里的 unit 是空的 —— U1b 之前的旧形状是 registerUnit({ manifest, card });现在清单由外壳从**已装清单**读出来、按 unit 交给浏览器(ADR-0038 §2.2)"]);
3569
+ warnRefusal("", "old-shape", ["registerUnit({ unit, card }) 里的 unit 是空的 —— U1b 之前的旧形状是 registerUnit({ manifest, card });现在清单由外壳从**已装清单**读出来、按 unit 交给浏览器(ADR-0038 §2.2)"]);
3081
3570
  notify();
3082
3571
  return () => {};
3083
3572
  }
@@ -3090,7 +3579,7 @@ function createClientUnitRegistry(options = {}) {
3090
3579
  registrations.push(entry);
3091
3580
  manifestsCache = void 0;
3092
3581
  if (!attach(entry)) {
3093
- warnRefusal(unit, [`宿主没有担保 unit「${unit}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]);
3582
+ warnRefusal(unit, "no-manifest", [`宿主没有担保 unit「${unit}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]);
3094
3583
  options.onUnknownUnit?.(unit);
3095
3584
  }
3096
3585
  notify();
@@ -3110,8 +3599,10 @@ function createClientUnitRegistry(options = {}) {
3110
3599
  return manifestsCache;
3111
3600
  },
3112
3601
  refusals: () => refusals,
3113
- setManifests(manifests) {
3602
+ installable: () => installableIds,
3603
+ setManifests(manifests, installable) {
3114
3604
  known = new Map(manifests.map((manifest) => [manifest.id, manifest]));
3605
+ installableIds = installable === void 0 ? null : new Set(installable);
3115
3606
  let changed = false;
3116
3607
  for (const entry of registrations) {
3117
3608
  const next = known.get(entry.unit);
@@ -3121,7 +3612,7 @@ function createClientUnitRegistry(options = {}) {
3121
3612
  }
3122
3613
  if (next === void 0) {
3123
3614
  detach(entry);
3124
- warnRefusal(entry.unit, [`宿主不再担保 unit「${entry.unit}」的清单(模块被卸了?)—— 这张卡片先摘下来`]);
3615
+ warnRefusal(entry.unit, "withdrawn", [`宿主不再担保 unit「${entry.unit}」的清单(模块被卸了?)—— 这张卡片先摘下来`]);
3125
3616
  changed = true;
3126
3617
  }
3127
3618
  }
@@ -3232,16 +3723,153 @@ function hasCard(roster) {
3232
3723
  function fixtureRoster(roster) {
3233
3724
  return hasCard(roster) ? roster : SAMPLE_ROSTER;
3234
3725
  }
3726
+ function boardModuleOf(face) {
3727
+ const module = toBoardModule(face, face.manifest);
3728
+ return module === void 0 ? [] : [module];
3729
+ }
3235
3730
  function fixtureSeed(roster, all, crash = false) {
3236
- const base = hasCard(roster) ? all : [toBoardModule(FIXTURE_FACE, FIXTURE_FACE.manifest)];
3237
- return crash ? [toBoardModule(CRASH_FACE, CRASH_FACE.manifest), ...base] : base;
3731
+ const base = hasCard(roster) ? all : boardModuleOf(FIXTURE_FACE);
3732
+ return crash ? [...boardModuleOf(CRASH_FACE), ...base] : base;
3733
+ }
3734
+ //#endregion
3735
+ //#region src/app/layouts/rightbar/market-shared-rows.ts
3736
+ var SHARED_STATE_KEY = {
3737
+ checking: "panels.market.checking",
3738
+ installed: "panels.market.sharedOk",
3739
+ outdated: "panels.market.sharedOutdated",
3740
+ unsatisfied: "panels.market.sharedUnsatisfied",
3741
+ missing: "panels.market.sharedMissing",
3742
+ unchecked: "panels.market.unchecked"
3743
+ };
3744
+ var SHARED_DOT = {
3745
+ checking: "ongoing",
3746
+ installed: "done",
3747
+ outdated: "warning",
3748
+ unsatisfied: "warning",
3749
+ missing: "idle",
3750
+ unchecked: "idle"
3751
+ };
3752
+ function sharedActions(row) {
3753
+ return [...row.canUpdate ? ["update-dependency"] : []];
3754
+ }
3755
+ var SHARED_RANK = {
3756
+ checking: -1,
3757
+ unchecked: 0,
3758
+ installed: 1,
3759
+ outdated: 2,
3760
+ unsatisfied: 3,
3761
+ missing: 4
3762
+ };
3763
+ function sharedRows(manifests, capabilities) {
3764
+ const catalog = manifests.filter((manifest) => (manifest.env?.plugins ?? []).length > 0 || (manifest.env?.libs ?? []).length > 0);
3765
+ const byId = new Map(catalog.map((manifest) => [manifest.id, manifest]));
3766
+ const buckets = /* @__PURE__ */ new Map();
3767
+ const bucketOf = (kind, name, label, purpose) => {
3768
+ const id = `${kind}:${name}`;
3769
+ const found = buckets.get(id);
3770
+ if (found !== void 0) return found;
3771
+ const created = {
3772
+ kind,
3773
+ name,
3774
+ label,
3775
+ users: [],
3776
+ states: [],
3777
+ ...purpose === void 0 ? {} : { purpose }
3778
+ };
3779
+ buckets.set(id, created);
3780
+ return created;
3781
+ };
3782
+ for (const manifest of catalog) {
3783
+ const capability = capabilities?.[manifest.id];
3784
+ const released = capability?.released === true;
3785
+ for (const need of manifest.env?.plugins ?? []) {
3786
+ const source = need.installSource;
3787
+ const bucket = bucketOf("plugin", need.name, source?.kind === "npm" ? source.package : need.name);
3788
+ if (released) continue;
3789
+ bucket.users.push(manifest.id);
3790
+ const state = capability?.plugins?.find((item) => item.name === need.name);
3791
+ bucket.states.push(state === void 0 ? "unchecked" : state.status === "ok" ? "installed" : state.status);
3792
+ if (state?.release !== void 0) {
3793
+ bucket.installed ??= state.release.installed;
3794
+ bucket.latest ??= state.release.latest;
3795
+ }
3796
+ bucket.command ??= state?.command;
3797
+ }
3798
+ for (const need of manifest.env?.libs ?? []) {
3799
+ const bucket = bucketOf("lib", need.name, need.name, need.purpose);
3800
+ if (released) continue;
3801
+ bucket.users.push(manifest.id);
3802
+ const state = capability?.libs?.find((item) => item.name === need.name);
3803
+ bucket.states.push(state === void 0 ? "unchecked" : state.status === "ok" ? "installed" : state.status);
3804
+ bucket.installed ??= state?.installed;
3805
+ bucket.latest ??= state?.latest;
3806
+ bucket.command ??= state?.command;
3807
+ }
3808
+ }
3809
+ const rows = [];
3810
+ for (const bucket of buckets.values()) {
3811
+ if (bucket.users.length === 0) continue;
3812
+ const state = capabilities === null ? "checking" : bucket.states.reduce((soFar, item) => SHARED_RANK[item] > SHARED_RANK[soFar] ? item : soFar, "unchecked");
3813
+ const version = bucket.installed === void 0 && bucket.latest === void 0 ? void 0 : {
3814
+ ...bucket.installed === void 0 ? {} : { installed: bucket.installed },
3815
+ ...bucket.latest === void 0 ? {} : { latest: bucket.latest }
3816
+ };
3817
+ const detail = bucket.purpose === void 0 ? void 0 : `${bucket.label} —— ${bucket.purpose}`;
3818
+ rows.push({
3819
+ id: `${bucket.kind}:${bucket.name}`,
3820
+ kind: bucket.kind,
3821
+ label: bucket.label,
3822
+ usedByKeys: bucket.users.map((unit) => byId.get(unit)?.card?.titleKey ?? unit),
3823
+ state,
3824
+ canUpdate: state === "outdated" || state === "unsatisfied",
3825
+ ...version === void 0 ? {} : { version },
3826
+ ...detail === void 0 ? {} : { detail }
3827
+ });
3828
+ }
3829
+ return rows;
3830
+ }
3831
+ //#endregion
3832
+ //#region src/app/layouts/rightbar/market-workbench-row.ts
3833
+ var WORKBENCH_ROW_ID = "workbench:self";
3834
+ var WORKBENCH_TITLE_KEY = "panels.market.workbenchName";
3835
+ function workbenchRow(version) {
3836
+ if (version === null || version === void 0 || version.installed === "") return void 0;
3837
+ const local = version.local === true;
3838
+ const latest = local ? void 0 : version.latest;
3839
+ const update = latest !== void 0 && latest !== version.installed ? {
3840
+ installed: version.installed,
3841
+ latest
3842
+ } : void 0;
3843
+ const note = local ? {
3844
+ key: "panels.market.workbenchLocal",
3845
+ params: {}
3846
+ } : void 0;
3847
+ return {
3848
+ id: WORKBENCH_ROW_ID,
3849
+ titleKey: WORKBENCH_TITLE_KEY,
3850
+ workbench: true,
3851
+ state: update === void 0 ? "installed" : "outdated",
3852
+ canInstall: false,
3853
+ canUpdate: update !== void 0,
3854
+ canUninstall: false,
3855
+ ...note === void 0 ? {} : { note },
3856
+ version: {
3857
+ installed: version.installed,
3858
+ ...latest === void 0 ? {} : { latest }
3859
+ },
3860
+ ...update === void 0 ? {} : { moduleUpdate: update },
3861
+ pkg: version.pkg
3862
+ };
3238
3863
  }
3239
3864
  //#endregion
3240
3865
  //#region src/app/layouts/rightbar/market-rows.ts
3241
3866
  var MARKET_STATE_KEY = {
3242
3867
  checking: "panels.market.checking",
3243
3868
  installed: "panels.market.installed",
3244
- outdated: "panels.market.outdated",
3869
+ inactive: "panels.market.notActive",
3870
+ unusable: "panels.market.notUsable",
3871
+ broken: "panels.market.broken",
3872
+ outdated: "panels.market.moduleOutdated",
3245
3873
  missing: "panels.market.missing",
3246
3874
  unchecked: "panels.market.unchecked",
3247
3875
  unknown: "panels.market.unchecked"
@@ -3249,6 +3877,9 @@ var MARKET_STATE_KEY = {
3249
3877
  var MARKET_DOT = {
3250
3878
  checking: "ongoing",
3251
3879
  installed: "done",
3880
+ inactive: "error",
3881
+ unusable: "error",
3882
+ broken: "error",
3252
3883
  outdated: "warning",
3253
3884
  missing: "idle",
3254
3885
  unchecked: "idle",
@@ -3258,8 +3889,9 @@ function marketRowTitle(row, t) {
3258
3889
  return row.label ?? t(row.titleKey);
3259
3890
  }
3260
3891
  function withClientRefusals(modules, refusals) {
3261
- if (refusals.length === 0) return modules;
3262
- const byUnit = new Map(refusals.map((one) => [one.unit, one.reasons]));
3892
+ const refused = refusals.filter((one) => one.kind !== "no-manifest");
3893
+ if (refused.length === 0) return modules;
3894
+ const byUnit = new Map(refused.map((one) => [one.unit, one.reasons]));
3263
3895
  return modules.map((module) => {
3264
3896
  const reasons = byUnit.get(module.unit);
3265
3897
  return reasons === void 0 ? module : {
@@ -3283,20 +3915,21 @@ function mergeTitles(known, manifests) {
3283
3915
  }
3284
3916
  return next ?? known;
3285
3917
  }
3286
- function installedRows(modules, manifests, listed, known) {
3918
+ function installedRows(modules, manifests, listed, known, defaults = /* @__PURE__ */ new Set(), changed = {}) {
3287
3919
  const titles = new Map(manifests.map((manifest) => [manifest.id, manifest.card?.titleKey]));
3288
3920
  const rows = [];
3289
3921
  for (const module of modules) {
3290
3922
  if (listed.has(module.unit)) continue;
3291
- const latest = module.latest;
3923
+ const latest = module.local === true ? void 0 : module.latest;
3292
3924
  const outdated = latest !== void 0 && latest !== module.installed;
3293
3925
  const loaded = titles.has(module.unit);
3294
3926
  const refused = refusalReasons(module.refused, module.clientRefused);
3927
+ const pending = !loaded && refused.length === 0;
3295
3928
  rows.push({
3296
3929
  id: module.unit,
3297
3930
  titleKey: titles.get(module.unit) ?? known?.get(module.unit) ?? module.pkg,
3298
- state: outdated ? "outdated" : "installed",
3299
- ...loaded || refused.length > 0 ? {} : { hint: "panels.market.moduleRestartHint" },
3931
+ state: outdated ? "outdated" : refused.length > 0 ? "unusable" : pending ? "inactive" : "installed",
3932
+ ...pending ? { hint: "panels.market.moduleRestartHint" } : {},
3300
3933
  ...refused.length === 0 ? {} : { note: {
3301
3934
  key: "panels.market.moduleRefused",
3302
3935
  params: { reason: refused.join(";") }
@@ -3313,12 +3946,19 @@ function installedRows(modules, manifests, listed, known) {
3313
3946
  ...outdated ? { moduleUpdate: {
3314
3947
  installed: module.installed,
3315
3948
  latest
3316
- } } : {}
3949
+ } } : {},
3950
+ defaultShown: defaults.has(module.unit),
3951
+ defaultChanged: changed[module.unit] ?? 0
3317
3952
  });
3318
3953
  }
3319
3954
  return rows;
3320
3955
  }
3956
+ var SWITCH_LOCKED = /* @__PURE__ */ new Set(["unusable", "broken"]);
3957
+ function marketSwitchLocked(row) {
3958
+ return SWITCH_LOCKED.has(row.state);
3959
+ }
3321
3960
  function marketActions$1(row) {
3961
+ if (row.workbench === true) return row.canUpdate ? ["update-workbench"] : [];
3322
3962
  if (row.plugin === true) return [...row.canUpdate ? ["update-plugin"] : [], ...row.canUninstall ? ["uninstall-plugin"] : []];
3323
3963
  return [
3324
3964
  ...row.canInstall ? ["install"] : [],
@@ -3326,8 +3966,8 @@ function marketActions$1(row) {
3326
3966
  ...row.canUninstall ? [row.pkg === void 0 ? "uninstall" : "remove-bundle"] : []
3327
3967
  ];
3328
3968
  }
3329
- function stateOf(capability) {
3330
- if (capability === void 0) return "unknown";
3969
+ function stateOf(capability, manifest, installed) {
3970
+ if (capability === void 0) return installed && !hasEnvSupply(manifest) ? "installed" : "unknown";
3331
3971
  if (capability.released === true) return "missing";
3332
3972
  if (capability.status === "missing-plugin") return "missing";
3333
3973
  if (capability.status === "unchecked") return "unchecked";
@@ -3343,8 +3983,9 @@ function envNameOf(source) {
3343
3983
  if (source.kind === "npm") return source.registryEnv;
3344
3984
  return "";
3345
3985
  }
3346
- function noteOf$1(state, install, manifest) {
3986
+ function noteOf$1(state, capability, manifest) {
3347
3987
  if (state === "installed") return void 0;
3988
+ const install = capability?.install;
3348
3989
  if (install === "env-missing") return {
3349
3990
  key: "panels.market.needEnv",
3350
3991
  params: { env: envNameOf((manifest.env?.plugins ?? []).find((need) => envNameOf(need.installSource) !== "")?.installSource) }
@@ -3357,9 +3998,19 @@ function noteOf$1(state, install, manifest) {
3357
3998
  key: "panels.market.badSource",
3358
3999
  params: {}
3359
4000
  };
4001
+ const missing = capability?.missing ?? [];
4002
+ if (state === "outdated" && missing.length > 0) return {
4003
+ key: "panels.market.needCommands",
4004
+ params: { commands: missing.join("、") },
4005
+ tone: "plain"
4006
+ };
3360
4007
  }
3361
4008
  function isOnMachine(state) {
3362
- return state === "installed" || state === "outdated";
4009
+ return state === "installed" || state === "outdated" || state === "inactive" || state === "unusable" || state === "broken";
4010
+ }
4011
+ function marketCatalog(manifests, installable) {
4012
+ if (installable === void 0 || installable === null) return manifests.filter(hasEnvSupply);
4013
+ return manifests.filter((manifest) => installable.has(manifest.id));
3363
4014
  }
3364
4015
  function liveManifests(manifests, capabilities, installed) {
3365
4016
  if (capabilities === null || installed === null) return manifests;
@@ -3373,14 +4024,19 @@ function marketHasUpdates(rows, shared = []) {
3373
4024
  function marketUpdatesOf(modules) {
3374
4025
  if (modules === null) return {};
3375
4026
  const next = {};
3376
- for (const module of modules) next[module.unit] = {
3377
- installed: module.installed,
3378
- ...module.latest === void 0 ? {} : { latest: module.latest }
3379
- };
4027
+ for (const module of modules) {
4028
+ const local = module.local === true;
4029
+ next[module.unit] = {
4030
+ installed: module.installed,
4031
+ ...local || module.latest === void 0 ? {} : { latest: module.latest },
4032
+ ...local ? { local: true } : {}
4033
+ };
4034
+ }
3380
4035
  return next;
3381
4036
  }
3382
- function marketHintVisible(manifests, capabilities, modules) {
3383
- return marketHasUpdates(marketRows(manifests, capabilities, marketUpdatesOf(modules)), sharedRows(manifests, capabilities));
4037
+ function marketHintVisible(manifests, capabilities, modules, workbench) {
4038
+ const self = workbenchRow(workbench);
4039
+ return marketHasUpdates([...marketRows(manifests, capabilities, marketUpdatesOf(modules)), ...self === void 0 ? [] : [self]], sharedRows(manifests, capabilities));
3384
4040
  }
3385
4041
  function marketSections(rows) {
3386
4042
  const installed = rows.filter((row) => isOnMachine(row.state));
@@ -3395,17 +4051,17 @@ function marketSections(rows) {
3395
4051
  rows: rest
3396
4052
  }]];
3397
4053
  }
3398
- function marketRows(manifests, capabilities, updates = {}) {
3399
- const catalog = manifests.filter((manifest) => (manifest.env?.plugins ?? []).length > 0 || (manifest.env?.libs ?? []).length > 0);
4054
+ function marketRows(manifests, capabilities, updates = {}, defaults = /* @__PURE__ */ new Set(), changed = {}) {
3400
4055
  const rows = [];
3401
- for (const manifest of catalog) {
4056
+ for (const manifest of manifests) {
3402
4057
  const capability = capabilities?.[manifest.id];
3403
4058
  const install = capability?.install;
3404
- const state = capabilities === null ? "checking" : stateOf(capability);
3405
- const note = noteOf$1(state, install, manifest);
4059
+ const entry = updates[manifest.id];
4060
+ const local = entry?.local === true;
4061
+ const state = capabilities === null ? "checking" : stateOf(capability, manifest, entry !== void 0);
4062
+ const note = noteOf$1(state, capability, manifest);
3406
4063
  const onMachine = isOnMachine(state);
3407
4064
  const reAdopt = capability?.released === true && install === void 0;
3408
- const entry = updates[manifest.id];
3409
4065
  const moduleUpdate = entry === void 0 || entry.latest === void 0 || entry.latest === entry.installed ? void 0 : {
3410
4066
  installed: entry.installed,
3411
4067
  latest: entry.latest
@@ -3422,101 +4078,10 @@ function marketRows(manifests, capabilities, updates = {}) {
3422
4078
  ...entry.latest === void 0 ? {} : { latest: entry.latest }
3423
4079
  } },
3424
4080
  ...moduleUpdate === void 0 ? {} : { moduleUpdate },
3425
- ...moduleUpdate === void 0 ? note === void 0 ? {} : { note } : {}
3426
- });
3427
- }
3428
- return rows;
3429
- }
3430
- var SHARED_STATE_KEY = {
3431
- checking: "panels.market.checking",
3432
- installed: "panels.market.sharedOk",
3433
- outdated: "panels.market.sharedOutdated",
3434
- unsatisfied: "panels.market.sharedUnsatisfied",
3435
- missing: "panels.market.sharedMissing",
3436
- unchecked: "panels.market.unchecked"
3437
- };
3438
- var SHARED_DOT = {
3439
- checking: "ongoing",
3440
- installed: "done",
3441
- outdated: "warning",
3442
- unsatisfied: "warning",
3443
- missing: "idle",
3444
- unchecked: "idle"
3445
- };
3446
- function sharedActions(row) {
3447
- return [...row.canUpdate ? ["update-dependency"] : []];
3448
- }
3449
- var SHARED_RANK = {
3450
- checking: -1,
3451
- unchecked: 0,
3452
- installed: 1,
3453
- outdated: 2,
3454
- unsatisfied: 3,
3455
- missing: 4
3456
- };
3457
- function sharedRows(manifests, capabilities) {
3458
- const catalog = manifests.filter((manifest) => (manifest.env?.plugins ?? []).length > 0 || (manifest.env?.libs ?? []).length > 0);
3459
- const byId = new Map(catalog.map((manifest) => [manifest.id, manifest]));
3460
- const buckets = /* @__PURE__ */ new Map();
3461
- const bucketOf = (kind, name, label, purpose) => {
3462
- const id = `${kind}:${name}`;
3463
- const found = buckets.get(id);
3464
- if (found !== void 0) return found;
3465
- const created = {
3466
- kind,
3467
- name,
3468
- label,
3469
- users: [],
3470
- states: [],
3471
- ...purpose === void 0 ? {} : { purpose }
3472
- };
3473
- buckets.set(id, created);
3474
- return created;
3475
- };
3476
- for (const manifest of catalog) {
3477
- const capability = capabilities?.[manifest.id];
3478
- const released = capability?.released === true;
3479
- for (const need of manifest.env?.plugins ?? []) {
3480
- const source = need.installSource;
3481
- const bucket = bucketOf("plugin", need.name, source?.kind === "npm" ? source.package : need.name);
3482
- if (released) continue;
3483
- bucket.users.push(manifest.id);
3484
- const state = capability?.plugins?.find((item) => item.name === need.name);
3485
- bucket.states.push(state === void 0 ? "unchecked" : state.status === "ok" ? "installed" : state.status);
3486
- if (state?.release !== void 0) {
3487
- bucket.installed ??= state.release.installed;
3488
- bucket.latest ??= state.release.latest;
3489
- }
3490
- bucket.command ??= state?.command;
3491
- }
3492
- for (const need of manifest.env?.libs ?? []) {
3493
- const bucket = bucketOf("lib", need.name, need.name, need.purpose);
3494
- if (released) continue;
3495
- bucket.users.push(manifest.id);
3496
- const state = capability?.libs?.find((item) => item.name === need.name);
3497
- bucket.states.push(state === void 0 ? "unchecked" : state.status === "ok" ? "installed" : state.status);
3498
- bucket.installed ??= state?.installed;
3499
- bucket.latest ??= state?.latest;
3500
- bucket.command ??= state?.command;
3501
- }
3502
- }
3503
- const rows = [];
3504
- for (const bucket of buckets.values()) {
3505
- if (bucket.users.length === 0) continue;
3506
- const state = capabilities === null ? "checking" : bucket.states.reduce((soFar, item) => SHARED_RANK[item] > SHARED_RANK[soFar] ? item : soFar, "unchecked");
3507
- const version = bucket.installed === void 0 && bucket.latest === void 0 ? void 0 : {
3508
- ...bucket.installed === void 0 ? {} : { installed: bucket.installed },
3509
- ...bucket.latest === void 0 ? {} : { latest: bucket.latest }
3510
- };
3511
- const detail = bucket.purpose === void 0 ? void 0 : `${bucket.label} —— ${bucket.purpose}`;
3512
- rows.push({
3513
- id: `${bucket.kind}:${bucket.name}`,
3514
- label: bucket.label,
3515
- usedByKeys: bucket.users.map((unit) => byId.get(unit)?.card?.titleKey ?? unit),
3516
- state,
3517
- canUpdate: state === "outdated" || state === "unsatisfied",
3518
- ...version === void 0 ? {} : { version },
3519
- ...detail === void 0 ? {} : { detail }
4081
+ ...moduleUpdate === void 0 ? note === void 0 ? {} : { note } : {},
4082
+ ...local ? { local: true } : {},
4083
+ defaultShown: defaults.has(manifest.id),
4084
+ defaultChanged: changed[manifest.id] ?? 0
3520
4085
  });
3521
4086
  }
3522
4087
  return rows;
@@ -3574,6 +4139,42 @@ function useHostWrite(options) {
3574
4139
  };
3575
4140
  }
3576
4141
  //#endregion
4142
+ //#region src/shared/hooks/use-visible-busy.ts
4143
+ var use_visible_busy_exports = /* @__PURE__ */ __exportAll({
4144
+ busyView: () => busyView,
4145
+ heldPhase: () => heldPhase,
4146
+ useVisibleBusy: () => useVisibleBusy
4147
+ });
4148
+ function heldPhase(phase, refreshing) {
4149
+ return refreshing && phase === "ready" ? "loading" : phase;
4150
+ }
4151
+ function busyView(active, visible) {
4152
+ return {
4153
+ busy: visible,
4154
+ settling: visible && !active
4155
+ };
4156
+ }
4157
+ function useVisibleBusy(active, floorMs) {
4158
+ const [visible, setVisible] = useState(active);
4159
+ const since = useRef(null);
4160
+ useEffect(() => {
4161
+ if (active) {
4162
+ if (since.current === null) since.current = Date.now();
4163
+ setVisible(true);
4164
+ return;
4165
+ }
4166
+ const held = holdBusy(since.current, Date.now(), floorMs);
4167
+ since.current = null;
4168
+ if (!held.visible) {
4169
+ setVisible(false);
4170
+ return;
4171
+ }
4172
+ const timer = setTimeout(() => setVisible(false), held.releaseInMs);
4173
+ return () => clearTimeout(timer);
4174
+ }, [active, floorMs]);
4175
+ return busyView(active, visible);
4176
+ }
4177
+ //#endregion
3577
4178
  //#region src/app/layouts/rightbar/market-plugin-rows.ts
3578
4179
  function installedPluginKept(value) {
3579
4180
  if (typeof value !== "object" || value === null) return void 0;
@@ -3591,34 +4192,40 @@ function installedPluginKept(value) {
3591
4192
  names
3592
4193
  };
3593
4194
  }
4195
+ function installedPluginNotice(value, t) {
4196
+ const kept = installedPluginKept(value);
4197
+ if (kept === void 0) return null;
4198
+ return t(kept.key, kept.names === void 0 ? {} : { names: kept.names.join(t("panels.market.listSeparator")) });
4199
+ }
3594
4200
  function noteOf(plugin) {
3595
4201
  if (plugin.broken === true) return {
3596
4202
  key: "panels.market.pluginBroken",
3597
- params: {}
4203
+ params: {},
4204
+ tone: "alert"
3598
4205
  };
3599
4206
  if (plugin.local === true) return void 0;
3600
- if (plugin.name !== void 0 && plugin.name !== plugin.pkg) return {
3601
- key: "panels.market.pluginAlsoKnownAs",
3602
- params: { pkg: plugin.pkg }
3603
- };
3604
4207
  }
3605
- function installedPluginRows(plugins) {
4208
+ function installedPluginRows(plugins, defaults = /* @__PURE__ */ new Set(), changed = {}) {
3606
4209
  return plugins.map((plugin) => {
4210
+ const id = `plugin:${plugin.pkg}`;
3607
4211
  const name = plugin.name ?? plugin.pkg;
3608
4212
  const outdated = plugin.installed !== void 0 && plugin.latest !== void 0 && plugin.latest !== plugin.installed;
3609
4213
  const note = noteOf(plugin);
3610
4214
  return {
3611
- id: `plugin:${plugin.pkg}`,
4215
+ id,
3612
4216
  titleKey: plugin.pkg,
3613
4217
  label: name,
3614
4218
  plugin: true,
3615
- state: outdated ? "outdated" : "installed",
4219
+ state: outdated ? "outdated" : plugin.broken === true ? "broken" : "installed",
3616
4220
  canInstall: false,
3617
4221
  canUpdate: outdated,
3618
4222
  canUninstall: true,
3619
4223
  ...plugin.local === true ? { local: true } : {},
3620
4224
  ...plugin.broken === true ? { broken: true } : {},
4225
+ defaultShown: defaults.has(id),
4226
+ defaultChanged: changed[id] ?? 0,
3621
4227
  ...note === void 0 ? {} : { note },
4228
+ ...plugin.installed === void 0 ? {} : { versionLabel: `${plugin.pkg}@${plugin.installed}` },
3622
4229
  pkg: plugin.pkg,
3623
4230
  ...plugin.installed === void 0 ? {} : { version: {
3624
4231
  installed: plugin.installed,
@@ -3627,8 +4234,315 @@ function installedPluginRows(plugins) {
3627
4234
  };
3628
4235
  });
3629
4236
  }
4237
+ var MarketPage_module_default = {
4238
+ marketList: "_marketList_csyus_1",
4239
+ marketRow: "_marketRow_csyus_10",
4240
+ marketIcon: "_marketIcon_csyus_20",
4241
+ marketMain: "_marketMain_csyus_32",
4242
+ marketName: "_marketName_csyus_39",
4243
+ marketDesc: "_marketDesc_csyus_48",
4244
+ marketUsedBy: "_marketUsedBy_csyus_59",
4245
+ marketVersion: "_marketVersion_csyus_73",
4246
+ marketLocalTag: "_marketLocalTag_csyus_95",
4247
+ marketEnd: "_marketEnd_csyus_106",
4248
+ marketSwitchSeat: "_marketSwitchSeat_csyus_113",
4249
+ marketActions: "_marketActions_csyus_126",
4250
+ marketUpdateAction: "_marketUpdateAction_csyus_132",
4251
+ marketSelfDivider: "_marketSelfDivider_csyus_138",
4252
+ marketSection: "_marketSection_csyus_143",
4253
+ marketSectionHead: "_marketSectionHead_csyus_150",
4254
+ marketSectionIcon: "_marketSectionIcon_csyus_156",
4255
+ marketSectionTitle: "_marketSectionTitle_csyus_163",
4256
+ marketSectionCount: "_marketSectionCount_csyus_169",
4257
+ marketProgress: "_marketProgress_csyus_176",
4258
+ marketNote: "_marketNote_csyus_186",
4259
+ marketNotePlain: "_marketNotePlain_csyus_193",
4260
+ marketFailure: "_marketFailure_csyus_201",
4261
+ marketEmpty: "_marketEmpty_csyus_208",
4262
+ marketPage: "_marketPage_csyus_213",
4263
+ marketPageHead: "_marketPageHead_csyus_231",
4264
+ marketPageTitle: "_marketPageTitle_csyus_239",
4265
+ marketPageIntro: "_marketPageIntro_csyus_244",
4266
+ marketPageTools: "_marketPageTools_csyus_250",
4267
+ marketIconButton: "_marketIconButton_csyus_259",
4268
+ marketIconWrap: "_marketIconWrap_csyus_284",
4269
+ marketIconButtonSpinning: "_marketIconButtonSpinning_csyus_288",
4270
+ "wb-spin": "_wb-spin_csyus_1",
4271
+ marketAddButton: "_marketAddButton_csyus_292",
4272
+ marketChecking: "_marketChecking_csyus_309",
4273
+ marketEmptyTitle: "_marketEmptyTitle_csyus_317"
4274
+ };
4275
+ //#endregion
4276
+ //#region src/app/layouts/rightbar/MarketStates.tsx
4277
+ function MarketChecking({ t }) {
4278
+ return /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmpty }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketChecking }, /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
4279
+ state: "ongoing",
4280
+ size: 14
4281
+ }), t("panels.market.checking")));
4282
+ }
4283
+ function MarketEmpty({ t }) {
4284
+ return /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmpty }, /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmptyTitle }, t("panels.market.empty")));
4285
+ }
4286
+ //#endregion
4287
+ //#region src/app/layouts/rightbar/market-section-icon.ts
4288
+ var SIZE$1 = 14;
4289
+ function marketSectionIcon(kind) {
4290
+ switch (kind) {
4291
+ case "installed": return h(IconModules, { size: SIZE$1 });
4292
+ case "pending": return h(_deepseek_ai_dsh_client_ui_primitives.IconDownloadOutlineRegular, { size: SIZE$1 });
4293
+ case "plugins": return h(_deepseek_ai_dsh_client_ui_primitives.IconCordisPluginOutlineRegular, { size: SIZE$1 });
4294
+ case "shared": return h(_deepseek_ai_dsh_client_ui_primitives.IconLinkOutlineRegular, { size: SIZE$1 });
4295
+ }
4296
+ }
4297
+ //#endregion
4298
+ //#region src/app/layouts/rightbar/market-row-icon.ts
4299
+ var SIZE = 18;
4300
+ function packageIcon(kind) {
4301
+ switch (kind) {
4302
+ case "module": return h(_deepseek_ai_dsh_client_ui_primitives.IconArchiveOutlineRegular, { size: SIZE });
4303
+ case "plugin": return h(IconOpencli, { size: SIZE });
4304
+ case "lib": return h(IconNpm, { size: SIZE });
4305
+ case "workbench": return h(IconPanelScreen, { size: SIZE });
4306
+ }
4307
+ }
4308
+ function marketRowKind(row) {
4309
+ if (row.workbench === true) return "workbench";
4310
+ if (row.plugin === true) return "plugin";
4311
+ return "module";
4312
+ }
4313
+ function sharedRowKind(row) {
4314
+ return row.kind === "plugin" ? "plugin" : "lib";
4315
+ }
4316
+ //#endregion
4317
+ //#region src/app/layouts/rightbar/market-view-text.ts
4318
+ var PROGRESS_KEY = {
4319
+ install: "panels.market.installing",
4320
+ update: "panels.market.updating",
4321
+ "update-bundle": "panels.market.updating",
4322
+ "remove-bundle": "panels.market.uninstalling",
4323
+ uninstall: "panels.market.uninstalling",
4324
+ "update-dependency": "panels.market.updating",
4325
+ "update-plugin": "panels.market.updating",
4326
+ "uninstall-plugin": "panels.market.uninstalling",
4327
+ "update-workbench": "panels.market.updating"
4328
+ };
4329
+ var ACTION_LABEL_KEY = {
4330
+ install: "panels.market.install",
4331
+ update: "panels.market.update",
4332
+ "update-bundle": "panels.market.update",
4333
+ "remove-bundle": "panels.market.uninstall",
4334
+ uninstall: "panels.market.uninstall",
4335
+ "update-dependency": "panels.market.update",
4336
+ "update-plugin": "panels.market.update",
4337
+ "uninstall-plugin": "panels.market.uninstall",
4338
+ "update-workbench": "panels.market.update"
4339
+ };
4340
+ function pendingRowOf(input) {
4341
+ const { pending, removing } = input;
4342
+ if (removing === null || pending === null) return void 0;
4343
+ if (input.rows.some((row) => row.id === removing)) return void 0;
4344
+ return {
4345
+ id: removing,
4346
+ titleKey: pending.titleKey ?? input.titles.get(removing) ?? removing,
4347
+ state: "installed",
4348
+ canInstall: false,
4349
+ canUpdate: false,
4350
+ canUninstall: true,
4351
+ ...pending.pkg === void 0 ? {} : { pkg: pending.pkg },
4352
+ ...pending.version === void 0 ? {} : { version: { installed: pending.version } }
4353
+ };
4354
+ }
4355
+ //#endregion
4356
+ //#region src/app/layouts/rightbar/SharedSection.tsx
4357
+ function SharedLine({ t, row, pending, failure, onAct }) {
4358
+ const running = pending !== null && pending.id === row.id ? pending : null;
4359
+ const locked = pending !== null;
4360
+ const actions = sharedActions(row);
4361
+ const stateText = t(SHARED_STATE_KEY[row.state]);
4362
+ const version = row.version;
4363
+ 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", {
4364
+ from: version.installed,
4365
+ to: version.latest
4366
+ }) : version.installed ?? version.latest ?? ""));
4367
+ return /* @__PURE__ */ h("li", { className: MarketPage_module_default.marketRow }, /* @__PURE__ */ h("span", {
4368
+ className: MarketPage_module_default.marketIcon,
4369
+ "aria-hidden": "true"
4370
+ }, 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", {
4371
+ className: MarketPage_module_default.marketDesc,
4372
+ role: "img",
4373
+ "aria-label": stateText
4374
+ }, row.state === "checking" ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
4375
+ state: "ongoing",
4376
+ size: 14
4377
+ }) : /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
4378
+ state: SHARED_DOT[row.state],
4379
+ size: 9
4380
+ }), 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(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
4381
+ state: "ongoing",
4382
+ size: 14
4383
+ }), t(PROGRESS_KEY[running.action])) : actions.length === 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketActions }, actions.map((action) => /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.Button, {
4384
+ key: action,
4385
+ type: "button",
4386
+ size: "sm",
4387
+ variant: "outline",
4388
+ disabled: locked,
4389
+ onClick: () => onAct(action)
4390
+ }, t(ACTION_LABEL_KEY[action]))))), failure === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketFailure }, failure));
4391
+ }
4392
+ function SharedSection({ t, rows, pending, failureOf, act }) {
4393
+ if (rows.length === 0) return null;
4394
+ return /* @__PURE__ */ h("section", { className: MarketPage_module_default.marketSection }, /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketSectionHead }, /* @__PURE__ */ h("span", {
4395
+ className: MarketPage_module_default.marketSectionIcon,
4396
+ "aria-hidden": "true"
4397
+ }, 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, {
4398
+ key: row.id,
4399
+ t,
4400
+ row,
4401
+ pending,
4402
+ failure: failureOf(row.id),
4403
+ onAct: (action) => void act(row.id, action)
4404
+ }))));
4405
+ }
4406
+ //#endregion
4407
+ //#region src/app/layouts/rightbar/panel-write.ts
4408
+ var PANEL_SETTLE_MS = 4e3;
4409
+ function rowKey(row) {
4410
+ return `${row.id}:${row.shown ? "1" : "0"}:${row.source}`;
4411
+ }
4412
+ function rowKeys(rows) {
4413
+ return rows.map(rowKey).join(",");
4414
+ }
4415
+ function panelBoardSignature(units, plugins, own) {
4416
+ return `${rowKeys(units)}|${rowKeys(plugins)}|${own ? "1" : "0"}`;
4417
+ }
4418
+ function machineBoardSignature(defaults, changed) {
4419
+ const counts = Object.entries(changed).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([id, count]) => `${id}:${String(count)}`);
4420
+ return `${[...defaults].sort().join(",")}|${counts.join(",")}`;
4421
+ }
4422
+ function nextPending(pending, signature) {
4423
+ return pending !== null && pending !== signature ? null : pending;
4424
+ }
4425
+ function useBoardSettle(signature) {
4426
+ const [held, setHeld] = useState(null);
4427
+ useEffect(() => {
4428
+ setHeld((current) => nextPending(current, signature));
4429
+ }, [signature]);
4430
+ useEffect(() => {
4431
+ if (held === null) return void 0;
4432
+ const timer = setTimeout(() => setHeld(null), PANEL_SETTLE_MS);
4433
+ return () => clearTimeout(timer);
4434
+ }, [held]);
4435
+ return {
4436
+ pending: held !== null,
4437
+ begin: () => setHeld(signature),
4438
+ clear: () => setHeld(null)
4439
+ };
4440
+ }
4441
+ //#endregion
4442
+ //#region src/app/layouts/rightbar/market-section.tsx
4443
+ var dangerActions = [
4444
+ "uninstall",
4445
+ "remove-bundle",
4446
+ "uninstall-plugin"
4447
+ ];
4448
+ var updateActions = [
4449
+ "update",
4450
+ "update-bundle",
4451
+ "update-plugin",
4452
+ "update-workbench"
4453
+ ];
4454
+ function MarketLine({ t, row, pending, failure, onAct, onDefault, boardBusy }) {
4455
+ const running = pending !== null && pending.id === row.id ? pending : null;
4456
+ const locked = pending !== null;
4457
+ const quiet = row.workbench === true && row.state === "installed" && row.hint === void 0;
4458
+ const actions = marketActions$1(row);
4459
+ const switchLocked = marketSwitchLocked(row);
4460
+ const stateText = t(MARKET_STATE_KEY[row.state]);
4461
+ return /* @__PURE__ */ h("li", { className: MarketPage_module_default.marketRow }, /* @__PURE__ */ h("span", {
4462
+ className: MarketPage_module_default.marketIcon,
4463
+ "aria-hidden": "true"
4464
+ }, 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", {
4465
+ from: row.version.installed,
4466
+ to: row.version.latest
4467
+ }) : 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", {
4468
+ className: MarketPage_module_default.marketDesc,
4469
+ role: "img",
4470
+ "aria-label": stateText
4471
+ }, row.state === "checking" ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
4472
+ state: "ongoing",
4473
+ size: 14
4474
+ }) : /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
4475
+ state: MARKET_DOT[row.state],
4476
+ size: 9
4477
+ }), 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(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
4478
+ state: "ongoing",
4479
+ size: 14
4480
+ }), t(PROGRESS_KEY[running.action])) : actions.length === 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketActions }, actions.map((action) => {
4481
+ const danger = dangerActions.includes(action);
4482
+ const update = updateActions.includes(action);
4483
+ return /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.Button, {
4484
+ key: action,
4485
+ type: "button",
4486
+ size: "sm",
4487
+ variant: action === "install" ? "primary" : "outline",
4488
+ className: danger ? "wb-dangerAction" : update ? MarketPage_module_default.marketUpdateAction : void 0,
4489
+ icon: danger ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineRegular, { size: 13 }) : void 0,
4490
+ "aria-label": danger ? t("panels.market.uninstallLabel", { name: marketRowTitle(row, t) }) : void 0,
4491
+ disabled: locked,
4492
+ onClick: () => onAct(action)
4493
+ }, t(ACTION_LABEL_KEY[action]));
4494
+ })), 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(_deepseek_ai_dsh_client_ui_primitives.Switch, {
4495
+ checked: row.defaultShown,
4496
+ disabled: boardBusy === true || locked || switchLocked,
4497
+ label: `${marketRowTitle(row, t)} · ${t("panels.market.defaultLabel")}`,
4498
+ onChange: (next) => onDefault?.(next)
4499
+ })))), row.note === void 0 ? null : /* @__PURE__ */ h("div", {
4500
+ className: row.note.tone === "plain" ? MarketPage_module_default.marketNotePlain : MarketPage_module_default.marketNote,
4501
+ title: row.note.params.reason === void 0 ? void 0 : t("panels.market.moduleRefusedDetail", row.note.params)
4502
+ }, t(row.note.key, row.note.params)), failure === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketFailure }, failure));
4503
+ }
4504
+ function MarketSection({ t, titleKey, icon, rows, pending, failureOf, act, confirmActions, onConfirming, onDefault, boardBusy }) {
4505
+ if (rows.length === 0) return null;
4506
+ return /* @__PURE__ */ h("section", { className: MarketPage_module_default.marketSection }, titleKey === void 0 ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketSectionHead }, /* @__PURE__ */ h("span", {
4507
+ className: MarketPage_module_default.marketSectionIcon,
4508
+ "aria-hidden": "true"
4509
+ }, 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, {
4510
+ key: row.id,
4511
+ t,
4512
+ row,
4513
+ pending,
4514
+ failure: failureOf(row.id),
4515
+ onAct: (action) => confirmActions.includes(action) ? onConfirming(row.id) : void act(row.id, action),
4516
+ onDefault: (next) => onDefault?.(row.id, next),
4517
+ boardBusy
4518
+ }))));
4519
+ }
3630
4520
  //#endregion
3631
4521
  //#region src/app/layouts/market/add-module-text.ts
4522
+ function previewOf(inspection, fallback) {
4523
+ if (inspection.status === "plugin") return {
4524
+ kind: "plugin",
4525
+ name: inspection.pkg,
4526
+ version: inspection.version ?? "",
4527
+ description: "",
4528
+ registry: inspection.registry ?? "",
4529
+ ...inspection.pluginName === void 0 ? {} : { pluginName: inspection.pluginName }
4530
+ };
4531
+ return {
4532
+ kind: "module",
4533
+ name: inspection.name ?? fallback,
4534
+ version: inspection.version ?? "",
4535
+ description: inspection.description ?? "",
4536
+ registry: inspection.registry ?? ""
4537
+ };
4538
+ }
4539
+ function resultKindOf(input) {
4540
+ if (input.plugin) return "plugin";
4541
+ if (input.change.application === "failed") return "failed";
4542
+ if (input.change.application === "restart-required") return "restart";
4543
+ if (input.change.application === "cancelled" || input.supplyState === "not-a-module") return "quiet";
4544
+ return "took-effect";
4545
+ }
3632
4546
  var GUIDE_ITEMS = [
3633
4547
  {
3634
4548
  titleKey: "panels.market.add.guideIdTitle",
@@ -3816,128 +4730,60 @@ function changeFailure(change, t) {
3816
4730
  if (change === void 0 || SHIPPED.includes(change.application)) return void 0;
3817
4731
  return failureReason(failureCode(change), change.application, t);
3818
4732
  }
3819
- var MarketPage_module_default = {
3820
- marketList: "_marketList_z6vtq_1",
3821
- marketRow: "_marketRow_z6vtq_10",
3822
- marketIcon: "_marketIcon_z6vtq_20",
3823
- marketMain: "_marketMain_z6vtq_32",
3824
- marketName: "_marketName_z6vtq_39",
3825
- marketDesc: "_marketDesc_z6vtq_48",
3826
- marketUsedBy: "_marketUsedBy_z6vtq_59",
3827
- marketVersion: "_marketVersion_z6vtq_73",
3828
- marketEnd: "_marketEnd_z6vtq_95",
3829
- marketActions: "_marketActions_z6vtq_102",
3830
- marketSection: "_marketSection_z6vtq_108",
3831
- marketSectionHead: "_marketSectionHead_z6vtq_115",
3832
- marketSectionTitle: "_marketSectionTitle_z6vtq_121",
3833
- marketSectionCount: "_marketSectionCount_z6vtq_127",
3834
- marketProgress: "_marketProgress_z6vtq_133",
3835
- marketNote: "_marketNote_z6vtq_143",
3836
- marketFailure: "_marketFailure_z6vtq_150",
3837
- marketEmpty: "_marketEmpty_z6vtq_157",
3838
- marketPage: "_marketPage_z6vtq_162",
3839
- marketPageHead: "_marketPageHead_z6vtq_180",
3840
- marketPageTitle: "_marketPageTitle_z6vtq_188",
3841
- marketPageIntro: "_marketPageIntro_z6vtq_193",
3842
- marketPageTools: "_marketPageTools_z6vtq_199",
3843
- marketIconButton: "_marketIconButton_z6vtq_208",
3844
- marketIconWrap: "_marketIconWrap_z6vtq_233",
3845
- marketIconButtonSpinning: "_marketIconButtonSpinning_z6vtq_237",
3846
- "wb-spin": "_wb-spin_z6vtq_1",
3847
- marketAddButton: "_marketAddButton_z6vtq_241",
3848
- marketChecking: "_marketChecking_z6vtq_258",
3849
- marketEmptyTitle: "_marketEmptyTitle_z6vtq_266"
3850
- };
3851
4733
  //#endregion
3852
- //#region src/app/layouts/rightbar/MarketStates.tsx
3853
- function MarketChecking({ t }) {
3854
- return /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmpty }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketChecking }, /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
3855
- state: "ongoing",
3856
- size: 14
3857
- }), t("panels.market.checking")));
3858
- }
3859
- function MarketEmpty({ t }) {
3860
- return /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmpty }, /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmptyTitle }, t("panels.market.empty")));
3861
- }
3862
- //#endregion
3863
- //#region src/app/layouts/rightbar/market-view-text.ts
3864
- var PROGRESS_KEY = {
3865
- install: "panels.market.installing",
3866
- update: "panels.market.updating",
3867
- "update-bundle": "panels.market.updating",
3868
- "remove-bundle": "panels.market.uninstalling",
3869
- uninstall: "panels.market.uninstalling",
3870
- "update-dependency": "panels.market.updating",
3871
- "update-plugin": "panels.market.updating",
3872
- "uninstall-plugin": "panels.market.uninstalling"
3873
- };
3874
- var ACTION_LABEL_KEY = {
3875
- install: "panels.market.install",
3876
- update: "panels.market.update",
3877
- "update-bundle": "panels.market.update",
3878
- "remove-bundle": "panels.market.uninstall",
3879
- uninstall: "panels.market.uninstall",
3880
- "update-dependency": "panels.market.update",
3881
- "update-plugin": "panels.market.update",
3882
- "uninstall-plugin": "panels.market.uninstall"
3883
- };
3884
- //#endregion
3885
- //#region src/app/layouts/rightbar/SharedSection.tsx
3886
- function SharedLine({ t, row, pending, failure, onAct }) {
3887
- const running = pending !== null && pending.id === row.id ? pending : null;
3888
- const locked = pending !== null;
3889
- const actions = sharedActions(row);
3890
- const stateText = t(SHARED_STATE_KEY[row.state]);
3891
- const version = row.version;
3892
- 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", {
3893
- from: version.installed,
3894
- to: version.latest
3895
- }) : version.installed ?? version.latest ?? ""));
3896
- return /* @__PURE__ */ h("li", { className: MarketPage_module_default.marketRow }, /* @__PURE__ */ h("span", {
3897
- className: MarketPage_module_default.marketIcon,
3898
- "aria-hidden": "true"
3899
- }, /* @__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", {
3900
- className: MarketPage_module_default.marketDesc,
3901
- role: "img",
3902
- "aria-label": stateText
3903
- }, row.state === "checking" ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
3904
- state: "ongoing",
3905
- size: 14
3906
- }) : /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
3907
- state: SHARED_DOT[row.state],
3908
- size: 9
3909
- }), 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(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
3910
- state: "ongoing",
3911
- size: 14
3912
- }), t(PROGRESS_KEY[running.action])) : actions.length === 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketActions }, actions.map((action) => /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.Button, {
3913
- key: action,
3914
- type: "button",
3915
- size: "sm",
3916
- variant: "outline",
3917
- disabled: locked,
3918
- onClick: () => onAct(action)
3919
- }, t(ACTION_LABEL_KEY[action]))))), failure === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketFailure }, failure));
3920
- }
3921
- function SharedSection({ t, rows, pending, failureOf, act }) {
3922
- if (rows.length === 0) return null;
3923
- 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, {
3924
- key: row.id,
3925
- t,
3926
- row,
3927
- pending,
3928
- failure: failureOf(row.id),
3929
- onAct: (action) => void act(row.id, action)
3930
- }))));
4734
+ //#region src/app/layouts/rightbar/market-act.ts
4735
+ function marketActOf(options) {
4736
+ const { t, mocked, rowOf, seats, send, onChanged } = options;
4737
+ return async (id, action) => {
4738
+ if (mocked) return;
4739
+ const row = rowOf(id);
4740
+ seats.setPending({
4741
+ id,
4742
+ action,
4743
+ ...row?.titleKey === void 0 ? {} : { titleKey: row.titleKey },
4744
+ ...row?.pkg === void 0 ? {} : { pkg: row.pkg },
4745
+ ...row?.version?.installed === void 0 ? {} : { version: row.version.installed }
4746
+ });
4747
+ seats.setConfirming(null);
4748
+ seats.setFailed(null);
4749
+ if (action !== "uninstall-plugin") seats.setNotice(null);
4750
+ const outcome = await send(action === "update-dependency" ? {
4751
+ action,
4752
+ id
4753
+ } : action === "remove-bundle" || action === "update-plugin" || action === "uninstall-plugin" || action === "update-workbench" ? {
4754
+ action,
4755
+ name: row?.pkg ?? ""
4756
+ } : {
4757
+ action,
4758
+ unit: id
4759
+ });
4760
+ seats.setPending(null);
4761
+ if (!outcome.ok) {
4762
+ onChanged();
4763
+ seats.setFailed({
4764
+ id,
4765
+ message: t("panels.market.failed", { reason: outcome.message })
4766
+ });
4767
+ return;
4768
+ }
4769
+ if (action === "uninstall-plugin") seats.setNotice(installedPluginNotice(outcome.value, t));
4770
+ const reason = changeFailure(changeOf(outcome.value), t);
4771
+ onChanged();
4772
+ if (reason !== void 0) seats.setFailed({
4773
+ id,
4774
+ message: t("panels.market.failed", { reason })
4775
+ });
4776
+ };
3931
4777
  }
3932
4778
  var PanelFoot_module_default = {
3933
- foot: "_foot_1us83_1",
3934
- footText: "_footText_1us83_12",
3935
- footTextMd: "_footTextMd_1us83_17"
4779
+ foot: "_foot_1ud1j_1",
4780
+ footText: "_footText_1ud1j_13",
4781
+ footTextMd: "_footTextMd_1ud1j_18"
3936
4782
  };
3937
4783
  //#endregion
3938
4784
  //#region src/shared/components/PanelFoot.tsx
3939
4785
  function PanelFoot({ text, size = "sm", children }) {
3940
- 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);
4786
+ 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);
3941
4787
  }
3942
4788
  //#endregion
3943
4789
  //#region src/app/layouts/rightbar/MarketView.tsx
@@ -3946,49 +4792,6 @@ var CONFIRM_UNINSTALL = [
3946
4792
  "remove-bundle",
3947
4793
  "uninstall-plugin"
3948
4794
  ];
3949
- var CONFIRM_REMOVE = ["remove-bundle"];
3950
- function MarketLine({ t, row, pending, failure, onAct }) {
3951
- const running = pending !== null && pending.id === row.id ? pending : null;
3952
- const locked = pending !== null;
3953
- const actions = marketActions$1(row);
3954
- const stateText = t(row.moduleUpdate === void 0 ? MARKET_STATE_KEY[row.state] : "panels.market.moduleOutdated");
3955
- return /* @__PURE__ */ h("li", { className: MarketPage_module_default.marketRow }, /* @__PURE__ */ h("span", {
3956
- className: MarketPage_module_default.marketIcon,
3957
- "aria-hidden": "true"
3958
- }, /* @__PURE__ */ h(IconModules, { size: 18 })), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketMain }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketName }, marketRowTitle(row, t), row.version === void 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketVersion }, row.version.installed !== void 0 && row.version.latest !== void 0 && row.version.installed !== row.version.latest ? t("panels.market.versionArrow", {
3959
- from: row.version.installed,
3960
- to: row.version.latest
3961
- }) : row.version.installed ?? row.version.latest ?? "")), /* @__PURE__ */ h("span", {
3962
- className: MarketPage_module_default.marketDesc,
3963
- role: "img",
3964
- "aria-label": stateText
3965
- }, row.state === "checking" ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
3966
- state: "ongoing",
3967
- size: 14
3968
- }) : /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
3969
- state: MARKET_DOT[row.state],
3970
- size: 9
3971
- }), 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(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
3972
- state: "ongoing",
3973
- size: 14
3974
- }), t(PROGRESS_KEY[running.action])) : actions.length === 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketActions }, actions.map((action) => {
3975
- const danger = action === "uninstall" || action === "remove-bundle";
3976
- return /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.Button, {
3977
- key: action,
3978
- type: "button",
3979
- size: "sm",
3980
- variant: action === "install" ? "primary" : "outline",
3981
- className: danger ? "wb-dangerAction" : void 0,
3982
- icon: danger ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineRegular, { size: 13 }) : void 0,
3983
- "aria-label": danger ? t("panels.market.uninstallLabel", { name: marketRowTitle(row, t) }) : void 0,
3984
- disabled: locked,
3985
- onClick: () => onAct(action)
3986
- }, t(ACTION_LABEL_KEY[action]));
3987
- }))), row.note === void 0 ? null : /* @__PURE__ */ h("div", {
3988
- className: MarketPage_module_default.marketNote,
3989
- title: row.note.params.reason === void 0 ? void 0 : t("panels.market.moduleRefusedDetail", row.note.params)
3990
- }, t(row.note.key, row.note.params)), failure === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketFailure }, failure));
3991
- }
3992
4795
  function ConfirmUninstall({ t, name, onConfirm, onCancel }) {
3993
4796
  const [acknowledged, setAcknowledged] = useState(false);
3994
4797
  return /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.RiskConfirmation, {
@@ -4003,26 +4806,31 @@ function ConfirmUninstall({ t, name, onConfirm, onCancel }) {
4003
4806
  onAcknowledgedChange: setAcknowledged,
4004
4807
  onCancel,
4005
4808
  onConfirm
4006
- });
4007
- }
4008
- function MarketSection({ t, titleKey, rows, pending, failureOf, act, confirmActions, onConfirming }) {
4009
- if (rows.length === 0) return null;
4010
- 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, {
4011
- key: row.id,
4012
- t,
4013
- row,
4014
- pending,
4015
- failure: failureOf(row.id),
4016
- onAct: (action) => confirmActions.includes(action) ? onConfirming(row.id) : void act(row.id, action)
4017
- }))));
4809
+ });
4018
4810
  }
4019
- function MarketBody({ t, shown, pluginList, installedList, shared, pending, failed, notice, act, onConfirming }) {
4811
+ function MarketBody({ t, self, shown, pluginList, installedList, shared, pending, failed, notice, act, onConfirming, setDefault, boardBusy }) {
4020
4812
  const failureOf = (id) => failed?.id === id ? failed.message : null;
4021
- return /* @__PURE__ */ h(Fragment, null, notice === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketNote }, notice), marketSections(shown).map((section) => /* @__PURE__ */ h(MarketSection, {
4813
+ return /* @__PURE__ */ h(Fragment, null, notice === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketNote }, notice), /* @__PURE__ */ h(MarketSection, {
4814
+ t,
4815
+ rows: self === void 0 ? [] : [self],
4816
+ onDefault: setDefault,
4817
+ boardBusy,
4818
+ pending,
4819
+ failureOf,
4820
+ act,
4821
+ confirmActions: CONFIRM_UNINSTALL,
4822
+ onConfirming
4823
+ }), self === void 0 ? null : /* @__PURE__ */ h("div", {
4824
+ className: MarketPage_module_default.marketSelfDivider,
4825
+ "aria-hidden": "true"
4826
+ }), marketSections([...shown, ...installedList]).map((section) => /* @__PURE__ */ h(MarketSection, {
4022
4827
  key: section.id,
4023
4828
  t,
4024
4829
  titleKey: section.titleKey,
4830
+ icon: marketSectionIcon(section.id === "installed" ? "installed" : "pending"),
4025
4831
  rows: section.rows,
4832
+ onDefault: setDefault,
4833
+ boardBusy,
4026
4834
  pending,
4027
4835
  failureOf,
4028
4836
  act,
@@ -4031,21 +4839,15 @@ function MarketBody({ t, shown, pluginList, installedList, shared, pending, fail
4031
4839
  })), /* @__PURE__ */ h(MarketSection, {
4032
4840
  t,
4033
4841
  titleKey: "panels.market.sectionPlugins",
4842
+ icon: marketSectionIcon("plugins"),
4034
4843
  rows: pluginList,
4844
+ onDefault: setDefault,
4845
+ boardBusy,
4035
4846
  pending,
4036
4847
  failureOf,
4037
4848
  act,
4038
4849
  confirmActions: CONFIRM_UNINSTALL,
4039
4850
  onConfirming
4040
- }), /* @__PURE__ */ h(MarketSection, {
4041
- t,
4042
- titleKey: installedList.length > 0 && installedList.every((row) => row.local === true) ? "panels.market.sectionLocal" : "panels.market.sectionUnlisted",
4043
- rows: installedList,
4044
- pending,
4045
- failureOf,
4046
- act,
4047
- confirmActions: CONFIRM_REMOVE,
4048
- onConfirming
4049
4851
  }), /* @__PURE__ */ h(PanelFoot, {
4050
4852
  size: "md",
4051
4853
  text: t("panels.market.foot")
@@ -4057,95 +4859,91 @@ function MarketBody({ t, shown, pluginList, installedList, shared, pending, fail
4057
4859
  act
4058
4860
  }));
4059
4861
  }
4060
- function MarketView({ t, manifests, capabilities, freshness, onChanged, updates, installed, installedRead, plugins, settling, mock }) {
4862
+ function MarketView({ t, manifests, installable, capabilities, freshness, onChanged, onPending, updates, installed, installedRead, workbench, plugins, settling, mock, defaults = [], changed = {} }) {
4061
4863
  const [titles, setTitles] = useState(/* @__PURE__ */ new Map());
4062
4864
  useEffect(() => {
4063
4865
  if (mock === void 0) setTitles((known) => mergeTitles(known, manifests));
4064
4866
  }, [manifests, mock]);
4065
4867
  const catalog = mock?.manifests ?? manifests;
4868
+ const marketable = mock === void 0 ? marketCatalog(manifests, installable) : catalog;
4066
4869
  const effective = mock === void 0 ? capabilities : mock.capabilities;
4067
- const source = liveManifests(catalog, effective, mock === void 0 && installed !== void 0 ? new Set(installed.map((item) => item.unit)) : null);
4068
- const rows = marketRows(source, effective, mock?.updates ?? updates ?? {});
4870
+ const source = liveManifests(marketable, effective, mock === void 0 && installed !== void 0 ? new Set(installed.map((item) => item.unit)) : null);
4871
+ const byDefault = new Set(defaults);
4872
+ const rows = marketRows(source, effective, mock?.updates ?? updates ?? {}, byDefault, changed);
4069
4873
  const shared = sharedRows(source, effective);
4070
4874
  const [pending, setPending] = useState(mock?.pending ?? null);
4875
+ useEffect(() => {
4876
+ onPending?.(pending !== null);
4877
+ return () => onPending?.(false);
4878
+ }, [pending, onPending]);
4071
4879
  const provision = useHostWrite({
4072
4880
  channel: "provision",
4073
4881
  networkText: t("panels.failed")
4074
4882
  });
4883
+ const boardWrite = useHostWrite({
4884
+ channel: "prefs",
4885
+ resource: "panels",
4886
+ networkText: t("panels.failed")
4887
+ });
4888
+ const [writingDefault, setWritingDefault] = useState(false);
4889
+ const settleDefault = useBoardSettle(machineBoardSignature(defaults, changed));
4890
+ const { busy: boardBusy } = useVisibleBusy(writingDefault || settleDefault.pending, 500);
4891
+ const setDefault = async (id, next) => {
4892
+ if (mock !== void 0) return;
4893
+ setWritingDefault(true);
4894
+ settleDefault.begin();
4895
+ const outcome = await boardWrite.send({
4896
+ action: next ? "show" : "hide",
4897
+ id,
4898
+ scope: "machine"
4899
+ });
4900
+ setWritingDefault(false);
4901
+ if (!outcome.ok) {
4902
+ settleDefault.clear();
4903
+ setNotice(t("panels.failed"));
4904
+ }
4905
+ };
4075
4906
  const [confirming, setConfirming] = useState(mock?.confirming ?? null);
4076
4907
  const [failed, setFailed] = useState(mock?.failure ?? null);
4077
4908
  const [notice, setNotice] = useState(mock?.notice ?? null);
4078
4909
  const removing = pending !== null && pending.action === "remove-bundle" && failed?.id !== pending.id ? pending.id : null;
4079
- const installedList = installedRows((mock?.installed ?? installed ?? []).filter((module) => !(settling?.has(module.unit) ?? false) && module.unit !== removing), catalog, new Set(rows.map((row) => row.id)), titles);
4080
- const pendingRow = removing === null || pending === null || rows.some((row) => row.id === removing) ? void 0 : {
4081
- id: removing,
4082
- titleKey: pending.titleKey ?? titles.get(removing) ?? removing,
4083
- state: "installed",
4084
- canInstall: false,
4085
- canUpdate: false,
4086
- canUninstall: true,
4087
- ...pending.pkg === void 0 ? {} : { pkg: pending.pkg },
4088
- ...pending.version === void 0 ? {} : { version: { installed: pending.version } }
4089
- };
4910
+ 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);
4911
+ const pendingRow = pendingRowOf({
4912
+ pending,
4913
+ removing,
4914
+ rows,
4915
+ titles
4916
+ });
4090
4917
  const shown = pendingRow === void 0 ? rows : [...rows, pendingRow];
4091
- const pluginList = installedPluginRows(mock?.plugins ?? plugins ?? []);
4918
+ const self = workbenchRow(mock === void 0 ? workbench : mock.workbench);
4919
+ const pluginList = installedPluginRows(mock?.plugins ?? plugins ?? [], byDefault, changed);
4092
4920
  const rowById = new Map([
4093
4921
  ...shown,
4922
+ ...self === void 0 ? [] : [self],
4094
4923
  ...installedList,
4095
4924
  ...pluginList
4096
4925
  ].map((row) => [row.id, row]));
4097
4926
  const confirmingRow = confirming === null ? void 0 : rowById.get(confirming);
4098
- const act = async (id, action) => {
4099
- if (mock !== void 0) return;
4100
- const row = rowById.get(id);
4101
- setPending({
4102
- id,
4103
- action,
4104
- ...row?.titleKey === void 0 ? {} : { titleKey: row.titleKey },
4105
- ...row?.pkg === void 0 ? {} : { pkg: row.pkg },
4106
- ...row?.version?.installed === void 0 ? {} : { version: row.version.installed }
4107
- });
4108
- setConfirming(null);
4109
- setFailed(null);
4110
- if (action !== "uninstall-plugin") setNotice(null);
4111
- const dependency = action === "update-dependency";
4112
- const byName = action === "remove-bundle" || action === "update-plugin" || action === "uninstall-plugin";
4113
- const outcome = await provision.send(dependency ? {
4114
- action,
4115
- id
4116
- } : byName ? {
4117
- action,
4118
- name: row?.pkg ?? ""
4119
- } : {
4120
- action,
4121
- unit: id
4122
- });
4123
- setPending(null);
4124
- if (!outcome.ok) {
4125
- onChanged();
4126
- setFailed({
4127
- id,
4128
- message: t("panels.market.failed", { reason: outcome.message })
4129
- });
4130
- return;
4131
- }
4132
- if (action === "uninstall-plugin") {
4133
- const kept = installedPluginKept(outcome.value);
4134
- setNotice(kept === void 0 ? null : t(kept.key, kept.names === void 0 ? {} : { names: kept.names.join(t("panels.market.listSeparator")) }));
4135
- }
4136
- const reason = changeFailure(changeOf(outcome.value), t);
4137
- onChanged();
4138
- if (reason !== void 0) setFailed({
4139
- id,
4140
- message: t("panels.market.failed", { reason })
4141
- });
4142
- };
4927
+ const act = marketActOf({
4928
+ t,
4929
+ mocked: mock !== void 0,
4930
+ rowOf: (id) => rowById.get(id),
4931
+ seats: {
4932
+ setPending,
4933
+ setConfirming,
4934
+ setFailed,
4935
+ setNotice
4936
+ },
4937
+ send: (body) => provision.send(body),
4938
+ onChanged
4939
+ });
4143
4940
  const settled = marketSettled(freshness, installedRead);
4144
- const nothing = shown.length === 0 && installedList.length === 0 && pluginList.length === 0;
4941
+ const nothing = shown.length === 0 && self === void 0 && installedList.length === 0 && pluginList.length === 0;
4145
4942
  if (!settled || (settling?.size ?? 0) > 0 && shown.length === 0 && installedList.length === 0) return /* @__PURE__ */ h(MarketChecking, { t });
4146
4943
  if (nothing) return /* @__PURE__ */ h(MarketEmpty, { t });
4147
4944
  return /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(MarketBody, {
4148
4945
  t,
4946
+ self,
4149
4947
  shown,
4150
4948
  pluginList,
4151
4949
  installedList,
@@ -4154,7 +4952,9 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
4154
4952
  failed,
4155
4953
  notice,
4156
4954
  act,
4157
- onConfirming: setConfirming
4955
+ onConfirming: setConfirming,
4956
+ setDefault,
4957
+ boardBusy
4158
4958
  }), /* @__PURE__ */ h(ConfirmUninstall, {
4159
4959
  key: confirming ?? "",
4160
4960
  t,
@@ -4170,6 +4970,182 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
4170
4970
  }));
4171
4971
  }
4172
4972
  //#endregion
4973
+ //#region src/modules/sessions/model/session-node.ts
4974
+ function visiblePendingKind(kind) {
4975
+ switch (kind) {
4976
+ case "approval":
4977
+ case "plan-review":
4978
+ case "question": return kind;
4979
+ default: return;
4980
+ }
4981
+ }
4982
+ function sessionNode(summary, statusById, list, pinnedIds, archivedIds) {
4983
+ const status = statusById.get(summary.id);
4984
+ const catalog = list.projectionsBySession[summary.id]?.values?.subagentCatalog;
4985
+ let runningSubagentCount = 0;
4986
+ for (const child of catalog ?? []) {
4987
+ const childStatus = statusById.get(child.id);
4988
+ const childRow = list.byId[child.id];
4989
+ if ((childStatus?.running ?? childRow?.running) === true) runningSubagentCount += 1;
4990
+ }
4991
+ return {
4992
+ id: summary.id,
4993
+ title: summary.blank ? "" : summary.displayTitle,
4994
+ blank: summary.blank,
4995
+ running: status?.running ?? summary.running,
4996
+ runningSubagentCount,
4997
+ completed: status?.completionUnread === true,
4998
+ pinned: !archivedIds.has(summary.id) && pinnedIds.has(summary.id),
4999
+ updatedAt: summary.updatedAt,
5000
+ pendingInteraction: visiblePendingKind(status?.pendingInteraction?.kind)
5001
+ };
5002
+ }
5003
+ function sessionStatuses(node, t) {
5004
+ const subagents = node.runningSubagentCount > 0 ? {
5005
+ state: "ongoing",
5006
+ label: t(node.runningSubagentCount === 1 ? "status.subagentsRunning.one" : "status.subagentsRunning.other", { n: node.runningSubagentCount })
5007
+ } : void 0;
5008
+ let pending;
5009
+ switch (node.pendingInteraction) {
5010
+ case "approval":
5011
+ pending = {
5012
+ state: "warning",
5013
+ label: t("status.waitingApproval")
5014
+ };
5015
+ break;
5016
+ case "plan-review":
5017
+ pending = {
5018
+ state: "warning",
5019
+ label: t("status.planReview")
5020
+ };
5021
+ break;
5022
+ case "question":
5023
+ pending = {
5024
+ state: "warning",
5025
+ label: t("status.waitingAnswer")
5026
+ };
5027
+ break;
5028
+ default: pending = void 0;
5029
+ }
5030
+ if (pending !== void 0) return subagents === void 0 ? [pending] : [pending, subagents];
5031
+ if (node.running) {
5032
+ const primary = {
5033
+ state: "ongoing",
5034
+ label: t("status.running")
5035
+ };
5036
+ return subagents === void 0 ? [primary] : [primary, subagents];
5037
+ }
5038
+ if (subagents !== void 0) return [subagents];
5039
+ if (node.completed) return [{
5040
+ state: "done",
5041
+ label: t("status.completed")
5042
+ }];
5043
+ return [{
5044
+ state: "idle",
5045
+ label: t("status.idle")
5046
+ }];
5047
+ }
5048
+ function currentSessionId(list, panelActive) {
5049
+ if (panelActive) return void 0;
5050
+ return Object.values(list.byId).find((session) => (session.retainedBy?.mainView ?? 0) > 0)?.id;
5051
+ }
5052
+ function orderSessionRows(rows, pinnedIds, archivedIds) {
5053
+ const placeholders = [];
5054
+ const leading = [];
5055
+ const rest = [];
5056
+ for (const row of rows) if (row.blank) placeholders.push(row);
5057
+ else if (!archivedIds.has(row.id) && pinnedIds.has(row.id)) leading.push(row);
5058
+ else rest.push(row);
5059
+ return [
5060
+ ...placeholders,
5061
+ ...leading,
5062
+ ...rest
5063
+ ];
5064
+ }
5065
+ function workspaceOfSession(workspaces, sessionId) {
5066
+ if (sessionId === void 0) return null;
5067
+ return workspaces.find((workspace) => workspace.sessionIds.includes(sessionId)) ?? null;
5068
+ }
5069
+ function sessionRows(workspaceSessionIds, list, archivedIds, current) {
5070
+ const rows = [];
5071
+ for (const id of workspaceSessionIds) {
5072
+ if (archivedIds.has(id)) continue;
5073
+ const row = list.byId[id];
5074
+ if (row === void 0 || row.origin === "subagent") continue;
5075
+ if (row.blank && row.id !== current) continue;
5076
+ rows.push(row);
5077
+ }
5078
+ return rows;
5079
+ }
5080
+ //#endregion
5081
+ //#region src/app/layouts/project-selection.ts
5082
+ var listeners$1 = /* @__PURE__ */ new Set();
5083
+ function selectedProjectId() {
5084
+ const stored = readText(STORAGE_KEY_PROJECT);
5085
+ return stored === "" ? null : stored;
5086
+ }
5087
+ function selectProject(workspaceId) {
5088
+ writeText(STORAGE_KEY_PROJECT, workspaceId);
5089
+ for (const listener of [...listeners$1]) try {
5090
+ listener();
5091
+ } catch {}
5092
+ }
5093
+ function subscribeProject(listener) {
5094
+ listeners$1.add(listener);
5095
+ return () => {
5096
+ listeners$1.delete(listener);
5097
+ };
5098
+ }
5099
+ //#endregion
5100
+ //#region src/app/layouts/rightbar/use-panels.ts
5101
+ function shouldDropPanels(workspace, previous) {
5102
+ return workspace !== previous;
5103
+ }
5104
+ function useEnabledUnits(refreshToken, workspace) {
5105
+ const [enabled, setEnabled] = useState(null);
5106
+ const lastWorkspace = useRef(workspace);
5107
+ useEffect(() => {
5108
+ let cancelled = false;
5109
+ if (shouldDropPanels(workspace, lastWorkspace.current)) {
5110
+ lastWorkspace.current = workspace;
5111
+ setEnabled(null);
5112
+ }
5113
+ const read = async () => {
5114
+ const response = await apiGet("panels", workspace === null ? {} : { path: workspace }).catch(() => null);
5115
+ if (cancelled) return;
5116
+ if (response?.ok === true && Array.isArray(response.units)) setEnabled({
5117
+ units: response.units,
5118
+ plugins: Array.isArray(response.plugins) ? response.plugins : [],
5119
+ defaults: Array.isArray(response.defaults) ? response.defaults : [],
5120
+ own: response.own === true,
5121
+ changed: response.changed ?? {}
5122
+ });
5123
+ };
5124
+ read();
5125
+ return () => {
5126
+ cancelled = true;
5127
+ };
5128
+ }, [
5129
+ refreshToken,
5130
+ useFactRevision("panels"),
5131
+ workspace
5132
+ ]);
5133
+ return enabled;
5134
+ }
5135
+ function useSelectedProjectId() {
5136
+ const [id, setId] = useState(() => selectedProjectId());
5137
+ useEffect(() => subscribeProject(() => setId(selectedProjectId())), []);
5138
+ return id;
5139
+ }
5140
+ function useBoardWorkspace(workspaces, sessions) {
5141
+ const projectId = useSelectedProjectId();
5142
+ const workspace = workspaces.items.find((item) => item.workspaceId === projectId) ?? workspaceOfSession(workspaces.items, currentSessionId(sessions, false));
5143
+ return {
5144
+ workspace,
5145
+ path: workspace?.path ?? null
5146
+ };
5147
+ }
5148
+ //#endregion
4173
5149
  //#region src/shared/api/bundle-install.ts
4174
5150
  var BUNDLE_REGISTRIES_ROUTE = "bundle-registries";
4175
5151
  var BUNDLE_INSPECT_ROUTE = "bundle-inspect";
@@ -4199,10 +5175,11 @@ function readInstalledPlugins(force = false) {
4199
5175
  var state = {
4200
5176
  modules: null,
4201
5177
  plugins: null,
5178
+ workbench: null,
4202
5179
  read: false,
4203
5180
  checkedAt: null
4204
5181
  };
4205
- var listeners$1 = /* @__PURE__ */ new Set();
5182
+ var listeners = /* @__PURE__ */ new Set();
4206
5183
  var inFlight = null;
4207
5184
  var readSeq = 0;
4208
5185
  var newestForceSeq = -1;
@@ -4210,14 +5187,14 @@ function moduleVersionsValue() {
4210
5187
  return state;
4211
5188
  }
4212
5189
  function subscribeModuleVersions(listener) {
4213
- listeners$1.add(listener);
5190
+ listeners.add(listener);
4214
5191
  return () => {
4215
- listeners$1.delete(listener);
5192
+ listeners.delete(listener);
4216
5193
  };
4217
5194
  }
4218
5195
  function publish(next) {
4219
5196
  state = next;
4220
- for (const listener of [...listeners$1]) listener();
5197
+ for (const listener of [...listeners]) listener();
4221
5198
  }
4222
5199
  function runModuleVersionsRead(force = false) {
4223
5200
  if (inFlight !== null && inFlight.force === force) return inFlight.promise;
@@ -4230,6 +5207,7 @@ function runModuleVersionsRead(force = false) {
4230
5207
  publish({
4231
5208
  modules: versions?.ok === true ? versions.modules : state.modules,
4232
5209
  plugins: plugins?.ok === true ? plugins.plugins : state.plugins,
5210
+ workbench: versions?.ok === true ? versions.workbench ?? null : state.workbench,
4233
5211
  read: true,
4234
5212
  checkedAt: Date.now()
4235
5213
  });
@@ -4262,6 +5240,7 @@ function useModuleVersions() {
4262
5240
  return {
4263
5241
  modules: value.modules,
4264
5242
  plugins: value.plugins,
5243
+ workbench: value.workbench,
4265
5244
  read: value.read,
4266
5245
  checkedAt: value.checkedAt,
4267
5246
  reload
@@ -4486,7 +5465,9 @@ function AddModulePreview({ t, state }) {
4486
5465
  const preview = state.preview;
4487
5466
  if (preview === null) return null;
4488
5467
  const source = preview.registry === "" ? t("panels.market.add.registryDefault") : preview.registry;
4489
- 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)));
5468
+ const plugin = preview.kind === "plugin";
5469
+ const pluginName = plugin ? preview.pluginName : void 0;
5470
+ 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);
4490
5471
  }
4491
5472
  function AddModuleResult({ t, state }) {
4492
5473
  const outcome = state.outcome;
@@ -4494,26 +5475,27 @@ function AddModuleResult({ t, state }) {
4494
5475
  const reason = failureReason(failureCode(outcome.change), outcome.change.application, t);
4495
5476
  const supply = supplyKey(outcome.supply.state);
4496
5477
  const builds = state.builds;
4497
- const failed = outcome.change.application === "failed";
4498
- const restart = outcome.change.application === "restart-required";
4499
- const cancelled = outcome.change.application === "cancelled";
4500
- const notModule = outcome.supply.state === "not-a-module";
4501
5478
  const plugin = outcome.plugin;
5479
+ const kind = resultKindOf({
5480
+ change: outcome.change,
5481
+ supplyState: outcome.supply.state,
5482
+ plugin: plugin !== void 0
5483
+ });
4502
5484
  const name = outcome.module.kind === "module" ? outcome.module.unit : outcome.module.pkg;
4503
5485
  return /* @__PURE__ */ h("div", { className: AddModule_module_default.body }, /* @__PURE__ */ h("div", { className: AddModule_module_default.hero }, /* @__PURE__ */ h("span", {
4504
5486
  className: AddModule_module_default.heroIcon,
4505
- "data-state": failed ? "error" : cancelled ? "idle" : "done",
5487
+ "data-state": kind === "failed" ? "error" : kind === "cancelled" ? "idle" : "done",
4506
5488
  "aria-hidden": "true"
4507
- }, failed ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, { size: 28 }) : cancelled ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
5489
+ }, kind === "failed" ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, { size: 28 }) : kind === "cancelled" ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
4508
5490
  state: "idle",
4509
5491
  size: 28
4510
5492
  }) : /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconCheckCircleFillRegular, { size: 28 })), /* @__PURE__ */ h("h2", {
4511
5493
  className: AddModule_module_default.wizardTitle,
4512
- role: failed ? "alert" : "status"
4513
- }, failed ? t("panels.market.add.failedTitle") : cancelled ? t("panels.market.add.cancelledTitle") : t("panels.market.add.installedTitle"))), /* @__PURE__ */ h("div", { className: AddModule_module_default.subject }, /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectName }, outcome.module.pkg), name === outcome.module.pkg ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, name), outcome.module.version === void 0 ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, t("panels.market.add.installVersion", { version: outcome.module.version }))), plugin !== void 0 ? /* @__PURE__ */ h("p", { className: AddModule_module_default.result }, t("panels.market.add.installedPlugin", { name: plugin.name ?? plugin.pkg })) : failed ? /* @__PURE__ */ h("p", {
5494
+ role: kind === "failed" ? "alert" : "status"
5495
+ }, 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", {
4514
5496
  className: AddModule_module_default.resultWarn,
4515
5497
  role: "alert"
4516
- }, t("panels.market.add.failed", { reason })) : restart ? /* @__PURE__ */ h("p", { className: AddModule_module_default.resultWarn }, t("panels.market.add.doneRestart")) : cancelled || notModule ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.result }, t("panels.market.add.tookEffect")), builds.length === 0 ? null : /* @__PURE__ */ h("div", { className: AddModule_module_default.approval }, /* @__PURE__ */ h("p", { className: AddModule_module_default.approvalTitle }, t("panels.market.add.approveTitle")), /* @__PURE__ */ h("p", { className: AddModule_module_default.approvalText }, t("panels.market.add.approveHint", { packages: builds.join("、") })), /* @__PURE__ */ h("p", { className: AddModule_module_default.approvalCaution }, t("panels.market.add.approveCaution"))), supply === void 0 || outcome.supply.state !== "failed" && (failed || cancelled) ? null : /* @__PURE__ */ h("p", { className: supplyTone(outcome.supply.state) }, t(supply, { reason: outcome.supply.reason ?? "" })), state.failure === null ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.problem }, state.failure), outcome.change.errorDetail === void 0 ? null : /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h("p", { className: AddModule_module_default.detailLabel }, t("panels.market.add.details")), /* @__PURE__ */ h("p", { className: AddModule_module_default.detail }, outcome.change.errorDetail)));
5498
+ }, 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)));
4517
5499
  }
4518
5500
  //#endregion
4519
5501
  //#region src/app/layouts/market/add-module-mock.ts
@@ -4590,6 +5572,7 @@ var ADD_MODULE_MOCKS = [
4590
5572
  phase: "preview",
4591
5573
  spec: "@dsh-workbench/module-hello",
4592
5574
  preview: {
5575
+ kind: "module",
4593
5576
  name: "@dsh-workbench/module-hello",
4594
5577
  version: "0.1.2",
4595
5578
  description: "最小样本模块:一枚「你好」卡片",
@@ -4597,15 +5580,30 @@ var ADD_MODULE_MOCKS = [
4597
5580
  }
4598
5581
  },
4599
5582
  {
4600
- id: "preview-no-source",
4601
- label: "预览(问不出源)",
5583
+ id: "preview-no-source",
5584
+ label: "预览(问不出源)",
5585
+ phase: "preview",
5586
+ spec: "@dsh-workbench/module-hello",
5587
+ preview: {
5588
+ kind: "module",
5589
+ name: "@dsh-workbench/module-hello",
5590
+ version: "",
5591
+ description: "",
5592
+ registry: ""
5593
+ }
5594
+ },
5595
+ {
5596
+ id: "preview-plugin",
5597
+ label: "预览(opencli 插件)",
4602
5598
  phase: "preview",
4603
- spec: "@dsh-workbench/module-hello",
5599
+ spec: "opencli-plugin-grafana",
4604
5600
  preview: {
4605
- name: "@dsh-workbench/module-hello",
4606
- version: "",
5601
+ kind: "plugin",
5602
+ name: "opencli-plugin-grafana",
5603
+ version: "1.0.16",
4607
5604
  description: "",
4608
- registry: ""
5605
+ registry: "registry.npmmirror.com",
5606
+ pluginName: "grafana"
4609
5607
  }
4610
5608
  },
4611
5609
  {
@@ -4776,42 +5774,6 @@ function stateOfMock(base, mock) {
4776
5774
  };
4777
5775
  }
4778
5776
  //#endregion
4779
- //#region src/shared/hooks/use-visible-busy.ts
4780
- var use_visible_busy_exports = /* @__PURE__ */ __exportAll({
4781
- busyView: () => busyView,
4782
- heldPhase: () => heldPhase,
4783
- useVisibleBusy: () => useVisibleBusy
4784
- });
4785
- function heldPhase(phase, refreshing) {
4786
- return refreshing && phase === "ready" ? "loading" : phase;
4787
- }
4788
- function busyView(active, visible) {
4789
- return {
4790
- busy: visible,
4791
- settling: visible && !active
4792
- };
4793
- }
4794
- function useVisibleBusy(active, floorMs) {
4795
- const [visible, setVisible] = useState(active);
4796
- const since = useRef(null);
4797
- useEffect(() => {
4798
- if (active) {
4799
- if (since.current === null) since.current = Date.now();
4800
- setVisible(true);
4801
- return;
4802
- }
4803
- const held = holdBusy(since.current, Date.now(), floorMs);
4804
- since.current = null;
4805
- if (!held.visible) {
4806
- setVisible(false);
4807
- return;
4808
- }
4809
- const timer = setTimeout(() => setVisible(false), held.releaseInMs);
4810
- return () => clearTimeout(timer);
4811
- }, [active, floorMs]);
4812
- return busyView(active, visible);
4813
- }
4814
- //#endregion
4815
5777
  //#region src/app/layouts/market/use-add-module.ts
4816
5778
  function newRequestId() {
4817
5779
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
@@ -4897,12 +5859,7 @@ function useAddModule(options) {
4897
5859
  setPhase("idle");
4898
5860
  return;
4899
5861
  }
4900
- setPreview({
4901
- name: inspection.name ?? wanted,
4902
- version: inspection.version ?? "",
4903
- description: inspection.description ?? "",
4904
- registry: inspection.registry ?? ""
4905
- });
5862
+ setPreview(previewOf(inspection, wanted));
4906
5863
  setPhase("preview");
4907
5864
  });
4908
5865
  }, [spec, registry]);
@@ -4950,14 +5907,21 @@ function useAddModule(options) {
4950
5907
  requestId: requestIdRef.current
4951
5908
  });
4952
5909
  }, [cancel]);
5910
+ const [removing, setRemoving] = useState(false);
4953
5911
  const removeIt = useCallback(() => {
4954
5912
  const pkg = outcome?.module.pkg;
4955
5913
  if (pkg === void 0) return;
5914
+ setRemoving(true);
5915
+ setFailure(null);
4956
5916
  remove.send({
4957
5917
  action: "remove-bundle",
4958
5918
  name: pkg
4959
5919
  }).then((result) => {
4960
- if (!result.ok) return;
5920
+ setRemoving(false);
5921
+ if (!result.ok) {
5922
+ setFailure(result.message);
5923
+ return;
5924
+ }
4961
5925
  onInstalled();
4962
5926
  });
4963
5927
  }, [
@@ -4984,6 +5948,7 @@ function useAddModule(options) {
4984
5948
  preview,
4985
5949
  outcome,
4986
5950
  failure,
5951
+ removing,
4987
5952
  builds: outcome?.change.pendingBuilds ?? [],
4988
5953
  setSpec,
4989
5954
  setChoice: useCallback((next) => {
@@ -5057,8 +6022,13 @@ function AddModuleDialog({ t, open, onClose, onInstalled }) {
5057
6022
  variant: "outline",
5058
6023
  size: "md",
5059
6024
  className: "wb-dangerAction",
6025
+ disabled: state.removing,
6026
+ "aria-busy": state.removing,
5060
6027
  onClick: state.removeIt
5061
- }, t("panels.market.add.remove")) : null, /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.Button, {
6028
+ }, state.removing ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
6029
+ state: "ongoing",
6030
+ size: 12
6031
+ }) : null, t(state.removing ? "panels.market.uninstalling" : "panels.market.add.remove")) : null, /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.Button, {
5062
6032
  type: "button",
5063
6033
  variant: "outline",
5064
6034
  size: "md",
@@ -5120,12 +6090,17 @@ function useLiveManifests(units) {
5120
6090
  useSyncExternalStore(useCallback((listener) => units.subscribe(listener), [units]), useCallback(() => units.version(), [units]));
5121
6091
  return units.manifests();
5122
6092
  }
6093
+ function useInstallableUnits(units) {
6094
+ useSyncExternalStore(useCallback((listener) => units.subscribe(listener), [units]), useCallback(() => units.version(), [units]));
6095
+ return units.installable();
6096
+ }
5123
6097
  function makeMarketEntryIcon(units) {
5124
6098
  return function MarketEntryIcon({ size = 16 }) {
5125
6099
  const manifests = useLiveManifests(units);
6100
+ const installable = useInstallableUnits(units);
5126
6101
  const { capabilities } = useCapabilityMap(0);
5127
- const { modules } = useModuleVersions();
5128
- const hasUpdates = marketHintVisible(manifests, capabilities, modules);
6102
+ const { modules, workbench } = useModuleVersions();
6103
+ const hasUpdates = marketHintVisible(marketCatalog(manifests, installable), capabilities, modules, workbench);
5129
6104
  useEffect(() => {
5130
6105
  publishPanelHint(MARKET_PANEL_ID, hasUpdates ? { labelKey: "panels.market.hasNew" } : null);
5131
6106
  return () => publishPanelHint(MARKET_PANEL_ID, null);
@@ -5135,9 +6110,13 @@ function makeMarketEntryIcon(units) {
5135
6110
  }
5136
6111
  function MarketPanel({ t, units }) {
5137
6112
  const manifests = useLiveManifests(units);
6113
+ const installable = useInstallableUnits(units);
5138
6114
  const { capabilities, checkedAt, checking, forceProbe, reload: reloadCapability } = useCapabilityMap(0);
5139
- const { modules, plugins, read: installedRead, reload: reloadVersions } = useModuleVersions();
6115
+ const { modules, plugins, workbench, read: installedRead, reload: reloadVersions } = useModuleVersions();
6116
+ const machineBoard = useEnabledUnits(0, null);
5140
6117
  const [adding, setAdding] = useState(false);
6118
+ const [acting, setActing] = useState(false);
6119
+ const openAddModule = useCallback(() => setAdding(true), []);
5141
6120
  const updates = useMemo(() => marketUpdatesOf(modules), [modules]);
5142
6121
  const installed = modules === null ? void 0 : withClientRefusals(modules, units.refusals());
5143
6122
  const reload = useCallback(() => {
@@ -5198,7 +6177,7 @@ function MarketPanel({ t, units }) {
5198
6177
  const mockNonce = fixturePick.nonce;
5199
6178
  const shownFreshness = mock === void 0 ? freshness : mock.loaded === false ? pendingFreshness : MOCK_FRESHNESS;
5200
6179
  const shownRead = mock === void 0 ? installedRead : mock.installedRead ?? true;
5201
- const busy = !marketSettled(shownFreshness, shownRead) || shownFreshness.checking;
6180
+ const busy = !marketSettled(shownFreshness, shownRead) || shownFreshness.checking || acting;
5202
6181
  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", {
5203
6182
  type: "button",
5204
6183
  className: `${MarketPage_module_default.marketIconButton}${shownFreshness.checking ? ` ${MarketPage_module_default.marketIconButtonSpinning}` : ""}`,
@@ -5217,7 +6196,7 @@ function MarketPanel({ t, units }) {
5217
6196
  className: MarketPage_module_default.marketAddButton,
5218
6197
  icon: /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: 13 }),
5219
6198
  disabled: busy,
5220
- onClick: () => setAdding(true)
6199
+ onClick: openAddModule
5221
6200
  }, t("panels.market.add.open")))), fixturePick.enabled ? /* @__PURE__ */ h(MockStrip, {
5222
6201
  mocks: marketMocks,
5223
6202
  index: fixturePick.index,
@@ -5226,15 +6205,20 @@ function MarketPanel({ t, units }) {
5226
6205
  key: `${mock?.id ?? "real-market"}-${mockNonce}`,
5227
6206
  t,
5228
6207
  manifests,
6208
+ installable,
5229
6209
  capabilities,
5230
6210
  freshness: shownFreshness,
5231
6211
  onChanged: reload,
6212
+ onPending: setActing,
5232
6213
  updates,
5233
6214
  installed,
5234
6215
  installedRead: shownRead,
6216
+ workbench,
5235
6217
  plugins,
5236
6218
  settling: mock === void 0 ? settling : void 0,
5237
- mock
6219
+ mock,
6220
+ defaults: machineBoard?.defaults ?? [],
6221
+ changed: machineBoard?.changed ?? {}
5238
6222
  }), /* @__PURE__ */ h(AddModuleDialog, {
5239
6223
  t,
5240
6224
  open: adding,
@@ -5259,25 +6243,6 @@ function registerMarketPanel(ctx, units) {
5259
6243
  }, MarketPanel));
5260
6244
  }
5261
6245
  //#endregion
5262
- //#region src/app/layouts/project-selection.ts
5263
- var listeners = /* @__PURE__ */ new Set();
5264
- function selectedProjectId() {
5265
- const stored = readText(STORAGE_KEY_PROJECT);
5266
- return stored === "" ? null : stored;
5267
- }
5268
- function selectProject(workspaceId) {
5269
- writeText(STORAGE_KEY_PROJECT, workspaceId);
5270
- for (const listener of [...listeners]) try {
5271
- listener();
5272
- } catch {}
5273
- }
5274
- function subscribeProject(listener) {
5275
- listeners.add(listener);
5276
- return () => {
5277
- listeners.delete(listener);
5278
- };
5279
- }
5280
- //#endregion
5281
6246
  //#region src/shared/api/diy.ts
5282
6247
  var DIY_PRESET_ID = "workbench-diy";
5283
6248
  var WORKSHOP_TITLE = "工作台DIY";
@@ -5306,7 +6271,7 @@ function createUnitManifestLoader(options = {}) {
5306
6271
  inFlight = true;
5307
6272
  try {
5308
6273
  const response = await apiGet(UNIT_MANIFESTS_ROUTE).catch(() => null);
5309
- if (response?.ok === true && Array.isArray(response.manifests)) registry.setManifests(response.manifests);
6274
+ if (response?.ok === true && Array.isArray(response.manifests)) registry.setManifests(response.manifests, Array.isArray(response.installable) ? response.installable : void 0);
5310
6275
  } finally {
5311
6276
  inFlight = false;
5312
6277
  if (queued) {
@@ -6143,6 +7108,131 @@ function createDshColumnSource(read, intervalMs) {
6143
7108
  }
6144
7109
  };
6145
7110
  }
7111
+ //#endregion
7112
+ //#region src/app/layouts/rightbar/dsh-surface.ts
7113
+ var DSH_SEAT_ATTRIBUTE = "data-sidebar-right-session";
7114
+ function dshSeatOnScreen(host) {
7115
+ if (host === void 0) return false;
7116
+ return host.querySelector(`[${DSH_SEAT_ATTRIBUTE}]`) !== null;
7117
+ }
7118
+ function createDshSurfaceWatch(read, onReady, intervalMs) {
7119
+ let timer;
7120
+ const disarm = () => {
7121
+ if (timer === void 0) return;
7122
+ clearInterval(timer);
7123
+ timer = void 0;
7124
+ };
7125
+ const tick = () => {
7126
+ if (!read()) return;
7127
+ disarm();
7128
+ onReady();
7129
+ };
7130
+ return {
7131
+ arm() {
7132
+ if (timer !== void 0) return;
7133
+ timer = setInterval(tick, intervalMs);
7134
+ },
7135
+ disarm
7136
+ };
7137
+ }
7138
+ //#endregion
7139
+ //#region src/app/layouts/rightbar/dsh-borrow.ts
7140
+ function createDshBorrow(host) {
7141
+ let pendingOpen = false;
7142
+ let pendingCall;
7143
+ let unsubscribe;
7144
+ let restore;
7145
+ let shimmed = false;
7146
+ const flush = () => {
7147
+ const official = host.official();
7148
+ if (official === void 0 || !dshSeatOnScreen(document)) return;
7149
+ if (pendingOpen) {
7150
+ pendingOpen = false;
7151
+ if (!official.isExpanded()) official.toggleExpanded();
7152
+ }
7153
+ const call = pendingCall;
7154
+ pendingCall = void 0;
7155
+ call?.();
7156
+ };
7157
+ const watch = createDshSurfaceWatch(() => dshSeatOnScreen(document), flush, 60);
7158
+ const subscribe = () => {
7159
+ const official = host.official();
7160
+ if (official === void 0 || unsubscribe !== void 0) return;
7161
+ unsubscribe = official.mounted.subscribe(() => {
7162
+ watch.arm();
7163
+ flush();
7164
+ });
7165
+ };
7166
+ const enter = (call) => {
7167
+ const official = host.official();
7168
+ if (official === void 0) return false;
7169
+ if (dshSeatOnScreen(document)) {
7170
+ if (!official.isExpanded()) official.toggleExpanded();
7171
+ call?.();
7172
+ return true;
7173
+ }
7174
+ subscribe();
7175
+ watch.arm();
7176
+ host.yieldColumn();
7177
+ pendingOpen = true;
7178
+ if (call !== void 0) pendingCall = call;
7179
+ return false;
7180
+ };
7181
+ const takeSeat = (call) => {
7182
+ shim();
7183
+ if (host.official() === void 0) return;
7184
+ enter(call);
7185
+ };
7186
+ const shim = () => {
7187
+ const official = host.official();
7188
+ if (official === void 0 || shimmed) return;
7189
+ const { openResource, openTab } = official;
7190
+ if (typeof openResource !== "function" || typeof openTab !== "function") return;
7191
+ shimmed = true;
7192
+ official.openResource = (address, options) => takeSeat(() => openResource.call(official, address, options));
7193
+ official.openTab = (kind, options) => takeSeat(() => openTab.call(official, kind, options));
7194
+ restore = () => {
7195
+ official.openResource = openResource;
7196
+ official.openTab = openTab;
7197
+ shimmed = false;
7198
+ };
7199
+ };
7200
+ return {
7201
+ open() {
7202
+ const official = host.official();
7203
+ if (official === void 0) return false;
7204
+ return official.mounted.getSnapshot() === void 0 || official.isExpanded();
7205
+ },
7206
+ use: takeSeat,
7207
+ toggle() {
7208
+ const official = host.official();
7209
+ if (official === void 0) return;
7210
+ if (!dshSeatOnScreen(document)) {
7211
+ pendingOpen = true;
7212
+ watch.arm();
7213
+ return;
7214
+ }
7215
+ official.toggleExpanded();
7216
+ },
7217
+ back() {
7218
+ pendingOpen = false;
7219
+ pendingCall = void 0;
7220
+ watch.disarm();
7221
+ host.reclaimColumn();
7222
+ },
7223
+ start() {
7224
+ shim();
7225
+ subscribe();
7226
+ },
7227
+ dispose() {
7228
+ unsubscribe?.();
7229
+ unsubscribe = void 0;
7230
+ watch.disarm();
7231
+ restore?.();
7232
+ restore = void 0;
7233
+ }
7234
+ };
7235
+ }
6146
7236
  var Breadcrumbs_module_default = {
6147
7237
  stripTabs: "_stripTabs_1dqp4_1",
6148
7238
  tab: "_tab_1dqp4_9",
@@ -6215,20 +7305,29 @@ function BoardMockStrip({ fixtures, show }) {
6215
7305
  });
6216
7306
  }
6217
7307
  var ModulesPage_module_default = {
6218
- trigger: "_trigger_1weg4_1",
6219
- pop: "_pop_1weg4_7",
6220
- head: "_head_1weg4_21",
6221
- title: "_title_1weg4_29",
6222
- reset: "_reset_1weg4_37",
6223
- list: "_list_1weg4_59",
6224
- row: "_row_1weg4_68",
6225
- rowOver: "_rowOver_1weg4_83",
6226
- ghost: "_ghost_1weg4_93",
6227
- grip: "_grip_1weg4_108",
6228
- label: "_label_1weg4_116",
6229
- name: "_name_1weg4_123",
6230
- error: "_error_1weg4_134",
6231
- dep: "_dep_1weg4_142"
7308
+ trigger: "_trigger_15ptp_1",
7309
+ pop: "_pop_15ptp_6",
7310
+ head: "_head_15ptp_20",
7311
+ title: "_title_15ptp_28",
7312
+ rowControls: "_rowControls_15ptp_36",
7313
+ reset: "_reset_15ptp_43",
7314
+ list: "_list_15ptp_65",
7315
+ row: "_row_15ptp_36",
7316
+ rowDragging: "_rowDragging_15ptp_85",
7317
+ rowBlocked: "_rowBlocked_15ptp_89",
7318
+ listDragging: "_listDragging_15ptp_93",
7319
+ rowOff: "_rowOff_15ptp_101",
7320
+ rowOver: "_rowOver_15ptp_109",
7321
+ ghost: "_ghost_15ptp_119",
7322
+ grip: "_grip_15ptp_134",
7323
+ gripDragging: "_gripDragging_15ptp_144",
7324
+ gripBlocked: "_gripBlocked_15ptp_148",
7325
+ label: "_label_15ptp_152",
7326
+ name: "_name_15ptp_159",
7327
+ error: "_error_15ptp_170",
7328
+ dep: "_dep_15ptp_178",
7329
+ group: "_group_15ptp_186",
7330
+ groupTitle: "_groupTitle_15ptp_191"
6232
7331
  };
6233
7332
  //#endregion
6234
7333
  //#region src/app/layouts/rightbar/panel-mock.ts
@@ -6241,6 +7340,32 @@ function row$1(id, titleKey, shown) {
6241
7340
  hasCard: true
6242
7341
  };
6243
7342
  }
7343
+ function noCardRow(id, titleKey) {
7344
+ return {
7345
+ id,
7346
+ titleKey,
7347
+ shown: false,
7348
+ source: "user",
7349
+ hasCard: false
7350
+ };
7351
+ }
7352
+ function plugin(id, pkg, title, shown) {
7353
+ return {
7354
+ id,
7355
+ pkg,
7356
+ title,
7357
+ shown,
7358
+ source: "user"
7359
+ };
7360
+ }
7361
+ var PLUGIN_MOCK = {
7362
+ id: "plugin",
7363
+ label: "opencli 插件行(标出是插件,能开能关)",
7364
+ units: [],
7365
+ plugins: [plugin("plugin:opencli-plugin-cmdb", "opencli-plugin-cmdb", "cmdb", true), plugin("plugin:opencli-plugin-notes", "opencli-plugin-notes", "notes", false)],
7366
+ capabilities: {},
7367
+ expect: { rows: 0 }
7368
+ };
6244
7369
  function probe(unit, status) {
6245
7370
  return { [unit]: {
6246
7371
  unit,
@@ -6258,7 +7383,7 @@ function buildPanelMocks(roster) {
6258
7383
  units: [],
6259
7384
  capabilities: {},
6260
7385
  expect: { rows: 0 }
6261
- }];
7386
+ }, PLUGIN_MOCK];
6262
7387
  const titleKey = found.card?.titleKey ?? found.id;
6263
7388
  const id = found.id;
6264
7389
  const on = row$1(id, titleKey, true);
@@ -6343,6 +7468,20 @@ function buildPanelMocks(roster) {
6343
7468
  on: true
6344
7469
  }
6345
7470
  },
7471
+ {
7472
+ id: "no-card",
7473
+ label: "没看板的模块(只有基座命令那种):也列出来、带「无看板」标签,开关照常能用,只是不参与排序",
7474
+ units: [on, noCardRow(`${id}-c`, `${titleKey}(无看板)`)],
7475
+ capabilities: {
7476
+ ...probe(id, "ok"),
7477
+ ...probe(`${id}-c`, "ok")
7478
+ },
7479
+ expect: {
7480
+ rows: 2,
7481
+ badge: null,
7482
+ on: true
7483
+ }
7484
+ },
6346
7485
  {
6347
7486
  id: "long",
6348
7487
  label: "超长模块名",
@@ -6393,7 +7532,7 @@ function buildPanelMocks(roster) {
6393
7532
  ...probe(`${id}-c`, "ok")
6394
7533
  },
6395
7534
  drag: {
6396
- from: 2,
7535
+ from: 1,
6397
7536
  over: 0,
6398
7537
  at: {
6399
7538
  x: 1230,
@@ -6404,7 +7543,34 @@ function buildPanelMocks(roster) {
6404
7543
  rows: 3,
6405
7544
  on: true
6406
7545
  }
6407
- }
7546
+ },
7547
+ {
7548
+ id: "drag-off",
7549
+ label: "拖到未开启的那一行上:落点不亮(松手也不动)",
7550
+ units: [
7551
+ on,
7552
+ twin,
7553
+ third
7554
+ ],
7555
+ capabilities: {
7556
+ ...probe(id, "ok"),
7557
+ ...probe(`${id}-b`, "ok"),
7558
+ ...probe(`${id}-c`, "ok")
7559
+ },
7560
+ drag: {
7561
+ from: 0,
7562
+ over: null,
7563
+ at: {
7564
+ x: 1230,
7565
+ y: 300
7566
+ }
7567
+ },
7568
+ expect: {
7569
+ rows: 3,
7570
+ on: true
7571
+ }
7572
+ },
7573
+ PLUGIN_MOCK
6408
7574
  ];
6409
7575
  }
6410
7576
  //#endregion
@@ -6417,6 +7583,22 @@ function available(capability) {
6417
7583
  function selectPanelUnits(units, capabilities) {
6418
7584
  return units.filter((unit) => available(capabilities?.[unit.id]));
6419
7585
  }
7586
+ function panelDropTarget(rows, index) {
7587
+ if (index === null) return null;
7588
+ const row = rows[index];
7589
+ return row?.shown === true && row.hasCard !== false ? index : null;
7590
+ }
7591
+ function rowAtPoint(boxes, y) {
7592
+ const last = boxes.length - 1;
7593
+ for (let at = 0; at <= last; at += 1) {
7594
+ const box = boxes[at];
7595
+ const next = boxes[at + 1];
7596
+ if (box === void 0) continue;
7597
+ const end = next === void 0 ? box.bottom : next.top;
7598
+ if (y >= box.top && (next === void 0 ? y <= end : y < end)) return at;
7599
+ }
7600
+ return null;
7601
+ }
6420
7602
  function panelBadgeKey(capability) {
6421
7603
  if (capability === void 0 || capability.status === "ok") return void 0;
6422
7604
  if (capability.status === "failed") return "panels.dep.failed";
@@ -6424,6 +7606,31 @@ function panelBadgeKey(capability) {
6424
7606
  if (capability.status === "missing-commands") return "panels.dep.missingCommands";
6425
7607
  return "panels.dep.unchecked";
6426
7608
  }
7609
+ function moduleRow(unit, capability) {
7610
+ const badge = panelBadgeKey(capability);
7611
+ return {
7612
+ id: unit.id,
7613
+ titleKey: unit.titleKey,
7614
+ plugin: false,
7615
+ hasCard: unit.hasCard,
7616
+ ...badge === void 0 ? {} : { badgeKey: badge },
7617
+ shown: unit.shown,
7618
+ source: unit.source
7619
+ };
7620
+ }
7621
+ function pluginRow(plugin) {
7622
+ return {
7623
+ id: plugin.id,
7624
+ title: plugin.title,
7625
+ plugin: true,
7626
+ shown: plugin.shown,
7627
+ source: plugin.source
7628
+ };
7629
+ }
7630
+ function selectPanelRows(units, plugins, capabilities) {
7631
+ const listed = new Set(plugins.map((plugin) => plugin.id));
7632
+ return [...selectPanelUnits(units, capabilities).filter((unit) => !listed.has(unit.id)).map((unit) => moduleRow(unit, capabilities?.[unit.id])), ...plugins.map(pluginRow)];
7633
+ }
6427
7634
  function selectBoardModules(units, byId, capabilities) {
6428
7635
  if (units === null) return [];
6429
7636
  return units.filter((unit) => unit.shown && available(capabilities?.[unit.id])).map((unit) => byId(unit.id)).filter((module) => module !== void 0);
@@ -6437,49 +7644,106 @@ function aggregateSummaries(summaries) {
6437
7644
  };
6438
7645
  }
6439
7646
  //#endregion
6440
- //#region src/app/layouts/rightbar/ModulesPage.tsx
6441
- var BLANK_DRAG_IMAGE = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
6442
- function ModulesPage({ t, units, workspace, capabilities, loading = false, onOpenMarket, mocked = false, mock }) {
6443
- const [drag, setDrag] = useState(mock?.drag ?? null);
6444
- const [busy, setBusy] = useState(mock?.busy ?? false);
6445
- const [failed, setFailed] = useState(mock?.failed ?? false);
6446
- const rows = selectPanelUnits(units, capabilities);
6447
- const empty = !loading && rows.length === 0;
6448
- const prefWrite = useHostWrite({
6449
- channel: "prefs",
6450
- resource: "panels",
6451
- networkText: t("panels.failed")
7647
+ //#region src/app/layouts/rightbar/PanelRowControls.tsx
7648
+ function PanelRowControls({ t, unit, label, busy, onWrite }) {
7649
+ return /* @__PURE__ */ h("span", { className: ModulesPage_module_default.rowControls }, /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.Switch, {
7650
+ checked: unit.shown,
7651
+ label: `${label} · ${unit.shown ? t("panels.enabled") : t("panels.disabled")}`,
7652
+ disabled: busy,
7653
+ onChange: (next) => onWrite({
7654
+ action: next ? "show" : "hide",
7655
+ id: unit.id
7656
+ })
7657
+ }));
7658
+ }
7659
+ //#endregion
7660
+ //#region src/app/layouts/rightbar/PanelGroupRows.tsx
7661
+ function PanelGroupRows({ t, rows, titleKey, busy, onWrite }) {
7662
+ if (rows.length === 0) return null;
7663
+ 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) => {
7664
+ const title = row.title ?? t(row.titleKey ?? row.id);
7665
+ return /* @__PURE__ */ h("li", {
7666
+ key: row.id,
7667
+ className: `${ModulesPage_module_default.row} ${row.shown ? "" : ModulesPage_module_default.rowOff}`
7668
+ }, /* @__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, {
7669
+ t,
7670
+ unit: row,
7671
+ label: title,
7672
+ busy,
7673
+ onWrite
7674
+ }));
7675
+ })));
7676
+ }
7677
+ //#endregion
7678
+ //#region src/app/layouts/rightbar/use-drag-listeners.ts
7679
+ function useDragListeners(active, handlers) {
7680
+ const latestRef = useRef(handlers);
7681
+ useEffect(() => {
7682
+ latestRef.current = handlers;
6452
7683
  });
6453
- const write = async (body) => {
6454
- if (mocked) return;
6455
- setBusy(true);
6456
- setFailed(false);
6457
- const outcome = await prefWrite.send({
6458
- ...body,
6459
- ...workspace === null ? {} : { path: workspace }
6460
- });
6461
- setBusy(false);
6462
- if (!outcome.ok) setFailed(true);
6463
- };
6464
- const drop = () => {
6465
- if (drag === null) return;
6466
- const moved = rows[drag.from];
6467
- setDrag(null);
6468
- if (moved === void 0 || drag.from === drag.over) return;
6469
- write({
6470
- action: "move",
6471
- id: moved.id,
6472
- index: drag.over
6473
- });
6474
- };
6475
- const dragging = drag === null ? void 0 : rows[drag.from];
6476
- return /* @__PURE__ */ h(Fragment, null, drag?.at === void 0 || dragging === void 0 ? null : /* @__PURE__ */ h("div", {
6477
- className: ModulesPage_module_default.ghost,
6478
- style: {
6479
- left: `${drag.at.x + 12}px`,
6480
- top: `${drag.at.y - 12}px`
7684
+ useEffect(() => {
7685
+ if (!active) return;
7686
+ const onMove = (event) => latestRef.current.move(event.clientX, event.clientY);
7687
+ const onUp = (event) => latestRef.current.drop(event.clientY);
7688
+ const onCancel = () => latestRef.current.cancel();
7689
+ window.addEventListener("pointermove", onMove);
7690
+ window.addEventListener("pointerup", onUp);
7691
+ window.addEventListener("pointercancel", onCancel);
7692
+ window.addEventListener("blur", onCancel);
7693
+ return () => {
7694
+ window.removeEventListener("pointermove", onMove);
7695
+ window.removeEventListener("pointerup", onUp);
7696
+ window.removeEventListener("pointercancel", onCancel);
7697
+ window.removeEventListener("blur", onCancel);
7698
+ };
7699
+ }, [active]);
7700
+ }
7701
+ //#endregion
7702
+ //#region src/app/layouts/rightbar/ModulesPage.tsx
7703
+ function rowBoxes(list) {
7704
+ return list === null ? [] : Array.from(list.children).map((item) => item.getBoundingClientRect());
7705
+ }
7706
+ function rowClass(row, index, drag) {
7707
+ const parts = [ModulesPage_module_default.row];
7708
+ if (!row.shown) parts.push(ModulesPage_module_default.rowOff);
7709
+ if (drag !== null) parts.push(row.shown ? ModulesPage_module_default.rowDragging : ModulesPage_module_default.rowBlocked);
7710
+ if (drag?.over === index) parts.push(ModulesPage_module_default.rowOver);
7711
+ return parts.join(" ");
7712
+ }
7713
+ function gripClass(drag) {
7714
+ if (drag === null) return ModulesPage_module_default.grip;
7715
+ return `${ModulesPage_module_default.grip} ${drag.over === null ? ModulesPage_module_default.gripBlocked : ModulesPage_module_default.gripDragging}`;
7716
+ }
7717
+ function RowLabel({ t, row }) {
7718
+ 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)));
7719
+ }
7720
+ function PanelRowItem({ t, row, index, drag, handlers, tipEpoch, busy, onWrite }) {
7721
+ return /* @__PURE__ */ h("li", { className: rowClass(row, index, drag) }, row.shown && row.hasCard !== false ? /* @__PURE__ */ h(Tip, {
7722
+ key: tipEpoch,
7723
+ label: t("panels.dragHint"),
7724
+ disabled: drag !== null
7725
+ }, /* @__PURE__ */ h("span", {
7726
+ className: gripClass(drag),
7727
+ "aria-hidden": "true",
7728
+ onPointerDown: (event) => {
7729
+ if (event.button !== 0) return;
7730
+ event.preventDefault();
7731
+ event.currentTarget.setPointerCapture(event.pointerId);
7732
+ handlers.begin(index, event.clientX, event.clientY);
6481
7733
  }
6482
- }, t(dragging.titleKey)), empty ? /* @__PURE__ */ h(CenteredState, {
7734
+ }, "⠿")) : /* @__PURE__ */ h("span", { "aria-hidden": "true" }), /* @__PURE__ */ h(RowLabel, {
7735
+ t,
7736
+ row
7737
+ }), /* @__PURE__ */ h(PanelRowControls, {
7738
+ t,
7739
+ unit: row,
7740
+ label: t(row.titleKey ?? row.id),
7741
+ busy,
7742
+ onWrite
7743
+ }));
7744
+ }
7745
+ function PanelEmpty({ t, onOpenMarket }) {
7746
+ return /* @__PURE__ */ h(CenteredState, {
6483
7747
  compact: true,
6484
7748
  icon: null,
6485
7749
  title: t("panels.noneInstalled"),
@@ -6490,60 +7754,178 @@ function ModulesPage({ t, units, workspace, capabilities, loading = false, onOpe
6490
7754
  variant: "outline",
6491
7755
  onClick: onOpenMarket
6492
7756
  }, t("panels.browseMarket"))
6493
- }) : /* @__PURE__ */ h("ul", { className: ModulesPage_module_default.list }, rows.map((unit, index) => {
6494
- const badge = panelBadgeKey(capabilities?.[unit.id]);
6495
- const dep = badge === void 0 ? void 0 : t(badge);
6496
- return /* @__PURE__ */ h("li", {
6497
- className: `${ModulesPage_module_default.row}${drag?.over === index ? ` ${ModulesPage_module_default.rowOver}` : ""}`,
6498
- key: unit.id,
6499
- draggable: true,
6500
- onDragStart: (event) => {
6501
- const blank = new Image();
6502
- blank.src = BLANK_DRAG_IMAGE;
6503
- event.dataTransfer.setDragImage(blank, 0, 0);
6504
- setDrag({
6505
- from: index,
6506
- over: index,
6507
- at: {
6508
- x: event.clientX,
6509
- y: event.clientY
6510
- }
6511
- });
6512
- },
6513
- onDragOver: (event) => {
6514
- event.preventDefault();
6515
- if (drag !== null) setDrag({
6516
- from: drag.from,
6517
- over: index,
6518
- at: {
6519
- x: event.clientX,
6520
- y: event.clientY
6521
- }
6522
- });
6523
- },
6524
- onDragEnd: drop,
6525
- onDrop: (event) => {
6526
- event.preventDefault();
6527
- drop();
7757
+ });
7758
+ }
7759
+ function DragGhost({ label, at }) {
7760
+ return /* @__PURE__ */ h("div", {
7761
+ className: ModulesPage_module_default.ghost,
7762
+ style: {
7763
+ left: `${at.x + 12}px`,
7764
+ top: `${at.y - 12}px`
7765
+ }
7766
+ }, label);
7767
+ }
7768
+ function ResetConfirmation({ t, open, busy, onCancel, onConfirm }) {
7769
+ const [acknowledged, setAcknowledged] = useState(false);
7770
+ const close = (next) => {
7771
+ setAcknowledged(false);
7772
+ next();
7773
+ };
7774
+ return /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.RiskConfirmation, {
7775
+ open,
7776
+ title: t("panels.followAllConfirmTitle"),
7777
+ description: t("panels.followAllConfirmDetail"),
7778
+ acknowledgeLabel: t("panels.followAllConfirmAck"),
7779
+ cancelLabel: t("panels.followAllConfirmNo"),
7780
+ closeLabel: t("panels.followAllConfirmNo"),
7781
+ confirmLabel: t("panels.followAllConfirmYes"),
7782
+ acknowledged,
7783
+ disabled: busy,
7784
+ onAcknowledgedChange: setAcknowledged,
7785
+ onCancel: () => close(onCancel),
7786
+ onConfirm: () => close(onConfirm)
7787
+ });
7788
+ }
7789
+ function ModulesPage({ t, units, plugins = [], workspace, capabilities, loading = false, onOpenMarket, mocked = false, mock, own = false }) {
7790
+ const [drag, setDrag] = useState(mock?.drag ?? null);
7791
+ const [tipEpoch, setTipEpoch] = useState(0);
7792
+ const [writing, setWriting] = useState(mock?.busy ?? false);
7793
+ const [failed, setFailed] = useState(mock?.failed ?? false);
7794
+ const [confirmingReset, setConfirmingReset] = useState(false);
7795
+ const listRef = useRef(null);
7796
+ const rows = selectPanelRows(units, plugins, capabilities);
7797
+ const modules = rows.filter((row) => !row.plugin);
7798
+ const carded = modules.filter((row) => row.hasCard !== false);
7799
+ const boardless = modules.filter((row) => row.hasCard === false);
7800
+ const pluginRows = rows.filter((row) => row.plugin);
7801
+ const empty = !loading && rows.length === 0;
7802
+ const settle = useBoardSettle(panelBoardSignature(units, plugins, own));
7803
+ const { busy } = useVisibleBusy(writing || settle.pending, 500);
7804
+ const prefWrite = useHostWrite({
7805
+ channel: "prefs",
7806
+ resource: "panels",
7807
+ networkText: t("panels.failed")
7808
+ });
7809
+ const write = async (body) => {
7810
+ if (mocked) return;
7811
+ setWriting(true);
7812
+ setFailed(false);
7813
+ settle.begin();
7814
+ const outcome = await prefWrite.send({
7815
+ ...body,
7816
+ ...workspace === null ? {} : { path: workspace }
7817
+ });
7818
+ setWriting(false);
7819
+ if (!outcome.ok) {
7820
+ settle.clear();
7821
+ setFailed(true);
7822
+ }
7823
+ };
7824
+ const writeRow = (body) => void write(body);
7825
+ const dropTargetAt = (y) => panelDropTarget(carded, rowAtPoint(rowBoxes(listRef.current), y));
7826
+ const beginDrag = (index, x, y) => {
7827
+ if (carded[index]?.shown !== true) return;
7828
+ setDrag({
7829
+ from: index,
7830
+ over: index,
7831
+ at: {
7832
+ x,
7833
+ y
6528
7834
  }
6529
- }, /* @__PURE__ */ h(Tip, { label: t("panels.dragHint") }, /* @__PURE__ */ h("span", {
6530
- className: ModulesPage_module_default.grip,
6531
- "aria-hidden": "true"
6532
- }, "⠿")), /* @__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(_deepseek_ai_dsh_client_ui_primitives.Switch, {
6533
- checked: unit.shown,
6534
- label: `${t(unit.titleKey)} · ${unit.shown ? t("panels.enabled") : t("panels.disabled")}`,
6535
- disabled: busy,
6536
- onChange: (next) => void write({
6537
- action: next ? "show" : "hide",
6538
- id: unit.id
6539
- })
6540
- }));
6541
- })), /* @__PURE__ */ h(PanelFoot, { text: t("panels.hintEffect") }, /* @__PURE__ */ h("button", {
7835
+ });
7836
+ };
7837
+ const trackDrag = (x, y) => {
7838
+ if (drag === null) return;
7839
+ setDrag({
7840
+ from: drag.from,
7841
+ over: dropTargetAt(y),
7842
+ at: {
7843
+ x,
7844
+ y
7845
+ }
7846
+ });
7847
+ };
7848
+ const settleDrag = (y) => {
7849
+ const from = drag?.from;
7850
+ setDrag(null);
7851
+ setTipEpoch((epoch) => epoch + 1);
7852
+ if (from === void 0) return;
7853
+ const moved = carded[from];
7854
+ const over = dropTargetAt(y);
7855
+ if (moved === void 0 || over === null || over === from) return;
7856
+ write({
7857
+ action: "move",
7858
+ id: moved.id,
7859
+ index: over
7860
+ });
7861
+ };
7862
+ const cancelDrag = () => {
7863
+ setDrag(null);
7864
+ setTipEpoch((epoch) => epoch + 1);
7865
+ };
7866
+ const handlers = {
7867
+ begin: beginDrag,
7868
+ move: trackDrag,
7869
+ drop: settleDrag,
7870
+ cancel: cancelDrag
7871
+ };
7872
+ useDragListeners(drag !== null, handlers);
7873
+ const dragged = drag === null ? void 0 : carded[drag.from];
7874
+ return /* @__PURE__ */ h(Fragment, null, drag?.at === void 0 || dragged === void 0 ? null : /* @__PURE__ */ h(DragGhost, {
7875
+ label: t(dragged.titleKey ?? dragged.id),
7876
+ at: drag.at
7877
+ }), empty ? /* @__PURE__ */ h(PanelEmpty, {
7878
+ t,
7879
+ onOpenMarket
7880
+ }) : null, carded.length === 0 ? null : /* @__PURE__ */ h("ul", {
7881
+ ref: listRef,
7882
+ className: `${ModulesPage_module_default.list}${drag === null ? "" : ` ${ModulesPage_module_default.listDragging}`}`
7883
+ }, carded.map((row, index) => /* @__PURE__ */ h(PanelRowItem, {
7884
+ key: row.id,
7885
+ t,
7886
+ row,
7887
+ index,
7888
+ drag,
7889
+ handlers,
7890
+ tipEpoch,
7891
+ busy,
7892
+ onWrite: writeRow
7893
+ }))), /* @__PURE__ */ h(PanelGroupRows, {
7894
+ t,
7895
+ rows: boardless,
7896
+ titleKey: "panels.groupBoardless",
7897
+ busy,
7898
+ onWrite: writeRow
7899
+ }), /* @__PURE__ */ h(PanelGroupRows, {
7900
+ t,
7901
+ rows: pluginRows,
7902
+ titleKey: "panels.groupPlugins",
7903
+ busy,
7904
+ onWrite: writeRow
7905
+ }), own ? /* @__PURE__ */ h(PanelFoot, null, /* @__PURE__ */ h("button", {
6542
7906
  type: "button",
6543
7907
  className: ModulesPage_module_default.reset,
6544
7908
  disabled: busy,
6545
- onClick: () => void write({ action: "reset" })
6546
- }, t("panels.reset"))), failed ? /* @__PURE__ */ h("p", { className: ModulesPage_module_default.error }, t("panels.failed")) : null);
7909
+ onClick: () => setConfirmingReset(true)
7910
+ }, t("panels.followAll"))) : null, /* @__PURE__ */ h(ResetConfirmation, {
7911
+ t,
7912
+ open: confirmingReset,
7913
+ busy,
7914
+ onCancel: () => setConfirmingReset(false),
7915
+ onConfirm: () => {
7916
+ setConfirmingReset(false);
7917
+ write({ action: "reset" });
7918
+ }
7919
+ }), failed ? /* @__PURE__ */ h("p", { className: ModulesPage_module_default.error }, t("panels.failed")) : null);
7920
+ }
7921
+ //#endregion
7922
+ //#region src/app/layouts/rightbar/panel-dismiss.ts
7923
+ function hasOpenModal(scope) {
7924
+ return scope.querySelector("[aria-modal=\"true\"]") !== null;
7925
+ }
7926
+ function dismissPanelByPointer(next, scope, onOpenChange) {
7927
+ if (!next && hasOpenModal(scope)) return;
7928
+ onOpenChange(next);
6547
7929
  }
6548
7930
  //#endregion
6549
7931
  //#region src/app/layouts/rightbar/PanelModules.tsx
@@ -6574,8 +7956,8 @@ function PanelModules({ t, open, onOpenChange, enabledUnits, workspace, refreshT
6574
7956
  });
6575
7957
  const panelMock = fixturePick.enabled ? fixturePick.current : void 0;
6576
7958
  const mockNonce = fixturePick.nonce;
6577
- (0, _deepseek_ai_dsh_client_ui_primitives.useDismissOnOutsidePointer)(root, open, onOpenChange);
6578
- const units = enabledUnits ?? [];
7959
+ (0, _deepseek_ai_dsh_client_ui_primitives.useDismissOnOutsidePointer)(root, open, (next) => dismissPanelByPointer(next, document, onOpenChange));
7960
+ const units = enabledUnits?.units ?? [];
6579
7961
  return /* @__PURE__ */ h("div", {
6580
7962
  className: ModulesPage_module_default.trigger,
6581
7963
  ref: root
@@ -6600,8 +7982,10 @@ function PanelModules({ t, open, onOpenChange, enabledUnits, workspace, refreshT
6600
7982
  key: `${panelMock?.id ?? "real-modules"}-${mockNonce}`,
6601
7983
  t,
6602
7984
  units: panelMock?.units ?? units,
7985
+ plugins: panelMock?.plugins ?? enabledUnits?.plugins ?? [],
6603
7986
  capabilities: panelMock === void 0 ? fixturePick.enabled ? null : capabilities : panelMock.capabilities,
6604
7987
  loading: enabledUnits === null,
7988
+ own: enabledUnits?.own === true,
6605
7989
  onOpenMarket,
6606
7990
  mocked: fixturePick.enabled,
6607
7991
  workspace,
@@ -6778,114 +8162,6 @@ function rightbarPresentation(input) {
6778
8162
  };
6779
8163
  }
6780
8164
  //#endregion
6781
- //#region src/modules/sessions/model/session-node.ts
6782
- function visiblePendingKind(kind) {
6783
- switch (kind) {
6784
- case "approval":
6785
- case "plan-review":
6786
- case "question": return kind;
6787
- default: return;
6788
- }
6789
- }
6790
- function sessionNode(summary, statusById, list, pinnedIds, archivedIds) {
6791
- const status = statusById.get(summary.id);
6792
- const catalog = list.projectionsBySession[summary.id]?.values?.subagentCatalog;
6793
- let runningSubagentCount = 0;
6794
- for (const child of catalog ?? []) {
6795
- const childStatus = statusById.get(child.id);
6796
- const childRow = list.byId[child.id];
6797
- if ((childStatus?.running ?? childRow?.running) === true) runningSubagentCount += 1;
6798
- }
6799
- return {
6800
- id: summary.id,
6801
- title: summary.blank ? "" : summary.displayTitle,
6802
- blank: summary.blank,
6803
- running: status?.running ?? summary.running,
6804
- runningSubagentCount,
6805
- completed: status?.completionUnread === true,
6806
- pinned: !archivedIds.has(summary.id) && pinnedIds.has(summary.id),
6807
- updatedAt: summary.updatedAt,
6808
- pendingInteraction: visiblePendingKind(status?.pendingInteraction?.kind)
6809
- };
6810
- }
6811
- function sessionStatuses(node, t) {
6812
- const subagents = node.runningSubagentCount > 0 ? {
6813
- state: "ongoing",
6814
- label: t(node.runningSubagentCount === 1 ? "status.subagentsRunning.one" : "status.subagentsRunning.other", { n: node.runningSubagentCount })
6815
- } : void 0;
6816
- let pending;
6817
- switch (node.pendingInteraction) {
6818
- case "approval":
6819
- pending = {
6820
- state: "warning",
6821
- label: t("status.waitingApproval")
6822
- };
6823
- break;
6824
- case "plan-review":
6825
- pending = {
6826
- state: "warning",
6827
- label: t("status.planReview")
6828
- };
6829
- break;
6830
- case "question":
6831
- pending = {
6832
- state: "warning",
6833
- label: t("status.waitingAnswer")
6834
- };
6835
- break;
6836
- default: pending = void 0;
6837
- }
6838
- if (pending !== void 0) return subagents === void 0 ? [pending] : [pending, subagents];
6839
- if (node.running) {
6840
- const primary = {
6841
- state: "ongoing",
6842
- label: t("status.running")
6843
- };
6844
- return subagents === void 0 ? [primary] : [primary, subagents];
6845
- }
6846
- if (subagents !== void 0) return [subagents];
6847
- if (node.completed) return [{
6848
- state: "done",
6849
- label: t("status.completed")
6850
- }];
6851
- return [{
6852
- state: "idle",
6853
- label: t("status.idle")
6854
- }];
6855
- }
6856
- function currentSessionId(list, panelActive) {
6857
- if (panelActive) return void 0;
6858
- return Object.values(list.byId).find((session) => (session.retainedBy?.mainView ?? 0) > 0)?.id;
6859
- }
6860
- function orderSessionRows(rows, pinnedIds, archivedIds) {
6861
- const placeholders = [];
6862
- const leading = [];
6863
- const rest = [];
6864
- for (const row of rows) if (row.blank) placeholders.push(row);
6865
- else if (!archivedIds.has(row.id) && pinnedIds.has(row.id)) leading.push(row);
6866
- else rest.push(row);
6867
- return [
6868
- ...placeholders,
6869
- ...leading,
6870
- ...rest
6871
- ];
6872
- }
6873
- function workspaceOfSession(workspaces, sessionId) {
6874
- if (sessionId === void 0) return null;
6875
- return workspaces.find((workspace) => workspace.sessionIds.includes(sessionId)) ?? null;
6876
- }
6877
- function sessionRows(workspaceSessionIds, list, archivedIds, current) {
6878
- const rows = [];
6879
- for (const id of workspaceSessionIds) {
6880
- if (archivedIds.has(id)) continue;
6881
- const row = list.byId[id];
6882
- if (row === void 0 || row.origin === "subagent") continue;
6883
- if (row.blank && row.id !== current) continue;
6884
- rows.push(row);
6885
- }
6886
- return rows;
6887
- }
6888
- //#endregion
6889
8165
  //#region src/app/layouts/rightbar/suite-world.ts
6890
8166
  function createSuiteWorld(input) {
6891
8167
  const sessionId = currentSessionId(input.sessions, false);
@@ -6902,47 +8178,52 @@ function createSuiteWorld(input) {
6902
8178
  };
6903
8179
  }
6904
8180
  //#endregion
6905
- //#region src/app/layouts/rightbar/use-panels.ts
6906
- function shouldDropPanels(workspace, previous) {
6907
- return workspace !== previous;
6908
- }
6909
- function useEnabledUnits(refreshToken, workspace) {
6910
- const [enabled, setEnabled] = useState(null);
6911
- const lastWorkspace = useRef(workspace);
6912
- useEffect(() => {
6913
- let cancelled = false;
6914
- if (shouldDropPanels(workspace, lastWorkspace.current)) {
6915
- lastWorkspace.current = workspace;
6916
- setEnabled(null);
6917
- }
6918
- const read = async () => {
6919
- const response = await apiGet("panels", workspace === null ? {} : { path: workspace }).catch(() => null);
6920
- if (cancelled) return;
6921
- if (response?.ok === true && Array.isArray(response.units)) setEnabled(response.units);
6922
- };
6923
- read();
6924
- return () => {
6925
- cancelled = true;
6926
- };
6927
- }, [
6928
- refreshToken,
6929
- useFactRevision("panels"),
6930
- workspace
6931
- ]);
6932
- return enabled;
6933
- }
6934
- function useSelectedProjectId() {
6935
- const [id, setId] = useState(() => selectedProjectId());
6936
- useEffect(() => subscribeProject(() => setId(selectedProjectId())), []);
6937
- return id;
6938
- }
6939
- function useBoardWorkspace(workspaces, sessions) {
6940
- const projectId = useSelectedProjectId();
6941
- const workspace = workspaces.items.find((item) => item.workspaceId === projectId) ?? workspaceOfSession(workspaces.items, currentSessionId(sessions, false));
6942
- return {
6943
- workspace,
6944
- path: workspace?.path ?? null
6945
- };
8181
+ //#region src/shared/hooks/panel-state-report.ts
8182
+ var FLUSH_MS = 400;
8183
+ var workspace = null;
8184
+ var timer = null;
8185
+ var pending = /* @__PURE__ */ new Map();
8186
+ function unitOfRoute(route) {
8187
+ const cut = route.indexOf("/");
8188
+ return cut <= 0 ? null : route.slice(0, cut);
8189
+ }
8190
+ function setPanelWorkspace(path) {
8191
+ if (path === workspace) return;
8192
+ const previous = workspace;
8193
+ workspace = path;
8194
+ if (previous !== null) pending.clear();
8195
+ }
8196
+ function reportPanelRead(input) {
8197
+ pending.set(`${input.unit}\u0000${input.route}`, {
8198
+ unit: input.unit,
8199
+ route: input.route,
8200
+ phase: input.phase,
8201
+ at: Date.now(),
8202
+ ...input.error === void 0 ? {} : { error: input.error }
8203
+ });
8204
+ if (timer !== null) return;
8205
+ timer = setTimeout(flush, FLUSH_MS);
8206
+ }
8207
+ function reportPanelCrash(input) {
8208
+ const target = workspace;
8209
+ if (target === null) return;
8210
+ apiPost(`${PANEL_STATE_PATH}/crash`, {
8211
+ workspace: target,
8212
+ unit: input.unit,
8213
+ reason: input.reason,
8214
+ at: Date.now()
8215
+ }).catch(() => void 0);
8216
+ }
8217
+ function flush() {
8218
+ timer = null;
8219
+ const target = workspace;
8220
+ const cards = [...pending.values()];
8221
+ pending.clear();
8222
+ if (target === null || cards.length === 0) return;
8223
+ apiPost(`${PANEL_STATE_PATH}/cards`, {
8224
+ workspace: target,
8225
+ cards
8226
+ }).catch(() => void 0);
6946
8227
  }
6947
8228
  var Rightbar_module_default = {
6948
8229
  panel: "_panel_135e7_1",
@@ -6997,7 +8278,7 @@ function PanelHeader({ t, trail, onGoTo, titleKeyOf, refreshing, at, refreshEnab
6997
8278
  onClick: onCollapse
6998
8279
  })))));
6999
8280
  }
7000
- function BoardContent({ top, plan, world, board, twoColumns, panelToken, onPanelRefresh, onNavigate, onOpenMarket, onSummary, onOpenModules, buildModule, t }) {
8281
+ function BoardContent({ top, plan, world, board, twoColumns, panelToken, onPanelRefresh, onNavigate, onOpenMarket, onSummary, onOpenModules, onCardFailure, buildModule, t }) {
7001
8282
  if (top.kind !== "board") {
7002
8283
  const owner = board.stepOwner(top.kind);
7003
8284
  if (owner === void 0) return /* @__PURE__ */ h(CenteredState, {
@@ -7009,7 +8290,8 @@ function BoardContent({ top, plan, world, board, twoColumns, panelToken, onPanel
7009
8290
  key,
7010
8291
  unit: owner.id,
7011
8292
  resetKey: `${key}:${panelToken}:${workspacePathOf(world)}`,
7012
- t
8293
+ t,
8294
+ onFailure: (reason) => onCardFailure(owner.id, reason)
7013
8295
  }, /* @__PURE__ */ h(ModuleHost, {
7014
8296
  module: owner,
7015
8297
  step: top.kind,
@@ -7042,7 +8324,8 @@ function BoardContent({ top, plan, world, board, twoColumns, panelToken, onPanel
7042
8324
  key,
7043
8325
  unit: module.id,
7044
8326
  resetKey: `${key}:${panelToken}:${workspacePathOf(world)}`,
7045
- t
8327
+ t,
8328
+ onFailure: (reason) => onCardFailure(module.id, reason)
7046
8329
  }, /* @__PURE__ */ h(ModuleHost, {
7047
8330
  module,
7048
8331
  world,
@@ -7068,13 +8351,14 @@ function Rightbar(props) {
7068
8351
  const { capabilities } = useCapabilityMap(panelToken);
7069
8352
  const board = useBoardWorkspace(workspaces, sessions);
7070
8353
  const boardWorkspace = board.path;
7071
- const enabledUnits = useEnabledUnits(panelToken, boardWorkspace);
8354
+ const panelBoard = useEnabledUnits(panelToken, boardWorkspace);
8355
+ const enabledUnits = panelBoard?.units ?? null;
7072
8356
  const [modulesOpen, setModulesOpen] = useState(false);
7073
8357
  const fixtures = useBoardMock(fixtureRoster(manifests));
7074
8358
  const visibleModules = selectBoardModules(enabledUnits, (id) => modules.byId(id), capabilities);
7075
8359
  const plan = planBoard(fixtures.shape, {
7076
8360
  modules: visibleModules,
7077
- configRead: enabledUnits !== null
8361
+ configRead: panelBoard !== null
7078
8362
  }, fixtureSeed(manifests, modules.all(), crashModeOn(window.location.search)));
7079
8363
  const world = createSuiteWorld({
7080
8364
  workspaces,
@@ -7091,6 +8375,16 @@ function Rightbar(props) {
7091
8375
  [id]: next
7092
8376
  }));
7093
8377
  }, []);
8378
+ const onCardFailure = useCallback((unit, reason) => {
8379
+ reportPanelCrash({
8380
+ unit,
8381
+ reason
8382
+ });
8383
+ }, []);
8384
+ const fixtureMode = mockModeOn(window.location.search) || crashModeOn(window.location.search);
8385
+ useEffect(() => {
8386
+ setPanelWorkspace(fixtureMode ? null : boardWorkspace);
8387
+ }, [boardWorkspace, fixtureMode]);
7094
8388
  const summary = aggregateSummaries(plan.modules.map((entry) => summaries[entry.module.id]).filter((item) => item !== void 0));
7095
8389
  const feedEnabled = plan.modules.length > 0 || plan.reading;
7096
8390
  const shown = state.expanded;
@@ -7135,7 +8429,7 @@ function Rightbar(props) {
7135
8429
  onRefresh: refreshPanel,
7136
8430
  modulesOpen,
7137
8431
  onModulesOpenChange: setModulesOpen,
7138
- enabledUnits,
8432
+ enabledUnits: panelBoard,
7139
8433
  manifests,
7140
8434
  workspace: boardWorkspace,
7141
8435
  refreshToken: panelToken,
@@ -7156,6 +8450,7 @@ function Rightbar(props) {
7156
8450
  onOpenMarket: openMarket,
7157
8451
  onSummary,
7158
8452
  onOpenModules: () => setModulesOpen(true),
8453
+ onCardFailure,
7159
8454
  buildModule: props.buildModule,
7160
8455
  t: props.t
7161
8456
  })));
@@ -7656,10 +8951,7 @@ function SessionLeading({ node, statuses, renderSlot }) {
7656
8951
  if (node.blank) return null;
7657
8952
  const primary = statuses[0];
7658
8953
  if (primary === void 0 || primary.state === "idle") return /* @__PURE__ */ h(Fragment, null, renderSlot("sidebar.session.row.leading", { sessionId: node.id }));
7659
- return /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
7660
- state: primary.state,
7661
- size: 10
7662
- }), statuses.map((status) => /* @__PURE__ */ h("span", {
8954
+ return /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: primary.state }), statuses.map((status) => /* @__PURE__ */ h("span", {
7663
8955
  className: "wb-visuallyHidden",
7664
8956
  key: status.label
7665
8957
  }, status.label)));
@@ -7734,6 +9026,21 @@ function SessionList({ workspace, pinnedIds, archived, panelActive, useSessions,
7734
9026
  function panelLabel(entry) {
7735
9027
  return typeof entry.label === "function" ? entry.label() : entry.label;
7736
9028
  }
9029
+ function addWorkspace(input) {
9030
+ input.add().catch(() => null).then((path) => {
9031
+ if (path === null || path === "") return;
9032
+ input.onBusy(true);
9033
+ input.onFailed(false);
9034
+ input.create(path).catch(() => void 0).then((view) => {
9035
+ input.onBusy(false);
9036
+ if (view?.workspaceId === void 0) {
9037
+ input.onFailed(true);
9038
+ return;
9039
+ }
9040
+ input.onCreated(view.workspaceId);
9041
+ });
9042
+ });
9043
+ }
7737
9044
  function Sidebar(props) {
7738
9045
  const { collapsed, renderSlot, t, useWorkspaces, usePanelInfo } = props;
7739
9046
  const items = useWorkspaces((state) => state.items);
@@ -7743,6 +9050,8 @@ function Sidebar(props) {
7743
9050
  const sessions = props.useSessions((state) => state);
7744
9051
  const [storedId, setStoredId] = useState(() => selectedProjectId());
7745
9052
  const [panelEntries, setPanelEntries] = useState(() => props.listPanels());
9053
+ const [creating, setCreating] = useState(false);
9054
+ const [createFailed, setCreateFailed] = useState(false);
7746
9055
  useEffect(() => props.subscribePanels(() => setPanelEntries(props.listPanels())), [props]);
7747
9056
  useEffect(() => subscribeProject(() => setStoredId(selectedProjectId())), []);
7748
9057
  const current = items.find((workspace) => workspace.workspaceId === storedId) ?? items[0] ?? null;
@@ -7760,11 +9069,12 @@ function Sidebar(props) {
7760
9069
  });
7761
9070
  };
7762
9071
  const addProject = () => {
7763
- props.pickDirectory().then((path) => {
7764
- if (path === null || path === "") return;
7765
- props.createWorkspace(path).then((view) => {
7766
- if (view?.workspaceId !== void 0) pickProject(view.workspaceId);
7767
- });
9072
+ addWorkspace({
9073
+ add: props.pickDirectory,
9074
+ create: props.createWorkspace,
9075
+ onBusy: setCreating,
9076
+ onFailed: setCreateFailed,
9077
+ onCreated: pickProject
7768
9078
  });
7769
9079
  };
7770
9080
  const wide = !collapsed;
@@ -7795,14 +9105,20 @@ function Sidebar(props) {
7795
9105
  size: isWide ? 16 : 18,
7796
9106
  active
7797
9107
  }, { only: id })
7798
- }))), wide ? /* @__PURE__ */ h(ProjectSwitcher, {
9108
+ }))), wide ? /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(ProjectSwitcher, {
7799
9109
  items,
7800
9110
  current,
7801
9111
  onPick: pickProject,
7802
9112
  onAdd: addProject,
7803
9113
  onRename: props.renameWorkspace,
7804
9114
  t
7805
- }) : null, /* @__PURE__ */ h(WorkspaceSection, {
9115
+ }), creating ? /* @__PURE__ */ h("p", {
9116
+ className: "wb-workspaceBusy",
9117
+ role: "status"
9118
+ }, /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
9119
+ state: "ongoing",
9120
+ size: 12
9121
+ }), t("project.add.busy")) : null, createFailed ? /* @__PURE__ */ h("p", { className: "wb-workspaceError" }, t("project.add.failed")) : null) : null, /* @__PURE__ */ h(WorkspaceSection, {
7806
9122
  t,
7807
9123
  wide,
7808
9124
  onNewSession: () => {
@@ -7841,7 +9157,7 @@ var palette_default = ":root {\n --wb-static-titlebar-fill: #ffffff8c;\n --wb-
7841
9157
  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";
7842
9158
  //#endregion
7843
9159
  //#region src/shared/styles/sidebar-app.css?raw
7844
- 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}";
9160
+ 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}";
7845
9161
  //#endregion
7846
9162
  //#region src/shared/styles/sidebar.css?raw
7847
9163
  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";
@@ -7928,6 +9244,12 @@ function useApiResource(route, query, refreshToken, options = {}) {
7928
9244
  ...prev.at === void 0 ? {} : { at: prev.at }
7929
9245
  } : { phase: "loading" });
7930
9246
  const flight = requestResource(route, queryRef.current, key);
9247
+ const owner = unitOfRoute(route);
9248
+ if (owner !== null) reportPanelRead({
9249
+ unit: owner,
9250
+ route,
9251
+ phase: "loading"
9252
+ });
7931
9253
  flight.task.then((response) => {
7932
9254
  if (cancelled) return;
7933
9255
  if (response.ok) {
@@ -7936,19 +9258,43 @@ function useApiResource(route, query, refreshToken, options = {}) {
7936
9258
  value: response,
7937
9259
  at: Date.now()
7938
9260
  });
9261
+ if (owner !== null) reportPanelRead({
9262
+ unit: owner,
9263
+ route,
9264
+ phase: "ready"
9265
+ });
7939
9266
  return;
7940
9267
  }
7941
9268
  setState({
7942
9269
  phase: "error",
7943
9270
  error: response.error
7944
9271
  });
9272
+ if (owner !== null) reportPanelRead({
9273
+ unit: owner,
9274
+ route,
9275
+ phase: "error",
9276
+ error: {
9277
+ code: response.error.code,
9278
+ message: response.error.message
9279
+ }
9280
+ });
7945
9281
  }).catch((reason) => {
7946
9282
  if (cancelled) return;
9283
+ const message = reason instanceof Error ? reason.message : String(reason);
7947
9284
  setState({
7948
9285
  phase: "error",
7949
9286
  error: {
7950
9287
  code: "network",
7951
- message: reason instanceof Error ? reason.message : String(reason)
9288
+ message
9289
+ }
9290
+ });
9291
+ if (owner !== null) reportPanelRead({
9292
+ unit: owner,
9293
+ route,
9294
+ phase: "error",
9295
+ error: {
9296
+ code: "network",
9297
+ message
7952
9298
  }
7953
9299
  });
7954
9300
  });
@@ -8217,7 +9563,7 @@ function messagesOf(units) {
8217
9563
  ...face.messages === void 0 ? {} : { messages: face.messages }
8218
9564
  }));
8219
9565
  }
8220
- 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*/";
9566
+ 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*/";
8221
9567
  function workbenchCss() {
8222
9568
  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}`;
8223
9569
  }
@@ -8351,16 +9697,6 @@ function mount(ctx) {
8351
9697
  };
8352
9698
  const rightbarHooks = { hooks: { rightbar: observable } };
8353
9699
  const sidebarRight = () => ctx.get("sidebarRight");
8354
- const dshColumn = createDshColumnSource(() => {
8355
- const official = sidebarRight();
8356
- if (official === void 0) return false;
8357
- return official.mounted.getSnapshot() === void 0 || official.isExpanded();
8358
- }, 400);
8359
- let pendingDshOpen = false;
8360
- let pendingOfficialCall;
8361
- let unsubscribeOfficial;
8362
- let restoreOfficial;
8363
- let officialShimmed = false;
8364
9700
  let workbenchColumnArmed = false;
8365
9701
  let disposeWorkbenchColumn;
8366
9702
  const armWorkbenchColumn = () => {
@@ -8382,87 +9718,37 @@ function mount(ctx) {
8382
9718
  disposeWorkbenchColumn?.();
8383
9719
  disposeWorkbenchColumn = void 0;
8384
9720
  };
8385
- const flushOfficialCall = () => {
8386
- const official = sidebarRight();
8387
- if (official === void 0 || official.mounted.getSnapshot() === void 0) return;
8388
- if (pendingDshOpen) {
8389
- pendingDshOpen = false;
8390
- if (!official.isExpanded()) official.toggleExpanded();
8391
- }
8392
- const call = pendingOfficialCall;
8393
- pendingOfficialCall = void 0;
8394
- call?.();
8395
- };
8396
- const watchOfficial = () => {
8397
- const official = sidebarRight();
8398
- if (official === void 0 || unsubscribeOfficial !== void 0) return;
8399
- unsubscribeOfficial = official.mounted.subscribe(flushOfficialCall);
8400
- };
8401
- const armDshColumn = () => {
8402
- const official = sidebarRight();
8403
- if (official === void 0) return false;
8404
- if (official.mounted.getSnapshot() !== void 0) {
8405
- if (!official.isExpanded()) official.toggleExpanded();
8406
- return true;
8407
- }
8408
- watchOfficial();
8409
- store.setColumn("dsh");
8410
- ctx.layout.closeRightbar();
8411
- releaseWorkbenchColumn();
8412
- pendingDshOpen = true;
8413
- return false;
8414
- };
8415
- const openInDshColumn = (call) => {
8416
- shimOfficialNavigation();
8417
- if (sidebarRight() === void 0) return;
8418
- if (armDshColumn()) {
8419
- call();
8420
- return;
9721
+ const borrow = createDshBorrow({
9722
+ official: sidebarRight,
9723
+ yieldColumn: () => {
9724
+ store.setColumn("dsh");
9725
+ ctx.layout.closeRightbar();
9726
+ releaseWorkbenchColumn();
9727
+ },
9728
+ reclaimColumn: () => {
9729
+ store.setColumn("workbench");
9730
+ armWorkbenchColumn();
9731
+ store.setExpanded(true);
8421
9732
  }
8422
- pendingOfficialCall = call;
8423
- };
8424
- const shimOfficialNavigation = () => {
8425
- const official = sidebarRight();
8426
- if (official === void 0 || officialShimmed) return;
8427
- const { openResource, openTab } = official;
8428
- if (typeof openResource !== "function" || typeof openTab !== "function") return;
8429
- officialShimmed = true;
8430
- official.openResource = (address, options) => openInDshColumn(() => openResource.call(official, address, options));
8431
- official.openTab = (kind, options) => openInDshColumn(() => openTab.call(official, kind, options));
8432
- restoreOfficial = () => {
8433
- official.openResource = openResource;
8434
- official.openTab = openTab;
8435
- officialShimmed = false;
8436
- };
8437
- };
9733
+ });
9734
+ const dshColumn = createDshColumnSource(() => borrow.open(), 400);
8438
9735
  const selectColumn = (column) => {
8439
9736
  if (store.getSnapshot().column === column) {
8440
9737
  if (column === "workbench") {
8441
9738
  rightbarActions.toggleRightbar();
8442
9739
  return;
8443
9740
  }
8444
- const current = sidebarRight();
8445
- if (current === void 0 || current.mounted.getSnapshot() === void 0) return;
8446
- current.toggleExpanded();
9741
+ borrow.toggle();
8447
9742
  return;
8448
9743
  }
8449
9744
  if (column === "workbench") {
8450
- store.setColumn("workbench");
8451
- pendingDshOpen = false;
8452
- armWorkbenchColumn();
8453
- store.setExpanded(true);
9745
+ borrow.back();
8454
9746
  return;
8455
9747
  }
8456
- openInDshColumn(() => {});
8457
- };
8458
- ctx.effect(() => () => {
8459
- unsubscribeOfficial?.();
8460
- unsubscribeOfficial = void 0;
8461
- restoreOfficial?.();
8462
- restoreOfficial = void 0;
8463
- }, "dsh-workbench: 官方椅面订阅与借道");
8464
- shimOfficialNavigation();
8465
- watchOfficial();
9748
+ borrow.use();
9749
+ };
9750
+ ctx.effect(() => () => borrow.dispose(), "dsh-workbench: 官方椅面订阅与借道");
9751
+ borrow.start();
8466
9752
  if (store.getSnapshot().column === "workbench") armWorkbenchColumn();
8467
9753
  ctx.slots.inject("sidebar", () => ctx.slots.register({
8468
9754
  name: "sidebar",