@machina.ai/cell-cli-core 1.20.2-rc1 → 1.25.0-rc1

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 (898) hide show
  1. package/dist/docs/AFTER_MERGE_PROMPT.md +26 -0
  2. package/dist/docs/CHANGES.md +124 -0
  3. package/dist/docs/api-proxy.md +27 -0
  4. package/dist/docs/architecture.md +80 -0
  5. package/dist/docs/assets/connected_devtools.png +0 -0
  6. package/dist/docs/assets/gemini-screenshot.png +0 -0
  7. package/dist/docs/assets/monitoring-dashboard-logs.png +0 -0
  8. package/dist/docs/assets/monitoring-dashboard-metrics.png +0 -0
  9. package/dist/docs/assets/monitoring-dashboard-overview.png +0 -0
  10. package/dist/docs/assets/release_patch.png +0 -0
  11. package/dist/docs/assets/theme-ansi-light.png +0 -0
  12. package/dist/docs/assets/theme-ansi.png +0 -0
  13. package/dist/docs/assets/theme-atom-one.png +0 -0
  14. package/dist/docs/assets/theme-ayu-light.png +0 -0
  15. package/dist/docs/assets/theme-ayu.png +0 -0
  16. package/dist/docs/assets/theme-custom.png +0 -0
  17. package/dist/docs/assets/theme-default-light.png +0 -0
  18. package/dist/docs/assets/theme-default.png +0 -0
  19. package/dist/docs/assets/theme-dracula.png +0 -0
  20. package/dist/docs/assets/theme-github-light.png +0 -0
  21. package/dist/docs/assets/theme-github.png +0 -0
  22. package/dist/docs/assets/theme-google-light.png +0 -0
  23. package/dist/docs/assets/theme-xcode-light.png +0 -0
  24. package/dist/docs/changelogs/index.md +612 -0
  25. package/dist/docs/changelogs/latest.md +153 -0
  26. package/dist/docs/changelogs/preview.md +131 -0
  27. package/dist/docs/changelogs/releases.md +1162 -0
  28. package/dist/docs/cli/authentication.md +3 -0
  29. package/dist/docs/cli/checkpointing.md +94 -0
  30. package/dist/docs/cli/commands.md +357 -0
  31. package/dist/docs/cli/custom-commands.md +315 -0
  32. package/dist/docs/cli/enterprise.md +564 -0
  33. package/dist/docs/cli/gemini-ignore.md +71 -0
  34. package/dist/docs/cli/gemini-md.md +109 -0
  35. package/dist/docs/cli/generation-settings.md +210 -0
  36. package/dist/docs/cli/headless.md +388 -0
  37. package/dist/docs/cli/index.md +63 -0
  38. package/dist/docs/cli/keyboard-shortcuts.md +136 -0
  39. package/dist/docs/cli/model-routing.md +37 -0
  40. package/dist/docs/cli/model.md +62 -0
  41. package/dist/docs/cli/sandbox.md +171 -0
  42. package/dist/docs/cli/session-management.md +158 -0
  43. package/dist/docs/cli/settings.md +148 -0
  44. package/dist/docs/cli/skills.md +188 -0
  45. package/dist/docs/cli/system-prompt.md +94 -0
  46. package/dist/docs/cli/telemetry.md +813 -0
  47. package/dist/docs/cli/themes.md +237 -0
  48. package/dist/docs/cli/token-caching.md +20 -0
  49. package/dist/docs/cli/trusted-folders.md +95 -0
  50. package/dist/docs/cli/tutorials/skills-getting-started.md +124 -0
  51. package/dist/docs/cli/tutorials.md +87 -0
  52. package/dist/docs/cli/uninstall.md +47 -0
  53. package/dist/docs/core/index.md +101 -0
  54. package/dist/docs/core/memport.md +246 -0
  55. package/dist/docs/core/policy-engine.md +268 -0
  56. package/dist/docs/core/tools-api.md +131 -0
  57. package/dist/docs/examples/proxy-script.md +83 -0
  58. package/dist/docs/extensions/extension-releasing.md +183 -0
  59. package/dist/docs/extensions/getting-started-extensions.md +244 -0
  60. package/dist/docs/extensions/index.md +343 -0
  61. package/dist/docs/faq.md +153 -0
  62. package/dist/docs/get-started/authentication.md +321 -0
  63. package/dist/docs/get-started/configuration-v1.md +890 -0
  64. package/dist/docs/get-started/configuration.md +1643 -0
  65. package/dist/docs/get-started/examples.md +218 -0
  66. package/dist/docs/get-started/gemini-3.md +101 -0
  67. package/dist/docs/get-started/index.md +71 -0
  68. package/dist/docs/get-started/installation.md +141 -0
  69. package/dist/docs/hooks/best-practices.md +856 -0
  70. package/dist/docs/hooks/index.md +723 -0
  71. package/dist/docs/hooks/reference.md +178 -0
  72. package/dist/docs/hooks/writing-hooks.md +1044 -0
  73. package/dist/docs/ide-integration/ide-companion-spec.md +267 -0
  74. package/dist/docs/ide-integration/index.md +201 -0
  75. package/dist/docs/index.md +147 -0
  76. package/dist/docs/integration-tests.md +211 -0
  77. package/dist/docs/issue-and-pr-automation.md +134 -0
  78. package/dist/docs/local-development.md +128 -0
  79. package/dist/docs/mcp_integration.md +160 -0
  80. package/dist/docs/mermaid/context.mmd +103 -0
  81. package/dist/docs/mermaid/render-path.mmd +64 -0
  82. package/dist/docs/npm.md +62 -0
  83. package/dist/docs/quota-and-pricing.md +158 -0
  84. package/dist/docs/release-confidence.md +164 -0
  85. package/dist/docs/releases.md +540 -0
  86. package/dist/docs/sidebar.json +301 -0
  87. package/dist/docs/tools/file-system.md +217 -0
  88. package/dist/docs/tools/index.md +95 -0
  89. package/dist/docs/tools/mcp-server.md +1045 -0
  90. package/dist/docs/tools/memory.md +54 -0
  91. package/dist/docs/tools/shell.md +260 -0
  92. package/dist/docs/tools/todos.md +56 -0
  93. package/dist/docs/tools/web-fetch.md +59 -0
  94. package/dist/docs/tools/web-search.md +42 -0
  95. package/dist/docs/tos-privacy.md +96 -0
  96. package/dist/docs/troubleshooting.md +162 -0
  97. package/dist/index.d.ts +1 -1
  98. package/dist/index.js +1 -1
  99. package/dist/index.js.map +1 -1
  100. package/dist/package.json +7 -4
  101. package/dist/src/agents/a2a-client-manager.d.ts +82 -0
  102. package/dist/src/agents/a2a-client-manager.js +295 -0
  103. package/dist/src/agents/a2a-client-manager.js.map +1 -0
  104. package/dist/src/agents/a2a-client-manager.test.js +281 -0
  105. package/dist/src/agents/a2a-client-manager.test.js.map +1 -0
  106. package/dist/src/agents/a2aUtils.d.ts +29 -0
  107. package/dist/src/agents/a2aUtils.js +113 -0
  108. package/dist/src/agents/a2aUtils.js.map +1 -0
  109. package/dist/src/agents/a2aUtils.test.js +147 -0
  110. package/dist/src/agents/a2aUtils.test.js.map +1 -0
  111. package/dist/src/agents/agentLoader.d.ts +68 -0
  112. package/dist/src/agents/agentLoader.js +255 -0
  113. package/dist/src/agents/agentLoader.js.map +1 -0
  114. package/dist/src/agents/agentLoader.test.js +307 -0
  115. package/dist/src/agents/agentLoader.test.js.map +1 -0
  116. package/dist/src/agents/cli-help-agent.d.ts +24 -0
  117. package/dist/src/agents/cli-help-agent.js +85 -0
  118. package/dist/src/agents/cli-help-agent.js.map +1 -0
  119. package/dist/src/agents/cli-help-agent.test.d.ts +6 -0
  120. package/dist/src/agents/cli-help-agent.test.js +65 -0
  121. package/dist/src/agents/cli-help-agent.test.js.map +1 -0
  122. package/dist/src/agents/codebase-investigator.d.ts +2 -2
  123. package/dist/src/agents/codebase-investigator.js +14 -8
  124. package/dist/src/agents/codebase-investigator.js.map +1 -1
  125. package/dist/src/agents/delegate-to-agent-tool.d.ts +19 -0
  126. package/dist/src/agents/delegate-to-agent-tool.js +122 -0
  127. package/dist/src/agents/delegate-to-agent-tool.js.map +1 -0
  128. package/dist/src/agents/delegate-to-agent-tool.test.d.ts +6 -0
  129. package/dist/src/agents/delegate-to-agent-tool.test.js +213 -0
  130. package/dist/src/agents/delegate-to-agent-tool.test.js.map +1 -0
  131. package/dist/src/agents/{executor.d.ts → local-executor.d.ts} +5 -11
  132. package/dist/src/agents/{executor.js → local-executor.js} +124 -63
  133. package/dist/src/agents/local-executor.js.map +1 -0
  134. package/dist/src/agents/local-executor.test.d.ts +6 -0
  135. package/dist/src/agents/{executor.test.js → local-executor.test.js} +136 -58
  136. package/dist/src/agents/local-executor.test.js.map +1 -0
  137. package/dist/src/agents/{invocation.d.ts → local-invocation.d.ts} +6 -7
  138. package/dist/src/agents/{invocation.js → local-invocation.js} +9 -10
  139. package/dist/src/agents/local-invocation.js.map +1 -0
  140. package/dist/src/agents/local-invocation.test.d.ts +6 -0
  141. package/dist/src/agents/{invocation.test.js → local-invocation.test.js} +29 -20
  142. package/dist/src/agents/local-invocation.test.js.map +1 -0
  143. package/dist/src/agents/registry.d.ts +37 -1
  144. package/dist/src/agents/registry.js +240 -27
  145. package/dist/src/agents/registry.js.map +1 -1
  146. package/dist/src/agents/registry.test.js +465 -30
  147. package/dist/src/agents/registry.test.js.map +1 -1
  148. package/dist/src/agents/remote-invocation.d.ts +35 -0
  149. package/dist/src/agents/remote-invocation.js +126 -0
  150. package/dist/src/agents/remote-invocation.js.map +1 -0
  151. package/dist/src/agents/remote-invocation.test.d.ts +6 -0
  152. package/dist/src/agents/remote-invocation.test.js +201 -0
  153. package/dist/src/agents/remote-invocation.test.js.map +1 -0
  154. package/dist/src/agents/subagent-tool-wrapper.d.ts +2 -2
  155. package/dist/src/agents/subagent-tool-wrapper.js +11 -6
  156. package/dist/src/agents/subagent-tool-wrapper.js.map +1 -1
  157. package/dist/src/agents/subagent-tool-wrapper.test.js +33 -19
  158. package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -1
  159. package/dist/src/agents/types.d.ts +21 -15
  160. package/dist/src/agents/types.js.map +1 -1
  161. package/dist/src/availability/errorClassification.d.ts +7 -0
  162. package/dist/src/availability/errorClassification.js +20 -0
  163. package/dist/src/availability/errorClassification.js.map +1 -0
  164. package/dist/src/availability/fallbackIntegration.test.d.ts +6 -0
  165. package/dist/src/availability/fallbackIntegration.test.js +58 -0
  166. package/dist/src/availability/fallbackIntegration.test.js.map +1 -0
  167. package/dist/src/availability/modelAvailabilityService.d.ts +3 -1
  168. package/dist/src/availability/modelAvailabilityService.js +3 -0
  169. package/dist/src/availability/modelAvailabilityService.js.map +1 -1
  170. package/dist/src/availability/modelPolicy.d.ts +8 -1
  171. package/dist/src/availability/policyCatalog.d.ts +1 -0
  172. package/dist/src/availability/policyCatalog.js +6 -7
  173. package/dist/src/availability/policyCatalog.js.map +1 -1
  174. package/dist/src/availability/policyCatalog.test.js +2 -2
  175. package/dist/src/availability/policyCatalog.test.js.map +1 -1
  176. package/dist/src/availability/policyHelpers.d.ts +34 -3
  177. package/dist/src/availability/policyHelpers.js +104 -13
  178. package/dist/src/availability/policyHelpers.js.map +1 -1
  179. package/dist/src/availability/policyHelpers.test.js +143 -13
  180. package/dist/src/availability/policyHelpers.test.js.map +1 -1
  181. package/dist/src/availability/testUtils.d.ts +10 -0
  182. package/dist/src/availability/testUtils.js +22 -0
  183. package/dist/src/availability/testUtils.js.map +1 -0
  184. package/dist/src/code_assist/experiments/client_metadata.js +2 -1
  185. package/dist/src/code_assist/experiments/client_metadata.js.map +1 -1
  186. package/dist/src/code_assist/experiments/client_metadata.test.js +7 -10
  187. package/dist/src/code_assist/experiments/client_metadata.test.js.map +1 -1
  188. package/dist/src/code_assist/experiments/experiments.d.ts +1 -1
  189. package/dist/src/code_assist/experiments/experiments.js +21 -0
  190. package/dist/src/code_assist/experiments/experiments.js.map +1 -1
  191. package/dist/src/code_assist/experiments/experiments_local.test.d.ts +6 -0
  192. package/dist/src/code_assist/experiments/experiments_local.test.js +110 -0
  193. package/dist/src/code_assist/experiments/experiments_local.test.js.map +1 -0
  194. package/dist/src/code_assist/oauth-credential-storage.js +3 -4
  195. package/dist/src/code_assist/oauth-credential-storage.js.map +1 -1
  196. package/dist/src/code_assist/oauth2.d.ts +2 -0
  197. package/dist/src/code_assist/oauth2.js +70 -14
  198. package/dist/src/code_assist/oauth2.js.map +1 -1
  199. package/dist/src/code_assist/oauth2.test.js +224 -22
  200. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  201. package/dist/src/code_assist/server.d.ts +9 -1
  202. package/dist/src/code_assist/server.js +74 -11
  203. package/dist/src/code_assist/server.js.map +1 -1
  204. package/dist/src/code_assist/server.test.js +199 -27
  205. package/dist/src/code_assist/server.test.js.map +1 -1
  206. package/dist/src/code_assist/setup.js +6 -4
  207. package/dist/src/code_assist/setup.js.map +1 -1
  208. package/dist/src/code_assist/setup.test.js +63 -0
  209. package/dist/src/code_assist/setup.test.js.map +1 -1
  210. package/dist/src/code_assist/telemetry.d.ts +14 -0
  211. package/dist/src/code_assist/telemetry.js +157 -0
  212. package/dist/src/code_assist/telemetry.js.map +1 -0
  213. package/dist/src/code_assist/telemetry.test.d.ts +6 -0
  214. package/dist/src/code_assist/telemetry.test.js +301 -0
  215. package/dist/src/code_assist/telemetry.test.js.map +1 -0
  216. package/dist/src/code_assist/types.d.ts +77 -1
  217. package/dist/src/code_assist/types.js +28 -0
  218. package/dist/src/code_assist/types.js.map +1 -1
  219. package/dist/src/commands/init.d.ts +7 -0
  220. package/dist/src/commands/init.js +53 -0
  221. package/dist/src/commands/init.js.map +1 -0
  222. package/dist/src/commands/init.test.d.ts +6 -0
  223. package/dist/src/commands/init.test.js +25 -0
  224. package/dist/src/commands/init.test.js.map +1 -0
  225. package/dist/src/commands/memory.d.ts +11 -0
  226. package/dist/src/commands/memory.js +80 -0
  227. package/dist/src/commands/memory.js.map +1 -0
  228. package/dist/src/commands/memory.test.d.ts +6 -0
  229. package/dist/src/commands/memory.test.js +155 -0
  230. package/dist/src/commands/memory.test.js.map +1 -0
  231. package/dist/src/commands/restore.d.ts +9 -0
  232. package/dist/src/commands/restore.js +46 -0
  233. package/dist/src/commands/restore.js.map +1 -0
  234. package/dist/src/commands/restore.test.d.ts +6 -0
  235. package/dist/src/commands/restore.test.js +137 -0
  236. package/dist/src/commands/restore.test.js.map +1 -0
  237. package/dist/src/commands/types.d.ts +41 -0
  238. package/dist/src/commands/types.js +7 -0
  239. package/dist/src/commands/types.js.map +1 -0
  240. package/dist/src/config/config.d.ts +145 -25
  241. package/dist/src/config/config.js +370 -132
  242. package/dist/src/config/config.js.map +1 -1
  243. package/dist/src/config/config.test.js +416 -50
  244. package/dist/src/config/config.test.js.map +1 -1
  245. package/dist/src/config/defaultModelConfigs.js +21 -0
  246. package/dist/src/config/defaultModelConfigs.js.map +1 -1
  247. package/dist/src/config/flashFallback.test.js +11 -35
  248. package/dist/src/config/flashFallback.test.js.map +1 -1
  249. package/dist/src/config/models.d.ts +36 -15
  250. package/dist/src/config/models.js +89 -28
  251. package/dist/src/config/models.js.map +1 -1
  252. package/dist/src/config/models.test.js +107 -77
  253. package/dist/src/config/models.test.js.map +1 -1
  254. package/dist/src/config/storage.d.ts +5 -0
  255. package/dist/src/config/storage.js +17 -2
  256. package/dist/src/config/storage.js.map +1 -1
  257. package/dist/src/config/storage.test.js +16 -0
  258. package/dist/src/config/storage.test.js.map +1 -1
  259. package/dist/src/confirmation-bus/message-bus.js +3 -1
  260. package/dist/src/confirmation-bus/message-bus.js.map +1 -1
  261. package/dist/src/confirmation-bus/types.d.ts +4 -0
  262. package/dist/src/core/baseLlmClient.d.ts +3 -1
  263. package/dist/src/core/baseLlmClient.js +60 -22
  264. package/dist/src/core/baseLlmClient.js.map +1 -1
  265. package/dist/src/core/baseLlmClient.test.js +177 -7
  266. package/dist/src/core/baseLlmClient.test.js.map +1 -1
  267. package/dist/src/core/client.d.ts +7 -1
  268. package/dist/src/core/client.js +261 -96
  269. package/dist/src/core/client.js.map +1 -1
  270. package/dist/src/core/client.test.js +397 -67
  271. package/dist/src/core/client.test.js.map +1 -1
  272. package/dist/src/core/clientHookTriggers.js +2 -2
  273. package/dist/src/core/clientHookTriggers.js.map +1 -1
  274. package/dist/src/core/contentGenerator.js +6 -4
  275. package/dist/src/core/contentGenerator.js.map +1 -1
  276. package/dist/src/core/contentGenerator.test.js +24 -23
  277. package/dist/src/core/contentGenerator.test.js.map +1 -1
  278. package/dist/src/core/coreToolHookTriggers.d.ts +9 -5
  279. package/dist/src/core/coreToolHookTriggers.js +119 -21
  280. package/dist/src/core/coreToolHookTriggers.js.map +1 -1
  281. package/dist/src/core/coreToolHookTriggers.test.d.ts +6 -0
  282. package/dist/src/core/coreToolHookTriggers.test.js +191 -0
  283. package/dist/src/core/coreToolHookTriggers.test.js.map +1 -0
  284. package/dist/src/core/coreToolScheduler.d.ts +7 -93
  285. package/dist/src/core/coreToolScheduler.js +139 -333
  286. package/dist/src/core/coreToolScheduler.js.map +1 -1
  287. package/dist/src/core/coreToolScheduler.test.js +304 -348
  288. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  289. package/dist/src/core/geminiChat.d.ts +26 -1
  290. package/dist/src/core/geminiChat.js +144 -80
  291. package/dist/src/core/geminiChat.js.map +1 -1
  292. package/dist/src/core/geminiChat.test.js +334 -253
  293. package/dist/src/core/geminiChat.test.js.map +1 -1
  294. package/dist/src/core/geminiChatHookTriggers.d.ts +8 -4
  295. package/dist/src/core/geminiChatHookTriggers.js +34 -12
  296. package/dist/src/core/geminiChatHookTriggers.js.map +1 -1
  297. package/dist/src/core/geminiChatHookTriggers.test.d.ts +6 -0
  298. package/dist/src/core/geminiChatHookTriggers.test.js +153 -0
  299. package/dist/src/core/geminiChatHookTriggers.test.js.map +1 -0
  300. package/dist/src/core/geminiChat_network_retry.test.d.ts +6 -0
  301. package/dist/src/core/geminiChat_network_retry.test.js +196 -0
  302. package/dist/src/core/geminiChat_network_retry.test.js.map +1 -0
  303. package/dist/src/core/logger.js.map +1 -1
  304. package/dist/src/core/loggingContentGenerator.js +19 -2
  305. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  306. package/dist/src/core/loggingContentGenerator.test.js +30 -0
  307. package/dist/src/core/loggingContentGenerator.test.js.map +1 -1
  308. package/dist/src/core/nonInteractiveToolExecutor.test.js +7 -8
  309. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  310. package/dist/src/core/prompts.js +48 -22
  311. package/dist/src/core/prompts.js.map +1 -1
  312. package/dist/src/core/prompts.test.js +66 -11
  313. package/dist/src/core/prompts.test.js.map +1 -1
  314. package/dist/src/core/tokenLimits.js +6 -12
  315. package/dist/src/core/tokenLimits.js.map +1 -1
  316. package/dist/src/core/tokenLimits.test.js +8 -4
  317. package/dist/src/core/tokenLimits.test.js.map +1 -1
  318. package/dist/src/core/turn.d.ts +21 -21
  319. package/dist/src/core/turn.js +32 -22
  320. package/dist/src/core/turn.js.map +1 -1
  321. package/dist/src/core/turn.test.js +79 -5
  322. package/dist/src/core/turn.test.js.map +1 -1
  323. package/dist/src/fallback/handler.js +55 -120
  324. package/dist/src/fallback/handler.js.map +1 -1
  325. package/dist/src/fallback/handler.test.js +115 -288
  326. package/dist/src/fallback/handler.test.js.map +1 -1
  327. package/dist/src/generated/git-commit.d.ts +3 -3
  328. package/dist/src/generated/git-commit.js +3 -3
  329. package/dist/src/hooks/hookAggregator.js +7 -0
  330. package/dist/src/hooks/hookAggregator.js.map +1 -1
  331. package/dist/src/hooks/hookEventHandler.d.ts +9 -5
  332. package/dist/src/hooks/hookEventHandler.js +120 -16
  333. package/dist/src/hooks/hookEventHandler.js.map +1 -1
  334. package/dist/src/hooks/hookEventHandler.test.js +231 -9
  335. package/dist/src/hooks/hookEventHandler.test.js.map +1 -1
  336. package/dist/src/hooks/hookPlanner.d.ts +1 -5
  337. package/dist/src/hooks/hookPlanner.js +2 -7
  338. package/dist/src/hooks/hookPlanner.js.map +1 -1
  339. package/dist/src/hooks/hookPlanner.test.js +62 -2
  340. package/dist/src/hooks/hookPlanner.test.js.map +1 -1
  341. package/dist/src/hooks/hookRegistry.d.ts +6 -18
  342. package/dist/src/hooks/hookRegistry.js +49 -35
  343. package/dist/src/hooks/hookRegistry.js.map +1 -1
  344. package/dist/src/hooks/hookRegistry.test.js +167 -8
  345. package/dist/src/hooks/hookRegistry.test.js.map +1 -1
  346. package/dist/src/hooks/hookRunner.d.ts +5 -3
  347. package/dist/src/hooks/hookRunner.js +68 -18
  348. package/dist/src/hooks/hookRunner.js.map +1 -1
  349. package/dist/src/hooks/hookRunner.test.js +173 -36
  350. package/dist/src/hooks/hookRunner.test.js.map +1 -1
  351. package/dist/src/hooks/hookSystem.d.ts +10 -6
  352. package/dist/src/hooks/hookSystem.js +36 -16
  353. package/dist/src/hooks/hookSystem.js.map +1 -1
  354. package/dist/src/hooks/hookSystem.test.js +123 -18
  355. package/dist/src/hooks/hookSystem.test.js.map +1 -1
  356. package/dist/src/hooks/hookTranslator.js +2 -1
  357. package/dist/src/hooks/hookTranslator.js.map +1 -1
  358. package/dist/src/hooks/index.d.ts +2 -1
  359. package/dist/src/hooks/index.js +1 -0
  360. package/dist/src/hooks/index.js.map +1 -1
  361. package/dist/src/hooks/trustedHooks.d.ts +28 -0
  362. package/dist/src/hooks/trustedHooks.js +90 -0
  363. package/dist/src/hooks/trustedHooks.js.map +1 -0
  364. package/dist/src/hooks/trustedHooks.test.d.ts +6 -0
  365. package/dist/src/hooks/trustedHooks.test.js +154 -0
  366. package/dist/src/hooks/trustedHooks.test.js.map +1 -0
  367. package/dist/src/hooks/types.d.ts +42 -11
  368. package/dist/src/hooks/types.js +31 -42
  369. package/dist/src/hooks/types.js.map +1 -1
  370. package/dist/src/hooks/types.test.js +9 -52
  371. package/dist/src/hooks/types.test.js.map +1 -1
  372. package/dist/src/ide/detect-ide.d.ts +4 -0
  373. package/dist/src/ide/detect-ide.js +7 -2
  374. package/dist/src/ide/detect-ide.js.map +1 -1
  375. package/dist/src/ide/detect-ide.test.js +42 -1
  376. package/dist/src/ide/detect-ide.test.js.map +1 -1
  377. package/dist/src/ide/ide-client.js +6 -1
  378. package/dist/src/ide/ide-client.js.map +1 -1
  379. package/dist/src/ide/ide-installer.js +2 -2
  380. package/dist/src/ide/ide-installer.js.map +1 -1
  381. package/dist/src/ide/ide-installer.test.js +12 -3
  382. package/dist/src/ide/ide-installer.test.js.map +1 -1
  383. package/dist/src/index.d.ts +23 -1
  384. package/dist/src/index.js +25 -2
  385. package/dist/src/index.js.map +1 -1
  386. package/dist/src/mcp/oauth-provider.js +7 -3
  387. package/dist/src/mcp/oauth-provider.js.map +1 -1
  388. package/dist/src/mcp/oauth-provider.test.js +4 -1
  389. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  390. package/dist/src/mcp/oauth-utils.d.ts +8 -1
  391. package/dist/src/mcp/oauth-utils.js +31 -2
  392. package/dist/src/mcp/oauth-utils.js.map +1 -1
  393. package/dist/src/mcp/oauth-utils.test.js +42 -0
  394. package/dist/src/mcp/oauth-utils.test.js.map +1 -1
  395. package/dist/src/mcp/token-storage/file-token-storage.js +2 -2
  396. package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -1
  397. package/dist/src/mcp/token-storage/keychain-token-storage.js +1 -1
  398. package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -1
  399. package/dist/src/output/json-formatter.d.ts +2 -2
  400. package/dist/src/output/json-formatter.js +6 -3
  401. package/dist/src/output/json-formatter.js.map +1 -1
  402. package/dist/src/output/json-formatter.test.js +37 -9
  403. package/dist/src/output/json-formatter.test.js.map +1 -1
  404. package/dist/src/output/stream-json-formatter.js +6 -0
  405. package/dist/src/output/stream-json-formatter.js.map +1 -1
  406. package/dist/src/output/stream-json-formatter.test.js +98 -100
  407. package/dist/src/output/stream-json-formatter.test.js.map +1 -1
  408. package/dist/src/output/types.d.ts +3 -0
  409. package/dist/src/output/types.js.map +1 -1
  410. package/dist/src/policy/config.js +140 -15
  411. package/dist/src/policy/config.js.map +1 -1
  412. package/dist/src/policy/config.test.js +24 -2
  413. package/dist/src/policy/config.test.js.map +1 -1
  414. package/dist/src/policy/persistence.test.d.ts +6 -0
  415. package/dist/src/policy/persistence.test.js +154 -0
  416. package/dist/src/policy/persistence.test.js.map +1 -0
  417. package/dist/src/policy/policies/agent.toml +31 -0
  418. package/dist/src/policy/policies/write.toml +5 -0
  419. package/dist/src/policy/policies/yolo.toml +1 -0
  420. package/dist/src/policy/policy-engine.d.ts +14 -1
  421. package/dist/src/policy/policy-engine.js +165 -7
  422. package/dist/src/policy/policy-engine.js.map +1 -1
  423. package/dist/src/policy/policy-engine.test.js +315 -3
  424. package/dist/src/policy/policy-engine.test.js.map +1 -1
  425. package/dist/src/policy/policy-updater.test.d.ts +6 -0
  426. package/dist/src/policy/policy-updater.test.js +116 -0
  427. package/dist/src/policy/policy-updater.test.js.map +1 -0
  428. package/dist/src/policy/shell-safety.test.d.ts +6 -0
  429. package/dist/src/policy/shell-safety.test.js +438 -0
  430. package/dist/src/policy/shell-safety.test.js.map +1 -0
  431. package/dist/src/policy/toml-loader.d.ts +3 -5
  432. package/dist/src/policy/toml-loader.js +43 -60
  433. package/dist/src/policy/toml-loader.js.map +1 -1
  434. package/dist/src/policy/toml-loader.test.js +41 -7
  435. package/dist/src/policy/toml-loader.test.js.map +1 -1
  436. package/dist/src/policy/types.d.ts +25 -0
  437. package/dist/src/policy/utils.d.ts +21 -0
  438. package/dist/src/policy/utils.js +45 -0
  439. package/dist/src/policy/utils.js.map +1 -0
  440. package/dist/src/policy/utils.test.d.ts +6 -0
  441. package/dist/src/policy/utils.test.js +92 -0
  442. package/dist/src/policy/utils.test.js.map +1 -0
  443. package/dist/src/resources/resource-registry.d.ts +30 -0
  444. package/dist/src/resources/resource-registry.js +57 -0
  445. package/dist/src/resources/resource-registry.js.map +1 -0
  446. package/dist/src/resources/resource-registry.test.d.ts +6 -0
  447. package/dist/src/resources/resource-registry.test.js +54 -0
  448. package/dist/src/resources/resource-registry.test.js.map +1 -0
  449. package/dist/src/routing/modelRouterService.js +0 -15
  450. package/dist/src/routing/modelRouterService.js.map +1 -1
  451. package/dist/src/routing/modelRouterService.test.js +0 -62
  452. package/dist/src/routing/modelRouterService.test.js.map +1 -1
  453. package/dist/src/routing/routingStrategy.d.ts +2 -0
  454. package/dist/src/routing/strategies/classifierStrategy.js +10 -21
  455. package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
  456. package/dist/src/routing/strategies/classifierStrategy.test.js +18 -1
  457. package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -1
  458. package/dist/src/routing/strategies/compositeStrategy.js +4 -2
  459. package/dist/src/routing/strategies/compositeStrategy.js.map +1 -1
  460. package/dist/src/routing/strategies/compositeStrategy.test.js +11 -10
  461. package/dist/src/routing/strategies/compositeStrategy.test.js.map +1 -1
  462. package/dist/src/routing/strategies/fallbackStrategy.d.ts +1 -1
  463. package/dist/src/routing/strategies/fallbackStrategy.js +21 -13
  464. package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -1
  465. package/dist/src/routing/strategies/fallbackStrategy.test.js +76 -39
  466. package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -1
  467. package/dist/src/routing/strategies/overrideStrategy.d.ts +1 -1
  468. package/dist/src/routing/strategies/overrideStrategy.js +5 -4
  469. package/dist/src/routing/strategies/overrideStrategy.js.map +1 -1
  470. package/dist/src/routing/strategies/overrideStrategy.test.js +14 -0
  471. package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -1
  472. package/dist/src/safety/checker-runner.js +17 -6
  473. package/dist/src/safety/checker-runner.js.map +1 -1
  474. package/dist/src/scheduler/tool-executor.d.ts +22 -0
  475. package/dist/src/scheduler/tool-executor.js +198 -0
  476. package/dist/src/scheduler/tool-executor.js.map +1 -0
  477. package/dist/src/scheduler/tool-executor.test.d.ts +6 -0
  478. package/dist/src/scheduler/tool-executor.test.js +231 -0
  479. package/dist/src/scheduler/tool-executor.test.js.map +1 -0
  480. package/dist/src/scheduler/tool-modifier.d.ts +23 -0
  481. package/dist/src/scheduler/tool-modifier.js +50 -0
  482. package/dist/src/scheduler/tool-modifier.js.map +1 -0
  483. package/dist/src/scheduler/tool-modifier.test.d.ts +6 -0
  484. package/dist/src/scheduler/tool-modifier.test.js +159 -0
  485. package/dist/src/scheduler/tool-modifier.test.js.map +1 -0
  486. package/dist/src/scheduler/types.d.ts +95 -0
  487. package/dist/src/scheduler/types.js +7 -0
  488. package/dist/src/scheduler/types.js.map +1 -0
  489. package/dist/src/services/chatCompressionService.js +8 -1
  490. package/dist/src/services/chatCompressionService.js.map +1 -1
  491. package/dist/src/services/chatCompressionService.test.js +3 -0
  492. package/dist/src/services/chatCompressionService.test.js.map +1 -1
  493. package/dist/src/services/chatRecordingService.d.ts +21 -1
  494. package/dist/src/services/chatRecordingService.js +57 -2
  495. package/dist/src/services/chatRecordingService.js.map +1 -1
  496. package/dist/src/services/chatRecordingService.test.js +43 -0
  497. package/dist/src/services/chatRecordingService.test.js.map +1 -1
  498. package/dist/src/services/contextManager.d.ts +5 -11
  499. package/dist/src/services/contextManager.js +20 -17
  500. package/dist/src/services/contextManager.js.map +1 -1
  501. package/dist/src/services/contextManager.test.js +40 -41
  502. package/dist/src/services/contextManager.test.js.map +1 -1
  503. package/dist/src/services/environmentSanitization.d.ts +15 -0
  504. package/dist/src/services/environmentSanitization.js +142 -0
  505. package/dist/src/services/environmentSanitization.js.map +1 -0
  506. package/dist/src/services/environmentSanitization.test.d.ts +6 -0
  507. package/dist/src/services/environmentSanitization.test.js +284 -0
  508. package/dist/src/services/environmentSanitization.test.js.map +1 -0
  509. package/dist/src/services/fileSystemService.d.ts +0 -9
  510. package/dist/src/services/fileSystemService.js +0 -11
  511. package/dist/src/services/fileSystemService.js.map +1 -1
  512. package/dist/src/services/gitService.js +15 -1
  513. package/dist/src/services/gitService.js.map +1 -1
  514. package/dist/src/services/gitService.test.js +56 -2
  515. package/dist/src/services/gitService.test.js.map +1 -1
  516. package/dist/src/services/loopDetectionService.js +4 -3
  517. package/dist/src/services/loopDetectionService.js.map +1 -1
  518. package/dist/src/services/loopDetectionService.test.js +14 -8
  519. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  520. package/dist/src/services/modelConfig.golden.test.js +32 -0
  521. package/dist/src/services/modelConfig.golden.test.js.map +1 -1
  522. package/dist/src/services/modelConfig.integration.test.js +3 -3
  523. package/dist/src/services/modelConfig.integration.test.js.map +1 -1
  524. package/dist/src/services/modelConfigService.d.ts +41 -4
  525. package/dist/src/services/modelConfigService.js +135 -75
  526. package/dist/src/services/modelConfigService.js.map +1 -1
  527. package/dist/src/services/modelConfigService.test.js +226 -0
  528. package/dist/src/services/modelConfigService.test.js.map +1 -1
  529. package/dist/src/services/modelConfigServiceTestUtils.d.ts +10 -0
  530. package/dist/src/services/modelConfigServiceTestUtils.js +17 -0
  531. package/dist/src/services/modelConfigServiceTestUtils.js.map +1 -0
  532. package/dist/src/services/sessionSummaryService.d.ts +28 -0
  533. package/dist/src/services/sessionSummaryService.js +131 -0
  534. package/dist/src/services/sessionSummaryService.js.map +1 -0
  535. package/dist/src/services/sessionSummaryService.test.d.ts +6 -0
  536. package/dist/src/services/sessionSummaryService.test.js +785 -0
  537. package/dist/src/services/sessionSummaryService.test.js.map +1 -0
  538. package/dist/src/services/sessionSummaryUtils.d.ts +16 -0
  539. package/dist/src/services/sessionSummaryUtils.js +129 -0
  540. package/dist/src/services/sessionSummaryUtils.js.map +1 -0
  541. package/dist/src/services/sessionSummaryUtils.test.d.ts +6 -0
  542. package/dist/src/services/sessionSummaryUtils.test.js +137 -0
  543. package/dist/src/services/sessionSummaryUtils.test.js.map +1 -0
  544. package/dist/src/services/shellExecutionService.d.ts +2 -0
  545. package/dist/src/services/shellExecutionService.js +34 -72
  546. package/dist/src/services/shellExecutionService.js.map +1 -1
  547. package/dist/src/services/shellExecutionService.test.js +114 -8
  548. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  549. package/dist/src/services/test-data/resolved-aliases-retry.golden.json +238 -0
  550. package/dist/src/services/test-data/resolved-aliases.golden.json +16 -0
  551. package/dist/src/skills/skillLoader.d.ts +31 -0
  552. package/dist/src/skills/skillLoader.js +77 -0
  553. package/dist/src/skills/skillLoader.js.map +1 -0
  554. package/dist/src/skills/skillLoader.test.d.ts +6 -0
  555. package/dist/src/skills/skillLoader.test.js +75 -0
  556. package/dist/src/skills/skillLoader.test.js.map +1 -0
  557. package/dist/src/skills/skillManager.d.ts +69 -0
  558. package/dist/src/skills/skillManager.js +127 -0
  559. package/dist/src/skills/skillManager.js.map +1 -0
  560. package/dist/src/skills/skillManager.test.d.ts +6 -0
  561. package/dist/src/skills/skillManager.test.js +210 -0
  562. package/dist/src/skills/skillManager.test.js.map +1 -0
  563. package/dist/src/telemetry/activity-detector.test.js.map +1 -1
  564. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +19 -9
  565. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +261 -164
  566. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  567. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +223 -27
  568. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  569. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +12 -3
  570. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +26 -5
  571. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  572. package/dist/src/telemetry/config.js +2 -0
  573. package/dist/src/telemetry/config.js.map +1 -1
  574. package/dist/src/telemetry/config.test.js +25 -0
  575. package/dist/src/telemetry/config.test.js.map +1 -1
  576. package/dist/src/telemetry/gcp-exporters.d.ts +4 -3
  577. package/dist/src/telemetry/gcp-exporters.js +8 -4
  578. package/dist/src/telemetry/gcp-exporters.js.map +1 -1
  579. package/dist/src/telemetry/index.d.ts +1 -1
  580. package/dist/src/telemetry/index.js +1 -1
  581. package/dist/src/telemetry/index.js.map +1 -1
  582. package/dist/src/telemetry/loggers.d.ts +4 -3
  583. package/dist/src/telemetry/loggers.js +351 -340
  584. package/dist/src/telemetry/loggers.js.map +1 -1
  585. package/dist/src/telemetry/loggers.test.circular.js +1 -0
  586. package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
  587. package/dist/src/telemetry/loggers.test.js +71 -15
  588. package/dist/src/telemetry/loggers.test.js.map +1 -1
  589. package/dist/src/telemetry/metrics.test.js.map +1 -1
  590. package/dist/src/telemetry/sdk.d.ts +9 -2
  591. package/dist/src/telemetry/sdk.js +142 -17
  592. package/dist/src/telemetry/sdk.js.map +1 -1
  593. package/dist/src/telemetry/sdk.test.js +130 -28
  594. package/dist/src/telemetry/sdk.test.js.map +1 -1
  595. package/dist/src/telemetry/startupProfiler.js +26 -3
  596. package/dist/src/telemetry/startupProfiler.js.map +1 -1
  597. package/dist/src/telemetry/startupProfiler.test.js +49 -7
  598. package/dist/src/telemetry/startupProfiler.test.js.map +1 -1
  599. package/dist/src/telemetry/telemetry.test.js +10 -3
  600. package/dist/src/telemetry/telemetry.test.js.map +1 -1
  601. package/dist/src/telemetry/trace.js.map +1 -1
  602. package/dist/src/telemetry/types.d.ts +37 -12
  603. package/dist/src/telemetry/types.js +61 -20
  604. package/dist/src/telemetry/types.js.map +1 -1
  605. package/dist/src/telemetry/uiTelemetry.d.ts +1 -0
  606. package/dist/src/telemetry/uiTelemetry.js +2 -0
  607. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  608. package/dist/src/telemetry/uiTelemetry.test.js +4 -0
  609. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  610. package/dist/src/test-utils/mock-message-bus.d.ts +1 -0
  611. package/dist/src/test-utils/mock-message-bus.js +29 -0
  612. package/dist/src/test-utils/mock-message-bus.js.map +1 -1
  613. package/dist/src/test-utils/mock-tool.d.ts +5 -3
  614. package/dist/src/test-utils/mock-tool.js +11 -10
  615. package/dist/src/test-utils/mock-tool.js.map +1 -1
  616. package/dist/src/tools/activate-skill.d.ts +27 -0
  617. package/dist/src/tools/activate-skill.js +133 -0
  618. package/dist/src/tools/activate-skill.js.map +1 -0
  619. package/dist/src/tools/activate-skill.test.d.ts +6 -0
  620. package/dist/src/tools/activate-skill.test.js +113 -0
  621. package/dist/src/tools/activate-skill.test.js.map +1 -0
  622. package/dist/src/tools/confirmation-policy.test.d.ts +6 -0
  623. package/dist/src/tools/confirmation-policy.test.js +143 -0
  624. package/dist/src/tools/confirmation-policy.test.js.map +1 -0
  625. package/dist/src/tools/edit.d.ts +27 -5
  626. package/dist/src/tools/edit.js +460 -136
  627. package/dist/src/tools/edit.js.map +1 -1
  628. package/dist/src/tools/edit.test.js +292 -526
  629. package/dist/src/tools/edit.test.js.map +1 -1
  630. package/dist/src/tools/get-internal-docs.d.ts +27 -0
  631. package/dist/src/tools/get-internal-docs.js +122 -0
  632. package/dist/src/tools/get-internal-docs.js.map +1 -0
  633. package/dist/src/tools/get-internal-docs.test.d.ts +6 -0
  634. package/dist/src/tools/get-internal-docs.test.js +57 -0
  635. package/dist/src/tools/get-internal-docs.test.js.map +1 -0
  636. package/dist/src/tools/glob.d.ts +2 -2
  637. package/dist/src/tools/glob.js +1 -1
  638. package/dist/src/tools/glob.js.map +1 -1
  639. package/dist/src/tools/glob.test.js +2 -1
  640. package/dist/src/tools/glob.test.js.map +1 -1
  641. package/dist/src/tools/grep.d.ts +2 -2
  642. package/dist/src/tools/grep.js +1 -1
  643. package/dist/src/tools/grep.js.map +1 -1
  644. package/dist/src/tools/grep.test.js +5 -4
  645. package/dist/src/tools/grep.test.js.map +1 -1
  646. package/dist/src/tools/ls.d.ts +2 -2
  647. package/dist/src/tools/ls.js +2 -2
  648. package/dist/src/tools/ls.js.map +1 -1
  649. package/dist/src/tools/ls.test.js +2 -1
  650. package/dist/src/tools/ls.test.js.map +1 -1
  651. package/dist/src/tools/mcp-client-manager.d.ts +2 -1
  652. package/dist/src/tools/mcp-client-manager.js +32 -9
  653. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  654. package/dist/src/tools/mcp-client-manager.test.js +41 -10
  655. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  656. package/dist/src/tools/mcp-client.d.ts +43 -6
  657. package/dist/src/tools/mcp-client.js +443 -176
  658. package/dist/src/tools/mcp-client.js.map +1 -1
  659. package/dist/src/tools/mcp-client.test.js +664 -39
  660. package/dist/src/tools/mcp-client.test.js.map +1 -1
  661. package/dist/src/tools/mcp-tool.d.ts +20 -5
  662. package/dist/src/tools/mcp-tool.js +21 -8
  663. package/dist/src/tools/mcp-tool.js.map +1 -1
  664. package/dist/src/tools/mcp-tool.test.js +35 -5
  665. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  666. package/dist/src/tools/memoryTool.d.ts +3 -3
  667. package/dist/src/tools/memoryTool.js +3 -4
  668. package/dist/src/tools/memoryTool.js.map +1 -1
  669. package/dist/src/tools/memoryTool.test.js +5 -2
  670. package/dist/src/tools/memoryTool.test.js.map +1 -1
  671. package/dist/src/tools/message-bus-integration.test.js +10 -37
  672. package/dist/src/tools/message-bus-integration.test.js.map +1 -1
  673. package/dist/src/tools/modifiable-tool.js.map +1 -1
  674. package/dist/src/tools/modifiable-tool.test.js +22 -13
  675. package/dist/src/tools/modifiable-tool.test.js.map +1 -1
  676. package/dist/src/tools/read-file.d.ts +2 -2
  677. package/dist/src/tools/read-file.js +2 -2
  678. package/dist/src/tools/read-file.js.map +1 -1
  679. package/dist/src/tools/read-file.test.js +3 -2
  680. package/dist/src/tools/read-file.test.js.map +1 -1
  681. package/dist/src/tools/read-many-files.d.ts +2 -2
  682. package/dist/src/tools/read-many-files.js +7 -6
  683. package/dist/src/tools/read-many-files.js.map +1 -1
  684. package/dist/src/tools/read-many-files.test.js +4 -3
  685. package/dist/src/tools/read-many-files.test.js.map +1 -1
  686. package/dist/src/tools/ripGrep.d.ts +3 -2
  687. package/dist/src/tools/ripGrep.js +18 -7
  688. package/dist/src/tools/ripGrep.js.map +1 -1
  689. package/dist/src/tools/ripGrep.test.js +60 -4
  690. package/dist/src/tools/ripGrep.test.js.map +1 -1
  691. package/dist/src/tools/shell.d.ts +5 -7
  692. package/dist/src/tools/shell.js +35 -49
  693. package/dist/src/tools/shell.js.map +1 -1
  694. package/dist/src/tools/shell.test.js +36 -59
  695. package/dist/src/tools/shell.test.js.map +1 -1
  696. package/dist/src/tools/tool-error.d.ts +6 -1
  697. package/dist/src/tools/tool-error.js +6 -0
  698. package/dist/src/tools/tool-error.js.map +1 -1
  699. package/dist/src/tools/tool-names.d.ts +17 -0
  700. package/dist/src/tools/tool-names.js +59 -0
  701. package/dist/src/tools/tool-names.js.map +1 -1
  702. package/dist/src/tools/tool-names.test.d.ts +6 -0
  703. package/dist/src/tools/tool-names.test.js +43 -0
  704. package/dist/src/tools/tool-names.test.js.map +1 -0
  705. package/dist/src/tools/tool-registry.d.ts +11 -7
  706. package/dist/src/tools/tool-registry.js +15 -10
  707. package/dist/src/tools/tool-registry.js.map +1 -1
  708. package/dist/src/tools/tool-registry.test.js +16 -11
  709. package/dist/src/tools/tool-registry.test.js.map +1 -1
  710. package/dist/src/tools/tools.d.ts +27 -6
  711. package/dist/src/tools/tools.js +44 -25
  712. package/dist/src/tools/tools.js.map +1 -1
  713. package/dist/src/tools/tools.test.js +3 -1
  714. package/dist/src/tools/tools.test.js.map +1 -1
  715. package/dist/src/tools/web-fetch.d.ts +2 -2
  716. package/dist/src/tools/web-fetch.js +21 -8
  717. package/dist/src/tools/web-fetch.js.map +1 -1
  718. package/dist/src/tools/web-fetch.test.js +18 -19
  719. package/dist/src/tools/web-fetch.test.js.map +1 -1
  720. package/dist/src/tools/web-search.d.ts +2 -2
  721. package/dist/src/tools/web-search.js +5 -5
  722. package/dist/src/tools/web-search.js.map +1 -1
  723. package/dist/src/tools/web-search.test.js +2 -1
  724. package/dist/src/tools/web-search.test.js.map +1 -1
  725. package/dist/src/tools/write-file.d.ts +2 -2
  726. package/dist/src/tools/write-file.js +14 -6
  727. package/dist/src/tools/write-file.js.map +1 -1
  728. package/dist/src/tools/write-file.test.js +49 -7
  729. package/dist/src/tools/write-file.test.js.map +1 -1
  730. package/dist/src/tools/write-todos.d.ts +2 -2
  731. package/dist/src/tools/write-todos.js +5 -4
  732. package/dist/src/tools/write-todos.js.map +1 -1
  733. package/dist/src/tools/write-todos.test.js +2 -1
  734. package/dist/src/tools/write-todos.test.js.map +1 -1
  735. package/dist/src/utils/apiConversionUtils.d.ts +12 -0
  736. package/dist/src/utils/apiConversionUtils.js +46 -0
  737. package/dist/src/utils/apiConversionUtils.js.map +1 -0
  738. package/dist/src/utils/apiConversionUtils.test.d.ts +6 -0
  739. package/dist/src/utils/apiConversionUtils.test.js +150 -0
  740. package/dist/src/utils/apiConversionUtils.test.js.map +1 -0
  741. package/dist/src/utils/bfsFileSearch.d.ts +8 -0
  742. package/dist/src/utils/bfsFileSearch.js +63 -23
  743. package/dist/src/utils/bfsFileSearch.js.map +1 -1
  744. package/dist/src/utils/bfsFileSearch.test.js +65 -1
  745. package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
  746. package/dist/src/utils/checkpointUtils.d.ts +82 -0
  747. package/dist/src/utils/checkpointUtils.js +117 -0
  748. package/dist/src/utils/checkpointUtils.js.map +1 -0
  749. package/dist/src/utils/checkpointUtils.test.d.ts +6 -0
  750. package/dist/src/utils/checkpointUtils.test.js +229 -0
  751. package/dist/src/utils/checkpointUtils.test.js.map +1 -0
  752. package/dist/src/utils/debugLogger.d.ts +3 -0
  753. package/dist/src/utils/debugLogger.js +28 -0
  754. package/dist/src/utils/debugLogger.js.map +1 -1
  755. package/dist/src/utils/editCorrector.d.ts +3 -3
  756. package/dist/src/utils/editCorrector.js +27 -10
  757. package/dist/src/utils/editCorrector.js.map +1 -1
  758. package/dist/src/utils/editCorrector.test.js +27 -23
  759. package/dist/src/utils/editCorrector.test.js.map +1 -1
  760. package/dist/src/utils/editor.d.ts +10 -1
  761. package/dist/src/utils/editor.js +48 -19
  762. package/dist/src/utils/editor.js.map +1 -1
  763. package/dist/src/utils/editor.test.js +27 -4
  764. package/dist/src/utils/editor.test.js.map +1 -1
  765. package/dist/src/utils/environmentContext.d.ts +1 -0
  766. package/dist/src/utils/environmentContext.js +4 -0
  767. package/dist/src/utils/environmentContext.js.map +1 -1
  768. package/dist/src/utils/environmentContext.test.js +2 -0
  769. package/dist/src/utils/environmentContext.test.js.map +1 -1
  770. package/dist/src/utils/errorReporting.d.ts +1 -1
  771. package/dist/src/utils/errorReporting.js +13 -12
  772. package/dist/src/utils/errorReporting.js.map +1 -1
  773. package/dist/src/utils/errorReporting.test.js +17 -14
  774. package/dist/src/utils/errorReporting.test.js.map +1 -1
  775. package/dist/src/utils/errors.d.ts +8 -0
  776. package/dist/src/utils/errors.js +39 -2
  777. package/dist/src/utils/errors.js.map +1 -1
  778. package/dist/src/utils/errors.test.d.ts +6 -0
  779. package/dist/src/utils/errors.test.js +155 -0
  780. package/dist/src/utils/errors.test.js.map +1 -0
  781. package/dist/src/utils/events.d.ts +71 -19
  782. package/dist/src/utils/events.js +35 -9
  783. package/dist/src/utils/events.js.map +1 -1
  784. package/dist/src/utils/events.test.js +25 -0
  785. package/dist/src/utils/events.test.js.map +1 -1
  786. package/dist/src/utils/extensionLoader.d.ts +2 -2
  787. package/dist/src/utils/extensionLoader.js +5 -6
  788. package/dist/src/utils/extensionLoader.js.map +1 -1
  789. package/dist/src/utils/extensionLoader.test.js +11 -0
  790. package/dist/src/utils/extensionLoader.test.js.map +1 -1
  791. package/dist/src/utils/fetch.d.ts +1 -1
  792. package/dist/src/utils/fetch.js +3 -3
  793. package/dist/src/utils/fetch.js.map +1 -1
  794. package/dist/src/utils/fileDiffUtils.d.ts +18 -0
  795. package/dist/src/utils/fileDiffUtils.js +37 -0
  796. package/dist/src/utils/fileDiffUtils.js.map +1 -0
  797. package/dist/src/utils/fileDiffUtils.test.d.ts +6 -0
  798. package/dist/src/utils/fileDiffUtils.test.js +84 -0
  799. package/dist/src/utils/fileDiffUtils.test.js.map +1 -0
  800. package/dist/src/utils/fileUtils.d.ts +4 -0
  801. package/dist/src/utils/fileUtils.js +53 -0
  802. package/dist/src/utils/fileUtils.js.map +1 -1
  803. package/dist/src/utils/fileUtils.test.js +127 -1
  804. package/dist/src/utils/fileUtils.test.js.map +1 -1
  805. package/dist/src/utils/filesearch/crawlCache.js.map +1 -1
  806. package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
  807. package/dist/src/utils/flashFallback.test.js +1 -1
  808. package/dist/src/utils/flashFallback.test.js.map +1 -1
  809. package/dist/src/utils/geminiIgnoreParser.d.ts +11 -0
  810. package/dist/src/utils/geminiIgnoreParser.js +20 -0
  811. package/dist/src/utils/geminiIgnoreParser.js.map +1 -1
  812. package/dist/src/utils/geminiIgnoreParser.test.js +48 -0
  813. package/dist/src/utils/geminiIgnoreParser.test.js.map +1 -1
  814. package/dist/src/utils/generateContentResponseUtilities.d.ts +3 -1
  815. package/dist/src/utils/generateContentResponseUtilities.js +106 -0
  816. package/dist/src/utils/generateContentResponseUtilities.js.map +1 -1
  817. package/dist/src/utils/generateContentResponseUtilities.test.js +279 -2
  818. package/dist/src/utils/generateContentResponseUtilities.test.js.map +1 -1
  819. package/dist/src/utils/getFolderStructure.js +7 -2
  820. package/dist/src/utils/getFolderStructure.js.map +1 -1
  821. package/dist/src/utils/gitIgnoreParser.js +9 -10
  822. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  823. package/dist/src/utils/googleErrors.js +31 -18
  824. package/dist/src/utils/googleErrors.js.map +1 -1
  825. package/dist/src/utils/googleErrors.test.js +10 -2
  826. package/dist/src/utils/googleErrors.test.js.map +1 -1
  827. package/dist/src/utils/googleQuotaErrors.d.ts +3 -3
  828. package/dist/src/utils/googleQuotaErrors.js +32 -6
  829. package/dist/src/utils/googleQuotaErrors.js.map +1 -1
  830. package/dist/src/utils/googleQuotaErrors.test.js +94 -2
  831. package/dist/src/utils/googleQuotaErrors.test.js.map +1 -1
  832. package/dist/src/utils/installationManager.test.js +11 -3
  833. package/dist/src/utils/installationManager.test.js.map +1 -1
  834. package/dist/src/utils/memoryDiscovery.js +3 -4
  835. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  836. package/dist/src/utils/memoryDiscovery.test.js +12 -1
  837. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  838. package/dist/src/utils/nextSpeakerChecker.test.js +4 -0
  839. package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
  840. package/dist/src/utils/partUtils.js +1 -1
  841. package/dist/src/utils/partUtils.js.map +1 -1
  842. package/dist/src/utils/pathCorrector.js +12 -2
  843. package/dist/src/utils/pathCorrector.js.map +1 -1
  844. package/dist/src/utils/pathCorrector.test.js +6 -2
  845. package/dist/src/utils/pathCorrector.test.js.map +1 -1
  846. package/dist/src/utils/paths.d.ts +10 -0
  847. package/dist/src/utils/paths.js +20 -1
  848. package/dist/src/utils/paths.js.map +1 -1
  849. package/dist/src/utils/retry.d.ts +12 -0
  850. package/dist/src/utils/retry.js +70 -17
  851. package/dist/src/utils/retry.js.map +1 -1
  852. package/dist/src/utils/retry.test.js +181 -21
  853. package/dist/src/utils/retry.test.js.map +1 -1
  854. package/dist/src/utils/shell-utils.d.ts +16 -47
  855. package/dist/src/utils/shell-utils.js +98 -194
  856. package/dist/src/utils/shell-utils.js.map +1 -1
  857. package/dist/src/utils/shell-utils.test.js +99 -288
  858. package/dist/src/utils/shell-utils.test.js.map +1 -1
  859. package/dist/src/utils/summarizer.test.js +3 -2
  860. package/dist/src/utils/summarizer.test.js.map +1 -1
  861. package/dist/src/utils/terminal.d.ts +4 -0
  862. package/dist/src/utils/terminal.js +12 -0
  863. package/dist/src/utils/terminal.js.map +1 -1
  864. package/dist/src/utils/terminalSerializer.test.js +17 -0
  865. package/dist/src/utils/terminalSerializer.test.js.map +1 -1
  866. package/dist/src/utils/tokenCalculation.js +20 -5
  867. package/dist/src/utils/tokenCalculation.js.map +1 -1
  868. package/dist/src/utils/tokenCalculation.test.js +11 -2
  869. package/dist/src/utils/tokenCalculation.test.js.map +1 -1
  870. package/dist/src/utils/tool-utils.d.ts +9 -0
  871. package/dist/src/utils/tool-utils.js +29 -0
  872. package/dist/src/utils/tool-utils.js.map +1 -1
  873. package/dist/src/utils/tool-utils.test.js +17 -2
  874. package/dist/src/utils/tool-utils.test.js.map +1 -1
  875. package/dist/src/utils/userAccountManager.test.js +5 -5
  876. package/dist/src/utils/userAccountManager.test.js.map +1 -1
  877. package/dist/src/utils/version.d.ts +6 -0
  878. package/dist/src/utils/version.js +15 -0
  879. package/dist/src/utils/version.js.map +1 -0
  880. package/dist/src/utils/version.test.d.ts +6 -0
  881. package/dist/src/utils/version.test.js +39 -0
  882. package/dist/src/utils/version.test.js.map +1 -0
  883. package/dist/src/utils/workspaceContext.test.js +1 -1
  884. package/dist/src/utils/workspaceContext.test.js.map +1 -1
  885. package/dist/tsconfig.tsbuildinfo +1 -1
  886. package/package.json +8 -6
  887. package/dist/src/agents/executor.js.map +0 -1
  888. package/dist/src/agents/executor.test.js.map +0 -1
  889. package/dist/src/agents/invocation.js.map +0 -1
  890. package/dist/src/agents/invocation.test.js.map +0 -1
  891. package/dist/src/tools/smart-edit.d.ts +0 -78
  892. package/dist/src/tools/smart-edit.js +0 -717
  893. package/dist/src/tools/smart-edit.js.map +0 -1
  894. package/dist/src/tools/smart-edit.test.js +0 -592
  895. package/dist/src/tools/smart-edit.test.js.map +0 -1
  896. /package/dist/src/agents/{executor.test.d.ts → a2a-client-manager.test.d.ts} +0 -0
  897. /package/dist/src/agents/{invocation.test.d.ts → a2aUtils.test.d.ts} +0 -0
  898. /package/dist/src/{tools/smart-edit.test.d.ts → agents/agentLoader.test.d.ts} +0 -0
@@ -3,37 +3,36 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { describe, it, expect, vi, beforeEach } from 'vitest';
7
- import { CoreToolScheduler, convertToFunctionResponse, truncateAndSaveToFile, } from './coreToolScheduler.js';
8
- import { DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES, DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD, BaseDeclarativeTool, BaseToolInvocation, ToolConfirmationOutcome, Kind, ApprovalMode, HookSystem, } from '../index.js';
6
+ import { describe, it, expect, vi } from 'vitest';
7
+ import { CoreToolScheduler } from './coreToolScheduler.js';
8
+ import { DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES, DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD, BaseDeclarativeTool, BaseToolInvocation, ToolConfirmationOutcome, Kind, ApprovalMode, HookSystem, PolicyDecision, } from '../index.js';
9
9
  import { createMockMessageBus } from '../test-utils/mock-message-bus.js';
10
10
  import { MockModifiableTool, MockTool, MOCK_TOOL_SHOULD_CONFIRM_EXECUTE, } from '../test-utils/mock-tool.js';
11
11
  import * as modifiableToolModule from '../tools/modifiable-tool.js';
12
- import * as fs from 'node:fs/promises';
13
- import * as path from 'node:path';
14
- import { isShellInvocationAllowlisted } from '../utils/shell-utils.js';
12
+ import { DEFAULT_GEMINI_MODEL } from '../config/models.js';
13
+ import { DiscoveredMCPTool } from '../tools/mcp-tool.js';
15
14
  vi.mock('fs/promises', () => ({
16
15
  writeFile: vi.fn(),
17
16
  }));
18
17
  class TestApprovalTool extends BaseDeclarativeTool {
19
18
  config;
20
19
  static Name = 'testApprovalTool';
21
- constructor(config) {
20
+ constructor(config, messageBus) {
22
21
  super(TestApprovalTool.Name, 'TestApprovalTool', 'A tool for testing approval logic', Kind.Edit, {
23
22
  properties: { id: { type: 'string' } },
24
23
  required: ['id'],
25
24
  type: 'object',
26
- });
25
+ }, messageBus);
27
26
  this.config = config;
28
27
  }
29
- createInvocation(params) {
30
- return new TestApprovalInvocation(this.config, params);
28
+ createInvocation(params, messageBus, _toolName, _toolDisplayName) {
29
+ return new TestApprovalInvocation(this.config, params, messageBus);
31
30
  }
32
31
  }
33
32
  class TestApprovalInvocation extends BaseToolInvocation {
34
33
  config;
35
- constructor(config, params) {
36
- super(params);
34
+ constructor(config, params, messageBus) {
35
+ super(params, messageBus);
37
36
  this.config = config;
38
37
  }
39
38
  getDescription() {
@@ -69,8 +68,8 @@ class TestApprovalInvocation extends BaseToolInvocation {
69
68
  class AbortDuringConfirmationInvocation extends BaseToolInvocation {
70
69
  abortController;
71
70
  abortError;
72
- constructor(abortController, abortError, params) {
73
- super(params);
71
+ constructor(abortController, abortError, params, messageBus) {
72
+ super(params, messageBus);
74
73
  this.abortController = abortController;
75
74
  this.abortError = abortError;
76
75
  }
@@ -88,16 +87,16 @@ class AbortDuringConfirmationInvocation extends BaseToolInvocation {
88
87
  class AbortDuringConfirmationTool extends BaseDeclarativeTool {
89
88
  abortController;
90
89
  abortError;
91
- constructor(abortController, abortError) {
90
+ constructor(abortController, abortError, messageBus) {
92
91
  super('abortDuringConfirmationTool', 'Abort During Confirmation Tool', 'A tool that aborts while confirming execution.', Kind.Other, {
93
92
  type: 'object',
94
93
  properties: {},
95
- });
94
+ }, messageBus);
96
95
  this.abortController = abortController;
97
96
  this.abortError = abortError;
98
97
  }
99
- createInvocation(params) {
100
- return new AbortDuringConfirmationInvocation(this.abortController, this.abortError, params);
98
+ createInvocation(params, messageBus, _toolName, _toolDisplayName) {
99
+ return new AbortDuringConfirmationInvocation(this.abortController, this.abortError, params, messageBus);
101
100
  }
102
101
  }
103
102
  async function waitForStatus(onToolCallsUpdate, status, timeout = 5000) {
@@ -143,6 +142,7 @@ function createMockConfig(overrides = {}) {
143
142
  getSessionId: () => 'test-session-id',
144
143
  getUsageStatisticsEnabled: () => true,
145
144
  getDebugMode: () => false,
145
+ isInteractive: () => true,
146
146
  getApprovalMode: () => ApprovalMode.DEFAULT,
147
147
  setApprovalMode: () => { },
148
148
  getAllowedTools: () => [],
@@ -153,6 +153,11 @@ function createMockConfig(overrides = {}) {
153
153
  getShellExecutionConfig: () => ({
154
154
  terminalWidth: 90,
155
155
  terminalHeight: 30,
156
+ sanitizationConfig: {
157
+ enableEnvironmentVariableRedaction: true,
158
+ allowedEnvironmentVariables: [],
159
+ blockedEnvironmentVariables: [],
160
+ },
156
161
  }),
157
162
  storage: {
158
163
  getProjectTempDir: () => '/tmp',
@@ -160,15 +165,33 @@ function createMockConfig(overrides = {}) {
160
165
  getTruncateToolOutputThreshold: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
161
166
  getTruncateToolOutputLines: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
162
167
  getToolRegistry: () => defaultToolRegistry,
163
- getUseSmartEdit: () => false,
168
+ getActiveModel: () => DEFAULT_GEMINI_MODEL,
164
169
  getGeminiClient: () => null,
165
- getEnableMessageBusIntegration: () => false,
166
- getMessageBus: () => null,
170
+ getMessageBus: () => createMockMessageBus(),
167
171
  getEnableHooks: () => false,
168
- getPolicyEngine: () => null,
169
172
  getExperiments: () => { },
170
173
  };
171
- return { ...baseConfig, ...overrides };
174
+ const finalConfig = { ...baseConfig, ...overrides };
175
+ // Patch the policy engine to use the final config if not overridden
176
+ if (!overrides.getPolicyEngine) {
177
+ finalConfig.getPolicyEngine = () => ({
178
+ check: async (toolCall, _serverName) => {
179
+ // Mock simple policy logic for tests
180
+ const mode = finalConfig.getApprovalMode();
181
+ if (mode === ApprovalMode.YOLO) {
182
+ return { decision: PolicyDecision.ALLOW };
183
+ }
184
+ const allowed = finalConfig.getAllowedTools();
185
+ if (allowed &&
186
+ (allowed.includes(toolCall.name) ||
187
+ allowed.some((p) => toolCall.name.startsWith(p)))) {
188
+ return { decision: PolicyDecision.ALLOW };
189
+ }
190
+ return { decision: PolicyDecision.ASK_USER };
191
+ },
192
+ });
193
+ }
194
+ return finalConfig;
172
195
  }
173
196
  describe('CoreToolScheduler', () => {
174
197
  it('should cancel a tool call if the signal is aborted before confirmation', async () => {
@@ -257,7 +280,6 @@ describe('CoreToolScheduler', () => {
257
280
  const onToolCallsUpdate = vi.fn();
258
281
  const mockConfig = createMockConfig({
259
282
  getToolRegistry: () => mockToolRegistry,
260
- isInteractive: () => false,
261
283
  getHookSystem: () => undefined,
262
284
  });
263
285
  const scheduler = new CoreToolScheduler({
@@ -347,7 +369,6 @@ describe('CoreToolScheduler', () => {
347
369
  const onToolCallsUpdate = vi.fn();
348
370
  const mockConfig = createMockConfig({
349
371
  getToolRegistry: () => mockToolRegistry,
350
- isInteractive: () => false,
351
372
  getHookSystem: () => undefined,
352
373
  });
353
374
  const scheduler = new CoreToolScheduler({
@@ -400,7 +421,7 @@ describe('CoreToolScheduler', () => {
400
421
  it('should mark tool call as cancelled when abort happens during confirmation error', async () => {
401
422
  const abortController = new AbortController();
402
423
  const abortError = new Error('Abort requested during confirmation');
403
- const declarativeTool = new AbortDuringConfirmationTool(abortController, abortError);
424
+ const declarativeTool = new AbortDuringConfirmationTool(abortController, abortError, createMockMessageBus());
404
425
  const mockToolRegistry = {
405
426
  getTool: () => declarativeTool,
406
427
  getFunctionDeclarations: () => [],
@@ -418,7 +439,7 @@ describe('CoreToolScheduler', () => {
418
439
  const onToolCallsUpdate = vi.fn();
419
440
  const mockConfig = createMockConfig({
420
441
  getToolRegistry: () => mockToolRegistry,
421
- isInteractive: () => false,
442
+ isInteractive: () => true,
422
443
  });
423
444
  const scheduler = new CoreToolScheduler({
424
445
  config: mockConfig,
@@ -441,34 +462,56 @@ describe('CoreToolScheduler', () => {
441
462
  const statuses = onToolCallsUpdate.mock.calls.flatMap((call) => call[0].map((toolCall) => toolCall.status));
442
463
  expect(statuses).not.toContain('error');
443
464
  });
444
- describe('getToolSuggestion', () => {
445
- it('should suggest the top N closest tool names for a typo', () => {
446
- // Create mocked tool registry
447
- const mockToolRegistry = {
448
- getAllToolNames: () => ['list_files', 'read_file', 'write_file'],
449
- };
450
- const mockConfig = createMockConfig({
451
- getToolRegistry: () => mockToolRegistry,
452
- isInteractive: () => false,
453
- });
454
- // Create scheduler
455
- const scheduler = new CoreToolScheduler({
456
- config: mockConfig,
457
- getPreferredEditor: () => 'vscode',
458
- });
459
- // Test that the right tool is selected, with only 1 result, for typos
460
- // @ts-expect-error accessing private method
461
- const misspelledTool = scheduler.getToolSuggestion('list_fils', 1);
462
- expect(misspelledTool).toBe(' Did you mean "list_files"?');
463
- // Test that the right tool is selected, with only 1 result, for prefixes
464
- // @ts-expect-error accessing private method
465
- const prefixedTool = scheduler.getToolSuggestion('github.list_files', 1);
466
- expect(prefixedTool).toBe(' Did you mean "list_files"?');
467
- // Test that the right tool is first
468
- // @ts-expect-error accessing private method
469
- const suggestionMultiple = scheduler.getToolSuggestion('list_fils');
470
- expect(suggestionMultiple).toBe(' Did you mean one of: "list_files", "read_file", "write_file"?');
465
+ it('should error when tool requires confirmation in non-interactive mode', async () => {
466
+ const mockTool = new MockTool({
467
+ name: 'mockTool',
468
+ shouldConfirmExecute: MOCK_TOOL_SHOULD_CONFIRM_EXECUTE,
471
469
  });
470
+ const declarativeTool = mockTool;
471
+ const mockToolRegistry = {
472
+ getTool: () => declarativeTool,
473
+ getFunctionDeclarations: () => [],
474
+ tools: new Map(),
475
+ discovery: {},
476
+ registerTool: () => { },
477
+ getToolByName: () => declarativeTool,
478
+ getToolByDisplayName: () => declarativeTool,
479
+ getTools: () => [],
480
+ discoverTools: async () => { },
481
+ getAllTools: () => [],
482
+ getToolsByServer: () => [],
483
+ };
484
+ const onAllToolCallsComplete = vi.fn();
485
+ const onToolCallsUpdate = vi.fn();
486
+ const mockConfig = createMockConfig({
487
+ getToolRegistry: () => mockToolRegistry,
488
+ isInteractive: () => false,
489
+ });
490
+ const scheduler = new CoreToolScheduler({
491
+ config: mockConfig,
492
+ onAllToolCallsComplete,
493
+ onToolCallsUpdate,
494
+ getPreferredEditor: () => 'vscode',
495
+ });
496
+ const abortController = new AbortController();
497
+ const request = {
498
+ callId: '1',
499
+ name: 'mockTool',
500
+ args: {},
501
+ isClientInitiated: false,
502
+ prompt_id: 'prompt-id-1',
503
+ };
504
+ await scheduler.schedule([request], abortController.signal);
505
+ expect(onAllToolCallsComplete).toHaveBeenCalled();
506
+ const completedCalls = onAllToolCallsComplete.mock
507
+ .calls[0][0];
508
+ expect(completedCalls[0].status).toBe('error');
509
+ const erroredCall = completedCalls[0];
510
+ const errorResponse = erroredCall.response;
511
+ const errorParts = errorResponse.responseParts;
512
+ // @ts-expect-error - accessing internal structure of FunctionResponsePart
513
+ const errorMessage = errorParts[0].functionResponse.response.error;
514
+ expect(errorMessage).toContain('Tool execution for "mockTool" requires user confirmation, which is not supported in non-interactive mode.');
472
515
  });
473
516
  });
474
517
  describe('CoreToolScheduler with payload', () => {
@@ -493,7 +536,6 @@ describe('CoreToolScheduler with payload', () => {
493
536
  const onToolCallsUpdate = vi.fn();
494
537
  const mockConfig = createMockConfig({
495
538
  getToolRegistry: () => mockToolRegistry,
496
- isInteractive: () => false,
497
539
  });
498
540
  const mockMessageBus = createMockMessageBus();
499
541
  mockConfig.getMessageBus = vi.fn().mockReturnValue(mockMessageBus);
@@ -522,6 +564,10 @@ describe('CoreToolScheduler with payload', () => {
522
564
  const payload = { newContent: 'final version' };
523
565
  await confirmationDetails.onConfirm(ToolConfirmationOutcome.ProceedOnce, payload);
524
566
  }
567
+ // After internal update, the tool should be awaiting approval again with the NEW content.
568
+ const updatedAwaitingCall = (await waitForStatus(onToolCallsUpdate, 'awaiting_approval'));
569
+ // Now confirm for real to execute.
570
+ await updatedAwaitingCall.confirmationDetails.onConfirm(ToolConfirmationOutcome.ProceedOnce);
525
571
  // Wait for the tool execution to complete
526
572
  await vi.waitFor(() => {
527
573
  expect(onAllToolCallsComplete).toHaveBeenCalled();
@@ -534,176 +580,9 @@ describe('CoreToolScheduler with payload', () => {
534
580
  });
535
581
  });
536
582
  });
537
- describe('convertToFunctionResponse', () => {
538
- const toolName = 'testTool';
539
- const callId = 'call1';
540
- it('should handle simple string llmContent', () => {
541
- const llmContent = 'Simple text output';
542
- const result = convertToFunctionResponse(toolName, callId, llmContent);
543
- expect(result).toEqual([
544
- {
545
- functionResponse: {
546
- name: toolName,
547
- id: callId,
548
- response: { output: 'Simple text output' },
549
- },
550
- },
551
- ]);
552
- });
553
- it('should handle llmContent as a single Part with text', () => {
554
- const llmContent = { text: 'Text from Part object' };
555
- const result = convertToFunctionResponse(toolName, callId, llmContent);
556
- expect(result).toEqual([
557
- {
558
- functionResponse: {
559
- name: toolName,
560
- id: callId,
561
- response: { output: 'Text from Part object' },
562
- },
563
- },
564
- ]);
565
- });
566
- it('should handle llmContent as a PartListUnion array with a single text Part', () => {
567
- const llmContent = [{ text: 'Text from array' }];
568
- const result = convertToFunctionResponse(toolName, callId, llmContent);
569
- expect(result).toEqual([
570
- {
571
- functionResponse: {
572
- name: toolName,
573
- id: callId,
574
- response: { output: 'Text from array' },
575
- },
576
- },
577
- ]);
578
- });
579
- it('should handle llmContent with inlineData', () => {
580
- const llmContent = {
581
- inlineData: { mimeType: 'image/png', data: 'base64...' },
582
- };
583
- const result = convertToFunctionResponse(toolName, callId, llmContent);
584
- expect(result).toEqual([
585
- {
586
- functionResponse: {
587
- name: toolName,
588
- id: callId,
589
- response: {
590
- output: 'Binary content of type image/png was processed.',
591
- },
592
- },
593
- },
594
- llmContent,
595
- ]);
596
- });
597
- it('should handle llmContent with fileData', () => {
598
- const llmContent = {
599
- fileData: { mimeType: 'application/pdf', fileUri: 'gs://...' },
600
- };
601
- const result = convertToFunctionResponse(toolName, callId, llmContent);
602
- expect(result).toEqual([
603
- {
604
- functionResponse: {
605
- name: toolName,
606
- id: callId,
607
- response: {
608
- output: 'Binary content of type application/pdf was processed.',
609
- },
610
- },
611
- },
612
- llmContent,
613
- ]);
614
- });
615
- it('should handle llmContent as an array of multiple Parts (text and inlineData)', () => {
616
- const llmContent = [
617
- { text: 'Some textual description' },
618
- { inlineData: { mimeType: 'image/jpeg', data: 'base64data...' } },
619
- { text: 'Another text part' },
620
- ];
621
- const result = convertToFunctionResponse(toolName, callId, llmContent);
622
- expect(result).toEqual([
623
- {
624
- functionResponse: {
625
- name: toolName,
626
- id: callId,
627
- response: { output: 'Tool execution succeeded.' },
628
- },
629
- },
630
- ...llmContent,
631
- ]);
632
- });
633
- it('should handle llmContent as an array with a single inlineData Part', () => {
634
- const llmContent = [
635
- { inlineData: { mimeType: 'image/gif', data: 'gifdata...' } },
636
- ];
637
- const result = convertToFunctionResponse(toolName, callId, llmContent);
638
- expect(result).toEqual([
639
- {
640
- functionResponse: {
641
- name: toolName,
642
- id: callId,
643
- response: {
644
- output: 'Binary content of type image/gif was processed.',
645
- },
646
- },
647
- },
648
- ...llmContent,
649
- ]);
650
- });
651
- it('should handle llmContent as a generic Part (not text, inlineData, or fileData)', () => {
652
- const llmContent = { functionCall: { name: 'test', args: {} } };
653
- const result = convertToFunctionResponse(toolName, callId, llmContent);
654
- expect(result).toEqual([
655
- {
656
- functionResponse: {
657
- name: toolName,
658
- id: callId,
659
- response: { output: 'Tool execution succeeded.' },
660
- },
661
- },
662
- ]);
663
- });
664
- it('should handle empty string llmContent', () => {
665
- const llmContent = '';
666
- const result = convertToFunctionResponse(toolName, callId, llmContent);
667
- expect(result).toEqual([
668
- {
669
- functionResponse: {
670
- name: toolName,
671
- id: callId,
672
- response: { output: '' },
673
- },
674
- },
675
- ]);
676
- });
677
- it('should handle llmContent as an empty array', () => {
678
- const llmContent = [];
679
- const result = convertToFunctionResponse(toolName, callId, llmContent);
680
- expect(result).toEqual([
681
- {
682
- functionResponse: {
683
- name: toolName,
684
- id: callId,
685
- response: { output: 'Tool execution succeeded.' },
686
- },
687
- },
688
- ]);
689
- });
690
- it('should handle llmContent as a Part with undefined inlineData/fileData/text', () => {
691
- const llmContent = {}; // An empty part object
692
- const result = convertToFunctionResponse(toolName, callId, llmContent);
693
- expect(result).toEqual([
694
- {
695
- functionResponse: {
696
- name: toolName,
697
- id: callId,
698
- response: { output: 'Tool execution succeeded.' },
699
- },
700
- },
701
- ]);
702
- });
703
- });
704
583
  class MockEditToolInvocation extends BaseToolInvocation {
705
- constructor(params) {
706
- super(params);
584
+ constructor(params, messageBus) {
585
+ super(params, messageBus);
707
586
  }
708
587
  getDescription() {
709
588
  return 'A mock edit tool invocation';
@@ -728,16 +607,16 @@ class MockEditToolInvocation extends BaseToolInvocation {
728
607
  }
729
608
  }
730
609
  class MockEditTool extends BaseDeclarativeTool {
731
- constructor() {
732
- super('mockEditTool', 'mockEditTool', 'A mock edit tool', Kind.Edit, {});
610
+ constructor(messageBus) {
611
+ super('mockEditTool', 'mockEditTool', 'A mock edit tool', Kind.Edit, {}, messageBus);
733
612
  }
734
- createInvocation(params) {
735
- return new MockEditToolInvocation(params);
613
+ createInvocation(params, messageBus, _toolName, _toolDisplayName) {
614
+ return new MockEditToolInvocation(params, messageBus);
736
615
  }
737
616
  }
738
617
  describe('CoreToolScheduler edit cancellation', () => {
739
618
  it('should preserve diff when an edit is cancelled', async () => {
740
- const mockEditTool = new MockEditTool();
619
+ const mockEditTool = new MockEditTool(createMockMessageBus());
741
620
  const mockToolRegistry = {
742
621
  getTool: () => mockEditTool,
743
622
  getFunctionDeclarations: () => [],
@@ -755,7 +634,6 @@ describe('CoreToolScheduler edit cancellation', () => {
755
634
  const onToolCallsUpdate = vi.fn();
756
635
  const mockConfig = createMockConfig({
757
636
  getToolRegistry: () => mockToolRegistry,
758
- isInteractive: () => false,
759
637
  });
760
638
  const mockMessageBus = createMockMessageBus();
761
639
  mockConfig.getMessageBus = vi.fn().mockReturnValue(mockMessageBus);
@@ -939,6 +817,7 @@ describe('CoreToolScheduler request queueing', () => {
939
817
  prompt_id: 'prompt-2',
940
818
  };
941
819
  // Schedule the first call, which will pause execution.
820
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
942
821
  scheduler.schedule([request1], abortController.signal);
943
822
  // Wait for the first call to be in the 'executing' state.
944
823
  await waitForStatus(onToolCallsUpdate, 'executing');
@@ -1008,6 +887,11 @@ describe('CoreToolScheduler request queueing', () => {
1008
887
  getShellExecutionConfig: () => ({
1009
888
  terminalWidth: 80,
1010
889
  terminalHeight: 24,
890
+ sanitizationConfig: {
891
+ enableEnvironmentVariableRedaction: true,
892
+ allowedEnvironmentVariables: [],
893
+ blockedEnvironmentVariables: [],
894
+ },
1011
895
  }),
1012
896
  isInteractive: () => false,
1013
897
  });
@@ -1063,9 +947,6 @@ describe('CoreToolScheduler request queueing', () => {
1063
947
  }
1064
948
  });
1065
949
  it('should require approval for a chained shell command even when prefix is allowlisted', async () => {
1066
- expect(isShellInvocationAllowlisted({
1067
- params: { command: 'git status && rm -rf /tmp/should-not-run' },
1068
- }, ['run_shell_command(git)'])).toBe(false);
1069
950
  const executeFn = vi.fn().mockResolvedValue({
1070
951
  llmContent: 'Shell command executed',
1071
952
  returnDisplay: 'Shell command executed',
@@ -1101,10 +982,17 @@ describe('CoreToolScheduler request queueing', () => {
1101
982
  getShellExecutionConfig: () => ({
1102
983
  terminalWidth: 80,
1103
984
  terminalHeight: 24,
985
+ sanitizationConfig: {
986
+ enableEnvironmentVariableRedaction: true,
987
+ allowedEnvironmentVariables: [],
988
+ blockedEnvironmentVariables: [],
989
+ },
1104
990
  }),
1105
991
  getToolRegistry: () => toolRegistry,
1106
- isInteractive: () => false,
1107
992
  getHookSystem: () => undefined,
993
+ getPolicyEngine: () => ({
994
+ check: async () => ({ decision: PolicyDecision.ASK_USER }),
995
+ }),
1108
996
  });
1109
997
  const scheduler = new CoreToolScheduler({
1110
998
  config: mockConfig,
@@ -1153,7 +1041,6 @@ describe('CoreToolScheduler request queueing', () => {
1153
1041
  const mockConfig = createMockConfig({
1154
1042
  getToolRegistry: () => mockToolRegistry,
1155
1043
  getApprovalMode: () => ApprovalMode.YOLO,
1156
- isInteractive: () => false,
1157
1044
  });
1158
1045
  const mockMessageBus = createMockMessageBus();
1159
1046
  mockConfig.getMessageBus = vi.fn().mockReturnValue(mockMessageBus);
@@ -1201,7 +1088,6 @@ describe('CoreToolScheduler request queueing', () => {
1201
1088
  setApprovalMode: (mode) => {
1202
1089
  approvalMode = mode;
1203
1090
  },
1204
- isInteractive: () => false,
1205
1091
  });
1206
1092
  const mockMessageBus = createMockMessageBus();
1207
1093
  mockConfig.getMessageBus = vi.fn().mockReturnValue(mockMessageBus);
@@ -1209,7 +1095,7 @@ describe('CoreToolScheduler request queueing', () => {
1209
1095
  mockConfig.getHookSystem = vi
1210
1096
  .fn()
1211
1097
  .mockReturnValue(new HookSystem(mockConfig));
1212
- const testTool = new TestApprovalTool(mockConfig);
1098
+ const testTool = new TestApprovalTool(mockConfig, mockMessageBus);
1213
1099
  const toolRegistry = {
1214
1100
  getTool: () => testTool,
1215
1101
  getFunctionDeclarations: () => [],
@@ -1564,119 +1450,189 @@ describe('CoreToolScheduler Sequential Execution', () => {
1564
1450
  });
1565
1451
  modifyWithEditorSpy.mockRestore();
1566
1452
  });
1567
- });
1568
- describe('truncateAndSaveToFile', () => {
1569
- const mockWriteFile = vi.mocked(fs.writeFile);
1570
- const THRESHOLD = 40_000;
1571
- const TRUNCATE_LINES = 1000;
1572
- beforeEach(() => {
1573
- vi.clearAllMocks();
1574
- });
1575
- it('should return content unchanged if below threshold', async () => {
1576
- const content = 'Short content';
1577
- const callId = 'test-call-id';
1578
- const projectTempDir = '/tmp';
1579
- const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1580
- expect(result).toEqual({ content });
1581
- expect(mockWriteFile).not.toHaveBeenCalled();
1582
- });
1583
- it('should truncate content by lines when content has many lines', async () => {
1584
- // Create content that exceeds 100,000 character threshold with many lines
1585
- const lines = Array(2000).fill('x'.repeat(100)); // 100 chars per line * 2000 lines = 200,000 chars
1586
- const content = lines.join('\n');
1587
- const callId = 'test-call-id';
1588
- const projectTempDir = '/tmp';
1589
- mockWriteFile.mockResolvedValue(undefined);
1590
- const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1591
- expect(result.outputFile).toBe(path.join(projectTempDir, `${callId}.output`));
1592
- expect(mockWriteFile).toHaveBeenCalledWith(path.join(projectTempDir, `${callId}.output`), content);
1593
- // Should contain the first and last lines with 1/5 head and 4/5 tail
1594
- const head = Math.floor(TRUNCATE_LINES / 5);
1595
- const beginning = lines.slice(0, head);
1596
- const end = lines.slice(-(TRUNCATE_LINES - head));
1597
- const expectedTruncated = beginning.join('\n') + '\n... [CONTENT TRUNCATED] ...\n' + end.join('\n');
1598
- expect(result.content).toContain('Tool output was too large and has been truncated');
1599
- expect(result.content).toContain('Truncated part of the output:');
1600
- expect(result.content).toContain(expectedTruncated);
1601
- });
1602
- it('should wrap and truncate content when content has few but long lines', async () => {
1603
- const content = 'a'.repeat(200_000); // A single very long line
1604
- const callId = 'test-call-id';
1605
- const projectTempDir = '/tmp';
1606
- const wrapWidth = 120;
1607
- mockWriteFile.mockResolvedValue(undefined);
1608
- // Manually wrap the content to generate the expected file content
1609
- const wrappedLines = [];
1610
- for (let i = 0; i < content.length; i += wrapWidth) {
1611
- wrappedLines.push(content.substring(i, i + wrapWidth));
1612
- }
1613
- const expectedFileContent = wrappedLines.join('\n');
1614
- const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1615
- expect(result.outputFile).toBe(path.join(projectTempDir, `${callId}.output`));
1616
- // Check that the file was written with the wrapped content
1617
- expect(mockWriteFile).toHaveBeenCalledWith(path.join(projectTempDir, `${callId}.output`), expectedFileContent);
1618
- // Should contain the first and last lines with 1/5 head and 4/5 tail of the wrapped content
1619
- const head = Math.floor(TRUNCATE_LINES / 5);
1620
- const beginning = wrappedLines.slice(0, head);
1621
- const end = wrappedLines.slice(-(TRUNCATE_LINES - head));
1622
- const expectedTruncated = beginning.join('\n') + '\n... [CONTENT TRUNCATED] ...\n' + end.join('\n');
1623
- expect(result.content).toContain('Tool output was too large and has been truncated');
1624
- expect(result.content).toContain('Truncated part of the output:');
1625
- expect(result.content).toContain(expectedTruncated);
1626
- });
1627
- it('should handle file write errors gracefully', async () => {
1628
- const content = 'a'.repeat(2_000_000);
1629
- const callId = 'test-call-id';
1630
- const projectTempDir = '/tmp';
1631
- mockWriteFile.mockRejectedValue(new Error('File write failed'));
1632
- const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1633
- expect(result.outputFile).toBeUndefined();
1634
- expect(result.content).toContain('[Note: Could not save full output to file]');
1635
- expect(mockWriteFile).toHaveBeenCalled();
1636
- });
1637
- it('should save to correct file path with call ID', async () => {
1638
- const content = 'a'.repeat(200_000);
1639
- const callId = 'unique-call-123';
1640
- const projectTempDir = '/custom/temp/dir';
1641
- const wrapWidth = 120;
1642
- mockWriteFile.mockResolvedValue(undefined);
1643
- // Manually wrap the content to generate the expected file content
1644
- const wrappedLines = [];
1645
- for (let i = 0; i < content.length; i += wrapWidth) {
1646
- wrappedLines.push(content.substring(i, i + wrapWidth));
1647
- }
1648
- const expectedFileContent = wrappedLines.join('\n');
1649
- const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1650
- const expectedPath = path.join(projectTempDir, `${callId}.output`);
1651
- expect(result.outputFile).toBe(expectedPath);
1652
- expect(mockWriteFile).toHaveBeenCalledWith(expectedPath, expectedFileContent);
1453
+ it('should pass serverName to policy engine for DiscoveredMCPTool', async () => {
1454
+ const mockMcpTool = {
1455
+ tool: async () => ({ functionDeclarations: [] }),
1456
+ callTool: async () => [],
1457
+ };
1458
+ const serverName = 'test-server';
1459
+ const toolName = 'test-tool';
1460
+ const mcpTool = new DiscoveredMCPTool(mockMcpTool, serverName, toolName, 'description', { type: 'object', properties: {} }, createMockMessageBus());
1461
+ const mockToolRegistry = {
1462
+ getTool: () => mcpTool,
1463
+ getFunctionDeclarations: () => [],
1464
+ tools: new Map(),
1465
+ discovery: {},
1466
+ registerTool: () => { },
1467
+ getToolByName: () => mcpTool,
1468
+ getToolByDisplayName: () => mcpTool,
1469
+ getTools: () => [],
1470
+ discoverTools: async () => { },
1471
+ getAllTools: () => [],
1472
+ getToolsByServer: () => [],
1473
+ };
1474
+ const mockPolicyEngineCheck = vi.fn().mockResolvedValue({
1475
+ decision: PolicyDecision.ALLOW,
1476
+ });
1477
+ const mockConfig = createMockConfig({
1478
+ getToolRegistry: () => mockToolRegistry,
1479
+ getPolicyEngine: () => ({
1480
+ check: mockPolicyEngineCheck,
1481
+ }),
1482
+ isInteractive: () => false,
1483
+ });
1484
+ const scheduler = new CoreToolScheduler({
1485
+ config: mockConfig,
1486
+ getPreferredEditor: () => 'vscode',
1487
+ });
1488
+ const abortController = new AbortController();
1489
+ const request = {
1490
+ callId: '1',
1491
+ name: toolName,
1492
+ args: {},
1493
+ isClientInitiated: false,
1494
+ prompt_id: 'prompt-id-1',
1495
+ };
1496
+ await scheduler.schedule(request, abortController.signal);
1497
+ expect(mockPolicyEngineCheck).toHaveBeenCalledWith(expect.objectContaining({ name: toolName }), serverName);
1653
1498
  });
1654
- it('should include helpful instructions in truncated message', async () => {
1655
- const content = 'a'.repeat(2_000_000);
1656
- const callId = 'test-call-id';
1657
- const projectTempDir = '/tmp';
1658
- mockWriteFile.mockResolvedValue(undefined);
1659
- const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1660
- expect(result.content).toContain('read_file tool with the absolute file path above');
1661
- expect(result.content).toContain('read_file tool with offset=0, limit=100');
1662
- expect(result.content).toContain('read_file tool with offset=N to skip N lines');
1663
- expect(result.content).toContain('read_file tool with limit=M to read only M lines');
1499
+ it('should not double-report completed tools when concurrent completions occur', async () => {
1500
+ // Arrange
1501
+ const executeFn = vi.fn().mockResolvedValue({ llmContent: 'success' });
1502
+ const mockTool = new MockTool({ name: 'mockTool', execute: executeFn });
1503
+ const declarativeTool = mockTool;
1504
+ const mockToolRegistry = {
1505
+ getTool: () => declarativeTool,
1506
+ getToolByName: () => declarativeTool,
1507
+ getFunctionDeclarations: () => [],
1508
+ tools: new Map(),
1509
+ discovery: {},
1510
+ registerTool: () => { },
1511
+ getToolByDisplayName: () => declarativeTool,
1512
+ getTools: () => [],
1513
+ discoverTools: async () => { },
1514
+ getAllTools: () => [],
1515
+ getToolsByServer: () => [],
1516
+ };
1517
+ let completionCallCount = 0;
1518
+ const onAllToolCallsComplete = vi.fn().mockImplementation(async () => {
1519
+ completionCallCount++;
1520
+ // Simulate slow reporting (e.g. Gemini API call)
1521
+ await new Promise((resolve) => setTimeout(resolve, 50));
1522
+ });
1523
+ const mockConfig = createMockConfig({
1524
+ getToolRegistry: () => mockToolRegistry,
1525
+ getApprovalMode: () => ApprovalMode.YOLO,
1526
+ isInteractive: () => false,
1527
+ });
1528
+ const mockMessageBus = createMockMessageBus();
1529
+ mockConfig.getMessageBus = vi.fn().mockReturnValue(mockMessageBus);
1530
+ mockConfig.getEnableHooks = vi.fn().mockReturnValue(false);
1531
+ mockConfig.getHookSystem = vi
1532
+ .fn()
1533
+ .mockReturnValue(new HookSystem(mockConfig));
1534
+ const scheduler = new CoreToolScheduler({
1535
+ config: mockConfig,
1536
+ onAllToolCallsComplete,
1537
+ getPreferredEditor: () => 'vscode',
1538
+ });
1539
+ const abortController = new AbortController();
1540
+ const request = {
1541
+ callId: '1',
1542
+ name: 'mockTool',
1543
+ args: {},
1544
+ isClientInitiated: false,
1545
+ prompt_id: 'prompt-1',
1546
+ };
1547
+ // Act
1548
+ // 1. Start execution
1549
+ const schedulePromise = scheduler.schedule([request], abortController.signal);
1550
+ // 2. Wait just enough for it to finish and enter checkAndNotifyCompletion
1551
+ // (awaiting our slow mock)
1552
+ await vi.waitFor(() => {
1553
+ expect(completionCallCount).toBe(1);
1554
+ });
1555
+ // 3. Trigger a concurrent completion event (e.g. via cancelAll)
1556
+ scheduler.cancelAll(abortController.signal);
1557
+ await schedulePromise;
1558
+ // Assert
1559
+ // Even though cancelAll was called while the first completion was in progress,
1560
+ // it should not have triggered a SECOND completion call because the first one
1561
+ // was still 'finalizing' and will drain any new tools.
1562
+ expect(onAllToolCallsComplete).toHaveBeenCalledTimes(1);
1664
1563
  });
1665
- it('should sanitize callId to prevent path traversal', async () => {
1666
- const content = 'a'.repeat(200_000);
1667
- const callId = '../../../../../etc/passwd';
1668
- const projectTempDir = '/tmp/safe_dir';
1669
- const wrapWidth = 120;
1670
- mockWriteFile.mockResolvedValue(undefined);
1671
- // Manually wrap the content to generate the expected file content
1672
- const wrappedLines = [];
1673
- for (let i = 0; i < content.length; i += wrapWidth) {
1674
- wrappedLines.push(content.substring(i, i + wrapWidth));
1675
- }
1676
- const expectedFileContent = wrappedLines.join('\n');
1677
- await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1678
- const expectedPath = path.join(projectTempDir, 'passwd.output');
1679
- expect(mockWriteFile).toHaveBeenCalledWith(expectedPath, expectedFileContent);
1564
+ it('should complete reporting all tools even mid-callback during abort', async () => {
1565
+ // Arrange
1566
+ const onAllToolCallsComplete = vi.fn().mockImplementation(async () => {
1567
+ // Simulate slow reporting
1568
+ await new Promise((resolve) => setTimeout(resolve, 50));
1569
+ });
1570
+ const mockTool = new MockTool({ name: 'mockTool' });
1571
+ const mockToolRegistry = {
1572
+ getTool: () => mockTool,
1573
+ getToolByName: () => mockTool,
1574
+ getFunctionDeclarations: () => [],
1575
+ tools: new Map(),
1576
+ discovery: {},
1577
+ registerTool: () => { },
1578
+ getToolByDisplayName: () => mockTool,
1579
+ getTools: () => [],
1580
+ discoverTools: async () => { },
1581
+ getAllTools: () => [],
1582
+ getToolsByServer: () => [],
1583
+ };
1584
+ const mockConfig = createMockConfig({
1585
+ getToolRegistry: () => mockToolRegistry,
1586
+ getApprovalMode: () => ApprovalMode.YOLO,
1587
+ isInteractive: () => false,
1588
+ });
1589
+ const scheduler = new CoreToolScheduler({
1590
+ config: mockConfig,
1591
+ onAllToolCallsComplete,
1592
+ getPreferredEditor: () => 'vscode',
1593
+ });
1594
+ const abortController = new AbortController();
1595
+ const signal = abortController.signal;
1596
+ // Act
1597
+ // 1. Start execution of two tools
1598
+ const schedulePromise = scheduler.schedule([
1599
+ {
1600
+ callId: '1',
1601
+ name: 'mockTool',
1602
+ args: {},
1603
+ isClientInitiated: false,
1604
+ prompt_id: 'prompt-1',
1605
+ },
1606
+ {
1607
+ callId: '2',
1608
+ name: 'mockTool',
1609
+ args: {},
1610
+ isClientInitiated: false,
1611
+ prompt_id: 'prompt-1',
1612
+ },
1613
+ ], signal);
1614
+ // 2. Wait for reporting to start
1615
+ await vi.waitFor(() => {
1616
+ expect(onAllToolCallsComplete).toHaveBeenCalled();
1617
+ });
1618
+ // 3. Abort the signal while reporting is in progress
1619
+ abortController.abort();
1620
+ await schedulePromise;
1621
+ // Assert
1622
+ // Verify that onAllToolCallsComplete was called and processed the tools,
1623
+ // and that the scheduler didn't just drop them because of the abort.
1624
+ expect(onAllToolCallsComplete).toHaveBeenCalled();
1625
+ const reportedTools = onAllToolCallsComplete.mock.calls.flatMap((call) =>
1626
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1627
+ call[0].map((t) => t.request.callId));
1628
+ // Both tools should have been reported exactly once with success status
1629
+ expect(reportedTools).toContain('1');
1630
+ expect(reportedTools).toContain('2');
1631
+ const allStatuses = onAllToolCallsComplete.mock.calls.flatMap((call) =>
1632
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1633
+ call[0].map((t) => t.status));
1634
+ expect(allStatuses).toEqual(['success', 'success']);
1635
+ expect(onAllToolCallsComplete).toHaveBeenCalledTimes(1);
1680
1636
  });
1681
1637
  });
1682
1638
  //# sourceMappingURL=coreToolScheduler.test.js.map