@office-ai/aioncli-core 0.26.0 → 0.30.0

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 (1152) hide show
  1. package/dist/docs/CONTRIBUTING.md +19 -10
  2. package/dist/docs/admin/enterprise-controls.md +115 -0
  3. package/dist/docs/architecture.md +3 -3
  4. package/dist/docs/assets/monitoring-dashboard-logs.png +0 -0
  5. package/dist/docs/assets/monitoring-dashboard-metrics.png +0 -0
  6. package/dist/docs/assets/monitoring-dashboard-overview.png +0 -0
  7. package/dist/docs/bedrock-integration-plan.md +595 -0
  8. package/dist/docs/changelogs/index.md +187 -0
  9. package/dist/docs/changelogs/latest.md +299 -209
  10. package/dist/docs/changelogs/preview.md +353 -115
  11. package/dist/docs/cli/checkpointing.md +2 -3
  12. package/dist/docs/cli/cli-reference.md +115 -0
  13. package/dist/docs/cli/commands.md +360 -247
  14. package/dist/docs/cli/creating-skills.md +80 -0
  15. package/dist/docs/cli/custom-commands.md +12 -9
  16. package/dist/docs/cli/enterprise.md +25 -5
  17. package/dist/docs/cli/gemini-md.md +20 -12
  18. package/dist/docs/cli/headless.md +34 -372
  19. package/dist/docs/cli/index.md +123 -63
  20. package/dist/docs/cli/keyboard-shortcuts.md +95 -84
  21. package/dist/docs/cli/model-routing.md +7 -2
  22. package/dist/docs/cli/model.md +1 -1
  23. package/dist/docs/cli/plan-mode.md +190 -0
  24. package/dist/docs/cli/rewind.md +51 -0
  25. package/dist/docs/cli/sandbox.md +4 -3
  26. package/dist/docs/cli/session-management.md +61 -44
  27. package/dist/docs/cli/settings.md +95 -61
  28. package/dist/docs/cli/skills.md +49 -71
  29. package/dist/docs/cli/system-prompt.md +32 -0
  30. package/dist/docs/cli/telemetry.md +75 -4
  31. package/dist/docs/cli/themes.md +85 -53
  32. package/dist/docs/cli/tutorials/automation.md +187 -0
  33. package/dist/docs/cli/tutorials/file-management.md +142 -0
  34. package/dist/docs/cli/tutorials/mcp-setup.md +105 -0
  35. package/dist/docs/cli/tutorials/memory-management.md +126 -0
  36. package/dist/docs/cli/tutorials/session-management.md +105 -0
  37. package/dist/docs/cli/tutorials/shell-commands.md +107 -0
  38. package/dist/docs/cli/tutorials/skills-getting-started.md +36 -58
  39. package/dist/docs/cli/tutorials/task-planning.md +93 -0
  40. package/dist/docs/cli/tutorials/web-tools.md +78 -0
  41. package/dist/docs/cli/uninstall.md +18 -0
  42. package/dist/docs/core/concepts.md +137 -0
  43. package/dist/docs/core/index.md +6 -0
  44. package/dist/docs/core/memport.md +2 -0
  45. package/dist/docs/core/policy-engine.md +57 -7
  46. package/dist/docs/core/remote-agents.md +84 -0
  47. package/dist/docs/core/subagents.md +191 -0
  48. package/dist/docs/extensions/best-practices.md +188 -0
  49. package/dist/docs/extensions/index.md +38 -270
  50. package/dist/docs/extensions/reference.md +265 -0
  51. package/dist/docs/extensions/releasing.md +154 -0
  52. package/dist/docs/extensions/writing-extensions.md +292 -0
  53. package/dist/docs/get-started/authentication.md +162 -0
  54. package/dist/docs/get-started/configuration-v1.md +5 -11
  55. package/dist/docs/get-started/configuration.md +228 -99
  56. package/dist/docs/get-started/examples.md +39 -119
  57. package/dist/docs/get-started/gemini-3.md +2 -17
  58. package/dist/docs/get-started/index.md +6 -4
  59. package/dist/docs/get-started/installation.md +110 -77
  60. package/dist/docs/hooks/best-practices.md +219 -398
  61. package/dist/docs/hooks/index.md +99 -622
  62. package/dist/docs/hooks/reference.md +269 -115
  63. package/dist/docs/hooks/writing-hooks.md +203 -779
  64. package/dist/docs/index.md +146 -147
  65. package/dist/docs/local-development.md +1 -1
  66. package/dist/docs/releases.md +3 -3
  67. package/dist/docs/sidebar.json +105 -217
  68. package/dist/docs/tools/activate-skill.md +43 -0
  69. package/dist/docs/tools/ask-user.md +95 -0
  70. package/dist/docs/tools/file-system.md +48 -139
  71. package/dist/docs/tools/index.md +92 -85
  72. package/dist/docs/tools/internal-docs.md +46 -0
  73. package/dist/docs/tools/mcp-server.md +29 -5
  74. package/dist/docs/tools/memory.md +21 -40
  75. package/dist/docs/tools/planning.md +55 -0
  76. package/dist/docs/tools/shell.md +45 -89
  77. package/dist/docs/tools/todos.md +22 -44
  78. package/dist/docs/tools/web-fetch.md +22 -46
  79. package/dist/docs/tools/web-search.md +19 -29
  80. package/dist/docs/tos-privacy.md +1 -1
  81. package/dist/docs/troubleshooting.md +20 -5
  82. package/dist/index.d.ts +2 -1
  83. package/dist/index.js +2 -1
  84. package/dist/index.js.map +1 -1
  85. package/dist/src/agents/a2a-client-manager.d.ts +4 -5
  86. package/dist/src/agents/a2a-client-manager.js +9 -131
  87. package/dist/src/agents/a2a-client-manager.js.map +1 -1
  88. package/dist/src/agents/a2a-client-manager.test.js +10 -27
  89. package/dist/src/agents/a2a-client-manager.test.js.map +1 -1
  90. package/dist/src/agents/a2aUtils.d.ts +3 -2
  91. package/dist/src/agents/a2aUtils.js +28 -26
  92. package/dist/src/agents/a2aUtils.js.map +1 -1
  93. package/dist/src/agents/a2aUtils.test.js +9 -9
  94. package/dist/src/agents/a2aUtils.test.js.map +1 -1
  95. package/dist/src/agents/acknowledgedAgents.d.ts +18 -0
  96. package/dist/src/agents/acknowledgedAgents.js +58 -0
  97. package/dist/src/agents/acknowledgedAgents.js.map +1 -0
  98. package/dist/src/agents/acknowledgedAgents.test.d.ts +6 -0
  99. package/dist/src/agents/acknowledgedAgents.test.js +70 -0
  100. package/dist/src/agents/acknowledgedAgents.test.js.map +1 -0
  101. package/dist/src/agents/agent-scheduler.d.ts +35 -0
  102. package/dist/src/agents/agent-scheduler.js +30 -0
  103. package/dist/src/agents/agent-scheduler.js.map +1 -0
  104. package/dist/src/agents/agent-scheduler.test.d.ts +6 -0
  105. package/dist/src/agents/agent-scheduler.test.js +56 -0
  106. package/dist/src/agents/agent-scheduler.test.js.map +1 -0
  107. package/dist/src/agents/agentLoader.d.ts +88 -0
  108. package/dist/src/agents/agentLoader.js +394 -0
  109. package/dist/src/agents/agentLoader.js.map +1 -0
  110. package/dist/src/agents/agentLoader.test.d.ts +6 -0
  111. package/dist/src/agents/agentLoader.test.js +458 -0
  112. package/dist/src/agents/agentLoader.test.js.map +1 -0
  113. package/dist/src/agents/auth-provider/base-provider.d.ts +40 -0
  114. package/dist/src/agents/auth-provider/base-provider.js +43 -0
  115. package/dist/src/agents/auth-provider/base-provider.js.map +1 -0
  116. package/dist/src/agents/auth-provider/base-provider.test.d.ts +6 -0
  117. package/dist/src/agents/auth-provider/base-provider.test.js +107 -0
  118. package/dist/src/agents/auth-provider/base-provider.test.js.map +1 -0
  119. package/dist/src/agents/auth-provider/factory.d.ts +27 -0
  120. package/dist/src/agents/auth-provider/factory.js +161 -0
  121. package/dist/src/agents/auth-provider/factory.js.map +1 -0
  122. package/dist/src/agents/auth-provider/factory.test.d.ts +6 -0
  123. package/dist/src/agents/auth-provider/factory.test.js +344 -0
  124. package/dist/src/agents/auth-provider/factory.test.js.map +1 -0
  125. package/dist/src/agents/auth-provider/types.d.ts +74 -0
  126. package/dist/src/agents/auth-provider/types.js +7 -0
  127. package/dist/src/agents/auth-provider/types.js.map +1 -0
  128. package/dist/src/agents/auth-provider/value-resolver.d.ts +29 -0
  129. package/dist/src/agents/auth-provider/value-resolver.js +85 -0
  130. package/dist/src/agents/auth-provider/value-resolver.js.map +1 -0
  131. package/dist/src/agents/auth-provider/value-resolver.test.d.ts +6 -0
  132. package/dist/src/agents/auth-provider/value-resolver.test.js +100 -0
  133. package/dist/src/agents/auth-provider/value-resolver.test.js.map +1 -0
  134. package/dist/src/agents/cli-help-agent.d.ts +24 -0
  135. package/dist/src/agents/cli-help-agent.js +80 -0
  136. package/dist/src/agents/cli-help-agent.js.map +1 -0
  137. package/dist/src/agents/cli-help-agent.test.d.ts +6 -0
  138. package/dist/src/agents/cli-help-agent.test.js +53 -0
  139. package/dist/src/agents/cli-help-agent.test.js.map +1 -0
  140. package/dist/src/agents/codebase-investigator.d.ts +2 -1
  141. package/dist/src/agents/codebase-investigator.js +68 -39
  142. package/dist/src/agents/codebase-investigator.js.map +1 -1
  143. package/dist/src/agents/codebase-investigator.test.js +37 -9
  144. package/dist/src/agents/codebase-investigator.test.js.map +1 -1
  145. package/dist/src/agents/generalist-agent.d.ts +21 -0
  146. package/dist/src/agents/generalist-agent.js +60 -0
  147. package/dist/src/agents/generalist-agent.js.map +1 -0
  148. package/dist/src/agents/generalist-agent.test.d.ts +6 -0
  149. package/dist/src/agents/generalist-agent.test.js +32 -0
  150. package/dist/src/agents/generalist-agent.test.js.map +1 -0
  151. package/dist/src/agents/introspection-agent.d.ts +2 -2
  152. package/dist/src/agents/local-executor.d.ts +2 -0
  153. package/dist/src/agents/local-executor.js +186 -90
  154. package/dist/src/agents/local-executor.js.map +1 -1
  155. package/dist/src/agents/local-executor.test.js +431 -256
  156. package/dist/src/agents/local-executor.test.js.map +1 -1
  157. package/dist/src/agents/local-invocation.test.js +15 -5
  158. package/dist/src/agents/local-invocation.test.js.map +1 -1
  159. package/dist/src/agents/registry.d.ts +24 -8
  160. package/dist/src/agents/registry.js +193 -96
  161. package/dist/src/agents/registry.js.map +1 -1
  162. package/dist/src/agents/registry.test.js +509 -58
  163. package/dist/src/agents/registry.test.js.map +1 -1
  164. package/dist/src/agents/registry_acknowledgement.test.d.ts +6 -0
  165. package/dist/src/agents/registry_acknowledgement.test.js +130 -0
  166. package/dist/src/agents/registry_acknowledgement.test.js.map +1 -0
  167. package/dist/src/agents/remote-invocation.js +12 -14
  168. package/dist/src/agents/remote-invocation.js.map +1 -1
  169. package/dist/src/agents/remote-invocation.test.js +16 -4
  170. package/dist/src/agents/remote-invocation.test.js.map +1 -1
  171. package/dist/src/agents/subagent-tool-wrapper.js +1 -3
  172. package/dist/src/agents/subagent-tool-wrapper.js.map +1 -1
  173. package/dist/src/agents/subagent-tool-wrapper.test.js +18 -27
  174. package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -1
  175. package/dist/src/agents/subagent-tool.d.ts +15 -0
  176. package/dist/src/agents/subagent-tool.js +57 -0
  177. package/dist/src/agents/subagent-tool.js.map +1 -0
  178. package/dist/src/agents/subagent-tool.test.d.ts +6 -0
  179. package/dist/src/agents/subagent-tool.test.js +97 -0
  180. package/dist/src/agents/subagent-tool.test.js.map +1 -0
  181. package/dist/src/agents/types.d.ts +37 -22
  182. package/dist/src/agents/types.js +12 -0
  183. package/dist/src/agents/types.js.map +1 -1
  184. package/dist/src/availability/fallbackIntegration.test.d.ts +6 -0
  185. package/dist/src/availability/fallbackIntegration.test.js +57 -0
  186. package/dist/src/availability/fallbackIntegration.test.js.map +1 -0
  187. package/dist/src/availability/policyCatalog.d.ts +3 -0
  188. package/dist/src/availability/policyCatalog.js +29 -5
  189. package/dist/src/availability/policyCatalog.js.map +1 -1
  190. package/dist/src/availability/policyCatalog.test.js +20 -1
  191. package/dist/src/availability/policyCatalog.test.js.map +1 -1
  192. package/dist/src/availability/policyHelpers.js +40 -11
  193. package/dist/src/availability/policyHelpers.js.map +1 -1
  194. package/dist/src/availability/policyHelpers.test.js +72 -2
  195. package/dist/src/availability/policyHelpers.test.js.map +1 -1
  196. package/dist/src/availability/testUtils.js +1 -0
  197. package/dist/src/availability/testUtils.js.map +1 -1
  198. package/dist/src/code_assist/admin/admin_controls.d.ts +49 -0
  199. package/dist/src/code_assist/admin/admin_controls.js +197 -0
  200. package/dist/src/code_assist/admin/admin_controls.js.map +1 -0
  201. package/dist/src/code_assist/admin/admin_controls.test.d.ts +6 -0
  202. package/dist/src/code_assist/admin/admin_controls.test.js +589 -0
  203. package/dist/src/code_assist/admin/admin_controls.test.js.map +1 -0
  204. package/dist/src/code_assist/admin/mcpUtils.d.ts +22 -0
  205. package/dist/src/code_assist/admin/mcpUtils.js +53 -0
  206. package/dist/src/code_assist/admin/mcpUtils.js.map +1 -0
  207. package/dist/src/code_assist/admin/mcpUtils.test.d.ts +6 -0
  208. package/dist/src/code_assist/admin/mcpUtils.test.js +101 -0
  209. package/dist/src/code_assist/admin/mcpUtils.test.js.map +1 -0
  210. package/dist/src/code_assist/codeAssist.js +2 -2
  211. package/dist/src/code_assist/codeAssist.js.map +1 -1
  212. package/dist/src/code_assist/codeAssist.test.d.ts +1 -1
  213. package/dist/src/code_assist/codeAssist.test.js +10 -6
  214. package/dist/src/code_assist/codeAssist.test.js.map +1 -1
  215. package/dist/src/code_assist/converter.js +8 -3
  216. package/dist/src/code_assist/converter.js.map +1 -1
  217. package/dist/src/code_assist/converter.test.js +8 -0
  218. package/dist/src/code_assist/converter.test.js.map +1 -1
  219. package/dist/src/code_assist/experiments/experiments.d.ts +1 -1
  220. package/dist/src/code_assist/experiments/experiments.js +22 -0
  221. package/dist/src/code_assist/experiments/experiments.js.map +1 -1
  222. package/dist/src/code_assist/experiments/experiments.test.js +1 -0
  223. package/dist/src/code_assist/experiments/experiments.test.js.map +1 -1
  224. package/dist/src/code_assist/experiments/experiments_local.test.d.ts +6 -0
  225. package/dist/src/code_assist/experiments/experiments_local.test.js +115 -0
  226. package/dist/src/code_assist/experiments/experiments_local.test.js.map +1 -0
  227. package/dist/src/code_assist/experiments/flagNames.d.ts +7 -0
  228. package/dist/src/code_assist/experiments/flagNames.js +7 -0
  229. package/dist/src/code_assist/experiments/flagNames.js.map +1 -1
  230. package/dist/src/code_assist/oauth-credential-storage.js +4 -4
  231. package/dist/src/code_assist/oauth-credential-storage.js.map +1 -1
  232. package/dist/src/code_assist/oauth2.test.js +10 -3
  233. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  234. package/dist/src/code_assist/server.d.ts +7 -4
  235. package/dist/src/code_assist/server.js +20 -4
  236. package/dist/src/code_assist/server.js.map +1 -1
  237. package/dist/src/code_assist/server.test.js +18 -5
  238. package/dist/src/code_assist/server.test.js.map +1 -1
  239. package/dist/src/code_assist/setup.d.ts +35 -3
  240. package/dist/src/code_assist/setup.js +98 -16
  241. package/dist/src/code_assist/setup.js.map +1 -1
  242. package/dist/src/code_assist/setup.test.js +322 -5
  243. package/dist/src/code_assist/setup.test.js.map +1 -1
  244. package/dist/src/code_assist/telemetry.js +2 -1
  245. package/dist/src/code_assist/telemetry.js.map +1 -1
  246. package/dist/src/code_assist/telemetry.test.js +2 -1
  247. package/dist/src/code_assist/telemetry.test.js.map +1 -1
  248. package/dist/src/code_assist/types.d.ts +255 -24
  249. package/dist/src/code_assist/types.js +57 -7
  250. package/dist/src/code_assist/types.js.map +1 -1
  251. package/dist/src/commands/memory.d.ts +11 -0
  252. package/dist/src/commands/memory.js +81 -0
  253. package/dist/src/commands/memory.js.map +1 -0
  254. package/dist/src/commands/memory.test.d.ts +6 -0
  255. package/dist/src/commands/memory.test.js +155 -0
  256. package/dist/src/commands/memory.test.js.map +1 -0
  257. package/dist/src/commands/restore.js +1 -0
  258. package/dist/src/commands/restore.js.map +1 -1
  259. package/dist/src/config/config.d.ts +267 -58
  260. package/dist/src/config/config.js +663 -164
  261. package/dist/src/config/config.js.map +1 -1
  262. package/dist/src/config/config.test.d.ts +1 -1
  263. package/dist/src/config/config.test.js +585 -166
  264. package/dist/src/config/config.test.js.map +1 -1
  265. package/dist/src/config/constants.d.ts +4 -0
  266. package/dist/src/config/constants.js +8 -0
  267. package/dist/src/config/constants.js.map +1 -1
  268. package/dist/src/config/defaultModelConfigs.js +27 -8
  269. package/dist/src/config/defaultModelConfigs.js.map +1 -1
  270. package/dist/src/config/memory.d.ts +14 -0
  271. package/dist/src/config/memory.js +28 -0
  272. package/dist/src/config/memory.js.map +1 -0
  273. package/dist/src/config/memory.test.d.ts +6 -0
  274. package/dist/src/config/memory.test.js +82 -0
  275. package/dist/src/config/memory.test.js.map +1 -0
  276. package/dist/src/config/models.d.ts +77 -6
  277. package/dist/src/config/models.js +240 -23
  278. package/dist/src/config/models.js.map +1 -1
  279. package/dist/src/config/models.test.js +153 -47
  280. package/dist/src/config/models.test.js.map +1 -1
  281. package/dist/src/config/projectRegistry.d.ts +36 -0
  282. package/dist/src/config/projectRegistry.js +262 -0
  283. package/dist/src/config/projectRegistry.js.map +1 -0
  284. package/dist/src/config/projectRegistry.test.d.ts +6 -0
  285. package/dist/src/config/projectRegistry.test.js +219 -0
  286. package/dist/src/config/projectRegistry.test.js.map +1 -0
  287. package/dist/src/config/storage.d.ts +23 -1
  288. package/dist/src/config/storage.js +104 -15
  289. package/dist/src/config/storage.js.map +1 -1
  290. package/dist/src/config/storage.test.js +118 -2
  291. package/dist/src/config/storage.test.js.map +1 -1
  292. package/dist/src/config/storageMigration.d.ts +16 -0
  293. package/dist/src/config/storageMigration.js +42 -0
  294. package/dist/src/config/storageMigration.js.map +1 -0
  295. package/dist/src/config/storageMigration.test.d.ts +6 -0
  296. package/dist/src/config/storageMigration.test.js +70 -0
  297. package/dist/src/config/storageMigration.test.js.map +1 -0
  298. package/dist/src/confirmation-bus/message-bus.js +3 -33
  299. package/dist/src/confirmation-bus/message-bus.js.map +1 -1
  300. package/dist/src/confirmation-bus/types.d.ts +95 -20
  301. package/dist/src/confirmation-bus/types.js +9 -3
  302. package/dist/src/confirmation-bus/types.js.map +1 -1
  303. package/dist/src/core/anthropicContentGenerator.d.ts +3 -2
  304. package/dist/src/core/anthropicContentGenerator.js +2 -2
  305. package/dist/src/core/anthropicContentGenerator.js.map +1 -1
  306. package/dist/src/core/baseLlmClient.d.ts +9 -0
  307. package/dist/src/core/baseLlmClient.js +9 -8
  308. package/dist/src/core/baseLlmClient.js.map +1 -1
  309. package/dist/src/core/baseLlmClient.test.js +17 -7
  310. package/dist/src/core/baseLlmClient.test.js.map +1 -1
  311. package/dist/src/core/bedrockContentGenerator.d.ts +73 -0
  312. package/dist/src/core/bedrockContentGenerator.js +628 -0
  313. package/dist/src/core/bedrockContentGenerator.js.map +1 -0
  314. package/dist/src/core/client.d.ts +13 -4
  315. package/dist/src/core/client.js +132 -41
  316. package/dist/src/core/client.js.map +1 -1
  317. package/dist/src/core/client.test.js +333 -79
  318. package/dist/src/core/client.test.js.map +1 -1
  319. package/dist/src/core/contentGenerator.d.ts +16 -3
  320. package/dist/src/core/contentGenerator.js +56 -2
  321. package/dist/src/core/contentGenerator.js.map +1 -1
  322. package/dist/src/core/contentGenerator.test.d.ts +1 -1
  323. package/dist/src/core/contentGenerator.test.js +127 -24
  324. package/dist/src/core/contentGenerator.test.js.map +1 -1
  325. package/dist/src/core/coreToolHookTriggers.d.ts +4 -36
  326. package/dist/src/core/coreToolHookTriggers.js +42 -150
  327. package/dist/src/core/coreToolHookTriggers.js.map +1 -1
  328. package/dist/src/core/coreToolHookTriggers.test.js +62 -94
  329. package/dist/src/core/coreToolHookTriggers.test.js.map +1 -1
  330. package/dist/src/core/coreToolScheduler.d.ts +1 -8
  331. package/dist/src/core/coreToolScheduler.js +160 -125
  332. package/dist/src/core/coreToolScheduler.js.map +1 -1
  333. package/dist/src/core/coreToolScheduler.test.js +480 -62
  334. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  335. package/dist/src/core/fakeContentGenerator.d.ts +4 -2
  336. package/dist/src/core/fakeContentGenerator.js +9 -2
  337. package/dist/src/core/fakeContentGenerator.js.map +1 -1
  338. package/dist/src/core/fakeContentGenerator.test.js +8 -7
  339. package/dist/src/core/fakeContentGenerator.test.js.map +1 -1
  340. package/dist/src/core/geminiChat.d.ts +31 -3
  341. package/dist/src/core/geminiChat.js +144 -34
  342. package/dist/src/core/geminiChat.js.map +1 -1
  343. package/dist/src/core/geminiChat.test.js +175 -50
  344. package/dist/src/core/geminiChat.test.js.map +1 -1
  345. package/dist/src/core/geminiChat_network_retry.test.js +146 -16
  346. package/dist/src/core/geminiChat_network_retry.test.js.map +1 -1
  347. package/dist/src/core/logger.js +11 -0
  348. package/dist/src/core/logger.js.map +1 -1
  349. package/dist/src/core/logger.test.js +2 -4
  350. package/dist/src/core/logger.test.js.map +1 -1
  351. package/dist/src/core/loggingContentGenerator.d.ts +7 -3
  352. package/dist/src/core/loggingContentGenerator.js +40 -21
  353. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  354. package/dist/src/core/loggingContentGenerator.test.d.ts +1 -1
  355. package/dist/src/core/loggingContentGenerator.test.js +50 -8
  356. package/dist/src/core/loggingContentGenerator.test.js.map +1 -1
  357. package/dist/src/core/openaiContentGenerator.d.ts +3 -2
  358. package/dist/src/core/openaiContentGenerator.js +18 -10
  359. package/dist/src/core/openaiContentGenerator.js.map +1 -1
  360. package/dist/src/core/openaiContentGenerator.test.js +57 -4
  361. package/dist/src/core/openaiContentGenerator.test.js.map +1 -1
  362. package/dist/src/core/prompts-substitution.test.d.ts +6 -0
  363. package/dist/src/core/prompts-substitution.test.js +109 -0
  364. package/dist/src/core/prompts-substitution.test.js.map +1 -0
  365. package/dist/src/core/prompts.d.ts +11 -9
  366. package/dist/src/core/prompts.js +14 -405
  367. package/dist/src/core/prompts.js.map +1 -1
  368. package/dist/src/core/prompts.test.js +290 -56
  369. package/dist/src/core/prompts.test.js.map +1 -1
  370. package/dist/src/core/recordingContentGenerator.d.ts +5 -3
  371. package/dist/src/core/recordingContentGenerator.js +12 -5
  372. package/dist/src/core/recordingContentGenerator.js.map +1 -1
  373. package/dist/src/core/recordingContentGenerator.test.js +5 -4
  374. package/dist/src/core/recordingContentGenerator.test.js.map +1 -1
  375. package/dist/src/core/tokenLimits.js +6 -10
  376. package/dist/src/core/tokenLimits.js.map +1 -1
  377. package/dist/src/core/tokenLimits.test.js +8 -4
  378. package/dist/src/core/tokenLimits.test.js.map +1 -1
  379. package/dist/src/core/turn.d.ts +10 -2
  380. package/dist/src/core/turn.js +36 -17
  381. package/dist/src/core/turn.js.map +1 -1
  382. package/dist/src/core/turn.test.js +82 -2
  383. package/dist/src/core/turn.test.js.map +1 -1
  384. package/dist/src/fallback/handler.js +1 -1
  385. package/dist/src/fallback/handler.js.map +1 -1
  386. package/dist/src/fallback/handler.test.js +10 -12
  387. package/dist/src/fallback/handler.test.js.map +1 -1
  388. package/dist/src/fallback/types.d.ts +9 -0
  389. package/dist/src/generated/git-commit.d.ts +2 -2
  390. package/dist/src/generated/git-commit.js +2 -2
  391. package/dist/src/hooks/hookAggregator.js +16 -4
  392. package/dist/src/hooks/hookAggregator.js.map +1 -1
  393. package/dist/src/hooks/hookEventHandler.d.ts +10 -16
  394. package/dist/src/hooks/hookEventHandler.js +35 -281
  395. package/dist/src/hooks/hookEventHandler.js.map +1 -1
  396. package/dist/src/hooks/hookEventHandler.test.js +189 -4
  397. package/dist/src/hooks/hookEventHandler.test.js.map +1 -1
  398. package/dist/src/hooks/hookRegistry.js +8 -3
  399. package/dist/src/hooks/hookRegistry.js.map +1 -1
  400. package/dist/src/hooks/hookRegistry.test.js +31 -2
  401. package/dist/src/hooks/hookRegistry.test.js.map +1 -1
  402. package/dist/src/hooks/hookRunner.js +21 -18
  403. package/dist/src/hooks/hookRunner.js.map +1 -1
  404. package/dist/src/hooks/hookSystem.d.ts +59 -0
  405. package/dist/src/hooks/hookSystem.js +206 -6
  406. package/dist/src/hooks/hookSystem.js.map +1 -1
  407. package/dist/src/hooks/hookSystem.test.js +20 -9
  408. package/dist/src/hooks/hookSystem.test.js.map +1 -1
  409. package/dist/src/hooks/hookTranslator.js +13 -6
  410. package/dist/src/hooks/hookTranslator.js.map +1 -1
  411. package/dist/src/hooks/index.d.ts +0 -1
  412. package/dist/src/hooks/index.js +0 -2
  413. package/dist/src/hooks/index.js.map +1 -1
  414. package/dist/src/hooks/trustedHooks.js +2 -0
  415. package/dist/src/hooks/trustedHooks.js.map +1 -1
  416. package/dist/src/hooks/types.d.ts +49 -1
  417. package/dist/src/hooks/types.js +43 -19
  418. package/dist/src/hooks/types.js.map +1 -1
  419. package/dist/src/hooks/types.test.js +13 -29
  420. package/dist/src/hooks/types.test.js.map +1 -1
  421. package/dist/src/ide/detect-ide.d.ts +49 -0
  422. package/dist/src/ide/detect-ide.js +56 -3
  423. package/dist/src/ide/detect-ide.js.map +1 -1
  424. package/dist/src/ide/detect-ide.test.js +70 -0
  425. package/dist/src/ide/detect-ide.test.js.map +1 -1
  426. package/dist/src/ide/ide-client.d.ts +0 -10
  427. package/dist/src/ide/ide-client.js +31 -199
  428. package/dist/src/ide/ide-client.js.map +1 -1
  429. package/dist/src/ide/ide-client.test.js +39 -191
  430. package/dist/src/ide/ide-client.test.js.map +1 -1
  431. package/dist/src/ide/ide-connection-utils.d.ts +27 -0
  432. package/dist/src/ide/ide-connection-utils.js +195 -0
  433. package/dist/src/ide/ide-connection-utils.js.map +1 -0
  434. package/dist/src/ide/ide-connection-utils.test.d.ts +6 -0
  435. package/dist/src/ide/ide-connection-utils.test.js +372 -0
  436. package/dist/src/ide/ide-connection-utils.test.js.map +1 -0
  437. package/dist/src/ide/ide-installer.js +76 -5
  438. package/dist/src/ide/ide-installer.js.map +1 -1
  439. package/dist/src/ide/ide-installer.test.js +40 -2
  440. package/dist/src/ide/ide-installer.test.js.map +1 -1
  441. package/dist/src/ide/types.d.ts +46 -46
  442. package/dist/src/index.d.ts +30 -2
  443. package/dist/src/index.js +31 -2
  444. package/dist/src/index.js.map +1 -1
  445. package/dist/src/mcp/oauth-provider.d.ts +10 -3
  446. package/dist/src/mcp/oauth-provider.js +49 -14
  447. package/dist/src/mcp/oauth-provider.js.map +1 -1
  448. package/dist/src/mcp/oauth-provider.test.js +180 -1
  449. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  450. package/dist/src/mcp/oauth-token-storage.js +3 -0
  451. package/dist/src/mcp/oauth-token-storage.js.map +1 -1
  452. package/dist/src/mcp/oauth-utils.d.ts +13 -4
  453. package/dist/src/mcp/oauth-utils.js +25 -19
  454. package/dist/src/mcp/oauth-utils.js.map +1 -1
  455. package/dist/src/mcp/oauth-utils.test.js +13 -8
  456. package/dist/src/mcp/oauth-utils.test.js.map +1 -1
  457. package/dist/src/mcp/sa-impersonation-provider.js +3 -1
  458. package/dist/src/mcp/sa-impersonation-provider.js.map +1 -1
  459. package/dist/src/mcp/token-storage/file-token-storage.js +6 -2
  460. package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -1
  461. package/dist/src/mcp/token-storage/hybrid-token-storage.js +4 -0
  462. package/dist/src/mcp/token-storage/hybrid-token-storage.js.map +1 -1
  463. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js +12 -0
  464. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js.map +1 -1
  465. package/dist/src/mcp/token-storage/keychain-token-storage.js +8 -0
  466. package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -1
  467. package/dist/src/mcp/token-storage/keychain-token-storage.test.js +10 -5
  468. package/dist/src/mcp/token-storage/keychain-token-storage.test.js.map +1 -1
  469. package/dist/src/output/json-formatter.test.js +2 -0
  470. package/dist/src/output/json-formatter.test.js.map +1 -1
  471. package/dist/src/output/stream-json-formatter.test.js +4 -0
  472. package/dist/src/output/stream-json-formatter.test.js.map +1 -1
  473. package/dist/src/policy/config.d.ts +5 -3
  474. package/dist/src/policy/config.js +137 -64
  475. package/dist/src/policy/config.js.map +1 -1
  476. package/dist/src/policy/config.test.js +218 -12
  477. package/dist/src/policy/config.test.js.map +1 -1
  478. package/dist/src/policy/persistence.test.js +31 -11
  479. package/dist/src/policy/persistence.test.js.map +1 -1
  480. package/dist/src/policy/policies/plan.toml +56 -0
  481. package/dist/src/policy/policies/read-only.toml +1 -11
  482. package/dist/src/policy/policies/yolo.toml +13 -2
  483. package/dist/src/policy/policy-engine.d.ts +16 -11
  484. package/dist/src/policy/policy-engine.js +208 -101
  485. package/dist/src/policy/policy-engine.js.map +1 -1
  486. package/dist/src/policy/policy-engine.test.js +538 -199
  487. package/dist/src/policy/policy-engine.test.js.map +1 -1
  488. package/dist/src/policy/policy-updater.test.js +20 -6
  489. package/dist/src/policy/policy-updater.test.js.map +1 -1
  490. package/dist/src/policy/shell-safety.test.js +371 -8
  491. package/dist/src/policy/shell-safety.test.js.map +1 -1
  492. package/dist/src/policy/stable-stringify.js +1 -0
  493. package/dist/src/policy/stable-stringify.js.map +1 -1
  494. package/dist/src/policy/toml-loader.d.ts +5 -5
  495. package/dist/src/policy/toml-loader.js +65 -22
  496. package/dist/src/policy/toml-loader.js.map +1 -1
  497. package/dist/src/policy/toml-loader.test.js +88 -9
  498. package/dist/src/policy/toml-loader.test.js.map +1 -1
  499. package/dist/src/policy/types.d.ts +26 -1
  500. package/dist/src/policy/types.js +8 -0
  501. package/dist/src/policy/types.js.map +1 -1
  502. package/dist/src/policy/utils.d.ts +5 -0
  503. package/dist/src/policy/utils.js +32 -1
  504. package/dist/src/policy/utils.js.map +1 -1
  505. package/dist/src/policy/utils.test.js +67 -7
  506. package/dist/src/policy/utils.test.js.map +1 -1
  507. package/dist/src/prompts/promptProvider.d.ts +19 -0
  508. package/dist/src/prompts/promptProvider.js +174 -0
  509. package/dist/src/prompts/promptProvider.js.map +1 -0
  510. package/dist/src/prompts/promptProvider.test.d.ts +6 -0
  511. package/dist/src/prompts/promptProvider.test.js +71 -0
  512. package/dist/src/prompts/promptProvider.test.js.map +1 -0
  513. package/dist/src/prompts/snippets.d.ts +86 -0
  514. package/dist/src/prompts/snippets.js +573 -0
  515. package/dist/src/prompts/snippets.js.map +1 -0
  516. package/dist/src/prompts/snippets.legacy.d.ts +91 -0
  517. package/dist/src/prompts/snippets.legacy.js +573 -0
  518. package/dist/src/prompts/snippets.legacy.js.map +1 -0
  519. package/dist/src/prompts/utils.d.ts +23 -0
  520. package/dist/src/prompts/utils.js +82 -0
  521. package/dist/src/prompts/utils.js.map +1 -0
  522. package/dist/src/routing/modelRouterService.js +18 -8
  523. package/dist/src/routing/modelRouterService.js.map +1 -1
  524. package/dist/src/routing/modelRouterService.test.js +14 -6
  525. package/dist/src/routing/modelRouterService.test.js.map +1 -1
  526. package/dist/src/routing/routingStrategy.d.ts +2 -0
  527. package/dist/src/routing/strategies/classifierStrategy.js +14 -9
  528. package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
  529. package/dist/src/routing/strategies/classifierStrategy.test.js +72 -7
  530. package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -1
  531. package/dist/src/routing/strategies/compositeStrategy.js +1 -0
  532. package/dist/src/routing/strategies/compositeStrategy.js.map +1 -1
  533. package/dist/src/routing/strategies/defaultStrategy.d.ts +1 -1
  534. package/dist/src/routing/strategies/defaultStrategy.js +5 -4
  535. package/dist/src/routing/strategies/defaultStrategy.js.map +1 -1
  536. package/dist/src/routing/strategies/defaultStrategy.test.js +58 -4
  537. package/dist/src/routing/strategies/defaultStrategy.test.js.map +1 -1
  538. package/dist/src/routing/strategies/fallbackStrategy.d.ts +1 -1
  539. package/dist/src/routing/strategies/fallbackStrategy.js +3 -3
  540. package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -1
  541. package/dist/src/routing/strategies/fallbackStrategy.test.js +13 -1
  542. package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -1
  543. package/dist/src/routing/strategies/numericalClassifierStrategy.d.ts +13 -0
  544. package/dist/src/routing/strategies/numericalClassifierStrategy.js +188 -0
  545. package/dist/src/routing/strategies/numericalClassifierStrategy.js.map +1 -0
  546. package/dist/src/routing/strategies/numericalClassifierStrategy.test.d.ts +6 -0
  547. package/dist/src/routing/strategies/numericalClassifierStrategy.test.js +401 -0
  548. package/dist/src/routing/strategies/numericalClassifierStrategy.test.js.map +1 -0
  549. package/dist/src/routing/strategies/overrideStrategy.d.ts +1 -1
  550. package/dist/src/routing/strategies/overrideStrategy.js +6 -6
  551. package/dist/src/routing/strategies/overrideStrategy.js.map +1 -1
  552. package/dist/src/routing/strategies/overrideStrategy.test.js +13 -3
  553. package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -1
  554. package/dist/src/safety/built-in.js +1 -0
  555. package/dist/src/safety/built-in.js.map +1 -1
  556. package/dist/src/safety/context-builder.js +3 -1
  557. package/dist/src/safety/context-builder.js.map +1 -1
  558. package/dist/src/scheduler/confirmation.d.ts +50 -0
  559. package/dist/src/scheduler/confirmation.js +204 -0
  560. package/dist/src/scheduler/confirmation.js.map +1 -0
  561. package/dist/src/scheduler/confirmation.test.d.ts +6 -0
  562. package/dist/src/scheduler/confirmation.test.js +310 -0
  563. package/dist/src/scheduler/confirmation.test.js.map +1 -0
  564. package/dist/src/scheduler/policy.d.ts +33 -0
  565. package/dist/src/scheduler/policy.js +119 -0
  566. package/dist/src/scheduler/policy.js.map +1 -0
  567. package/dist/src/scheduler/policy.test.d.ts +6 -0
  568. package/dist/src/scheduler/policy.test.js +419 -0
  569. package/dist/src/scheduler/policy.test.js.map +1 -0
  570. package/dist/src/scheduler/scheduler.d.ts +63 -0
  571. package/dist/src/scheduler/scheduler.js +371 -0
  572. package/dist/src/scheduler/scheduler.js.map +1 -0
  573. package/dist/src/scheduler/scheduler.test.d.ts +6 -0
  574. package/dist/src/scheduler/scheduler.test.js +937 -0
  575. package/dist/src/scheduler/scheduler.test.js.map +1 -0
  576. package/dist/src/scheduler/scheduler_waiting_callback.test.d.ts +6 -0
  577. package/dist/src/scheduler/scheduler_waiting_callback.test.js +62 -0
  578. package/dist/src/scheduler/scheduler_waiting_callback.test.js.map +1 -0
  579. package/dist/src/scheduler/state-manager.d.ts +74 -0
  580. package/dist/src/scheduler/state-manager.js +368 -0
  581. package/dist/src/scheduler/state-manager.js.map +1 -0
  582. package/dist/src/scheduler/state-manager.test.d.ts +6 -0
  583. package/dist/src/scheduler/state-manager.test.js +433 -0
  584. package/dist/src/scheduler/state-manager.test.js.map +1 -0
  585. package/dist/src/scheduler/tool-executor.js +25 -27
  586. package/dist/src/scheduler/tool-executor.js.map +1 -1
  587. package/dist/src/scheduler/tool-executor.test.js +26 -25
  588. package/dist/src/scheduler/tool-executor.test.js.map +1 -1
  589. package/dist/src/scheduler/tool-modifier.d.ts +23 -0
  590. package/dist/src/scheduler/tool-modifier.js +53 -0
  591. package/dist/src/scheduler/tool-modifier.js.map +1 -0
  592. package/dist/src/scheduler/tool-modifier.test.d.ts +6 -0
  593. package/dist/src/scheduler/tool-modifier.test.js +179 -0
  594. package/dist/src/scheduler/tool-modifier.test.js.map +1 -0
  595. package/dist/src/scheduler/types.d.ts +51 -8
  596. package/dist/src/scheduler/types.js +15 -1
  597. package/dist/src/scheduler/types.js.map +1 -1
  598. package/dist/src/services/chatCompressionService.d.ts +5 -1
  599. package/dist/src/services/chatCompressionService.js +169 -23
  600. package/dist/src/services/chatCompressionService.js.map +1 -1
  601. package/dist/src/services/chatCompressionService.test.js +382 -18
  602. package/dist/src/services/chatCompressionService.test.js.map +1 -1
  603. package/dist/src/services/chatRecordingService.d.ts +23 -3
  604. package/dist/src/services/chatRecordingService.js +137 -7
  605. package/dist/src/services/chatRecordingService.js.map +1 -1
  606. package/dist/src/services/chatRecordingService.test.js +450 -186
  607. package/dist/src/services/chatRecordingService.test.js.map +1 -1
  608. package/dist/src/services/contextManager.d.ts +7 -4
  609. package/dist/src/services/contextManager.js +43 -18
  610. package/dist/src/services/contextManager.js.map +1 -1
  611. package/dist/src/services/contextManager.test.js +54 -27
  612. package/dist/src/services/contextManager.test.js.map +1 -1
  613. package/dist/src/services/environmentSanitization.js +4 -3
  614. package/dist/src/services/environmentSanitization.js.map +1 -1
  615. package/dist/src/services/fileDiscoveryService.d.ts +14 -2
  616. package/dist/src/services/fileDiscoveryService.js +79 -7
  617. package/dist/src/services/fileDiscoveryService.js.map +1 -1
  618. package/dist/src/services/fileDiscoveryService.test.js +142 -10
  619. package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
  620. package/dist/src/services/gitService.d.ts +2 -1
  621. package/dist/src/services/gitService.js +16 -6
  622. package/dist/src/services/gitService.js.map +1 -1
  623. package/dist/src/services/gitService.test.js +26 -10
  624. package/dist/src/services/gitService.test.js.map +1 -1
  625. package/dist/src/services/loopDetectionService.js +23 -4
  626. package/dist/src/services/loopDetectionService.js.map +1 -1
  627. package/dist/src/services/loopDetectionService.test.js +24 -0
  628. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  629. package/dist/src/services/modelConfig.integration.test.js +2 -2
  630. package/dist/src/services/modelConfig.integration.test.js.map +1 -1
  631. package/dist/src/services/modelConfigService.d.ts +39 -4
  632. package/dist/src/services/modelConfigService.js +153 -76
  633. package/dist/src/services/modelConfigService.js.map +1 -1
  634. package/dist/src/services/modelConfigService.test.js +175 -0
  635. package/dist/src/services/modelConfigService.test.js.map +1 -1
  636. package/dist/src/services/modelConfigServiceTestUtils.js +3 -1
  637. package/dist/src/services/modelConfigServiceTestUtils.js.map +1 -1
  638. package/dist/src/services/sessionSummaryService.js +2 -0
  639. package/dist/src/services/sessionSummaryService.js.map +1 -1
  640. package/dist/src/services/sessionSummaryService.test.js +1 -1
  641. package/dist/src/services/sessionSummaryService.test.js.map +1 -1
  642. package/dist/src/services/shellExecutionService.d.ts +48 -0
  643. package/dist/src/services/shellExecutionService.js +339 -97
  644. package/dist/src/services/shellExecutionService.js.map +1 -1
  645. package/dist/src/services/shellExecutionService.test.js +132 -17
  646. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  647. package/dist/src/services/test-data/resolved-aliases-retry.golden.json +26 -8
  648. package/dist/src/services/test-data/resolved-aliases.golden.json +26 -8
  649. package/dist/src/services/toolOutputMaskingService.d.ts +43 -0
  650. package/dist/src/services/toolOutputMaskingService.js +286 -0
  651. package/dist/src/services/toolOutputMaskingService.js.map +1 -0
  652. package/dist/src/services/toolOutputMaskingService.test.d.ts +6 -0
  653. package/dist/src/services/toolOutputMaskingService.test.js +546 -0
  654. package/dist/src/services/toolOutputMaskingService.test.js.map +1 -0
  655. package/dist/src/skills/builtin/skill-creator/SKILL.md +382 -0
  656. package/dist/src/skills/builtin/skill-creator/scripts/init_skill.cjs +239 -0
  657. package/dist/src/skills/builtin/skill-creator/scripts/package_skill.cjs +106 -0
  658. package/dist/src/skills/builtin/skill-creator/scripts/validate_skill.cjs +131 -0
  659. package/dist/src/skills/skillLoader.d.ts +3 -0
  660. package/dist/src/skills/skillLoader.js +73 -12
  661. package/dist/src/skills/skillLoader.js.map +1 -1
  662. package/dist/src/skills/skillLoader.test.d.ts +5 -0
  663. package/dist/src/skills/skillLoader.test.js +195 -1
  664. package/dist/src/skills/skillLoader.test.js.map +1 -1
  665. package/dist/src/skills/skillManager.d.ts +25 -3
  666. package/dist/src/skills/skillManager.js +76 -11
  667. package/dist/src/skills/skillManager.js.map +1 -1
  668. package/dist/src/skills/skillManager.test.js +209 -9
  669. package/dist/src/skills/skillManager.test.js.map +1 -1
  670. package/dist/src/skills/skillManagerAlias.test.d.ts +6 -0
  671. package/dist/src/skills/skillManagerAlias.test.js +140 -0
  672. package/dist/src/skills/skillManagerAlias.test.js.map +1 -0
  673. package/dist/src/telemetry/activity-monitor.js +1 -0
  674. package/dist/src/telemetry/activity-monitor.js.map +1 -1
  675. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +25 -4
  676. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +207 -12
  677. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  678. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +210 -6
  679. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  680. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +23 -1
  681. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +61 -1
  682. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  683. package/dist/src/telemetry/file-exporters.js +2 -1
  684. package/dist/src/telemetry/file-exporters.js.map +1 -1
  685. package/dist/src/telemetry/file-exporters.test.d.ts +6 -0
  686. package/dist/src/telemetry/file-exporters.test.js +142 -0
  687. package/dist/src/telemetry/file-exporters.test.js.map +1 -0
  688. package/dist/src/telemetry/gcp-exporters.js +1 -0
  689. package/dist/src/telemetry/gcp-exporters.js.map +1 -1
  690. package/dist/src/telemetry/index.d.ts +3 -2
  691. package/dist/src/telemetry/index.js +3 -2
  692. package/dist/src/telemetry/index.js.map +1 -1
  693. package/dist/src/telemetry/integration.test.circular.js +2 -1
  694. package/dist/src/telemetry/integration.test.circular.js.map +1 -1
  695. package/dist/src/telemetry/llmRole.d.ts +18 -0
  696. package/dist/src/telemetry/llmRole.js +20 -0
  697. package/dist/src/telemetry/llmRole.js.map +1 -0
  698. package/dist/src/telemetry/loggers.d.ts +8 -1
  699. package/dist/src/telemetry/loggers.js +113 -10
  700. package/dist/src/telemetry/loggers.js.map +1 -1
  701. package/dist/src/telemetry/loggers.test.circular.js +5 -2
  702. package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
  703. package/dist/src/telemetry/loggers.test.js +169 -19
  704. package/dist/src/telemetry/loggers.test.js.map +1 -1
  705. package/dist/src/telemetry/memory-monitor.test.js +1 -0
  706. package/dist/src/telemetry/memory-monitor.test.js.map +1 -1
  707. package/dist/src/telemetry/metrics.d.ts +39 -1
  708. package/dist/src/telemetry/metrics.js +105 -4
  709. package/dist/src/telemetry/metrics.js.map +1 -1
  710. package/dist/src/telemetry/metrics.test.js +84 -4
  711. package/dist/src/telemetry/metrics.test.js.map +1 -1
  712. package/dist/src/telemetry/sanitize.test.js +2 -0
  713. package/dist/src/telemetry/sanitize.test.js.map +1 -1
  714. package/dist/src/telemetry/sdk.js +24 -0
  715. package/dist/src/telemetry/sdk.js.map +1 -1
  716. package/dist/src/telemetry/sdk.test.js +5 -1
  717. package/dist/src/telemetry/sdk.test.js.map +1 -1
  718. package/dist/src/telemetry/semantic.js +92 -0
  719. package/dist/src/telemetry/semantic.js.map +1 -1
  720. package/dist/src/telemetry/semantic.truncation.test.d.ts +1 -0
  721. package/dist/src/telemetry/semantic.truncation.test.js +92 -0
  722. package/dist/src/telemetry/semantic.truncation.test.js.map +1 -0
  723. package/dist/src/telemetry/telemetryAttributes.js +5 -0
  724. package/dist/src/telemetry/telemetryAttributes.js.map +1 -1
  725. package/dist/src/telemetry/types.d.ts +98 -15
  726. package/dist/src/telemetry/types.js +227 -16
  727. package/dist/src/telemetry/types.js.map +1 -1
  728. package/dist/src/telemetry/uiTelemetry.d.ts +16 -0
  729. package/dist/src/telemetry/uiTelemetry.js +39 -0
  730. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  731. package/dist/src/telemetry/uiTelemetry.test.js +29 -0
  732. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  733. package/dist/src/test-utils/mock-message-bus.d.ts +1 -19
  734. package/dist/src/test-utils/mock-message-bus.js +5 -65
  735. package/dist/src/test-utils/mock-message-bus.js.map +1 -1
  736. package/dist/src/test-utils/mock-tool.d.ts +1 -0
  737. package/dist/src/test-utils/mock-tool.js +1 -0
  738. package/dist/src/test-utils/mock-tool.js.map +1 -1
  739. package/dist/src/test-utils/mockWorkspaceContext.js +1 -0
  740. package/dist/src/test-utils/mockWorkspaceContext.js.map +1 -1
  741. package/dist/src/tools/activate-skill.d.ts +1 -0
  742. package/dist/src/tools/activate-skill.js +28 -25
  743. package/dist/src/tools/activate-skill.js.map +1 -1
  744. package/dist/src/tools/activate-skill.test.js +24 -6
  745. package/dist/src/tools/activate-skill.test.js.map +1 -1
  746. package/dist/src/tools/ask-user.d.ts +29 -0
  747. package/dist/src/tools/ask-user.js +141 -0
  748. package/dist/src/tools/ask-user.js.map +1 -0
  749. package/dist/src/tools/ask-user.test.d.ts +6 -0
  750. package/dist/src/tools/ask-user.test.js +446 -0
  751. package/dist/src/tools/ask-user.test.js.map +1 -0
  752. package/dist/src/tools/confirmation-policy.test.js +21 -0
  753. package/dist/src/tools/confirmation-policy.test.js.map +1 -1
  754. package/dist/src/tools/constants.d.ts +7 -0
  755. package/dist/src/tools/constants.js +8 -0
  756. package/dist/src/tools/constants.js.map +1 -0
  757. package/dist/src/tools/definitions/base-declarations.d.ts +26 -0
  758. package/dist/src/tools/definitions/base-declarations.js +30 -0
  759. package/dist/src/tools/definitions/base-declarations.js.map +1 -0
  760. package/dist/src/tools/definitions/coreTools.d.ts +36 -0
  761. package/dist/src/tools/definitions/coreTools.js +143 -0
  762. package/dist/src/tools/definitions/coreTools.js.map +1 -0
  763. package/dist/src/tools/definitions/coreToolsModelSnapshots.test.d.ts +6 -0
  764. package/dist/src/tools/definitions/coreToolsModelSnapshots.test.js +82 -0
  765. package/dist/src/tools/definitions/coreToolsModelSnapshots.test.js.map +1 -0
  766. package/dist/src/tools/definitions/dynamic-declaration-helpers.d.ts +30 -0
  767. package/dist/src/tools/definitions/dynamic-declaration-helpers.js +135 -0
  768. package/dist/src/tools/definitions/dynamic-declaration-helpers.js.map +1 -0
  769. package/dist/src/tools/definitions/model-family-sets/default-legacy.d.ts +11 -0
  770. package/dist/src/tools/definitions/model-family-sets/default-legacy.js +575 -0
  771. package/dist/src/tools/definitions/model-family-sets/default-legacy.js.map +1 -0
  772. package/dist/src/tools/definitions/model-family-sets/gemini-3.d.ts +14 -0
  773. package/dist/src/tools/definitions/model-family-sets/gemini-3.js +578 -0
  774. package/dist/src/tools/definitions/model-family-sets/gemini-3.js.map +1 -0
  775. package/dist/src/tools/definitions/modelFamilyService.d.ts +14 -0
  776. package/dist/src/tools/definitions/modelFamilyService.js +29 -0
  777. package/dist/src/tools/definitions/modelFamilyService.js.map +1 -0
  778. package/dist/src/tools/definitions/resolver.d.ts +15 -0
  779. package/dist/src/tools/definitions/resolver.js +27 -0
  780. package/dist/src/tools/definitions/resolver.js.map +1 -0
  781. package/dist/src/tools/definitions/resolver.test.d.ts +6 -0
  782. package/dist/src/tools/definitions/resolver.test.js +58 -0
  783. package/dist/src/tools/definitions/resolver.test.js.map +1 -0
  784. package/dist/src/tools/definitions/types.d.ts +44 -0
  785. package/dist/src/tools/definitions/types.js +7 -0
  786. package/dist/src/tools/definitions/types.js.map +1 -0
  787. package/dist/src/tools/diffOptions.d.ts +1 -1
  788. package/dist/src/tools/diffOptions.js +7 -3
  789. package/dist/src/tools/diffOptions.js.map +1 -1
  790. package/dist/src/tools/diffOptions.test.js +17 -0
  791. package/dist/src/tools/diffOptions.test.js.map +1 -1
  792. package/dist/src/tools/edit.d.ts +1 -0
  793. package/dist/src/tools/edit.js +52 -82
  794. package/dist/src/tools/edit.js.map +1 -1
  795. package/dist/src/tools/edit.test.js +96 -1
  796. package/dist/src/tools/edit.test.js.map +1 -1
  797. package/dist/src/tools/enter-plan-mode.d.ts +25 -0
  798. package/dist/src/tools/enter-plan-mode.js +69 -0
  799. package/dist/src/tools/enter-plan-mode.js.map +1 -0
  800. package/dist/src/tools/enter-plan-mode.test.d.ts +6 -0
  801. package/dist/src/tools/enter-plan-mode.test.js +102 -0
  802. package/dist/src/tools/enter-plan-mode.test.js.map +1 -0
  803. package/dist/src/tools/exit-plan-mode.d.ts +33 -0
  804. package/dist/src/tools/exit-plan-mode.js +173 -0
  805. package/dist/src/tools/exit-plan-mode.js.map +1 -0
  806. package/dist/src/tools/exit-plan-mode.test.d.ts +6 -0
  807. package/dist/src/tools/exit-plan-mode.test.js +311 -0
  808. package/dist/src/tools/exit-plan-mode.test.js.map +1 -0
  809. package/dist/src/tools/get-internal-docs.d.ts +1 -0
  810. package/dist/src/tools/get-internal-docs.js +17 -27
  811. package/dist/src/tools/get-internal-docs.js.map +1 -1
  812. package/dist/src/tools/glob.d.ts +1 -0
  813. package/dist/src/tools/glob.js +15 -36
  814. package/dist/src/tools/glob.js.map +1 -1
  815. package/dist/src/tools/glob.test.js +219 -280
  816. package/dist/src/tools/glob.test.js.map +1 -1
  817. package/dist/src/tools/grep.d.ts +18 -8
  818. package/dist/src/tools/grep.js +273 -247
  819. package/dist/src/tools/grep.js.map +1 -1
  820. package/dist/src/tools/grep.test.js +165 -16
  821. package/dist/src/tools/grep.test.js.map +1 -1
  822. package/dist/src/tools/line-endings.test.d.ts +6 -0
  823. package/dist/src/tools/line-endings.test.js +209 -0
  824. package/dist/src/tools/line-endings.test.js.map +1 -0
  825. package/dist/src/tools/ls.d.ts +1 -0
  826. package/dist/src/tools/ls.js +18 -37
  827. package/dist/src/tools/ls.js.map +1 -1
  828. package/dist/src/tools/ls.test.js +25 -3
  829. package/dist/src/tools/ls.test.js.map +1 -1
  830. package/dist/src/tools/mcp-client-manager.d.ts +18 -5
  831. package/dist/src/tools/mcp-client-manager.js +118 -37
  832. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  833. package/dist/src/tools/mcp-client-manager.test.js +124 -16
  834. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  835. package/dist/src/tools/mcp-client.d.ts +18 -7
  836. package/dist/src/tools/mcp-client.js +137 -42
  837. package/dist/src/tools/mcp-client.js.map +1 -1
  838. package/dist/src/tools/mcp-client.test.js +248 -29
  839. package/dist/src/tools/mcp-client.test.js.map +1 -1
  840. package/dist/src/tools/mcp-tool.d.ts +26 -4
  841. package/dist/src/tools/mcp-tool.js +17 -5
  842. package/dist/src/tools/mcp-tool.js.map +1 -1
  843. package/dist/src/tools/mcp-tool.test.js +5 -5
  844. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  845. package/dist/src/tools/memoryTool.d.ts +2 -7
  846. package/dist/src/tools/memoryTool.js +54 -80
  847. package/dist/src/tools/memoryTool.js.map +1 -1
  848. package/dist/src/tools/memoryTool.test.js +62 -114
  849. package/dist/src/tools/memoryTool.test.js.map +1 -1
  850. package/dist/src/tools/modifiable-tool.test.js +3 -3
  851. package/dist/src/tools/modifiable-tool.test.js.map +1 -1
  852. package/dist/src/tools/read-file.d.ts +2 -0
  853. package/dist/src/tools/read-file.js +26 -30
  854. package/dist/src/tools/read-file.js.map +1 -1
  855. package/dist/src/tools/read-file.test.js +90 -3
  856. package/dist/src/tools/read-file.test.js.map +1 -1
  857. package/dist/src/tools/read-many-files.d.ts +1 -0
  858. package/dist/src/tools/read-many-files.js +21 -63
  859. package/dist/src/tools/read-many-files.js.map +1 -1
  860. package/dist/src/tools/read-many-files.test.js +43 -1
  861. package/dist/src/tools/read-many-files.test.js.map +1 -1
  862. package/dist/src/tools/ripGrep.d.ts +20 -3
  863. package/dist/src/tools/ripGrep.js +217 -189
  864. package/dist/src/tools/ripGrep.js.map +1 -1
  865. package/dist/src/tools/ripGrep.test.js +745 -567
  866. package/dist/src/tools/ripGrep.test.js.map +1 -1
  867. package/dist/src/tools/shell.d.ts +1 -0
  868. package/dist/src/tools/shell.js +8 -3
  869. package/dist/src/tools/shell.js.map +1 -1
  870. package/dist/src/tools/shell.test.js +248 -11
  871. package/dist/src/tools/shell.test.js.map +1 -1
  872. package/dist/src/tools/tool-error.d.ts +4 -0
  873. package/dist/src/tools/tool-error.js +4 -0
  874. package/dist/src/tools/tool-error.js.map +1 -1
  875. package/dist/src/tools/tool-names.d.ts +27 -17
  876. package/dist/src/tools/tool-names.js +59 -20
  877. package/dist/src/tools/tool-names.js.map +1 -1
  878. package/dist/src/tools/tool-names.test.js +55 -2
  879. package/dist/src/tools/tool-names.test.js.map +1 -1
  880. package/dist/src/tools/tool-registry.d.ts +10 -2
  881. package/dist/src/tools/tool-registry.js +58 -11
  882. package/dist/src/tools/tool-registry.js.map +1 -1
  883. package/dist/src/tools/tool-registry.test.js +113 -1
  884. package/dist/src/tools/tool-registry.test.js.map +1 -1
  885. package/dist/src/tools/tools.d.ts +52 -5
  886. package/dist/src/tools/tools.js +35 -18
  887. package/dist/src/tools/tools.js.map +1 -1
  888. package/dist/src/tools/web-fetch.d.ts +1 -0
  889. package/dist/src/tools/web-fetch.js +12 -12
  890. package/dist/src/tools/web-fetch.js.map +1 -1
  891. package/dist/src/tools/web-search.d.ts +1 -0
  892. package/dist/src/tools/web-search.js +9 -11
  893. package/dist/src/tools/web-search.js.map +1 -1
  894. package/dist/src/tools/write-file.d.ts +1 -4
  895. package/dist/src/tools/write-file.js +42 -35
  896. package/dist/src/tools/write-file.js.map +1 -1
  897. package/dist/src/tools/write-file.test.js +105 -18
  898. package/dist/src/tools/write-file.test.js.map +1 -1
  899. package/dist/src/tools/write-todos.d.ts +1 -30
  900. package/dist/src/tools/write-todos.js +5 -123
  901. package/dist/src/tools/write-todos.js.map +1 -1
  902. package/dist/src/tools/xcode-mcp-fix-transport.d.ts +30 -0
  903. package/dist/src/tools/xcode-mcp-fix-transport.js +82 -0
  904. package/dist/src/tools/xcode-mcp-fix-transport.js.map +1 -0
  905. package/dist/src/tools/xcode-mcp-fix-transport.test.d.ts +1 -0
  906. package/dist/src/tools/xcode-mcp-fix-transport.test.js +98 -0
  907. package/dist/src/tools/xcode-mcp-fix-transport.test.js.map +1 -0
  908. package/dist/src/utils/apiConversionUtils.d.ts +12 -0
  909. package/dist/src/utils/apiConversionUtils.js +46 -0
  910. package/dist/src/utils/apiConversionUtils.js.map +1 -0
  911. package/dist/src/utils/apiConversionUtils.test.d.ts +6 -0
  912. package/dist/src/utils/apiConversionUtils.test.js +150 -0
  913. package/dist/src/utils/apiConversionUtils.test.js.map +1 -0
  914. package/dist/src/utils/authConsent.d.ts +10 -0
  915. package/dist/src/utils/authConsent.js +52 -0
  916. package/dist/src/utils/authConsent.js.map +1 -0
  917. package/dist/src/utils/authConsent.test.d.ts +6 -0
  918. package/dist/src/utils/authConsent.test.js +74 -0
  919. package/dist/src/utils/authConsent.test.js.map +1 -0
  920. package/dist/src/utils/bfsFileSearch.js +2 -0
  921. package/dist/src/utils/bfsFileSearch.js.map +1 -1
  922. package/dist/src/utils/bfsFileSearch.test.js +6 -1
  923. package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
  924. package/dist/src/utils/checkpointUtils.d.ts +2 -2
  925. package/dist/src/utils/checkpointUtils.js +2 -0
  926. package/dist/src/utils/checkpointUtils.js.map +1 -1
  927. package/dist/src/utils/checks.d.ts +19 -0
  928. package/dist/src/utils/checks.js +24 -0
  929. package/dist/src/utils/checks.js.map +1 -0
  930. package/dist/src/utils/checks.test.d.ts +6 -0
  931. package/dist/src/utils/checks.test.js +29 -0
  932. package/dist/src/utils/checks.test.js.map +1 -0
  933. package/dist/src/utils/constants.d.ts +7 -0
  934. package/dist/src/utils/constants.js +8 -0
  935. package/dist/src/utils/constants.js.map +1 -0
  936. package/dist/src/utils/deadlineTimer.d.ts +36 -0
  937. package/dist/src/utils/deadlineTimer.js +87 -0
  938. package/dist/src/utils/deadlineTimer.js.map +1 -0
  939. package/dist/src/utils/deadlineTimer.test.d.ts +6 -0
  940. package/dist/src/utils/deadlineTimer.test.js +64 -0
  941. package/dist/src/utils/deadlineTimer.test.js.map +1 -0
  942. package/dist/src/utils/editCorrector.d.ts +3 -3
  943. package/dist/src/utils/editCorrector.js +37 -10
  944. package/dist/src/utils/editCorrector.js.map +1 -1
  945. package/dist/src/utils/editCorrector.test.js +49 -20
  946. package/dist/src/utils/editCorrector.test.js.map +1 -1
  947. package/dist/src/utils/editor.d.ts +17 -3
  948. package/dist/src/utils/editor.js +84 -15
  949. package/dist/src/utils/editor.js.map +1 -1
  950. package/dist/src/utils/editor.test.js +160 -17
  951. package/dist/src/utils/editor.test.js.map +1 -1
  952. package/dist/src/utils/environmentContext.js +9 -20
  953. package/dist/src/utils/environmentContext.js.map +1 -1
  954. package/dist/src/utils/environmentContext.test.js +31 -14
  955. package/dist/src/utils/environmentContext.test.js.map +1 -1
  956. package/dist/src/utils/errors.d.ts +3 -0
  957. package/dist/src/utils/errors.js +13 -3
  958. package/dist/src/utils/errors.js.map +1 -1
  959. package/dist/src/utils/errors.test.js +23 -1
  960. package/dist/src/utils/errors.test.js.map +1 -1
  961. package/dist/src/utils/events.d.ts +107 -3
  962. package/dist/src/utils/events.js +65 -1
  963. package/dist/src/utils/events.js.map +1 -1
  964. package/dist/src/utils/events.test.js +43 -0
  965. package/dist/src/utils/events.test.js.map +1 -1
  966. package/dist/src/utils/extensionLoader.js +2 -0
  967. package/dist/src/utils/extensionLoader.js.map +1 -1
  968. package/dist/src/utils/extensionLoader.test.js +21 -0
  969. package/dist/src/utils/extensionLoader.test.js.map +1 -1
  970. package/dist/src/utils/fastAckHelper.d.ts +30 -0
  971. package/dist/src/utils/fastAckHelper.js +142 -0
  972. package/dist/src/utils/fastAckHelper.js.map +1 -0
  973. package/dist/src/utils/fastAckHelper.test.d.ts +6 -0
  974. package/dist/src/utils/fastAckHelper.test.js +115 -0
  975. package/dist/src/utils/fastAckHelper.test.js.map +1 -0
  976. package/dist/src/utils/fileDiffUtils.d.ts +18 -0
  977. package/dist/src/utils/fileDiffUtils.js +37 -0
  978. package/dist/src/utils/fileDiffUtils.js.map +1 -0
  979. package/dist/src/utils/fileDiffUtils.test.d.ts +6 -0
  980. package/dist/src/utils/fileDiffUtils.test.js +84 -0
  981. package/dist/src/utils/fileDiffUtils.test.js.map +1 -0
  982. package/dist/src/utils/fileUtils.d.ts +27 -3
  983. package/dist/src/utils/fileUtils.js +104 -60
  984. package/dist/src/utils/fileUtils.js.map +1 -1
  985. package/dist/src/utils/fileUtils.test.js +129 -109
  986. package/dist/src/utils/fileUtils.test.js.map +1 -1
  987. package/dist/src/utils/filesearch/crawler.d.ts +1 -0
  988. package/dist/src/utils/filesearch/crawler.js +18 -1
  989. package/dist/src/utils/filesearch/crawler.js.map +1 -1
  990. package/dist/src/utils/filesearch/crawler.test.js +101 -82
  991. package/dist/src/utils/filesearch/crawler.test.js.map +1 -1
  992. package/dist/src/utils/filesearch/fileSearch.d.ts +4 -3
  993. package/dist/src/utils/filesearch/fileSearch.js +5 -4
  994. package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
  995. package/dist/src/utils/filesearch/fileSearch.test.js +172 -84
  996. package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -1
  997. package/dist/src/utils/filesearch/ignore.d.ts +2 -7
  998. package/dist/src/utils/filesearch/ignore.js +7 -14
  999. package/dist/src/utils/filesearch/ignore.js.map +1 -1
  1000. package/dist/src/utils/filesearch/ignore.test.js +30 -32
  1001. package/dist/src/utils/filesearch/ignore.test.js.map +1 -1
  1002. package/dist/src/utils/formatters.d.ts +1 -1
  1003. package/dist/src/utils/formatters.js +1 -1
  1004. package/dist/src/utils/formatters.js.map +1 -1
  1005. package/dist/src/utils/formatters.test.js +5 -5
  1006. package/dist/src/utils/formatters.test.js.map +1 -1
  1007. package/dist/src/utils/generateContentResponseUtilities.js +3 -0
  1008. package/dist/src/utils/generateContentResponseUtilities.js.map +1 -1
  1009. package/dist/src/utils/getFolderStructure.test.js +5 -2
  1010. package/dist/src/utils/getFolderStructure.test.js.map +1 -1
  1011. package/dist/src/utils/getPty.js +3 -0
  1012. package/dist/src/utils/getPty.js.map +1 -1
  1013. package/dist/src/utils/gitIgnoreParser.js +10 -11
  1014. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  1015. package/dist/src/utils/googleErrors.js +4 -0
  1016. package/dist/src/utils/googleErrors.js.map +1 -1
  1017. package/dist/src/utils/googleQuotaErrors.d.ts +23 -9
  1018. package/dist/src/utils/googleQuotaErrors.js +90 -23
  1019. package/dist/src/utils/googleQuotaErrors.js.map +1 -1
  1020. package/dist/src/utils/googleQuotaErrors.test.js +168 -23
  1021. package/dist/src/utils/googleQuotaErrors.test.js.map +1 -1
  1022. package/dist/src/utils/headless.d.ts +26 -0
  1023. package/dist/src/utils/headless.js +33 -0
  1024. package/dist/src/utils/headless.js.map +1 -0
  1025. package/dist/src/utils/headless.test.d.ts +6 -0
  1026. package/dist/src/utils/headless.test.js +167 -0
  1027. package/dist/src/utils/headless.test.js.map +1 -0
  1028. package/dist/src/utils/httpErrors.js +4 -1
  1029. package/dist/src/utils/httpErrors.js.map +1 -1
  1030. package/dist/src/utils/ignoreFileParser.d.ts +30 -0
  1031. package/dist/src/utils/ignoreFileParser.js +100 -0
  1032. package/dist/src/utils/ignoreFileParser.js.map +1 -0
  1033. package/dist/src/utils/ignoreFileParser.test.d.ts +6 -0
  1034. package/dist/src/utils/ignoreFileParser.test.js +167 -0
  1035. package/dist/src/utils/ignoreFileParser.test.js.map +1 -0
  1036. package/dist/src/utils/installationManager.test.js +11 -3
  1037. package/dist/src/utils/installationManager.test.js.map +1 -1
  1038. package/dist/src/utils/llm-edit-fixer.js +9 -9
  1039. package/dist/src/utils/llm-edit-fixer.js.map +1 -1
  1040. package/dist/src/utils/llm-edit-fixer.test.js +2 -2
  1041. package/dist/src/utils/llm-edit-fixer.test.js.map +1 -1
  1042. package/dist/src/utils/memoryDiscovery.d.ts +11 -3
  1043. package/dist/src/utils/memoryDiscovery.js +122 -102
  1044. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  1045. package/dist/src/utils/memoryDiscovery.test.js +163 -109
  1046. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  1047. package/dist/src/utils/memoryImportProcessor.js +7 -24
  1048. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  1049. package/dist/src/utils/nextSpeakerChecker.js +3 -0
  1050. package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
  1051. package/dist/src/utils/package.js +10 -3
  1052. package/dist/src/utils/package.js.map +1 -1
  1053. package/dist/src/utils/package.test.d.ts +6 -0
  1054. package/dist/src/utils/package.test.js +57 -0
  1055. package/dist/src/utils/package.test.js.map +1 -0
  1056. package/dist/src/utils/partUtils.js +2 -1
  1057. package/dist/src/utils/partUtils.js.map +1 -1
  1058. package/dist/src/utils/paths.d.ts +33 -9
  1059. package/dist/src/utils/paths.js +88 -29
  1060. package/dist/src/utils/paths.js.map +1 -1
  1061. package/dist/src/utils/paths.test.js +206 -110
  1062. package/dist/src/utils/paths.test.js.map +1 -1
  1063. package/dist/src/utils/planUtils.d.ts +29 -0
  1064. package/dist/src/utils/planUtils.js +55 -0
  1065. package/dist/src/utils/planUtils.js.map +1 -0
  1066. package/dist/src/utils/planUtils.test.d.ts +6 -0
  1067. package/dist/src/utils/planUtils.test.js +76 -0
  1068. package/dist/src/utils/planUtils.test.js.map +1 -0
  1069. package/dist/src/utils/process-utils.d.ts +32 -0
  1070. package/dist/src/utils/process-utils.js +88 -0
  1071. package/dist/src/utils/process-utils.js.map +1 -0
  1072. package/dist/src/utils/process-utils.test.d.ts +6 -0
  1073. package/dist/src/utils/process-utils.test.js +103 -0
  1074. package/dist/src/utils/process-utils.test.js.map +1 -0
  1075. package/dist/src/utils/promptIdContext.d.ts +6 -0
  1076. package/dist/src/utils/promptIdContext.js +15 -0
  1077. package/dist/src/utils/promptIdContext.js.map +1 -1
  1078. package/dist/src/utils/quotaErrorDetection.js +3 -0
  1079. package/dist/src/utils/quotaErrorDetection.js.map +1 -1
  1080. package/dist/src/utils/retry.d.ts +4 -0
  1081. package/dist/src/utils/retry.js +84 -5
  1082. package/dist/src/utils/retry.js.map +1 -1
  1083. package/dist/src/utils/retry.test.js +70 -3
  1084. package/dist/src/utils/retry.test.js.map +1 -1
  1085. package/dist/src/utils/safeJsonStringify.js +1 -0
  1086. package/dist/src/utils/safeJsonStringify.js.map +1 -1
  1087. package/dist/src/utils/schemaValidator.d.ts +8 -1
  1088. package/dist/src/utils/schemaValidator.js +78 -11
  1089. package/dist/src/utils/schemaValidator.js.map +1 -1
  1090. package/dist/src/utils/schemaValidator.test.js +77 -0
  1091. package/dist/src/utils/schemaValidator.test.js.map +1 -1
  1092. package/dist/src/utils/security.d.ts +16 -0
  1093. package/dist/src/utils/security.js +91 -0
  1094. package/dist/src/utils/security.js.map +1 -0
  1095. package/dist/src/utils/security.test.d.ts +1 -0
  1096. package/dist/src/utils/security.test.js +121 -0
  1097. package/dist/src/utils/security.test.js.map +1 -0
  1098. package/dist/src/utils/shell-utils.d.ts +14 -0
  1099. package/dist/src/utils/shell-utils.integration.test.d.ts +1 -0
  1100. package/dist/src/utils/shell-utils.integration.test.js +58 -0
  1101. package/dist/src/utils/shell-utils.integration.test.js.map +1 -0
  1102. package/dist/src/utils/shell-utils.js +191 -30
  1103. package/dist/src/utils/shell-utils.js.map +1 -1
  1104. package/dist/src/utils/shell-utils.test.js +108 -1
  1105. package/dist/src/utils/shell-utils.test.js.map +1 -1
  1106. package/dist/src/utils/summarizer.js +2 -1
  1107. package/dist/src/utils/summarizer.js.map +1 -1
  1108. package/dist/src/utils/terminal.d.ts +4 -0
  1109. package/dist/src/utils/terminal.js +12 -0
  1110. package/dist/src/utils/terminal.js.map +1 -1
  1111. package/dist/src/utils/terminalSerializer.d.ts +1 -1
  1112. package/dist/src/utils/terminalSerializer.js +25 -13
  1113. package/dist/src/utils/terminalSerializer.js.map +1 -1
  1114. package/dist/src/utils/testUtils.js +1 -0
  1115. package/dist/src/utils/testUtils.js.map +1 -1
  1116. package/dist/src/utils/textUtils.d.ts +14 -0
  1117. package/dist/src/utils/textUtils.js +23 -0
  1118. package/dist/src/utils/textUtils.js.map +1 -1
  1119. package/dist/src/utils/textUtils.test.js +18 -1
  1120. package/dist/src/utils/textUtils.test.js.map +1 -1
  1121. package/dist/src/utils/tokenCalculation.d.ts +2 -2
  1122. package/dist/src/utils/tokenCalculation.js +87 -21
  1123. package/dist/src/utils/tokenCalculation.js.map +1 -1
  1124. package/dist/src/utils/tokenCalculation.test.js +189 -76
  1125. package/dist/src/utils/tokenCalculation.test.js.map +1 -1
  1126. package/dist/src/utils/tool-utils.d.ts +26 -0
  1127. package/dist/src/utils/tool-utils.js +36 -0
  1128. package/dist/src/utils/tool-utils.js.map +1 -1
  1129. package/dist/src/utils/tool-utils.test.js +73 -3
  1130. package/dist/src/utils/tool-utils.test.js.map +1 -1
  1131. package/dist/src/utils/toolCallContext.d.ts +35 -0
  1132. package/dist/src/utils/toolCallContext.js +29 -0
  1133. package/dist/src/utils/toolCallContext.js.map +1 -0
  1134. package/dist/src/utils/toolCallContext.test.d.ts +6 -0
  1135. package/dist/src/utils/toolCallContext.test.js +68 -0
  1136. package/dist/src/utils/toolCallContext.test.js.map +1 -0
  1137. package/dist/src/utils/userAccountManager.js +1 -0
  1138. package/dist/src/utils/userAccountManager.js.map +1 -1
  1139. package/dist/src/utils/userAccountManager.test.js +5 -5
  1140. package/dist/src/utils/userAccountManager.test.js.map +1 -1
  1141. package/dist/src/utils/version.d.ts +2 -0
  1142. package/dist/src/utils/version.js +14 -3
  1143. package/dist/src/utils/version.js.map +1 -1
  1144. package/dist/src/utils/version.test.js +15 -1
  1145. package/dist/src/utils/version.test.js.map +1 -1
  1146. package/dist/src/utils/workspaceContext.d.ts +28 -0
  1147. package/dist/src/utils/workspaceContext.js +74 -9
  1148. package/dist/src/utils/workspaceContext.js.map +1 -1
  1149. package/dist/src/utils/workspaceContext.test.js +56 -1
  1150. package/dist/src/utils/workspaceContext.test.js.map +1 -1
  1151. package/dist/tsconfig.tsbuildinfo +1 -1
  1152. package/package.json +25 -15
@@ -6,11 +6,15 @@
6
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
+ import { isSubpath } from '../utils/paths.js';
9
10
  import fs from 'node:fs/promises';
10
11
  import os from 'node:os';
11
12
  import { Storage } from '../config/storage.js';
13
+ import { GEMINI_IGNORE_FILE_NAME } from '../config/constants.js';
12
14
  import { createMockWorkspaceContext } from '../test-utils/mockWorkspaceContext.js';
13
15
  import { spawn } from 'node:child_process';
16
+ import { PassThrough, Readable } from 'node:stream';
17
+ import EventEmitter from 'node:events';
14
18
  import { downloadRipGrep } from '@joshua.litt/get-ripgrep';
15
19
  import { createMockMessageBus } from '../test-utils/mock-message-bus.js';
16
20
  // Mock dependencies for canUseRipgrep
@@ -144,30 +148,32 @@ describe('ensureRgPath', () => {
144
148
  function createMockSpawn(options = {}) {
145
149
  const { outputData, exitCode = 0, signal } = options;
146
150
  return () => {
147
- const mockProcess = {
148
- stdout: {
149
- on: vi.fn(),
150
- removeListener: vi.fn(),
151
- },
152
- stderr: {
153
- on: vi.fn(),
154
- removeListener: vi.fn(),
151
+ // strict Readable implementation
152
+ let pushed = false;
153
+ const stdout = new Readable({
154
+ read() {
155
+ if (!pushed) {
156
+ if (outputData) {
157
+ this.push(outputData);
158
+ }
159
+ this.push(null); // EOF
160
+ pushed = true;
161
+ }
155
162
  },
156
- on: vi.fn(),
157
- removeListener: vi.fn(),
158
- kill: vi.fn(),
159
- };
160
- // Set up event listeners immediately
163
+ });
164
+ const stderr = new PassThrough();
165
+ const mockProcess = new EventEmitter();
166
+ mockProcess.stdout = stdout;
167
+ mockProcess.stderr = stderr;
168
+ mockProcess.kill = vi.fn();
169
+ // @ts-expect-error - mocking private/internal property
170
+ mockProcess.killed = false;
171
+ // @ts-expect-error - mocking private/internal property
172
+ mockProcess.exitCode = null;
173
+ // Emulating process exit
161
174
  setTimeout(() => {
162
- const stdoutDataHandler = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
163
- const closeHandler = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
164
- if (stdoutDataHandler && outputData) {
165
- stdoutDataHandler(Buffer.from(outputData));
166
- }
167
- if (closeHandler) {
168
- closeHandler(exitCode, signal);
169
- }
170
- }, 0);
175
+ mockProcess.emit('close', exitCode, signal);
176
+ }, 10);
171
177
  return mockProcess;
172
178
  };
173
179
  }
@@ -178,11 +184,16 @@ describe('RipGrepTool', () => {
178
184
  let ripgrepBinaryPath;
179
185
  let grepTool;
180
186
  const abortSignal = new AbortController().signal;
181
- const mockConfig = {
187
+ let mockConfig = {
182
188
  getTargetDir: () => tempRootDir,
183
189
  getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
184
190
  getDebugMode: () => false,
191
+ getFileFilteringRespectGitIgnore: () => true,
185
192
  getFileFilteringRespectGeminiIgnore: () => true,
193
+ getFileFilteringOptions: () => ({
194
+ respectGitIgnore: true,
195
+ respectGeminiIgnore: true,
196
+ }),
186
197
  };
187
198
  beforeEach(async () => {
188
199
  downloadRipGrepMock.mockReset();
@@ -196,6 +207,36 @@ describe('RipGrepTool', () => {
196
207
  await fs.writeFile(ripgrepBinaryPath, '');
197
208
  storageSpy.mockImplementation(() => binDir);
198
209
  tempRootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'grep-tool-root-'));
210
+ mockConfig = {
211
+ getTargetDir: () => tempRootDir,
212
+ getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
213
+ getDebugMode: () => false,
214
+ getFileFilteringRespectGitIgnore: () => true,
215
+ getFileFilteringRespectGeminiIgnore: () => true,
216
+ getFileFilteringOptions: () => ({
217
+ respectGitIgnore: true,
218
+ respectGeminiIgnore: true,
219
+ }),
220
+ storage: {
221
+ getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
222
+ },
223
+ isPathAllowed(absolutePath) {
224
+ const workspaceContext = this.getWorkspaceContext();
225
+ if (workspaceContext.isPathWithinWorkspace(absolutePath)) {
226
+ return true;
227
+ }
228
+ const projectTempDir = this.storage.getProjectTempDir();
229
+ return isSubpath(path.resolve(projectTempDir), absolutePath);
230
+ },
231
+ validatePathAccess(absolutePath) {
232
+ if (this.isPathAllowed(absolutePath)) {
233
+ return null;
234
+ }
235
+ const workspaceDirs = this.getWorkspaceContext().getDirectories();
236
+ const projectTempDir = this.storage.getProjectTempDir();
237
+ return `Path not in workspace: Attempted path "${absolutePath}" resolves outside the allowed workspace directories: ${workspaceDirs.join(', ')} or the project temp directory: ${projectTempDir}`;
238
+ },
239
+ };
199
240
  grepTool = new RipGrepTool(mockConfig, createMockMessageBus());
200
241
  // Create some test files and directories
201
242
  await fs.writeFile(path.join(tempRootDir, 'fileA.txt'), 'hello world\nsecond line with world');
@@ -226,14 +267,13 @@ describe('RipGrepTool', () => {
226
267
  params: { pattern: 'hello', dir_path: '.', include: '*.txt' },
227
268
  expected: null,
228
269
  },
229
- {
230
- name: 'invalid regex pattern',
231
- params: { pattern: '[[' },
232
- expected: null,
233
- },
234
270
  ])('should return null for valid params ($name)', ({ params, expected }) => {
235
271
  expect(grepTool.validateToolParams(params)).toBe(expected);
236
272
  });
273
+ it('should throw error for invalid regex pattern', () => {
274
+ const params = { pattern: '[[' };
275
+ expect(grepTool.validateToolParams(params)).toMatch(/Invalid regular expression pattern provided/);
276
+ });
237
277
  it('should return error if pattern is missing', () => {
238
278
  const params = { dir_path: '.' };
239
279
  expect(grepTool.validateToolParams(params)).toBe(`params must have required property 'pattern'`);
@@ -244,8 +284,9 @@ describe('RipGrepTool', () => {
244
284
  dir_path: 'nonexistent',
245
285
  };
246
286
  // Check for the core error message, as the full path might vary
247
- expect(grepTool.validateToolParams(params)).toContain('Path does not exist');
248
- expect(grepTool.validateToolParams(params)).toContain('nonexistent');
287
+ const result = grepTool.validateToolParams(params);
288
+ expect(result).toMatch(/Path does not exist/);
289
+ expect(result).toMatch(/nonexistent/);
249
290
  });
250
291
  it('should allow path to be a file', async () => {
251
292
  const filePath = path.join(tempRootDir, 'fileA.txt');
@@ -299,6 +340,35 @@ describe('RipGrepTool', () => {
299
340
  expect(result.llmContent).toContain('L1: another world in sub dir');
300
341
  expect(result.returnDisplay).toBe('Found 3 matches');
301
342
  });
343
+ it('should ignore matches that escape the base path', async () => {
344
+ mockSpawn.mockImplementationOnce(createMockSpawn({
345
+ outputData: JSON.stringify({
346
+ type: 'match',
347
+ data: {
348
+ path: { text: '..env' },
349
+ line_number: 1,
350
+ lines: { text: 'world in ..env\n' },
351
+ },
352
+ }) +
353
+ '\n' +
354
+ JSON.stringify({
355
+ type: 'match',
356
+ data: {
357
+ path: { text: '../secret.txt' },
358
+ line_number: 1,
359
+ lines: { text: 'leak\n' },
360
+ },
361
+ }) +
362
+ '\n',
363
+ exitCode: 0,
364
+ }));
365
+ const params = { pattern: 'world' };
366
+ const invocation = grepTool.build(params);
367
+ const result = await invocation.execute(abortSignal);
368
+ expect(result.llmContent).toContain('File: ..env');
369
+ expect(result.llmContent).toContain('L1: world in ..env');
370
+ expect(result.llmContent).not.toContain('secret.txt');
371
+ });
302
372
  it('should find matches in a specific path', async () => {
303
373
  // Setup specific mock for this test - searching in 'sub' should only return matches from that directory
304
374
  mockSpawn.mockImplementationOnce(createMockSpawn({
@@ -344,40 +414,17 @@ describe('RipGrepTool', () => {
344
414
  it('should find matches with an include glob and path', async () => {
345
415
  await fs.writeFile(path.join(tempRootDir, 'sub', 'another.js'), 'const greeting = "hello";');
346
416
  // Setup specific mock for this test - searching for 'hello' in 'sub' with '*.js' filter
347
- mockSpawn.mockImplementationOnce(() => {
348
- const mockProcess = {
349
- stdout: {
350
- on: vi.fn(),
351
- removeListener: vi.fn(),
352
- },
353
- stderr: {
354
- on: vi.fn(),
355
- removeListener: vi.fn(),
417
+ mockSpawn.mockImplementationOnce(createMockSpawn({
418
+ outputData: JSON.stringify({
419
+ type: 'match',
420
+ data: {
421
+ path: { text: 'another.js' },
422
+ line_number: 1,
423
+ lines: { text: 'const greeting = "hello";\n' },
356
424
  },
357
- on: vi.fn(),
358
- removeListener: vi.fn(),
359
- kill: vi.fn(),
360
- };
361
- setTimeout(() => {
362
- const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
363
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
364
- if (onData) {
365
- // Only return match from the .js file in sub directory
366
- onData(Buffer.from(JSON.stringify({
367
- type: 'match',
368
- data: {
369
- path: { text: 'another.js' },
370
- line_number: 1,
371
- lines: { text: 'const greeting = "hello";\n' },
372
- },
373
- }) + '\n'));
374
- }
375
- if (onClose) {
376
- onClose(0);
377
- }
378
- }, 0);
379
- return mockProcess;
380
- });
425
+ }) + '\n',
426
+ exitCode: 0,
427
+ }));
381
428
  const params = {
382
429
  pattern: 'hello',
383
430
  dir_path: 'sub',
@@ -401,52 +448,132 @@ describe('RipGrepTool', () => {
401
448
  expect(result.llmContent).toContain('No matches found for pattern "nonexistentpattern" in path ".".');
402
449
  expect(result.returnDisplay).toBe('No matches found');
403
450
  });
404
- it('should return an error from ripgrep for invalid regex pattern', async () => {
405
- mockSpawn.mockImplementationOnce(createMockSpawn({
451
+ it('should throw error for invalid regex pattern during build', async () => {
452
+ const params = { pattern: '[[' };
453
+ expect(() => grepTool.build(params)).toThrow(/Invalid regular expression pattern provided/);
454
+ });
455
+ it('should ignore invalid regex error from ripgrep when it is not a user error', async () => {
456
+ mockSpawn.mockImplementation(createMockSpawn({
457
+ outputData: '',
406
458
  exitCode: 2,
459
+ signal: undefined,
407
460
  }));
408
- const params = { pattern: '[[' };
409
- const invocation = grepTool.build(params);
461
+ const invocation = grepTool.build({
462
+ pattern: 'foo',
463
+ dir_path: tempRootDir,
464
+ });
410
465
  const result = await invocation.execute(abortSignal);
411
- expect(result.llmContent).toContain('ripgrep exited with code 2');
412
- expect(result.returnDisplay).toContain('Error: ripgrep exited with code 2');
466
+ expect(result.llmContent).toContain('Process exited with code 2');
467
+ expect(result.returnDisplay).toContain('Error: Process exited with code 2');
413
468
  });
414
- it('should handle regex special characters correctly', async () => {
415
- // Setup specific mock for this test - regex pattern 'foo.*bar' should match 'const foo = "bar";'
416
- mockSpawn.mockImplementationOnce(() => {
417
- const mockProcess = {
418
- stdout: {
419
- on: vi.fn(),
420
- removeListener: vi.fn(),
421
- },
422
- stderr: {
423
- on: vi.fn(),
424
- removeListener: vi.fn(),
425
- },
426
- on: vi.fn(),
427
- removeListener: vi.fn(),
428
- kill: vi.fn(),
429
- };
430
- setTimeout(() => {
431
- const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
432
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
433
- if (onData) {
434
- // Return match for the regex pattern
435
- onData(Buffer.from(JSON.stringify({
436
- type: 'match',
437
- data: {
438
- path: { text: 'fileB.js' },
439
- line_number: 1,
440
- lines: { text: 'const foo = "bar";\n' },
441
- },
442
- }) + '\n'));
469
+ it('should handle massive output by terminating early without crashing (Regression)', async () => {
470
+ const massiveOutputLines = 30000;
471
+ // Custom mock for massive streaming
472
+ mockSpawn.mockImplementation(() => {
473
+ const stdout = new PassThrough();
474
+ const stderr = new PassThrough();
475
+ const mockProcess = new EventEmitter();
476
+ mockProcess.stdout = stdout;
477
+ mockProcess.stderr = stderr;
478
+ mockProcess.kill = vi.fn();
479
+ // @ts-expect-error - mocking private/internal property
480
+ mockProcess.killed = false;
481
+ // @ts-expect-error - mocking private/internal property
482
+ mockProcess.exitCode = null;
483
+ // Push data over time
484
+ let linesPushed = 0;
485
+ const pushInterval = setInterval(() => {
486
+ if (linesPushed >= massiveOutputLines) {
487
+ clearInterval(pushInterval);
488
+ stdout.end();
489
+ mockProcess.emit('close', 0);
490
+ return;
491
+ }
492
+ // Push a batch
493
+ try {
494
+ for (let i = 0; i < 2000 && linesPushed < massiveOutputLines; i++) {
495
+ const match = JSON.stringify({
496
+ type: 'match',
497
+ data: {
498
+ path: { text: `file_${linesPushed}.txt` },
499
+ line_number: 1,
500
+ lines: { text: `match ${linesPushed}\n` },
501
+ },
502
+ });
503
+ stdout.write(match + '\n');
504
+ linesPushed++;
505
+ }
443
506
  }
444
- if (onClose) {
445
- onClose(0);
507
+ catch (_e) {
508
+ clearInterval(pushInterval);
446
509
  }
447
- }, 0);
510
+ }, 1);
511
+ mockProcess.kill = vi.fn().mockImplementation(() => {
512
+ clearInterval(pushInterval);
513
+ stdout.end();
514
+ // Emit close async to allow listeners to attach
515
+ setTimeout(() => mockProcess.emit('close', 0, 'SIGTERM'), 0);
516
+ return true;
517
+ });
448
518
  return mockProcess;
449
519
  });
520
+ const invocation = grepTool.build({
521
+ pattern: 'test',
522
+ dir_path: tempRootDir,
523
+ });
524
+ const result = await invocation.execute(abortSignal);
525
+ expect(result.returnDisplay).toContain('(limited)');
526
+ }, 10000);
527
+ it('should filter out files based on FileDiscoveryService even if ripgrep returns them', async () => {
528
+ // Create .geminiignore to ignore 'ignored.txt'
529
+ await fs.writeFile(path.join(tempRootDir, GEMINI_IGNORE_FILE_NAME), 'ignored.txt');
530
+ // Re-initialize tool so FileDiscoveryService loads the new .geminiignore
531
+ const toolWithIgnore = new RipGrepTool(mockConfig, createMockMessageBus());
532
+ // Mock ripgrep returning both an ignored file and an allowed file
533
+ mockSpawn.mockImplementationOnce(createMockSpawn({
534
+ outputData: JSON.stringify({
535
+ type: 'match',
536
+ data: {
537
+ path: { text: 'ignored.txt' },
538
+ line_number: 1,
539
+ lines: { text: 'should be ignored\n' },
540
+ },
541
+ }) +
542
+ '\n' +
543
+ JSON.stringify({
544
+ type: 'match',
545
+ data: {
546
+ path: { text: 'allowed.txt' },
547
+ line_number: 1,
548
+ lines: { text: 'should be kept\n' },
549
+ },
550
+ }) +
551
+ '\n',
552
+ exitCode: 0,
553
+ }));
554
+ const params = { pattern: 'should' };
555
+ const invocation = toolWithIgnore.build(params);
556
+ const result = await invocation.execute(abortSignal);
557
+ // Verify ignored file is filtered out
558
+ expect(result.llmContent).toContain('allowed.txt');
559
+ expect(result.llmContent).toContain('should be kept');
560
+ expect(result.llmContent).not.toContain('ignored.txt');
561
+ expect(result.llmContent).not.toContain('should be ignored');
562
+ expect(result.returnDisplay).toContain('Found 1 match');
563
+ });
564
+ it('should handle regex special characters correctly', async () => {
565
+ // Setup specific mock for this test - regex pattern 'foo.*bar' should match 'const foo = "bar";'
566
+ mockSpawn.mockImplementationOnce(createMockSpawn({
567
+ outputData: JSON.stringify({
568
+ type: 'match',
569
+ data: {
570
+ path: { text: 'fileB.js' },
571
+ line_number: 1,
572
+ lines: { text: 'const foo = "bar";\n' },
573
+ },
574
+ }) + '\n',
575
+ exitCode: 0,
576
+ }));
450
577
  const params = { pattern: 'foo.*bar' }; // Matches 'const foo = "bar";'
451
578
  const invocation = grepTool.build(params);
452
579
  const result = await invocation.execute(abortSignal);
@@ -456,50 +583,27 @@ describe('RipGrepTool', () => {
456
583
  });
457
584
  it('should be case-insensitive by default (JS fallback)', async () => {
458
585
  // Setup specific mock for this test - case insensitive search for 'HELLO'
459
- mockSpawn.mockImplementationOnce(() => {
460
- const mockProcess = {
461
- stdout: {
462
- on: vi.fn(),
463
- removeListener: vi.fn(),
464
- },
465
- stderr: {
466
- on: vi.fn(),
467
- removeListener: vi.fn(),
586
+ mockSpawn.mockImplementationOnce(createMockSpawn({
587
+ outputData: JSON.stringify({
588
+ type: 'match',
589
+ data: {
590
+ path: { text: 'fileA.txt' },
591
+ line_number: 1,
592
+ lines: { text: 'hello world\n' },
468
593
  },
469
- on: vi.fn(),
470
- removeListener: vi.fn(),
471
- kill: vi.fn(),
472
- };
473
- setTimeout(() => {
474
- const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
475
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
476
- if (onData) {
477
- // Return case-insensitive matches for 'HELLO'
478
- onData(Buffer.from(JSON.stringify({
479
- type: 'match',
480
- data: {
481
- path: { text: 'fileA.txt' },
482
- line_number: 1,
483
- lines: { text: 'hello world\n' },
484
- },
485
- }) +
486
- '\n' +
487
- JSON.stringify({
488
- type: 'match',
489
- data: {
490
- path: { text: 'fileB.js' },
491
- line_number: 2,
492
- lines: { text: 'function baz() { return "hello"; }\n' },
493
- },
494
- }) +
495
- '\n'));
496
- }
497
- if (onClose) {
498
- onClose(0);
499
- }
500
- }, 0);
501
- return mockProcess;
502
- });
594
+ }) +
595
+ '\n' +
596
+ JSON.stringify({
597
+ type: 'match',
598
+ data: {
599
+ path: { text: 'fileB.js' },
600
+ line_number: 2,
601
+ lines: { text: 'function baz() { return "hello"; }\n' },
602
+ },
603
+ }) +
604
+ '\n',
605
+ exitCode: 0,
606
+ }));
503
607
  const params = { pattern: 'HELLO' };
504
608
  const invocation = grepTool.build(params);
505
609
  const result = await invocation.execute(abortSignal);
@@ -535,92 +639,63 @@ describe('RipGrepTool', () => {
535
639
  getTargetDir: () => tempRootDir,
536
640
  getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir, [secondDir]),
537
641
  getDebugMode: () => false,
642
+ getFileFilteringRespectGitIgnore: () => true,
538
643
  getFileFilteringRespectGeminiIgnore: () => true,
644
+ getFileFilteringOptions: () => ({
645
+ respectGitIgnore: true,
646
+ respectGeminiIgnore: true,
647
+ }),
648
+ storage: {
649
+ getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
650
+ },
651
+ isPathAllowed(absolutePath) {
652
+ const workspaceContext = this.getWorkspaceContext();
653
+ if (workspaceContext.isPathWithinWorkspace(absolutePath)) {
654
+ return true;
655
+ }
656
+ const projectTempDir = this.storage.getProjectTempDir();
657
+ return isSubpath(path.resolve(projectTempDir), absolutePath);
658
+ },
659
+ validatePathAccess(absolutePath) {
660
+ if (this.isPathAllowed(absolutePath)) {
661
+ return null;
662
+ }
663
+ const workspaceDirs = this.getWorkspaceContext().getDirectories();
664
+ const projectTempDir = this.storage.getProjectTempDir();
665
+ return `Path not in workspace: Attempted path "${absolutePath}" resolves outside the allowed workspace directories: ${workspaceDirs.join(', ')} or the project temp directory: ${projectTempDir}`;
666
+ },
539
667
  };
540
668
  // Setup specific mock for this test - multi-directory search for 'world'
541
669
  // Mock will be called twice - once for each directory
542
- let callCount = 0;
543
- mockSpawn.mockImplementation(() => {
544
- callCount++;
545
- const mockProcess = {
546
- stdout: {
547
- on: vi.fn(),
548
- removeListener: vi.fn(),
549
- },
550
- stderr: {
551
- on: vi.fn(),
552
- removeListener: vi.fn(),
670
+ mockSpawn.mockImplementationOnce(createMockSpawn({
671
+ outputData: JSON.stringify({
672
+ type: 'match',
673
+ data: {
674
+ path: { text: 'fileA.txt' },
675
+ line_number: 1,
676
+ lines: { text: 'hello world\n' },
553
677
  },
554
- on: vi.fn(),
555
- removeListener: vi.fn(),
556
- kill: vi.fn(),
557
- };
558
- setTimeout(() => {
559
- const stdoutDataHandler = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
560
- const closeHandler = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
561
- let outputData = '';
562
- if (callCount === 1) {
563
- // First directory (tempRootDir)
564
- outputData =
565
- JSON.stringify({
566
- type: 'match',
567
- data: {
568
- path: { text: 'fileA.txt' },
569
- line_number: 1,
570
- lines: { text: 'hello world\n' },
571
- },
572
- }) +
573
- '\n' +
574
- JSON.stringify({
575
- type: 'match',
576
- data: {
577
- path: { text: 'fileA.txt' },
578
- line_number: 2,
579
- lines: { text: 'second line with world\n' },
580
- },
581
- }) +
582
- '\n' +
583
- JSON.stringify({
584
- type: 'match',
585
- data: {
586
- path: { text: 'sub/fileC.txt' },
587
- line_number: 1,
588
- lines: { text: 'another world in sub dir\n' },
589
- },
590
- }) +
591
- '\n';
592
- }
593
- else if (callCount === 2) {
594
- // Second directory (secondDir)
595
- outputData =
596
- JSON.stringify({
597
- type: 'match',
598
- data: {
599
- path: { text: 'other.txt' },
600
- line_number: 2,
601
- lines: { text: 'world in second\n' },
602
- },
603
- }) +
604
- '\n' +
605
- JSON.stringify({
606
- type: 'match',
607
- data: {
608
- path: { text: 'another.js' },
609
- line_number: 1,
610
- lines: { text: 'function world() { return "test"; }\n' },
611
- },
612
- }) +
613
- '\n';
614
- }
615
- if (stdoutDataHandler && outputData) {
616
- stdoutDataHandler(Buffer.from(outputData));
617
- }
618
- if (closeHandler) {
619
- closeHandler(0);
620
- }
621
- }, 0);
622
- return mockProcess;
623
- });
678
+ }) +
679
+ '\n' +
680
+ JSON.stringify({
681
+ type: 'match',
682
+ data: {
683
+ path: { text: 'fileA.txt' },
684
+ line_number: 2,
685
+ lines: { text: 'second line with world\n' },
686
+ },
687
+ }) +
688
+ '\n' +
689
+ JSON.stringify({
690
+ type: 'match',
691
+ data: {
692
+ path: { text: 'sub/fileC.txt' },
693
+ line_number: 1,
694
+ lines: { text: 'another world in sub dir\n' },
695
+ },
696
+ }) +
697
+ '\n',
698
+ }));
624
699
  const multiDirGrepTool = new RipGrepTool(multiDirConfig, createMockMessageBus());
625
700
  const params = { pattern: 'world' };
626
701
  const invocation = multiDirGrepTool.build(params);
@@ -652,42 +727,43 @@ describe('RipGrepTool', () => {
652
727
  getTargetDir: () => tempRootDir,
653
728
  getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir, [secondDir]),
654
729
  getDebugMode: () => false,
730
+ getFileFilteringRespectGitIgnore: () => true,
655
731
  getFileFilteringRespectGeminiIgnore: () => true,
732
+ getFileFilteringOptions: () => ({
733
+ respectGitIgnore: true,
734
+ respectGeminiIgnore: true,
735
+ }),
736
+ storage: {
737
+ getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
738
+ },
739
+ isPathAllowed(absolutePath) {
740
+ const workspaceContext = this.getWorkspaceContext();
741
+ if (workspaceContext.isPathWithinWorkspace(absolutePath)) {
742
+ return true;
743
+ }
744
+ const projectTempDir = this.storage.getProjectTempDir();
745
+ return isSubpath(path.resolve(projectTempDir), absolutePath);
746
+ },
747
+ validatePathAccess(absolutePath) {
748
+ if (this.isPathAllowed(absolutePath)) {
749
+ return null;
750
+ }
751
+ const workspaceDirs = this.getWorkspaceContext().getDirectories();
752
+ const projectTempDir = this.storage.getProjectTempDir();
753
+ return `Path not in workspace: Attempted path "${absolutePath}" resolves outside the allowed workspace directories: ${workspaceDirs.join(', ')} or the project temp directory: ${projectTempDir}`;
754
+ },
656
755
  };
657
756
  // Setup specific mock for this test - searching in 'sub' should only return matches from that directory
658
- mockSpawn.mockImplementationOnce(() => {
659
- const mockProcess = {
660
- stdout: {
661
- on: vi.fn(),
662
- removeListener: vi.fn(),
663
- },
664
- stderr: {
665
- on: vi.fn(),
666
- removeListener: vi.fn(),
757
+ mockSpawn.mockImplementationOnce(createMockSpawn({
758
+ outputData: JSON.stringify({
759
+ type: 'match',
760
+ data: {
761
+ path: { text: 'fileC.txt' },
762
+ line_number: 1,
763
+ lines: { text: 'another world in sub dir\n' },
667
764
  },
668
- on: vi.fn(),
669
- removeListener: vi.fn(),
670
- kill: vi.fn(),
671
- };
672
- setTimeout(() => {
673
- const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
674
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
675
- if (onData) {
676
- onData(Buffer.from(JSON.stringify({
677
- type: 'match',
678
- data: {
679
- path: { text: 'fileC.txt' },
680
- line_number: 1,
681
- lines: { text: 'another world in sub dir\n' },
682
- },
683
- }) + '\n'));
684
- }
685
- if (onClose) {
686
- onClose(0);
687
- }
688
- }, 0);
689
- return mockProcess;
690
- });
765
+ }) + '\n',
766
+ }));
691
767
  const multiDirGrepTool = new RipGrepTool(multiDirConfig, createMockMessageBus());
692
768
  // Search only in the 'sub' directory of the first workspace
693
769
  const params = { pattern: 'world', dir_path: 'sub' };
@@ -714,38 +790,17 @@ describe('RipGrepTool', () => {
714
790
  });
715
791
  it('should abort streaming search when signal is triggered', async () => {
716
792
  // Setup specific mock for this test - simulate process being killed due to abort
717
- mockSpawn.mockImplementationOnce(() => {
718
- const mockProcess = {
719
- stdout: {
720
- on: vi.fn(),
721
- removeListener: vi.fn(),
722
- },
723
- stderr: {
724
- on: vi.fn(),
725
- removeListener: vi.fn(),
726
- },
727
- on: vi.fn(),
728
- removeListener: vi.fn(),
729
- kill: vi.fn(),
730
- };
731
- // Simulate process being aborted - use setTimeout to ensure handlers are registered first
732
- setTimeout(() => {
733
- const closeHandler = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
734
- if (closeHandler) {
735
- // Simulate process killed by signal (code is null, signal is SIGTERM)
736
- closeHandler(null, 'SIGTERM');
737
- }
738
- }, 0);
739
- return mockProcess;
740
- });
793
+ mockSpawn.mockImplementationOnce(createMockSpawn({
794
+ exitCode: null,
795
+ signal: 'SIGTERM',
796
+ }));
741
797
  const controller = new AbortController();
742
798
  const params = { pattern: 'test' };
743
799
  const invocation = grepTool.build(params);
744
800
  // Abort immediately before starting the search
745
801
  controller.abort();
746
802
  const result = await invocation.execute(controller.signal);
747
- expect(result.llmContent).toContain('Error during grep search operation: ripgrep exited with code null');
748
- expect(result.returnDisplay).toContain('Error: ripgrep exited with code null');
803
+ expect(result.returnDisplay).toContain('No matches found');
749
804
  });
750
805
  });
751
806
  describe('error handling and edge cases', () => {
@@ -754,7 +809,7 @@ describe('RipGrepTool', () => {
754
809
  pattern: 'test',
755
810
  dir_path: '../outside',
756
811
  };
757
- expect(() => grepTool.build(params)).toThrow(/Path validation failed/);
812
+ expect(() => grepTool.build(params)).toThrow(/Path not in workspace/);
758
813
  });
759
814
  it.each([
760
815
  {
@@ -783,39 +838,16 @@ describe('RipGrepTool', () => {
783
838
  const specialFileName = 'file with spaces & symbols!.txt';
784
839
  await fs.writeFile(path.join(tempRootDir, specialFileName), 'hello world with special chars');
785
840
  // Setup specific mock for this test - searching for 'world' should find the file with special characters
786
- mockSpawn.mockImplementationOnce(() => {
787
- const mockProcess = {
788
- stdout: {
789
- on: vi.fn(),
790
- removeListener: vi.fn(),
791
- },
792
- stderr: {
793
- on: vi.fn(),
794
- removeListener: vi.fn(),
841
+ mockSpawn.mockImplementationOnce(createMockSpawn({
842
+ outputData: JSON.stringify({
843
+ type: 'match',
844
+ data: {
845
+ path: { text: specialFileName },
846
+ line_number: 1,
847
+ lines: { text: 'hello world with special chars\n' },
795
848
  },
796
- on: vi.fn(),
797
- removeListener: vi.fn(),
798
- kill: vi.fn(),
799
- };
800
- setTimeout(() => {
801
- const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
802
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
803
- if (onData) {
804
- onData(Buffer.from(JSON.stringify({
805
- type: 'match',
806
- data: {
807
- path: { text: specialFileName },
808
- line_number: 1,
809
- lines: { text: 'hello world with special chars\n' },
810
- },
811
- }) + '\n'));
812
- }
813
- if (onClose) {
814
- onClose(0);
815
- }
816
- }, 0);
817
- return mockProcess;
818
- });
849
+ }) + '\n',
850
+ }));
819
851
  const params = { pattern: 'world' };
820
852
  const invocation = grepTool.build(params);
821
853
  const result = await invocation.execute(abortSignal);
@@ -827,39 +859,16 @@ describe('RipGrepTool', () => {
827
859
  await fs.mkdir(deepPath, { recursive: true });
828
860
  await fs.writeFile(path.join(deepPath, 'deep.txt'), 'content in deep directory');
829
861
  // Setup specific mock for this test - searching for 'deep' should find the deeply nested file
830
- mockSpawn.mockImplementationOnce(() => {
831
- const mockProcess = {
832
- stdout: {
833
- on: vi.fn(),
834
- removeListener: vi.fn(),
835
- },
836
- stderr: {
837
- on: vi.fn(),
838
- removeListener: vi.fn(),
862
+ mockSpawn.mockImplementationOnce(createMockSpawn({
863
+ outputData: JSON.stringify({
864
+ type: 'match',
865
+ data: {
866
+ path: { text: 'a/b/c/d/e/deep.txt' },
867
+ line_number: 1,
868
+ lines: { text: 'content in deep directory\n' },
839
869
  },
840
- on: vi.fn(),
841
- removeListener: vi.fn(),
842
- kill: vi.fn(),
843
- };
844
- setTimeout(() => {
845
- const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
846
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
847
- if (onData) {
848
- onData(Buffer.from(JSON.stringify({
849
- type: 'match',
850
- data: {
851
- path: { text: 'a/b/c/d/e/deep.txt' },
852
- line_number: 1,
853
- lines: { text: 'content in deep directory\n' },
854
- },
855
- }) + '\n'));
856
- }
857
- if (onClose) {
858
- onClose(0);
859
- }
860
- }, 0);
861
- return mockProcess;
862
- });
870
+ }) + '\n',
871
+ }));
863
872
  const params = { pattern: 'deep' };
864
873
  const invocation = grepTool.build(params);
865
874
  const result = await invocation.execute(abortSignal);
@@ -871,39 +880,16 @@ describe('RipGrepTool', () => {
871
880
  it('should handle complex regex patterns', async () => {
872
881
  await fs.writeFile(path.join(tempRootDir, 'code.js'), 'function getName() { return "test"; }\nconst getValue = () => "value";');
873
882
  // Setup specific mock for this test - regex pattern should match function declarations
874
- mockSpawn.mockImplementationOnce(() => {
875
- const mockProcess = {
876
- stdout: {
877
- on: vi.fn(),
878
- removeListener: vi.fn(),
879
- },
880
- stderr: {
881
- on: vi.fn(),
882
- removeListener: vi.fn(),
883
+ mockSpawn.mockImplementationOnce(createMockSpawn({
884
+ outputData: JSON.stringify({
885
+ type: 'match',
886
+ data: {
887
+ path: { text: 'code.js' },
888
+ line_number: 1,
889
+ lines: { text: 'function getName() { return "test"; }\n' },
883
890
  },
884
- on: vi.fn(),
885
- removeListener: vi.fn(),
886
- kill: vi.fn(),
887
- };
888
- setTimeout(() => {
889
- const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
890
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
891
- if (onData) {
892
- onData(Buffer.from(JSON.stringify({
893
- type: 'match',
894
- data: {
895
- path: { text: 'code.js' },
896
- line_number: 1,
897
- lines: { text: 'function getName() { return "test"; }\n' },
898
- },
899
- }) + '\n'));
900
- }
901
- if (onClose) {
902
- onClose(0);
903
- }
904
- }, 0);
905
- return mockProcess;
906
- });
891
+ }) + '\n',
892
+ }));
907
893
  const params = { pattern: 'function\\s+\\w+\\s*\\(' };
908
894
  const invocation = grepTool.build(params);
909
895
  const result = await invocation.execute(abortSignal);
@@ -913,58 +899,35 @@ describe('RipGrepTool', () => {
913
899
  it('should handle case sensitivity correctly in JS fallback', async () => {
914
900
  await fs.writeFile(path.join(tempRootDir, 'case.txt'), 'Hello World\nhello world\nHELLO WORLD');
915
901
  // Setup specific mock for this test - case insensitive search should match all variants
916
- mockSpawn.mockImplementationOnce(() => {
917
- const mockProcess = {
918
- stdout: {
919
- on: vi.fn(),
920
- removeListener: vi.fn(),
921
- },
922
- stderr: {
923
- on: vi.fn(),
924
- removeListener: vi.fn(),
902
+ mockSpawn.mockImplementationOnce(createMockSpawn({
903
+ outputData: JSON.stringify({
904
+ type: 'match',
905
+ data: {
906
+ path: { text: 'case.txt' },
907
+ line_number: 1,
908
+ lines: { text: 'Hello World\n' },
925
909
  },
926
- on: vi.fn(),
927
- removeListener: vi.fn(),
928
- kill: vi.fn(),
929
- };
930
- setTimeout(() => {
931
- const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
932
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
933
- if (onData) {
934
- onData(Buffer.from(JSON.stringify({
935
- type: 'match',
936
- data: {
937
- path: { text: 'case.txt' },
938
- line_number: 1,
939
- lines: { text: 'Hello World\n' },
940
- },
941
- }) +
942
- '\n' +
943
- JSON.stringify({
944
- type: 'match',
945
- data: {
946
- path: { text: 'case.txt' },
947
- line_number: 2,
948
- lines: { text: 'hello world\n' },
949
- },
950
- }) +
951
- '\n' +
952
- JSON.stringify({
953
- type: 'match',
954
- data: {
955
- path: { text: 'case.txt' },
956
- line_number: 3,
957
- lines: { text: 'HELLO WORLD\n' },
958
- },
959
- }) +
960
- '\n'));
961
- }
962
- if (onClose) {
963
- onClose(0);
964
- }
965
- }, 0);
966
- return mockProcess;
967
- });
910
+ }) +
911
+ '\n' +
912
+ JSON.stringify({
913
+ type: 'match',
914
+ data: {
915
+ path: { text: 'case.txt' },
916
+ line_number: 2,
917
+ lines: { text: 'hello world\n' },
918
+ },
919
+ }) +
920
+ '\n' +
921
+ JSON.stringify({
922
+ type: 'match',
923
+ data: {
924
+ path: { text: 'case.txt' },
925
+ line_number: 3,
926
+ lines: { text: 'HELLO WORLD\n' },
927
+ },
928
+ }) +
929
+ '\n',
930
+ }));
968
931
  const params = { pattern: 'hello' };
969
932
  const invocation = grepTool.build(params);
970
933
  const result = await invocation.execute(abortSignal);
@@ -975,39 +938,16 @@ describe('RipGrepTool', () => {
975
938
  it('should handle escaped regex special characters', async () => {
976
939
  await fs.writeFile(path.join(tempRootDir, 'special.txt'), 'Price: $19.99\nRegex: [a-z]+ pattern\nEmail: test@example.com');
977
940
  // Setup specific mock for this test - escaped regex pattern should match price format
978
- mockSpawn.mockImplementationOnce(() => {
979
- const mockProcess = {
980
- stdout: {
981
- on: vi.fn(),
982
- removeListener: vi.fn(),
983
- },
984
- stderr: {
985
- on: vi.fn(),
986
- removeListener: vi.fn(),
941
+ mockSpawn.mockImplementationOnce(createMockSpawn({
942
+ outputData: JSON.stringify({
943
+ type: 'match',
944
+ data: {
945
+ path: { text: 'special.txt' },
946
+ line_number: 1,
947
+ lines: { text: 'Price: $19.99\n' },
987
948
  },
988
- on: vi.fn(),
989
- removeListener: vi.fn(),
990
- kill: vi.fn(),
991
- };
992
- setTimeout(() => {
993
- const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
994
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
995
- if (onData) {
996
- onData(Buffer.from(JSON.stringify({
997
- type: 'match',
998
- data: {
999
- path: { text: 'special.txt' },
1000
- line_number: 1,
1001
- lines: { text: 'Price: $19.99\n' },
1002
- },
1003
- }) + '\n'));
1004
- }
1005
- if (onClose) {
1006
- onClose(0);
1007
- }
1008
- }, 0);
1009
- return mockProcess;
1010
- });
949
+ }) + '\n',
950
+ }));
1011
951
  const params = { pattern: '\\$\\d+\\.\\d+' };
1012
952
  const invocation = grepTool.build(params);
1013
953
  const result = await invocation.execute(abortSignal);
@@ -1022,49 +962,26 @@ describe('RipGrepTool', () => {
1022
962
  await fs.writeFile(path.join(tempRootDir, 'test.js'), 'javascript content');
1023
963
  await fs.writeFile(path.join(tempRootDir, 'test.txt'), 'text content');
1024
964
  // Setup specific mock for this test - include pattern should filter to only ts/tsx files
1025
- mockSpawn.mockImplementationOnce(() => {
1026
- const mockProcess = {
1027
- stdout: {
1028
- on: vi.fn(),
1029
- removeListener: vi.fn(),
1030
- },
1031
- stderr: {
1032
- on: vi.fn(),
1033
- removeListener: vi.fn(),
965
+ mockSpawn.mockImplementationOnce(createMockSpawn({
966
+ outputData: JSON.stringify({
967
+ type: 'match',
968
+ data: {
969
+ path: { text: 'test.ts' },
970
+ line_number: 1,
971
+ lines: { text: 'typescript content\n' },
1034
972
  },
1035
- on: vi.fn(),
1036
- removeListener: vi.fn(),
1037
- kill: vi.fn(),
1038
- };
1039
- setTimeout(() => {
1040
- const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
1041
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
1042
- if (onData) {
1043
- onData(Buffer.from(JSON.stringify({
1044
- type: 'match',
1045
- data: {
1046
- path: { text: 'test.ts' },
1047
- line_number: 1,
1048
- lines: { text: 'typescript content\n' },
1049
- },
1050
- }) +
1051
- '\n' +
1052
- JSON.stringify({
1053
- type: 'match',
1054
- data: {
1055
- path: { text: 'test.tsx' },
1056
- line_number: 1,
1057
- lines: { text: 'tsx content\n' },
1058
- },
1059
- }) +
1060
- '\n'));
1061
- }
1062
- if (onClose) {
1063
- onClose(0);
1064
- }
1065
- }, 0);
1066
- return mockProcess;
1067
- });
973
+ }) +
974
+ '\n' +
975
+ JSON.stringify({
976
+ type: 'match',
977
+ data: {
978
+ path: { text: 'test.tsx' },
979
+ line_number: 1,
980
+ lines: { text: 'tsx content\n' },
981
+ },
982
+ }) +
983
+ '\n',
984
+ }));
1068
985
  const params = {
1069
986
  pattern: 'content',
1070
987
  include: '*.{ts,tsx}',
@@ -1081,39 +998,16 @@ describe('RipGrepTool', () => {
1081
998
  await fs.writeFile(path.join(tempRootDir, 'src', 'main.ts'), 'source code');
1082
999
  await fs.writeFile(path.join(tempRootDir, 'other.ts'), 'other code');
1083
1000
  // Setup specific mock for this test - include pattern should filter to only src/** files
1084
- mockSpawn.mockImplementationOnce(() => {
1085
- const mockProcess = {
1086
- stdout: {
1087
- on: vi.fn(),
1088
- removeListener: vi.fn(),
1089
- },
1090
- stderr: {
1091
- on: vi.fn(),
1092
- removeListener: vi.fn(),
1001
+ mockSpawn.mockImplementationOnce(createMockSpawn({
1002
+ outputData: JSON.stringify({
1003
+ type: 'match',
1004
+ data: {
1005
+ path: { text: 'src/main.ts' },
1006
+ line_number: 1,
1007
+ lines: { text: 'source code\n' },
1093
1008
  },
1094
- on: vi.fn(),
1095
- removeListener: vi.fn(),
1096
- kill: vi.fn(),
1097
- };
1098
- setTimeout(() => {
1099
- const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
1100
- const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
1101
- if (onData) {
1102
- onData(Buffer.from(JSON.stringify({
1103
- type: 'match',
1104
- data: {
1105
- path: { text: 'src/main.ts' },
1106
- line_number: 1,
1107
- lines: { text: 'source code\n' },
1108
- },
1109
- }) + '\n'));
1110
- }
1111
- if (onClose) {
1112
- onClose(0);
1113
- }
1114
- }, 0);
1115
- return mockProcess;
1116
- });
1009
+ }) + '\n',
1010
+ }));
1117
1011
  const params = {
1118
1012
  pattern: 'code',
1119
1013
  include: 'src/**',
@@ -1163,27 +1057,32 @@ describe('RipGrepTool', () => {
1163
1057
  expect(result.llmContent).toContain('Found 1 match for pattern "HELLO"');
1164
1058
  expect(result.llmContent).toContain('L1: HELLO world');
1165
1059
  });
1166
- it.each([
1167
- {
1168
- name: 'fixed_strings parameter',
1169
- params: { pattern: 'hello.world', fixed_strings: true },
1170
- mockOutput: {
1171
- path: { text: 'fileA.txt' },
1172
- line_number: 1,
1173
- lines: { text: 'hello.world\n' },
1174
- },
1175
- expectedArgs: ['--fixed-strings'],
1176
- expectedPattern: 'hello.world',
1177
- },
1178
- ])('should handle $name', async ({ params, mockOutput, expectedArgs, expectedPattern }) => {
1060
+ it('should handle fixed_strings parameter', async () => {
1179
1061
  mockSpawn.mockImplementationOnce(createMockSpawn({
1180
- outputData: JSON.stringify({ type: 'match', data: mockOutput }) + '\n',
1062
+ outputData: JSON.stringify({
1063
+ type: 'match',
1064
+ data: {
1065
+ path: { text: 'fileA.txt' },
1066
+ line_number: 1,
1067
+ lines: { text: 'hello.world\n' },
1068
+ },
1069
+ }) + '\n',
1181
1070
  exitCode: 0,
1182
1071
  }));
1183
- const invocation = grepTool.build(params);
1072
+ const invocation = grepTool.build({
1073
+ pattern: 'hello.world',
1074
+ fixed_strings: true,
1075
+ });
1184
1076
  const result = await invocation.execute(abortSignal);
1185
- expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining(expectedArgs), expect.anything());
1186
- expect(result.llmContent).toContain(`Found 1 match for pattern "${expectedPattern}"`);
1077
+ expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining(['--fixed-strings']), expect.anything());
1078
+ expect(result.llmContent).toContain('Found 1 match for pattern "hello.world"');
1079
+ });
1080
+ it('should allow invalid regex patterns when fixed_strings is true', () => {
1081
+ const params = {
1082
+ pattern: '[[',
1083
+ fixed_strings: true,
1084
+ };
1085
+ expect(grepTool.validateToolParams(params)).toBeNull();
1187
1086
  });
1188
1087
  it('should handle no_ignore parameter', async () => {
1189
1088
  mockSpawn.mockImplementationOnce(createMockSpawn({
@@ -1206,14 +1105,86 @@ describe('RipGrepTool', () => {
1206
1105
  expect(result.llmContent).toContain('File: ignored.log');
1207
1106
  expect(result.llmContent).toContain('L1: secret log entry');
1208
1107
  });
1108
+ it('should disable gitignore rules when respectGitIgnore is false', async () => {
1109
+ const configWithoutGitIgnore = {
1110
+ getTargetDir: () => tempRootDir,
1111
+ getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
1112
+ getDebugMode: () => false,
1113
+ getFileFilteringRespectGitIgnore: () => false,
1114
+ getFileFilteringRespectGeminiIgnore: () => true,
1115
+ getFileFilteringOptions: () => ({
1116
+ respectGitIgnore: false,
1117
+ respectGeminiIgnore: true,
1118
+ }),
1119
+ storage: {
1120
+ getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
1121
+ },
1122
+ isPathAllowed(absolutePath) {
1123
+ const workspaceContext = this.getWorkspaceContext();
1124
+ if (workspaceContext.isPathWithinWorkspace(absolutePath)) {
1125
+ return true;
1126
+ }
1127
+ const projectTempDir = this.storage.getProjectTempDir();
1128
+ return isSubpath(path.resolve(projectTempDir), absolutePath);
1129
+ },
1130
+ validatePathAccess(absolutePath) {
1131
+ if (this.isPathAllowed(absolutePath)) {
1132
+ return null;
1133
+ }
1134
+ const workspaceDirs = this.getWorkspaceContext().getDirectories();
1135
+ const projectTempDir = this.storage.getProjectTempDir();
1136
+ return `Path not in workspace: Attempted path "${absolutePath}" resolves outside the allowed workspace directories: ${workspaceDirs.join(', ')} or the project temp directory: ${projectTempDir}`;
1137
+ },
1138
+ };
1139
+ const gitIgnoreDisabledTool = new RipGrepTool(configWithoutGitIgnore, createMockMessageBus());
1140
+ mockSpawn.mockImplementationOnce(createMockSpawn({
1141
+ outputData: JSON.stringify({
1142
+ type: 'match',
1143
+ data: {
1144
+ path: { text: 'ignored.log' },
1145
+ line_number: 1,
1146
+ lines: { text: 'secret log entry\n' },
1147
+ },
1148
+ }) + '\n',
1149
+ exitCode: 0,
1150
+ }));
1151
+ const params = { pattern: 'secret' };
1152
+ const invocation = gitIgnoreDisabledTool.build(params);
1153
+ await invocation.execute(abortSignal);
1154
+ expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining(['--no-ignore-vcs', '--no-ignore-exclude']), expect.anything());
1155
+ });
1209
1156
  it('should add .geminiignore when enabled and patterns exist', async () => {
1210
- const geminiIgnorePath = path.join(tempRootDir, '.geminiignore');
1157
+ const geminiIgnorePath = path.join(tempRootDir, GEMINI_IGNORE_FILE_NAME);
1211
1158
  await fs.writeFile(geminiIgnorePath, 'ignored.log');
1212
1159
  const configWithGeminiIgnore = {
1213
1160
  getTargetDir: () => tempRootDir,
1214
1161
  getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
1215
1162
  getDebugMode: () => false,
1163
+ getFileFilteringRespectGitIgnore: () => true,
1216
1164
  getFileFilteringRespectGeminiIgnore: () => true,
1165
+ getFileFilteringOptions: () => ({
1166
+ respectGitIgnore: true,
1167
+ respectGeminiIgnore: true,
1168
+ }),
1169
+ storage: {
1170
+ getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
1171
+ },
1172
+ isPathAllowed(absolutePath) {
1173
+ const workspaceContext = this.getWorkspaceContext();
1174
+ if (workspaceContext.isPathWithinWorkspace(absolutePath)) {
1175
+ return true;
1176
+ }
1177
+ const projectTempDir = this.storage.getProjectTempDir();
1178
+ return isSubpath(path.resolve(projectTempDir), absolutePath);
1179
+ },
1180
+ validatePathAccess(absolutePath) {
1181
+ if (this.isPathAllowed(absolutePath)) {
1182
+ return null;
1183
+ }
1184
+ const workspaceDirs = this.getWorkspaceContext().getDirectories();
1185
+ const projectTempDir = this.storage.getProjectTempDir();
1186
+ return `Path not in workspace: Attempted path "${absolutePath}" resolves outside the allowed workspace directories: ${workspaceDirs.join(', ')} or the project temp directory: ${projectTempDir}`;
1187
+ },
1217
1188
  };
1218
1189
  const geminiIgnoreTool = new RipGrepTool(configWithGeminiIgnore, createMockMessageBus());
1219
1190
  mockSpawn.mockImplementationOnce(createMockSpawn({
@@ -1233,13 +1204,37 @@ describe('RipGrepTool', () => {
1233
1204
  expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining(['--ignore-file', geminiIgnorePath]), expect.anything());
1234
1205
  });
1235
1206
  it('should skip .geminiignore when disabled', async () => {
1236
- const geminiIgnorePath = path.join(tempRootDir, '.geminiignore');
1207
+ const geminiIgnorePath = path.join(tempRootDir, GEMINI_IGNORE_FILE_NAME);
1237
1208
  await fs.writeFile(geminiIgnorePath, 'ignored.log');
1238
1209
  const configWithoutGeminiIgnore = {
1239
1210
  getTargetDir: () => tempRootDir,
1240
1211
  getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
1241
1212
  getDebugMode: () => false,
1213
+ getFileFilteringRespectGitIgnore: () => true,
1242
1214
  getFileFilteringRespectGeminiIgnore: () => false,
1215
+ getFileFilteringOptions: () => ({
1216
+ respectGitIgnore: true,
1217
+ respectGeminiIgnore: false,
1218
+ }),
1219
+ storage: {
1220
+ getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
1221
+ },
1222
+ isPathAllowed(absolutePath) {
1223
+ const workspaceContext = this.getWorkspaceContext();
1224
+ if (workspaceContext.isPathWithinWorkspace(absolutePath)) {
1225
+ return true;
1226
+ }
1227
+ const projectTempDir = this.storage.getProjectTempDir();
1228
+ return isSubpath(path.resolve(projectTempDir), absolutePath);
1229
+ },
1230
+ validatePathAccess(absolutePath) {
1231
+ if (this.isPathAllowed(absolutePath)) {
1232
+ return null;
1233
+ }
1234
+ const workspaceDirs = this.getWorkspaceContext().getDirectories();
1235
+ const projectTempDir = this.storage.getProjectTempDir();
1236
+ return `Path not in workspace: Attempted path "${absolutePath}" resolves outside the allowed workspace directories: ${workspaceDirs.join(', ')} or the project temp directory: ${projectTempDir}`;
1237
+ },
1243
1238
  };
1244
1239
  const geminiIgnoreTool = new RipGrepTool(configWithoutGeminiIgnore, createMockMessageBus());
1245
1240
  mockSpawn.mockImplementationOnce(createMockSpawn({
@@ -1261,18 +1256,41 @@ describe('RipGrepTool', () => {
1261
1256
  it('should handle context parameters', async () => {
1262
1257
  mockSpawn.mockImplementationOnce(createMockSpawn({
1263
1258
  outputData: JSON.stringify({
1264
- type: 'match',
1259
+ type: 'context',
1265
1260
  data: {
1266
1261
  path: { text: 'fileA.txt' },
1267
- line_number: 2,
1268
- lines: { text: 'second line with world\n' },
1269
- lines_before: [{ text: 'hello world\n' }],
1270
- lines_after: [
1271
- { text: 'third line\n' },
1272
- { text: 'fourth line\n' },
1273
- ],
1262
+ line_number: 1,
1263
+ lines: { text: 'hello world\n' },
1274
1264
  },
1275
- }) + '\n',
1265
+ }) +
1266
+ '\n' +
1267
+ JSON.stringify({
1268
+ type: 'match',
1269
+ data: {
1270
+ path: { text: 'fileA.txt' },
1271
+ line_number: 2,
1272
+ lines: { text: 'second line with world\n' },
1273
+ },
1274
+ }) +
1275
+ '\n' +
1276
+ JSON.stringify({
1277
+ type: 'context',
1278
+ data: {
1279
+ path: { text: 'fileA.txt' },
1280
+ line_number: 3,
1281
+ lines: { text: 'third line\n' },
1282
+ },
1283
+ }) +
1284
+ '\n' +
1285
+ JSON.stringify({
1286
+ type: 'context',
1287
+ data: {
1288
+ path: { text: 'fileA.txt' },
1289
+ line_number: 4,
1290
+ lines: { text: 'fourth line\n' },
1291
+ },
1292
+ }) +
1293
+ '\n',
1276
1294
  exitCode: 0,
1277
1295
  }));
1278
1296
  const params = {
@@ -1293,9 +1311,10 @@ describe('RipGrepTool', () => {
1293
1311
  ]), expect.anything());
1294
1312
  expect(result.llmContent).toContain('Found 1 match for pattern "world"');
1295
1313
  expect(result.llmContent).toContain('File: fileA.txt');
1314
+ expect(result.llmContent).toContain('L1- hello world');
1296
1315
  expect(result.llmContent).toContain('L2: second line with world');
1297
- // Note: Ripgrep JSON output for context lines doesn't include line numbers for context lines directly
1298
- // The current parsing only extracts the matched line, so we only assert on that.
1316
+ expect(result.llmContent).toContain('L3- third line');
1317
+ expect(result.llmContent).toContain('L4- fourth line');
1299
1318
  });
1300
1319
  });
1301
1320
  describe('getDescription', () => {
@@ -1335,6 +1354,29 @@ describe('RipGrepTool', () => {
1335
1354
  getTargetDir: () => tempRootDir,
1336
1355
  getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir, ['/another/dir']),
1337
1356
  getDebugMode: () => false,
1357
+ getFileFilteringOptions: () => ({
1358
+ respectGitIgnore: true,
1359
+ respectGeminiIgnore: true,
1360
+ }),
1361
+ storage: {
1362
+ getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
1363
+ },
1364
+ isPathAllowed(absolutePath) {
1365
+ const workspaceContext = this.getWorkspaceContext();
1366
+ if (workspaceContext.isPathWithinWorkspace(absolutePath)) {
1367
+ return true;
1368
+ }
1369
+ const projectTempDir = this.storage.getProjectTempDir();
1370
+ return isSubpath(path.resolve(projectTempDir), absolutePath);
1371
+ },
1372
+ validatePathAccess(absolutePath) {
1373
+ if (this.isPathAllowed(absolutePath)) {
1374
+ return null;
1375
+ }
1376
+ const workspaceDirs = this.getWorkspaceContext().getDirectories();
1377
+ const projectTempDir = this.storage.getProjectTempDir();
1378
+ return `Path not in workspace: Attempted path "${absolutePath}" resolves outside the allowed workspace directories: ${workspaceDirs.join(', ')} or the project temp directory: ${projectTempDir}`;
1379
+ },
1338
1380
  };
1339
1381
  const multiDirGrepTool = new RipGrepTool(multiDirConfig, createMockMessageBus());
1340
1382
  const params = { pattern: 'testPattern' };
@@ -1354,6 +1396,142 @@ describe('RipGrepTool', () => {
1354
1396
  expect(invocation.getDescription()).toContain(path.join('src', 'app'));
1355
1397
  });
1356
1398
  });
1399
+ describe('new parameters', () => {
1400
+ it('should pass --max-count when max_matches_per_file is provided', async () => {
1401
+ mockSpawn.mockImplementationOnce(createMockSpawn({
1402
+ outputData: JSON.stringify({
1403
+ type: 'match',
1404
+ data: {
1405
+ path: { text: 'fileA.txt' },
1406
+ line_number: 1,
1407
+ lines: { text: 'hello world\n' },
1408
+ },
1409
+ }) + '\n',
1410
+ exitCode: 0,
1411
+ }));
1412
+ const params = {
1413
+ pattern: 'world',
1414
+ max_matches_per_file: 1,
1415
+ };
1416
+ const invocation = grepTool.build(params);
1417
+ await invocation.execute(abortSignal);
1418
+ const spawnArgs = mockSpawn.mock.calls[0][1];
1419
+ expect(spawnArgs).toContain('--max-count');
1420
+ expect(spawnArgs).toContain('1');
1421
+ });
1422
+ it('should respect total_max_matches and truncate results', async () => {
1423
+ // Return 3 matches, but set total_max_matches to 2
1424
+ mockSpawn.mockImplementationOnce(createMockSpawn({
1425
+ outputData: JSON.stringify({
1426
+ type: 'match',
1427
+ data: {
1428
+ path: { text: 'fileA.txt' },
1429
+ line_number: 1,
1430
+ lines: { text: 'match 1\n' },
1431
+ },
1432
+ }) +
1433
+ '\n' +
1434
+ JSON.stringify({
1435
+ type: 'match',
1436
+ data: {
1437
+ path: { text: 'fileA.txt' },
1438
+ line_number: 2,
1439
+ lines: { text: 'match 2\n' },
1440
+ },
1441
+ }) +
1442
+ '\n' +
1443
+ JSON.stringify({
1444
+ type: 'match',
1445
+ data: {
1446
+ path: { text: 'fileA.txt' },
1447
+ line_number: 3,
1448
+ lines: { text: 'match 3\n' },
1449
+ },
1450
+ }) +
1451
+ '\n',
1452
+ exitCode: 0,
1453
+ }));
1454
+ const params = {
1455
+ pattern: 'match',
1456
+ total_max_matches: 2,
1457
+ };
1458
+ const invocation = grepTool.build(params);
1459
+ const result = await invocation.execute(abortSignal);
1460
+ expect(result.llmContent).toContain('Found 2 matches');
1461
+ expect(result.llmContent).toContain('results limited to 2 matches for performance');
1462
+ expect(result.llmContent).toContain('L1: match 1');
1463
+ expect(result.llmContent).toContain('L2: match 2');
1464
+ expect(result.llmContent).not.toContain('L3: match 3');
1465
+ expect(result.returnDisplay).toBe('Found 2 matches (limited)');
1466
+ });
1467
+ it('should return only file paths when names_only is true', async () => {
1468
+ mockSpawn.mockImplementationOnce(createMockSpawn({
1469
+ outputData: JSON.stringify({
1470
+ type: 'match',
1471
+ data: {
1472
+ path: { text: 'fileA.txt' },
1473
+ line_number: 1,
1474
+ lines: { text: 'hello world\n' },
1475
+ },
1476
+ }) +
1477
+ '\n' +
1478
+ JSON.stringify({
1479
+ type: 'match',
1480
+ data: {
1481
+ path: { text: 'fileB.txt' },
1482
+ line_number: 5,
1483
+ lines: { text: 'hello again\n' },
1484
+ },
1485
+ }) +
1486
+ '\n',
1487
+ exitCode: 0,
1488
+ }));
1489
+ const params = {
1490
+ pattern: 'hello',
1491
+ names_only: true,
1492
+ };
1493
+ const invocation = grepTool.build(params);
1494
+ const result = await invocation.execute(abortSignal);
1495
+ expect(result.llmContent).toContain('Found 2 files with matches');
1496
+ expect(result.llmContent).toContain('fileA.txt');
1497
+ expect(result.llmContent).toContain('fileB.txt');
1498
+ expect(result.llmContent).not.toContain('L1:');
1499
+ expect(result.llmContent).not.toContain('hello world');
1500
+ });
1501
+ it('should filter out matches based on exclude_pattern', async () => {
1502
+ mockSpawn.mockImplementationOnce(createMockSpawn({
1503
+ outputData: JSON.stringify({
1504
+ type: 'match',
1505
+ data: {
1506
+ path: { text: 'fileA.txt' },
1507
+ line_number: 1,
1508
+ lines: { text: 'Copyright 2025 Google LLC\n' },
1509
+ },
1510
+ }) +
1511
+ '\n' +
1512
+ JSON.stringify({
1513
+ type: 'match',
1514
+ data: {
1515
+ path: { text: 'fileB.txt' },
1516
+ line_number: 1,
1517
+ lines: { text: 'Copyright 2026 Google LLC\n' },
1518
+ },
1519
+ }) +
1520
+ '\n',
1521
+ exitCode: 0,
1522
+ }));
1523
+ const params = {
1524
+ pattern: 'Copyright .* Google LLC',
1525
+ exclude_pattern: '2026',
1526
+ };
1527
+ const invocation = grepTool.build(params);
1528
+ const result = await invocation.execute(abortSignal);
1529
+ expect(result.llmContent).toContain('Found 1 match');
1530
+ expect(result.llmContent).toContain('fileA.txt');
1531
+ expect(result.llmContent).not.toContain('fileB.txt');
1532
+ expect(result.llmContent).toContain('Copyright 2025 Google LLC');
1533
+ });
1534
+ });
1357
1535
  });
1358
1536
  afterAll(() => {
1359
1537
  storageSpy.mockRestore();