@jingyi0605/codingns4dsh 0.2.1-rc.5 → 0.2.1-rc.7

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 (174) hide show
  1. package/README.en.md +4 -4
  2. package/README.md +5 -5
  3. package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.d.ts +1 -1
  4. package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.js +1 -1
  5. package/data/build/dist/client/bundle.js +1550 -148
  6. package/data/build/dist/client/bundle.js.map +1 -1
  7. package/data/build/dist/client/cli-slots.js +2 -2
  8. package/data/build/dist/client/cli-slots.js.map +1 -1
  9. package/data/build/dist/client/client.delegate-command.js +3 -2
  10. package/data/build/dist/client/client.delegate-command.js.map +1 -1
  11. package/data/build/dist/client/client.magpie-model-tag.js +24 -8
  12. package/data/build/dist/client/client.magpie-model-tag.js.map +1 -1
  13. package/data/build/dist/client/client.native-workspace-store.js +26 -15
  14. package/data/build/dist/client/client.native-workspace-store.js.map +1 -1
  15. package/data/build/dist/client/client.session-translation.js +25 -0
  16. package/data/build/dist/client/client.session-translation.js.map +1 -1
  17. package/data/build/dist/client/client.transport.js +224 -0
  18. package/data/build/dist/client/client.transport.js.map +1 -1
  19. package/data/build/dist/client/delegate-command.js +2 -1
  20. package/data/build/dist/client/delegate-command.js.map +1 -1
  21. package/data/build/dist/client/desktop-assistant.js +224 -0
  22. package/data/build/dist/client/features/index.d.ts +2 -1
  23. package/data/build/dist/client/features/index.d.ts.map +1 -1
  24. package/data/build/dist/client/features/index.js +3 -1
  25. package/data/build/dist/client/features/index.js.map +1 -1
  26. package/data/build/dist/client/features/magpie-management-page.d.ts +7 -3
  27. package/data/build/dist/client/features/magpie-management-page.d.ts.map +1 -1
  28. package/data/build/dist/client/features/magpie-management-page.js +142 -8
  29. package/data/build/dist/client/features/magpie-management-page.js.map +1 -1
  30. package/data/build/dist/client/features/workspace-mcp.d.ts +3 -0
  31. package/data/build/dist/client/features/workspace-mcp.d.ts.map +1 -0
  32. package/data/build/dist/client/features/workspace-mcp.js +320 -0
  33. package/data/build/dist/client/features/workspace-mcp.js.map +1 -0
  34. package/data/build/dist/client/locale.d.ts.map +1 -1
  35. package/data/build/dist/client/locale.js +180 -0
  36. package/data/build/dist/client/locale.js.map +1 -1
  37. package/data/build/dist/client/locales/magpie.d.ts.map +1 -1
  38. package/data/build/dist/client/locales/magpie.js +12 -0
  39. package/data/build/dist/client/locales/magpie.js.map +1 -1
  40. package/data/build/dist/client/locales/panels.d.ts.map +1 -1
  41. package/data/build/dist/client/locales/panels.js +18 -0
  42. package/data/build/dist/client/locales/panels.js.map +1 -1
  43. package/data/build/dist/client/locales/usage.d.ts.map +1 -1
  44. package/data/build/dist/client/locales/usage.js +14 -0
  45. package/data/build/dist/client/locales/usage.js.map +1 -1
  46. package/data/build/dist/client/magpie-model-tag.d.ts +4 -2
  47. package/data/build/dist/client/magpie-model-tag.d.ts.map +1 -1
  48. package/data/build/dist/client/magpie-model-tag.js +25 -8
  49. package/data/build/dist/client/magpie-model-tag.js.map +1 -1
  50. package/data/build/dist/client/native-model-translation-menu.d.ts +1 -0
  51. package/data/build/dist/client/native-model-translation-menu.d.ts.map +1 -1
  52. package/data/build/dist/client/native-model-translation-menu.js +2 -2
  53. package/data/build/dist/client/native-model-translation-menu.js.map +1 -1
  54. package/data/build/dist/client/session-translation-chat.d.ts.map +1 -1
  55. package/data/build/dist/client/session-translation-chat.js +6 -2
  56. package/data/build/dist/client/session-translation-chat.js.map +1 -1
  57. package/data/build/dist/client/settings-section.d.ts.map +1 -1
  58. package/data/build/dist/client/settings-section.js +6 -3
  59. package/data/build/dist/client/settings-section.js.map +1 -1
  60. package/data/build/dist/client/subscription-slot.d.ts.map +1 -1
  61. package/data/build/dist/client/subscription-slot.js +104 -11
  62. package/data/build/dist/client/subscription-slot.js.map +1 -1
  63. package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.d.ts +18 -0
  64. package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.d.ts.map +1 -0
  65. package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.js +172 -0
  66. package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.js.map +1 -0
  67. package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.d.ts +28 -0
  68. package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.d.ts.map +1 -0
  69. package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.js +103 -0
  70. package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.js.map +1 -0
  71. package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.d.ts +26 -0
  72. package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.d.ts.map +1 -0
  73. package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.js +86 -0
  74. package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.js.map +1 -0
  75. package/data/build/dist/dsh-capabilities/matrix.d.ts.map +1 -1
  76. package/data/build/dist/dsh-capabilities/matrix.js +17 -14
  77. package/data/build/dist/dsh-capabilities/matrix.js.map +1 -1
  78. package/data/build/dist/dsh-capabilities/routes.d.ts.map +1 -1
  79. package/data/build/dist/dsh-capabilities/routes.js +19 -10
  80. package/data/build/dist/dsh-capabilities/routes.js.map +1 -1
  81. package/data/build/dist/dsh-capabilities/types.d.ts +1 -1
  82. package/data/build/dist/dsh-capabilities/types.d.ts.map +1 -1
  83. package/data/build/dist/dsh-capabilities/types.js.map +1 -1
  84. package/data/build/dist/host/cli-adapters/claude-model-options.d.ts.map +1 -1
  85. package/data/build/dist/host/cli-adapters/claude-model-options.js +13 -2
  86. package/data/build/dist/host/cli-adapters/claude-model-options.js.map +1 -1
  87. package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts.map +1 -1
  88. package/data/build/dist/host/cli-adapters/dsh-message-projector.js +6 -2
  89. package/data/build/dist/host/cli-adapters/dsh-message-projector.js.map +1 -1
  90. package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
  91. package/data/build/dist/host/cli-adapters/feature.js +12 -4
  92. package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
  93. package/data/build/dist/host/cli-adapters/magpie-usage.d.ts +13 -2
  94. package/data/build/dist/host/cli-adapters/magpie-usage.d.ts.map +1 -1
  95. package/data/build/dist/host/cli-adapters/magpie-usage.js +186 -14
  96. package/data/build/dist/host/cli-adapters/magpie-usage.js.map +1 -1
  97. package/data/build/dist/host/dsh-runtime-version.d.ts.map +1 -1
  98. package/data/build/dist/host/dsh-runtime-version.js +4 -1
  99. package/data/build/dist/host/dsh-runtime-version.js.map +1 -1
  100. package/data/build/dist/host/features/index.d.ts +1 -0
  101. package/data/build/dist/host/features/index.d.ts.map +1 -1
  102. package/data/build/dist/host/features/index.js +3 -0
  103. package/data/build/dist/host/features/index.js.map +1 -1
  104. package/data/build/dist/host/features/workspace-mcp.d.ts +9 -0
  105. package/data/build/dist/host/features/workspace-mcp.d.ts.map +1 -0
  106. package/data/build/dist/host/features/workspace-mcp.js +197 -0
  107. package/data/build/dist/host/features/workspace-mcp.js.map +1 -0
  108. package/data/build/dist/host/index.d.ts.map +1 -1
  109. package/data/build/dist/host/index.js +6 -2
  110. package/data/build/dist/host/index.js.map +1 -1
  111. package/data/build/dist/host/native-session-bridge.d.ts +2 -0
  112. package/data/build/dist/host/native-session-bridge.d.ts.map +1 -1
  113. package/data/build/dist/host/native-session-bridge.js +30 -0
  114. package/data/build/dist/host/native-session-bridge.js.map +1 -1
  115. package/data/build/dist/host/rpc.d.ts +4 -1
  116. package/data/build/dist/host/rpc.d.ts.map +1 -1
  117. package/data/build/dist/host/rpc.js +57 -9
  118. package/data/build/dist/host/rpc.js.map +1 -1
  119. package/data/build/dist/host/session-handle-eviction.d.ts +4 -2
  120. package/data/build/dist/host/session-handle-eviction.d.ts.map +1 -1
  121. package/data/build/dist/host/session-handle-eviction.js +10 -9
  122. package/data/build/dist/host/session-handle-eviction.js.map +1 -1
  123. package/data/build/dist/host/terminal/terminal-process-service.d.ts +22 -0
  124. package/data/build/dist/host/terminal/terminal-process-service.d.ts.map +1 -1
  125. package/data/build/dist/host/terminal/terminal-process-service.js +102 -0
  126. package/data/build/dist/host/terminal/terminal-process-service.js.map +1 -1
  127. package/data/build/dist/host/terminal/terminal-service.d.ts +5 -1
  128. package/data/build/dist/host/terminal/terminal-service.d.ts.map +1 -1
  129. package/data/build/dist/host/terminal/terminal-service.js +32 -0
  130. package/data/build/dist/host/terminal/terminal-service.js.map +1 -1
  131. package/data/build/dist/host/workspace-mcp/api-key-store.d.ts +16 -0
  132. package/data/build/dist/host/workspace-mcp/api-key-store.d.ts.map +1 -0
  133. package/data/build/dist/host/workspace-mcp/api-key-store.js +65 -0
  134. package/data/build/dist/host/workspace-mcp/api-key-store.js.map +1 -0
  135. package/data/build/dist/host/workspace-mcp/tools.d.ts +54 -0
  136. package/data/build/dist/host/workspace-mcp/tools.d.ts.map +1 -0
  137. package/data/build/dist/host/workspace-mcp/tools.js +800 -0
  138. package/data/build/dist/host/workspace-mcp/tools.js.map +1 -0
  139. package/data/build/dist/host/workspace-mcp/transport.d.ts +35 -0
  140. package/data/build/dist/host/workspace-mcp/transport.d.ts.map +1 -0
  141. package/data/build/dist/host/workspace-mcp/transport.js +575 -0
  142. package/data/build/dist/host/workspace-mcp/transport.js.map +1 -0
  143. package/data/build/dist/shared/contracts/cli-adapter.d.ts +2 -0
  144. package/data/build/dist/shared/contracts/cli-adapter.d.ts.map +1 -1
  145. package/data/build/dist/shared/contracts/errors.d.ts +2 -2
  146. package/data/build/dist/shared/contracts/errors.d.ts.map +1 -1
  147. package/data/build/dist/shared/contracts/errors.js +1 -1
  148. package/data/build/dist/shared/contracts/errors.js.map +1 -1
  149. package/data/build/dist/shared/contracts/magpie-management.d.ts +15 -1
  150. package/data/build/dist/shared/contracts/magpie-management.d.ts.map +1 -1
  151. package/data/build/dist/shared/contracts/session-translation.d.ts +4 -0
  152. package/data/build/dist/shared/contracts/session-translation.d.ts.map +1 -1
  153. package/data/build/dist/shared/contracts/session-translation.js +21 -0
  154. package/data/build/dist/shared/contracts/session-translation.js.map +1 -1
  155. package/data/build/dist/shared/contracts/subscription.d.ts +7 -0
  156. package/data/build/dist/shared/contracts/subscription.d.ts.map +1 -1
  157. package/data/build/dist/shared/contracts/subscription.js.map +1 -1
  158. package/data/build/dist/shared/contracts/terminal.d.ts +2 -0
  159. package/data/build/dist/shared/contracts/terminal.d.ts.map +1 -1
  160. package/data/build/dist/shared/contracts/version.d.ts +7 -7
  161. package/data/build/dist/shared/contracts/version.d.ts.map +1 -1
  162. package/data/build/dist/shared/contracts/version.js +11 -17
  163. package/data/build/dist/shared/contracts/version.js.map +1 -1
  164. package/data/build/dist/shared/index.d.ts +1 -1
  165. package/data/build/dist/shared/index.d.ts.map +1 -1
  166. package/data/build/dist/shared/index.js +1 -1
  167. package/data/build/dist/shared/index.js.map +1 -1
  168. package/package.json +3 -3
  169. package/profile/README.md +6 -6
  170. package/profile/package.json +3 -3
  171. package/profile/scripts/check-dsh-install.mjs +14 -1
  172. package/profile/version.json +2 -2
  173. package/scripts/check-dsh-install.mjs +14 -1
  174. package/version.json +2 -2
@@ -4093,7 +4093,9 @@ window.__ModuleLoader__.load({
4093
4093
  flex: "none",
4094
4094
  alignItems: "center",
4095
4095
  justifyContent: "center",
4096
- width: "18px",
4096
+ minWidth: "18px",
4097
+ maxWidth: "45%",
4098
+ gap: "4px",
4097
4099
  height: "18px",
4098
4100
  marginInlineStart: "auto",
4099
4101
  whiteSpace: "nowrap",
@@ -4107,29 +4109,43 @@ window.__ModuleLoader__.load({
4107
4109
  objectFit: "contain",
4108
4110
  borderRadius: "4px"
4109
4111
  };
4112
+ const providerStyle = {
4113
+ minWidth: 0,
4114
+ overflow: "hidden",
4115
+ textOverflow: "ellipsis",
4116
+ fontSize: "12px",
4117
+ color: "var(--dsw-alias-label-secondary)"
4118
+ };
4110
4119
  /** Compact visual source marker shared by every model-list surface. */
4111
- function MagpieModelTag() {
4120
+ function MagpieModelTag(props) {
4112
4121
  return (0, react.createElement)("span", {
4113
4122
  [MAGPIE_MODEL_TAG_ATTRIBUTE]: "",
4114
4123
  role: "note",
4115
- "aria-label": "Provided by Magpie",
4116
- title: "Provided by Magpie",
4124
+ "aria-label": props.providerId ?? "Provided by Magpie",
4125
+ title: props.providerId ?? "Provided by Magpie",
4117
4126
  style: tagStyle
4118
- }, (0, react.createElement)("img", {
4127
+ }, props.providerId === void 0 ? null : (0, react.createElement)("span", { style: providerStyle }, props.providerId), (0, react.createElement)("img", {
4119
4128
  src: magpieModelLogoUrl(),
4120
4129
  alt: "Provided by Magpie",
4121
4130
  style: tagLogoStyle
4122
4131
  }));
4123
4132
  }
4124
4133
  /** Native DSH owns its menu DOM, so its option rows receive the same badge imperatively. */
4125
- function createMagpieModelTagNode(document, modelId) {
4134
+ function createMagpieModelTagNode(document, modelId, providerId) {
4126
4135
  const tag = document.createElement("span");
4127
4136
  tag.setAttribute(MAGPIE_MODEL_TAG_ATTRIBUTE, "");
4128
4137
  if (modelId !== void 0) tag.dataset.modelId = modelId;
4138
+ if (providerId !== void 0) tag.dataset.providerId = providerId;
4129
4139
  tag.setAttribute("role", "note");
4130
- tag.setAttribute("aria-label", "Provided by Magpie");
4131
- tag.title = "Provided by Magpie";
4140
+ tag.setAttribute("aria-label", providerId ?? "Provided by Magpie");
4141
+ tag.title = providerId ?? "Provided by Magpie";
4132
4142
  Object.assign(tag.style, tagStyle);
4143
+ if (providerId !== void 0) {
4144
+ const provider = document.createElement("span");
4145
+ provider.textContent = providerId;
4146
+ Object.assign(provider.style, providerStyle);
4147
+ tag.append(provider);
4148
+ }
4133
4149
  const logo = document.createElement("img");
4134
4150
  logo.setAttribute("src", magpieModelLogoUrl());
4135
4151
  logo.setAttribute("alt", "Provided by Magpie");
@@ -8352,13 +8368,13 @@ window.__ModuleLoader__.load({
8352
8368
  //#region src/shared/contracts/version.ts
8353
8369
  /** DSH verification target, synchronized with the root version.json. */
8354
8370
  const DSH_VERSION = "0.2.1-rc.3";
8371
+ /** DSH 测试版本别名,供新代码表达语义,保留 DSH_VERSION 兼容旧调用方。 */
8372
+ const DSH_TESTED_VERSION = DSH_VERSION;
8355
8373
  /**
8356
- * Supported hosts retain the 0.2.0-rc.2 floor and include 0.2.1-rc.2.
8357
- * Capability adapters preserve earlier subagent, peer and message contracts.
8358
- * Keep an explicit upper bound: a later prerelease requires verification before
8359
- * either installation checks or runtime capability selection may accept it.
8374
+ * Only the minimum version blocks installation and activation.
8375
+ * Hosts newer than DSH_TESTED_VERSION receive an advisory warning.
8360
8376
  */
8361
- const DSH_COMPATIBILITY = ">=0.2.0-rc.2 <=0.2.1-rc.3";
8377
+ const DSH_COMPATIBILITY = ">=0.2.0-rc.2";
8362
8378
  /**
8363
8379
  * 兼容范围下界,即插件仍然接受的最低 DSH 版本。
8364
8380
  *
@@ -8367,7 +8383,7 @@ window.__ModuleLoader__.load({
8367
8383
  * “不支持的 DSH 版本”,把仅仅缺少启动页注入的页面误判为宿主不兼容。
8368
8384
  */
8369
8385
  function minimumSupportedDshVersion() {
8370
- return /^>=([^ ]+)/u.exec(">=0.2.0-rc.2 <=0.2.1-rc.3")?.[1] ?? "0.2.1-rc.3";
8386
+ return /^>=([^ ]+)/u.exec(">=0.2.0-rc.2")?.[1] ?? "0.2.1-rc.3";
8371
8387
  }
8372
8388
  /** Host 注入到浏览器页面的真实 DSH 版本全局字段。 */
8373
8389
  const CODINGNS_DSH_VERSION_GLOBAL = "__CODINGNS_DSH_VERSION__";
@@ -8376,17 +8392,16 @@ window.__ModuleLoader__.load({
8376
8392
  return /^0\.1\.5(?:-|$)/u.test(version);
8377
8393
  }
8378
8394
  /** Codingns4DSH 插件自身的 npm 版本。 */
8379
- const CODINGNS_VERSION = "0.2.1-rc.5";
8380
- /** 判断宿主版本是否落在当前插件声明的 DSH 兼容范围内;范围省略上界时不校验上限。 */
8395
+ const CODINGNS_VERSION = "0.2.1-rc.7";
8396
+ /** Accept any valid host version at or above the supported minimum. */
8381
8397
  function isDshVersionCompatible(version) {
8382
- const match = /^>=([^ ]+)(?: <=([^ ]+))?$/u.exec(DSH_COMPATIBILITY);
8398
+ return isDshVersionAtLeast(version, minimumSupportedDshVersion());
8399
+ }
8400
+ /** Newer hosts stay enabled; this predicate controls advisory notices only. */
8401
+ function isDshVersionNewerThanTested(version) {
8383
8402
  const actual = parseVersion(version);
8384
- const minimum = parseVersion(match?.[1] ?? "");
8385
- if (match === null || !actual || !minimum) return version === DSH_VERSION;
8386
- if (match[2] === void 0) return compareVersions(actual, minimum) >= 0;
8387
- const maximum = parseVersion(match[2]);
8388
- if (maximum === void 0) return version === DSH_VERSION;
8389
- return compareVersions(actual, minimum) >= 0 && compareVersions(actual, maximum) <= 0;
8403
+ const tested = parseVersion(DSH_TESTED_VERSION);
8404
+ return actual !== void 0 && tested !== void 0 && compareVersions(actual, tested) > 0;
8390
8405
  }
8391
8406
  /** 判断 DSH 版本是否达到某个功能模块要求的最低版本。 */
8392
8407
  function isDshVersionAtLeast(version, minimum) {
@@ -9024,6 +9039,12 @@ window.__ModuleLoader__.load({
9024
9039
  return DSH_COMPATIBILITY;
9025
9040
  }
9026
9041
  });
9042
+ Object.defineProperty(exports, "DSH_TESTED_VERSION", {
9043
+ enumerable: true,
9044
+ get: function() {
9045
+ return DSH_TESTED_VERSION;
9046
+ }
9047
+ });
9027
9048
  Object.defineProperty(exports, "DSH_VERSION", {
9028
9049
  enumerable: true,
9029
9050
  get: function() {
@@ -9090,6 +9111,12 @@ window.__ModuleLoader__.load({
9090
9111
  return isDshVersionCompatible;
9091
9112
  }
9092
9113
  });
9114
+ Object.defineProperty(exports, "isDshVersionNewerThanTested", {
9115
+ enumerable: true,
9116
+ get: function() {
9117
+ return isDshVersionNewerThanTested;
9118
+ }
9119
+ });
9093
9120
  Object.defineProperty(exports, "isFeatureDshVersionCompatible", {
9094
9121
  enumerable: true,
9095
9122
  get: function() {
@@ -16947,6 +16974,25 @@ window.__ModuleLoader__.load({
16947
16974
  model
16948
16975
  };
16949
16976
  }
16977
+ /** Retain known diagnostics without copying raw provider errors into history or UI. */
16978
+ function readSessionTranslationDiagnostics(value) {
16979
+ const failure = asRecord(asRecord(value)?.failure);
16980
+ if (typeof failure?.retryable !== "boolean") return {};
16981
+ switch (failure.code) {
16982
+ case "timeout":
16983
+ case "cancelled":
16984
+ case "rate-limit":
16985
+ case "network":
16986
+ case "unavailable":
16987
+ case "invalid-response":
16988
+ case "configuration":
16989
+ case "provider": return { failure: {
16990
+ code: failure.code,
16991
+ retryable: failure.retryable
16992
+ } };
16993
+ default: return {};
16994
+ }
16995
+ }
16950
16996
  /** Preserve available metrics while accepting records saved before metrics existed. */
16951
16997
  function readSessionTranslationMetrics(value) {
16952
16998
  const record = asRecord(value);
@@ -16979,6 +17025,12 @@ window.__ModuleLoader__.load({
16979
17025
  return normalizeSessionTranslationSettings;
16980
17026
  }
16981
17027
  });
17028
+ Object.defineProperty(exports, "readSessionTranslationDiagnostics", {
17029
+ enumerable: true,
17030
+ get: function() {
17031
+ return readSessionTranslationDiagnostics;
17032
+ }
17033
+ });
16982
17034
  Object.defineProperty(exports, "readSessionTranslationMetrics", {
16983
17035
  enumerable: true,
16984
17036
  get: function() {
@@ -18722,6 +18774,15 @@ window.__ModuleLoader__.load({
18722
18774
  "translation.statusTranslating": "Translating…",
18723
18775
  "translation.progressHelp": "Preparing and translating your message. The translation result will be available when this finishes.",
18724
18776
  "translation.statusFailed": "Translation failed; original kept",
18777
+ "translation.failure.timeout": "The translation request timed out.",
18778
+ "translation.failure.cancelled": "The translation request was cancelled.",
18779
+ "translation.failure.rate-limit": "The translation provider rate limit was reached.",
18780
+ "translation.failure.network": "A network error interrupted the translation request.",
18781
+ "translation.failure.unavailable": "The translation provider was temporarily unavailable.",
18782
+ "translation.failure.invalid-response": "The translation response failed format, language, completion, or protected-text validation.",
18783
+ "translation.failure.configuration": "The translation model or provider configuration was rejected or unavailable.",
18784
+ "translation.failure.provider": "The translation provider or runtime reported an unclassified error.",
18785
+ "translation.failure.unknown": "No failure details were saved for this translation.",
18725
18786
  "translation.retry": "Retry translation",
18726
18787
  "translation.sendDirectly": "Send directly",
18727
18788
  "translation.cancelSending": "Cancel sending",
@@ -18823,6 +18884,15 @@ window.__ModuleLoader__.load({
18823
18884
  "translation.statusTranslating": "正在翻译…",
18824
18885
  "translation.progressHelp": "正在准备并翻译消息,完成后可查看翻译结果。",
18825
18886
  "translation.statusFailed": "翻译失败,已保留原文",
18887
+ "translation.failure.timeout": "翻译请求超时。",
18888
+ "translation.failure.cancelled": "翻译请求已取消。",
18889
+ "translation.failure.rate-limit": "翻译服务商的请求频率已达上限。",
18890
+ "translation.failure.network": "网络错误中断了翻译请求。",
18891
+ "translation.failure.unavailable": "翻译服务商暂时不可用。",
18892
+ "translation.failure.invalid-response": "翻译结果未通过格式、语言、完整性或受保护文本校验。",
18893
+ "translation.failure.configuration": "翻译模型或服务商配置被拒绝或不可用。",
18894
+ "translation.failure.provider": "翻译服务商或运行时返回了未分类错误。",
18895
+ "translation.failure.unknown": "此翻译未保存失败详情。",
18826
18896
  "translation.retry": "重试翻译",
18827
18897
  "translation.sendDirectly": "直接发送",
18828
18898
  "translation.cancelSending": "取消发送",
@@ -19420,6 +19490,13 @@ window.__ModuleLoader__.load({
19420
19490
  "usage.magpieTotalTokens": "Input + output",
19421
19491
  "usage.magpieCost": "Estimated cost",
19422
19492
  "usage.magpieCacheHitRate": "Cache hit rate",
19493
+ "usage.magpieAccountPolicies": "Codex account controls",
19494
+ "usage.magpieResetCountLabel": "Reset cards",
19495
+ "usage.magpieResetCount": "{count} reset cards",
19496
+ "usage.magpieResetWhenWeek": "Auto-use a reset when the weekly window is exhausted",
19497
+ "usage.magpieResetBeforeExpiry": "Auto-use a reset before it expires",
19498
+ "usage.magpieUseCredits": "Use credits after quota is exhausted",
19499
+ "usage.magpieUseReset": "Use one reset card",
19423
19500
  "usage.magpieUpdated": "Updated {time}",
19424
19501
  "usage.magpieAgent": "Agent: {agent}",
19425
19502
  "usage.magpieSessionNoUsage": "No matching session usage today.",
@@ -19626,6 +19703,13 @@ window.__ModuleLoader__.load({
19626
19703
  "usage.magpieTotalTokens": "输入 + 输出",
19627
19704
  "usage.magpieCost": "预估费用",
19628
19705
  "usage.magpieCacheHitRate": "缓存命中率",
19706
+ "usage.magpieAccountPolicies": "Codex 账号控制",
19707
+ "usage.magpieResetCountLabel": "重置卡",
19708
+ "usage.magpieResetCount": "{count} 张重置卡",
19709
+ "usage.magpieResetWhenWeek": "周额度用尽时自动使用重置卡",
19710
+ "usage.magpieResetBeforeExpiry": "重置卡到期前自动使用",
19711
+ "usage.magpieUseCredits": "额度用尽后使用点数",
19712
+ "usage.magpieUseReset": "使用一张重置卡",
19629
19713
  "usage.magpieUpdated": "更新于 {time}",
19630
19714
  "usage.magpieAgent": "Agent:{agent}",
19631
19715
  "usage.magpieSessionNoUsage": "今天还没有找到此会话的用量。",
@@ -20934,6 +21018,12 @@ window.__ModuleLoader__.load({
20934
21018
  "magpie.hostRequestFailed": "The Host request failed. Check the Host connection and retry.",
20935
21019
  "magpie.usageUnavailable": "Usage data could not be read. Other sections may still be available.",
20936
21020
  "magpie.quotaUnavailable": "Subscription data could not be read.",
21021
+ "magpie.codexControlsUnavailable": "Codex account identity was not reported; account controls are unavailable.",
21022
+ "magpie.codexPolicyFailed": "Could not update the Codex account setting. Refresh and try again.",
21023
+ "magpie.codexPolicyUnavailable": "Codex policy settings are unavailable.",
21024
+ "magpie.codexResetFailed": "Could not use a reset card. Refresh and try again.",
21025
+ "magpie.resetDialogAccount": "Account: {account}",
21026
+ "magpie.resetDialogBody": "This uses one reset card from the {count} available and immediately restores the current quota window. This cannot be undone. Continue?",
20937
21027
  "magpie.historyUnavailable": "Quota history could not be read.",
20938
21028
  "magpie.noUsage": "No usage was reported for this period.",
20939
21029
  "magpie.noSessions": "No sessions were reported for this period.",
@@ -21284,6 +21374,12 @@ window.__ModuleLoader__.load({
21284
21374
  "magpie.hostRequestFailed": "Host 请求失败。请检查 Host 连接后重试。",
21285
21375
  "magpie.usageUnavailable": "无法读取用量数据;其他区块仍可能可用。",
21286
21376
  "magpie.quotaUnavailable": "无法读取订阅数据。",
21377
+ "magpie.codexControlsUnavailable": "未报告 Codex 账号身份,无法显示账号控制项。",
21378
+ "magpie.codexPolicyFailed": "无法更新 Codex 账号设置,请刷新后重试。",
21379
+ "magpie.codexPolicyUnavailable": "暂时无法读取 Codex 使用规则。",
21380
+ "magpie.codexResetFailed": "无法使用重置卡,请刷新后重试。",
21381
+ "magpie.resetDialogAccount": "账号:{account}",
21382
+ "magpie.resetDialogBody": "将使用当前 {count} 张重置卡中的 1 张,并立即恢复当前额度窗口。此操作不可撤销,确定继续吗?",
21287
21383
  "magpie.historyUnavailable": "无法读取额度历史。",
21288
21384
  "magpie.noUsage": "此周期没有用量记录。",
21289
21385
  "magpie.noSessions": "此周期没有会话记录。",
@@ -21659,6 +21755,8 @@ window.__ModuleLoader__.load({
21659
21755
  "settings.subtitle": "Configure modules without changing DSH global settings.",
21660
21756
  "settings.version": "Codingns4DSH v{version}",
21661
21757
  "settings.compatibility": "Compatible with DSH {range}",
21758
+ "settings.testedDshVersion": "Tested with DSH {version}",
21759
+ "settings.untestedDshWarning": "DSH {version} is newer than the latest tested version ({tested}). Compatibility has not been verified; plugin installation and operation remain enabled.",
21662
21760
  "settings.toggle": "{label} toggle",
21663
21761
  "settings.legacyFallback": "This DSH version uses compatibility mode; multi-tab and shell-selection extensions are unavailable.",
21664
21762
  "settings.versionBlocked": "This module is unavailable on DSH {version}; it requires DSH {minimum} or newer.",
@@ -21683,6 +21781,94 @@ window.__ModuleLoader__.load({
21683
21781
  "feature.cliAdapters.description": "View installed external Agents, versions, command paths, available models, and enable them independently. External Agent context panels keep only the occupancy percentage and totals.",
21684
21782
  "feature.workspaceSession.label": "Workspace session enhancement",
21685
21783
  "feature.workspaceSession.description": "Show Agent logos, archived-session entries, workspace hiding controls, subscription or usage information, local quick sessions, and an optional remembered conversation/right-sidebar width ratio.",
21784
+ "feature.workspaceMcp.label": "Workspace MCP server",
21785
+ "feature.workspaceMcp.description": "Expose managed workspace tools to local MCP clients through an authenticated Host listener.",
21786
+ "workspaceMcp.setupTitle": "MCP access key",
21787
+ "workspaceMcp.setupInstruction": "Generate a key to save it on the Host and enable the local MCP listener.",
21788
+ "workspaceMcp.generateKey": "Generate key and enable",
21789
+ "workspaceMcp.rotateKey": "Rotate key",
21790
+ "workspaceMcp.generating": "Generating…",
21791
+ "workspaceMcp.generatedKey": "Generated Workspace MCP API key",
21792
+ "workspaceMcp.keyGenerated": "Workspace MCP key generated and module enabled.",
21793
+ "workspaceMcp.copyKey": "Copy key",
21794
+ "workspaceMcp.keyCopied": "Workspace MCP key copied.",
21795
+ "workspaceMcp.copyFailed": "Could not copy the key. Select and copy it manually.",
21796
+ "workspaceMcp.keyShownOnce": "This key is shown only now. Copy it into your MCP client before closing or refreshing this panel.",
21797
+ "workspaceMcp.capabilityDescription": "MCP capability description",
21798
+ "workspaceMcp.capabilityTitle": "Supported MCP capabilities",
21799
+ "workspaceMcp.capabilitySubtitle": "The list below describes the fixed Workspace MCP tool catalog and its access boundaries.",
21800
+ "workspaceMcp.capabilityName": "Name",
21801
+ "workspaceMcp.capabilityPermission": "Permission",
21802
+ "workspaceMcp.capabilityDescriptionField": "Description",
21803
+ "workspaceMcp.capabilityParameters": "Invocation parameters",
21804
+ "workspaceMcp.capabilityRemarks": "Remarks",
21805
+ "workspaceMcp.closeCapabilities": "Close",
21806
+ "workspaceMcp.installPromptTitle": "Install the Agent Skill",
21807
+ "workspaceMcp.installPromptHint": "Copy this prompt to your Agent. It will install the root SKILL.md into that Agent’s personal skills directory.",
21808
+ "workspaceMcp.copyInstallPrompt": "Copy install prompt",
21809
+ "workspaceMcp.installPromptCopied": "Agent Skill installation prompt copied.",
21810
+ "workspaceMcp.installPromptText": "Fetch https://github.com/jingyi0605/Codingns4DSH/blob/main/SKILL.md and install it into your personal Agent Skills directory using your documented Skill installation method.",
21811
+ "workspaceMcp.capability.workspaceList.permission": "Read managed workspace metadata",
21812
+ "workspaceMcp.capability.workspaceList.description": "Lists managed workspaces available to the local Host.",
21813
+ "workspaceMcp.capability.workspaceList.parameters": "{}",
21814
+ "workspaceMcp.capability.workspaceList.remarks": "Returns names and active session counts; filesystem roots are never exposed.",
21815
+ "workspaceMcp.capability.sessionList.permission": "Read bounded session metadata",
21816
+ "workspaceMcp.capability.sessionList.description": "Lists sessions belonging to managed workspaces.",
21817
+ "workspaceMcp.capability.sessionList.parameters": "{ workspaceId?, limit?, offset? }",
21818
+ "workspaceMcp.capability.sessionList.remarks": "Results are paginated and contain metadata only, without full conversation history.",
21819
+ "workspaceMcp.capability.sessionCreate.permission": "Create a managed session and optionally queue a prompt",
21820
+ "workspaceMcp.capability.sessionCreate.description": "Creates a native DSH session and can select an installed adapter/model.",
21821
+ "workspaceMcp.capability.sessionCreate.parameters": "{ workspaceId, adapterId?, modelId?, prompt? }",
21822
+ "workspaceMcp.capability.sessionCreate.remarks": "External adapter sessions require an initial prompt; uncertain outcomes include the created session ID.",
21823
+ "workspaceMcp.capability.sessionContinue.permission": "Queue a message in an existing session",
21824
+ "workspaceMcp.capability.sessionContinue.description": "Continues one exact managed session without replacing its identity.",
21825
+ "workspaceMcp.capability.sessionContinue.parameters": "{ sessionId, message }",
21826
+ "workspaceMcp.capability.sessionContinue.remarks": "The session is revalidated immediately before prompt admission.",
21827
+ "workspaceMcp.capability.sessionQuestions.permission": "Read unresolved native questions",
21828
+ "workspaceMcp.capability.sessionQuestions.description": "Lists questions currently awaiting an answer in a managed session.",
21829
+ "workspaceMcp.capability.sessionQuestions.parameters": "{ sessionId }",
21830
+ "workspaceMcp.capability.sessionQuestions.remarks": "Question content and options are bounded; archived or unrelated sessions are rejected.",
21831
+ "workspaceMcp.capability.sessionAnswer.permission": "Answer one unresolved native question",
21832
+ "workspaceMcp.capability.sessionAnswer.description": "Submits validated answers through the native DSH question mechanism.",
21833
+ "workspaceMcp.capability.sessionAnswer.parameters": "{ sessionId, callId, answer }",
21834
+ "workspaceMcp.capability.sessionAnswer.remarks": "The call ID must come from the current question list and answers are checked against its options.",
21835
+ "workspaceMcp.capability.sessionRequestPermission.permission": "Request human approval",
21836
+ "workspaceMcp.capability.sessionRequestPermission.description": "Asks the native DSH approval UI to decide an operation.",
21837
+ "workspaceMcp.capability.sessionRequestPermission.parameters": "{ sessionId, toolName, reason, callId? }",
21838
+ "workspaceMcp.capability.sessionRequestPermission.remarks": "Requires an active DSH turn; the MCP client cannot approve its own request.",
21839
+ "workspaceMcp.capability.sessionPermissionStatus.permission": "Read an owned approval outcome",
21840
+ "workspaceMcp.capability.sessionPermissionStatus.description": "Reads the status of an approval request created by this MCP feature.",
21841
+ "workspaceMcp.capability.sessionPermissionStatus.parameters": "{ sessionId, requestId }",
21842
+ "workspaceMcp.capability.sessionPermissionStatus.remarks": "Only DSH-issued request IDs retained by the live feature are queryable.",
21843
+ "workspaceMcp.capability.terminalList.permission": "Read live terminal metadata",
21844
+ "workspaceMcp.capability.terminalList.description": "Lists terminal instances attached to one managed session.",
21845
+ "workspaceMcp.capability.terminalList.parameters": "{ workspaceId, sessionId }",
21846
+ "workspaceMcp.capability.terminalList.remarks": "Only live terminals in the specified workspace/session scope are returned.",
21847
+ "workspaceMcp.capability.terminalRead.permission": "Read terminal output",
21848
+ "workspaceMcp.capability.terminalRead.description": "Returns a bounded output snapshot from one live terminal.",
21849
+ "workspaceMcp.capability.terminalRead.parameters": "{ workspaceId, sessionId, terminalId, limitBytes? }",
21850
+ "workspaceMcp.capability.terminalRead.remarks": "Output is limited to 64 KiB and is never read from an unrelated terminal.",
21851
+ "workspaceMcp.capability.terminalWrite.permission": "Write terminal input",
21852
+ "workspaceMcp.capability.terminalWrite.description": "Writes bounded text to one existing live terminal process.",
21853
+ "workspaceMcp.capability.terminalWrite.parameters": "{ workspaceId, sessionId, terminalId, data }",
21854
+ "workspaceMcp.capability.terminalWrite.remarks": "Input is limited to 16 KiB, rejects NUL bytes, and cannot create arbitrary processes.",
21855
+ "workspaceMcp.statusTitle": "Host status",
21856
+ "workspaceMcp.loading": "Reading Workspace MCP status…",
21857
+ "workspaceMcp.statusFailed": "Unable to read Workspace MCP status from the Host.",
21858
+ "workspaceMcp.apiKeyStatus": "API key: {status}",
21859
+ "workspaceMcp.enabledStatus": "Module: {status}",
21860
+ "workspaceMcp.listeningStatus": "Listener: {status}",
21861
+ "workspaceMcp.configured": "configured",
21862
+ "workspaceMcp.notConfigured": "not configured",
21863
+ "workspaceMcp.on": "on",
21864
+ "workspaceMcp.off": "off",
21865
+ "workspaceMcp.url": "Endpoint",
21866
+ "workspaceMcp.refresh": "Refresh status",
21867
+ "workspaceMcp.reason.keyMissing": "Generate a Workspace MCP API key to start the listener.",
21868
+ "workspaceMcp.reason.keyStoreFailed": "The Host could not access the Workspace MCP key file.",
21869
+ "workspaceMcp.reason.disabled": "The Workspace MCP module is disabled.",
21870
+ "workspaceMcp.reason.listenFailed": "The local MCP listener could not start.",
21871
+ "workspaceMcp.reason.other": "The Host reported an additional status reason.",
21686
21872
  "feature.assistant.label": "Global smart assistant (Testing)",
21687
21873
  "feature.assistant.description": "Summarize progress across selected workspaces and route voice or text instructions to an explicit target session. After enabling this module, fully quit and restart DSH Desktop.",
21688
21874
  "voice.globalAssistant": "Global voice assistant (Testing)",
@@ -22117,6 +22303,8 @@ window.__ModuleLoader__.load({
22117
22303
  "settings.subtitle": "按模块配置 Codingns4DSH 功能,不影响 DSH 的全局设置。",
22118
22304
  "settings.version": "Codingns4DSH v{version}",
22119
22305
  "settings.compatibility": "兼容 DSH {range}",
22306
+ "settings.testedDshVersion": "已验证 DSH {version}",
22307
+ "settings.untestedDshWarning": "当前 DSH {version} 高于插件最新已验证版本({tested}),兼容性尚未验证;不影响插件安装和运行。",
22120
22308
  "settings.toggle": "{label}开关",
22121
22309
  "settings.legacyFallback": "当前 DSH 版本使用兼容模式;多 Tab 和 Shell 选择扩展不可用。",
22122
22310
  "settings.versionBlocked": "当前 DSH {version} 不支持此模块;需要 DSH {minimum} 或更高版本。",
@@ -22141,6 +22329,94 @@ window.__ModuleLoader__.load({
22141
22329
  "feature.cliAdapters.description": "管理外部 Agent",
22142
22330
  "feature.workspaceSession.label": "工作区会话增强",
22143
22331
  "feature.workspaceSession.description": "增强工作区会话体验",
22332
+ "feature.workspaceMcp.label": "工作区 MCP 服务",
22333
+ "feature.workspaceMcp.description": "通过 Host 本机认证监听器向 MCP 客户端提供受管理工作区工具。",
22334
+ "workspaceMcp.setupTitle": "MCP 访问密钥",
22335
+ "workspaceMcp.setupInstruction": "生成密钥后会保存在 Host 并自动启用本机 MCP 监听器。",
22336
+ "workspaceMcp.generateKey": "生成密钥并启用",
22337
+ "workspaceMcp.rotateKey": "轮换密钥",
22338
+ "workspaceMcp.generating": "正在生成…",
22339
+ "workspaceMcp.generatedKey": "生成的 Workspace MCP API Key",
22340
+ "workspaceMcp.keyGenerated": "Workspace MCP 密钥已生成,模块已启用。",
22341
+ "workspaceMcp.copyKey": "复制密钥",
22342
+ "workspaceMcp.keyCopied": "Workspace MCP 密钥已复制。",
22343
+ "workspaceMcp.copyFailed": "无法复制密钥,请手动选择并复制。",
22344
+ "workspaceMcp.keyShownOnce": "密钥仅在此时显示。关闭或刷新面板前,请先复制到 MCP 客户端。",
22345
+ "workspaceMcp.capabilityDescription": "MCP 能力说明",
22346
+ "workspaceMcp.capabilityTitle": "支持的 MCP 能力",
22347
+ "workspaceMcp.capabilitySubtitle": "以下列表说明 Workspace MCP 的固定工具目录及其访问边界。",
22348
+ "workspaceMcp.capabilityName": "名称",
22349
+ "workspaceMcp.capabilityPermission": "权限",
22350
+ "workspaceMcp.capabilityDescriptionField": "描述",
22351
+ "workspaceMcp.capabilityParameters": "调用参数",
22352
+ "workspaceMcp.capabilityRemarks": "备注",
22353
+ "workspaceMcp.closeCapabilities": "关闭",
22354
+ "workspaceMcp.installPromptTitle": "安装 Agent Skill",
22355
+ "workspaceMcp.installPromptHint": "复制此提示词并发送给 Agent,它会将仓库根目录的 SKILL.md 安装到该 Agent 的个人 Skills 目录。",
22356
+ "workspaceMcp.copyInstallPrompt": "复制安装提示词",
22357
+ "workspaceMcp.installPromptCopied": "Agent Skill 安装提示词已复制。",
22358
+ "workspaceMcp.installPromptText": "获取 https://github.com/jingyi0605/Codingns4DSH/blob/main/SKILL.md,并使用你已记录的 Skill 安装方式,将其安装到你自己的 Agent 个人 Skills 目录。",
22359
+ "workspaceMcp.capability.workspaceList.permission": "读取受管理工作区元数据",
22360
+ "workspaceMcp.capability.workspaceList.description": "列出当前 Host 可管理的工作区。",
22361
+ "workspaceMcp.capability.workspaceList.parameters": "{}",
22362
+ "workspaceMcp.capability.workspaceList.remarks": "只返回名称和活动会话数,不暴露文件系统根目录。",
22363
+ "workspaceMcp.capability.sessionList.permission": "读取有界会话元数据",
22364
+ "workspaceMcp.capability.sessionList.description": "列出受管理工作区中的会话。",
22365
+ "workspaceMcp.capability.sessionList.parameters": "{ workspaceId?, limit?, offset? }",
22366
+ "workspaceMcp.capability.sessionList.remarks": "结果支持分页,只返回元数据,不返回完整对话历史。",
22367
+ "workspaceMcp.capability.sessionCreate.permission": "创建受管理会话并可排队发送初始提示",
22368
+ "workspaceMcp.capability.sessionCreate.description": "创建原生 DSH 会话,并可选择已安装的适配器和模型。",
22369
+ "workspaceMcp.capability.sessionCreate.parameters": "{ workspaceId, adapterId?, modelId?, prompt? }",
22370
+ "workspaceMcp.capability.sessionCreate.remarks": "外部适配器会话必须提供初始提示;不确定结果会返回已创建的会话 ID。",
22371
+ "workspaceMcp.capability.sessionContinue.permission": "向已有会话排队发送消息",
22372
+ "workspaceMcp.capability.sessionContinue.description": "继续指定的受管理会话,不替换其身份。",
22373
+ "workspaceMcp.capability.sessionContinue.parameters": "{ sessionId, message }",
22374
+ "workspaceMcp.capability.sessionContinue.remarks": "消息接纳前会重新校验会话归属和可用性。",
22375
+ "workspaceMcp.capability.sessionQuestions.permission": "读取未解决的原生问题",
22376
+ "workspaceMcp.capability.sessionQuestions.description": "列出受管理会话中等待回答的问题。",
22377
+ "workspaceMcp.capability.sessionQuestions.parameters": "{ sessionId }",
22378
+ "workspaceMcp.capability.sessionQuestions.remarks": "问题内容和选项有大小限制;归档或无关会话会被拒绝。",
22379
+ "workspaceMcp.capability.sessionAnswer.permission": "回答一个未解决的原生问题",
22380
+ "workspaceMcp.capability.sessionAnswer.description": "通过 DSH 原生问题机制提交经过校验的答案。",
22381
+ "workspaceMcp.capability.sessionAnswer.parameters": "{ sessionId, callId, answer }",
22382
+ "workspaceMcp.capability.sessionAnswer.remarks": "callId 必须来自当前问题列表,答案会按原生选项校验。",
22383
+ "workspaceMcp.capability.sessionRequestPermission.permission": "请求人工审批",
22384
+ "workspaceMcp.capability.sessionRequestPermission.description": "通过 DSH 原生审批界面请求对某项操作作出决定。",
22385
+ "workspaceMcp.capability.sessionRequestPermission.parameters": "{ sessionId, toolName, reason, callId? }",
22386
+ "workspaceMcp.capability.sessionRequestPermission.remarks": "必须存在活动 DSH 回合;MCP 客户端不能批准自己的请求。",
22387
+ "workspaceMcp.capability.sessionPermissionStatus.permission": "读取已拥有的审批结果",
22388
+ "workspaceMcp.capability.sessionPermissionStatus.description": "读取当前 MCP 模块创建的审批请求状态。",
22389
+ "workspaceMcp.capability.sessionPermissionStatus.parameters": "{ sessionId, requestId }",
22390
+ "workspaceMcp.capability.sessionPermissionStatus.remarks": "只能查询当前模块保留的 DSH 原生请求 ID。",
22391
+ "workspaceMcp.capability.terminalList.permission": "读取活动终端元数据",
22392
+ "workspaceMcp.capability.terminalList.description": "列出一个受管理会话附属的终端实例。",
22393
+ "workspaceMcp.capability.terminalList.parameters": "{ workspaceId, sessionId }",
22394
+ "workspaceMcp.capability.terminalList.remarks": "只返回指定工作区和会话范围内的活动终端。",
22395
+ "workspaceMcp.capability.terminalRead.permission": "读取终端输出",
22396
+ "workspaceMcp.capability.terminalRead.description": "读取一个活动终端的有界输出快照。",
22397
+ "workspaceMcp.capability.terminalRead.parameters": "{ workspaceId, sessionId, terminalId, limitBytes? }",
22398
+ "workspaceMcp.capability.terminalRead.remarks": "输出上限为 64 KiB,不会读取其他终端。",
22399
+ "workspaceMcp.capability.terminalWrite.permission": "写入终端输入",
22400
+ "workspaceMcp.capability.terminalWrite.description": "向一个已有的活动终端进程写入有界文本。",
22401
+ "workspaceMcp.capability.terminalWrite.parameters": "{ workspaceId, sessionId, terminalId, data }",
22402
+ "workspaceMcp.capability.terminalWrite.remarks": "输入上限为 16 KiB,拒绝 NUL 字节,不能创建任意进程。",
22403
+ "workspaceMcp.statusTitle": "Host 状态",
22404
+ "workspaceMcp.loading": "正在读取工作区 MCP 状态…",
22405
+ "workspaceMcp.statusFailed": "无法从 Host 读取工作区 MCP 状态。",
22406
+ "workspaceMcp.apiKeyStatus": "API Key:{status}",
22407
+ "workspaceMcp.enabledStatus": "模块:{status}",
22408
+ "workspaceMcp.listeningStatus": "监听器:{status}",
22409
+ "workspaceMcp.configured": "已配置",
22410
+ "workspaceMcp.notConfigured": "未配置",
22411
+ "workspaceMcp.on": "已开启",
22412
+ "workspaceMcp.off": "已关闭",
22413
+ "workspaceMcp.url": "端点",
22414
+ "workspaceMcp.refresh": "刷新状态",
22415
+ "workspaceMcp.reason.keyMissing": "请生成 Workspace MCP API Key 以启动监听器。",
22416
+ "workspaceMcp.reason.keyStoreFailed": "Host 无法访问 Workspace MCP 密钥文件。",
22417
+ "workspaceMcp.reason.disabled": "工作区 MCP 模块已关闭。",
22418
+ "workspaceMcp.reason.listenFailed": "本机 MCP 监听器无法启动。",
22419
+ "workspaceMcp.reason.other": "Host 返回了其他状态原因。",
22144
22420
  "feature.assistant.label": "全局智能助理(测试中)",
22145
22421
  "feature.assistant.description": "汇总受管工作区进展,并把语音或文字指令派发到明确的目标会话。启用该模块后,请彻底重启 DSH Desktop。",
22146
22422
  "voice.globalAssistant": "全局语音助理(测试中)",
@@ -25128,7 +25404,7 @@ window.__ModuleLoader__.load({
25128
25404
  this.code = code;
25129
25405
  }
25130
25406
  };
25131
- /** 启动期严格检查 DSH 兼容范围,不对未知版本静默降级。 */
25407
+ /** Enforce the DSH minimum version without rejecting newer hosts. */
25132
25408
  function assertSupportedDshVersion(version) {
25133
25409
  if (!require_native_workspace_store.isDshVersionCompatible(version)) throw new CodingNsDshError(CODINGNS_DSH_ERROR_CODES.DSH_VERSION_UNSUPPORTED, `不支持的 DSH 版本: ${version};当前插件兼容范围为 ${SUPPORTED_DSH_COMPATIBILITY}`);
25134
25410
  }
@@ -25302,12 +25578,12 @@ window.__ModuleLoader__.load({
25302
25578
  if (typeof fields.status === "number" && fields.status >= 400) return true;
25303
25579
  if (typeof fields.state === "string" && /^(failed|disconnected|closed|degraded)$/iu.test(fields.state)) return true;
25304
25580
  if (typeof fields.event === "string" && fields.event !== event) {
25305
- const nestedFields = isRecord$11(fields.fields) ? fields.fields : {};
25581
+ const nestedFields = isRecord$12(fields.fields) ? fields.fields : {};
25306
25582
  return isDshTransportWarningEvent(fields.event, nestedFields);
25307
25583
  }
25308
25584
  return false;
25309
25585
  }
25310
- function isRecord$11(value) {
25586
+ function isRecord$12(value) {
25311
25587
  return typeof value === "object" && value !== null && !Array.isArray(value);
25312
25588
  }
25313
25589
  /**
@@ -27349,7 +27625,7 @@ window.__ModuleLoader__.load({
27349
27625
  async onMessage(event) {
27350
27626
  const sourceWindow = event.source;
27351
27627
  if (this.disposed || sourceWindow === null || !this.iframeWindows.has(sourceWindow)) return;
27352
- if (!isRecord$10(event.data) || typeof event.data.kind !== "string") return;
27628
+ if (!isRecord$11(event.data) || typeof event.data.kind !== "string") return;
27353
27629
  const message = event.data;
27354
27630
  if (message.kind !== "dsh-web-debug" && typeof message.id !== "string") return;
27355
27631
  if (typeof message.id === "string") this.messageWindows.set(message.id, sourceWindow);
@@ -27360,7 +27636,7 @@ window.__ModuleLoader__.load({
27360
27636
  try {
27361
27637
  if (message.kind === "dsh-web-debug") {
27362
27638
  const eventName = typeof message.event === "string" ? message.event : "unknown";
27363
- const fields = isRecord$10(message.fields) ? message.fields : {};
27639
+ const fields = isRecord$11(message.fields) ? message.fields : {};
27364
27640
  this.debug.log(`iframe.${eventName}`, fields);
27365
27641
  if (/^(bridge\.ws\.|client\.connection\.)/u.test(eventName)) await this.options.transport.webRequest("web.debug", {
27366
27642
  event: eventName,
@@ -27369,7 +27645,7 @@ window.__ModuleLoader__.load({
27369
27645
  return;
27370
27646
  }
27371
27647
  if (message.kind === "fetch") {
27372
- const input = isRecord$10(message.input) ? message.input : {};
27648
+ const input = isRecord$11(message.input) ? message.input : {};
27373
27649
  const path = resolveRemotePath(typeof input.path === "string" ? input.path : "/");
27374
27650
  const body = typeof message.body === "string" ? message.body : typeof input.body === "string" ? input.body : void 0;
27375
27651
  const response = path.startsWith("/assets/") || path.startsWith("/plugins/") ? {
@@ -27395,7 +27671,7 @@ window.__ModuleLoader__.load({
27395
27671
  return;
27396
27672
  }
27397
27673
  if (message.kind === "script") {
27398
- const input = isRecord$10(message.input) ? message.input : {};
27674
+ const input = isRecord$11(message.input) ? message.input : {};
27399
27675
  const path = resolveRemotePath(typeof input.path === "string" ? input.path : "/");
27400
27676
  const url = await this.loadScript(path, void 0);
27401
27677
  this.postResponse(message.id, {
@@ -27405,7 +27681,7 @@ window.__ModuleLoader__.load({
27405
27681
  return;
27406
27682
  }
27407
27683
  if (message.kind === "image") {
27408
- const input = isRecord$10(message.input) ? message.input : {};
27684
+ const input = isRecord$11(message.input) ? message.input : {};
27409
27685
  const path = resolveRemotePath(typeof input.path === "string" ? input.path : "/");
27410
27686
  const url = await this.loadImage(path);
27411
27687
  this.postResponse(message.id, {
@@ -27415,7 +27691,7 @@ window.__ModuleLoader__.load({
27415
27691
  return;
27416
27692
  }
27417
27693
  if (message.kind === "style") {
27418
- const input = isRecord$10(message.input) ? message.input : {};
27694
+ const input = isRecord$11(message.input) ? message.input : {};
27419
27695
  const path = resolveRemotePath(typeof input.path === "string" ? input.path : "/");
27420
27696
  const url = await this.loadStyle(path, void 0);
27421
27697
  this.postResponse(message.id, {
@@ -27425,7 +27701,7 @@ window.__ModuleLoader__.load({
27425
27701
  return;
27426
27702
  }
27427
27703
  if (message.kind === "ws.open") {
27428
- const input = isRecord$10(message.input) ? message.input : {};
27704
+ const input = isRecord$11(message.input) ? message.input : {};
27429
27705
  const opened = this.options.transport.openWebStreamWithId("web.ws.open", {
27430
27706
  sessionId: this.sessionIdValue,
27431
27707
  path: resolveRemotePath(typeof input.path === "string" ? input.path : "/")
@@ -27517,7 +27793,7 @@ window.__ModuleLoader__.load({
27517
27793
  for await (const value of stream) {
27518
27794
  if (!opened) {
27519
27795
  opened = true;
27520
- if (isRecord$10(value) && value.opened === true) {
27796
+ if (isRecord$11(value) && value.opened === true) {
27521
27797
  this.socketReady.get(id)?.resolve();
27522
27798
  this.socketReady.delete(id);
27523
27799
  continue;
@@ -28171,7 +28447,7 @@ window.__ModuleLoader__.load({
28171
28447
  const policy = "default-src 'self' blob: data:; script-src 'self' blob: data: 'unsafe-inline' 'unsafe-eval'; style-src 'self' blob: data: 'unsafe-inline'; img-src 'self' blob: data:; font-src 'self' blob: data:; media-src 'self' blob: data:; worker-src 'self' blob:; connect-src 'none'; frame-src 'self' blob: data:";
28172
28448
  for (const node of documentValue.querySelectorAll("meta[http-equiv]")) if ((node.getAttribute("http-equiv") ?? "").toLowerCase() === "content-security-policy") node.setAttribute("content", policy);
28173
28449
  }
28174
- function isRecord$10(value) {
28450
+ function isRecord$11(value) {
28175
28451
  return typeof value === "object" && value !== null && !Array.isArray(value);
28176
28452
  }
28177
28453
  function toBytes(value) {
@@ -29461,11 +29737,11 @@ window.__ModuleLoader__.load({
29461
29737
  };
29462
29738
  }
29463
29739
  function readMarker(event) {
29464
- if (!isRecord$9(event)) return null;
29740
+ if (!isRecord$10(event)) return null;
29465
29741
  const data = event.data;
29466
- if (!isRecord$9(data)) return null;
29467
- const candidate = event.type === "assistant/live-chunk" ? isRecord$9(data.chunk) ? data.chunk.codingnsExternalTool : void 0 : event.type === "assistant/attempt" ? data.codingnsExternalTool : void 0;
29468
- if (!isRecord$9(candidate) || candidate.source !== "codingns-external-tool") return null;
29742
+ if (!isRecord$10(data)) return null;
29743
+ const candidate = event.type === "assistant/live-chunk" ? isRecord$10(data.chunk) ? data.chunk.codingnsExternalTool : void 0 : event.type === "assistant/attempt" ? data.codingnsExternalTool : void 0;
29744
+ if (!isRecord$10(candidate) || candidate.source !== "codingns-external-tool") return null;
29469
29745
  if (typeof candidate.callId !== "string" || candidate.callId === "") return null;
29470
29746
  if (typeof candidate.name !== "string" || typeof candidate.arguments !== "string") return null;
29471
29747
  if (candidate.phase !== "start" && candidate.phase !== "update") return null;
@@ -29481,7 +29757,7 @@ window.__ModuleLoader__.load({
29481
29757
  ...typeof candidate.error === "string" ? { error: candidate.error } : {}
29482
29758
  };
29483
29759
  }
29484
- function isRecord$9(value) {
29760
+ function isRecord$10(value) {
29485
29761
  return typeof value === "object" && value !== null && !Array.isArray(value);
29486
29762
  }
29487
29763
  //#endregion
@@ -29959,9 +30235,9 @@ window.__ModuleLoader__.load({
29959
30235
  return {
29960
30236
  async targets(signal, query) {
29961
30237
  const rows = /* @__PURE__ */ new Map();
29962
- const localRows = record$1(record$1(sessions.list?.getSnapshot())?.byId) ?? {};
30238
+ const localRows = record$2(record$2(sessions.list?.getSnapshot())?.byId) ?? {};
29963
30239
  for (const [id, value] of Object.entries(localRows)) rows.set(id, {
29964
- ...record$1(value),
30240
+ ...record$2(value),
29965
30241
  sessionId: id
29966
30242
  });
29967
30243
  const remote = service(context, "remote.session");
@@ -29973,17 +30249,17 @@ window.__ModuleLoader__.load({
29973
30249
  return query === void 0 ? targets : selectRecentTerminalShareTargets(targets, snapshot, query.sessionId, query.limit);
29974
30250
  };
29975
30251
  signal?.throwIfAborted();
29976
- const ids = array$1((query === void 0 ? void 0 : array$1(record$1(workspaceSnapshot())?.items).map(record$1).find((item) => array$1(item?.sessionIds).includes(query.sessionId)))?.sessionIds);
30252
+ const ids = array$1((query === void 0 ? void 0 : array$1(record$2(workspaceSnapshot())?.items).map(record$2).find((item) => array$1(item?.sessionIds).includes(query.sessionId)))?.sessionIds);
29977
30253
  if (query !== void 0 && ids.length > 0 && ids.every((id) => typeof id === "string" && rows.has(id))) return selectTargets();
29978
30254
  do {
29979
30255
  signal?.throwIfAborted();
29980
30256
  if (remote?.list === void 0) break;
29981
- const page = record$1(unwrap$1(await remote.list(cursor === void 0 ? {} : { cursor }, signal)));
30257
+ const page = record$2(unwrap$1(await remote.list(cursor === void 0 ? {} : { cursor }, signal)));
29982
30258
  for (const value of array$1(page?.items)) {
29983
- const id = string$3(record$1(value)?.sessionId);
30259
+ const id = string$3(record$2(value)?.sessionId);
29984
30260
  if (id !== "") rows.set(id, {
29985
- ...record$1(value),
29986
- ...record$1(localRows[id]),
30261
+ ...record$2(value),
30262
+ ...record$2(localRows[id]),
29987
30263
  sessionId: id
29988
30264
  });
29989
30265
  }
@@ -29996,7 +30272,7 @@ window.__ModuleLoader__.load({
29996
30272
  return selectTargets();
29997
30273
  },
29998
30274
  source(sessionId) {
29999
- const workspace = array$1(record$1(workspaceSnapshot())?.items).map(record$1).find((item) => array$1(item?.sessionIds).includes(sessionId));
30275
+ const workspace = array$1(record$2(workspaceSnapshot())?.items).map(record$2).find((item) => array$1(item?.sessionIds).includes(sessionId));
30000
30276
  return {
30001
30277
  hostId: require_primitives_adapter.parseVirtualSessionId(sessionId)?.hostId ?? "local",
30002
30278
  workspaceId: string$3(workspace?.workspaceId)
@@ -30013,7 +30289,7 @@ window.__ModuleLoader__.load({
30013
30289
  });
30014
30290
  },
30015
30291
  async createTarget(sourceSessionId) {
30016
- const workspaceId = string$3(array$1(record$1(workspaceSnapshot())?.items).map(record$1).find((item) => array$1(item?.sessionIds).includes(sourceSessionId))?.workspaceId);
30292
+ const workspaceId = string$3(array$1(record$2(workspaceSnapshot())?.items).map(record$2).find((item) => array$1(item?.sessionIds).includes(sourceSessionId))?.workspaceId);
30017
30293
  if (workspaceId === "") throw new Error("当前会话的工作区尚未就绪,请稍后重试");
30018
30294
  if (typeof sessions.create !== "function") throw new Error("当前 DSH 缺少新建会话能力");
30019
30295
  const sessionId = await sessions.create({ workspaceId });
@@ -30051,12 +30327,12 @@ window.__ModuleLoader__.load({
30051
30327
  }
30052
30328
  /** 原生工作区快照同时包含 PeerHost 投影和归档集合。 */
30053
30329
  function readTerminalShareTargets(rows, snapshot) {
30054
- const state = record$1(snapshot);
30055
- const workspaces = array$1(state?.items).map(record$1);
30330
+ const state = record$2(snapshot);
30331
+ const workspaces = array$1(state?.items).map(record$2);
30056
30332
  const archived = new Set(array$1(state?.archivedSessionIds));
30057
30333
  for (const workspace of workspaces) for (const id of array$1(workspace?.archivedSessionIds)) archived.add(id);
30058
30334
  return rows.flatMap((raw) => {
30059
- const item = record$1(raw);
30335
+ const item = record$2(raw);
30060
30336
  const sessionId = string$3(item?.sessionId) || string$3(item?.id);
30061
30337
  if (sessionId === "" || item?.blank === true || archived.has(sessionId) || Number(item?.archivedAt) > 0) return [];
30062
30338
  const workspace = workspaces.find((entry) => array$1(entry?.sessionIds).includes(sessionId));
@@ -30064,7 +30340,7 @@ window.__ModuleLoader__.load({
30064
30340
  const hostId = require_primitives_adapter.parseVirtualSessionId(sessionId)?.hostId ?? require_primitives_adapter.parseVirtualWorkspaceId(workspaceId)?.hostId ?? "local";
30065
30341
  return [{
30066
30342
  sessionId,
30067
- title: string$3(record$1(record$1(item?.projections)?.values)?.title) || string$3(item?.title) || sessionId,
30343
+ title: string$3(record$2(record$2(item?.projections)?.values)?.title) || string$3(item?.title) || sessionId,
30068
30344
  workspaceId,
30069
30345
  hostId,
30070
30346
  workspaceTitle: string$3(workspace?.title) || string$3(workspace?.path) || workspaceId,
@@ -30075,7 +30351,7 @@ window.__ModuleLoader__.load({
30075
30351
  }
30076
30352
  /** 新建入口由菜单单独提供;已有会话只按更新时间排序,初始最多五项。 */
30077
30353
  function selectRecentTerminalShareTargets(targets, snapshot, sessionId, limit = 5) {
30078
- const workspace = array$1(record$1(snapshot)?.items).map(record$1).find((item) => array$1(item?.sessionIds).includes(sessionId));
30354
+ const workspace = array$1(record$2(snapshot)?.items).map(record$2).find((item) => array$1(item?.sessionIds).includes(sessionId));
30079
30355
  const workspaceId = string$3(workspace?.workspaceId) || targets.find((item) => item.sessionId === sessionId)?.workspaceId;
30080
30356
  const workspaceOrder = array$1(workspace?.sessionIds);
30081
30357
  return targets.filter((item) => workspaceId ? item.workspaceId === workspaceId : item.sessionId === sessionId).sort((left, right) => (right.updatedAt ?? 0) - (left.updatedAt ?? 0) || workspaceOrder.indexOf(left.sessionId) - workspaceOrder.indexOf(right.sessionId)).slice(0, Math.max(1, limit));
@@ -30085,8 +30361,8 @@ window.__ModuleLoader__.load({
30085
30361
  return Number.isFinite(time) ? time : 0;
30086
30362
  }
30087
30363
  function isArchivedSession(sessionId, snapshot) {
30088
- const state = record$1(snapshot);
30089
- return array$1(state?.archivedSessionIds).includes(sessionId) || array$1(state?.items).some((workspace) => array$1(record$1(workspace)?.archivedSessionIds).includes(sessionId));
30364
+ const state = record$2(snapshot);
30365
+ return array$1(state?.archivedSessionIds).includes(sessionId) || array$1(state?.items).some((workspace) => array$1(record$2(workspace)?.archivedSessionIds).includes(sessionId));
30090
30366
  }
30091
30367
  function service(context, name) {
30092
30368
  try {
@@ -30096,7 +30372,7 @@ window.__ModuleLoader__.load({
30096
30372
  return;
30097
30373
  }
30098
30374
  }
30099
- function record$1(value) {
30375
+ function record$2(value) {
30100
30376
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
30101
30377
  }
30102
30378
  function string$3(value) {
@@ -30106,8 +30382,8 @@ window.__ModuleLoader__.load({
30106
30382
  return Array.isArray(value) ? value : [];
30107
30383
  }
30108
30384
  function unwrap$1(value) {
30109
- const item = record$1(value);
30110
- if (item?.ok === false) throw new Error(string$3(record$1(item.error)?.message) || "读取会话列表失败");
30385
+ const item = record$2(value);
30386
+ if (item?.ok === false) throw new Error(string$3(record$2(item.error)?.message) || "读取会话列表失败");
30111
30387
  return item?.ok === true ? item.value : value;
30112
30388
  }
30113
30389
  //#endregion
@@ -30163,7 +30439,7 @@ window.__ModuleLoader__.load({
30163
30439
  const call = block?.kind === void 0 ? block : block.call;
30164
30440
  const args = parseRecord(call?.argsRaw);
30165
30441
  const questions = args?.questions;
30166
- if (!Array.isArray(questions) || !questions.every(isQuestion)) return void 0;
30442
+ if (!Array.isArray(questions) || !questions.every(isQuestion$1)) return void 0;
30167
30443
  const output = parseRecord(Array.isArray(block?.content) && block.content.length === 1 && block.content[0]?.type === "text" ? block.content[0].text : void 0);
30168
30444
  return {
30169
30445
  args,
@@ -30232,7 +30508,7 @@ window.__ModuleLoader__.load({
30232
30508
  return;
30233
30509
  }
30234
30510
  }
30235
- function isQuestion(value) {
30511
+ function isQuestion$1(value) {
30236
30512
  return value !== null && typeof value === "object" && typeof value.id === "string" && typeof value.question === "string" && (value.header === void 0 || typeof value.header === "string") && (value.detail === void 0 || typeof value.detail === "string") && (value.options === void 0 || Array.isArray(value.options) && value.options.every((o) => o !== null && typeof o?.label === "string" && (o.description === void 0 || typeof o.description === "string")));
30237
30513
  }
30238
30514
  function validAnswers(value) {
@@ -30546,6 +30822,311 @@ window.__ModuleLoader__.load({
30546
30822
  } };
30547
30823
  }
30548
30824
  //#endregion
30825
+ //#region src/dsh-capabilities/host/workspace-session-control-adapter.ts
30826
+ /** Narrow typed adapter over DSH's public SessionController surface. */
30827
+ function supportsWorkspaceSessionControl(context) {
30828
+ const controller = asController(readContext(context, "sessionController"));
30829
+ const agents = asRecord$10(readContext(context, "agents"));
30830
+ return controller !== void 0 && typeof controller.create === "function" && typeof controller.list === "function" && typeof controller.prompt === "function" && typeof controller.modelCatalog === "function" && typeof agents?.get === "function";
30831
+ }
30832
+ function createWorkspaceSessionControlAdapter(context) {
30833
+ const controller = asController(readContext(context, "sessionController"));
30834
+ if (!supportsWorkspaceSessionControl(context) || controller === void 0) throw new TypeError("DSH SessionController workspace control is unavailable");
30835
+ const agents = controller.agents;
30836
+ const agentRegistry = asRecord$10(readContext(context, "agents"));
30837
+ const llm = asRecord$10(readContext(context, "llm"));
30838
+ const selectModel = async (sessionId, selection, signal) => {
30839
+ signal.throwIfAborted();
30840
+ if (agents?.selectForNextRequest === void 0 || llm === void 0 || typeof llm.resolveCallConfig !== "function") throw new Error("Session-local DSH model selection is unavailable");
30841
+ if (controller.resolveAgent === void 0) throw new Error("DSH Session Agent resolution is unavailable");
30842
+ const found = asRecord$10(await controller.resolveAgent.call(controller, sessionId));
30843
+ if (found === void 0 || "error" in found || found.agent === void 0) throw new Error("DSH session Agent is unavailable for model selection");
30844
+ const resolved = asRecord$10(await llm.resolveCallConfig.call(llm, selection));
30845
+ if (typeof resolved?.provider !== "string" || typeof resolved.model !== "string") throw new Error("The requested DSH model route is unavailable");
30846
+ const liveAgent = (agentRegistry?.get)?.call(agentRegistry, sessionId);
30847
+ if (liveAgent === void 0 || liveAgent !== found.agent) throw new Error("DSH did not retain the selected Session Agent");
30848
+ agents.selectForNextRequest.call(agents, found.agent, {
30849
+ provider: resolved.provider,
30850
+ model: resolved.model,
30851
+ ...typeof resolved.reasoningEffort === "string" ? { reasoningEffort: resolved.reasoningEffort } : {}
30852
+ });
30853
+ return { selected: {
30854
+ provider: resolved.provider,
30855
+ model: resolved.model,
30856
+ ...typeof resolved.reasoningEffort === "string" ? { reasoningEffort: resolved.reasoningEffort } : {}
30857
+ } };
30858
+ };
30859
+ return {
30860
+ create: (request, signal) => {
30861
+ signal.throwIfAborted();
30862
+ return controller.create.call(controller, request);
30863
+ },
30864
+ list: (signal) => {
30865
+ signal.throwIfAborted();
30866
+ return controller.list.call(controller, {}, signal);
30867
+ },
30868
+ prompt: (request, signal) => controller.prompt.call(controller, request, signal),
30869
+ modelCatalog: () => controller.modelCatalog.call(controller),
30870
+ ...typeof controller.resolveAgent === "function" ? { prepareSession: async (sessionId, signal) => {
30871
+ signal.throwIfAborted();
30872
+ const result = asRecord$10(await controller.resolveAgent.call(controller, sessionId));
30873
+ if (result === void 0 || "error" in result || result.agent === void 0) throw new Error("DSH Session Agent could not be prepared");
30874
+ const liveAgent = (agentRegistry?.get)?.call(agentRegistry, sessionId);
30875
+ if (liveAgent === void 0 || liveAgent !== result.agent) throw new Error("DSH did not retain the prepared Session Agent");
30876
+ } } : {},
30877
+ ...typeof controller.agents?.selectForNextRequest === "function" && typeof llm?.resolveCallConfig === "function" ? { selectModel: async (sessionId, selection, signal) => await selectModel(sessionId, selection, signal) } : {}
30878
+ };
30879
+ }
30880
+ function asController(value) {
30881
+ return asRecord$10(value);
30882
+ }
30883
+ function readContext(context, name) {
30884
+ if (typeof context !== "object" || context === null || typeof context.get !== "function") return void 0;
30885
+ try {
30886
+ return context.get(name);
30887
+ } catch {
30888
+ return;
30889
+ }
30890
+ }
30891
+ function asRecord$10(value) {
30892
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
30893
+ }
30894
+ //#endregion
30895
+ //#region src/dsh-capabilities/host/workspace-pending-questions-adapter.ts
30896
+ function supportsWorkspacePendingQuestions(context) {
30897
+ const get = contextGet(context);
30898
+ return hasMethod$2(get?.("sessions"), "get") && hasMethod$2(get?.("agents"), "get") && hasMethod$2(get?.("agents"), "roots") && hasMethod$2(get?.("sessionProjections"), "stateOf") && hasMethod$2(get?.("userQuestions"), "answer");
30899
+ }
30900
+ function createWorkspacePendingQuestionsAdapter(context) {
30901
+ const get = contextGet(context);
30902
+ const sessions = get?.("sessions");
30903
+ const agents = get?.("agents");
30904
+ const projections = get?.("sessionProjections");
30905
+ const questions = get?.("userQuestions");
30906
+ if (!supportsWorkspacePendingQuestions(context) || !sessions || !agents || !projections || !questions) throw new TypeError("DSH pending questions capability is unavailable");
30907
+ return {
30908
+ list(sessionId) {
30909
+ let session;
30910
+ try {
30911
+ session = sessions.get(sessionId);
30912
+ } catch {
30913
+ return null;
30914
+ }
30915
+ if (session === void 0) return null;
30916
+ let agent;
30917
+ try {
30918
+ agent = agents.get(sessionId);
30919
+ } catch {
30920
+ return null;
30921
+ }
30922
+ if (agent === void 0 || record$1(agent)?.session !== session || !(agents.roots?.() ?? []).includes(agent)) return null;
30923
+ try {
30924
+ const userQuestions = record$1(record$1(projections.stateOf(session, "userQuestions"))?.questions);
30925
+ let active;
30926
+ try {
30927
+ active = userQuestions?.active;
30928
+ } catch {
30929
+ return null;
30930
+ }
30931
+ if (!Array.isArray(active)) return null;
30932
+ return active.flatMap((raw) => {
30933
+ const pending = record$1(raw);
30934
+ if (typeof pending?.callId !== "string" || pending.state !== "open" && pending.state !== "continued" || !Array.isArray(pending.questions)) return [];
30935
+ return [{
30936
+ callId: pending.callId,
30937
+ state: pending.state,
30938
+ questions: pending.questions.filter(isQuestion)
30939
+ }];
30940
+ });
30941
+ } catch {
30942
+ return null;
30943
+ }
30944
+ },
30945
+ answer(sessionId, callId, answer) {
30946
+ let agent;
30947
+ try {
30948
+ agent = agents.get(sessionId);
30949
+ } catch {
30950
+ return false;
30951
+ }
30952
+ let session;
30953
+ try {
30954
+ session = sessions.get(sessionId);
30955
+ } catch {
30956
+ return false;
30957
+ }
30958
+ if (agent === void 0 || session === void 0 || record$1(agent)?.session !== session || !(agents.roots?.() ?? []).includes(agent)) return false;
30959
+ try {
30960
+ return questions.answer(agent, callId, answer) === true;
30961
+ } catch {
30962
+ return false;
30963
+ }
30964
+ }
30965
+ };
30966
+ }
30967
+ function contextGet(context) {
30968
+ if (typeof context !== "object" || context === null || typeof context.get !== "function") return void 0;
30969
+ return context.get.bind(context);
30970
+ }
30971
+ function hasMethod$2(value, name) {
30972
+ return typeof value === "object" && value !== null && typeof value[name] === "function";
30973
+ }
30974
+ function record$1(value) {
30975
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
30976
+ }
30977
+ function isQuestion(value) {
30978
+ const item = record$1(value);
30979
+ return typeof item?.id === "string" && typeof item.question === "string";
30980
+ }
30981
+ //#endregion
30982
+ //#region src/dsh-capabilities/host/workspace-approval-adapter.ts
30983
+ function supportsWorkspaceApproval(context) {
30984
+ const nativeContext = asContext(context);
30985
+ const get = nativeContext?.get.bind(nativeContext);
30986
+ return nativeContext?.on !== void 0 && hasMethod$1(safeGet(get, "agents"), "get") && hasMethod$1(safeGet(get, "approval"), "request");
30987
+ }
30988
+ function createWorkspaceApprovalAdapter(context) {
30989
+ const nativeContext = asContext(context);
30990
+ const get = nativeContext?.get.bind(nativeContext);
30991
+ if (!supportsWorkspaceApproval(context)) throw new TypeError("DSH approval capability is unavailable");
30992
+ const activeRequests = /* @__PURE__ */ new Set();
30993
+ let disposed = false;
30994
+ return {
30995
+ dispose() {
30996
+ disposed = true;
30997
+ for (const cancel of activeRequests) cancel();
30998
+ activeRequests.clear();
30999
+ },
31000
+ startRequest(input) {
31001
+ if (disposed || input.signal.aborted) return null;
31002
+ const agents = safeGet(get, "agents");
31003
+ const approval = safeGet(get, "approval");
31004
+ if (agents === void 0 || approval === void 0) return null;
31005
+ let agent;
31006
+ try {
31007
+ agent = asAgent(agents.get(input.sessionId));
31008
+ } catch {
31009
+ return null;
31010
+ }
31011
+ if (agent?.status !== "running" || agent.session === void 0 || typeof agent.session.seq !== "number" || nativeContext?.on === void 0) return null;
31012
+ const startingSeq = agent.session.seq;
31013
+ const requestLifetime = new AbortController();
31014
+ let requestDisposed = false;
31015
+ let disposeTurnListener;
31016
+ let disposeApprovalListener;
31017
+ let approvalEvent;
31018
+ const abortRequest = () => requestLifetime.abort(input.signal.reason);
31019
+ const cleanup = () => {
31020
+ if (requestDisposed) return;
31021
+ requestDisposed = true;
31022
+ input.signal.removeEventListener("abort", abortRequest);
31023
+ requestLifetime.signal.removeEventListener("abort", cleanup);
31024
+ if (typeof disposeTurnListener === "function") disposeTurnListener();
31025
+ if (typeof disposeApprovalListener === "function") disposeApprovalListener();
31026
+ activeRequests.delete(abortRequest);
31027
+ };
31028
+ requestLifetime.signal.addEventListener("abort", cleanup, { once: true });
31029
+ if (input.signal.aborted) abortRequest();
31030
+ else input.signal.addEventListener("abort", abortRequest, { once: true });
31031
+ try {
31032
+ disposeTurnListener = nativeContext.on("session/event", (sessionValue, eventValue) => {
31033
+ const session = asRecord$9(sessionValue);
31034
+ const event = asRecord$9(eventValue);
31035
+ if ((typeof session?.id === "string" ? session.id : asRecord$9(session?.header)?.id) === input.sessionId && event?.type === "turn/end") requestLifetime.abort();
31036
+ }, { global: true });
31037
+ } catch {
31038
+ cleanup();
31039
+ return null;
31040
+ }
31041
+ if (typeof disposeTurnListener !== "function") {
31042
+ cleanup();
31043
+ return null;
31044
+ }
31045
+ activeRequests.add(abortRequest);
31046
+ try {
31047
+ disposeApprovalListener = nativeContext.on("session/event", (sessionValue, eventValue) => {
31048
+ const session = asRecord$9(sessionValue);
31049
+ const event = asRecord$9(eventValue);
31050
+ const data = asRecord$9(event?.data);
31051
+ const sessionId = typeof session?.id === "string" ? session.id : asRecord$9(session?.header)?.id;
31052
+ if (sessionId !== input.sessionId || event?.type !== "approval/asked" || event.seq !== startingSeq || typeof data?.id !== "string" || data.toolName !== input.toolName || data.callId !== input.callId || data.reason !== input.reason) return;
31053
+ approvalEvent = {
31054
+ sessionId,
31055
+ seq: startingSeq,
31056
+ id: data.id,
31057
+ toolName: data.toolName,
31058
+ ...typeof data.callId === "string" ? { callId: data.callId } : {},
31059
+ ...typeof data.reason === "string" ? { reason: data.reason } : {}
31060
+ };
31061
+ }, { global: true });
31062
+ } catch {
31063
+ cleanup();
31064
+ return null;
31065
+ }
31066
+ if (typeof disposeApprovalListener !== "function") {
31067
+ cleanup();
31068
+ return null;
31069
+ }
31070
+ let outcome;
31071
+ try {
31072
+ outcome = Promise.resolve(approval.request({
31073
+ agent,
31074
+ toolName: input.toolName,
31075
+ ...input.callId === void 0 ? {} : { callId: input.callId },
31076
+ ...input.reason === void 0 ? {} : { reason: input.reason },
31077
+ signal: requestLifetime.signal
31078
+ }));
31079
+ } catch {
31080
+ cleanup();
31081
+ return null;
31082
+ }
31083
+ disposeApprovalListener();
31084
+ disposeApprovalListener = void 0;
31085
+ const event = approvalEvent;
31086
+ if (event === void 0 || event.seq !== startingSeq || event.sessionId !== input.sessionId || event.toolName !== input.toolName || event.callId !== input.callId || event.reason !== input.reason) {
31087
+ cleanup();
31088
+ outcome.catch(() => void 0);
31089
+ return null;
31090
+ }
31091
+ let onCancellation;
31092
+ const cancelled = requestLifetime.signal.aborted ? Promise.resolve("cancelled") : new Promise((resolve) => {
31093
+ onCancellation = () => resolve("cancelled");
31094
+ requestLifetime.signal.addEventListener("abort", onCancellation, { once: true });
31095
+ });
31096
+ return {
31097
+ requestId: event.id,
31098
+ outcome: Promise.race([outcome.then((result) => isOutcome(result) ? result : "unavailable", () => requestLifetime.signal.aborted ? "cancelled" : "unavailable"), cancelled]).finally(() => {
31099
+ if (onCancellation !== void 0) requestLifetime.signal.removeEventListener("abort", onCancellation);
31100
+ cleanup();
31101
+ })
31102
+ };
31103
+ }
31104
+ };
31105
+ }
31106
+ function safeGet(get, name) {
31107
+ try {
31108
+ return get?.(name);
31109
+ } catch {
31110
+ return;
31111
+ }
31112
+ }
31113
+ function asContext(context) {
31114
+ if (typeof context !== "object" || context === null || typeof context.get !== "function") return void 0;
31115
+ return context;
31116
+ }
31117
+ function hasMethod$1(value, name) {
31118
+ return typeof value === "object" && value !== null && typeof value[name] === "function";
31119
+ }
31120
+ function asAgent(value) {
31121
+ return typeof value === "object" && value !== null ? value : void 0;
31122
+ }
31123
+ function asRecord$9(value) {
31124
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
31125
+ }
31126
+ function isOutcome(value) {
31127
+ return value === "allowed-once" || value === "rejected" || value === "cancelled" || value === "unavailable";
31128
+ }
31129
+ //#endregion
30549
31130
  //#region src/dsh-capabilities/host/session-prompt-adapter.ts
30550
31131
  function supportsSessionPromptAssembly(value) {
30551
31132
  const ctx = value;
@@ -31242,7 +31823,7 @@ window.__ModuleLoader__.load({
31242
31823
  for (const [capability, id] of [["plugin.update.inspect", "plugin-manager-inspect-021"], ["plugin.update.apply", "plugin-manager-install-021"]]) add({
31243
31824
  id,
31244
31825
  capability,
31245
- supportedDsh: ">=0.2.1-rc.2 <=0.2.1-rc.2",
31826
+ supportedDsh: ">=0.2.1-rc.2",
31246
31827
  runtime,
31247
31828
  priority: 10,
31248
31829
  status: "supported",
@@ -31264,7 +31845,7 @@ window.__ModuleLoader__.load({
31264
31845
  for (const role of ["member", "lead"]) add({
31265
31846
  id: `agent-team-external-${role}-021`,
31266
31847
  capability: `agent-team.external-${role}`,
31267
- supportedDsh: ">=0.2.1-alpha.2 <=0.2.1-rc.3",
31848
+ supportedDsh: ">=0.2.1-alpha.2",
31268
31849
  runtime,
31269
31850
  priority: 10,
31270
31851
  status: "supported",
@@ -31275,7 +31856,7 @@ window.__ModuleLoader__.load({
31275
31856
  add({
31276
31857
  id: "session-performance-projection-021",
31277
31858
  capability: "session.external-performance",
31278
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.3",
31859
+ supportedDsh: ">=0.2.1-alpha.3",
31279
31860
  runtime,
31280
31861
  priority: 10,
31281
31862
  status: "supported",
@@ -31319,7 +31900,7 @@ window.__ModuleLoader__.load({
31319
31900
  add({
31320
31901
  id: "session-prompt-assembly-021",
31321
31902
  capability: "session.prompt-assembly",
31322
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.3",
31903
+ supportedDsh: ">=0.2.1-alpha.3",
31323
31904
  runtime,
31324
31905
  priority: 10,
31325
31906
  status: "supported",
@@ -31330,7 +31911,7 @@ window.__ModuleLoader__.load({
31330
31911
  add({
31331
31912
  id: "session-external-model-selection-021",
31332
31913
  capability: "session.external-model-selection",
31333
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.3",
31914
+ supportedDsh: ">=0.2.1-alpha.3",
31334
31915
  runtime,
31335
31916
  priority: 10,
31336
31917
  status: "supported",
@@ -31352,7 +31933,7 @@ window.__ModuleLoader__.load({
31352
31933
  add({
31353
31934
  id: "session-activation-021",
31354
31935
  capability: "session.activation",
31355
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.3",
31936
+ supportedDsh: ">=0.2.1-alpha.3",
31356
31937
  runtime,
31357
31938
  priority: 10,
31358
31939
  status: "supported",
@@ -31360,10 +31941,43 @@ window.__ModuleLoader__.load({
31360
31941
  detect: (ctx) => hasMethods(read(ctx, "sessionController"), ["create", "resolveAgent"]),
31361
31942
  create: (ctx) => read(ctx, "sessionController")
31362
31943
  });
31944
+ add({
31945
+ id: "workspace-session-control-020",
31946
+ capability: "workspace.session-control",
31947
+ supportedDsh: range020,
31948
+ runtime,
31949
+ priority: 10,
31950
+ status: "supported",
31951
+ introducedIn: "0.2.0-rc.2",
31952
+ detect: supportsWorkspaceSessionControl,
31953
+ create: createWorkspaceSessionControlAdapter
31954
+ });
31955
+ add({
31956
+ id: "workspace-pending-questions-020",
31957
+ capability: "workspace.pending-questions",
31958
+ supportedDsh: range020,
31959
+ runtime,
31960
+ priority: 10,
31961
+ status: "supported",
31962
+ introducedIn: "0.2.0-rc.2",
31963
+ detect: supportsWorkspacePendingQuestions,
31964
+ create: createWorkspacePendingQuestionsAdapter
31965
+ });
31966
+ add({
31967
+ id: "workspace-approval-020",
31968
+ capability: "workspace.approval",
31969
+ supportedDsh: range020,
31970
+ runtime,
31971
+ priority: 10,
31972
+ status: "supported",
31973
+ introducedIn: "0.2.0-rc.2",
31974
+ detect: supportsWorkspaceApproval,
31975
+ create: createWorkspaceApprovalAdapter
31976
+ });
31363
31977
  for (const capability of ["connection.peer", "connection.uplink"]) add({
31364
31978
  id: `${capability}-021`,
31365
31979
  capability,
31366
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.3",
31980
+ supportedDsh: ">=0.2.1-alpha.3",
31367
31981
  runtime,
31368
31982
  priority: 40,
31369
31983
  status: "supported",
@@ -31481,7 +32095,7 @@ window.__ModuleLoader__.load({
31481
32095
  add({
31482
32096
  id: "session-performance-presentation-021",
31483
32097
  capability: "session.external-performance",
31484
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.3",
32098
+ supportedDsh: ">=0.2.1-alpha.3",
31485
32099
  runtime,
31486
32100
  priority: 10,
31487
32101
  status: "supported",
@@ -31514,7 +32128,7 @@ window.__ModuleLoader__.load({
31514
32128
  add({
31515
32129
  id: "message-presentation-021",
31516
32130
  capability: "conversation.message-presentation",
31517
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.3",
32131
+ supportedDsh: ">=0.2.1-alpha.3",
31518
32132
  runtime,
31519
32133
  priority: 10,
31520
32134
  status: "supported",
@@ -31835,7 +32449,7 @@ window.__ModuleLoader__.load({
31835
32449
  add({
31836
32450
  id: "conversation-draft-share-021",
31837
32451
  capability: "conversation.draft-share",
31838
- supportedDsh: ">=0.2.1-alpha.1 <=0.2.1-rc.3",
32452
+ supportedDsh: ">=0.2.1-alpha.1",
31839
32453
  runtime: "client",
31840
32454
  priority: 30,
31841
32455
  status: "supported",
@@ -34522,7 +35136,7 @@ window.__ModuleLoader__.load({
34522
35136
  }
34523
35137
  /** 只接受形如探测结果的载荷;字段缺失或类型不符时返回 null,而不是猜测“已安装”。 */
34524
35138
  function normalizeDetection(value) {
34525
- if (!isRecord$8(value)) return null;
35139
+ if (!isRecord$9(value)) return null;
34526
35140
  const { installed, source, command, version, reason, checkedAt, platform } = value;
34527
35141
  if (typeof installed !== "boolean" || typeof checkedAt !== "string") return null;
34528
35142
  if (platform !== "macos" && platform !== "windows" && platform !== "linux") return null;
@@ -34540,7 +35154,7 @@ window.__ModuleLoader__.load({
34540
35154
  checkedAt
34541
35155
  };
34542
35156
  }
34543
- function isRecord$8(value) {
35157
+ function isRecord$9(value) {
34544
35158
  return typeof value === "object" && value !== null && !Array.isArray(value);
34545
35159
  }
34546
35160
  //#endregion
@@ -36350,6 +36964,12 @@ window.__ModuleLoader__.load({
36350
36964
  const [dashboardLoading, setDashboardLoading] = (0, react.useState)(true);
36351
36965
  const [dashboardError, setDashboardError] = (0, react.useState)(false);
36352
36966
  const [dashboardIssue, setDashboardIssue] = (0, react.useState)(null);
36967
+ const [quotaPolicyPending, setQuotaPolicyPending] = (0, react.useState)(null);
36968
+ const [quotaPolicyFailed, setQuotaPolicyFailed] = (0, react.useState)(false);
36969
+ const [quotaResetTarget, setQuotaResetTarget] = (0, react.useState)(null);
36970
+ const [quotaResetPending, setQuotaResetPending] = (0, react.useState)(false);
36971
+ const [quotaResetResult, setQuotaResetResult] = (0, react.useState)(null);
36972
+ const [quotaResetFailed, setQuotaResetFailed] = (0, react.useState)(false);
36353
36973
  const [chartMetric, setChartMetric] = (0, react.useState)("calls");
36354
36974
  const [sessionSearch, setSessionSearch] = (0, react.useState)("");
36355
36975
  const [selectedSession, setSelectedSession] = (0, react.useState)(null);
@@ -36372,14 +36992,17 @@ window.__ModuleLoader__.load({
36372
36992
  const dashboardSequence = (0, react.useRef)(0);
36373
36993
  const requestSequence = (0, react.useRef)(0);
36374
36994
  const managementSequence = (0, react.useRef)(0);
36375
- const loadDashboard = (0, react.useCallback)(async (signal) => {
36995
+ const loadDashboard = (0, react.useCallback)(async (signal, force = false) => {
36376
36996
  const sequence = dashboardSequence.current + 1;
36377
36997
  dashboardSequence.current = sequence;
36378
36998
  setDashboardLoading(true);
36379
36999
  setDashboardError(false);
36380
37000
  setDashboardIssue(null);
36381
37001
  try {
36382
- const next = await callMagpieRpc(rpc, "usage/dashboard", { period }, signal);
37002
+ const next = await callMagpieRpc(rpc, "usage/dashboard", {
37003
+ period,
37004
+ ...force ? { force: true } : {}
37005
+ }, signal);
36383
37006
  if (signal.aborted || sequence !== dashboardSequence.current) return;
36384
37007
  setDashboard(next);
36385
37008
  const issue = next?.availabilityIssue ?? (next === null ? "host-rpc-outdated" : null);
@@ -36394,6 +37017,48 @@ window.__ModuleLoader__.load({
36394
37017
  if (!signal.aborted && sequence === dashboardSequence.current) setDashboardLoading(false);
36395
37018
  }
36396
37019
  }, [period, rpc]);
37020
+ const updateQuotaPolicy = (0, react.useCallback)(async (user, policy, enabled) => {
37021
+ if (quotaPolicyPending !== null) return;
37022
+ setQuotaPolicyPending(`${user}:${policy}`);
37023
+ setQuotaPolicyFailed(false);
37024
+ try {
37025
+ await callMagpieRpc(rpc, "usage/account/update", {
37026
+ user,
37027
+ policy,
37028
+ enabled
37029
+ });
37030
+ await loadDashboard(new AbortController().signal, true);
37031
+ } catch {
37032
+ setQuotaPolicyFailed(true);
37033
+ } finally {
37034
+ setQuotaPolicyPending(null);
37035
+ }
37036
+ }, [
37037
+ loadDashboard,
37038
+ quotaPolicyPending,
37039
+ rpc
37040
+ ]);
37041
+ const closeQuotaReset = () => {
37042
+ if (quotaResetPending) return;
37043
+ setQuotaResetTarget(null);
37044
+ setQuotaResetResult(null);
37045
+ setQuotaResetFailed(false);
37046
+ };
37047
+ const confirmQuotaReset = async () => {
37048
+ const target = quotaResetTarget;
37049
+ if (target === null || quotaResetPending) return;
37050
+ setQuotaResetPending(true);
37051
+ setQuotaResetFailed(false);
37052
+ try {
37053
+ const result = await callMagpieRpc(rpc, "usage/reset", { user: target.user });
37054
+ setQuotaResetResult(result.outcome);
37055
+ await loadDashboard(new AbortController().signal, true);
37056
+ } catch {
37057
+ setQuotaResetFailed(true);
37058
+ } finally {
37059
+ setQuotaResetPending(false);
37060
+ }
37061
+ };
36397
37062
  (0, react.useEffect)(() => {
36398
37063
  const controller = new AbortController();
36399
37064
  loadDashboard(controller.signal);
@@ -36726,8 +37391,30 @@ window.__ModuleLoader__.load({
36726
37391
  dashboard,
36727
37392
  loading: dashboardLoading,
36728
37393
  quotaView,
36729
- t
36730
- })));
37394
+ t,
37395
+ policyPending: quotaPolicyPending,
37396
+ policyFailed: quotaPolicyFailed,
37397
+ onPolicyChange: updateQuotaPolicy,
37398
+ onResetRequest: (quota) => {
37399
+ if (quota.user === null || quota.resets?.count === null || quota.resets?.count === void 0 || quota.resets.count <= 0) return;
37400
+ setQuotaResetTarget({
37401
+ user: quota.user,
37402
+ account: quota.alias ?? quota.name,
37403
+ count: quota.resets.count
37404
+ });
37405
+ setQuotaResetResult(null);
37406
+ setQuotaResetFailed(false);
37407
+ }
37408
+ })), quotaResetTarget !== null && (0, react.createElement)(MagpieQuotaResetDialog, {
37409
+ target: quotaResetTarget,
37410
+ pending: quotaResetPending,
37411
+ result: quotaResetResult,
37412
+ failed: quotaResetFailed,
37413
+ t,
37414
+ onCancel: closeQuotaReset,
37415
+ onConfirm: confirmQuotaReset,
37416
+ onClose: closeQuotaReset
37417
+ }));
36731
37418
  }
36732
37419
  function OverviewPage({ dashboard, loading, error, chartMetric, onChartMetricChange, t, onOpenSession }) {
36733
37420
  const [modelBreakdownMode, setModelBreakdownMode] = (0, react.useState)("aggregate");
@@ -37238,7 +37925,7 @@ window.__ModuleLoader__.load({
37238
37925
  fill: "currentColor"
37239
37926
  }));
37240
37927
  }
37241
- function QuotasPage({ dashboard, loading, quotaView = require_native_workspace_store.DEFAULT_SUBSCRIPTION_REPORT_SETTINGS.quotaView, t }) {
37928
+ function QuotasPage({ dashboard, loading, quotaView = require_native_workspace_store.DEFAULT_SUBSCRIPTION_REPORT_SETTINGS.quotaView, t, policyPending = null, policyFailed = false, onPolicyChange = () => void 0, onResetRequest = () => void 0 }) {
37242
37929
  const quotaUnavailable = dashboard?.quotaStatus !== "available";
37243
37930
  const quotas = dashboard?.quotas ?? [];
37244
37931
  const quotaHistory = dashboard?.quotaHistory ?? [];
@@ -37249,7 +37936,11 @@ window.__ModuleLoader__.load({
37249
37936
  key: group.provider,
37250
37937
  group,
37251
37938
  quotaView,
37252
- t
37939
+ t,
37940
+ policyPending,
37941
+ policyFailed,
37942
+ onPolicyChange,
37943
+ onResetRequest
37253
37944
  }))), (0, react.createElement)("section", { className: "codingns-magpie-panel codingns-magpie-history-panel" }, (0, react.createElement)("div", { className: "codingns-magpie-panel-head" }, (0, react.createElement)("div", void 0, (0, react.createElement)("h2", void 0, t("magpie.quotaHistory")), (0, react.createElement)("p", void 0, t("magpie.quotaHistoryNote")))), quotaHistory.length === 0 ? (0, react.createElement)("div", { className: "codingns-magpie-inline-empty" }, t(dashboard === null && loading ? "magpie.loading" : dashboard?.quotaHistoryStatus === "available" ? "magpie.noHistory" : "magpie.historyUnavailable")) : (0, react.createElement)("div", { className: "codingns-magpie-history-grid" }, ...quotaHistory.map((history) => (0, react.createElement)(QuotaHistoryCard, {
37254
37945
  key: `${history.provider}:${history.user ?? ""}`,
37255
37946
  history
@@ -37329,7 +38020,7 @@ window.__ModuleLoader__.load({
37329
38020
  * 同一厂商的多个账号(如 WorkBuddy 的 4 个)共用一张卡,避免每个账号各占一张卡导致
37330
38021
  * 同类账号被拆散在网格各处;单账号厂商的读法与改造前一致。
37331
38022
  */
37332
- function QuotaGroupCard({ group, quotaView = require_native_workspace_store.DEFAULT_SUBSCRIPTION_REPORT_SETTINGS.quotaView, t }) {
38023
+ function QuotaGroupCard({ group, quotaView = require_native_workspace_store.DEFAULT_SUBSCRIPTION_REPORT_SETTINGS.quotaView, t, policyPending, policyFailed, onPolicyChange, onResetRequest }) {
37333
38024
  const first = group.accounts[0];
37334
38025
  const [collapsed, setCollapsed] = (0, react.useState)(false);
37335
38026
  const multi = group.accounts.length > 1;
@@ -37351,6 +38042,10 @@ window.__ModuleLoader__.load({
37351
38042
  quota,
37352
38043
  quotaView,
37353
38044
  t,
38045
+ policyPending,
38046
+ policyFailed,
38047
+ onPolicyChange,
38048
+ onResetRequest,
37354
38049
  showHeading: multi
37355
38050
  })));
37356
38051
  }
@@ -37361,11 +38056,18 @@ window.__ModuleLoader__.load({
37361
38056
  * Sub2api 的钱包余额、按积分计量的 WorkBuddy)单独显示余额行,与 Magpie 原生卡片
37362
38057
  * 一致——过去这些账号只剩一条空进度条,余额被完全藏起来。
37363
38058
  */
37364
- function QuotaAccountSection({ quota, quotaView = require_native_workspace_store.DEFAULT_SUBSCRIPTION_REPORT_SETTINGS.quotaView, t, showHeading }) {
38059
+ function QuotaAccountSection({ quota, quotaView = require_native_workspace_store.DEFAULT_SUBSCRIPTION_REPORT_SETTINGS.quotaView, t, showHeading, policyPending, policyFailed, onPolicyChange, onResetRequest }) {
37365
38060
  const dailyValues = quota.daily.days.map((point) => point.used).filter((value) => value !== null);
37366
38061
  const balance = resolveQuotaAccountBalance(quota);
37367
38062
  const percentWindows = quota.windows.filter((window) => window.usedPercent !== null || window.remainingPercent !== null);
37368
- return (0, react.createElement)("div", { className: "codingns-magpie-quota-account-block" }, showHeading && (0, react.createElement)("div", { className: "codingns-magpie-quota-account-head" }, (0, react.createElement)("strong", void 0, quota.alias ?? quota.name), quota.user !== null && (0, react.createElement)("span", void 0, t("magpie.account", { account: quota.user })), quota.plan !== null && (0, react.createElement)("small", void 0, quota.plan)), !showHeading && quota.user !== null && (0, react.createElement)("div", { className: "codingns-magpie-quota-account" }, t("magpie.account", { account: quota.user })), balance !== null && (0, react.createElement)("div", { className: "codingns-magpie-quota-balance" }, (0, react.createElement)("span", { className: "codingns-magpie-quota-balance-label" }, t("magpie.balance")), (0, react.createElement)("strong", {
38063
+ return (0, react.createElement)("div", { className: "codingns-magpie-quota-account-block" }, showHeading && (0, react.createElement)("div", { className: "codingns-magpie-quota-account-head" }, (0, react.createElement)("strong", void 0, quota.alias ?? quota.name), quota.user !== null && (0, react.createElement)("span", void 0, t("magpie.account", { account: quota.user })), quota.plan !== null && (0, react.createElement)("small", void 0, quota.plan)), !showHeading && quota.user !== null && (0, react.createElement)("div", { className: "codingns-magpie-quota-account" }, t("magpie.account", { account: quota.user })), quota.provider.toLocaleLowerCase() === "codex" && (0, react.createElement)(MagpieQuotaControls, {
38064
+ quota,
38065
+ t,
38066
+ policyPending,
38067
+ policyFailed,
38068
+ onPolicyChange,
38069
+ onResetRequest
38070
+ }), balance !== null && (0, react.createElement)("div", { className: "codingns-magpie-quota-balance" }, (0, react.createElement)("span", { className: "codingns-magpie-quota-balance-label" }, t("magpie.balance")), (0, react.createElement)("strong", {
37369
38071
  className: balance.money ? "codingns-magpie-quota-balance-value is-money" : "codingns-magpie-quota-balance-value",
37370
38072
  title: balance.raw
37371
38073
  }, balance.text)), quota.windows.length === 0 ? balance === null && (0, react.createElement)("div", { className: "codingns-magpie-inline-empty" }, t("magpie.noLimit")) : percentWindows.length > 0 && percentWindows.map((window) => {
@@ -37379,6 +38081,84 @@ window.__ModuleLoader__.load({
37379
38081
  }, (0, react.createElement)("div", { className: "codingns-magpie-quota-window-head" }, (0, react.createElement)("strong", void 0, window.name), (0, react.createElement)("span", void 0, headline)), (0, react.createElement)("div", { className: "codingns-magpie-track quota-track" }, used === null || remaining === null ? null : (0, react.createElement)("span", { style: { width: `${Math.max(0, Math.min(100, barPercent ?? 0))}%` } })), (0, react.createElement)("div", { className: "codingns-magpie-quota-foot" }, (0, react.createElement)("span", void 0, window.amount !== null && window.limit !== null ? `${formatValue(window.amount)} / ${formatValue(window.limit)} ${window.unit ?? ""}` : window.display ?? ""), window.resetsAt !== null && (0, react.createElement)("span", void 0, t("magpie.resets", { time: formatTimestamp(window.resetsAt) }))));
37380
38082
  }), balance !== null && percentWindows.length === 0 && quota.windows.some((window) => window.resetsAt !== null) && (0, react.createElement)("div", { className: "codingns-magpie-quota-foot" }, ...quota.windows.filter((window) => window.resetsAt !== null).map((window) => (0, react.createElement)("span", { key: window.name }, t("magpie.resets", { time: formatTimestamp(window.resetsAt) })))), quota.daily.days.length > 1 && (0, react.createElement)("div", { className: "codingns-magpie-daily-chart" }, (0, react.createElement)(Sparkline, { values: dailyValues }), (0, react.createElement)("small", void 0, t("magpie.dailyUsage"))));
37381
38083
  }
38084
+ function MagpieQuotaControls({ quota, t, policyPending, policyFailed, onPolicyChange, onResetRequest }) {
38085
+ const user = quota.user;
38086
+ const resetCount = quota.resets?.count;
38087
+ const policyUnavailable = user === null || quota.policyStatus === "unavailable" || quota.autoReset === void 0 || quota.useCredits === void 0;
38088
+ return (0, react.createElement)("div", { className: "codingns-magpie-codex-controls" }, (0, react.createElement)("div", { className: "codingns-magpie-codex-reset-count" }, (0, react.createElement)("span", void 0, t("usage.magpieResetCountLabel")), (0, react.createElement)("strong", void 0, resetCount === null || resetCount === void 0 ? "—" : t("usage.magpieResetCount", { count: resetCount }))), policyUnavailable ? (0, react.createElement)("div", {
38089
+ className: "codingns-magpie-codex-unavailable",
38090
+ role: "status"
38091
+ }, t("magpie.codexPolicyUnavailable")) : quota.autoReset !== void 0 && (0, react.createElement)(MagpieQuotaPolicySwitch, {
38092
+ label: t("usage.magpieResetWhenWeek"),
38093
+ checked: quota.autoReset.week,
38094
+ pending: policyPending === `${user}:week`,
38095
+ disabled: policyPending !== null,
38096
+ onChange: (enabled) => onPolicyChange(user, "week", enabled)
38097
+ }), !policyUnavailable && quota.autoReset !== void 0 && (0, react.createElement)(MagpieQuotaPolicySwitch, {
38098
+ label: t("usage.magpieResetBeforeExpiry"),
38099
+ checked: quota.autoReset.expiring,
38100
+ pending: policyPending === `${user}:expiring`,
38101
+ disabled: policyPending !== null,
38102
+ onChange: (enabled) => onPolicyChange(user, "expiring", enabled)
38103
+ }), !policyUnavailable && quota.useCredits !== void 0 && (0, react.createElement)(MagpieQuotaPolicySwitch, {
38104
+ label: t("usage.magpieUseCredits"),
38105
+ checked: quota.useCredits,
38106
+ pending: policyPending === `${user}:credits`,
38107
+ disabled: policyPending !== null,
38108
+ onChange: (enabled) => onPolicyChange(user, "credits", enabled)
38109
+ }), policyFailed && (0, react.createElement)("div", {
38110
+ className: "codingns-magpie-codex-error",
38111
+ role: "alert"
38112
+ }, t("magpie.codexPolicyFailed")), user !== null && resetCount !== null && resetCount !== void 0 && (0, react.createElement)("button", {
38113
+ type: "button",
38114
+ className: "codingns-magpie-codex-reset-button",
38115
+ disabled: resetCount <= 0,
38116
+ onClick: () => onResetRequest(quota)
38117
+ }, t("usage.magpieUseReset")));
38118
+ }
38119
+ function MagpieQuotaPolicySwitch({ label, checked, pending, disabled, onChange }) {
38120
+ return (0, react.createElement)("button", {
38121
+ type: "button",
38122
+ role: "switch",
38123
+ "aria-checked": checked,
38124
+ disabled,
38125
+ "aria-busy": pending,
38126
+ className: "codingns-magpie-codex-policy",
38127
+ onClick: () => onChange(!checked)
38128
+ }, (0, react.createElement)("span", void 0, label), (0, react.createElement)("span", { className: `codingns-magpie-codex-switch${checked ? " is-on" : ""}` }, (0, react.createElement)("span")));
38129
+ }
38130
+ function MagpieQuotaResetDialog({ target, pending, result, failed, t, onCancel, onConfirm, onClose }) {
38131
+ const finished = result !== null || failed;
38132
+ const outcomeMessage = result === null ? null : t({
38133
+ reset: "usage.resetOutcomeReset",
38134
+ alreadyRedeemed: "usage.resetOutcomeAlreadyRedeemed",
38135
+ nothingToReset: "usage.resetOutcomeNothingToReset",
38136
+ noCredit: "usage.resetOutcomeNoCredit"
38137
+ }[result]);
38138
+ return (0, react.createElement)("div", {
38139
+ className: "codingns-magpie-codex-reset-overlay",
38140
+ role: "presentation",
38141
+ onMouseDown: (event) => {
38142
+ if (event.target === event.currentTarget && !pending) onCancel();
38143
+ }
38144
+ }, (0, react.createElement)("div", {
38145
+ className: "codingns-magpie-codex-reset-dialog",
38146
+ role: "dialog",
38147
+ "aria-modal": true,
38148
+ "aria-label": t("usage.resetDialogTitle")
38149
+ }, (0, react.createElement)("strong", void 0, t("usage.resetDialogTitle")), (0, react.createElement)("span", void 0, t("magpie.resetDialogAccount", { account: target.account })), (0, react.createElement)("span", { className: failed ? "is-error" : result === "reset" || result === "alreadyRedeemed" ? "is-success" : "" }, pending ? t("usage.resetDialogPending") : failed ? t("magpie.codexResetFailed") : outcomeMessage ?? t("magpie.resetDialogBody", { count: target.count })), (0, react.createElement)("div", { className: "codingns-magpie-codex-reset-actions" }, finished ? (0, react.createElement)("button", {
38150
+ type: "button",
38151
+ onClick: onClose
38152
+ }, t("usage.resetDialogClose")) : (0, react.createElement)("button", {
38153
+ type: "button",
38154
+ disabled: pending,
38155
+ onClick: onCancel
38156
+ }, t("usage.resetDialogCancel")), !finished && (0, react.createElement)("button", {
38157
+ type: "button",
38158
+ disabled: pending,
38159
+ onClick: onConfirm
38160
+ }, t("usage.resetDialogConfirm")))));
38161
+ }
37382
38162
  function QuotaHistoryCard({ history }) {
37383
38163
  return (0, react.createElement)("div", { className: "codingns-magpie-history-card" }, (0, react.createElement)("div", { className: "codingns-magpie-provider-inline" }, (0, react.createElement)(MagpieProviderLogo, {
37384
38164
  identities: [history.provider],
@@ -37689,6 +38469,13 @@ window.__ModuleLoader__.load({
37689
38469
  .codingns-magpie-quota-balance-label{flex:0 0 auto;color:var(--mp-muted);font-size:${require_theme.uiFontSize(13)}}
37690
38470
  .codingns-magpie-quota-balance-value{min-width:0;overflow:hidden;color:var(--mp-ink);font-size:${require_theme.uiFontSize(15)};font-weight:600;font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap}
37691
38471
  .codingns-magpie-quota-balance-value.is-money{font-size:${require_theme.uiFontSize(17)};letter-spacing:-.01em}
38472
+ .codingns-magpie-codex-controls{display:grid;gap:2px;margin:9px 0 10px;padding:8px 10px;border-top:.5px solid var(--mp-line);border-bottom:.5px solid var(--mp-line);background:color-mix(in srgb,var(--mp-layer) 45%,transparent)}
38473
+ .codingns-magpie-codex-reset-count{display:flex;align-items:center;justify-content:space-between;gap:8px;min-width:0;padding:2px 0 5px;color:var(--mp-muted);font-size:${require_theme.uiFontSize(12)}}.codingns-magpie-codex-reset-count strong{color:var(--mp-ink);font-size:${require_theme.uiFontSize(13)};font-variant-numeric:tabular-nums}
38474
+ .codingns-magpie-codex-policy{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;min-width:0;min-height:32px;padding:4px 0;border:0;background:transparent;color:var(--mp-muted);font:inherit;font-size:${require_theme.uiFontSize(12)};text-align:left;cursor:pointer}.codingns-magpie-codex-policy>span:first-child{min-width:0;line-height:1.4;overflow-wrap:anywhere}.codingns-magpie-codex-policy:disabled{opacity:.58;cursor:wait}.codingns-magpie-codex-policy:focus-visible,.codingns-magpie-codex-reset-button:focus-visible{outline:2px solid color-mix(in srgb,var(--mp-accent) 60%,transparent);outline-offset:2px}
38475
+ .codingns-magpie-codex-switch{display:grid;place-items:center;flex:0 0 34px;width:34px;height:20px;padding:2px;border-radius:999px;background:var(--mp-line-strong);transition:background .15s}.codingns-magpie-codex-switch>span{justify-self:start;width:16px;height:16px;border-radius:50%;background:var(--mp-surface);box-shadow:0 1px 2px rgba(0,0,0,.18);transition:transform .15s}.codingns-magpie-codex-switch.is-on{background:var(--mp-accent)}.codingns-magpie-codex-switch.is-on>span{transform:translateX(14px)}
38476
+ .codingns-magpie-codex-unavailable,.codingns-magpie-codex-error{padding:5px 0;color:var(--mp-caption);font-size:${require_theme.uiFontSize(12)}}.codingns-magpie-codex-error{color:var(--dsw-alias-state-error-primary,#c54b4b)}
38477
+ .codingns-magpie-codex-reset-button{justify-self:start;min-height:27px;margin-top:4px;padding:0 9px;border:.5px solid var(--mp-line-strong);border-radius:var(--dsw-radius-sm,6px);background:transparent;color:var(--mp-ink);font:inherit;font-size:${require_theme.uiFontSize(12)};cursor:pointer}.codingns-magpie-codex-reset-button:hover:not(:disabled){border-color:var(--mp-accent);color:var(--mp-accent)}.codingns-magpie-codex-reset-button:disabled{opacity:.45;cursor:not-allowed}
38478
+ .codingns-magpie-codex-reset-overlay{position:absolute;inset:0;z-index:30;display:flex;align-items:center;justify-content:center;overflow:auto;padding:20px;background:color-mix(in srgb,var(--mp-surface) 70%,rgba(0,0,0,.3));backdrop-filter:blur(2px)}.codingns-magpie-codex-reset-dialog{display:grid;gap:10px;width:min(420px,100%);padding:16px;border:.5px solid var(--mp-line-strong);border-radius:var(--mp-radius);background:var(--mp-surface);box-shadow:var(--dsw-elevation-prominent,0 16px 44px rgba(0,0,0,.2));font-size:${require_theme.uiFontSize(13)};line-height:1.5}.codingns-magpie-codex-reset-dialog>strong{font-size:${require_theme.uiFontSize(14)}}.codingns-magpie-codex-reset-dialog>span{color:var(--mp-muted);overflow-wrap:anywhere}.codingns-magpie-codex-reset-dialog>span.is-error{color:var(--dsw-alias-state-error-primary,#c54b4b)}.codingns-magpie-codex-reset-dialog>span.is-success{color:var(--dsw-alias-state-success-primary,#3f9d6b)}.codingns-magpie-codex-reset-actions{display:flex;justify-content:flex-end;gap:8px;padding-top:3px}.codingns-magpie-codex-reset-actions button{min-height:30px;padding:0 11px;border:.5px solid var(--mp-line-strong);border-radius:var(--dsw-radius-sm,6px);background:transparent;color:var(--mp-ink);font:inherit;font-size:${require_theme.uiFontSize(12)};cursor:pointer}.codingns-magpie-codex-reset-actions button:last-child{border-color:var(--mp-accent);background:var(--mp-accent);color:var(--dsw-alias-label-primary-foreground,#fff)}.codingns-magpie-codex-reset-actions button:disabled{opacity:.5;cursor:wait}
37692
38479
  .codingns-magpie-quota-window{padding:11px 0;border-top:.5px solid var(--mp-line)}.codingns-magpie-quota-window-head,.codingns-magpie-quota-foot,.codingns-magpie-history-line-head{display:flex;align-items:center;justify-content:space-between;gap:9px}.codingns-magpie-quota-window-head{font-size:${require_theme.uiFontSize(13)};font-weight:500}.codingns-magpie-quota-window-head span{color:var(--mp-muted);font-variant-numeric:tabular-nums}.quota-track{height:6px}.quota-track span{background:linear-gradient(90deg,var(--mp-accent),color-mix(in srgb,var(--mp-accent) 55%,transparent))}.codingns-magpie-quota-foot{color:var(--mp-caption);font-size:${require_theme.uiFontSize(12)}}
37693
38480
  .codingns-magpie-daily-chart{display:grid;grid-template-columns:1fr auto;align-items:center;gap:9px;margin-top:4px;padding-top:10px;border-top:.5px solid var(--mp-line);color:var(--mp-muted);font-size:${require_theme.uiFontSize(12)}}.codingns-magpie-sparkline{width:100%;height:30px;overflow:visible}.codingns-magpie-sparkline polyline{stroke:var(--mp-accent);stroke-width:2;vector-effect:non-scaling-stroke}
37694
38481
  .codingns-magpie-history-panel{padding:17px;margin-top:14px}.codingns-magpie-history-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px}.codingns-magpie-history-card{padding:12px;border:1px solid var(--mp-line);border-radius:9px;background:var(--mp-card)}.codingns-magpie-history-card>strong,.codingns-magpie-history-card>small{display:block}.codingns-magpie-history-card>strong{font-size:${require_theme.uiFontSize(13)};font-weight:600}.codingns-magpie-history-card>small{margin-top:3px;color:var(--mp-caption);font-size:${require_theme.uiFontSize(12)}}.codingns-magpie-history-line{margin-top:10px}.codingns-magpie-history-line-head{font-size:${require_theme.uiFontSize(12)}}.codingns-magpie-history-line-head span:last-child{font-variant-numeric:tabular-nums;font-weight:650}
@@ -38454,7 +39241,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
38454
39241
  const fiberKey = Object.getOwnPropertyNames(row).find((key) => key.startsWith("__reactFiber$"));
38455
39242
  if (fiberKey === void 0) return void 0;
38456
39243
  let current = carrier[fiberKey];
38457
- for (let depth = 0; depth < 32 && isRecord$7(current); depth += 1) {
39244
+ for (let depth = 0; depth < 32 && isRecord$8(current); depth += 1) {
38458
39245
  const fiber = current;
38459
39246
  const sessionId = sessionIdFromProps(fiber.memoizedProps) ?? sessionIdFromProps(fiber.pendingProps);
38460
39247
  if (sessionId !== void 0) return sessionId;
@@ -38462,15 +39249,15 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
38462
39249
  }
38463
39250
  }
38464
39251
  function sessionIdFromProps(value) {
38465
- if (!isRecord$7(value)) return void 0;
39252
+ if (!isRecord$8(value)) return void 0;
38466
39253
  for (const key of ["node", "result"]) {
38467
39254
  const candidate = value[key];
38468
- if (!isRecord$7(candidate) || typeof candidate.id !== "string") continue;
39255
+ if (!isRecord$8(candidate) || typeof candidate.id !== "string") continue;
38469
39256
  const sessionId = candidate.id.trim();
38470
39257
  if (sessionId !== "") return sessionId;
38471
39258
  }
38472
39259
  }
38473
- function isRecord$7(value) {
39260
+ function isRecord$8(value) {
38474
39261
  return typeof value === "object" && value !== null && !Array.isArray(value);
38475
39262
  }
38476
39263
  //#endregion
@@ -38833,7 +39620,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
38833
39620
  }
38834
39621
  function findWorkspaceIdInFiber(value) {
38835
39622
  let current = value;
38836
- for (let depth = 0; depth < 24 && isRecord$6(current); depth += 1) {
39623
+ for (let depth = 0; depth < 24 && isRecord$7(current); depth += 1) {
38837
39624
  for (const props of [current.memoizedProps, current.pendingProps]) {
38838
39625
  const id = findWorkspaceIdInProps(props);
38839
39626
  if (id !== void 0) return id;
@@ -38842,7 +39629,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
38842
39629
  }
38843
39630
  }
38844
39631
  function findWorkspaceIdInProps(value) {
38845
- if (!isRecord$6(value)) return void 0;
39632
+ if (!isRecord$7(value)) return void 0;
38846
39633
  for (const key of ["workspaceId", "workspaceID"]) {
38847
39634
  const id = readString$1(value[key]);
38848
39635
  if (id !== void 0) return id;
@@ -39294,7 +40081,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
39294
40081
  dom.querySelector(`[${WORKSPACE_SESSION_ARCHIVE_MODAL_ATTRIBUTE}]`)?.remove();
39295
40082
  }
39296
40083
  function normalizeRemote(value) {
39297
- if (!isRecord$6(value)) return {};
40084
+ if (!isRecord$7(value)) return {};
39298
40085
  const workspace = asRecord$7(readRemoteProperty(value, "workspace")) ?? asRecord$7(readRemoteProperty(value, "workspaceController"));
39299
40086
  const session = asRecord$7(readRemoteProperty(value, "session")) ?? asRecord$7(readRemoteProperty(value, "sessionController"));
39300
40087
  return {
@@ -39320,7 +40107,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
39320
40107
  }) : [];
39321
40108
  }
39322
40109
  function asRecord$7(value) {
39323
- return isRecord$6(value) ? value : void 0;
40110
+ return isRecord$7(value) ? value : void 0;
39324
40111
  }
39325
40112
  /** DSH Remote 的直接调用返回 RemoteResult;测试桩和旧宿主可能直接返回 value。 */
39326
40113
  function unwrapRemoteValue$1(value) {
@@ -39328,7 +40115,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
39328
40115
  if (record === void 0 || typeof record.ok !== "boolean") return value;
39329
40116
  return record.ok ? record.value : void 0;
39330
40117
  }
39331
- function isRecord$6(value) {
40118
+ function isRecord$7(value) {
39332
40119
  return typeof value === "object" && value !== null && !Array.isArray(value);
39333
40120
  }
39334
40121
  //#endregion
@@ -40436,6 +41223,8 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
40436
41223
  const [resetPending, setResetPending] = (0, react.useState)(false);
40437
41224
  const [resetResult, setResetResult] = (0, react.useState)(null);
40438
41225
  const [resetError, setResetError] = (0, react.useState)(null);
41226
+ const [resetTargetUser, setResetTargetUser] = (0, react.useState)(null);
41227
+ const [magpiePolicyPending, setMagpiePolicyPending] = (0, react.useState)(null);
40439
41228
  const sessionRef = (0, react.useRef)(void 0);
40440
41229
  const routeKeyRef = (0, react.useRef)(null);
40441
41230
  const modelSelectionRevision = props.useSession?.((value) => JSON.stringify([value.modelSelection, value.running]));
@@ -40650,20 +41439,22 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
40650
41439
  setResetOpen(false);
40651
41440
  setResetResult(null);
40652
41441
  setResetError(null);
41442
+ setResetTargetUser(null);
40653
41443
  };
40654
41444
  const confirmReset = () => {
40655
- if (resetPending || adapterId === null) return;
41445
+ if (resetPending) return;
40656
41446
  setResetPending(true);
40657
41447
  setResetError(null);
40658
41448
  (async () => {
40659
41449
  try {
40660
- const result = await require_magpie_model_tag.callCliRpc(props.rpc, "subscription/reset", {
41450
+ const result = resetTargetUser === null ? adapterId === null ? null : await require_magpie_model_tag.callCliRpc(props.rpc, "subscription/reset", {
40661
41451
  sessionId: props.sessionId?.trim() ?? "",
40662
41452
  adapterId,
40663
41453
  ...providerId === null ? {} : { providerId }
40664
- });
41454
+ }) : await require_magpie_model_tag.callCliRpc(props.rpc, "magpie/usage/reset", { user: resetTargetUser });
41455
+ if (result === null) throw new Error(t("usage.resetFailed"));
40665
41456
  setResetResult(result.outcome);
40666
- invalidateSubscriptionUsageCache(subscriptionUsageCache, adapterId, providerId);
41457
+ if (adapterId !== null) invalidateSubscriptionUsageCache(subscriptionUsageCache, adapterId, providerId);
40667
41458
  await refreshRef.current?.();
40668
41459
  } catch (error) {
40669
41460
  setResetError(error instanceof Error ? error.message : "");
@@ -40672,6 +41463,23 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
40672
41463
  }
40673
41464
  })();
40674
41465
  };
41466
+ const requestMagpieReset = (user) => {
41467
+ setOpen(false);
41468
+ setResetResult(null);
41469
+ setResetError(null);
41470
+ setResetTargetUser(user);
41471
+ setResetOpen(true);
41472
+ };
41473
+ const updateMagpiePolicy = (user, policy, enabled) => {
41474
+ const key = `${user}:${policy}`;
41475
+ if (magpiePolicyPending !== null) return;
41476
+ setMagpiePolicyPending(key);
41477
+ require_magpie_model_tag.callCliRpc(props.rpc, "magpie/usage/account/update", {
41478
+ user,
41479
+ policy,
41480
+ enabled
41481
+ }).then(() => refreshRef.current?.()).catch(() => void 0).finally(() => setMagpiePolicyPending(null));
41482
+ };
40675
41483
  useDismissOnOutsidePointer(rootRef, open, () => setOpen(false), { portal: magpieRequestsDialogRef });
40676
41484
  useDismissOnOutsidePointer(resetDialogRef, resetOpen && !resetPending, closeResetDialog);
40677
41485
  if (!eligible || snapshot === null) return null;
@@ -40679,6 +41487,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
40679
41487
  const magpie = snapshot.magpie;
40680
41488
  const readout = resolveMagpieTriggerReadout(magpie);
40681
41489
  const label = t("usage.magpieUsageLabel");
41490
+ const resetCount = resetTargetUser === null ? 0 : magpie.quotas.find((quota) => quota.provider === "codex" && quota.user?.toLocaleLowerCase() === resetTargetUser.toLocaleLowerCase())?.resets?.count ?? 0;
40682
41491
  return (0, react.createElement)("div", {
40683
41492
  ref: rootRef,
40684
41493
  style: subscriptionRootStyle
@@ -40702,6 +41511,9 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
40702
41511
  rpc: props.rpc,
40703
41512
  usage: magpie,
40704
41513
  t,
41514
+ onPolicyChange: updateMagpiePolicy,
41515
+ policyPending: magpiePolicyPending,
41516
+ onResetRequest: requestMagpieReset,
40705
41517
  tab: magpieTab,
40706
41518
  onTabChange: setMagpieTab,
40707
41519
  expandedGroups: expandedQuotaGroups,
@@ -40709,6 +41521,16 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
40709
41521
  placement: magpiePlacement,
40710
41522
  popoverRef: magpiePopoverRef,
40711
41523
  requestsDialogRef: magpieRequestsDialogRef
41524
+ }), resetOpen && resetTargetUser !== null && (0, react.createElement)(ResetConfirmDialog, {
41525
+ count: resetCount,
41526
+ pending: resetPending,
41527
+ result: resetResult,
41528
+ error: resetError,
41529
+ t,
41530
+ onCancel: closeResetDialog,
41531
+ onConfirm: confirmReset,
41532
+ onClose: closeResetDialog,
41533
+ dialogRef: resetDialogRef
40712
41534
  }));
40713
41535
  }
40714
41536
  const usage = snapshot.providerUsage;
@@ -40753,6 +41575,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
40753
41575
  setOpen(false);
40754
41576
  setResetResult(null);
40755
41577
  setResetError(null);
41578
+ setResetTargetUser(null);
40756
41579
  setResetOpen(true);
40757
41580
  }
40758
41581
  } : null;
@@ -40840,7 +41663,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
40840
41663
  dialogRef: resetDialogRef
40841
41664
  }));
40842
41665
  }
40843
- function MagpieUsagePopover({ rpc, usage, t, tab = "usage", onTabChange = () => {}, expandedGroups = [], onToggleGroup = () => {}, placement = {
41666
+ function MagpieUsagePopover({ rpc, usage, t, onPolicyChange = () => {}, policyPending = null, onResetRequest = () => {}, tab = "usage", onTabChange = () => {}, expandedGroups = [], onToggleGroup = () => {}, placement = {
40844
41667
  left: 0,
40845
41668
  width: 400
40846
41669
  }, popoverRef, requestsDialogRef }) {
@@ -40911,7 +41734,10 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
40911
41734
  usage,
40912
41735
  aggregateRows,
40913
41736
  sessionRows,
40914
- t
41737
+ t,
41738
+ onPolicyChange,
41739
+ policyPending,
41740
+ onResetRequest
40915
41741
  }) : MagpieRoutePanel({
40916
41742
  rpc,
40917
41743
  usage,
@@ -40922,11 +41748,56 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
40922
41748
  ...requestsDialogRef === void 0 ? {} : { requestsDialogRef }
40923
41749
  })));
40924
41750
  }
40925
- function MagpieUsagePanel({ usage, aggregateRows, sessionRows, t }) {
41751
+ function MagpieUsagePanel({ usage, aggregateRows, sessionRows, t, onPolicyChange = () => {}, policyPending = null, onResetRequest = () => {} }) {
41752
+ const policyQuotas = [...usage.quotas ?? [], ...usage.providerAccounts ?? []].filter((quota) => quota.provider === "codex" && quota.user !== null && (quota.autoReset !== void 0 || quota.useCredits !== void 0 || quota.resets !== void 0)).filter((quota, index, rows) => rows.findIndex((item) => item.user?.toLocaleLowerCase() === quota.user?.toLocaleLowerCase()) === index);
40926
41753
  return (0, react.createElement)("div", void 0, (0, react.createElement)("section", { style: magpieUsageSectionStyle }, (0, react.createElement)("strong", { style: magpieSectionTitleStyle }, t("usage.magpieAggregateTitle")), usage.usageStatus === "available" ? createMagpieRows(aggregateRows) : (0, react.createElement)("div", { style: magpieMutedTextStyle }, t("usage.magpieUsageUnavailable"))), (0, react.createElement)("section", { style: magpieUsageSectionStyle }, (0, react.createElement)("strong", { style: magpieSectionTitleStyle }, t(usage.sessionPeriod === "today" ? "usage.magpieSessionTodayTitle" : "usage.magpieSessionTitle")), usage.sessionId !== null && (0, react.createElement)("div", { style: magpieSessionIdentityStyle }, (0, react.createElement)("div", { style: magpieSessionNameRowStyle }, (0, react.createElement)("span", { style: { flex: "none" } }, t("usage.magpieAgent", { agent: usage.agent })), usage.sessionName !== void 0 && (0, react.createElement)("strong", {
40927
41754
  style: magpieSessionNameStyle,
40928
41755
  title: usage.sessionName
40929
- }, usage.sessionName)), (0, react.createElement)("code", { style: magpieSessionIdStyle }, usage.sessionId)), usage.session === null ? (0, react.createElement)("div", { style: magpieMutedTextStyle }, usage.sessionId === null ? t("usage.magpieSessionIdUnavailable") : t("usage.magpieSessionNoUsage")) : createMagpieRows(sessionRows)));
41756
+ }, usage.sessionName)), (0, react.createElement)("code", { style: magpieSessionIdStyle }, usage.sessionId)), usage.session === null ? (0, react.createElement)("div", { style: magpieMutedTextStyle }, usage.sessionId === null ? t("usage.magpieSessionIdUnavailable") : t("usage.magpieSessionNoUsage")) : createMagpieRows(sessionRows)), policyQuotas.length > 0 && (0, react.createElement)("section", { style: magpieUsageSectionStyle }, (0, react.createElement)("strong", { style: magpieSectionTitleStyle }, t("usage.magpieAccountPolicies")), ...policyQuotas.map((quota, index) => createMagpieAccountPolicyCard(quota, t, index, onPolicyChange, policyPending, onResetRequest))));
41757
+ }
41758
+ function createMagpieAccountPolicyCard(quota, t, index, onPolicyChange, policyPending, onResetRequest) {
41759
+ const user = quota.user ?? "";
41760
+ const resetCount = quota.resets?.count;
41761
+ return (0, react.createElement)("div", {
41762
+ key: `codex-policy:${user}:${index}`,
41763
+ style: magpieAccountPolicyCardStyle
41764
+ }, (0, react.createElement)("div", { style: magpieAccountPolicyHeadingStyle }, (0, react.createElement)("strong", { title: user }, user), resetCount !== null && resetCount !== void 0 && (0, react.createElement)("span", { style: magpieHeaderMutedStyle }, t("usage.magpieResetCount", { count: resetCount }))), quota.autoReset !== void 0 && (0, react.createElement)(MagpiePolicySwitch, {
41765
+ label: t("usage.magpieResetWhenWeek"),
41766
+ checked: quota.autoReset.week,
41767
+ pending: policyPending === `${user}:week`,
41768
+ onChange: (enabled) => onPolicyChange(user, "week", enabled)
41769
+ }), quota.autoReset !== void 0 && (0, react.createElement)(MagpiePolicySwitch, {
41770
+ label: t("usage.magpieResetBeforeExpiry"),
41771
+ checked: quota.autoReset.expiring,
41772
+ pending: policyPending === `${user}:expiring`,
41773
+ onChange: (enabled) => onPolicyChange(user, "expiring", enabled)
41774
+ }), quota.useCredits !== void 0 && (0, react.createElement)(MagpiePolicySwitch, {
41775
+ label: t("usage.magpieUseCredits"),
41776
+ checked: quota.useCredits,
41777
+ pending: policyPending === `${user}:credits`,
41778
+ onChange: (enabled) => onPolicyChange(user, "credits", enabled)
41779
+ }), resetCount !== null && resetCount !== void 0 && (0, react.createElement)("button", {
41780
+ type: "button",
41781
+ disabled: resetCount <= 0,
41782
+ onClick: () => onResetRequest(user),
41783
+ style: require_theme.dshSettingsButtonStyle
41784
+ }, t("usage.magpieUseReset")));
41785
+ }
41786
+ function MagpiePolicySwitch({ label, checked, pending, onChange }) {
41787
+ return (0, react.createElement)("button", {
41788
+ type: "button",
41789
+ role: "switch",
41790
+ "aria-checked": checked,
41791
+ disabled: pending,
41792
+ onClick: () => onChange(!checked),
41793
+ style: magpiePolicySwitchStyle
41794
+ }, (0, react.createElement)("span", void 0, label), (0, react.createElement)("span", { style: {
41795
+ ...magpiePolicySwitchTrackStyle,
41796
+ ...checked ? magpiePolicySwitchOnStyle : {}
41797
+ } }, (0, react.createElement)("span", { style: {
41798
+ ...magpiePolicySwitchThumbStyle,
41799
+ ...checked ? magpiePolicySwitchThumbOnStyle : {}
41800
+ } })));
40930
41801
  }
40931
41802
  function magpieQuotaUnavailableMessage(usage, quotas, t) {
40932
41803
  return usage.quotaStatus === "unavailable" ? t("usage.magpieQuotaUnavailable") : usage.quotaStatus === "provider-unavailable" ? t("usage.magpieQuotaProviderUnavailable") : quotas.length === 0 ? t("usage.magpieQuotaNoData") : null;
@@ -41161,7 +42032,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
41161
42032
  }, signal);
41162
42033
  if (!result.ok) throw new Error(result.error.message);
41163
42034
  const value = result.value;
41164
- return isRecord$5(value) && Array.isArray(value.items) ? value : null;
42035
+ return isRecord$6(value) && Array.isArray(value.items) ? value : null;
41165
42036
  }
41166
42037
  /**
41167
42038
  * 请求模态框:外壳(遮罩、标题、关闭)由弹层提供,明细直接复用管理页的请求用量视图。
@@ -41250,17 +42121,17 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
41250
42121
  }
41251
42122
  function normalizeSubscriptionSnapshot(value) {
41252
42123
  if (value === null || value === void 0) return null;
41253
- if (!isRecord$5(value)) return null;
42124
+ if (!isRecord$6(value)) return null;
41254
42125
  if ("providerUsage" in value || "magpie" in value) return {
41255
- providerUsage: isRecord$5(value.providerUsage) ? value.providerUsage : null,
41256
- magpie: isRecord$5(value.magpie) ? value.magpie : null
42126
+ providerUsage: isRecord$6(value.providerUsage) ? value.providerUsage : null,
42127
+ magpie: isRecord$6(value.magpie) ? value.magpie : null
41257
42128
  };
41258
42129
  return {
41259
42130
  providerUsage: value,
41260
42131
  magpie: null
41261
42132
  };
41262
42133
  }
41263
- function isRecord$5(value) {
42134
+ function isRecord$6(value) {
41264
42135
  return typeof value === "object" && value !== null && !Array.isArray(value);
41265
42136
  }
41266
42137
  function SubscriptionPopover({ usage, providerName, t, nowMs, reset }) {
@@ -42088,6 +42959,60 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
42088
42959
  marginTop: 7,
42089
42960
  borderTop: `1px solid ${require_theme.dshThemeColor.border}`
42090
42961
  };
42962
+ const magpieAccountPolicyCardStyle = {
42963
+ display: "grid",
42964
+ gap: 5,
42965
+ marginTop: 7,
42966
+ padding: "8px 9px",
42967
+ border: `1px solid ${require_theme.dshThemeColor.border}`,
42968
+ borderRadius: 9,
42969
+ background: require_theme.dshThemeColor.surfaceSubtle
42970
+ };
42971
+ const magpieAccountPolicyHeadingStyle = {
42972
+ display: "flex",
42973
+ justifyContent: "space-between",
42974
+ alignItems: "baseline",
42975
+ gap: 8,
42976
+ minWidth: 0,
42977
+ fontSize: require_theme.uiFontSize(12)
42978
+ };
42979
+ const magpiePolicySwitchStyle = {
42980
+ display: "flex",
42981
+ alignItems: "center",
42982
+ justifyContent: "space-between",
42983
+ gap: 8,
42984
+ width: "100%",
42985
+ padding: "2px 0",
42986
+ border: 0,
42987
+ background: "transparent",
42988
+ color: require_theme.dshThemeColor.labelSecondary,
42989
+ fontFamily: "inherit",
42990
+ fontSize: require_theme.uiFontSize(11),
42991
+ lineHeight: "15px",
42992
+ textAlign: "left",
42993
+ cursor: "pointer"
42994
+ };
42995
+ const magpiePolicySwitchTrackStyle = {
42996
+ display: "inline-flex",
42997
+ alignItems: "center",
42998
+ flex: "none",
42999
+ width: 28,
43000
+ height: 16,
43001
+ padding: 2,
43002
+ boxSizing: "border-box",
43003
+ borderRadius: 999,
43004
+ background: require_theme.dshThemeColor.border,
43005
+ transition: "background .15s ease"
43006
+ };
43007
+ const magpiePolicySwitchOnStyle = { background: require_theme.dshThemeColor.accent };
43008
+ const magpiePolicySwitchThumbStyle = {
43009
+ width: 12,
43010
+ height: 12,
43011
+ borderRadius: "50%",
43012
+ background: require_theme.dshThemeColor.menuBackground,
43013
+ transition: "transform .15s ease"
43014
+ };
43015
+ const magpiePolicySwitchThumbOnStyle = { transform: "translateX(12px)" };
42091
43016
  const magpieStatsGridStyle = {
42092
43017
  display: "grid",
42093
43018
  gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
@@ -44003,7 +44928,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
44003
44928
  existing?.remove();
44004
44929
  continue;
44005
44930
  }
44006
- if (existing?.dataset.modelId === model.id) {
44931
+ if (existing?.dataset.modelId === model.id && existing.dataset.providerId === model.magpieProviderId) {
44007
44932
  if (row.children[row.children.length - 1] !== existing) {
44008
44933
  existing.remove();
44009
44934
  row.append(existing);
@@ -44011,7 +44936,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
44011
44936
  continue;
44012
44937
  }
44013
44938
  existing?.remove();
44014
- const tag = require_magpie_model_tag.createMagpieModelTagNode(document, model.id);
44939
+ const tag = require_magpie_model_tag.createMagpieModelTagNode(document, model.id, model.magpieProviderId);
44015
44940
  row.append(tag);
44016
44941
  }
44017
44942
  }
@@ -44661,10 +45586,11 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
44661
45586
  const nativeAvailable = nativeDefault !== void 0;
44662
45587
  const [nativeMenu, setNativeMenu] = (0, react.useState)(null);
44663
45588
  const catalog = catalogState?.adapterId === selection.adapterId && catalogState.sessionId === sessionId ? catalogState.value : null;
44664
- const nativeModels = selection.adapterId === "dsh" ? (catalog?.groups ?? []).flatMap((group) => group.models.map(({ id, name, source }) => ({
45589
+ const nativeModels = selection.adapterId === "dsh" ? (catalog?.groups ?? []).flatMap((group) => group.models.map(({ id, name, source, magpieProviderId }) => ({
44665
45590
  id,
44666
45591
  name,
44667
- ...source === "magpie" ? { source } : {}
45592
+ ...source === "magpie" ? { source } : {},
45593
+ ...magpieProviderId === void 0 ? {} : { magpieProviderId }
44668
45594
  }))) : [];
44669
45595
  nativeMagpieModelsRef.current = nativeModels;
44670
45596
  const nativeMagpieModelRevision = JSON.stringify(nativeModels);
@@ -45038,7 +45964,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
45038
45964
  overflow: "hidden",
45039
45965
  textOverflow: "ellipsis",
45040
45966
  whiteSpace: "nowrap"
45041
- } }, item.name), item.id === model?.id && (0, react.createElement)("span", { "aria-hidden": true }, "✓"), item.source === "magpie" && (0, react.createElement)(require_magpie_model_tag.MagpieModelTag, {}));
45967
+ } }, item.name), item.id === model?.id && (0, react.createElement)("span", { "aria-hidden": true }, "✓"), item.source === "magpie" && (0, react.createElement)(require_magpie_model_tag.MagpieModelTag, { providerId: item.magpieProviderId }));
45042
45968
  }))), visibleModelGroups.length === 0 && (0, react.createElement)("div", {
45043
45969
  key: "model-empty",
45044
45970
  role: "status",
@@ -45704,7 +46630,7 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
45704
46630
  //#endregion
45705
46631
  //#region src/client/features/workspace-session-enhancement.ts
45706
46632
  /** descriptor 的 label/description 只是词典缺失时的兜底,取内置中文词典。 */
45707
- const fallbackT$2 = require_transport.resolveCodingNsTranslator();
46633
+ const fallbackT$3 = require_transport.resolveCodingNsTranslator();
45708
46634
  /** DSH 0.1.6 原生会话行增强:Logo 与归档会话入口共用同一生命周期。 */
45709
46635
  const workspaceSessionEnhancementFeature = {
45710
46636
  descriptor: {
@@ -45714,8 +46640,8 @@ html[data-codingns-mobile-sidebar="on"] .codingns-magpie-page{padding-left:0;--m
45714
46640
  dependencies: ["cliAdapters"],
45715
46641
  runtime: "client",
45716
46642
  ui: {
45717
- label: fallbackT$2("feature.workspaceSession.label"),
45718
- description: fallbackT$2("feature.workspaceSession.description"),
46643
+ label: fallbackT$3("feature.workspaceSession.label"),
46644
+ description: fallbackT$3("feature.workspaceSession.description"),
45719
46645
  labelKey: "feature.workspaceSession.label",
45720
46646
  descriptionKey: "feature.workspaceSession.description",
45721
46647
  order: 35,
@@ -47598,7 +48524,7 @@ ${SCOPE} article>div:last-child>button { float:none!important; order:1; min-heig
47598
48524
  //#endregion
47599
48525
  //#region src/client/features/mobile-access.ts
47600
48526
  /** descriptor 的 label/description 只是词典缺失时的兜底,取内置中文词典。 */
47601
- const fallbackT$1 = require_transport.resolveCodingNsTranslator();
48527
+ const fallbackT$2 = require_transport.resolveCodingNsTranslator();
47602
48528
  /**
47603
48529
  * 移动端访问增强。
47604
48530
  *
@@ -47622,8 +48548,8 @@ ${SCOPE} article>div:last-child>button { float:none!important; order:1; min-heig
47622
48548
  fallback: "disable"
47623
48549
  }],
47624
48550
  ui: {
47625
- label: fallbackT$1("feature.mobileAccess.label"),
47626
- description: fallbackT$1("feature.mobileAccess.description"),
48551
+ label: fallbackT$2("feature.mobileAccess.label"),
48552
+ description: fallbackT$2("feature.mobileAccess.description"),
47627
48553
  labelKey: "feature.mobileAccess.label",
47628
48554
  descriptionKey: "feature.mobileAccess.description",
47629
48555
  order: 36,
@@ -53880,7 +54806,7 @@ ${SCOPE} article>div:last-child>button { float:none!important; order:1; min-heig
53880
54806
  //#endregion
53881
54807
  //#region src/client/features/file-management.ts
53882
54808
  /** descriptor 的 label/description 只是词典缺失时的兜底,取内置中文词典。 */
53883
- const fallbackT = require_transport.resolveCodingNsTranslator();
54809
+ const fallbackT$1 = require_transport.resolveCodingNsTranslator();
53884
54810
  /** 文件管理增强:只在模块启用期间挂载右键菜单和文本编辑器。 */
53885
54811
  const fileManagementFeature = {
53886
54812
  descriptor: {
@@ -53890,8 +54816,8 @@ ${SCOPE} article>div:last-child>button { float:none!important; order:1; min-heig
53890
54816
  dependencies: [],
53891
54817
  runtime: "client",
53892
54818
  ui: {
53893
- label: fallbackT("feature.fileManagement.label"),
53894
- description: fallbackT("feature.fileManagement.description"),
54819
+ label: fallbackT$1("feature.fileManagement.label"),
54820
+ description: fallbackT$1("feature.fileManagement.description"),
53895
54821
  labelKey: "feature.fileManagement.label",
53896
54822
  descriptionKey: "feature.fileManagement.description",
53897
54823
  order: 40,
@@ -68852,7 +69778,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
68852
69778
  const store = require_native_workspace_store.readNativeWorkspaceListStore(input.uiContext);
68853
69779
  if (store === void 0) return () => void 0;
68854
69780
  const service = require_native_workspace_store.readNativeService(input.uiContext, "workspaces");
68855
- const serviceRecord = isRecord$4(service) ? service : void 0;
69781
+ const serviceRecord = isRecord$5(service) ? service : void 0;
68856
69782
  const sessionStoreValue = require_native_workspace_store.readNativeService(input.uiContext, "sessions", "list");
68857
69783
  const sessionStore = isSnapshotStore(sessionStoreValue) ? sessionStoreValue : void 0;
68858
69784
  const ownsGetSnapshot = Object.hasOwn(store, "getSnapshot");
@@ -68915,7 +69841,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
68915
69841
  async function refreshPeerHostNativeSessions(uiContext) {
68916
69842
  if (uiContext === void 0) return;
68917
69843
  const sessions = require_native_workspace_store.readNativeService(uiContext, "sessions");
68918
- const refresh = isRecord$4(sessions) ? sessions.refresh : void 0;
69844
+ const refresh = isRecord$5(sessions) ? sessions.refresh : void 0;
68919
69845
  if (typeof refresh !== "function") return;
68920
69846
  const owner = uiContext;
68921
69847
  const state = refreshStates.get(owner);
@@ -69035,7 +69961,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
69035
69961
  const byId = state?.byId;
69036
69962
  const workspaceState = asRecord$4(workspaceSnapshot);
69037
69963
  const items = Array.isArray(workspaceState?.items) ? workspaceState.items : [];
69038
- if (state === null || !isRecord$4(byId) || items.length === 0) return snapshot;
69964
+ if (state === null || !isRecord$5(byId) || items.length === 0) return snapshot;
69039
69965
  let changed = false;
69040
69966
  const nextById = { ...byId };
69041
69967
  for (const [id, value] of Object.entries(byId)) {
@@ -69185,13 +70111,13 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
69185
70111
  return merged.length === original.length && merged.every((id, index) => id === original[index]) ? void 0 : merged;
69186
70112
  }
69187
70113
  function asRecord$4(value) {
69188
- return isRecord$4(value) ? value : null;
70114
+ return isRecord$5(value) ? value : null;
69189
70115
  }
69190
- function isRecord$4(value) {
70116
+ function isRecord$5(value) {
69191
70117
  return typeof value === "object" && value !== null && !Array.isArray(value);
69192
70118
  }
69193
70119
  function isSnapshotStore(value) {
69194
- return isRecord$4(value) && typeof value.getSnapshot === "function" && typeof value.subscribe === "function";
70120
+ return isRecord$5(value) && typeof value.getSnapshot === "function" && typeof value.subscribe === "function";
69195
70121
  }
69196
70122
  //#endregion
69197
70123
  //#region src/client/peer-host-workspace-tag.ts
@@ -69362,7 +70288,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
69362
70288
  const fiberKey = Object.getOwnPropertyNames(row).find((key) => key.startsWith("__reactFiber$"));
69363
70289
  if (fiberKey === void 0) return void 0;
69364
70290
  let current = row[fiberKey];
69365
- for (let depth = 0; depth < 24 && isRecord$3(current); depth += 1) {
70291
+ for (let depth = 0; depth < 24 && isRecord$4(current); depth += 1) {
69366
70292
  for (const props of [current.memoizedProps, current.pendingProps]) {
69367
70293
  const found = readWorkspaceIdFromProps(props);
69368
70294
  if (found !== void 0) return found;
@@ -69371,7 +70297,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
69371
70297
  }
69372
70298
  }
69373
70299
  function readWorkspaceIdFromProps(value) {
69374
- if (!isRecord$3(value)) return void 0;
70300
+ if (!isRecord$4(value)) return void 0;
69375
70301
  for (const key of ["workspaceId", "workspaceID"]) {
69376
70302
  const candidate = value[key];
69377
70303
  if (typeof candidate === "string" && candidate.trim() !== "") return candidate.trim();
@@ -69385,7 +70311,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
69385
70311
  "data"
69386
70312
  ]) {
69387
70313
  const nested = value[key];
69388
- if (!isRecord$3(nested)) continue;
70314
+ if (!isRecord$4(nested)) continue;
69389
70315
  const candidate = nested.workspaceId ?? nested.id;
69390
70316
  if (typeof candidate === "string" && candidate.trim() !== "") return candidate.trim();
69391
70317
  }
@@ -69421,7 +70347,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
69421
70347
  });
69422
70348
  host.append(element);
69423
70349
  }
69424
- function isRecord$3(value) {
70350
+ function isRecord$4(value) {
69425
70351
  return typeof value === "object" && value !== null && !Array.isArray(value);
69426
70352
  }
69427
70353
  //#endregion
@@ -72868,11 +73794,11 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
72868
73794
  if (this.leaseRequest === leaseRequest) this.leaseRequest = void 0;
72869
73795
  });
72870
73796
  if (!lease.ok) throw new Error(lease.error.message);
72871
- if (isRecord$2(lease.value) && lease.value.unavailable === true) throw new Error(typeof lease.value.message === "string" ? lease.value.message : "本地 Sherpa 语音运行时不可用");
73797
+ if (isRecord$3(lease.value) && lease.value.unavailable === true) throw new Error(typeof lease.value.message === "string" ? lease.value.message : "本地 Sherpa 语音运行时不可用");
72872
73798
  if (abort.signal.aborted) throw new Error("语音启动已取消");
72873
73799
  this.hostLeaseActive = true;
72874
- this.epoch = readEpoch(isRecord$2(lease.value) ? lease.value : {}, this.epoch + 1);
72875
- if (isRecord$2(lease.value) && lease.value.diagnosticsEnabled === true) {
73800
+ this.epoch = readEpoch(isRecord$3(lease.value) ? lease.value : {}, this.epoch + 1);
73801
+ if (isRecord$3(lease.value) && lease.value.diagnosticsEnabled === true) {
72876
73802
  this.diagnostics = new ClientVoiceDiagnostics(this.services, {
72877
73803
  ownerId: this.configuredOwner,
72878
73804
  callId
@@ -72981,7 +73907,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
72981
73907
  }
72982
73908
  this.capture = void 0;
72983
73909
  const pendingLease = await leaseRequest?.catch(() => void 0);
72984
- if (pendingLease?.ok && !(isRecord$2(pendingLease.value) && pendingLease.value.unavailable === true)) this.hostLeaseActive = true;
73910
+ if (pendingLease?.ok && !(isRecord$3(pendingLease.value) && pendingLease.value.unavailable === true)) this.hostLeaseActive = true;
72985
73911
  if (this.hostLeaseActive) {
72986
73912
  this.hostLeaseActive = false;
72987
73913
  await callCodingNsRpcResult(this.services.rpc, "assistant/voice/stop", { ownerId: this.configuredOwner }).catch(() => void 0);
@@ -73007,7 +73933,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
73007
73933
  const result = await callCodingNsRpcResult(this.services.rpc, "assistant/voice/interrupt", { ownerId: this.configuredOwner });
73008
73934
  if (!result.ok) throw new Error(result.error.message);
73009
73935
  if (!this.active) return;
73010
- this.epoch = readEpoch(isRecord$2(result.value) ? result.value : {}, this.epoch + 1);
73936
+ this.epoch = readEpoch(isRecord$3(result.value) ? result.value : {}, this.epoch + 1);
73011
73937
  this.emit({
73012
73938
  type: "barge-in",
73013
73939
  epoch: this.epoch
@@ -73244,12 +74170,12 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
73244
74170
  while (isCurrent()) {
73245
74171
  if (!result.ok) throw new Error(result.error.message);
73246
74172
  const pushed = reply.updates.take();
73247
- if (pushed !== void 0 && (!isRecord$2(result.value) || result.value.state === "running" || pushed.state !== "running")) result = {
74173
+ if (pushed !== void 0 && (!isRecord$3(result.value) || result.value.state === "running" || pushed.state !== "running")) result = {
73248
74174
  ok: true,
73249
74175
  value: pushed
73250
74176
  };
73251
74177
  const run = result.value;
73252
- if (!isRecord$2(run) || typeof run.text !== "string" || ![
74178
+ if (!isRecord$3(run) || typeof run.text !== "string" || ![
73253
74179
  "running",
73254
74180
  "completed",
73255
74181
  "failed",
@@ -73387,11 +74313,11 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
73387
74313
  function readEpoch(value, fallback) {
73388
74314
  return typeof value.epoch === "number" && Number.isInteger(value.epoch) ? value.epoch : fallback;
73389
74315
  }
73390
- function isRecord$2(value) {
74316
+ function isRecord$3(value) {
73391
74317
  return typeof value === "object" && value !== null && !Array.isArray(value);
73392
74318
  }
73393
74319
  function isVoiceChatRun(value) {
73394
- return isRecord$2(value) && typeof value.requestId === "string" && typeof value.text === "string" && value.text.length <= 16e3 && [
74320
+ return isRecord$3(value) && typeof value.requestId === "string" && typeof value.text === "string" && value.text.length <= 16e3 && [
73395
74321
  "running",
73396
74322
  "completed",
73397
74323
  "failed",
@@ -77470,6 +78396,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
77470
78396
  const detailsTitle = props.translationT(inputFailure ? "translation.inputFailedTitle" : "translation.detailsTitle");
77471
78397
  const pending = record === void 0 || output.pending;
77472
78398
  const failed = record?.failed === true;
78399
+ const failure = require_session_translation.readSessionTranslationDiagnostics(record).failure;
77473
78400
  const alreadyTargetLanguage = record?.alreadyTargetLanguage === true;
77474
78401
  const statusText = pending ? props.translationT("translation.statusTranslating") : failed ? props.translationT("translation.statusFailed") : alreadyTargetLanguage ? props.translationT("translation.statusNotNeeded") : props.translationT("translation.statusTranslated");
77475
78402
  const statusColor = pending ? require_theme.dshThemeColor.accent : failed ? require_theme.dshThemeColor.error : alreadyTargetLanguage ? require_theme.dshThemeColor.accent : require_theme.dshThemeColor.success;
@@ -77563,7 +78490,10 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
77563
78490
  `${props.translationT("translation.modelUsed")}: ${alreadyTargetLanguage ? props.translationT("translation.modelNotUsed") : formatModel(record.model, props.translationT)}`,
77564
78491
  ...record.durationMs === void 0 ? [] : [`${(record.durationMs / 1e3).toFixed(2)} s`],
77565
78492
  ...record.totalTokens === void 0 ? [] : [`${record.totalTokens} tok`]
77566
- ].join(" · ")), props.inputFailure === void 0 ? null : (0, react.createElement)("p", { role: "alert" }, props.translationT("translation.inputFailedHelp")), decisionError ? (0, react.createElement)("p", {
78493
+ ].join(" · ")), props.inputFailure === void 0 ? null : (0, react.createElement)("p", { role: "alert" }, props.translationT("translation.inputFailedHelp")), pending || !failed ? null : (0, react.createElement)("p", {
78494
+ role: "alert",
78495
+ style: { color: require_theme.dshThemeColor.error }
78496
+ }, props.translationT(`translation.failure.${failure?.code ?? "unknown"}`)), decisionError ? (0, react.createElement)("p", {
77567
78497
  role: "alert",
77568
78498
  style: { color: require_theme.dshThemeColor.error }
77569
78499
  }, props.translationT("translation.decisionFailed")) : null, props.inputFailure !== void 0 ? (0, react.createElement)("div", { style: {
@@ -78408,6 +79338,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
78408
79338
  ...candidate.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
78409
79339
  ...model === void 0 ? {} : { model },
78410
79340
  ...candidate.failed === true ? { failed: true } : {},
79341
+ ...require_session_translation.readSessionTranslationDiagnostics(candidate),
78411
79342
  ...require_session_translation.readSessionTranslationMetrics(candidate)
78412
79343
  };
78413
79344
  }
@@ -78434,6 +79365,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
78434
79365
  ...candidate.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
78435
79366
  ...model === void 0 ? {} : { model },
78436
79367
  ...candidate.failed === true ? { failed: true } : {},
79368
+ ...require_session_translation.readSessionTranslationDiagnostics(candidate),
78437
79369
  ...require_session_translation.readSessionTranslationMetrics(candidate)
78438
79370
  };
78439
79371
  }
@@ -78447,6 +79379,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
78447
79379
  ...record.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
78448
79380
  ...record.model === void 0 ? {} : { model: record.model },
78449
79381
  ...record.failed === true ? { failed: true } : {},
79382
+ ...require_session_translation.readSessionTranslationDiagnostics(record),
78450
79383
  ...require_session_translation.readSessionTranslationMetrics(record)
78451
79384
  };
78452
79385
  }
@@ -79040,6 +79973,463 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
79040
79973
  start: () => void 0
79041
79974
  };
79042
79975
  //#endregion
79976
+ //#region src/client/features/workspace-mcp.ts
79977
+ const fallbackT = require_transport.resolveCodingNsTranslator();
79978
+ const workspaceMcpFeature = {
79979
+ descriptor: {
79980
+ name: "workspaceMcp",
79981
+ version: "0.1.0",
79982
+ enabledByDefault: false,
79983
+ dependencies: [],
79984
+ runtime: "client",
79985
+ ui: {
79986
+ label: fallbackT("feature.workspaceMcp.label"),
79987
+ description: fallbackT("feature.workspaceMcp.description"),
79988
+ labelKey: "feature.workspaceMcp.label",
79989
+ descriptionKey: "feature.workspaceMcp.description",
79990
+ order: 60,
79991
+ defaultOpen: false
79992
+ }
79993
+ },
79994
+ start() {},
79995
+ settingsPanel: WorkspaceMcpPanel
79996
+ };
79997
+ const WORKSPACE_MCP_CAPABILITIES = [
79998
+ {
79999
+ name: "workspace_list",
80000
+ permissionKey: "workspaceMcp.capability.workspaceList.permission",
80001
+ descriptionKey: "workspaceMcp.capability.workspaceList.description",
80002
+ parametersKey: "workspaceMcp.capability.workspaceList.parameters",
80003
+ remarksKey: "workspaceMcp.capability.workspaceList.remarks"
80004
+ },
80005
+ {
80006
+ name: "session_list",
80007
+ permissionKey: "workspaceMcp.capability.sessionList.permission",
80008
+ descriptionKey: "workspaceMcp.capability.sessionList.description",
80009
+ parametersKey: "workspaceMcp.capability.sessionList.parameters",
80010
+ remarksKey: "workspaceMcp.capability.sessionList.remarks"
80011
+ },
80012
+ {
80013
+ name: "session_create",
80014
+ permissionKey: "workspaceMcp.capability.sessionCreate.permission",
80015
+ descriptionKey: "workspaceMcp.capability.sessionCreate.description",
80016
+ parametersKey: "workspaceMcp.capability.sessionCreate.parameters",
80017
+ remarksKey: "workspaceMcp.capability.sessionCreate.remarks"
80018
+ },
80019
+ {
80020
+ name: "session_continue",
80021
+ permissionKey: "workspaceMcp.capability.sessionContinue.permission",
80022
+ descriptionKey: "workspaceMcp.capability.sessionContinue.description",
80023
+ parametersKey: "workspaceMcp.capability.sessionContinue.parameters",
80024
+ remarksKey: "workspaceMcp.capability.sessionContinue.remarks"
80025
+ },
80026
+ {
80027
+ name: "session_questions",
80028
+ permissionKey: "workspaceMcp.capability.sessionQuestions.permission",
80029
+ descriptionKey: "workspaceMcp.capability.sessionQuestions.description",
80030
+ parametersKey: "workspaceMcp.capability.sessionQuestions.parameters",
80031
+ remarksKey: "workspaceMcp.capability.sessionQuestions.remarks"
80032
+ },
80033
+ {
80034
+ name: "session_answer",
80035
+ permissionKey: "workspaceMcp.capability.sessionAnswer.permission",
80036
+ descriptionKey: "workspaceMcp.capability.sessionAnswer.description",
80037
+ parametersKey: "workspaceMcp.capability.sessionAnswer.parameters",
80038
+ remarksKey: "workspaceMcp.capability.sessionAnswer.remarks"
80039
+ },
80040
+ {
80041
+ name: "session_request_permission",
80042
+ permissionKey: "workspaceMcp.capability.sessionRequestPermission.permission",
80043
+ descriptionKey: "workspaceMcp.capability.sessionRequestPermission.description",
80044
+ parametersKey: "workspaceMcp.capability.sessionRequestPermission.parameters",
80045
+ remarksKey: "workspaceMcp.capability.sessionRequestPermission.remarks"
80046
+ },
80047
+ {
80048
+ name: "session_permission_status",
80049
+ permissionKey: "workspaceMcp.capability.sessionPermissionStatus.permission",
80050
+ descriptionKey: "workspaceMcp.capability.sessionPermissionStatus.description",
80051
+ parametersKey: "workspaceMcp.capability.sessionPermissionStatus.parameters",
80052
+ remarksKey: "workspaceMcp.capability.sessionPermissionStatus.remarks"
80053
+ },
80054
+ {
80055
+ name: "terminal_list",
80056
+ permissionKey: "workspaceMcp.capability.terminalList.permission",
80057
+ descriptionKey: "workspaceMcp.capability.terminalList.description",
80058
+ parametersKey: "workspaceMcp.capability.terminalList.parameters",
80059
+ remarksKey: "workspaceMcp.capability.terminalList.remarks"
80060
+ },
80061
+ {
80062
+ name: "terminal_read",
80063
+ permissionKey: "workspaceMcp.capability.terminalRead.permission",
80064
+ descriptionKey: "workspaceMcp.capability.terminalRead.description",
80065
+ parametersKey: "workspaceMcp.capability.terminalRead.parameters",
80066
+ remarksKey: "workspaceMcp.capability.terminalRead.remarks"
80067
+ },
80068
+ {
80069
+ name: "terminal_write",
80070
+ permissionKey: "workspaceMcp.capability.terminalWrite.permission",
80071
+ descriptionKey: "workspaceMcp.capability.terminalWrite.description",
80072
+ parametersKey: "workspaceMcp.capability.terminalWrite.parameters",
80073
+ remarksKey: "workspaceMcp.capability.terminalWrite.remarks"
80074
+ }
80075
+ ];
80076
+ const REASON_KEYS = {
80077
+ "api-key-missing": "workspaceMcp.reason.keyMissing",
80078
+ "api-key-not-configured": "workspaceMcp.reason.keyMissing",
80079
+ "key-store-failed": "workspaceMcp.reason.keyStoreFailed",
80080
+ disabled: "workspaceMcp.reason.disabled",
80081
+ "listen-failed": "workspaceMcp.reason.listenFailed",
80082
+ "listener-error": "workspaceMcp.reason.listenFailed",
80083
+ "startup-failed": "workspaceMcp.reason.listenFailed"
80084
+ };
80085
+ function WorkspaceMcpPanel({ services, enabled, notify }) {
80086
+ const t = require_transport.useCodingNsTranslator(services.locale);
80087
+ const [status, setStatus] = (0, react.useState)(null);
80088
+ const [loading, setLoading] = (0, react.useState)(true);
80089
+ const [failed, setFailed] = (0, react.useState)(false);
80090
+ const [refreshCount, setRefreshCount] = (0, react.useState)(0);
80091
+ const [busy, setBusy] = (0, react.useState)(false);
80092
+ const [generatedKey, setGeneratedKey] = (0, react.useState)(null);
80093
+ const [capabilitiesOpen, setCapabilitiesOpen] = (0, react.useState)(false);
80094
+ (0, react.useEffect)(() => {
80095
+ let active = true;
80096
+ setLoading(true);
80097
+ setFailed(false);
80098
+ services.rpc.call(require_transport.CODINGNS_RPC_CHANNEL, "workspaceMcp/status", {}).then((result) => {
80099
+ if (!result.ok) throw new Error("Workspace MCP status request failed");
80100
+ const next = normalizeStatus(result.value);
80101
+ if (next === null) throw new Error("Invalid Workspace MCP status");
80102
+ if (active) setStatus(next);
80103
+ }).catch(() => {
80104
+ if (active) {
80105
+ setStatus(null);
80106
+ setFailed(true);
80107
+ }
80108
+ }).finally(() => {
80109
+ if (active) setLoading(false);
80110
+ });
80111
+ return () => {
80112
+ active = false;
80113
+ };
80114
+ }, [
80115
+ services.rpc,
80116
+ enabled,
80117
+ refreshCount
80118
+ ]);
80119
+ (0, react.useEffect)(() => {
80120
+ if (!capabilitiesOpen) return;
80121
+ const closeOnEscape = (event) => {
80122
+ if (event.key === "Escape") setCapabilitiesOpen(false);
80123
+ };
80124
+ globalThis.addEventListener("keydown", closeOnEscape);
80125
+ return () => globalThis.removeEventListener("keydown", closeOnEscape);
80126
+ }, [capabilitiesOpen]);
80127
+ const reasonKey = status?.reason === null || status?.reason === void 0 ? null : Object.prototype.hasOwnProperty.call(REASON_KEYS, status.reason) ? REASON_KEYS[status.reason] ?? "workspaceMcp.reason.other" : "workspaceMcp.reason.other";
80128
+ const url = safeWorkspaceMcpUrl(status?.url);
80129
+ const generateKey = async () => {
80130
+ setBusy(true);
80131
+ setGeneratedKey(null);
80132
+ try {
80133
+ const result = await services.rpc.call(require_transport.CODINGNS_RPC_CHANNEL, "workspaceMcp/generate-key", {});
80134
+ if (!result.ok || !isRecord$2(result.value) || typeof result.value.apiKey !== "string") throw new Error(result.ok ? "Invalid Workspace MCP key response" : result.error.message);
80135
+ setGeneratedKey(result.value.apiKey);
80136
+ setRefreshCount((count) => count + 1);
80137
+ notify({
80138
+ kind: "success",
80139
+ message: t("workspaceMcp.keyGenerated")
80140
+ });
80141
+ } catch (error) {
80142
+ notify({
80143
+ kind: "error",
80144
+ message: error instanceof Error ? error.message : String(error)
80145
+ });
80146
+ } finally {
80147
+ setBusy(false);
80148
+ }
80149
+ };
80150
+ const copyKey = async () => {
80151
+ if (generatedKey === null) return;
80152
+ try {
80153
+ await navigator.clipboard.writeText(generatedKey);
80154
+ notify({
80155
+ kind: "success",
80156
+ message: t("workspaceMcp.keyCopied")
80157
+ });
80158
+ } catch {
80159
+ notify({
80160
+ kind: "error",
80161
+ message: t("workspaceMcp.copyFailed")
80162
+ });
80163
+ }
80164
+ };
80165
+ const installPrompt = t("workspaceMcp.installPromptText");
80166
+ const copyInstallPrompt = async () => {
80167
+ try {
80168
+ await navigator.clipboard.writeText(installPrompt);
80169
+ notify({
80170
+ kind: "success",
80171
+ message: t("workspaceMcp.installPromptCopied")
80172
+ });
80173
+ } catch {
80174
+ notify({
80175
+ kind: "error",
80176
+ message: t("workspaceMcp.copyFailed")
80177
+ });
80178
+ }
80179
+ };
80180
+ const compactButtonStyle = {
80181
+ ...require_theme.dshSettingsButtonStyle,
80182
+ flex: "1 1 0",
80183
+ minWidth: 0,
80184
+ minHeight: 32,
80185
+ padding: "6px 9px",
80186
+ fontSize: require_theme.uiFontSize(12),
80187
+ lineHeight: 1.25,
80188
+ whiteSpace: "normal"
80189
+ };
80190
+ return (0, react.createElement)("div", { style: {
80191
+ display: "flex",
80192
+ flexDirection: "column",
80193
+ gap: 12
80194
+ } }, (0, react.createElement)("div", { style: require_theme.dshSettingsNoteStyle }, (0, react.createElement)("strong", { style: {
80195
+ display: "block",
80196
+ marginBottom: 4
80197
+ } }, t("workspaceMcp.setupTitle")), (0, react.createElement)("span", void 0, t("workspaceMcp.setupInstruction"))), (0, react.createElement)("div", { style: {
80198
+ display: "flex",
80199
+ flexWrap: "nowrap",
80200
+ gap: 8,
80201
+ minWidth: 0
80202
+ } }, (0, react.createElement)("button", {
80203
+ type: "button",
80204
+ style: compactButtonStyle,
80205
+ onClick: () => setCapabilitiesOpen(true)
80206
+ }, t("workspaceMcp.capabilityDescription")), (0, react.createElement)("button", {
80207
+ type: "button",
80208
+ disabled: busy || loading,
80209
+ onClick: () => void generateKey(),
80210
+ style: compactButtonStyle
80211
+ }, busy ? t("workspaceMcp.generating") : t(status?.apiKeyConfigured ? "workspaceMcp.rotateKey" : "workspaceMcp.generateKey")), (0, react.createElement)("button", {
80212
+ type: "button",
80213
+ disabled: loading || busy,
80214
+ onClick: () => setRefreshCount((count) => count + 1),
80215
+ style: compactButtonStyle
80216
+ }, t("workspaceMcp.refresh"))), generatedKey === null ? null : (0, react.createElement)("div", { style: {
80217
+ display: "flex",
80218
+ flexWrap: "wrap",
80219
+ gap: 8,
80220
+ alignItems: "center"
80221
+ } }, (0, react.createElement)("input", {
80222
+ type: "text",
80223
+ readOnly: true,
80224
+ value: generatedKey,
80225
+ autoComplete: "off",
80226
+ spellCheck: false,
80227
+ "aria-label": t("workspaceMcp.generatedKey"),
80228
+ style: {
80229
+ ...require_theme.dshSettingsFieldStyle,
80230
+ flex: "1 1 260px",
80231
+ minWidth: 0
80232
+ },
80233
+ onFocus: (event) => event.currentTarget.select()
80234
+ }), (0, react.createElement)("button", {
80235
+ type: "button",
80236
+ onClick: () => void copyKey(),
80237
+ style: require_theme.dshSettingsButtonStyle
80238
+ }, t("workspaceMcp.copyKey")), (0, react.createElement)("span", { style: {
80239
+ flexBasis: "100%",
80240
+ color: require_theme.dshThemeColor.warning,
80241
+ fontSize: require_theme.uiFontSize(12),
80242
+ lineHeight: 1.5
80243
+ } }, t("workspaceMcp.keyShownOnce"))), (0, react.createElement)("div", {
80244
+ "aria-live": "polite",
80245
+ style: {
80246
+ display: "flex",
80247
+ flexDirection: "column",
80248
+ gap: 6,
80249
+ fontSize: require_theme.uiFontSize(12),
80250
+ lineHeight: 1.5,
80251
+ overflowWrap: "anywhere"
80252
+ }
80253
+ }, (0, react.createElement)("strong", void 0, t("workspaceMcp.statusTitle")), loading ? (0, react.createElement)("span", void 0, t("workspaceMcp.loading")) : null, failed ? (0, react.createElement)("span", {
80254
+ role: "alert",
80255
+ style: { color: require_theme.dshThemeColor.error }
80256
+ }, t("workspaceMcp.statusFailed")) : null, status !== null && !loading ? (0, react.createElement)("span", void 0, t("workspaceMcp.apiKeyStatus", { status: t(status.apiKeyConfigured ? "workspaceMcp.configured" : "workspaceMcp.notConfigured") })) : null, status !== null && !loading ? (0, react.createElement)("span", void 0, t("workspaceMcp.enabledStatus", { status: t(status.enabled ? "workspaceMcp.on" : "workspaceMcp.off") })) : null, status !== null && !loading ? (0, react.createElement)("span", void 0, t("workspaceMcp.listeningStatus", { status: t(status.listening ? "workspaceMcp.on" : "workspaceMcp.off") })) : null, status !== null && !loading && url !== null ? (0, react.createElement)("span", void 0, (0, react.createElement)("span", { style: { color: require_theme.dshThemeColor.labelSecondary } }, `${t("workspaceMcp.url")}: `), (0, react.createElement)("code", void 0, url)) : null, reasonKey !== null && status !== null && !loading ? (0, react.createElement)("span", { style: { color: require_theme.dshThemeColor.labelSecondary } }, t(reasonKey)) : null), (0, react.createElement)("div", { style: {
80257
+ display: "flex",
80258
+ flexDirection: "column",
80259
+ gap: 8,
80260
+ paddingTop: 12,
80261
+ borderTop: `1px solid ${require_theme.dshThemeColor.border}`
80262
+ } }, (0, react.createElement)("strong", { style: { fontSize: require_theme.uiFontSize(13) } }, t("workspaceMcp.installPromptTitle")), (0, react.createElement)("span", { style: {
80263
+ color: require_theme.dshThemeColor.labelSecondary,
80264
+ fontSize: require_theme.uiFontSize(12),
80265
+ lineHeight: 1.5
80266
+ } }, t("workspaceMcp.installPromptHint")), (0, react.createElement)("pre", { style: {
80267
+ margin: 0,
80268
+ padding: 10,
80269
+ maxHeight: 112,
80270
+ overflow: "auto",
80271
+ whiteSpace: "pre-wrap",
80272
+ overflowWrap: "anywhere",
80273
+ border: `1px solid ${require_theme.dshThemeColor.border}`,
80274
+ borderRadius: 6,
80275
+ color: require_theme.dshThemeColor.labelSecondary,
80276
+ background: require_theme.dshThemeColor.pageBackground,
80277
+ fontSize: require_theme.uiFontSize(11),
80278
+ lineHeight: 1.45
80279
+ } }, installPrompt), (0, react.createElement)("button", {
80280
+ type: "button",
80281
+ onClick: () => void copyInstallPrompt(),
80282
+ style: {
80283
+ ...require_theme.dshSettingsButtonStyle,
80284
+ alignSelf: "flex-end",
80285
+ minHeight: 32,
80286
+ padding: "6px 10px",
80287
+ fontSize: require_theme.uiFontSize(12)
80288
+ }
80289
+ }, t("workspaceMcp.copyInstallPrompt"))), capabilitiesOpen ? createWorkspaceMcpCapabilitiesModal(t, () => setCapabilitiesOpen(false)) : null);
80290
+ }
80291
+ function createWorkspaceMcpCapabilitiesModal(t, onClose) {
80292
+ return (0, react.createElement)("div", {
80293
+ role: "presentation",
80294
+ onClick: onClose,
80295
+ style: {
80296
+ position: "fixed",
80297
+ inset: 0,
80298
+ zIndex: 2e3,
80299
+ display: "flex",
80300
+ alignItems: "center",
80301
+ justifyContent: "center",
80302
+ padding: 16,
80303
+ background: "rgba(0, 0, 0, 0.62)",
80304
+ boxSizing: "border-box"
80305
+ },
80306
+ "data-workspace-mcp-capabilities": true
80307
+ }, (0, react.createElement)("div", {
80308
+ role: "dialog",
80309
+ "aria-modal": true,
80310
+ "aria-labelledby": "codingns-workspace-mcp-capability-title",
80311
+ onClick: (event) => event.stopPropagation(),
80312
+ style: {
80313
+ display: "flex",
80314
+ flexDirection: "column",
80315
+ width: "min(960px, 100%)",
80316
+ maxHeight: "min(820px, calc(100dvh - 32px))",
80317
+ overflow: "hidden",
80318
+ border: `1px solid ${require_theme.dshThemeColor.border}`,
80319
+ borderRadius: 12,
80320
+ background: require_theme.dshThemeColor.menuBackground,
80321
+ color: require_theme.dshThemeColor.labelPrimary,
80322
+ boxShadow: "0 20px 70px rgba(0, 0, 0, 0.45)"
80323
+ }
80324
+ }, (0, react.createElement)("div", { style: {
80325
+ display: "flex",
80326
+ alignItems: "flex-start",
80327
+ justifyContent: "space-between",
80328
+ gap: 16,
80329
+ padding: "18px 20px 14px",
80330
+ borderBottom: `1px solid ${require_theme.dshThemeColor.border}`
80331
+ } }, (0, react.createElement)("div", { style: { minWidth: 0 } }, (0, react.createElement)("h2", {
80332
+ id: "codingns-workspace-mcp-capability-title",
80333
+ style: {
80334
+ margin: 0,
80335
+ fontSize: require_theme.uiFontSize(18),
80336
+ lineHeight: 1.3
80337
+ }
80338
+ }, t("workspaceMcp.capabilityTitle")), (0, react.createElement)("p", { style: {
80339
+ margin: "6px 0 0",
80340
+ color: require_theme.dshThemeColor.labelSecondary,
80341
+ fontSize: require_theme.uiFontSize(12),
80342
+ lineHeight: 1.5
80343
+ } }, t("workspaceMcp.capabilitySubtitle"))), (0, react.createElement)("button", {
80344
+ type: "button",
80345
+ "aria-label": t("workspaceMcp.closeCapabilities"),
80346
+ onClick: onClose,
80347
+ style: {
80348
+ ...require_theme.dshSettingsButtonStyle,
80349
+ minWidth: 36,
80350
+ padding: "8px 10px",
80351
+ fontSize: require_theme.uiFontSize(18),
80352
+ lineHeight: 1
80353
+ }
80354
+ }, "×")), (0, react.createElement)("div", { style: {
80355
+ padding: 14,
80356
+ overflowY: "auto",
80357
+ overflowX: "auto",
80358
+ overscrollBehavior: "contain"
80359
+ } }, (0, react.createElement)("table", { style: {
80360
+ width: "100%",
80361
+ minWidth: 900,
80362
+ borderCollapse: "collapse",
80363
+ tableLayout: "fixed",
80364
+ fontSize: require_theme.uiFontSize(13),
80365
+ lineHeight: 1.5
80366
+ } }, (0, react.createElement)("colgroup", void 0, (0, react.createElement)("col", { style: { width: 170 } }), (0, react.createElement)("col", { style: { width: 190 } }), (0, react.createElement)("col", { style: { width: 230 } }), (0, react.createElement)("col", { style: { width: 185 } }), (0, react.createElement)("col", { style: { width: 235 } })), (0, react.createElement)("thead", void 0, (0, react.createElement)("tr", void 0, ...[
80367
+ "workspaceMcp.capabilityName",
80368
+ "workspaceMcp.capabilityPermission",
80369
+ "workspaceMcp.capabilityDescriptionField",
80370
+ "workspaceMcp.capabilityParameters",
80371
+ "workspaceMcp.capabilityRemarks"
80372
+ ].map((key) => (0, react.createElement)("th", {
80373
+ key,
80374
+ scope: "col",
80375
+ style: {
80376
+ padding: "10px 12px",
80377
+ textAlign: "left",
80378
+ verticalAlign: "top",
80379
+ color: require_theme.dshThemeColor.labelSecondary,
80380
+ fontSize: require_theme.uiFontSize(12),
80381
+ fontWeight: 650,
80382
+ borderBottom: `1px solid ${require_theme.dshThemeColor.border}`,
80383
+ background: require_theme.dshThemeColor.pageBackground
80384
+ }
80385
+ }, t(key))))), (0, react.createElement)("tbody", void 0, ...WORKSPACE_MCP_CAPABILITIES.map((capability, index) => (0, react.createElement)("tr", {
80386
+ key: capability.name,
80387
+ style: { background: index % 2 === 0 ? "rgba(255, 255, 255, 0.025)" : "transparent" }
80388
+ }, (0, react.createElement)("td", { style: capabilityCellStyle }, (0, react.createElement)("code", { style: { overflowWrap: "anywhere" } }, capability.name)), (0, react.createElement)("td", { style: capabilityCellStyle }, t(capability.permissionKey)), (0, react.createElement)("td", { style: capabilityCellStyle }, t(capability.descriptionKey)), (0, react.createElement)("td", { style: capabilityCellStyle }, (0, react.createElement)("code", { style: {
80389
+ whiteSpace: "pre-wrap",
80390
+ overflowWrap: "anywhere"
80391
+ } }, t(capability.parametersKey))), (0, react.createElement)("td", { style: capabilityCellStyle }, t(capability.remarksKey))))))), (0, react.createElement)("div", { style: {
80392
+ display: "flex",
80393
+ justifyContent: "flex-end",
80394
+ padding: "12px 20px 16px",
80395
+ borderTop: `1px solid ${require_theme.dshThemeColor.border}`
80396
+ } }, (0, react.createElement)("button", {
80397
+ type: "button",
80398
+ onClick: onClose,
80399
+ style: require_theme.dshSettingsPrimaryButtonStyle
80400
+ }, t("workspaceMcp.closeCapabilities")))));
80401
+ }
80402
+ const capabilityCellStyle = {
80403
+ padding: "11px 12px",
80404
+ textAlign: "left",
80405
+ verticalAlign: "top",
80406
+ overflowWrap: "anywhere",
80407
+ borderBottom: `1px solid ${require_theme.dshThemeColor.border}`
80408
+ };
80409
+ function normalizeStatus(value) {
80410
+ if (!isRecord$2(value) || typeof value.apiKeyConfigured !== "boolean" || typeof value.enabled !== "boolean" || typeof value.listening !== "boolean" || value.url !== null && typeof value.url !== "string" || value.reason !== null && typeof value.reason !== "string") return null;
80411
+ return {
80412
+ apiKeyConfigured: value.apiKeyConfigured,
80413
+ enabled: value.enabled,
80414
+ listening: value.listening,
80415
+ url: value.url,
80416
+ reason: value.reason
80417
+ };
80418
+ }
80419
+ function safeWorkspaceMcpUrl(value) {
80420
+ if (value === null || value === void 0) return null;
80421
+ try {
80422
+ const url = new URL(value);
80423
+ if (url.protocol !== "http:" || url.hostname !== "127.0.0.1" || url.search !== "" || url.hash !== "" || url.pathname !== "/mcp" || value !== `${url.origin}/mcp`) return null;
80424
+ return url.toString();
80425
+ } catch {
80426
+ return null;
80427
+ }
80428
+ }
80429
+ function isRecord$2(value) {
80430
+ return typeof value === "object" && value !== null && !Array.isArray(value);
80431
+ }
80432
+ //#endregion
79043
80433
  //#region src/features/host-router.ts
79044
80434
  /** 统一管理当前 Host/PeerHost 的完整作用域和 generation。 */
79045
80435
  var HostRouter = class {
@@ -79258,6 +80648,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
79258
80648
  /** Client 侧功能模块清单:新增模块在这里登记一行,不需要改动设置页和入口。 */
79259
80649
  const CLIENT_FEATURES = [
79260
80650
  pluginUpdateFeature,
80651
+ workspaceMcpFeature,
79261
80652
  lanAccessFeature,
79262
80653
  loginProtectionFeature,
79263
80654
  reverseProxyFeature,
@@ -79388,7 +80779,7 @@ button.${settingsPromoClass.version}:focus-visible{${focusRing}}
79388
80779
  return (0, react.createElement)("aside", {
79389
80780
  className: settingsPromoClass.root,
79390
80781
  "aria-label": t("settings.promo.sectionLabel")
79391
- }, (0, react.createElement)("div", { className: settingsPromoClass.row }, (0, react.createElement)("div", { className: settingsPromoClass.brand }, (0, react.createElement)("div", { className: settingsPromoClass.headline }, (0, react.createElement)(StarBurstIcon, { className: settingsPromoClass.logo }), (0, react.createElement)("h3", { className: settingsPromoClass.title }, t("common.brand"))), versionControl ?? (0, react.createElement)("span", { className: settingsPromoClass.version }, t("settings.promo.version", { version: "0.2.1-rc.5" }))), (0, react.createElement)("p", { className: settingsPromoClass.text }, t("settings.promo.starHint"), (0, react.createElement)("span", {
80782
+ }, (0, react.createElement)("div", { className: settingsPromoClass.row }, (0, react.createElement)("div", { className: settingsPromoClass.brand }, (0, react.createElement)("div", { className: settingsPromoClass.headline }, (0, react.createElement)(StarBurstIcon, { className: settingsPromoClass.logo }), (0, react.createElement)("h3", { className: settingsPromoClass.title }, t("common.brand"))), versionControl ?? (0, react.createElement)("span", { className: settingsPromoClass.version }, t("settings.promo.version", { version: "0.2.1-rc.7" }))), (0, react.createElement)("p", { className: settingsPromoClass.text }, t("settings.promo.starHint"), (0, react.createElement)("span", {
79392
80783
  className: settingsPromoClass.hand,
79393
80784
  "aria-hidden": true
79394
80785
  }, "👉")), (0, react.createElement)("a", {
@@ -79447,7 +80838,7 @@ button.${settingsPromoClass.version}:focus-visible{${focusRing}}
79447
80838
  }
79448
80839
  //#endregion
79449
80840
  //#region src/client/update-store.ts
79450
- const DEFAULT_PLUGIN_UPDATE_CHANNEL = "0.2.1-rc.5".includes("-") ? "next" : "latest";
80841
+ const DEFAULT_PLUGIN_UPDATE_CHANNEL = "0.2.1-rc.7".includes("-") ? "next" : "latest";
79451
80842
  var PluginUpdateStore = class {
79452
80843
  rpc;
79453
80844
  snapshot = {
@@ -79973,7 +81364,18 @@ button.${settingsPromoClass.version}:focus-visible{${focusRing}}
79973
81364
  ...require_theme.dshSettingsToastStyle,
79974
81365
  borderColor: toast.kind === "error" ? require_theme.dshThemeColor.error : toast.kind === "success" ? require_theme.dshThemeColor.success : require_theme.dshThemeColor.border
79975
81366
  }
79976
- }, toast.message), (0, react.createElement)(CodingNsSettingsUpdate, { services }), (0, react.createElement)("header", { style: require_theme.dshSettingsHeaderStyle }, (0, react.createElement)("p", { style: require_theme.dshSettingsSubtitleStyle }, t("settings.subtitle"))), (0, react.createElement)("div", { style: {
81367
+ }, toast.message), (0, react.createElement)(CodingNsSettingsUpdate, { services }), require_native_workspace_store.isDshVersionNewerThanTested(services.dshVersion) ? (0, react.createElement)("div", {
81368
+ role: "status",
81369
+ style: {
81370
+ padding: "10px 12px",
81371
+ border: `1px solid ${require_theme.dshThemeColor.warning}`,
81372
+ borderRadius: 6,
81373
+ background: require_theme.dshThemeColor.surfaceSubtle
81374
+ }
81375
+ }, t("settings.untestedDshWarning", {
81376
+ version: services.dshVersion,
81377
+ tested: require_native_workspace_store.DSH_TESTED_VERSION
81378
+ })) : null, (0, react.createElement)("header", { style: require_theme.dshSettingsHeaderStyle }, (0, react.createElement)("p", { style: require_theme.dshSettingsSubtitleStyle }, t("settings.subtitle"))), (0, react.createElement)("div", { style: {
79977
81379
  display: "flex",
79978
81380
  flexDirection: "column",
79979
81381
  gap: 12
@@ -80009,7 +81411,7 @@ button.${settingsPromoClass.version}:focus-visible{${focusRing}}
80009
81411
  border: `1px solid ${require_theme.dshThemeColor.border}`,
80010
81412
  borderRadius: 6,
80011
81413
  background: require_theme.dshThemeColor.surfaceSubtle
80012
- } }, (0, react.createElement)("div", void 0, t("settings.compatibility", { range: require_native_workspace_store.DSH_COMPATIBILITY })), (0, react.createElement)("a", {
81414
+ } }, (0, react.createElement)("div", void 0, t("settings.compatibility", { range: require_native_workspace_store.DSH_COMPATIBILITY })), (0, react.createElement)("div", void 0, t("settings.testedDshVersion", { version: require_native_workspace_store.DSH_TESTED_VERSION })), (0, react.createElement)("a", {
80013
81415
  href: CODINGNS_GITHUB_URL,
80014
81416
  target: "_blank",
80015
81417
  rel: "noreferrer",
@@ -85855,7 +87257,7 @@ button.${settingsPromoClass.version}:focus-visible{${focusRing}}
85855
87257
  function isInjectedStage0Runtime(scope = globalThis) {
85856
87258
  return scope[CODINGNS_STAGE0_GLOBAL] === true;
85857
87259
  }
85858
- route("plugin.update.inspect", "plugin-manager-inspect-021", "host", ">=0.2.1-rc.2 <=0.2.1-rc.2", "supported", ["dsh-capabilities/host/plugin-update-adapter.ts", "host/features/plugin-update.ts"]), route("plugin.update.apply", "plugin-manager-install-021", "host", ">=0.2.1-rc.2 <=0.2.1-rc.2", "supported", ["dsh-capabilities/host/plugin-update-adapter.ts", "host/update/service.ts"]), route("plugin.host.activation-status", "plugin-host-version-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/update/service.ts"]), route("plugin.client.reload-status", "plugin-client-reload-unavailable-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/client/plugin-reload-adapter.ts", "client/update-panel.ts"]), route("session.external-performance", "session-performance-projection-021", "host", ">=0.2.1-alpha.3 <=0.2.1-rc.3", "supported", ["dsh-capabilities/host/session-performance-adapter.ts", "host/cli-adapters/feature.ts"]), route("session.external-performance", "session-performance-presentation-021", "client", ">=0.2.1-alpha.3 <=0.2.1-rc.3", "supported", ["dsh-capabilities/client/session-performance-adapter.ts", "client/features/cli-adapters.ts"]), route("quick-app.proxy", "quick-app-host-proxy-021", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", [
87260
+ route("plugin.update.inspect", "plugin-manager-inspect-021", "host", ">=0.2.1-rc.2", "supported", ["dsh-capabilities/host/plugin-update-adapter.ts", "host/features/plugin-update.ts"]), route("plugin.update.apply", "plugin-manager-install-021", "host", ">=0.2.1-rc.2", "supported", ["dsh-capabilities/host/plugin-update-adapter.ts", "host/update/service.ts"]), route("plugin.host.activation-status", "plugin-host-version-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/update/service.ts"]), route("plugin.client.reload-status", "plugin-client-reload-unavailable-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/client/plugin-reload-adapter.ts", "client/update-panel.ts"]), route("session.external-performance", "session-performance-projection-021", "host", ">=0.2.1-alpha.3", "supported", ["dsh-capabilities/host/session-performance-adapter.ts", "host/cli-adapters/feature.ts"]), route("session.external-performance", "session-performance-presentation-021", "client", ">=0.2.1-alpha.3", "supported", ["dsh-capabilities/client/session-performance-adapter.ts", "client/features/cli-adapters.ts"]), route("quick-app.proxy", "quick-app-host-proxy-021", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", [
85859
87261
  "dsh-capabilities/host/quick-app-proxy-adapter.ts",
85860
87262
  "dsh-capabilities/host/quick-app-proxy-provider.ts",
85861
87263
  "host/features/quick-apps.ts",
@@ -85871,22 +87273,22 @@ button.${settingsPromoClass.version}:focus-visible{${focusRing}}
85871
87273
  "dsh-capabilities/host/quick-app-transport.ts",
85872
87274
  "host/features/quick-apps.ts",
85873
87275
  "host/features/lan-access-dsh.ts"
85874
- ]), route("sidebar.footer-action", "sidebar-footer-action-021", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/client/quick-app-footer-adapter.ts", "client/features/quick-apps.ts"]), route("session.prompt-assembly", "session-prompt-assembly-021", "host", ">=0.2.1-alpha.3 <=0.2.1-rc.3", "supported", [
87276
+ ]), route("sidebar.footer-action", "sidebar-footer-action-021", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/client/quick-app-footer-adapter.ts", "client/features/quick-apps.ts"]), route("session.prompt-assembly", "session-prompt-assembly-021", "host", ">=0.2.1-alpha.3", "supported", [
85875
87277
  "dsh-capabilities/host/session-prompt-adapter.ts",
85876
87278
  "host/features/session-prompt-translation.ts",
85877
87279
  "host/cli-adapters/feature.ts"
85878
- ]), route("session.external-model-selection", "session-external-model-selection-021", "host", ">=0.2.1-alpha.3 <=0.2.1-rc.3", "supported", ["dsh-capabilities/host/session-model-selection-adapter.ts", "host/cli-adapters/feature.ts"]), route("session.activation", "session-activation-020", "host", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["dsh-capabilities/host/session-activation-adapter.ts", "host/native-session-bridge.ts"]), route("session.activation", "session-activation-021", "host", ">=0.2.1-alpha.3 <=0.2.1-rc.3", "supported", ["dsh-capabilities/host/session-activation-adapter.ts", "host/native-session-bridge.ts"]), route("conversation.message-presentation", "message-presentation-020", "client", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["dsh-capabilities/client/message-presentation-adapter.ts", "client/session-translation-chat.ts"]), route("conversation.message-presentation", "message-presentation-021", "client", ">=0.2.1-alpha.3 <=0.2.1-rc.3", "supported", ["dsh-capabilities/client/message-presentation-adapter.ts", "client/session-translation-chat.ts"]), route("connection.peer", "connection.peer-021", "host", ">=0.2.1-alpha.3 <=0.2.1-rc.3", "supported", [
87280
+ ]), route("session.external-model-selection", "session-external-model-selection-021", "host", ">=0.2.1-alpha.3", "supported", ["dsh-capabilities/host/session-model-selection-adapter.ts", "host/cli-adapters/feature.ts"]), route("session.activation", "session-activation-020", "host", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["dsh-capabilities/host/session-activation-adapter.ts", "host/native-session-bridge.ts"]), route("session.activation", "session-activation-021", "host", ">=0.2.1-alpha.3", "supported", ["dsh-capabilities/host/session-activation-adapter.ts", "host/native-session-bridge.ts"]), route("workspace.session-control", "workspace-session-control-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/host/workspace-session-control-adapter.ts", "host/workspace-mcp/tools.ts"]), route("workspace.pending-questions", "workspace-pending-questions-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/host/workspace-pending-questions-adapter.ts", "host/workspace-mcp/tools.ts"]), route("workspace.approval", "workspace-approval-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/host/workspace-approval-adapter.ts", "host/workspace-mcp/tools.ts"]), route("conversation.message-presentation", "message-presentation-020", "client", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["dsh-capabilities/client/message-presentation-adapter.ts", "client/session-translation-chat.ts"]), route("conversation.message-presentation", "message-presentation-021", "client", ">=0.2.1-alpha.3", "supported", ["dsh-capabilities/client/message-presentation-adapter.ts", "client/session-translation-chat.ts"]), route("connection.peer", "connection.peer-021", "host", ">=0.2.1-alpha.3", "supported", [
85879
87281
  "dsh-capabilities/host/connection-peer-adapter.ts",
85880
87282
  "host/rpc.ts",
85881
87283
  "host/features/global-voice-rpc.ts",
85882
87284
  "host/modules/peer-host/peer-host-native-dispatch.ts"
85883
- ]), route("connection.uplink", "connection.uplink-021", "host", ">=0.2.1-alpha.3 <=0.2.1-rc.3", "supported", ["dsh-capabilities/host/native-dispatch-adapter.ts", "host/modules/peer-host/peer-host-native-dispatch.ts"]), route("session.title", "session-title-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/host/session-title-adapter.ts", "host/features/session-title-optimization.ts"]), route("session.working-directory", "session-working-directory-021", "host", ">=0.2.1-alpha.2", "supported", ["host/terminal/terminal-controller.ts", "host/index.ts"]), route("llm.text", "llm-text-021", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", [
87285
+ ]), route("connection.uplink", "connection.uplink-021", "host", ">=0.2.1-alpha.3", "supported", ["dsh-capabilities/host/native-dispatch-adapter.ts", "host/modules/peer-host/peer-host-native-dispatch.ts"]), route("session.title", "session-title-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/host/session-title-adapter.ts", "host/features/session-title-optimization.ts"]), route("session.working-directory", "session-working-directory-021", "host", ">=0.2.1-alpha.2", "supported", ["host/terminal/terminal-controller.ts", "host/index.ts"]), route("llm.text", "llm-text-021", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", [
85884
87286
  "dsh-capabilities/host/assistant-llm-adapter.ts",
85885
87287
  "host/features/assistant-text-chat.ts",
85886
87288
  "dsh-capabilities/host/session-title-adapter.ts",
85887
87289
  "host/features/session-title-optimization.ts",
85888
87290
  "host/features/git-management.ts"
85889
- ]), route("assistant.agent", "assistant-agent-021", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/host/assistant-agent-adapter.ts", "host/features/global-voice-rpc.ts"]), route("settings.store", "legacy-settings-scope", "host", ">=0.1.5-rc.3 <=0.1.6", "supported", ["host/settings.ts", "host/features/*"]), route("settings.store", "config-forms", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/settings.ts", "client/settings-bridge.ts"]), route("connection.rpc", "legacy-rpc-handler", "host", ">=0.1.5-rc.3 <=0.1.6", "supported", ["host/rpc.ts"]), route("connection.rpc", "peer-aware-rpc-handler", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/rpc.ts"]), route("connection.peer", "peer-scope", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/rpc.ts"]), route("ui.icon.plus", "fixed-plus-icon", "client", ">=0.1.5-rc.3 <=0.1.6", "supported", ["client/terminal/xterm-view.ts"]), route("ui.icon.plus", "regular-plus-icon", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/terminal/xterm-view.ts"]), route("ui.icon.chevron", "fixed-chevron-icon", "client", ">=0.1.5-rc.3 <=0.1.6", "supported", ["client/terminal/ui.ts"]), route("ui.icon.chevron", "regular-chevron-icon", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/terminal/ui.ts"]), route("locale.runtime", "locale-runtime", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/locale.ts"]), route("theme.runtime", "theme-runtime", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/theme.ts"]), route("conversation.tool-call", "conversation-events", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/external-tool-stream.ts"]), route("sidebar.right", "sidebar-right-tabs", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/terminal/ui.ts"]), route("sidebar.global-panel", "sidebar-panellist-main-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/client/global-panel-adapter.ts", "client/features/magpie-management.ts"]), route("typert.remote", "remote-result", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/terminal/terminal-controller.ts", "client/terminal/model.ts"]), route("peer-host.store", "peer-host-store", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.handshake", "peer-host-handshake", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.http-proxy", "peer-host-http-proxy", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.ws-proxy", "peer-host-ws-proxy", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.aggregate", "peer-host-aggregate", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.relay-route", "peer-host-relay-route", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.native-navigation", "peer-host-native-navigation-legacy", "client", ">=0.1.5-rc.3 <=0.1.6", "deprecated", ["client/features/peer-host.ts"]), route("peer-host.native-navigation", "peer-host-native-navigation-modern", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/features/peer-host.ts"]), route("peer-host.remote-web-context-fallback", "peer-host-remote-web-context-fallback", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/features/peer-host.ts"]), route("settings.store", "settings-forms-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/settings.ts", "host/rpc.ts"]), route("connection.rpc", "connection-rpc-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/rpc.ts", "transport/dsh-transport.ts"]), route("connection.peer", "connection-peer-admission-020", "host", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["host/rpc.ts"]), route("connection.attachment", "connection-rpc-attachment-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/rpc.ts", "transport/dsh-transport.ts"]), route("connection.uplink", "connection-rpc-uplink-020", "host", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["host/rpc.ts", "transport/dsh-transport.ts"]), route("typert.remote", "remote-context-stream-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/terminal/terminal-controller.ts", "client/terminal/model.ts"]), route("typert.context", "typert-context-registry-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.host.ts", "host/terminal/terminal-controller.ts"]), route("typert.stream", "typert-remote-stream-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.host.ts", "typert.remote-client.ts"]), route("session.format-v4", "session-format-v4", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/native-session-bridge.ts", "host/session-migration-repair.ts"]), route("subagent.continuable", "subagent-continuable-020", "host", ">=0.2.0-rc.1 <=0.2.1-alpha.1", "supported", ["host/cli-adapters/session-store.ts", "host/cli-adapters/feature.ts"]), route("subagent.continuable", "subagent-activation-021", "host", ">=0.2.1-alpha.2", "supported", ["host/cli-adapters/native-team-subagent.ts", "host/cli-adapters/native-subagent-dispatch.ts"]), route("agent-team.native", "agent-team-native-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/cli-adapters/feature.ts", "host/cli-adapters/native-team-proxy.ts"]), route("agent-team.external-member", "agent-team-external-member-021", "host", ">=0.2.1-alpha.2 <=0.2.1-rc.3", "supported", ["host/cli-adapters/feature.ts", "host/cli-bridge/team-dispatch.ts"]), route("agent-team.external-lead", "agent-team-external-lead-021", "host", ">=0.2.1-alpha.2 <=0.2.1-rc.3", "supported", ["host/cli-adapters/feature.ts", "host/cli-bridge/team-dispatch.ts"]), route("ui.icon.plus", "regular-plus-icon-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/xterm-view.ts"]), route("ui.icon.chevron", "regular-chevron-icon-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/ui.ts"]), route("locale.runtime", "locale-runtime-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/locale.ts"]), route("theme.runtime", "theme-runtime-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/theme.ts"]), route("theme.font-scale", "theme-font-scale-021", "client", ">=0.2.1-alpha.2", "supported", ["client/font-scale.ts", "client/index.ts"]), route("conversation.tool-call", "conversation-events-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/external-tool-stream.ts"]), route("conversation.draft-share", "conversation-draft-share-021", "client", ">=0.2.1-alpha.1 <=0.2.1-rc.3", "supported", ["client/terminal/ui.ts", "client/terminal/sharing.ts"]), route("conversation.interaction-translation", "interaction-presentation-021", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/session-translation-interactions.ts"]), route("sidebar.right", "sidebar-right-dock-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/ui.ts"]), route("typert.remote", "remote-context-stream-020-client", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/model.ts"]), route("typert.context", "typert-context-registry-020-client", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.remote-client.ts", "client/terminal/model.ts"]), route("typert.stream", "typert-remote-stream-020-client", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.remote-client.ts", "client/terminal/model.ts"]), route("client.boot-graph", "client-web-boot-graph-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/index.ts", "package.json"]), route("peer-host.native-navigation", "peer-host-native-navigation-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/features/peer-host.ts"]), route("peer-host.remote-web-context-fallback", "peer-host-remote-web-context-fallback-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/features/peer-host.ts"]), route("peer-host.store", "peer-host-store-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.handshake", "peer-host-handshake-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.http-proxy", "peer-host-http-proxy-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts", "host/modules/peer-host/quick-app-gateway.ts"]), route("peer-host.ws-proxy", "peer-host-ws-proxy-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.aggregate", "peer-host-aggregate-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.aggregated-transport", "peer-host-aggregated-transport-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/modules/peer-host/aggregated-host-transport.ts"]), route("peer-host.client-preboot-transport", "peer-host-client-preboot-transport-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", [
87291
+ ]), route("assistant.agent", "assistant-agent-021", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/host/assistant-agent-adapter.ts", "host/features/global-voice-rpc.ts"]), route("settings.store", "legacy-settings-scope", "host", ">=0.1.5-rc.3 <=0.1.6", "supported", ["host/settings.ts", "host/features/*"]), route("settings.store", "config-forms", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/settings.ts", "client/settings-bridge.ts"]), route("connection.rpc", "legacy-rpc-handler", "host", ">=0.1.5-rc.3 <=0.1.6", "supported", ["host/rpc.ts"]), route("connection.rpc", "peer-aware-rpc-handler", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/rpc.ts"]), route("connection.peer", "peer-scope", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/rpc.ts"]), route("ui.icon.plus", "fixed-plus-icon", "client", ">=0.1.5-rc.3 <=0.1.6", "supported", ["client/terminal/xterm-view.ts"]), route("ui.icon.plus", "regular-plus-icon", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/terminal/xterm-view.ts"]), route("ui.icon.chevron", "fixed-chevron-icon", "client", ">=0.1.5-rc.3 <=0.1.6", "supported", ["client/terminal/ui.ts"]), route("ui.icon.chevron", "regular-chevron-icon", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/terminal/ui.ts"]), route("locale.runtime", "locale-runtime", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/locale.ts"]), route("theme.runtime", "theme-runtime", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/theme.ts"]), route("conversation.tool-call", "conversation-events", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/external-tool-stream.ts"]), route("sidebar.right", "sidebar-right-tabs", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/terminal/ui.ts"]), route("sidebar.global-panel", "sidebar-panellist-main-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/client/global-panel-adapter.ts", "client/features/magpie-management.ts"]), route("typert.remote", "remote-result", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/terminal/terminal-controller.ts", "client/terminal/model.ts"]), route("peer-host.store", "peer-host-store", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.handshake", "peer-host-handshake", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.http-proxy", "peer-host-http-proxy", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.ws-proxy", "peer-host-ws-proxy", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.aggregate", "peer-host-aggregate", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.relay-route", "peer-host-relay-route", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.native-navigation", "peer-host-native-navigation-legacy", "client", ">=0.1.5-rc.3 <=0.1.6", "deprecated", ["client/features/peer-host.ts"]), route("peer-host.native-navigation", "peer-host-native-navigation-modern", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/features/peer-host.ts"]), route("peer-host.remote-web-context-fallback", "peer-host-remote-web-context-fallback", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/features/peer-host.ts"]), route("settings.store", "settings-forms-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/settings.ts", "host/rpc.ts"]), route("connection.rpc", "connection-rpc-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/rpc.ts", "transport/dsh-transport.ts"]), route("connection.peer", "connection-peer-admission-020", "host", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["host/rpc.ts"]), route("connection.attachment", "connection-rpc-attachment-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/rpc.ts", "transport/dsh-transport.ts"]), route("connection.uplink", "connection-rpc-uplink-020", "host", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["host/rpc.ts", "transport/dsh-transport.ts"]), route("typert.remote", "remote-context-stream-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/terminal/terminal-controller.ts", "client/terminal/model.ts"]), route("typert.context", "typert-context-registry-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.host.ts", "host/terminal/terminal-controller.ts"]), route("typert.stream", "typert-remote-stream-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.host.ts", "typert.remote-client.ts"]), route("session.format-v4", "session-format-v4", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/native-session-bridge.ts", "host/session-migration-repair.ts"]), route("subagent.continuable", "subagent-continuable-020", "host", ">=0.2.0-rc.1 <=0.2.1-alpha.1", "supported", ["host/cli-adapters/session-store.ts", "host/cli-adapters/feature.ts"]), route("subagent.continuable", "subagent-activation-021", "host", ">=0.2.1-alpha.2", "supported", ["host/cli-adapters/native-team-subagent.ts", "host/cli-adapters/native-subagent-dispatch.ts"]), route("agent-team.native", "agent-team-native-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/cli-adapters/feature.ts", "host/cli-adapters/native-team-proxy.ts"]), route("agent-team.external-member", "agent-team-external-member-021", "host", ">=0.2.1-alpha.2", "supported", ["host/cli-adapters/feature.ts", "host/cli-bridge/team-dispatch.ts"]), route("agent-team.external-lead", "agent-team-external-lead-021", "host", ">=0.2.1-alpha.2", "supported", ["host/cli-adapters/feature.ts", "host/cli-bridge/team-dispatch.ts"]), route("ui.icon.plus", "regular-plus-icon-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/xterm-view.ts"]), route("ui.icon.chevron", "regular-chevron-icon-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/ui.ts"]), route("locale.runtime", "locale-runtime-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/locale.ts"]), route("theme.runtime", "theme-runtime-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/theme.ts"]), route("theme.font-scale", "theme-font-scale-021", "client", ">=0.2.1-alpha.2", "supported", ["client/font-scale.ts", "client/index.ts"]), route("conversation.tool-call", "conversation-events-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/external-tool-stream.ts"]), route("conversation.draft-share", "conversation-draft-share-021", "client", ">=0.2.1-alpha.1", "supported", ["client/terminal/ui.ts", "client/terminal/sharing.ts"]), route("conversation.interaction-translation", "interaction-presentation-021", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/session-translation-interactions.ts"]), route("sidebar.right", "sidebar-right-dock-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/ui.ts"]), route("typert.remote", "remote-context-stream-020-client", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/model.ts"]), route("typert.context", "typert-context-registry-020-client", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.remote-client.ts", "client/terminal/model.ts"]), route("typert.stream", "typert-remote-stream-020-client", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.remote-client.ts", "client/terminal/model.ts"]), route("client.boot-graph", "client-web-boot-graph-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/index.ts", "package.json"]), route("peer-host.native-navigation", "peer-host-native-navigation-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/features/peer-host.ts"]), route("peer-host.remote-web-context-fallback", "peer-host-remote-web-context-fallback-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/features/peer-host.ts"]), route("peer-host.store", "peer-host-store-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.handshake", "peer-host-handshake-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.http-proxy", "peer-host-http-proxy-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts", "host/modules/peer-host/quick-app-gateway.ts"]), route("peer-host.ws-proxy", "peer-host-ws-proxy-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.aggregate", "peer-host-aggregate-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.aggregated-transport", "peer-host-aggregated-transport-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/modules/peer-host/aggregated-host-transport.ts"]), route("peer-host.client-preboot-transport", "peer-host-client-preboot-transport-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", [
85890
87292
  "bootstrap/index.ts",
85891
87293
  "host/index-injection.ts",
85892
87294
  "client/features/peer-host.ts"
@@ -91907,5 +93309,5 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
91907
93309
  });
91908
93310
 
91909
93311
  })();
91910
- // codingns-client-revision: cdc65a7993088d3811defac6055cbb865cf55f0c7e8f63cba0776f815335e082
93312
+ // codingns-client-revision: b72c0083de197d850d138dad49153dd85be9eb7fa81595c4642289baac3e4baf
91911
93313
  //# sourceMappingURL=bundle.js.map