@office-ai/aioncli-core 0.8.1 → 0.18.5

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 (778) hide show
  1. package/dist/index.d.ts +8 -2
  2. package/dist/index.js +7 -2
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/agents/codebase-investigator.d.ts +36 -1
  5. package/dist/src/agents/codebase-investigator.js +93 -34
  6. package/dist/src/agents/codebase-investigator.js.map +1 -1
  7. package/dist/src/agents/codebase-investigator.test.d.ts +6 -0
  8. package/dist/src/agents/codebase-investigator.test.js +35 -0
  9. package/dist/src/agents/codebase-investigator.test.js.map +1 -0
  10. package/dist/src/agents/executor.d.ts +37 -11
  11. package/dist/src/agents/executor.js +512 -150
  12. package/dist/src/agents/executor.js.map +1 -1
  13. package/dist/src/agents/executor.test.js +1188 -245
  14. package/dist/src/agents/executor.test.js.map +1 -1
  15. package/dist/src/agents/invocation.d.ts +5 -2
  16. package/dist/src/agents/invocation.js +4 -2
  17. package/dist/src/agents/invocation.js.map +1 -1
  18. package/dist/src/agents/invocation.test.js +9 -0
  19. package/dist/src/agents/invocation.test.js.map +1 -1
  20. package/dist/src/agents/registry.d.ts +6 -1
  21. package/dist/src/agents/registry.js +51 -4
  22. package/dist/src/agents/registry.js.map +1 -1
  23. package/dist/src/agents/registry.test.js +30 -16
  24. package/dist/src/agents/registry.test.js.map +1 -1
  25. package/dist/src/agents/subagent-tool-wrapper.d.ts +3 -1
  26. package/dist/src/agents/subagent-tool-wrapper.js +4 -3
  27. package/dist/src/agents/subagent-tool-wrapper.js.map +1 -1
  28. package/dist/src/agents/subagent-tool-wrapper.test.js +9 -4
  29. package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -1
  30. package/dist/src/agents/types.d.ts +37 -7
  31. package/dist/src/agents/types.js +2 -0
  32. package/dist/src/agents/types.js.map +1 -1
  33. package/dist/src/code_assist/codeAssist.js +1 -1
  34. package/dist/src/code_assist/codeAssist.test.d.ts +6 -0
  35. package/dist/src/code_assist/codeAssist.test.js +99 -0
  36. package/dist/src/code_assist/codeAssist.test.js.map +1 -0
  37. package/dist/src/code_assist/converter.d.ts +1 -0
  38. package/dist/src/code_assist/converter.js +1 -0
  39. package/dist/src/code_assist/converter.js.map +1 -1
  40. package/dist/src/code_assist/converter.test.js +19 -0
  41. package/dist/src/code_assist/converter.test.js.map +1 -1
  42. package/dist/src/code_assist/experiments/client_metadata.d.ts +12 -0
  43. package/dist/src/code_assist/experiments/client_metadata.js +50 -0
  44. package/dist/src/code_assist/experiments/client_metadata.js.map +1 -0
  45. package/dist/src/code_assist/experiments/client_metadata.test.d.ts +6 -0
  46. package/dist/src/code_assist/experiments/client_metadata.test.js +99 -0
  47. package/dist/src/code_assist/experiments/client_metadata.test.js.map +1 -0
  48. package/dist/src/code_assist/experiments/experiments.d.ts +17 -0
  49. package/dist/src/code_assist/experiments/experiments.js +36 -0
  50. package/dist/src/code_assist/experiments/experiments.js.map +1 -0
  51. package/dist/src/code_assist/experiments/experiments.test.d.ts +6 -0
  52. package/dist/src/code_assist/experiments/experiments.test.js +92 -0
  53. package/dist/src/code_assist/experiments/experiments.test.js.map +1 -0
  54. package/dist/src/code_assist/experiments/flagNames.d.ts +13 -0
  55. package/dist/src/code_assist/experiments/flagNames.js +13 -0
  56. package/dist/src/code_assist/experiments/flagNames.js.map +1 -0
  57. package/dist/src/code_assist/experiments/types.d.ts +35 -0
  58. package/dist/src/code_assist/experiments/types.js +7 -0
  59. package/dist/src/code_assist/experiments/types.js.map +1 -0
  60. package/dist/src/code_assist/oauth-credential-storage.js +6 -5
  61. package/dist/src/code_assist/oauth-credential-storage.js.map +1 -1
  62. package/dist/src/code_assist/oauth-credential-storage.test.js +65 -3
  63. package/dist/src/code_assist/oauth-credential-storage.test.js.map +1 -1
  64. package/dist/src/code_assist/oauth2.d.ts +2 -2
  65. package/dist/src/code_assist/oauth2.js +161 -93
  66. package/dist/src/code_assist/oauth2.js.map +1 -1
  67. package/dist/src/code_assist/oauth2.test.js +103 -57
  68. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  69. package/dist/src/code_assist/server.d.ts +6 -4
  70. package/dist/src/code_assist/server.js +16 -8
  71. package/dist/src/code_assist/server.js.map +1 -1
  72. package/dist/src/code_assist/server.test.js +126 -28
  73. package/dist/src/code_assist/server.test.js.map +1 -1
  74. package/dist/src/code_assist/setup.d.ts +2 -2
  75. package/dist/src/code_assist/setup.js +4 -2
  76. package/dist/src/code_assist/setup.js.map +1 -1
  77. package/dist/src/code_assist/types.d.ts +1 -1
  78. package/dist/src/code_assist/types.js.map +1 -1
  79. package/dist/src/commands/extensions.d.ts +7 -0
  80. package/dist/src/commands/extensions.js +9 -0
  81. package/dist/src/commands/extensions.js.map +1 -0
  82. package/dist/src/commands/extensions.test.d.ts +6 -0
  83. package/dist/src/commands/extensions.test.js +19 -0
  84. package/dist/src/commands/extensions.test.js.map +1 -0
  85. package/dist/src/config/config.d.ts +169 -43
  86. package/dist/src/config/config.js +418 -79
  87. package/dist/src/config/config.js.map +1 -1
  88. package/dist/src/config/config.test.js +684 -49
  89. package/dist/src/config/config.test.js.map +1 -1
  90. package/dist/src/config/defaultModelConfigs.d.ts +7 -0
  91. package/dist/src/config/defaultModelConfigs.js +185 -0
  92. package/dist/src/config/defaultModelConfigs.js.map +1 -0
  93. package/dist/src/config/models.d.ts +23 -2
  94. package/dist/src/config/models.js +50 -7
  95. package/dist/src/config/models.js.map +1 -1
  96. package/dist/src/config/models.test.js +71 -10
  97. package/dist/src/config/models.test.js.map +1 -1
  98. package/dist/src/config/storage.d.ts +3 -1
  99. package/dist/src/config/storage.js +22 -2
  100. package/dist/src/config/storage.js.map +1 -1
  101. package/dist/src/config/storage.test.js +7 -6
  102. package/dist/src/config/storage.test.js.map +1 -1
  103. package/dist/src/confirmation-bus/message-bus.d.ts +3 -2
  104. package/dist/src/confirmation-bus/message-bus.js +9 -3
  105. package/dist/src/confirmation-bus/message-bus.js.map +1 -1
  106. package/dist/src/confirmation-bus/message-bus.test.js +30 -24
  107. package/dist/src/confirmation-bus/message-bus.test.js.map +1 -1
  108. package/dist/src/confirmation-bus/types.d.ts +13 -2
  109. package/dist/src/confirmation-bus/types.js +1 -0
  110. package/dist/src/confirmation-bus/types.js.map +1 -1
  111. package/dist/src/core/apiKeyCredentialStorage.d.ts +17 -0
  112. package/dist/src/core/apiKeyCredentialStorage.js +64 -0
  113. package/dist/src/core/apiKeyCredentialStorage.js.map +1 -0
  114. package/dist/src/core/apiKeyCredentialStorage.test.d.ts +6 -0
  115. package/dist/src/core/apiKeyCredentialStorage.test.js +71 -0
  116. package/dist/src/core/apiKeyCredentialStorage.test.js.map +1 -0
  117. package/dist/src/core/baseLlmClient.d.ts +4 -8
  118. package/dist/src/core/baseLlmClient.js +6 -11
  119. package/dist/src/core/baseLlmClient.js.map +1 -1
  120. package/dist/src/core/baseLlmClient.test.js +22 -27
  121. package/dist/src/core/baseLlmClient.test.js.map +1 -1
  122. package/dist/src/core/client.d.ts +12 -19
  123. package/dist/src/core/client.js +104 -206
  124. package/dist/src/core/client.js.map +1 -1
  125. package/dist/src/core/client.test.js +329 -452
  126. package/dist/src/core/client.test.js.map +1 -1
  127. package/dist/src/core/contentGenerator.d.ts +3 -2
  128. package/dist/src/core/contentGenerator.js +56 -41
  129. package/dist/src/core/contentGenerator.js.map +1 -1
  130. package/dist/src/core/contentGenerator.test.js +49 -1
  131. package/dist/src/core/contentGenerator.test.js.map +1 -1
  132. package/dist/src/core/coreToolScheduler.d.ts +8 -4
  133. package/dist/src/core/coreToolScheduler.js +348 -179
  134. package/dist/src/core/coreToolScheduler.js.map +1 -1
  135. package/dist/src/core/coreToolScheduler.test.js +575 -219
  136. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  137. package/dist/src/core/fakeContentGenerator.d.ts +33 -0
  138. package/dist/src/core/fakeContentGenerator.js +58 -0
  139. package/dist/src/core/fakeContentGenerator.js.map +1 -0
  140. package/dist/src/core/fakeContentGenerator.test.d.ts +6 -0
  141. package/dist/src/core/fakeContentGenerator.test.js +127 -0
  142. package/dist/src/core/fakeContentGenerator.test.js.map +1 -0
  143. package/dist/src/core/geminiChat.d.ts +23 -18
  144. package/dist/src/core/geminiChat.js +186 -108
  145. package/dist/src/core/geminiChat.js.map +1 -1
  146. package/dist/src/core/geminiChat.test.js +581 -270
  147. package/dist/src/core/geminiChat.test.js.map +1 -1
  148. package/dist/src/core/logger.d.ts +7 -2
  149. package/dist/src/core/logger.js +35 -27
  150. package/dist/src/core/logger.js.map +1 -1
  151. package/dist/src/core/logger.test.js +45 -29
  152. package/dist/src/core/logger.test.js.map +1 -1
  153. package/dist/src/core/loggingContentGenerator.d.ts +1 -0
  154. package/dist/src/core/loggingContentGenerator.js +113 -33
  155. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  156. package/dist/src/core/loggingContentGenerator.test.d.ts +6 -0
  157. package/dist/src/core/loggingContentGenerator.test.js +180 -0
  158. package/dist/src/core/loggingContentGenerator.test.js.map +1 -0
  159. package/dist/src/core/nonInteractiveToolExecutor.d.ts +3 -2
  160. package/dist/src/core/nonInteractiveToolExecutor.js +12 -7
  161. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
  162. package/dist/src/core/nonInteractiveToolExecutor.test.js +12 -8
  163. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  164. package/dist/src/core/openaiContentGenerator.d.ts +15 -1
  165. package/dist/src/core/openaiContentGenerator.js +139 -22
  166. package/dist/src/core/openaiContentGenerator.js.map +1 -1
  167. package/dist/src/core/prompts.d.ts +2 -1
  168. package/dist/src/core/prompts.js +135 -154
  169. package/dist/src/core/prompts.js.map +1 -1
  170. package/dist/src/core/prompts.test.js +128 -189
  171. package/dist/src/core/prompts.test.js.map +1 -1
  172. package/dist/src/core/recordingContentGenerator.d.ts +18 -0
  173. package/dist/src/core/recordingContentGenerator.js +77 -0
  174. package/dist/src/core/recordingContentGenerator.js.map +1 -0
  175. package/dist/src/core/recordingContentGenerator.test.d.ts +6 -0
  176. package/dist/src/core/recordingContentGenerator.test.js +101 -0
  177. package/dist/src/core/recordingContentGenerator.test.js.map +1 -0
  178. package/dist/src/core/tokenLimits.test.d.ts +6 -0
  179. package/dist/src/core/tokenLimits.test.js +26 -0
  180. package/dist/src/core/tokenLimits.test.js.map +1 -0
  181. package/dist/src/core/turn.d.ts +23 -3
  182. package/dist/src/core/turn.js +18 -9
  183. package/dist/src/core/turn.js.map +1 -1
  184. package/dist/src/core/turn.test.js +98 -104
  185. package/dist/src/core/turn.test.js.map +1 -1
  186. package/dist/src/fallback/handler.js +60 -8
  187. package/dist/src/fallback/handler.js.map +1 -1
  188. package/dist/src/fallback/handler.test.js +132 -17
  189. package/dist/src/fallback/handler.test.js.map +1 -1
  190. package/dist/src/fallback/types.d.ts +1 -1
  191. package/dist/src/generated/git-commit.d.ts +2 -2
  192. package/dist/src/generated/git-commit.js +2 -2
  193. package/dist/src/generated/git-commit.js.map +1 -1
  194. package/dist/src/hooks/hookAggregator.d.ts +68 -0
  195. package/dist/src/hooks/hookAggregator.js +262 -0
  196. package/dist/src/hooks/hookAggregator.js.map +1 -0
  197. package/dist/src/hooks/hookAggregator.test.d.ts +6 -0
  198. package/dist/src/hooks/hookAggregator.test.js +387 -0
  199. package/dist/src/hooks/hookAggregator.test.js.map +1 -0
  200. package/dist/src/hooks/hookPlanner.d.ts +46 -0
  201. package/dist/src/hooks/hookPlanner.js +108 -0
  202. package/dist/src/hooks/hookPlanner.js.map +1 -0
  203. package/dist/src/hooks/hookPlanner.test.d.ts +6 -0
  204. package/dist/src/hooks/hookPlanner.test.js +255 -0
  205. package/dist/src/hooks/hookPlanner.test.js.map +1 -0
  206. package/dist/src/hooks/hookRegistry.d.ts +87 -0
  207. package/dist/src/hooks/hookRegistry.js +198 -0
  208. package/dist/src/hooks/hookRegistry.js.map +1 -0
  209. package/dist/src/hooks/hookRegistry.test.d.ts +6 -0
  210. package/dist/src/hooks/hookRegistry.test.js +341 -0
  211. package/dist/src/hooks/hookRegistry.test.js.map +1 -0
  212. package/dist/src/hooks/hookRunner.d.ts +42 -0
  213. package/dist/src/hooks/hookRunner.js +272 -0
  214. package/dist/src/hooks/hookRunner.js.map +1 -0
  215. package/dist/src/hooks/hookRunner.test.d.ts +6 -0
  216. package/dist/src/hooks/hookRunner.test.js +468 -0
  217. package/dist/src/hooks/hookRunner.test.js.map +1 -0
  218. package/dist/src/hooks/hookTranslator.d.ts +113 -0
  219. package/dist/src/hooks/hookTranslator.js +232 -0
  220. package/dist/src/hooks/hookTranslator.js.map +1 -0
  221. package/dist/src/hooks/hookTranslator.test.d.ts +6 -0
  222. package/dist/src/hooks/hookTranslator.test.js +192 -0
  223. package/dist/src/hooks/hookTranslator.test.js.map +1 -0
  224. package/dist/src/hooks/types.d.ts +384 -0
  225. package/dist/src/hooks/types.js +284 -0
  226. package/dist/src/hooks/types.js.map +1 -0
  227. package/dist/src/hooks/types.test.d.ts +6 -0
  228. package/dist/src/hooks/types.test.js +313 -0
  229. package/dist/src/hooks/types.test.js.map +1 -0
  230. package/dist/src/ide/detect-ide.d.ts +4 -0
  231. package/dist/src/ide/detect-ide.js +6 -1
  232. package/dist/src/ide/detect-ide.js.map +1 -1
  233. package/dist/src/ide/detect-ide.test.js +16 -0
  234. package/dist/src/ide/detect-ide.test.js.map +1 -1
  235. package/dist/src/ide/ide-client.d.ts +3 -1
  236. package/dist/src/ide/ide-client.js +12 -10
  237. package/dist/src/ide/ide-client.js.map +1 -1
  238. package/dist/src/ide/ide-client.test.js +163 -4
  239. package/dist/src/ide/ide-client.test.js.map +1 -1
  240. package/dist/src/ide/ide-installer.js +66 -21
  241. package/dist/src/ide/ide-installer.js.map +1 -1
  242. package/dist/src/ide/ide-installer.test.js +54 -1
  243. package/dist/src/ide/ide-installer.test.js.map +1 -1
  244. package/dist/src/ide/process-utils.js +85 -75
  245. package/dist/src/ide/process-utils.js.map +1 -1
  246. package/dist/src/ide/process-utils.test.js +83 -90
  247. package/dist/src/ide/process-utils.test.js.map +1 -1
  248. package/dist/src/ide/types.d.ts +5 -5
  249. package/dist/src/ide/types.js +1 -1
  250. package/dist/src/index.d.ts +21 -0
  251. package/dist/src/index.js +24 -0
  252. package/dist/src/index.js.map +1 -1
  253. package/dist/src/mcp/google-auth-provider.d.ts +2 -0
  254. package/dist/src/mcp/google-auth-provider.js +21 -3
  255. package/dist/src/mcp/google-auth-provider.js.map +1 -1
  256. package/dist/src/mcp/google-auth-provider.test.js +42 -9
  257. package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
  258. package/dist/src/mcp/oauth-provider.d.ts +8 -5
  259. package/dist/src/mcp/oauth-provider.js +140 -55
  260. package/dist/src/mcp/oauth-provider.js.map +1 -1
  261. package/dist/src/mcp/oauth-provider.test.js +369 -2
  262. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  263. package/dist/src/mcp/oauth-token-storage.js +5 -4
  264. package/dist/src/mcp/oauth-token-storage.js.map +1 -1
  265. package/dist/src/mcp/oauth-token-storage.test.js +17 -11
  266. package/dist/src/mcp/oauth-token-storage.test.js.map +1 -1
  267. package/dist/src/mcp/oauth-utils.d.ts +7 -0
  268. package/dist/src/mcp/oauth-utils.js +28 -8
  269. package/dist/src/mcp/oauth-utils.js.map +1 -1
  270. package/dist/src/mcp/oauth-utils.test.js +45 -2
  271. package/dist/src/mcp/oauth-utils.test.js.map +1 -1
  272. package/dist/src/mcp/sa-impersonation-provider.d.ts +0 -6
  273. package/dist/src/mcp/sa-impersonation-provider.js +6 -23
  274. package/dist/src/mcp/sa-impersonation-provider.js.map +1 -1
  275. package/dist/src/mcp/token-storage/base-token-storage.test.js +75 -84
  276. package/dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -1
  277. package/dist/src/mcp/token-storage/file-token-storage.js +3 -2
  278. package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -1
  279. package/dist/src/mcp/token-storage/file-token-storage.test.js +11 -8
  280. package/dist/src/mcp/token-storage/file-token-storage.test.js.map +1 -1
  281. package/dist/src/mcp/token-storage/keychain-token-storage.d.ts +6 -2
  282. package/dist/src/mcp/token-storage/keychain-token-storage.js +63 -7
  283. package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -1
  284. package/dist/src/mcp/token-storage/keychain-token-storage.test.js +54 -3
  285. package/dist/src/mcp/token-storage/keychain-token-storage.test.js.map +1 -1
  286. package/dist/src/mcp/token-storage/types.d.ts +6 -0
  287. package/dist/src/mcp/token-storage/types.js.map +1 -1
  288. package/dist/src/output/stream-json-formatter.d.ts +32 -0
  289. package/dist/src/output/stream-json-formatter.js +52 -0
  290. package/dist/src/output/stream-json-formatter.js.map +1 -0
  291. package/dist/src/output/stream-json-formatter.test.d.ts +6 -0
  292. package/dist/src/output/stream-json-formatter.test.js +479 -0
  293. package/dist/src/output/stream-json-formatter.test.js.map +1 -0
  294. package/dist/src/output/types.d.ts +63 -1
  295. package/dist/src/output/types.js +11 -0
  296. package/dist/src/output/types.js.map +1 -1
  297. package/dist/src/policy/config.d.ts +31 -0
  298. package/dist/src/policy/config.js +199 -0
  299. package/dist/src/policy/config.js.map +1 -0
  300. package/dist/src/policy/config.test.d.ts +6 -0
  301. package/dist/src/policy/config.test.js +538 -0
  302. package/dist/src/policy/config.test.js.map +1 -0
  303. package/dist/src/policy/index.d.ts +2 -0
  304. package/dist/src/policy/index.js +2 -0
  305. package/dist/src/policy/index.js.map +1 -1
  306. package/dist/src/policy/policies/discovered.toml +8 -0
  307. package/dist/src/policy/policies/read-only.toml +56 -0
  308. package/dist/src/policy/policies/write.toml +73 -0
  309. package/dist/src/policy/policies/yolo.toml +31 -0
  310. package/dist/src/policy/policy-engine.d.ts +12 -3
  311. package/dist/src/policy/policy-engine.js +74 -8
  312. package/dist/src/policy/policy-engine.js.map +1 -1
  313. package/dist/src/policy/policy-engine.test.js +460 -76
  314. package/dist/src/policy/policy-engine.test.js.map +1 -1
  315. package/dist/src/policy/toml-loader.d.ts +47 -0
  316. package/dist/src/policy/toml-loader.js +411 -0
  317. package/dist/src/policy/toml-loader.js.map +1 -0
  318. package/dist/src/policy/toml-loader.test.d.ts +6 -0
  319. package/dist/src/policy/toml-loader.test.js +376 -0
  320. package/dist/src/policy/toml-loader.test.js.map +1 -0
  321. package/dist/src/policy/types.d.ts +83 -0
  322. package/dist/src/policy/types.js +10 -0
  323. package/dist/src/policy/types.js.map +1 -1
  324. package/dist/src/prompts/mcp-prompts.test.d.ts +6 -0
  325. package/dist/src/prompts/mcp-prompts.test.js +39 -0
  326. package/dist/src/prompts/mcp-prompts.test.js.map +1 -0
  327. package/dist/src/prompts/prompt-registry.js +2 -1
  328. package/dist/src/prompts/prompt-registry.js.map +1 -1
  329. package/dist/src/prompts/prompt-registry.test.d.ts +6 -0
  330. package/dist/src/prompts/prompt-registry.test.js +96 -0
  331. package/dist/src/prompts/prompt-registry.test.js.map +1 -0
  332. package/dist/src/routing/modelRouterService.js +15 -0
  333. package/dist/src/routing/modelRouterService.js.map +1 -1
  334. package/dist/src/routing/modelRouterService.test.js +62 -0
  335. package/dist/src/routing/modelRouterService.test.js.map +1 -1
  336. package/dist/src/routing/strategies/classifierStrategy.d.ts +1 -1
  337. package/dist/src/routing/strategies/classifierStrategy.js +9 -16
  338. package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
  339. package/dist/src/routing/strategies/classifierStrategy.test.js +17 -13
  340. package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -1
  341. package/dist/src/routing/strategies/fallbackStrategy.js +1 -1
  342. package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -1
  343. package/dist/src/routing/strategies/fallbackStrategy.test.js +4 -0
  344. package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -1
  345. package/dist/src/routing/strategies/overrideStrategy.js +2 -2
  346. package/dist/src/routing/strategies/overrideStrategy.js.map +1 -1
  347. package/dist/src/routing/strategies/overrideStrategy.test.js +3 -0
  348. package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -1
  349. package/dist/src/safety/built-in.d.ts +21 -0
  350. package/dist/src/safety/built-in.js +106 -0
  351. package/dist/src/safety/built-in.js.map +1 -0
  352. package/dist/src/safety/built-in.test.d.ts +6 -0
  353. package/dist/src/safety/built-in.test.js +199 -0
  354. package/dist/src/safety/built-in.test.js.map +1 -0
  355. package/dist/src/safety/checker-runner.d.ts +48 -0
  356. package/dist/src/safety/checker-runner.js +208 -0
  357. package/dist/src/safety/checker-runner.js.map +1 -0
  358. package/dist/src/safety/checker-runner.test.d.ts +6 -0
  359. package/dist/src/safety/checker-runner.test.js +238 -0
  360. package/dist/src/safety/checker-runner.test.js.map +1 -0
  361. package/dist/src/safety/context-builder.d.ts +23 -0
  362. package/dist/src/safety/context-builder.js +47 -0
  363. package/dist/src/safety/context-builder.js.map +1 -0
  364. package/dist/src/safety/context-builder.test.d.ts +6 -0
  365. package/dist/src/safety/context-builder.test.js +49 -0
  366. package/dist/src/safety/context-builder.test.js.map +1 -0
  367. package/dist/src/safety/protocol.d.ts +88 -0
  368. package/dist/src/safety/protocol.js +15 -0
  369. package/dist/src/safety/protocol.js.map +1 -0
  370. package/dist/src/safety/registry.d.ts +26 -0
  371. package/dist/src/safety/registry.js +65 -0
  372. package/dist/src/safety/registry.js.map +1 -0
  373. package/dist/src/safety/registry.test.d.ts +6 -0
  374. package/dist/src/safety/registry.test.js +31 -0
  375. package/dist/src/safety/registry.test.js.map +1 -0
  376. package/dist/src/services/chatCompressionService.d.ts +32 -0
  377. package/dist/src/services/chatCompressionService.js +162 -0
  378. package/dist/src/services/chatCompressionService.js.map +1 -0
  379. package/dist/src/services/chatCompressionService.test.d.ts +6 -0
  380. package/dist/src/services/chatCompressionService.test.js +210 -0
  381. package/dist/src/services/chatCompressionService.test.js.map +1 -0
  382. package/dist/src/services/chatRecordingService.d.ts +3 -2
  383. package/dist/src/services/chatRecordingService.js +11 -9
  384. package/dist/src/services/chatRecordingService.js.map +1 -1
  385. package/dist/src/services/fileDiscoveryService.d.ts +2 -14
  386. package/dist/src/services/fileDiscoveryService.js +19 -55
  387. package/dist/src/services/fileDiscoveryService.js.map +1 -1
  388. package/dist/src/services/fileDiscoveryService.test.js +91 -11
  389. package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
  390. package/dist/src/services/loopDetectionService.d.ts +4 -1
  391. package/dist/src/services/loopDetectionService.js +95 -42
  392. package/dist/src/services/loopDetectionService.js.map +1 -1
  393. package/dist/src/services/loopDetectionService.test.js +220 -12
  394. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  395. package/dist/src/services/modelConfig.golden.test.d.ts +6 -0
  396. package/dist/src/services/modelConfig.golden.test.js +42 -0
  397. package/dist/src/services/modelConfig.golden.test.js.map +1 -0
  398. package/dist/src/services/modelConfig.integration.test.d.ts +6 -0
  399. package/dist/src/services/modelConfig.integration.test.js +247 -0
  400. package/dist/src/services/modelConfig.integration.test.js.map +1 -0
  401. package/dist/src/services/modelConfigService.d.ts +48 -0
  402. package/dist/src/services/modelConfigService.js +151 -0
  403. package/dist/src/services/modelConfigService.js.map +1 -0
  404. package/dist/src/services/modelConfigService.test.d.ts +6 -0
  405. package/dist/src/services/modelConfigService.test.js +531 -0
  406. package/dist/src/services/modelConfigService.test.js.map +1 -0
  407. package/dist/src/services/shellExecutionService.d.ts +1 -0
  408. package/dist/src/services/shellExecutionService.js +195 -92
  409. package/dist/src/services/shellExecutionService.js.map +1 -1
  410. package/dist/src/services/shellExecutionService.test.js +137 -14
  411. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  412. package/dist/src/services/test-data/resolved-aliases.golden.json +202 -0
  413. package/dist/src/telemetry/activity-monitor.d.ts +116 -0
  414. package/dist/src/telemetry/activity-monitor.js +209 -0
  415. package/dist/src/telemetry/activity-monitor.js.map +1 -0
  416. package/dist/src/telemetry/activity-monitor.test.d.ts +6 -0
  417. package/dist/src/telemetry/activity-monitor.test.js +251 -0
  418. package/dist/src/telemetry/activity-monitor.test.js.map +1 -0
  419. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +25 -7
  420. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +294 -76
  421. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  422. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +1 -0
  423. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +192 -66
  424. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  425. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +25 -3
  426. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +59 -5
  427. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  428. package/dist/src/telemetry/constants.d.ts +0 -28
  429. package/dist/src/telemetry/constants.js +0 -29
  430. package/dist/src/telemetry/constants.js.map +1 -1
  431. package/dist/src/telemetry/gcp-exporters.js +0 -1
  432. package/dist/src/telemetry/gcp-exporters.js.map +1 -1
  433. package/dist/src/telemetry/gcp-exporters.test.js +1 -1
  434. package/dist/src/telemetry/gcp-exporters.test.js.map +1 -1
  435. package/dist/src/telemetry/index.d.ts +7 -3
  436. package/dist/src/telemetry/index.js +13 -4
  437. package/dist/src/telemetry/index.js.map +1 -1
  438. package/dist/src/telemetry/loggers.d.ts +14 -7
  439. package/dist/src/telemetry/loggers.js +197 -320
  440. package/dist/src/telemetry/loggers.js.map +1 -1
  441. package/dist/src/telemetry/loggers.test.circular.js +0 -1
  442. package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
  443. package/dist/src/telemetry/loggers.test.js +460 -59
  444. package/dist/src/telemetry/loggers.test.js.map +1 -1
  445. package/dist/src/telemetry/memory-monitor.d.ts +149 -0
  446. package/dist/src/telemetry/memory-monitor.js +335 -0
  447. package/dist/src/telemetry/memory-monitor.js.map +1 -0
  448. package/dist/src/telemetry/memory-monitor.test.d.ts +6 -0
  449. package/dist/src/telemetry/memory-monitor.test.js +472 -0
  450. package/dist/src/telemetry/memory-monitor.test.js.map +1 -0
  451. package/dist/src/telemetry/metrics.d.ts +180 -4
  452. package/dist/src/telemetry/metrics.js +270 -6
  453. package/dist/src/telemetry/metrics.js.map +1 -1
  454. package/dist/src/telemetry/metrics.test.js +502 -184
  455. package/dist/src/telemetry/metrics.test.js.map +1 -1
  456. package/dist/src/telemetry/sdk.js +3 -2
  457. package/dist/src/telemetry/sdk.js.map +1 -1
  458. package/dist/src/telemetry/semantic.d.ts +82 -0
  459. package/dist/src/telemetry/semantic.js +269 -0
  460. package/dist/src/telemetry/semantic.js.map +1 -0
  461. package/dist/src/telemetry/semantic.test.d.ts +6 -0
  462. package/dist/src/telemetry/semantic.test.js +387 -0
  463. package/dist/src/telemetry/semantic.test.js.map +1 -0
  464. package/dist/src/telemetry/telemetry-utils.test.js +29 -28
  465. package/dist/src/telemetry/telemetry-utils.test.js.map +1 -1
  466. package/dist/src/telemetry/telemetryAttributes.d.ts +8 -0
  467. package/dist/src/telemetry/telemetryAttributes.js +19 -0
  468. package/dist/src/telemetry/telemetryAttributes.js.map +1 -0
  469. package/dist/src/telemetry/trace.d.ts +46 -0
  470. package/dist/src/telemetry/trace.js +121 -0
  471. package/dist/src/telemetry/trace.js.map +1 -0
  472. package/dist/src/telemetry/types.d.ts +227 -29
  473. package/dist/src/telemetry/types.js +858 -72
  474. package/dist/src/telemetry/types.js.map +1 -1
  475. package/dist/src/telemetry/uiTelemetry.d.ts +1 -1
  476. package/dist/src/telemetry/uiTelemetry.js +7 -7
  477. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  478. package/dist/src/telemetry/uiTelemetry.test.js +89 -67
  479. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  480. package/dist/src/test-utils/config.d.ts +1 -1
  481. package/dist/src/test-utils/config.js +1 -1
  482. package/dist/src/tools/base-tool-invocation.test.d.ts +6 -0
  483. package/dist/src/tools/base-tool-invocation.test.js +85 -0
  484. package/dist/src/tools/base-tool-invocation.test.js.map +1 -0
  485. package/dist/src/tools/edit.d.ts +4 -3
  486. package/dist/src/tools/edit.js +50 -47
  487. package/dist/src/tools/edit.js.map +1 -1
  488. package/dist/src/tools/edit.test.js +306 -216
  489. package/dist/src/tools/edit.test.js.map +1 -1
  490. package/dist/src/tools/glob.d.ts +4 -3
  491. package/dist/src/tools/glob.js +24 -27
  492. package/dist/src/tools/glob.js.map +1 -1
  493. package/dist/src/tools/glob.test.js +212 -205
  494. package/dist/src/tools/glob.test.js.map +1 -1
  495. package/dist/src/tools/grep.d.ts +4 -3
  496. package/dist/src/tools/grep.js +31 -25
  497. package/dist/src/tools/grep.js.map +1 -1
  498. package/dist/src/tools/grep.test.js +15 -12
  499. package/dist/src/tools/grep.test.js.map +1 -1
  500. package/dist/src/tools/ls.d.ts +4 -3
  501. package/dist/src/tools/ls.js +29 -35
  502. package/dist/src/tools/ls.js.map +1 -1
  503. package/dist/src/tools/ls.test.js +34 -42
  504. package/dist/src/tools/ls.test.js.map +1 -1
  505. package/dist/src/tools/mcp-client-manager.d.ts +49 -11
  506. package/dist/src/tools/mcp-client-manager.js +191 -31
  507. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  508. package/dist/src/tools/mcp-client-manager.test.js +132 -25
  509. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  510. package/dist/src/tools/mcp-client.d.ts +12 -5
  511. package/dist/src/tools/mcp-client.js +287 -267
  512. package/dist/src/tools/mcp-client.js.map +1 -1
  513. package/dist/src/tools/mcp-client.test.js +352 -45
  514. package/dist/src/tools/mcp-client.test.js.map +1 -1
  515. package/dist/src/tools/mcp-tool.d.ts +6 -2
  516. package/dist/src/tools/mcp-tool.js +19 -8
  517. package/dist/src/tools/mcp-tool.js.map +1 -1
  518. package/dist/src/tools/mcp-tool.test.js +186 -273
  519. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  520. package/dist/src/tools/memoryTool.d.ts +7 -5
  521. package/dist/src/tools/memoryTool.js +14 -12
  522. package/dist/src/tools/memoryTool.js.map +1 -1
  523. package/dist/src/tools/memoryTool.test.js +10 -9
  524. package/dist/src/tools/memoryTool.test.js.map +1 -1
  525. package/dist/src/tools/message-bus-integration.test.js +14 -1
  526. package/dist/src/tools/message-bus-integration.test.js.map +1 -1
  527. package/dist/src/tools/modifiable-tool.d.ts +5 -1
  528. package/dist/src/tools/modifiable-tool.js +38 -16
  529. package/dist/src/tools/modifiable-tool.js.map +1 -1
  530. package/dist/src/tools/modifiable-tool.test.js +66 -31
  531. package/dist/src/tools/modifiable-tool.test.js.map +1 -1
  532. package/dist/src/tools/read-file.d.ts +6 -5
  533. package/dist/src/tools/read-file.js +26 -32
  534. package/dist/src/tools/read-file.js.map +1 -1
  535. package/dist/src/tools/read-file.test.js +68 -33
  536. package/dist/src/tools/read-file.test.js.map +1 -1
  537. package/dist/src/tools/read-many-files.d.ts +6 -12
  538. package/dist/src/tools/read-many-files.js +28 -57
  539. package/dist/src/tools/read-many-files.js.map +1 -1
  540. package/dist/src/tools/read-many-files.test.js +37 -36
  541. package/dist/src/tools/read-many-files.test.js.map +1 -1
  542. package/dist/src/tools/ripGrep.d.ts +28 -10
  543. package/dist/src/tools/ripGrep.js +195 -193
  544. package/dist/src/tools/ripGrep.js.map +1 -1
  545. package/dist/src/tools/ripGrep.test.js +533 -204
  546. package/dist/src/tools/ripGrep.test.js.map +1 -1
  547. package/dist/src/tools/shell.d.ts +8 -6
  548. package/dist/src/tools/shell.js +64 -38
  549. package/dist/src/tools/shell.js.map +1 -1
  550. package/dist/src/tools/shell.test.js +134 -43
  551. package/dist/src/tools/shell.test.js.map +1 -1
  552. package/dist/src/tools/smart-edit.d.ts +10 -23
  553. package/dist/src/tools/smart-edit.js +100 -85
  554. package/dist/src/tools/smart-edit.js.map +1 -1
  555. package/dist/src/tools/smart-edit.test.js +229 -179
  556. package/dist/src/tools/smart-edit.test.js.map +1 -1
  557. package/dist/src/tools/tool-error.d.ts +21 -0
  558. package/dist/src/tools/tool-error.js +27 -0
  559. package/dist/src/tools/tool-error.js.map +1 -1
  560. package/dist/src/tools/tool-names.d.ts +17 -0
  561. package/dist/src/tools/tool-names.js +21 -0
  562. package/dist/src/tools/tool-names.js.map +1 -0
  563. package/dist/src/tools/tool-registry.d.ts +32 -20
  564. package/dist/src/tools/tool-registry.js +122 -78
  565. package/dist/src/tools/tool-registry.js.map +1 -1
  566. package/dist/src/tools/tool-registry.test.js +167 -90
  567. package/dist/src/tools/tool-registry.test.js.map +1 -1
  568. package/dist/src/tools/tools.d.ts +23 -8
  569. package/dist/src/tools/tools.js +69 -37
  570. package/dist/src/tools/tools.js.map +1 -1
  571. package/dist/src/tools/web-fetch.d.ts +11 -3
  572. package/dist/src/tools/web-fetch.js +80 -38
  573. package/dist/src/tools/web-fetch.js.map +1 -1
  574. package/dist/src/tools/web-fetch.test.js +338 -9
  575. package/dist/src/tools/web-fetch.test.js.map +1 -1
  576. package/dist/src/tools/web-search.d.ts +4 -3
  577. package/dist/src/tools/web-search.js +11 -9
  578. package/dist/src/tools/web-search.js.map +1 -1
  579. package/dist/src/tools/web-search.test.js +6 -0
  580. package/dist/src/tools/web-search.test.js.map +1 -1
  581. package/dist/src/tools/write-file.d.ts +3 -2
  582. package/dist/src/tools/write-file.js +41 -40
  583. package/dist/src/tools/write-file.js.map +1 -1
  584. package/dist/src/tools/write-file.test.js +130 -123
  585. package/dist/src/tools/write-file.test.js.map +1 -1
  586. package/dist/src/tools/write-todos.d.ts +34 -9
  587. package/dist/src/tools/write-todos.js +54 -11
  588. package/dist/src/tools/write-todos.js.map +1 -1
  589. package/dist/src/tools/write-todos.test.js +2 -2
  590. package/dist/src/tools/write-todos.test.js.map +1 -1
  591. package/dist/src/utils/bfsFileSearch.js +3 -2
  592. package/dist/src/utils/bfsFileSearch.js.map +1 -1
  593. package/dist/src/utils/channel.d.ts +19 -0
  594. package/dist/src/utils/channel.js +49 -0
  595. package/dist/src/utils/channel.js.map +1 -0
  596. package/dist/src/utils/channel.test.d.ts +6 -0
  597. package/dist/src/utils/channel.test.js +170 -0
  598. package/dist/src/utils/channel.test.js.map +1 -0
  599. package/dist/src/utils/debugLogger.d.ts +25 -0
  600. package/dist/src/utils/debugLogger.js +33 -0
  601. package/dist/src/utils/debugLogger.js.map +1 -0
  602. package/dist/src/utils/debugLogger.test.d.ts +6 -0
  603. package/dist/src/utils/debugLogger.test.js +69 -0
  604. package/dist/src/utils/debugLogger.test.js.map +1 -0
  605. package/dist/src/utils/delay.d.ts +16 -0
  606. package/dist/src/utils/delay.js +43 -0
  607. package/dist/src/utils/delay.js.map +1 -0
  608. package/dist/src/utils/delay.test.d.ts +6 -0
  609. package/dist/src/utils/delay.test.js +88 -0
  610. package/dist/src/utils/delay.test.js.map +1 -0
  611. package/dist/src/utils/editCorrector.js +10 -25
  612. package/dist/src/utils/editCorrector.js.map +1 -1
  613. package/dist/src/utils/editCorrector.test.js +19 -5
  614. package/dist/src/utils/editCorrector.test.js.map +1 -1
  615. package/dist/src/utils/editor.d.ts +4 -2
  616. package/dist/src/utils/editor.js +53 -39
  617. package/dist/src/utils/editor.js.map +1 -1
  618. package/dist/src/utils/editor.test.js +18 -45
  619. package/dist/src/utils/editor.test.js.map +1 -1
  620. package/dist/src/utils/environmentContext.d.ts +2 -1
  621. package/dist/src/utils/environmentContext.js +20 -33
  622. package/dist/src/utils/environmentContext.js.map +1 -1
  623. package/dist/src/utils/environmentContext.test.js +6 -34
  624. package/dist/src/utils/environmentContext.test.js.map +1 -1
  625. package/dist/src/utils/errorParsing.d.ts +1 -1
  626. package/dist/src/utils/errorParsing.js +5 -33
  627. package/dist/src/utils/errorParsing.js.map +1 -1
  628. package/dist/src/utils/errorParsing.test.js +0 -88
  629. package/dist/src/utils/errorParsing.test.js.map +1 -1
  630. package/dist/src/utils/errors.d.ts +3 -0
  631. package/dist/src/utils/errors.js +6 -0
  632. package/dist/src/utils/errors.js.map +1 -1
  633. package/dist/src/utils/events.d.ts +121 -0
  634. package/dist/src/utils/events.js +84 -0
  635. package/dist/src/utils/events.js.map +1 -0
  636. package/dist/src/utils/events.test.d.ts +6 -0
  637. package/dist/src/utils/events.test.js +212 -0
  638. package/dist/src/utils/events.test.js.map +1 -0
  639. package/dist/src/utils/extensionLoader.d.ts +86 -0
  640. package/dist/src/utils/extensionLoader.js +208 -0
  641. package/dist/src/utils/extensionLoader.js.map +1 -0
  642. package/dist/src/utils/extensionLoader.test.d.ts +6 -0
  643. package/dist/src/utils/extensionLoader.test.js +154 -0
  644. package/dist/src/utils/extensionLoader.test.js.map +1 -0
  645. package/dist/src/utils/fetch.d.ts +1 -0
  646. package/dist/src/utils/fetch.js +4 -0
  647. package/dist/src/utils/fetch.js.map +1 -1
  648. package/dist/src/utils/fileUtils.d.ts +4 -0
  649. package/dist/src/utils/fileUtils.js +34 -2
  650. package/dist/src/utils/fileUtils.js.map +1 -1
  651. package/dist/src/utils/fileUtils.test.js +87 -61
  652. package/dist/src/utils/fileUtils.test.js.map +1 -1
  653. package/dist/src/utils/filesearch/fileSearch.js +1 -1
  654. package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
  655. package/dist/src/utils/flashFallback.test.js +28 -47
  656. package/dist/src/utils/flashFallback.test.js.map +1 -1
  657. package/dist/src/utils/formatters.d.ts +1 -0
  658. package/dist/src/utils/formatters.js +2 -1
  659. package/dist/src/utils/formatters.js.map +1 -1
  660. package/dist/src/utils/formatters.test.d.ts +6 -0
  661. package/dist/src/utils/formatters.test.js +26 -0
  662. package/dist/src/utils/formatters.test.js.map +1 -0
  663. package/dist/src/utils/getFolderStructure.js +9 -17
  664. package/dist/src/utils/getFolderStructure.js.map +1 -1
  665. package/dist/src/utils/getFolderStructure.test.js +7 -6
  666. package/dist/src/utils/getFolderStructure.test.js.map +1 -1
  667. package/dist/src/utils/gitIgnoreParser.d.ts +4 -1
  668. package/dist/src/utils/gitIgnoreParser.js +28 -10
  669. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  670. package/dist/src/utils/gitIgnoreParser.test.js +58 -0
  671. package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
  672. package/dist/src/utils/googleErrors.d.ts +104 -0
  673. package/dist/src/utils/googleErrors.js +152 -0
  674. package/dist/src/utils/googleErrors.js.map +1 -0
  675. package/dist/src/utils/googleErrors.test.d.ts +6 -0
  676. package/dist/src/utils/googleErrors.test.js +301 -0
  677. package/dist/src/utils/googleErrors.test.js.map +1 -0
  678. package/dist/src/utils/googleQuotaErrors.d.ts +37 -0
  679. package/dist/src/utils/googleQuotaErrors.js +157 -0
  680. package/dist/src/utils/googleQuotaErrors.js.map +1 -0
  681. package/dist/src/utils/googleQuotaErrors.test.d.ts +6 -0
  682. package/dist/src/utils/googleQuotaErrors.test.js +311 -0
  683. package/dist/src/utils/googleQuotaErrors.test.js.map +1 -0
  684. package/dist/src/utils/httpErrors.d.ts +18 -0
  685. package/dist/src/utils/httpErrors.js +36 -0
  686. package/dist/src/utils/httpErrors.js.map +1 -0
  687. package/dist/src/utils/ignorePatterns.test.js +26 -30
  688. package/dist/src/utils/ignorePatterns.test.js.map +1 -1
  689. package/dist/src/utils/installationManager.js +2 -1
  690. package/dist/src/utils/installationManager.js.map +1 -1
  691. package/dist/src/utils/installationManager.test.js +6 -4
  692. package/dist/src/utils/installationManager.test.js.map +1 -1
  693. package/dist/src/utils/llm-edit-fixer.d.ts +1 -1
  694. package/dist/src/utils/llm-edit-fixer.js +33 -9
  695. package/dist/src/utils/llm-edit-fixer.js.map +1 -1
  696. package/dist/src/utils/llm-edit-fixer.test.js +38 -1
  697. package/dist/src/utils/llm-edit-fixer.test.js.map +1 -1
  698. package/dist/src/utils/memoryDiscovery.d.ts +20 -1
  699. package/dist/src/utils/memoryDiscovery.js +176 -12
  700. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  701. package/dist/src/utils/memoryDiscovery.test.js +299 -40
  702. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  703. package/dist/src/utils/memoryImportProcessor.js +4 -3
  704. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  705. package/dist/src/utils/memoryImportProcessor.test.js +8 -14
  706. package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
  707. package/dist/src/utils/nextSpeakerChecker.js +3 -3
  708. package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
  709. package/dist/src/utils/nextSpeakerChecker.test.js +13 -5
  710. package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
  711. package/dist/src/utils/package.d.ts +12 -0
  712. package/dist/src/utils/package.js +15 -0
  713. package/dist/src/utils/package.js.map +1 -0
  714. package/dist/src/utils/pathCorrector.d.ts +25 -0
  715. package/dist/src/utils/pathCorrector.js +33 -0
  716. package/dist/src/utils/pathCorrector.js.map +1 -0
  717. package/dist/src/utils/pathCorrector.test.d.ts +6 -0
  718. package/dist/src/utils/pathCorrector.test.js +83 -0
  719. package/dist/src/utils/pathCorrector.test.js.map +1 -0
  720. package/dist/src/utils/pathReader.js +4 -4
  721. package/dist/src/utils/pathReader.js.map +1 -1
  722. package/dist/src/utils/pathReader.test.js +44 -1
  723. package/dist/src/utils/pathReader.test.js.map +1 -1
  724. package/dist/src/utils/paths.d.ts +1 -1
  725. package/dist/src/utils/paths.js +131 -29
  726. package/dist/src/utils/paths.js.map +1 -1
  727. package/dist/src/utils/paths.test.js +200 -68
  728. package/dist/src/utils/paths.test.js.map +1 -1
  729. package/dist/src/utils/quotaErrorDetection.d.ts +0 -2
  730. package/dist/src/utils/quotaErrorDetection.js +0 -46
  731. package/dist/src/utils/quotaErrorDetection.js.map +1 -1
  732. package/dist/src/utils/retry.d.ts +3 -10
  733. package/dist/src/utils/retry.js +97 -195
  734. package/dist/src/utils/retry.js.map +1 -1
  735. package/dist/src/utils/retry.test.js +179 -145
  736. package/dist/src/utils/retry.test.js.map +1 -1
  737. package/dist/src/utils/safeJsonStringify.d.ts +4 -4
  738. package/dist/src/utils/safeJsonStringify.js +31 -7
  739. package/dist/src/utils/safeJsonStringify.js.map +1 -1
  740. package/dist/src/utils/shell-utils.d.ts +15 -2
  741. package/dist/src/utils/shell-utils.js +387 -140
  742. package/dist/src/utils/shell-utils.js.map +1 -1
  743. package/dist/src/utils/shell-utils.test.js +244 -62
  744. package/dist/src/utils/shell-utils.test.js.map +1 -1
  745. package/dist/src/utils/stdio.d.ts +32 -0
  746. package/dist/src/utils/stdio.js +85 -0
  747. package/dist/src/utils/stdio.js.map +1 -0
  748. package/dist/src/utils/stdio.test.d.ts +6 -0
  749. package/dist/src/utils/stdio.test.js +47 -0
  750. package/dist/src/utils/stdio.test.js.map +1 -0
  751. package/dist/src/utils/summarizer.d.ts +4 -2
  752. package/dist/src/utils/summarizer.js +8 -9
  753. package/dist/src/utils/summarizer.js.map +1 -1
  754. package/dist/src/utils/summarizer.test.js +32 -12
  755. package/dist/src/utils/summarizer.test.js.map +1 -1
  756. package/dist/src/utils/systemEncoding.js +5 -4
  757. package/dist/src/utils/systemEncoding.js.map +1 -1
  758. package/dist/src/utils/systemEncoding.test.js +2 -1
  759. package/dist/src/utils/systemEncoding.test.js.map +1 -1
  760. package/dist/src/utils/terminal.d.ts +14 -0
  761. package/dist/src/utils/terminal.js +38 -0
  762. package/dist/src/utils/terminal.js.map +1 -0
  763. package/dist/src/utils/tool-utils.d.ts +2 -2
  764. package/dist/src/utils/tool-utils.js +15 -6
  765. package/dist/src/utils/tool-utils.js.map +1 -1
  766. package/dist/src/utils/tool-utils.test.js +8 -0
  767. package/dist/src/utils/tool-utils.test.js.map +1 -1
  768. package/dist/src/utils/userAccountManager.js +5 -4
  769. package/dist/src/utils/userAccountManager.js.map +1 -1
  770. package/dist/src/utils/userAccountManager.test.js +9 -7
  771. package/dist/src/utils/userAccountManager.test.js.map +1 -1
  772. package/dist/src/utils/workspaceContext.d.ts +4 -3
  773. package/dist/src/utils/workspaceContext.js +13 -13
  774. package/dist/src/utils/workspaceContext.js.map +1 -1
  775. package/dist/src/utils/workspaceContext.test.js +8 -7
  776. package/dist/src/utils/workspaceContext.test.js.map +1 -1
  777. package/dist/tsconfig.tsbuildinfo +1 -1
  778. package/package.json +12 -7
@@ -3,109 +3,140 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { describe, it, expect, beforeEach, afterEach, vi, } from 'vitest';
6
+ import { describe, it, expect, beforeEach, afterEach, afterAll, vi, } from 'vitest';
7
7
  import { canUseRipgrep, RipGrepTool, ensureRgPath } from './ripGrep.js';
8
8
  import path from 'node:path';
9
9
  import fs from 'node:fs/promises';
10
- import os, { EOL } from 'node:os';
10
+ import os from 'node:os';
11
+ import { Storage } from '../config/storage.js';
11
12
  import { createMockWorkspaceContext } from '../test-utils/mockWorkspaceContext.js';
12
13
  import { spawn } from 'node:child_process';
13
14
  import { downloadRipGrep } from '@joshua.litt/get-ripgrep';
14
- import { fileExists } from '../utils/fileUtils.js';
15
15
  // Mock dependencies for canUseRipgrep
16
16
  vi.mock('@joshua.litt/get-ripgrep', () => ({
17
17
  downloadRipGrep: vi.fn(),
18
18
  }));
19
- vi.mock('../utils/fileUtils.js', async (importOriginal) => {
20
- const actual = await importOriginal();
21
- return {
22
- ...actual,
23
- fileExists: vi.fn(),
24
- };
25
- });
26
- vi.mock('../config/storage.js', () => ({
27
- Storage: {
28
- getGlobalBinDir: vi.fn().mockReturnValue('/mock/bin/dir'),
29
- },
30
- }));
31
19
  // Mock child_process for ripgrep calls
32
20
  vi.mock('child_process', () => ({
33
21
  spawn: vi.fn(),
34
22
  }));
35
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
+ }
36
30
  describe('canUseRipgrep', () => {
37
- beforeEach(() => {
38
- vi.clearAllMocks();
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 });
39
44
  });
40
45
  it('should return true if ripgrep already exists', async () => {
41
- fileExists.mockResolvedValue(true);
46
+ const existingPath = path.join(binDir, getRipgrepBinaryName());
47
+ await fs.writeFile(existingPath, '');
42
48
  const result = await canUseRipgrep();
43
49
  expect(result).toBe(true);
44
- expect(fileExists).toHaveBeenCalledWith(path.join('/mock/bin/dir', 'rg'));
45
- expect(downloadRipGrep).not.toHaveBeenCalled();
50
+ expect(downloadRipGrepMock).not.toHaveBeenCalled();
46
51
  });
47
52
  it('should download ripgrep and return true if it does not exist initially', async () => {
48
- fileExists
49
- .mockResolvedValueOnce(false)
50
- .mockResolvedValueOnce(true);
51
- downloadRipGrep.mockResolvedValue(undefined);
53
+ const expectedPath = path.join(binDir, getRipgrepBinaryName());
54
+ downloadRipGrepMock.mockImplementation(async () => {
55
+ await fs.writeFile(expectedPath, '');
56
+ });
52
57
  const result = await canUseRipgrep();
53
58
  expect(result).toBe(true);
54
- expect(fileExists).toHaveBeenCalledTimes(2);
55
- expect(downloadRipGrep).toHaveBeenCalledWith('/mock/bin/dir');
59
+ expect(downloadRipGrep).toHaveBeenCalledWith(binDir);
60
+ await expect(fs.access(expectedPath)).resolves.toBeUndefined();
56
61
  });
57
62
  it('should return false if download fails and file does not exist', async () => {
58
- fileExists.mockResolvedValue(false);
59
- downloadRipGrep.mockResolvedValue(undefined);
60
63
  const result = await canUseRipgrep();
61
64
  expect(result).toBe(false);
62
- expect(fileExists).toHaveBeenCalledTimes(2);
63
- expect(downloadRipGrep).toHaveBeenCalledWith('/mock/bin/dir');
65
+ expect(downloadRipGrep).toHaveBeenCalledWith(binDir);
64
66
  });
65
67
  it('should propagate errors from downloadRipGrep', async () => {
66
68
  const error = new Error('Download failed');
67
- fileExists.mockResolvedValue(false);
68
- downloadRipGrep.mockRejectedValue(error);
69
+ downloadRipGrepMock.mockRejectedValue(error);
69
70
  await expect(canUseRipgrep()).rejects.toThrow(error);
70
- expect(fileExists).toHaveBeenCalledTimes(1);
71
- expect(downloadRipGrep).toHaveBeenCalledWith('/mock/bin/dir');
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();
72
89
  });
73
90
  });
74
91
  describe('ensureRgPath', () => {
75
- beforeEach(() => {
76
- vi.clearAllMocks();
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 });
77
105
  });
78
106
  it('should return rg path if ripgrep already exists', async () => {
79
- fileExists.mockResolvedValue(true);
107
+ const existingPath = path.join(binDir, getRipgrepBinaryName());
108
+ await fs.writeFile(existingPath, '');
80
109
  const rgPath = await ensureRgPath();
81
- expect(rgPath).toBe(path.join('/mock/bin/dir', 'rg'));
82
- expect(fileExists).toHaveBeenCalledOnce();
110
+ expect(rgPath).toBe(existingPath);
83
111
  expect(downloadRipGrep).not.toHaveBeenCalled();
84
112
  });
85
113
  it('should return rg path if ripgrep is downloaded successfully', async () => {
86
- fileExists
87
- .mockResolvedValueOnce(false)
88
- .mockResolvedValueOnce(true);
89
- downloadRipGrep.mockResolvedValue(undefined);
114
+ const expectedPath = path.join(binDir, getRipgrepBinaryName());
115
+ downloadRipGrepMock.mockImplementation(async () => {
116
+ await fs.writeFile(expectedPath, '');
117
+ });
90
118
  const rgPath = await ensureRgPath();
91
- expect(rgPath).toBe(path.join('/mock/bin/dir', 'rg'));
92
- expect(downloadRipGrep).toHaveBeenCalledOnce();
93
- expect(fileExists).toHaveBeenCalledTimes(2);
119
+ expect(rgPath).toBe(expectedPath);
120
+ expect(downloadRipGrep).toHaveBeenCalledTimes(1);
121
+ await expect(fs.access(expectedPath)).resolves.toBeUndefined();
94
122
  });
95
123
  it('should throw an error if ripgrep cannot be used after download attempt', async () => {
96
- fileExists.mockResolvedValue(false);
97
- downloadRipGrep.mockResolvedValue(undefined);
98
124
  await expect(ensureRgPath()).rejects.toThrow('Cannot use ripgrep.');
99
- expect(downloadRipGrep).toHaveBeenCalledOnce();
100
- expect(fileExists).toHaveBeenCalledTimes(2);
125
+ expect(downloadRipGrep).toHaveBeenCalledTimes(1);
101
126
  });
102
127
  it('should propagate errors from downloadRipGrep', async () => {
103
128
  const error = new Error('Download failed');
104
- fileExists.mockResolvedValue(false);
105
- downloadRipGrep.mockRejectedValue(error);
129
+ downloadRipGrepMock.mockRejectedValue(error);
106
130
  await expect(ensureRgPath()).rejects.toThrow(error);
107
- expect(fileExists).toHaveBeenCalledTimes(1);
108
- expect(downloadRipGrep).toHaveBeenCalledWith('/mock/bin/dir');
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();
109
140
  });
110
141
  });
111
142
  // Helper function to create mock spawn implementations
@@ -141,6 +172,9 @@ function createMockSpawn(options = {}) {
141
172
  }
142
173
  describe('RipGrepTool', () => {
143
174
  let tempRootDir;
175
+ let tempBinRoot;
176
+ let binDir;
177
+ let ripgrepBinaryPath;
144
178
  let grepTool;
145
179
  const abortSignal = new AbortController().signal;
146
180
  const mockConfig = {
@@ -149,10 +183,16 @@ describe('RipGrepTool', () => {
149
183
  getDebugMode: () => false,
150
184
  };
151
185
  beforeEach(async () => {
152
- vi.clearAllMocks();
153
- downloadRipGrep.mockResolvedValue(undefined);
154
- fileExists.mockResolvedValue(true);
155
- mockSpawn.mockClear();
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);
156
196
  tempRootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'grep-tool-root-'));
157
197
  grepTool = new RipGrepTool(mockConfig);
158
198
  // Create some test files and directories
@@ -163,58 +203,93 @@ describe('RipGrepTool', () => {
163
203
  await fs.writeFile(path.join(tempRootDir, 'sub', 'fileD.md'), '# Markdown file\nThis is a test.');
164
204
  });
165
205
  afterEach(async () => {
206
+ storageSpy.mockImplementation(() => originalGetGlobalBinDir());
166
207
  await fs.rm(tempRootDir, { recursive: true, force: true });
208
+ await fs.rm(tempBinRoot, { recursive: true, force: true });
167
209
  });
168
210
  describe('validateToolParams', () => {
169
- it('should return null for valid params (pattern only)', () => {
170
- const params = { pattern: 'hello' };
171
- expect(grepTool.validateToolParams(params)).toBeNull();
172
- });
173
- it('should return null for valid params (pattern and path)', () => {
174
- const params = { pattern: 'hello', path: '.' };
175
- expect(grepTool.validateToolParams(params)).toBeNull();
176
- });
177
- it('should return null for valid params (pattern, path, and include)', () => {
178
- const params = {
179
- pattern: 'hello',
180
- path: '.',
181
- include: '*.txt',
182
- };
183
- expect(grepTool.validateToolParams(params)).toBeNull();
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);
184
234
  });
185
235
  it('should return error if pattern is missing', () => {
186
- const params = { path: '.' };
236
+ const params = { dir_path: '.' };
187
237
  expect(grepTool.validateToolParams(params)).toBe(`params must have required property 'pattern'`);
188
238
  });
189
- it('should return null for what would be an invalid regex pattern', () => {
190
- const params = { pattern: '[[' };
191
- expect(grepTool.validateToolParams(params)).toBeNull();
192
- });
193
239
  it('should return error if path does not exist', () => {
194
240
  const params = {
195
241
  pattern: 'hello',
196
- path: 'nonexistent',
242
+ dir_path: 'nonexistent',
197
243
  };
198
244
  // Check for the core error message, as the full path might vary
199
- expect(grepTool.validateToolParams(params)).toContain('Failed to access path stats for');
245
+ expect(grepTool.validateToolParams(params)).toContain('Path does not exist');
200
246
  expect(grepTool.validateToolParams(params)).toContain('nonexistent');
201
247
  });
202
- it('should return error if path is a file, not a directory', async () => {
248
+ it('should allow path to be a file', async () => {
203
249
  const filePath = path.join(tempRootDir, 'fileA.txt');
204
- const params = { pattern: 'hello', path: filePath };
205
- expect(grepTool.validateToolParams(params)).toContain(`Path is not a directory: ${filePath}`);
250
+ const params = {
251
+ pattern: 'hello',
252
+ dir_path: filePath,
253
+ };
254
+ expect(grepTool.validateToolParams(params)).toBeNull();
206
255
  });
207
256
  });
208
257
  describe('execute', () => {
209
258
  it('should find matches for a simple pattern in all files', async () => {
210
259
  mockSpawn.mockImplementationOnce(createMockSpawn({
211
- outputData: `fileA.txt:1:hello world${EOL}fileA.txt:2:second line with world${EOL}sub/fileC.txt:1:another world in sub dir${EOL}`,
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',
212
287
  exitCode: 0,
213
288
  }));
214
289
  const params = { pattern: 'world' };
215
290
  const invocation = grepTool.build(params);
216
291
  const result = await invocation.execute(abortSignal);
217
- expect(result.llmContent).toContain('Found 3 matches for pattern "world" in the workspace directory');
292
+ expect(result.llmContent).toContain('Found 3 matches for pattern "world" in path "."');
218
293
  expect(result.llmContent).toContain('File: fileA.txt');
219
294
  expect(result.llmContent).toContain('L1: hello world');
220
295
  expect(result.llmContent).toContain('L2: second line with world');
@@ -225,10 +300,17 @@ describe('RipGrepTool', () => {
225
300
  it('should find matches in a specific path', async () => {
226
301
  // Setup specific mock for this test - searching in 'sub' should only return matches from that directory
227
302
  mockSpawn.mockImplementationOnce(createMockSpawn({
228
- outputData: `fileC.txt:1:another world in sub dir${EOL}`,
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',
229
311
  exitCode: 0,
230
312
  }));
231
- const params = { pattern: 'world', path: 'sub' };
313
+ const params = { pattern: 'world', dir_path: 'sub' };
232
314
  const invocation = grepTool.build(params);
233
315
  const result = await invocation.execute(abortSignal);
234
316
  expect(result.llmContent).toContain('Found 1 match for pattern "world" in path "sub"');
@@ -239,13 +321,20 @@ describe('RipGrepTool', () => {
239
321
  it('should find matches with an include glob', async () => {
240
322
  // Setup specific mock for this test
241
323
  mockSpawn.mockImplementationOnce(createMockSpawn({
242
- outputData: `fileB.js:2:function baz() { return "hello"; }${EOL}`,
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',
243
332
  exitCode: 0,
244
333
  }));
245
334
  const params = { pattern: 'hello', include: '*.js' };
246
335
  const invocation = grepTool.build(params);
247
336
  const result = await invocation.execute(abortSignal);
248
- expect(result.llmContent).toContain('Found 1 match for pattern "hello" in the workspace directory (filter: "*.js"):');
337
+ expect(result.llmContent).toContain('Found 1 match for pattern "hello" in path "." (filter: "*.js"):');
249
338
  expect(result.llmContent).toContain('File: fileB.js');
250
339
  expect(result.llmContent).toContain('L2: function baz() { return "hello"; }');
251
340
  expect(result.returnDisplay).toBe('Found 1 match');
@@ -272,7 +361,14 @@ describe('RipGrepTool', () => {
272
361
  const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
273
362
  if (onData) {
274
363
  // Only return match from the .js file in sub directory
275
- onData(Buffer.from(`another.js:1:const greeting = "hello";${EOL}`));
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'));
276
372
  }
277
373
  if (onClose) {
278
374
  onClose(0);
@@ -282,7 +378,7 @@ describe('RipGrepTool', () => {
282
378
  });
283
379
  const params = {
284
380
  pattern: 'hello',
285
- path: 'sub',
381
+ dir_path: 'sub',
286
382
  include: '*.js',
287
383
  };
288
384
  const invocation = grepTool.build(params);
@@ -300,7 +396,7 @@ describe('RipGrepTool', () => {
300
396
  const params = { pattern: 'nonexistentpattern' };
301
397
  const invocation = grepTool.build(params);
302
398
  const result = await invocation.execute(abortSignal);
303
- expect(result.llmContent).toContain('No matches found for pattern "nonexistentpattern" in the workspace directory.');
399
+ expect(result.llmContent).toContain('No matches found for pattern "nonexistentpattern" in path ".".');
304
400
  expect(result.returnDisplay).toBe('No matches found');
305
401
  });
306
402
  it('should return an error from ripgrep for invalid regex pattern', async () => {
@@ -334,7 +430,14 @@ describe('RipGrepTool', () => {
334
430
  const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
335
431
  if (onData) {
336
432
  // Return match for the regex pattern
337
- onData(Buffer.from(`fileB.js:1:const foo = "bar";${EOL}`));
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'));
338
441
  }
339
442
  if (onClose) {
340
443
  onClose(0);
@@ -345,7 +448,7 @@ describe('RipGrepTool', () => {
345
448
  const params = { pattern: 'foo.*bar' }; // Matches 'const foo = "bar";'
346
449
  const invocation = grepTool.build(params);
347
450
  const result = await invocation.execute(abortSignal);
348
- expect(result.llmContent).toContain('Found 1 match for pattern "foo.*bar" in the workspace directory:');
451
+ expect(result.llmContent).toContain('Found 1 match for pattern "foo.*bar" in path ".":');
349
452
  expect(result.llmContent).toContain('File: fileB.js');
350
453
  expect(result.llmContent).toContain('L1: const foo = "bar";');
351
454
  });
@@ -370,7 +473,24 @@ describe('RipGrepTool', () => {
370
473
  const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
371
474
  if (onData) {
372
475
  // Return case-insensitive matches for 'HELLO'
373
- onData(Buffer.from(`fileA.txt:1:hello world${EOL}fileB.js:2:function baz() { return "hello"; }${EOL}`));
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'));
374
494
  }
375
495
  if (onClose) {
376
496
  onClose(0);
@@ -381,20 +501,19 @@ describe('RipGrepTool', () => {
381
501
  const params = { pattern: 'HELLO' };
382
502
  const invocation = grepTool.build(params);
383
503
  const result = await invocation.execute(abortSignal);
384
- expect(result.llmContent).toContain('Found 2 matches for pattern "HELLO" in the workspace directory:');
504
+ expect(result.llmContent).toContain('Found 2 matches for pattern "HELLO" in path ".":');
385
505
  expect(result.llmContent).toContain('File: fileA.txt');
386
506
  expect(result.llmContent).toContain('L1: hello world');
387
507
  expect(result.llmContent).toContain('File: fileB.js');
388
508
  expect(result.llmContent).toContain('L2: function baz() { return "hello"; }');
389
509
  });
390
510
  it('should throw an error if params are invalid', async () => {
391
- const params = { path: '.' }; // Invalid: pattern missing
511
+ const params = { dir_path: '.' }; // Invalid: pattern missing
392
512
  expect(() => grepTool.build(params)).toThrow(/params must have required property 'pattern'/);
393
513
  });
394
514
  it('should throw an error if ripgrep is not available', async () => {
395
- // Make ensureRgPath throw
396
- fileExists.mockResolvedValue(false);
397
- downloadRipGrep.mockResolvedValue(undefined);
515
+ await fs.rm(ripgrepBinaryPath, { force: true });
516
+ downloadRipGrepMock.mockResolvedValue(undefined);
398
517
  const params = { pattern: 'world' };
399
518
  const invocation = grepTool.build(params);
400
519
  expect(await invocation.execute(abortSignal)).toStrictEqual({
@@ -404,7 +523,7 @@ describe('RipGrepTool', () => {
404
523
  });
405
524
  });
406
525
  describe('multi-directory workspace', () => {
407
- it('should search across all workspace directories when no path is specified', async () => {
526
+ it('should search only CWD when no path is specified (default behavior)', async () => {
408
527
  // Create additional directory with test files
409
528
  const secondDir = await fs.mkdtemp(path.join(os.tmpdir(), 'grep-tool-second-'));
410
529
  await fs.writeFile(path.join(secondDir, 'other.txt'), 'hello from second directory\nworld in second');
@@ -440,19 +559,55 @@ describe('RipGrepTool', () => {
440
559
  if (callCount === 1) {
441
560
  // First directory (tempRootDir)
442
561
  outputData =
443
- [
444
- 'fileA.txt:1:hello world',
445
- 'fileA.txt:2:second line with world',
446
- 'sub/fileC.txt:1:another world in sub dir',
447
- ].join(EOL) + EOL;
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';
448
589
  }
449
590
  else if (callCount === 2) {
450
591
  // Second directory (secondDir)
451
592
  outputData =
452
- [
453
- 'other.txt:2:world in second',
454
- 'another.js:1:function world() { return "test"; }',
455
- ].join(EOL) + EOL;
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';
456
611
  }
457
612
  if (stdoutDataHandler && outputData) {
458
613
  stdoutDataHandler(Buffer.from(outputData));
@@ -467,19 +622,19 @@ describe('RipGrepTool', () => {
467
622
  const params = { pattern: 'world' };
468
623
  const invocation = multiDirGrepTool.build(params);
469
624
  const result = await invocation.execute(abortSignal);
470
- // Should find matches in both directories
471
- expect(result.llmContent).toContain('Found 5 matches for pattern "world"');
625
+ // Should find matches in CWD only (default behavior now)
626
+ expect(result.llmContent).toContain('Found 3 matches for pattern "world" in path "."');
472
627
  // Matches from first directory
473
628
  expect(result.llmContent).toContain('fileA.txt');
474
629
  expect(result.llmContent).toContain('L1: hello world');
475
630
  expect(result.llmContent).toContain('L2: second line with world');
476
631
  expect(result.llmContent).toContain('fileC.txt');
477
632
  expect(result.llmContent).toContain('L1: another world in sub dir');
478
- // Matches from both directories
479
- expect(result.llmContent).toContain('other.txt');
480
- expect(result.llmContent).toContain('L2: world in second');
481
- expect(result.llmContent).toContain('another.js');
482
- expect(result.llmContent).toContain('L1: function world()');
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()');
483
638
  // Clean up
484
639
  await fs.rm(secondDir, { recursive: true, force: true });
485
640
  mockSpawn.mockClear();
@@ -514,7 +669,14 @@ describe('RipGrepTool', () => {
514
669
  const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
515
670
  const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
516
671
  if (onData) {
517
- onData(Buffer.from(`fileC.txt:1:another world in sub dir${EOL}`));
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'));
518
680
  }
519
681
  if (onClose) {
520
682
  onClose(0);
@@ -524,7 +686,7 @@ describe('RipGrepTool', () => {
524
686
  });
525
687
  const multiDirGrepTool = new RipGrepTool(multiDirConfig);
526
688
  // Search only in the 'sub' directory of the first workspace
527
- const params = { pattern: 'world', path: 'sub' };
689
+ const params = { pattern: 'world', dir_path: 'sub' };
528
690
  const invocation = multiDirGrepTool.build(params);
529
691
  const result = await invocation.execute(abortSignal);
530
692
  // Should only find matches in the specified sub directory
@@ -584,67 +746,31 @@ describe('RipGrepTool', () => {
584
746
  });
585
747
  describe('error handling and edge cases', () => {
586
748
  it('should handle workspace boundary violations', () => {
587
- const params = { pattern: 'test', path: '../outside' };
749
+ const params = {
750
+ pattern: 'test',
751
+ dir_path: '../outside',
752
+ };
588
753
  expect(() => grepTool.build(params)).toThrow(/Path validation failed/);
589
754
  });
590
- it('should handle empty directories gracefully', async () => {
591
- const emptyDir = path.join(tempRootDir, 'empty');
592
- await fs.mkdir(emptyDir);
593
- // Setup specific mock for this test - searching in empty directory should return no matches
594
- mockSpawn.mockImplementationOnce(() => {
595
- const mockProcess = {
596
- stdout: {
597
- on: vi.fn(),
598
- removeListener: vi.fn(),
599
- },
600
- stderr: {
601
- on: vi.fn(),
602
- removeListener: vi.fn(),
603
- },
604
- on: vi.fn(),
605
- removeListener: vi.fn(),
606
- kill: vi.fn(),
607
- };
608
- setTimeout(() => {
609
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
610
- if (onClose) {
611
- onClose(1);
612
- }
613
- }, 0);
614
- return mockProcess;
615
- });
616
- const params = { pattern: 'test', path: 'empty' };
617
- const invocation = grepTool.build(params);
618
- const result = await invocation.execute(abortSignal);
619
- expect(result.llmContent).toContain('No matches found');
620
- expect(result.returnDisplay).toBe('No matches found');
621
- });
622
- it('should handle empty files correctly', async () => {
623
- await fs.writeFile(path.join(tempRootDir, 'empty.txt'), '');
624
- // Setup specific mock for this test - searching for anything in empty files should return no matches
625
- mockSpawn.mockImplementationOnce(() => {
626
- const mockProcess = {
627
- stdout: {
628
- on: vi.fn(),
629
- removeListener: vi.fn(),
630
- },
631
- stderr: {
632
- on: vi.fn(),
633
- removeListener: vi.fn(),
634
- },
635
- on: vi.fn(),
636
- removeListener: vi.fn(),
637
- kill: vi.fn(),
638
- };
639
- setTimeout(() => {
640
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
641
- if (onClose) {
642
- onClose(1);
643
- }
644
- }, 0);
645
- return mockProcess;
646
- });
647
- const params = { pattern: 'anything' };
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();
648
774
  const invocation = grepTool.build(params);
649
775
  const result = await invocation.execute(abortSignal);
650
776
  expect(result.llmContent).toContain('No matches found');
@@ -671,7 +797,14 @@ describe('RipGrepTool', () => {
671
797
  const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
672
798
  const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
673
799
  if (onData) {
674
- onData(Buffer.from(`${specialFileName}:1:hello world with special chars${EOL}`));
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'));
675
808
  }
676
809
  if (onClose) {
677
810
  onClose(0);
@@ -708,7 +841,14 @@ describe('RipGrepTool', () => {
708
841
  const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
709
842
  const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
710
843
  if (onData) {
711
- onData(Buffer.from(`a/b/c/d/e/deep.txt:1:content in deep directory${EOL}`));
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'));
712
852
  }
713
853
  if (onClose) {
714
854
  onClose(0);
@@ -745,7 +885,14 @@ describe('RipGrepTool', () => {
745
885
  const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
746
886
  const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
747
887
  if (onData) {
748
- onData(Buffer.from(`code.js:1:function getName() { return "test"; }${EOL}`));
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'));
749
896
  }
750
897
  if (onClose) {
751
898
  onClose(0);
@@ -780,7 +927,33 @@ describe('RipGrepTool', () => {
780
927
  const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
781
928
  const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
782
929
  if (onData) {
783
- onData(Buffer.from(`case.txt:1:Hello World${EOL}case.txt:2:hello world${EOL}case.txt:3:HELLO WORLD${EOL}`));
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'));
784
957
  }
785
958
  if (onClose) {
786
959
  onClose(0);
@@ -816,7 +989,14 @@ describe('RipGrepTool', () => {
816
989
  const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
817
990
  const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
818
991
  if (onData) {
819
- onData(Buffer.from(`special.txt:1:Price: $19.99${EOL}`));
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'));
820
1000
  }
821
1001
  if (onClose) {
822
1002
  onClose(0);
@@ -856,7 +1036,24 @@ describe('RipGrepTool', () => {
856
1036
  const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
857
1037
  const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
858
1038
  if (onData) {
859
- onData(Buffer.from(`test.ts:1:typescript content${EOL}test.tsx:1:tsx content${EOL}`));
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'));
860
1057
  }
861
1058
  if (onClose) {
862
1059
  onClose(0);
@@ -898,7 +1095,14 @@ describe('RipGrepTool', () => {
898
1095
  const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
899
1096
  const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
900
1097
  if (onData) {
901
- onData(Buffer.from(`src/main.ts:1:source code${EOL}`));
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'));
902
1106
  }
903
1107
  if (onClose) {
904
1108
  onClose(0);
@@ -916,34 +1120,161 @@ describe('RipGrepTool', () => {
916
1120
  expect(result.llmContent).not.toContain('other.ts');
917
1121
  });
918
1122
  });
919
- describe('getDescription', () => {
920
- it('should generate correct description with pattern only', () => {
921
- const params = { pattern: 'testPattern' };
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 };
922
1197
  const invocation = grepTool.build(params);
923
- expect(invocation.getDescription()).toBe("'testPattern'");
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');
924
1204
  });
925
- it('should generate correct description with pattern and include', () => {
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
+ }));
926
1222
  const params = {
927
- pattern: 'testPattern',
928
- include: '*.ts',
1223
+ pattern: 'world',
1224
+ context: 1,
1225
+ after: 2,
1226
+ before: 1,
929
1227
  };
930
1228
  const invocation = grepTool.build(params);
931
- expect(invocation.getDescription()).toBe("'testPattern' in *.ts");
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);
932
1265
  });
933
1266
  it('should generate correct description with pattern and path', async () => {
934
1267
  const dirPath = path.join(tempRootDir, 'src', 'app');
935
1268
  await fs.mkdir(dirPath, { recursive: true });
936
1269
  const params = {
937
1270
  pattern: 'testPattern',
938
- path: path.join('src', 'app'),
1271
+ dir_path: path.join('src', 'app'),
939
1272
  };
940
1273
  const invocation = grepTool.build(params);
941
- // The path will be relative to the tempRootDir, so we check for containment.
942
1274
  expect(invocation.getDescription()).toContain("'testPattern' within");
943
1275
  expect(invocation.getDescription()).toContain(path.join('src', 'app'));
944
1276
  });
945
- it('should indicate searching across all workspace directories when no path specified', () => {
946
- // Create a mock config with multiple directories
1277
+ it('should use ./ when no path is specified (defaults to CWD)', () => {
947
1278
  const multiDirConfig = {
948
1279
  getTargetDir: () => tempRootDir,
949
1280
  getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir, ['/another/dir']),
@@ -952,7 +1283,7 @@ describe('RipGrepTool', () => {
952
1283
  const multiDirGrepTool = new RipGrepTool(multiDirConfig);
953
1284
  const params = { pattern: 'testPattern' };
954
1285
  const invocation = multiDirGrepTool.build(params);
955
- expect(invocation.getDescription()).toBe("'testPattern' across all workspace directories");
1286
+ expect(invocation.getDescription()).toBe("'testPattern' within ./");
956
1287
  });
957
1288
  it('should generate correct description with pattern, include, and path', async () => {
958
1289
  const dirPath = path.join(tempRootDir, 'src', 'app');
@@ -960,17 +1291,15 @@ describe('RipGrepTool', () => {
960
1291
  const params = {
961
1292
  pattern: 'testPattern',
962
1293
  include: '*.ts',
963
- path: path.join('src', 'app'),
1294
+ dir_path: path.join('src', 'app'),
964
1295
  };
965
1296
  const invocation = grepTool.build(params);
966
1297
  expect(invocation.getDescription()).toContain("'testPattern' in *.ts within");
967
1298
  expect(invocation.getDescription()).toContain(path.join('src', 'app'));
968
1299
  });
969
- it('should use ./ for root path in description', () => {
970
- const params = { pattern: 'testPattern', path: '.' };
971
- const invocation = grepTool.build(params);
972
- expect(invocation.getDescription()).toBe("'testPattern' within ./");
973
- });
974
1300
  });
975
1301
  });
1302
+ afterAll(() => {
1303
+ storageSpy.mockRestore();
1304
+ });
976
1305
  //# sourceMappingURL=ripGrep.test.js.map