@jingyi0605/codingns4dsh 0.2.1-beta.13 → 0.2.1-beta.15

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 (392) hide show
  1. package/README.en.md +5 -5
  2. package/README.md +6 -9
  3. package/data/build/dist/bootstrap/dsh-connection-adapter.d.ts +1 -1
  4. package/data/build/dist/bootstrap/dsh-connection-adapter.d.ts.map +1 -1
  5. package/data/build/dist/bootstrap/index.d.ts +1 -1
  6. package/data/build/dist/bootstrap/index.d.ts.map +1 -1
  7. package/data/build/dist/client/bundle.js +1947 -585
  8. package/data/build/dist/client/bundle.js.map +1 -1
  9. package/data/build/dist/client/cli-slots.d.ts.map +1 -1
  10. package/data/build/dist/client/cli-slots.js +11 -3
  11. package/data/build/dist/client/cli-slots.js.map +1 -1
  12. package/data/build/dist/client/client.model-catalog-cache.js +9 -1
  13. package/data/build/dist/client/client.model-catalog-cache.js.map +1 -1
  14. package/data/build/dist/client/client.native-workspace-store.js +65 -15
  15. package/data/build/dist/client/client.native-workspace-store.js.map +1 -1
  16. package/data/build/dist/client/client.transport.js +70 -4
  17. package/data/build/dist/client/client.transport.js.map +1 -1
  18. package/data/build/dist/client/desktop-assistant.js +180 -114
  19. package/data/build/dist/client/features/cli-adapters.js +4 -2
  20. package/data/build/dist/client/features/cli-adapters.js.map +1 -1
  21. package/data/build/dist/client/features/file-management.d.ts.map +1 -1
  22. package/data/build/dist/client/features/file-management.js +16 -0
  23. package/data/build/dist/client/features/file-management.js.map +1 -1
  24. package/data/build/dist/client/features/lan-access-panel.d.ts.map +1 -1
  25. package/data/build/dist/client/features/lan-access-panel.js +1 -0
  26. package/data/build/dist/client/features/lan-access-panel.js.map +1 -1
  27. package/data/build/dist/client/features/mobile-access.d.ts.map +1 -1
  28. package/data/build/dist/client/features/mobile-access.js +7 -0
  29. package/data/build/dist/client/features/mobile-access.js.map +1 -1
  30. package/data/build/dist/client/features/peer-host.d.ts.map +1 -1
  31. package/data/build/dist/client/features/peer-host.js +3 -0
  32. package/data/build/dist/client/features/peer-host.js.map +1 -1
  33. package/data/build/dist/client/features/session-translation.js +2 -2
  34. package/data/build/dist/client/features/session-translation.js.map +1 -1
  35. package/data/build/dist/client/features/workspace-session-enhancement.d.ts.map +1 -1
  36. package/data/build/dist/client/features/workspace-session-enhancement.js +6 -0
  37. package/data/build/dist/client/features/workspace-session-enhancement.js.map +1 -1
  38. package/data/build/dist/client/file-management-dom.d.ts +20 -1
  39. package/data/build/dist/client/file-management-dom.d.ts.map +1 -1
  40. package/data/build/dist/client/file-management-dom.js +94 -18
  41. package/data/build/dist/client/file-management-dom.js.map +1 -1
  42. package/data/build/dist/client/file-viewer-copy-path-menu.d.ts +27 -0
  43. package/data/build/dist/client/file-viewer-copy-path-menu.d.ts.map +1 -0
  44. package/data/build/dist/client/file-viewer-copy-path-menu.js +101 -0
  45. package/data/build/dist/client/file-viewer-copy-path-menu.js.map +1 -0
  46. package/data/build/dist/client/git-management-settings.d.ts +4 -0
  47. package/data/build/dist/client/git-management-settings.d.ts.map +1 -0
  48. package/data/build/dist/client/git-management-settings.js +73 -0
  49. package/data/build/dist/client/git-management-settings.js.map +1 -0
  50. package/data/build/dist/client/git-management.d.ts +2 -1
  51. package/data/build/dist/client/git-management.d.ts.map +1 -1
  52. package/data/build/dist/client/git-management.js +55 -34
  53. package/data/build/dist/client/git-management.js.map +1 -1
  54. package/data/build/dist/client/git-panel-styles.d.ts +4 -0
  55. package/data/build/dist/client/git-panel-styles.d.ts.map +1 -1
  56. package/data/build/dist/client/git-panel-styles.js +14 -0
  57. package/data/build/dist/client/git-panel-styles.js.map +1 -1
  58. package/data/build/dist/client/locale.d.ts.map +1 -1
  59. package/data/build/dist/client/locale.js +10 -2
  60. package/data/build/dist/client/locale.js.map +1 -1
  61. package/data/build/dist/client/locales/cliManagement.d.ts.map +1 -1
  62. package/data/build/dist/client/locales/cliManagement.js +16 -0
  63. package/data/build/dist/client/locales/cliManagement.js.map +1 -1
  64. package/data/build/dist/client/locales/git.d.ts.map +1 -1
  65. package/data/build/dist/client/locales/git.js +30 -2
  66. package/data/build/dist/client/locales/git.js.map +1 -1
  67. package/data/build/dist/client/locales/peerHost.d.ts.map +1 -1
  68. package/data/build/dist/client/locales/peerHost.js +2 -0
  69. package/data/build/dist/client/locales/peerHost.js.map +1 -1
  70. package/data/build/dist/client/locales/quickApps.d.ts +6 -0
  71. package/data/build/dist/client/locales/quickApps.d.ts.map +1 -1
  72. package/data/build/dist/client/locales/quickApps.js +12 -0
  73. package/data/build/dist/client/locales/quickApps.js.map +1 -1
  74. package/data/build/dist/client/mobile-team-panel-dom.d.ts +14 -0
  75. package/data/build/dist/client/mobile-team-panel-dom.d.ts.map +1 -0
  76. package/data/build/dist/client/mobile-team-panel-dom.js +164 -0
  77. package/data/build/dist/client/mobile-team-panel-dom.js.map +1 -0
  78. package/data/build/dist/client/model-priority-pool.d.ts +23 -0
  79. package/data/build/dist/client/model-priority-pool.d.ts.map +1 -0
  80. package/data/build/dist/client/{session-translation-model-pool.js → model-priority-pool.js} +8 -9
  81. package/data/build/dist/client/model-priority-pool.js.map +1 -0
  82. package/data/build/dist/client/provider-icons.d.ts.map +1 -1
  83. package/data/build/dist/client/provider-icons.js +3 -1
  84. package/data/build/dist/client/provider-icons.js.map +1 -1
  85. package/data/build/dist/client/quick-apps/browser-storage.d.ts +24 -0
  86. package/data/build/dist/client/quick-apps/browser-storage.d.ts.map +1 -0
  87. package/data/build/dist/client/quick-apps/browser-storage.js +114 -0
  88. package/data/build/dist/client/quick-apps/browser-storage.js.map +1 -0
  89. package/data/build/dist/client/quick-apps/client.d.ts +3 -1
  90. package/data/build/dist/client/quick-apps/client.d.ts.map +1 -1
  91. package/data/build/dist/client/quick-apps/client.js +4 -4
  92. package/data/build/dist/client/quick-apps/client.js.map +1 -1
  93. package/data/build/dist/client/quick-apps/launcher.d.ts.map +1 -1
  94. package/data/build/dist/client/quick-apps/launcher.js +23 -8
  95. package/data/build/dist/client/quick-apps/launcher.js.map +1 -1
  96. package/data/build/dist/client/quick-apps/presentation.d.ts.map +1 -1
  97. package/data/build/dist/client/quick-apps/presentation.js +18 -2
  98. package/data/build/dist/client/quick-apps/presentation.js.map +1 -1
  99. package/data/build/dist/client/quick-apps/rail-preference.d.ts +5 -0
  100. package/data/build/dist/client/quick-apps/rail-preference.d.ts.map +1 -0
  101. package/data/build/dist/client/quick-apps/rail-preference.js +19 -0
  102. package/data/build/dist/client/quick-apps/rail-preference.js.map +1 -0
  103. package/data/build/dist/client/quick-apps/styles.d.ts.map +1 -1
  104. package/data/build/dist/client/quick-apps/styles.js +12 -2
  105. package/data/build/dist/client/quick-apps/styles.js.map +1 -1
  106. package/data/build/dist/client/quick-apps/viewer.d.ts.map +1 -1
  107. package/data/build/dist/client/quick-apps/viewer.js +13 -3
  108. package/data/build/dist/client/quick-apps/viewer.js.map +1 -1
  109. package/data/build/dist/client/style.css +219 -219
  110. package/data/build/dist/client/workspace-session-rightbar-dom.d.ts.map +1 -1
  111. package/data/build/dist/client/workspace-session-rightbar-dom.js +12 -21
  112. package/data/build/dist/client/workspace-session-rightbar-dom.js.map +1 -1
  113. package/data/build/dist/client/workspace-session-visibility-dom.d.ts +3 -0
  114. package/data/build/dist/client/workspace-session-visibility-dom.d.ts.map +1 -1
  115. package/data/build/dist/client/workspace-session-visibility-dom.js +43 -10
  116. package/data/build/dist/client/workspace-session-visibility-dom.js.map +1 -1
  117. package/data/build/dist/dsh-capabilities/client/composer-presentation-adapter.d.ts +8 -0
  118. package/data/build/dist/dsh-capabilities/client/composer-presentation-adapter.d.ts.map +1 -0
  119. package/data/build/dist/dsh-capabilities/client/composer-presentation-adapter.js +71 -0
  120. package/data/build/dist/dsh-capabilities/client/composer-presentation-adapter.js.map +1 -0
  121. package/data/build/dist/dsh-capabilities/client/peer-host-attachment-adapter.d.ts +3 -0
  122. package/data/build/dist/dsh-capabilities/client/peer-host-attachment-adapter.d.ts.map +1 -0
  123. package/data/build/dist/dsh-capabilities/client/peer-host-attachment-adapter.js +27 -0
  124. package/data/build/dist/dsh-capabilities/client/peer-host-attachment-adapter.js.map +1 -0
  125. package/data/build/dist/dsh-capabilities/client/session-performance-adapter.d.ts +2 -1
  126. package/data/build/dist/dsh-capabilities/client/session-performance-adapter.d.ts.map +1 -1
  127. package/data/build/dist/dsh-capabilities/client/session-performance-adapter.js +22 -47
  128. package/data/build/dist/dsh-capabilities/client/session-performance-adapter.js.map +1 -1
  129. package/data/build/dist/dsh-capabilities/host/agent-team-adapter.d.ts +52 -0
  130. package/data/build/dist/dsh-capabilities/host/agent-team-adapter.d.ts.map +1 -0
  131. package/data/build/dist/dsh-capabilities/host/agent-team-adapter.js +109 -0
  132. package/data/build/dist/dsh-capabilities/host/agent-team-adapter.js.map +1 -0
  133. package/data/build/dist/dsh-capabilities/host/quick-app-proxy-provider.js +1 -1
  134. package/data/build/dist/dsh-capabilities/host/quick-app-proxy-provider.js.map +1 -1
  135. package/data/build/dist/dsh-capabilities/matrix.d.ts.map +1 -1
  136. package/data/build/dist/dsh-capabilities/matrix.js +12 -10
  137. package/data/build/dist/dsh-capabilities/matrix.js.map +1 -1
  138. package/data/build/dist/dsh-capabilities/routes.d.ts.map +1 -1
  139. package/data/build/dist/dsh-capabilities/routes.js +13 -8
  140. package/data/build/dist/dsh-capabilities/routes.js.map +1 -1
  141. package/data/build/dist/dsh-capabilities/types.d.ts +1 -1
  142. package/data/build/dist/dsh-capabilities/types.d.ts.map +1 -1
  143. package/data/build/dist/dsh-capabilities/types.js.map +1 -1
  144. package/data/build/dist/host/cli-adapters/acp-cli-driver.d.ts.map +1 -1
  145. package/data/build/dist/host/cli-adapters/acp-cli-driver.js +6 -3
  146. package/data/build/dist/host/cli-adapters/acp-cli-driver.js.map +1 -1
  147. package/data/build/dist/host/cli-adapters/claude-driver.d.ts.map +1 -1
  148. package/data/build/dist/host/cli-adapters/claude-driver.js +4 -0
  149. package/data/build/dist/host/cli-adapters/claude-driver.js.map +1 -1
  150. package/data/build/dist/host/cli-adapters/codex-driver.d.ts.map +1 -1
  151. package/data/build/dist/host/cli-adapters/codex-driver.js +13 -6
  152. package/data/build/dist/host/cli-adapters/codex-driver.js.map +1 -1
  153. package/data/build/dist/host/cli-adapters/command-code-acp-loader.d.ts.map +1 -1
  154. package/data/build/dist/host/cli-adapters/command-code-acp-loader.js +11 -1
  155. package/data/build/dist/host/cli-adapters/command-code-acp-loader.js.map +1 -1
  156. package/data/build/dist/host/cli-adapters/command-code-driver.js +5 -3
  157. package/data/build/dist/host/cli-adapters/command-code-driver.js.map +1 -1
  158. package/data/build/dist/host/cli-adapters/desktop-app-runtime.d.ts +3 -1
  159. package/data/build/dist/host/cli-adapters/desktop-app-runtime.d.ts.map +1 -1
  160. package/data/build/dist/host/cli-adapters/desktop-app-runtime.js +41 -4
  161. package/data/build/dist/host/cli-adapters/desktop-app-runtime.js.map +1 -1
  162. package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts.map +1 -1
  163. package/data/build/dist/host/cli-adapters/dsh-message-projector.js +2 -1
  164. package/data/build/dist/host/cli-adapters/dsh-message-projector.js.map +1 -1
  165. package/data/build/dist/host/cli-adapters/dsh-tool-history.js +3 -2
  166. package/data/build/dist/host/cli-adapters/dsh-tool-history.js.map +1 -1
  167. package/data/build/dist/host/cli-adapters/dsh-virtual-providers.d.ts.map +1 -1
  168. package/data/build/dist/host/cli-adapters/dsh-virtual-providers.js +3 -2
  169. package/data/build/dist/host/cli-adapters/dsh-virtual-providers.js.map +1 -1
  170. package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
  171. package/data/build/dist/host/cli-adapters/feature.js +134 -29
  172. package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
  173. package/data/build/dist/host/cli-adapters/gemini-driver.d.ts.map +1 -1
  174. package/data/build/dist/host/cli-adapters/gemini-driver.js +4 -2
  175. package/data/build/dist/host/cli-adapters/gemini-driver.js.map +1 -1
  176. package/data/build/dist/host/cli-adapters/grok-driver.d.ts +4 -0
  177. package/data/build/dist/host/cli-adapters/grok-driver.d.ts.map +1 -1
  178. package/data/build/dist/host/cli-adapters/grok-driver.js +183 -9
  179. package/data/build/dist/host/cli-adapters/grok-driver.js.map +1 -1
  180. package/data/build/dist/host/cli-adapters/grok-performance-projection.d.ts.map +1 -1
  181. package/data/build/dist/host/cli-adapters/grok-performance-projection.js +2 -1
  182. package/data/build/dist/host/cli-adapters/grok-performance-projection.js.map +1 -1
  183. package/data/build/dist/host/cli-adapters/legacy-session-adapter.d.ts.map +1 -1
  184. package/data/build/dist/host/cli-adapters/legacy-session-adapter.js +20 -3
  185. package/data/build/dist/host/cli-adapters/legacy-session-adapter.js.map +1 -1
  186. package/data/build/dist/host/cli-adapters/management-methods.d.ts +5 -0
  187. package/data/build/dist/host/cli-adapters/management-methods.d.ts.map +1 -1
  188. package/data/build/dist/host/cli-adapters/management-methods.js +9 -0
  189. package/data/build/dist/host/cli-adapters/management-methods.js.map +1 -1
  190. package/data/build/dist/host/cli-adapters/management-process.d.ts.map +1 -1
  191. package/data/build/dist/host/cli-adapters/management-process.js +13 -2
  192. package/data/build/dist/host/cli-adapters/management-process.js.map +1 -1
  193. package/data/build/dist/host/cli-adapters/management.d.ts.map +1 -1
  194. package/data/build/dist/host/cli-adapters/management.js +6 -1
  195. package/data/build/dist/host/cli-adapters/management.js.map +1 -1
  196. package/data/build/dist/host/cli-adapters/mcode-driver.d.ts.map +1 -1
  197. package/data/build/dist/host/cli-adapters/mcode-driver.js +11 -4
  198. package/data/build/dist/host/cli-adapters/mcode-driver.js.map +1 -1
  199. package/data/build/dist/host/cli-adapters/native-subagent-dispatch.d.ts +1 -1
  200. package/data/build/dist/host/cli-adapters/native-subagent-dispatch.d.ts.map +1 -1
  201. package/data/build/dist/host/cli-adapters/native-subagent-dispatch.js +11 -3
  202. package/data/build/dist/host/cli-adapters/native-subagent-dispatch.js.map +1 -1
  203. package/data/build/dist/host/cli-adapters/native-team-subagent.d.ts +7 -1
  204. package/data/build/dist/host/cli-adapters/native-team-subagent.d.ts.map +1 -1
  205. package/data/build/dist/host/cli-adapters/native-team-subagent.js +4 -2
  206. package/data/build/dist/host/cli-adapters/native-team-subagent.js.map +1 -1
  207. package/data/build/dist/host/cli-adapters/opencode-v2-protocol.js +3 -1
  208. package/data/build/dist/host/cli-adapters/opencode-v2-protocol.js.map +1 -1
  209. package/data/build/dist/host/cli-adapters/pi-driver.d.ts.map +1 -1
  210. package/data/build/dist/host/cli-adapters/pi-driver.js +44 -10
  211. package/data/build/dist/host/cli-adapters/pi-driver.js.map +1 -1
  212. package/data/build/dist/host/cli-adapters/registry.d.ts +4 -1
  213. package/data/build/dist/host/cli-adapters/registry.d.ts.map +1 -1
  214. package/data/build/dist/host/cli-adapters/registry.js +65 -25
  215. package/data/build/dist/host/cli-adapters/registry.js.map +1 -1
  216. package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts.map +1 -1
  217. package/data/build/dist/host/cli-adapters/standard-stream-driver.js +4 -0
  218. package/data/build/dist/host/cli-adapters/standard-stream-driver.js.map +1 -1
  219. package/data/build/dist/host/cli-adapters/subagent-tool.js +1 -1
  220. package/data/build/dist/host/cli-adapters/subagent-tool.js.map +1 -1
  221. package/data/build/dist/host/cli-adapters/team-input.d.ts +17 -0
  222. package/data/build/dist/host/cli-adapters/team-input.d.ts.map +1 -0
  223. package/data/build/dist/host/cli-adapters/team-input.js +67 -0
  224. package/data/build/dist/host/cli-adapters/team-input.js.map +1 -0
  225. package/data/build/dist/host/cli-adapters/update-check.d.ts.map +1 -1
  226. package/data/build/dist/host/cli-adapters/update-check.js +5 -5
  227. package/data/build/dist/host/cli-adapters/update-check.js.map +1 -1
  228. package/data/build/dist/host/cli-adapters/zcode-driver.d.ts.map +1 -1
  229. package/data/build/dist/host/cli-adapters/zcode-driver.js +6 -1
  230. package/data/build/dist/host/cli-adapters/zcode-driver.js.map +1 -1
  231. package/data/build/dist/host/cli-adapters/zcode-update.d.ts +8 -0
  232. package/data/build/dist/host/cli-adapters/zcode-update.d.ts.map +1 -0
  233. package/data/build/dist/host/cli-adapters/zcode-update.js +149 -0
  234. package/data/build/dist/host/cli-adapters/zcode-update.js.map +1 -0
  235. package/data/build/dist/host/cli-bridge/bridge-holder.d.ts +14 -0
  236. package/data/build/dist/host/cli-bridge/bridge-holder.d.ts.map +1 -1
  237. package/data/build/dist/host/cli-bridge/bridge-holder.js +53 -6
  238. package/data/build/dist/host/cli-bridge/bridge-holder.js.map +1 -1
  239. package/data/build/dist/host/cli-bridge/bridge-server.d.ts +6 -0
  240. package/data/build/dist/host/cli-bridge/bridge-server.d.ts.map +1 -1
  241. package/data/build/dist/host/cli-bridge/bridge-server.js +61 -6
  242. package/data/build/dist/host/cli-bridge/bridge-server.js.map +1 -1
  243. package/data/build/dist/host/cli-bridge/command-code-mod.d.ts.map +1 -1
  244. package/data/build/dist/host/cli-bridge/command-code-mod.js +86 -0
  245. package/data/build/dist/host/cli-bridge/command-code-mod.js.map +1 -1
  246. package/data/build/dist/host/cli-bridge/dispatch.js +1 -1
  247. package/data/build/dist/host/cli-bridge/dispatch.js.map +1 -1
  248. package/data/build/dist/host/cli-bridge/injections.d.ts +11 -0
  249. package/data/build/dist/host/cli-bridge/injections.d.ts.map +1 -1
  250. package/data/build/dist/host/cli-bridge/injections.js +62 -7
  251. package/data/build/dist/host/cli-bridge/injections.js.map +1 -1
  252. package/data/build/dist/host/cli-bridge/mcp-stdio-entry.d.ts +1 -1
  253. package/data/build/dist/host/cli-bridge/mcp-stdio-entry.js +64 -7
  254. package/data/build/dist/host/cli-bridge/mcp-stdio-entry.js.map +1 -1
  255. package/data/build/dist/host/cli-bridge/pi-extension-entry.d.ts +3 -0
  256. package/data/build/dist/host/cli-bridge/pi-extension-entry.d.ts.map +1 -0
  257. package/data/build/dist/host/cli-bridge/pi-extension-entry.js +9 -0
  258. package/data/build/dist/host/cli-bridge/pi-extension-entry.js.map +1 -0
  259. package/data/build/dist/host/cli-bridge/pi-extension.d.ts +52 -0
  260. package/data/build/dist/host/cli-bridge/pi-extension.d.ts.map +1 -0
  261. package/data/build/dist/host/cli-bridge/pi-extension.js +273 -0
  262. package/data/build/dist/host/cli-bridge/pi-extension.js.map +1 -0
  263. package/data/build/dist/host/cli-bridge/search-dispatch.d.ts +20 -0
  264. package/data/build/dist/host/cli-bridge/search-dispatch.d.ts.map +1 -0
  265. package/data/build/dist/host/cli-bridge/search-dispatch.js +61 -0
  266. package/data/build/dist/host/cli-bridge/search-dispatch.js.map +1 -0
  267. package/data/build/dist/host/cli-bridge/team-adapters.d.ts +11 -0
  268. package/data/build/dist/host/cli-bridge/team-adapters.d.ts.map +1 -0
  269. package/data/build/dist/host/cli-bridge/team-adapters.js +23 -0
  270. package/data/build/dist/host/cli-bridge/team-adapters.js.map +1 -0
  271. package/data/build/dist/host/cli-bridge/team-dispatch.d.ts +28 -0
  272. package/data/build/dist/host/cli-bridge/team-dispatch.d.ts.map +1 -0
  273. package/data/build/dist/host/cli-bridge/team-dispatch.js +208 -0
  274. package/data/build/dist/host/cli-bridge/team-dispatch.js.map +1 -0
  275. package/data/build/dist/host/cli-bridge/team-tool.d.ts +3 -0
  276. package/data/build/dist/host/cli-bridge/team-tool.d.ts.map +1 -0
  277. package/data/build/dist/host/cli-bridge/team-tool.js +18 -0
  278. package/data/build/dist/host/cli-bridge/team-tool.js.map +1 -0
  279. package/data/build/dist/host/features/file-management.d.ts.map +1 -1
  280. package/data/build/dist/host/features/file-management.js +2 -1
  281. package/data/build/dist/host/features/file-management.js.map +1 -1
  282. package/data/build/dist/host/features/git-commit-message.d.ts +5 -0
  283. package/data/build/dist/host/features/git-commit-message.d.ts.map +1 -0
  284. package/data/build/dist/host/features/git-commit-message.js +66 -0
  285. package/data/build/dist/host/features/git-commit-message.js.map +1 -0
  286. package/data/build/dist/host/features/git-management.d.ts +11 -2
  287. package/data/build/dist/host/features/git-management.d.ts.map +1 -1
  288. package/data/build/dist/host/features/git-management.js +61 -7
  289. package/data/build/dist/host/features/git-management.js.map +1 -1
  290. package/data/build/dist/host/features/lan-access-dsh.d.ts.map +1 -1
  291. package/data/build/dist/host/features/lan-access-dsh.js +2 -2
  292. package/data/build/dist/host/features/lan-access-dsh.js.map +1 -1
  293. package/data/build/dist/host/features/quick-apps.js +2 -2
  294. package/data/build/dist/host/features/quick-apps.js.map +1 -1
  295. package/data/build/dist/host/features/session-prompt-translation.d.ts.map +1 -1
  296. package/data/build/dist/host/features/session-prompt-translation.js +11 -3
  297. package/data/build/dist/host/features/session-prompt-translation.js.map +1 -1
  298. package/data/build/dist/host/index.d.ts.map +1 -1
  299. package/data/build/dist/host/index.js +6 -38
  300. package/data/build/dist/host/index.js.map +1 -1
  301. package/data/build/dist/host/lan-access-dsh.d.ts +9 -1
  302. package/data/build/dist/host/lan-access-dsh.d.ts.map +1 -1
  303. package/data/build/dist/host/lan-access-dsh.js +38 -11
  304. package/data/build/dist/host/lan-access-dsh.js.map +1 -1
  305. package/data/build/dist/host/modules/quick-apps/egress.d.ts +35 -0
  306. package/data/build/dist/host/modules/quick-apps/egress.d.ts.map +1 -0
  307. package/data/build/dist/host/modules/quick-apps/egress.js +244 -0
  308. package/data/build/dist/host/modules/quick-apps/egress.js.map +1 -0
  309. package/data/build/dist/host/modules/quick-apps/registry.d.ts.map +1 -1
  310. package/data/build/dist/host/modules/quick-apps/registry.js +10 -1
  311. package/data/build/dist/host/modules/quick-apps/registry.js.map +1 -1
  312. package/data/build/dist/host/modules/quick-apps/remote.d.ts +1 -1
  313. package/data/build/dist/host/modules/quick-apps/remote.d.ts.map +1 -1
  314. package/data/build/dist/host/modules/quick-apps/remote.js +6 -5
  315. package/data/build/dist/host/modules/quick-apps/remote.js.map +1 -1
  316. package/data/build/dist/host/modules/quick-apps/service.d.ts +1 -1
  317. package/data/build/dist/host/modules/quick-apps/service.d.ts.map +1 -1
  318. package/data/build/dist/host/modules/quick-apps/service.js +8 -4
  319. package/data/build/dist/host/modules/quick-apps/service.js.map +1 -1
  320. package/data/build/dist/host/modules/quick-apps/static-handler.d.ts +1 -1
  321. package/data/build/dist/host/modules/quick-apps/static-handler.d.ts.map +1 -1
  322. package/data/build/dist/host/modules/quick-apps/static-handler.js +35 -3
  323. package/data/build/dist/host/modules/quick-apps/static-handler.js.map +1 -1
  324. package/data/build/dist/host/rpc.js +2 -2
  325. package/data/build/dist/host/rpc.js.map +1 -1
  326. package/data/build/dist/host/session-changes.d.ts.map +1 -1
  327. package/data/build/dist/host/session-changes.js +6 -2
  328. package/data/build/dist/host/session-changes.js.map +1 -1
  329. package/data/build/dist/host/session-migration-repair.js +48 -35
  330. package/data/build/dist/host/session-migration-repair.js.map +1 -1
  331. package/data/build/dist/host/settings.d.ts.map +1 -1
  332. package/data/build/dist/host/settings.js +8 -0
  333. package/data/build/dist/host/settings.js.map +1 -1
  334. package/data/build/dist/host/workspace-root.d.ts +14 -0
  335. package/data/build/dist/host/workspace-root.d.ts.map +1 -0
  336. package/data/build/dist/host/workspace-root.js +99 -0
  337. package/data/build/dist/host/workspace-root.js.map +1 -0
  338. package/data/build/dist/shared/cli-provider-route.d.ts +7 -0
  339. package/data/build/dist/shared/cli-provider-route.d.ts.map +1 -0
  340. package/data/build/dist/shared/cli-provider-route.js +13 -0
  341. package/data/build/dist/shared/cli-provider-route.js.map +1 -0
  342. package/data/build/dist/shared/contracts/agent-team.d.ts +14 -0
  343. package/data/build/dist/shared/contracts/agent-team.d.ts.map +1 -0
  344. package/data/build/dist/shared/contracts/agent-team.js +48 -0
  345. package/data/build/dist/shared/contracts/agent-team.js.map +1 -0
  346. package/data/build/dist/shared/contracts/cli-adapter.d.ts +10 -0
  347. package/data/build/dist/shared/contracts/cli-adapter.d.ts.map +1 -1
  348. package/data/build/dist/shared/contracts/config.d.ts +5 -1
  349. package/data/build/dist/shared/contracts/config.d.ts.map +1 -1
  350. package/data/build/dist/shared/contracts/config.js +3 -0
  351. package/data/build/dist/shared/contracts/config.js.map +1 -1
  352. package/data/build/dist/shared/contracts/errors.d.ts +2 -2
  353. package/data/build/dist/shared/contracts/errors.d.ts.map +1 -1
  354. package/data/build/dist/shared/contracts/git.d.ts +17 -0
  355. package/data/build/dist/shared/contracts/git.d.ts.map +1 -1
  356. package/data/build/dist/shared/contracts/git.js +27 -1
  357. package/data/build/dist/shared/contracts/git.js.map +1 -1
  358. package/data/build/dist/shared/contracts/quick-apps.d.ts +2 -0
  359. package/data/build/dist/shared/contracts/quick-apps.d.ts.map +1 -1
  360. package/data/build/dist/shared/contracts/quick-apps.js.map +1 -1
  361. package/data/build/dist/shared/contracts/version.d.ts +9 -15
  362. package/data/build/dist/shared/contracts/version.d.ts.map +1 -1
  363. package/data/build/dist/shared/contracts/version.js +8 -14
  364. package/data/build/dist/shared/contracts/version.js.map +1 -1
  365. package/data/build/dist/shared/index.d.ts +2 -1
  366. package/data/build/dist/shared/index.d.ts.map +1 -1
  367. package/data/build/dist/shared/index.js +2 -1
  368. package/data/build/dist/shared/index.js.map +1 -1
  369. package/data/build/dist/shared/quick-app-browser-storage.d.ts +33 -0
  370. package/data/build/dist/shared/quick-app-browser-storage.d.ts.map +1 -0
  371. package/data/build/dist/shared/quick-app-browser-storage.js +33 -0
  372. package/data/build/dist/shared/quick-app-browser-storage.js.map +1 -0
  373. package/data/build/dist/shared/quick-app-network-allow.d.ts +8 -0
  374. package/data/build/dist/shared/quick-app-network-allow.d.ts.map +1 -0
  375. package/data/build/dist/shared/quick-app-network-allow.js +192 -0
  376. package/data/build/dist/shared/quick-app-network-allow.js.map +1 -0
  377. package/data/build/dist/shared/quick-app-network-bootstrap.d.ts +9 -0
  378. package/data/build/dist/shared/quick-app-network-bootstrap.d.ts.map +1 -0
  379. package/data/build/dist/shared/quick-app-network-bootstrap.js +134 -0
  380. package/data/build/dist/shared/quick-app-network-bootstrap.js.map +1 -0
  381. package/data/build/dist/shared/quick-app-storage-bootstrap.d.ts +9 -0
  382. package/data/build/dist/shared/quick-app-storage-bootstrap.d.ts.map +1 -0
  383. package/data/build/dist/shared/quick-app-storage-bootstrap.js +189 -0
  384. package/data/build/dist/shared/quick-app-storage-bootstrap.js.map +1 -0
  385. package/package.json +32 -32
  386. package/profile/README.md +2 -2
  387. package/profile/package.json +3 -3
  388. package/profile/version.json +3 -3
  389. package/version.json +3 -3
  390. package/data/build/dist/client/session-translation-model-pool.d.ts +0 -16
  391. package/data/build/dist/client/session-translation-model-pool.d.ts.map +0 -1
  392. package/data/build/dist/client/session-translation-model-pool.js.map +0 -1
@@ -7013,6 +7013,13 @@ window.__ModuleLoader__.load({
7013
7013
  var exports = module.exports;
7014
7014
  const require_transport = require("@jingyi0605/codingns4dsh/client.transport.js");
7015
7015
  const require_primitives_adapter = require("@jingyi0605/codingns4dsh/client.primitives-adapter.js");
7016
+ /** A bare brand name does not establish ownership of a DSH provider. */
7017
+ function fromCliProviderId(provider) {
7018
+ if (typeof provider !== "string" || !provider.startsWith("codingns-cli-")) return void 0;
7019
+ const adapterId = provider.slice(13);
7020
+ return adapterId === "" ? void 0 : adapterId;
7021
+ }
7022
+ //#endregion
7016
7023
  //#region src/client/provider-icons.ts
7017
7024
  /** 未绑定和未知 Agent 使用中性灰,绝不冒充任一已知品牌色。 */
7018
7025
  const PROVIDER_NEUTRAL_COLOR = "#71717a";
@@ -7162,7 +7169,8 @@ window.__ModuleLoader__.load({
7162
7169
  }
7163
7170
  /** 兼容旧版 CN profile 的会话快照,但不重新暴露第二个 Provider。 */
7164
7171
  function normalizeProviderAdapterId(adapterId) {
7165
- return adapterId === "codebuddy-cn" ? "codebuddy" : adapterId;
7172
+ const normalized = fromCliProviderId(adapterId) ?? adapterId;
7173
+ return normalized === "codebuddy-cn" ? "codebuddy" : normalized;
7166
7174
  }
7167
7175
  const CODINGNS4DSH_DEBUG_LEVEL_ENV = "CODINGNS4DSH_DEBUG_LEVEL";
7168
7176
  const LEGACY_DEBUG_ENV = "CODINGNS4DSH_TUNNEL_DEBUG";
@@ -7971,21 +7979,15 @@ window.__ModuleLoader__.load({
7971
7979
  const require_assistant_notifications = require("@jingyi0605/codingns4dsh/client.assistant-notifications.js");
7972
7980
  const require_session_translation = require("@jingyi0605/codingns4dsh/client.session-translation.js");
7973
7981
  //#region src/shared/contracts/version.ts
7974
- /** 当前经过完整验证的 DSH 版本;源文件由根目录 version.json 同步。 */
7975
- const DSH_VERSION = "0.2.1-alpha.3";
7982
+ /** DSH verification target, synchronized with the root version.json. */
7983
+ const DSH_VERSION = "0.2.1-rc.2";
7976
7984
  /**
7977
- * 插件正式验证的 DSH 版本范围,覆盖 rc.2 到当前验证的 alpha.2。
7978
- *
7979
- * 0.2.0-rc.2、0.2.1-alpha.1 与 0.2.1-alpha.2 属于同一 API 世代:插件直接消费的
7980
- * 20 个宿主包中 18 个接口面未变,会话格式仍为 v4。唯一的服务级破坏性变化是
7981
- * alpha.2 用 `subagents.startActivation()` 取代 `startContinuable()`,由
7982
- * `subagent.activation` / `subagent.continuable` 两条能力路由分别探测,业务侧
7983
- * 经 `startNativeSubagent()` 归一化调用,因此同一个版本范围仍然成立。
7984
- *
7985
- * 这里保留明确上界,是为了让 npm/DSH 安装期也能识别 0.2.1-alpha.2 这个跨 patch
7986
- * 预发布版本;出现新的 API 世代或结构变化时,应重新验证并更新范围与能力路由。
7985
+ * Supported hosts retain the 0.2.0-rc.2 floor and include 0.2.1-rc.2.
7986
+ * Capability adapters preserve earlier subagent, peer and message contracts.
7987
+ * Keep an explicit upper bound: a later prerelease requires verification before
7988
+ * either installation checks or runtime capability selection may accept it.
7987
7989
  */
7988
- const DSH_COMPATIBILITY = ">=0.2.0-rc.2 <=0.2.1-alpha.3";
7990
+ const DSH_COMPATIBILITY = ">=0.2.0-rc.2 <=0.2.1-rc.2";
7989
7991
  /**
7990
7992
  * 兼容范围下界,即插件仍然接受的最低 DSH 版本。
7991
7993
  *
@@ -7994,7 +7996,7 @@ window.__ModuleLoader__.load({
7994
7996
  * “不支持的 DSH 版本”,把仅仅缺少启动页注入的页面误判为宿主不兼容。
7995
7997
  */
7996
7998
  function minimumSupportedDshVersion() {
7997
- return /^>=([^ ]+)/u.exec(">=0.2.0-rc.2 <=0.2.1-alpha.3")?.[1] ?? "0.2.1-alpha.3";
7999
+ return /^>=([^ ]+)/u.exec(">=0.2.0-rc.2 <=0.2.1-rc.2")?.[1] ?? "0.2.1-rc.2";
7998
8000
  }
7999
8001
  /** Host 注入到浏览器页面的真实 DSH 版本全局字段。 */
8000
8002
  const CODINGNS_DSH_VERSION_GLOBAL = "__CODINGNS_DSH_VERSION__";
@@ -8003,7 +8005,7 @@ window.__ModuleLoader__.load({
8003
8005
  return /^0\.1\.5(?:-|$)/u.test(version);
8004
8006
  }
8005
8007
  /** Codingns4DSH 插件自身的 npm 版本。 */
8006
- const CODINGNS_VERSION = "0.2.1-beta.13";
8008
+ const CODINGNS_VERSION = "0.2.1-beta.15";
8007
8009
  /** 判断宿主版本是否落在当前插件声明的 DSH 兼容范围内;范围省略上界时不校验上限。 */
8008
8010
  function isDshVersionCompatible(version) {
8009
8011
  const match = /^>=([^ ]+)(?: <=([^ ]+))?$/u.exec(DSH_COMPATIBILITY);
@@ -8061,6 +8063,36 @@ window.__ModuleLoader__.load({
8061
8063
  return 0;
8062
8064
  }
8063
8065
  //#endregion
8066
+ //#region src/shared/contracts/git.ts
8067
+ const DEFAULT_GIT_MANAGEMENT_SETTINGS = {
8068
+ commitMessageEnabled: true,
8069
+ commitMessageDetail: "concise",
8070
+ commitMessageModels: [],
8071
+ commitMessagePrompt: ""
8072
+ };
8073
+ const MAX_GIT_COMMIT_MESSAGE_CHARS = 1e4;
8074
+ const MAX_GIT_COMMIT_PROMPT_CHARS = 1e4;
8075
+ function normalizeGitManagementSettings(value) {
8076
+ const seen = /* @__PURE__ */ new Set();
8077
+ return {
8078
+ commitMessageEnabled: value?.commitMessageEnabled !== false,
8079
+ commitMessageDetail: value?.commitMessageDetail === "detailed" ? "detailed" : "concise",
8080
+ commitMessagePrompt: typeof value?.commitMessagePrompt === "string" ? value.commitMessagePrompt : "",
8081
+ commitMessageModels: (value?.commitMessageModels ?? []).flatMap((item) => {
8082
+ const provider = item?.provider?.trim();
8083
+ const model = item?.model?.trim();
8084
+ if (!provider || !model) return [];
8085
+ const key = JSON.stringify([provider, model]);
8086
+ if (seen.has(key)) return [];
8087
+ seen.add(key);
8088
+ return [{
8089
+ provider,
8090
+ model
8091
+ }];
8092
+ })
8093
+ };
8094
+ }
8095
+ //#endregion
8064
8096
  //#region src/shared/contracts/config.ts
8065
8097
  const DEFAULT_ASSISTANT_VOICE_SETTINGS = {
8066
8098
  initialized: false,
@@ -8249,6 +8281,7 @@ window.__ModuleLoader__.load({
8249
8281
  const CODINGNS_MOBILE_ACCESS_FIELD = "mobileAccess";
8250
8282
  const CODINGNS_SUBSCRIPTION_USAGE_FIELD = "subscriptionUsage";
8251
8283
  const CODINGNS_SESSION_TRANSLATION_FIELD = "sessionTranslation";
8284
+ const CODINGNS_GIT_MANAGEMENT_FIELD = "gitManagement";
8252
8285
  const CODINGNS_ASSISTANT_FIELD = "assistant";
8253
8286
  const DEFAULT_CODINGNS_CONTROL_BASE_URL = "https://channel.codingns.com:1443";
8254
8287
  const DEFAULT_CODINGNS_CONTROL_BASE_URLS = [DEFAULT_CODINGNS_CONTROL_BASE_URL];
@@ -8293,6 +8326,7 @@ window.__ModuleLoader__.load({
8293
8326
  agentAdapterPreferences: {},
8294
8327
  subagentBridge: DEFAULT_SUBAGENT_BRIDGE_SETTINGS,
8295
8328
  sessionTranslation: require_session_translation.DEFAULT_SESSION_TRANSLATION_SETTINGS,
8329
+ gitManagement: DEFAULT_GIT_MANAGEMENT_SETTINGS,
8296
8330
  terminalEnhancement: DEFAULT_TERMINAL_ENHANCEMENT_SETTINGS,
8297
8331
  workspaceSessionEnhancement: DEFAULT_WORKSPACE_SESSION_ENHANCEMENT_SETTINGS,
8298
8332
  fileManagement: DEFAULT_FILE_MANAGEMENT_SETTINGS,
@@ -8449,6 +8483,12 @@ window.__ModuleLoader__.load({
8449
8483
  return CODINGNS_FILE_MANAGEMENT_FIELD;
8450
8484
  }
8451
8485
  });
8486
+ Object.defineProperty(exports, "CODINGNS_GIT_MANAGEMENT_FIELD", {
8487
+ enumerable: true,
8488
+ get: function() {
8489
+ return CODINGNS_GIT_MANAGEMENT_FIELD;
8490
+ }
8491
+ });
8452
8492
  Object.defineProperty(exports, "CODINGNS_H5_LOGIN_URL", {
8453
8493
  enumerable: true,
8454
8494
  get: function() {
@@ -8593,6 +8633,18 @@ window.__ModuleLoader__.load({
8593
8633
  return DSH_VERSION;
8594
8634
  }
8595
8635
  });
8636
+ Object.defineProperty(exports, "MAX_GIT_COMMIT_MESSAGE_CHARS", {
8637
+ enumerable: true,
8638
+ get: function() {
8639
+ return MAX_GIT_COMMIT_MESSAGE_CHARS;
8640
+ }
8641
+ });
8642
+ Object.defineProperty(exports, "MAX_GIT_COMMIT_PROMPT_CHARS", {
8643
+ enumerable: true,
8644
+ get: function() {
8645
+ return MAX_GIT_COMMIT_PROMPT_CHARS;
8646
+ }
8647
+ });
8596
8648
  Object.defineProperty(exports, "MOBILE_VIEWPORT_MAX_PX_LIMITS", {
8597
8649
  enumerable: true,
8598
8650
  get: function() {
@@ -8665,6 +8717,12 @@ window.__ModuleLoader__.load({
8665
8717
  return minimumSupportedDshVersion;
8666
8718
  }
8667
8719
  });
8720
+ Object.defineProperty(exports, "normalizeGitManagementSettings", {
8721
+ enumerable: true,
8722
+ get: function() {
8723
+ return normalizeGitManagementSettings;
8724
+ }
8725
+ });
8668
8726
  Object.defineProperty(exports, "normalizeLanAccessDshPwaSettings", {
8669
8727
  enumerable: true,
8670
8728
  get: function() {
@@ -17895,7 +17953,21 @@ window.__ModuleLoader__.load({
17895
17953
  "git.stagingEmpty": "Staging area is empty",
17896
17954
  "git.stagedCount": "{count} staged",
17897
17955
  "git.commitPlaceholder": "Type a commit message here",
17898
- "git.draftUnavailable": "Commit message generation is not available yet",
17956
+ "git.generatingMessage": "Generating commit message…",
17957
+ "git.generationEnabled": "Generate commit messages",
17958
+ "git.generationEnabledHelp": "Show the Generate button in the Git panel to draft a message from staged changes.",
17959
+ "git.messageDetail": "Commit message level",
17960
+ "git.messageConcise": "Concise — subject only",
17961
+ "git.messageDetailed": "Detailed — subject and change summary",
17962
+ "git.messageModels": "Commit message models",
17963
+ "git.messageModelsPicker": "Add commit message models",
17964
+ "git.messageModelsHelp": "Drag to set priority; models are tried in order. An empty pool follows the default DSH model. If generation fails, your existing draft is kept.",
17965
+ "git.settingsSaved": "Git settings saved",
17966
+ "git.messagePrompt": "Git commit rule prompt",
17967
+ "git.messagePromptHelp": "Custom rules for commit-message language, style, and conventions. Leave blank to use defaults; the selected detail level still applies.",
17968
+ "git.messagePromptPlaceholder": "For example: Use Conventional Commits, include a scope, and write in English.",
17969
+ "git.messagePromptSave": "Save commit rules",
17970
+ "git.messagePromptSaving": "Saving commit rules…",
17899
17971
  "git.draftMessage": "Generate commit message",
17900
17972
  "git.commit": "Commit",
17901
17973
  "git.stagedFiles": "Staged files",
@@ -18003,7 +18075,21 @@ window.__ModuleLoader__.load({
18003
18075
  "git.stagingEmpty": "暂存区为空",
18004
18076
  "git.stagedCount": "{count} 个已暂存",
18005
18077
  "git.commitPlaceholder": "在这里输入提交信息",
18006
- "git.draftUnavailable": "生成提交信息功能暂未开放",
18078
+ "git.generatingMessage": "正在生成提交信息…",
18079
+ "git.generationEnabled": "生成 Git 提交信息",
18080
+ "git.generationEnabledHelp": "在 Git 面板显示生成按钮,根据已暂存的改动起草提交信息。",
18081
+ "git.messageDetail": "提交信息级别",
18082
+ "git.messageConcise": "简洁 — 仅标题",
18083
+ "git.messageDetailed": "详细 — 标题与变更摘要",
18084
+ "git.messageModels": "提交信息模型",
18085
+ "git.messageModelsPicker": "添加提交信息模型",
18086
+ "git.messageModelsHelp": "拖拽调整优先级,按顺序尝试模型;模型池为空时跟随 DSH 默认模型。生成失败时保留已有草稿。",
18087
+ "git.settingsSaved": "Git 设置已保存",
18088
+ "git.messagePrompt": "Git 提交规则提示词",
18089
+ "git.messagePromptHelp": "自定义提交信息的语言、风格和格式规范。留空时使用默认规则;简洁或详细级别仍然生效。",
18090
+ "git.messagePromptPlaceholder": "例如:使用 Conventional Commits 格式,包含 scope,并使用英文编写。",
18091
+ "git.messagePromptSave": "保存提交规则",
18092
+ "git.messagePromptSaving": "正在保存提交规则…",
18007
18093
  "git.draftMessage": "生成提交信息",
18008
18094
  "git.commit": "提交",
18009
18095
  "git.stagedFiles": "暂存文件",
@@ -18366,6 +18452,7 @@ window.__ModuleLoader__.load({
18366
18452
  "peerHost.fileWorkspaceUnavailable": "The remote file scope is unavailable or inconsistent. Please wait for PeerHost workspaces to refresh.",
18367
18453
  "peerHost.questionSessionUnavailable": "The session for this remote question is unavailable. Please reconnect.",
18368
18454
  "peerHost.sessionUnavailable": "The remote session scope is unavailable. Please wait for PeerHost workspaces to refresh.",
18455
+ "peerHost.attachmentFolderUnsupported": "Add individual files to the remote session; local folders cannot be attached.",
18369
18456
  "peerHost.reference.section": "Conversations",
18370
18457
  "peerHost.reference.newSession": "New session",
18371
18458
  "peerHost.stateExternal": "The Transport structure of this page is not supported, so the plugin cannot wrap it and PeerHost aggregation is disabled; refreshing the page will not change the result.",
@@ -18446,6 +18533,7 @@ window.__ModuleLoader__.load({
18446
18533
  "peerHost.fileWorkspaceUnavailable": "远程文件作用域不可用或不一致,请等待 PeerHost 工作区刷新",
18447
18534
  "peerHost.questionSessionUnavailable": "远端问题所属会话不可用,请重新连接",
18448
18535
  "peerHost.sessionUnavailable": "远端会话作用域暂不可用,请等待 PeerHost 工作区刷新",
18536
+ "peerHost.attachmentFolderUnsupported": "请向远程会话添加单个文件,不能附加本机文件夹。",
18449
18537
  "peerHost.reference.section": "对话",
18450
18538
  "peerHost.reference.newSession": "新会话",
18451
18539
  "peerHost.stateExternal": "当前页面的 Transport 结构不受支持,插件无法包装它,PeerHost 聚合已停用;刷新页面不会改变结果。",
@@ -19675,6 +19763,8 @@ window.__ModuleLoader__.load({
19675
19763
  //#endregion
19676
19764
  //#region src/client/locales/quickApps.ts
19677
19765
  const en$2 = {
19766
+ "quickApps.storagePreview": "App data is saved in this browser. IndexedDB and URLs starting with / are not supported in this view.",
19767
+ "quickApps.storageFailed": "App data could not be saved in this browser: {message}",
19678
19768
  "quickApps.sandboxPreview": "Workspace preview. Browser storage and URLs starting with / may not work in this view.",
19679
19769
  "quickApps.runtime.not-configured": "This Host does not provide workspace HTML previews. Update its CodingNS plugin and reopen the shortcut.",
19680
19770
  "quickApps.runtime.config-invalid": "The Host’s HTML hosting configuration or TLS certificate is invalid.",
@@ -19785,6 +19875,10 @@ window.__ModuleLoader__.load({
19785
19875
  "quickApps.kind": "Open as",
19786
19876
  "quickApps.html": "HTML application",
19787
19877
  "quickApps.text": "Text document",
19878
+ "quickApps.networkAllow": "Local addresses",
19879
+ "quickApps.networkAllowHelp": "Leave this empty to block loopback, private networks, link-local addresses, and cloud metadata. Add one local IP, CIDR range, or hostname per line, up to 16. Examples: 127.0.0.1, localhost, 192.168.1.0/24.",
19880
+ "quickApps.networkAllowPlaceholder": "127.0.0.1\nlocalhost\n192.168.1.0/24",
19881
+ "quickApps.networkAllowInvalid": "Use a local IP address, CIDR range, or hostname, with one entry per line.",
19788
19882
  "quickApps.spa": "Use the entry page for application navigation",
19789
19883
  "quickApps.pathHelp": "Enter workspace-relative paths. Use a dedicated application folder; an empty folder path selects the workspace root.",
19790
19884
  "quickApps.empty": "No shortcuts yet. In edit mode, add an HTML application or text document from a managed workspace.",
@@ -19802,6 +19896,8 @@ window.__ModuleLoader__.load({
19802
19896
  "quickApps.status.missing-file": "The entry file or application folder is missing or cannot be accessed."
19803
19897
  };
19804
19898
  const zh$2 = {
19899
+ "quickApps.storagePreview": "应用数据保存在当前浏览器中。此视图不支持 IndexedDB 和以 / 开头的网址。",
19900
+ "quickApps.storageFailed": "无法在当前浏览器中保存应用数据:{message}",
19805
19901
  "quickApps.sandboxPreview": "工作区预览:浏览器存储和以 / 开头的网址可能无法在此视图中使用。",
19806
19902
  "quickApps.runtime.not-configured": "此主机尚不支持工作区 HTML 预览,请更新其 CodingNS 插件后重新打开快捷方式。",
19807
19903
  "quickApps.runtime.config-invalid": "主机的 HTML 托管配置或 TLS 证书无效。",
@@ -19912,6 +20008,10 @@ window.__ModuleLoader__.load({
19912
20008
  "quickApps.kind": "打开方式",
19913
20009
  "quickApps.html": "HTML 应用",
19914
20010
  "quickApps.text": "文本文档",
20011
+ "quickApps.networkAllow": "允许的本地地址",
20012
+ "quickApps.networkAllowHelp": "留空则拒绝回环、私网、链路本地和云元数据地址。每行填写一个本地 IP、CIDR 网段或主机名,最多 16 个。例如 127.0.0.1、localhost、192.168.1.0/24。",
20013
+ "quickApps.networkAllowPlaceholder": "127.0.0.1\nlocalhost\n192.168.1.0/24",
20014
+ "quickApps.networkAllowInvalid": "请逐行填写本地 IP、CIDR 网段或主机名。",
19915
20015
  "quickApps.spa": "应用内导航使用入口页面",
19916
20016
  "quickApps.pathHelp": "填写相对于工作区的路径。建议使用专用应用目录;目录留空表示工作区根目录。",
19917
20017
  "quickApps.empty": "还没有快捷方式。可在编辑模式下从受管工作区添加 HTML 应用或文本文档。",
@@ -19931,6 +20031,14 @@ window.__ModuleLoader__.load({
19931
20031
  //#endregion
19932
20032
  //#region src/client/locales/cliManagement.ts
19933
20033
  const en$1 = {
20034
+ "cli.team.label": "Team eligibility",
20035
+ "cli.team.leadAndMember": "Collaborator and Lead",
20036
+ "cli.team.member": "Collaborator",
20037
+ "cli.team.reason.version": "Full Team support requires a verified DSH alpha.2 or alpha.3 host.",
20038
+ "cli.team.reason.profile": "Enable the native DSH Team profile to use Teams.",
20039
+ "cli.team.reason.disabled": "Enable the CodingNS bridge and this Agent to use Teams.",
20040
+ "cli.team.reason.adapter": "This Agent does not provide the required Team tool transport.",
20041
+ "cli.team.reason.installation": "Install and enable this Agent before using Teams.",
19934
20042
  "cli.manage.reasonLabel.application-managed": "Check in app",
19935
20043
  "cli.manage.reasonLabel.unknown-version": "Version unknown",
19936
20044
  "cli.manage.reasonLabel.legacy-distribution": "Legacy distribution",
@@ -20000,6 +20108,14 @@ window.__ModuleLoader__.load({
20000
20108
  "cli.manage.reviewAgain": "Review another operation"
20001
20109
  };
20002
20110
  const zh$1 = {
20111
+ "cli.team.label": "团队适配能力",
20112
+ "cli.team.leadAndMember": "协作者和管理者",
20113
+ "cli.team.member": "协作者",
20114
+ "cli.team.reason.version": "完整团队功能需要经过验证的 DSH alpha.2 或 alpha.3 主机。",
20115
+ "cli.team.reason.profile": "请启用 DSH 原生团队配置后使用团队功能。",
20116
+ "cli.team.reason.disabled": "请启用 CodingNS 桥接和此 Agent 后使用团队功能。",
20117
+ "cli.team.reason.adapter": "此 Agent 尚未提供所需的团队工具通道。",
20118
+ "cli.team.reason.installation": "请先安装并启用此 Agent,再使用团队功能。",
20003
20119
  "cli.manage.reasonLabel.application-managed": "在应用中检查",
20004
20120
  "cli.manage.reasonLabel.unknown-version": "版本未知",
20005
20121
  "cli.manage.reasonLabel.legacy-distribution": "旧版发行包",
@@ -20190,7 +20306,7 @@ window.__ModuleLoader__.load({
20190
20306
  "feature.fileManagement.label": "File management enhancements",
20191
20307
  "feature.fileManagement.description": "Add file and folder operation menus to the DSH file sidebar and edit common text files in place.",
20192
20308
  "fileManagement.menuEnhancement": "File and folder operation menu",
20193
- "fileManagement.menuEnhancementDescription": "Show the right-click operation menu for files and folders in the DSH sidebar.",
20309
+ "fileManagement.menuEnhancementDescription": "Show the right-click operation menu for files and folders in the DSH sidebar, and copy relative or absolute paths from the file viewer.",
20194
20310
  "fileManagement.fileEditor": "File viewer editor",
20195
20311
  "fileManagement.fileEditorDescription": "Show the icon button for editing supported text files with syntax highlighting and line numbers.",
20196
20312
  "fileManagement.sessionChangedFiles": "Show current session changed files",
@@ -20468,6 +20584,8 @@ window.__ModuleLoader__.load({
20468
20584
  "cli.currentAgent": "Current Agent: {name}{locked}",
20469
20585
  "cli.locked": " (locked)",
20470
20586
  "cli.selectAgent": "Select Agent",
20587
+ "cli.catalogLoadFailed": "Could not load external Agents.",
20588
+ "cli.retryCatalog": "Retry loading Agents",
20471
20589
  "workspace.showLogo": "Show Agent logo",
20472
20590
  "workspace.logoDescription": "Display the selected external Agent logo in native workspace session rows.",
20473
20591
  "workspace.optimizeSessionTitles": "Optimize DSH session title generation",
@@ -20494,6 +20612,8 @@ window.__ModuleLoader__.load({
20494
20612
  "workspace.rememberConversationRightbarRatio": "Remember conversation and right sidebar width ratio",
20495
20613
  "workspace.rememberConversationRightbarRatioDescription": "Restore the right sidebar proportion after refreshing this browser; the ratio is stored locally.",
20496
20614
  "mobile.sidebarGestures": "Swipe to open or close sidebars",
20615
+ "mobile.team.title": "Agent Team",
20616
+ "mobile.team.close": "Close Agent Team",
20497
20617
  "mobile.sidebarGesturesDescription": "On touch devices, swipe horizontally in the conversation area to toggle a sidebar. Cross the configured share of the viewport width, or give a quick flick to trigger it.",
20498
20618
  "mobile.sidebarGestureMapping": "Swipe direction",
20499
20619
  "mobile.sidebarGestureMappingInward": "Swipe right: session list; swipe left: right sidebar",
@@ -20639,7 +20759,7 @@ window.__ModuleLoader__.load({
20639
20759
  "feature.fileManagement.label": "文件管理增强",
20640
20760
  "feature.fileManagement.description": "增强文件侧栏操作",
20641
20761
  "fileManagement.menuEnhancement": "文件管理菜单增强",
20642
- "fileManagement.menuEnhancementDescription": "在 DSH 文件侧栏为文件和目录显示右键操作菜单。",
20762
+ "fileManagement.menuEnhancementDescription": "在 DSH 文件侧栏为文件和目录显示右键操作菜单,并在文件查看器中复制相对路径或绝对路径。",
20643
20763
  "fileManagement.fileEditor": "文件查看器编辑功能",
20644
20764
  "fileManagement.fileEditorDescription": "为支持的文本文件显示编辑图标按钮,并保留语法高亮和行号。",
20645
20765
  "fileManagement.sessionChangedFiles": "显示当前会话修改的文件",
@@ -20917,6 +21037,8 @@ window.__ModuleLoader__.load({
20917
21037
  "cli.currentAgent": "当前 Agent:{name}{locked}",
20918
21038
  "cli.locked": "(已锁定)",
20919
21039
  "cli.selectAgent": "选择 Agent",
21040
+ "cli.catalogLoadFailed": "无法加载外部 Agent。",
21041
+ "cli.retryCatalog": "重新加载 Agent",
20920
21042
  "workspace.showLogo": "显示 Agent Logo",
20921
21043
  "workspace.logoDescription": "在原生工作区会话行显示所选外部 Agent 的 Logo。",
20922
21044
  "workspace.optimizeSessionTitles": "优化DSH会话标题生成逻辑",
@@ -20943,6 +21065,8 @@ window.__ModuleLoader__.load({
20943
21065
  "workspace.rememberConversationRightbarRatio": "记忆对话窗口与右侧栏的宽度比例",
20944
21066
  "workspace.rememberConversationRightbarRatioDescription": "刷新后恢复右侧栏比例;比例仅保存在当前浏览器中。",
20945
21067
  "mobile.sidebarGestures": "横滑开合侧栏",
21068
+ "mobile.team.title": "智能体团队",
21069
+ "mobile.team.close": "关闭智能体团队",
20946
21070
  "mobile.sidebarGesturesDescription": "触摸设备上在对话区横滑即可开合侧栏;跨过设定的视口宽度比例即触发,快速轻甩同样有效。",
20947
21071
  "mobile.sidebarGestureMapping": "方向映射",
20948
21072
  "mobile.sidebarGestureMappingInward": "右滑开合会话列表,左滑开合右边栏",
@@ -22603,6 +22727,11 @@ window.__ModuleLoader__.load({
22603
22727
  setCopiedUrl(null);
22604
22728
  setDshPort(String(current.dshPort));
22605
22729
  setListenPort(String(current.listenPort));
22730
+ setSavedSettings((prev) => prev === void 0 ? prev : {
22731
+ ...prev,
22732
+ dshPort: current.dshPort,
22733
+ listenPort: current.listenPort
22734
+ });
22606
22735
  const url = buildLanAccessUrls(current, interfaceAddresses)[0] ?? `http://${current.listenHost}:${current.actualListenPort ?? current.listenPort}/`;
22607
22736
  notify({
22608
22737
  kind: "success",
@@ -24532,15 +24661,15 @@ window.__ModuleLoader__.load({
24532
24661
  sendHello() {
24533
24662
  this.send(this.createEnvelope("session.hello", "session", {
24534
24663
  protocol: this.options.protocol ?? "dsh-transport-v1",
24535
- dshVersion: this.options.dshVersion ?? "0.2.1-alpha.3",
24664
+ dshVersion: this.options.dshVersion ?? "0.2.1-rc.2",
24536
24665
  capabilities: [...this.options.capabilities ?? []]
24537
24666
  }));
24538
24667
  }
24539
24668
  sendReady(capabilities, peerDshVersion) {
24540
24669
  this.send(this.createEnvelope("session.ready", "session", {
24541
24670
  protocol: this.options.protocol ?? "dsh-transport-v1",
24542
- dshVersion: peerDshVersion ?? this.options.dshVersion ?? "0.2.1-alpha.3",
24543
- hostDshVersion: this.options.dshVersion ?? "0.2.1-alpha.3",
24671
+ dshVersion: peerDshVersion ?? this.options.dshVersion ?? "0.2.1-rc.2",
24672
+ hostDshVersion: this.options.dshVersion ?? "0.2.1-rc.2",
24544
24673
  capabilities: [...capabilities],
24545
24674
  byteCredit: 65536,
24546
24675
  messageCredit: 32
@@ -29063,6 +29192,76 @@ window.__ModuleLoader__.load({
29063
29192
  return `:is([data-slot="${name}"],[data-slot="${contextComposerSlotName(name)}"])`;
29064
29193
  }
29065
29194
  //#endregion
29195
+ //#region src/dsh-capabilities/client/composer-presentation-adapter.ts
29196
+ const presentations = /* @__PURE__ */ new WeakMap();
29197
+ /** Compose customizations over one native composer, sharing its child-slot mirror. */
29198
+ function installComposerPresentation(owner, slots, decorate, element, hooks) {
29199
+ const { useMemo, useSyncExternalStore } = hooks;
29200
+ let presentation = presentations.get(owner);
29201
+ if (presentation === void 0) {
29202
+ const state = {
29203
+ decorators: [decorate],
29204
+ listeners: /* @__PURE__ */ new Set(),
29205
+ dispose: () => void 0
29206
+ };
29207
+ const subscribe = (listener) => {
29208
+ state.listeners.add(listener);
29209
+ return () => {
29210
+ state.listeners.delete(listener);
29211
+ };
29212
+ };
29213
+ const snapshot = () => state.decorators;
29214
+ state.dispose = followPresentationEntry(slots, "conversation.composer.bar", (entry) => entry.children?.["conversation.composer.dock"] !== void 0, (native) => {
29215
+ const names = Object.fromEntries(Object.keys(native.children ?? {}).map((name) => [name, contextComposerSlotName(name)]));
29216
+ const removers = [];
29217
+ const remove = slots.register({
29218
+ name: "conversation.composer.bar",
29219
+ ...native.options,
29220
+ priority: (native.options.priority ?? 0) - 1,
29221
+ locale: native.locale,
29222
+ inject: native.inject,
29223
+ store: native.store,
29224
+ select: native.select,
29225
+ children: Object.fromEntries(Object.entries(native.children ?? {}).map(([name, spec]) => [names[name], spec]))
29226
+ }, (props) => {
29227
+ const decorators = useSyncExternalStore(subscribe, snapshot, snapshot);
29228
+ return element(useMemo(() => decorators.reduceRight((component, wrapper) => wrapper(component), native.component), [decorators]), {
29229
+ ...props,
29230
+ renderSlot: (name, ...args) => props.renderSlot(names[name] ?? name, ...args),
29231
+ ...props.renderSlotChain === void 0 ? {} : { renderSlotChain: (name, ...args) => props.renderSlotChain(names[name] ?? name, ...args) }
29232
+ });
29233
+ });
29234
+ try {
29235
+ for (const [source, target] of Object.entries(names)) removers.push(mirrorPresentationSlot(slots, source, target, element));
29236
+ } catch (error) {
29237
+ for (const dispose of removers.reverse()) dispose();
29238
+ remove();
29239
+ throw error;
29240
+ }
29241
+ return () => {
29242
+ for (const dispose of removers.reverse()) dispose();
29243
+ remove();
29244
+ };
29245
+ });
29246
+ presentation = state;
29247
+ presentations.set(owner, state);
29248
+ } else {
29249
+ presentation.decorators = [...presentation.decorators, decorate];
29250
+ for (const listener of presentation.listeners) listener();
29251
+ }
29252
+ const state = presentation;
29253
+ let disposed = false;
29254
+ return () => {
29255
+ if (disposed) return;
29256
+ disposed = true;
29257
+ state.decorators = state.decorators.filter((wrapper) => wrapper !== decorate);
29258
+ if (state.decorators.length === 0) {
29259
+ state.dispose();
29260
+ presentations.delete(owner);
29261
+ } else for (const listener of state.listeners) listener();
29262
+ };
29263
+ }
29264
+ //#endregion
29066
29265
  //#region src/dsh-capabilities/client/session-performance-adapter.ts
29067
29266
  function supportsSessionPerformancePresentation(context) {
29068
29267
  const slots = context?.slots;
@@ -29076,7 +29275,7 @@ window.__ModuleLoader__.load({
29076
29275
  /** Reuse the native activity pill, dialog, localization, settings, and session binding. */
29077
29276
  function createSessionPerformancePresentation(context) {
29078
29277
  const slots = context.slots;
29079
- return { install(useAdapter, element) {
29278
+ return { install(useAdapter, element, hooks) {
29080
29279
  const wrappers = /* @__PURE__ */ new Set();
29081
29280
  const removeActivity = followPresentationEntry(slots, "conversation.composer.dock", (entry) => entry.options.id === "activity" && !wrappers.has(entry.component), (native) => {
29082
29281
  const Activity = native.component;
@@ -29117,7 +29316,7 @@ window.__ModuleLoader__.load({
29117
29316
  };
29118
29317
  });
29119
29318
  try {
29120
- const removeContext = installGrokContextPresentation(slots, useAdapter, element);
29319
+ const removeContext = installGrokContextPresentation(context, slots, useAdapter, element, hooks);
29121
29320
  return () => {
29122
29321
  removeContext();
29123
29322
  removeActivity();
@@ -29129,48 +29328,157 @@ window.__ModuleLoader__.load({
29129
29328
  } };
29130
29329
  }
29131
29330
  /** ContextMeter lives inside the native composer bar, rather than in its own slot. */
29132
- function installGrokContextPresentation(slots, useAdapter, element) {
29133
- return followPresentationEntry(slots, "conversation.composer.bar", (entry) => entry.children?.["conversation.composer.dock"] !== void 0, (native) => {
29134
- const names = Object.fromEntries(Object.keys(native.children ?? {}).map((name) => [name, contextComposerSlotName(name)]));
29135
- const removers = [];
29136
- const remove = slots.register({
29137
- name: "conversation.composer.bar",
29138
- ...native.options,
29139
- priority: (native.options.priority ?? 0) - 1,
29140
- locale: native.locale,
29141
- inject: native.inject,
29142
- store: native.store,
29143
- select: native.select,
29144
- children: Object.fromEntries(Object.entries(native.children ?? {}).map(([name, spec]) => [names[name], spec]))
29145
- }, (props) => {
29146
- const adapter = useAdapter(props.sessionId ?? "");
29147
- return element(native.component, {
29148
- ...props,
29149
- renderSlot: (name, ...args) => props.renderSlot(names[name] ?? name, ...args),
29150
- ...props.renderSlotChain === void 0 ? {} : { renderSlotChain: (name, ...args) => props.renderSlotChain(names[name] ?? name, ...args) },
29151
- useProjection: (key, ...args) => {
29152
- const original = props.useProjection(key, ...args);
29153
- if (key === "contextBreakdown" && adapter === "grok") return void 0;
29154
- if (key !== "contextPressure") return original;
29155
- const value = props.useProjection(GROK_CONTEXT_PROJECTION);
29156
- if (adapter !== "grok") return original;
29157
- const pressure = value ?? {};
29158
- return typeof args[0] === "function" ? args[0](pressure) : pressure;
29159
- }
29160
- });
29331
+ function installGrokContextPresentation(owner, slots, useAdapter, element, hooks) {
29332
+ return installComposerPresentation(owner, slots, (Native) => function ComposerWithGrokContext(props) {
29333
+ const adapter = useAdapter(props.sessionId ?? "");
29334
+ return element(Native, {
29335
+ ...props,
29336
+ useProjection: (key, ...args) => {
29337
+ const original = props.useProjection(key, ...args);
29338
+ if (key === "contextBreakdown" && adapter === "grok") return void 0;
29339
+ if (key !== "contextPressure") return original;
29340
+ const value = props.useProjection(GROK_CONTEXT_PROJECTION);
29341
+ if (adapter !== "grok") return original;
29342
+ const pressure = value ?? {};
29343
+ return typeof args[0] === "function" ? args[0](pressure) : pressure;
29344
+ }
29161
29345
  });
29162
- try {
29163
- for (const [source, target] of Object.entries(names)) removers.push(mirrorPresentationSlot(slots, source, target, element));
29164
- } catch (error) {
29165
- for (const dispose of removers.reverse()) dispose();
29166
- remove();
29167
- throw error;
29168
- }
29169
- return () => {
29170
- for (const dispose of removers.reverse()) dispose();
29171
- remove();
29346
+ }, element, hooks);
29347
+ }
29348
+ //#endregion
29349
+ //#region src/dsh-capabilities/host/agent-team-adapter.ts
29350
+ const MEMBER_METHODS = [
29351
+ "membership",
29352
+ "listMembers",
29353
+ "sendMessage",
29354
+ "listTasks",
29355
+ "getTask",
29356
+ "createTask",
29357
+ "updateTask",
29358
+ "waitForChange"
29359
+ ];
29360
+ function supportsExternalAgentTeam(context, lead = false) {
29361
+ return hasMethods$1(read$1(context, "agentTeams"), [...MEMBER_METHODS, ...lead ? ["spawnTeammate", "interrupt"] : []]) && hasMethods$1(read$1(context, "agents"), ["get", "list"]) && hasMethods$1(read$1(context, "subagents"), [
29362
+ "registerProvider",
29363
+ "startActivation",
29364
+ "sendMessage"
29365
+ ]);
29366
+ }
29367
+ function createAgentTeamAdapter(context) {
29368
+ return new DshAgentTeamAdapter(read$1(context, "agentTeams"), read$1(context, "agents"), () => read$1(context, "sessionController"));
29369
+ }
29370
+ /** Exact Agent identity and all DSH-specific calls stay at this boundary. */
29371
+ var DshAgentTeamAdapter = class {
29372
+ service;
29373
+ agents;
29374
+ controller;
29375
+ lifetime = new AbortController();
29376
+ supportsLead;
29377
+ constructor(service, agents, controller) {
29378
+ this.service = service;
29379
+ this.agents = agents;
29380
+ this.controller = controller;
29381
+ this.supportsLead = hasMethods$1(service, ["spawnTeammate", "interrupt"]);
29382
+ }
29383
+ get signal() {
29384
+ return this.lifetime.signal;
29385
+ }
29386
+ async nativeRoute(model, effort, provider) {
29387
+ const controller = typeof this.controller === "function" ? this.controller() : this.controller;
29388
+ if (!controller?.modelCatalog) throw teamError("TEAM_NATIVE_ROUTE_UNAVAILABLE", "A native DSH model catalog is required for mixed Teams.");
29389
+ const catalog = await controller.modelCatalog();
29390
+ const selectedModel = model ?? catalog.default?.model;
29391
+ const selectedProvider = provider ?? (model === void 0 ? catalog.default?.provider : void 0);
29392
+ const matches = (catalog.groups ?? []).flatMap((group) => group.id.startsWith("codingns-cli-") || selectedProvider && group.id !== selectedProvider ? [] : (group.models ?? []).filter((item) => item.id === selectedModel).map((item) => ({
29393
+ provider: group.id,
29394
+ item
29395
+ })));
29396
+ if (matches.length !== 1) throw teamError("TEAM_NATIVE_ROUTE_UNAVAILABLE", "Select an unambiguous native DSH provider and model.");
29397
+ const match = matches[0];
29398
+ const reasoningEffort = effort ?? (model === void 0 && match.provider === catalog.default?.provider ? catalog.default?.reasoningEffort : void 0);
29399
+ if (reasoningEffort && !match.item.reasoning?.efforts?.some((item) => item.id === reasoningEffort)) throw teamError("TEAM_MODEL_UNSUPPORTED", "The requested native effort is unavailable.");
29400
+ return {
29401
+ provider: match.provider,
29402
+ model: match.item.id,
29403
+ ...reasoningEffort ? { reasoningEffort } : {}
29172
29404
  };
29173
- });
29405
+ }
29406
+ resolveAgent(sessionId) {
29407
+ if (this.signal.aborted || sessionId.trim() === "") return void 0;
29408
+ const direct = this.agents.get(sessionId);
29409
+ if (isAgent(direct) && this.isCurrent(direct) && sessionIdOf(direct) === sessionId) return direct;
29410
+ return this.agents.list().find((candidate) => isAgent(candidate) && this.isCurrent(candidate) && sessionIdOf(candidate) === sessionId);
29411
+ }
29412
+ identity(agent) {
29413
+ this.signal.throwIfAborted();
29414
+ if (!this.isCurrent(agent)) throw teamError("TEAM_CALLER_UNAVAILABLE", "The calling Agent is no longer live.");
29415
+ const member = this.service.membership(agent);
29416
+ if (member?.role !== "lead" && member?.role !== "teammate" || typeof member.id !== "string" || typeof member.name !== "string") throw teamError("TEAM_NOT_MEMBER", "The calling Agent is not a native Team member.");
29417
+ return {
29418
+ sessionId: sessionIdOf(agent),
29419
+ teamId: member.id,
29420
+ role: member.role,
29421
+ name: member.name
29422
+ };
29423
+ }
29424
+ invoke(agent, action, input, signal) {
29425
+ const identity = this.identity(agent);
29426
+ if ((action === "spawn" || action === "interrupt" || action === "task_update" && input.action === "reassign") && identity.role !== "lead") throw teamError("TEAM_LEAD_REQUIRED", "Only the Team Lead may perform this operation.");
29427
+ const combined = signal ? AbortSignal.any([signal, this.signal]) : this.signal;
29428
+ combined.throwIfAborted();
29429
+ switch (action) {
29430
+ case "status": return {
29431
+ identity,
29432
+ supportsLead: this.supportsLead
29433
+ };
29434
+ case "members": return this.service.listMembers(agent);
29435
+ case "message": return this.service.sendMessage(agent, {
29436
+ ...input,
29437
+ signal: combined
29438
+ });
29439
+ case "tasks": return this.service.listTasks(agent);
29440
+ case "task": return this.service.getTask(agent, String(input.taskId));
29441
+ case "task_create": return this.service.createTask(agent, input);
29442
+ case "task_update": return this.service.updateTask(agent, input);
29443
+ case "wait": return this.service.waitForChange(agent, Number(input.timeoutMs), combined);
29444
+ case "spawn":
29445
+ if (!this.service.spawnTeammate) throw teamError("TEAM_OPERATION_UNAVAILABLE", "Teammate creation is unavailable.");
29446
+ return this.service.spawnTeammate(agent, {
29447
+ ...input,
29448
+ signal: combined
29449
+ });
29450
+ case "interrupt":
29451
+ if (!this.service.interrupt) throw teamError("TEAM_OPERATION_UNAVAILABLE", "Team interruption is unavailable.");
29452
+ return this.service.interrupt(agent, String(input.target));
29453
+ }
29454
+ }
29455
+ dispose() {
29456
+ this.lifetime.abort(teamError("TEAM_SERVICE_UNAVAILABLE", "The native Team service was removed."));
29457
+ }
29458
+ isCurrent(agent) {
29459
+ return this.agents.get(agent.id) === agent;
29460
+ }
29461
+ };
29462
+ function sessionIdOf(agent) {
29463
+ return agent.session?.header?.id?.trim() || agent.id;
29464
+ }
29465
+ function teamError(code, message) {
29466
+ return Object.assign(new Error(message), { code });
29467
+ }
29468
+ function isAgent(value) {
29469
+ return typeof value === "object" && value !== null && typeof Reflect.get(value, "id") === "string";
29470
+ }
29471
+ function hasMethods$1(value, methods) {
29472
+ return value !== null && (typeof value === "object" || typeof value === "function") && methods.every((method) => typeof Reflect.get(value, method) === "function");
29473
+ }
29474
+ function read$1(context, name) {
29475
+ if (typeof context !== "object" || context === null) return void 0;
29476
+ try {
29477
+ const get = Reflect.get(context, "get");
29478
+ return typeof get === "function" ? get.call(context, name) : Reflect.get(context, name);
29479
+ } catch {
29480
+ return;
29481
+ }
29174
29482
  }
29175
29483
  //#endregion
29176
29484
  //#region src/dsh-capabilities/routes.ts
@@ -29187,10 +29495,21 @@ window.__ModuleLoader__.load({
29187
29495
  const range020 = require_native_workspace_store.DSH_COMPATIBILITY;
29188
29496
  const add = (route) => registry.register(route);
29189
29497
  if (runtime === "host") {
29498
+ for (const role of ["member", "lead"]) add({
29499
+ id: `agent-team-external-${role}-021`,
29500
+ capability: `agent-team.external-${role}`,
29501
+ supportedDsh: ">=0.2.1-alpha.2 <=0.2.1-rc.2",
29502
+ runtime,
29503
+ priority: 10,
29504
+ status: "supported",
29505
+ introducedIn: "0.2.1-alpha.2",
29506
+ detect: (ctx) => supportsExternalAgentTeam(ctx, role === "lead"),
29507
+ create: createAgentTeamAdapter
29508
+ });
29190
29509
  add({
29191
29510
  id: "session-performance-projection-021",
29192
29511
  capability: "session.external-performance",
29193
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
29512
+ supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.2",
29194
29513
  runtime,
29195
29514
  priority: 10,
29196
29515
  status: "supported",
@@ -29234,7 +29553,7 @@ window.__ModuleLoader__.load({
29234
29553
  add({
29235
29554
  id: "session-prompt-assembly-021",
29236
29555
  capability: "session.prompt-assembly",
29237
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
29556
+ supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.2",
29238
29557
  runtime,
29239
29558
  priority: 10,
29240
29559
  status: "supported",
@@ -29245,7 +29564,7 @@ window.__ModuleLoader__.load({
29245
29564
  add({
29246
29565
  id: "session-external-model-selection-021",
29247
29566
  capability: "session.external-model-selection",
29248
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
29567
+ supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.2",
29249
29568
  runtime,
29250
29569
  priority: 10,
29251
29570
  status: "supported",
@@ -29267,7 +29586,7 @@ window.__ModuleLoader__.load({
29267
29586
  add({
29268
29587
  id: "session-activation-021",
29269
29588
  capability: "session.activation",
29270
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
29589
+ supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.2",
29271
29590
  runtime,
29272
29591
  priority: 10,
29273
29592
  status: "supported",
@@ -29278,7 +29597,7 @@ window.__ModuleLoader__.load({
29278
29597
  for (const capability of ["connection.peer", "connection.uplink"]) add({
29279
29598
  id: `${capability}-021`,
29280
29599
  capability,
29281
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
29600
+ supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.2",
29282
29601
  runtime,
29283
29602
  priority: 40,
29284
29603
  status: "supported",
@@ -29374,7 +29693,7 @@ window.__ModuleLoader__.load({
29374
29693
  add({
29375
29694
  id: "session-performance-presentation-021",
29376
29695
  capability: "session.external-performance",
29377
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
29696
+ supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.2",
29378
29697
  runtime,
29379
29698
  priority: 10,
29380
29699
  status: "supported",
@@ -29407,7 +29726,7 @@ window.__ModuleLoader__.load({
29407
29726
  add({
29408
29727
  id: "message-presentation-021",
29409
29728
  capability: "conversation.message-presentation",
29410
- supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
29729
+ supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-rc.2",
29411
29730
  runtime,
29412
29731
  priority: 10,
29413
29732
  status: "supported",
@@ -29728,7 +30047,7 @@ window.__ModuleLoader__.load({
29728
30047
  add({
29729
30048
  id: "conversation-draft-share-021",
29730
30049
  capability: "conversation.draft-share",
29731
- supportedDsh: ">=0.2.1-alpha.1 <=0.2.1-alpha.3",
30050
+ supportedDsh: ">=0.2.1-alpha.1 <=0.2.1-rc.2",
29732
30051
  runtime: "client",
29733
30052
  priority: 30,
29734
30053
  status: "supported",
@@ -31153,7 +31472,10 @@ window.__ModuleLoader__.load({
31153
31472
  const uiContext = context.services.uiContext;
31154
31473
  if (uiContext !== void 0) {
31155
31474
  const performance = createDshCapabilityRegistry(context.services.dshVersion, "client", uiContext).getProfile(uiContext).capabilities.get("session.external-performance")?.value;
31156
- if (performance !== void 0) context.resources.add(performance.install((sessionId) => (0, react.useSyncExternalStore)(subscribeSessionAdapters, () => sessionAdapterId(sessionId), () => sessionAdapterId(sessionId)), react.createElement));
31475
+ if (performance !== void 0) context.resources.add(performance.install((sessionId) => (0, react.useSyncExternalStore)(subscribeSessionAdapters, () => sessionAdapterId(sessionId), () => sessionAdapterId(sessionId)), react.createElement, {
31476
+ useMemo: react.useMemo,
31477
+ useSyncExternalStore: react.useSyncExternalStore
31478
+ }));
31157
31479
  const { registerDelegateCommand } = await require.async("./client.delegate-command.js");
31158
31480
  context.resources.add(registerDelegateCommand(uiContext, {
31159
31481
  rpc: context.services.rpc,
@@ -31850,7 +32172,10 @@ window.__ModuleLoader__.load({
31850
32172
  margin: 0,
31851
32173
  overflowWrap: "anywhere",
31852
32174
  color: require_theme.dshThemeColor.labelSecondary
31853
- } }, adapter.diagnostic), (0, react.createElement)("dt", void 0, t("cli.protocol")), (0, react.createElement)("dd", { style: { margin: 0 } }, adapter.protocol ?? t("cli.undeclared")), (0, react.createElement)("dt", void 0, t("cli.capabilities")), (0, react.createElement)("dd", { style: {
32175
+ } }, adapter.diagnostic), adapter.team && (0, react.createElement)("dt", void 0, t("cli.team.label")), adapter.team && (0, react.createElement)("dd", { style: {
32176
+ margin: 0,
32177
+ overflowWrap: "anywhere"
32178
+ } }, adapter.team.member ? t(adapter.team.lead ? "cli.team.leadAndMember" : "cli.team.member") : t(`cli.team.reason.${adapter.team.reason ?? "adapter"}`)), (0, react.createElement)("dt", void 0, t("cli.protocol")), (0, react.createElement)("dd", { style: { margin: 0 } }, adapter.protocol ?? t("cli.undeclared")), (0, react.createElement)("dt", void 0, t("cli.capabilities")), (0, react.createElement)("dd", { style: {
31854
32179
  margin: 0,
31855
32180
  overflowWrap: "anywhere"
31856
32181
  } }, adapter.capabilities?.join(t("common.listSeparator")) ?? t("cli.undeclared"))), (0, react.createElement)("h4", { style: { margin: "16px 0 8px" } }, t("cli.modelCatalog")), modelsError && (0, react.createElement)("div", {
@@ -33110,6 +33435,8 @@ window.__ModuleLoader__.load({
33110
33435
  const MENU_ATTRIBUTE$1 = "aria-haspopup";
33111
33436
  const WORKSPACE_MENU_PATTERN = /(?:更多|菜单|选项|操作|more|menu|option|action)/iu;
33112
33437
  const WORKSPACE_FILTER_PATTERN = /(?:视图选项|筛选选项|筛选会话|分组方式|排序方式|view\s*options?|filter\s*(?:options?|sessions?)|group\s*by|sort\s*by)/iu;
33438
+ /** 标题栏上的筛选按钮文案。菜单行里的“分组方式 / Group by”不能算作这个按钮。 */
33439
+ const WORKSPACE_FILTER_TOOLBAR_PATTERN = /(?:视图选项|筛选选项|view\s*options?|filter\s*options?)/iu;
33113
33440
  /**
33114
33441
  * 给原生工作区菜单增加隐藏动作,并通过工作区筛选菜单控制恢复列表。
33115
33442
  *
@@ -33122,7 +33449,7 @@ window.__ModuleLoader__.load({
33122
33449
  const remote = options.remote;
33123
33450
  const t = require_transport.resolveCodingNsTranslator(options.locale);
33124
33451
  let hiddenWorkspaceIds = new Set(normalizeIds(options.hiddenWorkspaceIds ?? []));
33125
- let workspaces = [];
33452
+ let fallbackWorkspaces = [];
33126
33453
  let disposed = false;
33127
33454
  let scanQueued = false;
33128
33455
  let loading;
@@ -33154,14 +33481,14 @@ window.__ModuleLoader__.load({
33154
33481
  });
33155
33482
  };
33156
33483
  const refreshData = async () => {
33157
- if (disposed) return;
33484
+ if (disposed || options.readNativeWorkspaceSnapshot?.() !== void 0) return;
33158
33485
  if (loading !== void 0) {
33159
33486
  await loading;
33160
33487
  return;
33161
33488
  }
33162
33489
  loading = loadWorkspaceRecords(remote).then((next) => {
33163
33490
  if (disposed) return;
33164
- workspaces = next;
33491
+ fallbackWorkspaces = next;
33165
33492
  scan();
33166
33493
  }).catch(() => void 0).finally(() => {
33167
33494
  loading = void 0;
@@ -33174,6 +33501,7 @@ window.__ModuleLoader__.load({
33174
33501
  try {
33175
33502
  clearHiddenWorkspaceNodes(dom);
33176
33503
  if (!showHiddenWorkspaces) removeVisibilityEntries(dom);
33504
+ const workspaces = options.readNativeWorkspaceSnapshot?.()?.items ?? fallbackWorkspaces;
33177
33505
  const headers = findWorkspaceHeaders(dom);
33178
33506
  const workspaceIds = new Set(workspaces.map((workspace) => workspace.workspaceId));
33179
33507
  for (const header of headers) {
@@ -33201,8 +33529,9 @@ window.__ModuleLoader__.load({
33201
33529
  });
33202
33530
  const menus = findWorkspaceMenus(dom);
33203
33531
  knownNativeMenus = new Set(menus);
33532
+ removeStrayFilterActions(dom);
33204
33533
  const menuContextFresh = menuContextPending;
33205
- if (menus.length > 0) menuContextPending = false;
33534
+ if (menus.some(isVisibleMenu)) menuContextPending = false;
33206
33535
  const currentMenu = [...menus].reverse().find(isVisibleMenu);
33207
33536
  const currentMenuKind = currentMenu === void 0 ? activeMenuKind : isWorkspaceFilterMenu(currentMenu) ? "filter" : "workspace";
33208
33537
  const filterContextFresh = menuContextFresh && activeMenuKind === "filter";
@@ -33320,6 +33649,17 @@ window.__ModuleLoader__.load({
33320
33649
  const label = `${element.textContent ?? ""} ${element.getAttribute("aria-label") ?? ""} ${element.title}`.replace(/\s+/gu, " ");
33321
33650
  return WORKSPACE_FILTER_PATTERN.test(label);
33322
33651
  }
33652
+ /**
33653
+ * 筛选按钮和它的提示文字都在标题行里。标题行、操作按钮栏因此也会带上
33654
+ * “视图选项”,但不能把它们当成展开后的筛选菜单。
33655
+ */
33656
+ function containsFilterTrigger(element) {
33657
+ return [...element.querySelectorAll("button,[role=\"button\"]")].some((button) => {
33658
+ if (button.getAttribute("role") === "menuitem" || button.getAttribute("role") === "menuitemcheckbox") return false;
33659
+ const label = `${button.textContent ?? ""} ${button.getAttribute("aria-label") ?? ""} ${button.title}`.replace(/\s+/gu, " ");
33660
+ return WORKSPACE_FILTER_TOOLBAR_PATTERN.test(label);
33661
+ });
33662
+ }
33323
33663
  function findWorkspaceMenus(dom) {
33324
33664
  const explicit = [...dom.querySelectorAll("[role=\"menu\"], [role=\"listbox\"], [data-menu-content], [data-radix-menu-content]")];
33325
33665
  if (explicit.length > 0) return explicit;
@@ -33329,7 +33669,7 @@ window.__ModuleLoader__.load({
33329
33669
  let current = item.parentElement;
33330
33670
  for (let depth = 0; depth < 8 && current !== null; depth += 1, current = current.parentElement) counts.set(current, (counts.get(current) ?? 0) + 1);
33331
33671
  }
33332
- const candidates = [...counts.keys()].filter((element) => (counts.get(element) ?? 0) >= 3 && isWorkspaceFilterMenu(element));
33672
+ const candidates = [...counts.keys()].filter((element) => (counts.get(element) ?? 0) >= 3 && isWorkspaceFilterMenu(element) && !containsFilterTrigger(element));
33333
33673
  return candidates.filter((element) => !candidates.some((other) => other !== element && element.contains(other)));
33334
33674
  }
33335
33675
  /**
@@ -33338,12 +33678,12 @@ window.__ModuleLoader__.load({
33338
33678
  */
33339
33679
  function selectFilterMenus(menus, menuWorkspaceIds, activeWorkspaceId, allowUnidentified) {
33340
33680
  const visible = menus.filter(isVisibleMenu);
33341
- const candidates = visible.filter(isWorkspaceFilterMenu);
33681
+ const candidates = visible.filter((menu) => isWorkspaceFilterMenu(menu) && !containsFilterTrigger(menu));
33342
33682
  const owned = candidates.filter((menu) => menu.querySelector(`[${WORKSPACE_SESSION_HIDDEN_FILTER_ATTRIBUTE}]`) !== null);
33343
33683
  if (owned.length > 0) return [owned[owned.length - 1]];
33344
33684
  if (allowUnidentified && candidates.length > 0) return [candidates[candidates.length - 1]];
33345
33685
  if (!allowUnidentified) return [];
33346
- const fallback = visible.filter((menu) => menuWorkspaceIds.get(menu) === void 0 && (activeWorkspaceId === void 0 || resolveWorkspaceId(menu) !== activeWorkspaceId) && menu.querySelector(`[data-codingns-hidden-workspace-menu]`) === null);
33686
+ const fallback = visible.filter((menu) => !containsFilterTrigger(menu) && menuWorkspaceIds.get(menu) === void 0 && (activeWorkspaceId === void 0 || resolveWorkspaceId(menu) !== activeWorkspaceId) && menu.querySelector(`[data-codingns-hidden-workspace-menu]`) === null);
33347
33687
  return fallback.length > 0 ? [fallback[fallback.length - 1]] : [];
33348
33688
  }
33349
33689
  function selectWorkspaceMenus(menus, allowUnidentified, menuWorkspaceIds) {
@@ -33359,6 +33699,15 @@ window.__ModuleLoader__.load({
33359
33699
  const label = `${element.textContent ?? ""} ${element.getAttribute("aria-label") ?? ""} ${element.getAttribute("title") ?? ""}`;
33360
33700
  return WORKSPACE_FILTER_PATTERN.test(label);
33361
33701
  }
33702
+ /** 标题行里的副本不由 React 菜单持有,可以直接移除;菜单内的条目留给宿主卸载。 */
33703
+ function removeStrayFilterActions(dom) {
33704
+ for (const node of dom.querySelectorAll(`[${WORKSPACE_SESSION_HIDDEN_FILTER_ATTRIBUTE}]`)) {
33705
+ const host = node.parentElement;
33706
+ if (host !== null && isWorkspaceFilterMenu(host) && !containsFilterTrigger(host)) continue;
33707
+ if (node.closest("[role=\"menu\"], [role=\"listbox\"], [data-menu-content], [data-radix-menu-content]") !== null) continue;
33708
+ node.remove();
33709
+ }
33710
+ }
33362
33711
  function injectWorkspaceMenuActions(menus, dom, activeWorkspaceId, workspaceIds, menuWorkspaceIds, onHide, t) {
33363
33712
  for (const menu of menus) {
33364
33713
  for (const stale of menu.querySelectorAll(`[${WORKSPACE_SESSION_HIDDEN_FILTER_ATTRIBUTE}]`)) stale.remove();
@@ -33388,7 +33737,7 @@ window.__ModuleLoader__.load({
33388
33737
  }
33389
33738
  }
33390
33739
  function injectFilterMenuAction(dom, menus, checked, onChange, onClose, t) {
33391
- const menu = menus.find(isWorkspaceFilterMenu) ?? menus[menus.length - 1];
33740
+ const menu = menus.find((candidate) => isWorkspaceFilterMenu(candidate) && !containsFilterTrigger(candidate)) ?? [...menus].reverse().find((candidate) => !containsFilterTrigger(candidate));
33392
33741
  if (menu === void 0) return;
33393
33742
  for (const stale of menu.querySelectorAll(`[${WORKSPACE_SESSION_HIDDEN_MENU_ATTRIBUTE}]`)) stale.remove();
33394
33743
  const existing = menu.querySelector(`[${WORKSPACE_SESSION_HIDDEN_FILTER_ATTRIBUTE}]`);
@@ -33453,9 +33802,7 @@ window.__ModuleLoader__.load({
33453
33802
  const workspaceId = resolveWorkspaceId(header);
33454
33803
  if (workspaceId !== void 0 && !recordsById.has(workspaceId)) recordsById.set(workspaceId, {
33455
33804
  workspaceId,
33456
- title: workspaceId,
33457
- sessionIds: [],
33458
- archivedSessionIds: []
33805
+ title: workspaceId
33459
33806
  });
33460
33807
  }
33461
33808
  const hidden = [...hiddenWorkspaceIds].reverse().flatMap((workspaceId) => {
@@ -34080,7 +34427,7 @@ window.__ModuleLoader__.load({
34080
34427
  * 没有 locale 服务时的静态兜底:命名空间绑定固定指向内置中文词典,
34081
34428
  * 且不产生任何语言变更通知。生产路径由 registerSubscriptionSlot 注入 DSH locale。
34082
34429
  */
34083
- const FALLBACK_LOCALE = {
34430
+ const FALLBACK_LOCALE$1 = {
34084
34431
  bind: () => require_transport.resolveCodingNsTranslator(void 0),
34085
34432
  getSnapshot: () => ({ revision: 0 }),
34086
34433
  subscribe: () => () => {},
@@ -34136,13 +34483,13 @@ window.__ModuleLoader__.load({
34136
34483
  inject: (sessionId) => ({
34137
34484
  rpc,
34138
34485
  sessionId,
34139
- locale: locale ?? FALLBACK_LOCALE,
34486
+ locale: locale ?? FALLBACK_LOCALE$1,
34140
34487
  ...getRefreshIntervalMins === void 0 ? {} : { getRefreshIntervalMins }
34141
34488
  })
34142
34489
  }, CommandCodeSubscriptionSlot));
34143
34490
  }
34144
34491
  function CommandCodeSubscriptionSlot(props) {
34145
- const t = require_transport.useCodingNsTranslator(props.locale ?? FALLBACK_LOCALE);
34492
+ const t = require_transport.useCodingNsTranslator(props.locale ?? FALLBACK_LOCALE$1);
34146
34493
  const subscriptionUsageCache = usageCache(props.rpc);
34147
34494
  const [usage, setUsage] = (0, react.useState)(null);
34148
34495
  const [adapterId, setAdapterId] = (0, react.useState)(null);
@@ -36167,23 +36514,21 @@ window.__ModuleLoader__.load({
36167
36514
  let userInteracting = false;
36168
36515
  let userCommitPending = false;
36169
36516
  let applying = false;
36170
- let pendingShare;
36517
+ let lastRestore;
36171
36518
  const scan = () => {
36172
36519
  if (disposed || dom === void 0 || win === void 0) return;
36173
36520
  const handle = findRightbarHandle(dom);
36174
- if (handle === void 0) return;
36521
+ if (handle === void 0) {
36522
+ lastRestore = void 0;
36523
+ return;
36524
+ }
36175
36525
  if (applying) return;
36176
36526
  const share = readRightbarShare(handle, win);
36177
36527
  if (share === void 0) return;
36178
- if (pendingShare !== void 0) {
36179
- const expectedShare = pendingShare;
36180
- pendingShare = void 0;
36181
- if (sharesMatch(share, expectedShare)) return;
36182
- if (handle.style.left !== "") return;
36183
- }
36184
36528
  if (userCommitPending) {
36185
36529
  userCommitPending = false;
36186
36530
  desiredShare = share;
36531
+ lastRestore = void 0;
36187
36532
  writeStoredShare(storage, share);
36188
36533
  return;
36189
36534
  }
@@ -36222,9 +36567,7 @@ window.__ModuleLoader__.load({
36222
36567
  };
36223
36568
  const onResize = () => {
36224
36569
  if (disposed || win === void 0 || dom === void 0) return;
36225
- const handle = findRightbarHandle(dom);
36226
- const savedShare = readStoredShare(storage);
36227
- if (handle !== void 0 && savedShare !== void 0) applyShare(handle, savedShare, win);
36570
+ desiredShare = readStoredShare(storage) ?? desiredShare;
36228
36571
  scheduleScan();
36229
36572
  };
36230
36573
  dom?.addEventListener("mousedown", onPointerStart, true);
@@ -36234,7 +36577,10 @@ window.__ModuleLoader__.load({
36234
36577
  win?.addEventListener("resize", onResize);
36235
36578
  scheduleScan();
36236
36579
  return {
36237
- refresh: scheduleScan,
36580
+ refresh() {
36581
+ lastRestore = void 0;
36582
+ scheduleScan();
36583
+ },
36238
36584
  dispose() {
36239
36585
  if (disposed) return;
36240
36586
  disposed = true;
@@ -36248,10 +36594,15 @@ window.__ModuleLoader__.load({
36248
36594
  };
36249
36595
  function applyShare(handle, share, targetWindow) {
36250
36596
  const containerWidth = resolveContainerWidth(handle, targetWindow);
36597
+ if (lastRestore?.handle === handle && Math.abs(lastRestore.containerWidth - containerWidth) < 1 && sharesMatch(lastRestore.share, share)) return;
36598
+ lastRestore = {
36599
+ handle,
36600
+ containerWidth,
36601
+ share
36602
+ };
36251
36603
  const rightWidth = containerWidth * share;
36252
36604
  const targetClientX = resolveContainerRect(handle, targetWindow.innerWidth).left + containerWidth - rightWidth;
36253
36605
  applying = true;
36254
- pendingShare = share;
36255
36606
  try {
36256
36607
  const nativeResizeDispatched = dispatchNativeResize(handle, targetWindow, targetClientX);
36257
36608
  if (!nativeResizeDispatched && handle.matches("[data-side=\"rightbar\"]")) handle.style.left = `${Math.round(containerWidth - rightWidth)}px`;
@@ -36810,13 +37161,22 @@ window.__ModuleLoader__.load({
36810
37161
  version: null,
36811
37162
  command: null
36812
37163
  }]);
37164
+ const [catalogFailed, setCatalogFailed] = (0, react.useState)(false);
37165
+ const [catalogRetry, setCatalogRetry] = (0, react.useState)(0);
36813
37166
  const [open, setOpen] = (0, react.useState)(false);
36814
37167
  const rootRef = (0, react.useRef)(null);
36815
37168
  const locked = isSessionLocked(session);
36816
37169
  useDismissOnOutsidePointer(rootRef, open, () => setOpen(false));
36817
37170
  (0, react.useEffect)(() => {
36818
- return watchAdapterCatalog(props.rpc, sessionId, (value) => setAgents(require_model_catalog_cache.adapterCatalogWithDsh(value)));
36819
- }, [props.rpc, sessionId]);
37171
+ return watchAdapterCatalog(props.rpc, sessionId, (value) => {
37172
+ setAgents(require_model_catalog_cache.adapterCatalogWithDsh(value));
37173
+ setCatalogFailed(false);
37174
+ }, () => setCatalogFailed(true));
37175
+ }, [
37176
+ props.rpc,
37177
+ sessionId,
37178
+ catalogRetry
37179
+ ]);
36820
37180
  (0, react.useEffect)(() => {
36821
37181
  if (locked) setOpen(false);
36822
37182
  }, [locked]);
@@ -36865,7 +37225,24 @@ window.__ModuleLoader__.load({
36865
37225
  role: "menu",
36866
37226
  "aria-label": t("cli.selectAgent"),
36867
37227
  style: agentMenuStyle
36868
- }, ...agents.map((agent) => {
37228
+ }, catalogFailed && (0, react.createElement)("div", {
37229
+ role: "alert",
37230
+ style: {
37231
+ padding: 8,
37232
+ fontSize: require_theme.uiFontSize(13)
37233
+ }
37234
+ }, (0, react.createElement)("div", null, t("cli.catalogLoadFailed")), (0, react.createElement)("button", {
37235
+ type: "button",
37236
+ role: "menuitem",
37237
+ style: {
37238
+ ...agentOptionStyle,
37239
+ minHeight: 30
37240
+ },
37241
+ onClick: () => {
37242
+ setCatalogFailed(false);
37243
+ setCatalogRetry((value) => value + 1);
37244
+ }
37245
+ }, t("cli.retryCatalog"))), ...agents.map((agent) => {
36869
37246
  const selected = agent.id === selection.adapterId;
36870
37247
  const available = agent.installed && agent.enabled;
36871
37248
  const icon = require_model_catalog_cache.providerIconUrl(agent.id);
@@ -38060,6 +38437,7 @@ window.__ModuleLoader__.load({
38060
38437
  let visibilityDom;
38061
38438
  let rightbarDom;
38062
38439
  let disposeAdapterRefresh;
38440
+ let disposeVisibilityRefresh;
38063
38441
  let disposeSubscription;
38064
38442
  let disposeQuickPhrases;
38065
38443
  let disposeSkillCommand;
@@ -38088,6 +38466,7 @@ window.__ModuleLoader__.load({
38088
38466
  if (visibilityDom === void 0) {
38089
38467
  visibilityDom = startWorkspaceSessionVisibilityDom({
38090
38468
  remote: context.services.remote,
38469
+ readNativeWorkspaceSnapshot: () => require_native_workspace_store.readNativeWorkspaceSnapshot(context.services.uiContext),
38091
38470
  hiddenWorkspaceIds,
38092
38471
  locale: context.services.locale,
38093
38472
  onHiddenWorkspaceIdsChange: async (ids) => {
@@ -38098,11 +38477,14 @@ window.__ModuleLoader__.load({
38098
38477
  }]);
38099
38478
  }
38100
38479
  });
38480
+ disposeVisibilityRefresh = require_native_workspace_store.readNativeWorkspaceListStore(context.services.uiContext)?.subscribe(() => visibilityDom?.refresh());
38101
38481
  return;
38102
38482
  }
38103
38483
  visibilityDom.setHiddenWorkspaceIds(hiddenWorkspaceIds);
38104
38484
  };
38105
38485
  const disableWorkspaceVisibility = () => {
38486
+ disposeVisibilityRefresh?.();
38487
+ disposeVisibilityRefresh = void 0;
38106
38488
  visibilityDom?.dispose();
38107
38489
  visibilityDom = void 0;
38108
38490
  };
@@ -39344,6 +39726,167 @@ ${scope} [data-dockkit-strip-tabs] {
39344
39726
  `[${MOBILE_SETTINGS_MODAL_ATTRIBUTE}="on"]>div{box-sizing:border-box!important;min-width:0!important;flex:1 1 auto!important;width:auto!important}`,
39345
39727
  `[${MOBILE_SETTINGS_MODAL_ATTRIBUTE}="on"]>div>div:last-child{box-sizing:border-box!important;min-width:0!important;width:100%!important;padding-left:8px!important;padding-right:8px!important}`
39346
39728
  ].join("");
39729
+ //#endregion
39730
+ //#region src/client/mobile-team-panel-dom.ts
39731
+ const PANEL = "[data-team-panel][role=\"dialog\"]";
39732
+ const MOBILE = "data-codingns-mobile-team";
39733
+ const HEADER = "data-codingns-team-header";
39734
+ /** Adapt the native portal while DSH retains roster, task, and dismissal ownership. */
39735
+ function startMobileTeamPanelDom(options = {}) {
39736
+ const dom = options.document ?? (typeof document === "undefined" ? void 0 : document);
39737
+ const win = options.window ?? (typeof window === "undefined" ? void 0 : window);
39738
+ const Observer = options.MutationObserver ?? (typeof MutationObserver === "undefined" ? void 0 : MutationObserver);
39739
+ const t = require_transport.resolveCodingNsTranslator(options.locale);
39740
+ const headers = /* @__PURE__ */ new Map();
39741
+ let style;
39742
+ let queued = false;
39743
+ let disposed = false;
39744
+ const remove = (panel, header) => {
39745
+ header.remove();
39746
+ panel.removeAttribute(MOBILE);
39747
+ headers.delete(panel);
39748
+ };
39749
+ const refresh = () => {
39750
+ if (disposed || !dom) return;
39751
+ const max = typeof options.mobileViewportMaxPx === "function" ? options.mobileViewportMaxPx() : options.mobileViewportMaxPx ?? 1024;
39752
+ const width = win?.innerWidth ?? 0;
39753
+ const panels = new Set(Number.isFinite(width) && width > 0 && Number.isFinite(max) && width <= max ? dom.querySelectorAll(PANEL) : []);
39754
+ for (const [panel, header] of headers) if (!panels.has(panel)) remove(panel, header);
39755
+ if (!panels.size) {
39756
+ style?.remove();
39757
+ style = void 0;
39758
+ return;
39759
+ }
39760
+ if (!style) {
39761
+ style = dom.createElement("style");
39762
+ style.dataset.plugin = "codingns4dsh";
39763
+ style.dataset.pluginCss = "codingns4dsh-mobile-team-panel";
39764
+ style.textContent = MOBILE_TEAM_PANEL_STYLES;
39765
+ dom.head.appendChild(style);
39766
+ }
39767
+ for (const panel of panels) {
39768
+ panel.setAttribute(MOBILE, "on");
39769
+ let header = headers.get(panel);
39770
+ if (!header) {
39771
+ header = createHeader(dom, panel);
39772
+ panel.insertBefore(header, panel.firstChild);
39773
+ headers.set(panel, header);
39774
+ }
39775
+ const title = panel.getAttribute("aria-label") || t("mobile.team.title");
39776
+ const heading = header.firstElementChild;
39777
+ if (heading.textContent !== title) heading.textContent = title;
39778
+ const button = header.lastElementChild;
39779
+ const label = t("mobile.team.close");
39780
+ if (button.getAttribute("aria-label") !== label) button.setAttribute("aria-label", label);
39781
+ if (button.getAttribute("title") !== label) button.setAttribute("title", label);
39782
+ }
39783
+ };
39784
+ const schedule = () => {
39785
+ if (disposed || queued) return;
39786
+ queued = true;
39787
+ queueMicrotask(() => {
39788
+ queued = false;
39789
+ refresh();
39790
+ });
39791
+ };
39792
+ const observer = dom && Observer ? new Observer(schedule) : void 0;
39793
+ if (dom?.documentElement) observer?.observe(dom.documentElement, {
39794
+ childList: true,
39795
+ subtree: true,
39796
+ attributes: true,
39797
+ attributeFilter: ["data-team-panel", "aria-label"]
39798
+ });
39799
+ win?.addEventListener("resize", schedule);
39800
+ const unsubscribeLocale = options.locale?.subscribe(schedule);
39801
+ refresh();
39802
+ return {
39803
+ refresh,
39804
+ dispose() {
39805
+ if (disposed) return;
39806
+ disposed = true;
39807
+ observer?.disconnect();
39808
+ win?.removeEventListener("resize", schedule);
39809
+ unsubscribeLocale?.();
39810
+ for (const [panel, header] of headers) remove(panel, header);
39811
+ style?.remove();
39812
+ style = void 0;
39813
+ }
39814
+ };
39815
+ }
39816
+ function createHeader(dom, panel) {
39817
+ const header = dom.createElement("div");
39818
+ header.setAttribute(HEADER, "");
39819
+ const button = dom.createElement("button");
39820
+ button.type = "button";
39821
+ const svg = dom.createElementNS("http://www.w3.org/2000/svg", "svg");
39822
+ svg.setAttribute("viewBox", "0 0 24 24");
39823
+ svg.setAttribute("width", "20");
39824
+ svg.setAttribute("height", "20");
39825
+ svg.setAttribute("aria-hidden", "true");
39826
+ const close = dom.createElementNS("http://www.w3.org/2000/svg", "path");
39827
+ close.setAttribute("d", "M6 6l12 12m0-12L6 18");
39828
+ close.setAttribute("fill", "none");
39829
+ close.setAttribute("stroke", "currentColor");
39830
+ close.setAttribute("stroke-width", "2");
39831
+ close.setAttribute("stroke-linecap", "round");
39832
+ svg.appendChild(close);
39833
+ button.appendChild(svg);
39834
+ button.addEventListener("click", (event) => {
39835
+ event.stopPropagation();
39836
+ const Keyboard = dom.defaultView?.KeyboardEvent;
39837
+ if (!Keyboard) return;
39838
+ button.focus({ preventScroll: true });
39839
+ panel.dispatchEvent(new Keyboard("keydown", {
39840
+ key: "Escape",
39841
+ bubbles: true,
39842
+ cancelable: true
39843
+ }));
39844
+ });
39845
+ header.append(dom.createElement("strong"), button);
39846
+ return header;
39847
+ }
39848
+ const SCOPE = `[${MOBILE}="on"]`;
39849
+ const MOBILE_TEAM_PANEL_STYLES = `
39850
+ ${SCOPE} {
39851
+ box-sizing:border-box!important;
39852
+ top:max(8px, env(safe-area-inset-top, 0px))!important;
39853
+ left:max(8px, env(safe-area-inset-left, 0px))!important;
39854
+ right:max(8px, env(safe-area-inset-right, 0px))!important;
39855
+ bottom:auto!important; width:auto!important; max-width:none!important;
39856
+ height:calc(100vh - 16px)!important;
39857
+ height:calc(100dvh - max(8px, env(safe-area-inset-top, 0px)) - max(8px, env(safe-area-inset-bottom, 0px)))!important;
39858
+ max-height:none!important; padding:0!important; visibility:visible!important; overflow:hidden!important;
39859
+ }
39860
+ ${SCOPE}>[${HEADER}] {
39861
+ flex:0 0 auto; display:flex; align-items:center; justify-content:space-between; gap:12px; padding:6px 8px 6px 16px;
39862
+ border-bottom:1px solid var(--dsw-alias-border-l2, #ddd); color:var(--dsw-alias-label-primary, CanvasText);
39863
+ }
39864
+ ${SCOPE}>[${HEADER}] strong { min-width:0; font-size:15px; overflow-wrap:anywhere; }
39865
+ ${SCOPE}>[${HEADER}] button {
39866
+ display:inline-flex; align-items:center; justify-content:center; flex:0 0 44px; width:44px; height:44px;
39867
+ padding:0; border:0; border-radius:10px; color:var(--dsw-alias-label-primary, CanvasText); background:transparent;
39868
+ cursor:pointer; touch-action:manipulation; -webkit-tap-highlight-color:transparent;
39869
+ }
39870
+ ${SCOPE}>[${HEADER}] button:hover { background:var(--dsw-alias-interactive-bg-hover, rgba(127,127,127,.1)); }
39871
+ ${SCOPE}>[${HEADER}] button:focus-visible { outline:2px solid var(--dsw-focus-ring-color, #1677ff); outline-offset:-2px; }
39872
+ ${SCOPE}>[${HEADER}] svg { display:block; pointer-events:none; }
39873
+ ${SCOPE}>div:not([${HEADER}]) {
39874
+ flex:1 1 auto!important; min-height:0!important; min-width:0; padding:0 12px 12px!important;
39875
+ overflow-y:auto!important; overscroll-behavior:contain; scrollbar-gutter:auto!important; -webkit-overflow-scrolling:touch;
39876
+ }
39877
+ ${SCOPE} section:first-of-type>div { grid-template-columns:repeat(auto-fit, minmax(min(150px, 100%), 1fr))!important; }
39878
+ ${SCOPE} section:first-of-type button { min-height:64px; padding:10px!important; touch-action:manipulation; }
39879
+ ${SCOPE} section:first-of-type button>span:last-child>span { flex-wrap:wrap; }
39880
+ ${SCOPE} section:first-of-type button>span:last-child>span>span:first-child { white-space:normal!important; overflow-wrap:anywhere; }
39881
+ ${SCOPE} article { min-width:0; padding:12px!important; }
39882
+ ${SCOPE} article>div:first-child { align-items:flex-start!important; }
39883
+ ${SCOPE} article>div:first-child strong { flex:1; min-width:0; font-size:14px!important; line-height:1.45; overflow-wrap:anywhere; }
39884
+ ${SCOPE} article>div:first-child>span { flex:0 0 auto; white-space:nowrap; }
39885
+ ${SCOPE} article p { font-size:13px!important; line-height:1.55!important; overflow-wrap:anywhere; }
39886
+ ${SCOPE} article>div:last-child { display:flex; flex-wrap:wrap; align-items:center; gap:4px 10px; }
39887
+ ${SCOPE} article>div:last-child>span { min-width:0; max-width:100%; margin-right:0!important; overflow-wrap:anywhere; }
39888
+ ${SCOPE} article>div:last-child>button { float:none!important; order:1; min-height:36px; margin-left:auto!important; padding:6px!important; touch-action:manipulation; }
39889
+ `;
39347
39890
  //#endregion
39348
39891
  //#region src/client/features/mobile-access-panel.ts
39349
39892
  /**
@@ -39821,17 +40364,23 @@ ${scope} [data-dockkit-strip-tabs] {
39821
40364
  mobileViewportMaxPx: () => require_native_workspace_store.normalizeMobileAccessSettings(context.services.settings.getSnapshot().value?.mobileAccess).mobileViewportMaxPx
39822
40365
  });
39823
40366
  const rightbarTabs = startMobileRightbarTabsDom({ mobileViewportMaxPx: () => require_native_workspace_store.normalizeMobileAccessSettings(context.services.settings.getSnapshot().value?.mobileAccess).mobileViewportMaxPx });
40367
+ const teamPanel = startMobileTeamPanelDom({
40368
+ locale: context.services.locale,
40369
+ mobileViewportMaxPx: () => require_native_workspace_store.normalizeMobileAccessSettings(context.services.settings.getSnapshot().value?.mobileAccess).mobileViewportMaxPx
40370
+ });
39824
40371
  context.resources.add(context.services.settings.subscribe(() => {
39825
40372
  controller.refresh();
39826
40373
  gestures.refresh();
39827
40374
  settingsModal.refresh();
39828
40375
  rightbarTabs.refresh();
40376
+ teamPanel.refresh();
39829
40377
  }));
39830
40378
  context.resources.add(() => {
39831
40379
  controller.dispose();
39832
40380
  gestures.dispose();
39833
40381
  settingsModal.dispose();
39834
40382
  rightbarTabs.dispose();
40383
+ teamPanel.dispose();
39835
40384
  });
39836
40385
  },
39837
40386
  settingsPanel: MobileAccessPanel
@@ -40953,6 +41502,512 @@ ${scope} [data-dockkit-strip-tabs] {
40953
41502
  }
40954
41503
  };
40955
41504
  //#endregion
41505
+ //#region src/client/model-priority-pool.ts
41506
+ /** The persisted pool owns priority; modal choices and drag previews remain local until confirmed. */
41507
+ function ModelPriorityPool({ models: pool, catalog, disabled, pending, t, onChange, titleKey = "translation.modelTitle", pickerTitleKey = "translation.modelPickerTitle", helpKey = "translation.modelHelp", saveRejectedKey = "translation.saveRejected" }) {
41508
+ const available = new Map((catalog?.models ?? []).filter((model) => !require_session_translation.isSessionTranslationAdapter(model.provider)).map((model) => [modelKey(model), model]));
41509
+ const pooled = new Set(pool.map(modelKey));
41510
+ const [selection, setSelection] = (0, react.useState)(null);
41511
+ const [search, setSearch] = (0, react.useState)("");
41512
+ const [saveFailed, setSaveFailed] = (0, react.useState)(false);
41513
+ const [resetOpen, setResetOpen] = (0, react.useState)(false);
41514
+ const [resetFailed, setResetFailed] = (0, react.useState)(false);
41515
+ const [preview, setPreview] = (0, react.useState)(null);
41516
+ const [announcement, setAnnouncement] = (0, react.useState)("");
41517
+ const drag = (0, react.useRef)(null);
41518
+ const list = (0, react.useRef)(null);
41519
+ const poolIdentity = JSON.stringify(pool);
41520
+ const pickerOpen = selection !== null;
41521
+ const locked = disabled || pickerOpen || resetOpen;
41522
+ const cancelDrag = () => {
41523
+ drag.current = null;
41524
+ setPreview(null);
41525
+ };
41526
+ (0, react.useEffect)(() => {
41527
+ cancelDrag();
41528
+ }, [disabled, poolIdentity]);
41529
+ (0, react.useEffect)(() => {
41530
+ if (disabled && !pending) {
41531
+ setSelection(null);
41532
+ setResetOpen(false);
41533
+ }
41534
+ }, [disabled, pending]);
41535
+ const candidates = [...available.values()].filter((model) => !pooled.has(modelKey(model)));
41536
+ const query = search.trim().toLowerCase();
41537
+ const filtered = candidates.filter((model) => `${model.label} ${model.provider} ${model.model}`.toLowerCase().includes(query));
41538
+ const additions = [...selection ?? []].flatMap((key) => {
41539
+ const model = available.get(key);
41540
+ return model === void 0 || pooled.has(key) ? [] : [{
41541
+ provider: model.provider,
41542
+ model: model.model
41543
+ }];
41544
+ });
41545
+ const closePicker = () => {
41546
+ if (!pending) setSelection(null);
41547
+ };
41548
+ const addSelected = async () => {
41549
+ if (disabled || additions.length === 0) return;
41550
+ setSaveFailed(false);
41551
+ if (await onChange([...pool, ...additions])) setSelection(null);
41552
+ else setSaveFailed(true);
41553
+ };
41554
+ const closeReset = () => {
41555
+ if (!pending) setResetOpen(false);
41556
+ };
41557
+ const confirmReset = async () => {
41558
+ if (disabled || !resetOpen) return;
41559
+ setResetFailed(false);
41560
+ if (await onChange([])) setResetOpen(false);
41561
+ else setResetFailed(true);
41562
+ };
41563
+ const commitOrder = (order, key) => {
41564
+ if (locked) return;
41565
+ onChange(order).then((saved) => {
41566
+ if (saved) setAnnouncement(t("translation.modelReordered", {
41567
+ model: available.get(key)?.label ?? order.find((model) => modelKey(model) === key)?.model ?? "",
41568
+ priority: order.findIndex((model) => modelKey(model) === key) + 1
41569
+ }));
41570
+ });
41571
+ };
41572
+ const startDrag = (event, key) => {
41573
+ if (locked || pool.length < 2 || event.button !== 0 || list.current === null) return;
41574
+ event.preventDefault();
41575
+ event.currentTarget.focus();
41576
+ list.current.setPointerCapture(event.pointerId);
41577
+ drag.current = {
41578
+ pointerId: event.pointerId,
41579
+ key,
41580
+ startY: event.clientY,
41581
+ original: pool,
41582
+ order: pool
41583
+ };
41584
+ };
41585
+ const rowAtPointer = (event) => {
41586
+ const target = event.currentTarget.ownerDocument.elementFromPoint(event.clientX, event.clientY)?.closest("[data-codingns-translation-model-key]");
41587
+ return target !== null && target !== void 0 && list.current?.contains(target) ? target : void 0;
41588
+ };
41589
+ const moveDrag = (event) => {
41590
+ const current = drag.current;
41591
+ const root = list.current;
41592
+ if (locked || current === null || current.pointerId !== event.pointerId || root === null) return;
41593
+ if (preview === null && Math.abs(event.clientY - current.startY) < 4) return;
41594
+ event.preventDefault();
41595
+ const rect = root.getBoundingClientRect();
41596
+ if (event.clientY < rect.top + 24) root.scrollTop -= 12;
41597
+ else if (event.clientY > rect.bottom - 24) root.scrollTop += 12;
41598
+ const target = rowAtPointer(event);
41599
+ if (target === void 0) return;
41600
+ const targetIndex = current.order.findIndex((model) => modelKey(model) === target.dataset.codingnsTranslationModelKey);
41601
+ const sourceIndex = current.order.findIndex((model) => modelKey(model) === current.key);
41602
+ if (targetIndex < 0 || sourceIndex < 0 || targetIndex === sourceIndex) return;
41603
+ const next = {
41604
+ ...current,
41605
+ order: moveModel(current.order, sourceIndex, targetIndex)
41606
+ };
41607
+ drag.current = next;
41608
+ setPreview(next);
41609
+ };
41610
+ const finishDrag = (event) => {
41611
+ const current = drag.current;
41612
+ if (current === null || current.pointerId !== event.pointerId) return;
41613
+ cancelDrag();
41614
+ if (!locked && rowAtPointer(event) !== void 0 && JSON.stringify(current.order) !== JSON.stringify(current.original)) commitOrder(current.order, current.key);
41615
+ };
41616
+ const keyboardMove = (event, key) => {
41617
+ if (event.key === "Escape" && drag.current !== null) {
41618
+ event.stopPropagation();
41619
+ cancelDrag();
41620
+ return;
41621
+ }
41622
+ if (locked || drag.current !== null || ![
41623
+ "ArrowUp",
41624
+ "ArrowDown",
41625
+ "Home",
41626
+ "End"
41627
+ ].includes(event.key)) return;
41628
+ event.preventDefault();
41629
+ const index = pool.findIndex((model) => modelKey(model) === key);
41630
+ const target = event.key === "Home" ? 0 : event.key === "End" ? pool.length - 1 : index + (event.key === "ArrowUp" ? -1 : 1);
41631
+ if (index >= 0 && target >= 0 && target < pool.length && target !== index) commitOrder(moveModel(pool, index, target), key);
41632
+ };
41633
+ return (0, react.createElement)("div", {
41634
+ className: "codingns-translation-pool",
41635
+ "aria-busy": pending
41636
+ }, (0, react.createElement)("style", null, modelPoolCss), (0, react.createElement)("div", { className: "codingns-translation-pool-toolbar" }, (0, react.createElement)("span", { style: require_theme.dshSettingsHelpStyle }, t(pool.length === 0 ? "translation.modelDefaultActive" : "translation.modelPoolCount", { count: pool.length })), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
41637
+ type: "button",
41638
+ variant: "outline",
41639
+ size: "sm",
41640
+ disabled: disabled || resetOpen,
41641
+ icon: (0, react.createElement)(require_primitives_adapter.resolvePlusIcon(), { size: 14 }),
41642
+ "aria-haspopup": "dialog",
41643
+ "aria-expanded": pickerOpen,
41644
+ onClick: () => {
41645
+ if (!disabled && !resetOpen) {
41646
+ setSearch("");
41647
+ setSaveFailed(false);
41648
+ setSelection(/* @__PURE__ */ new Set());
41649
+ }
41650
+ }
41651
+ }, t("translation.modelAdd"))), pool.length === 0 ? (0, react.createElement)("div", { className: "codingns-translation-pool-empty" }, (0, react.createElement)(require_primitives_adapter.resolveDataIcon(), { size: 22 }), (0, react.createElement)("span", null, t("translation.modelPoolEmpty"))) : (0, react.createElement)("ol", {
41652
+ ref: list,
41653
+ className: "codingns-translation-pool-list",
41654
+ "aria-label": t(titleKey),
41655
+ onPointerMove: moveDrag,
41656
+ onPointerUp: finishDrag,
41657
+ onPointerCancel: cancelDrag,
41658
+ onLostPointerCapture: cancelDrag
41659
+ }, ...(preview?.order ?? pool).map((model, index) => {
41660
+ const key = modelKey(model);
41661
+ const entry = available.get(key);
41662
+ const label = entry?.label ?? `${model.provider} / ${model.model}`;
41663
+ return (0, react.createElement)("li", {
41664
+ key,
41665
+ "data-codingns-translation-model-key": key,
41666
+ className: `codingns-translation-pool-row${preview?.key === key ? " is-dragging" : ""}`
41667
+ }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
41668
+ type: "button",
41669
+ size: "sm",
41670
+ disabled: locked || pool.length < 2,
41671
+ className: "codingns-translation-pool-handle",
41672
+ "aria-label": t("translation.modelDrag", { model: label }),
41673
+ title: t("translation.modelDragHelp"),
41674
+ onPointerDown: (event) => startDrag(event, key),
41675
+ onKeyDown: (event) => keyboardMove(event, key)
41676
+ }, (0, react.createElement)(DragHandleIcon)), (0, react.createElement)("span", {
41677
+ className: "codingns-translation-pool-priority",
41678
+ title: t("translation.modelPriority", { priority: index + 1 })
41679
+ }, index + 1), (0, react.createElement)(ModelIdentity, {
41680
+ model,
41681
+ label,
41682
+ t
41683
+ }), catalog !== null && entry === void 0 && (0, react.createElement)("span", { className: "codingns-translation-pool-unavailable" }, t("translation.modelUnavailable")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
41684
+ type: "button",
41685
+ size: "sm",
41686
+ disabled: locked,
41687
+ className: "codingns-translation-pool-remove",
41688
+ "aria-label": t("translation.modelRemove", { model: label }),
41689
+ title: t("translation.modelRemove", { model: label }),
41690
+ onClick: () => {
41691
+ if (!locked) onChange(pool.filter((item) => modelKey(item) !== key));
41692
+ }
41693
+ }, (0, react.createElement)(require_primitives_adapter.resolveAssistantControlIcon("close"), { size: 14 })));
41694
+ })), (0, react.createElement)("div", { className: "codingns-translation-pool-toolbar" }, (0, react.createElement)("span", { style: {
41695
+ ...require_theme.dshSettingsHelpStyle,
41696
+ flex: 1
41697
+ } }, t(helpKey)), pool.length > 0 && (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
41698
+ type: "button",
41699
+ size: "sm",
41700
+ disabled: disabled || pickerOpen,
41701
+ style: { color: require_theme.dshThemeColor.error },
41702
+ "aria-haspopup": "dialog",
41703
+ "aria-expanded": resetOpen,
41704
+ onClick: () => {
41705
+ if (!locked) {
41706
+ setResetFailed(false);
41707
+ setResetOpen(true);
41708
+ }
41709
+ }
41710
+ }, t("translation.modelFollowDefault"))), (0, react.createElement)("span", {
41711
+ role: "status",
41712
+ "aria-live": "polite",
41713
+ className: "codingns-translation-pool-status"
41714
+ }, announcement), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
41715
+ open: pickerOpen,
41716
+ onClose: closePicker,
41717
+ title: t(pickerTitleKey),
41718
+ closeLabel: t("translation.modelCancel"),
41719
+ description: t("translation.modelPickerHelp"),
41720
+ className: "codingns-translation-model-picker",
41721
+ contentClassName: "codingns-translation-model-picker-content",
41722
+ footer: (0, react.createElement)(react.Fragment, null, (0, react.createElement)("span", {
41723
+ className: "codingns-translation-picker-count",
41724
+ "aria-live": "polite",
41725
+ style: require_theme.dshSettingsHelpStyle
41726
+ }, t("translation.modelPickerCount", { count: additions.length })), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
41727
+ type: "button",
41728
+ variant: "outline",
41729
+ disabled: pending,
41730
+ onClick: closePicker
41731
+ }, t("translation.modelCancel")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
41732
+ type: "button",
41733
+ variant: "primary",
41734
+ disabled: disabled || additions.length === 0,
41735
+ onClick: () => {
41736
+ addSelected();
41737
+ }
41738
+ }, t("translation.modelAddSelected", { count: additions.length })))
41739
+ }, (0, react.createElement)("div", {
41740
+ className: "codingns-translation-picker-body",
41741
+ "aria-busy": pending
41742
+ }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Input, {
41743
+ type: "search",
41744
+ value: search,
41745
+ placeholder: t("translation.modelSearch"),
41746
+ "aria-label": t("translation.modelSearch"),
41747
+ "data-modal-autofocus": true,
41748
+ disabled,
41749
+ onChange: (event) => setSearch(event.currentTarget.value)
41750
+ }), (0, react.createElement)("div", {
41751
+ className: "codingns-translation-picker-list",
41752
+ role: "group",
41753
+ "aria-label": t(pickerTitleKey)
41754
+ }, ...filtered.map((model) => {
41755
+ const key = modelKey(model);
41756
+ return (0, react.createElement)("div", {
41757
+ key,
41758
+ className: `codingns-translation-picker-choice${selection?.has(key) ? " is-selected" : ""}`
41759
+ }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Checkbox, {
41760
+ checked: selection?.has(key) === true,
41761
+ disabled,
41762
+ label: model.label,
41763
+ onChange: (checked) => {
41764
+ if (disabled) return;
41765
+ setSelection((previous) => {
41766
+ const next = new Set(previous);
41767
+ if (checked) next.add(key);
41768
+ else next.delete(key);
41769
+ return next;
41770
+ });
41771
+ }
41772
+ }), (0, react.createElement)("span", {
41773
+ className: "codingns-translation-picker-provider",
41774
+ style: require_theme.dshSettingsHelpStyle
41775
+ }, t(isOfficialProvider(model.provider) ? "translation.modelOfficial" : "translation.modelThirdParty")));
41776
+ }), filtered.length > 0 ? null : (0, react.createElement)("div", {
41777
+ className: "codingns-translation-pool-empty",
41778
+ role: "status"
41779
+ }, t(catalog === null ? "translation.modelLoading" : candidates.length > 0 ? "translation.modelNoMatches" : available.size > 0 ? "translation.modelAllAdded" : "translation.modelEmpty"))), saveFailed && (0, react.createElement)("span", {
41780
+ role: "alert",
41781
+ style: {
41782
+ ...require_theme.dshSettingsHelpStyle,
41783
+ color: require_theme.dshThemeColor.error
41784
+ }
41785
+ }, t(saveRejectedKey)))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
41786
+ open: resetOpen,
41787
+ onClose: closeReset,
41788
+ title: t("translation.modelResetTitle"),
41789
+ closeLabel: t("translation.modelCancel"),
41790
+ description: t("translation.modelResetHelp", { count: pool.length }),
41791
+ footer: (0, react.createElement)(react.Fragment, null, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
41792
+ type: "button",
41793
+ variant: "outline",
41794
+ disabled: pending,
41795
+ "data-modal-autofocus": true,
41796
+ onClick: closeReset
41797
+ }, t("translation.modelCancel")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
41798
+ type: "button",
41799
+ variant: "outline",
41800
+ disabled,
41801
+ style: { color: require_theme.dshThemeColor.error },
41802
+ onClick: () => {
41803
+ confirmReset();
41804
+ }
41805
+ }, t("translation.modelResetConfirm")))
41806
+ }, resetFailed ? (0, react.createElement)("span", {
41807
+ role: "alert",
41808
+ style: {
41809
+ ...require_theme.dshSettingsHelpStyle,
41810
+ color: require_theme.dshThemeColor.error
41811
+ }
41812
+ }, t(saveRejectedKey)) : void 0));
41813
+ }
41814
+ function modelKey(model) {
41815
+ return JSON.stringify([model.provider, model.model]);
41816
+ }
41817
+ function moveModel(pool, source, target) {
41818
+ const next = [...pool];
41819
+ const model = next.splice(source, 1)[0];
41820
+ if (model !== void 0) next.splice(target, 0, model);
41821
+ return next;
41822
+ }
41823
+ function isOfficialProvider(provider) {
41824
+ return /^(?:deepseek(?:-official)?|official-deepseek)$/iu.test(provider.trim());
41825
+ }
41826
+ function ModelIdentity({ model, label, t }) {
41827
+ const [provider, ...name] = label.split(" / ");
41828
+ return (0, react.createElement)("div", {
41829
+ className: "codingns-translation-pool-identity",
41830
+ title: label
41831
+ }, (0, react.createElement)("span", { className: "codingns-translation-pool-name" }, name.join(" / ") || model.model), (0, react.createElement)("span", { style: require_theme.dshSettingsHelpStyle }, `${provider ?? model.provider} · ${t(isOfficialProvider(model.provider) ? "translation.modelOfficial" : "translation.modelThirdParty")}`));
41832
+ }
41833
+ function DragHandleIcon() {
41834
+ return (0, react.createElement)("svg", {
41835
+ width: 14,
41836
+ height: 18,
41837
+ viewBox: "0 0 14 18",
41838
+ fill: "currentColor",
41839
+ "aria-hidden": true,
41840
+ focusable: false
41841
+ }, ...[5, 9].flatMap((cx) => [
41842
+ 4,
41843
+ 9,
41844
+ 14
41845
+ ].map((cy) => (0, react.createElement)("circle", {
41846
+ key: `${cx}:${cy}`,
41847
+ cx,
41848
+ cy,
41849
+ r: 1
41850
+ }))));
41851
+ }
41852
+ const modelPoolCss = `
41853
+ .codingns-translation-pool{display:grid;gap:10px;min-width:0}
41854
+ .codingns-translation-pool-toolbar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}
41855
+ .codingns-translation-pool-list{list-style:none;margin:0;padding:0;max-height:352px;overflow:auto;overscroll-behavior:contain;border:.5px solid ${require_theme.dshThemeColor.menuBorder};border-radius:var(--dsw-radius-md,12px);background:${require_theme.dshThemeColor.pageBackground}}
41856
+ .codingns-translation-pool-row{display:flex;align-items:center;gap:10px;min-height:64px;padding:8px 12px 8px 6px;box-sizing:border-box}
41857
+ .codingns-translation-pool-row:not(:last-child){border-bottom:.5px solid ${require_theme.dshThemeColor.menuBorder}}
41858
+ .codingns-translation-pool-row:hover{background:${require_theme.dshThemeColor.hoverBackground}}
41859
+ .codingns-translation-pool-row.is-dragging{background:${require_theme.dshThemeColor.activeBackground};box-shadow:inset 2px 0 ${require_theme.dshThemeColor.accent}}
41860
+ .codingns-translation-pool .codingns-translation-pool-handle{width:28px;flex:0 0 28px;padding:0;touch-action:none;cursor:grab;color:${require_theme.dshThemeColor.labelTertiary}}
41861
+ .codingns-translation-pool .codingns-translation-pool-handle:active{cursor:grabbing}
41862
+ .codingns-translation-pool .codingns-translation-pool-handle:disabled{cursor:default}
41863
+ .codingns-translation-pool-priority{display:flex;align-items:center;justify-content:center;flex:0 0 24px;height:24px;border-radius:var(--dsw-radius-sm,8px);background:${require_theme.dshThemeColor.surfaceSubtle};color:${require_theme.dshThemeColor.labelSecondary};font-size:${require_theme.uiFontSize(12)};font-variant-numeric:tabular-nums}
41864
+ .codingns-translation-pool-identity{display:grid;gap:2px;min-width:0;flex:1}
41865
+ .codingns-translation-pool-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:${require_theme.dshThemeColor.labelPrimary};font-size:${require_theme.uiFontSize(13)};font-weight:500;line-height:20px}
41866
+ .codingns-translation-pool-identity>span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
41867
+ .codingns-translation-pool .codingns-translation-pool-remove{flex:0 0 28px;width:28px;padding:0;color:${require_theme.dshThemeColor.labelTertiary}}
41868
+ .codingns-translation-pool-unavailable{max-width:110px;flex-shrink:0;color:${require_theme.dshThemeColor.warning};font-size:${require_theme.uiFontSize(11)};line-height:16px}
41869
+ .codingns-translation-pool-empty{display:flex;align-items:center;justify-content:center;gap:10px;padding:22px 14px;color:${require_theme.dshThemeColor.labelTertiary};background:${require_theme.dshThemeColor.surfaceSubtle};border-radius:var(--dsw-radius-md,12px);font-size:${require_theme.uiFontSize(12)};text-align:center;line-height:20px}
41870
+ .codingns-translation-pool-status{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
41871
+ .codingns-translation-model-picker{width:min(520px,100%);max-height:100%;color:${require_theme.dshThemeColor.labelPrimary}}
41872
+ .codingns-translation-model-picker-content{min-height:0;overflow:auto}
41873
+ .codingns-translation-picker-body{display:grid;gap:12px;padding-bottom:4px}
41874
+ .codingns-translation-picker-list{display:grid;gap:6px;min-height:80px;max-height:320px;overflow:auto;overscroll-behavior:contain}
41875
+ .codingns-translation-picker-choice{display:grid;gap:3px;padding:10px 12px;border:.5px solid ${require_theme.dshThemeColor.menuBorder};border-radius:var(--dsw-radius-sm,8px);background:${require_theme.dshThemeColor.pageBackground}}
41876
+ .codingns-translation-picker-choice:hover,.codingns-translation-picker-choice.is-selected{background:${require_theme.dshThemeColor.hoverBackground}}
41877
+ .codingns-translation-picker-choice>label{align-items:flex-start;gap:10px;overflow-wrap:anywhere}
41878
+ .codingns-translation-picker-choice input{margin-top:2px}
41879
+ .codingns-translation-picker-provider{padding-left:26px}
41880
+ .codingns-translation-picker-count{margin-right:auto}
41881
+ @media(max-width:480px){.codingns-translation-pool-row{gap:6px;padding-right:8px}.codingns-translation-pool-unavailable{max-width:70px}.codingns-translation-picker-choice{padding:10px}}
41882
+ `;
41883
+ //#endregion
41884
+ //#region src/client/git-management-settings.ts
41885
+ function GitManagementSettingsPanel({ services, enabled, snapshot, notify }) {
41886
+ const t = require_transport.useCodingNsTranslator(services.locale);
41887
+ const value = require_native_workspace_store.normalizeGitManagementSettings(snapshot.value?.gitManagement);
41888
+ const [saving, setSaving] = (0, react.useState)(false);
41889
+ const [promptDraft, setPromptDraft] = (0, react.useState)(null);
41890
+ const promptText = promptDraft ?? value.commitMessagePrompt;
41891
+ const savingRef = (0, react.useRef)(false);
41892
+ const [catalog, setCatalog] = (0, react.useState)(null);
41893
+ const disabled = !enabled || snapshot.status !== "ready" || !snapshot.writable || saving;
41894
+ const generationDisabled = disabled || !value.commitMessageEnabled;
41895
+ (0, react.useEffect)(() => {
41896
+ if (!enabled) return;
41897
+ const abort = new AbortController();
41898
+ services.rpc.call(require_transport.CODINGNS_RPC_CHANNEL, "git/models", {}, AbortSignal.any([abort.signal, AbortSignal.timeout(1e4)])).then((result) => {
41899
+ if (!abort.signal.aborted && result.ok) setCatalog(result.value);
41900
+ }).catch(() => void 0);
41901
+ return () => abort.abort();
41902
+ }, [services.rpc, enabled]);
41903
+ const save = async (patch) => {
41904
+ if (disabled || savingRef.current) return false;
41905
+ savingRef.current = true;
41906
+ setSaving(true);
41907
+ try {
41908
+ const next = {
41909
+ ...require_native_workspace_store.normalizeGitManagementSettings(services.settings.getSnapshot().value?.gitManagement),
41910
+ ...patch
41911
+ };
41912
+ if (!await services.settings.set("gitManagement", next)) throw new Error(t("settings.moduleWriteRejected"));
41913
+ notify({
41914
+ kind: "success",
41915
+ message: t("git.settingsSaved")
41916
+ });
41917
+ return true;
41918
+ } catch (error) {
41919
+ notify({
41920
+ kind: "error",
41921
+ message: error instanceof Error ? error.message : String(error)
41922
+ });
41923
+ return false;
41924
+ } finally {
41925
+ savingRef.current = false;
41926
+ setSaving(false);
41927
+ }
41928
+ };
41929
+ return (0, react.createElement)("div", {
41930
+ style: {
41931
+ ...require_theme.dshFormRootStyle,
41932
+ opacity: disabled ? .55 : 1,
41933
+ pointerEvents: disabled ? "none" : "auto"
41934
+ },
41935
+ "aria-disabled": disabled
41936
+ }, (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
41937
+ label: t("git.generationEnabled"),
41938
+ description: t("git.generationEnabledHelp"),
41939
+ checked: value.commitMessageEnabled,
41940
+ disabled,
41941
+ onChange: (checked) => {
41942
+ save({ commitMessageEnabled: checked });
41943
+ }
41944
+ }), (0, react.createElement)("div", {
41945
+ "aria-disabled": generationDisabled,
41946
+ style: {
41947
+ opacity: generationDisabled ? .55 : 1,
41948
+ pointerEvents: generationDisabled ? "none" : "auto"
41949
+ }
41950
+ }, (0, react.createElement)("label", { style: {
41951
+ ...require_theme.dshSettingsListRowStyle,
41952
+ flexDirection: "column",
41953
+ alignItems: "stretch",
41954
+ gap: 6
41955
+ } }, (0, react.createElement)("span", { style: require_theme.dshSettingsFieldLabelStyle }, t("git.messageDetail")), (0, react.createElement)("select", {
41956
+ value: value.commitMessageDetail,
41957
+ disabled: generationDisabled,
41958
+ style: require_theme.dshSettingsFieldStyle,
41959
+ onChange: (event) => {
41960
+ save({ commitMessageDetail: event.currentTarget.value === "detailed" ? "detailed" : "concise" });
41961
+ }
41962
+ }, (0, react.createElement)("option", { value: "concise" }, t("git.messageConcise")), (0, react.createElement)("option", { value: "detailed" }, t("git.messageDetailed")))), (0, react.createElement)("div", { style: {
41963
+ ...require_theme.dshSettingsFieldLabelStyle,
41964
+ margin: "12px 0 8px"
41965
+ } }, t("git.messageModels")), (0, react.createElement)(ModelPriorityPool, {
41966
+ models: value.commitMessageModels,
41967
+ catalog,
41968
+ disabled: generationDisabled,
41969
+ pending: saving,
41970
+ t,
41971
+ titleKey: "git.messageModels",
41972
+ pickerTitleKey: "git.messageModelsPicker",
41973
+ helpKey: "git.messageModelsHelp",
41974
+ saveRejectedKey: "settings.moduleWriteRejected",
41975
+ onChange: (models) => save({ commitMessageModels: models })
41976
+ }), (0, react.createElement)("div", { style: {
41977
+ display: "grid",
41978
+ gap: 6,
41979
+ marginTop: 16
41980
+ } }, (0, react.createElement)("label", { style: {
41981
+ display: "grid",
41982
+ gap: 6
41983
+ } }, (0, react.createElement)("span", { style: require_theme.dshSettingsFieldLabelStyle }, t("git.messagePrompt")), (0, react.createElement)("textarea", {
41984
+ rows: 5,
41985
+ value: promptText,
41986
+ maxLength: require_native_workspace_store.MAX_GIT_COMMIT_PROMPT_CHARS,
41987
+ disabled: generationDisabled,
41988
+ "aria-label": t("git.messagePrompt"),
41989
+ placeholder: t("git.messagePromptPlaceholder"),
41990
+ style: {
41991
+ ...require_theme.dshSettingsFieldStyle,
41992
+ resize: "vertical"
41993
+ },
41994
+ onChange: (event) => {
41995
+ if (!generationDisabled) setPromptDraft(event.currentTarget.value);
41996
+ }
41997
+ })), (0, react.createElement)("div", { style: require_theme.dshSettingsHelpStyle }, t("git.messagePromptHelp")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
41998
+ type: "button",
41999
+ variant: "outline",
42000
+ size: "sm",
42001
+ style: { justifySelf: "start" },
42002
+ disabled: generationDisabled || promptText === value.commitMessagePrompt,
42003
+ onClick: () => {
42004
+ if (!generationDisabled) save({ commitMessagePrompt: promptText }).then((accepted) => {
42005
+ if (accepted) setPromptDraft(null);
42006
+ });
42007
+ }
42008
+ }, t(saving ? "git.messagePromptSaving" : "git.messagePromptSave")))));
42009
+ }
42010
+ //#endregion
40956
42011
  //#region src/client/git-history-graph.ts
40957
42012
  /**
40958
42013
  * 版本列表左侧提交图的泳道布局。
@@ -41171,6 +42226,10 @@ ${scope} [data-dockkit-strip-tabs] {
41171
42226
  * 内联样式只负责尺寸与排版。取值全部来自 DSH 真实令牌,与内置组件同一套观感。
41172
42227
  */
41173
42228
  const gitPanelClass = {
42229
+ panel: "codingns4dsh-git-panel",
42230
+ contentGrid: "codingns4dsh-git-content-grid",
42231
+ column: "codingns4dsh-git-column",
42232
+ columnSwitch: "codingns4dsh-git-column-switch",
41174
42233
  action: "codingns4dsh-git-action",
41175
42234
  actionDanger: "codingns4dsh-git-action-danger",
41176
42235
  button: "codingns4dsh-git-button",
@@ -41205,6 +42264,16 @@ ${scope} [data-dockkit-strip-tabs] {
41205
42264
  const active = "background:var(--dsw-alias-interactive-bg-active)";
41206
42265
  const disabled = "opacity:.4;cursor:not-allowed";
41207
42266
  const gitPanelCss = `
42267
+ .${gitPanelClass.panel}{container-type:inline-size;container-name:codingns4dsh-git;scrollbar-gutter:stable}
42268
+ .${gitPanelClass.contentGrid}{grid-template-columns:minmax(0,1fr)}
42269
+ .${gitPanelClass.column},.${gitPanelClass.columnSwitch}{display:flex}
42270
+ .${gitPanelClass.contentGrid}[data-active-column='files']>[data-git-column='history'],.${gitPanelClass.contentGrid}[data-active-column='history']>[data-git-column='files']{display:none}
42271
+ /* Column visibility depends on the scrollport width, never on the rendered grid tracks. */
42272
+ @container codingns4dsh-git (min-width:612px){
42273
+ .${gitPanelClass.columnSwitch}{display:none}
42274
+ .${gitPanelClass.contentGrid}{grid-template-columns:repeat(2,minmax(0,1fr))}
42275
+ .${gitPanelClass.contentGrid}[data-active-column]>[data-git-column]{display:flex}
42276
+ }
41208
42277
  .${gitPanelClass.action}{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;padding:0;border:0;border-radius:var(--dsw-radius-sm);color:var(--dsw-alias-label-secondary);background:transparent;cursor:pointer;font-size:16px;line-height:1}
41209
42278
  .${gitPanelClass.action}:hover:not(:disabled){${hover};color:var(--dsw-alias-label-primary)}
41210
42279
  .${gitPanelClass.action}:active:not(:disabled){${active}}
@@ -41343,6 +42412,7 @@ ${scope} [data-dockkit-strip-tabs] {
41343
42412
  rpc: services.rpc,
41344
42413
  remote: services.remote,
41345
42414
  uiContext: ctx,
42415
+ settings: services.settings,
41346
42416
  t
41347
42417
  })
41348
42418
  }, GitPanel)));
@@ -41406,6 +42476,11 @@ ${scope} [data-dockkit-strip-tabs] {
41406
42476
  function GitPanel(props) {
41407
42477
  const sessionId = String(props.sessionId);
41408
42478
  const t = props.t;
42479
+ const settingsStore = (0, react.useMemo)(() => ({
42480
+ subscribe: (listener) => props.settings?.subscribe(listener) ?? (() => void 0),
42481
+ read: () => props.settings?.getSnapshot()
42482
+ }), [props.settings]);
42483
+ const generationEnabled = (0, react.useSyncExternalStore)(settingsStore.subscribe, settingsStore.read, settingsStore.read)?.value?.gitManagement?.commitMessageEnabled !== false;
41409
42484
  const tabInfo = props.useTabInfo();
41410
42485
  useGitWorkspaceSnapshot(props.uiContext);
41411
42486
  const projectedWorkspaceId = require_native_workspace_store.readNativeWorkspaceSnapshot(props.uiContext)?.items.find((item) => item.sessionIds.includes(sessionId))?.workspaceId;
@@ -41414,43 +42489,37 @@ ${scope} [data-dockkit-strip-tabs] {
41414
42489
  const [history, setHistory] = (0, react.useState)([]);
41415
42490
  const [branches, setBranches] = (0, react.useState)(null);
41416
42491
  const [subject, setSubject] = (0, react.useState)("");
41417
- const [busy, setBusy] = (0, react.useState)(false);
42492
+ const [operationBusy, setBusy] = (0, react.useState)(false);
42493
+ const [generating, setGenerating] = (0, react.useState)(false);
42494
+ const draftRequest = (0, react.useRef)(null);
42495
+ const busy = operationBusy || generating;
41418
42496
  const [activeOperation, setActiveOperation] = (0, react.useState)(null);
41419
42497
  const [toast, setToast] = (0, react.useState)(null);
41420
42498
  const [diffView, setDiffView] = (0, react.useState)(null);
41421
42499
  const [fileDiff, setFileDiff] = (0, react.useState)(null);
41422
- const [singleColumn, setSingleColumn] = (0, react.useState)(false);
41423
42500
  const [activeColumn, setActiveColumn] = (0, react.useState)("files");
41424
42501
  const [historyScope, setHistoryScope] = (0, react.useState)("all");
41425
42502
  const [historyTotalCount, setHistoryTotalCount] = (0, react.useState)(0);
41426
42503
  const [historyLoadingMore, setHistoryLoadingMore] = (0, react.useState)(false);
41427
- const contentGridRef = (0, react.useRef)(null);
41428
42504
  const historyExpanded = (0, react.useRef)(false);
41429
42505
  const gridVisible = status !== null && status.snapshot.enabled !== false;
42506
+ (0, react.useEffect)(() => {
42507
+ setGenerating(false);
42508
+ return () => {
42509
+ draftRequest.current?.abort();
42510
+ draftRequest.current = null;
42511
+ };
42512
+ }, [
42513
+ workspaceId,
42514
+ generationEnabled,
42515
+ sessionId,
42516
+ projectedWorkspaceId
42517
+ ]);
41430
42518
  (0, react.useEffect)(() => {
41431
42519
  if (toast === null) return;
41432
42520
  const timer = globalThis.setTimeout(() => setToast(null), 3200);
41433
42521
  return () => globalThis.clearTimeout(timer);
41434
42522
  }, [toast]);
41435
- (0, react.useEffect)(() => {
41436
- const element = contentGridRef.current;
41437
- if (element === null) {
41438
- setSingleColumn(false);
41439
- return;
41440
- }
41441
- const update = () => {
41442
- const tracks = getComputedStyle(element).gridTemplateColumns.split(" ").filter((track) => track !== "");
41443
- setSingleColumn(tracks.length <= 1);
41444
- };
41445
- update();
41446
- if (typeof ResizeObserver === "undefined") {
41447
- window.addEventListener("resize", update);
41448
- return () => window.removeEventListener("resize", update);
41449
- }
41450
- const observer = new ResizeObserver(update);
41451
- observer.observe(element);
41452
- return () => observer.disconnect();
41453
- }, [gridVisible]);
41454
42523
  const notify = (kind, message) => setToast({
41455
42524
  kind,
41456
42525
  message
@@ -41624,6 +42693,26 @@ ${scope} [data-dockkit-strip-tabs] {
41624
42693
  }
41625
42694
  run("git/commit", { subject: value }, () => setSubject(""));
41626
42695
  };
42696
+ const generateMessage = async () => {
42697
+ if (!generationEnabled || busy || workspaceId === void 0 || draftRequest.current !== null) return;
42698
+ const abort = new AbortController();
42699
+ draftRequest.current = abort;
42700
+ setGenerating(true);
42701
+ notify("info", t("git.generatingMessage"));
42702
+ try {
42703
+ const draft = await call$1(props.rpc, "git/generate-message", { workspaceId }, abort.signal);
42704
+ if (abort.signal.aborted) return;
42705
+ setSubject(draft.message);
42706
+ setToast(null);
42707
+ } catch (error) {
42708
+ if (!abort.signal.aborted) notify("error", error instanceof Error ? error.message : String(error));
42709
+ } finally {
42710
+ if (draftRequest.current === abort) {
42711
+ draftRequest.current = null;
42712
+ setGenerating(false);
42713
+ }
42714
+ }
42715
+ };
41627
42716
  const copyCommitHash = (commitHash) => {
41628
42717
  copyText(commitHash).then((copied) => notify(copied ? "success" : "error", copied ? t("git.commitHashCopied") : t("git.copyUnsupported")));
41629
42718
  };
@@ -41692,10 +42781,14 @@ ${scope} [data-dockkit-strip-tabs] {
41692
42781
  const discardAll = () => {
41693
42782
  run("git/discard", { targets: changes.map((item) => item.path) });
41694
42783
  };
41695
- return (0, react.createElement)("section", {
42784
+ const panel = (0, react.createElement)("section", {
42785
+ className: gitPanelClass.panel,
41696
42786
  style: panelStyle,
41697
42787
  "data-git-management-panel": "true"
41698
- }, (0, react.createElement)("header", { style: headerStyle }, singleColumn ? (0, react.createElement)("div", { style: columnSwitchStyle }, (0, react.createElement)(SegmentedControl, {
42788
+ }, (0, react.createElement)("header", { style: headerStyle }, gridVisible ? (0, react.createElement)("div", {
42789
+ className: gitPanelClass.columnSwitch,
42790
+ style: columnSwitchStyle
42791
+ }, (0, react.createElement)(SegmentedControl, {
41699
42792
  id: "codingns4dsh-git-view",
41700
42793
  value: activeColumn,
41701
42794
  onChange: setActiveColumn,
@@ -41747,39 +42840,35 @@ ${scope} [data-dockkit-strip-tabs] {
41747
42840
  unstaged: unstaged.length,
41748
42841
  total: historyTotalCount,
41749
42842
  scope: historyScope === "all" ? t("git.allBranches") : t("git.currentBranch")
41750
- })) : null, diffView !== null ? (0, react.createElement)(DiffViewer, {
41751
- diff: diffView,
41752
- onClose: () => setDiffView(null),
41753
- t
41754
- }) : null, fileDiff !== null ? (0, react.createElement)(FileDiffViewer, {
41755
- path: fileDiff.path,
41756
- staged: fileDiff.staged,
41757
- diff: fileDiff.diff,
41758
- onClose: () => setFileDiff(null),
41759
- t
41760
- }) : null, status !== null && status.snapshot.enabled !== false ? (0, react.createElement)("div", {
41761
- ref: contentGridRef,
41762
- style: contentGridStyle
41763
- }, singleColumn && activeColumn !== "files" ? null : (0, react.createElement)("div", { style: columnStyle }, (0, react.createElement)("section", { style: commitSectionStyle }, (0, react.createElement)("div", { style: sectionHeaderStyle }, (0, react.createElement)("strong", void 0, t("git.commitChanges")), (0, react.createElement)("span", { style: mutedStyle }, staged.length === 0 ? t("git.stagingEmpty") : t("git.stagedCount", { count: staged.length }))), (0, react.createElement)("div", { style: commitEditorRowStyle }, (0, react.createElement)("textarea", {
42843
+ })) : null, status !== null && status.snapshot.enabled !== false ? (0, react.createElement)("div", {
42844
+ className: gitPanelClass.contentGrid,
42845
+ style: contentGridStyle,
42846
+ "data-active-column": activeColumn
42847
+ }, (0, react.createElement)("div", {
42848
+ className: gitPanelClass.column,
42849
+ style: columnStyle,
42850
+ "data-git-column": "files"
42851
+ }, (0, react.createElement)("section", { style: commitSectionStyle }, (0, react.createElement)("div", { style: sectionHeaderStyle }, (0, react.createElement)("strong", void 0, t("git.commitChanges")), (0, react.createElement)("span", { style: mutedStyle }, staged.length === 0 ? t("git.stagingEmpty") : t("git.stagedCount", { count: staged.length }))), (0, react.createElement)("div", { style: commitEditorRowStyle }, (0, react.createElement)("textarea", {
41764
42852
  value: subject,
41765
42853
  disabled: busy || workspaceId === void 0,
42854
+ maxLength: require_native_workspace_store.MAX_GIT_COMMIT_MESSAGE_CHARS,
41766
42855
  className: gitPanelClass.field,
41767
42856
  onChange: (event) => setSubject(event.currentTarget.value),
41768
- onKeyDown: (event) => {
41769
- if (event.key === "Enter") event.preventDefault();
41770
- },
41771
42857
  placeholder: t("git.commitPlaceholder"),
41772
- rows: 1,
42858
+ rows: Math.min(8, subject.split("\n").length),
41773
42859
  style: commitSubjectStyle
41774
- }), (0, react.createElement)("button", {
42860
+ }), generationEnabled && (0, react.createElement)("button", {
41775
42861
  type: "button",
41776
- disabled: busy || workspaceId === void 0,
41777
- onClick: () => notify("info", t("git.draftUnavailable")),
42862
+ disabled: busy || workspaceId === void 0 || staged.length === 0,
42863
+ onClick: () => {
42864
+ generateMessage();
42865
+ },
41778
42866
  className: `${gitPanelClass.button} ${gitPanelClass.field}`,
41779
42867
  style: draftButtonStyle,
41780
- title: t("git.draftMessage"),
41781
- "aria-label": t("git.draftMessage")
41782
- }, "✦")), (0, react.createElement)("div", { style: commitActionsStyle }, (0, react.createElement)("button", {
42868
+ title: t(generating ? "git.generatingMessage" : "git.draftMessage"),
42869
+ "aria-label": t("git.draftMessage"),
42870
+ "aria-busy": generating
42871
+ }, generating ? "…" : "✦")), (0, react.createElement)("div", { style: commitActionsStyle }, (0, react.createElement)("button", {
41783
42872
  type: "button",
41784
42873
  disabled: busy || workspaceId === void 0,
41785
42874
  onClick: () => void run("git/status", {}, (value) => setStatus(value)),
@@ -41811,7 +42900,11 @@ ${scope} [data-dockkit-strip-tabs] {
41811
42900
  onBatchAction: (action, paths) => void run(`git/${action}`, { targets: paths }),
41812
42901
  onBulkAction: () => void run("git/stage", { targets: unstaged.map((item) => item.path) }),
41813
42902
  t
41814
- }) : null), singleColumn && activeColumn !== "history" ? null : (0, react.createElement)("div", { style: columnStyle }, (0, react.createElement)(HistorySection, {
42903
+ }) : null), (0, react.createElement)("div", {
42904
+ className: gitPanelClass.column,
42905
+ style: columnStyle,
42906
+ "data-git-column": "history"
42907
+ }, (0, react.createElement)(HistorySection, {
41815
42908
  history,
41816
42909
  totalCount: historyTotalCount,
41817
42910
  hasMore: history.length < historyTotalCount,
@@ -41832,6 +42925,17 @@ ${scope} [data-dockkit-strip-tabs] {
41832
42925
  onUndo: () => runGitOperation("undo"),
41833
42926
  t
41834
42927
  }))) : null);
42928
+ return (0, react.createElement)(react.Fragment, void 0, panel, diffView !== null ? (0, react.createElement)(DiffViewer, {
42929
+ diff: diffView,
42930
+ onClose: () => setDiffView(null),
42931
+ t
42932
+ }) : null, fileDiff !== null ? (0, react.createElement)(FileDiffViewer, {
42933
+ path: fileDiff.path,
42934
+ staged: fileDiff.staged,
42935
+ diff: fileDiff.diff,
42936
+ onClose: () => setFileDiff(null),
42937
+ t
42938
+ }) : null);
41835
42939
  }
41836
42940
  function ChangeSection({ title, staged, items, busy, onOpenDiff, onAction, onBatchAction, onBulkAction, t }) {
41837
42941
  const [hoveredPath, setHoveredPath] = (0, react.useState)(null);
@@ -43042,7 +44146,8 @@ ${scope} [data-dockkit-strip-tabs] {
43042
44146
  display: "flex",
43043
44147
  flexDirection: "column",
43044
44148
  gap: 12,
43045
- minHeight: "100%",
44149
+ height: "100%",
44150
+ minHeight: 0,
43046
44151
  padding: "12px 14px 20px",
43047
44152
  overflow: "auto",
43048
44153
  color: require_theme.dshThemeColor.labelPrimary
@@ -43067,7 +44172,6 @@ ${scope} [data-dockkit-strip-tabs] {
43067
44172
  gap: 4
43068
44173
  };
43069
44174
  const columnSwitchStyle = {
43070
- display: "flex",
43071
44175
  alignItems: "center",
43072
44176
  justifyContent: "center",
43073
44177
  width: "100%",
@@ -43079,12 +44183,10 @@ ${scope} [data-dockkit-strip-tabs] {
43079
44183
  };
43080
44184
  const contentGridStyle = {
43081
44185
  display: "grid",
43082
- gridTemplateColumns: "repeat(auto-fit, minmax(300px, 1fr))",
43083
44186
  alignItems: "start",
43084
44187
  gap: 12
43085
44188
  };
43086
44189
  const columnStyle = {
43087
- display: "flex",
43088
44190
  flexDirection: "column",
43089
44191
  gap: 12,
43090
44192
  minWidth: 0
@@ -43412,7 +44514,7 @@ ${scope} [data-dockkit-strip-tabs] {
43412
44514
  width: "100%",
43413
44515
  minHeight: 34,
43414
44516
  boxSizing: "border-box",
43415
- resize: "none",
44517
+ resize: "vertical",
43416
44518
  padding: "7px 10px",
43417
44519
  borderRadius: 8,
43418
44520
  font: "inherit",
@@ -43511,9 +44613,11 @@ ${scope} [data-dockkit-strip-tabs] {
43511
44613
  context.resources.add(registerGitManagementUi(uiContext, {
43512
44614
  rpc: context.services.rpc,
43513
44615
  remote: context.services.remote,
43514
- locale: context.services.locale
44616
+ locale: context.services.locale,
44617
+ settings: context.services.settings
43515
44618
  }));
43516
- }
44619
+ },
44620
+ settingsPanel: GitManagementSettingsPanel
43517
44621
  };
43518
44622
  //#endregion
43519
44623
  //#region src/client/engine-loader.ts
@@ -43550,6 +44654,8 @@ ${scope} [data-dockkit-strip-tabs] {
43550
44654
  //#endregion
43551
44655
  //#region src/client/file-management-dom.ts
43552
44656
  const DOCUMENT_PREVIEW_SELECTOR = "[data-document-preview]";
44657
+ const FILE_TREE_ENTRY_SELECTOR = "[data-files-entry][data-files-path]";
44658
+ const PREVIEW_PATH_SELECTOR = "[data-textpreview-path]";
43553
44659
  const loadEditorEngine = createEngineLoader(() => require.async("./client.editor-engine.js"));
43554
44660
  /** 可直接交给文本编辑器的扩展名;未知扩展名仍按只读预览处理,避免误打开二进制文件。 */
43555
44661
  const TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -43698,11 +44804,19 @@ ${scope} [data-dockkit-strip-tabs] {
43698
44804
  };
43699
44805
  const onContextMenu = (event) => {
43700
44806
  if (!options.menuEnhancement) return;
43701
- const target = event.target?.closest("[data-files-entry][data-files-path]");
43702
- if (target == null) return;
44807
+ const origin = eventElement(event.target);
44808
+ const treeEntry = origin?.closest(FILE_TREE_ENTRY_SELECTOR);
44809
+ if (treeEntry != null) {
44810
+ event.preventDefault();
44811
+ event.stopPropagation();
44812
+ openMenu(treeEntry, event.clientX, event.clientY);
44813
+ return;
44814
+ }
44815
+ const previewPath = previewPathLabel(origin);
44816
+ if (previewPath == null) return;
43703
44817
  event.preventDefault();
43704
44818
  event.stopPropagation();
43705
- openMenu(target, event.clientX, event.clientY);
44819
+ openPreviewCopyPathMenu(previewPath, event.clientX, event.clientY);
43706
44820
  };
43707
44821
  const onDocumentPointerDown = (event) => {
43708
44822
  if (menu === void 0) return;
@@ -43752,7 +44866,6 @@ ${scope} [data-dockkit-strip-tabs] {
43752
44866
  dispose
43753
44867
  };
43754
44868
  function openMenu(item, x, y) {
43755
- closeMenu();
43756
44869
  const rawPath = item.dataset.filesPath ?? "";
43757
44870
  const kind = item.dataset.filesEntry === "directory" ? "directory" : "file";
43758
44871
  if (rawPath === "") return;
@@ -43768,7 +44881,7 @@ ${scope} [data-dockkit-strip-tabs] {
43768
44881
  path: base
43769
44882
  };
43770
44883
  const panel = item.closest("[data-files-state=\"tree\"]");
43771
- const items = [
44884
+ showMenu([
43772
44885
  {
43773
44886
  label: t(kind === "directory" ? "fileMenu.expandFolder" : "fileMenu.openFile"),
43774
44887
  action: () => clickEntry(item)
@@ -43832,9 +44945,35 @@ ${scope} [data-dockkit-strip-tabs] {
43832
44945
  label: t("fileMenu.delete"),
43833
44946
  action: () => void deleteEntry(target, panel)
43834
44947
  }
43835
- ];
44948
+ ], x, y, "tree");
44949
+ }
44950
+ function openPreviewCopyPathMenu(pathLabel, x, y) {
44951
+ const parsed = parseFileTarget((pathLabel.closest("[data-textpreview-url], [data-document-preview]")?.getAttribute("data-textpreview-url") ?? "").split(/[?#]/u)[0] ?? "");
44952
+ const displayPath = pathLabel.getAttribute("title")?.trim() || void 0;
44953
+ const workspaceRoot = filesRootForEntry(pathLabel);
44954
+ const paths = resolveFileCopyPaths({
44955
+ ...parsed === void 0 ? {} : { resourcePath: parsed.path },
44956
+ ...displayPath === void 0 ? {} : { displayPath },
44957
+ ...workspaceRoot === void 0 ? {} : { workspaceRoot }
44958
+ });
44959
+ if (paths === void 0) {
44960
+ showNotice(t("fileMenu.unresolvedPath"));
44961
+ return;
44962
+ }
44963
+ showMenu([{
44964
+ label: t("fileMenu.copyRelativePath"),
44965
+ action: () => void copyResolvedFilePath(paths.relative, false, t)
44966
+ }, {
44967
+ label: t("fileMenu.copyAbsolutePath"),
44968
+ action: () => void copyResolvedFilePath(paths.absolute, true, t)
44969
+ }], x, y, "preview");
44970
+ }
44971
+ function showMenu(items, x, y, kind) {
44972
+ closeMenu();
44973
+ if (items.length === 0) return;
43836
44974
  menu = document.createElement("div");
43837
44975
  menu.setAttribute("role", "menu");
44976
+ menu.setAttribute("data-file-management-menu", kind);
43838
44977
  menu.style.cssText = "position:fixed;z-index:2147483647;min-width:190px;padding:5px;background:var(--dsw-alias-bg-layer-3,#242526);border:1px solid var(--dsw-alias-border-l2,#666);border-radius:8px;box-shadow:0 8px 30px #0008;color:var(--dsw-alias-label-primary,#eee);font:13px var(--dsw-font,system-ui,sans-serif)";
43839
44978
  for (const item of items) {
43840
44979
  const button = document.createElement("button");
@@ -43857,7 +44996,7 @@ ${scope} [data-dockkit-strip-tabs] {
43857
44996
  }
43858
44997
  document.body.append(menu);
43859
44998
  const width = menu.offsetWidth || 190;
43860
- const height = menu.offsetHeight || 360;
44999
+ const height = menu.offsetHeight || (kind === "preview" ? 88 : 360);
43861
45000
  menu.style.left = `${Math.max(8, Math.min(x, window.innerWidth - width - 8))}px`;
43862
45001
  menu.style.top = `${Math.max(8, Math.min(y, window.innerHeight - height - 8))}px`;
43863
45002
  }
@@ -43916,15 +45055,16 @@ ${scope} [data-dockkit-strip-tabs] {
43916
45055
  }
43917
45056
  }
43918
45057
  async function copyPath(item, absolute) {
43919
- const path = item.dataset.filesPath ?? "";
43920
- const root = filesRootForEntry(item);
43921
- const value = absolute ? absolutePath(path, root) : relativePath(path, root);
43922
- try {
43923
- await copyTextToClipboard(value);
43924
- showNotice(t(absolute ? "fileMenu.copiedAbsolutePath" : "fileMenu.copiedRelativePath"));
43925
- } catch {
43926
- showNotice(t("fileMenu.copyPathFailed"));
45058
+ const workspaceRoot = filesRootForEntry(item);
45059
+ const paths = resolveFileCopyPaths({
45060
+ resourcePath: item.dataset.filesPath ?? "",
45061
+ ...workspaceRoot === void 0 ? {} : { workspaceRoot }
45062
+ });
45063
+ if (paths === void 0) {
45064
+ showNotice(t("fileMenu.unresolvedPath"));
45065
+ return;
43927
45066
  }
45067
+ await copyResolvedFilePath(absolute ? paths.absolute : paths.relative, absolute, t);
43928
45068
  }
43929
45069
  async function runMutation(action, payload, panel) {
43930
45070
  try {
@@ -44159,6 +45299,19 @@ ${scope} [data-dockkit-strip-tabs] {
44159
45299
  if (pattern.test(label)) return button;
44160
45300
  }
44161
45301
  }
45302
+ function eventElement(target) {
45303
+ if (target != null && typeof target.closest === "function") return target;
45304
+ const parent = target?.parentElement;
45305
+ return parent != null && typeof parent.closest === "function" ? parent : null;
45306
+ }
45307
+ function previewPathLabel(origin) {
45308
+ if (origin == null || origin.closest("[data-textpreview-body]") != null) return null;
45309
+ const labeled = origin.closest(PREVIEW_PATH_SELECTOR);
45310
+ if (labeled != null) return labeled;
45311
+ const pathLabel = origin.closest("[data-path-label]");
45312
+ if (pathLabel == null) return null;
45313
+ return pathLabel.closest("[data-textpreview-url], [data-document-preview]") == null ? null : pathLabel;
45314
+ }
44162
45315
  function parseFileTarget(url) {
44163
45316
  const match = /^dsh-resource:\/\/file\/session\/([^/]+)\/(.*)$/u.exec(url);
44164
45317
  if (match === null) return void 0;
@@ -44213,6 +45366,29 @@ ${scope} [data-dockkit-strip-tabs] {
44213
45366
  if (normalizedPath.startsWith(`${normalizedRoot}/`)) return normalizedPath.slice(normalizedRoot.length + 1);
44214
45367
  return path;
44215
45368
  }
45369
+ /** 从资源地址、查看器标题和工作区根目录合成可复制的相对路径与绝对路径。 */
45370
+ function resolveFileCopyPaths(input) {
45371
+ const resourcePath = input.resourcePath?.trim() ?? "";
45372
+ const displayPath = input.displayPath?.trim() ?? "";
45373
+ const resourceAbsolutePath = input.resourceAbsolutePath?.trim() ?? "";
45374
+ const workspaceRoot = input.workspaceRoot?.trim() || void 0;
45375
+ if ((resourcePath || displayPath || resourceAbsolutePath) === "") return void 0;
45376
+ const absolute = resourceAbsolutePath || (isAbsoluteLike(displayPath) ? displayPath : "") || absolutePath(resourcePath || displayPath, workspaceRoot);
45377
+ const relative = relativePath(resourcePath || (isAbsoluteLike(displayPath) ? displayPath : resourcePath) || absolute, workspaceRoot);
45378
+ if (absolute === "" && relative === "") return void 0;
45379
+ return {
45380
+ relative,
45381
+ absolute
45382
+ };
45383
+ }
45384
+ async function copyResolvedFilePath(value, absolute, t) {
45385
+ try {
45386
+ await copyTextToClipboard(value);
45387
+ showNotice(t(absolute ? "fileMenu.copiedAbsolutePath" : "fileMenu.copiedRelativePath"));
45388
+ } catch {
45389
+ showNotice(t("fileMenu.copyPathFailed"));
45390
+ }
45391
+ }
44216
45392
  async function copyTextToClipboard(text) {
44217
45393
  if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) try {
44218
45394
  await navigator.clipboard.writeText(text);
@@ -45170,6 +46346,98 @@ ${scope} [data-dockkit-strip-tabs] {
45170
46346
  };
45171
46347
  const diffContextLineStyle = { display: "block" };
45172
46348
  //#endregion
46349
+ //#region src/client/file-viewer-copy-path-menu.ts
46350
+ const FILE_VIEWER_COPY_PATH_MENU_ID = "codingns4dsh-copy-file-path";
46351
+ /** 标签菜单 extras 在单测或 Slot 未注入 locale 时退回内置中文词典。 */
46352
+ const FALLBACK_LOCALE = {
46353
+ bind: () => require_transport.resolveCodingNsTranslator(void 0),
46354
+ getSnapshot: () => ({ revision: 0 }),
46355
+ subscribe: () => () => void 0,
46356
+ register: () => () => void 0
46357
+ };
46358
+ const tabMenuItemStyle = {
46359
+ display: "block",
46360
+ width: "100%",
46361
+ boxSizing: "border-box",
46362
+ padding: "4px 7px",
46363
+ color: "var(--dsw-alias-label-primary)",
46364
+ fontSize: "calc(var(--dsh-content-font-size-secondary, 13px) - 1px)",
46365
+ textAlign: "left",
46366
+ background: "transparent",
46367
+ border: "none",
46368
+ borderRadius: "var(--dsw-radius-md)",
46369
+ cursor: "pointer"
46370
+ };
46371
+ /** 在文件查看器标签的原生右键菜单末尾加入复制相对/绝对路径。 */
46372
+ function registerFileViewerCopyPathMenu(slots, locale) {
46373
+ if (slots === void 0 || typeof slots.inject !== "function" || typeof slots.register !== "function") return () => void 0;
46374
+ try {
46375
+ return slots.inject("sidebar.right.tab.menu.item", () => slots.register({
46376
+ name: "sidebar.right.tab.menu.item",
46377
+ id: FILE_VIEWER_COPY_PATH_MENU_ID,
46378
+ order: 80
46379
+ }, function FileTabCopyPathMenu(props) {
46380
+ const resolvedLocale = props.locale ?? locale;
46381
+ return FileTabCopyPathMenuItems({
46382
+ ...props,
46383
+ ...resolvedLocale === void 0 ? {} : { locale: resolvedLocale }
46384
+ });
46385
+ }));
46386
+ } catch {
46387
+ return () => void 0;
46388
+ }
46389
+ }
46390
+ function FileTabCopyPathMenuItems(props) {
46391
+ const t = require_transport.useCodingNsTranslator(props.locale ?? FALLBACK_LOCALE);
46392
+ const paths = fileCopyPathsForTab(props);
46393
+ if (paths === void 0) return null;
46394
+ return (0, react.createElement)(react.Fragment, null, copyPathMenuItem(t, "fileMenu.copyRelativePath", "relative", () => {
46395
+ props.dismiss();
46396
+ copyResolvedFilePath(paths.relative, false, t);
46397
+ }), copyPathMenuItem(t, "fileMenu.copyAbsolutePath", "absolute", () => {
46398
+ props.dismiss();
46399
+ copyResolvedFilePath(paths.absolute, true, t);
46400
+ }));
46401
+ }
46402
+ function fileCopyPathsForTab(props) {
46403
+ const address = (props.tab.contentId ?? "").split(/[?#]/u)[0] ?? "";
46404
+ const parsed = parseFileTarget(address);
46405
+ if (parsed === void 0) return void 0;
46406
+ const workspaceRoot = workspaceRootForSession(props.sessionId);
46407
+ const resourceAbsolutePath = props.useResource?.(address)?.value?.absolutePath;
46408
+ return resolveFileCopyPaths({
46409
+ resourcePath: parsed.path,
46410
+ ...workspaceRoot === void 0 ? {} : { workspaceRoot },
46411
+ ...resourceAbsolutePath === void 0 ? {} : { resourceAbsolutePath }
46412
+ });
46413
+ }
46414
+ function copyPathMenuItem(t, key, kind, onSelect) {
46415
+ return (0, react.createElement)("button", {
46416
+ type: "button",
46417
+ role: "menuitem",
46418
+ "data-file-copy-path": kind,
46419
+ style: tabMenuItemStyle,
46420
+ onMouseEnter: (event) => {
46421
+ event.currentTarget.style.background = "var(--dsw-alias-interactive-bg-hover, rgba(127,127,127,.12))";
46422
+ },
46423
+ onMouseLeave: (event) => {
46424
+ event.currentTarget.style.background = "transparent";
46425
+ },
46426
+ onClick: onSelect
46427
+ }, t(key));
46428
+ }
46429
+ function workspaceRootForSession(sessionId) {
46430
+ if (typeof document === "undefined") return void 0;
46431
+ if (sessionId !== void 0 && sessionId !== "") {
46432
+ const scoped = document.querySelector(`[data-sidebar-right-session="${cssAttribute(sessionId)}"] [data-files-root]`)?.getAttribute("data-files-root")?.trim();
46433
+ if (scoped) return scoped;
46434
+ }
46435
+ return document.querySelector("[data-files-root]")?.getAttribute("data-files-root")?.trim() || void 0;
46436
+ }
46437
+ function cssAttribute(value) {
46438
+ return value.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"");
46439
+ }
46440
+ //#endregion
45173
46441
  //#region src/client/html-workspace-files.ts
45174
46442
  const REQUEST = "codingns.html-files.request.v1";
45175
46443
  const RESPONSE = "codingns.html-files.response.v1";
@@ -45351,6 +46619,8 @@ ${scope} [data-dockkit-strip-tabs] {
45351
46619
  const dom = startFileManagementDom(context.services.rpc, readOptions());
45352
46620
  context.resources.add(startHtmlWorkspaceFiles(context.services.rpc, context.services.locale));
45353
46621
  let disposeSessionView;
46622
+ let disposeCopyPathMenu;
46623
+ const slots = context.services.uiContext?.slots ?? context.services.slots;
45354
46624
  const syncSessionView = () => {
45355
46625
  const value = {
45356
46626
  ...require_native_workspace_store.DEFAULT_FILE_MANAGEMENT_SETTINGS,
@@ -45362,14 +46632,28 @@ ${scope} [data-dockkit-strip-tabs] {
45362
46632
  disposeSessionView = void 0;
45363
46633
  }
45364
46634
  };
46635
+ const syncCopyPathMenu = () => {
46636
+ const value = {
46637
+ ...require_native_workspace_store.DEFAULT_FILE_MANAGEMENT_SETTINGS,
46638
+ ...context.services.settings.getSnapshot().value?.fileManagement
46639
+ };
46640
+ if (value.menuEnhancement && disposeCopyPathMenu === void 0) disposeCopyPathMenu = registerFileViewerCopyPathMenu(slots, context.services.locale);
46641
+ else if (!value.menuEnhancement && disposeCopyPathMenu !== void 0) {
46642
+ disposeCopyPathMenu();
46643
+ disposeCopyPathMenu = void 0;
46644
+ }
46645
+ };
45365
46646
  syncSessionView();
46647
+ syncCopyPathMenu();
45366
46648
  const unsubscribe = context.services.settings.subscribe(() => {
45367
46649
  dom.setOptions(readOptions());
45368
46650
  syncSessionView();
46651
+ syncCopyPathMenu();
45369
46652
  });
45370
46653
  context.resources.add(unsubscribe);
45371
46654
  context.resources.add(dom.dispose);
45372
46655
  context.resources.add(() => disposeSessionView?.());
46656
+ context.resources.add(() => disposeCopyPathMenu?.());
45373
46657
  },
45374
46658
  settingsPanel: FileManagementPanel
45375
46659
  };
@@ -45449,7 +46733,7 @@ ${scope} [data-dockkit-strip-tabs] {
45449
46733
  saved.push(app);
45450
46734
  continue;
45451
46735
  }
45452
- const { id, title, hostId, workspaceId, entryPath, documentRoot, kind, fileAccess, spaFallback, mounts } = app;
46736
+ const { id, title, hostId, workspaceId, entryPath, documentRoot, kind, fileAccess, spaFallback, networkAllow, mounts } = app;
45453
46737
  saved.push(await this.call("upsert", {
45454
46738
  expectedRevision: app.revision,
45455
46739
  app: {
@@ -45462,6 +46746,7 @@ ${scope} [data-dockkit-strip-tabs] {
45462
46746
  kind,
45463
46747
  ...fileAccess ? { fileAccess } : {},
45464
46748
  spaFallback,
46749
+ ...networkAllow?.length ? { networkAllow } : {},
45465
46750
  mounts,
45466
46751
  order
45467
46752
  }
@@ -45469,12 +46754,15 @@ ${scope} [data-dockkit-strip-tabs] {
45469
46754
  }
45470
46755
  return saved;
45471
46756
  }
45472
- async open(id) {
46757
+ async open(id, browserStorage = true) {
45473
46758
  const closing = this.close();
45474
46759
  const generation = this.generation;
45475
46760
  await closing;
45476
46761
  if (generation !== this.generation) return void 0;
45477
- const result = await this.call("launch", { id });
46762
+ const result = await this.call("launch", {
46763
+ id,
46764
+ ...browserStorage ? { browserStorage: true } : {}
46765
+ });
45478
46766
  if (generation !== this.generation) {
45479
46767
  if (result.launchId) await this.call("close", { id: result.launchId });
45480
46768
  return;
@@ -45490,6 +46778,176 @@ ${scope} [data-dockkit-strip-tabs] {
45490
46778
  }
45491
46779
  };
45492
46780
  //#endregion
46781
+ //#region src/shared/quick-app-network-allow.ts
46782
+ const RANGES = [
46783
+ ["0.0.0.0", 8],
46784
+ ["10.0.0.0", 8],
46785
+ ["100.64.0.0", 10],
46786
+ ["127.0.0.0", 8],
46787
+ ["169.254.0.0", 16],
46788
+ ["172.16.0.0", 12],
46789
+ ["192.0.0.0", 24],
46790
+ ["192.0.2.0", 24],
46791
+ ["192.88.99.0", 24],
46792
+ ["192.168.0.0", 16],
46793
+ ["198.18.0.0", 15],
46794
+ ["198.51.100.0", 24],
46795
+ ["203.0.113.0", 24],
46796
+ ["224.0.0.0", 4],
46797
+ ["240.0.0.0", 4],
46798
+ ["255.255.255.255", 32],
46799
+ ["::", 128],
46800
+ ["::1", 128],
46801
+ ["fc00::", 7],
46802
+ ["fe80::", 10],
46803
+ ["ff00::", 8],
46804
+ ["2001:db8::", 32]
46805
+ ].map(([text, prefix]) => {
46806
+ const ip = parseIp(text);
46807
+ if (!ip) throw new Error(`Invalid egress range ${text}.`);
46808
+ return {
46809
+ family: ip.family,
46810
+ bytes: ip.bytes,
46811
+ prefix
46812
+ };
46813
+ });
46814
+ function parseQuickAppNetworkAllow(value) {
46815
+ if (value === void 0) return [];
46816
+ if (!Array.isArray(value) || value.length > 16) throw invalid();
46817
+ const allow = [];
46818
+ const seen = /* @__PURE__ */ new Set();
46819
+ for (const item of value) {
46820
+ if (typeof item !== "string") throw invalid();
46821
+ const text = item.trim().toLowerCase();
46822
+ if (!text) continue;
46823
+ const canonical = canonicalEntry(text);
46824
+ if (!canonical) throw invalid();
46825
+ if (seen.has(canonical)) continue;
46826
+ seen.add(canonical);
46827
+ allow.push(canonical);
46828
+ }
46829
+ return allow;
46830
+ }
46831
+ function canonicalEntry(text) {
46832
+ if (text.length > 253) return null;
46833
+ const slash = text.lastIndexOf("/");
46834
+ if (slash > 0) {
46835
+ const prefix = Number(text.slice(slash + 1));
46836
+ const ip = canonicalIp(text.slice(0, slash));
46837
+ const max = ip?.family === 4 ? 32 : 128;
46838
+ if (!ip || !/^\d{1,3}$/u.test(text.slice(slash + 1)) || prefix < 1 || prefix > max || !blockedRange(ip, prefix)) return null;
46839
+ const network = mask(ip.bytes, prefix);
46840
+ const formatted = formatIp({
46841
+ family: ip.family,
46842
+ bytes: network
46843
+ });
46844
+ return prefix === max ? formatted : `${formatted}/${prefix}`;
46845
+ }
46846
+ const ip = canonicalIp(text);
46847
+ if (ip) return blockedRange(ip, ip.family === 4 ? 32 : 128) ? formatIp(ip) : null;
46848
+ const host = text.endsWith(".") ? text.slice(0, -1) : text;
46849
+ if (!host || host.endsWith(".") || /^\d+$/u.test(host) || parseIp(host)) return null;
46850
+ return /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/u.test(host) ? host : null;
46851
+ }
46852
+ function blockedRange(ip, prefix) {
46853
+ return RANGES.some((range) => range.family === ip.family && range.prefix <= prefix && samePrefix(range.bytes, ip.bytes, range.prefix));
46854
+ }
46855
+ function canonicalIp(text) {
46856
+ const parsed = parseIp(text);
46857
+ if (!parsed) return null;
46858
+ if (parsed.family === 6 && parsed.bytes.subarray(0, 10).every((byte) => byte === 0) && parsed.bytes[10] === 255 && parsed.bytes[11] === 255) return {
46859
+ family: 4,
46860
+ bytes: parsed.bytes.subarray(12)
46861
+ };
46862
+ return parsed;
46863
+ }
46864
+ function parseIp(text) {
46865
+ if (text.includes("%") || text.includes("/")) return null;
46866
+ if (/^(?:0|[1-9]\d{0,2})(?:\.(?:0|[1-9]\d{0,2})){3}$/u.test(text)) {
46867
+ const bytes = text.split(".").map((part) => Number(part));
46868
+ if (bytes.every((part) => part <= 255)) return {
46869
+ family: 4,
46870
+ bytes: Uint8Array.from(bytes)
46871
+ };
46872
+ return null;
46873
+ }
46874
+ const halves = text.split("::");
46875
+ if (halves.length > 2) return null;
46876
+ const side = (value) => {
46877
+ if (value === "") return [];
46878
+ const parts = value.split(":");
46879
+ const groups = [];
46880
+ for (let index = 0; index < parts.length; index += 1) {
46881
+ const part = parts[index] ?? "";
46882
+ if (index === parts.length - 1 && part.includes(".")) {
46883
+ const tail = parseIp(part);
46884
+ if (tail?.family !== 4) return null;
46885
+ groups.push(tail.bytes[0] << 8 | tail.bytes[1], tail.bytes[2] << 8 | tail.bytes[3]);
46886
+ } else if (!/^[0-9a-f]{1,4}$/u.test(part)) return null;
46887
+ else groups.push(Number.parseInt(part, 16));
46888
+ }
46889
+ return groups;
46890
+ };
46891
+ const left = side(halves[0] ?? "");
46892
+ const right = halves.length === 2 ? side(halves[1] ?? "") : [];
46893
+ if (!left || !right || halves.length === 1 && left.length !== 8 || halves.length === 2 && left.length + right.length >= 8) return null;
46894
+ const groups = halves.length === 1 ? left : [
46895
+ ...left,
46896
+ ...Array(8 - left.length - right.length).fill(0),
46897
+ ...right
46898
+ ];
46899
+ const bytes = /* @__PURE__ */ new Uint8Array(16);
46900
+ groups.forEach((group, index) => {
46901
+ bytes[index * 2] = group >> 8;
46902
+ bytes[index * 2 + 1] = group & 255;
46903
+ });
46904
+ return {
46905
+ family: 6,
46906
+ bytes
46907
+ };
46908
+ }
46909
+ function formatIp(ip) {
46910
+ if (ip.family === 4) return [...ip.bytes].join(".");
46911
+ const groups = Array.from({ length: 8 }, (_, index) => ip.bytes[index * 2] << 8 | ip.bytes[index * 2 + 1]);
46912
+ let start = -1;
46913
+ let length = 0;
46914
+ for (let index = 0; index < groups.length;) {
46915
+ if (groups[index] !== 0) {
46916
+ index += 1;
46917
+ continue;
46918
+ }
46919
+ let end = index;
46920
+ while (end < groups.length && groups[end] === 0) end += 1;
46921
+ if (end - index > length) {
46922
+ start = index;
46923
+ length = end - index;
46924
+ }
46925
+ index = end;
46926
+ }
46927
+ const hex = groups.map((group) => group.toString(16));
46928
+ if (length < 2) return hex.join(":");
46929
+ return `${hex.slice(0, start).join(":")}::${hex.slice(start + length).join(":")}`;
46930
+ }
46931
+ function mask(bytes, prefix) {
46932
+ const out = bytes.slice();
46933
+ const whole = Math.floor(prefix / 8);
46934
+ const bits = prefix % 8;
46935
+ if (bits) out[whole] = (out[whole] ?? 0) & 255 << 8 - bits;
46936
+ for (let index = whole + (bits ? 1 : 0); index < out.length; index += 1) out[index] = 0;
46937
+ return out;
46938
+ }
46939
+ function samePrefix(left, right, prefix) {
46940
+ const whole = Math.floor(prefix / 8);
46941
+ for (let index = 0; index < whole; index += 1) if (left[index] !== right[index]) return false;
46942
+ const bits = prefix % 8;
46943
+ if (!bits) return true;
46944
+ const select = 255 << 8 - bits & 255;
46945
+ return ((left[whole] ?? 0) & select) === ((right[whole] ?? 0) & select);
46946
+ }
46947
+ function invalid() {
46948
+ return /* @__PURE__ */ new Error("Invalid local network allow list.");
46949
+ }
46950
+ //#endregion
45493
46951
  //#region src/client/quick-apps/presentation.ts
45494
46952
  function newQuickAppDraft(order) {
45495
46953
  return {
@@ -45502,6 +46960,7 @@ ${scope} [data-dockkit-strip-tabs] {
45502
46960
  kind: "html",
45503
46961
  fileAccess: "workspace",
45504
46962
  spaFallback: false,
46963
+ networkAllow: [],
45505
46964
  mounts: [],
45506
46965
  order,
45507
46966
  expectedRevision: 0
@@ -45521,7 +46980,19 @@ ${scope} [data-dockkit-strip-tabs] {
45521
46980
  };
45522
46981
  }
45523
46982
  function draftChanged(draft, app) {
45524
- return Object.keys(newQuickAppDraft(0)).some((key) => key !== "expectedRevision" && JSON.stringify(draft[key]) !== JSON.stringify(app[key]));
46983
+ return Object.keys(newQuickAppDraft(0)).some((key) => {
46984
+ if (key === "expectedRevision") return false;
46985
+ if (key === "networkAllow") return !sameNetworkAllow(draft.networkAllow, app.networkAllow);
46986
+ return JSON.stringify(draft[key]) !== JSON.stringify(app[key]);
46987
+ });
46988
+ }
46989
+ function sameNetworkAllow(draft, saved) {
46990
+ const lines = (draft ?? []).map((item) => item.trim()).filter(Boolean);
46991
+ try {
46992
+ return JSON.stringify(parseQuickAppNetworkAllow(lines)) === JSON.stringify(parseQuickAppNetworkAllow(saved ?? []));
46993
+ } catch {
46994
+ return false;
46995
+ }
45525
46996
  }
45526
46997
  /** Match the parent workspace shortcut rail's stable, name-based icon treatment. */
45527
46998
  function shortcutIcon(app) {
@@ -45602,7 +47073,8 @@ ${scope} [data-dockkit-strip-tabs] {
45602
47073
  .codingns-quick-app-rail button:disabled{opacity:.5;cursor:not-allowed}
45603
47074
  .codingns-quick-app-rail button:focus-visible{outline:2px solid ${require_theme.dshThemeColor.accent};outline-offset:-2px}
45604
47075
  .codingns-quick-app-rail .qa-grid{position:relative;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:4px;padding-top:4px;max-height:min(35dvh,240px);overflow:auto;overscroll-behavior:contain}
45605
- .codingns-quick-app-rail .qa-shortcut{position:relative;min-width:0}
47076
+ /* Clip the edit-mode tilt. Its rotating border box would otherwise become scrollable overflow and toggle the grid scrollbar, which shifts the rows below. */
47077
+ .codingns-quick-app-rail .qa-shortcut{position:relative;min-width:0;overflow:clip}
45606
47078
  .codingns-quick-app-rail .qa-tile{display:flex;flex-direction:column;align-items:center;gap:3px;width:100%;min-width:0;min-height:54px;padding:2px;border:0;border-radius:8px;background:transparent;color:inherit;font:inherit;cursor:pointer}
45607
47079
  .codingns-quick-app-rail .qa-tile[data-editing=true]{outline:1px dashed ${require_theme.dshThemeColor.border};outline-offset:-1px;cursor:grab;touch-action:none;user-select:none;-webkit-touch-callout:none}
45608
47080
  .codingns-quick-app-rail .qa-tile[data-dragging=true]{cursor:grabbing;background:${require_theme.dshThemeColor.hoverBackground};outline:2px solid ${require_theme.dshThemeColor.accent};opacity:.7}
@@ -45646,6 +47118,9 @@ ${scope} [data-dockkit-strip-tabs] {
45646
47118
  /* DSH Input paints its wrapper; the inner input must remain undecorated. */
45647
47119
  .codingns-quick-app-dialog :is(.qa-input,.qa-select,.qa-file-input){box-sizing:border-box;width:100%;min-width:0;max-width:100%;height:40px;border:0;border-radius:8px;background:${require_theme.dshThemeColor.surfaceSubtle};color:${require_theme.dshThemeColor.labelPrimary};font:inherit;font-size:${require_theme.uiFontSize(13)};font-weight:400}
45648
47120
  .codingns-quick-app-dialog :is(.qa-input,.qa-select){padding:0 11px}
47121
+ .codingns-quick-app-dialog .qa-allow{box-sizing:border-box;width:100%;min-width:0;min-height:88px;padding:8px 11px;border:0;border-radius:8px;background:${require_theme.dshThemeColor.surfaceSubtle};color:${require_theme.dshThemeColor.labelPrimary};font:inherit;font-size:${require_theme.uiFontSize(13)};font-weight:400;resize:vertical}
47122
+ .codingns-quick-app-dialog .qa-allow:focus{outline:2px solid ${require_theme.dshThemeColor.accent};outline-offset:-2px}
47123
+ .codingns-quick-app-dialog .qa-allow:disabled{opacity:.5}
45649
47124
  .codingns-quick-app-dialog .qa-input input{width:100%;min-width:0;padding:0;border:0;border-radius:0;outline:none;background:transparent;color:inherit;font:inherit;box-shadow:none}
45650
47125
  .codingns-quick-app-dialog :is(.qa-input,.qa-file-input):focus-within{outline:2px solid ${require_theme.dshThemeColor.accent};outline-offset:-2px}
45651
47126
  .codingns-quick-app-dialog :is(.qa-input,.qa-file-input):has(input:disabled){opacity:.5}
@@ -45692,8 +47167,14 @@ ${scope} [data-dockkit-strip-tabs] {
45692
47167
  .codingns-quick-app-dialog .qa-view-surface{display:flex;flex:1;flex-direction:column;min-width:0;min-height:0;color:${require_theme.dshThemeColor.labelPrimary};background:${require_theme.dshThemeColor.pageBackground}}
45693
47168
  .codingns-quick-app-dialog :is(.qa-view-titlebar,.qa-view-toolbar){display:flex;flex:none;align-items:center;gap:4px;box-sizing:border-box;height:38px;padding:0 6px 0 16px;border-bottom:.5px solid ${require_theme.dshThemeColor.menuBorder}}
45694
47169
  .codingns-quick-app-dialog .qa-view-titlebar{gap:8px}
47170
+ .codingns-quick-app-dialog .qa-view-title{display:flex;flex:1;align-items:center;gap:8px;min-width:0}
45695
47171
  .codingns-quick-app-dialog .qa-view-titlebar h2{flex:1;min-width:0;margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:${require_theme.uiFontSize(13)};font-weight:500}
45696
- .codingns-quick-app-dialog .qa-view-titlebar>svg{flex:none}
47172
+ .codingns-quick-app-dialog .qa-view-title>svg{flex:none}
47173
+ /* Fullscreen title sits in the window chrome. Center the name clear of the macOS traffic lights and the trailing controls. */
47174
+ .codingns-quick-app-dialog.qa-viewer.qa-maximized .qa-view-titlebar{position:relative;justify-content:flex-end}
47175
+ .codingns-quick-app-dialog.qa-viewer.qa-maximized .qa-view-title{position:absolute;left:88px;right:88px;top:0;height:100%;flex:none;justify-content:center;pointer-events:none}
47176
+ .codingns-quick-app-dialog.qa-viewer.qa-maximized .qa-view-title>svg{display:none}
47177
+ .codingns-quick-app-dialog.qa-viewer.qa-maximized .qa-view-title h2{flex:0 1 auto;text-align:center}
45697
47178
  .codingns-quick-app-dialog .qa-view-tool{display:inline-flex;flex:none;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:0;border-radius:var(--dsw-radius-sm,6px);background:transparent;color:${require_theme.dshThemeColor.labelSecondary};cursor:pointer}
45698
47179
  .codingns-quick-app-dialog .qa-view-tool svg{width:15px;height:15px}
45699
47180
  .codingns-quick-app-dialog .qa-view-tool:hover:not(:disabled){color:${require_theme.dshThemeColor.labelPrimary};background:${require_theme.dshThemeColor.hoverBackground}}
@@ -56890,6 +58371,169 @@ ${scope} [data-dockkit-strip-tabs] {
56890
58371
  }));
56891
58372
  }
56892
58373
  //#endregion
58374
+ //#region src/shared/quick-app-browser-storage.ts
58375
+ const QUICK_APP_STORAGE_PROTOCOL = "codingns.quick-app-storage.v1";
58376
+ const QUICK_APP_STORAGE_LIMITS = Object.freeze({
58377
+ bytes: 2097152,
58378
+ keys: 1024,
58379
+ pending: 64,
58380
+ timeoutMs: 1e4
58381
+ });
58382
+ function validateQuickAppStorageEntries(value) {
58383
+ if (!Array.isArray(value)) throw new DOMException("Invalid application storage data.", "DataError");
58384
+ if (value.length > QUICK_APP_STORAGE_LIMITS.keys) throw new DOMException("Application storage quota exceeded.", "QuotaExceededError");
58385
+ if (Array.from(value).some((entry) => !Array.isArray(entry) || entry.length !== 2 || Array.from(entry).some((part) => typeof part !== "string")) || new Set(value.map((entry) => entry[0])).size !== value.length) throw new DOMException("Invalid application storage data.", "DataError");
58386
+ if (JSON.stringify(value).length * 2 > QUICK_APP_STORAGE_LIMITS.bytes) throw new DOMException("Application storage quota exceeded.", "QuotaExceededError");
58387
+ }
58388
+ function isQuickAppStorageRequest(value) {
58389
+ if (!value || typeof value !== "object") return false;
58390
+ const request = value;
58391
+ if (Object.keys(request).some((key) => ![
58392
+ "id",
58393
+ "area",
58394
+ "operation",
58395
+ "key",
58396
+ "value"
58397
+ ].includes(key)) || !Number.isSafeInteger(request.id) || Number(request.id) < 1 || request.area !== "local" && request.area !== "session" || typeof request.operation !== "string") return false;
58398
+ if (request.operation === "setItem") return typeof request.key === "string" && typeof request.value === "string" && (request.key.length + request.value.length) * 2 <= QUICK_APP_STORAGE_LIMITS.bytes;
58399
+ if (request.operation === "getItem" || request.operation === "removeItem") return typeof request.key === "string" && request.key.length * 2 <= QUICK_APP_STORAGE_LIMITS.bytes && request.value === void 0;
58400
+ return [
58401
+ "clear",
58402
+ "keys",
58403
+ "flush"
58404
+ ].includes(request.operation) && request.key === void 0 && request.value === void 0;
58405
+ }
58406
+ //#endregion
58407
+ //#region src/client/quick-apps/browser-storage.ts
58408
+ function storageFailure(error) {
58409
+ return {
58410
+ name: error instanceof Error ? error.name : "UnknownError",
58411
+ message: error instanceof Error ? error.message : "Application storage failed."
58412
+ };
58413
+ }
58414
+ /** Only this object chooses the namespace; requests cannot provide storage keys or identities. */
58415
+ function createQuickAppBrowserStore(scope, resolve) {
58416
+ const key = scope;
58417
+ if (!key.startsWith("codingns.quickApps.storage.v1:") || key.length > 8192) throw new DOMException("Invalid application storage scope.", "SecurityError");
58418
+ const read = (area) => {
58419
+ const text = resolve(area).getItem(key);
58420
+ if (text !== null && text.length * 2 > QUICK_APP_STORAGE_LIMITS.bytes) throw new DOMException("Application storage quota exceeded.", "QuotaExceededError");
58421
+ let entries;
58422
+ try {
58423
+ entries = text === null ? [] : JSON.parse(text);
58424
+ } catch {
58425
+ throw new DOMException("Application storage is not valid JSON.", "DataError");
58426
+ }
58427
+ validateQuickAppStorageEntries(entries);
58428
+ return entries;
58429
+ };
58430
+ return {
58431
+ read,
58432
+ execute(request) {
58433
+ if (!isQuickAppStorageRequest(request)) throw new DOMException("Invalid application storage request.", "SecurityError");
58434
+ const store = resolve(request.area);
58435
+ const entries = new Map(request.operation === "clear" ? [] : read(request.area));
58436
+ let value = null;
58437
+ switch (request.operation) {
58438
+ case "getItem":
58439
+ value = entries.get(request.key) ?? null;
58440
+ break;
58441
+ case "setItem":
58442
+ entries.set(request.key, request.value);
58443
+ break;
58444
+ case "removeItem":
58445
+ entries.delete(request.key);
58446
+ break;
58447
+ case "keys": value = [...entries.keys()];
58448
+ }
58449
+ const snapshot = [...entries];
58450
+ validateQuickAppStorageEntries(snapshot);
58451
+ if (request.operation === "clear") store.removeItem(key);
58452
+ else if (request.operation === "setItem" || request.operation === "removeItem") store.setItem(key, JSON.stringify(snapshot));
58453
+ return {
58454
+ id: request.id,
58455
+ value,
58456
+ entries: snapshot
58457
+ };
58458
+ }
58459
+ };
58460
+ }
58461
+ /** Exact window + launch token authenticate the initial transfer; Origin:null alone never does. */
58462
+ function attachQuickAppStorageBroker(options) {
58463
+ const { owner, token, expiresAt, onError } = options;
58464
+ const store = createQuickAppBrowserStore(options.scope, (area) => area === "local" ? owner.localStorage : owner.sessionStorage);
58465
+ let active = true;
58466
+ let port;
58467
+ let documentId;
58468
+ const shutdown = () => {
58469
+ port?.postMessage({
58470
+ type: "closed",
58471
+ error: {
58472
+ name: "SecurityError",
58473
+ message: "The application storage channel was closed."
58474
+ }
58475
+ });
58476
+ port?.close();
58477
+ port = void 0;
58478
+ };
58479
+ const connect = (event) => {
58480
+ const frameWindow = options.frame()?.contentWindow;
58481
+ const data = event.data;
58482
+ if (!active || Date.now() >= expiresAt || !frameWindow || event.source !== frameWindow || event.origin !== "null" || !data || data.type !== "codingns.quick-app-storage.v1" || data.token !== token || typeof data.documentId !== "string" || !/^[a-f0-9]{32}$/u.test(data.documentId) || documentId === data.documentId) return;
58483
+ shutdown();
58484
+ documentId = data.documentId;
58485
+ const channel = new MessageChannel();
58486
+ port = channel.port1;
58487
+ const current = port;
58488
+ const snapshot = {};
58489
+ const errors = {};
58490
+ for (const area of ["local", "session"]) try {
58491
+ snapshot[area] = store.read(area);
58492
+ } catch (error) {
58493
+ errors[area] = storageFailure(error);
58494
+ onError(new Error(errors[area].message));
58495
+ }
58496
+ current.onmessage = (message) => {
58497
+ if (current !== port) return;
58498
+ if (!active || Date.now() >= expiresAt) {
58499
+ shutdown();
58500
+ return;
58501
+ }
58502
+ try {
58503
+ current.postMessage(store.execute(message.data));
58504
+ } catch (error) {
58505
+ const failure = storageFailure(error);
58506
+ const id = message.data?.id;
58507
+ current.postMessage({
58508
+ id,
58509
+ error: failure
58510
+ });
58511
+ onError(new Error(failure.message));
58512
+ if (!isQuickAppStorageRequest(message.data)) shutdown();
58513
+ }
58514
+ };
58515
+ frameWindow.postMessage({
58516
+ type: QUICK_APP_STORAGE_PROTOCOL,
58517
+ token,
58518
+ documentId,
58519
+ snapshot,
58520
+ errors
58521
+ }, "*", [channel.port2]);
58522
+ };
58523
+ owner.addEventListener("message", connect);
58524
+ const expiry = setTimeout(() => {
58525
+ active = false;
58526
+ shutdown();
58527
+ owner.removeEventListener("message", connect);
58528
+ }, Math.max(0, Math.min(expiresAt - Date.now(), 2147483647)));
58529
+ return () => {
58530
+ active = false;
58531
+ clearTimeout(expiry);
58532
+ owner.removeEventListener("message", connect);
58533
+ shutdown();
58534
+ };
58535
+ }
58536
+ //#endregion
56893
58537
  //#region src/client/quick-apps/viewer.ts
56894
58538
  const defaultMode = (path) => /\.(?:md|markdown)$/iu.test(path) && require_primitives_adapter.hasNativeMarkdown() ? "markdown" : "source";
56895
58539
  /** Native renderers and editor with Quick Apps ownership, save preconditions and lifetime. */
@@ -56912,6 +58556,9 @@ ${scope} [data-dockkit-strip-tabs] {
56912
58556
  const [confirmation, setConfirmation] = (0, react.useState)(null);
56913
58557
  const generation = (0, react.useRef)(0);
56914
58558
  const pending = (0, react.useRef)(false);
58559
+ const frame = (0, react.useRef)(null);
58560
+ const storageTranslator = (0, react.useRef)(t);
58561
+ storageTranslator.current = t;
56915
58562
  const dirty = doc !== void 0 && draft !== doc.content;
56916
58563
  const path = doc?.path ?? app.entryPath;
56917
58564
  const accept = (next) => {
@@ -56934,6 +58581,20 @@ ${scope} [data-dockkit-strip-tabs] {
56934
58581
  (0, react.useEffect)(() => {
56935
58582
  if (error) setFrameLoading(false);
56936
58583
  }, [error]);
58584
+ (0, react.useEffect)(() => {
58585
+ if (view.kind !== "html" || view.isolation !== "sandbox-proxy" || !view.storageToken || !view.storageScope || typeof window === "undefined") return;
58586
+ return attachQuickAppStorageBroker({
58587
+ owner: window,
58588
+ frame: () => frame.current,
58589
+ token: view.storageToken,
58590
+ scope: view.storageScope,
58591
+ expiresAt: view.expiresAt,
58592
+ onError: (cause) => setMessage({
58593
+ error: true,
58594
+ text: storageTranslator.current("quickApps.storageFailed", { message: cause.message })
58595
+ })
58596
+ });
58597
+ }, [view]);
56937
58598
  (0, react.useEffect)(() => {
56938
58599
  if (!dirty || typeof window === "undefined") return;
56939
58600
  const prevent = (event) => {
@@ -57079,14 +58740,14 @@ ${scope} [data-dockkit-strip-tabs] {
57079
58740
  }, (0, react.createElement)("section", {
57080
58741
  className: `qa-view-surface qa-view-${view.kind}`,
57081
58742
  "aria-busy": disabled
57082
- }, (0, react.createElement)("header", { className: "qa-view-titlebar" }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
58743
+ }, (0, react.createElement)("header", { className: "qa-view-titlebar" }, (0, react.createElement)("div", { className: "qa-view-title" }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
57083
58744
  kind: (0, _deepseek_ai_dsh_client_ui_primitives.classifyFileType)(path),
57084
58745
  size: 16
57085
58746
  }), (0, react.createElement)("h2", null, app.title), dirty ? (0, react.createElement)("span", {
57086
58747
  className: "qa-document-dirty",
57087
58748
  title: t("quickApps.unsaved"),
57088
58749
  "aria-label": t("quickApps.unsaved")
57089
- }, "●") : null, tool(t(maximized ? "quickApps.restore" : "quickApps.maximize"), require_primitives_adapter.resolveViewerIcon(maximized ? "restore" : "fullscreen"), () => setMaximized(!maximized), { pressed: maximized }), tool(t("quickApps.back"), require_primitives_adapter.resolveAssistantControlIcon("close"), () => guard(onClose), { disabled })), (0, react.createElement)("div", {
58750
+ }, "●") : null), tool(t(maximized ? "quickApps.restore" : "quickApps.maximize"), require_primitives_adapter.resolveViewerIcon(maximized ? "restore" : "fullscreen"), () => setMaximized(!maximized), { pressed: maximized }), tool(t("quickApps.back"), require_primitives_adapter.resolveAssistantControlIcon("close"), () => guard(onClose), { disabled })), (0, react.createElement)("div", {
57090
58751
  className: "qa-view-toolbar",
57091
58752
  role: "group",
57092
58753
  "aria-label": t("quickApps.viewerTools")
@@ -57145,7 +58806,7 @@ ${scope} [data-dockkit-strip-tabs] {
57145
58806
  }, t("quickApps.markdownUnavailable")) : null, view.kind === "html" && view.isolation === "sandbox-proxy" ? (0, react.createElement)("p", {
57146
58807
  className: "qa-view-status",
57147
58808
  role: "status"
57148
- }, t("quickApps.sandboxPreview")) : null, doc ? mode === "edit" ? (0, react.createElement)(QuickAppEditor, {
58809
+ }, t(view.storageToken ? "quickApps.storagePreview" : "quickApps.sandboxPreview")) : null, doc ? mode === "edit" ? (0, react.createElement)(QuickAppEditor, {
57149
58810
  key: path,
57150
58811
  content: draft,
57151
58812
  path,
@@ -57167,6 +58828,7 @@ ${scope} [data-dockkit-strip-tabs] {
57167
58828
  tabIndex: 0,
57168
58829
  "aria-label": app.title
57169
58830
  }, (0, react.createElement)("pre", null, draft)) : view.kind === "html" ? (0, react.createElement)("iframe", {
58831
+ ref: frame,
57170
58832
  key: view.launchId,
57171
58833
  className: "qa-view-frame",
57172
58834
  title: app.title,
@@ -57385,6 +59047,22 @@ ${scope} [data-dockkit-strip-tabs] {
57385
59047
  };
57386
59048
  }
57387
59049
  //#endregion
59050
+ //#region src/client/quick-apps/rail-preference.ts
59051
+ const QUICK_APPS_RAIL_COLLAPSED_KEY = "codingns4dsh.quickApps.railCollapsed";
59052
+ /** Edit mode is a session action; only the collapsed rail is restored after reload. */
59053
+ function readQuickAppsRailCollapsed() {
59054
+ try {
59055
+ return globalThis.localStorage?.getItem(QUICK_APPS_RAIL_COLLAPSED_KEY) === "1";
59056
+ } catch {
59057
+ return false;
59058
+ }
59059
+ }
59060
+ function writeQuickAppsRailCollapsed(collapsed) {
59061
+ try {
59062
+ globalThis.localStorage?.setItem(QUICK_APPS_RAIL_COLLAPSED_KEY, collapsed ? "1" : "0");
59063
+ } catch {}
59064
+ }
59065
+ //#endregion
57388
59066
  //#region src/client/settings-anchor.ts
57389
59067
  /**
57390
59068
  * 设置区锚点解析。
@@ -57516,9 +59194,17 @@ ${scope} [data-dockkit-strip-tabs] {
57516
59194
  const formId = (0, react.useId)();
57517
59195
  const client = (0, react.useMemo)(() => new QuickAppsClient(services.rpc), [services.rpc]);
57518
59196
  const [screen, setScreen] = (0, react.useState)(null);
57519
- const [mode, setMode] = (0, react.useState)("normal");
59197
+ const [mode, setMode] = (0, react.useState)(() => readQuickAppsRailCollapsed() ? "collapsed" : "normal");
57520
59198
  const editing = mode === "edit";
57521
59199
  const collapsed = mode === "collapsed";
59200
+ const expandRail = () => {
59201
+ writeQuickAppsRailCollapsed(false);
59202
+ setMode("normal");
59203
+ };
59204
+ const collapseRail = () => {
59205
+ writeQuickAppsRailCollapsed(true);
59206
+ setMode("collapsed");
59207
+ };
57522
59208
  const [pickingFile, setPickingFile] = (0, react.useState)(false);
57523
59209
  const [apps, setApps] = (0, react.useState)([]);
57524
59210
  const [notice, setNotice] = (0, react.useState)(null);
@@ -57660,16 +59346,25 @@ ${scope} [data-dockkit-strip-tabs] {
57660
59346
  const invalid = {};
57661
59347
  if (!workspaces.some((workspace) => workspace.workspaceId === draft.workspaceId && (workspace.hostId ?? "local") === draft.hostId)) invalid.workspaceId = t("quickApps.chooseWorkspace");
57662
59348
  if (!draft.entryPath.trim()) invalid.entryPath = t("quickApps.entryRequired");
59349
+ const lines = (draft.networkAllow ?? []).map((line) => line.trim()).filter(Boolean);
59350
+ let networkAllow = [];
59351
+ try {
59352
+ networkAllow = parseQuickAppNetworkAllow(lines);
59353
+ } catch {
59354
+ invalid.networkAllow = t("quickApps.networkAllowInvalid");
59355
+ }
57663
59356
  if (Object.keys(invalid).length) {
57664
59357
  setErrors(invalid);
57665
59358
  return;
57666
59359
  }
57667
59360
  perform(async (current) => {
59361
+ const { networkAllow: _draftAllow, ...fields } = draft;
57668
59362
  const saved = await client.call("upsert", {
57669
59363
  app: {
57670
- ...draft,
59364
+ ...fields,
57671
59365
  fileAccess: draft.kind === "html" ? "workspace" : void 0,
57672
- title: draft.title.trim() || entryTitle(draft.entryPath)
59366
+ title: draft.title.trim() || entryTitle(draft.entryPath),
59367
+ ...networkAllow.length ? { networkAllow } : {}
57673
59368
  },
57674
59369
  expectedRevision: draft.expectedRevision
57675
59370
  });
@@ -57770,7 +59465,23 @@ ${scope} [data-dockkit-strip-tabs] {
57770
59465
  value: draft.kind,
57771
59466
  disabled: busy,
57772
59467
  onChange: (event) => updateDraft({ kind: event.target.value })
57773
- }, (0, react.createElement)("option", { value: "html" }, t("quickApps.html")), (0, react.createElement)("option", { value: "text" }, t("quickApps.text")))), draft.kind === "html" && selected ? (0, react.createElement)("p", { className: "qa-help" }, t("quickApps.workspaceAccessHelp", { workspace: selected.title })) : null, draft.id ? (0, react.createElement)("fieldset", {
59468
+ }, (0, react.createElement)("option", { value: "html" }, t("quickApps.html")), (0, react.createElement)("option", { value: "text" }, t("quickApps.text")))), (0, react.createElement)(QuickAppField, {
59469
+ id: `${formId}-network-allow`,
59470
+ label: t("quickApps.networkAllow"),
59471
+ error: errors.networkAllow,
59472
+ help: t("quickApps.networkAllowHelp")
59473
+ }, (0, react.createElement)("textarea", {
59474
+ id: `${formId}-network-allow`,
59475
+ className: "qa-allow",
59476
+ rows: 4,
59477
+ value: (draft.networkAllow ?? []).join("\n"),
59478
+ disabled: busy,
59479
+ spellCheck: false,
59480
+ placeholder: t("quickApps.networkAllowPlaceholder"),
59481
+ "aria-invalid": Boolean(errors.networkAllow),
59482
+ "aria-describedby": `${formId}-network-allow-help`,
59483
+ onChange: (event) => updateDraft({ networkAllow: event.target.value.split("\n") })
59484
+ })), draft.kind === "html" && selected ? (0, react.createElement)("p", { className: "qa-help" }, t("quickApps.workspaceAccessHelp", { workspace: selected.title })) : null, draft.id ? (0, react.createElement)("fieldset", {
57774
59485
  className: "qa-management",
57775
59486
  disabled: busy || changed,
57776
59487
  "aria-label": t("quickApps.accessAndRemoval")
@@ -57839,10 +59550,10 @@ ${scope} [data-dockkit-strip-tabs] {
57839
59550
  }, apps.length) : null, (0, react.createElement)("div", { className: "qa-controls" }, !collapsed ? editing ? control(t("quickApps.add"), "add", add) : control(t("quickApps.manage"), "edit", () => {
57840
59551
  setMode("edit");
57841
59552
  setNotice(null);
57842
- }) : null, collapsed ? control(t("quickApps.expandBar"), "expand", () => setMode("normal")) : editing ? control(t("quickApps.done"), "done", () => {
59553
+ }) : null, collapsed ? control(t("quickApps.expandBar"), "expand", expandRail) : editing ? control(t("quickApps.done"), "done", () => {
57843
59554
  setMode("normal");
57844
59555
  setNotice(null);
57845
- }) : control(t("quickApps.collapseBar"), "collapse", () => setMode("collapsed")))), !collapsed ? (0, react.createElement)("div", { className: "qa-rail-content" }, !screen && notice ? (0, react.createElement)("p", {
59556
+ }) : control(t("quickApps.collapseBar"), "collapse", collapseRail))), !collapsed ? (0, react.createElement)("div", { className: "qa-rail-content" }, !screen && notice ? (0, react.createElement)("p", {
57846
59557
  className: "qa-rail-notice",
57847
59558
  role: notice.tone === "error" ? "alert" : "status",
57848
59559
  title: notice.text
@@ -57886,7 +59597,7 @@ ${scope} [data-dockkit-strip-tabs] {
57886
59597
  return;
57887
59598
  }
57888
59599
  perform(async (current) => {
57889
- const view = await client.open(app.id);
59600
+ const view = await client.open(app.id, app.kind === "html");
57890
59601
  if (current() && view) navigate({
57891
59602
  kind: "view",
57892
59603
  app,
@@ -57920,7 +59631,7 @@ ${scope} [data-dockkit-strip-tabs] {
57920
59631
  onClose: close,
57921
59632
  onReload: () => {
57922
59633
  perform(async (current) => {
57923
- const view = await client.open(screen.app.id);
59634
+ const view = await client.open(screen.app.id, screen.app.kind === "html");
57924
59635
  if (current() && view) setScreen({
57925
59636
  ...screen,
57926
59637
  view
@@ -61476,6 +63187,34 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
61476
63187
  return require_primitives_adapter.parseVirtualWorkspaceId(workspaceId)?.targetHostId ?? void 0;
61477
63188
  }
61478
63189
  //#endregion
63190
+ //#region src/dsh-capabilities/client/peer-host-attachment-adapter.ts
63191
+ /** Native file paths describe the client machine; remote sessions must upload bytes. */
63192
+ function installPeerHostAttachmentIntake(context, folderError) {
63193
+ const slots = context?.get?.("slots");
63194
+ if (slots === void 0 || ![
63195
+ "inject",
63196
+ "register",
63197
+ "entries",
63198
+ "subscribe"
63199
+ ].every((key) => typeof slots[key] === "function")) return () => void 0;
63200
+ return installComposerPresentation(context, slots, (Native) => function PeerHostComposer(props) {
63201
+ if (typeof props.sessionId !== "string" || require_primitives_adapter.parseVirtualSessionId(props.sessionId) === null || typeof props.addFiles !== "function") return (0, react.createElement)(Native, props);
63202
+ return (0, react.createElement)(Native, {
63203
+ ...props,
63204
+ addFiles: (files, directories) => {
63205
+ if (files.some((file) => directories?.has(file))) return folderError;
63206
+ return props.addFiles(files.map((file) => new File([file], file.name, {
63207
+ type: file.type,
63208
+ lastModified: file.lastModified
63209
+ })));
63210
+ }
63211
+ });
63212
+ }, react.createElement, {
63213
+ useMemo: react.useMemo,
63214
+ useSyncExternalStore: react.useSyncExternalStore
63215
+ });
63216
+ }
63217
+ //#endregion
61479
63218
  //#region src/client/features/peer-host.ts
61480
63219
  /** 聚合刷新周期;远端资源只影响自身节点,刷新失败不改变本机界面。 */
61481
63220
  const PEER_HOST_AGGREGATE_REFRESH_MS = 3e4;
@@ -61644,6 +63383,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
61644
63383
  const fetchImpl = typeof originalGlobalFetch === "function" ? originalGlobalFetch.bind(globalThis) : void 0;
61645
63384
  const scopes = /* @__PURE__ */ new Map();
61646
63385
  const remoteHostScopes = /* @__PURE__ */ new Map();
63386
+ const restoreAttachmentIntake = installPeerHostAttachmentIntake(uiContext, t("peerHost.attachmentFolderUnsupported"));
61647
63387
  let activeModelCatalogScopeKey;
61648
63388
  const modelCatalogScopeKey = (scope) => {
61649
63389
  if (scope?.targetHostId === null || scope?.targetHostId === void 0) return void 0;
@@ -62246,6 +63986,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
62246
63986
  mergeEvents: (local, signal) => events.open(local, signal),
62247
63987
  dispose() {
62248
63988
  events.dispose();
63989
+ restoreAttachmentIntake();
62249
63990
  restoreAnchorClick();
62250
63991
  restoreGlobalFetch();
62251
63992
  if (aggregateRefreshTimer !== void 0) clearTimeout(aggregateRefreshTimer);
@@ -68086,386 +69827,6 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
68086
69827
  context.resources.add(dispose);
68087
69828
  }
68088
69829
  };
68089
- //#endregion
68090
- //#region src/client/session-translation-model-pool.ts
68091
- /** The persisted pool owns priority; modal choices and drag previews remain local until confirmed. */
68092
- function SessionTranslationModelPool({ value, catalog, disabled, pending, t, onChange }) {
68093
- const pool = value.translationModels ?? (value.translationModel === void 0 ? [] : [value.translationModel]);
68094
- const available = new Map((catalog?.models ?? []).filter((model) => !require_session_translation.isSessionTranslationAdapter(model.provider)).map((model) => [modelKey(model), model]));
68095
- const pooled = new Set(pool.map(modelKey));
68096
- const [selection, setSelection] = (0, react.useState)(null);
68097
- const [search, setSearch] = (0, react.useState)("");
68098
- const [saveFailed, setSaveFailed] = (0, react.useState)(false);
68099
- const [resetOpen, setResetOpen] = (0, react.useState)(false);
68100
- const [resetFailed, setResetFailed] = (0, react.useState)(false);
68101
- const [preview, setPreview] = (0, react.useState)(null);
68102
- const [announcement, setAnnouncement] = (0, react.useState)("");
68103
- const drag = (0, react.useRef)(null);
68104
- const list = (0, react.useRef)(null);
68105
- const poolIdentity = JSON.stringify(pool);
68106
- const pickerOpen = selection !== null;
68107
- const locked = disabled || pickerOpen || resetOpen;
68108
- const cancelDrag = () => {
68109
- drag.current = null;
68110
- setPreview(null);
68111
- };
68112
- (0, react.useEffect)(() => {
68113
- cancelDrag();
68114
- }, [disabled, poolIdentity]);
68115
- (0, react.useEffect)(() => {
68116
- if (disabled && !pending) {
68117
- setSelection(null);
68118
- setResetOpen(false);
68119
- }
68120
- }, [disabled, pending]);
68121
- const candidates = [...available.values()].filter((model) => !pooled.has(modelKey(model)));
68122
- const query = search.trim().toLowerCase();
68123
- const filtered = candidates.filter((model) => `${model.label} ${model.provider} ${model.model}`.toLowerCase().includes(query));
68124
- const additions = [...selection ?? []].flatMap((key) => {
68125
- const model = available.get(key);
68126
- return model === void 0 || pooled.has(key) ? [] : [{
68127
- provider: model.provider,
68128
- model: model.model
68129
- }];
68130
- });
68131
- const closePicker = () => {
68132
- if (!pending) setSelection(null);
68133
- };
68134
- const addSelected = async () => {
68135
- if (disabled || additions.length === 0) return;
68136
- setSaveFailed(false);
68137
- if (await onChange([...pool, ...additions])) setSelection(null);
68138
- else setSaveFailed(true);
68139
- };
68140
- const closeReset = () => {
68141
- if (!pending) setResetOpen(false);
68142
- };
68143
- const confirmReset = async () => {
68144
- if (disabled || !resetOpen) return;
68145
- setResetFailed(false);
68146
- if (await onChange([])) setResetOpen(false);
68147
- else setResetFailed(true);
68148
- };
68149
- const commitOrder = (order, key) => {
68150
- if (locked) return;
68151
- onChange(order).then((saved) => {
68152
- if (saved) setAnnouncement(t("translation.modelReordered", {
68153
- model: available.get(key)?.label ?? order.find((model) => modelKey(model) === key)?.model ?? "",
68154
- priority: order.findIndex((model) => modelKey(model) === key) + 1
68155
- }));
68156
- });
68157
- };
68158
- const startDrag = (event, key) => {
68159
- if (locked || pool.length < 2 || event.button !== 0 || list.current === null) return;
68160
- event.preventDefault();
68161
- event.currentTarget.focus();
68162
- list.current.setPointerCapture(event.pointerId);
68163
- drag.current = {
68164
- pointerId: event.pointerId,
68165
- key,
68166
- startY: event.clientY,
68167
- original: pool,
68168
- order: pool
68169
- };
68170
- };
68171
- const rowAtPointer = (event) => {
68172
- const target = event.currentTarget.ownerDocument.elementFromPoint(event.clientX, event.clientY)?.closest("[data-codingns-translation-model-key]");
68173
- return target !== null && target !== void 0 && list.current?.contains(target) ? target : void 0;
68174
- };
68175
- const moveDrag = (event) => {
68176
- const current = drag.current;
68177
- const root = list.current;
68178
- if (locked || current === null || current.pointerId !== event.pointerId || root === null) return;
68179
- if (preview === null && Math.abs(event.clientY - current.startY) < 4) return;
68180
- event.preventDefault();
68181
- const rect = root.getBoundingClientRect();
68182
- if (event.clientY < rect.top + 24) root.scrollTop -= 12;
68183
- else if (event.clientY > rect.bottom - 24) root.scrollTop += 12;
68184
- const target = rowAtPointer(event);
68185
- if (target === void 0) return;
68186
- const targetIndex = current.order.findIndex((model) => modelKey(model) === target.dataset.codingnsTranslationModelKey);
68187
- const sourceIndex = current.order.findIndex((model) => modelKey(model) === current.key);
68188
- if (targetIndex < 0 || sourceIndex < 0 || targetIndex === sourceIndex) return;
68189
- const next = {
68190
- ...current,
68191
- order: moveModel(current.order, sourceIndex, targetIndex)
68192
- };
68193
- drag.current = next;
68194
- setPreview(next);
68195
- };
68196
- const finishDrag = (event) => {
68197
- const current = drag.current;
68198
- if (current === null || current.pointerId !== event.pointerId) return;
68199
- cancelDrag();
68200
- if (!locked && rowAtPointer(event) !== void 0 && JSON.stringify(current.order) !== JSON.stringify(current.original)) commitOrder(current.order, current.key);
68201
- };
68202
- const keyboardMove = (event, key) => {
68203
- if (event.key === "Escape" && drag.current !== null) {
68204
- event.stopPropagation();
68205
- cancelDrag();
68206
- return;
68207
- }
68208
- if (locked || drag.current !== null || ![
68209
- "ArrowUp",
68210
- "ArrowDown",
68211
- "Home",
68212
- "End"
68213
- ].includes(event.key)) return;
68214
- event.preventDefault();
68215
- const index = pool.findIndex((model) => modelKey(model) === key);
68216
- const target = event.key === "Home" ? 0 : event.key === "End" ? pool.length - 1 : index + (event.key === "ArrowUp" ? -1 : 1);
68217
- if (index >= 0 && target >= 0 && target < pool.length && target !== index) commitOrder(moveModel(pool, index, target), key);
68218
- };
68219
- return (0, react.createElement)("div", {
68220
- className: "codingns-translation-pool",
68221
- "aria-busy": pending
68222
- }, (0, react.createElement)("style", null, modelPoolCss), (0, react.createElement)("div", { className: "codingns-translation-pool-toolbar" }, (0, react.createElement)("span", { style: require_theme.dshSettingsHelpStyle }, t(pool.length === 0 ? "translation.modelDefaultActive" : "translation.modelPoolCount", { count: pool.length })), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
68223
- type: "button",
68224
- variant: "outline",
68225
- size: "sm",
68226
- disabled: disabled || resetOpen,
68227
- icon: (0, react.createElement)(require_primitives_adapter.resolvePlusIcon(), { size: 14 }),
68228
- "aria-haspopup": "dialog",
68229
- "aria-expanded": pickerOpen,
68230
- onClick: () => {
68231
- if (!disabled && !resetOpen) {
68232
- setSearch("");
68233
- setSaveFailed(false);
68234
- setSelection(/* @__PURE__ */ new Set());
68235
- }
68236
- }
68237
- }, t("translation.modelAdd"))), pool.length === 0 ? (0, react.createElement)("div", { className: "codingns-translation-pool-empty" }, (0, react.createElement)(require_primitives_adapter.resolveDataIcon(), { size: 22 }), (0, react.createElement)("span", null, t("translation.modelPoolEmpty"))) : (0, react.createElement)("ol", {
68238
- ref: list,
68239
- className: "codingns-translation-pool-list",
68240
- "aria-label": t("translation.modelTitle"),
68241
- onPointerMove: moveDrag,
68242
- onPointerUp: finishDrag,
68243
- onPointerCancel: cancelDrag,
68244
- onLostPointerCapture: cancelDrag
68245
- }, ...(preview?.order ?? pool).map((model, index) => {
68246
- const key = modelKey(model);
68247
- const entry = available.get(key);
68248
- const label = entry?.label ?? `${model.provider} / ${model.model}`;
68249
- return (0, react.createElement)("li", {
68250
- key,
68251
- "data-codingns-translation-model-key": key,
68252
- className: `codingns-translation-pool-row${preview?.key === key ? " is-dragging" : ""}`
68253
- }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
68254
- type: "button",
68255
- size: "sm",
68256
- disabled: locked || pool.length < 2,
68257
- className: "codingns-translation-pool-handle",
68258
- "aria-label": t("translation.modelDrag", { model: label }),
68259
- title: t("translation.modelDragHelp"),
68260
- onPointerDown: (event) => startDrag(event, key),
68261
- onKeyDown: (event) => keyboardMove(event, key)
68262
- }, (0, react.createElement)(DragHandleIcon)), (0, react.createElement)("span", {
68263
- className: "codingns-translation-pool-priority",
68264
- title: t("translation.modelPriority", { priority: index + 1 })
68265
- }, index + 1), (0, react.createElement)(ModelIdentity, {
68266
- model,
68267
- label,
68268
- t
68269
- }), catalog !== null && entry === void 0 && (0, react.createElement)("span", { className: "codingns-translation-pool-unavailable" }, t("translation.modelUnavailable")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
68270
- type: "button",
68271
- size: "sm",
68272
- disabled: locked,
68273
- className: "codingns-translation-pool-remove",
68274
- "aria-label": t("translation.modelRemove", { model: label }),
68275
- title: t("translation.modelRemove", { model: label }),
68276
- onClick: () => {
68277
- if (!locked) onChange(pool.filter((item) => modelKey(item) !== key));
68278
- }
68279
- }, (0, react.createElement)(require_primitives_adapter.resolveAssistantControlIcon("close"), { size: 14 })));
68280
- })), (0, react.createElement)("div", { className: "codingns-translation-pool-toolbar" }, (0, react.createElement)("span", { style: {
68281
- ...require_theme.dshSettingsHelpStyle,
68282
- flex: 1
68283
- } }, t("translation.modelHelp")), pool.length > 0 && (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
68284
- type: "button",
68285
- size: "sm",
68286
- disabled: disabled || pickerOpen,
68287
- style: { color: require_theme.dshThemeColor.error },
68288
- "aria-haspopup": "dialog",
68289
- "aria-expanded": resetOpen,
68290
- onClick: () => {
68291
- if (!locked) {
68292
- setResetFailed(false);
68293
- setResetOpen(true);
68294
- }
68295
- }
68296
- }, t("translation.modelFollowDefault"))), (0, react.createElement)("span", {
68297
- role: "status",
68298
- "aria-live": "polite",
68299
- className: "codingns-translation-pool-status"
68300
- }, announcement), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
68301
- open: pickerOpen,
68302
- onClose: closePicker,
68303
- title: t("translation.modelPickerTitle"),
68304
- closeLabel: t("translation.modelCancel"),
68305
- description: t("translation.modelPickerHelp"),
68306
- className: "codingns-translation-model-picker",
68307
- contentClassName: "codingns-translation-model-picker-content",
68308
- footer: (0, react.createElement)(react.Fragment, null, (0, react.createElement)("span", {
68309
- className: "codingns-translation-picker-count",
68310
- "aria-live": "polite",
68311
- style: require_theme.dshSettingsHelpStyle
68312
- }, t("translation.modelPickerCount", { count: additions.length })), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
68313
- type: "button",
68314
- variant: "outline",
68315
- disabled: pending,
68316
- onClick: closePicker
68317
- }, t("translation.modelCancel")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
68318
- type: "button",
68319
- variant: "primary",
68320
- disabled: disabled || additions.length === 0,
68321
- onClick: () => {
68322
- addSelected();
68323
- }
68324
- }, t("translation.modelAddSelected", { count: additions.length })))
68325
- }, (0, react.createElement)("div", {
68326
- className: "codingns-translation-picker-body",
68327
- "aria-busy": pending
68328
- }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Input, {
68329
- type: "search",
68330
- value: search,
68331
- placeholder: t("translation.modelSearch"),
68332
- "aria-label": t("translation.modelSearch"),
68333
- "data-modal-autofocus": true,
68334
- disabled,
68335
- onChange: (event) => setSearch(event.currentTarget.value)
68336
- }), (0, react.createElement)("div", {
68337
- className: "codingns-translation-picker-list",
68338
- role: "group",
68339
- "aria-label": t("translation.modelPickerTitle")
68340
- }, ...filtered.map((model) => {
68341
- const key = modelKey(model);
68342
- return (0, react.createElement)("div", {
68343
- key,
68344
- className: `codingns-translation-picker-choice${selection?.has(key) ? " is-selected" : ""}`
68345
- }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Checkbox, {
68346
- checked: selection?.has(key) === true,
68347
- disabled,
68348
- label: model.label,
68349
- onChange: (checked) => {
68350
- if (disabled) return;
68351
- setSelection((previous) => {
68352
- const next = new Set(previous);
68353
- if (checked) next.add(key);
68354
- else next.delete(key);
68355
- return next;
68356
- });
68357
- }
68358
- }), (0, react.createElement)("span", {
68359
- className: "codingns-translation-picker-provider",
68360
- style: require_theme.dshSettingsHelpStyle
68361
- }, t(isOfficialProvider(model.provider) ? "translation.modelOfficial" : "translation.modelThirdParty")));
68362
- }), filtered.length > 0 ? null : (0, react.createElement)("div", {
68363
- className: "codingns-translation-pool-empty",
68364
- role: "status"
68365
- }, t(catalog === null ? "translation.modelLoading" : candidates.length > 0 ? "translation.modelNoMatches" : available.size > 0 ? "translation.modelAllAdded" : "translation.modelEmpty"))), saveFailed && (0, react.createElement)("span", {
68366
- role: "alert",
68367
- style: {
68368
- ...require_theme.dshSettingsHelpStyle,
68369
- color: require_theme.dshThemeColor.error
68370
- }
68371
- }, t("translation.saveRejected")))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
68372
- open: resetOpen,
68373
- onClose: closeReset,
68374
- title: t("translation.modelResetTitle"),
68375
- closeLabel: t("translation.modelCancel"),
68376
- description: t("translation.modelResetHelp", { count: pool.length }),
68377
- footer: (0, react.createElement)(react.Fragment, null, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
68378
- type: "button",
68379
- variant: "outline",
68380
- disabled: pending,
68381
- "data-modal-autofocus": true,
68382
- onClick: closeReset
68383
- }, t("translation.modelCancel")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
68384
- type: "button",
68385
- variant: "outline",
68386
- disabled,
68387
- style: { color: require_theme.dshThemeColor.error },
68388
- onClick: () => {
68389
- confirmReset();
68390
- }
68391
- }, t("translation.modelResetConfirm")))
68392
- }, resetFailed ? (0, react.createElement)("span", {
68393
- role: "alert",
68394
- style: {
68395
- ...require_theme.dshSettingsHelpStyle,
68396
- color: require_theme.dshThemeColor.error
68397
- }
68398
- }, t("translation.saveRejected")) : void 0));
68399
- }
68400
- function modelKey(model) {
68401
- return JSON.stringify([model.provider, model.model]);
68402
- }
68403
- function moveModel(pool, source, target) {
68404
- const next = [...pool];
68405
- const model = next.splice(source, 1)[0];
68406
- if (model !== void 0) next.splice(target, 0, model);
68407
- return next;
68408
- }
68409
- function isOfficialProvider(provider) {
68410
- return /^(?:deepseek(?:-official)?|official-deepseek)$/iu.test(provider.trim());
68411
- }
68412
- function ModelIdentity({ model, label, t }) {
68413
- const [provider, ...name] = label.split(" / ");
68414
- return (0, react.createElement)("div", {
68415
- className: "codingns-translation-pool-identity",
68416
- title: label
68417
- }, (0, react.createElement)("span", { className: "codingns-translation-pool-name" }, name.join(" / ") || model.model), (0, react.createElement)("span", { style: require_theme.dshSettingsHelpStyle }, `${provider ?? model.provider} · ${t(isOfficialProvider(model.provider) ? "translation.modelOfficial" : "translation.modelThirdParty")}`));
68418
- }
68419
- function DragHandleIcon() {
68420
- return (0, react.createElement)("svg", {
68421
- width: 14,
68422
- height: 18,
68423
- viewBox: "0 0 14 18",
68424
- fill: "currentColor",
68425
- "aria-hidden": true,
68426
- focusable: false
68427
- }, ...[5, 9].flatMap((cx) => [
68428
- 4,
68429
- 9,
68430
- 14
68431
- ].map((cy) => (0, react.createElement)("circle", {
68432
- key: `${cx}:${cy}`,
68433
- cx,
68434
- cy,
68435
- r: 1
68436
- }))));
68437
- }
68438
- const modelPoolCss = `
68439
- .codingns-translation-pool{display:grid;gap:10px;min-width:0}
68440
- .codingns-translation-pool-toolbar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}
68441
- .codingns-translation-pool-list{list-style:none;margin:0;padding:0;max-height:352px;overflow:auto;overscroll-behavior:contain;border:.5px solid ${require_theme.dshThemeColor.menuBorder};border-radius:var(--dsw-radius-md,12px);background:${require_theme.dshThemeColor.pageBackground}}
68442
- .codingns-translation-pool-row{display:flex;align-items:center;gap:10px;min-height:64px;padding:8px 12px 8px 6px;box-sizing:border-box}
68443
- .codingns-translation-pool-row:not(:last-child){border-bottom:.5px solid ${require_theme.dshThemeColor.menuBorder}}
68444
- .codingns-translation-pool-row:hover{background:${require_theme.dshThemeColor.hoverBackground}}
68445
- .codingns-translation-pool-row.is-dragging{background:${require_theme.dshThemeColor.activeBackground};box-shadow:inset 2px 0 ${require_theme.dshThemeColor.accent}}
68446
- .codingns-translation-pool .codingns-translation-pool-handle{width:28px;flex:0 0 28px;padding:0;touch-action:none;cursor:grab;color:${require_theme.dshThemeColor.labelTertiary}}
68447
- .codingns-translation-pool .codingns-translation-pool-handle:active{cursor:grabbing}
68448
- .codingns-translation-pool .codingns-translation-pool-handle:disabled{cursor:default}
68449
- .codingns-translation-pool-priority{display:flex;align-items:center;justify-content:center;flex:0 0 24px;height:24px;border-radius:var(--dsw-radius-sm,8px);background:${require_theme.dshThemeColor.surfaceSubtle};color:${require_theme.dshThemeColor.labelSecondary};font-size:${require_theme.uiFontSize(12)};font-variant-numeric:tabular-nums}
68450
- .codingns-translation-pool-identity{display:grid;gap:2px;min-width:0;flex:1}
68451
- .codingns-translation-pool-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:${require_theme.dshThemeColor.labelPrimary};font-size:${require_theme.uiFontSize(13)};font-weight:500;line-height:20px}
68452
- .codingns-translation-pool-identity>span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
68453
- .codingns-translation-pool .codingns-translation-pool-remove{flex:0 0 28px;width:28px;padding:0;color:${require_theme.dshThemeColor.labelTertiary}}
68454
- .codingns-translation-pool-unavailable{max-width:110px;flex-shrink:0;color:${require_theme.dshThemeColor.warning};font-size:${require_theme.uiFontSize(11)};line-height:16px}
68455
- .codingns-translation-pool-empty{display:flex;align-items:center;justify-content:center;gap:10px;padding:22px 14px;color:${require_theme.dshThemeColor.labelTertiary};background:${require_theme.dshThemeColor.surfaceSubtle};border-radius:var(--dsw-radius-md,12px);font-size:${require_theme.uiFontSize(12)};text-align:center;line-height:20px}
68456
- .codingns-translation-pool-status{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
68457
- .codingns-translation-model-picker{width:min(520px,100%);max-height:100%;color:${require_theme.dshThemeColor.labelPrimary}}
68458
- .codingns-translation-model-picker-content{min-height:0;overflow:auto}
68459
- .codingns-translation-picker-body{display:grid;gap:12px;padding-bottom:4px}
68460
- .codingns-translation-picker-list{display:grid;gap:6px;min-height:80px;max-height:320px;overflow:auto;overscroll-behavior:contain}
68461
- .codingns-translation-picker-choice{display:grid;gap:3px;padding:10px 12px;border:.5px solid ${require_theme.dshThemeColor.menuBorder};border-radius:var(--dsw-radius-sm,8px);background:${require_theme.dshThemeColor.pageBackground}}
68462
- .codingns-translation-picker-choice:hover,.codingns-translation-picker-choice.is-selected{background:${require_theme.dshThemeColor.hoverBackground}}
68463
- .codingns-translation-picker-choice>label{align-items:flex-start;gap:10px;overflow-wrap:anywhere}
68464
- .codingns-translation-picker-choice input{margin-top:2px}
68465
- .codingns-translation-picker-provider{padding-left:26px}
68466
- .codingns-translation-picker-count{margin-right:auto}
68467
- @media(max-width:480px){.codingns-translation-pool-row{gap:6px;padding-right:8px}.codingns-translation-pool-unavailable{max-width:70px}.codingns-translation-picker-choice{padding:10px}}
68468
- `;
68469
69830
  //#endregion
68470
69831
  //#region src/client/session-translation-rules.ts
68471
69832
  /** Only saved entries enter translation prompts; cancelled or failed edits stay local. */
@@ -70352,8 +71713,8 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
70352
71713
  }, t(languageLabelKeys[language]))))), (0, react.createElement)("div", { style: {
70353
71714
  ...require_theme.dshSettingsSectionHeaderStyle,
70354
71715
  marginTop: 12
70355
- } }, (0, react.createElement)("span", { style: require_theme.dshSettingsFieldLabelStyle }, t("translation.modelTitle"))), (0, react.createElement)(SessionTranslationModelPool, {
70356
- value,
71716
+ } }, (0, react.createElement)("span", { style: require_theme.dshSettingsFieldLabelStyle }, t("translation.modelTitle"))), (0, react.createElement)(ModelPriorityPool, {
71717
+ models: value.translationModels ?? (value.translationModel === void 0 ? [] : [value.translationModel]),
70357
71718
  catalog,
70358
71719
  disabled,
70359
71720
  pending: saving,
@@ -71114,7 +72475,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
71114
72475
  return value === void 0 ? void 0 : (({ cliSessions: _cliSessions, ...clientValue }) => clientValue)(value);
71115
72476
  }
71116
72477
  //#endregion
71117
- //#region node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.6-alpha.2/node_modules/@deepseek-ai/cosmokit/lib/index.js
72478
+ //#region node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.6/node_modules/@deepseek-ai/cosmokit/lib/index.js
71118
72479
  /** Return true when a value is `null` or `undefined`. */
71119
72480
  function isNullable(value) {
71120
72481
  return value === null || value === void 0;
@@ -71283,7 +72644,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
71283
72644
  Time.template = template;
71284
72645
  })(Time || (Time = {}));
71285
72646
  //#endregion
71286
- //#region node_modules/.pnpm/@deepseek-ai+cordis@4.0.5-alpha.2_@deepseek-ai+cordis-plugin-include@1.0.10-alpha.2_@de_d750ba50d5bee7081316b89f08b32afa/node_modules/@deepseek-ai/cordis/lib/index.js
72647
+ //#region node_modules/.pnpm/@deepseek-ai+cordis@4.0.5_@deepseek-ai+cordis-plugin-include@1.0.10_@deepseek-ai+cordis-plugin-loader@1.0.6/node_modules/@deepseek-ai/cordis/lib/index.js
71287
72648
  /** Ordered collection of disposable values with O(1) deletion by value. */
71288
72649
  var DisposableList = class {
71289
72650
  sn = 0;
@@ -76657,7 +78018,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
76657
78018
  function isInjectedStage0Runtime(scope = globalThis) {
76658
78019
  return scope[CODINGNS_STAGE0_GLOBAL] === true;
76659
78020
  }
76660
- route("session.external-performance", "session-performance-projection-021", "host", ">=0.2.1-alpha.3 <=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 <=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", [
78021
+ route("session.external-performance", "session-performance-projection-021", "host", ">=0.2.1-alpha.3 <=0.2.1-rc.2", "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.2", "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", [
76661
78022
  "dsh-capabilities/host/quick-app-proxy-adapter.ts",
76662
78023
  "dsh-capabilities/host/quick-app-proxy-provider.ts",
76663
78024
  "host/features/quick-apps.ts",
@@ -76673,21 +78034,22 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
76673
78034
  "dsh-capabilities/host/quick-app-transport.ts",
76674
78035
  "host/features/quick-apps.ts",
76675
78036
  "host/features/lan-access-dsh.ts"
76676
- ]), 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-alpha.3", "supported", [
78037
+ ]), 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.2", "supported", [
76677
78038
  "dsh-capabilities/host/session-prompt-adapter.ts",
76678
78039
  "host/features/session-prompt-translation.ts",
76679
78040
  "host/cli-adapters/feature.ts"
76680
- ]), route("session.external-model-selection", "session-external-model-selection-021", "host", ">=0.2.1-alpha.3 <=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 <=0.2.1-alpha.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-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 <=0.2.1-alpha.3", "supported", [
78041
+ ]), route("session.external-model-selection", "session-external-model-selection-021", "host", ">=0.2.1-alpha.3 <=0.2.1-rc.2", "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.2", "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.2", "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.2", "supported", [
76681
78042
  "dsh-capabilities/host/connection-peer-adapter.ts",
76682
78043
  "host/rpc.ts",
76683
78044
  "host/features/global-voice-rpc.ts",
76684
78045
  "host/modules/peer-host/peer-host-native-dispatch.ts"
76685
- ]), route("connection.uplink", "connection.uplink-021", "host", ">=0.2.1-alpha.3 <=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", [
78046
+ ]), route("connection.uplink", "connection.uplink-021", "host", ">=0.2.1-alpha.3 <=0.2.1-rc.2", "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", [
76686
78047
  "dsh-capabilities/host/assistant-llm-adapter.ts",
76687
78048
  "host/features/assistant-text-chat.ts",
76688
78049
  "dsh-capabilities/host/session-title-adapter.ts",
76689
- "host/features/session-title-optimization.ts"
76690
- ]), 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("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("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-alpha.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", [
78050
+ "host/features/session-title-optimization.ts",
78051
+ "host/features/git-management.ts"
78052
+ ]), 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("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.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 <=0.2.1-rc.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 <=0.2.1-rc.2", "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", [
76691
78053
  "bootstrap/index.ts",
76692
78054
  "host/index-injection.ts",
76693
78055
  "client/features/peer-host.ts"
@@ -76711,7 +78073,7 @@ button[${ACCOUNT_ATTRIBUTE}]:focus-visible{outline:2px solid ${require_theme.dsh
76711
78073
  };
76712
78074
  }
76713
78075
  //#endregion
76714
- //#region node_modules/.pnpm/@deepseek-ai+dsh-util-workspace-path@0.2.1-alpha.3_@deepseek-ai+cordis@4.0.5-alpha.2/node_modules/@deepseek-ai/dsh-util-workspace-path/lib/index.js
78076
+ //#region node_modules/.pnpm/@deepseek-ai+dsh-util-workspace-path@0.2.1-rc.2_@deepseek-ai+cordis@4.0.5/node_modules/@deepseek-ai/dsh-util-workspace-path/lib/index.js
76715
78077
  /**
76716
78078
  * The `dsh-resource://file/…` address grammar: how a file is named across the
76717
78079
  * Sidebar and the resource model, built and parsed without touching a
@@ -82707,5 +84069,5 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
82707
84069
  });
82708
84070
 
82709
84071
  })();
82710
- // codingns-client-revision: d8d89415f203949d6b5364ae54ea8e25cbe03bb2149cbf1f7b5d436d466d8101
84072
+ // codingns-client-revision: c70e6c4185d35edabf441612e5012044ffdd0658ca60590d6c3b9e3bbf4a3d5a
82711
84073
  //# sourceMappingURL=bundle.js.map