@office-ai/aioncli-core 0.2.2 → 0.8.1

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 (758) hide show
  1. package/dist/index.d.ts +10 -3
  2. package/dist/index.js +10 -3
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/agents/codebase-investigator.d.ts +11 -0
  5. package/dist/src/agents/codebase-investigator.js +73 -0
  6. package/dist/src/agents/codebase-investigator.js.map +1 -0
  7. package/dist/src/agents/executor.d.ts +88 -0
  8. package/dist/src/agents/executor.js +417 -0
  9. package/dist/src/agents/executor.js.map +1 -0
  10. package/dist/src/agents/executor.test.js +419 -0
  11. package/dist/src/agents/executor.test.js.map +1 -0
  12. package/dist/src/agents/invocation.d.ts +43 -0
  13. package/dist/src/agents/invocation.js +100 -0
  14. package/dist/src/agents/invocation.js.map +1 -0
  15. package/dist/src/agents/invocation.test.js +206 -0
  16. package/dist/src/agents/invocation.test.js.map +1 -0
  17. package/dist/src/agents/registry.d.ts +35 -0
  18. package/dist/src/agents/registry.js +58 -0
  19. package/dist/src/agents/registry.js.map +1 -0
  20. package/dist/src/agents/registry.test.js +146 -0
  21. package/dist/src/agents/registry.test.js.map +1 -0
  22. package/dist/src/agents/schema-utils.d.ts +39 -0
  23. package/dist/src/agents/schema-utils.js +57 -0
  24. package/dist/src/agents/schema-utils.js.map +1 -0
  25. package/dist/src/agents/schema-utils.test.d.ts +6 -0
  26. package/dist/src/agents/schema-utils.test.js +144 -0
  27. package/dist/src/agents/schema-utils.test.js.map +1 -0
  28. package/dist/src/agents/subagent-tool-wrapper.d.ts +36 -0
  29. package/dist/src/agents/subagent-tool-wrapper.js +47 -0
  30. package/dist/src/agents/subagent-tool-wrapper.js.map +1 -0
  31. package/dist/src/agents/subagent-tool-wrapper.test.d.ts +6 -0
  32. package/dist/src/agents/subagent-tool-wrapper.test.js +105 -0
  33. package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -0
  34. package/dist/src/agents/types.d.ts +116 -0
  35. package/dist/src/agents/types.js +17 -0
  36. package/dist/src/agents/types.js.map +1 -0
  37. package/dist/src/agents/utils.d.ts +15 -0
  38. package/dist/src/agents/utils.js +29 -0
  39. package/dist/src/agents/utils.js.map +1 -0
  40. package/dist/src/agents/utils.test.d.ts +6 -0
  41. package/dist/src/agents/utils.test.js +87 -0
  42. package/dist/src/agents/utils.test.js.map +1 -0
  43. package/dist/src/code_assist/codeAssist.d.ts +6 -3
  44. package/dist/src/code_assist/codeAssist.js +12 -0
  45. package/dist/src/code_assist/codeAssist.js.map +1 -1
  46. package/dist/src/code_assist/converter.d.ts +4 -1
  47. package/dist/src/code_assist/converter.js +38 -5
  48. package/dist/src/code_assist/converter.js.map +1 -1
  49. package/dist/src/code_assist/converter.test.js +93 -0
  50. package/dist/src/code_assist/converter.test.js.map +1 -1
  51. package/dist/src/code_assist/oauth-credential-storage.d.ts +25 -0
  52. package/dist/src/code_assist/oauth-credential-storage.js +109 -0
  53. package/dist/src/code_assist/oauth-credential-storage.js.map +1 -0
  54. package/dist/src/code_assist/oauth-credential-storage.test.d.ts +6 -0
  55. package/dist/src/code_assist/oauth-credential-storage.test.js +136 -0
  56. package/dist/src/code_assist/oauth-credential-storage.test.js.map +1 -0
  57. package/dist/src/code_assist/oauth2.d.ts +1 -1
  58. package/dist/src/code_assist/oauth2.js +107 -48
  59. package/dist/src/code_assist/oauth2.js.map +1 -1
  60. package/dist/src/code_assist/oauth2.test.js +735 -343
  61. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  62. package/dist/src/code_assist/server.d.ts +4 -4
  63. package/dist/src/code_assist/server.js +25 -2
  64. package/dist/src/code_assist/server.js.map +1 -1
  65. package/dist/src/code_assist/server.test.js +25 -0
  66. package/dist/src/code_assist/server.test.js.map +1 -1
  67. package/dist/src/code_assist/setup.d.ts +1 -1
  68. package/dist/src/code_assist/setup.js +1 -1
  69. package/dist/src/code_assist/setup.js.map +1 -1
  70. package/dist/src/code_assist/setup.test.js.map +1 -1
  71. package/dist/src/code_assist/types.d.ts +17 -2
  72. package/dist/src/config/config.d.ts +121 -25
  73. package/dist/src/config/config.js +298 -87
  74. package/dist/src/config/config.js.map +1 -1
  75. package/dist/src/config/config.test.js +370 -131
  76. package/dist/src/config/config.test.js.map +1 -1
  77. package/dist/src/config/constants.d.ts +11 -0
  78. package/dist/src/config/constants.js +16 -0
  79. package/dist/src/config/constants.js.map +1 -0
  80. package/dist/src/config/models.d.ts +16 -0
  81. package/dist/src/config/models.js +29 -0
  82. package/dist/src/config/models.js.map +1 -1
  83. package/dist/src/config/models.test.d.ts +6 -0
  84. package/dist/src/config/models.test.js +55 -0
  85. package/dist/src/config/models.test.js.map +1 -0
  86. package/dist/src/config/storage.d.ts +34 -0
  87. package/dist/src/config/storage.js +95 -0
  88. package/dist/src/config/storage.js.map +1 -0
  89. package/dist/src/config/storage.test.d.ts +6 -0
  90. package/dist/src/config/storage.test.js +47 -0
  91. package/dist/src/config/storage.test.js.map +1 -0
  92. package/dist/src/confirmation-bus/index.d.ts +7 -0
  93. package/dist/src/confirmation-bus/index.js +8 -0
  94. package/dist/src/confirmation-bus/index.js.map +1 -0
  95. package/dist/src/confirmation-bus/message-bus.d.ts +17 -0
  96. package/dist/src/confirmation-bus/message-bus.js +81 -0
  97. package/dist/src/confirmation-bus/message-bus.js.map +1 -0
  98. package/dist/src/confirmation-bus/message-bus.test.d.ts +6 -0
  99. package/dist/src/confirmation-bus/message-bus.test.js +164 -0
  100. package/dist/src/confirmation-bus/message-bus.test.js.map +1 -0
  101. package/dist/src/confirmation-bus/types.d.ts +38 -0
  102. package/dist/src/confirmation-bus/types.js +15 -0
  103. package/dist/src/confirmation-bus/types.js.map +1 -0
  104. package/dist/src/core/baseLlmClient.d.ts +54 -0
  105. package/dist/src/core/baseLlmClient.js +190 -0
  106. package/dist/src/core/baseLlmClient.js.map +1 -0
  107. package/dist/src/core/baseLlmClient.test.d.ts +6 -0
  108. package/dist/src/core/baseLlmClient.test.js +316 -0
  109. package/dist/src/core/baseLlmClient.test.js.map +1 -0
  110. package/dist/src/core/client.d.ts +28 -28
  111. package/dist/src/core/client.js +187 -333
  112. package/dist/src/core/client.js.map +1 -1
  113. package/dist/src/core/client.test.js +745 -500
  114. package/dist/src/core/client.test.js.map +1 -1
  115. package/dist/src/core/contentGenerator.d.ts +4 -4
  116. package/dist/src/core/contentGenerator.js +6 -7
  117. package/dist/src/core/contentGenerator.js.map +1 -1
  118. package/dist/src/core/contentGenerator.test.js +1 -3
  119. package/dist/src/core/contentGenerator.test.js.map +1 -1
  120. package/dist/src/core/coreToolScheduler.d.ts +20 -7
  121. package/dist/src/core/coreToolScheduler.js +216 -53
  122. package/dist/src/core/coreToolScheduler.js.map +1 -1
  123. package/dist/src/core/coreToolScheduler.test.js +564 -88
  124. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  125. package/dist/src/core/geminiChat.d.ts +54 -43
  126. package/dist/src/core/geminiChat.js +298 -280
  127. package/dist/src/core/geminiChat.js.map +1 -1
  128. package/dist/src/core/geminiChat.test.js +1255 -321
  129. package/dist/src/core/geminiChat.test.js.map +1 -1
  130. package/dist/src/core/geminiRequest.js +1 -0
  131. package/dist/src/core/geminiRequest.js.map +1 -1
  132. package/dist/src/core/logger.d.ts +4 -2
  133. package/dist/src/core/logger.js +4 -3
  134. package/dist/src/core/logger.js.map +1 -1
  135. package/dist/src/core/logger.test.js +17 -16
  136. package/dist/src/core/logger.test.js.map +1 -1
  137. package/dist/src/core/loggingContentGenerator.d.ts +3 -3
  138. package/dist/src/core/loggingContentGenerator.js +15 -16
  139. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  140. package/dist/src/core/nonInteractiveToolExecutor.d.ts +3 -5
  141. package/dist/src/core/nonInteractiveToolExecutor.js +14 -122
  142. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
  143. package/dist/src/core/nonInteractiveToolExecutor.test.js +158 -78
  144. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  145. package/dist/src/core/openaiContentGenerator.d.ts +4 -3
  146. package/dist/src/core/openaiContentGenerator.js +21 -14
  147. package/dist/src/core/openaiContentGenerator.js.map +1 -1
  148. package/dist/src/core/openaiContentGenerator.test.js +1 -0
  149. package/dist/src/core/openaiContentGenerator.test.js.map +1 -1
  150. package/dist/src/core/prompts.d.ts +5 -0
  151. package/dist/src/core/prompts.js +66 -44
  152. package/dist/src/core/prompts.js.map +1 -1
  153. package/dist/src/core/prompts.test.js +130 -1
  154. package/dist/src/core/prompts.test.js.map +1 -1
  155. package/dist/src/core/subagent.d.ts +24 -18
  156. package/dist/src/core/subagent.js +125 -90
  157. package/dist/src/core/subagent.js.map +1 -1
  158. package/dist/src/core/subagent.test.js +59 -44
  159. package/dist/src/core/subagent.test.js.map +1 -1
  160. package/dist/src/core/turn.d.ts +37 -13
  161. package/dist/src/core/turn.js +63 -28
  162. package/dist/src/core/turn.js.map +1 -1
  163. package/dist/src/core/turn.test.js +359 -100
  164. package/dist/src/core/turn.test.js.map +1 -1
  165. package/dist/src/fallback/handler.d.ts +7 -0
  166. package/dist/src/fallback/handler.js +129 -0
  167. package/dist/src/fallback/handler.js.map +1 -0
  168. package/dist/src/fallback/handler.test.d.ts +6 -0
  169. package/dist/src/fallback/handler.test.js +130 -0
  170. package/dist/src/fallback/handler.test.js.map +1 -0
  171. package/dist/src/fallback/types.d.ts +14 -0
  172. package/dist/src/fallback/types.js +7 -0
  173. package/dist/src/fallback/types.js.map +1 -0
  174. package/dist/src/generated/git-commit.d.ts +1 -1
  175. package/dist/src/generated/git-commit.js +1 -1
  176. package/dist/src/ide/constants.d.ts +3 -0
  177. package/dist/src/ide/constants.js +3 -0
  178. package/dist/src/ide/constants.js.map +1 -1
  179. package/dist/src/ide/detect-ide.d.ts +48 -12
  180. package/dist/src/ide/detect-ide.js +47 -66
  181. package/dist/src/ide/detect-ide.js.map +1 -1
  182. package/dist/src/ide/detect-ide.test.js +79 -52
  183. package/dist/src/ide/detect-ide.test.js.map +1 -1
  184. package/dist/src/ide/ide-client.d.ts +69 -23
  185. package/dist/src/ide/ide-client.js +372 -78
  186. package/dist/src/ide/ide-client.js.map +1 -1
  187. package/dist/src/ide/ide-client.test.js +375 -30
  188. package/dist/src/ide/ide-client.test.js.map +1 -1
  189. package/dist/src/ide/ide-installer.d.ts +2 -2
  190. package/dist/src/ide/ide-installer.js +37 -24
  191. package/dist/src/ide/ide-installer.js.map +1 -1
  192. package/dist/src/ide/ide-installer.test.js +104 -26
  193. package/dist/src/ide/ide-installer.test.js.map +1 -1
  194. package/dist/src/ide/ideContext.d.ts +35 -365
  195. package/dist/src/ide/ideContext.js +60 -106
  196. package/dist/src/ide/ideContext.js.map +1 -1
  197. package/dist/src/ide/ideContext.test.js +152 -24
  198. package/dist/src/ide/ideContext.test.js.map +1 -1
  199. package/dist/src/ide/process-utils.d.ts +7 -5
  200. package/dist/src/ide/process-utils.js +81 -50
  201. package/dist/src/ide/process-utils.js.map +1 -1
  202. package/dist/src/ide/process-utils.test.d.ts +6 -0
  203. package/dist/src/ide/process-utils.test.js +158 -0
  204. package/dist/src/ide/process-utils.test.js.map +1 -0
  205. package/dist/src/ide/types.d.ts +486 -0
  206. package/dist/src/ide/types.js +138 -0
  207. package/dist/src/ide/types.js.map +1 -0
  208. package/dist/src/index.d.ts +20 -2
  209. package/dist/src/index.js +20 -2
  210. package/dist/src/index.js.map +1 -1
  211. package/dist/src/mcp/google-auth-provider.d.ts +3 -3
  212. package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
  213. package/dist/src/mcp/oauth-provider.d.ts +17 -13
  214. package/dist/src/mcp/oauth-provider.js +81 -69
  215. package/dist/src/mcp/oauth-provider.js.map +1 -1
  216. package/dist/src/mcp/oauth-provider.test.js +212 -37
  217. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  218. package/dist/src/mcp/oauth-token-storage.d.ts +14 -32
  219. package/dist/src/mcp/oauth-token-storage.js +54 -25
  220. package/dist/src/mcp/oauth-token-storage.js.map +1 -1
  221. package/dist/src/mcp/oauth-token-storage.test.js +256 -162
  222. package/dist/src/mcp/oauth-token-storage.test.js.map +1 -1
  223. package/dist/src/mcp/oauth-utils.d.ts +9 -1
  224. package/dist/src/mcp/oauth-utils.js +42 -27
  225. package/dist/src/mcp/oauth-utils.js.map +1 -1
  226. package/dist/src/mcp/oauth-utils.test.js +41 -1
  227. package/dist/src/mcp/oauth-utils.test.js.map +1 -1
  228. package/dist/src/mcp/sa-impersonation-provider.d.ts +33 -0
  229. package/dist/src/mcp/sa-impersonation-provider.js +130 -0
  230. package/dist/src/mcp/sa-impersonation-provider.js.map +1 -0
  231. package/dist/src/mcp/sa-impersonation-provider.test.d.ts +6 -0
  232. package/dist/src/mcp/sa-impersonation-provider.test.js +117 -0
  233. package/dist/src/mcp/sa-impersonation-provider.test.js.map +1 -0
  234. package/dist/src/mcp/token-storage/base-token-storage.d.ts +19 -0
  235. package/dist/src/mcp/token-storage/base-token-storage.js +36 -0
  236. package/dist/src/mcp/token-storage/base-token-storage.js.map +1 -0
  237. package/dist/src/mcp/token-storage/base-token-storage.test.d.ts +6 -0
  238. package/dist/src/mcp/token-storage/base-token-storage.test.js +160 -0
  239. package/dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -0
  240. package/dist/src/mcp/token-storage/file-token-storage.d.ts +24 -0
  241. package/dist/src/mcp/token-storage/file-token-storage.js +144 -0
  242. package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -0
  243. package/dist/src/mcp/token-storage/file-token-storage.test.d.ts +6 -0
  244. package/dist/src/mcp/token-storage/file-token-storage.test.js +235 -0
  245. package/dist/src/mcp/token-storage/file-token-storage.test.js.map +1 -0
  246. package/dist/src/mcp/token-storage/hybrid-token-storage.d.ts +23 -0
  247. package/dist/src/mcp/token-storage/hybrid-token-storage.js +78 -0
  248. package/dist/src/mcp/token-storage/hybrid-token-storage.js.map +1 -0
  249. package/dist/src/mcp/token-storage/hybrid-token-storage.test.d.ts +6 -0
  250. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js +193 -0
  251. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js.map +1 -0
  252. package/dist/src/mcp/token-storage/index.d.ts +11 -0
  253. package/dist/src/mcp/token-storage/index.js +12 -0
  254. package/dist/src/mcp/token-storage/index.js.map +1 -0
  255. package/dist/src/mcp/token-storage/keychain-token-storage.d.ts +31 -0
  256. package/dist/src/mcp/token-storage/keychain-token-storage.js +190 -0
  257. package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -0
  258. package/dist/src/mcp/token-storage/keychain-token-storage.test.d.ts +6 -0
  259. package/dist/src/mcp/token-storage/keychain-token-storage.test.js +254 -0
  260. package/dist/src/mcp/token-storage/keychain-token-storage.test.js.map +1 -0
  261. package/dist/src/mcp/token-storage/types.d.ts +38 -0
  262. package/dist/src/mcp/token-storage/types.js +11 -0
  263. package/dist/src/mcp/token-storage/types.js.map +1 -0
  264. package/dist/src/output/json-formatter.d.ts +11 -0
  265. package/dist/src/output/json-formatter.js +30 -0
  266. package/dist/src/output/json-formatter.js.map +1 -0
  267. package/dist/src/output/json-formatter.test.d.ts +6 -0
  268. package/dist/src/output/json-formatter.test.js +266 -0
  269. package/dist/src/output/json-formatter.test.js.map +1 -0
  270. package/dist/src/output/types.d.ts +20 -0
  271. package/dist/src/output/types.js +11 -0
  272. package/dist/src/output/types.js.map +1 -0
  273. package/dist/src/policy/index.d.ts +7 -0
  274. package/dist/src/policy/index.js +8 -0
  275. package/dist/src/policy/index.js.map +1 -0
  276. package/dist/src/policy/policy-engine.d.ts +30 -0
  277. package/dist/src/policy/policy-engine.js +92 -0
  278. package/dist/src/policy/policy-engine.js.map +1 -0
  279. package/dist/src/policy/policy-engine.test.d.ts +6 -0
  280. package/dist/src/policy/policy-engine.test.js +515 -0
  281. package/dist/src/policy/policy-engine.test.js.map +1 -0
  282. package/dist/src/policy/stable-stringify.d.ts +58 -0
  283. package/dist/src/policy/stable-stringify.js +122 -0
  284. package/dist/src/policy/stable-stringify.js.map +1 -0
  285. package/dist/src/policy/types.d.ts +47 -0
  286. package/dist/src/policy/types.js +12 -0
  287. package/dist/src/policy/types.js.map +1 -0
  288. package/dist/src/prompts/mcp-prompts.d.ts +2 -2
  289. package/dist/src/prompts/prompt-registry.d.ts +1 -1
  290. package/dist/src/routing/modelRouterService.d.ts +23 -0
  291. package/dist/src/routing/modelRouterService.js +70 -0
  292. package/dist/src/routing/modelRouterService.js.map +1 -0
  293. package/dist/src/routing/modelRouterService.test.d.ts +6 -0
  294. package/dist/src/routing/modelRouterService.test.js +98 -0
  295. package/dist/src/routing/modelRouterService.test.js.map +1 -0
  296. package/dist/src/routing/routingStrategy.d.ts +62 -0
  297. package/dist/src/routing/routingStrategy.js +7 -0
  298. package/dist/src/routing/routingStrategy.js.map +1 -0
  299. package/dist/src/routing/strategies/classifierStrategy.d.ts +12 -0
  300. package/dist/src/routing/strategies/classifierStrategy.js +173 -0
  301. package/dist/src/routing/strategies/classifierStrategy.js.map +1 -0
  302. package/dist/src/routing/strategies/classifierStrategy.test.d.ts +6 -0
  303. package/dist/src/routing/strategies/classifierStrategy.test.js +192 -0
  304. package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -0
  305. package/dist/src/routing/strategies/compositeStrategy.d.ts +26 -0
  306. package/dist/src/routing/strategies/compositeStrategy.js +68 -0
  307. package/dist/src/routing/strategies/compositeStrategy.js.map +1 -0
  308. package/dist/src/routing/strategies/compositeStrategy.test.d.ts +6 -0
  309. package/dist/src/routing/strategies/compositeStrategy.test.js +123 -0
  310. package/dist/src/routing/strategies/compositeStrategy.test.js.map +1 -0
  311. package/dist/src/routing/strategies/defaultStrategy.d.ts +12 -0
  312. package/dist/src/routing/strategies/defaultStrategy.js +20 -0
  313. package/dist/src/routing/strategies/defaultStrategy.js.map +1 -0
  314. package/dist/src/routing/strategies/defaultStrategy.test.d.ts +6 -0
  315. package/dist/src/routing/strategies/defaultStrategy.test.js +26 -0
  316. package/dist/src/routing/strategies/defaultStrategy.test.js.map +1 -0
  317. package/dist/src/routing/strategies/fallbackStrategy.d.ts +12 -0
  318. package/dist/src/routing/strategies/fallbackStrategy.js +25 -0
  319. package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -0
  320. package/dist/src/routing/strategies/fallbackStrategy.test.d.ts +6 -0
  321. package/dist/src/routing/strategies/fallbackStrategy.test.js +55 -0
  322. package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -0
  323. package/dist/src/routing/strategies/overrideStrategy.d.ts +15 -0
  324. package/dist/src/routing/strategies/overrideStrategy.js +28 -0
  325. package/dist/src/routing/strategies/overrideStrategy.js.map +1 -0
  326. package/dist/src/routing/strategies/overrideStrategy.test.d.ts +6 -0
  327. package/dist/src/routing/strategies/overrideStrategy.test.js +42 -0
  328. package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -0
  329. package/dist/src/services/chatRecordingService.d.ts +8 -14
  330. package/dist/src/services/chatRecordingService.js +33 -21
  331. package/dist/src/services/chatRecordingService.js.map +1 -1
  332. package/dist/src/services/chatRecordingService.test.js +69 -25
  333. package/dist/src/services/chatRecordingService.test.js.map +1 -1
  334. package/dist/src/services/fileDiscoveryService.d.ts +10 -0
  335. package/dist/src/services/fileDiscoveryService.js +32 -18
  336. package/dist/src/services/fileDiscoveryService.js.map +1 -1
  337. package/dist/src/services/fileDiscoveryService.test.js +3 -3
  338. package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
  339. package/dist/src/services/fileSystemService.d.ts +9 -0
  340. package/dist/src/services/fileSystemService.js +12 -1
  341. package/dist/src/services/fileSystemService.js.map +1 -1
  342. package/dist/src/services/fileSystemService.test.js +1 -1
  343. package/dist/src/services/fileSystemService.test.js.map +1 -1
  344. package/dist/src/services/gitService.d.ts +3 -1
  345. package/dist/src/services/gitService.js +30 -24
  346. package/dist/src/services/gitService.js.map +1 -1
  347. package/dist/src/services/gitService.test.js +30 -37
  348. package/dist/src/services/gitService.test.js.map +1 -1
  349. package/dist/src/services/loopDetectionService.d.ts +8 -2
  350. package/dist/src/services/loopDetectionService.js +64 -24
  351. package/dist/src/services/loopDetectionService.js.map +1 -1
  352. package/dist/src/services/loopDetectionService.test.js +64 -13
  353. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  354. package/dist/src/services/shellExecutionService.d.ts +36 -2
  355. package/dist/src/services/shellExecutionService.js +238 -47
  356. package/dist/src/services/shellExecutionService.js.map +1 -1
  357. package/dist/src/services/shellExecutionService.test.js +197 -58
  358. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  359. package/dist/src/telemetry/activity-detector.d.ts +41 -0
  360. package/dist/src/telemetry/activity-detector.js +61 -0
  361. package/dist/src/telemetry/activity-detector.js.map +1 -0
  362. package/dist/src/telemetry/activity-detector.test.d.ts +6 -0
  363. package/dist/src/telemetry/activity-detector.test.js +136 -0
  364. package/dist/src/telemetry/activity-detector.test.js.map +1 -0
  365. package/dist/src/telemetry/activity-types.d.ts +19 -0
  366. package/dist/src/telemetry/activity-types.js +21 -0
  367. package/dist/src/telemetry/activity-types.js.map +1 -0
  368. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +34 -4
  369. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +322 -15
  370. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  371. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +1 -0
  372. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +321 -11
  373. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  374. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +51 -2
  375. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +124 -2
  376. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  377. package/dist/src/telemetry/config.d.ts +31 -0
  378. package/dist/src/telemetry/config.js +76 -0
  379. package/dist/src/telemetry/config.js.map +1 -0
  380. package/dist/src/telemetry/config.test.d.ts +6 -0
  381. package/dist/src/telemetry/config.test.js +124 -0
  382. package/dist/src/telemetry/config.test.js.map +1 -0
  383. package/dist/src/telemetry/constants.d.ts +17 -7
  384. package/dist/src/telemetry/constants.js +18 -7
  385. package/dist/src/telemetry/constants.js.map +1 -1
  386. package/dist/src/telemetry/file-exporters.d.ts +5 -4
  387. package/dist/src/telemetry/file-exporters.js +1 -1
  388. package/dist/src/telemetry/file-exporters.js.map +1 -1
  389. package/dist/src/telemetry/gcp-exporters.d.ts +34 -0
  390. package/dist/src/telemetry/gcp-exporters.js +117 -0
  391. package/dist/src/telemetry/gcp-exporters.js.map +1 -0
  392. package/dist/src/telemetry/gcp-exporters.test.d.ts +6 -0
  393. package/dist/src/telemetry/gcp-exporters.test.js +318 -0
  394. package/dist/src/telemetry/gcp-exporters.test.js.map +1 -0
  395. package/dist/src/telemetry/high-water-mark-tracker.d.ts +43 -0
  396. package/dist/src/telemetry/high-water-mark-tracker.js +88 -0
  397. package/dist/src/telemetry/high-water-mark-tracker.js.map +1 -0
  398. package/dist/src/telemetry/high-water-mark-tracker.test.d.ts +6 -0
  399. package/dist/src/telemetry/high-water-mark-tracker.test.js +152 -0
  400. package/dist/src/telemetry/high-water-mark-tracker.test.js.map +1 -0
  401. package/dist/src/telemetry/index.d.ts +12 -2
  402. package/dist/src/telemetry/index.js +16 -2
  403. package/dist/src/telemetry/index.js.map +1 -1
  404. package/dist/src/telemetry/loggers.d.ts +17 -2
  405. package/dist/src/telemetry/loggers.js +316 -14
  406. package/dist/src/telemetry/loggers.js.map +1 -1
  407. package/dist/src/telemetry/loggers.test.circular.js +3 -3
  408. package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
  409. package/dist/src/telemetry/loggers.test.js +452 -48
  410. package/dist/src/telemetry/loggers.test.js.map +1 -1
  411. package/dist/src/telemetry/metrics.d.ts +323 -12
  412. package/dist/src/telemetry/metrics.js +464 -83
  413. package/dist/src/telemetry/metrics.js.map +1 -1
  414. package/dist/src/telemetry/metrics.test.js +583 -38
  415. package/dist/src/telemetry/metrics.test.js.map +1 -1
  416. package/dist/src/telemetry/rate-limiter.d.ts +48 -0
  417. package/dist/src/telemetry/rate-limiter.js +100 -0
  418. package/dist/src/telemetry/rate-limiter.js.map +1 -0
  419. package/dist/src/telemetry/rate-limiter.test.d.ts +6 -0
  420. package/dist/src/telemetry/rate-limiter.test.js +207 -0
  421. package/dist/src/telemetry/rate-limiter.test.js.map +1 -0
  422. package/dist/src/telemetry/sdk.d.ts +1 -1
  423. package/dist/src/telemetry/sdk.js +20 -2
  424. package/dist/src/telemetry/sdk.js.map +1 -1
  425. package/dist/src/telemetry/sdk.test.js +108 -0
  426. package/dist/src/telemetry/sdk.test.js.map +1 -1
  427. package/dist/src/telemetry/telemetry-utils.d.ts +6 -0
  428. package/dist/src/telemetry/telemetry-utils.js +14 -0
  429. package/dist/src/telemetry/telemetry-utils.js.map +1 -0
  430. package/dist/src/telemetry/telemetry-utils.test.d.ts +6 -0
  431. package/dist/src/telemetry/telemetry-utils.test.js +40 -0
  432. package/dist/src/telemetry/telemetry-utils.test.js.map +1 -0
  433. package/dist/src/telemetry/types.d.ts +136 -8
  434. package/dist/src/telemetry/types.js +233 -11
  435. package/dist/src/telemetry/types.js.map +1 -1
  436. package/dist/src/telemetry/uiTelemetry.d.ts +3 -3
  437. package/dist/src/telemetry/uiTelemetry.js +7 -8
  438. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  439. package/dist/src/telemetry/uiTelemetry.test.js +33 -29
  440. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  441. package/dist/src/test-utils/config.d.ts +2 -1
  442. package/dist/src/test-utils/config.js.map +1 -1
  443. package/dist/src/test-utils/index.d.ts +6 -0
  444. package/dist/src/test-utils/index.js +7 -0
  445. package/dist/src/test-utils/index.js.map +1 -0
  446. package/dist/src/test-utils/mock-tool.d.ts +66 -0
  447. package/dist/src/test-utils/{tools.js → mock-tool.js} +45 -29
  448. package/dist/src/test-utils/mock-tool.js.map +1 -0
  449. package/dist/src/test-utils/mockWorkspaceContext.d.ts +1 -1
  450. package/dist/src/tools/diffOptions.d.ts +1 -1
  451. package/dist/src/tools/diffOptions.js +21 -13
  452. package/dist/src/tools/diffOptions.js.map +1 -1
  453. package/dist/src/tools/diffOptions.test.js +58 -22
  454. package/dist/src/tools/diffOptions.test.js.map +1 -1
  455. package/dist/src/tools/edit.d.ts +6 -5
  456. package/dist/src/tools/edit.js +58 -40
  457. package/dist/src/tools/edit.js.map +1 -1
  458. package/dist/src/tools/edit.test.js +192 -16
  459. package/dist/src/tools/edit.test.js.map +1 -1
  460. package/dist/src/tools/glob.d.ts +7 -2
  461. package/dist/src/tools/glob.js +42 -23
  462. package/dist/src/tools/glob.js.map +1 -1
  463. package/dist/src/tools/glob.test.js +80 -4
  464. package/dist/src/tools/glob.test.js.map +1 -1
  465. package/dist/src/tools/grep.d.ts +3 -2
  466. package/dist/src/tools/grep.js +35 -15
  467. package/dist/src/tools/grep.js.map +1 -1
  468. package/dist/src/tools/grep.test.js +26 -3
  469. package/dist/src/tools/grep.test.js.map +1 -1
  470. package/dist/src/tools/ls.d.ts +3 -2
  471. package/dist/src/tools/ls.js +31 -39
  472. package/dist/src/tools/ls.js.map +1 -1
  473. package/dist/src/tools/ls.test.js +145 -280
  474. package/dist/src/tools/ls.test.js.map +1 -1
  475. package/dist/src/tools/mcp-client-manager.d.ts +8 -6
  476. package/dist/src/tools/mcp-client-manager.js +13 -4
  477. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  478. package/dist/src/tools/mcp-client-manager.test.js +20 -1
  479. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  480. package/dist/src/tools/mcp-client.d.ts +18 -21
  481. package/dist/src/tools/mcp-client.js +87 -120
  482. package/dist/src/tools/mcp-client.js.map +1 -1
  483. package/dist/src/tools/mcp-client.test.js +32 -152
  484. package/dist/src/tools/mcp-client.test.js.map +1 -1
  485. package/dist/src/tools/mcp-tool.d.ts +6 -4
  486. package/dist/src/tools/mcp-tool.js +51 -13
  487. package/dist/src/tools/mcp-tool.js.map +1 -1
  488. package/dist/src/tools/mcp-tool.test.js +166 -12
  489. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  490. package/dist/src/tools/memoryTool.d.ts +3 -2
  491. package/dist/src/tools/memoryTool.js +14 -37
  492. package/dist/src/tools/memoryTool.js.map +1 -1
  493. package/dist/src/tools/memoryTool.test.js +16 -4
  494. package/dist/src/tools/memoryTool.test.js.map +1 -1
  495. package/dist/src/tools/message-bus-integration.test.d.ts +6 -0
  496. package/dist/src/tools/message-bus-integration.test.js +183 -0
  497. package/dist/src/tools/message-bus-integration.test.js.map +1 -0
  498. package/dist/src/tools/modifiable-tool.d.ts +2 -2
  499. package/dist/src/tools/modifiable-tool.js +3 -3
  500. package/dist/src/tools/modifiable-tool.js.map +1 -1
  501. package/dist/src/tools/modifiable-tool.test.js +4 -4
  502. package/dist/src/tools/modifiable-tool.test.js.map +1 -1
  503. package/dist/src/tools/read-file.d.ts +3 -2
  504. package/dist/src/tools/read-file.js +33 -43
  505. package/dist/src/tools/read-file.js.map +1 -1
  506. package/dist/src/tools/read-file.test.js +39 -7
  507. package/dist/src/tools/read-file.test.js.map +1 -1
  508. package/dist/src/tools/read-many-files.d.ts +3 -2
  509. package/dist/src/tools/read-many-files.js +52 -107
  510. package/dist/src/tools/read-many-files.js.map +1 -1
  511. package/dist/src/tools/read-many-files.test.js +64 -11
  512. package/dist/src/tools/read-many-files.test.js.map +1 -1
  513. package/dist/src/tools/ripGrep.d.ts +55 -0
  514. package/dist/src/tools/ripGrep.js +393 -0
  515. package/dist/src/tools/ripGrep.js.map +1 -0
  516. package/dist/src/tools/ripGrep.test.d.ts +6 -0
  517. package/dist/src/tools/ripGrep.test.js +976 -0
  518. package/dist/src/tools/ripGrep.test.js.map +1 -0
  519. package/dist/src/tools/shell.d.ts +13 -2
  520. package/dist/src/tools/shell.js +42 -32
  521. package/dist/src/tools/shell.js.map +1 -1
  522. package/dist/src/tools/shell.test.js +57 -75
  523. package/dist/src/tools/shell.test.js.map +1 -1
  524. package/dist/src/tools/smart-edit.d.ts +91 -0
  525. package/dist/src/tools/smart-edit.js +702 -0
  526. package/dist/src/tools/smart-edit.js.map +1 -0
  527. package/dist/src/tools/smart-edit.test.d.ts +6 -0
  528. package/dist/src/tools/smart-edit.test.js +542 -0
  529. package/dist/src/tools/smart-edit.test.js.map +1 -0
  530. package/dist/src/tools/tool-error.d.ts +18 -1
  531. package/dist/src/tools/tool-error.js +27 -0
  532. package/dist/src/tools/tool-error.js.map +1 -1
  533. package/dist/src/tools/tool-registry.d.ts +10 -4
  534. package/dist/src/tools/tool-registry.js +20 -7
  535. package/dist/src/tools/tool-registry.js.map +1 -1
  536. package/dist/src/tools/tool-registry.test.js +93 -10
  537. package/dist/src/tools/tool-registry.test.js.map +1 -1
  538. package/dist/src/tools/tools.d.ts +33 -16
  539. package/dist/src/tools/tools.js +115 -5
  540. package/dist/src/tools/tools.js.map +1 -1
  541. package/dist/src/tools/tools.test.js +1 -2
  542. package/dist/src/tools/tools.test.js.map +1 -1
  543. package/dist/src/tools/web-fetch.d.ts +3 -2
  544. package/dist/src/tools/web-fetch.js +14 -10
  545. package/dist/src/tools/web-fetch.js.map +1 -1
  546. package/dist/src/tools/web-fetch.test.js +55 -16
  547. package/dist/src/tools/web-fetch.test.js.map +1 -1
  548. package/dist/src/tools/web-search.d.ts +4 -3
  549. package/dist/src/tools/web-search.js +31 -8
  550. package/dist/src/tools/web-search.js.map +1 -1
  551. package/dist/src/tools/web-search.test.js +69 -1
  552. package/dist/src/tools/web-search.test.js.map +1 -1
  553. package/dist/src/tools/write-file.d.ts +4 -3
  554. package/dist/src/tools/write-file.js +17 -18
  555. package/dist/src/tools/write-file.js.map +1 -1
  556. package/dist/src/tools/write-file.test.js +108 -24
  557. package/dist/src/tools/write-file.test.js.map +1 -1
  558. package/dist/src/tools/write-todos.d.ts +25 -0
  559. package/dist/src/tools/write-todos.js +150 -0
  560. package/dist/src/tools/write-todos.js.map +1 -0
  561. package/dist/src/tools/write-todos.test.d.ts +6 -0
  562. package/dist/src/tools/write-todos.test.js +89 -0
  563. package/dist/src/tools/write-todos.test.js.map +1 -0
  564. package/dist/src/utils/bfsFileSearch.d.ts +2 -2
  565. package/dist/src/utils/bfsFileSearch.js +13 -7
  566. package/dist/src/utils/bfsFileSearch.js.map +1 -1
  567. package/dist/src/utils/bfsFileSearch.test.js +3 -3
  568. package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
  569. package/dist/src/utils/editCorrector.d.ts +9 -8
  570. package/dist/src/utils/editCorrector.js +62 -19
  571. package/dist/src/utils/editCorrector.js.map +1 -1
  572. package/dist/src/utils/editCorrector.test.js +33 -82
  573. package/dist/src/utils/editCorrector.test.js.map +1 -1
  574. package/dist/src/utils/editor.js +32 -45
  575. package/dist/src/utils/editor.js.map +1 -1
  576. package/dist/src/utils/editor.test.js +62 -76
  577. package/dist/src/utils/editor.test.js.map +1 -1
  578. package/dist/src/utils/environmentContext.d.ts +2 -2
  579. package/dist/src/utils/errorParsing.js +2 -2
  580. package/dist/src/utils/errorParsing.js.map +1 -1
  581. package/dist/src/utils/errorParsing.test.js +7 -7
  582. package/dist/src/utils/errorParsing.test.js.map +1 -1
  583. package/dist/src/utils/errorReporting.d.ts +1 -1
  584. package/dist/src/utils/errors.d.ts +25 -0
  585. package/dist/src/utils/errors.js +42 -0
  586. package/dist/src/utils/errors.js.map +1 -1
  587. package/dist/src/utils/fetch.js +1 -1
  588. package/dist/src/utils/fetch.js.map +1 -1
  589. package/dist/src/utils/fileUtils.d.ts +24 -12
  590. package/dist/src/utils/fileUtils.js +170 -79
  591. package/dist/src/utils/fileUtils.js.map +1 -1
  592. package/dist/src/utils/fileUtils.test.js +347 -29
  593. package/dist/src/utils/fileUtils.test.js.map +1 -1
  594. package/dist/src/utils/filesearch/crawler.d.ts +1 -1
  595. package/dist/src/utils/filesearch/crawler.test.js +2 -2
  596. package/dist/src/utils/filesearch/crawler.test.js.map +1 -1
  597. package/dist/src/utils/filesearch/fileSearch.d.ts +1 -0
  598. package/dist/src/utils/filesearch/fileSearch.js +14 -9
  599. package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
  600. package/dist/src/utils/filesearch/fileSearch.test.js +90 -0
  601. package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -1
  602. package/dist/src/utils/flashFallback.test.d.ts +6 -0
  603. package/dist/src/utils/{flashFallback.integration.test.js → flashFallback.test.js} +33 -29
  604. package/dist/src/utils/flashFallback.test.js.map +1 -0
  605. package/dist/src/utils/geminiIgnoreParser.d.ts +18 -0
  606. package/dist/src/utils/geminiIgnoreParser.js +61 -0
  607. package/dist/src/utils/geminiIgnoreParser.js.map +1 -0
  608. package/dist/src/utils/geminiIgnoreParser.test.d.ts +6 -0
  609. package/dist/src/utils/geminiIgnoreParser.test.js +50 -0
  610. package/dist/src/utils/geminiIgnoreParser.test.js.map +1 -0
  611. package/dist/src/utils/generateContentResponseUtilities.d.ts +1 -2
  612. package/dist/src/utils/generateContentResponseUtilities.js +1 -13
  613. package/dist/src/utils/generateContentResponseUtilities.js.map +1 -1
  614. package/dist/src/utils/generateContentResponseUtilities.test.js +2 -40
  615. package/dist/src/utils/generateContentResponseUtilities.test.js.map +1 -1
  616. package/dist/src/utils/getFolderStructure.d.ts +2 -2
  617. package/dist/src/utils/getFolderStructure.js +3 -3
  618. package/dist/src/utils/getFolderStructure.js.map +1 -1
  619. package/dist/src/utils/getFolderStructure.test.js +4 -4
  620. package/dist/src/utils/getFolderStructure.test.js.map +1 -1
  621. package/dist/src/utils/gitIgnoreParser.d.ts +3 -7
  622. package/dist/src/utils/gitIgnoreParser.js +126 -35
  623. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  624. package/dist/src/utils/gitIgnoreParser.test.js +69 -38
  625. package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
  626. package/dist/src/utils/gitUtils.js +2 -2
  627. package/dist/src/utils/gitUtils.js.map +1 -1
  628. package/dist/src/utils/ignorePatterns.d.ts +103 -0
  629. package/dist/src/utils/ignorePatterns.js +220 -0
  630. package/dist/src/utils/ignorePatterns.js.map +1 -0
  631. package/dist/src/utils/ignorePatterns.test.d.ts +6 -0
  632. package/dist/src/utils/ignorePatterns.test.js +250 -0
  633. package/dist/src/utils/ignorePatterns.test.js.map +1 -0
  634. package/dist/src/utils/installationManager.d.ts +16 -0
  635. package/dist/src/utils/installationManager.js +50 -0
  636. package/dist/src/utils/installationManager.js.map +1 -0
  637. package/dist/src/utils/installationManager.test.d.ts +6 -0
  638. package/dist/src/utils/installationManager.test.js +83 -0
  639. package/dist/src/utils/installationManager.test.js.map +1 -0
  640. package/dist/src/utils/language-detection.d.ts +6 -0
  641. package/dist/src/utils/language-detection.js +101 -0
  642. package/dist/src/utils/language-detection.js.map +1 -0
  643. package/dist/src/utils/llm-edit-fixer.d.ts +26 -0
  644. package/dist/src/utils/llm-edit-fixer.js +131 -0
  645. package/dist/src/utils/llm-edit-fixer.js.map +1 -0
  646. package/dist/src/utils/llm-edit-fixer.test.d.ts +6 -0
  647. package/dist/src/utils/llm-edit-fixer.test.js +186 -0
  648. package/dist/src/utils/llm-edit-fixer.test.js.map +1 -0
  649. package/dist/src/utils/memoryDiscovery.d.ts +7 -6
  650. package/dist/src/utils/memoryDiscovery.js +68 -33
  651. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  652. package/dist/src/utils/memoryDiscovery.test.js +88 -26
  653. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  654. package/dist/src/utils/memoryImportProcessor.js +15 -22
  655. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  656. package/dist/src/utils/memoryImportProcessor.test.js +16 -141
  657. package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
  658. package/dist/src/utils/messageInspectors.d.ts +1 -1
  659. package/dist/src/utils/nextSpeakerChecker.d.ts +3 -3
  660. package/dist/src/utils/nextSpeakerChecker.js +8 -2
  661. package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
  662. package/dist/src/utils/nextSpeakerChecker.test.js +75 -64
  663. package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
  664. package/dist/src/utils/partUtils.d.ts +22 -1
  665. package/dist/src/utils/partUtils.js +68 -0
  666. package/dist/src/utils/partUtils.js.map +1 -1
  667. package/dist/src/utils/partUtils.test.js +112 -1
  668. package/dist/src/utils/partUtils.test.js.map +1 -1
  669. package/dist/src/utils/pathReader.d.ts +17 -0
  670. package/dist/src/utils/pathReader.js +92 -0
  671. package/dist/src/utils/pathReader.js.map +1 -0
  672. package/dist/src/utils/pathReader.test.d.ts +6 -0
  673. package/dist/src/utils/pathReader.test.js +363 -0
  674. package/dist/src/utils/pathReader.test.js.map +1 -0
  675. package/dist/src/utils/paths.d.ts +0 -17
  676. package/dist/src/utils/paths.js +2 -28
  677. package/dist/src/utils/paths.js.map +1 -1
  678. package/dist/src/utils/promptIdContext.d.ts +7 -0
  679. package/dist/src/utils/promptIdContext.js +8 -0
  680. package/dist/src/utils/promptIdContext.js.map +1 -0
  681. package/dist/src/utils/quotaErrorDetection.d.ts +1 -1
  682. package/dist/src/utils/retry.d.ts +3 -1
  683. package/dist/src/utils/retry.js +60 -5
  684. package/dist/src/utils/retry.js.map +1 -1
  685. package/dist/src/utils/retry.test.js +35 -3
  686. package/dist/src/utils/retry.test.js.map +1 -1
  687. package/dist/src/utils/schemaValidator.js +15 -1
  688. package/dist/src/utils/schemaValidator.js.map +1 -1
  689. package/dist/src/utils/schemaValidator.test.d.ts +6 -0
  690. package/dist/src/utils/schemaValidator.test.js +113 -0
  691. package/dist/src/utils/schemaValidator.test.js.map +1 -0
  692. package/dist/src/utils/session.js +1 -1
  693. package/dist/src/utils/session.js.map +1 -1
  694. package/dist/src/utils/shell-utils.d.ts +6 -1
  695. package/dist/src/utils/shell-utils.js +51 -30
  696. package/dist/src/utils/shell-utils.js.map +1 -1
  697. package/dist/src/utils/shell-utils.test.js +9 -0
  698. package/dist/src/utils/shell-utils.test.js.map +1 -1
  699. package/dist/src/utils/summarizer.d.ts +2 -2
  700. package/dist/src/utils/summarizer.test.js.map +1 -1
  701. package/dist/src/utils/systemEncoding.js +2 -2
  702. package/dist/src/utils/systemEncoding.js.map +1 -1
  703. package/dist/src/utils/systemEncoding.test.js +2 -2
  704. package/dist/src/utils/systemEncoding.test.js.map +1 -1
  705. package/dist/src/utils/terminalSerializer.d.ts +25 -0
  706. package/dist/src/utils/terminalSerializer.js +432 -0
  707. package/dist/src/utils/terminalSerializer.js.map +1 -0
  708. package/dist/src/utils/terminalSerializer.test.d.ts +6 -0
  709. package/dist/src/utils/terminalSerializer.test.js +176 -0
  710. package/dist/src/utils/terminalSerializer.test.js.map +1 -0
  711. package/dist/src/utils/textUtils.d.ts +5 -0
  712. package/dist/src/utils/textUtils.js +14 -0
  713. package/dist/src/utils/textUtils.js.map +1 -1
  714. package/dist/src/utils/textUtils.test.d.ts +6 -0
  715. package/dist/src/utils/textUtils.test.js +59 -0
  716. package/dist/src/utils/textUtils.test.js.map +1 -0
  717. package/dist/src/utils/thoughtUtils.d.ts +21 -0
  718. package/dist/src/utils/thoughtUtils.js +39 -0
  719. package/dist/src/utils/thoughtUtils.js.map +1 -0
  720. package/dist/src/utils/thoughtUtils.test.d.ts +6 -0
  721. package/dist/src/utils/thoughtUtils.test.js +78 -0
  722. package/dist/src/utils/thoughtUtils.test.js.map +1 -0
  723. package/dist/src/utils/tool-utils.d.ts +19 -0
  724. package/dist/src/utils/tool-utils.js +58 -0
  725. package/dist/src/utils/tool-utils.js.map +1 -0
  726. package/dist/src/utils/tool-utils.test.d.ts +6 -0
  727. package/dist/src/utils/tool-utils.test.js +61 -0
  728. package/dist/src/utils/tool-utils.test.js.map +1 -0
  729. package/dist/src/utils/userAccountManager.d.ts +20 -0
  730. package/dist/src/utils/userAccountManager.js +114 -0
  731. package/dist/src/utils/userAccountManager.js.map +1 -0
  732. package/dist/src/utils/userAccountManager.test.d.ts +6 -0
  733. package/dist/src/utils/{user_account.test.js → userAccountManager.test.js} +33 -30
  734. package/dist/src/utils/userAccountManager.test.js.map +1 -0
  735. package/dist/src/utils/workspaceContext.js +13 -7
  736. package/dist/src/utils/workspaceContext.js.map +1 -1
  737. package/dist/src/utils/workspaceContext.test.js +41 -16
  738. package/dist/src/utils/workspaceContext.test.js.map +1 -1
  739. package/dist/tsconfig.tsbuildinfo +1 -1
  740. package/package.json +18 -9
  741. package/dist/src/core/modelCheck.d.ts +0 -14
  742. package/dist/src/core/modelCheck.js +0 -62
  743. package/dist/src/core/modelCheck.js.map +0 -1
  744. package/dist/src/test-utils/tools.d.ts +0 -44
  745. package/dist/src/test-utils/tools.js.map +0 -1
  746. package/dist/src/utils/flashFallback.integration.test.js.map +0 -1
  747. package/dist/src/utils/user_account.d.ts +0 -9
  748. package/dist/src/utils/user_account.js +0 -109
  749. package/dist/src/utils/user_account.js.map +0 -1
  750. package/dist/src/utils/user_account.test.js.map +0 -1
  751. package/dist/src/utils/user_id.d.ts +0 -11
  752. package/dist/src/utils/user_id.js +0 -49
  753. package/dist/src/utils/user_id.js.map +0 -1
  754. package/dist/src/utils/user_id.test.js +0 -21
  755. package/dist/src/utils/user_id.test.js.map +0 -1
  756. /package/dist/src/{utils/flashFallback.integration.test.d.ts → agents/executor.test.d.ts} +0 -0
  757. /package/dist/src/{utils/user_account.test.d.ts → agents/invocation.test.d.ts} +0 -0
  758. /package/dist/src/{utils/user_id.test.d.ts → agents/registry.test.d.ts} +0 -0
@@ -3,10 +3,15 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { describe, it, expect, vi } from 'vitest';
7
- import { CoreToolScheduler, convertToFunctionResponse, } from './coreToolScheduler.js';
8
- import { BaseDeclarativeTool, BaseToolInvocation, ToolConfirmationOutcome, Kind, ApprovalMode, } from '../index.js';
9
- import { MockModifiableTool, MockTool } from '../test-utils/tools.js';
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, } from '../index.js';
9
+ import { MockModifiableTool, MockTool, MOCK_TOOL_SHOULD_CONFIRM_EXECUTE, } from '../test-utils/mock-tool.js';
10
+ import * as fs from 'node:fs/promises';
11
+ import * as path from 'node:path';
12
+ vi.mock('fs/promises', () => ({
13
+ writeFile: vi.fn(),
14
+ }));
10
15
  class TestApprovalTool extends BaseDeclarativeTool {
11
16
  config;
12
17
  static Name = 'testApprovalTool';
@@ -58,10 +63,70 @@ class TestApprovalInvocation extends BaseToolInvocation {
58
63
  };
59
64
  }
60
65
  }
66
+ class AbortDuringConfirmationInvocation extends BaseToolInvocation {
67
+ abortController;
68
+ abortError;
69
+ constructor(abortController, abortError, params) {
70
+ super(params);
71
+ this.abortController = abortController;
72
+ this.abortError = abortError;
73
+ }
74
+ async shouldConfirmExecute(_signal) {
75
+ this.abortController.abort();
76
+ throw this.abortError;
77
+ }
78
+ async execute(_abortSignal) {
79
+ throw new Error('execute should not be called when confirmation fails');
80
+ }
81
+ getDescription() {
82
+ return 'Abort during confirmation invocation';
83
+ }
84
+ }
85
+ class AbortDuringConfirmationTool extends BaseDeclarativeTool {
86
+ abortController;
87
+ abortError;
88
+ constructor(abortController, abortError) {
89
+ super('abortDuringConfirmationTool', 'Abort During Confirmation Tool', 'A tool that aborts while confirming execution.', Kind.Other, {
90
+ type: 'object',
91
+ properties: {},
92
+ });
93
+ this.abortController = abortController;
94
+ this.abortError = abortError;
95
+ }
96
+ createInvocation(params) {
97
+ return new AbortDuringConfirmationInvocation(this.abortController, this.abortError, params);
98
+ }
99
+ }
100
+ async function waitForStatus(onToolCallsUpdate, status, timeout = 5000) {
101
+ return new Promise((resolve, reject) => {
102
+ const startTime = Date.now();
103
+ const check = () => {
104
+ if (Date.now() - startTime > timeout) {
105
+ const seenStatuses = onToolCallsUpdate.mock.calls
106
+ .flatMap((call) => call[0])
107
+ .map((toolCall) => toolCall.status);
108
+ reject(new Error(`Timed out waiting for status "${status}". Seen statuses: ${seenStatuses.join(', ')}`));
109
+ return;
110
+ }
111
+ const foundCall = onToolCallsUpdate.mock.calls
112
+ .flatMap((call) => call[0])
113
+ .find((toolCall) => toolCall.status === status);
114
+ if (foundCall) {
115
+ resolve(foundCall);
116
+ }
117
+ else {
118
+ setTimeout(check, 10); // Check again in 10ms
119
+ }
120
+ };
121
+ check();
122
+ });
123
+ }
61
124
  describe('CoreToolScheduler', () => {
62
125
  it('should cancel a tool call if the signal is aborted before confirmation', async () => {
63
- const mockTool = new MockTool();
64
- mockTool.shouldConfirm = true;
126
+ const mockTool = new MockTool({
127
+ name: 'mockTool',
128
+ shouldConfirmExecute: MOCK_TOOL_SHOULD_CONFIRM_EXECUTE,
129
+ });
65
130
  const declarativeTool = mockTool;
66
131
  const mockToolRegistry = {
67
132
  getTool: () => declarativeTool,
@@ -83,14 +148,27 @@ describe('CoreToolScheduler', () => {
83
148
  getUsageStatisticsEnabled: () => true,
84
149
  getDebugMode: () => false,
85
150
  getApprovalMode: () => ApprovalMode.DEFAULT,
151
+ getAllowedTools: () => [],
86
152
  getContentGeneratorConfig: () => ({
87
153
  model: 'test-model',
88
154
  authType: 'oauth-personal',
89
155
  }),
156
+ getShellExecutionConfig: () => ({
157
+ terminalWidth: 90,
158
+ terminalHeight: 30,
159
+ }),
160
+ storage: {
161
+ getProjectTempDir: () => '/tmp',
162
+ },
163
+ getTruncateToolOutputThreshold: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
164
+ getTruncateToolOutputLines: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
165
+ getToolRegistry: () => mockToolRegistry,
166
+ getUseSmartEdit: () => false,
167
+ getUseModelRouter: () => false,
168
+ getGeminiClient: () => null, // No client needed for these tests
90
169
  };
91
170
  const scheduler = new CoreToolScheduler({
92
171
  config: mockConfig,
93
- toolRegistry: mockToolRegistry,
94
172
  onAllToolCallsComplete,
95
173
  onToolCallsUpdate,
96
174
  getPreferredEditor: () => 'vscode',
@@ -111,10 +189,108 @@ describe('CoreToolScheduler', () => {
111
189
  .calls[0][0];
112
190
  expect(completedCalls[0].status).toBe('cancelled');
113
191
  });
192
+ it('should mark tool call as cancelled when abort happens during confirmation error', async () => {
193
+ const abortController = new AbortController();
194
+ const abortError = new Error('Abort requested during confirmation');
195
+ const declarativeTool = new AbortDuringConfirmationTool(abortController, abortError);
196
+ const mockToolRegistry = {
197
+ getTool: () => declarativeTool,
198
+ getFunctionDeclarations: () => [],
199
+ tools: new Map(),
200
+ discovery: {},
201
+ registerTool: () => { },
202
+ getToolByName: () => declarativeTool,
203
+ getToolByDisplayName: () => declarativeTool,
204
+ getTools: () => [],
205
+ discoverTools: async () => { },
206
+ getAllTools: () => [],
207
+ getToolsByServer: () => [],
208
+ };
209
+ const onAllToolCallsComplete = vi.fn();
210
+ const onToolCallsUpdate = vi.fn();
211
+ const mockConfig = {
212
+ getSessionId: () => 'test-session-id',
213
+ getUsageStatisticsEnabled: () => true,
214
+ getDebugMode: () => false,
215
+ getApprovalMode: () => ApprovalMode.DEFAULT,
216
+ getAllowedTools: () => [],
217
+ getContentGeneratorConfig: () => ({
218
+ model: 'test-model',
219
+ authType: 'oauth-personal',
220
+ }),
221
+ getShellExecutionConfig: () => ({
222
+ terminalWidth: 90,
223
+ terminalHeight: 30,
224
+ }),
225
+ storage: {
226
+ getProjectTempDir: () => '/tmp',
227
+ },
228
+ getTruncateToolOutputThreshold: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
229
+ getTruncateToolOutputLines: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
230
+ getToolRegistry: () => mockToolRegistry,
231
+ getUseSmartEdit: () => false,
232
+ getUseModelRouter: () => false,
233
+ getGeminiClient: () => null,
234
+ };
235
+ const scheduler = new CoreToolScheduler({
236
+ config: mockConfig,
237
+ onAllToolCallsComplete,
238
+ onToolCallsUpdate,
239
+ getPreferredEditor: () => 'vscode',
240
+ onEditorClose: vi.fn(),
241
+ });
242
+ const request = {
243
+ callId: 'abort-1',
244
+ name: 'abortDuringConfirmationTool',
245
+ args: {},
246
+ isClientInitiated: false,
247
+ prompt_id: 'prompt-id-abort',
248
+ };
249
+ await scheduler.schedule([request], abortController.signal);
250
+ expect(onAllToolCallsComplete).toHaveBeenCalled();
251
+ const completedCalls = onAllToolCallsComplete.mock
252
+ .calls[0][0];
253
+ expect(completedCalls[0].status).toBe('cancelled');
254
+ const statuses = onToolCallsUpdate.mock.calls.flatMap((call) => call[0].map((toolCall) => toolCall.status));
255
+ expect(statuses).not.toContain('error');
256
+ });
257
+ describe('getToolSuggestion', () => {
258
+ it('should suggest the top N closest tool names for a typo', () => {
259
+ // Create mocked tool registry
260
+ const mockConfig = {
261
+ getToolRegistry: () => mockToolRegistry,
262
+ getUseSmartEdit: () => false,
263
+ getUseModelRouter: () => false,
264
+ getGeminiClient: () => null, // No client needed for these tests
265
+ };
266
+ const mockToolRegistry = {
267
+ getAllToolNames: () => ['list_files', 'read_file', 'write_file'],
268
+ };
269
+ // Create scheduler
270
+ const scheduler = new CoreToolScheduler({
271
+ config: mockConfig,
272
+ getPreferredEditor: () => 'vscode',
273
+ onEditorClose: vi.fn(),
274
+ });
275
+ // Test that the right tool is selected, with only 1 result, for typos
276
+ // @ts-expect-error accessing private method
277
+ const misspelledTool = scheduler.getToolSuggestion('list_fils', 1);
278
+ expect(misspelledTool).toBe(' Did you mean "list_files"?');
279
+ // Test that the right tool is selected, with only 1 result, for prefixes
280
+ // @ts-expect-error accessing private method
281
+ const prefixedTool = scheduler.getToolSuggestion('github.list_files', 1);
282
+ expect(prefixedTool).toBe(' Did you mean "list_files"?');
283
+ // Test that the right tool is first
284
+ // @ts-expect-error accessing private method
285
+ const suggestionMultiple = scheduler.getToolSuggestion('list_fils');
286
+ expect(suggestionMultiple).toBe(' Did you mean one of: "list_files", "read_file", "write_file"?');
287
+ });
288
+ });
114
289
  });
115
290
  describe('CoreToolScheduler with payload', () => {
116
291
  it('should update args and diff and execute tool when payload is provided', async () => {
117
292
  const mockTool = new MockModifiableTool();
293
+ mockTool.executeFn = vi.fn();
118
294
  const declarativeTool = mockTool;
119
295
  const mockToolRegistry = {
120
296
  getTool: () => declarativeTool,
@@ -136,14 +312,27 @@ describe('CoreToolScheduler with payload', () => {
136
312
  getUsageStatisticsEnabled: () => true,
137
313
  getDebugMode: () => false,
138
314
  getApprovalMode: () => ApprovalMode.DEFAULT,
315
+ getAllowedTools: () => [],
139
316
  getContentGeneratorConfig: () => ({
140
317
  model: 'test-model',
141
318
  authType: 'oauth-personal',
142
319
  }),
320
+ getShellExecutionConfig: () => ({
321
+ terminalWidth: 90,
322
+ terminalHeight: 30,
323
+ }),
324
+ storage: {
325
+ getProjectTempDir: () => '/tmp',
326
+ },
327
+ getTruncateToolOutputThreshold: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
328
+ getTruncateToolOutputLines: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
329
+ getToolRegistry: () => mockToolRegistry,
330
+ getUseSmartEdit: () => false,
331
+ getUseModelRouter: () => false,
332
+ getGeminiClient: () => null, // No client needed for these tests
143
333
  };
144
334
  const scheduler = new CoreToolScheduler({
145
335
  config: mockConfig,
146
- toolRegistry: mockToolRegistry,
147
336
  onAllToolCallsComplete,
148
337
  onToolCallsUpdate,
149
338
  getPreferredEditor: () => 'vscode',
@@ -158,17 +347,16 @@ describe('CoreToolScheduler with payload', () => {
158
347
  prompt_id: 'prompt-id-2',
159
348
  };
160
349
  await scheduler.schedule([request], abortController.signal);
161
- await vi.waitFor(() => {
162
- const awaitingCall = onToolCallsUpdate.mock.calls.find((call) => call[0][0].status === 'awaiting_approval')?.[0][0];
163
- expect(awaitingCall).toBeDefined();
164
- });
165
- const awaitingCall = onToolCallsUpdate.mock.calls.find((call) => call[0][0].status === 'awaiting_approval')?.[0][0];
350
+ const awaitingCall = (await waitForStatus(onToolCallsUpdate, 'awaiting_approval'));
166
351
  const confirmationDetails = awaitingCall.confirmationDetails;
167
352
  if (confirmationDetails) {
168
353
  const payload = { newContent: 'final version' };
169
354
  await confirmationDetails.onConfirm(ToolConfirmationOutcome.ProceedOnce, payload);
170
355
  }
171
- expect(onAllToolCallsComplete).toHaveBeenCalled();
356
+ // Wait for the tool execution to complete
357
+ await vi.waitFor(() => {
358
+ expect(onAllToolCallsComplete).toHaveBeenCalled();
359
+ });
172
360
  const completedCalls = onAllToolCallsComplete.mock
173
361
  .calls[0][0];
174
362
  expect(completedCalls[0].status).toBe('success');
@@ -183,35 +371,41 @@ describe('convertToFunctionResponse', () => {
183
371
  it('should handle simple string llmContent', () => {
184
372
  const llmContent = 'Simple text output';
185
373
  const result = convertToFunctionResponse(toolName, callId, llmContent);
186
- expect(result).toEqual({
187
- functionResponse: {
188
- name: toolName,
189
- id: callId,
190
- response: { output: 'Simple text output' },
374
+ expect(result).toEqual([
375
+ {
376
+ functionResponse: {
377
+ name: toolName,
378
+ id: callId,
379
+ response: { output: 'Simple text output' },
380
+ },
191
381
  },
192
- });
382
+ ]);
193
383
  });
194
384
  it('should handle llmContent as a single Part with text', () => {
195
385
  const llmContent = { text: 'Text from Part object' };
196
386
  const result = convertToFunctionResponse(toolName, callId, llmContent);
197
- expect(result).toEqual({
198
- functionResponse: {
199
- name: toolName,
200
- id: callId,
201
- response: { output: 'Text from Part object' },
387
+ expect(result).toEqual([
388
+ {
389
+ functionResponse: {
390
+ name: toolName,
391
+ id: callId,
392
+ response: { output: 'Text from Part object' },
393
+ },
202
394
  },
203
- });
395
+ ]);
204
396
  });
205
397
  it('should handle llmContent as a PartListUnion array with a single text Part', () => {
206
398
  const llmContent = [{ text: 'Text from array' }];
207
399
  const result = convertToFunctionResponse(toolName, callId, llmContent);
208
- expect(result).toEqual({
209
- functionResponse: {
210
- name: toolName,
211
- id: callId,
212
- response: { output: 'Text from array' },
400
+ expect(result).toEqual([
401
+ {
402
+ functionResponse: {
403
+ name: toolName,
404
+ id: callId,
405
+ response: { output: 'Text from array' },
406
+ },
213
407
  },
214
- });
408
+ ]);
215
409
  });
216
410
  it('should handle llmContent with inlineData', () => {
217
411
  const llmContent = {
@@ -288,24 +482,28 @@ describe('convertToFunctionResponse', () => {
288
482
  it('should handle llmContent as a generic Part (not text, inlineData, or fileData)', () => {
289
483
  const llmContent = { functionCall: { name: 'test', args: {} } };
290
484
  const result = convertToFunctionResponse(toolName, callId, llmContent);
291
- expect(result).toEqual({
292
- functionResponse: {
293
- name: toolName,
294
- id: callId,
295
- response: { output: 'Tool execution succeeded.' },
485
+ expect(result).toEqual([
486
+ {
487
+ functionResponse: {
488
+ name: toolName,
489
+ id: callId,
490
+ response: { output: 'Tool execution succeeded.' },
491
+ },
296
492
  },
297
- });
493
+ ]);
298
494
  });
299
495
  it('should handle empty string llmContent', () => {
300
496
  const llmContent = '';
301
497
  const result = convertToFunctionResponse(toolName, callId, llmContent);
302
- expect(result).toEqual({
303
- functionResponse: {
304
- name: toolName,
305
- id: callId,
306
- response: { output: '' },
498
+ expect(result).toEqual([
499
+ {
500
+ functionResponse: {
501
+ name: toolName,
502
+ id: callId,
503
+ response: { output: '' },
504
+ },
307
505
  },
308
- });
506
+ ]);
309
507
  });
310
508
  it('should handle llmContent as an empty array', () => {
311
509
  const llmContent = [];
@@ -323,13 +521,15 @@ describe('convertToFunctionResponse', () => {
323
521
  it('should handle llmContent as a Part with undefined inlineData/fileData/text', () => {
324
522
  const llmContent = {}; // An empty part object
325
523
  const result = convertToFunctionResponse(toolName, callId, llmContent);
326
- expect(result).toEqual({
327
- functionResponse: {
328
- name: toolName,
329
- id: callId,
330
- response: { output: 'Tool execution succeeded.' },
524
+ expect(result).toEqual([
525
+ {
526
+ functionResponse: {
527
+ name: toolName,
528
+ id: callId,
529
+ response: { output: 'Tool execution succeeded.' },
530
+ },
331
531
  },
332
- });
532
+ ]);
333
533
  });
334
534
  });
335
535
  class MockEditToolInvocation extends BaseToolInvocation {
@@ -369,15 +569,14 @@ class MockEditTool extends BaseDeclarativeTool {
369
569
  describe('CoreToolScheduler edit cancellation', () => {
370
570
  it('should preserve diff when an edit is cancelled', async () => {
371
571
  const mockEditTool = new MockEditTool();
372
- const declarativeTool = mockEditTool;
373
572
  const mockToolRegistry = {
374
- getTool: () => declarativeTool,
573
+ getTool: () => mockEditTool,
375
574
  getFunctionDeclarations: () => [],
376
575
  tools: new Map(),
377
576
  discovery: {},
378
577
  registerTool: () => { },
379
- getToolByName: () => declarativeTool,
380
- getToolByDisplayName: () => declarativeTool,
578
+ getToolByName: () => mockEditTool,
579
+ getToolByDisplayName: () => mockEditTool,
381
580
  getTools: () => [],
382
581
  discoverTools: async () => { },
383
582
  getAllTools: () => [],
@@ -390,14 +589,25 @@ describe('CoreToolScheduler edit cancellation', () => {
390
589
  getUsageStatisticsEnabled: () => true,
391
590
  getDebugMode: () => false,
392
591
  getApprovalMode: () => ApprovalMode.DEFAULT,
592
+ getAllowedTools: () => [],
393
593
  getContentGeneratorConfig: () => ({
394
594
  model: 'test-model',
395
595
  authType: 'oauth-personal',
396
596
  }),
597
+ getShellExecutionConfig: () => ({
598
+ terminalWidth: 90,
599
+ terminalHeight: 30,
600
+ }),
601
+ storage: {
602
+ getProjectTempDir: () => '/tmp',
603
+ },
604
+ getToolRegistry: () => mockToolRegistry,
605
+ getUseSmartEdit: () => false,
606
+ getUseModelRouter: () => false,
607
+ getGeminiClient: () => null, // No client needed for these tests
397
608
  };
398
609
  const scheduler = new CoreToolScheduler({
399
610
  config: mockConfig,
400
- toolRegistry: mockToolRegistry,
401
611
  onAllToolCallsComplete,
402
612
  onToolCallsUpdate,
403
613
  getPreferredEditor: () => 'vscode',
@@ -412,9 +622,7 @@ describe('CoreToolScheduler edit cancellation', () => {
412
622
  prompt_id: 'prompt-id-1',
413
623
  };
414
624
  await scheduler.schedule([request], abortController.signal);
415
- // Wait for the tool to reach awaiting_approval state
416
- const awaitingCall = onToolCallsUpdate.mock.calls.find((call) => call[0][0].status === 'awaiting_approval')?.[0][0];
417
- expect(awaitingCall).toBeDefined();
625
+ const awaitingCall = (await waitForStatus(onToolCallsUpdate, 'awaiting_approval'));
418
626
  // Cancel the edit
419
627
  const confirmationDetails = awaitingCall.confirmationDetails;
420
628
  if (confirmationDetails) {
@@ -435,13 +643,15 @@ describe('CoreToolScheduler edit cancellation', () => {
435
643
  describe('CoreToolScheduler YOLO mode', () => {
436
644
  it('should execute tool requiring confirmation directly without waiting', async () => {
437
645
  // Arrange
438
- const mockTool = new MockTool();
439
- mockTool.executeFn.mockReturnValue({
646
+ const executeFn = vi.fn().mockResolvedValue({
440
647
  llmContent: 'Tool executed',
441
648
  returnDisplay: 'Tool executed',
442
649
  });
443
- // This tool would normally require confirmation.
444
- mockTool.shouldConfirm = true;
650
+ const mockTool = new MockTool({
651
+ name: 'mockTool',
652
+ execute: executeFn,
653
+ shouldConfirmExecute: MOCK_TOOL_SHOULD_CONFIRM_EXECUTE,
654
+ });
445
655
  const declarativeTool = mockTool;
446
656
  const mockToolRegistry = {
447
657
  getTool: () => declarativeTool,
@@ -465,14 +675,27 @@ describe('CoreToolScheduler YOLO mode', () => {
465
675
  getUsageStatisticsEnabled: () => true,
466
676
  getDebugMode: () => false,
467
677
  getApprovalMode: () => ApprovalMode.YOLO,
678
+ getAllowedTools: () => [],
468
679
  getContentGeneratorConfig: () => ({
469
680
  model: 'test-model',
470
681
  authType: 'oauth-personal',
471
682
  }),
683
+ getShellExecutionConfig: () => ({
684
+ terminalWidth: 90,
685
+ terminalHeight: 30,
686
+ }),
687
+ storage: {
688
+ getProjectTempDir: () => '/tmp',
689
+ },
690
+ getToolRegistry: () => mockToolRegistry,
691
+ getTruncateToolOutputThreshold: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
692
+ getTruncateToolOutputLines: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
693
+ getUseSmartEdit: () => false,
694
+ getUseModelRouter: () => false,
695
+ getGeminiClient: () => null, // No client needed for these tests
472
696
  };
473
697
  const scheduler = new CoreToolScheduler({
474
698
  config: mockConfig,
475
- toolRegistry: mockToolRegistry,
476
699
  onAllToolCallsComplete,
477
700
  onToolCallsUpdate,
478
701
  getPreferredEditor: () => 'vscode',
@@ -488,9 +711,13 @@ describe('CoreToolScheduler YOLO mode', () => {
488
711
  };
489
712
  // Act
490
713
  await scheduler.schedule([request], abortController.signal);
714
+ // Wait for the tool execution to complete
715
+ await vi.waitFor(() => {
716
+ expect(onAllToolCallsComplete).toHaveBeenCalled();
717
+ });
491
718
  // Assert
492
719
  // 1. The tool's execute method was called directly.
493
- expect(mockTool.executeFn).toHaveBeenCalledWith({ param: 'value' });
720
+ expect(executeFn).toHaveBeenCalledWith({ param: 'value' });
494
721
  // 2. The tool call status never entered 'awaiting_approval'.
495
722
  const statusUpdates = onToolCallsUpdate.mock.calls
496
723
  .map((call) => call[0][0]?.status)
@@ -503,7 +730,6 @@ describe('CoreToolScheduler YOLO mode', () => {
503
730
  'success',
504
731
  ]);
505
732
  // 3. The final callback indicates the tool call was successful.
506
- expect(onAllToolCallsComplete).toHaveBeenCalled();
507
733
  const completedCalls = onAllToolCallsComplete.mock
508
734
  .calls[0][0];
509
735
  expect(completedCalls).toHaveLength(1);
@@ -520,8 +746,8 @@ describe('CoreToolScheduler request queueing', () => {
520
746
  const firstCallPromise = new Promise((resolve) => {
521
747
  resolveFirstCall = resolve;
522
748
  });
523
- const mockTool = new MockTool();
524
- mockTool.executeFn.mockImplementation(() => firstCallPromise);
749
+ const executeFn = vi.fn().mockImplementation(() => firstCallPromise);
750
+ const mockTool = new MockTool({ name: 'mockTool', execute: executeFn });
525
751
  const declarativeTool = mockTool;
526
752
  const mockToolRegistry = {
527
753
  getTool: () => declarativeTool,
@@ -543,14 +769,27 @@ describe('CoreToolScheduler request queueing', () => {
543
769
  getUsageStatisticsEnabled: () => true,
544
770
  getDebugMode: () => false,
545
771
  getApprovalMode: () => ApprovalMode.YOLO, // Use YOLO to avoid confirmation prompts
772
+ getAllowedTools: () => [],
546
773
  getContentGeneratorConfig: () => ({
547
774
  model: 'test-model',
548
775
  authType: 'oauth-personal',
549
776
  }),
777
+ getShellExecutionConfig: () => ({
778
+ terminalWidth: 90,
779
+ terminalHeight: 30,
780
+ }),
781
+ storage: {
782
+ getProjectTempDir: () => '/tmp',
783
+ },
784
+ getTruncateToolOutputThreshold: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
785
+ getTruncateToolOutputLines: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
786
+ getToolRegistry: () => mockToolRegistry,
787
+ getUseSmartEdit: () => false,
788
+ getUseModelRouter: () => false,
789
+ getGeminiClient: () => null, // No client needed for these tests
550
790
  };
551
791
  const scheduler = new CoreToolScheduler({
552
792
  config: mockConfig,
553
- toolRegistry: mockToolRegistry,
554
793
  onAllToolCallsComplete,
555
794
  onToolCallsUpdate,
556
795
  getPreferredEditor: () => 'vscode',
@@ -574,15 +813,11 @@ describe('CoreToolScheduler request queueing', () => {
574
813
  // Schedule the first call, which will pause execution.
575
814
  scheduler.schedule([request1], abortController.signal);
576
815
  // Wait for the first call to be in the 'executing' state.
577
- await vi.waitFor(() => {
578
- const calls = onToolCallsUpdate.mock.calls.at(-1)?.[0];
579
- expect(calls?.[0]?.status).toBe('executing');
580
- });
816
+ await waitForStatus(onToolCallsUpdate, 'executing');
581
817
  // Schedule the second call while the first is "running".
582
818
  const schedulePromise2 = scheduler.schedule([request2], abortController.signal);
583
819
  // Ensure the second tool call hasn't been executed yet.
584
- expect(mockTool.executeFn).toHaveBeenCalledTimes(1);
585
- expect(mockTool.executeFn).toHaveBeenCalledWith({ a: 1 });
820
+ expect(executeFn).toHaveBeenCalledWith({ a: 1 });
586
821
  // Complete the first tool call.
587
822
  resolveFirstCall({
588
823
  llmContent: 'First call complete',
@@ -590,14 +825,6 @@ describe('CoreToolScheduler request queueing', () => {
590
825
  });
591
826
  // Wait for the second schedule promise to resolve.
592
827
  await schedulePromise2;
593
- // Wait for the second call to be in the 'executing' state.
594
- await vi.waitFor(() => {
595
- const calls = onToolCallsUpdate.mock.calls.at(-1)?.[0];
596
- expect(calls?.[0]?.status).toBe('executing');
597
- });
598
- // Now the second tool call should have been executed.
599
- expect(mockTool.executeFn).toHaveBeenCalledTimes(2);
600
- expect(mockTool.executeFn).toHaveBeenCalledWith({ b: 2 });
601
828
  // Let the second call finish.
602
829
  const secondCallResult = {
603
830
  llmContent: 'Second call complete',
@@ -606,6 +833,11 @@ describe('CoreToolScheduler request queueing', () => {
606
833
  // Since the mock is shared, we need to resolve the current promise.
607
834
  // In a real scenario, a new promise would be created for the second call.
608
835
  resolveFirstCall(secondCallResult);
836
+ await vi.waitFor(() => {
837
+ // Now the second tool call should have been executed.
838
+ expect(executeFn).toHaveBeenCalledTimes(2);
839
+ });
840
+ expect(executeFn).toHaveBeenCalledWith({ b: 2 });
609
841
  // Wait for the second completion.
610
842
  await vi.waitFor(() => {
611
843
  expect(onAllToolCallsComplete).toHaveBeenCalledTimes(2);
@@ -614,8 +846,112 @@ describe('CoreToolScheduler request queueing', () => {
614
846
  expect(onAllToolCallsComplete.mock.calls[0][0][0].status).toBe('success');
615
847
  expect(onAllToolCallsComplete.mock.calls[1][0][0].status).toBe('success');
616
848
  });
849
+ it('should auto-approve a tool call if it is on the allowedTools list', async () => {
850
+ // Arrange
851
+ const executeFn = vi.fn().mockResolvedValue({
852
+ llmContent: 'Tool executed',
853
+ returnDisplay: 'Tool executed',
854
+ });
855
+ const mockTool = new MockTool({
856
+ name: 'mockTool',
857
+ execute: executeFn,
858
+ shouldConfirmExecute: MOCK_TOOL_SHOULD_CONFIRM_EXECUTE,
859
+ });
860
+ const declarativeTool = mockTool;
861
+ const toolRegistry = {
862
+ getTool: () => declarativeTool,
863
+ getToolByName: () => declarativeTool,
864
+ getFunctionDeclarations: () => [],
865
+ tools: new Map(),
866
+ discovery: {},
867
+ registerTool: () => { },
868
+ getToolByDisplayName: () => declarativeTool,
869
+ getTools: () => [],
870
+ discoverTools: async () => { },
871
+ getAllTools: () => [],
872
+ getToolsByServer: () => [],
873
+ };
874
+ const onAllToolCallsComplete = vi.fn();
875
+ const onToolCallsUpdate = vi.fn();
876
+ // Configure the scheduler to auto-approve the specific tool call.
877
+ const mockConfig = {
878
+ getSessionId: () => 'test-session-id',
879
+ getUsageStatisticsEnabled: () => true,
880
+ getDebugMode: () => false,
881
+ getApprovalMode: () => ApprovalMode.DEFAULT, // Not YOLO mode
882
+ getAllowedTools: () => ['mockTool'], // Auto-approve this tool
883
+ getToolRegistry: () => toolRegistry,
884
+ getContentGeneratorConfig: () => ({
885
+ model: 'test-model',
886
+ authType: 'oauth-personal',
887
+ }),
888
+ getShellExecutionConfig: () => ({
889
+ terminalWidth: 80,
890
+ terminalHeight: 24,
891
+ }),
892
+ getTerminalWidth: vi.fn(() => 80),
893
+ getTerminalHeight: vi.fn(() => 24),
894
+ storage: {
895
+ getProjectTempDir: () => '/tmp',
896
+ },
897
+ getTruncateToolOutputThreshold: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
898
+ getTruncateToolOutputLines: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
899
+ getUseSmartEdit: () => false,
900
+ getUseModelRouter: () => false,
901
+ getGeminiClient: () => null, // No client needed for these tests
902
+ };
903
+ const scheduler = new CoreToolScheduler({
904
+ config: mockConfig,
905
+ onAllToolCallsComplete,
906
+ onToolCallsUpdate,
907
+ getPreferredEditor: () => 'vscode',
908
+ onEditorClose: vi.fn(),
909
+ });
910
+ const abortController = new AbortController();
911
+ const request = {
912
+ callId: '1',
913
+ name: 'mockTool',
914
+ args: { param: 'value' },
915
+ isClientInitiated: false,
916
+ prompt_id: 'prompt-auto-approved',
917
+ };
918
+ // Act
919
+ await scheduler.schedule([request], abortController.signal);
920
+ // Wait for the tool execution to complete
921
+ await vi.waitFor(() => {
922
+ expect(onAllToolCallsComplete).toHaveBeenCalled();
923
+ });
924
+ // Assert
925
+ // 1. The tool's execute method was called directly.
926
+ expect(executeFn).toHaveBeenCalledWith({ param: 'value' });
927
+ // 2. The tool call status never entered 'awaiting_approval'.
928
+ const statusUpdates = onToolCallsUpdate.mock.calls
929
+ .map((call) => call[0][0]?.status)
930
+ .filter(Boolean);
931
+ expect(statusUpdates).not.toContain('awaiting_approval');
932
+ expect(statusUpdates).toEqual([
933
+ 'validating',
934
+ 'scheduled',
935
+ 'executing',
936
+ 'success',
937
+ ]);
938
+ // 3. The final callback indicates the tool call was successful.
939
+ expect(onAllToolCallsComplete).toHaveBeenCalled();
940
+ const completedCalls = onAllToolCallsComplete.mock
941
+ .calls[0][0];
942
+ expect(completedCalls).toHaveLength(1);
943
+ const completedCall = completedCalls[0];
944
+ expect(completedCall.status).toBe('success');
945
+ if (completedCall.status === 'success') {
946
+ expect(completedCall.response.resultDisplay).toBe('Tool executed');
947
+ }
948
+ });
617
949
  it('should handle two synchronous calls to schedule', async () => {
618
- const mockTool = new MockTool();
950
+ const executeFn = vi.fn().mockResolvedValue({
951
+ llmContent: 'Tool executed',
952
+ returnDisplay: 'Tool executed',
953
+ });
954
+ const mockTool = new MockTool({ name: 'mockTool', execute: executeFn });
619
955
  const declarativeTool = mockTool;
620
956
  const mockToolRegistry = {
621
957
  getTool: () => declarativeTool,
@@ -637,14 +973,27 @@ describe('CoreToolScheduler request queueing', () => {
637
973
  getUsageStatisticsEnabled: () => true,
638
974
  getDebugMode: () => false,
639
975
  getApprovalMode: () => ApprovalMode.YOLO,
976
+ getAllowedTools: () => [],
640
977
  getContentGeneratorConfig: () => ({
641
978
  model: 'test-model',
642
979
  authType: 'oauth-personal',
643
980
  }),
981
+ getShellExecutionConfig: () => ({
982
+ terminalWidth: 90,
983
+ terminalHeight: 30,
984
+ }),
985
+ storage: {
986
+ getProjectTempDir: () => '/tmp',
987
+ },
988
+ getTruncateToolOutputThreshold: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
989
+ getTruncateToolOutputLines: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
990
+ getToolRegistry: () => mockToolRegistry,
991
+ getUseSmartEdit: () => false,
992
+ getUseModelRouter: () => false,
993
+ getGeminiClient: () => null, // No client needed for these tests
644
994
  };
645
995
  const scheduler = new CoreToolScheduler({
646
996
  config: mockConfig,
647
- toolRegistry: mockToolRegistry,
648
997
  onAllToolCallsComplete,
649
998
  onToolCallsUpdate,
650
999
  getPreferredEditor: () => 'vscode',
@@ -671,9 +1020,9 @@ describe('CoreToolScheduler request queueing', () => {
671
1020
  // Wait for both promises to resolve.
672
1021
  await Promise.all([schedulePromise1, schedulePromise2]);
673
1022
  // Ensure the tool was called twice with the correct arguments.
674
- expect(mockTool.executeFn).toHaveBeenCalledTimes(2);
675
- expect(mockTool.executeFn).toHaveBeenCalledWith({ a: 1 });
676
- expect(mockTool.executeFn).toHaveBeenCalledWith({ b: 2 });
1023
+ expect(executeFn).toHaveBeenCalledTimes(2);
1024
+ expect(executeFn).toHaveBeenCalledWith({ a: 1 });
1025
+ expect(executeFn).toHaveBeenCalledWith({ b: 2 });
677
1026
  // Ensure completion callbacks were called twice.
678
1027
  expect(onAllToolCallsComplete).toHaveBeenCalledTimes(2);
679
1028
  });
@@ -684,9 +1033,22 @@ describe('CoreToolScheduler request queueing', () => {
684
1033
  getUsageStatisticsEnabled: () => true,
685
1034
  getDebugMode: () => false,
686
1035
  getApprovalMode: () => approvalMode,
1036
+ getAllowedTools: () => [],
687
1037
  setApprovalMode: (mode) => {
688
1038
  approvalMode = mode;
689
1039
  },
1040
+ getShellExecutionConfig: () => ({
1041
+ terminalWidth: 90,
1042
+ terminalHeight: 30,
1043
+ }),
1044
+ storage: {
1045
+ getProjectTempDir: () => '/tmp',
1046
+ },
1047
+ getTruncateToolOutputThreshold: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
1048
+ getTruncateToolOutputLines: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
1049
+ getUseSmartEdit: () => false,
1050
+ getUseModelRouter: () => false,
1051
+ getGeminiClient: () => null, // No client needed for these tests
690
1052
  };
691
1053
  const testTool = new TestApprovalTool(mockConfig);
692
1054
  const toolRegistry = {
@@ -709,12 +1071,12 @@ describe('CoreToolScheduler request queueing', () => {
709
1071
  discoverTools: async () => { },
710
1072
  discovery: {},
711
1073
  };
1074
+ mockConfig.getToolRegistry = () => toolRegistry;
712
1075
  const onAllToolCallsComplete = vi.fn();
713
1076
  const onToolCallsUpdate = vi.fn();
714
1077
  const pendingConfirmations = [];
715
1078
  const scheduler = new CoreToolScheduler({
716
1079
  config: mockConfig,
717
- toolRegistry: toolRegistry,
718
1080
  onAllToolCallsComplete,
719
1081
  onToolCallsUpdate: (toolCalls) => {
720
1082
  onToolCallsUpdate(toolCalls);
@@ -781,4 +1143,118 @@ describe('CoreToolScheduler request queueing', () => {
781
1143
  expect(approvalMode).toBe(ApprovalMode.AUTO_EDIT);
782
1144
  });
783
1145
  });
1146
+ describe('truncateAndSaveToFile', () => {
1147
+ const mockWriteFile = vi.mocked(fs.writeFile);
1148
+ const THRESHOLD = 40_000;
1149
+ const TRUNCATE_LINES = 1000;
1150
+ beforeEach(() => {
1151
+ vi.clearAllMocks();
1152
+ });
1153
+ it('should return content unchanged if below threshold', async () => {
1154
+ const content = 'Short content';
1155
+ const callId = 'test-call-id';
1156
+ const projectTempDir = '/tmp';
1157
+ const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1158
+ expect(result).toEqual({ content });
1159
+ expect(mockWriteFile).not.toHaveBeenCalled();
1160
+ });
1161
+ it('should truncate content by lines when content has many lines', async () => {
1162
+ // Create content that exceeds 100,000 character threshold with many lines
1163
+ const lines = Array(2000).fill('x'.repeat(100)); // 100 chars per line * 2000 lines = 200,000 chars
1164
+ const content = lines.join('\n');
1165
+ const callId = 'test-call-id';
1166
+ const projectTempDir = '/tmp';
1167
+ mockWriteFile.mockResolvedValue(undefined);
1168
+ const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1169
+ expect(result.outputFile).toBe(path.join(projectTempDir, `${callId}.output`));
1170
+ expect(mockWriteFile).toHaveBeenCalledWith(path.join(projectTempDir, `${callId}.output`), content);
1171
+ // Should contain the first and last lines with 1/5 head and 4/5 tail
1172
+ const head = Math.floor(TRUNCATE_LINES / 5);
1173
+ const beginning = lines.slice(0, head);
1174
+ const end = lines.slice(-(TRUNCATE_LINES - head));
1175
+ const expectedTruncated = beginning.join('\n') + '\n... [CONTENT TRUNCATED] ...\n' + end.join('\n');
1176
+ expect(result.content).toContain('Tool output was too large and has been truncated');
1177
+ expect(result.content).toContain('Truncated part of the output:');
1178
+ expect(result.content).toContain(expectedTruncated);
1179
+ });
1180
+ it('should wrap and truncate content when content has few but long lines', async () => {
1181
+ const content = 'a'.repeat(200_000); // A single very long line
1182
+ const callId = 'test-call-id';
1183
+ const projectTempDir = '/tmp';
1184
+ const wrapWidth = 120;
1185
+ mockWriteFile.mockResolvedValue(undefined);
1186
+ // Manually wrap the content to generate the expected file content
1187
+ const wrappedLines = [];
1188
+ for (let i = 0; i < content.length; i += wrapWidth) {
1189
+ wrappedLines.push(content.substring(i, i + wrapWidth));
1190
+ }
1191
+ const expectedFileContent = wrappedLines.join('\n');
1192
+ const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1193
+ expect(result.outputFile).toBe(path.join(projectTempDir, `${callId}.output`));
1194
+ // Check that the file was written with the wrapped content
1195
+ expect(mockWriteFile).toHaveBeenCalledWith(path.join(projectTempDir, `${callId}.output`), expectedFileContent);
1196
+ // Should contain the first and last lines with 1/5 head and 4/5 tail of the wrapped content
1197
+ const head = Math.floor(TRUNCATE_LINES / 5);
1198
+ const beginning = wrappedLines.slice(0, head);
1199
+ const end = wrappedLines.slice(-(TRUNCATE_LINES - head));
1200
+ const expectedTruncated = beginning.join('\n') + '\n... [CONTENT TRUNCATED] ...\n' + end.join('\n');
1201
+ expect(result.content).toContain('Tool output was too large and has been truncated');
1202
+ expect(result.content).toContain('Truncated part of the output:');
1203
+ expect(result.content).toContain(expectedTruncated);
1204
+ });
1205
+ it('should handle file write errors gracefully', async () => {
1206
+ const content = 'a'.repeat(2_000_000);
1207
+ const callId = 'test-call-id';
1208
+ const projectTempDir = '/tmp';
1209
+ mockWriteFile.mockRejectedValue(new Error('File write failed'));
1210
+ const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1211
+ expect(result.outputFile).toBeUndefined();
1212
+ expect(result.content).toContain('[Note: Could not save full output to file]');
1213
+ expect(mockWriteFile).toHaveBeenCalled();
1214
+ });
1215
+ it('should save to correct file path with call ID', async () => {
1216
+ const content = 'a'.repeat(200_000);
1217
+ const callId = 'unique-call-123';
1218
+ const projectTempDir = '/custom/temp/dir';
1219
+ const wrapWidth = 120;
1220
+ mockWriteFile.mockResolvedValue(undefined);
1221
+ // Manually wrap the content to generate the expected file content
1222
+ const wrappedLines = [];
1223
+ for (let i = 0; i < content.length; i += wrapWidth) {
1224
+ wrappedLines.push(content.substring(i, i + wrapWidth));
1225
+ }
1226
+ const expectedFileContent = wrappedLines.join('\n');
1227
+ const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1228
+ const expectedPath = path.join(projectTempDir, `${callId}.output`);
1229
+ expect(result.outputFile).toBe(expectedPath);
1230
+ expect(mockWriteFile).toHaveBeenCalledWith(expectedPath, expectedFileContent);
1231
+ });
1232
+ it('should include helpful instructions in truncated message', async () => {
1233
+ const content = 'a'.repeat(2_000_000);
1234
+ const callId = 'test-call-id';
1235
+ const projectTempDir = '/tmp';
1236
+ mockWriteFile.mockResolvedValue(undefined);
1237
+ const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1238
+ expect(result.content).toContain('read_file tool with the absolute file path above');
1239
+ expect(result.content).toContain('read_file tool with offset=0, limit=100');
1240
+ expect(result.content).toContain('read_file tool with offset=N to skip N lines');
1241
+ expect(result.content).toContain('read_file tool with limit=M to read only M lines');
1242
+ });
1243
+ it('should sanitize callId to prevent path traversal', async () => {
1244
+ const content = 'a'.repeat(200_000);
1245
+ const callId = '../../../../../etc/passwd';
1246
+ const projectTempDir = '/tmp/safe_dir';
1247
+ const wrapWidth = 120;
1248
+ mockWriteFile.mockResolvedValue(undefined);
1249
+ // Manually wrap the content to generate the expected file content
1250
+ const wrappedLines = [];
1251
+ for (let i = 0; i < content.length; i += wrapWidth) {
1252
+ wrappedLines.push(content.substring(i, i + wrapWidth));
1253
+ }
1254
+ const expectedFileContent = wrappedLines.join('\n');
1255
+ await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
1256
+ const expectedPath = path.join(projectTempDir, 'passwd.output');
1257
+ expect(mockWriteFile).toHaveBeenCalledWith(expectedPath, expectedFileContent);
1258
+ });
1259
+ });
784
1260
  //# sourceMappingURL=coreToolScheduler.test.js.map