@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,119 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { JsonRpcProcess } from './json-rpc-process.js';
3
+ import { WINDOWS } from './process-utils.js';
4
+ export async function detectBinary(options) {
5
+ const run = options.spawnSync ?? spawnSync;
6
+ for (const command of options.binaries) {
7
+ try {
8
+ const result = run(command, ['--version'], { encoding: 'utf8', timeout: 3_000, windowsHide: true, shell: WINDOWS });
9
+ const output = `${result.stdout ?? ''}${result.stderr ?? ''}`;
10
+ const version = output.match(/\d+\.\d+(?:\.\d+)?/u)?.[0] ?? null;
11
+ if (result.status === 0 && version !== null)
12
+ return { installed: true, version, command };
13
+ }
14
+ catch { /* PATH 中没有该命令 */ }
15
+ }
16
+ return { installed: false, version: null, command: null };
17
+ }
18
+ /** 把一个 JSON-RPC 请求期间收到的通知排成异步流,同时等待最终响应。 */
19
+ export async function* streamRpcRequest(process, method, params, signal, options = {}) {
20
+ const queue = [];
21
+ let wake;
22
+ let settled = false;
23
+ let failure;
24
+ const listener = (message) => {
25
+ queue.push(message);
26
+ options.onNotification?.(message);
27
+ wake?.();
28
+ wake = undefined;
29
+ };
30
+ const removeListener = process.addNotificationListener(listener);
31
+ const response = process.request(method, params, {
32
+ ...(signal === undefined ? {} : { signal }),
33
+ ...(options.killOnAbort === undefined ? {} : { killOnAbort: options.killOnAbort }),
34
+ }).then((value) => { settled = true; wake?.(); wake = undefined; return value; }, (error) => { failure = error; settled = true; wake?.(); wake = undefined; return undefined; });
35
+ try {
36
+ while (!settled || queue.length > 0) {
37
+ if (queue.length > 0) {
38
+ yield queue.shift();
39
+ continue;
40
+ }
41
+ await new Promise((resolve) => { wake = resolve; });
42
+ }
43
+ if (failure !== undefined)
44
+ throw failure;
45
+ return await response;
46
+ }
47
+ finally {
48
+ removeListener();
49
+ if (options.dispose !== false)
50
+ process.dispose();
51
+ }
52
+ }
53
+ export function emptyCatalog() {
54
+ return { groups: [], currentModel: null, currentEffort: null };
55
+ }
56
+ export function textValue(value) {
57
+ if (typeof value === 'string')
58
+ return value;
59
+ if (!isRecord(value))
60
+ return null;
61
+ for (const key of ['text', 'delta', 'content', 'message'])
62
+ if (typeof value[key] === 'string')
63
+ return value[key];
64
+ return null;
65
+ }
66
+ export function usageChunk(value) {
67
+ if (!isRecord(value))
68
+ return null;
69
+ const usage = isRecord(value.usage) ? value.usage : value;
70
+ const explicitUncachedInputTokens = optionalNumberValue(usage.uncachedInputTokens ?? usage.uncached_input_tokens);
71
+ const inputTokens = explicitUncachedInputTokens
72
+ ?? numberValue(usage.inputTokens ?? usage.input_tokens ?? usage.prompt_tokens ?? usage.promptTokenCount);
73
+ const outputTokens = numberValue(usage.outputTokens ?? usage.output_tokens ?? usage.completion_tokens ?? usage.candidatesTokenCount);
74
+ const cacheReadInputTokens = optionalNumberValue(usage.cache_read_input_tokens ?? usage.cacheReadInputTokens);
75
+ const cacheWriteInputTokens = optionalNumberValue(usage.cache_creation_input_tokens ?? usage.cacheCreationInputTokens);
76
+ const cacheReadTokens = optionalNumberValue(usage.cacheReadTokens
77
+ ?? usage.cachedReadTokens
78
+ ?? usage.cache_read_tokens
79
+ ?? usage.cached_read_tokens
80
+ ?? usage.cache_read_input_tokens
81
+ ?? usage.cachedInputTokens
82
+ ?? usage.cached_input_tokens
83
+ ?? usage.cachedContentTokenCount
84
+ ?? cacheReadInputTokens);
85
+ const cacheWriteTokens = optionalNumberValue(usage.cacheWriteTokens
86
+ ?? usage.cacheCreationTokens
87
+ ?? usage.cache_write_tokens
88
+ ?? usage.cache_creation_tokens
89
+ ?? usage.cache_write_input_tokens
90
+ ?? usage.cache_creation_input_tokens
91
+ ?? cacheWriteInputTokens);
92
+ if (inputTokens === 0 && outputTokens === 0 && cacheReadTokens === undefined && cacheWriteTokens === undefined)
93
+ return null;
94
+ const totalTokens = optionalNumberValue(usage.totalTokens ?? usage.total_tokens ?? usage.totalTokenCount);
95
+ const hasCacheBreakdown = explicitUncachedInputTokens !== undefined || cacheReadTokens !== undefined || cacheWriteTokens !== undefined;
96
+ const cachedInputTokens = (cacheReadTokens ?? 0) + (cacheWriteTokens ?? 0);
97
+ const inputExcludesCache = explicitUncachedInputTokens !== undefined || cacheReadInputTokens !== undefined || cacheWriteInputTokens !== undefined;
98
+ const fullInputTokens = inputTokens + (inputExcludesCache ? cachedInputTokens : 0);
99
+ return {
100
+ type: 'usage',
101
+ inputTokens,
102
+ outputTokens,
103
+ ...(cacheReadTokens === undefined ? {} : { cacheReadTokens }),
104
+ ...(cacheWriteTokens === undefined ? {} : { cacheWriteTokens }),
105
+ ...(hasCacheBreakdown ? { uncachedInputTokens: inputExcludesCache ? inputTokens : Math.max(0, inputTokens - cachedInputTokens) } : {}),
106
+ ...(totalTokens === undefined && !hasCacheBreakdown ? {} : { totalTokens: totalTokens ?? fullInputTokens + outputTokens }),
107
+ ...(cacheReadTokens === undefined || fullInputTokens <= 0
108
+ ? {}
109
+ : { cacheHitRate: Number((cacheReadTokens / fullInputTokens * 100).toFixed(4)) }),
110
+ };
111
+ }
112
+ export function isRecord(value) {
113
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
114
+ }
115
+ function numberValue(value) { return typeof value === 'number' && Number.isFinite(value) ? value : 0; }
116
+ function optionalNumberValue(value) {
117
+ return typeof value === 'number' && Number.isFinite(value) ? Math.max(0, value) : undefined;
118
+ }
119
+ //# sourceMappingURL=rpc-driver-utils.js.map
@@ -0,0 +1,20 @@
1
+ import type { Dirent } from 'node:fs';
2
+ import type { CodingNsCliSessionProbeInput, CodingNsCliSessionProbeResult } from './driver.js';
3
+ export interface StoredSessionProbeOptions {
4
+ readonly roots: readonly string[];
5
+ readonly matches: (path: string, entry: Dirent, providerSessionId: string) => boolean;
6
+ readonly validate: (path: string, providerSessionId: string) => Promise<boolean>;
7
+ readonly maxDepth?: number;
8
+ }
9
+ /**
10
+ * 在 Provider 的权威存储中只读查找会话。只有精确引用不存在,或成功扫描过
11
+ * 至少一个权威根目录仍未找到时,才返回 missing。
12
+ */
13
+ export declare function probeStoredSession(input: CodingNsCliSessionProbeInput, options: StoredSessionProbeOptions): Promise<CodingNsCliSessionProbeResult>;
14
+ /** 读取 JSONL 第一条非空记录,限制读取量,避免为一次探测加载完整历史。 */
15
+ export declare function readFirstJsonRecord(path: string): Promise<Record<string, unknown> | null>;
16
+ /** 将文件或目录引用规整到会话目录,供目录型 Provider 复用。 */
17
+ export declare function resolveSessionDirectory(path: string): Promise<string>;
18
+ /** 仅验证目标是普通文件,不读取历史正文。 */
19
+ export declare function isRegularFile(path: string): Promise<boolean>;
20
+ //# sourceMappingURL=session-probe.d.ts.map
@@ -0,0 +1,139 @@
1
+ import { open, readdir, stat } from 'node:fs/promises';
2
+ import { dirname, join } from 'node:path';
3
+ /**
4
+ * 在 Provider 的权威存储中只读查找会话。只有精确引用不存在,或成功扫描过
5
+ * 至少一个权威根目录仍未找到时,才返回 missing。
6
+ */
7
+ export async function probeStoredSession(input, options) {
8
+ const providerSessionId = input.providerSessionId?.trim();
9
+ if (!providerSessionId)
10
+ return { state: 'unknown', reason: '缺少 Provider 会话标识' };
11
+ throwIfAborted(input.signal);
12
+ const rawStoreRef = input.rawStoreRef?.trim();
13
+ let exactHintFailure;
14
+ if (rawStoreRef) {
15
+ const exactResult = await validateCandidate(rawStoreRef, providerSessionId, options.validate, true, input.signal);
16
+ if (exactResult.state === 'available' || exactResult.state === 'unreachable' || exactResult.state === 'unknown')
17
+ return exactResult;
18
+ // rawStoreRef 只是 hint。Provider 可能移动文件,也可能复用旧路径;ENOENT、
19
+ // 内容不匹配或损坏都必须继续扫描权威 roots,找到后再更新引用。
20
+ exactHintFailure = exactResult;
21
+ }
22
+ let accessibleRoots = 0;
23
+ const candidates = [];
24
+ for (const root of options.roots) {
25
+ try {
26
+ throwIfAborted(input.signal);
27
+ const entries = await walk(root, options.maxDepth ?? 6, input.signal);
28
+ accessibleRoots += 1;
29
+ for (const entry of entries)
30
+ if (options.matches(entry.path, entry.entry, providerSessionId))
31
+ candidates.push(entry.path);
32
+ }
33
+ catch (error) {
34
+ if (errorCode(error) === 'ENOENT')
35
+ continue;
36
+ if (isAccessError(error))
37
+ return { state: 'unreachable', reason: '无法读取 Provider 会话存储' };
38
+ return { state: 'unknown', reason: 'Provider 会话存储探测失败' };
39
+ }
40
+ }
41
+ if (candidates.length === 0) {
42
+ if (exactHintFailure?.state === 'corrupt')
43
+ return exactHintFailure;
44
+ return accessibleRoots > 0
45
+ ? { state: 'missing', reason: 'Provider 会话存储中不存在该会话' }
46
+ : exactHintFailure ?? { state: 'unknown', reason: 'Provider 会话存储不存在或尚未初始化' };
47
+ }
48
+ let sawCorrupt = false;
49
+ for (const candidate of candidates) {
50
+ const result = await validateCandidate(candidate, providerSessionId, options.validate, false, input.signal);
51
+ if (result.state === 'available')
52
+ return result;
53
+ if (result.state === 'unreachable' || result.state === 'unknown')
54
+ return result;
55
+ if (result.state === 'corrupt')
56
+ sawCorrupt = true;
57
+ }
58
+ return sawCorrupt
59
+ ? { state: 'corrupt', reason: 'Provider 会话记录无法验证' }
60
+ : { state: 'missing', reason: 'Provider 会话记录已被删除' };
61
+ }
62
+ /** 读取 JSONL 第一条非空记录,限制读取量,避免为一次探测加载完整历史。 */
63
+ export async function readFirstJsonRecord(path) {
64
+ const handle = await open(path, 'r');
65
+ try {
66
+ const buffer = new Uint8Array(64 * 1024);
67
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
68
+ const line = new TextDecoder().decode(buffer.subarray(0, bytesRead)).split(/\r?\n/u).find((value) => value.trim() !== '');
69
+ if (line === undefined)
70
+ return null;
71
+ const value = JSON.parse(line);
72
+ return isRecord(value) ? value : null;
73
+ }
74
+ finally {
75
+ await handle.close();
76
+ }
77
+ }
78
+ /** 将文件或目录引用规整到会话目录,供目录型 Provider 复用。 */
79
+ export async function resolveSessionDirectory(path) {
80
+ return (await stat(path)).isDirectory() ? path : dirname(path);
81
+ }
82
+ /** 仅验证目标是普通文件,不读取历史正文。 */
83
+ export async function isRegularFile(path) {
84
+ return (await stat(path)).isFile();
85
+ }
86
+ async function validateCandidate(path, providerSessionId, validate, exact, signal) {
87
+ try {
88
+ throwIfAborted(signal);
89
+ const valid = await validate(path, providerSessionId);
90
+ throwIfAborted(signal);
91
+ return valid
92
+ ? { state: 'available', reason: 'Provider 原始会话可用', rawStoreRef: path }
93
+ : { state: 'corrupt', reason: 'Provider 会话记录与绑定标识不一致', rawStoreRef: path };
94
+ }
95
+ catch (error) {
96
+ if (errorCode(error) === 'ENOENT' || errorCode(error) === 'ENOTDIR') {
97
+ return { state: 'missing', reason: exact ? '绑定的 Provider 会话记录已被删除' : 'Provider 会话记录已被删除' };
98
+ }
99
+ if (error instanceof SyntaxError)
100
+ return { state: 'corrupt', reason: 'Provider 会话记录不是有效 JSON', rawStoreRef: path };
101
+ if (isAccessError(error))
102
+ return { state: 'unreachable', reason: '没有权限读取 Provider 会话记录', rawStoreRef: path };
103
+ return { state: 'unknown', reason: 'Provider 会话记录验证失败', rawStoreRef: path };
104
+ }
105
+ }
106
+ async function walk(root, maxDepth, signal) {
107
+ const found = [];
108
+ const queue = [{ path: root, depth: 0 }];
109
+ while (queue.length > 0) {
110
+ throwIfAborted(signal);
111
+ const current = queue.shift();
112
+ const entries = await readdir(current.path, { withFileTypes: true });
113
+ throwIfAborted(signal);
114
+ for (const entry of entries) {
115
+ const path = join(current.path, entry.name);
116
+ found.push({ path, entry });
117
+ if (entry.isDirectory() && current.depth < maxDepth)
118
+ queue.push({ path, depth: current.depth + 1 });
119
+ }
120
+ }
121
+ return found;
122
+ }
123
+ function throwIfAborted(signal) {
124
+ if (signal?.aborted !== true)
125
+ return;
126
+ const error = new Error('Provider 会话探测已取消');
127
+ error.name = 'AbortError';
128
+ throw error;
129
+ }
130
+ function errorCode(error) {
131
+ return typeof error === 'object' && error !== null && 'code' in error && typeof error.code === 'string' ? error.code : undefined;
132
+ }
133
+ function isAccessError(error) {
134
+ return errorCode(error) === 'EACCES' || errorCode(error) === 'EPERM';
135
+ }
136
+ function isRecord(value) {
137
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
138
+ }
139
+ //# sourceMappingURL=session-probe.js.map
@@ -0,0 +1,68 @@
1
+ import type { SettingsScope } from '@deepseek-ai/dsh-settings';
2
+ import type { CodingNsCliAdapterId, CodingNsCliSessionConfig, CodingNsCliProviderSessionState, CodingNsCliSessionRecord, CodingNsCliSessionStatus, CodingNsSessionAdapterBinding } from '../../shared/contracts/cli-adapter.js';
3
+ import type { CodingNsSettings } from '../../shared/contracts/config.js';
4
+ /**
5
+ * 可替换的会话持久化后端。
6
+ *
7
+ * 默认实现写入 DSH 的 Codingns4DSH 设置文档;当 DSH 暴露原生 SessionStore
8
+ * 扩展点后,只需替换这个后端,不需要改 Registry 或驱动。
9
+ */
10
+ export interface CodingNsCliSessionPersistence {
11
+ write(records: readonly CodingNsCliSessionRecord[]): Promise<void>;
12
+ }
13
+ export interface CodingNsCliSessionStoreOptions {
14
+ readonly settings?: SettingsScope<CodingNsSettings>;
15
+ readonly persistence?: CodingNsCliSessionPersistence;
16
+ }
17
+ export interface CodingNsCliSessionPatch {
18
+ readonly adapterId?: CodingNsCliAdapterId;
19
+ readonly modelId?: string;
20
+ readonly effortId?: string;
21
+ readonly providerSessionId?: string;
22
+ readonly rawStoreRef?: string;
23
+ readonly title?: string;
24
+ readonly cwd?: string;
25
+ readonly status?: CodingNsCliSessionStatus;
26
+ readonly providerState?: CodingNsCliProviderSessionState;
27
+ readonly providerCheckedAt?: string;
28
+ readonly providerStateReason?: string;
29
+ readonly lastError?: string;
30
+ }
31
+ export interface CodingNsCliProviderStatePatch {
32
+ readonly state: CodingNsCliProviderSessionState;
33
+ readonly checkedAt: string;
34
+ readonly reason?: string;
35
+ readonly rawStoreRef?: string;
36
+ }
37
+ /**
38
+ * Host-only 的外部 Agent 会话索引。
39
+ *
40
+ * 进程句柄、refresh token、原始消息都不进入这里;它只记录下次恢复运行时
41
+ * 所需的 providerSessionId 和给列表页展示的摘要。写入按顺序排队,避免多轮
42
+ * 流式事件同时更新设置时发生后写覆盖先写。
43
+ */
44
+ export declare class CodingNsCliSessionStore {
45
+ private readonly records;
46
+ private readonly settings;
47
+ private readonly persistence;
48
+ private writeTail;
49
+ constructor(options?: CodingNsCliSessionStoreOptions);
50
+ /** 将设置变更重新载入内存;非法或不完整记录会被忽略。 */
51
+ sync(records: readonly CodingNsCliSessionRecord[] | undefined): void;
52
+ get(sessionId: string): CodingNsCliSessionRecord | undefined;
53
+ list(options?: {
54
+ readonly includeArchived?: boolean;
55
+ readonly adapterId?: string;
56
+ }): CodingNsCliSessionRecord[];
57
+ /** 浏览器会话行只需要这两个字段,Host-only 恢复信息不得跨过 RPC 边界。 */
58
+ adapterBindings(): CodingNsSessionAdapterBinding[];
59
+ /** 创建或更新记录;返回值是内存中的规范化记录,持久化在后台串行完成。 */
60
+ upsert(sessionId: string, patch: CodingNsCliSessionPatch & CodingNsCliSessionConfig): CodingNsCliSessionRecord;
61
+ archive(sessionId: string): CodingNsCliSessionRecord | undefined;
62
+ /** 更新 Provider 存在性,不改变会话活动时间,避免后台检查扰乱侧栏排序。 */
63
+ updateProviderState(sessionId: string, patch: CodingNsCliProviderStatePatch): CodingNsCliSessionRecord | undefined;
64
+ flush(): Promise<void>;
65
+ private hydrateRecord;
66
+ private schedulePersist;
67
+ }
68
+ //# sourceMappingURL=session-store.d.ts.map
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Host-only 的外部 Agent 会话索引。
3
+ *
4
+ * 进程句柄、refresh token、原始消息都不进入这里;它只记录下次恢复运行时
5
+ * 所需的 providerSessionId 和给列表页展示的摘要。写入按顺序排队,避免多轮
6
+ * 流式事件同时更新设置时发生后写覆盖先写。
7
+ */
8
+ export class CodingNsCliSessionStore {
9
+ records = new Map();
10
+ settings;
11
+ persistence;
12
+ writeTail = Promise.resolve();
13
+ constructor(options = {}) {
14
+ this.settings = options.settings;
15
+ this.persistence = options.persistence;
16
+ for (const record of options.settings?.get().cliSessions ?? [])
17
+ this.hydrateRecord(record, true);
18
+ }
19
+ /** 将设置变更重新载入内存;非法或不完整记录会被忽略。 */
20
+ sync(records) {
21
+ if (records === undefined)
22
+ return;
23
+ this.records.clear();
24
+ for (const record of records)
25
+ this.hydrateRecord(record, false);
26
+ }
27
+ get(sessionId) {
28
+ return this.records.get(sessionId);
29
+ }
30
+ list(options = {}) {
31
+ return [...this.records.values()]
32
+ .filter((record) => options.includeArchived === true || record.status !== 'archived')
33
+ .filter((record) => options.adapterId === undefined || record.adapterId === options.adapterId)
34
+ .sort((left, right) => right.updatedAt.localeCompare(left.updatedAt))
35
+ .map((record) => ({ ...record }));
36
+ }
37
+ /** 浏览器会话行只需要这两个字段,Host-only 恢复信息不得跨过 RPC 边界。 */
38
+ adapterBindings() {
39
+ return this.list().map((record) => ({
40
+ sessionId: record.dshSessionId,
41
+ adapterId: record.adapterId,
42
+ }));
43
+ }
44
+ /** 创建或更新记录;返回值是内存中的规范化记录,持久化在后台串行完成。 */
45
+ upsert(sessionId, patch) {
46
+ const now = new Date().toISOString();
47
+ const previous = this.records.get(sessionId);
48
+ const adapterId = patch.adapterId ?? previous?.adapterId ?? 'dsh';
49
+ const sameAdapter = previous?.adapterId === adapterId;
50
+ const base = sameAdapter ? previous : undefined;
51
+ const providerSessionId = patch.providerSessionId?.trim();
52
+ // providerSessionId 是 Provider 绑定的身份。即使适配器没变,身份一旦改变,
53
+ // 旧路径和旧探测结果也不能继承,否则会拿旧会话的状态判断新会话。
54
+ const providerIdentityChanged = providerSessionId !== undefined
55
+ && providerSessionId !== base?.providerSessionId;
56
+ const providerBase = providerIdentityChanged ? undefined : base;
57
+ const record = {
58
+ dshSessionId: sessionId,
59
+ adapterId,
60
+ ...(patch.modelId?.trim() ? { modelId: patch.modelId.trim() } : base?.modelId ? { modelId: base.modelId } : {}),
61
+ ...(patch.effortId?.trim() ? { effortId: patch.effortId.trim() } : base?.effortId ? { effortId: base.effortId } : {}),
62
+ ...(providerSessionId ? { providerSessionId } : base?.providerSessionId ? { providerSessionId: base.providerSessionId } : {}),
63
+ ...(patch.rawStoreRef?.trim() ? { rawStoreRef: patch.rawStoreRef.trim() } : providerBase?.rawStoreRef ? { rawStoreRef: providerBase.rawStoreRef } : {}),
64
+ ...(patch.title?.trim() ? { title: patch.title.trim() } : base?.title ? { title: base.title } : {}),
65
+ ...(patch.cwd?.trim() ? { cwd: patch.cwd.trim() } : base?.cwd ? { cwd: base.cwd } : {}),
66
+ ...(patch.lastError?.trim() ? { lastError: patch.lastError.trim() } : {}),
67
+ // archived 是侧栏 tombstone。延迟到达的 turn/end 或驱动 finish 不能把它
68
+ // 重新写回 idle;恢复必须走未来显式的 unarchive 链路。
69
+ status: base?.status === 'archived' ? 'archived' : patch.status ?? base?.status ?? 'idle',
70
+ ...(patch.providerState !== undefined
71
+ ? { providerState: patch.providerState }
72
+ : providerBase?.providerState !== undefined
73
+ ? { providerState: providerBase.providerState }
74
+ : {}),
75
+ ...(patch.providerCheckedAt?.trim()
76
+ ? { providerCheckedAt: patch.providerCheckedAt.trim() }
77
+ : patch.providerState === undefined && providerBase?.providerCheckedAt
78
+ ? { providerCheckedAt: providerBase.providerCheckedAt }
79
+ : {}),
80
+ ...(patch.providerStateReason?.trim()
81
+ ? { providerStateReason: patch.providerStateReason.trim() }
82
+ : patch.providerState === undefined && providerBase?.providerStateReason
83
+ ? { providerStateReason: providerBase.providerStateReason }
84
+ : {}),
85
+ createdAt: base?.createdAt ?? now,
86
+ updatedAt: now,
87
+ };
88
+ this.records.set(sessionId, record);
89
+ this.schedulePersist();
90
+ return { ...record };
91
+ }
92
+ archive(sessionId) {
93
+ const previous = this.records.get(sessionId);
94
+ if (previous === undefined)
95
+ return undefined;
96
+ const record = { ...previous, status: 'archived', updatedAt: new Date().toISOString() };
97
+ this.records.set(sessionId, record);
98
+ this.schedulePersist();
99
+ return { ...record };
100
+ }
101
+ /** 更新 Provider 存在性,不改变会话活动时间,避免后台检查扰乱侧栏排序。 */
102
+ updateProviderState(sessionId, patch) {
103
+ const previous = this.records.get(sessionId);
104
+ if (previous === undefined)
105
+ return undefined;
106
+ const { providerStateReason: _previousReason, ...base } = previous;
107
+ const record = {
108
+ ...base,
109
+ providerState: patch.state,
110
+ providerCheckedAt: patch.checkedAt,
111
+ ...(patch.reason?.trim() ? { providerStateReason: patch.reason.trim() } : {}),
112
+ ...(patch.rawStoreRef?.trim() ? { rawStoreRef: patch.rawStoreRef.trim() } : {}),
113
+ };
114
+ this.records.set(sessionId, record);
115
+ this.schedulePersist();
116
+ return { ...record };
117
+ }
118
+ async flush() {
119
+ await this.writeTail;
120
+ }
121
+ hydrateRecord(value, resetActive) {
122
+ if (!isRecord(value))
123
+ return;
124
+ if (typeof value.dshSessionId !== 'string' || value.dshSessionId.trim() === '')
125
+ return;
126
+ if (typeof value.adapterId !== 'string' || value.adapterId.trim() === '')
127
+ return;
128
+ if (!isStatus(value.status) || typeof value.createdAt !== 'string' || typeof value.updatedAt !== 'string')
129
+ return;
130
+ this.records.set(value.dshSessionId, {
131
+ dshSessionId: value.dshSessionId,
132
+ adapterId: value.adapterId,
133
+ ...(stringValue(value.modelId) ? { modelId: stringValue(value.modelId) } : {}),
134
+ ...(stringValue(value.effortId) ? { effortId: stringValue(value.effortId) } : {}),
135
+ ...(stringValue(value.providerSessionId) ? { providerSessionId: stringValue(value.providerSessionId) } : {}),
136
+ ...(stringValue(value.rawStoreRef) ? { rawStoreRef: stringValue(value.rawStoreRef) } : {}),
137
+ ...(stringValue(value.title) ? { title: stringValue(value.title) } : {}),
138
+ ...(stringValue(value.cwd) ? { cwd: stringValue(value.cwd) } : {}),
139
+ ...(stringValue(value.lastError) ? { lastError: stringValue(value.lastError) } : {}),
140
+ // active 只描述当前 Host 进程中的执行。进程重启后没有仍在运行的 Turn,
141
+ // 必须回到 idle,否则列表刷新会永久跳过该记录的存活探测。
142
+ status: resetActive && value.status === 'active' ? 'idle' : value.status,
143
+ ...(isProviderState(value.providerState) ? { providerState: value.providerState } : {}),
144
+ ...(stringValue(value.providerCheckedAt) ? { providerCheckedAt: stringValue(value.providerCheckedAt) } : {}),
145
+ ...(stringValue(value.providerStateReason) ? { providerStateReason: stringValue(value.providerStateReason) } : {}),
146
+ createdAt: value.createdAt,
147
+ updatedAt: value.updatedAt,
148
+ });
149
+ }
150
+ schedulePersist() {
151
+ const snapshot = this.list({ includeArchived: true });
152
+ this.writeTail = this.writeTail
153
+ .catch(() => undefined)
154
+ .then(async () => {
155
+ if (this.persistence !== undefined)
156
+ await this.persistence.write(snapshot);
157
+ if (this.settings !== undefined)
158
+ await this.settings.update({ cliSessions: snapshot });
159
+ });
160
+ }
161
+ }
162
+ function isStatus(value) {
163
+ return value === 'active' || value === 'idle' || value === 'error' || value === 'archived';
164
+ }
165
+ function isProviderState(value) {
166
+ return value === 'unchecked'
167
+ || value === 'available'
168
+ || value === 'missing'
169
+ || value === 'corrupt'
170
+ || value === 'unreachable'
171
+ || value === 'unknown'
172
+ || value === 'ephemeral';
173
+ }
174
+ function stringValue(value) {
175
+ return typeof value === 'string' && value.trim() !== '' ? value : undefined;
176
+ }
177
+ function isRecord(value) {
178
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
179
+ }
180
+ //# sourceMappingURL=session-store.js.map
@@ -0,0 +1,45 @@
1
+ import { spawn, spawnSync } from 'node:child_process';
2
+ import type { CodingNsCliAdapterDescriptor, CodingNsCliModelCatalog, CodingNsAgentEvent, CodingNsCliTurnInput } from '../../shared/contracts/cli-adapter.js';
3
+ import type { CodingNsCliDriver } from './driver.js';
4
+ export interface StandardStreamDriverOptions {
5
+ readonly binaries?: readonly string[];
6
+ /** 仅供会话存在性探测使用;测试和自定义安装可覆盖默认存储根目录。 */
7
+ readonly sessionRoots?: readonly string[];
8
+ readonly spawnSync?: typeof spawnSync;
9
+ readonly spawn?: typeof spawn;
10
+ readonly versionArgs?: readonly string[];
11
+ readonly modelArgs?: readonly string[];
12
+ }
13
+ /**
14
+ * 把采用 JSONL/stream-json 的 CLI 统一成 Codingns4DSH 的最小驱动契约。
15
+ * 子类只需提供命令参数和事件映射,进程终止、stderr 消费及清理由这里统一处理。
16
+ */
17
+ export declare abstract class StandardStreamDriver implements CodingNsCliDriver {
18
+ readonly descriptor: Omit<CodingNsCliAdapterDescriptor, 'installed' | 'enabled' | 'version' | 'command'>;
19
+ protected readonly binaries: readonly string[];
20
+ protected readonly runSpawnSync: typeof spawnSync;
21
+ protected readonly runSpawn: typeof spawn;
22
+ private readonly versionArgs;
23
+ private readonly modelArgs;
24
+ private cachedBinary;
25
+ private readonly processes;
26
+ protected constructor(descriptor: Omit<CodingNsCliAdapterDescriptor, 'installed' | 'enabled' | 'version' | 'command'>, defaults: {
27
+ binaries: readonly string[];
28
+ versionArgs?: readonly string[];
29
+ modelArgs?: readonly string[];
30
+ }, options?: StandardStreamDriverOptions);
31
+ detect(): Promise<{
32
+ installed: boolean;
33
+ version: string | null;
34
+ command: string | null;
35
+ }>;
36
+ listModels(): Promise<CodingNsCliModelCatalog>;
37
+ executeTurn(input: CodingNsCliTurnInput): AsyncIterable<CodingNsAgentEvent>;
38
+ dispose(): void;
39
+ protected parseVersion(output: string): string | null;
40
+ protected abstract buildArgs(input: CodingNsCliTurnInput): readonly string[];
41
+ protected parseEvent(value: Record<string, unknown>, input: CodingNsCliTurnInput): readonly CodingNsAgentEvent[];
42
+ protected parseModels(output: string): CodingNsCliModelCatalog;
43
+ }
44
+ export declare function emptyCatalog(): CodingNsCliModelCatalog;
45
+ //# sourceMappingURL=standard-stream-driver.d.ts.map