@office-ai/aioncli-core 0.2.3 → 0.18.4

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 (1051) hide show
  1. package/dist/index.d.ts +16 -3
  2. package/dist/index.js +15 -3
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/agents/codebase-investigator.d.ts +46 -0
  5. package/dist/src/agents/codebase-investigator.js +132 -0
  6. package/dist/src/agents/codebase-investigator.js.map +1 -0
  7. package/dist/src/agents/codebase-investigator.test.js +35 -0
  8. package/dist/src/agents/codebase-investigator.test.js.map +1 -0
  9. package/dist/src/agents/executor.d.ts +114 -0
  10. package/dist/src/agents/executor.js +779 -0
  11. package/dist/src/agents/executor.js.map +1 -0
  12. package/dist/src/agents/executor.test.js +1362 -0
  13. package/dist/src/agents/executor.test.js.map +1 -0
  14. package/dist/src/agents/invocation.d.ts +46 -0
  15. package/dist/src/agents/invocation.js +102 -0
  16. package/dist/src/agents/invocation.js.map +1 -0
  17. package/dist/src/agents/invocation.test.js +215 -0
  18. package/dist/src/agents/invocation.test.js.map +1 -0
  19. package/dist/src/agents/registry.d.ts +40 -0
  20. package/dist/src/agents/registry.js +105 -0
  21. package/dist/src/agents/registry.js.map +1 -0
  22. package/dist/src/agents/registry.test.d.ts +6 -0
  23. package/dist/src/agents/registry.test.js +160 -0
  24. package/dist/src/agents/registry.test.js.map +1 -0
  25. package/dist/src/agents/schema-utils.d.ts +39 -0
  26. package/dist/src/agents/schema-utils.js +57 -0
  27. package/dist/src/agents/schema-utils.js.map +1 -0
  28. package/dist/src/agents/schema-utils.test.d.ts +6 -0
  29. package/dist/src/agents/schema-utils.test.js +144 -0
  30. package/dist/src/agents/schema-utils.test.js.map +1 -0
  31. package/dist/src/agents/subagent-tool-wrapper.d.ts +38 -0
  32. package/dist/src/agents/subagent-tool-wrapper.js +48 -0
  33. package/dist/src/agents/subagent-tool-wrapper.js.map +1 -0
  34. package/dist/src/agents/subagent-tool-wrapper.test.d.ts +6 -0
  35. package/dist/src/agents/subagent-tool-wrapper.test.js +110 -0
  36. package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -0
  37. package/dist/src/agents/types.d.ts +146 -0
  38. package/dist/src/agents/types.js +19 -0
  39. package/dist/src/agents/types.js.map +1 -0
  40. package/dist/src/agents/utils.d.ts +15 -0
  41. package/dist/src/agents/utils.js +29 -0
  42. package/dist/src/agents/utils.js.map +1 -0
  43. package/dist/src/agents/utils.test.d.ts +6 -0
  44. package/dist/src/agents/utils.test.js +87 -0
  45. package/dist/src/agents/utils.test.js.map +1 -0
  46. package/dist/src/code_assist/codeAssist.d.ts +6 -3
  47. package/dist/src/code_assist/codeAssist.js +13 -1
  48. package/dist/src/code_assist/codeAssist.js.map +1 -1
  49. package/dist/src/code_assist/codeAssist.test.d.ts +6 -0
  50. package/dist/src/code_assist/codeAssist.test.js +99 -0
  51. package/dist/src/code_assist/codeAssist.test.js.map +1 -0
  52. package/dist/src/code_assist/converter.d.ts +5 -1
  53. package/dist/src/code_assist/converter.js +39 -5
  54. package/dist/src/code_assist/converter.js.map +1 -1
  55. package/dist/src/code_assist/converter.test.js +112 -0
  56. package/dist/src/code_assist/converter.test.js.map +1 -1
  57. package/dist/src/code_assist/experiments/client_metadata.d.ts +12 -0
  58. package/dist/src/code_assist/experiments/client_metadata.js +50 -0
  59. package/dist/src/code_assist/experiments/client_metadata.js.map +1 -0
  60. package/dist/src/code_assist/experiments/client_metadata.test.d.ts +6 -0
  61. package/dist/src/code_assist/experiments/client_metadata.test.js +99 -0
  62. package/dist/src/code_assist/experiments/client_metadata.test.js.map +1 -0
  63. package/dist/src/code_assist/experiments/experiments.d.ts +17 -0
  64. package/dist/src/code_assist/experiments/experiments.js +36 -0
  65. package/dist/src/code_assist/experiments/experiments.js.map +1 -0
  66. package/dist/src/code_assist/experiments/experiments.test.d.ts +6 -0
  67. package/dist/src/code_assist/experiments/experiments.test.js +92 -0
  68. package/dist/src/code_assist/experiments/experiments.test.js.map +1 -0
  69. package/dist/src/code_assist/experiments/flagNames.d.ts +13 -0
  70. package/dist/src/code_assist/experiments/flagNames.js +13 -0
  71. package/dist/src/code_assist/experiments/flagNames.js.map +1 -0
  72. package/dist/src/code_assist/experiments/types.d.ts +35 -0
  73. package/dist/src/code_assist/experiments/types.js +7 -0
  74. package/dist/src/code_assist/experiments/types.js.map +1 -0
  75. package/dist/src/code_assist/oauth-credential-storage.d.ts +25 -0
  76. package/dist/src/code_assist/oauth-credential-storage.js +110 -0
  77. package/dist/src/code_assist/oauth-credential-storage.js.map +1 -0
  78. package/dist/src/code_assist/oauth-credential-storage.test.d.ts +6 -0
  79. package/dist/src/code_assist/oauth-credential-storage.test.js +198 -0
  80. package/dist/src/code_assist/oauth-credential-storage.test.js.map +1 -0
  81. package/dist/src/code_assist/oauth2.d.ts +3 -3
  82. package/dist/src/code_assist/oauth2.js +252 -125
  83. package/dist/src/code_assist/oauth2.js.map +1 -1
  84. package/dist/src/code_assist/oauth2.test.js +788 -350
  85. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  86. package/dist/src/code_assist/server.d.ts +8 -6
  87. package/dist/src/code_assist/server.js +41 -10
  88. package/dist/src/code_assist/server.js.map +1 -1
  89. package/dist/src/code_assist/server.test.js +151 -28
  90. package/dist/src/code_assist/server.test.js.map +1 -1
  91. package/dist/src/code_assist/setup.d.ts +2 -2
  92. package/dist/src/code_assist/setup.js +5 -3
  93. package/dist/src/code_assist/setup.js.map +1 -1
  94. package/dist/src/code_assist/setup.test.js.map +1 -1
  95. package/dist/src/code_assist/types.d.ts +18 -3
  96. package/dist/src/code_assist/types.js.map +1 -1
  97. package/dist/src/commands/extensions.d.ts +7 -0
  98. package/dist/src/commands/extensions.js +9 -0
  99. package/dist/src/commands/extensions.js.map +1 -0
  100. package/dist/src/commands/extensions.test.d.ts +6 -0
  101. package/dist/src/commands/extensions.test.js +19 -0
  102. package/dist/src/commands/extensions.test.js.map +1 -0
  103. package/dist/src/config/config.d.ts +282 -60
  104. package/dist/src/config/config.js +677 -129
  105. package/dist/src/config/config.js.map +1 -1
  106. package/dist/src/config/config.test.js +1020 -146
  107. package/dist/src/config/config.test.js.map +1 -1
  108. package/dist/src/config/constants.d.ts +11 -0
  109. package/dist/src/config/constants.js +16 -0
  110. package/dist/src/config/constants.js.map +1 -0
  111. package/dist/src/config/defaultModelConfigs.d.ts +7 -0
  112. package/dist/src/config/defaultModelConfigs.js +185 -0
  113. package/dist/src/config/defaultModelConfigs.js.map +1 -0
  114. package/dist/src/config/models.d.ts +37 -0
  115. package/dist/src/config/models.js +72 -0
  116. package/dist/src/config/models.js.map +1 -1
  117. package/dist/src/config/models.test.d.ts +6 -0
  118. package/dist/src/config/models.test.js +116 -0
  119. package/dist/src/config/models.test.js.map +1 -0
  120. package/dist/src/config/storage.d.ts +36 -0
  121. package/dist/src/config/storage.js +115 -0
  122. package/dist/src/config/storage.js.map +1 -0
  123. package/dist/src/config/storage.test.d.ts +6 -0
  124. package/dist/src/config/storage.test.js +48 -0
  125. package/dist/src/config/storage.test.js.map +1 -0
  126. package/dist/src/confirmation-bus/index.d.ts +7 -0
  127. package/dist/src/confirmation-bus/index.js +8 -0
  128. package/dist/src/confirmation-bus/index.js.map +1 -0
  129. package/dist/src/confirmation-bus/message-bus.d.ts +18 -0
  130. package/dist/src/confirmation-bus/message-bus.js +87 -0
  131. package/dist/src/confirmation-bus/message-bus.js.map +1 -0
  132. package/dist/src/confirmation-bus/message-bus.test.d.ts +6 -0
  133. package/dist/src/confirmation-bus/message-bus.test.js +170 -0
  134. package/dist/src/confirmation-bus/message-bus.test.js.map +1 -0
  135. package/dist/src/confirmation-bus/types.d.ts +49 -0
  136. package/dist/src/confirmation-bus/types.js +16 -0
  137. package/dist/src/confirmation-bus/types.js.map +1 -0
  138. package/dist/src/core/apiKeyCredentialStorage.d.ts +17 -0
  139. package/dist/src/core/apiKeyCredentialStorage.js +64 -0
  140. package/dist/src/core/apiKeyCredentialStorage.js.map +1 -0
  141. package/dist/src/core/apiKeyCredentialStorage.test.d.ts +6 -0
  142. package/dist/src/core/apiKeyCredentialStorage.test.js +71 -0
  143. package/dist/src/core/apiKeyCredentialStorage.test.js.map +1 -0
  144. package/dist/src/core/baseLlmClient.d.ts +50 -0
  145. package/dist/src/core/baseLlmClient.js +185 -0
  146. package/dist/src/core/baseLlmClient.js.map +1 -0
  147. package/dist/src/core/baseLlmClient.test.d.ts +6 -0
  148. package/dist/src/core/baseLlmClient.test.js +311 -0
  149. package/dist/src/core/baseLlmClient.test.js.map +1 -0
  150. package/dist/src/core/client.d.ts +30 -42
  151. package/dist/src/core/client.js +178 -477
  152. package/dist/src/core/client.js.map +1 -1
  153. package/dist/src/core/client.test.js +739 -617
  154. package/dist/src/core/client.test.js.map +1 -1
  155. package/dist/src/core/contentGenerator.d.ts +7 -6
  156. package/dist/src/core/contentGenerator.js +59 -45
  157. package/dist/src/core/contentGenerator.js.map +1 -1
  158. package/dist/src/core/contentGenerator.test.js +50 -4
  159. package/dist/src/core/contentGenerator.test.js.map +1 -1
  160. package/dist/src/core/coreToolScheduler.d.ts +28 -11
  161. package/dist/src/core/coreToolScheduler.js +493 -161
  162. package/dist/src/core/coreToolScheduler.js.map +1 -1
  163. package/dist/src/core/coreToolScheduler.test.js +995 -163
  164. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  165. package/dist/src/core/fakeContentGenerator.d.ts +33 -0
  166. package/dist/src/core/fakeContentGenerator.js +58 -0
  167. package/dist/src/core/fakeContentGenerator.js.map +1 -0
  168. package/dist/src/core/fakeContentGenerator.test.d.ts +6 -0
  169. package/dist/src/core/fakeContentGenerator.test.js +127 -0
  170. package/dist/src/core/fakeContentGenerator.test.js.map +1 -0
  171. package/dist/src/core/geminiChat.d.ts +61 -55
  172. package/dist/src/core/geminiChat.js +388 -366
  173. package/dist/src/core/geminiChat.js.map +1 -1
  174. package/dist/src/core/geminiChat.test.js +1600 -355
  175. package/dist/src/core/geminiChat.test.js.map +1 -1
  176. package/dist/src/core/geminiRequest.js +1 -0
  177. package/dist/src/core/geminiRequest.js.map +1 -1
  178. package/dist/src/core/logger.d.ts +11 -4
  179. package/dist/src/core/logger.js +39 -30
  180. package/dist/src/core/logger.js.map +1 -1
  181. package/dist/src/core/logger.test.js +62 -45
  182. package/dist/src/core/logger.test.js.map +1 -1
  183. package/dist/src/core/loggingContentGenerator.d.ts +4 -3
  184. package/dist/src/core/loggingContentGenerator.js +116 -37
  185. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  186. package/dist/src/core/loggingContentGenerator.test.d.ts +6 -0
  187. package/dist/src/core/loggingContentGenerator.test.js +180 -0
  188. package/dist/src/core/loggingContentGenerator.test.js.map +1 -0
  189. package/dist/src/core/nonInteractiveToolExecutor.d.ts +4 -5
  190. package/dist/src/core/nonInteractiveToolExecutor.js +17 -120
  191. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
  192. package/dist/src/core/nonInteractiveToolExecutor.test.js +168 -84
  193. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  194. package/dist/src/core/openaiContentGenerator.d.ts +4 -3
  195. package/dist/src/core/openaiContentGenerator.js +49 -19
  196. package/dist/src/core/openaiContentGenerator.js.map +1 -1
  197. package/dist/src/core/openaiContentGenerator.test.js +1 -0
  198. package/dist/src/core/openaiContentGenerator.test.js.map +1 -1
  199. package/dist/src/core/prompts.d.ts +7 -1
  200. package/dist/src/core/prompts.js +198 -195
  201. package/dist/src/core/prompts.js.map +1 -1
  202. package/dist/src/core/prompts.test.js +172 -104
  203. package/dist/src/core/prompts.test.js.map +1 -1
  204. package/dist/src/core/recordingContentGenerator.d.ts +18 -0
  205. package/dist/src/core/recordingContentGenerator.js +77 -0
  206. package/dist/src/core/recordingContentGenerator.js.map +1 -0
  207. package/dist/src/core/recordingContentGenerator.test.d.ts +6 -0
  208. package/dist/src/core/recordingContentGenerator.test.js +101 -0
  209. package/dist/src/core/recordingContentGenerator.test.js.map +1 -0
  210. package/dist/src/core/subagent.d.ts +24 -18
  211. package/dist/src/core/subagent.js +125 -90
  212. package/dist/src/core/subagent.js.map +1 -1
  213. package/dist/src/core/subagent.test.js +59 -44
  214. package/dist/src/core/subagent.test.js.map +1 -1
  215. package/dist/src/core/tokenLimits.test.d.ts +6 -0
  216. package/dist/src/core/tokenLimits.test.js +26 -0
  217. package/dist/src/core/tokenLimits.test.js.map +1 -0
  218. package/dist/src/core/turn.d.ts +57 -13
  219. package/dist/src/core/turn.js +79 -35
  220. package/dist/src/core/turn.js.map +1 -1
  221. package/dist/src/core/turn.test.js +373 -120
  222. package/dist/src/core/turn.test.js.map +1 -1
  223. package/dist/src/fallback/handler.d.ts +7 -0
  224. package/dist/src/fallback/handler.js +181 -0
  225. package/dist/src/fallback/handler.js.map +1 -0
  226. package/dist/src/fallback/handler.test.d.ts +6 -0
  227. package/dist/src/fallback/handler.test.js +245 -0
  228. package/dist/src/fallback/handler.test.js.map +1 -0
  229. package/dist/src/fallback/types.d.ts +14 -0
  230. package/dist/src/fallback/types.js +7 -0
  231. package/dist/src/fallback/types.js.map +1 -0
  232. package/dist/src/generated/git-commit.d.ts +2 -2
  233. package/dist/src/generated/git-commit.js +2 -2
  234. package/dist/src/generated/git-commit.js.map +1 -1
  235. package/dist/src/hooks/hookAggregator.d.ts +68 -0
  236. package/dist/src/hooks/hookAggregator.js +262 -0
  237. package/dist/src/hooks/hookAggregator.js.map +1 -0
  238. package/dist/src/hooks/hookAggregator.test.d.ts +6 -0
  239. package/dist/src/hooks/hookAggregator.test.js +387 -0
  240. package/dist/src/hooks/hookAggregator.test.js.map +1 -0
  241. package/dist/src/hooks/hookPlanner.d.ts +46 -0
  242. package/dist/src/hooks/hookPlanner.js +108 -0
  243. package/dist/src/hooks/hookPlanner.js.map +1 -0
  244. package/dist/src/hooks/hookPlanner.test.d.ts +6 -0
  245. package/dist/src/hooks/hookPlanner.test.js +255 -0
  246. package/dist/src/hooks/hookPlanner.test.js.map +1 -0
  247. package/dist/src/hooks/hookRegistry.d.ts +87 -0
  248. package/dist/src/hooks/hookRegistry.js +198 -0
  249. package/dist/src/hooks/hookRegistry.js.map +1 -0
  250. package/dist/src/hooks/hookRegistry.test.d.ts +6 -0
  251. package/dist/src/hooks/hookRegistry.test.js +341 -0
  252. package/dist/src/hooks/hookRegistry.test.js.map +1 -0
  253. package/dist/src/hooks/hookRunner.d.ts +42 -0
  254. package/dist/src/hooks/hookRunner.js +272 -0
  255. package/dist/src/hooks/hookRunner.js.map +1 -0
  256. package/dist/src/hooks/hookRunner.test.d.ts +6 -0
  257. package/dist/src/hooks/hookRunner.test.js +468 -0
  258. package/dist/src/hooks/hookRunner.test.js.map +1 -0
  259. package/dist/src/hooks/hookTranslator.d.ts +113 -0
  260. package/dist/src/hooks/hookTranslator.js +232 -0
  261. package/dist/src/hooks/hookTranslator.js.map +1 -0
  262. package/dist/src/hooks/hookTranslator.test.d.ts +6 -0
  263. package/dist/src/hooks/hookTranslator.test.js +192 -0
  264. package/dist/src/hooks/hookTranslator.test.js.map +1 -0
  265. package/dist/src/hooks/types.d.ts +384 -0
  266. package/dist/src/hooks/types.js +284 -0
  267. package/dist/src/hooks/types.js.map +1 -0
  268. package/dist/src/hooks/types.test.d.ts +6 -0
  269. package/dist/src/hooks/types.test.js +313 -0
  270. package/dist/src/hooks/types.test.js.map +1 -0
  271. package/dist/src/ide/constants.d.ts +3 -0
  272. package/dist/src/ide/constants.js +3 -0
  273. package/dist/src/ide/constants.js.map +1 -1
  274. package/dist/src/ide/detect-ide.d.ts +52 -12
  275. package/dist/src/ide/detect-ide.js +51 -65
  276. package/dist/src/ide/detect-ide.js.map +1 -1
  277. package/dist/src/ide/detect-ide.test.js +95 -52
  278. package/dist/src/ide/detect-ide.test.js.map +1 -1
  279. package/dist/src/ide/ide-client.d.ts +72 -24
  280. package/dist/src/ide/ide-client.js +380 -84
  281. package/dist/src/ide/ide-client.js.map +1 -1
  282. package/dist/src/ide/ide-client.test.js +539 -35
  283. package/dist/src/ide/ide-client.test.js.map +1 -1
  284. package/dist/src/ide/ide-installer.d.ts +2 -2
  285. package/dist/src/ide/ide-installer.js +93 -35
  286. package/dist/src/ide/ide-installer.js.map +1 -1
  287. package/dist/src/ide/ide-installer.test.js +157 -26
  288. package/dist/src/ide/ide-installer.test.js.map +1 -1
  289. package/dist/src/ide/ideContext.d.ts +35 -365
  290. package/dist/src/ide/ideContext.js +60 -106
  291. package/dist/src/ide/ideContext.js.map +1 -1
  292. package/dist/src/ide/ideContext.test.js +152 -24
  293. package/dist/src/ide/ideContext.test.js.map +1 -1
  294. package/dist/src/ide/process-utils.d.ts +7 -5
  295. package/dist/src/ide/process-utils.js +108 -67
  296. package/dist/src/ide/process-utils.js.map +1 -1
  297. package/dist/src/ide/process-utils.test.d.ts +6 -0
  298. package/dist/src/ide/process-utils.test.js +151 -0
  299. package/dist/src/ide/process-utils.test.js.map +1 -0
  300. package/dist/src/ide/types.d.ts +486 -0
  301. package/dist/src/ide/types.js +138 -0
  302. package/dist/src/ide/types.js.map +1 -0
  303. package/dist/src/index.d.ts +41 -2
  304. package/dist/src/index.js +44 -2
  305. package/dist/src/index.js.map +1 -1
  306. package/dist/src/mcp/google-auth-provider.d.ts +5 -3
  307. package/dist/src/mcp/google-auth-provider.js +21 -3
  308. package/dist/src/mcp/google-auth-provider.js.map +1 -1
  309. package/dist/src/mcp/google-auth-provider.test.js +42 -9
  310. package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
  311. package/dist/src/mcp/oauth-provider.d.ts +25 -18
  312. package/dist/src/mcp/oauth-provider.js +194 -97
  313. package/dist/src/mcp/oauth-provider.js.map +1 -1
  314. package/dist/src/mcp/oauth-provider.test.js +581 -39
  315. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  316. package/dist/src/mcp/oauth-token-storage.d.ts +14 -32
  317. package/dist/src/mcp/oauth-token-storage.js +58 -28
  318. package/dist/src/mcp/oauth-token-storage.js.map +1 -1
  319. package/dist/src/mcp/oauth-token-storage.test.js +262 -162
  320. package/dist/src/mcp/oauth-token-storage.test.js.map +1 -1
  321. package/dist/src/mcp/oauth-utils.d.ts +16 -1
  322. package/dist/src/mcp/oauth-utils.js +68 -33
  323. package/dist/src/mcp/oauth-utils.js.map +1 -1
  324. package/dist/src/mcp/oauth-utils.test.js +86 -3
  325. package/dist/src/mcp/oauth-utils.test.js.map +1 -1
  326. package/dist/src/mcp/sa-impersonation-provider.d.ts +27 -0
  327. package/dist/src/mcp/sa-impersonation-provider.js +113 -0
  328. package/dist/src/mcp/sa-impersonation-provider.js.map +1 -0
  329. package/dist/src/mcp/sa-impersonation-provider.test.d.ts +6 -0
  330. package/dist/src/mcp/sa-impersonation-provider.test.js +117 -0
  331. package/dist/src/mcp/sa-impersonation-provider.test.js.map +1 -0
  332. package/dist/src/mcp/token-storage/base-token-storage.d.ts +19 -0
  333. package/dist/src/mcp/token-storage/base-token-storage.js +36 -0
  334. package/dist/src/mcp/token-storage/base-token-storage.js.map +1 -0
  335. package/dist/src/mcp/token-storage/base-token-storage.test.d.ts +6 -0
  336. package/dist/src/mcp/token-storage/base-token-storage.test.js +151 -0
  337. package/dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -0
  338. package/dist/src/mcp/token-storage/file-token-storage.d.ts +24 -0
  339. package/dist/src/mcp/token-storage/file-token-storage.js +145 -0
  340. package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -0
  341. package/dist/src/mcp/token-storage/file-token-storage.test.d.ts +6 -0
  342. package/dist/src/mcp/token-storage/file-token-storage.test.js +238 -0
  343. package/dist/src/mcp/token-storage/file-token-storage.test.js.map +1 -0
  344. package/dist/src/mcp/token-storage/hybrid-token-storage.d.ts +23 -0
  345. package/dist/src/mcp/token-storage/hybrid-token-storage.js +78 -0
  346. package/dist/src/mcp/token-storage/hybrid-token-storage.js.map +1 -0
  347. package/dist/src/mcp/token-storage/hybrid-token-storage.test.d.ts +6 -0
  348. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js +193 -0
  349. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js.map +1 -0
  350. package/dist/src/mcp/token-storage/index.d.ts +11 -0
  351. package/dist/src/mcp/token-storage/index.js +12 -0
  352. package/dist/src/mcp/token-storage/index.js.map +1 -0
  353. package/dist/src/mcp/token-storage/keychain-token-storage.d.ts +35 -0
  354. package/dist/src/mcp/token-storage/keychain-token-storage.js +246 -0
  355. package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -0
  356. package/dist/src/mcp/token-storage/keychain-token-storage.test.d.ts +6 -0
  357. package/dist/src/mcp/token-storage/keychain-token-storage.test.js +305 -0
  358. package/dist/src/mcp/token-storage/keychain-token-storage.test.js.map +1 -0
  359. package/dist/src/mcp/token-storage/types.d.ts +44 -0
  360. package/dist/src/mcp/token-storage/types.js +11 -0
  361. package/dist/src/mcp/token-storage/types.js.map +1 -0
  362. package/dist/src/output/json-formatter.d.ts +11 -0
  363. package/dist/src/output/json-formatter.js +30 -0
  364. package/dist/src/output/json-formatter.js.map +1 -0
  365. package/dist/src/output/json-formatter.test.d.ts +6 -0
  366. package/dist/src/output/json-formatter.test.js +266 -0
  367. package/dist/src/output/json-formatter.test.js.map +1 -0
  368. package/dist/src/output/stream-json-formatter.d.ts +32 -0
  369. package/dist/src/output/stream-json-formatter.js +52 -0
  370. package/dist/src/output/stream-json-formatter.js.map +1 -0
  371. package/dist/src/output/stream-json-formatter.test.d.ts +6 -0
  372. package/dist/src/output/stream-json-formatter.test.js +479 -0
  373. package/dist/src/output/stream-json-formatter.test.js.map +1 -0
  374. package/dist/src/output/types.d.ts +82 -0
  375. package/dist/src/output/types.js +22 -0
  376. package/dist/src/output/types.js.map +1 -0
  377. package/dist/src/policy/config.d.ts +31 -0
  378. package/dist/src/policy/config.js +199 -0
  379. package/dist/src/policy/config.js.map +1 -0
  380. package/dist/src/policy/config.test.d.ts +6 -0
  381. package/dist/src/policy/config.test.js +538 -0
  382. package/dist/src/policy/config.test.js.map +1 -0
  383. package/dist/src/policy/index.d.ts +9 -0
  384. package/dist/src/policy/index.js +10 -0
  385. package/dist/src/policy/index.js.map +1 -0
  386. package/dist/src/policy/policies/discovered.toml +8 -0
  387. package/dist/src/policy/policies/read-only.toml +56 -0
  388. package/dist/src/policy/policies/write.toml +73 -0
  389. package/dist/src/policy/policies/yolo.toml +31 -0
  390. package/dist/src/policy/policy-engine.d.ts +39 -0
  391. package/dist/src/policy/policy-engine.js +158 -0
  392. package/dist/src/policy/policy-engine.js.map +1 -0
  393. package/dist/src/policy/policy-engine.test.d.ts +6 -0
  394. package/dist/src/policy/policy-engine.test.js +899 -0
  395. package/dist/src/policy/policy-engine.test.js.map +1 -0
  396. package/dist/src/policy/stable-stringify.d.ts +58 -0
  397. package/dist/src/policy/stable-stringify.js +122 -0
  398. package/dist/src/policy/stable-stringify.js.map +1 -0
  399. package/dist/src/policy/toml-loader.d.ts +47 -0
  400. package/dist/src/policy/toml-loader.js +411 -0
  401. package/dist/src/policy/toml-loader.js.map +1 -0
  402. package/dist/src/policy/toml-loader.test.d.ts +6 -0
  403. package/dist/src/policy/toml-loader.test.js +376 -0
  404. package/dist/src/policy/toml-loader.test.js.map +1 -0
  405. package/dist/src/policy/types.d.ts +130 -0
  406. package/dist/src/policy/types.js +22 -0
  407. package/dist/src/policy/types.js.map +1 -0
  408. package/dist/src/prompts/mcp-prompts.d.ts +2 -2
  409. package/dist/src/prompts/mcp-prompts.test.d.ts +6 -0
  410. package/dist/src/prompts/mcp-prompts.test.js +39 -0
  411. package/dist/src/prompts/mcp-prompts.test.js.map +1 -0
  412. package/dist/src/prompts/prompt-registry.d.ts +1 -1
  413. package/dist/src/prompts/prompt-registry.js +2 -1
  414. package/dist/src/prompts/prompt-registry.js.map +1 -1
  415. package/dist/src/prompts/prompt-registry.test.d.ts +6 -0
  416. package/dist/src/prompts/prompt-registry.test.js +96 -0
  417. package/dist/src/prompts/prompt-registry.test.js.map +1 -0
  418. package/dist/src/routing/modelRouterService.d.ts +23 -0
  419. package/dist/src/routing/modelRouterService.js +85 -0
  420. package/dist/src/routing/modelRouterService.js.map +1 -0
  421. package/dist/src/routing/modelRouterService.test.d.ts +6 -0
  422. package/dist/src/routing/modelRouterService.test.js +160 -0
  423. package/dist/src/routing/modelRouterService.test.js.map +1 -0
  424. package/dist/src/routing/routingStrategy.d.ts +62 -0
  425. package/dist/src/routing/routingStrategy.js +7 -0
  426. package/dist/src/routing/routingStrategy.js.map +1 -0
  427. package/dist/src/routing/strategies/classifierStrategy.d.ts +12 -0
  428. package/dist/src/routing/strategies/classifierStrategy.js +166 -0
  429. package/dist/src/routing/strategies/classifierStrategy.js.map +1 -0
  430. package/dist/src/routing/strategies/classifierStrategy.test.d.ts +6 -0
  431. package/dist/src/routing/strategies/classifierStrategy.test.js +196 -0
  432. package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -0
  433. package/dist/src/routing/strategies/compositeStrategy.d.ts +26 -0
  434. package/dist/src/routing/strategies/compositeStrategy.js +68 -0
  435. package/dist/src/routing/strategies/compositeStrategy.js.map +1 -0
  436. package/dist/src/routing/strategies/compositeStrategy.test.d.ts +6 -0
  437. package/dist/src/routing/strategies/compositeStrategy.test.js +123 -0
  438. package/dist/src/routing/strategies/compositeStrategy.test.js.map +1 -0
  439. package/dist/src/routing/strategies/defaultStrategy.d.ts +12 -0
  440. package/dist/src/routing/strategies/defaultStrategy.js +20 -0
  441. package/dist/src/routing/strategies/defaultStrategy.js.map +1 -0
  442. package/dist/src/routing/strategies/defaultStrategy.test.d.ts +6 -0
  443. package/dist/src/routing/strategies/defaultStrategy.test.js +26 -0
  444. package/dist/src/routing/strategies/defaultStrategy.test.js.map +1 -0
  445. package/dist/src/routing/strategies/fallbackStrategy.d.ts +12 -0
  446. package/dist/src/routing/strategies/fallbackStrategy.js +25 -0
  447. package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -0
  448. package/dist/src/routing/strategies/fallbackStrategy.test.d.ts +6 -0
  449. package/dist/src/routing/strategies/fallbackStrategy.test.js +59 -0
  450. package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -0
  451. package/dist/src/routing/strategies/overrideStrategy.d.ts +15 -0
  452. package/dist/src/routing/strategies/overrideStrategy.js +28 -0
  453. package/dist/src/routing/strategies/overrideStrategy.js.map +1 -0
  454. package/dist/src/routing/strategies/overrideStrategy.test.d.ts +6 -0
  455. package/dist/src/routing/strategies/overrideStrategy.test.js +45 -0
  456. package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -0
  457. package/dist/src/safety/built-in.d.ts +21 -0
  458. package/dist/src/safety/built-in.js +106 -0
  459. package/dist/src/safety/built-in.js.map +1 -0
  460. package/dist/src/safety/built-in.test.d.ts +6 -0
  461. package/dist/src/safety/built-in.test.js +199 -0
  462. package/dist/src/safety/built-in.test.js.map +1 -0
  463. package/dist/src/safety/checker-runner.d.ts +48 -0
  464. package/dist/src/safety/checker-runner.js +208 -0
  465. package/dist/src/safety/checker-runner.js.map +1 -0
  466. package/dist/src/safety/checker-runner.test.d.ts +6 -0
  467. package/dist/src/safety/checker-runner.test.js +238 -0
  468. package/dist/src/safety/checker-runner.test.js.map +1 -0
  469. package/dist/src/safety/context-builder.d.ts +23 -0
  470. package/dist/src/safety/context-builder.js +47 -0
  471. package/dist/src/safety/context-builder.js.map +1 -0
  472. package/dist/src/safety/context-builder.test.d.ts +6 -0
  473. package/dist/src/safety/context-builder.test.js +49 -0
  474. package/dist/src/safety/context-builder.test.js.map +1 -0
  475. package/dist/src/safety/protocol.d.ts +88 -0
  476. package/dist/src/safety/protocol.js +15 -0
  477. package/dist/src/safety/protocol.js.map +1 -0
  478. package/dist/src/safety/registry.d.ts +26 -0
  479. package/dist/src/safety/registry.js +65 -0
  480. package/dist/src/safety/registry.js.map +1 -0
  481. package/dist/src/safety/registry.test.d.ts +6 -0
  482. package/dist/src/safety/registry.test.js +31 -0
  483. package/dist/src/safety/registry.test.js.map +1 -0
  484. package/dist/src/services/chatCompressionService.d.ts +32 -0
  485. package/dist/src/services/chatCompressionService.js +162 -0
  486. package/dist/src/services/chatCompressionService.js.map +1 -0
  487. package/dist/src/services/chatCompressionService.test.d.ts +6 -0
  488. package/dist/src/services/chatCompressionService.test.js +210 -0
  489. package/dist/src/services/chatCompressionService.test.js.map +1 -0
  490. package/dist/src/services/chatRecordingService.d.ts +10 -15
  491. package/dist/src/services/chatRecordingService.js +43 -29
  492. package/dist/src/services/chatRecordingService.js.map +1 -1
  493. package/dist/src/services/chatRecordingService.test.js +69 -25
  494. package/dist/src/services/chatRecordingService.test.js.map +1 -1
  495. package/dist/src/services/fileDiscoveryService.d.ts +8 -10
  496. package/dist/src/services/fileDiscoveryService.js +31 -53
  497. package/dist/src/services/fileDiscoveryService.js.map +1 -1
  498. package/dist/src/services/fileDiscoveryService.test.js +94 -14
  499. package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
  500. package/dist/src/services/fileSystemService.d.ts +9 -0
  501. package/dist/src/services/fileSystemService.js +12 -1
  502. package/dist/src/services/fileSystemService.js.map +1 -1
  503. package/dist/src/services/fileSystemService.test.js +1 -1
  504. package/dist/src/services/fileSystemService.test.js.map +1 -1
  505. package/dist/src/services/gitService.d.ts +3 -1
  506. package/dist/src/services/gitService.js +30 -24
  507. package/dist/src/services/gitService.js.map +1 -1
  508. package/dist/src/services/gitService.test.js +30 -37
  509. package/dist/src/services/gitService.test.js.map +1 -1
  510. package/dist/src/services/loopDetectionService.d.ts +12 -3
  511. package/dist/src/services/loopDetectionService.js +148 -55
  512. package/dist/src/services/loopDetectionService.js.map +1 -1
  513. package/dist/src/services/loopDetectionService.test.js +280 -21
  514. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  515. package/dist/src/services/modelConfig.golden.test.d.ts +6 -0
  516. package/dist/src/services/modelConfig.golden.test.js +42 -0
  517. package/dist/src/services/modelConfig.golden.test.js.map +1 -0
  518. package/dist/src/services/modelConfig.integration.test.d.ts +6 -0
  519. package/dist/src/services/modelConfig.integration.test.js +247 -0
  520. package/dist/src/services/modelConfig.integration.test.js.map +1 -0
  521. package/dist/src/services/modelConfigService.d.ts +48 -0
  522. package/dist/src/services/modelConfigService.js +151 -0
  523. package/dist/src/services/modelConfigService.js.map +1 -0
  524. package/dist/src/services/modelConfigService.test.d.ts +6 -0
  525. package/dist/src/services/modelConfigService.test.js +531 -0
  526. package/dist/src/services/modelConfigService.test.js.map +1 -0
  527. package/dist/src/services/shellExecutionService.d.ts +37 -2
  528. package/dist/src/services/shellExecutionService.js +361 -67
  529. package/dist/src/services/shellExecutionService.js.map +1 -1
  530. package/dist/src/services/shellExecutionService.test.js +333 -71
  531. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  532. package/dist/src/services/test-data/resolved-aliases.golden.json +202 -0
  533. package/dist/src/telemetry/activity-detector.d.ts +41 -0
  534. package/dist/src/telemetry/activity-detector.js +61 -0
  535. package/dist/src/telemetry/activity-detector.js.map +1 -0
  536. package/dist/src/telemetry/activity-detector.test.d.ts +6 -0
  537. package/dist/src/telemetry/activity-detector.test.js +136 -0
  538. package/dist/src/telemetry/activity-detector.test.js.map +1 -0
  539. package/dist/src/telemetry/activity-monitor.d.ts +116 -0
  540. package/dist/src/telemetry/activity-monitor.js +209 -0
  541. package/dist/src/telemetry/activity-monitor.js.map +1 -0
  542. package/dist/src/telemetry/activity-monitor.test.d.ts +6 -0
  543. package/dist/src/telemetry/activity-monitor.test.js +251 -0
  544. package/dist/src/telemetry/activity-monitor.test.js.map +1 -0
  545. package/dist/src/telemetry/activity-types.d.ts +19 -0
  546. package/dist/src/telemetry/activity-types.js +21 -0
  547. package/dist/src/telemetry/activity-types.js.map +1 -0
  548. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +53 -5
  549. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +581 -56
  550. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  551. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +2 -0
  552. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +467 -31
  553. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  554. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +75 -4
  555. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +182 -6
  556. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  557. package/dist/src/telemetry/config.d.ts +31 -0
  558. package/dist/src/telemetry/config.js +76 -0
  559. package/dist/src/telemetry/config.js.map +1 -0
  560. package/dist/src/telemetry/config.test.d.ts +6 -0
  561. package/dist/src/telemetry/config.test.js +124 -0
  562. package/dist/src/telemetry/config.test.js.map +1 -0
  563. package/dist/src/telemetry/constants.d.ts +0 -18
  564. package/dist/src/telemetry/constants.js +0 -18
  565. package/dist/src/telemetry/constants.js.map +1 -1
  566. package/dist/src/telemetry/file-exporters.d.ts +5 -4
  567. package/dist/src/telemetry/file-exporters.js +1 -1
  568. package/dist/src/telemetry/file-exporters.js.map +1 -1
  569. package/dist/src/telemetry/gcp-exporters.d.ts +34 -0
  570. package/dist/src/telemetry/gcp-exporters.js +116 -0
  571. package/dist/src/telemetry/gcp-exporters.js.map +1 -0
  572. package/dist/src/telemetry/gcp-exporters.test.d.ts +6 -0
  573. package/dist/src/telemetry/gcp-exporters.test.js +318 -0
  574. package/dist/src/telemetry/gcp-exporters.test.js.map +1 -0
  575. package/dist/src/telemetry/high-water-mark-tracker.d.ts +43 -0
  576. package/dist/src/telemetry/high-water-mark-tracker.js +88 -0
  577. package/dist/src/telemetry/high-water-mark-tracker.js.map +1 -0
  578. package/dist/src/telemetry/high-water-mark-tracker.test.d.ts +6 -0
  579. package/dist/src/telemetry/high-water-mark-tracker.test.js +152 -0
  580. package/dist/src/telemetry/high-water-mark-tracker.test.js.map +1 -0
  581. package/dist/src/telemetry/index.d.ts +16 -2
  582. package/dist/src/telemetry/index.js +25 -2
  583. package/dist/src/telemetry/index.js.map +1 -1
  584. package/dist/src/telemetry/loggers.d.ts +25 -3
  585. package/dist/src/telemetry/loggers.js +333 -154
  586. package/dist/src/telemetry/loggers.js.map +1 -1
  587. package/dist/src/telemetry/loggers.test.circular.js +3 -4
  588. package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
  589. package/dist/src/telemetry/loggers.test.js +868 -63
  590. package/dist/src/telemetry/loggers.test.js.map +1 -1
  591. package/dist/src/telemetry/memory-monitor.d.ts +149 -0
  592. package/dist/src/telemetry/memory-monitor.js +335 -0
  593. package/dist/src/telemetry/memory-monitor.js.map +1 -0
  594. package/dist/src/telemetry/memory-monitor.test.d.ts +6 -0
  595. package/dist/src/telemetry/memory-monitor.test.js +472 -0
  596. package/dist/src/telemetry/memory-monitor.test.js.map +1 -0
  597. package/dist/src/telemetry/metrics.d.ts +498 -11
  598. package/dist/src/telemetry/metrics.js +729 -84
  599. package/dist/src/telemetry/metrics.js.map +1 -1
  600. package/dist/src/telemetry/metrics.test.js +964 -101
  601. package/dist/src/telemetry/metrics.test.js.map +1 -1
  602. package/dist/src/telemetry/rate-limiter.d.ts +48 -0
  603. package/dist/src/telemetry/rate-limiter.js +100 -0
  604. package/dist/src/telemetry/rate-limiter.js.map +1 -0
  605. package/dist/src/telemetry/rate-limiter.test.d.ts +6 -0
  606. package/dist/src/telemetry/rate-limiter.test.js +207 -0
  607. package/dist/src/telemetry/rate-limiter.test.js.map +1 -0
  608. package/dist/src/telemetry/sdk.d.ts +1 -1
  609. package/dist/src/telemetry/sdk.js +23 -4
  610. package/dist/src/telemetry/sdk.js.map +1 -1
  611. package/dist/src/telemetry/sdk.test.js +108 -0
  612. package/dist/src/telemetry/sdk.test.js.map +1 -1
  613. package/dist/src/telemetry/semantic.d.ts +82 -0
  614. package/dist/src/telemetry/semantic.js +269 -0
  615. package/dist/src/telemetry/semantic.js.map +1 -0
  616. package/dist/src/telemetry/semantic.test.d.ts +6 -0
  617. package/dist/src/telemetry/semantic.test.js +387 -0
  618. package/dist/src/telemetry/semantic.test.js.map +1 -0
  619. package/dist/src/telemetry/telemetry-utils.d.ts +6 -0
  620. package/dist/src/telemetry/telemetry-utils.js +14 -0
  621. package/dist/src/telemetry/telemetry-utils.js.map +1 -0
  622. package/dist/src/telemetry/telemetry-utils.test.d.ts +6 -0
  623. package/dist/src/telemetry/telemetry-utils.test.js +41 -0
  624. package/dist/src/telemetry/telemetry-utils.test.js.map +1 -0
  625. package/dist/src/telemetry/telemetryAttributes.d.ts +8 -0
  626. package/dist/src/telemetry/telemetryAttributes.js +19 -0
  627. package/dist/src/telemetry/telemetryAttributes.js.map +1 -0
  628. package/dist/src/telemetry/trace.d.ts +46 -0
  629. package/dist/src/telemetry/trace.js +121 -0
  630. package/dist/src/telemetry/trace.js.map +1 -0
  631. package/dist/src/telemetry/types.d.ts +351 -25
  632. package/dist/src/telemetry/types.js +1071 -63
  633. package/dist/src/telemetry/types.js.map +1 -1
  634. package/dist/src/telemetry/uiTelemetry.d.ts +4 -4
  635. package/dist/src/telemetry/uiTelemetry.js +14 -15
  636. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  637. package/dist/src/telemetry/uiTelemetry.test.js +122 -96
  638. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  639. package/dist/src/test-utils/config.d.ts +3 -2
  640. package/dist/src/test-utils/config.js +1 -1
  641. package/dist/src/test-utils/config.js.map +1 -1
  642. package/dist/src/test-utils/index.d.ts +6 -0
  643. package/dist/src/test-utils/index.js +7 -0
  644. package/dist/src/test-utils/index.js.map +1 -0
  645. package/dist/src/test-utils/mock-tool.d.ts +66 -0
  646. package/dist/src/test-utils/{tools.js → mock-tool.js} +45 -29
  647. package/dist/src/test-utils/mock-tool.js.map +1 -0
  648. package/dist/src/test-utils/mockWorkspaceContext.d.ts +1 -1
  649. package/dist/src/tools/base-tool-invocation.test.d.ts +6 -0
  650. package/dist/src/tools/base-tool-invocation.test.js +85 -0
  651. package/dist/src/tools/base-tool-invocation.test.js.map +1 -0
  652. package/dist/src/tools/diffOptions.d.ts +1 -1
  653. package/dist/src/tools/diffOptions.js +21 -13
  654. package/dist/src/tools/diffOptions.js.map +1 -1
  655. package/dist/src/tools/diffOptions.test.js +58 -22
  656. package/dist/src/tools/diffOptions.test.js.map +1 -1
  657. package/dist/src/tools/edit.d.ts +10 -8
  658. package/dist/src/tools/edit.js +100 -79
  659. package/dist/src/tools/edit.js.map +1 -1
  660. package/dist/src/tools/edit.test.js +429 -163
  661. package/dist/src/tools/edit.test.js.map +1 -1
  662. package/dist/src/tools/glob.d.ts +11 -5
  663. package/dist/src/tools/glob.js +58 -42
  664. package/dist/src/tools/glob.js.map +1 -1
  665. package/dist/src/tools/glob.test.js +249 -166
  666. package/dist/src/tools/glob.test.js.map +1 -1
  667. package/dist/src/tools/grep.d.ts +7 -5
  668. package/dist/src/tools/grep.js +66 -40
  669. package/dist/src/tools/grep.js.map +1 -1
  670. package/dist/src/tools/grep.test.js +41 -15
  671. package/dist/src/tools/grep.test.js.map +1 -1
  672. package/dist/src/tools/ls.d.ts +7 -5
  673. package/dist/src/tools/ls.js +54 -68
  674. package/dist/src/tools/ls.js.map +1 -1
  675. package/dist/src/tools/ls.test.js +150 -293
  676. package/dist/src/tools/ls.test.js.map +1 -1
  677. package/dist/src/tools/mcp-client-manager.d.ts +52 -12
  678. package/dist/src/tools/mcp-client-manager.js +196 -27
  679. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  680. package/dist/src/tools/mcp-client-manager.test.js +139 -13
  681. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  682. package/dist/src/tools/mcp-client.d.ts +28 -24
  683. package/dist/src/tools/mcp-client.js +338 -351
  684. package/dist/src/tools/mcp-client.js.map +1 -1
  685. package/dist/src/tools/mcp-client.test.js +380 -193
  686. package/dist/src/tools/mcp-client.test.js.map +1 -1
  687. package/dist/src/tools/mcp-tool.d.ts +11 -5
  688. package/dist/src/tools/mcp-tool.js +66 -17
  689. package/dist/src/tools/mcp-tool.js.map +1 -1
  690. package/dist/src/tools/mcp-tool.test.js +278 -211
  691. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  692. package/dist/src/tools/memoryTool.d.ts +10 -7
  693. package/dist/src/tools/memoryTool.js +28 -49
  694. package/dist/src/tools/memoryTool.js.map +1 -1
  695. package/dist/src/tools/memoryTool.test.js +26 -13
  696. package/dist/src/tools/memoryTool.test.js.map +1 -1
  697. package/dist/src/tools/message-bus-integration.test.d.ts +6 -0
  698. package/dist/src/tools/message-bus-integration.test.js +196 -0
  699. package/dist/src/tools/message-bus-integration.test.js.map +1 -0
  700. package/dist/src/tools/modifiable-tool.d.ts +7 -3
  701. package/dist/src/tools/modifiable-tool.js +41 -19
  702. package/dist/src/tools/modifiable-tool.js.map +1 -1
  703. package/dist/src/tools/modifiable-tool.test.js +70 -35
  704. package/dist/src/tools/modifiable-tool.test.js.map +1 -1
  705. package/dist/src/tools/read-file.d.ts +9 -7
  706. package/dist/src/tools/read-file.js +39 -60
  707. package/dist/src/tools/read-file.js.map +1 -1
  708. package/dist/src/tools/read-file.test.js +103 -36
  709. package/dist/src/tools/read-file.test.js.map +1 -1
  710. package/dist/src/tools/read-many-files.d.ts +9 -14
  711. package/dist/src/tools/read-many-files.js +71 -155
  712. package/dist/src/tools/read-many-files.js.map +1 -1
  713. package/dist/src/tools/read-many-files.test.js +98 -44
  714. package/dist/src/tools/read-many-files.test.js.map +1 -1
  715. package/dist/src/tools/ripGrep.d.ts +73 -0
  716. package/dist/src/tools/ripGrep.js +395 -0
  717. package/dist/src/tools/ripGrep.js.map +1 -0
  718. package/dist/src/tools/ripGrep.test.d.ts +6 -0
  719. package/dist/src/tools/ripGrep.test.js +1305 -0
  720. package/dist/src/tools/ripGrep.test.js.map +1 -0
  721. package/dist/src/tools/shell.d.ts +19 -6
  722. package/dist/src/tools/shell.js +92 -56
  723. package/dist/src/tools/shell.js.map +1 -1
  724. package/dist/src/tools/shell.test.js +176 -103
  725. package/dist/src/tools/shell.test.js.map +1 -1
  726. package/dist/src/tools/smart-edit.d.ts +78 -0
  727. package/dist/src/tools/smart-edit.js +717 -0
  728. package/dist/src/tools/smart-edit.js.map +1 -0
  729. package/dist/src/tools/smart-edit.test.d.ts +6 -0
  730. package/dist/src/tools/smart-edit.test.js +592 -0
  731. package/dist/src/tools/smart-edit.test.js.map +1 -0
  732. package/dist/src/tools/tool-error.d.ts +39 -1
  733. package/dist/src/tools/tool-error.js +54 -0
  734. package/dist/src/tools/tool-error.js.map +1 -1
  735. package/dist/src/tools/tool-names.d.ts +17 -0
  736. package/dist/src/tools/tool-names.js +21 -0
  737. package/dist/src/tools/tool-names.js.map +1 -0
  738. package/dist/src/tools/tool-registry.d.ts +38 -20
  739. package/dist/src/tools/tool-registry.js +134 -77
  740. package/dist/src/tools/tool-registry.js.map +1 -1
  741. package/dist/src/tools/tool-registry.test.js +218 -58
  742. package/dist/src/tools/tool-registry.test.js.map +1 -1
  743. package/dist/src/tools/tools.d.ts +49 -17
  744. package/dist/src/tools/tools.js +150 -8
  745. package/dist/src/tools/tools.js.map +1 -1
  746. package/dist/src/tools/tools.test.js +1 -2
  747. package/dist/src/tools/tools.test.js.map +1 -1
  748. package/dist/src/tools/web-fetch.d.ts +14 -5
  749. package/dist/src/tools/web-fetch.js +90 -44
  750. package/dist/src/tools/web-fetch.js.map +1 -1
  751. package/dist/src/tools/web-fetch.test.js +388 -20
  752. package/dist/src/tools/web-fetch.test.js.map +1 -1
  753. package/dist/src/tools/web-search.d.ts +8 -6
  754. package/dist/src/tools/web-search.js +40 -15
  755. package/dist/src/tools/web-search.js.map +1 -1
  756. package/dist/src/tools/web-search.test.js +75 -1
  757. package/dist/src/tools/web-search.test.js.map +1 -1
  758. package/dist/src/tools/write-file.d.ts +7 -5
  759. package/dist/src/tools/write-file.js +54 -54
  760. package/dist/src/tools/write-file.js.map +1 -1
  761. package/dist/src/tools/write-file.test.js +237 -146
  762. package/dist/src/tools/write-file.test.js.map +1 -1
  763. package/dist/src/tools/write-todos.d.ts +50 -0
  764. package/dist/src/tools/write-todos.js +193 -0
  765. package/dist/src/tools/write-todos.js.map +1 -0
  766. package/dist/src/tools/write-todos.test.d.ts +6 -0
  767. package/dist/src/tools/write-todos.test.js +89 -0
  768. package/dist/src/tools/write-todos.test.js.map +1 -0
  769. package/dist/src/utils/bfsFileSearch.d.ts +2 -2
  770. package/dist/src/utils/bfsFileSearch.js +16 -9
  771. package/dist/src/utils/bfsFileSearch.js.map +1 -1
  772. package/dist/src/utils/bfsFileSearch.test.js +3 -3
  773. package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
  774. package/dist/src/utils/channel.d.ts +19 -0
  775. package/dist/src/utils/channel.js +49 -0
  776. package/dist/src/utils/channel.js.map +1 -0
  777. package/dist/src/utils/channel.test.d.ts +6 -0
  778. package/dist/src/utils/channel.test.js +170 -0
  779. package/dist/src/utils/channel.test.js.map +1 -0
  780. package/dist/src/utils/debugLogger.d.ts +25 -0
  781. package/dist/src/utils/debugLogger.js +33 -0
  782. package/dist/src/utils/debugLogger.js.map +1 -0
  783. package/dist/src/utils/debugLogger.test.d.ts +6 -0
  784. package/dist/src/utils/debugLogger.test.js +69 -0
  785. package/dist/src/utils/debugLogger.test.js.map +1 -0
  786. package/dist/src/utils/delay.d.ts +16 -0
  787. package/dist/src/utils/delay.js +43 -0
  788. package/dist/src/utils/delay.js.map +1 -0
  789. package/dist/src/utils/delay.test.d.ts +6 -0
  790. package/dist/src/utils/delay.test.js +88 -0
  791. package/dist/src/utils/delay.test.js.map +1 -0
  792. package/dist/src/utils/editCorrector.d.ts +9 -8
  793. package/dist/src/utils/editCorrector.js +62 -34
  794. package/dist/src/utils/editCorrector.js.map +1 -1
  795. package/dist/src/utils/editCorrector.test.js +52 -87
  796. package/dist/src/utils/editCorrector.test.js.map +1 -1
  797. package/dist/src/utils/editor.d.ts +4 -2
  798. package/dist/src/utils/editor.js +56 -55
  799. package/dist/src/utils/editor.js.map +1 -1
  800. package/dist/src/utils/editor.test.js +47 -88
  801. package/dist/src/utils/editor.test.js.map +1 -1
  802. package/dist/src/utils/environmentContext.d.ts +3 -2
  803. package/dist/src/utils/environmentContext.js +20 -33
  804. package/dist/src/utils/environmentContext.js.map +1 -1
  805. package/dist/src/utils/environmentContext.test.js +6 -34
  806. package/dist/src/utils/environmentContext.test.js.map +1 -1
  807. package/dist/src/utils/errorParsing.d.ts +1 -1
  808. package/dist/src/utils/errorParsing.js +5 -33
  809. package/dist/src/utils/errorParsing.js.map +1 -1
  810. package/dist/src/utils/errorParsing.test.js +0 -88
  811. package/dist/src/utils/errorParsing.test.js.map +1 -1
  812. package/dist/src/utils/errorReporting.d.ts +1 -1
  813. package/dist/src/utils/errors.d.ts +28 -0
  814. package/dist/src/utils/errors.js +48 -0
  815. package/dist/src/utils/errors.js.map +1 -1
  816. package/dist/src/utils/events.d.ts +121 -0
  817. package/dist/src/utils/events.js +84 -0
  818. package/dist/src/utils/events.js.map +1 -0
  819. package/dist/src/utils/events.test.d.ts +6 -0
  820. package/dist/src/utils/events.test.js +212 -0
  821. package/dist/src/utils/events.test.js.map +1 -0
  822. package/dist/src/utils/extensionLoader.d.ts +86 -0
  823. package/dist/src/utils/extensionLoader.js +208 -0
  824. package/dist/src/utils/extensionLoader.js.map +1 -0
  825. package/dist/src/utils/extensionLoader.test.d.ts +6 -0
  826. package/dist/src/utils/extensionLoader.test.js +154 -0
  827. package/dist/src/utils/extensionLoader.test.js.map +1 -0
  828. package/dist/src/utils/fetch.d.ts +1 -0
  829. package/dist/src/utils/fetch.js +5 -1
  830. package/dist/src/utils/fetch.js.map +1 -1
  831. package/dist/src/utils/fileUtils.d.ts +28 -12
  832. package/dist/src/utils/fileUtils.js +204 -81
  833. package/dist/src/utils/fileUtils.js.map +1 -1
  834. package/dist/src/utils/fileUtils.test.js +426 -82
  835. package/dist/src/utils/fileUtils.test.js.map +1 -1
  836. package/dist/src/utils/filesearch/crawler.d.ts +1 -1
  837. package/dist/src/utils/filesearch/crawler.test.js +2 -2
  838. package/dist/src/utils/filesearch/crawler.test.js.map +1 -1
  839. package/dist/src/utils/filesearch/fileSearch.d.ts +1 -0
  840. package/dist/src/utils/filesearch/fileSearch.js +14 -9
  841. package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
  842. package/dist/src/utils/filesearch/fileSearch.test.js +90 -0
  843. package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -1
  844. package/dist/src/utils/flashFallback.test.d.ts +6 -0
  845. package/dist/src/utils/flashFallback.test.js +103 -0
  846. package/dist/src/utils/flashFallback.test.js.map +1 -0
  847. package/dist/src/utils/formatters.d.ts +1 -0
  848. package/dist/src/utils/formatters.js +2 -1
  849. package/dist/src/utils/formatters.js.map +1 -1
  850. package/dist/src/utils/formatters.test.d.ts +6 -0
  851. package/dist/src/utils/formatters.test.js +26 -0
  852. package/dist/src/utils/formatters.test.js.map +1 -0
  853. package/dist/src/utils/geminiIgnoreParser.d.ts +18 -0
  854. package/dist/src/utils/geminiIgnoreParser.js +61 -0
  855. package/dist/src/utils/geminiIgnoreParser.js.map +1 -0
  856. package/dist/src/utils/geminiIgnoreParser.test.d.ts +6 -0
  857. package/dist/src/utils/geminiIgnoreParser.test.js +50 -0
  858. package/dist/src/utils/geminiIgnoreParser.test.js.map +1 -0
  859. package/dist/src/utils/generateContentResponseUtilities.d.ts +1 -2
  860. package/dist/src/utils/generateContentResponseUtilities.js +1 -13
  861. package/dist/src/utils/generateContentResponseUtilities.js.map +1 -1
  862. package/dist/src/utils/generateContentResponseUtilities.test.js +2 -40
  863. package/dist/src/utils/generateContentResponseUtilities.test.js.map +1 -1
  864. package/dist/src/utils/getFolderStructure.d.ts +2 -2
  865. package/dist/src/utils/getFolderStructure.js +12 -20
  866. package/dist/src/utils/getFolderStructure.js.map +1 -1
  867. package/dist/src/utils/getFolderStructure.test.js +11 -10
  868. package/dist/src/utils/getFolderStructure.test.js.map +1 -1
  869. package/dist/src/utils/gitIgnoreParser.d.ts +7 -8
  870. package/dist/src/utils/gitIgnoreParser.js +145 -36
  871. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  872. package/dist/src/utils/gitIgnoreParser.test.js +127 -38
  873. package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
  874. package/dist/src/utils/gitUtils.js +2 -2
  875. package/dist/src/utils/gitUtils.js.map +1 -1
  876. package/dist/src/utils/googleErrors.d.ts +104 -0
  877. package/dist/src/utils/googleErrors.js +152 -0
  878. package/dist/src/utils/googleErrors.js.map +1 -0
  879. package/dist/src/utils/googleErrors.test.d.ts +6 -0
  880. package/dist/src/utils/googleErrors.test.js +301 -0
  881. package/dist/src/utils/googleErrors.test.js.map +1 -0
  882. package/dist/src/utils/googleQuotaErrors.d.ts +37 -0
  883. package/dist/src/utils/googleQuotaErrors.js +157 -0
  884. package/dist/src/utils/googleQuotaErrors.js.map +1 -0
  885. package/dist/src/utils/googleQuotaErrors.test.d.ts +6 -0
  886. package/dist/src/utils/googleQuotaErrors.test.js +311 -0
  887. package/dist/src/utils/googleQuotaErrors.test.js.map +1 -0
  888. package/dist/src/utils/httpErrors.d.ts +18 -0
  889. package/dist/src/utils/httpErrors.js +36 -0
  890. package/dist/src/utils/httpErrors.js.map +1 -0
  891. package/dist/src/utils/ignorePatterns.d.ts +103 -0
  892. package/dist/src/utils/ignorePatterns.js +220 -0
  893. package/dist/src/utils/ignorePatterns.js.map +1 -0
  894. package/dist/src/utils/ignorePatterns.test.d.ts +6 -0
  895. package/dist/src/utils/ignorePatterns.test.js +246 -0
  896. package/dist/src/utils/ignorePatterns.test.js.map +1 -0
  897. package/dist/src/utils/installationManager.d.ts +16 -0
  898. package/dist/src/utils/installationManager.js +51 -0
  899. package/dist/src/utils/installationManager.js.map +1 -0
  900. package/dist/src/utils/installationManager.test.d.ts +6 -0
  901. package/dist/src/utils/installationManager.test.js +85 -0
  902. package/dist/src/utils/installationManager.test.js.map +1 -0
  903. package/dist/src/utils/language-detection.d.ts +6 -0
  904. package/dist/src/utils/language-detection.js +101 -0
  905. package/dist/src/utils/language-detection.js.map +1 -0
  906. package/dist/src/utils/llm-edit-fixer.d.ts +26 -0
  907. package/dist/src/utils/llm-edit-fixer.js +155 -0
  908. package/dist/src/utils/llm-edit-fixer.js.map +1 -0
  909. package/dist/src/utils/llm-edit-fixer.test.d.ts +6 -0
  910. package/dist/src/utils/llm-edit-fixer.test.js +223 -0
  911. package/dist/src/utils/llm-edit-fixer.test.js.map +1 -0
  912. package/dist/src/utils/memoryDiscovery.d.ts +26 -6
  913. package/dist/src/utils/memoryDiscovery.js +239 -40
  914. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  915. package/dist/src/utils/memoryDiscovery.test.js +365 -44
  916. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  917. package/dist/src/utils/memoryImportProcessor.js +19 -25
  918. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  919. package/dist/src/utils/memoryImportProcessor.test.js +24 -155
  920. package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
  921. package/dist/src/utils/messageInspectors.d.ts +1 -1
  922. package/dist/src/utils/nextSpeakerChecker.d.ts +3 -3
  923. package/dist/src/utils/nextSpeakerChecker.js +10 -4
  924. package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
  925. package/dist/src/utils/nextSpeakerChecker.test.js +85 -66
  926. package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
  927. package/dist/src/utils/package.d.ts +12 -0
  928. package/dist/src/utils/package.js +15 -0
  929. package/dist/src/utils/package.js.map +1 -0
  930. package/dist/src/utils/partUtils.d.ts +22 -1
  931. package/dist/src/utils/partUtils.js +68 -0
  932. package/dist/src/utils/partUtils.js.map +1 -1
  933. package/dist/src/utils/partUtils.test.js +112 -1
  934. package/dist/src/utils/partUtils.test.js.map +1 -1
  935. package/dist/src/utils/pathCorrector.d.ts +25 -0
  936. package/dist/src/utils/pathCorrector.js +33 -0
  937. package/dist/src/utils/pathCorrector.js.map +1 -0
  938. package/dist/src/utils/pathCorrector.test.d.ts +6 -0
  939. package/dist/src/utils/pathCorrector.test.js +83 -0
  940. package/dist/src/utils/pathCorrector.test.js.map +1 -0
  941. package/dist/src/utils/pathReader.d.ts +17 -0
  942. package/dist/src/utils/pathReader.js +92 -0
  943. package/dist/src/utils/pathReader.js.map +1 -0
  944. package/dist/src/utils/pathReader.test.d.ts +6 -0
  945. package/dist/src/utils/pathReader.test.js +406 -0
  946. package/dist/src/utils/pathReader.test.js.map +1 -0
  947. package/dist/src/utils/paths.d.ts +1 -18
  948. package/dist/src/utils/paths.js +133 -57
  949. package/dist/src/utils/paths.js.map +1 -1
  950. package/dist/src/utils/paths.test.js +200 -68
  951. package/dist/src/utils/paths.test.js.map +1 -1
  952. package/dist/src/utils/promptIdContext.d.ts +7 -0
  953. package/dist/src/utils/promptIdContext.js +8 -0
  954. package/dist/src/utils/promptIdContext.js.map +1 -0
  955. package/dist/src/utils/quotaErrorDetection.d.ts +1 -3
  956. package/dist/src/utils/quotaErrorDetection.js +0 -46
  957. package/dist/src/utils/quotaErrorDetection.js.map +1 -1
  958. package/dist/src/utils/retry.d.ts +5 -10
  959. package/dist/src/utils/retry.js +114 -197
  960. package/dist/src/utils/retry.js.map +1 -1
  961. package/dist/src/utils/retry.test.js +196 -130
  962. package/dist/src/utils/retry.test.js.map +1 -1
  963. package/dist/src/utils/safeJsonStringify.d.ts +4 -4
  964. package/dist/src/utils/safeJsonStringify.js +31 -7
  965. package/dist/src/utils/safeJsonStringify.js.map +1 -1
  966. package/dist/src/utils/schemaValidator.js +15 -1
  967. package/dist/src/utils/schemaValidator.js.map +1 -1
  968. package/dist/src/utils/schemaValidator.test.d.ts +6 -0
  969. package/dist/src/utils/schemaValidator.test.js +113 -0
  970. package/dist/src/utils/schemaValidator.test.js.map +1 -0
  971. package/dist/src/utils/session.js +1 -1
  972. package/dist/src/utils/session.js.map +1 -1
  973. package/dist/src/utils/shell-utils.d.ts +21 -3
  974. package/dist/src/utils/shell-utils.js +427 -159
  975. package/dist/src/utils/shell-utils.js.map +1 -1
  976. package/dist/src/utils/shell-utils.test.js +250 -59
  977. package/dist/src/utils/shell-utils.test.js.map +1 -1
  978. package/dist/src/utils/stdio.d.ts +32 -0
  979. package/dist/src/utils/stdio.js +85 -0
  980. package/dist/src/utils/stdio.js.map +1 -0
  981. package/dist/src/utils/stdio.test.d.ts +6 -0
  982. package/dist/src/utils/stdio.test.js +47 -0
  983. package/dist/src/utils/stdio.test.js.map +1 -0
  984. package/dist/src/utils/summarizer.d.ts +6 -4
  985. package/dist/src/utils/summarizer.js +8 -9
  986. package/dist/src/utils/summarizer.js.map +1 -1
  987. package/dist/src/utils/summarizer.test.js +32 -12
  988. package/dist/src/utils/summarizer.test.js.map +1 -1
  989. package/dist/src/utils/systemEncoding.js +7 -6
  990. package/dist/src/utils/systemEncoding.js.map +1 -1
  991. package/dist/src/utils/systemEncoding.test.js +4 -3
  992. package/dist/src/utils/systemEncoding.test.js.map +1 -1
  993. package/dist/src/utils/terminal.d.ts +14 -0
  994. package/dist/src/utils/terminal.js +38 -0
  995. package/dist/src/utils/terminal.js.map +1 -0
  996. package/dist/src/utils/terminalSerializer.d.ts +25 -0
  997. package/dist/src/utils/terminalSerializer.js +432 -0
  998. package/dist/src/utils/terminalSerializer.js.map +1 -0
  999. package/dist/src/utils/terminalSerializer.test.d.ts +6 -0
  1000. package/dist/src/utils/terminalSerializer.test.js +176 -0
  1001. package/dist/src/utils/terminalSerializer.test.js.map +1 -0
  1002. package/dist/src/utils/textUtils.d.ts +5 -0
  1003. package/dist/src/utils/textUtils.js +14 -0
  1004. package/dist/src/utils/textUtils.js.map +1 -1
  1005. package/dist/src/utils/textUtils.test.d.ts +6 -0
  1006. package/dist/src/utils/textUtils.test.js +59 -0
  1007. package/dist/src/utils/textUtils.test.js.map +1 -0
  1008. package/dist/src/utils/thoughtUtils.d.ts +21 -0
  1009. package/dist/src/utils/thoughtUtils.js +39 -0
  1010. package/dist/src/utils/thoughtUtils.js.map +1 -0
  1011. package/dist/src/utils/thoughtUtils.test.d.ts +6 -0
  1012. package/dist/src/utils/thoughtUtils.test.js +78 -0
  1013. package/dist/src/utils/thoughtUtils.test.js.map +1 -0
  1014. package/dist/src/utils/tool-utils.d.ts +19 -0
  1015. package/dist/src/utils/tool-utils.js +67 -0
  1016. package/dist/src/utils/tool-utils.js.map +1 -0
  1017. package/dist/src/utils/tool-utils.test.d.ts +6 -0
  1018. package/dist/src/utils/tool-utils.test.js +69 -0
  1019. package/dist/src/utils/tool-utils.test.js.map +1 -0
  1020. package/dist/src/utils/userAccountManager.d.ts +20 -0
  1021. package/dist/src/utils/userAccountManager.js +115 -0
  1022. package/dist/src/utils/userAccountManager.js.map +1 -0
  1023. package/dist/src/utils/userAccountManager.test.d.ts +6 -0
  1024. package/dist/src/utils/{user_account.test.js → userAccountManager.test.js} +41 -36
  1025. package/dist/src/utils/userAccountManager.test.js.map +1 -0
  1026. package/dist/src/utils/workspaceContext.d.ts +4 -3
  1027. package/dist/src/utils/workspaceContext.js +23 -17
  1028. package/dist/src/utils/workspaceContext.js.map +1 -1
  1029. package/dist/src/utils/workspaceContext.test.js +45 -19
  1030. package/dist/src/utils/workspaceContext.test.js.map +1 -1
  1031. package/dist/tsconfig.tsbuildinfo +1 -1
  1032. package/package.json +24 -10
  1033. package/dist/src/core/modelCheck.d.ts +0 -14
  1034. package/dist/src/core/modelCheck.js +0 -62
  1035. package/dist/src/core/modelCheck.js.map +0 -1
  1036. package/dist/src/test-utils/tools.d.ts +0 -44
  1037. package/dist/src/test-utils/tools.js.map +0 -1
  1038. package/dist/src/utils/flashFallback.integration.test.js +0 -118
  1039. package/dist/src/utils/flashFallback.integration.test.js.map +0 -1
  1040. package/dist/src/utils/user_account.d.ts +0 -9
  1041. package/dist/src/utils/user_account.js +0 -109
  1042. package/dist/src/utils/user_account.js.map +0 -1
  1043. package/dist/src/utils/user_account.test.js.map +0 -1
  1044. package/dist/src/utils/user_id.d.ts +0 -11
  1045. package/dist/src/utils/user_id.js +0 -49
  1046. package/dist/src/utils/user_id.js.map +0 -1
  1047. package/dist/src/utils/user_id.test.js +0 -21
  1048. package/dist/src/utils/user_id.test.js.map +0 -1
  1049. /package/dist/src/{utils/flashFallback.integration.test.d.ts → agents/codebase-investigator.test.d.ts} +0 -0
  1050. /package/dist/src/{utils/user_account.test.d.ts → agents/executor.test.d.ts} +0 -0
  1051. /package/dist/src/{utils/user_id.test.d.ts → agents/invocation.test.d.ts} +0 -0
@@ -0,0 +1,1305 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect, beforeEach, afterEach, afterAll, vi, } from 'vitest';
7
+ import { canUseRipgrep, RipGrepTool, ensureRgPath } from './ripGrep.js';
8
+ import path from 'node:path';
9
+ import fs from 'node:fs/promises';
10
+ import os from 'node:os';
11
+ import { Storage } from '../config/storage.js';
12
+ import { createMockWorkspaceContext } from '../test-utils/mockWorkspaceContext.js';
13
+ import { spawn } from 'node:child_process';
14
+ import { downloadRipGrep } from '@joshua.litt/get-ripgrep';
15
+ // Mock dependencies for canUseRipgrep
16
+ vi.mock('@joshua.litt/get-ripgrep', () => ({
17
+ downloadRipGrep: vi.fn(),
18
+ }));
19
+ // Mock child_process for ripgrep calls
20
+ vi.mock('child_process', () => ({
21
+ spawn: vi.fn(),
22
+ }));
23
+ const mockSpawn = vi.mocked(spawn);
24
+ const downloadRipGrepMock = vi.mocked(downloadRipGrep);
25
+ const originalGetGlobalBinDir = Storage.getGlobalBinDir.bind(Storage);
26
+ const storageSpy = vi.spyOn(Storage, 'getGlobalBinDir');
27
+ function getRipgrepBinaryName() {
28
+ return process.platform === 'win32' ? 'rg.exe' : 'rg';
29
+ }
30
+ describe('canUseRipgrep', () => {
31
+ let tempRootDir;
32
+ let binDir;
33
+ beforeEach(async () => {
34
+ downloadRipGrepMock.mockReset();
35
+ downloadRipGrepMock.mockResolvedValue(undefined);
36
+ tempRootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ripgrep-bin-'));
37
+ binDir = path.join(tempRootDir, 'bin');
38
+ await fs.mkdir(binDir, { recursive: true });
39
+ storageSpy.mockImplementation(() => binDir);
40
+ });
41
+ afterEach(async () => {
42
+ storageSpy.mockImplementation(() => originalGetGlobalBinDir());
43
+ await fs.rm(tempRootDir, { recursive: true, force: true });
44
+ });
45
+ it('should return true if ripgrep already exists', async () => {
46
+ const existingPath = path.join(binDir, getRipgrepBinaryName());
47
+ await fs.writeFile(existingPath, '');
48
+ const result = await canUseRipgrep();
49
+ expect(result).toBe(true);
50
+ expect(downloadRipGrepMock).not.toHaveBeenCalled();
51
+ });
52
+ it('should download ripgrep and return true if it does not exist initially', async () => {
53
+ const expectedPath = path.join(binDir, getRipgrepBinaryName());
54
+ downloadRipGrepMock.mockImplementation(async () => {
55
+ await fs.writeFile(expectedPath, '');
56
+ });
57
+ const result = await canUseRipgrep();
58
+ expect(result).toBe(true);
59
+ expect(downloadRipGrep).toHaveBeenCalledWith(binDir);
60
+ await expect(fs.access(expectedPath)).resolves.toBeUndefined();
61
+ });
62
+ it('should return false if download fails and file does not exist', async () => {
63
+ const result = await canUseRipgrep();
64
+ expect(result).toBe(false);
65
+ expect(downloadRipGrep).toHaveBeenCalledWith(binDir);
66
+ });
67
+ it('should propagate errors from downloadRipGrep', async () => {
68
+ const error = new Error('Download failed');
69
+ downloadRipGrepMock.mockRejectedValue(error);
70
+ await expect(canUseRipgrep()).rejects.toThrow(error);
71
+ expect(downloadRipGrep).toHaveBeenCalledWith(binDir);
72
+ });
73
+ it('should only download once when called concurrently', async () => {
74
+ const expectedPath = path.join(binDir, getRipgrepBinaryName());
75
+ downloadRipGrepMock.mockImplementation(() => new Promise((resolve, reject) => {
76
+ setTimeout(() => {
77
+ fs.writeFile(expectedPath, '')
78
+ .then(() => resolve())
79
+ .catch(reject);
80
+ }, 0);
81
+ }));
82
+ const firstCall = ensureRgPath();
83
+ const secondCall = ensureRgPath();
84
+ const [pathOne, pathTwo] = await Promise.all([firstCall, secondCall]);
85
+ expect(pathOne).toBe(expectedPath);
86
+ expect(pathTwo).toBe(expectedPath);
87
+ expect(downloadRipGrepMock).toHaveBeenCalledTimes(1);
88
+ await expect(fs.access(expectedPath)).resolves.toBeUndefined();
89
+ });
90
+ });
91
+ describe('ensureRgPath', () => {
92
+ let tempRootDir;
93
+ let binDir;
94
+ beforeEach(async () => {
95
+ downloadRipGrepMock.mockReset();
96
+ downloadRipGrepMock.mockResolvedValue(undefined);
97
+ tempRootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ripgrep-bin-'));
98
+ binDir = path.join(tempRootDir, 'bin');
99
+ await fs.mkdir(binDir, { recursive: true });
100
+ storageSpy.mockImplementation(() => binDir);
101
+ });
102
+ afterEach(async () => {
103
+ storageSpy.mockImplementation(() => originalGetGlobalBinDir());
104
+ await fs.rm(tempRootDir, { recursive: true, force: true });
105
+ });
106
+ it('should return rg path if ripgrep already exists', async () => {
107
+ const existingPath = path.join(binDir, getRipgrepBinaryName());
108
+ await fs.writeFile(existingPath, '');
109
+ const rgPath = await ensureRgPath();
110
+ expect(rgPath).toBe(existingPath);
111
+ expect(downloadRipGrep).not.toHaveBeenCalled();
112
+ });
113
+ it('should return rg path if ripgrep is downloaded successfully', async () => {
114
+ const expectedPath = path.join(binDir, getRipgrepBinaryName());
115
+ downloadRipGrepMock.mockImplementation(async () => {
116
+ await fs.writeFile(expectedPath, '');
117
+ });
118
+ const rgPath = await ensureRgPath();
119
+ expect(rgPath).toBe(expectedPath);
120
+ expect(downloadRipGrep).toHaveBeenCalledTimes(1);
121
+ await expect(fs.access(expectedPath)).resolves.toBeUndefined();
122
+ });
123
+ it('should throw an error if ripgrep cannot be used after download attempt', async () => {
124
+ await expect(ensureRgPath()).rejects.toThrow('Cannot use ripgrep.');
125
+ expect(downloadRipGrep).toHaveBeenCalledTimes(1);
126
+ });
127
+ it('should propagate errors from downloadRipGrep', async () => {
128
+ const error = new Error('Download failed');
129
+ downloadRipGrepMock.mockRejectedValue(error);
130
+ await expect(ensureRgPath()).rejects.toThrow(error);
131
+ expect(downloadRipGrep).toHaveBeenCalledWith(binDir);
132
+ });
133
+ it.runIf(process.platform === 'win32')('should detect ripgrep when only rg.exe exists on Windows', async () => {
134
+ const expectedRgExePath = path.join(binDir, 'rg.exe');
135
+ await fs.writeFile(expectedRgExePath, '');
136
+ const rgPath = await ensureRgPath();
137
+ expect(rgPath).toBe(expectedRgExePath);
138
+ expect(downloadRipGrep).not.toHaveBeenCalled();
139
+ await expect(fs.access(expectedRgExePath)).resolves.toBeUndefined();
140
+ });
141
+ });
142
+ // Helper function to create mock spawn implementations
143
+ function createMockSpawn(options = {}) {
144
+ const { outputData, exitCode = 0, signal } = options;
145
+ return () => {
146
+ const mockProcess = {
147
+ stdout: {
148
+ on: vi.fn(),
149
+ removeListener: vi.fn(),
150
+ },
151
+ stderr: {
152
+ on: vi.fn(),
153
+ removeListener: vi.fn(),
154
+ },
155
+ on: vi.fn(),
156
+ removeListener: vi.fn(),
157
+ kill: vi.fn(),
158
+ };
159
+ // Set up event listeners immediately
160
+ setTimeout(() => {
161
+ const stdoutDataHandler = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
162
+ const closeHandler = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
163
+ if (stdoutDataHandler && outputData) {
164
+ stdoutDataHandler(Buffer.from(outputData));
165
+ }
166
+ if (closeHandler) {
167
+ closeHandler(exitCode, signal);
168
+ }
169
+ }, 0);
170
+ return mockProcess;
171
+ };
172
+ }
173
+ describe('RipGrepTool', () => {
174
+ let tempRootDir;
175
+ let tempBinRoot;
176
+ let binDir;
177
+ let ripgrepBinaryPath;
178
+ let grepTool;
179
+ const abortSignal = new AbortController().signal;
180
+ const mockConfig = {
181
+ getTargetDir: () => tempRootDir,
182
+ getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
183
+ getDebugMode: () => false,
184
+ };
185
+ beforeEach(async () => {
186
+ downloadRipGrepMock.mockReset();
187
+ downloadRipGrepMock.mockResolvedValue(undefined);
188
+ mockSpawn.mockReset();
189
+ tempBinRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'ripgrep-bin-'));
190
+ binDir = path.join(tempBinRoot, 'bin');
191
+ await fs.mkdir(binDir, { recursive: true });
192
+ const binaryName = process.platform === 'win32' ? 'rg.exe' : 'rg';
193
+ ripgrepBinaryPath = path.join(binDir, binaryName);
194
+ await fs.writeFile(ripgrepBinaryPath, '');
195
+ storageSpy.mockImplementation(() => binDir);
196
+ tempRootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'grep-tool-root-'));
197
+ grepTool = new RipGrepTool(mockConfig);
198
+ // Create some test files and directories
199
+ await fs.writeFile(path.join(tempRootDir, 'fileA.txt'), 'hello world\nsecond line with world');
200
+ await fs.writeFile(path.join(tempRootDir, 'fileB.js'), 'const foo = "bar";\nfunction baz() { return "hello"; }');
201
+ await fs.mkdir(path.join(tempRootDir, 'sub'));
202
+ await fs.writeFile(path.join(tempRootDir, 'sub', 'fileC.txt'), 'another world in sub dir');
203
+ await fs.writeFile(path.join(tempRootDir, 'sub', 'fileD.md'), '# Markdown file\nThis is a test.');
204
+ });
205
+ afterEach(async () => {
206
+ storageSpy.mockImplementation(() => originalGetGlobalBinDir());
207
+ await fs.rm(tempRootDir, { recursive: true, force: true });
208
+ await fs.rm(tempBinRoot, { recursive: true, force: true });
209
+ });
210
+ describe('validateToolParams', () => {
211
+ it.each([
212
+ {
213
+ name: 'pattern only',
214
+ params: { pattern: 'hello' },
215
+ expected: null,
216
+ },
217
+ {
218
+ name: 'pattern and path',
219
+ params: { pattern: 'hello', dir_path: '.' },
220
+ expected: null,
221
+ },
222
+ {
223
+ name: 'pattern, path, and include',
224
+ params: { pattern: 'hello', dir_path: '.', include: '*.txt' },
225
+ expected: null,
226
+ },
227
+ {
228
+ name: 'invalid regex pattern',
229
+ params: { pattern: '[[' },
230
+ expected: null,
231
+ },
232
+ ])('should return null for valid params ($name)', ({ params, expected }) => {
233
+ expect(grepTool.validateToolParams(params)).toBe(expected);
234
+ });
235
+ it('should return error if pattern is missing', () => {
236
+ const params = { dir_path: '.' };
237
+ expect(grepTool.validateToolParams(params)).toBe(`params must have required property 'pattern'`);
238
+ });
239
+ it('should return error if path does not exist', () => {
240
+ const params = {
241
+ pattern: 'hello',
242
+ dir_path: 'nonexistent',
243
+ };
244
+ // Check for the core error message, as the full path might vary
245
+ expect(grepTool.validateToolParams(params)).toContain('Path does not exist');
246
+ expect(grepTool.validateToolParams(params)).toContain('nonexistent');
247
+ });
248
+ it('should allow path to be a file', async () => {
249
+ const filePath = path.join(tempRootDir, 'fileA.txt');
250
+ const params = {
251
+ pattern: 'hello',
252
+ dir_path: filePath,
253
+ };
254
+ expect(grepTool.validateToolParams(params)).toBeNull();
255
+ });
256
+ });
257
+ describe('execute', () => {
258
+ it('should find matches for a simple pattern in all files', async () => {
259
+ mockSpawn.mockImplementationOnce(createMockSpawn({
260
+ outputData: JSON.stringify({
261
+ type: 'match',
262
+ data: {
263
+ path: { text: 'fileA.txt' },
264
+ line_number: 1,
265
+ lines: { text: 'hello world\n' },
266
+ },
267
+ }) +
268
+ '\n' +
269
+ JSON.stringify({
270
+ type: 'match',
271
+ data: {
272
+ path: { text: 'fileA.txt' },
273
+ line_number: 2,
274
+ lines: { text: 'second line with world\n' },
275
+ },
276
+ }) +
277
+ '\n' +
278
+ JSON.stringify({
279
+ type: 'match',
280
+ data: {
281
+ path: { text: 'sub/fileC.txt' },
282
+ line_number: 1,
283
+ lines: { text: 'another world in sub dir\n' },
284
+ },
285
+ }) +
286
+ '\n',
287
+ exitCode: 0,
288
+ }));
289
+ const params = { pattern: 'world' };
290
+ const invocation = grepTool.build(params);
291
+ const result = await invocation.execute(abortSignal);
292
+ expect(result.llmContent).toContain('Found 3 matches for pattern "world" in path "."');
293
+ expect(result.llmContent).toContain('File: fileA.txt');
294
+ expect(result.llmContent).toContain('L1: hello world');
295
+ expect(result.llmContent).toContain('L2: second line with world');
296
+ expect(result.llmContent).toContain(`File: ${path.join('sub', 'fileC.txt')}`);
297
+ expect(result.llmContent).toContain('L1: another world in sub dir');
298
+ expect(result.returnDisplay).toBe('Found 3 matches');
299
+ });
300
+ it('should find matches in a specific path', async () => {
301
+ // Setup specific mock for this test - searching in 'sub' should only return matches from that directory
302
+ mockSpawn.mockImplementationOnce(createMockSpawn({
303
+ outputData: JSON.stringify({
304
+ type: 'match',
305
+ data: {
306
+ path: { text: 'fileC.txt' },
307
+ line_number: 1,
308
+ lines: { text: 'another world in sub dir\n' },
309
+ },
310
+ }) + '\n',
311
+ exitCode: 0,
312
+ }));
313
+ const params = { pattern: 'world', dir_path: 'sub' };
314
+ const invocation = grepTool.build(params);
315
+ const result = await invocation.execute(abortSignal);
316
+ expect(result.llmContent).toContain('Found 1 match for pattern "world" in path "sub"');
317
+ expect(result.llmContent).toContain('File: fileC.txt'); // Path relative to 'sub'
318
+ expect(result.llmContent).toContain('L1: another world in sub dir');
319
+ expect(result.returnDisplay).toBe('Found 1 match');
320
+ });
321
+ it('should find matches with an include glob', async () => {
322
+ // Setup specific mock for this test
323
+ mockSpawn.mockImplementationOnce(createMockSpawn({
324
+ outputData: JSON.stringify({
325
+ type: 'match',
326
+ data: {
327
+ path: { text: 'fileB.js' },
328
+ line_number: 2,
329
+ lines: { text: 'function baz() { return "hello"; }\n' },
330
+ },
331
+ }) + '\n',
332
+ exitCode: 0,
333
+ }));
334
+ const params = { pattern: 'hello', include: '*.js' };
335
+ const invocation = grepTool.build(params);
336
+ const result = await invocation.execute(abortSignal);
337
+ expect(result.llmContent).toContain('Found 1 match for pattern "hello" in path "." (filter: "*.js"):');
338
+ expect(result.llmContent).toContain('File: fileB.js');
339
+ expect(result.llmContent).toContain('L2: function baz() { return "hello"; }');
340
+ expect(result.returnDisplay).toBe('Found 1 match');
341
+ });
342
+ it('should find matches with an include glob and path', async () => {
343
+ await fs.writeFile(path.join(tempRootDir, 'sub', 'another.js'), 'const greeting = "hello";');
344
+ // Setup specific mock for this test - searching for 'hello' in 'sub' with '*.js' filter
345
+ mockSpawn.mockImplementationOnce(() => {
346
+ const mockProcess = {
347
+ stdout: {
348
+ on: vi.fn(),
349
+ removeListener: vi.fn(),
350
+ },
351
+ stderr: {
352
+ on: vi.fn(),
353
+ removeListener: vi.fn(),
354
+ },
355
+ on: vi.fn(),
356
+ removeListener: vi.fn(),
357
+ kill: vi.fn(),
358
+ };
359
+ setTimeout(() => {
360
+ const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
361
+ const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
362
+ if (onData) {
363
+ // Only return match from the .js file in sub directory
364
+ onData(Buffer.from(JSON.stringify({
365
+ type: 'match',
366
+ data: {
367
+ path: { text: 'another.js' },
368
+ line_number: 1,
369
+ lines: { text: 'const greeting = "hello";\n' },
370
+ },
371
+ }) + '\n'));
372
+ }
373
+ if (onClose) {
374
+ onClose(0);
375
+ }
376
+ }, 0);
377
+ return mockProcess;
378
+ });
379
+ const params = {
380
+ pattern: 'hello',
381
+ dir_path: 'sub',
382
+ include: '*.js',
383
+ };
384
+ const invocation = grepTool.build(params);
385
+ const result = await invocation.execute(abortSignal);
386
+ expect(result.llmContent).toContain('Found 1 match for pattern "hello" in path "sub" (filter: "*.js")');
387
+ expect(result.llmContent).toContain('File: another.js');
388
+ expect(result.llmContent).toContain('L1: const greeting = "hello";');
389
+ expect(result.returnDisplay).toBe('Found 1 match');
390
+ });
391
+ it('should return "No matches found" when pattern does not exist', async () => {
392
+ // Setup specific mock for no matches
393
+ mockSpawn.mockImplementationOnce(createMockSpawn({
394
+ exitCode: 1, // No matches found
395
+ }));
396
+ const params = { pattern: 'nonexistentpattern' };
397
+ const invocation = grepTool.build(params);
398
+ const result = await invocation.execute(abortSignal);
399
+ expect(result.llmContent).toContain('No matches found for pattern "nonexistentpattern" in path ".".');
400
+ expect(result.returnDisplay).toBe('No matches found');
401
+ });
402
+ it('should return an error from ripgrep for invalid regex pattern', async () => {
403
+ mockSpawn.mockImplementationOnce(createMockSpawn({
404
+ exitCode: 2,
405
+ }));
406
+ const params = { pattern: '[[' };
407
+ const invocation = grepTool.build(params);
408
+ const result = await invocation.execute(abortSignal);
409
+ expect(result.llmContent).toContain('ripgrep exited with code 2');
410
+ expect(result.returnDisplay).toContain('Error: ripgrep exited with code 2');
411
+ });
412
+ it('should handle regex special characters correctly', async () => {
413
+ // Setup specific mock for this test - regex pattern 'foo.*bar' should match 'const foo = "bar";'
414
+ mockSpawn.mockImplementationOnce(() => {
415
+ const mockProcess = {
416
+ stdout: {
417
+ on: vi.fn(),
418
+ removeListener: vi.fn(),
419
+ },
420
+ stderr: {
421
+ on: vi.fn(),
422
+ removeListener: vi.fn(),
423
+ },
424
+ on: vi.fn(),
425
+ removeListener: vi.fn(),
426
+ kill: vi.fn(),
427
+ };
428
+ setTimeout(() => {
429
+ const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
430
+ const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
431
+ if (onData) {
432
+ // Return match for the regex pattern
433
+ onData(Buffer.from(JSON.stringify({
434
+ type: 'match',
435
+ data: {
436
+ path: { text: 'fileB.js' },
437
+ line_number: 1,
438
+ lines: { text: 'const foo = "bar";\n' },
439
+ },
440
+ }) + '\n'));
441
+ }
442
+ if (onClose) {
443
+ onClose(0);
444
+ }
445
+ }, 0);
446
+ return mockProcess;
447
+ });
448
+ const params = { pattern: 'foo.*bar' }; // Matches 'const foo = "bar";'
449
+ const invocation = grepTool.build(params);
450
+ const result = await invocation.execute(abortSignal);
451
+ expect(result.llmContent).toContain('Found 1 match for pattern "foo.*bar" in path ".":');
452
+ expect(result.llmContent).toContain('File: fileB.js');
453
+ expect(result.llmContent).toContain('L1: const foo = "bar";');
454
+ });
455
+ it('should be case-insensitive by default (JS fallback)', async () => {
456
+ // Setup specific mock for this test - case insensitive search for 'HELLO'
457
+ mockSpawn.mockImplementationOnce(() => {
458
+ const mockProcess = {
459
+ stdout: {
460
+ on: vi.fn(),
461
+ removeListener: vi.fn(),
462
+ },
463
+ stderr: {
464
+ on: vi.fn(),
465
+ removeListener: vi.fn(),
466
+ },
467
+ on: vi.fn(),
468
+ removeListener: vi.fn(),
469
+ kill: vi.fn(),
470
+ };
471
+ setTimeout(() => {
472
+ const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
473
+ const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
474
+ if (onData) {
475
+ // Return case-insensitive matches for 'HELLO'
476
+ onData(Buffer.from(JSON.stringify({
477
+ type: 'match',
478
+ data: {
479
+ path: { text: 'fileA.txt' },
480
+ line_number: 1,
481
+ lines: { text: 'hello world\n' },
482
+ },
483
+ }) +
484
+ '\n' +
485
+ JSON.stringify({
486
+ type: 'match',
487
+ data: {
488
+ path: { text: 'fileB.js' },
489
+ line_number: 2,
490
+ lines: { text: 'function baz() { return "hello"; }\n' },
491
+ },
492
+ }) +
493
+ '\n'));
494
+ }
495
+ if (onClose) {
496
+ onClose(0);
497
+ }
498
+ }, 0);
499
+ return mockProcess;
500
+ });
501
+ const params = { pattern: 'HELLO' };
502
+ const invocation = grepTool.build(params);
503
+ const result = await invocation.execute(abortSignal);
504
+ expect(result.llmContent).toContain('Found 2 matches for pattern "HELLO" in path ".":');
505
+ expect(result.llmContent).toContain('File: fileA.txt');
506
+ expect(result.llmContent).toContain('L1: hello world');
507
+ expect(result.llmContent).toContain('File: fileB.js');
508
+ expect(result.llmContent).toContain('L2: function baz() { return "hello"; }');
509
+ });
510
+ it('should throw an error if params are invalid', async () => {
511
+ const params = { dir_path: '.' }; // Invalid: pattern missing
512
+ expect(() => grepTool.build(params)).toThrow(/params must have required property 'pattern'/);
513
+ });
514
+ it('should throw an error if ripgrep is not available', async () => {
515
+ await fs.rm(ripgrepBinaryPath, { force: true });
516
+ downloadRipGrepMock.mockResolvedValue(undefined);
517
+ const params = { pattern: 'world' };
518
+ const invocation = grepTool.build(params);
519
+ expect(await invocation.execute(abortSignal)).toStrictEqual({
520
+ llmContent: 'Error during grep search operation: Cannot use ripgrep.',
521
+ returnDisplay: 'Error: Cannot use ripgrep.',
522
+ });
523
+ });
524
+ });
525
+ describe('multi-directory workspace', () => {
526
+ it('should search only CWD when no path is specified (default behavior)', async () => {
527
+ // Create additional directory with test files
528
+ const secondDir = await fs.mkdtemp(path.join(os.tmpdir(), 'grep-tool-second-'));
529
+ await fs.writeFile(path.join(secondDir, 'other.txt'), 'hello from second directory\nworld in second');
530
+ await fs.writeFile(path.join(secondDir, 'another.js'), 'function world() { return "test"; }');
531
+ // Create a mock config with multiple directories
532
+ const multiDirConfig = {
533
+ getTargetDir: () => tempRootDir,
534
+ getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir, [secondDir]),
535
+ getDebugMode: () => false,
536
+ };
537
+ // Setup specific mock for this test - multi-directory search for 'world'
538
+ // Mock will be called twice - once for each directory
539
+ let callCount = 0;
540
+ mockSpawn.mockImplementation(() => {
541
+ callCount++;
542
+ const mockProcess = {
543
+ stdout: {
544
+ on: vi.fn(),
545
+ removeListener: vi.fn(),
546
+ },
547
+ stderr: {
548
+ on: vi.fn(),
549
+ removeListener: vi.fn(),
550
+ },
551
+ on: vi.fn(),
552
+ removeListener: vi.fn(),
553
+ kill: vi.fn(),
554
+ };
555
+ setTimeout(() => {
556
+ const stdoutDataHandler = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
557
+ const closeHandler = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
558
+ let outputData = '';
559
+ if (callCount === 1) {
560
+ // First directory (tempRootDir)
561
+ outputData =
562
+ JSON.stringify({
563
+ type: 'match',
564
+ data: {
565
+ path: { text: 'fileA.txt' },
566
+ line_number: 1,
567
+ lines: { text: 'hello world\n' },
568
+ },
569
+ }) +
570
+ '\n' +
571
+ JSON.stringify({
572
+ type: 'match',
573
+ data: {
574
+ path: { text: 'fileA.txt' },
575
+ line_number: 2,
576
+ lines: { text: 'second line with world\n' },
577
+ },
578
+ }) +
579
+ '\n' +
580
+ JSON.stringify({
581
+ type: 'match',
582
+ data: {
583
+ path: { text: 'sub/fileC.txt' },
584
+ line_number: 1,
585
+ lines: { text: 'another world in sub dir\n' },
586
+ },
587
+ }) +
588
+ '\n';
589
+ }
590
+ else if (callCount === 2) {
591
+ // Second directory (secondDir)
592
+ outputData =
593
+ JSON.stringify({
594
+ type: 'match',
595
+ data: {
596
+ path: { text: 'other.txt' },
597
+ line_number: 2,
598
+ lines: { text: 'world in second\n' },
599
+ },
600
+ }) +
601
+ '\n' +
602
+ JSON.stringify({
603
+ type: 'match',
604
+ data: {
605
+ path: { text: 'another.js' },
606
+ line_number: 1,
607
+ lines: { text: 'function world() { return "test"; }\n' },
608
+ },
609
+ }) +
610
+ '\n';
611
+ }
612
+ if (stdoutDataHandler && outputData) {
613
+ stdoutDataHandler(Buffer.from(outputData));
614
+ }
615
+ if (closeHandler) {
616
+ closeHandler(0);
617
+ }
618
+ }, 0);
619
+ return mockProcess;
620
+ });
621
+ const multiDirGrepTool = new RipGrepTool(multiDirConfig);
622
+ const params = { pattern: 'world' };
623
+ const invocation = multiDirGrepTool.build(params);
624
+ const result = await invocation.execute(abortSignal);
625
+ // Should find matches in CWD only (default behavior now)
626
+ expect(result.llmContent).toContain('Found 3 matches for pattern "world" in path "."');
627
+ // Matches from first directory
628
+ expect(result.llmContent).toContain('fileA.txt');
629
+ expect(result.llmContent).toContain('L1: hello world');
630
+ expect(result.llmContent).toContain('L2: second line with world');
631
+ expect(result.llmContent).toContain('fileC.txt');
632
+ expect(result.llmContent).toContain('L1: another world in sub dir');
633
+ // Should NOT find matches from second directory
634
+ expect(result.llmContent).not.toContain('other.txt');
635
+ expect(result.llmContent).not.toContain('world in second');
636
+ expect(result.llmContent).not.toContain('another.js');
637
+ expect(result.llmContent).not.toContain('function world()');
638
+ // Clean up
639
+ await fs.rm(secondDir, { recursive: true, force: true });
640
+ mockSpawn.mockClear();
641
+ });
642
+ it('should search only specified path within workspace directories', async () => {
643
+ // Create additional directory
644
+ const secondDir = await fs.mkdtemp(path.join(os.tmpdir(), 'grep-tool-second-'));
645
+ await fs.mkdir(path.join(secondDir, 'sub'));
646
+ await fs.writeFile(path.join(secondDir, 'sub', 'test.txt'), 'hello from second sub directory');
647
+ // Create a mock config with multiple directories
648
+ const multiDirConfig = {
649
+ getTargetDir: () => tempRootDir,
650
+ getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir, [secondDir]),
651
+ getDebugMode: () => false,
652
+ };
653
+ // Setup specific mock for this test - searching in 'sub' should only return matches from that directory
654
+ mockSpawn.mockImplementationOnce(() => {
655
+ const mockProcess = {
656
+ stdout: {
657
+ on: vi.fn(),
658
+ removeListener: vi.fn(),
659
+ },
660
+ stderr: {
661
+ on: vi.fn(),
662
+ removeListener: vi.fn(),
663
+ },
664
+ on: vi.fn(),
665
+ removeListener: vi.fn(),
666
+ kill: vi.fn(),
667
+ };
668
+ setTimeout(() => {
669
+ const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
670
+ const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
671
+ if (onData) {
672
+ onData(Buffer.from(JSON.stringify({
673
+ type: 'match',
674
+ data: {
675
+ path: { text: 'fileC.txt' },
676
+ line_number: 1,
677
+ lines: { text: 'another world in sub dir\n' },
678
+ },
679
+ }) + '\n'));
680
+ }
681
+ if (onClose) {
682
+ onClose(0);
683
+ }
684
+ }, 0);
685
+ return mockProcess;
686
+ });
687
+ const multiDirGrepTool = new RipGrepTool(multiDirConfig);
688
+ // Search only in the 'sub' directory of the first workspace
689
+ const params = { pattern: 'world', dir_path: 'sub' };
690
+ const invocation = multiDirGrepTool.build(params);
691
+ const result = await invocation.execute(abortSignal);
692
+ // Should only find matches in the specified sub directory
693
+ expect(result.llmContent).toContain('Found 1 match for pattern "world" in path "sub"');
694
+ expect(result.llmContent).toContain('File: fileC.txt');
695
+ expect(result.llmContent).toContain('L1: another world in sub dir');
696
+ // Should not contain matches from second directory
697
+ expect(result.llmContent).not.toContain('test.txt');
698
+ // Clean up
699
+ await fs.rm(secondDir, { recursive: true, force: true });
700
+ });
701
+ });
702
+ describe('abort signal handling', () => {
703
+ it('should handle AbortSignal during search', async () => {
704
+ const controller = new AbortController();
705
+ const params = { pattern: 'world' };
706
+ const invocation = grepTool.build(params);
707
+ controller.abort();
708
+ const result = await invocation.execute(controller.signal);
709
+ expect(result).toBeDefined();
710
+ });
711
+ it('should abort streaming search when signal is triggered', async () => {
712
+ // Setup specific mock for this test - simulate process being killed due to abort
713
+ mockSpawn.mockImplementationOnce(() => {
714
+ const mockProcess = {
715
+ stdout: {
716
+ on: vi.fn(),
717
+ removeListener: vi.fn(),
718
+ },
719
+ stderr: {
720
+ on: vi.fn(),
721
+ removeListener: vi.fn(),
722
+ },
723
+ on: vi.fn(),
724
+ removeListener: vi.fn(),
725
+ kill: vi.fn(),
726
+ };
727
+ // Simulate process being aborted - use setTimeout to ensure handlers are registered first
728
+ setTimeout(() => {
729
+ const closeHandler = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
730
+ if (closeHandler) {
731
+ // Simulate process killed by signal (code is null, signal is SIGTERM)
732
+ closeHandler(null, 'SIGTERM');
733
+ }
734
+ }, 0);
735
+ return mockProcess;
736
+ });
737
+ const controller = new AbortController();
738
+ const params = { pattern: 'test' };
739
+ const invocation = grepTool.build(params);
740
+ // Abort immediately before starting the search
741
+ controller.abort();
742
+ const result = await invocation.execute(controller.signal);
743
+ expect(result.llmContent).toContain('Error during grep search operation: ripgrep exited with code null');
744
+ expect(result.returnDisplay).toContain('Error: ripgrep exited with code null');
745
+ });
746
+ });
747
+ describe('error handling and edge cases', () => {
748
+ it('should handle workspace boundary violations', () => {
749
+ const params = {
750
+ pattern: 'test',
751
+ dir_path: '../outside',
752
+ };
753
+ expect(() => grepTool.build(params)).toThrow(/Path validation failed/);
754
+ });
755
+ it.each([
756
+ {
757
+ name: 'empty directories',
758
+ setup: async () => {
759
+ const emptyDir = path.join(tempRootDir, 'empty');
760
+ await fs.mkdir(emptyDir);
761
+ return { pattern: 'test', dir_path: 'empty' };
762
+ },
763
+ },
764
+ {
765
+ name: 'empty files',
766
+ setup: async () => {
767
+ await fs.writeFile(path.join(tempRootDir, 'empty.txt'), '');
768
+ return { pattern: 'anything' };
769
+ },
770
+ },
771
+ ])('should handle $name gracefully', async ({ setup }) => {
772
+ mockSpawn.mockImplementationOnce(createMockSpawn({ exitCode: 1 }));
773
+ const params = await setup();
774
+ const invocation = grepTool.build(params);
775
+ const result = await invocation.execute(abortSignal);
776
+ expect(result.llmContent).toContain('No matches found');
777
+ });
778
+ it('should handle special characters in file names', async () => {
779
+ const specialFileName = 'file with spaces & symbols!.txt';
780
+ await fs.writeFile(path.join(tempRootDir, specialFileName), 'hello world with special chars');
781
+ // Setup specific mock for this test - searching for 'world' should find the file with special characters
782
+ mockSpawn.mockImplementationOnce(() => {
783
+ const mockProcess = {
784
+ stdout: {
785
+ on: vi.fn(),
786
+ removeListener: vi.fn(),
787
+ },
788
+ stderr: {
789
+ on: vi.fn(),
790
+ removeListener: vi.fn(),
791
+ },
792
+ on: vi.fn(),
793
+ removeListener: vi.fn(),
794
+ kill: vi.fn(),
795
+ };
796
+ setTimeout(() => {
797
+ const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
798
+ const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
799
+ if (onData) {
800
+ onData(Buffer.from(JSON.stringify({
801
+ type: 'match',
802
+ data: {
803
+ path: { text: specialFileName },
804
+ line_number: 1,
805
+ lines: { text: 'hello world with special chars\n' },
806
+ },
807
+ }) + '\n'));
808
+ }
809
+ if (onClose) {
810
+ onClose(0);
811
+ }
812
+ }, 0);
813
+ return mockProcess;
814
+ });
815
+ const params = { pattern: 'world' };
816
+ const invocation = grepTool.build(params);
817
+ const result = await invocation.execute(abortSignal);
818
+ expect(result.llmContent).toContain(specialFileName);
819
+ expect(result.llmContent).toContain('hello world with special chars');
820
+ });
821
+ it('should handle deeply nested directories', async () => {
822
+ const deepPath = path.join(tempRootDir, 'a', 'b', 'c', 'd', 'e');
823
+ await fs.mkdir(deepPath, { recursive: true });
824
+ await fs.writeFile(path.join(deepPath, 'deep.txt'), 'content in deep directory');
825
+ // Setup specific mock for this test - searching for 'deep' should find the deeply nested file
826
+ mockSpawn.mockImplementationOnce(() => {
827
+ const mockProcess = {
828
+ stdout: {
829
+ on: vi.fn(),
830
+ removeListener: vi.fn(),
831
+ },
832
+ stderr: {
833
+ on: vi.fn(),
834
+ removeListener: vi.fn(),
835
+ },
836
+ on: vi.fn(),
837
+ removeListener: vi.fn(),
838
+ kill: vi.fn(),
839
+ };
840
+ setTimeout(() => {
841
+ const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
842
+ const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
843
+ if (onData) {
844
+ onData(Buffer.from(JSON.stringify({
845
+ type: 'match',
846
+ data: {
847
+ path: { text: 'a/b/c/d/e/deep.txt' },
848
+ line_number: 1,
849
+ lines: { text: 'content in deep directory\n' },
850
+ },
851
+ }) + '\n'));
852
+ }
853
+ if (onClose) {
854
+ onClose(0);
855
+ }
856
+ }, 0);
857
+ return mockProcess;
858
+ });
859
+ const params = { pattern: 'deep' };
860
+ const invocation = grepTool.build(params);
861
+ const result = await invocation.execute(abortSignal);
862
+ expect(result.llmContent).toContain('deep.txt');
863
+ expect(result.llmContent).toContain('content in deep directory');
864
+ });
865
+ });
866
+ describe('regex pattern validation', () => {
867
+ it('should handle complex regex patterns', async () => {
868
+ await fs.writeFile(path.join(tempRootDir, 'code.js'), 'function getName() { return "test"; }\nconst getValue = () => "value";');
869
+ // Setup specific mock for this test - regex pattern should match function declarations
870
+ mockSpawn.mockImplementationOnce(() => {
871
+ const mockProcess = {
872
+ stdout: {
873
+ on: vi.fn(),
874
+ removeListener: vi.fn(),
875
+ },
876
+ stderr: {
877
+ on: vi.fn(),
878
+ removeListener: vi.fn(),
879
+ },
880
+ on: vi.fn(),
881
+ removeListener: vi.fn(),
882
+ kill: vi.fn(),
883
+ };
884
+ setTimeout(() => {
885
+ const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
886
+ const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
887
+ if (onData) {
888
+ onData(Buffer.from(JSON.stringify({
889
+ type: 'match',
890
+ data: {
891
+ path: { text: 'code.js' },
892
+ line_number: 1,
893
+ lines: { text: 'function getName() { return "test"; }\n' },
894
+ },
895
+ }) + '\n'));
896
+ }
897
+ if (onClose) {
898
+ onClose(0);
899
+ }
900
+ }, 0);
901
+ return mockProcess;
902
+ });
903
+ const params = { pattern: 'function\\s+\\w+\\s*\\(' };
904
+ const invocation = grepTool.build(params);
905
+ const result = await invocation.execute(abortSignal);
906
+ expect(result.llmContent).toContain('function getName()');
907
+ expect(result.llmContent).not.toContain('const getValue');
908
+ });
909
+ it('should handle case sensitivity correctly in JS fallback', async () => {
910
+ await fs.writeFile(path.join(tempRootDir, 'case.txt'), 'Hello World\nhello world\nHELLO WORLD');
911
+ // Setup specific mock for this test - case insensitive search should match all variants
912
+ mockSpawn.mockImplementationOnce(() => {
913
+ const mockProcess = {
914
+ stdout: {
915
+ on: vi.fn(),
916
+ removeListener: vi.fn(),
917
+ },
918
+ stderr: {
919
+ on: vi.fn(),
920
+ removeListener: vi.fn(),
921
+ },
922
+ on: vi.fn(),
923
+ removeListener: vi.fn(),
924
+ kill: vi.fn(),
925
+ };
926
+ setTimeout(() => {
927
+ const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
928
+ const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
929
+ if (onData) {
930
+ onData(Buffer.from(JSON.stringify({
931
+ type: 'match',
932
+ data: {
933
+ path: { text: 'case.txt' },
934
+ line_number: 1,
935
+ lines: { text: 'Hello World\n' },
936
+ },
937
+ }) +
938
+ '\n' +
939
+ JSON.stringify({
940
+ type: 'match',
941
+ data: {
942
+ path: { text: 'case.txt' },
943
+ line_number: 2,
944
+ lines: { text: 'hello world\n' },
945
+ },
946
+ }) +
947
+ '\n' +
948
+ JSON.stringify({
949
+ type: 'match',
950
+ data: {
951
+ path: { text: 'case.txt' },
952
+ line_number: 3,
953
+ lines: { text: 'HELLO WORLD\n' },
954
+ },
955
+ }) +
956
+ '\n'));
957
+ }
958
+ if (onClose) {
959
+ onClose(0);
960
+ }
961
+ }, 0);
962
+ return mockProcess;
963
+ });
964
+ const params = { pattern: 'hello' };
965
+ const invocation = grepTool.build(params);
966
+ const result = await invocation.execute(abortSignal);
967
+ expect(result.llmContent).toContain('Hello World');
968
+ expect(result.llmContent).toContain('hello world');
969
+ expect(result.llmContent).toContain('HELLO WORLD');
970
+ });
971
+ it('should handle escaped regex special characters', async () => {
972
+ await fs.writeFile(path.join(tempRootDir, 'special.txt'), 'Price: $19.99\nRegex: [a-z]+ pattern\nEmail: test@example.com');
973
+ // Setup specific mock for this test - escaped regex pattern should match price format
974
+ mockSpawn.mockImplementationOnce(() => {
975
+ const mockProcess = {
976
+ stdout: {
977
+ on: vi.fn(),
978
+ removeListener: vi.fn(),
979
+ },
980
+ stderr: {
981
+ on: vi.fn(),
982
+ removeListener: vi.fn(),
983
+ },
984
+ on: vi.fn(),
985
+ removeListener: vi.fn(),
986
+ kill: vi.fn(),
987
+ };
988
+ setTimeout(() => {
989
+ const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
990
+ const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
991
+ if (onData) {
992
+ onData(Buffer.from(JSON.stringify({
993
+ type: 'match',
994
+ data: {
995
+ path: { text: 'special.txt' },
996
+ line_number: 1,
997
+ lines: { text: 'Price: $19.99\n' },
998
+ },
999
+ }) + '\n'));
1000
+ }
1001
+ if (onClose) {
1002
+ onClose(0);
1003
+ }
1004
+ }, 0);
1005
+ return mockProcess;
1006
+ });
1007
+ const params = { pattern: '\\$\\d+\\.\\d+' };
1008
+ const invocation = grepTool.build(params);
1009
+ const result = await invocation.execute(abortSignal);
1010
+ expect(result.llmContent).toContain('Price: $19.99');
1011
+ expect(result.llmContent).not.toContain('Email: test@example.com');
1012
+ });
1013
+ });
1014
+ describe('include pattern filtering', () => {
1015
+ it('should handle multiple file extensions in include pattern', async () => {
1016
+ await fs.writeFile(path.join(tempRootDir, 'test.ts'), 'typescript content');
1017
+ await fs.writeFile(path.join(tempRootDir, 'test.tsx'), 'tsx content');
1018
+ await fs.writeFile(path.join(tempRootDir, 'test.js'), 'javascript content');
1019
+ await fs.writeFile(path.join(tempRootDir, 'test.txt'), 'text content');
1020
+ // Setup specific mock for this test - include pattern should filter to only ts/tsx files
1021
+ mockSpawn.mockImplementationOnce(() => {
1022
+ const mockProcess = {
1023
+ stdout: {
1024
+ on: vi.fn(),
1025
+ removeListener: vi.fn(),
1026
+ },
1027
+ stderr: {
1028
+ on: vi.fn(),
1029
+ removeListener: vi.fn(),
1030
+ },
1031
+ on: vi.fn(),
1032
+ removeListener: vi.fn(),
1033
+ kill: vi.fn(),
1034
+ };
1035
+ setTimeout(() => {
1036
+ const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
1037
+ const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
1038
+ if (onData) {
1039
+ onData(Buffer.from(JSON.stringify({
1040
+ type: 'match',
1041
+ data: {
1042
+ path: { text: 'test.ts' },
1043
+ line_number: 1,
1044
+ lines: { text: 'typescript content\n' },
1045
+ },
1046
+ }) +
1047
+ '\n' +
1048
+ JSON.stringify({
1049
+ type: 'match',
1050
+ data: {
1051
+ path: { text: 'test.tsx' },
1052
+ line_number: 1,
1053
+ lines: { text: 'tsx content\n' },
1054
+ },
1055
+ }) +
1056
+ '\n'));
1057
+ }
1058
+ if (onClose) {
1059
+ onClose(0);
1060
+ }
1061
+ }, 0);
1062
+ return mockProcess;
1063
+ });
1064
+ const params = {
1065
+ pattern: 'content',
1066
+ include: '*.{ts,tsx}',
1067
+ };
1068
+ const invocation = grepTool.build(params);
1069
+ const result = await invocation.execute(abortSignal);
1070
+ expect(result.llmContent).toContain('test.ts');
1071
+ expect(result.llmContent).toContain('test.tsx');
1072
+ expect(result.llmContent).not.toContain('test.js');
1073
+ expect(result.llmContent).not.toContain('test.txt');
1074
+ });
1075
+ it('should handle directory patterns in include', async () => {
1076
+ await fs.mkdir(path.join(tempRootDir, 'src'), { recursive: true });
1077
+ await fs.writeFile(path.join(tempRootDir, 'src', 'main.ts'), 'source code');
1078
+ await fs.writeFile(path.join(tempRootDir, 'other.ts'), 'other code');
1079
+ // Setup specific mock for this test - include pattern should filter to only src/** files
1080
+ mockSpawn.mockImplementationOnce(() => {
1081
+ const mockProcess = {
1082
+ stdout: {
1083
+ on: vi.fn(),
1084
+ removeListener: vi.fn(),
1085
+ },
1086
+ stderr: {
1087
+ on: vi.fn(),
1088
+ removeListener: vi.fn(),
1089
+ },
1090
+ on: vi.fn(),
1091
+ removeListener: vi.fn(),
1092
+ kill: vi.fn(),
1093
+ };
1094
+ setTimeout(() => {
1095
+ const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
1096
+ const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
1097
+ if (onData) {
1098
+ onData(Buffer.from(JSON.stringify({
1099
+ type: 'match',
1100
+ data: {
1101
+ path: { text: 'src/main.ts' },
1102
+ line_number: 1,
1103
+ lines: { text: 'source code\n' },
1104
+ },
1105
+ }) + '\n'));
1106
+ }
1107
+ if (onClose) {
1108
+ onClose(0);
1109
+ }
1110
+ }, 0);
1111
+ return mockProcess;
1112
+ });
1113
+ const params = {
1114
+ pattern: 'code',
1115
+ include: 'src/**',
1116
+ };
1117
+ const invocation = grepTool.build(params);
1118
+ const result = await invocation.execute(abortSignal);
1119
+ expect(result.llmContent).toContain('main.ts');
1120
+ expect(result.llmContent).not.toContain('other.ts');
1121
+ });
1122
+ });
1123
+ describe('advanced search options', () => {
1124
+ it('should handle case_sensitive parameter', async () => {
1125
+ // Case-insensitive search (default)
1126
+ mockSpawn.mockImplementationOnce(createMockSpawn({
1127
+ outputData: JSON.stringify({
1128
+ type: 'match',
1129
+ data: {
1130
+ path: { text: 'fileA.txt' },
1131
+ line_number: 1,
1132
+ lines: { text: 'hello world\n' },
1133
+ },
1134
+ }) + '\n',
1135
+ exitCode: 0,
1136
+ }));
1137
+ let params = { pattern: 'HELLO' };
1138
+ let invocation = grepTool.build(params);
1139
+ let result = await invocation.execute(abortSignal);
1140
+ expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining(['--ignore-case']), expect.anything());
1141
+ expect(result.llmContent).toContain('Found 1 match for pattern "HELLO"');
1142
+ expect(result.llmContent).toContain('L1: hello world');
1143
+ // Case-sensitive search
1144
+ mockSpawn.mockImplementationOnce(createMockSpawn({
1145
+ outputData: JSON.stringify({
1146
+ type: 'match',
1147
+ data: {
1148
+ path: { text: 'fileA.txt' },
1149
+ line_number: 1,
1150
+ lines: { text: 'HELLO world\n' },
1151
+ },
1152
+ }) + '\n',
1153
+ exitCode: 0,
1154
+ }));
1155
+ params = { pattern: 'HELLO', case_sensitive: true };
1156
+ invocation = grepTool.build(params);
1157
+ result = await invocation.execute(abortSignal);
1158
+ expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.not.arrayContaining(['--ignore-case']), expect.anything());
1159
+ expect(result.llmContent).toContain('Found 1 match for pattern "HELLO"');
1160
+ expect(result.llmContent).toContain('L1: HELLO world');
1161
+ });
1162
+ it.each([
1163
+ {
1164
+ name: 'fixed_strings parameter',
1165
+ params: { pattern: 'hello.world', fixed_strings: true },
1166
+ mockOutput: {
1167
+ path: { text: 'fileA.txt' },
1168
+ line_number: 1,
1169
+ lines: { text: 'hello.world\n' },
1170
+ },
1171
+ expectedArgs: ['--fixed-strings'],
1172
+ expectedPattern: 'hello.world',
1173
+ },
1174
+ ])('should handle $name', async ({ params, mockOutput, expectedArgs, expectedPattern }) => {
1175
+ mockSpawn.mockImplementationOnce(createMockSpawn({
1176
+ outputData: JSON.stringify({ type: 'match', data: mockOutput }) + '\n',
1177
+ exitCode: 0,
1178
+ }));
1179
+ const invocation = grepTool.build(params);
1180
+ const result = await invocation.execute(abortSignal);
1181
+ expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining(expectedArgs), expect.anything());
1182
+ expect(result.llmContent).toContain(`Found 1 match for pattern "${expectedPattern}"`);
1183
+ });
1184
+ it('should handle no_ignore parameter', async () => {
1185
+ mockSpawn.mockImplementationOnce(createMockSpawn({
1186
+ outputData: JSON.stringify({
1187
+ type: 'match',
1188
+ data: {
1189
+ path: { text: 'ignored.log' },
1190
+ line_number: 1,
1191
+ lines: { text: 'secret log entry\n' },
1192
+ },
1193
+ }) + '\n',
1194
+ exitCode: 0,
1195
+ }));
1196
+ const params = { pattern: 'secret', no_ignore: true };
1197
+ const invocation = grepTool.build(params);
1198
+ const result = await invocation.execute(abortSignal);
1199
+ expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining(['--no-ignore']), expect.anything());
1200
+ expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.not.arrayContaining(['--glob', '!node_modules']), expect.anything());
1201
+ expect(result.llmContent).toContain('Found 1 match for pattern "secret"');
1202
+ expect(result.llmContent).toContain('File: ignored.log');
1203
+ expect(result.llmContent).toContain('L1: secret log entry');
1204
+ });
1205
+ it('should handle context parameters', async () => {
1206
+ mockSpawn.mockImplementationOnce(createMockSpawn({
1207
+ outputData: JSON.stringify({
1208
+ type: 'match',
1209
+ data: {
1210
+ path: { text: 'fileA.txt' },
1211
+ line_number: 2,
1212
+ lines: { text: 'second line with world\n' },
1213
+ lines_before: [{ text: 'hello world\n' }],
1214
+ lines_after: [
1215
+ { text: 'third line\n' },
1216
+ { text: 'fourth line\n' },
1217
+ ],
1218
+ },
1219
+ }) + '\n',
1220
+ exitCode: 0,
1221
+ }));
1222
+ const params = {
1223
+ pattern: 'world',
1224
+ context: 1,
1225
+ after: 2,
1226
+ before: 1,
1227
+ };
1228
+ const invocation = grepTool.build(params);
1229
+ const result = await invocation.execute(abortSignal);
1230
+ expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining([
1231
+ '--context',
1232
+ '1',
1233
+ '--after-context',
1234
+ '2',
1235
+ '--before-context',
1236
+ '1',
1237
+ ]), expect.anything());
1238
+ expect(result.llmContent).toContain('Found 1 match for pattern "world"');
1239
+ expect(result.llmContent).toContain('File: fileA.txt');
1240
+ expect(result.llmContent).toContain('L2: second line with world');
1241
+ // Note: Ripgrep JSON output for context lines doesn't include line numbers for context lines directly
1242
+ // The current parsing only extracts the matched line, so we only assert on that.
1243
+ });
1244
+ });
1245
+ describe('getDescription', () => {
1246
+ it.each([
1247
+ {
1248
+ name: 'pattern only',
1249
+ params: { pattern: 'testPattern' },
1250
+ expected: "'testPattern' within ./",
1251
+ },
1252
+ {
1253
+ name: 'pattern and include',
1254
+ params: { pattern: 'testPattern', include: '*.ts' },
1255
+ expected: "'testPattern' in *.ts within ./",
1256
+ },
1257
+ {
1258
+ name: 'root path in description',
1259
+ params: { pattern: 'testPattern', dir_path: '.' },
1260
+ expected: "'testPattern' within ./",
1261
+ },
1262
+ ])('should generate correct description with $name', ({ params, expected }) => {
1263
+ const invocation = grepTool.build(params);
1264
+ expect(invocation.getDescription()).toBe(expected);
1265
+ });
1266
+ it('should generate correct description with pattern and path', async () => {
1267
+ const dirPath = path.join(tempRootDir, 'src', 'app');
1268
+ await fs.mkdir(dirPath, { recursive: true });
1269
+ const params = {
1270
+ pattern: 'testPattern',
1271
+ dir_path: path.join('src', 'app'),
1272
+ };
1273
+ const invocation = grepTool.build(params);
1274
+ expect(invocation.getDescription()).toContain("'testPattern' within");
1275
+ expect(invocation.getDescription()).toContain(path.join('src', 'app'));
1276
+ });
1277
+ it('should use ./ when no path is specified (defaults to CWD)', () => {
1278
+ const multiDirConfig = {
1279
+ getTargetDir: () => tempRootDir,
1280
+ getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir, ['/another/dir']),
1281
+ getDebugMode: () => false,
1282
+ };
1283
+ const multiDirGrepTool = new RipGrepTool(multiDirConfig);
1284
+ const params = { pattern: 'testPattern' };
1285
+ const invocation = multiDirGrepTool.build(params);
1286
+ expect(invocation.getDescription()).toBe("'testPattern' within ./");
1287
+ });
1288
+ it('should generate correct description with pattern, include, and path', async () => {
1289
+ const dirPath = path.join(tempRootDir, 'src', 'app');
1290
+ await fs.mkdir(dirPath, { recursive: true });
1291
+ const params = {
1292
+ pattern: 'testPattern',
1293
+ include: '*.ts',
1294
+ dir_path: path.join('src', 'app'),
1295
+ };
1296
+ const invocation = grepTool.build(params);
1297
+ expect(invocation.getDescription()).toContain("'testPattern' in *.ts within");
1298
+ expect(invocation.getDescription()).toContain(path.join('src', 'app'));
1299
+ });
1300
+ });
1301
+ });
1302
+ afterAll(() => {
1303
+ storageSpy.mockRestore();
1304
+ });
1305
+ //# sourceMappingURL=ripGrep.test.js.map