@jingyi0605/codingns4dsh 0.2.0-rc.2 → 0.2.0-rc.3

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 (353) hide show
  1. package/README.en.md +4 -4
  2. package/README.md +15 -6
  3. package/assets/provider-icons/antigravity.svg +39 -0
  4. package/assets/provider-icons/codebuddy.svg +37 -0
  5. package/assets/provider-icons/cursor-cli.svg +1 -0
  6. package/assets/provider-icons/kiro-cli.svg +11 -0
  7. package/assets/provider-icons/qoder-cn.svg +5 -0
  8. package/assets/provider-icons/qoder.svg +5 -0
  9. package/assets/provider-icons/workbuddy.svg +29 -0
  10. package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.d.ts.map +1 -1
  11. package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.js +78 -1
  12. package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.js.map +1 -1
  13. package/data/build/dist/client/bundle.js +3864 -507
  14. package/data/build/dist/client/bundle.js.map +1 -1
  15. package/data/build/dist/client/cli-catalog.d.ts +1 -1
  16. package/data/build/dist/client/cli-catalog.d.ts.map +1 -1
  17. package/data/build/dist/client/cli-catalog.js +11 -5
  18. package/data/build/dist/client/cli-catalog.js.map +1 -1
  19. package/data/build/dist/client/cli-slots.d.ts.map +1 -1
  20. package/data/build/dist/client/cli-slots.js +111 -13
  21. package/data/build/dist/client/cli-slots.js.map +1 -1
  22. package/data/build/dist/client/debug/ui.d.ts.map +1 -1
  23. package/data/build/dist/client/debug/ui.js +2 -1
  24. package/data/build/dist/client/debug/ui.js.map +1 -1
  25. package/data/build/dist/client/delegate-command.d.ts +1 -0
  26. package/data/build/dist/client/delegate-command.d.ts.map +1 -1
  27. package/data/build/dist/client/delegate-command.js +486 -27
  28. package/data/build/dist/client/delegate-command.js.map +1 -1
  29. package/data/build/dist/client/delegate-plan.d.ts +13 -4
  30. package/data/build/dist/client/delegate-plan.d.ts.map +1 -1
  31. package/data/build/dist/client/delegate-plan.js +10 -6
  32. package/data/build/dist/client/delegate-plan.js.map +1 -1
  33. package/data/build/dist/client/delegate-ui-dom.d.ts +46 -0
  34. package/data/build/dist/client/delegate-ui-dom.d.ts.map +1 -1
  35. package/data/build/dist/client/delegate-ui-dom.js +291 -7
  36. package/data/build/dist/client/delegate-ui-dom.js.map +1 -1
  37. package/data/build/dist/client/features/cli-adapters.d.ts.map +1 -1
  38. package/data/build/dist/client/features/cli-adapters.js +117 -8
  39. package/data/build/dist/client/features/cli-adapters.js.map +1 -1
  40. package/data/build/dist/client/features/mobile-access-panel.d.ts.map +1 -1
  41. package/data/build/dist/client/features/mobile-access-panel.js +8 -7
  42. package/data/build/dist/client/features/mobile-access-panel.js.map +1 -1
  43. package/data/build/dist/client/features/peer-host.d.ts +6 -4
  44. package/data/build/dist/client/features/peer-host.d.ts.map +1 -1
  45. package/data/build/dist/client/features/peer-host.js +346 -18
  46. package/data/build/dist/client/features/peer-host.js.map +1 -1
  47. package/data/build/dist/client/git-history-graph.d.ts +2 -2
  48. package/data/build/dist/client/git-history-graph.d.ts.map +1 -1
  49. package/data/build/dist/client/git-history-graph.js +2 -2
  50. package/data/build/dist/client/git-history-graph.js.map +1 -1
  51. package/data/build/dist/client/git-management.d.ts.map +1 -1
  52. package/data/build/dist/client/git-management.js +21 -1
  53. package/data/build/dist/client/git-management.js.map +1 -1
  54. package/data/build/dist/client/locale.d.ts.map +1 -1
  55. package/data/build/dist/client/locale.js +60 -6
  56. package/data/build/dist/client/locale.js.map +1 -1
  57. package/data/build/dist/client/locales/terminalAuth.d.ts.map +1 -1
  58. package/data/build/dist/client/locales/terminalAuth.js +4 -0
  59. package/data/build/dist/client/locales/terminalAuth.js.map +1 -1
  60. package/data/build/dist/client/locales/usage.d.ts.map +1 -1
  61. package/data/build/dist/client/locales/usage.js +20 -0
  62. package/data/build/dist/client/locales/usage.js.map +1 -1
  63. package/data/build/dist/client/mobile-session-interaction.d.ts.map +1 -1
  64. package/data/build/dist/client/mobile-session-interaction.js +24 -7
  65. package/data/build/dist/client/mobile-session-interaction.js.map +1 -1
  66. package/data/build/dist/client/mobile-sidebar-gestures.d.ts +55 -7
  67. package/data/build/dist/client/mobile-sidebar-gestures.d.ts.map +1 -1
  68. package/data/build/dist/client/mobile-sidebar-gestures.js +339 -40
  69. package/data/build/dist/client/mobile-sidebar-gestures.js.map +1 -1
  70. package/data/build/dist/client/model-catalog-cache.d.ts +5 -0
  71. package/data/build/dist/client/model-catalog-cache.d.ts.map +1 -0
  72. package/data/build/dist/client/model-catalog-cache.js +58 -0
  73. package/data/build/dist/client/model-catalog-cache.js.map +1 -0
  74. package/data/build/dist/client/peer-host-aggregate-refresh.d.ts +7 -0
  75. package/data/build/dist/client/peer-host-aggregate-refresh.d.ts.map +1 -1
  76. package/data/build/dist/client/peer-host-aggregate-refresh.js +13 -1
  77. package/data/build/dist/client/peer-host-aggregate-refresh.js.map +1 -1
  78. package/data/build/dist/client/peer-host-native-projection.d.ts +16 -1
  79. package/data/build/dist/client/peer-host-native-projection.d.ts.map +1 -1
  80. package/data/build/dist/client/peer-host-native-projection.js +49 -8
  81. package/data/build/dist/client/peer-host-native-projection.js.map +1 -1
  82. package/data/build/dist/client/peer-host-native-store-projection.d.ts +6 -2
  83. package/data/build/dist/client/peer-host-native-store-projection.d.ts.map +1 -1
  84. package/data/build/dist/client/peer-host-native-store-projection.js +308 -10
  85. package/data/build/dist/client/peer-host-native-store-projection.js.map +1 -1
  86. package/data/build/dist/client/provider-icon-assets.js +14 -0
  87. package/data/build/dist/client/provider-icon-assets.js.map +1 -1
  88. package/data/build/dist/client/provider-icons.d.ts.map +1 -1
  89. package/data/build/dist/client/provider-icons.js +15 -3
  90. package/data/build/dist/client/provider-icons.js.map +1 -1
  91. package/data/build/dist/client/remote-web-context.js +10 -6
  92. package/data/build/dist/client/remote-web-context.js.map +1 -1
  93. package/data/build/dist/client/service-tier.d.ts +54 -0
  94. package/data/build/dist/client/service-tier.d.ts.map +1 -0
  95. package/data/build/dist/client/service-tier.js +78 -0
  96. package/data/build/dist/client/service-tier.js.map +1 -0
  97. package/data/build/dist/client/settings-promo-styles.d.ts +28 -0
  98. package/data/build/dist/client/settings-promo-styles.d.ts.map +1 -0
  99. package/data/build/dist/client/settings-promo-styles.js +58 -0
  100. package/data/build/dist/client/settings-promo-styles.js.map +1 -0
  101. package/data/build/dist/client/settings-promo.d.ts +14 -0
  102. package/data/build/dist/client/settings-promo.d.ts.map +1 -0
  103. package/data/build/dist/client/settings-promo.js +68 -0
  104. package/data/build/dist/client/settings-promo.js.map +1 -0
  105. package/data/build/dist/client/settings-section.d.ts +2 -1
  106. package/data/build/dist/client/settings-section.d.ts.map +1 -1
  107. package/data/build/dist/client/settings-section.js +7 -4
  108. package/data/build/dist/client/settings-section.js.map +1 -1
  109. package/data/build/dist/client/subscription-slot.d.ts.map +1 -1
  110. package/data/build/dist/client/subscription-slot.js +181 -16
  111. package/data/build/dist/client/subscription-slot.js.map +1 -1
  112. package/data/build/dist/client/terminal/model.d.ts +82 -3
  113. package/data/build/dist/client/terminal/model.d.ts.map +1 -1
  114. package/data/build/dist/client/terminal/model.js +368 -29
  115. package/data/build/dist/client/terminal/model.js.map +1 -1
  116. package/data/build/dist/client/terminal/recovery.d.ts +16 -1
  117. package/data/build/dist/client/terminal/recovery.d.ts.map +1 -1
  118. package/data/build/dist/client/terminal/recovery.js +101 -39
  119. package/data/build/dist/client/terminal/recovery.js.map +1 -1
  120. package/data/build/dist/client/terminal/styles.d.ts +10 -0
  121. package/data/build/dist/client/terminal/styles.d.ts.map +1 -1
  122. package/data/build/dist/client/terminal/styles.js +27 -3
  123. package/data/build/dist/client/terminal/styles.js.map +1 -1
  124. package/data/build/dist/client/terminal/ui.d.ts +3 -2
  125. package/data/build/dist/client/terminal/ui.d.ts.map +1 -1
  126. package/data/build/dist/client/terminal/ui.js +215 -104
  127. package/data/build/dist/client/terminal/ui.js.map +1 -1
  128. package/data/build/dist/client/terminal/xterm-view.d.ts +5 -1
  129. package/data/build/dist/client/terminal/xterm-view.d.ts.map +1 -1
  130. package/data/build/dist/client/terminal/xterm-view.js +378 -20
  131. package/data/build/dist/client/terminal/xterm-view.js.map +1 -1
  132. package/data/build/dist/host/cli-adapters/acp-cli-driver.d.ts +58 -0
  133. package/data/build/dist/host/cli-adapters/acp-cli-driver.d.ts.map +1 -0
  134. package/data/build/dist/host/cli-adapters/acp-cli-driver.js +271 -0
  135. package/data/build/dist/host/cli-adapters/acp-cli-driver.js.map +1 -0
  136. package/data/build/dist/host/cli-adapters/antigravity-driver.d.ts +30 -0
  137. package/data/build/dist/host/cli-adapters/antigravity-driver.d.ts.map +1 -0
  138. package/data/build/dist/host/cli-adapters/antigravity-driver.js +210 -0
  139. package/data/build/dist/host/cli-adapters/antigravity-driver.js.map +1 -0
  140. package/data/build/dist/host/cli-adapters/claude-driver.js +1 -1
  141. package/data/build/dist/host/cli-adapters/claude-driver.js.map +1 -1
  142. package/data/build/dist/host/cli-adapters/codebuddy-driver.d.ts +139 -0
  143. package/data/build/dist/host/cli-adapters/codebuddy-driver.d.ts.map +1 -0
  144. package/data/build/dist/host/cli-adapters/codebuddy-driver.js +1721 -0
  145. package/data/build/dist/host/cli-adapters/codebuddy-driver.js.map +1 -0
  146. package/data/build/dist/host/cli-adapters/codebuddy-subscription.d.ts +53 -0
  147. package/data/build/dist/host/cli-adapters/codebuddy-subscription.d.ts.map +1 -0
  148. package/data/build/dist/host/cli-adapters/codebuddy-subscription.js +778 -0
  149. package/data/build/dist/host/cli-adapters/codebuddy-subscription.js.map +1 -0
  150. package/data/build/dist/host/cli-adapters/codex-driver.d.ts +12 -0
  151. package/data/build/dist/host/cli-adapters/codex-driver.d.ts.map +1 -1
  152. package/data/build/dist/host/cli-adapters/codex-driver.js +153 -6
  153. package/data/build/dist/host/cli-adapters/codex-driver.js.map +1 -1
  154. package/data/build/dist/host/cli-adapters/command-code-driver.d.ts +43 -3
  155. package/data/build/dist/host/cli-adapters/command-code-driver.d.ts.map +1 -1
  156. package/data/build/dist/host/cli-adapters/command-code-driver.js +637 -72
  157. package/data/build/dist/host/cli-adapters/command-code-driver.js.map +1 -1
  158. package/data/build/dist/host/cli-adapters/command-code-history.d.ts +147 -0
  159. package/data/build/dist/host/cli-adapters/command-code-history.d.ts.map +1 -0
  160. package/data/build/dist/host/cli-adapters/command-code-history.js +659 -0
  161. package/data/build/dist/host/cli-adapters/command-code-history.js.map +1 -0
  162. package/data/build/dist/host/cli-adapters/cursor-driver.d.ts +12 -0
  163. package/data/build/dist/host/cli-adapters/cursor-driver.d.ts.map +1 -0
  164. package/data/build/dist/host/cli-adapters/cursor-driver.js +20 -0
  165. package/data/build/dist/host/cli-adapters/cursor-driver.js.map +1 -0
  166. package/data/build/dist/host/cli-adapters/custom-upstream-classifier.d.ts +67 -0
  167. package/data/build/dist/host/cli-adapters/custom-upstream-classifier.d.ts.map +1 -0
  168. package/data/build/dist/host/cli-adapters/custom-upstream-classifier.js +169 -0
  169. package/data/build/dist/host/cli-adapters/custom-upstream-classifier.js.map +1 -0
  170. package/data/build/dist/host/cli-adapters/delegate-dispatch.d.ts +2 -1
  171. package/data/build/dist/host/cli-adapters/delegate-dispatch.d.ts.map +1 -1
  172. package/data/build/dist/host/cli-adapters/delegate-dispatch.js +14 -61
  173. package/data/build/dist/host/cli-adapters/delegate-dispatch.js.map +1 -1
  174. package/data/build/dist/host/cli-adapters/delegation-authorization.d.ts +19 -0
  175. package/data/build/dist/host/cli-adapters/delegation-authorization.d.ts.map +1 -0
  176. package/data/build/dist/host/cli-adapters/delegation-authorization.js +49 -0
  177. package/data/build/dist/host/cli-adapters/delegation-authorization.js.map +1 -0
  178. package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.d.ts +34 -0
  179. package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.d.ts.map +1 -0
  180. package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.js +121 -0
  181. package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.js.map +1 -0
  182. package/data/build/dist/host/cli-adapters/driver.d.ts +6 -0
  183. package/data/build/dist/host/cli-adapters/driver.d.ts.map +1 -1
  184. package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
  185. package/data/build/dist/host/cli-adapters/feature.js +269 -18
  186. package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
  187. package/data/build/dist/host/cli-adapters/kiro-driver.d.ts +12 -0
  188. package/data/build/dist/host/cli-adapters/kiro-driver.d.ts.map +1 -0
  189. package/data/build/dist/host/cli-adapters/kiro-driver.js +18 -0
  190. package/data/build/dist/host/cli-adapters/kiro-driver.js.map +1 -0
  191. package/data/build/dist/host/cli-adapters/legacy-session-adapter.d.ts.map +1 -1
  192. package/data/build/dist/host/cli-adapters/legacy-session-adapter.js +11 -0
  193. package/data/build/dist/host/cli-adapters/legacy-session-adapter.js.map +1 -1
  194. package/data/build/dist/host/cli-adapters/model-catalog.d.ts +5 -0
  195. package/data/build/dist/host/cli-adapters/model-catalog.d.ts.map +1 -1
  196. package/data/build/dist/host/cli-adapters/model-catalog.js +130 -0
  197. package/data/build/dist/host/cli-adapters/model-catalog.js.map +1 -1
  198. package/data/build/dist/host/cli-adapters/native-subagent-dispatch.d.ts +33 -3
  199. package/data/build/dist/host/cli-adapters/native-subagent-dispatch.d.ts.map +1 -1
  200. package/data/build/dist/host/cli-adapters/native-subagent-dispatch.js +115 -9
  201. package/data/build/dist/host/cli-adapters/native-subagent-dispatch.js.map +1 -1
  202. package/data/build/dist/host/cli-adapters/native-team-subagent.d.ts +14 -2
  203. package/data/build/dist/host/cli-adapters/native-team-subagent.d.ts.map +1 -1
  204. package/data/build/dist/host/cli-adapters/native-team-subagent.js +23 -4
  205. package/data/build/dist/host/cli-adapters/native-team-subagent.js.map +1 -1
  206. package/data/build/dist/host/cli-adapters/new-api-subscription.d.ts +75 -0
  207. package/data/build/dist/host/cli-adapters/new-api-subscription.d.ts.map +1 -0
  208. package/data/build/dist/host/cli-adapters/new-api-subscription.js +959 -0
  209. package/data/build/dist/host/cli-adapters/new-api-subscription.js.map +1 -0
  210. package/data/build/dist/host/cli-adapters/opencode-driver.d.ts.map +1 -1
  211. package/data/build/dist/host/cli-adapters/opencode-driver.js +9 -7
  212. package/data/build/dist/host/cli-adapters/opencode-driver.js.map +1 -1
  213. package/data/build/dist/host/cli-adapters/provider-subscription.d.ts +33 -3
  214. package/data/build/dist/host/cli-adapters/provider-subscription.d.ts.map +1 -1
  215. package/data/build/dist/host/cli-adapters/provider-subscription.js +158 -40
  216. package/data/build/dist/host/cli-adapters/provider-subscription.js.map +1 -1
  217. package/data/build/dist/host/cli-adapters/qoder-driver.d.ts +71 -0
  218. package/data/build/dist/host/cli-adapters/qoder-driver.d.ts.map +1 -0
  219. package/data/build/dist/host/cli-adapters/qoder-driver.js +553 -0
  220. package/data/build/dist/host/cli-adapters/qoder-driver.js.map +1 -0
  221. package/data/build/dist/host/cli-adapters/qoder-subscription.d.ts +31 -0
  222. package/data/build/dist/host/cli-adapters/qoder-subscription.d.ts.map +1 -0
  223. package/data/build/dist/host/cli-adapters/qoder-subscription.js +178 -0
  224. package/data/build/dist/host/cli-adapters/qoder-subscription.js.map +1 -0
  225. package/data/build/dist/host/cli-adapters/registry.d.ts +41 -2
  226. package/data/build/dist/host/cli-adapters/registry.d.ts.map +1 -1
  227. package/data/build/dist/host/cli-adapters/registry.js +187 -18
  228. package/data/build/dist/host/cli-adapters/registry.js.map +1 -1
  229. package/data/build/dist/host/cli-adapters/session-store.d.ts +4 -0
  230. package/data/build/dist/host/cli-adapters/session-store.d.ts.map +1 -1
  231. package/data/build/dist/host/cli-adapters/session-store.js +18 -2
  232. package/data/build/dist/host/cli-adapters/session-store.js.map +1 -1
  233. package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts +14 -1
  234. package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts.map +1 -1
  235. package/data/build/dist/host/cli-adapters/standard-stream-driver.js +121 -23
  236. package/data/build/dist/host/cli-adapters/standard-stream-driver.js.map +1 -1
  237. package/data/build/dist/host/cli-adapters/stream-normalizer.d.ts +10 -1
  238. package/data/build/dist/host/cli-adapters/stream-normalizer.d.ts.map +1 -1
  239. package/data/build/dist/host/cli-adapters/stream-normalizer.js +23 -0
  240. package/data/build/dist/host/cli-adapters/stream-normalizer.js.map +1 -1
  241. package/data/build/dist/host/cli-adapters/subagent-tool.d.ts.map +1 -1
  242. package/data/build/dist/host/cli-adapters/subagent-tool.js +53 -7
  243. package/data/build/dist/host/cli-adapters/subagent-tool.js.map +1 -1
  244. package/data/build/dist/host/cli-bridge/bridge-server.d.ts +5 -0
  245. package/data/build/dist/host/cli-bridge/bridge-server.d.ts.map +1 -1
  246. package/data/build/dist/host/cli-bridge/bridge-server.js +7 -2
  247. package/data/build/dist/host/cli-bridge/bridge-server.js.map +1 -1
  248. package/data/build/dist/host/cli-bridge/command-code-mod.d.ts +5 -1
  249. package/data/build/dist/host/cli-bridge/command-code-mod.d.ts.map +1 -1
  250. package/data/build/dist/host/cli-bridge/command-code-mod.js +43 -12
  251. package/data/build/dist/host/cli-bridge/command-code-mod.js.map +1 -1
  252. package/data/build/dist/host/cli-bridge/dispatch.d.ts.map +1 -1
  253. package/data/build/dist/host/cli-bridge/dispatch.js +43 -5
  254. package/data/build/dist/host/cli-bridge/dispatch.js.map +1 -1
  255. package/data/build/dist/host/cli-bridge/mcp-stdio-entry.js +24 -5
  256. package/data/build/dist/host/cli-bridge/mcp-stdio-entry.js.map +1 -1
  257. package/data/build/dist/host/features/peer-host.d.ts +21 -1
  258. package/data/build/dist/host/features/peer-host.d.ts.map +1 -1
  259. package/data/build/dist/host/features/peer-host.js +174 -30
  260. package/data/build/dist/host/features/peer-host.js.map +1 -1
  261. package/data/build/dist/host/features/types.d.ts +2 -0
  262. package/data/build/dist/host/features/types.d.ts.map +1 -1
  263. package/data/build/dist/host/index.d.ts +11 -1
  264. package/data/build/dist/host/index.d.ts.map +1 -1
  265. package/data/build/dist/host/index.js +12 -2
  266. package/data/build/dist/host/index.js.map +1 -1
  267. package/data/build/dist/host/modules/peer-host/peer-host-native-protocol.js +6 -1
  268. package/data/build/dist/host/modules/peer-host/peer-host-native-protocol.js.map +1 -1
  269. package/data/build/dist/host/modules/peer-host/peer-host-virtual-registry.d.ts +2 -0
  270. package/data/build/dist/host/modules/peer-host/peer-host-virtual-registry.d.ts.map +1 -1
  271. package/data/build/dist/host/modules/peer-host/peer-host-virtual-registry.js +26 -7
  272. package/data/build/dist/host/modules/peer-host/peer-host-virtual-registry.js.map +1 -1
  273. package/data/build/dist/host/native-session-bridge.d.ts.map +1 -1
  274. package/data/build/dist/host/native-session-bridge.js +36 -7
  275. package/data/build/dist/host/native-session-bridge.js.map +1 -1
  276. package/data/build/dist/host/rpc.js +5 -2
  277. package/data/build/dist/host/rpc.js.map +1 -1
  278. package/data/build/dist/host/settings.d.ts.map +1 -1
  279. package/data/build/dist/host/settings.js +12 -5
  280. package/data/build/dist/host/settings.js.map +1 -1
  281. package/data/build/dist/host/terminal/backends/local-pty-backend.d.ts.map +1 -1
  282. package/data/build/dist/host/terminal/backends/local-pty-backend.js +14 -0
  283. package/data/build/dist/host/terminal/backends/local-pty-backend.js.map +1 -1
  284. package/data/build/dist/host/terminal/backends/tmux-backend.d.ts +40 -1
  285. package/data/build/dist/host/terminal/backends/tmux-backend.d.ts.map +1 -1
  286. package/data/build/dist/host/terminal/backends/tmux-backend.js +291 -18
  287. package/data/build/dist/host/terminal/backends/tmux-backend.js.map +1 -1
  288. package/data/build/dist/host/terminal/runtime-adapter.d.ts +32 -0
  289. package/data/build/dist/host/terminal/runtime-adapter.d.ts.map +1 -1
  290. package/data/build/dist/host/terminal/runtime-adapter.js +8 -0
  291. package/data/build/dist/host/terminal/runtime-adapter.js.map +1 -1
  292. package/data/build/dist/host/terminal/runtime-manager.d.ts +3 -0
  293. package/data/build/dist/host/terminal/runtime-manager.d.ts.map +1 -1
  294. package/data/build/dist/host/terminal/runtime-manager.js +92 -4
  295. package/data/build/dist/host/terminal/runtime-manager.js.map +1 -1
  296. package/data/build/dist/host/terminal/terminal-controller.d.ts.map +1 -1
  297. package/data/build/dist/host/terminal/terminal-controller.js +58 -6
  298. package/data/build/dist/host/terminal/terminal-controller.js.map +1 -1
  299. package/data/build/dist/host/terminal/terminal-process-service.d.ts.map +1 -1
  300. package/data/build/dist/host/terminal/terminal-process-service.js +12 -2
  301. package/data/build/dist/host/terminal/terminal-process-service.js.map +1 -1
  302. package/data/build/dist/host/terminal/terminal-service.d.ts +41 -4
  303. package/data/build/dist/host/terminal/terminal-service.d.ts.map +1 -1
  304. package/data/build/dist/host/terminal/terminal-service.js +551 -61
  305. package/data/build/dist/host/terminal/terminal-service.js.map +1 -1
  306. package/data/build/dist/index.d.ts +2 -2
  307. package/data/build/dist/index.d.ts.map +1 -1
  308. package/data/build/dist/index.js +2 -2
  309. package/data/build/dist/index.js.map +1 -1
  310. package/data/build/dist/shared/contracts/cli-adapter.d.ts +64 -2
  311. package/data/build/dist/shared/contracts/cli-adapter.d.ts.map +1 -1
  312. package/data/build/dist/shared/contracts/config.d.ts +54 -11
  313. package/data/build/dist/shared/contracts/config.d.ts.map +1 -1
  314. package/data/build/dist/shared/contracts/config.js +52 -8
  315. package/data/build/dist/shared/contracts/config.js.map +1 -1
  316. package/data/build/dist/shared/contracts/subscription.d.ts +5 -1
  317. package/data/build/dist/shared/contracts/subscription.d.ts.map +1 -1
  318. package/data/build/dist/shared/contracts/subscription.js.map +1 -1
  319. package/data/build/dist/shared/contracts/terminal.d.ts +8 -1
  320. package/data/build/dist/shared/contracts/terminal.d.ts.map +1 -1
  321. package/data/build/dist/shared/contracts/version.d.ts +1 -1
  322. package/data/build/dist/shared/contracts/version.js +1 -1
  323. package/data/build/dist/shared/debug.d.ts +8 -0
  324. package/data/build/dist/shared/debug.d.ts.map +1 -1
  325. package/data/build/dist/shared/debug.js +43 -7
  326. package/data/build/dist/shared/debug.js.map +1 -1
  327. package/data/build/dist/shared/delegation-carrier.d.ts +24 -0
  328. package/data/build/dist/shared/delegation-carrier.d.ts.map +1 -0
  329. package/data/build/dist/shared/delegation-carrier.js +111 -0
  330. package/data/build/dist/shared/delegation-carrier.js.map +1 -0
  331. package/data/build/dist/shared/index.d.ts +2 -2
  332. package/data/build/dist/shared/index.d.ts.map +1 -1
  333. package/data/build/dist/shared/index.js +2 -2
  334. package/data/build/dist/shared/index.js.map +1 -1
  335. package/data/build/dist/shared/terminal-input.d.ts +8 -0
  336. package/data/build/dist/shared/terminal-input.d.ts.map +1 -0
  337. package/data/build/dist/shared/terminal-input.js +10 -0
  338. package/data/build/dist/shared/terminal-input.js.map +1 -0
  339. package/data/build/dist/transport/debug.d.ts +7 -0
  340. package/data/build/dist/transport/debug.d.ts.map +1 -1
  341. package/data/build/dist/transport/debug.js +33 -5
  342. package/data/build/dist/transport/debug.js.map +1 -1
  343. package/data/build/dist/transport/index.d.ts +1 -1
  344. package/data/build/dist/transport/index.d.ts.map +1 -1
  345. package/data/build/dist/transport/index.js +1 -1
  346. package/data/build/dist/transport/index.js.map +1 -1
  347. package/data/build/dist/typert.host.js +1 -1
  348. package/data/build/dist/typert.host.js.map +1 -1
  349. package/package.json +1 -1
  350. package/profile/README.md +2 -2
  351. package/profile/package.json +2 -2
  352. package/profile/version.json +1 -1
  353. package/version.json +1 -1
@@ -0,0 +1,71 @@
1
+ import { spawn, spawnSync } from 'node:child_process';
2
+ import type { CodingNsAgentEvent, CodingNsAgentPermissionResponse, CodingNsCliModelCatalog, CodingNsAgentQuestionResponse, CodingNsCliTurnInput } from '../../shared/contracts/cli-adapter.js';
3
+ import type { CodingNsCliDriver, CodingNsCliSessionProbeInput, CodingNsCliSessionProbeResult } from './driver.js';
4
+ /** Qoder 的两个发行身份共用协议和驱动,只在这里保存产品差异。 */
5
+ export type QoderCliVariant = 'qoder' | 'qoder-cn';
6
+ export interface QoderCliProfile {
7
+ readonly variant: QoderCliVariant;
8
+ readonly id: 'qoder' | 'qoder-cn';
9
+ readonly name: 'Qoder' | 'Qoder CN';
10
+ readonly binaries: readonly string[];
11
+ readonly tokenEnv: 'QODER_PERSONAL_ACCESS_TOKEN' | 'QODERCN_PERSONAL_ACCESS_TOKEN';
12
+ readonly userConfigEnv: 'QODER_USER_CONFIG_DIR' | 'QODERCN_USER_CONFIG_DIR';
13
+ readonly userConfigDirectory: '.qoder' | '.qoder-cn';
14
+ }
15
+ export declare const QODER_PROFILES: Readonly<Record<QoderCliVariant, QoderCliProfile>>;
16
+ export interface QoderCliDriverOptions {
17
+ /** 默认是国际版 Qoder;Qoder CN 传入 `variant: 'qoder-cn'`。 */
18
+ readonly variant?: QoderCliVariant;
19
+ readonly binaries?: readonly string[];
20
+ readonly spawnSync?: typeof spawnSync;
21
+ readonly spawn?: typeof spawn;
22
+ /** 测试或托管环境可覆盖进程环境;不会改变宿主进程的 process.env。 */
23
+ readonly environment?: Readonly<Record<string, string | undefined>>;
24
+ }
25
+ /** Qoder ACP 在未返回动态模型目录时的保守目录。 */
26
+ export declare const QODER_CATALOG: CodingNsCliModelCatalog;
27
+ /**
28
+ * Qoder/Qoder CN 官方 ACP 客户端。
29
+ *
30
+ * 这里仅依赖 CLI 的 `--acp` 公共入口,不依赖 qoder-agent-sdk。ACP 会话存储
31
+ * 位置没有公开只读索引,因此 probeSession 明确返回 unknown,避免用 resume
32
+ * 或 prompt 之类有副作用的请求伪造“会话存在”。
33
+ */
34
+ export declare class QoderCliDriver implements CodingNsCliDriver {
35
+ readonly descriptor: {
36
+ readonly id: 'qoder' | 'qoder-cn';
37
+ readonly name: 'Qoder' | 'Qoder CN';
38
+ readonly protocol: 'acp';
39
+ readonly capabilities: readonly ['models', 'stream', 'resume', 'interrupt', 'tool-events', 'reasoning', 'usage', 'permission'];
40
+ };
41
+ private readonly profile;
42
+ private readonly binaries;
43
+ private readonly runSpawnSync;
44
+ private readonly runSpawn;
45
+ private readonly baseEnvironment;
46
+ private cachedBinary;
47
+ private readonly sessions;
48
+ private readonly processes;
49
+ readonly supportsToolStepSplitting = true;
50
+ constructor(options?: QoderCliDriverOptions);
51
+ detect(): Promise<{
52
+ installed: boolean;
53
+ version: string | null;
54
+ command: string | null;
55
+ }>;
56
+ listModels(): Promise<CodingNsCliModelCatalog>;
57
+ probeSession(input: CodingNsCliSessionProbeInput): Promise<CodingNsCliSessionProbeResult>;
58
+ executeTurn(input: CodingNsCliTurnInput): AsyncIterable<CodingNsAgentEvent>;
59
+ respondPermission(sessionId: string, response: CodingNsAgentPermissionResponse): void;
60
+ /** Qoder 当前 ACP 文档没有独立问题请求;保留接口以便未来协议扩展时不破坏驱动。 */
61
+ respondQuestion(_sessionId: string, _response: CodingNsAgentQuestionResponse): void;
62
+ interrupt(sessionId: string): Promise<void>;
63
+ dispose(): void;
64
+ private getSession;
65
+ private startSession;
66
+ private loadSession;
67
+ private ensurePermission;
68
+ }
69
+ /** 解析 qodercn --list-models 的稳定表格输出。 */
70
+ export declare function parseQoderModelList(output: string, profile?: QoderCliProfile): CodingNsCliModelCatalog;
71
+ //# sourceMappingURL=qoder-driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qoder-driver.d.ts","sourceRoot":"","sources":["../../../../../src/host/cli-adapters/qoder-driver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,553 @@
1
+ import { spawn, spawnSync } from 'node:child_process';
2
+ import { readFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { JsonRpcProcess } from './json-rpc-process.js';
6
+ import { buildAcpPromptBlocks } from './attachment-utils.js';
7
+ import { acpBridgeMcpServers } from '../cli-bridge/injections.js';
8
+ import { isRecord, usageChunk } from './rpc-driver-utils.js';
9
+ import { firstToolText, normalizeToolStatus, serializeToolValue } from './tool-observation.js';
10
+ export const QODER_PROFILES = {
11
+ qoder: {
12
+ variant: 'qoder',
13
+ id: 'qoder',
14
+ name: 'Qoder',
15
+ binaries: ['qoder', 'qodercli', 'qoder.cmd', 'qodercli.cmd'],
16
+ tokenEnv: 'QODER_PERSONAL_ACCESS_TOKEN',
17
+ userConfigEnv: 'QODER_USER_CONFIG_DIR',
18
+ userConfigDirectory: '.qoder',
19
+ },
20
+ 'qoder-cn': {
21
+ variant: 'qoder-cn',
22
+ id: 'qoder-cn',
23
+ name: 'Qoder CN',
24
+ binaries: ['qodercn', 'qoderclicn', 'qodercn.cmd', 'qoderclicn.cmd'],
25
+ tokenEnv: 'QODERCN_PERSONAL_ACCESS_TOKEN',
26
+ userConfigEnv: 'QODERCN_USER_CONFIG_DIR',
27
+ userConfigDirectory: '.qoder-cn',
28
+ },
29
+ };
30
+ /** Qoder ACP 在未返回动态模型目录时的保守目录。 */
31
+ export const QODER_CATALOG = {
32
+ groups: [{
33
+ id: 'qoder',
34
+ name: 'Qoder',
35
+ models: [{ id: 'provider-default', name: '跟随 Qoder 默认模型', efforts: [] }],
36
+ }],
37
+ currentModel: null,
38
+ currentEffort: null,
39
+ };
40
+ /**
41
+ * Qoder/Qoder CN 官方 ACP 客户端。
42
+ *
43
+ * 这里仅依赖 CLI 的 `--acp` 公共入口,不依赖 qoder-agent-sdk。ACP 会话存储
44
+ * 位置没有公开只读索引,因此 probeSession 明确返回 unknown,避免用 resume
45
+ * 或 prompt 之类有副作用的请求伪造“会话存在”。
46
+ */
47
+ export class QoderCliDriver {
48
+ descriptor;
49
+ profile;
50
+ binaries;
51
+ runSpawnSync;
52
+ runSpawn;
53
+ baseEnvironment;
54
+ cachedBinary = null;
55
+ sessions = new Map();
56
+ processes = new Set();
57
+ // Qoder ACP 的通知队列可以在工具完成后暂停并由 Registry 续读;它不自行伪造
58
+ // Provider turn,因此使用通用工具分步能力,而不是 supportsSegmentedTurns。
59
+ supportsToolStepSplitting = true;
60
+ constructor(options = {}) {
61
+ this.profile = QODER_PROFILES[options.variant ?? 'qoder'];
62
+ this.binaries = options.binaries ?? this.profile.binaries;
63
+ this.runSpawnSync = options.spawnSync ?? spawnSync;
64
+ this.runSpawn = options.spawn ?? spawn;
65
+ this.baseEnvironment = qoderEnvironment(this.profile, options.environment ?? process.env);
66
+ this.descriptor = {
67
+ id: this.profile.id,
68
+ name: this.profile.name,
69
+ protocol: 'acp',
70
+ capabilities: ['models', 'stream', 'resume', 'interrupt', 'tool-events', 'reasoning', 'usage', 'permission'],
71
+ };
72
+ }
73
+ async detect() {
74
+ if (this.cachedBinary !== null) {
75
+ const version = readVersion(this.runSpawnSync, this.cachedBinary, this.baseEnvironment);
76
+ if (version !== null)
77
+ return { installed: true, version, command: this.cachedBinary };
78
+ this.cachedBinary = null;
79
+ }
80
+ for (const binary of this.binaries) {
81
+ const version = readVersion(this.runSpawnSync, binary, this.baseEnvironment);
82
+ if (version === null)
83
+ continue;
84
+ this.cachedBinary = binary;
85
+ return { installed: true, version, command: binary };
86
+ }
87
+ return { installed: false, version: null, command: null };
88
+ }
89
+ async listModels() {
90
+ const detected = await this.detect();
91
+ if (detected.command === null)
92
+ return { groups: [], currentModel: null, currentEffort: null };
93
+ // Qoder CLI 自己公开了只读 --list-models,不能再用 ACP session/new 冒充目录探测。
94
+ // 该命令在缓存命中和联网刷新两种情况下都返回同一张用户可用目录表。
95
+ try {
96
+ const result = this.runSpawnSync(detected.command, ['--list-models'], {
97
+ encoding: 'utf8', timeout: 15_000, windowsHide: true, env: this.baseEnvironment,
98
+ });
99
+ if (result.status === 0) {
100
+ const catalog = parseQoderModelList(`${result.stdout ?? ''}\n${result.stderr ?? ''}`, this.profile);
101
+ if (catalog.groups[0]?.models.length)
102
+ return catalog;
103
+ }
104
+ }
105
+ catch { /* 目录刷新失败时继续使用明确的保守回退 */ }
106
+ return { ...qoderCatalogForProfile(this.profile), fallback: true };
107
+ }
108
+ async probeSession(input) {
109
+ // Qoder 没有公开会话目录和只读索引接口;禁止以 ACP resume/load 代替探测。
110
+ return {
111
+ state: 'unknown',
112
+ reason: 'Qoder ACP 未公开可安全读取的会话索引,无法在不改变 Provider 状态的前提下探测',
113
+ ...(input.rawStoreRef?.trim() ? { rawStoreRef: input.rawStoreRef.trim() } : {}),
114
+ };
115
+ }
116
+ async *executeTurn(input) {
117
+ const command = this.cachedBinary ?? (await this.detect()).command;
118
+ if (command === null)
119
+ throw new Error(`${this.profile.name} 未安装`);
120
+ const session = await this.getSession(input, command);
121
+ session.permission = input.permission;
122
+ if (session.acpSessionId === '') {
123
+ const attached = input.providerSessionId === undefined
124
+ ? await this.startSession(session, input)
125
+ : await this.loadSession(session, input);
126
+ session.acpSessionId = readSessionId(attached) ?? input.providerSessionId ?? input.sessionId;
127
+ }
128
+ yield { type: 'session-binding', providerSessionId: session.acpSessionId };
129
+ if (input.modelId?.trim() && input.modelId !== 'provider-default') {
130
+ await session.rpc.request('session/set_model', { sessionId: session.acpSessionId, modelId: input.modelId }, { signal: input.signal, killOnAbort: false }).catch(() => undefined);
131
+ }
132
+ const eventQueue = createQoderTurnEventQueue();
133
+ session.eventQueue = eventQueue;
134
+ let assistantMessageSegment = 0;
135
+ const toolNames = new Map();
136
+ let promptResult;
137
+ let promptError;
138
+ let rpcExited = false;
139
+ const removeExitListener = session.rpc.addExitListener(() => { rpcExited = true; eventQueue.close(); });
140
+ const promptBlocks = await buildAcpPromptBlocks(input.prompt, input.attachments ?? []);
141
+ const sendPromise = session.rpc.request('session/prompt', {
142
+ sessionId: session.acpSessionId,
143
+ prompt: promptBlocks,
144
+ }, {
145
+ signal: input.signal,
146
+ killOnAbort: false,
147
+ onNotification: (message) => {
148
+ // JsonRpcProcess 会先通知监听器,再在下一个微任务调用 server handler。
149
+ // 先登记权限 deferred,确保 UI 消费 permission-request 后可以立即应答。
150
+ if (message.method === 'session/request_permission')
151
+ this.ensurePermission(session, message);
152
+ if (belongsToSession(message, session.acpSessionId))
153
+ eventQueue.push(message);
154
+ },
155
+ }).then((value) => { promptResult = value; return value; }, (error) => { promptError = error; return undefined; });
156
+ const onAbort = () => {
157
+ void session.rpc.request('session/cancel', { sessionId: session.acpSessionId }, { killOnAbort: false }).catch(() => undefined);
158
+ eventQueue.close();
159
+ };
160
+ if (input.signal?.aborted)
161
+ onAbort();
162
+ else
163
+ input.signal?.addEventListener('abort', onAbort, { once: true });
164
+ try {
165
+ while (true) {
166
+ const next = await Promise.race([
167
+ eventQueue.next(),
168
+ sendPromise.then(() => ({ __response: true })),
169
+ ]);
170
+ if (next !== null && typeof next === 'object' && '__response' in next)
171
+ break;
172
+ if (next.done)
173
+ break;
174
+ const chunk = qoderAcpMessageToChunk(next.value, input, toolNames, assistantMessageSegment);
175
+ if (chunk !== null)
176
+ yield chunk;
177
+ if (chunk?.type === 'tool-event' && (chunk.status === 'completed' || chunk.status === 'failed')) {
178
+ assistantMessageSegment += 1;
179
+ }
180
+ }
181
+ await sendPromise.catch(() => undefined);
182
+ if (promptError !== undefined && !input.signal?.aborted)
183
+ throw promptError;
184
+ if (rpcExited && !input.signal?.aborted)
185
+ throw new Error(`${this.profile.name} ACP 进程已退出`);
186
+ yield { type: 'finish', reason: qoderPromptReason(promptResult, input.signal) };
187
+ }
188
+ catch (error) {
189
+ if (!input.signal?.aborted)
190
+ throw error;
191
+ yield { type: 'finish', reason: 'cancel' };
192
+ }
193
+ finally {
194
+ input.signal?.removeEventListener('abort', onAbort);
195
+ removeExitListener();
196
+ if (session.eventQueue === eventQueue)
197
+ session.eventQueue = undefined;
198
+ eventQueue.close();
199
+ }
200
+ }
201
+ respondPermission(sessionId, response) {
202
+ const session = this.sessions.get(sessionId);
203
+ const pending = session?.pendingPermissions.get(response.requestId);
204
+ if (session === undefined || pending === undefined)
205
+ throw new Error(`${this.profile.name} 权限请求不存在`);
206
+ session.pendingPermissions.delete(response.requestId);
207
+ pending.resolve({ outcome: { outcome: 'selected', optionId: response.approved ? pending.allowOptionId : pending.rejectOptionId } });
208
+ }
209
+ /** Qoder 当前 ACP 文档没有独立问题请求;保留接口以便未来协议扩展时不破坏驱动。 */
210
+ respondQuestion(_sessionId, _response) {
211
+ throw new Error(`${this.profile.name} ACP 不支持问题请求`);
212
+ }
213
+ async interrupt(sessionId) {
214
+ const session = this.sessions.get(sessionId);
215
+ if (session === undefined || session.acpSessionId === '')
216
+ return;
217
+ await session.rpc.request('session/cancel', { sessionId: session.acpSessionId }, { killOnAbort: false }).catch(() => undefined);
218
+ }
219
+ dispose() {
220
+ for (const session of this.sessions.values())
221
+ session.rpc.dispose();
222
+ this.sessions.clear();
223
+ for (const rpc of this.processes)
224
+ rpc.dispose();
225
+ this.processes.clear();
226
+ this.cachedBinary = null;
227
+ }
228
+ async getSession(input, command) {
229
+ const previous = this.sessions.get(input.sessionId);
230
+ const permissionMode = qoderPermissionMode(input.permission);
231
+ if (previous !== undefined && previous.cwd === input.cwd && previous.effortId === normalizedEffort(input.effortId) && previous.permissionMode === permissionMode && !previous.rpc.isClosed)
232
+ return previous;
233
+ previous?.rpc.dispose();
234
+ const session = {
235
+ rpc: new JsonRpcProcess({ command, args: qoderAcpArgs(input.effortId, input.permission), cwd: input.cwd, env: this.baseEnvironment, spawn: this.runSpawn }),
236
+ cwd: input.cwd,
237
+ effortId: normalizedEffort(input.effortId),
238
+ permissionMode,
239
+ acpSessionId: '',
240
+ permission: input.permission,
241
+ pendingPermissions: new Map(),
242
+ eventQueue: undefined,
243
+ };
244
+ this.sessions.set(input.sessionId, session);
245
+ this.processes.add(session.rpc);
246
+ session.rpc.addExitListener(() => {
247
+ this.processes.delete(session.rpc);
248
+ if (this.sessions.get(input.sessionId)?.rpc === session.rpc)
249
+ this.sessions.delete(input.sessionId);
250
+ });
251
+ session.rpc.setServerRequestHandler((request) => {
252
+ if (request.method !== 'session/request_permission')
253
+ throw new Error('请求不受支持');
254
+ const requestId = permissionRequestId(request);
255
+ if (requestId === null)
256
+ throw new Error('权限请求缺少 request id');
257
+ return this.ensurePermission(session, request);
258
+ });
259
+ try {
260
+ await session.rpc.request('initialize', {
261
+ protocolVersion: 1,
262
+ clientInfo: { name: 'codingns4dsh', version: '0.2.0' },
263
+ // Qoder 1.1 的 ACP schema 不接受空的 fs/terminal capability 对象;
264
+ // Qoder 自己负责工具执行,Host 只声明基础协议能力即可。
265
+ clientCapabilities: {},
266
+ }, { signal: input.signal, killOnAbort: false });
267
+ session.rpc.notify('initialized', {});
268
+ return session;
269
+ }
270
+ catch (error) {
271
+ session.rpc.dispose();
272
+ this.sessions.delete(input.sessionId);
273
+ throw error;
274
+ }
275
+ }
276
+ async startSession(session, input) {
277
+ return session.rpc.request('session/new', {
278
+ cwd: input.cwd ?? process.cwd(),
279
+ mcpServers: acpBridgeMcpServers(input.sessionId, this.profile.id),
280
+ }, { signal: input.signal, killOnAbort: false });
281
+ }
282
+ async loadSession(session, input) {
283
+ // Provider 会话不存在时必须保留失败诊断,不能退回新会话并重复发送原请求。
284
+ return session.rpc.request('session/load', {
285
+ sessionId: input.providerSessionId,
286
+ cwd: input.cwd ?? process.cwd(),
287
+ mcpServers: acpBridgeMcpServers(input.sessionId, this.profile.id),
288
+ }, { signal: input.signal, killOnAbort: false });
289
+ }
290
+ ensurePermission(session, request) {
291
+ const requestId = permissionRequestId(request);
292
+ const existing = session.pendingPermissions.get(requestId);
293
+ if (existing !== undefined)
294
+ return existing.promise;
295
+ let resolve;
296
+ const promise = new Promise((value) => { resolve = value; });
297
+ const options = permissionOptions(request);
298
+ const pending = {
299
+ promise,
300
+ resolve,
301
+ allowOptionId: options.allow,
302
+ rejectOptionId: options.reject,
303
+ };
304
+ session.pendingPermissions.set(requestId, pending);
305
+ return promise;
306
+ }
307
+ }
308
+ function qoderEnvironment(profile, source) {
309
+ const env = { ...source };
310
+ // 两套 CLI 不能继承对方的登录票据或用户配置根;否则 Qoder CN 可能静默复用国际版登录态。
311
+ delete env[profile.variant === 'qoder' ? 'QODERCN_PERSONAL_ACCESS_TOKEN' : 'QODER_PERSONAL_ACCESS_TOKEN'];
312
+ delete env[profile.variant === 'qoder' ? 'QODERCN_USER_CONFIG_DIR' : 'QODER_USER_CONFIG_DIR'];
313
+ env[profile.userConfigEnv] = profile.userConfigDirectory;
314
+ return env;
315
+ }
316
+ function normalizedEffort(value) {
317
+ const normalized = value?.trim().toLowerCase();
318
+ return normalized === undefined || normalized === '' || normalized === 'default' ? undefined : normalized;
319
+ }
320
+ function qoderAcpArgs(effortId, permission) {
321
+ // Qoder 默认 ACP 模式是 `default`,即使 `ls`、`find` 这类只读操作也可能弹出
322
+ // Provider 自己的 Bash 审批。DSH 已经负责统一审批展示,使用 Qoder 的安全
323
+ // 分类模式让只读操作直接通过,同时仍让写入和高风险命令进入安全判定。
324
+ const args = ['--acp', '--permission-mode', qoderPermissionMode(permission)];
325
+ const effort = normalizedEffort(effortId);
326
+ if (effort !== undefined && ['low', 'medium', 'high'].includes(effort))
327
+ args.push('--reasoning-effort', effort);
328
+ return args;
329
+ }
330
+ function qoderPermissionMode(permission) {
331
+ if (permission?.approvalPolicy !== 'never')
332
+ return 'auto';
333
+ return permission.sandboxMode === 'danger-full-access' ? 'bypass_permissions' : 'dont_ask';
334
+ }
335
+ function readVersion(run, command, env) {
336
+ try {
337
+ const result = run(command, ['--version'], {
338
+ encoding: 'utf8', timeout: 5_000, windowsHide: true, env,
339
+ });
340
+ if (result.status !== 0)
341
+ return null;
342
+ return `${result.stdout ?? ''}\n${result.stderr ?? ''}`.match(/\b\d+\.\d+(?:\.\d+)?(?:[-+][0-9A-Za-z.-]+)?\b/u)?.[0] ?? null;
343
+ }
344
+ catch {
345
+ return null;
346
+ }
347
+ }
348
+ function qoderCatalogForProfile(profile) {
349
+ return {
350
+ ...QODER_CATALOG,
351
+ groups: [{
352
+ ...QODER_CATALOG.groups[0],
353
+ id: profile.id,
354
+ name: profile.name,
355
+ models: QODER_CATALOG.groups[0].models.map((model) => model.id === 'provider-default'
356
+ ? { ...model, name: `跟随 ${profile.name} 默认模型` }
357
+ : model),
358
+ }],
359
+ };
360
+ }
361
+ const QODER_REASONING_EFFORTS = ['low', 'medium', 'high'];
362
+ /** Qoder ACP 返回的稳定 modelId;--list-models 只打印 display name。 */
363
+ const QODER_MODEL_IDS = {
364
+ auto: 'auto',
365
+ 'qwen3.8-max': 'qmodel_38max',
366
+ 'qwen3.8-flash': 'qfmodel',
367
+ 'qwen3.7-max': 'qmodel_latest',
368
+ 'qwen3.7-plus': 'qmodel',
369
+ 'qwen3.7-flash': 'q37fmodel',
370
+ 'deepseek-v4-pro': 'dmodel',
371
+ 'deepseek-flash': 'dfmodel',
372
+ 'glm-5.3': 'gmodel',
373
+ 'glm-5.3-flash': 'gfmodel',
374
+ 'glm-5.2': 'gm51model',
375
+ 'kimi-k3': 'kmodel_latest',
376
+ 'kimi-k2.8-preview': 'kmodel',
377
+ 'minimax-m2.7': 'mmodel',
378
+ };
379
+ const QODER_NON_REASONING_MODELS = new Set(['deepseek-flash', 'kimi-k3', 'minimax-m2.7']);
380
+ /** 解析 qodercn --list-models 的稳定表格输出。 */
381
+ export function parseQoderModelList(output, profile = QODER_PROFILES['qoder-cn']) {
382
+ const models = output
383
+ .split(/\r?\n/u)
384
+ .map((line) => line.replace(/\u001b\[[0-9;]*m/gu, '').trim())
385
+ .filter((line) => line !== '' && !/^model$/iu.test(line) && !/^[-_]+$/u.test(line))
386
+ .map((line) => line.split(/\s{2,}|\t/u)[0]?.trim() ?? line)
387
+ .filter((name) => name !== '' && !/^(?:qoder(?:cn|cli)?|qoderclicn)\s+\d+\./iu.test(name))
388
+ .filter((name, index, all) => all.indexOf(name) === index);
389
+ if (models.length === 0)
390
+ return qoderCatalogForProfile(profile);
391
+ const entries = models.map((name) => {
392
+ const isAuto = /^auto$/iu.test(name);
393
+ const normalized = name.toLowerCase();
394
+ const id = isAuto ? 'provider-default' : QODER_MODEL_IDS[normalized] ?? name;
395
+ const efforts = QODER_NON_REASONING_MODELS.has(normalized) ? [] : [...QODER_REASONING_EFFORTS];
396
+ return {
397
+ id,
398
+ name: isAuto ? `跟随 ${profile.name} 默认模型` : name,
399
+ efforts,
400
+ };
401
+ });
402
+ return {
403
+ groups: [{ id: profile.id, name: profile.name, models: entries }],
404
+ // CLI 没有公开当前线程选择;把“当前”交给 Registry 的会话偏好恢复。
405
+ currentModel: null,
406
+ currentEffort: null,
407
+ };
408
+ }
409
+ function readSessionId(value) {
410
+ if (!isRecord(value))
411
+ return null;
412
+ if (typeof value.sessionId === 'string' && value.sessionId.trim())
413
+ return value.sessionId.trim();
414
+ if (isRecord(value.session) && typeof value.session.id === 'string' && value.session.id.trim())
415
+ return value.session.id.trim();
416
+ return typeof value.id === 'string' && value.id.trim() ? value.id.trim() : null;
417
+ }
418
+ function belongsToSession(message, sessionId) {
419
+ if (!isRecord(message.params))
420
+ return true;
421
+ const params = message.params;
422
+ const candidate = typeof params.sessionId === 'string' ? params.sessionId : isRecord(params.update) && typeof params.update.sessionId === 'string' ? params.update.sessionId : undefined;
423
+ return candidate === undefined || candidate === sessionId;
424
+ }
425
+ function permissionRequestId(message) {
426
+ if (typeof message.id === 'string' || typeof message.id === 'number')
427
+ return String(message.id);
428
+ if (!isRecord(message.params))
429
+ return null;
430
+ const id = message.params.requestId ?? message.params.id;
431
+ return typeof id === 'string' || typeof id === 'number' ? String(id) : null;
432
+ }
433
+ function permissionOptions(message) {
434
+ const params = isRecord(message.params) ? message.params : {};
435
+ const options = Array.isArray(params.options) ? params.options : [];
436
+ const ids = options.flatMap((option) => {
437
+ if (!isRecord(option))
438
+ return [];
439
+ const id = typeof option.optionId === 'string' ? option.optionId : typeof option.id === 'string' ? option.id : null;
440
+ const kind = typeof option.kind === 'string' ? option.kind.toLowerCase() : '';
441
+ return id === null ? [] : [{ id, kind }];
442
+ });
443
+ return {
444
+ allow: ids.find((option) => /allow|approve|accept/u.test(option.kind))?.id ?? ids[0]?.id ?? 'allow-once',
445
+ reject: ids.find((option) => /reject|deny|cancel/u.test(option.kind))?.id ?? 'reject-once',
446
+ };
447
+ }
448
+ function qoderPromptReason(value, signal) {
449
+ if (signal?.aborted)
450
+ return 'cancel';
451
+ if (!isRecord(value) || typeof value.stopReason !== 'string')
452
+ return 'stop';
453
+ const reason = value.stopReason.toLowerCase();
454
+ if (reason.includes('cancel'))
455
+ return 'cancel';
456
+ if (reason.includes('error') || reason.includes('fail'))
457
+ return 'error';
458
+ return 'stop';
459
+ }
460
+ function qoderAcpMessageToChunk(message, input, toolNames, assistantMessageSegment = 0) {
461
+ const params = isRecord(message.params) ? message.params : message;
462
+ const update = isRecord(params.update) ? params.update : params;
463
+ const rawType = firstToolText(update.sessionUpdate, update.type, message.method) ?? '';
464
+ const type = rawType.toLowerCase();
465
+ const text = acpText(update.delta ?? update.text ?? update.content ?? update.message ?? update.detail);
466
+ if (type.includes('request_permission') || type.includes('permission')) {
467
+ const requestId = permissionRequestId(message);
468
+ if (requestId !== null) {
469
+ const tool = isRecord(update.toolCall) ? update.toolCall : isRecord(update.tool_call) ? update.tool_call : update;
470
+ const meta = isRecord(update._meta) && isRecord(update._meta.qoder) ? update._meta.qoder : {};
471
+ const callId = firstToolText(tool.callId, tool.call_id, tool.toolCallId, tool.tool_call_id, tool.id, update.toolCallId, update.tool_call_id, update.id);
472
+ const explicitToolName = firstToolText(meta.toolName, tool.name, tool.toolName, tool.tool_name, update.name, update.toolName, update.tool_name);
473
+ const toolName = explicitToolName
474
+ ?? (callId === undefined ? undefined : toolNames?.get(callId))
475
+ ?? firstToolText(tool.title, update.title);
476
+ if (callId !== undefined && toolName !== undefined && toolName !== 'tool')
477
+ toolNames?.set(callId, toolName);
478
+ const kind = firstToolText(update.kind, update.permissionKind, tool.kind) ?? toolName ?? 'unknown';
479
+ return { type: 'permission-request', requestId, kind, ...(toolName ? { toolName } : {}), ...(callId ? { callId } : {}), ...(text ? { detail: text } : {}) };
480
+ }
481
+ }
482
+ const providerMessageId = qoderMessageId(update);
483
+ const messageId = providerMessageId ?? `qoder-assistant-${input.sessionId}-${assistantMessageSegment}`;
484
+ if (type.includes('agent_message') || type.includes('text'))
485
+ return text === null ? null : { type: 'text-delta', text, messageId };
486
+ if (type.includes('agent_thought') || type.includes('thought') || type.includes('reason'))
487
+ return text === null ? null : { type: 'reasoning-delta', text, messageId };
488
+ if (type.includes('tool') || type.includes('command')) {
489
+ const tool = isRecord(update.toolCall) ? update.toolCall : isRecord(update.tool_call) ? update.tool_call : update;
490
+ const meta = isRecord(update._meta) && isRecord(update._meta.qoder) ? update._meta.qoder : {};
491
+ const callId = firstToolText(tool.callId, tool.call_id, tool.toolCallId, tool.tool_call_id, tool.id, update.toolCallId, update.tool_call_id, update.id);
492
+ const explicitToolName = firstToolText(meta.toolName, tool.name, tool.toolName, tool.tool_name, update.name, update.toolName, update.tool_name);
493
+ const toolName = explicitToolName
494
+ ?? (callId === undefined ? undefined : toolNames?.get(callId))
495
+ ?? firstToolText(tool.title, update.title);
496
+ if (toolName === undefined && callId === undefined)
497
+ return null;
498
+ if (callId !== undefined && toolName !== undefined && toolName !== 'tool')
499
+ toolNames?.set(callId, toolName);
500
+ const inputValue = serializeToolValue(tool.rawInput ?? tool.input ?? tool.arguments ?? tool.args ?? update.rawInput);
501
+ const output = serializeToolValue(tool.rawOutput ?? tool.output ?? tool.result ?? update.rawOutput);
502
+ const error = serializeToolValue(tool.error ?? update.error);
503
+ const fallback = error !== undefined || type.includes('error') || type.includes('fail') ? 'failed' : output !== undefined || type.includes('complete') || type.includes('result') ? 'completed' : 'running';
504
+ return { type: 'tool-event', toolName: toolName ?? 'tool', status: normalizeToolStatus(tool.status ?? tool.state ?? update.status, fallback), ...(callId ? { callId } : {}), ...(inputValue !== undefined ? { input: inputValue } : {}), ...(output !== undefined ? { output, outputMode: type.includes('delta') ? 'delta' : 'snapshot' } : {}), ...(error !== undefined ? { error } : {}) };
505
+ }
506
+ return usageChunk(update);
507
+ }
508
+ /** ACP 版本间字段名不稳定;优先使用 Provider 的真实 assistant item 标识。 */
509
+ function qoderMessageId(update) {
510
+ const content = isRecord(update.content) ? update.content : undefined;
511
+ const meta = isRecord(update._meta) && isRecord(update._meta.qoder) ? update._meta.qoder : undefined;
512
+ return firstToolText(update.messageId, update.message_id, content?.messageId, content?.message_id, meta?.messageId, meta?.message_id);
513
+ }
514
+ function acpText(value) {
515
+ if (typeof value === 'string')
516
+ return value;
517
+ if (Array.isArray(value)) {
518
+ const text = value.map((item) => acpText(item) ?? '').join('');
519
+ return text === '' ? null : text;
520
+ }
521
+ if (!isRecord(value))
522
+ return null;
523
+ if (typeof value.text === 'string')
524
+ return value.text;
525
+ if (typeof value.delta === 'string')
526
+ return value.delta;
527
+ if (typeof value.content === 'string')
528
+ return value.content;
529
+ if (isRecord(value.content))
530
+ return acpText(value.content);
531
+ return null;
532
+ }
533
+ function createQoderTurnEventQueue() {
534
+ const pending = [];
535
+ let wake;
536
+ let closed = false;
537
+ return {
538
+ get terminated() { return closed; },
539
+ async next() {
540
+ if (pending.length > 0)
541
+ return { value: pending.shift(), done: false };
542
+ if (closed)
543
+ return { value: undefined, done: true };
544
+ await new Promise((resolve) => { wake = resolve; });
545
+ if (pending.length > 0)
546
+ return { value: pending.shift(), done: false };
547
+ return { value: undefined, done: true };
548
+ },
549
+ push(message) { pending.push(message); wake?.(); wake = undefined; },
550
+ close() { closed = true; wake?.(); wake = undefined; },
551
+ };
552
+ }
553
+ //# sourceMappingURL=qoder-driver.js.map