@jingyi0605/codingns4dsh 0.1.0

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 (312) hide show
  1. package/README.md +1114 -0
  2. package/assets/provider-icons/claude-code.png +0 -0
  3. package/assets/provider-icons/codex.png +0 -0
  4. package/assets/provider-icons/command-code.svg +5 -0
  5. package/assets/provider-icons/deepseek-harness.svg +9 -0
  6. package/assets/provider-icons/gemini.png +0 -0
  7. package/assets/provider-icons/grok.png +0 -0
  8. package/assets/provider-icons/kimi.png +0 -0
  9. package/assets/provider-icons/opencode.png +0 -0
  10. package/assets/provider-icons/pi.svg +7 -0
  11. package/data/build/dist/bootstrap/dsh-connection-adapter.d.ts +97 -0
  12. package/data/build/dist/bootstrap/dsh-connection-adapter.js +169 -0
  13. package/data/build/dist/bootstrap/index.d.ts +38 -0
  14. package/data/build/dist/bootstrap/index.js +44 -0
  15. package/data/build/dist/client/account-bar.d.ts +9 -0
  16. package/data/build/dist/client/account-bar.js +398 -0
  17. package/data/build/dist/client/bundle.js +26167 -0
  18. package/data/build/dist/client/cli-catalog.d.ts +24 -0
  19. package/data/build/dist/client/cli-catalog.js +108 -0
  20. package/data/build/dist/client/cli-slots.d.ts +38 -0
  21. package/data/build/dist/client/cli-slots.js +297 -0
  22. package/data/build/dist/client/debug/ui.d.ts +12 -0
  23. package/data/build/dist/client/debug/ui.js +451 -0
  24. package/data/build/dist/client/dsh-h5-bootstrap.d.ts +64 -0
  25. package/data/build/dist/client/dsh-h5-bootstrap.js +293 -0
  26. package/data/build/dist/client/dsh-runtime-version.d.ts +3 -0
  27. package/data/build/dist/client/dsh-runtime-version.js +11 -0
  28. package/data/build/dist/client/external-tool-stream.d.ts +24 -0
  29. package/data/build/dist/client/external-tool-stream.js +114 -0
  30. package/data/build/dist/client/features/cli-adapters.d.ts +7 -0
  31. package/data/build/dist/client/features/cli-adapters.js +215 -0
  32. package/data/build/dist/client/features/debug.d.ts +4 -0
  33. package/data/build/dist/client/features/debug.js +24 -0
  34. package/data/build/dist/client/features/index.d.ts +33 -0
  35. package/data/build/dist/client/features/index.js +44 -0
  36. package/data/build/dist/client/features/lan-access-panel.d.ts +5 -0
  37. package/data/build/dist/client/features/lan-access-panel.js +146 -0
  38. package/data/build/dist/client/features/lan-access.d.ts +9 -0
  39. package/data/build/dist/client/features/lan-access.js +30 -0
  40. package/data/build/dist/client/features/login-protection-panel.d.ts +5 -0
  41. package/data/build/dist/client/features/login-protection-panel.js +91 -0
  42. package/data/build/dist/client/features/login-protection-session.d.ts +6 -0
  43. package/data/build/dist/client/features/login-protection-session.js +25 -0
  44. package/data/build/dist/client/features/login-protection.d.ts +4 -0
  45. package/data/build/dist/client/features/login-protection.js +23 -0
  46. package/data/build/dist/client/features/reverse-proxy-panel.d.ts +9 -0
  47. package/data/build/dist/client/features/reverse-proxy-panel.js +159 -0
  48. package/data/build/dist/client/features/reverse-proxy.d.ts +12 -0
  49. package/data/build/dist/client/features/reverse-proxy.js +112 -0
  50. package/data/build/dist/client/features/terminal-enhancement-panel.d.ts +5 -0
  51. package/data/build/dist/client/features/terminal-enhancement-panel.js +160 -0
  52. package/data/build/dist/client/features/terminal-enhancement.d.ts +4 -0
  53. package/data/build/dist/client/features/terminal-enhancement.js +24 -0
  54. package/data/build/dist/client/features/types.d.ts +58 -0
  55. package/data/build/dist/client/features/types.js +2 -0
  56. package/data/build/dist/client/features/workspace-session-enhancement-panel.d.ts +5 -0
  57. package/data/build/dist/client/features/workspace-session-enhancement-panel.js +66 -0
  58. package/data/build/dist/client/features/workspace-session-enhancement.d.ts +4 -0
  59. package/data/build/dist/client/features/workspace-session-enhancement.js +101 -0
  60. package/data/build/dist/client/h5-bootstrap-entry.d.ts +2 -0
  61. package/data/build/dist/client/h5-bootstrap-entry.js +17 -0
  62. package/data/build/dist/client/index.d.ts +31 -0
  63. package/data/build/dist/client/index.js +98 -0
  64. package/data/build/dist/client/lan-access.d.ts +28 -0
  65. package/data/build/dist/client/lan-access.js +68 -0
  66. package/data/build/dist/client/locale.d.ts +20 -0
  67. package/data/build/dist/client/locale.js +393 -0
  68. package/data/build/dist/client/provider-icon-assets.d.ts +2 -0
  69. package/data/build/dist/client/provider-icon-assets.js +23 -0
  70. package/data/build/dist/client/provider-icons.d.ts +19 -0
  71. package/data/build/dist/client/provider-icons.js +39 -0
  72. package/data/build/dist/client/remote-web-context.d.ts +57 -0
  73. package/data/build/dist/client/remote-web-context.js +939 -0
  74. package/data/build/dist/client/session-adapter-cache.d.ts +18 -0
  75. package/data/build/dist/client/session-adapter-cache.js +84 -0
  76. package/data/build/dist/client/settings-bridge.d.ts +32 -0
  77. package/data/build/dist/client/settings-bridge.js +126 -0
  78. package/data/build/dist/client/settings-section.d.ts +30 -0
  79. package/data/build/dist/client/settings-section.js +93 -0
  80. package/data/build/dist/client/subscription-slot.d.ts +18 -0
  81. package/data/build/dist/client/subscription-slot.js +223 -0
  82. package/data/build/dist/client/terminal/index.d.ts +4 -0
  83. package/data/build/dist/client/terminal/index.js +3 -0
  84. package/data/build/dist/client/terminal/model.d.ts +116 -0
  85. package/data/build/dist/client/terminal/model.js +435 -0
  86. package/data/build/dist/client/terminal/styles.d.ts +21 -0
  87. package/data/build/dist/client/terminal/styles.js +51 -0
  88. package/data/build/dist/client/terminal/ui.d.ts +19 -0
  89. package/data/build/dist/client/terminal/ui.js +257 -0
  90. package/data/build/dist/client/terminal/xterm-view.d.ts +13 -0
  91. package/data/build/dist/client/terminal/xterm-view.js +213 -0
  92. package/data/build/dist/client/theme.d.ts +56 -0
  93. package/data/build/dist/client/theme.js +186 -0
  94. package/data/build/dist/client/workspace-session-archive-dom.d.ts +29 -0
  95. package/data/build/dist/client/workspace-session-archive-dom.js +525 -0
  96. package/data/build/dist/client/workspace-session-fiber.d.ts +3 -0
  97. package/data/build/dist/client/workspace-session-fiber.js +33 -0
  98. package/data/build/dist/client/workspace-session-logo-dom.d.ts +26 -0
  99. package/data/build/dist/client/workspace-session-logo-dom.js +128 -0
  100. package/data/build/dist/features/index.d.ts +3 -0
  101. package/data/build/dist/features/index.js +2 -0
  102. package/data/build/dist/features/registry.d.ts +74 -0
  103. package/data/build/dist/features/registry.js +382 -0
  104. package/data/build/dist/features/resource-scope/index.d.ts +39 -0
  105. package/data/build/dist/features/resource-scope/index.js +161 -0
  106. package/data/build/dist/host/auth-session.d.ts +42 -0
  107. package/data/build/dist/host/auth-session.js +186 -0
  108. package/data/build/dist/host/cli-adapters/claude-driver.d.ts +14 -0
  109. package/data/build/dist/host/cli-adapters/claude-driver.js +103 -0
  110. package/data/build/dist/host/cli-adapters/codex-driver.d.ts +45 -0
  111. package/data/build/dist/host/cli-adapters/codex-driver.js +534 -0
  112. package/data/build/dist/host/cli-adapters/command-code-driver.d.ts +38 -0
  113. package/data/build/dist/host/cli-adapters/command-code-driver.js +394 -0
  114. package/data/build/dist/host/cli-adapters/command-code-subscription.d.ts +19 -0
  115. package/data/build/dist/host/cli-adapters/command-code-subscription.js +126 -0
  116. package/data/build/dist/host/cli-adapters/driver.d.ts +41 -0
  117. package/data/build/dist/host/cli-adapters/driver.js +2 -0
  118. package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts +37 -0
  119. package/data/build/dist/host/cli-adapters/dsh-message-projector.js +180 -0
  120. package/data/build/dist/host/cli-adapters/dsh-tool-history.d.ts +48 -0
  121. package/data/build/dist/host/cli-adapters/dsh-tool-history.js +373 -0
  122. package/data/build/dist/host/cli-adapters/feature.d.ts +7 -0
  123. package/data/build/dist/host/cli-adapters/feature.js +335 -0
  124. package/data/build/dist/host/cli-adapters/gemini-driver.d.ts +24 -0
  125. package/data/build/dist/host/cli-adapters/gemini-driver.js +427 -0
  126. package/data/build/dist/host/cli-adapters/grok-driver.d.ts +38 -0
  127. package/data/build/dist/host/cli-adapters/grok-driver.js +372 -0
  128. package/data/build/dist/host/cli-adapters/http-sse-client.d.ts +22 -0
  129. package/data/build/dist/host/cli-adapters/http-sse-client.js +99 -0
  130. package/data/build/dist/host/cli-adapters/interaction-events.d.ts +11 -0
  131. package/data/build/dist/host/cli-adapters/interaction-events.js +80 -0
  132. package/data/build/dist/host/cli-adapters/json-rpc-process.d.ts +65 -0
  133. package/data/build/dist/host/cli-adapters/json-rpc-process.js +256 -0
  134. package/data/build/dist/host/cli-adapters/kimi-driver.d.ts +21 -0
  135. package/data/build/dist/host/cli-adapters/kimi-driver.js +382 -0
  136. package/data/build/dist/host/cli-adapters/model-catalog.d.ts +22 -0
  137. package/data/build/dist/host/cli-adapters/model-catalog.js +89 -0
  138. package/data/build/dist/host/cli-adapters/opencode-driver.d.ts +55 -0
  139. package/data/build/dist/host/cli-adapters/opencode-driver.js +728 -0
  140. package/data/build/dist/host/cli-adapters/pi-driver.d.ts +43 -0
  141. package/data/build/dist/host/cli-adapters/pi-driver.js +312 -0
  142. package/data/build/dist/host/cli-adapters/process-utils.d.ts +16 -0
  143. package/data/build/dist/host/cli-adapters/process-utils.js +27 -0
  144. package/data/build/dist/host/cli-adapters/provider-subscription.d.ts +82 -0
  145. package/data/build/dist/host/cli-adapters/provider-subscription.js +610 -0
  146. package/data/build/dist/host/cli-adapters/registry.d.ts +95 -0
  147. package/data/build/dist/host/cli-adapters/registry.js +659 -0
  148. package/data/build/dist/host/cli-adapters/rpc-driver-utils.d.ts +24 -0
  149. package/data/build/dist/host/cli-adapters/rpc-driver-utils.js +119 -0
  150. package/data/build/dist/host/cli-adapters/session-probe.d.ts +20 -0
  151. package/data/build/dist/host/cli-adapters/session-probe.js +139 -0
  152. package/data/build/dist/host/cli-adapters/session-store.d.ts +68 -0
  153. package/data/build/dist/host/cli-adapters/session-store.js +180 -0
  154. package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts +45 -0
  155. package/data/build/dist/host/cli-adapters/standard-stream-driver.js +205 -0
  156. package/data/build/dist/host/cli-adapters/stream-normalizer.d.ts +25 -0
  157. package/data/build/dist/host/cli-adapters/stream-normalizer.js +83 -0
  158. package/data/build/dist/host/cli-adapters/tool-observation.d.ts +9 -0
  159. package/data/build/dist/host/cli-adapters/tool-observation.js +39 -0
  160. package/data/build/dist/host/control-api-client.d.ts +84 -0
  161. package/data/build/dist/host/control-api-client.js +130 -0
  162. package/data/build/dist/host/credential-store.d.ts +54 -0
  163. package/data/build/dist/host/credential-store.js +114 -0
  164. package/data/build/dist/host/debug.d.ts +79 -0
  165. package/data/build/dist/host/debug.js +295 -0
  166. package/data/build/dist/host/dsh-device-runtime.d.ts +39 -0
  167. package/data/build/dist/host/dsh-device-runtime.js +118 -0
  168. package/data/build/dist/host/dsh-gateway-feature.d.ts +5 -0
  169. package/data/build/dist/host/dsh-gateway-feature.js +55 -0
  170. package/data/build/dist/host/dsh-runtime-version.d.ts +12 -0
  171. package/data/build/dist/host/dsh-runtime-version.js +69 -0
  172. package/data/build/dist/host/features/auth.d.ts +11 -0
  173. package/data/build/dist/host/features/auth.js +273 -0
  174. package/data/build/dist/host/features/debug.d.ts +5 -0
  175. package/data/build/dist/host/features/debug.js +90 -0
  176. package/data/build/dist/host/features/host-status.d.ts +12 -0
  177. package/data/build/dist/host/features/host-status.js +54 -0
  178. package/data/build/dist/host/features/index.d.ts +19 -0
  179. package/data/build/dist/host/features/index.js +29 -0
  180. package/data/build/dist/host/features/lan-access-dsh.d.ts +8 -0
  181. package/data/build/dist/host/features/lan-access-dsh.js +45 -0
  182. package/data/build/dist/host/features/terminal-process.d.ts +5 -0
  183. package/data/build/dist/host/features/terminal-process.js +110 -0
  184. package/data/build/dist/host/features/terminal-status.d.ts +18 -0
  185. package/data/build/dist/host/features/terminal-status.js +56 -0
  186. package/data/build/dist/host/features/types.d.ts +41 -0
  187. package/data/build/dist/host/features/types.js +2 -0
  188. package/data/build/dist/host/index.d.ts +43 -0
  189. package/data/build/dist/host/index.js +135 -0
  190. package/data/build/dist/host/lan-access-dsh.d.ts +83 -0
  191. package/data/build/dist/host/lan-access-dsh.js +831 -0
  192. package/data/build/dist/host/native-session-bridge.d.ts +130 -0
  193. package/data/build/dist/host/native-session-bridge.js +317 -0
  194. package/data/build/dist/host/relay-tunnel-runtime.d.ts +97 -0
  195. package/data/build/dist/host/relay-tunnel-runtime.js +361 -0
  196. package/data/build/dist/host/remote-web-runtime.d.ts +78 -0
  197. package/data/build/dist/host/remote-web-runtime.js +559 -0
  198. package/data/build/dist/host/rpc-table.d.ts +32 -0
  199. package/data/build/dist/host/rpc-table.js +47 -0
  200. package/data/build/dist/host/rpc.d.ts +18 -0
  201. package/data/build/dist/host/rpc.js +248 -0
  202. package/data/build/dist/host/settings.d.ts +19 -0
  203. package/data/build/dist/host/settings.js +80 -0
  204. package/data/build/dist/host/terminal/attachment-registry.d.ts +17 -0
  205. package/data/build/dist/host/terminal/attachment-registry.js +49 -0
  206. package/data/build/dist/host/terminal/backends/conpty-backend.d.ts +39 -0
  207. package/data/build/dist/host/terminal/backends/conpty-backend.js +160 -0
  208. package/data/build/dist/host/terminal/backends/local-pty-backend.d.ts +36 -0
  209. package/data/build/dist/host/terminal/backends/local-pty-backend.js +178 -0
  210. package/data/build/dist/host/terminal/backends/tmux-backend.d.ts +40 -0
  211. package/data/build/dist/host/terminal/backends/tmux-backend.js +191 -0
  212. package/data/build/dist/host/terminal/broker/conpty-broker-client.d.ts +27 -0
  213. package/data/build/dist/host/terminal/broker/conpty-broker-client.js +154 -0
  214. package/data/build/dist/host/terminal/broker/conpty-broker-process.d.ts +10 -0
  215. package/data/build/dist/host/terminal/broker/conpty-broker-process.js +147 -0
  216. package/data/build/dist/host/terminal/broker/conpty-broker-protocol.d.ts +92 -0
  217. package/data/build/dist/host/terminal/broker/conpty-broker-protocol.js +134 -0
  218. package/data/build/dist/host/terminal/controller-factory.d.ts +37 -0
  219. package/data/build/dist/host/terminal/controller-factory.js +82 -0
  220. package/data/build/dist/host/terminal/index.d.ts +17 -0
  221. package/data/build/dist/host/terminal/index.js +17 -0
  222. package/data/build/dist/host/terminal/runtime-adapter.d.ts +77 -0
  223. package/data/build/dist/host/terminal/runtime-adapter.js +18 -0
  224. package/data/build/dist/host/terminal/runtime-manager.d.ts +41 -0
  225. package/data/build/dist/host/terminal/runtime-manager.js +179 -0
  226. package/data/build/dist/host/terminal/shell-detection.d.ts +23 -0
  227. package/data/build/dist/host/terminal/shell-detection.js +105 -0
  228. package/data/build/dist/host/terminal/startup.d.ts +33 -0
  229. package/data/build/dist/host/terminal/startup.js +100 -0
  230. package/data/build/dist/host/terminal/terminal-controller.d.ts +78 -0
  231. package/data/build/dist/host/terminal/terminal-controller.js +324 -0
  232. package/data/build/dist/host/terminal/terminal-process-service.d.ts +30 -0
  233. package/data/build/dist/host/terminal/terminal-process-service.js +194 -0
  234. package/data/build/dist/host/terminal/terminal-process-store.d.ts +45 -0
  235. package/data/build/dist/host/terminal/terminal-process-store.js +183 -0
  236. package/data/build/dist/host/terminal/terminal-service.d.ts +87 -0
  237. package/data/build/dist/host/terminal/terminal-service.js +528 -0
  238. package/data/build/dist/host/terminal/terminal-store.d.ts +49 -0
  239. package/data/build/dist/host/terminal/terminal-store.js +242 -0
  240. package/data/build/dist/index.d.ts +37 -0
  241. package/data/build/dist/index.js +26 -0
  242. package/data/build/dist/shared/contracts/auth.d.ts +122 -0
  243. package/data/build/dist/shared/contracts/auth.js +8 -0
  244. package/data/build/dist/shared/contracts/cli-adapter.d.ts +192 -0
  245. package/data/build/dist/shared/contracts/cli-adapter.js +2 -0
  246. package/data/build/dist/shared/contracts/command-code.d.ts +5 -0
  247. package/data/build/dist/shared/contracts/command-code.js +2 -0
  248. package/data/build/dist/shared/contracts/config.d.ts +113 -0
  249. package/data/build/dist/shared/contracts/config.js +86 -0
  250. package/data/build/dist/shared/contracts/debug-config.d.ts +28 -0
  251. package/data/build/dist/shared/contracts/debug-config.js +78 -0
  252. package/data/build/dist/shared/contracts/debug.d.ts +75 -0
  253. package/data/build/dist/shared/contracts/debug.js +121 -0
  254. package/data/build/dist/shared/contracts/dsh-device.d.ts +72 -0
  255. package/data/build/dist/shared/contracts/dsh-device.js +2 -0
  256. package/data/build/dist/shared/contracts/errors.d.ts +33 -0
  257. package/data/build/dist/shared/contracts/errors.js +41 -0
  258. package/data/build/dist/shared/contracts/feature.d.ts +71 -0
  259. package/data/build/dist/shared/contracts/feature.js +2 -0
  260. package/data/build/dist/shared/contracts/host-status.d.ts +14 -0
  261. package/data/build/dist/shared/contracts/host-status.js +2 -0
  262. package/data/build/dist/shared/contracts/lan-access-dsh.d.ts +30 -0
  263. package/data/build/dist/shared/contracts/lan-access-dsh.js +2 -0
  264. package/data/build/dist/shared/contracts/peer-host.d.ts +37 -0
  265. package/data/build/dist/shared/contracts/peer-host.js +9 -0
  266. package/data/build/dist/shared/contracts/signaling.d.ts +67 -0
  267. package/data/build/dist/shared/contracts/signaling.js +2 -0
  268. package/data/build/dist/shared/contracts/subscription.d.ts +69 -0
  269. package/data/build/dist/shared/contracts/subscription.js +2 -0
  270. package/data/build/dist/shared/contracts/terminal-process.d.ts +65 -0
  271. package/data/build/dist/shared/contracts/terminal-process.js +2 -0
  272. package/data/build/dist/shared/contracts/terminal.d.ts +127 -0
  273. package/data/build/dist/shared/contracts/terminal.js +2 -0
  274. package/data/build/dist/shared/contracts/transport.d.ts +45 -0
  275. package/data/build/dist/shared/contracts/transport.js +3 -0
  276. package/data/build/dist/shared/contracts/version.d.ts +19 -0
  277. package/data/build/dist/shared/contracts/version.js +74 -0
  278. package/data/build/dist/shared/index.d.ts +22 -0
  279. package/data/build/dist/shared/index.js +9 -0
  280. package/data/build/dist/transport/carrier.d.ts +38 -0
  281. package/data/build/dist/transport/carrier.js +268 -0
  282. package/data/build/dist/transport/debug.d.ts +22 -0
  283. package/data/build/dist/transport/debug.js +57 -0
  284. package/data/build/dist/transport/dsh-envelope.d.ts +41 -0
  285. package/data/build/dist/transport/dsh-envelope.js +107 -0
  286. package/data/build/dist/transport/dsh-gateway.d.ts +64 -0
  287. package/data/build/dist/transport/dsh-gateway.js +254 -0
  288. package/data/build/dist/transport/dsh-session.d.ts +55 -0
  289. package/data/build/dist/transport/dsh-session.js +256 -0
  290. package/data/build/dist/transport/dsh-transport.d.ts +57 -0
  291. package/data/build/dist/transport/dsh-transport.js +125 -0
  292. package/data/build/dist/transport/frame.d.ts +132 -0
  293. package/data/build/dist/transport/frame.js +168 -0
  294. package/data/build/dist/transport/index.d.ts +11 -0
  295. package/data/build/dist/transport/index.js +11 -0
  296. package/data/build/dist/transport/multiplexer.d.ts +63 -0
  297. package/data/build/dist/transport/multiplexer.js +323 -0
  298. package/data/build/dist/transport/webrtc-client.d.ts +65 -0
  299. package/data/build/dist/transport/webrtc-client.js +255 -0
  300. package/data/build/dist/transport/webrtc-host.d.ts +58 -0
  301. package/data/build/dist/transport/webrtc-host.js +252 -0
  302. package/data/build/dist/typert.host.d.ts +25 -0
  303. package/data/build/dist/typert.host.js +150 -0
  304. package/dsh.bundle.patch +12 -0
  305. package/package.json +135 -0
  306. package/profile/README.md +27 -0
  307. package/profile/cordis.patch.yml +2 -0
  308. package/profile/package.json +20 -0
  309. package/profile/scripts/check-dsh-install.mjs +71 -0
  310. package/profile/version.json +5 -0
  311. package/scripts/check-dsh-install.mjs +88 -0
  312. package/version.json +6 -0
@@ -0,0 +1,128 @@
1
+ import { providerVisual } from './provider-icons.js';
2
+ import { sessionAdapterId, subscribeSessionAdapters } from './session-adapter-cache.js';
3
+ import { resolveDshSessionId } from './workspace-session-fiber.js';
4
+ export const WORKSPACE_SESSION_ROW_SELECTOR = '[role="treeitem"]';
5
+ export const WORKSPACE_SESSION_LOGO_ATTRIBUTE = 'data-codingns-session-logo';
6
+ /**
7
+ * 为 DSH 0.1.6-alpha.2 会话行安装兼容注入器。
8
+ *
9
+ * 该版本没有 leading Slot,也没有把 sessionId 写进 DOM。这里仅读取 React
10
+ * Fiber 上 `node.id`/`result.id` 两个已验证字段;任何不匹配都直接跳过。
11
+ */
12
+ export function startWorkspaceSessionLogoDom(options = {}) {
13
+ const dom = options.document ?? (typeof document === 'undefined' ? undefined : document);
14
+ const Observer = options.MutationObserver
15
+ ?? (typeof MutationObserver === 'undefined' ? undefined : MutationObserver);
16
+ // SessionStore 只记录显式选择;没有外部绑定时,DSH Registry 的权威默认值就是 dsh。
17
+ const adapterIdForSession = options.adapterIdForSession
18
+ ?? ((sessionId) => sessionAdapterId(sessionId) ?? 'dsh');
19
+ const visualForAdapter = options.visualForAdapter ?? providerVisual;
20
+ let disposed = false;
21
+ let scanQueued = false;
22
+ const scan = () => {
23
+ if (disposed || dom === undefined)
24
+ return;
25
+ // DSH 原生工作区会话行和搜索结果都声明为 treeitem。只读这个稳定语义
26
+ // 标记,禁止把对话区里的按钮、复制按钮或适配器选择按钮当成会话行。
27
+ const rows = dom.querySelectorAll(WORKSPACE_SESSION_ROW_SELECTOR);
28
+ for (const row of rows) {
29
+ const sessionId = resolveDshSessionId(row);
30
+ if (sessionId === undefined)
31
+ continue;
32
+ upsertSessionLogo(row, sessionId, visualForAdapter(adapterIdForSession(sessionId)), dom);
33
+ }
34
+ };
35
+ const scheduleScan = () => {
36
+ if (disposed || scanQueued)
37
+ return;
38
+ scanQueued = true;
39
+ queueMicrotask(() => {
40
+ scanQueued = false;
41
+ scan();
42
+ });
43
+ };
44
+ const observer = dom === undefined || Observer === undefined
45
+ ? undefined
46
+ : new Observer(scheduleScan);
47
+ if (observer !== undefined && dom !== undefined) {
48
+ observer.observe(dom.documentElement, { childList: true, subtree: true });
49
+ }
50
+ const unsubscribe = subscribeSessionAdapters(scheduleScan);
51
+ scan();
52
+ return {
53
+ refresh: scheduleScan,
54
+ dispose() {
55
+ if (disposed)
56
+ return;
57
+ disposed = true;
58
+ observer?.disconnect();
59
+ unsubscribe();
60
+ if (dom !== undefined)
61
+ removeWorkspaceSessionLogos(dom);
62
+ },
63
+ };
64
+ }
65
+ /** 移除当前文档中全部由本模块插入的节点。 */
66
+ export function removeWorkspaceSessionLogos(dom) {
67
+ for (const node of dom.querySelectorAll(`[${WORKSPACE_SESSION_LOGO_ATTRIBUTE}]`))
68
+ node.remove();
69
+ }
70
+ function upsertSessionLogo(row, sessionId, visual, dom) {
71
+ const existing = row.querySelector(`[${WORKSPACE_SESSION_LOGO_ATTRIBUTE}]`);
72
+ const adapterKey = visual.adapterId ?? '';
73
+ if (existing?.dataset.codingnsSessionId === sessionId
74
+ && existing.dataset.codingnsAdapterId === adapterKey)
75
+ return;
76
+ existing?.remove();
77
+ const logo = createLogoElement(dom, sessionId, visual);
78
+ const parent = row.tagName === 'BUTTON' && row.firstElementChild !== null
79
+ ? row.firstElementChild
80
+ : row;
81
+ parent.insertBefore(logo, parent.firstChild);
82
+ }
83
+ function createLogoElement(dom, sessionId, visual) {
84
+ const container = dom.createElement('span');
85
+ container.setAttribute(WORKSPACE_SESSION_LOGO_ATTRIBUTE, '');
86
+ container.dataset.codingnsSessionId = sessionId;
87
+ container.dataset.codingnsAdapterId = visual.adapterId ?? '';
88
+ container.title = visual.displayName;
89
+ container.setAttribute('aria-hidden', 'true');
90
+ Object.assign(container.style, {
91
+ width: '16px',
92
+ height: '16px',
93
+ flex: '0 0 16px',
94
+ display: 'inline-flex',
95
+ alignItems: 'center',
96
+ justifyContent: 'center',
97
+ marginRight: '4px',
98
+ pointerEvents: 'none',
99
+ overflow: 'hidden',
100
+ });
101
+ if (visual.iconUrl !== undefined) {
102
+ const image = dom.createElement('img');
103
+ image.src = visual.iconUrl;
104
+ image.alt = '';
105
+ image.setAttribute('aria-hidden', 'true');
106
+ Object.assign(image.style, {
107
+ width: '16px',
108
+ height: '16px',
109
+ display: 'block',
110
+ objectFit: 'contain',
111
+ });
112
+ container.appendChild(image);
113
+ return container;
114
+ }
115
+ container.textContent = '?';
116
+ Object.assign(container.style, {
117
+ boxSizing: 'border-box',
118
+ border: '1px solid var(--dsw-alias-border-l2, currentColor)',
119
+ borderRadius: '4px',
120
+ color: 'var(--dsw-alias-label-tertiary, currentColor)',
121
+ fontSize: '10px',
122
+ fontWeight: '600',
123
+ lineHeight: '14px',
124
+ });
125
+ return container;
126
+ }
127
+ export { resolveDshSessionId } from './workspace-session-fiber.js';
128
+ //# sourceMappingURL=workspace-session-logo-dom.js.map
@@ -0,0 +1,3 @@
1
+ export { FeatureRegistry, FeatureRegistryError, FeatureResourceScopeImpl, type FeatureRegistryErrorCode, type FeatureSnapshot, } from './registry.js';
2
+ export type { FeatureContext, FeatureDescriptor, FeatureDisposer, FeatureModule, FeatureResourceScope, FeatureRuntime, FeatureState, FeatureUiDescriptor, } from '../shared/contracts/feature.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { FeatureRegistry, FeatureRegistryError, FeatureResourceScopeImpl, } from './registry.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,74 @@
1
+ import type { FeatureDescriptor, FeatureDisposer, FeatureModule, FeatureResourceScope, FeatureState } from '../shared/contracts/feature.js';
2
+ export type FeatureRegistryErrorCode = 'FEATURE_INVALID_DESCRIPTOR' | 'FEATURE_ALREADY_REGISTERED' | 'FEATURE_NOT_FOUND' | 'FEATURE_DEPENDENCY_MISSING' | 'FEATURE_DEPENDENCY_CYCLE' | 'FEATURE_START_FAILED' | 'FEATURE_DISPOSE_FAILED' | 'FEATURE_STATE_INVALID';
3
+ export declare class FeatureRegistryError extends Error {
4
+ readonly code: FeatureRegistryErrorCode;
5
+ readonly featureName: string | null;
6
+ constructor(code: FeatureRegistryErrorCode, message: string, featureName?: string | null, options?: ErrorOptions);
7
+ }
8
+ export interface FeatureSnapshot {
9
+ name: string;
10
+ version: string;
11
+ state: FeatureState;
12
+ runtime: FeatureDescriptor['runtime'];
13
+ dependencies: readonly string[];
14
+ reason: string | null;
15
+ }
16
+ /**
17
+ * 管理功能模块的依赖、状态和资源所有权。
18
+ *
19
+ * 注册表本身不创建计时器、socket 或进程;所有资源必须通过 context.resources
20
+ * 登记,卸载时由注册表统一按逆序释放。它不感知界面:设置页需要的标题、说明和
21
+ * 排序放在 descriptor.ui 中由宿主读取,因此新增模块不需要修改注册表。
22
+ */
23
+ export declare class FeatureResourceScopeImpl implements FeatureResourceScope {
24
+ private readonly disposers;
25
+ private isDisposed;
26
+ get disposed(): boolean;
27
+ add(disposer: FeatureDisposer): void;
28
+ dispose(): Promise<void>;
29
+ }
30
+ /**
31
+ * 模块注册表:负责依赖排序、状态迁移、并发串行化和资源释放。
32
+ *
33
+ * @typeParam S - 注入给每个模块的宿主服务集合。
34
+ * @typeParam M - 注册的模块类型;宿主可用它携带额外模块契约(例如设置面板)。
35
+ */
36
+ export declare class FeatureRegistry<S = unknown, M extends FeatureModule<S> = FeatureModule<S>> {
37
+ private readonly services;
38
+ private readonly records;
39
+ private readonly operations;
40
+ /** @param services - 每个模块在 start 时通过 context.services 取用的服务集合。 */
41
+ constructor(services: S);
42
+ register(module: M): void;
43
+ registerMany(modules: readonly M[]): void;
44
+ has(name: string): boolean;
45
+ getState(name: string): FeatureState;
46
+ getSnapshot(name: string): FeatureSnapshot;
47
+ list(): FeatureSnapshot[];
48
+ /** 按注册顺序返回模块本体,供宿主渲染设置页或查询模块能力。 */
49
+ modules(): readonly M[];
50
+ /** 返回单个模块本体;未注册时抛出 FEATURE_NOT_FOUND。 */
51
+ getModule(name: string): M;
52
+ /** 按注册顺序返回描述符,宿主用它计算期望启用集合。 */
53
+ descriptors(): readonly FeatureDescriptor[];
54
+ validate(): void;
55
+ start(name: string): Promise<void>;
56
+ /**
57
+ * 把模块状态对齐到期望启用集合。
58
+ *
59
+ * 期望启用的模块连同它们的依赖会被启动,其余已启用模块会被停用。依赖会被
60
+ * 自动纳入期望集合,避免「子模块要启用、父模块却被停用」互相拆台。
61
+ * 并发调用按模块串行队列排队,最终状态由最后一次调用决定。
62
+ */
63
+ reconcile(enabledNames: readonly string[]): Promise<void>;
64
+ drain(name: string): Promise<void>;
65
+ dispose(name: string): Promise<void>;
66
+ disable(name: string): Promise<void>;
67
+ /** 把期望集合补齐为含依赖的闭包,避免依赖在停用阶段被误停。 */
68
+ private resolveDesired;
69
+ private startInternal;
70
+ private activeDependents;
71
+ private getRecord;
72
+ private enqueue;
73
+ }
74
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1,382 @@
1
+ export class FeatureRegistryError extends Error {
2
+ code;
3
+ featureName;
4
+ constructor(code, message, featureName = null, options) {
5
+ super(message, options);
6
+ this.name = 'FeatureRegistryError';
7
+ this.code = code;
8
+ this.featureName = featureName;
9
+ }
10
+ }
11
+ /**
12
+ * 管理功能模块的依赖、状态和资源所有权。
13
+ *
14
+ * 注册表本身不创建计时器、socket 或进程;所有资源必须通过 context.resources
15
+ * 登记,卸载时由注册表统一按逆序释放。它不感知界面:设置页需要的标题、说明和
16
+ * 排序放在 descriptor.ui 中由宿主读取,因此新增模块不需要修改注册表。
17
+ */
18
+ export class FeatureResourceScopeImpl {
19
+ disposers = [];
20
+ isDisposed = false;
21
+ get disposed() {
22
+ return this.isDisposed;
23
+ }
24
+ add(disposer) {
25
+ if (typeof disposer !== 'function') {
26
+ throw new TypeError('Feature disposer must be a function');
27
+ }
28
+ if (this.isDisposed) {
29
+ throw new Error('Feature resource scope is already disposed');
30
+ }
31
+ this.disposers.push(disposer);
32
+ }
33
+ async dispose() {
34
+ if (this.isDisposed)
35
+ return;
36
+ this.isDisposed = true;
37
+ const errors = [];
38
+ for (let index = this.disposers.length - 1; index >= 0; index -= 1) {
39
+ try {
40
+ await this.disposers[index]();
41
+ }
42
+ catch (error) {
43
+ errors.push(error);
44
+ }
45
+ }
46
+ this.disposers.length = 0;
47
+ if (errors.length > 0) {
48
+ throw new AggregateError(errors, 'One or more feature resources failed to dispose');
49
+ }
50
+ }
51
+ }
52
+ /**
53
+ * 模块注册表:负责依赖排序、状态迁移、并发串行化和资源释放。
54
+ *
55
+ * @typeParam S - 注入给每个模块的宿主服务集合。
56
+ * @typeParam M - 注册的模块类型;宿主可用它携带额外模块契约(例如设置面板)。
57
+ */
58
+ export class FeatureRegistry {
59
+ services;
60
+ records = new Map();
61
+ operations = new Map();
62
+ /** @param services - 每个模块在 start 时通过 context.services 取用的服务集合。 */
63
+ constructor(services) {
64
+ this.services = services;
65
+ }
66
+ register(module) {
67
+ validateDescriptor(module?.descriptor);
68
+ const name = module.descriptor.name;
69
+ if (this.records.has(name)) {
70
+ throw new FeatureRegistryError('FEATURE_ALREADY_REGISTERED', `Feature already registered: ${name}`, name);
71
+ }
72
+ const resources = new FeatureResourceScopeImpl();
73
+ this.records.set(name, {
74
+ module,
75
+ state: 'disabled',
76
+ reason: null,
77
+ resources,
78
+ context: { descriptor: module.descriptor, resources, services: this.services },
79
+ });
80
+ }
81
+ registerMany(modules) {
82
+ for (const module of modules)
83
+ this.register(module);
84
+ }
85
+ has(name) {
86
+ return this.records.has(name);
87
+ }
88
+ getState(name) {
89
+ return this.getRecord(name).state;
90
+ }
91
+ getSnapshot(name) {
92
+ return snapshot(this.getRecord(name));
93
+ }
94
+ list() {
95
+ return [...this.records.values()].map(snapshot);
96
+ }
97
+ /** 按注册顺序返回模块本体,供宿主渲染设置页或查询模块能力。 */
98
+ modules() {
99
+ return [...this.records.values()].map((record) => record.module);
100
+ }
101
+ /** 返回单个模块本体;未注册时抛出 FEATURE_NOT_FOUND。 */
102
+ getModule(name) {
103
+ return this.getRecord(name).module;
104
+ }
105
+ /** 按注册顺序返回描述符,宿主用它计算期望启用集合。 */
106
+ descriptors() {
107
+ return [...this.records.values()].map((record) => record.module.descriptor);
108
+ }
109
+ validate() {
110
+ for (const record of this.records.values()) {
111
+ for (const dependency of record.module.descriptor.dependencies) {
112
+ if (!this.records.has(dependency)) {
113
+ throw new FeatureRegistryError('FEATURE_DEPENDENCY_MISSING', `Feature ${record.module.descriptor.name} depends on missing feature ${dependency}`, record.module.descriptor.name);
114
+ }
115
+ }
116
+ }
117
+ const visiting = new Set();
118
+ const visited = new Set();
119
+ const visit = (name) => {
120
+ if (visiting.has(name)) {
121
+ throw new FeatureRegistryError('FEATURE_DEPENDENCY_CYCLE', `Feature dependency cycle includes ${name}`, name);
122
+ }
123
+ if (visited.has(name))
124
+ return;
125
+ visiting.add(name);
126
+ for (const dependency of this.getRecord(name).module.descriptor.dependencies)
127
+ visit(dependency);
128
+ visiting.delete(name);
129
+ visited.add(name);
130
+ };
131
+ for (const name of this.records.keys())
132
+ visit(name);
133
+ }
134
+ async start(name) {
135
+ return this.enqueue(name, async () => {
136
+ this.validate();
137
+ await this.startInternal(name, new Set());
138
+ });
139
+ }
140
+ /**
141
+ * 把模块状态对齐到期望启用集合。
142
+ *
143
+ * 期望启用的模块连同它们的依赖会被启动,其余已启用模块会被停用。依赖会被
144
+ * 自动纳入期望集合,避免「子模块要启用、父模块却被停用」互相拆台。
145
+ * 并发调用按模块串行队列排队,最终状态由最后一次调用决定。
146
+ */
147
+ async reconcile(enabledNames) {
148
+ this.validate();
149
+ const desired = this.resolveDesired(enabledNames);
150
+ for (const name of this.records.keys()) {
151
+ if (desired.has(name))
152
+ await this.start(name);
153
+ }
154
+ for (const name of this.records.keys()) {
155
+ if (!desired.has(name))
156
+ await this.disable(name);
157
+ }
158
+ }
159
+ async drain(name) {
160
+ return this.enqueue(name, async () => {
161
+ const record = this.getRecord(name);
162
+ if (record.state === 'disabled')
163
+ return;
164
+ if (record.state === 'enabling') {
165
+ throw new FeatureRegistryError('FEATURE_STATE_INVALID', `Cannot drain enabling feature: ${name}`, name);
166
+ }
167
+ if (record.state === 'draining')
168
+ return;
169
+ if (record.state === 'failed')
170
+ return;
171
+ record.state = 'draining';
172
+ try {
173
+ await record.module.drain?.(record.context);
174
+ }
175
+ catch (error) {
176
+ record.reason = errorMessage(error);
177
+ throw new FeatureRegistryError('FEATURE_DISPOSE_FAILED', `Failed to drain feature ${name}`, name, {
178
+ cause: error,
179
+ });
180
+ }
181
+ });
182
+ }
183
+ async dispose(name) {
184
+ return this.enqueue(name, async () => {
185
+ const record = this.getRecord(name);
186
+ if (record.state === 'disabled')
187
+ return;
188
+ const errors = [];
189
+ if (record.state === 'enabled') {
190
+ record.state = 'draining';
191
+ try {
192
+ await record.module.drain?.(record.context);
193
+ }
194
+ catch (error) {
195
+ errors.push(error);
196
+ }
197
+ }
198
+ try {
199
+ await record.module.dispose?.(record.context);
200
+ }
201
+ catch (error) {
202
+ errors.push(error);
203
+ }
204
+ try {
205
+ await record.resources.dispose();
206
+ }
207
+ catch (error) {
208
+ errors.push(error);
209
+ }
210
+ record.state = 'disabled';
211
+ record.reason = errors.length > 0 ? errors.map(errorMessage).join('; ') : null;
212
+ if (errors.length > 0) {
213
+ throw new FeatureRegistryError('FEATURE_DISPOSE_FAILED', `Failed to dispose feature ${name}`, name, {
214
+ cause: new AggregateError(errors),
215
+ });
216
+ }
217
+ });
218
+ }
219
+ async disable(name) {
220
+ this.validate();
221
+ const dependents = this.activeDependents(name);
222
+ for (const dependent of dependents)
223
+ await this.disable(dependent);
224
+ await this.dispose(name);
225
+ }
226
+ /** 把期望集合补齐为含依赖的闭包,避免依赖在停用阶段被误停。 */
227
+ resolveDesired(enabledNames) {
228
+ const desired = new Set();
229
+ const include = (name) => {
230
+ if (desired.has(name))
231
+ return;
232
+ desired.add(name);
233
+ for (const dependency of this.getRecord(name).module.descriptor.dependencies)
234
+ include(dependency);
235
+ };
236
+ for (const name of enabledNames) {
237
+ if (this.records.has(name))
238
+ include(name);
239
+ }
240
+ return desired;
241
+ }
242
+ async startInternal(name, starting) {
243
+ const record = this.getRecord(name);
244
+ if (record.state === 'enabled')
245
+ return;
246
+ if (record.state === 'enabling') {
247
+ throw new FeatureRegistryError('FEATURE_STATE_INVALID', `Feature is already enabling: ${name}`, name);
248
+ }
249
+ if (record.state === 'draining') {
250
+ throw new FeatureRegistryError('FEATURE_STATE_INVALID', `Feature is draining: ${name}`, name);
251
+ }
252
+ if (starting.has(name)) {
253
+ throw new FeatureRegistryError('FEATURE_DEPENDENCY_CYCLE', `Feature dependency cycle includes ${name}`, name);
254
+ }
255
+ starting.add(name);
256
+ for (const dependency of record.module.descriptor.dependencies) {
257
+ await this.enqueue(dependency, () => this.startInternal(dependency, starting));
258
+ }
259
+ starting.delete(name);
260
+ if (record.resources.disposed) {
261
+ record.resources = new FeatureResourceScopeImpl();
262
+ record.context = { descriptor: record.module.descriptor, resources: record.resources, services: this.services };
263
+ }
264
+ record.state = 'enabling';
265
+ record.reason = null;
266
+ try {
267
+ const returned = await record.module.start(record.context);
268
+ addReturnedDisposer(record.resources, returned);
269
+ record.state = 'enabled';
270
+ }
271
+ catch (error) {
272
+ try {
273
+ await record.resources.dispose();
274
+ }
275
+ catch (disposeError) {
276
+ error = new AggregateError([error, disposeError], 'Feature start and cleanup failed');
277
+ }
278
+ record.state = 'failed';
279
+ record.reason = errorMessage(error);
280
+ throw new FeatureRegistryError('FEATURE_START_FAILED', `Failed to start feature ${name}`, name, { cause: error });
281
+ }
282
+ }
283
+ activeDependents(name) {
284
+ const result = [];
285
+ for (const record of this.records.values()) {
286
+ if (record.state !== 'enabled' && record.state !== 'draining')
287
+ continue;
288
+ if (record.module.descriptor.dependencies.includes(name))
289
+ result.push(record.module.descriptor.name);
290
+ }
291
+ return result;
292
+ }
293
+ getRecord(name) {
294
+ const record = this.records.get(name);
295
+ if (!record)
296
+ throw new FeatureRegistryError('FEATURE_NOT_FOUND', `Feature not found: ${name}`, name);
297
+ return record;
298
+ }
299
+ enqueue(name, operation) {
300
+ const previous = this.operations.get(name) ?? Promise.resolve();
301
+ const next = previous.then(operation, operation);
302
+ this.operations.set(name, next);
303
+ const cleanup = () => {
304
+ if (this.operations.get(name) === next)
305
+ this.operations.delete(name);
306
+ };
307
+ void next.then(cleanup, cleanup);
308
+ return next;
309
+ }
310
+ }
311
+ function validateDescriptor(descriptor) {
312
+ if (!descriptor || typeof descriptor.name !== 'string' || descriptor.name.trim() === '') {
313
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', 'Feature descriptor requires a non-empty name');
314
+ }
315
+ if (typeof descriptor.version !== 'string' || descriptor.version.trim() === '') {
316
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} requires a version`, descriptor.name);
317
+ }
318
+ if (typeof descriptor.enabledByDefault !== 'boolean') {
319
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid enabledByDefault`, descriptor.name);
320
+ }
321
+ if (descriptor.runtime !== 'host' && descriptor.runtime !== 'client' && descriptor.runtime !== 'both') {
322
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid runtime`, descriptor.name);
323
+ }
324
+ if (descriptor.activation !== undefined && descriptor.activation !== 'live' && descriptor.activation !== 'restart') {
325
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid activation`, descriptor.name);
326
+ }
327
+ if (descriptor.minimumDshVersion !== undefined
328
+ && (typeof descriptor.minimumDshVersion !== 'string' || descriptor.minimumDshVersion.trim() === '')) {
329
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid minimumDshVersion`, descriptor.name);
330
+ }
331
+ if (!Array.isArray(descriptor.dependencies) || descriptor.dependencies.some((dependency) => typeof dependency !== 'string' || dependency.trim() === '')) {
332
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid dependencies`, descriptor.name);
333
+ }
334
+ if (new Set(descriptor.dependencies).size !== descriptor.dependencies.length) {
335
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has duplicate dependencies`, descriptor.name);
336
+ }
337
+ validateUiDescriptor(descriptor);
338
+ }
339
+ function validateUiDescriptor(descriptor) {
340
+ const ui = descriptor.ui;
341
+ if (ui === undefined)
342
+ return;
343
+ if (typeof ui.label !== 'string' || ui.label.trim() === '') {
344
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid ui.label`, descriptor.name);
345
+ }
346
+ if (typeof ui.description !== 'string' || ui.description.trim() === '') {
347
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid ui.description`, descriptor.name);
348
+ }
349
+ if (ui.order !== undefined && !Number.isFinite(ui.order)) {
350
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid ui.order`, descriptor.name);
351
+ }
352
+ if (ui.defaultOpen !== undefined && typeof ui.defaultOpen !== 'boolean') {
353
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid ui.defaultOpen`, descriptor.name);
354
+ }
355
+ if (ui.alwaysEnabled !== undefined && typeof ui.alwaysEnabled !== 'boolean') {
356
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid ui.alwaysEnabled`, descriptor.name);
357
+ }
358
+ if (ui.legacyFallback !== undefined && typeof ui.legacyFallback !== 'boolean') {
359
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid ui.legacyFallback`, descriptor.name);
360
+ }
361
+ if (ui.legacyFallbackKey !== undefined && (typeof ui.legacyFallbackKey !== 'string' || ui.legacyFallbackKey.trim() === '')) {
362
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid ui.legacyFallbackKey`, descriptor.name);
363
+ }
364
+ }
365
+ function addReturnedDisposer(resources, returned) {
366
+ if (returned !== undefined)
367
+ resources.add(returned);
368
+ }
369
+ function snapshot(record) {
370
+ return {
371
+ name: record.module.descriptor.name,
372
+ version: record.module.descriptor.version,
373
+ state: record.state,
374
+ runtime: record.module.descriptor.runtime,
375
+ dependencies: [...record.module.descriptor.dependencies],
376
+ reason: record.reason,
377
+ };
378
+ }
379
+ function errorMessage(error) {
380
+ return error instanceof Error ? error.message : String(error);
381
+ }
382
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1,39 @@
1
+ import { type ResourceScopeDisposer, type ResourceScopeInput, type ResourceScopeRef, type ResourceScopeSnapshot } from '../../shared/contracts/peer-host.js';
2
+ export { ResourceScopeStaleError, type ResourceScopeDisposer, type ResourceScopeInput, type ResourceScopeRef, type ResourceScopeSnapshot, } from '../../shared/contracts/peer-host.js';
3
+ /**
4
+ * 管理当前 Host/Workspace/PeerHost 资源作用域。
5
+ *
6
+ * 这是纯状态协调器:它不发请求、不创建连接,也不理解具体资源类型。
7
+ * 作用域切换会立即让旧 generation 失效,然后清理旧 disposer,最后保留新快照。
8
+ */
9
+ export declare class ResourceScopeManager {
10
+ private activeScope;
11
+ private nextGeneration;
12
+ private transitionTail;
13
+ constructor(initialScope?: ResourceScopeInput);
14
+ /** 返回当前快照;返回值不可用于修改管理器内部状态。 */
15
+ getCurrent(): ResourceScopeSnapshot | null;
16
+ /**
17
+ * 切换作用域。并发切换会按调用顺序串行化,避免旧 disposer 交叉执行。
18
+ * 相同作用域不会制造无意义的新 generation,但仍可附加 disposer。
19
+ */
20
+ switchTo(input: ResourceScopeInput, disposer?: ResourceScopeDisposer): Promise<ResourceScopeSnapshot>;
21
+ /**
22
+ * 为当前作用域注册清理函数。传入旧快照会直接失败,防止资源归属错乱。
23
+ */
24
+ addDisposer(disposer: ResourceScopeDisposer): () => void;
25
+ /**
26
+ * 按快照注册清理函数。异步初始化完成后应优先使用此方法,避免旧作用域
27
+ * 的初始化结果把 disposer 错挂到新作用域。
28
+ */
29
+ registerDisposer(scope: ResourceScopeRef, disposer: ResourceScopeDisposer): () => void;
30
+ /** 判断快照是否仍然代表当前作用域。 */
31
+ isCurrent(scope: ResourceScopeRef | null | undefined): boolean;
32
+ /** 旧请求回写前调用;作用域不匹配时抛出稳定错误。 */
33
+ assertCurrent(scope: ResourceScopeRef): void;
34
+ /** 只有当前作用域才能执行写入,避免旧请求污染新作用域。 */
35
+ commitIfCurrent<T>(scope: ResourceScopeRef, write: () => T): T;
36
+ /** 清理当前作用域并使其失效。后续可重新 switchTo。 */
37
+ clear(): Promise<void>;
38
+ }
39
+ //# sourceMappingURL=index.d.ts.map