aws-runtime-bridge 1.9.78 → 1.9.80

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 (596) hide show
  1. package/dist/adapter/AcodeSdkAdapter.d.ts +0 -1
  2. package/dist/adapter/AcodeSdkAdapter.js +11 -1986
  3. package/dist/adapter/AdapterRegistry.d.ts +0 -1
  4. package/dist/adapter/AdapterRegistry.js +2 -100
  5. package/dist/adapter/ClaudeSdkAdapter.d.ts +0 -1
  6. package/dist/adapter/ClaudeSdkAdapter.js +4 -1300
  7. package/dist/adapter/CodexSdkAdapter.d.ts +0 -1
  8. package/dist/adapter/CodexSdkAdapter.js +4 -836
  9. package/dist/adapter/OpencodeSdkAdapter.d.ts +0 -1
  10. package/dist/adapter/OpencodeSdkAdapter.js +4 -879
  11. package/dist/adapter/SdkProviderSpi.d.ts +0 -1
  12. package/dist/adapter/SdkProviderSpi.js +2 -55
  13. package/dist/adapter/acode-tool-names.d.ts +0 -1
  14. package/dist/adapter/acode-tool-names.js +2 -37
  15. package/dist/adapter/idle-poll-loop.d.ts +0 -1
  16. package/dist/adapter/idle-poll-loop.js +2 -59
  17. package/dist/adapter/index.d.ts +0 -1
  18. package/dist/adapter/index.js +2 -11
  19. package/dist/adapter/instance-ai-config-resolver.d.ts +0 -1
  20. package/dist/adapter/instance-ai-config-resolver.js +2 -46
  21. package/dist/adapter/types.d.ts +0 -1
  22. package/dist/adapter/types.js +2 -443
  23. package/dist/adapters/cc-switch/common.d.ts +0 -1
  24. package/dist/adapters/cc-switch/common.js +2 -61
  25. package/dist/adapters/cc-switch/index.d.ts +0 -1
  26. package/dist/adapters/cc-switch/index.js +2 -57
  27. package/dist/adapters/cc-switch/mcp-acode.d.ts +0 -1
  28. package/dist/adapters/cc-switch/mcp-acode.js +2 -71
  29. package/dist/adapters/cc-switch/mcp-claude.d.ts +0 -1
  30. package/dist/adapters/cc-switch/mcp-claude.js +2 -89
  31. package/dist/adapters/cc-switch/mcp-claudecode.d.ts +0 -1
  32. package/dist/adapters/cc-switch/mcp-claudecode.js +2 -77
  33. package/dist/adapters/cc-switch/mcp-codex.d.ts +0 -1
  34. package/dist/adapters/cc-switch/mcp-codex.js +11 -249
  35. package/dist/adapters/cc-switch/mcp-opencode.d.ts +0 -1
  36. package/dist/adapters/cc-switch/mcp-opencode.js +2 -97
  37. package/dist/adapters/cc-switch/mcp-placeholder.d.ts +0 -1
  38. package/dist/adapters/cc-switch/mcp-placeholder.js +2 -19
  39. package/dist/adapters/cc-switch/skill-acode.d.ts +0 -1
  40. package/dist/adapters/cc-switch/skill-acode.js +2 -12
  41. package/dist/adapters/cc-switch/skill-claude.d.ts +0 -1
  42. package/dist/adapters/cc-switch/skill-claude.js +2 -11
  43. package/dist/adapters/cc-switch/skill-claudecode.d.ts +0 -1
  44. package/dist/adapters/cc-switch/skill-claudecode.js +2 -11
  45. package/dist/adapters/cc-switch/skill-codex.d.ts +0 -1
  46. package/dist/adapters/cc-switch/skill-codex.js +2 -6
  47. package/dist/adapters/cc-switch/skill-directory.d.ts +0 -1
  48. package/dist/adapters/cc-switch/skill-directory.js +3 -137
  49. package/dist/adapters/cc-switch/skill-opencode.d.ts +0 -1
  50. package/dist/adapters/cc-switch/skill-opencode.js +2 -11
  51. package/dist/adapters/cc-switch/skill-placeholder.d.ts +0 -1
  52. package/dist/adapters/cc-switch/skill-placeholder.js +2 -19
  53. package/dist/config.d.ts +0 -1
  54. package/dist/config.js +2 -290
  55. package/dist/index.d.ts +0 -1
  56. package/dist/index.js +2 -573
  57. package/dist/middleware/auth.d.ts +0 -1
  58. package/dist/middleware/auth.js +2 -98
  59. package/dist/routes/acode-todos.d.ts +0 -1
  60. package/dist/routes/acode-todos.js +2 -75
  61. package/dist/routes/ai-sources.d.ts +0 -1
  62. package/dist/routes/ai-sources.js +2 -132
  63. package/dist/routes/dashboard.d.ts +0 -1
  64. package/dist/routes/dashboard.js +182 -649
  65. package/dist/routes/events.d.ts +0 -1
  66. package/dist/routes/events.js +2 -22
  67. package/dist/routes/file-browser.d.ts +0 -1
  68. package/dist/routes/file-browser.js +2 -781
  69. package/dist/routes/file-diff-rollback.d.ts +0 -1
  70. package/dist/routes/file-diff-rollback.js +2 -301
  71. package/dist/routes/file-snapshot.d.ts +0 -1
  72. package/dist/routes/file-snapshot.js +2 -156
  73. package/dist/routes/git.d.ts +0 -1
  74. package/dist/routes/git.js +28 -1900
  75. package/dist/routes/instance.d.ts +0 -1
  76. package/dist/routes/instance.js +3 -748
  77. package/dist/routes/mcp.d.ts +0 -1
  78. package/dist/routes/mcp.js +2 -196
  79. package/dist/routes/processes.d.ts +0 -1
  80. package/dist/routes/processes.js +2 -252
  81. package/dist/routes/properties.d.ts +0 -1
  82. package/dist/routes/properties.js +2 -72
  83. package/dist/routes/pty.d.ts +0 -1
  84. package/dist/routes/pty.js +6 -560
  85. package/dist/routes/runtime-binding.d.ts +0 -1
  86. package/dist/routes/runtime-binding.js +2 -263
  87. package/dist/routes/sessions.d.ts +0 -1
  88. package/dist/routes/sessions.js +2 -758
  89. package/dist/routes/skills.d.ts +0 -1
  90. package/dist/routes/skills.js +2 -187
  91. package/dist/routes/sub-agents.d.ts +0 -1
  92. package/dist/routes/sub-agents.js +20 -279
  93. package/dist/routes/system-metrics.d.ts +0 -1
  94. package/dist/routes/system-metrics.js +2 -20
  95. package/dist/routes/task-context.d.ts +0 -1
  96. package/dist/routes/task-context.js +2 -78
  97. package/dist/routes/terminal.d.ts +0 -1
  98. package/dist/routes/terminal.js +54 -2882
  99. package/dist/routes/yml.d.ts +0 -1
  100. package/dist/routes/yml.js +2 -223
  101. package/dist/services/acode-package.d.ts +0 -1
  102. package/dist/services/acode-package.js +2 -111
  103. package/dist/services/agent-event-store.d.ts +0 -1
  104. package/dist/services/agent-event-store.js +2 -81
  105. package/dist/services/agent-process-manager.d.ts +0 -1
  106. package/dist/services/agent-process-manager.js +2 -796
  107. package/dist/services/ai-source-apply.d.ts +0 -1
  108. package/dist/services/ai-source-apply.js +2 -83
  109. package/dist/services/auto-register.d.ts +0 -1
  110. package/dist/services/auto-register.js +2 -1053
  111. package/dist/services/aws-client-agent-mcp.d.ts +0 -1
  112. package/dist/services/aws-client-agent-mcp.js +3 -337
  113. package/dist/services/bridge-package-publish-hooks.d.ts +0 -1
  114. package/dist/services/bridge-package-publish-hooks.js +2 -115
  115. package/dist/services/cc-switch-sdk.d.ts +0 -1
  116. package/dist/services/cc-switch-sdk.js +2 -135
  117. package/dist/services/cli-commands.d.ts +6 -1
  118. package/dist/services/cli-commands.js +6 -645
  119. package/dist/services/event-delta-pusher.d.ts +0 -1
  120. package/dist/services/event-delta-pusher.js +2 -95
  121. package/dist/services/fileSnapshotStore.d.ts +0 -1
  122. package/dist/services/fileSnapshotStore.js +2 -500
  123. package/dist/services/instance-ai-config-service.d.ts +0 -1
  124. package/dist/services/instance-ai-config-service.js +2 -174
  125. package/dist/services/instance-init-service.d.ts +0 -1
  126. package/dist/services/instance-init-service.js +2 -193
  127. package/dist/services/instance-service.d.ts +0 -1
  128. package/dist/services/instance-service.js +2 -237
  129. package/dist/services/instance-state.d.ts +0 -1
  130. package/dist/services/instance-state.js +2 -94
  131. package/dist/services/legacy-path-migration.d.ts +0 -1
  132. package/dist/services/legacy-path-migration.js +2 -66
  133. package/dist/services/lifecycle-state.d.ts +0 -1
  134. package/dist/services/lifecycle-state.js +3 -110
  135. package/dist/services/mcp-launch-binding-queue.d.ts +0 -1
  136. package/dist/services/mcp-launch-binding-queue.js +2 -175
  137. package/dist/services/orphan-monitor.d.ts +0 -1
  138. package/dist/services/orphan-monitor.js +2 -382
  139. package/dist/services/panel-auth.d.ts +0 -1
  140. package/dist/services/panel-auth.js +2 -168
  141. package/dist/services/process-detector.d.ts +0 -1
  142. package/dist/services/process-detector.js +18 -1019
  143. package/dist/services/process-registry.d.ts +0 -1
  144. package/dist/services/process-registry.js +2 -375
  145. package/dist/services/ring-buffer.d.ts +0 -1
  146. package/dist/services/ring-buffer.js +2 -103
  147. package/dist/services/runtime-binding.d.ts +0 -1
  148. package/dist/services/runtime-binding.js +6 -363
  149. package/dist/services/runtime-lifecycle-policy.d.ts +0 -1
  150. package/dist/services/runtime-lifecycle-policy.js +2 -35
  151. package/dist/services/session-output.d.ts +0 -1
  152. package/dist/services/session-output.js +5 -539
  153. package/dist/services/startup-config-wizard.d.ts +0 -1
  154. package/dist/services/startup-config-wizard.js +14 -258
  155. package/dist/services/sub-agent-manager-instance.d.ts +0 -1
  156. package/dist/services/sub-agent-manager-instance.js +2 -12
  157. package/dist/services/system-metrics.d.ts +0 -1
  158. package/dist/services/system-metrics.js +2 -252
  159. package/dist/services/terminal-persistence.d.ts +0 -1
  160. package/dist/services/terminal-persistence.js +2 -176
  161. package/dist/services/tool-installer.d.ts +0 -1
  162. package/dist/services/tool-installer.js +5 -751
  163. package/dist/services/tunnel-client.d.ts +0 -1
  164. package/dist/services/tunnel-client.js +2 -402
  165. package/dist/services/windows-service-manager.d.ts +3 -2
  166. package/dist/services/windows-service-manager.js +2 -54
  167. package/dist/services/workspace-files.d.ts +0 -1
  168. package/dist/services/workspace-files.js +2 -1275
  169. package/dist/services/workspace-watch.d.ts +0 -1
  170. package/dist/services/workspace-watch.js +2 -123
  171. package/dist/services/workspaceTaskChangeWatcher.d.ts +0 -1
  172. package/dist/services/workspaceTaskChangeWatcher.js +2 -483
  173. package/dist/types.d.ts +0 -1
  174. package/dist/types.js +1 -1
  175. package/dist/utils/file-utils.d.ts +0 -1
  176. package/dist/utils/file-utils.js +3 -208
  177. package/dist/utils/instance-ai-config-debug-logger.d.ts +0 -1
  178. package/dist/utils/instance-ai-config-debug-logger.js +4 -63
  179. package/dist/utils/logger.d.ts +0 -1
  180. package/dist/utils/logger.js +2 -154
  181. package/dist/utils/mcp-utils.d.ts +0 -1
  182. package/dist/utils/mcp-utils.js +2 -187
  183. package/dist/utils/path-utils.d.ts +0 -1
  184. package/dist/utils/path-utils.js +2 -44
  185. package/dist/utils/sdk-package-loader.d.ts +0 -1
  186. package/dist/utils/sdk-package-loader.js +2 -78
  187. package/dist/utils/validation.d.ts +0 -1
  188. package/dist/utils/validation.js +2 -53
  189. package/dist/utils/yaml-utils.d.ts +0 -1
  190. package/dist/utils/yaml-utils.js +2 -312
  191. package/node_modules/@cc-switch/sdk/dist/constants.d.ts +0 -1
  192. package/node_modules/@cc-switch/sdk/dist/constants.js +2 -63
  193. package/node_modules/@cc-switch/sdk/dist/errors.d.ts +0 -1
  194. package/node_modules/@cc-switch/sdk/dist/errors.js +2 -8
  195. package/node_modules/@cc-switch/sdk/dist/index.d.ts +0 -1
  196. package/node_modules/@cc-switch/sdk/dist/index.js +2 -9
  197. package/node_modules/@cc-switch/sdk/dist/schemas.d.ts +0 -1
  198. package/node_modules/@cc-switch/sdk/dist/schemas.js +2 -38
  199. package/node_modules/@cc-switch/sdk/dist/sdk.d.ts +0 -1
  200. package/node_modules/@cc-switch/sdk/dist/sdk.js +2 -470
  201. package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.d.ts +0 -1
  202. package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.js +4 -307
  203. package/node_modules/@cc-switch/sdk/dist/services/mcp-model.d.ts +0 -1
  204. package/node_modules/@cc-switch/sdk/dist/services/mcp-model.js +2 -37
  205. package/node_modules/@cc-switch/sdk/dist/services/mcp-service.d.ts +0 -1
  206. package/node_modules/@cc-switch/sdk/dist/services/mcp-service.js +2 -9
  207. package/node_modules/@cc-switch/sdk/dist/services/skill-model.d.ts +0 -1
  208. package/node_modules/@cc-switch/sdk/dist/services/skill-model.js +2 -41
  209. package/node_modules/@cc-switch/sdk/dist/services/skill-service.d.ts +0 -1
  210. package/node_modules/@cc-switch/sdk/dist/services/skill-service.js +2 -9
  211. package/node_modules/@cc-switch/sdk/dist/state.d.ts +0 -1
  212. package/node_modules/@cc-switch/sdk/dist/state.js +2 -19
  213. package/node_modules/@cc-switch/sdk/dist/types.d.ts +0 -1
  214. package/node_modules/@cc-switch/sdk/dist/types.js +1 -1
  215. package/node_modules/@cc-switch/sdk/dist/utils/fs.d.ts +0 -1
  216. package/node_modules/@cc-switch/sdk/dist/utils/fs.js +3 -114
  217. package/node_modules/@cc-switch/sdk/dist/utils/id.d.ts +0 -1
  218. package/node_modules/@cc-switch/sdk/dist/utils/id.js +2 -12
  219. package/node_modules/@cc-switch/sdk/package.json +1 -1
  220. package/package/acode/dist/ask-user-question-tool.d.ts +0 -1
  221. package/package/acode/dist/ask-user-question-tool.js +4 -233
  222. package/package/acode/dist/built-in-file-tools.d.ts +0 -1
  223. package/package/acode/dist/built-in-file-tools.js +4 -966
  224. package/package/acode/dist/built-in-symbols-tool.d.ts +0 -1
  225. package/package/acode/dist/built-in-symbols-tool.js +2 -117
  226. package/package/acode/dist/builtins/commandArtifacts.d.ts +0 -1
  227. package/package/acode/dist/builtins/commandArtifacts.js +9 -97
  228. package/package/acode/dist/builtins/commandOutputEvents.d.ts +0 -1
  229. package/package/acode/dist/builtins/commandOutputEvents.js +2 -56
  230. package/package/acode/dist/builtins/shellCommandPreparation.d.ts +0 -1
  231. package/package/acode/dist/builtins/shellCommandPreparation.js +5 -44
  232. package/package/acode/dist/builtins/shellCommandResult.d.ts +0 -1
  233. package/package/acode/dist/builtins/shellCommandResult.js +2 -71
  234. package/package/acode/dist/builtins/shellCommandRunner.d.ts +0 -1
  235. package/package/acode/dist/builtins/shellCommandRunner.js +2 -115
  236. package/package/acode/dist/builtins/shellOutputDecoder.d.ts +0 -1
  237. package/package/acode/dist/builtins/shellOutputDecoder.js +2 -94
  238. package/package/acode/dist/cli.d.ts +0 -1
  239. package/package/acode/dist/cli.js +4 -38
  240. package/package/acode/dist/commands/commandLoader.d.ts +0 -1
  241. package/package/acode/dist/commands/commandLoader.js +2 -33
  242. package/package/acode/dist/commands/commandParser.d.ts +0 -1
  243. package/package/acode/dist/commands/commandParser.js +3 -77
  244. package/package/acode/dist/commands/commandRegistry.d.ts +0 -1
  245. package/package/acode/dist/commands/commandRegistry.js +2 -30
  246. package/package/acode/dist/compaction.d.ts +0 -1
  247. package/package/acode/dist/compaction.js +7 -919
  248. package/package/acode/dist/config.d.ts +0 -1
  249. package/package/acode/dist/config.js +5 -105
  250. package/package/acode/dist/fs-utils.d.ts +0 -1
  251. package/package/acode/dist/fs-utils.js +2 -79
  252. package/package/acode/dist/hooks/hookBus.d.ts +0 -1
  253. package/package/acode/dist/hooks/hookBus.js +2 -40
  254. package/package/acode/dist/index.d.ts +0 -1
  255. package/package/acode/dist/index.js +2 -19
  256. package/package/acode/dist/mcpToolNames.d.ts +0 -1
  257. package/package/acode/dist/mcpToolNames.js +2 -17
  258. package/package/acode/dist/parsers/ast-cache.d.ts +0 -1
  259. package/package/acode/dist/parsers/ast-cache.js +2 -76
  260. package/package/acode/dist/parsers/language-detector.d.ts +0 -1
  261. package/package/acode/dist/parsers/language-detector.js +2 -44
  262. package/package/acode/dist/parsers/language-queries.d.ts +0 -1
  263. package/package/acode/dist/parsers/language-queries.js +12 -602
  264. package/package/acode/dist/parsers/symbol-extractor.d.ts +0 -1
  265. package/package/acode/dist/parsers/symbol-extractor.js +3 -164
  266. package/package/acode/dist/parsers/tree-sitter-loader.d.ts +0 -1
  267. package/package/acode/dist/parsers/tree-sitter-loader.js +2 -64
  268. package/package/acode/dist/parsers/types.d.ts +0 -1
  269. package/package/acode/dist/parsers/types.js +1 -7
  270. package/package/acode/dist/runtime.d.ts +0 -1
  271. package/package/acode/dist/runtime.js +86 -3771
  272. package/package/acode/dist/skill-tool.d.ts +0 -1
  273. package/package/acode/dist/skill-tool.js +5 -174
  274. package/package/acode/dist/sub-agent-manager.d.ts +0 -1
  275. package/package/acode/dist/sub-agent-manager.js +2 -1159
  276. package/package/acode/dist/sub-agent-store.d.ts +0 -1
  277. package/package/acode/dist/sub-agent-store.js +4 -236
  278. package/package/acode/dist/sub-agent-tools.d.ts +0 -1
  279. package/package/acode/dist/sub-agent-tools.js +15 -369
  280. package/package/acode/dist/sub-agent-types.d.ts +0 -1
  281. package/package/acode/dist/sub-agent-types.js +1 -8
  282. package/package/acode/dist/todo-store.d.ts +0 -1
  283. package/package/acode/dist/todo-store.js +2 -73
  284. package/package/acode/dist/todo-tool.d.ts +0 -1
  285. package/package/acode/dist/todo-tool.js +5 -121
  286. package/package/acode/dist/types.d.ts +0 -1
  287. package/package/acode/dist/types.js +1 -1
  288. package/package/acode/package.json +2 -2
  289. package/package/aws-client-agent-mcp/dist/agent-client.d.ts +0 -1
  290. package/package/aws-client-agent-mcp/dist/agent-client.js +2 -890
  291. package/package/aws-client-agent-mcp/dist/agent-client.test.d.ts +0 -1
  292. package/package/aws-client-agent-mcp/dist/agent-client.test.js +0 -1
  293. package/package/aws-client-agent-mcp/dist/config.d.ts +0 -1
  294. package/package/aws-client-agent-mcp/dist/config.js +2 -243
  295. package/package/aws-client-agent-mcp/dist/config.test.d.ts +0 -1
  296. package/package/aws-client-agent-mcp/dist/config.test.js +0 -1
  297. package/package/aws-client-agent-mcp/dist/constants.d.ts +0 -1
  298. package/package/aws-client-agent-mcp/dist/constants.js +2 -24
  299. package/package/aws-client-agent-mcp/dist/context-manager.d.ts +0 -1
  300. package/package/aws-client-agent-mcp/dist/context-manager.js +2 -477
  301. package/package/aws-client-agent-mcp/dist/context-manager.test.d.ts +0 -1
  302. package/package/aws-client-agent-mcp/dist/context-manager.test.js +0 -1
  303. package/package/aws-client-agent-mcp/dist/http-client.d.ts +0 -1
  304. package/package/aws-client-agent-mcp/dist/http-client.js +2 -446
  305. package/package/aws-client-agent-mcp/dist/http-client.test.d.ts +0 -1
  306. package/package/aws-client-agent-mcp/dist/http-client.test.js +0 -1
  307. package/package/aws-client-agent-mcp/dist/index.d.ts +0 -1
  308. package/package/aws-client-agent-mcp/dist/index.js +2 -34
  309. package/package/aws-client-agent-mcp/dist/logger.d.ts +0 -1
  310. package/package/aws-client-agent-mcp/dist/logger.js +3 -178
  311. package/package/aws-client-agent-mcp/dist/logger.test.d.ts +0 -1
  312. package/package/aws-client-agent-mcp/dist/logger.test.js +0 -1
  313. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +0 -1
  314. package/package/aws-client-agent-mcp/dist/mcp-server.js +38 -2709
  315. package/package/aws-client-agent-mcp/dist/mcp-server.test.d.ts +0 -1
  316. package/package/aws-client-agent-mcp/dist/mcp-server.test.js +0 -1
  317. package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +0 -1
  318. package/package/aws-client-agent-mcp/dist/mcp-tools.js +22 -562
  319. package/package/aws-client-agent-mcp/dist/mcp-tools.test.d.ts +0 -1
  320. package/package/aws-client-agent-mcp/dist/mcp-tools.test.js +0 -1
  321. package/package/aws-client-agent-mcp/dist/memory-store.d.ts +0 -1
  322. package/package/aws-client-agent-mcp/dist/memory-store.js +4 -826
  323. package/package/aws-client-agent-mcp/dist/memory-store.test.d.ts +0 -1
  324. package/package/aws-client-agent-mcp/dist/memory-store.test.js +0 -1
  325. package/package/aws-client-agent-mcp/dist/memory-tools.d.ts +0 -1
  326. package/package/aws-client-agent-mcp/dist/memory-tools.js +31 -294
  327. package/package/aws-client-agent-mcp/dist/message-buffer.d.ts +0 -1
  328. package/package/aws-client-agent-mcp/dist/message-buffer.js +2 -288
  329. package/package/aws-client-agent-mcp/dist/message-buffer.test.d.ts +0 -1
  330. package/package/aws-client-agent-mcp/dist/message-buffer.test.js +0 -1
  331. package/package/aws-client-agent-mcp/dist/messageContent.d.ts +0 -1
  332. package/package/aws-client-agent-mcp/dist/messageContent.js +2 -125
  333. package/package/aws-client-agent-mcp/dist/runtime-launch-binding.d.ts +0 -1
  334. package/package/aws-client-agent-mcp/dist/runtime-launch-binding.js +2 -103
  335. package/package/aws-client-agent-mcp/dist/runtime-launch-binding.test.d.ts +0 -1
  336. package/package/aws-client-agent-mcp/dist/runtime-launch-binding.test.js +0 -1
  337. package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts +0 -1
  338. package/package/aws-client-agent-mcp/dist/server-memory-store.js +2 -96
  339. package/package/aws-client-agent-mcp/dist/status-reporter.d.ts +0 -1
  340. package/package/aws-client-agent-mcp/dist/status-reporter.js +3 -327
  341. package/package/aws-client-agent-mcp/dist/status-reporter.test.d.ts +0 -1
  342. package/package/aws-client-agent-mcp/dist/status-reporter.test.js +0 -1
  343. package/package/aws-client-agent-mcp/dist/types.d.ts +0 -1
  344. package/package/aws-client-agent-mcp/dist/types.js +2 -9
  345. package/package/aws-client-agent-mcp/dist/websocket-client.d.ts +0 -1
  346. package/package/aws-client-agent-mcp/dist/websocket-client.js +2 -677
  347. package/package/aws-client-agent-mcp/dist/websocket-client.test.d.ts +0 -1
  348. package/package/aws-client-agent-mcp/dist/websocket-client.test.js +0 -1
  349. package/package/aws-client-agent-mcp/package.json +1 -1
  350. package/package/cc-switch-sdk/dist/constants.d.ts +0 -1
  351. package/package/cc-switch-sdk/dist/constants.js +2 -63
  352. package/package/cc-switch-sdk/dist/errors.d.ts +0 -1
  353. package/package/cc-switch-sdk/dist/errors.js +2 -8
  354. package/package/cc-switch-sdk/dist/index.d.ts +0 -1
  355. package/package/cc-switch-sdk/dist/index.js +2 -9
  356. package/package/cc-switch-sdk/dist/schemas.d.ts +0 -1
  357. package/package/cc-switch-sdk/dist/schemas.js +2 -38
  358. package/package/cc-switch-sdk/dist/sdk.d.ts +0 -1
  359. package/package/cc-switch-sdk/dist/sdk.js +2 -470
  360. package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts +0 -1
  361. package/package/cc-switch-sdk/dist/services/ai-config-service.js +4 -307
  362. package/package/cc-switch-sdk/dist/services/mcp-model.d.ts +0 -1
  363. package/package/cc-switch-sdk/dist/services/mcp-model.js +2 -37
  364. package/package/cc-switch-sdk/dist/services/mcp-service.d.ts +0 -1
  365. package/package/cc-switch-sdk/dist/services/mcp-service.js +2 -9
  366. package/package/cc-switch-sdk/dist/services/skill-model.d.ts +0 -1
  367. package/package/cc-switch-sdk/dist/services/skill-model.js +2 -41
  368. package/package/cc-switch-sdk/dist/services/skill-service.d.ts +0 -1
  369. package/package/cc-switch-sdk/dist/services/skill-service.js +2 -9
  370. package/package/cc-switch-sdk/dist/state.d.ts +0 -1
  371. package/package/cc-switch-sdk/dist/state.js +2 -19
  372. package/package/cc-switch-sdk/dist/types.d.ts +0 -1
  373. package/package/cc-switch-sdk/dist/types.js +1 -1
  374. package/package/cc-switch-sdk/dist/utils/fs.d.ts +0 -1
  375. package/package/cc-switch-sdk/dist/utils/fs.js +3 -114
  376. package/package/cc-switch-sdk/dist/utils/id.d.ts +0 -1
  377. package/package/cc-switch-sdk/dist/utils/id.js +2 -12
  378. package/package/cc-switch-sdk/package.json +1 -1
  379. package/package.json +4 -2
  380. package/dist/adapter/AcodeSdkAdapter.d.ts.map +0 -1
  381. package/dist/adapter/AdapterRegistry.d.ts.map +0 -1
  382. package/dist/adapter/ClaudeSdkAdapter.d.ts.map +0 -1
  383. package/dist/adapter/CodexSdkAdapter.d.ts.map +0 -1
  384. package/dist/adapter/OpencodeSdkAdapter.d.ts.map +0 -1
  385. package/dist/adapter/SdkProviderSpi.d.ts.map +0 -1
  386. package/dist/adapter/acode-tool-names.d.ts.map +0 -1
  387. package/dist/adapter/idle-poll-loop.d.ts.map +0 -1
  388. package/dist/adapter/index.d.ts.map +0 -1
  389. package/dist/adapter/instance-ai-config-resolver.d.ts.map +0 -1
  390. package/dist/adapter/types.d.ts.map +0 -1
  391. package/dist/adapters/cc-switch/common.d.ts.map +0 -1
  392. package/dist/adapters/cc-switch/index.d.ts.map +0 -1
  393. package/dist/adapters/cc-switch/mcp-acode.d.ts.map +0 -1
  394. package/dist/adapters/cc-switch/mcp-claude.d.ts.map +0 -1
  395. package/dist/adapters/cc-switch/mcp-claudecode.d.ts.map +0 -1
  396. package/dist/adapters/cc-switch/mcp-codex.d.ts.map +0 -1
  397. package/dist/adapters/cc-switch/mcp-opencode.d.ts.map +0 -1
  398. package/dist/adapters/cc-switch/mcp-placeholder.d.ts.map +0 -1
  399. package/dist/adapters/cc-switch/skill-acode.d.ts.map +0 -1
  400. package/dist/adapters/cc-switch/skill-claude.d.ts.map +0 -1
  401. package/dist/adapters/cc-switch/skill-claudecode.d.ts.map +0 -1
  402. package/dist/adapters/cc-switch/skill-codex.d.ts.map +0 -1
  403. package/dist/adapters/cc-switch/skill-directory.d.ts.map +0 -1
  404. package/dist/adapters/cc-switch/skill-opencode.d.ts.map +0 -1
  405. package/dist/adapters/cc-switch/skill-placeholder.d.ts.map +0 -1
  406. package/dist/config.d.ts.map +0 -1
  407. package/dist/index.d.ts.map +0 -1
  408. package/dist/middleware/auth.d.ts.map +0 -1
  409. package/dist/routes/acode-todos.d.ts.map +0 -1
  410. package/dist/routes/ai-sources.d.ts.map +0 -1
  411. package/dist/routes/dashboard.d.ts.map +0 -1
  412. package/dist/routes/events.d.ts.map +0 -1
  413. package/dist/routes/file-browser.d.ts.map +0 -1
  414. package/dist/routes/file-diff-rollback.d.ts.map +0 -1
  415. package/dist/routes/file-snapshot.d.ts.map +0 -1
  416. package/dist/routes/git.d.ts.map +0 -1
  417. package/dist/routes/instance.d.ts.map +0 -1
  418. package/dist/routes/mcp.d.ts.map +0 -1
  419. package/dist/routes/processes.d.ts.map +0 -1
  420. package/dist/routes/properties.d.ts.map +0 -1
  421. package/dist/routes/pty.d.ts.map +0 -1
  422. package/dist/routes/runtime-binding.d.ts.map +0 -1
  423. package/dist/routes/sessions.d.ts.map +0 -1
  424. package/dist/routes/skills.d.ts.map +0 -1
  425. package/dist/routes/sub-agents.d.ts.map +0 -1
  426. package/dist/routes/system-metrics.d.ts.map +0 -1
  427. package/dist/routes/task-context.d.ts.map +0 -1
  428. package/dist/routes/terminal.d.ts.map +0 -1
  429. package/dist/routes/yml.d.ts.map +0 -1
  430. package/dist/services/acode-package.d.ts.map +0 -1
  431. package/dist/services/agent-event-store.d.ts.map +0 -1
  432. package/dist/services/agent-process-manager.d.ts.map +0 -1
  433. package/dist/services/ai-source-apply.d.ts.map +0 -1
  434. package/dist/services/auto-register.d.ts.map +0 -1
  435. package/dist/services/aws-client-agent-mcp.d.ts.map +0 -1
  436. package/dist/services/bridge-package-publish-hooks.d.ts.map +0 -1
  437. package/dist/services/cc-switch-sdk.d.ts.map +0 -1
  438. package/dist/services/cli-commands.d.ts.map +0 -1
  439. package/dist/services/event-delta-pusher.d.ts.map +0 -1
  440. package/dist/services/fileSnapshotStore.d.ts.map +0 -1
  441. package/dist/services/instance-ai-config-service.d.ts.map +0 -1
  442. package/dist/services/instance-init-service.d.ts.map +0 -1
  443. package/dist/services/instance-service.d.ts.map +0 -1
  444. package/dist/services/instance-state.d.ts.map +0 -1
  445. package/dist/services/legacy-path-migration.d.ts.map +0 -1
  446. package/dist/services/lifecycle-state.d.ts.map +0 -1
  447. package/dist/services/mcp-launch-binding-queue.d.ts.map +0 -1
  448. package/dist/services/orphan-monitor.d.ts.map +0 -1
  449. package/dist/services/panel-auth.d.ts.map +0 -1
  450. package/dist/services/process-detector.d.ts.map +0 -1
  451. package/dist/services/process-registry.d.ts.map +0 -1
  452. package/dist/services/ring-buffer.d.ts.map +0 -1
  453. package/dist/services/runtime-binding.d.ts.map +0 -1
  454. package/dist/services/runtime-lifecycle-policy.d.ts.map +0 -1
  455. package/dist/services/session-output.d.ts.map +0 -1
  456. package/dist/services/startup-config-wizard.d.ts.map +0 -1
  457. package/dist/services/sub-agent-manager-instance.d.ts.map +0 -1
  458. package/dist/services/system-metrics.d.ts.map +0 -1
  459. package/dist/services/terminal-persistence.d.ts.map +0 -1
  460. package/dist/services/tool-installer.d.ts.map +0 -1
  461. package/dist/services/tunnel-client.d.ts.map +0 -1
  462. package/dist/services/windows-service-manager.d.ts.map +0 -1
  463. package/dist/services/workspace-files.d.ts.map +0 -1
  464. package/dist/services/workspace-watch.d.ts.map +0 -1
  465. package/dist/services/workspaceTaskChangeWatcher.d.ts.map +0 -1
  466. package/dist/types.d.ts.map +0 -1
  467. package/dist/utils/file-utils.d.ts.map +0 -1
  468. package/dist/utils/instance-ai-config-debug-logger.d.ts.map +0 -1
  469. package/dist/utils/logger.d.ts.map +0 -1
  470. package/dist/utils/mcp-utils.d.ts.map +0 -1
  471. package/dist/utils/path-utils.d.ts.map +0 -1
  472. package/dist/utils/sdk-package-loader.d.ts.map +0 -1
  473. package/dist/utils/validation.d.ts.map +0 -1
  474. package/dist/utils/yaml-utils.d.ts.map +0 -1
  475. package/node_modules/@cc-switch/sdk/dist/constants.d.ts.map +0 -1
  476. package/node_modules/@cc-switch/sdk/dist/errors.d.ts.map +0 -1
  477. package/node_modules/@cc-switch/sdk/dist/index.d.ts.map +0 -1
  478. package/node_modules/@cc-switch/sdk/dist/schemas.d.ts.map +0 -1
  479. package/node_modules/@cc-switch/sdk/dist/sdk.d.ts.map +0 -1
  480. package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.d.ts.map +0 -1
  481. package/node_modules/@cc-switch/sdk/dist/services/mcp-model.d.ts.map +0 -1
  482. package/node_modules/@cc-switch/sdk/dist/services/mcp-service.d.ts.map +0 -1
  483. package/node_modules/@cc-switch/sdk/dist/services/skill-model.d.ts.map +0 -1
  484. package/node_modules/@cc-switch/sdk/dist/services/skill-service.d.ts.map +0 -1
  485. package/node_modules/@cc-switch/sdk/dist/state.d.ts.map +0 -1
  486. package/node_modules/@cc-switch/sdk/dist/types.d.ts.map +0 -1
  487. package/node_modules/@cc-switch/sdk/dist/utils/fs.d.ts.map +0 -1
  488. package/node_modules/@cc-switch/sdk/dist/utils/id.d.ts.map +0 -1
  489. package/package/acode/dist/ask-user-question-tool.d.ts.map +0 -1
  490. package/package/acode/dist/built-in-file-tools.d.ts.map +0 -1
  491. package/package/acode/dist/built-in-symbols-tool.d.ts.map +0 -1
  492. package/package/acode/dist/builtins/commandArtifacts.d.ts.map +0 -1
  493. package/package/acode/dist/builtins/commandOutputEvents.d.ts.map +0 -1
  494. package/package/acode/dist/builtins/shellCommandPreparation.d.ts.map +0 -1
  495. package/package/acode/dist/builtins/shellCommandResult.d.ts.map +0 -1
  496. package/package/acode/dist/builtins/shellCommandRunner.d.ts.map +0 -1
  497. package/package/acode/dist/builtins/shellOutputDecoder.d.ts.map +0 -1
  498. package/package/acode/dist/cli.d.ts.map +0 -1
  499. package/package/acode/dist/commands/commandLoader.d.ts.map +0 -1
  500. package/package/acode/dist/commands/commandParser.d.ts.map +0 -1
  501. package/package/acode/dist/commands/commandRegistry.d.ts.map +0 -1
  502. package/package/acode/dist/compaction.d.ts.map +0 -1
  503. package/package/acode/dist/config.d.ts.map +0 -1
  504. package/package/acode/dist/fs-utils.d.ts.map +0 -1
  505. package/package/acode/dist/hooks/hookBus.d.ts.map +0 -1
  506. package/package/acode/dist/index.d.ts.map +0 -1
  507. package/package/acode/dist/mcpToolNames.d.ts.map +0 -1
  508. package/package/acode/dist/parsers/ast-cache.d.ts.map +0 -1
  509. package/package/acode/dist/parsers/language-detector.d.ts.map +0 -1
  510. package/package/acode/dist/parsers/language-queries.d.ts.map +0 -1
  511. package/package/acode/dist/parsers/symbol-extractor.d.ts.map +0 -1
  512. package/package/acode/dist/parsers/tree-sitter-loader.d.ts.map +0 -1
  513. package/package/acode/dist/parsers/types.d.ts.map +0 -1
  514. package/package/acode/dist/runtime.d.ts.map +0 -1
  515. package/package/acode/dist/skill-tool.d.ts.map +0 -1
  516. package/package/acode/dist/sub-agent-manager.d.ts.map +0 -1
  517. package/package/acode/dist/sub-agent-store.d.ts.map +0 -1
  518. package/package/acode/dist/sub-agent-tools.d.ts.map +0 -1
  519. package/package/acode/dist/sub-agent-types.d.ts.map +0 -1
  520. package/package/acode/dist/todo-store.d.ts.map +0 -1
  521. package/package/acode/dist/todo-tool.d.ts.map +0 -1
  522. package/package/acode/dist/types.d.ts.map +0 -1
  523. package/package/aws-client-agent-mcp/dist/agent-client.d.ts.map +0 -1
  524. package/package/aws-client-agent-mcp/dist/agent-client.js.map +0 -1
  525. package/package/aws-client-agent-mcp/dist/agent-client.test.d.ts.map +0 -1
  526. package/package/aws-client-agent-mcp/dist/agent-client.test.js.map +0 -1
  527. package/package/aws-client-agent-mcp/dist/config.d.ts.map +0 -1
  528. package/package/aws-client-agent-mcp/dist/config.js.map +0 -1
  529. package/package/aws-client-agent-mcp/dist/config.test.d.ts.map +0 -1
  530. package/package/aws-client-agent-mcp/dist/config.test.js.map +0 -1
  531. package/package/aws-client-agent-mcp/dist/constants.d.ts.map +0 -1
  532. package/package/aws-client-agent-mcp/dist/constants.js.map +0 -1
  533. package/package/aws-client-agent-mcp/dist/context-manager.d.ts.map +0 -1
  534. package/package/aws-client-agent-mcp/dist/context-manager.js.map +0 -1
  535. package/package/aws-client-agent-mcp/dist/context-manager.test.d.ts.map +0 -1
  536. package/package/aws-client-agent-mcp/dist/context-manager.test.js.map +0 -1
  537. package/package/aws-client-agent-mcp/dist/http-client.d.ts.map +0 -1
  538. package/package/aws-client-agent-mcp/dist/http-client.js.map +0 -1
  539. package/package/aws-client-agent-mcp/dist/http-client.test.d.ts.map +0 -1
  540. package/package/aws-client-agent-mcp/dist/http-client.test.js.map +0 -1
  541. package/package/aws-client-agent-mcp/dist/index.d.ts.map +0 -1
  542. package/package/aws-client-agent-mcp/dist/index.js.map +0 -1
  543. package/package/aws-client-agent-mcp/dist/logger.d.ts.map +0 -1
  544. package/package/aws-client-agent-mcp/dist/logger.js.map +0 -1
  545. package/package/aws-client-agent-mcp/dist/logger.test.d.ts.map +0 -1
  546. package/package/aws-client-agent-mcp/dist/logger.test.js.map +0 -1
  547. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +0 -1
  548. package/package/aws-client-agent-mcp/dist/mcp-server.js.map +0 -1
  549. package/package/aws-client-agent-mcp/dist/mcp-server.test.d.ts.map +0 -1
  550. package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +0 -1
  551. package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts.map +0 -1
  552. package/package/aws-client-agent-mcp/dist/mcp-tools.js.map +0 -1
  553. package/package/aws-client-agent-mcp/dist/mcp-tools.test.d.ts.map +0 -1
  554. package/package/aws-client-agent-mcp/dist/mcp-tools.test.js.map +0 -1
  555. package/package/aws-client-agent-mcp/dist/memory-store.d.ts.map +0 -1
  556. package/package/aws-client-agent-mcp/dist/memory-store.js.map +0 -1
  557. package/package/aws-client-agent-mcp/dist/memory-store.test.d.ts.map +0 -1
  558. package/package/aws-client-agent-mcp/dist/memory-store.test.js.map +0 -1
  559. package/package/aws-client-agent-mcp/dist/memory-tools.d.ts.map +0 -1
  560. package/package/aws-client-agent-mcp/dist/memory-tools.js.map +0 -1
  561. package/package/aws-client-agent-mcp/dist/message-buffer.d.ts.map +0 -1
  562. package/package/aws-client-agent-mcp/dist/message-buffer.js.map +0 -1
  563. package/package/aws-client-agent-mcp/dist/message-buffer.test.d.ts.map +0 -1
  564. package/package/aws-client-agent-mcp/dist/message-buffer.test.js.map +0 -1
  565. package/package/aws-client-agent-mcp/dist/messageContent.d.ts.map +0 -1
  566. package/package/aws-client-agent-mcp/dist/messageContent.js.map +0 -1
  567. package/package/aws-client-agent-mcp/dist/runtime-launch-binding.d.ts.map +0 -1
  568. package/package/aws-client-agent-mcp/dist/runtime-launch-binding.js.map +0 -1
  569. package/package/aws-client-agent-mcp/dist/runtime-launch-binding.test.d.ts.map +0 -1
  570. package/package/aws-client-agent-mcp/dist/runtime-launch-binding.test.js.map +0 -1
  571. package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts.map +0 -1
  572. package/package/aws-client-agent-mcp/dist/server-memory-store.js.map +0 -1
  573. package/package/aws-client-agent-mcp/dist/status-reporter.d.ts.map +0 -1
  574. package/package/aws-client-agent-mcp/dist/status-reporter.js.map +0 -1
  575. package/package/aws-client-agent-mcp/dist/status-reporter.test.d.ts.map +0 -1
  576. package/package/aws-client-agent-mcp/dist/status-reporter.test.js.map +0 -1
  577. package/package/aws-client-agent-mcp/dist/types.d.ts.map +0 -1
  578. package/package/aws-client-agent-mcp/dist/types.js.map +0 -1
  579. package/package/aws-client-agent-mcp/dist/websocket-client.d.ts.map +0 -1
  580. package/package/aws-client-agent-mcp/dist/websocket-client.js.map +0 -1
  581. package/package/aws-client-agent-mcp/dist/websocket-client.test.d.ts.map +0 -1
  582. package/package/aws-client-agent-mcp/dist/websocket-client.test.js.map +0 -1
  583. package/package/cc-switch-sdk/dist/constants.d.ts.map +0 -1
  584. package/package/cc-switch-sdk/dist/errors.d.ts.map +0 -1
  585. package/package/cc-switch-sdk/dist/index.d.ts.map +0 -1
  586. package/package/cc-switch-sdk/dist/schemas.d.ts.map +0 -1
  587. package/package/cc-switch-sdk/dist/sdk.d.ts.map +0 -1
  588. package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts.map +0 -1
  589. package/package/cc-switch-sdk/dist/services/mcp-model.d.ts.map +0 -1
  590. package/package/cc-switch-sdk/dist/services/mcp-service.d.ts.map +0 -1
  591. package/package/cc-switch-sdk/dist/services/skill-model.d.ts.map +0 -1
  592. package/package/cc-switch-sdk/dist/services/skill-service.d.ts.map +0 -1
  593. package/package/cc-switch-sdk/dist/state.d.ts.map +0 -1
  594. package/package/cc-switch-sdk/dist/types.d.ts.map +0 -1
  595. package/package/cc-switch-sdk/dist/utils/fs.d.ts.map +0 -1
  596. package/package/cc-switch-sdk/dist/utils/id.d.ts.map +0 -1
@@ -1,1300 +1,4 @@
1
- /**
2
- * Claude Code Agent SDK Adapter
3
- *
4
- * 通过 @anthropic-ai/claude-agent-sdk 的 query() API
5
- * 实现与 Claude Code 的结构化交互。
6
- *
7
- * 核心特性:
8
- * - 支持 autoAccept 模式自动确认所有权限
9
- * - 支持 AskUserQuestion 拦截并转发到聊天面板
10
- * - 支持 turn_complete 事件精确判断 AI 就绪状态
11
- */
12
- import { execSync } from 'child_process';
13
- import { EventEmitter } from 'events';
14
- import * as fs from 'fs';
15
- import * as path from 'path';
16
- import { v4 as uuidv4 } from 'uuid';
17
- import { importBridgeSdkPackage } from '../utils/sdk-package-loader.js';
18
- import { IdlePollLoop } from './idle-poll-loop.js';
19
- import { getToolActionInfo } from './types.js';
20
- // ============ AsyncIterableQueue ============
21
- /**
22
- * 可排队的 AsyncIterable,用于向 SDK query() 输入流推送用户消息
23
- */
24
- class AsyncIterableQueue {
25
- constructor() {
26
- this.queue = [];
27
- this.resolve = null;
28
- this.done = false;
29
- }
30
- enqueue(item) {
31
- if (this.done)
32
- return;
33
- if (this.resolve) {
34
- const r = this.resolve;
35
- this.resolve = null;
36
- r({ value: item, done: false });
37
- }
38
- else {
39
- this.queue.push(item);
40
- }
41
- }
42
- close() {
43
- this.done = true;
44
- if (this.resolve) {
45
- const r = this.resolve;
46
- this.resolve = null;
47
- r({ value: undefined, done: true });
48
- }
49
- }
50
- [Symbol.asyncIterator]() {
51
- return {
52
- next: () => {
53
- if (this.queue.length > 0) {
54
- return Promise.resolve({ value: this.queue.shift(), done: false });
55
- }
56
- if (this.done) {
57
- return Promise.resolve({ value: undefined, done: true });
58
- }
59
- return new Promise((resolve) => {
60
- this.resolve = resolve;
61
- });
62
- },
63
- };
64
- }
65
- }
66
- // ============ ClaudeSdkAdapter ============
67
- /**
68
- * Claude Code Agent SDK Adapter
69
- */
70
- export class ClaudeSdkAdapter extends EventEmitter {
71
- constructor() {
72
- super(...arguments);
73
- this.providerId = 'claude-code';
74
- this.displayName = 'Claude Code';
75
- this.sessions = new Map();
76
- this.sdkQueries = new Map();
77
- this.inputStreams = new Map();
78
- this.abortControllers = new Map();
79
- this.sdkModule = null;
80
- // 挂起的权限请求
81
- this.pendingPermissions = new Map();
82
- // 挂起的 AskUserQuestion
83
- this.pendingQuestions = new Map();
84
- // 正在处理的工具调用 ID(用于去重)
85
- this.activeToolUseIds = new Map(); // sessionId -> toolUseId
86
- // 最近处理的工具名(用于 stream_event 和 tool_use 的去重)
87
- this.recentToolNames = new Map(); // sessionId -> { name, time }
88
- // 收集工具参数的缓冲区(用于 stream_event 模式)
89
- this.toolInputBuffers = new Map(); // "${sessionId}:${toolUseId}" -> JSON string
90
- // ============ 空闲命令管理 ============
91
- this.idleCommands = new Map();
92
- this.idleTimers = new Map();
93
- this.idlePollLoops = new Map();
94
- this.lastActivityAt = new Map();
95
- }
96
- // ============ 生命周期方法 ============
97
- async startSession(sessionId, config) {
98
- // ★ 特征日志:确认使用的是 Claude Code Adapter
99
- console.log(`[ClaudeSdkAdapter] ★★★ 启动 Claude Code SDK 会话 ★★★ sessionId="${sessionId}", command="${config.command}", workingDirectory="${config.workingDirectory}"`);
100
- const session = {
101
- sessionId,
102
- status: 'starting',
103
- messages: [],
104
- createdAt: new Date().toISOString(),
105
- totalUsage: { inputTokens: 0, outputTokens: 0 },
106
- };
107
- this.sessions.set(sessionId, session);
108
- try {
109
- const sdk = await this.loadSdk();
110
- const abortController = new AbortController();
111
- this.abortControllers.set(sessionId, abortController);
112
- // 创建输入流
113
- const inputStream = new AsyncIterableQueue();
114
- this.inputStreams.set(sessionId, inputStream);
115
- // 构建选项
116
- const options = this.buildQueryOptions(sessionId, config, abortController);
117
- // 启动 SDK query
118
- const sdkQuery = sdk.query({
119
- prompt: inputStream,
120
- options,
121
- });
122
- this.sdkQueries.set(sessionId, sdkQuery);
123
- // 启动流消费(异步,不阻塞)
124
- this.consumeStream(sessionId, sdkQuery).catch(err => {
125
- console.error(`[ClaudeSdkAdapter] Stream error for ${sessionId}:`, err);
126
- });
127
- // ★ 等待一小段时间让 SDK 进程启动
128
- await new Promise(resolve => setTimeout(resolve, 100));
129
- // 发送初始 prompt
130
- if (config.initialPrompt) {
131
- // 有初始 prompt,启动后会进入思考状态
132
- session.status = 'starting';
133
- this.emit('status-change', sessionId, 'starting');
134
- const userMsg = {
135
- id: uuidv4(),
136
- sessionId,
137
- role: 'user',
138
- content: config.initialPrompt,
139
- timestamp: new Date().toISOString(),
140
- };
141
- session.messages.push(userMsg);
142
- this.emit('conversation-message', sessionId, userMsg);
143
- // ★ 解析初始 prompt 中的图片标记
144
- const initialContent = this.parseMessageContent(config.initialPrompt);
145
- inputStream.enqueue({
146
- type: 'user',
147
- message: {
148
- role: 'user',
149
- content: initialContent,
150
- },
151
- });
152
- }
153
- else {
154
- // 没有初始 prompt,等待用户输入
155
- session.status = 'waiting_input';
156
- this.emit('status-change', sessionId, 'waiting_input', { usage: session.totalUsage });
157
- // 如果有空闲命令配置,立即启动空闲检测
158
- if (this.idleCommands.has(sessionId)) {
159
- this.startIdleDetection(sessionId);
160
- }
161
- }
162
- }
163
- catch (error) {
164
- const errorMessage = error instanceof Error ? error.message : String(error);
165
- session.status = 'error';
166
- this.emit('status-change', sessionId, 'error');
167
- this.emitEvent(sessionId, {
168
- type: 'error',
169
- sessionId,
170
- timestamp: new Date().toISOString(),
171
- data: { text: `Failed to start session: ${errorMessage}` },
172
- });
173
- throw error;
174
- }
175
- }
176
- async sendMessage(sessionId, message) {
177
- const session = this.sessions.get(sessionId);
178
- const inputStream = this.inputStreams.get(sessionId);
179
- if (!session || !inputStream) {
180
- throw new Error(`Session ${sessionId} not found`);
181
- }
182
- if (session.status === 'error') {
183
- throw new Error(`Session ${sessionId} is in error state`);
184
- }
185
- // 记录用户消息
186
- const userMsg = {
187
- id: uuidv4(),
188
- sessionId,
189
- role: 'user',
190
- content: message,
191
- timestamp: new Date().toISOString(),
192
- };
193
- session.messages.push(userMsg);
194
- this.emit('conversation-message', sessionId, userMsg);
195
- // 更新状态 - 用户发送消息后,AI 将开始处理
196
- session.status = 'thinking';
197
- this.emit('status-change', sessionId, 'thinking');
198
- // ★ 解析消息中的图片标记,构造多模态内容
199
- const content = this.parseMessageContent(message);
200
- // 推送到输入流
201
- inputStream.enqueue({
202
- type: 'user',
203
- message: {
204
- role: 'user',
205
- content,
206
- },
207
- });
208
- }
209
- /**
210
- * 解析消息内容,提取图片和文本
211
- * 支持 [图片: url] 标记格式
212
- */
213
- parseMessageContent(message) {
214
- const content = [];
215
- // 匹配 [图片: url] 格式
216
- const imageTagRegex = /\[图片\s*:\s*([^\]\n]+?)\s*\]/gi;
217
- let lastIndex = 0;
218
- let match = imageTagRegex.exec(message);
219
- while (match !== null) {
220
- // 添加图片之前的文本
221
- if (match.index > lastIndex) {
222
- const text = message.slice(lastIndex, match.index).trim();
223
- if (text) {
224
- content.push({ type: 'text', text });
225
- }
226
- }
227
- // 添加图片
228
- const imageUrl = match[1].trim();
229
- if (imageUrl) {
230
- console.log(`[ClaudeSdkAdapter] 添加图片 URL: ${imageUrl}`);
231
- content.push({
232
- type: 'image',
233
- source: {
234
- type: 'url',
235
- url: imageUrl,
236
- },
237
- });
238
- }
239
- lastIndex = match.index + match[0].length;
240
- match = imageTagRegex.exec(message);
241
- }
242
- // 添加最后的文本
243
- if (lastIndex < message.length) {
244
- const text = message.slice(lastIndex).trim();
245
- if (text) {
246
- content.push({ type: 'text', text });
247
- }
248
- }
249
- // 如果没有找到任何内容,返回原始消息作为文本
250
- if (content.length === 0) {
251
- content.push({ type: 'text', text: message });
252
- }
253
- return content;
254
- }
255
- async sendConfirmation(sessionId, accept) {
256
- const pending = this.pendingPermissions.get(sessionId);
257
- if (pending) {
258
- if (accept) {
259
- pending.resolve({ behavior: 'allow', updatedInput: pending.toolInput });
260
- }
261
- else {
262
- pending.resolve({ behavior: 'deny', message: 'User denied' });
263
- }
264
- this.pendingPermissions.delete(sessionId);
265
- }
266
- }
267
- async sendQuestionAnswer(sessionId, answers) {
268
- const pending = this.pendingQuestions.get(sessionId);
269
- if (!pending)
270
- return;
271
- const questions = pending.toolInput.questions;
272
- let answersText = '用户已回答了您的问题:\n';
273
- if (Array.isArray(questions)) {
274
- questions.forEach((q, i) => {
275
- const key = String(i);
276
- const answer = answers[key] || answers[q.header || ''] || answers[q.question] || '(未填写)';
277
- answersText += `• ${q.header || q.question}:${answer}\n`;
278
- });
279
- }
280
- else {
281
- answersText += JSON.stringify(answers);
282
- }
283
- pending.resolve({ behavior: 'deny', message: answersText });
284
- this.pendingQuestions.delete(sessionId);
285
- }
286
- async abortCurrentTurn(sessionId) {
287
- const abortController = this.abortControllers.get(sessionId);
288
- if (abortController) {
289
- abortController.abort();
290
- }
291
- }
292
- async terminateSession(sessionId) {
293
- const session = this.sessions.get(sessionId);
294
- const sdkQuery = this.sdkQueries.get(sessionId);
295
- const inputStream = this.inputStreams.get(sessionId);
296
- if (inputStream) {
297
- inputStream.close();
298
- }
299
- if (sdkQuery) {
300
- try {
301
- sdkQuery.close();
302
- }
303
- catch {
304
- // ignore
305
- }
306
- }
307
- if (session) {
308
- session.status = 'terminated';
309
- this.emit('status-change', sessionId, 'terminated');
310
- this.emitEvent(sessionId, {
311
- type: 'session_complete',
312
- sessionId,
313
- timestamp: new Date().toISOString(),
314
- data: { exitCode: 0 },
315
- });
316
- }
317
- this.cleanupSession(sessionId);
318
- }
319
- getConversation(sessionId) {
320
- return this.sessions.get(sessionId)?.messages ?? [];
321
- }
322
- hasSession(sessionId) {
323
- return this.sessions.has(sessionId);
324
- }
325
- getProviderSessionId(sessionId) {
326
- return this.sessions.get(sessionId)?.providerSessionId;
327
- }
328
- getSessionStatus(sessionId) {
329
- return this.sessions.get(sessionId)?.status;
330
- }
331
- getSessionPid(sessionId) {
332
- return this.sessions.get(sessionId)?.pid;
333
- }
334
- cleanup() {
335
- for (const sessionId of this.sessions.keys()) {
336
- try {
337
- this.terminateSession(sessionId);
338
- }
339
- catch {
340
- // ignore
341
- }
342
- }
343
- this.sessions.clear();
344
- this.sdkQueries.clear();
345
- this.inputStreams.clear();
346
- this.abortControllers.clear();
347
- this.pendingPermissions.clear();
348
- this.pendingQuestions.clear();
349
- this.idleCommands.clear();
350
- this.idleTimers.clear();
351
- }
352
- /**
353
- * 设置空闲命令配置
354
- */
355
- setIdleCommands(sessionId, commands) {
356
- this.idleCommands.set(sessionId, commands);
357
- // 如果当前状态是 waiting_input,立即启动空闲检测
358
- const session = this.sessions.get(sessionId);
359
- if (session && session.status === 'waiting_input' && (commands.idleInputCommand || commands.nonInputCommand)) {
360
- this.startIdleDetection(sessionId);
361
- }
362
- }
363
- /**
364
- * 启动空闲检测定时器
365
- */
366
- startIdleDetection(sessionId) {
367
- // 清除现有定时器
368
- this.stopIdleDetection(sessionId);
369
- const commands = this.idleCommands.get(sessionId);
370
- if (!commands?.idleInputCommand) {
371
- return;
372
- }
373
- if (this.isMessagePollingIdleCommand(commands.idleInputCommand)) {
374
- const idleLoop = this.getIdlePollLoop(sessionId);
375
- idleLoop.start();
376
- return;
377
- }
378
- this.lastActivityAt.set(sessionId, Date.now());
379
- // 每500ms检测一次空闲状态
380
- const timer = setInterval(() => {
381
- this.checkIdleState(sessionId);
382
- }, 500);
383
- this.idleTimers.set(sessionId, timer);
384
- }
385
- /**
386
- * 停止空闲检测定时器
387
- */
388
- stopIdleDetection(sessionId) {
389
- this.idlePollLoops.get(sessionId)?.stop();
390
- const timer = this.idleTimers.get(sessionId);
391
- if (timer) {
392
- clearInterval(timer);
393
- this.idleTimers.delete(sessionId);
394
- }
395
- }
396
- /**
397
- * 检测空闲状态并执行命令
398
- */
399
- checkIdleState(sessionId) {
400
- const session = this.sessions.get(sessionId);
401
- if (!session || session.status !== 'waiting_input') {
402
- return;
403
- }
404
- const commands = this.idleCommands.get(sessionId);
405
- if (!commands || (!commands.idleInputCommand && !commands.nonInputCommand)) {
406
- return;
407
- }
408
- const lastActivity = this.lastActivityAt.get(sessionId) || 0;
409
- const idleTime = Date.now() - lastActivity;
410
- // 空闲1.5秒后执行空闲命令
411
- const IDLE_THRESHOLD = 1500;
412
- if (idleTime < IDLE_THRESHOLD) {
413
- return;
414
- }
415
- // 标记活动时间,避免重复执行
416
- this.lastActivityAt.set(sessionId, Date.now());
417
- // SDK 模式:空闲时发送一个简单的提示消息让 AI 调用 poll_message
418
- // 实际的消息获取由 AI 通过 MCP 工具 poll_message 完成
419
- if (commands.idleInputCommand) {
420
- // 解析空闲命令,提取实际要执行的指令
421
- const command = commands.idleInputCommand;
422
- // 如果空闲命令包含 poll_message/get_message,引导 AI 进入阻塞式消息轮询。
423
- if (this.isMessagePollingIdleCommand(command)) {
424
- this.sendIdlePrompt(sessionId, this.buildMessagePollingIdlePrompt());
425
- }
426
- else {
427
- // 其他命令,直接作为消息发送给 AI
428
- this.sendIdlePrompt(sessionId, command);
429
- }
430
- }
431
- }
432
- /**
433
- * 发送空闲提示到 SDK
434
- */
435
- sendIdlePrompt(sessionId, prompt, options) {
436
- const inputStream = this.inputStreams.get(sessionId);
437
- if (!inputStream)
438
- return;
439
- // 更新状态。poll_message 是阻塞监听动作,保持 waiting_input,避免 UI 误判为“思考中卡死”。
440
- const session = this.sessions.get(sessionId);
441
- if (session && !options?.keepWaitingStatus) {
442
- session.status = 'thinking';
443
- this.emit('status-change', sessionId, 'thinking');
444
- }
445
- // 发送空闲提示
446
- inputStream.enqueue({
447
- type: 'user',
448
- message: {
449
- role: 'user',
450
- content: [{ type: 'text', text: prompt }],
451
- },
452
- });
453
- }
454
- isMessagePollingIdleCommand(command) {
455
- const normalized = command.trim();
456
- if (!normalized) {
457
- return false;
458
- }
459
- const lower = normalized.toLowerCase();
460
- return lower.includes('poll_message') || lower.includes('get_message') || normalized.includes('取消息');
461
- }
462
- buildMessagePollingIdlePrompt() {
463
- return '系统提醒:当前工作已完成或运行时已进入空闲状态。请立即调用 poll_message 工具阻塞等待新消息和流程线任务提醒;收到流程任务提醒后调用 my_task 查看已由后台静默抢占的任务详情并直接处理;完成任务后调用 submit_task_result 提交结果,然后继续 poll_message。';
464
- }
465
- /**
466
- * 获取当前会话的空闲轮询驱动器。
467
- * 主流程:惰性创建 -> 绑定会话状态与命令读取 -> 统一派发 poll/普通 idle prompt。
468
- */
469
- getIdlePollLoop(sessionId) {
470
- const existing = this.idlePollLoops.get(sessionId);
471
- if (existing)
472
- return existing;
473
- const loop = new IdlePollLoop({
474
- getStatus: () => this.sessions.get(sessionId)?.status,
475
- getCommand: () => this.idleCommands.get(sessionId)?.idleInputCommand,
476
- isPollingCommand: (command) => this.isMessagePollingIdleCommand(command),
477
- dispatchPollingPrompt: () => this.sendIdlePrompt(sessionId, this.buildMessagePollingIdlePrompt(), { keepWaitingStatus: true }),
478
- dispatchRegularIdleCommand: (command) => this.sendIdlePrompt(sessionId, command),
479
- });
480
- this.idlePollLoops.set(sessionId, loop);
481
- return loop;
482
- }
483
- /**
484
- * 发送手动快捷键 token 序列,和空闲自动命令共用解析逻辑。
485
- */
486
- async sendShortcutInput(sessionId, command) {
487
- await this.executeIdleCommand(sessionId, command);
488
- }
489
- /**
490
- * 执行空闲命令(支持 [enter], [wait:n] 等 token)
491
- */
492
- async executeIdleCommand(sessionId, command) {
493
- const inputStream = this.inputStreams.get(sessionId);
494
- if (!inputStream)
495
- return;
496
- // 解析命令 token
497
- const tokenPattern = /\[(.+?)\]/g;
498
- let cursor = 0;
499
- const tokens = [];
500
- let match = tokenPattern.exec(command);
501
- while (match !== null) {
502
- if (match.index > cursor) {
503
- tokens.push({ type: 'text', value: command.slice(cursor, match.index) });
504
- }
505
- const token = match[1];
506
- if (token.startsWith('wait:')) {
507
- const seconds = parseFloat(token.slice(5));
508
- if (!isNaN(seconds)) {
509
- tokens.push({ type: 'wait', value: seconds * 1000 });
510
- }
511
- }
512
- else {
513
- // 映射按键 token
514
- const keyMap = {
515
- 'enter': '\r',
516
- 'up': '\x1b[A',
517
- 'down': '\x1b[B',
518
- 'left': '\x1b[D',
519
- 'right': '\x1b[C',
520
- 'tab': '\t',
521
- 'esc': '\x1b',
522
- 'escape': '\x1b',
523
- 'space': ' ',
524
- 'ctrl+c': '\x03',
525
- };
526
- tokens.push({ type: 'key', value: keyMap[token.toLowerCase()] || token });
527
- }
528
- cursor = match.index + match[0].length;
529
- match = tokenPattern.exec(command);
530
- }
531
- if (cursor < command.length) {
532
- tokens.push({ type: 'text', value: command.slice(cursor) });
533
- }
534
- // 执行 tokens
535
- for (const token of tokens) {
536
- if (token.type === 'wait') {
537
- await new Promise(resolve => setTimeout(resolve, token.value));
538
- }
539
- else {
540
- const text = String(token.value);
541
- inputStream.enqueue({
542
- type: 'user',
543
- message: {
544
- role: 'user',
545
- content: [{ type: 'text', text }],
546
- },
547
- });
548
- }
549
- }
550
- }
551
- /**
552
- * 更新活动时间(在收到输出或状态变化时调用)
553
- */
554
- updateActivity(sessionId) {
555
- this.lastActivityAt.set(sessionId, Date.now());
556
- }
557
- /**
558
- * 恢复之前的会话
559
- * 注意:SDK 的 resume 功能需要 providerSessionId
560
- */
561
- async resumeSession(sessionId, providerSessionId, config) {
562
- // 目前简化实现:重新启动一个新会话
563
- // TODO: 使用 SDK 的 resume API 恢复会话上下文
564
- const session = {
565
- sessionId,
566
- providerSessionId,
567
- status: 'starting',
568
- messages: [],
569
- createdAt: new Date().toISOString(),
570
- totalUsage: { inputTokens: 0, outputTokens: 0 },
571
- };
572
- this.sessions.set(sessionId, session);
573
- try {
574
- await this.startSession(sessionId, config);
575
- session.providerSessionId = providerSessionId;
576
- }
577
- catch (error) {
578
- session.status = 'error';
579
- this.emit('status-change', sessionId, 'error');
580
- throw error;
581
- }
582
- }
583
- // ============ 私有方法 ============
584
- async loadSdk() {
585
- if (!this.sdkModule) {
586
- try {
587
- this.sdkModule = await importBridgeSdkPackage('@anthropic-ai/claude-agent-sdk');
588
- }
589
- catch (err) {
590
- throw new Error(`Failed to load @anthropic-ai/claude-agent-sdk. Please install: npm install @anthropic-ai/claude-agent-sdk. Original error: ${err}`);
591
- }
592
- }
593
- return this.sdkModule;
594
- }
595
- /**
596
- * 查找 Claude Code 可执行文件路径
597
- * 支持 Windows / macOS / Linux
598
- */
599
- findClaudeExecutable(command) {
600
- const normalizedCommand = this.extractExecutableCommand(command);
601
- // 1. 如果是绝对路径,直接返回
602
- if (path.isAbsolute(normalizedCommand) && fs.existsSync(normalizedCommand)) {
603
- const resolvedWrapper = this.resolveWindowsWrapper(normalizedCommand);
604
- if (resolvedWrapper) {
605
- return resolvedWrapper;
606
- }
607
- if (this.isWindowsWrapperPath(normalizedCommand)) {
608
- console.warn(`[ClaudeSdkAdapter] Skipping wrapper script for Claude Code executable: ${normalizedCommand}`);
609
- return undefined;
610
- }
611
- return normalizedCommand;
612
- }
613
- const pathExecutable = this.resolveExecutableFromPath(normalizedCommand);
614
- if (pathExecutable) {
615
- return pathExecutable;
616
- }
617
- // 2. Windows 特定路径(作为 claude 默认命令的兜底)
618
- if (process.platform === 'win32' && this.shouldUseDefaultClaudeFallbacks(normalizedCommand)) {
619
- const userProfile = process.env.USERPROFILE || '';
620
- const localAppData = process.env.LOCALAPPDATA || '';
621
- const appData = process.env.APPDATA || '';
622
- // Volta 安装路径(优先检查)
623
- const voltaCandidates = [
624
- path.join(localAppData, 'Volta', 'tools', 'shared', '@anthropic-ai', 'claude-code', 'cli.js'),
625
- path.join(localAppData, 'Volta', 'tools', 'image', 'packages', '@anthropic-ai', 'claude-code', 'cli.js'),
626
- ];
627
- for (const p of voltaCandidates) {
628
- if (fs.existsSync(p)) {
629
- console.log(`[ClaudeSdkAdapter] Found Claude Code CLI via Volta: ${p}`);
630
- return p;
631
- }
632
- }
633
- const candidates = [
634
- path.join(appData, 'npm', 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'),
635
- path.join(localAppData, 'Programs', 'claude-code', 'claude.exe'),
636
- path.join(userProfile, '.local', 'bin', 'claude.exe'),
637
- ];
638
- for (const p of candidates) {
639
- if (p && fs.existsSync(p)) {
640
- console.log(`[ClaudeSdkAdapter] Found Claude Code CLI: ${p}`);
641
- return p;
642
- }
643
- }
644
- }
645
- // 3. macOS/Linux 特定路径(作为 claude 默认命令的兜底)
646
- const home = process.env.HOME || '';
647
- const candidates = [
648
- path.join(home, '.local', 'bin', 'claude'),
649
- path.join(home, '.npm-global', 'bin', 'claude'),
650
- path.join(home, '.local', 'share', 'mise', 'shims', 'claude'),
651
- path.join(home, '.asdf', 'shims', 'claude'),
652
- `/opt/homebrew/bin/claude`,
653
- `/usr/local/bin/claude`,
654
- `/usr/bin/claude`,
655
- `/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js`,
656
- `/usr/lib/node_modules/@anthropic-ai/claude-code/cli.js`,
657
- path.join(home, '.local', 'share', 'volta', 'tools', 'shared', '@anthropic-ai', 'claude-code', 'cli.js'),
658
- path.join(home, '.volta', 'tools', 'shared', '@anthropic-ai', 'claude-code', 'cli.js'),
659
- ];
660
- if (this.shouldUseDefaultClaudeFallbacks(normalizedCommand)) {
661
- for (const p of candidates) {
662
- if (p && fs.existsSync(p)) {
663
- console.log(`[ClaudeSdkAdapter] Found Claude Code CLI: ${p}`);
664
- return p;
665
- }
666
- }
667
- }
668
- // 4. 尝试 npm root -g
669
- if (this.shouldUseDefaultClaudeFallbacks(normalizedCommand)) {
670
- try {
671
- const npmRoot = execSync('npm root -g', { encoding: 'utf8', timeout: 5000 }).trim();
672
- const cliJs = path.join(npmRoot, '@anthropic-ai', 'claude-code', 'cli.js');
673
- if (fs.existsSync(cliJs)) {
674
- console.log(`[ClaudeSdkAdapter] Found Claude Code CLI via npm root: ${cliJs}`);
675
- return cliJs;
676
- }
677
- }
678
- catch {
679
- // 忽略
680
- }
681
- }
682
- console.warn(`[ClaudeSdkAdapter] Claude Code executable not found for command: ${normalizedCommand}`);
683
- return undefined;
684
- }
685
- /**
686
- * 从面板配置的命令行中提取实际可执行文件,避免把参数一起传给 PATH 查找。
687
- */
688
- extractExecutableCommand(command) {
689
- const input = (command || 'claude').trim() || 'claude';
690
- const firstToken = input.match(/^\s*(?:"([^"]+)"|'([^']+)'|(\S+))/);
691
- return firstToken?.[1] || firstToken?.[2] || firstToken?.[3] || 'claude';
692
- }
693
- /**
694
- * 按当前 Bridge 进程的 PATH/PATHEXT 直接查找可执行文件,避免依赖 which/where 和 shell 解析。
695
- */
696
- resolveExecutableFromPath(command) {
697
- const pathValue = process.env.PATH || '';
698
- if (!pathValue) {
699
- return undefined;
700
- }
701
- const commandHasExtension = path.extname(command).length > 0;
702
- const extensions = process.platform === 'win32'
703
- ? this.getWindowsPathExtensions(commandHasExtension)
704
- : [''];
705
- for (const directory of pathValue.split(path.delimiter)) {
706
- if (!directory) {
707
- continue;
708
- }
709
- for (const extension of extensions) {
710
- const candidate = path.join(directory, `${command}${extension}`);
711
- if (!fs.existsSync(candidate)) {
712
- continue;
713
- }
714
- if (this.isWindowsWrapperPath(candidate)) {
715
- const resolvedWrapper = this.resolveWindowsWrapper(candidate);
716
- if (resolvedWrapper) {
717
- return resolvedWrapper;
718
- }
719
- continue;
720
- }
721
- console.log(`[ClaudeSdkAdapter] Found Claude Code CLI via PATH: ${candidate}`);
722
- return candidate;
723
- }
724
- }
725
- return undefined;
726
- }
727
- getWindowsPathExtensions(commandHasExtension) {
728
- if (commandHasExtension) {
729
- return [''];
730
- }
731
- const pathExt = process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM;.PS1';
732
- return pathExt
733
- .split(';')
734
- .map((extension) => extension.trim())
735
- .filter((extension) => extension.length > 0);
736
- }
737
- shouldUseDefaultClaudeFallbacks(command) {
738
- return ['claude', 'claude-code', 'claudecode'].includes(command.toLowerCase());
739
- }
740
- isWindowsWrapperPath(filePath) {
741
- const extension = path.extname(filePath).toLowerCase();
742
- return ['.cmd', '.bat', '.ps1'].includes(extension);
743
- }
744
- resolveWindowsWrapper(wrapperPath) {
745
- if (!this.isWindowsWrapperPath(wrapperPath)) {
746
- return undefined;
747
- }
748
- return this.resolveCliJsFromWrapper(wrapperPath);
749
- }
750
- /**
751
- * 从 wrapper 脚本解析 cli.js 路径
752
- */
753
- resolveCliJsFromWrapper(wrapperPath) {
754
- try {
755
- const content = fs.readFileSync(wrapperPath, 'utf8');
756
- // Volta wrapper: volta run %~n0 %*
757
- if (content.includes('volta run')) {
758
- const voltaShared = path.join(process.env.LOCALAPPDATA || '', 'Volta', 'tools', 'shared', '@anthropic-ai', 'claude-code', 'cli.js');
759
- if (fs.existsSync(voltaShared)) {
760
- return voltaShared;
761
- }
762
- }
763
- const wrapperDirectory = path.dirname(wrapperPath);
764
- const npmCliJs = path.join(wrapperDirectory, 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js');
765
- if (fs.existsSync(npmCliJs)) {
766
- return npmCliJs;
767
- }
768
- }
769
- catch {
770
- // 忽略
771
- }
772
- return undefined;
773
- }
774
- buildQueryOptions(sessionId, config, abortController) {
775
- const options = {
776
- cwd: config.workingDirectory,
777
- abortController,
778
- settingSources: ['user', 'project', 'local'],
779
- // 启用部分消息以获取增量输出
780
- includePartialMessages: true,
781
- };
782
- // ★ 关键:指定 Claude Code 可执行文件路径
783
- // SDK 需要这个来启动 Claude Code CLI
784
- const execPath = this.findClaudeExecutable(config.command);
785
- if (execPath) {
786
- options.pathToClaudeCodeExecutable = execPath;
787
- // ★ 特征日志:明确显示使用的是 Claude Code 可执行文件
788
- console.log(`[ClaudeSdkAdapter] ★★★ 使用 Claude Code 可执行文件 ★★★ path="${execPath}"`);
789
- }
790
- else {
791
- console.warn(`[ClaudeSdkAdapter] ★★★ 警告:未找到 Claude Code 可执行文件 ★★★ command="${config.command}"`);
792
- }
793
- // 模型配置
794
- if (config.model) {
795
- options.model = config.model;
796
- }
797
- // 最大轮次
798
- if (config.maxTurns && config.maxTurns > 0) {
799
- options.maxTurns = config.maxTurns;
800
- }
801
- // MCP 服务器
802
- if (config.mcpConfigPath) {
803
- try {
804
- const raw = fs.readFileSync(config.mcpConfigPath, 'utf-8');
805
- const parsed = JSON.parse(raw);
806
- options.mcpServers = { ...config.extraMcpServers, ...parsed.mcpServers };
807
- }
808
- catch {
809
- options.mcpServers = config.extraMcpServers || {};
810
- }
811
- }
812
- else {
813
- options.mcpServers = config.extraMcpServers || {};
814
- }
815
- // 允许的工具
816
- if (config.allowedTools && config.allowedTools.length > 0) {
817
- options.allowedTools = config.allowedTools;
818
- }
819
- else {
820
- options.allowedTools = [
821
- 'Read',
822
- 'Write',
823
- 'Edit',
824
- 'Bash',
825
- 'Glob',
826
- 'Grep',
827
- 'WebSearch',
828
- 'WebFetch',
829
- 'Task',
830
- 'NotebookEdit',
831
- 'LSP',
832
- 'Skill',
833
- 'mcp__*',
834
- ];
835
- }
836
- // 环境变量
837
- options.env = { ...process.env, ...config.envOverrides };
838
- // 权限模式 - 使用 canUseTool 回调统一处理权限,不使用 bypassPermissions
839
- // 原因:bypassPermissions 模式下 SDK 可能跳过 canUseTool 回调,
840
- // 导致 AskUserQuestion 等需要用户交互的工具无法被拦截,前端收不到提问事件。
841
- // 改为通过 canUseTool 回调实现 autoAccept 逻辑:
842
- // - AskUserQuestion → 始终拦截,转发到前端等待用户回答
843
- // - autoAccept 普通工具 → 直接允许
844
- // - 非 autoAccept 普通工具 → 询问用户
845
- options.canUseTool = this.createPermissionHandler(sessionId, config.autoAccept);
846
- return options;
847
- }
848
- createPermissionHandler(sessionId, autoAccept) {
849
- return async (toolName, toolInput, _options) => {
850
- // AskUserQuestion 特殊处理:始终拦截,转发到前端等待用户回答
851
- if (toolName === 'AskUserQuestion' || toolName === 'ask_user_question') {
852
- return new Promise((resolve) => {
853
- this.pendingQuestions.set(sessionId, { resolve, toolInput });
854
- this.emit('ask-user-question', {
855
- sessionId,
856
- toolCallId: this.activeToolUseIds.get(sessionId) || undefined,
857
- questions: toolInput.questions,
858
- });
859
- });
860
- }
861
- // autoAccept 模式直接允许普通工具
862
- // 返回 { behavior: 'allow', updatedInput } 格式
863
- if (autoAccept) {
864
- return { behavior: 'allow', updatedInput: toolInput };
865
- }
866
- // 非 autoAccept 模式,询问用户
867
- return new Promise((resolve) => {
868
- this.pendingPermissions.set(sessionId, { resolve, toolInput });
869
- this.emit('permission-request', {
870
- sessionId,
871
- toolName,
872
- toolInput,
873
- permissionPrompt: `Allow ${toolName}?`,
874
- });
875
- });
876
- };
877
- }
878
- async consumeStream(sessionId, sdkQuery) {
879
- const session = this.sessions.get(sessionId);
880
- if (!session)
881
- return;
882
- try {
883
- for await (const msg of sdkQuery) {
884
- const sdkMsg = msg;
885
- this.handleSdkMessage(sessionId, session, sdkMsg);
886
- }
887
- }
888
- catch (error) {
889
- if (this.abortControllers.get(sessionId)?.signal.aborted) {
890
- // 主动中止,正常结束
891
- return;
892
- }
893
- const errorMessage = error instanceof Error ? error.message : String(error);
894
- this.emitEvent(sessionId, {
895
- type: 'error',
896
- sessionId,
897
- timestamp: new Date().toISOString(),
898
- data: { text: `Stream error: ${errorMessage}` },
899
- });
900
- }
901
- }
902
- /**
903
- * Apply Claude SDK usage snapshots to the adapter session.
904
- * Main flow: accept assistant-step or final-result usage, then keep the largest observed totals.
905
- */
906
- applyUsage(session, usage) {
907
- if (!usage)
908
- return;
909
- if (Number.isFinite(usage.input_tokens)) {
910
- session.totalUsage.inputTokens = Math.max(session.totalUsage.inputTokens, usage.input_tokens ?? 0);
911
- }
912
- if (Number.isFinite(usage.output_tokens)) {
913
- session.totalUsage.outputTokens = Math.max(session.totalUsage.outputTokens, usage.output_tokens ?? 0);
914
- }
915
- }
916
- handleSdkMessage(sessionId, session, msg) {
917
- const timestamp = new Date().toISOString();
918
- // ★ 调试日志:记录所有收到的消息类型
919
- console.log(`[ClaudeSdkAdapter] Received message type: "${msg.type}", subtype: "${msg.subtype || ''}"`);
920
- // ★ 如果有工具名,也记录下来
921
- if (msg.tool_name) {
922
- console.log(`[ClaudeSdkAdapter] Tool name: "${msg.tool_name}"`);
923
- }
924
- switch (msg.type) {
925
- case 'text':
926
- // AI 正在输出文本
927
- if (msg.delta) {
928
- // 更新状态为思考中(如果有文本输出)
929
- if (session.status !== 'thinking') {
930
- session.status = 'thinking';
931
- this.emit('status-change', sessionId, 'thinking');
932
- this.stopIdleDetection(sessionId);
933
- }
934
- this.emitEvent(sessionId, {
935
- type: 'text_delta',
936
- sessionId,
937
- timestamp,
938
- data: { text: msg.delta },
939
- });
940
- }
941
- break;
942
- case 'thinking':
943
- // AI 正在思考/推理
944
- if (session.status !== 'thinking') {
945
- session.status = 'thinking';
946
- this.emit('status-change', sessionId, 'thinking');
947
- this.stopIdleDetection(sessionId);
948
- }
949
- if (msg.content || msg.delta) {
950
- this.emitEvent(sessionId, {
951
- type: 'thinking',
952
- sessionId,
953
- timestamp,
954
- data: { text: msg.delta || msg.content },
955
- });
956
- }
957
- break;
958
- case 'tool_use':
959
- case 'tool_use_start':
960
- // AI 正在调用工具
961
- {
962
- const actionInfo = { ...getToolActionInfo(msg.tool_name, msg.tool_input), actionId: msg.tool_use_id };
963
- const nextStatus = actionInfo.actionType === 'idle' ? 'waiting_input' : 'tool_using';
964
- session.status = nextStatus;
965
- const mcpServer = this.extractMcpServerName(msg.tool_name || '');
966
- this.emit('status-change', sessionId, nextStatus, {
967
- actionType: actionInfo.actionType,
968
- actionLabel: actionInfo.actionLabel,
969
- actionDetail: actionInfo.actionDetail,
970
- actionId: actionInfo.actionId,
971
- usage: session.totalUsage,
972
- ...(mcpServer ? { metadata: { mcpServer } } : {}),
973
- });
974
- if (actionInfo.actionType !== 'idle') {
975
- this.stopIdleDetection(sessionId);
976
- }
977
- this.handleToolUse(sessionId, session, msg, timestamp);
978
- }
979
- break;
980
- case 'tool_result':
981
- case 'tool_use_end':
982
- this.emitEvent(sessionId, {
983
- type: 'tool_use_end',
984
- sessionId,
985
- timestamp,
986
- data: {
987
- toolName: msg.tool_name,
988
- toolResult: msg.tool_result,
989
- isError: msg.is_error,
990
- toolUseId: msg.tool_use_id,
991
- },
992
- });
993
- break;
994
- case 'result':
995
- // ★ SDK 的 turn_complete 事件是 'result' 类型
996
- {
997
- const isSuccess = msg.subtype === 'success';
998
- this.applyUsage(session, msg.usage);
999
- // 发送 turn_complete 事件
1000
- this.emitEvent(sessionId, {
1001
- type: 'turn_complete',
1002
- sessionId,
1003
- timestamp,
1004
- data: {
1005
- usage: session.totalUsage,
1006
- text: isSuccess ? msg.result : undefined,
1007
- },
1008
- });
1009
- // ★ 更新状态为等待输入
1010
- session.status = 'waiting_input';
1011
- // ★ 修复:当空闲检测即将重新启动 poll_message 轮询时,在 status-change 中
1012
- // 保留 idle 动作信息,避免 bridge 清空动作字段导致前端显示 "空闲"。
1013
- const willResumePolling = (() => {
1014
- const idleCmds = this.idleCommands.get(sessionId);
1015
- return Boolean(idleCmds?.idleInputCommand && this.isMessagePollingIdleCommand(idleCmds.idleInputCommand));
1016
- })();
1017
- if (willResumePolling) {
1018
- this.emit('status-change', sessionId, 'waiting_input', {
1019
- actionType: 'idle',
1020
- actionLabel: '监听消息',
1021
- actionDetail: 'aws-mcp/poll_message',
1022
- usage: session.totalUsage,
1023
- });
1024
- }
1025
- else {
1026
- this.emit('status-change', sessionId, 'waiting_input', { usage: session.totalUsage });
1027
- }
1028
- // 如果有空闲命令配置,启动空闲检测
1029
- if (this.idleCommands.has(sessionId)) {
1030
- this.startIdleDetection(sessionId);
1031
- }
1032
- }
1033
- break;
1034
- case 'system':
1035
- // 系统消息,可能包含初始化数据
1036
- if (msg.subtype === 'init') {
1037
- console.log(`[ClaudeSdkAdapter] Session ${sessionId} initialized: model=${msg.model}, tools=${msg.tools?.length || 0}`);
1038
- }
1039
- break;
1040
- case 'assistant':
1041
- // AI 响应完成,可能包含完整消息
1042
- this.applyUsage(session, msg.message?.usage);
1043
- if (msg.message?.content) {
1044
- const textContent = msg.message.content
1045
- .filter((c) => c.type === 'text' && c.text)
1046
- .map((c) => c.text || '')
1047
- .join('');
1048
- if (textContent) {
1049
- session.messages.push({
1050
- id: uuidv4(),
1051
- sessionId,
1052
- role: 'assistant',
1053
- content: textContent,
1054
- timestamp,
1055
- });
1056
- }
1057
- }
1058
- break;
1059
- case 'user':
1060
- // 用户消息(工具结果)
1061
- if (msg.tool_use_result !== undefined) {
1062
- // 工具执行结果
1063
- }
1064
- break;
1065
- case 'error':
1066
- session.status = 'error';
1067
- this.emit('status-change', sessionId, 'error');
1068
- this.emitEvent(sessionId, {
1069
- type: 'error',
1070
- sessionId,
1071
- timestamp,
1072
- data: { text: msg.content || 'Unknown error' },
1073
- });
1074
- break;
1075
- case 'stream_event':
1076
- // SDK 流式事件 - 处理工具调用的增量更新
1077
- this.handleStreamEvent(sessionId, session, msg, timestamp);
1078
- break;
1079
- default:
1080
- // 未知消息类型,记录日志
1081
- console.log(`[ClaudeSdkAdapter] Unknown message type: ${msg.type}`, msg);
1082
- }
1083
- }
1084
- handleToolUse(sessionId, session, msg, timestamp) {
1085
- // 检查是否与 stream_event 处理的工具调用匹配(去重)
1086
- const recentInfo = this.recentToolNames.get(sessionId);
1087
- const toolNameSuffix = this.extractToolNameSuffix(msg.tool_name || '');
1088
- if (recentInfo) {
1089
- const timeDiff = Date.now() - recentInfo.time;
1090
- // 如果在 30s 内,且工具名后缀相同,认为是同一个调用(content_block_stop 已发出事件)
1091
- if (timeDiff < 30000 && recentInfo.name === toolNameSuffix) {
1092
- console.log(`[ClaudeSdkAdapter] Tool use ${msg.tool_name} matches recent stream_event (${recentInfo.name}), skipping duplicate event`);
1093
- // 清理记录
1094
- this.recentToolNames.delete(sessionId);
1095
- this.activeToolUseIds.delete(sessionId);
1096
- // 只记录到消息历史,不重复发送事件(content_block_stop 已经发过)
1097
- session.messages.push({
1098
- id: uuidv4(),
1099
- sessionId,
1100
- role: 'tool_use',
1101
- content: `${msg.tool_name}: ${JSON.stringify(msg.tool_input).slice(0, 100)}`,
1102
- timestamp,
1103
- toolName: msg.tool_name,
1104
- toolInput: msg.tool_input,
1105
- toolUseId: msg.tool_use_id,
1106
- });
1107
- return;
1108
- }
1109
- }
1110
- // 清理过期记录
1111
- this.recentToolNames.delete(sessionId);
1112
- this.activeToolUseIds.delete(sessionId);
1113
- // 获取工具动作分类信息
1114
- const actionInfo = getToolActionInfo(msg.tool_name, msg.tool_input);
1115
- console.log(`[ClaudeSdkAdapter] Tool use: ${msg.tool_name}, actionType: ${actionInfo.actionType}, actionDetail: ${actionInfo.actionDetail}`);
1116
- const mcpServer = this.extractMcpServerName(msg.tool_name || '');
1117
- this.emitEvent(sessionId, {
1118
- type: 'tool_use_start',
1119
- sessionId,
1120
- timestamp,
1121
- data: {
1122
- toolName: msg.tool_name,
1123
- toolInput: msg.tool_input,
1124
- toolUseId: msg.tool_use_id,
1125
- actionType: actionInfo.actionType,
1126
- actionLabel: actionInfo.actionLabel,
1127
- actionDetail: actionInfo.actionDetail,
1128
- ...(mcpServer ? { metadata: { mcpServer } } : {}),
1129
- },
1130
- });
1131
- // 记录到消息历史
1132
- session.messages.push({
1133
- id: uuidv4(),
1134
- sessionId,
1135
- role: 'tool_use',
1136
- content: `${msg.tool_name}: ${JSON.stringify(msg.tool_input).slice(0, 100)}`,
1137
- timestamp,
1138
- toolName: msg.tool_name,
1139
- toolInput: msg.tool_input,
1140
- toolUseId: msg.tool_use_id,
1141
- });
1142
- }
1143
- /**
1144
- * 处理 SDK 流式事件
1145
- * 用于检测工具调用开始、增量更新和结束
1146
- *
1147
- * 注意:此方法只更新状态,不发送时间线事件
1148
- * 时间线事件由 handleToolUse 发送,这样能获取完整的工具参数
1149
- */
1150
- handleStreamEvent(sessionId, session, msg, timestamp) {
1151
- const event = msg.event;
1152
- if (!event)
1153
- return;
1154
- // 处理 content_block_start 事件 - 工具调用开始
1155
- if (event.type === 'content_block_start') {
1156
- const contentBlock = event.content_block;
1157
- if (contentBlock?.type === 'tool_use' && contentBlock.name) {
1158
- const toolName = contentBlock.name;
1159
- const toolId = contentBlock.id || `stream_${Date.now()}`;
1160
- console.log(`[ClaudeSdkAdapter] Tool use started via stream_event: ${toolName} (id: ${toolId})`);
1161
- // 记录当前活跃的工具调用 ID(用于去重)
1162
- this.activeToolUseIds.set(sessionId, toolId);
1163
- // 记录工具名(用于与后续 tool_use 消息匹配去重)
1164
- // 提取工具名后缀:aws-mcp__get_profile -> get_profile
1165
- const toolNameSuffix = this.extractToolNameSuffix(toolName);
1166
- this.recentToolNames.set(sessionId, { name: toolNameSuffix, time: Date.now() });
1167
- // 初始化参数缓冲区
1168
- const bufferKey = `${sessionId}:${toolId}`;
1169
- this.toolInputBuffers.set(bufferKey, '');
1170
- // 先不更新状态,等待收集参数后更新
1171
- }
1172
- }
1173
- // 处理 content_block_delta 事件 - 收集工具参数增量
1174
- if (event.type === 'content_block_delta') {
1175
- if (event.delta?.type === 'input_json_delta' && event.delta.partial_json) {
1176
- const toolId = this.activeToolUseIds.get(sessionId);
1177
- if (toolId) {
1178
- const bufferKey = `${sessionId}:${toolId}`;
1179
- const currentBuffer = this.toolInputBuffers.get(bufferKey) || '';
1180
- this.toolInputBuffers.set(bufferKey, currentBuffer + event.delta.partial_json);
1181
- console.log(`[ClaudeSdkAdapter] Tool input delta at index ${event.index}, buffer length: ${currentBuffer.length + event.delta.partial_json.length}`);
1182
- }
1183
- }
1184
- }
1185
- // 处理 content_block_stop 事件 - 工具调用参数收集完成
1186
- if (event.type === 'content_block_stop') {
1187
- const toolId = this.activeToolUseIds.get(sessionId);
1188
- const recentInfo = this.recentToolNames.get(sessionId);
1189
- if (toolId && recentInfo) {
1190
- const bufferKey = `${sessionId}:${toolId}`;
1191
- const jsonStr = this.toolInputBuffers.get(bufferKey) || '';
1192
- console.log(`[ClaudeSdkAdapter] Content block stopped at index ${event.index}, collected JSON length: ${jsonStr.length}`);
1193
- // 尝试解析完整的工具参数
1194
- let toolInput;
1195
- if (jsonStr) {
1196
- try {
1197
- toolInput = JSON.parse(jsonStr);
1198
- console.log(`[ClaudeSdkAdapter] Parsed tool input:`, JSON.stringify(toolInput).slice(0, 200));
1199
- }
1200
- catch {
1201
- console.warn(`[ClaudeSdkAdapter] Failed to parse tool input JSON:`, jsonStr.slice(0, 100));
1202
- }
1203
- }
1204
- // 获取工具动作分类信息(使用��整参数)
1205
- const actionInfo = { ...getToolActionInfo(recentInfo.name, toolInput), actionId: toolId };
1206
- const mcpServer = this.extractMcpServerName(recentInfo.name);
1207
- // 更新状态
1208
- session.status = 'tool_using';
1209
- this.emit('status-change', sessionId, 'tool_using', {
1210
- actionType: actionInfo.actionType,
1211
- actionLabel: actionInfo.actionLabel,
1212
- actionDetail: actionInfo.actionDetail,
1213
- actionId: actionInfo.actionId,
1214
- usage: session.totalUsage,
1215
- ...(mcpServer ? { metadata: { mcpServer } } : {}),
1216
- });
1217
- this.stopIdleDetection(sessionId);
1218
- // 发送工具调用开始事件(此时有完整参数)
1219
- this.emitEvent(sessionId, {
1220
- type: 'tool_use_start',
1221
- sessionId,
1222
- timestamp,
1223
- data: {
1224
- toolName: recentInfo.name,
1225
- toolInput,
1226
- toolUseId: toolId,
1227
- actionType: actionInfo.actionType,
1228
- actionLabel: actionInfo.actionLabel,
1229
- actionDetail: actionInfo.actionDetail,
1230
- actionId: actionInfo.actionId,
1231
- ...(mcpServer ? { metadata: { mcpServer } } : {}),
1232
- },
1233
- });
1234
- // 记录到消息历史
1235
- session.messages.push({
1236
- id: uuidv4(),
1237
- sessionId,
1238
- role: 'tool_use',
1239
- content: `${recentInfo.name}: ${jsonStr.slice(0, 100)}`,
1240
- timestamp,
1241
- toolName: recentInfo.name,
1242
- toolInput,
1243
- toolUseId: toolId,
1244
- });
1245
- // 清理缓冲区(保留 recentToolNames 用于后续 tool_use 消息去重)
1246
- this.toolInputBuffers.delete(bufferKey);
1247
- this.activeToolUseIds.delete(sessionId);
1248
- // 注意:不在此处删除 recentToolNames,让后续 tool_use 消息能匹配去重
1249
- // recentToolNames 会在 handleToolUse 中匹配成功后删除,或过期后自动清理
1250
- }
1251
- }
1252
- }
1253
- /**
1254
- * 从 Claude SDK 工具名中提取 MCP 服务器名
1255
- * Claude SDK 的 MCP 工具命名格式:mcp__<server>__<tool>
1256
- * 例如:mcp__memory-server__list_memories -> memory-server
1257
- */
1258
- extractMcpServerName(toolName) {
1259
- if (toolName.startsWith('mcp__')) {
1260
- const parts = toolName.split('__');
1261
- // mcp__<server>__<tool> — 至少 3 段
1262
- if (parts.length >= 3) {
1263
- return parts[1];
1264
- }
1265
- }
1266
- return undefined;
1267
- }
1268
- /**
1269
- * 提取工具名后缀
1270
- * 用于匹配不同格式的工具名
1271
- * 例如:aws-mcp__get_profile -> get_profile
1272
- */
1273
- extractToolNameSuffix(toolName) {
1274
- // 如果包含 __,取最后一部分
1275
- if (toolName.includes('__')) {
1276
- return toolName.split('__').pop() || toolName;
1277
- }
1278
- // 如果包含 -mcp__,取后面的部分
1279
- if (toolName.includes('-mcp__')) {
1280
- const idx = toolName.indexOf('-mcp__');
1281
- return toolName.substring(idx + 6);
1282
- }
1283
- return toolName;
1284
- }
1285
- emitEvent(sessionId, event) {
1286
- this.emit('event', event);
1287
- }
1288
- cleanupSession(sessionId) {
1289
- this.stopIdleDetection(sessionId);
1290
- this.sessions.delete(sessionId);
1291
- this.sdkQueries.delete(sessionId);
1292
- this.inputStreams.delete(sessionId);
1293
- this.abortControllers.delete(sessionId);
1294
- this.pendingPermissions.delete(sessionId);
1295
- this.pendingQuestions.delete(sessionId);
1296
- this.idleCommands.delete(sessionId);
1297
- this.idlePollLoops.delete(sessionId);
1298
- this.lastActivityAt.delete(sessionId);
1299
- }
1300
- }
1
+ import{execSync as S}from"child_process";import{EventEmitter as C}from"events";import*as p from"fs";import*as c from"path";import{v4 as h}from"uuid";import{importBridgeSdkPackage as y}from"../utils/sdk-package-loader.js";import{IdlePollLoop as k}from"./idle-poll-loop.js";import{getToolActionInfo as f}from"./types.js";class v{constructor(){this.queue=[],this.resolve=null,this.done=!1}enqueue(t){if(!this.done)if(this.resolve){const e=this.resolve;this.resolve=null,e({value:t,done:!1})}else this.queue.push(t)}close(){if(this.done=!0,this.resolve){const t=this.resolve;this.resolve=null,t({value:void 0,done:!0})}}[Symbol.asyncIterator](){return{next:()=>this.queue.length>0?Promise.resolve({value:this.queue.shift(),done:!1}):this.done?Promise.resolve({value:void 0,done:!0}):new Promise(t=>{this.resolve=t})}}}class A extends C{constructor(){super(...arguments),this.providerId="claude-code",this.displayName="Claude Code",this.sessions=new Map,this.sdkQueries=new Map,this.inputStreams=new Map,this.abortControllers=new Map,this.sdkModule=null,this.pendingPermissions=new Map,this.pendingQuestions=new Map,this.activeToolUseIds=new Map,this.recentToolNames=new Map,this.toolInputBuffers=new Map,this.idleCommands=new Map,this.idleTimers=new Map,this.idlePollLoops=new Map,this.lastActivityAt=new Map}async startSession(t,e){console.log(`[ClaudeSdkAdapter] \u2605\u2605\u2605 \u542F\u52A8 Claude Code SDK \u4F1A\u8BDD \u2605\u2605\u2605 sessionId="${t}", command="${e.command}", workingDirectory="${e.workingDirectory}"`);const o={sessionId:t,status:"starting",messages:[],createdAt:new Date().toISOString(),totalUsage:{inputTokens:0,outputTokens:0}};this.sessions.set(t,o);try{const a=await this.loadSdk(),n=new AbortController;this.abortControllers.set(t,n);const i=new v;this.inputStreams.set(t,i);const s=this.buildQueryOptions(t,e,n),r=a.query({prompt:i,options:s});if(this.sdkQueries.set(t,r),this.consumeStream(t,r).catch(l=>{console.error(`[ClaudeSdkAdapter] Stream error for ${t}:`,l)}),await new Promise(l=>setTimeout(l,100)),e.initialPrompt){o.status="starting",this.emit("status-change",t,"starting");const l={id:h(),sessionId:t,role:"user",content:e.initialPrompt,timestamp:new Date().toISOString()};o.messages.push(l),this.emit("conversation-message",t,l);const d=this.parseMessageContent(e.initialPrompt);i.enqueue({type:"user",message:{role:"user",content:d}})}else o.status="waiting_input",this.emit("status-change",t,"waiting_input",{usage:o.totalUsage}),this.idleCommands.has(t)&&this.startIdleDetection(t)}catch(a){const n=a instanceof Error?a.message:String(a);throw o.status="error",this.emit("status-change",t,"error"),this.emitEvent(t,{type:"error",sessionId:t,timestamp:new Date().toISOString(),data:{text:`Failed to start session: ${n}`}}),a}}async sendMessage(t,e){const o=this.sessions.get(t),a=this.inputStreams.get(t);if(!o||!a)throw new Error(`Session ${t} not found`);if(o.status==="error")throw new Error(`Session ${t} is in error state`);const n={id:h(),sessionId:t,role:"user",content:e,timestamp:new Date().toISOString()};o.messages.push(n),this.emit("conversation-message",t,n),o.status="thinking",this.emit("status-change",t,"thinking");const i=this.parseMessageContent(e);a.enqueue({type:"user",message:{role:"user",content:i}})}parseMessageContent(t){const e=[],o=/\[图片\s*:\s*([^\]\n]+?)\s*\]/gi;let a=0,n=o.exec(t);for(;n!==null;){if(n.index>a){const s=t.slice(a,n.index).trim();s&&e.push({type:"text",text:s})}const i=n[1].trim();i&&(console.log(`[ClaudeSdkAdapter] \u6DFB\u52A0\u56FE\u7247 URL: ${i}`),e.push({type:"image",source:{type:"url",url:i}})),a=n.index+n[0].length,n=o.exec(t)}if(a<t.length){const i=t.slice(a).trim();i&&e.push({type:"text",text:i})}return e.length===0&&e.push({type:"text",text:t}),e}async sendConfirmation(t,e){const o=this.pendingPermissions.get(t);o&&(e?o.resolve({behavior:"allow",updatedInput:o.toolInput}):o.resolve({behavior:"deny",message:"User denied"}),this.pendingPermissions.delete(t))}async sendQuestionAnswer(t,e){const o=this.pendingQuestions.get(t);if(!o)return;const a=o.toolInput.questions;let n=`\u7528\u6237\u5DF2\u56DE\u7B54\u4E86\u60A8\u7684\u95EE\u9898\uFF1A
2
+ `;Array.isArray(a)?a.forEach((i,s)=>{const r=String(s),l=e[r]||e[i.header||""]||e[i.question]||"\uFF08\u672A\u586B\u5199\uFF09";n+=`\u2022 ${i.header||i.question}\uFF1A${l}
3
+ `}):n+=JSON.stringify(e),o.resolve({behavior:"deny",message:n}),this.pendingQuestions.delete(t)}async abortCurrentTurn(t){const e=this.abortControllers.get(t);e&&e.abort()}async terminateSession(t){const e=this.sessions.get(t),o=this.sdkQueries.get(t),a=this.inputStreams.get(t);if(a&&a.close(),o)try{o.close()}catch{}e&&(e.status="terminated",this.emit("status-change",t,"terminated"),this.emitEvent(t,{type:"session_complete",sessionId:t,timestamp:new Date().toISOString(),data:{exitCode:0}})),this.cleanupSession(t)}getConversation(t){return this.sessions.get(t)?.messages??[]}hasSession(t){return this.sessions.has(t)}getProviderSessionId(t){return this.sessions.get(t)?.providerSessionId}getSessionStatus(t){return this.sessions.get(t)?.status}getSessionPid(t){return this.sessions.get(t)?.pid}cleanup(){for(const t of this.sessions.keys())try{this.terminateSession(t)}catch{}this.sessions.clear(),this.sdkQueries.clear(),this.inputStreams.clear(),this.abortControllers.clear(),this.pendingPermissions.clear(),this.pendingQuestions.clear(),this.idleCommands.clear(),this.idleTimers.clear()}setIdleCommands(t,e){this.idleCommands.set(t,e);const o=this.sessions.get(t);o&&o.status==="waiting_input"&&(e.idleInputCommand||e.nonInputCommand)&&this.startIdleDetection(t)}startIdleDetection(t){this.stopIdleDetection(t);const e=this.idleCommands.get(t);if(!e?.idleInputCommand)return;if(this.isMessagePollingIdleCommand(e.idleInputCommand)){this.getIdlePollLoop(t).start();return}this.lastActivityAt.set(t,Date.now());const o=setInterval(()=>{this.checkIdleState(t)},500);this.idleTimers.set(t,o)}stopIdleDetection(t){this.idlePollLoops.get(t)?.stop();const e=this.idleTimers.get(t);e&&(clearInterval(e),this.idleTimers.delete(t))}checkIdleState(t){const e=this.sessions.get(t);if(!e||e.status!=="waiting_input")return;const o=this.idleCommands.get(t);if(!o||!o.idleInputCommand&&!o.nonInputCommand)return;const a=this.lastActivityAt.get(t)||0;if(!(Date.now()-a<1500)&&(this.lastActivityAt.set(t,Date.now()),o.idleInputCommand)){const s=o.idleInputCommand;this.isMessagePollingIdleCommand(s)?this.sendIdlePrompt(t,this.buildMessagePollingIdlePrompt()):this.sendIdlePrompt(t,s)}}sendIdlePrompt(t,e,o){const a=this.inputStreams.get(t);if(!a)return;const n=this.sessions.get(t);n&&!o?.keepWaitingStatus&&(n.status="thinking",this.emit("status-change",t,"thinking")),a.enqueue({type:"user",message:{role:"user",content:[{type:"text",text:e}]}})}isMessagePollingIdleCommand(t){const e=t.trim();if(!e)return!1;const o=e.toLowerCase();return o.includes("poll_message")||o.includes("get_message")||e.includes("\u53D6\u6D88\u606F")}buildMessagePollingIdlePrompt(){return"\u7CFB\u7EDF\u63D0\u9192\uFF1A\u5F53\u524D\u5DE5\u4F5C\u5DF2\u5B8C\u6210\u6216\u8FD0\u884C\u65F6\u5DF2\u8FDB\u5165\u7A7A\u95F2\u72B6\u6001\u3002\u8BF7\u7ACB\u5373\u8C03\u7528 poll_message \u5DE5\u5177\u963B\u585E\u7B49\u5F85\u65B0\u6D88\u606F\u548C\u6D41\u7A0B\u7EBF\u4EFB\u52A1\u63D0\u9192\uFF1B\u6536\u5230\u6D41\u7A0B\u4EFB\u52A1\u63D0\u9192\u540E\u8C03\u7528 my_task \u67E5\u770B\u5DF2\u7531\u540E\u53F0\u9759\u9ED8\u62A2\u5360\u7684\u4EFB\u52A1\u8BE6\u60C5\u5E76\u76F4\u63A5\u5904\u7406\uFF1B\u5B8C\u6210\u4EFB\u52A1\u540E\u8C03\u7528 submit_task_result \u63D0\u4EA4\u7ED3\u679C\uFF0C\u7136\u540E\u7EE7\u7EED poll_message\u3002"}getIdlePollLoop(t){const e=this.idlePollLoops.get(t);if(e)return e;const o=new k({getStatus:()=>this.sessions.get(t)?.status,getCommand:()=>this.idleCommands.get(t)?.idleInputCommand,isPollingCommand:a=>this.isMessagePollingIdleCommand(a),dispatchPollingPrompt:()=>this.sendIdlePrompt(t,this.buildMessagePollingIdlePrompt(),{keepWaitingStatus:!0}),dispatchRegularIdleCommand:a=>this.sendIdlePrompt(t,a)});return this.idlePollLoops.set(t,o),o}async sendShortcutInput(t,e){await this.executeIdleCommand(t,e)}async executeIdleCommand(t,e){const o=this.inputStreams.get(t);if(!o)return;const a=/\[(.+?)\]/g;let n=0;const i=[];let s=a.exec(e);for(;s!==null;){s.index>n&&i.push({type:"text",value:e.slice(n,s.index)});const r=s[1];if(r.startsWith("wait:")){const l=parseFloat(r.slice(5));isNaN(l)||i.push({type:"wait",value:l*1e3})}else{const l={enter:"\r",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C",tab:" ",esc:"\x1B",escape:"\x1B",space:" ","ctrl+c":""};i.push({type:"key",value:l[r.toLowerCase()]||r})}n=s.index+s[0].length,s=a.exec(e)}n<e.length&&i.push({type:"text",value:e.slice(n)});for(const r of i)if(r.type==="wait")await new Promise(l=>setTimeout(l,r.value));else{const l=String(r.value);o.enqueue({type:"user",message:{role:"user",content:[{type:"text",text:l}]}})}}updateActivity(t){this.lastActivityAt.set(t,Date.now())}async resumeSession(t,e,o){const a={sessionId:t,providerSessionId:e,status:"starting",messages:[],createdAt:new Date().toISOString(),totalUsage:{inputTokens:0,outputTokens:0}};this.sessions.set(t,a);try{await this.startSession(t,o),a.providerSessionId=e}catch(n){throw a.status="error",this.emit("status-change",t,"error"),n}}async loadSdk(){if(!this.sdkModule)try{this.sdkModule=await y("@anthropic-ai/claude-agent-sdk")}catch(t){throw new Error(`Failed to load @anthropic-ai/claude-agent-sdk. Please install: npm install @anthropic-ai/claude-agent-sdk. Original error: ${t}`)}return this.sdkModule}findClaudeExecutable(t){const e=this.extractExecutableCommand(t);if(c.isAbsolute(e)&&p.existsSync(e)){const i=this.resolveWindowsWrapper(e);if(i)return i;if(this.isWindowsWrapperPath(e)){console.warn(`[ClaudeSdkAdapter] Skipping wrapper script for Claude Code executable: ${e}`);return}return e}const o=this.resolveExecutableFromPath(e);if(o)return o;if(process.platform==="win32"&&this.shouldUseDefaultClaudeFallbacks(e)){const i=process.env.USERPROFILE||"",s=process.env.LOCALAPPDATA||"",r=process.env.APPDATA||"",l=[c.join(s,"Volta","tools","shared","@anthropic-ai","claude-code","cli.js"),c.join(s,"Volta","tools","image","packages","@anthropic-ai","claude-code","cli.js")];for(const u of l)if(p.existsSync(u))return console.log(`[ClaudeSdkAdapter] Found Claude Code CLI via Volta: ${u}`),u;const d=[c.join(r,"npm","node_modules","@anthropic-ai","claude-code","cli.js"),c.join(s,"Programs","claude-code","claude.exe"),c.join(i,".local","bin","claude.exe")];for(const u of d)if(u&&p.existsSync(u))return console.log(`[ClaudeSdkAdapter] Found Claude Code CLI: ${u}`),u}const a=process.env.HOME||"",n=[c.join(a,".local","bin","claude"),c.join(a,".npm-global","bin","claude"),c.join(a,".local","share","mise","shims","claude"),c.join(a,".asdf","shims","claude"),"/opt/homebrew/bin/claude","/usr/local/bin/claude","/usr/bin/claude","/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js","/usr/lib/node_modules/@anthropic-ai/claude-code/cli.js",c.join(a,".local","share","volta","tools","shared","@anthropic-ai","claude-code","cli.js"),c.join(a,".volta","tools","shared","@anthropic-ai","claude-code","cli.js")];if(this.shouldUseDefaultClaudeFallbacks(e)){for(const i of n)if(i&&p.existsSync(i))return console.log(`[ClaudeSdkAdapter] Found Claude Code CLI: ${i}`),i}if(this.shouldUseDefaultClaudeFallbacks(e))try{const i=S("npm root -g",{encoding:"utf8",timeout:5e3}).trim(),s=c.join(i,"@anthropic-ai","claude-code","cli.js");if(p.existsSync(s))return console.log(`[ClaudeSdkAdapter] Found Claude Code CLI via npm root: ${s}`),s}catch{}console.warn(`[ClaudeSdkAdapter] Claude Code executable not found for command: ${e}`)}extractExecutableCommand(t){const o=((t||"claude").trim()||"claude").match(/^\s*(?:"([^"]+)"|'([^']+)'|(\S+))/);return o?.[1]||o?.[2]||o?.[3]||"claude"}resolveExecutableFromPath(t){const e=process.env.PATH||"";if(!e)return;const o=c.extname(t).length>0,a=process.platform==="win32"?this.getWindowsPathExtensions(o):[""];for(const n of e.split(c.delimiter))if(n)for(const i of a){const s=c.join(n,`${t}${i}`);if(p.existsSync(s)){if(this.isWindowsWrapperPath(s)){const r=this.resolveWindowsWrapper(s);if(r)return r;continue}return console.log(`[ClaudeSdkAdapter] Found Claude Code CLI via PATH: ${s}`),s}}}getWindowsPathExtensions(t){return t?[""]:(process.env.PATHEXT||".EXE;.CMD;.BAT;.COM;.PS1").split(";").map(o=>o.trim()).filter(o=>o.length>0)}shouldUseDefaultClaudeFallbacks(t){return["claude","claude-code","claudecode"].includes(t.toLowerCase())}isWindowsWrapperPath(t){const e=c.extname(t).toLowerCase();return[".cmd",".bat",".ps1"].includes(e)}resolveWindowsWrapper(t){if(this.isWindowsWrapperPath(t))return this.resolveCliJsFromWrapper(t)}resolveCliJsFromWrapper(t){try{if(p.readFileSync(t,"utf8").includes("volta run")){const n=c.join(process.env.LOCALAPPDATA||"","Volta","tools","shared","@anthropic-ai","claude-code","cli.js");if(p.existsSync(n))return n}const o=c.dirname(t),a=c.join(o,"node_modules","@anthropic-ai","claude-code","cli.js");if(p.existsSync(a))return a}catch{}}buildQueryOptions(t,e,o){const a={cwd:e.workingDirectory,abortController:o,settingSources:["user","project","local"],includePartialMessages:!0},n=this.findClaudeExecutable(e.command);if(n?(a.pathToClaudeCodeExecutable=n,console.log(`[ClaudeSdkAdapter] \u2605\u2605\u2605 \u4F7F\u7528 Claude Code \u53EF\u6267\u884C\u6587\u4EF6 \u2605\u2605\u2605 path="${n}"`)):console.warn(`[ClaudeSdkAdapter] \u2605\u2605\u2605 \u8B66\u544A\uFF1A\u672A\u627E\u5230 Claude Code \u53EF\u6267\u884C\u6587\u4EF6 \u2605\u2605\u2605 command="${e.command}"`),e.model&&(a.model=e.model),e.maxTurns&&e.maxTurns>0&&(a.maxTurns=e.maxTurns),e.mcpConfigPath)try{const i=p.readFileSync(e.mcpConfigPath,"utf-8"),s=JSON.parse(i);a.mcpServers={...e.extraMcpServers,...s.mcpServers}}catch{a.mcpServers=e.extraMcpServers||{}}else a.mcpServers=e.extraMcpServers||{};return e.allowedTools&&e.allowedTools.length>0?a.allowedTools=e.allowedTools:a.allowedTools=["Read","Write","Edit","Bash","Glob","Grep","WebSearch","WebFetch","Task","NotebookEdit","LSP","Skill","mcp__*"],a.env={...process.env,...e.envOverrides},a.canUseTool=this.createPermissionHandler(t,e.autoAccept),a}createPermissionHandler(t,e){return async(o,a,n)=>o==="AskUserQuestion"||o==="ask_user_question"?new Promise(i=>{this.pendingQuestions.set(t,{resolve:i,toolInput:a}),this.emit("ask-user-question",{sessionId:t,toolCallId:this.activeToolUseIds.get(t)||void 0,questions:a.questions})}):e?{behavior:"allow",updatedInput:a}:new Promise(i=>{this.pendingPermissions.set(t,{resolve:i,toolInput:a}),this.emit("permission-request",{sessionId:t,toolName:o,toolInput:a,permissionPrompt:`Allow ${o}?`})})}async consumeStream(t,e){const o=this.sessions.get(t);if(o)try{for await(const a of e){const n=a;this.handleSdkMessage(t,o,n)}}catch(a){if(this.abortControllers.get(t)?.signal.aborted)return;const n=a instanceof Error?a.message:String(a);this.emitEvent(t,{type:"error",sessionId:t,timestamp:new Date().toISOString(),data:{text:`Stream error: ${n}`}})}}applyUsage(t,e){e&&(Number.isFinite(e.input_tokens)&&(t.totalUsage.inputTokens=Math.max(t.totalUsage.inputTokens,e.input_tokens??0)),Number.isFinite(e.output_tokens)&&(t.totalUsage.outputTokens=Math.max(t.totalUsage.outputTokens,e.output_tokens??0)))}handleSdkMessage(t,e,o){const a=new Date().toISOString();switch(console.log(`[ClaudeSdkAdapter] Received message type: "${o.type}", subtype: "${o.subtype||""}"`),o.tool_name&&console.log(`[ClaudeSdkAdapter] Tool name: "${o.tool_name}"`),o.type){case"text":o.delta&&(e.status!=="thinking"&&(e.status="thinking",this.emit("status-change",t,"thinking"),this.stopIdleDetection(t)),this.emitEvent(t,{type:"text_delta",sessionId:t,timestamp:a,data:{text:o.delta}}));break;case"thinking":e.status!=="thinking"&&(e.status="thinking",this.emit("status-change",t,"thinking"),this.stopIdleDetection(t)),(o.content||o.delta)&&this.emitEvent(t,{type:"thinking",sessionId:t,timestamp:a,data:{text:o.delta||o.content}});break;case"tool_use":case"tool_use_start":{const n={...f(o.tool_name,o.tool_input),actionId:o.tool_use_id},i=n.actionType==="idle"?"waiting_input":"tool_using";e.status=i;const s=this.extractMcpServerName(o.tool_name||"");this.emit("status-change",t,i,{actionType:n.actionType,actionLabel:n.actionLabel,actionDetail:n.actionDetail,actionId:n.actionId,usage:e.totalUsage,...s?{metadata:{mcpServer:s}}:{}}),n.actionType!=="idle"&&this.stopIdleDetection(t),this.handleToolUse(t,e,o,a)}break;case"tool_result":case"tool_use_end":this.emitEvent(t,{type:"tool_use_end",sessionId:t,timestamp:a,data:{toolName:o.tool_name,toolResult:o.tool_result,isError:o.is_error,toolUseId:o.tool_use_id}});break;case"result":{const n=o.subtype==="success";this.applyUsage(e,o.usage),this.emitEvent(t,{type:"turn_complete",sessionId:t,timestamp:a,data:{usage:e.totalUsage,text:n?o.result:void 0}}),e.status="waiting_input",(()=>{const s=this.idleCommands.get(t);return!!(s?.idleInputCommand&&this.isMessagePollingIdleCommand(s.idleInputCommand))})()?this.emit("status-change",t,"waiting_input",{actionType:"idle",actionLabel:"\u76D1\u542C\u6D88\u606F",actionDetail:"aws-mcp/poll_message",usage:e.totalUsage}):this.emit("status-change",t,"waiting_input",{usage:e.totalUsage}),this.idleCommands.has(t)&&this.startIdleDetection(t)}break;case"system":o.subtype==="init"&&console.log(`[ClaudeSdkAdapter] Session ${t} initialized: model=${o.model}, tools=${o.tools?.length||0}`);break;case"assistant":if(this.applyUsage(e,o.message?.usage),o.message?.content){const n=o.message.content.filter(i=>i.type==="text"&&i.text).map(i=>i.text||"").join("");n&&e.messages.push({id:h(),sessionId:t,role:"assistant",content:n,timestamp:a})}break;case"user":o.tool_use_result;break;case"error":e.status="error",this.emit("status-change",t,"error"),this.emitEvent(t,{type:"error",sessionId:t,timestamp:a,data:{text:o.content||"Unknown error"}});break;case"stream_event":this.handleStreamEvent(t,e,o,a);break;default:console.log(`[ClaudeSdkAdapter] Unknown message type: ${o.type}`,o)}}handleToolUse(t,e,o,a){const n=this.recentToolNames.get(t),i=this.extractToolNameSuffix(o.tool_name||"");if(n&&Date.now()-n.time<3e4&&n.name===i){console.log(`[ClaudeSdkAdapter] Tool use ${o.tool_name} matches recent stream_event (${n.name}), skipping duplicate event`),this.recentToolNames.delete(t),this.activeToolUseIds.delete(t),e.messages.push({id:h(),sessionId:t,role:"tool_use",content:`${o.tool_name}: ${JSON.stringify(o.tool_input).slice(0,100)}`,timestamp:a,toolName:o.tool_name,toolInput:o.tool_input,toolUseId:o.tool_use_id});return}this.recentToolNames.delete(t),this.activeToolUseIds.delete(t);const s=f(o.tool_name,o.tool_input);console.log(`[ClaudeSdkAdapter] Tool use: ${o.tool_name}, actionType: ${s.actionType}, actionDetail: ${s.actionDetail}`);const r=this.extractMcpServerName(o.tool_name||"");this.emitEvent(t,{type:"tool_use_start",sessionId:t,timestamp:a,data:{toolName:o.tool_name,toolInput:o.tool_input,toolUseId:o.tool_use_id,actionType:s.actionType,actionLabel:s.actionLabel,actionDetail:s.actionDetail,...r?{metadata:{mcpServer:r}}:{}}}),e.messages.push({id:h(),sessionId:t,role:"tool_use",content:`${o.tool_name}: ${JSON.stringify(o.tool_input).slice(0,100)}`,timestamp:a,toolName:o.tool_name,toolInput:o.tool_input,toolUseId:o.tool_use_id})}handleStreamEvent(t,e,o,a){const n=o.event;if(n){if(n.type==="content_block_start"){const i=n.content_block;if(i?.type==="tool_use"&&i.name){const s=i.name,r=i.id||`stream_${Date.now()}`;console.log(`[ClaudeSdkAdapter] Tool use started via stream_event: ${s} (id: ${r})`),this.activeToolUseIds.set(t,r);const l=this.extractToolNameSuffix(s);this.recentToolNames.set(t,{name:l,time:Date.now()});const d=`${t}:${r}`;this.toolInputBuffers.set(d,"")}}if(n.type==="content_block_delta"&&n.delta?.type==="input_json_delta"&&n.delta.partial_json){const i=this.activeToolUseIds.get(t);if(i){const s=`${t}:${i}`,r=this.toolInputBuffers.get(s)||"";this.toolInputBuffers.set(s,r+n.delta.partial_json),console.log(`[ClaudeSdkAdapter] Tool input delta at index ${n.index}, buffer length: ${r.length+n.delta.partial_json.length}`)}}if(n.type==="content_block_stop"){const i=this.activeToolUseIds.get(t),s=this.recentToolNames.get(t);if(i&&s){const r=`${t}:${i}`,l=this.toolInputBuffers.get(r)||"";console.log(`[ClaudeSdkAdapter] Content block stopped at index ${n.index}, collected JSON length: ${l.length}`);let d;if(l)try{d=JSON.parse(l),console.log("[ClaudeSdkAdapter] Parsed tool input:",JSON.stringify(d).slice(0,200))}catch{console.warn("[ClaudeSdkAdapter] Failed to parse tool input JSON:",l.slice(0,100))}const u={...f(s.name,d),actionId:i},m=this.extractMcpServerName(s.name);e.status="tool_using",this.emit("status-change",t,"tool_using",{actionType:u.actionType,actionLabel:u.actionLabel,actionDetail:u.actionDetail,actionId:u.actionId,usage:e.totalUsage,...m?{metadata:{mcpServer:m}}:{}}),this.stopIdleDetection(t),this.emitEvent(t,{type:"tool_use_start",sessionId:t,timestamp:a,data:{toolName:s.name,toolInput:d,toolUseId:i,actionType:u.actionType,actionLabel:u.actionLabel,actionDetail:u.actionDetail,actionId:u.actionId,...m?{metadata:{mcpServer:m}}:{}}}),e.messages.push({id:h(),sessionId:t,role:"tool_use",content:`${s.name}: ${l.slice(0,100)}`,timestamp:a,toolName:s.name,toolInput:d,toolUseId:i}),this.toolInputBuffers.delete(r),this.activeToolUseIds.delete(t)}}}}extractMcpServerName(t){if(t.startsWith("mcp__")){const e=t.split("__");if(e.length>=3)return e[1]}}extractToolNameSuffix(t){if(t.includes("__"))return t.split("__").pop()||t;if(t.includes("-mcp__")){const e=t.indexOf("-mcp__");return t.substring(e+6)}return t}emitEvent(t,e){this.emit("event",e)}cleanupSession(t){this.stopIdleDetection(t),this.sessions.delete(t),this.sdkQueries.delete(t),this.inputStreams.delete(t),this.abortControllers.delete(t),this.pendingPermissions.delete(t),this.pendingQuestions.delete(t),this.idleCommands.delete(t),this.idlePollLoops.delete(t),this.lastActivityAt.delete(t)}}export{A as ClaudeSdkAdapter};
4
+