@bastani/atomic 0.9.2-alpha.1 → 0.9.3-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (455) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/README.md +2 -2
  3. package/dist/builtin/cursor/CHANGELOG.md +6 -0
  4. package/dist/builtin/cursor/package.json +2 -2
  5. package/dist/builtin/intercom/CHANGELOG.md +6 -0
  6. package/dist/builtin/intercom/package.json +1 -1
  7. package/dist/builtin/mcp/CHANGELOG.md +12 -0
  8. package/dist/builtin/mcp/direct-tools.ts +4 -2
  9. package/dist/builtin/mcp/package.json +1 -1
  10. package/dist/builtin/mcp/proxy-call.ts +3 -1
  11. package/dist/builtin/mcp/utils.ts +18 -7
  12. package/dist/builtin/subagents/CHANGELOG.md +17 -0
  13. package/dist/builtin/subagents/README.md +6 -6
  14. package/dist/builtin/subagents/agents/code-simplifier.md +7 -6
  15. package/dist/builtin/subagents/agents/codebase-analyzer.md +5 -4
  16. package/dist/builtin/subagents/agents/codebase-locator.md +3 -3
  17. package/dist/builtin/subagents/agents/codebase-online-researcher.md +10 -10
  18. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +4 -4
  19. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +3 -3
  20. package/dist/builtin/subagents/agents/codebase-research-locator.md +4 -4
  21. package/dist/builtin/subagents/agents/debugger.md +5 -5
  22. package/dist/builtin/subagents/agents/worker.md +56 -0
  23. package/dist/builtin/subagents/package.json +1 -1
  24. package/dist/builtin/subagents/skills/subagent/SKILL.md +11 -11
  25. package/dist/builtin/subagents/src/agents/agent-loaders.ts +3 -5
  26. package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +3 -3
  27. package/dist/builtin/subagents/src/extension/schemas.ts +2 -2
  28. package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -3
  29. package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +1 -1
  30. package/dist/builtin/subagents/src/runs/shared/nested-render.ts +2 -2
  31. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -1
  32. package/dist/builtin/subagents/src/shared/types-depth.ts +5 -5
  33. package/dist/builtin/subagents/src/shared/types-runtime.ts +2 -1
  34. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -2
  35. package/dist/builtin/web-access/CHANGELOG.md +6 -0
  36. package/dist/builtin/web-access/package.json +1 -1
  37. package/dist/builtin/workflows/CHANGELOG.md +21 -0
  38. package/dist/builtin/workflows/README.md +2 -2
  39. package/dist/builtin/workflows/builtin/goal-artifacts.ts +11 -6
  40. package/dist/builtin/workflows/builtin/goal-ledger.ts +33 -1
  41. package/dist/builtin/workflows/builtin/goal-prompts.ts +23 -28
  42. package/dist/builtin/workflows/builtin/goal-reducer.ts +2 -2
  43. package/dist/builtin/workflows/builtin/goal-reports.ts +2 -5
  44. package/dist/builtin/workflows/builtin/goal-review.ts +1 -1
  45. package/dist/builtin/workflows/builtin/goal-runner.ts +10 -17
  46. package/dist/builtin/workflows/builtin/open-claude-design-feedback.ts +3 -3
  47. package/dist/builtin/workflows/builtin/open-claude-design-phases.ts +1 -3
  48. package/dist/builtin/workflows/builtin/open-claude-design-setup.ts +1 -1
  49. package/dist/builtin/workflows/builtin/ralph-core.ts +7 -17
  50. package/dist/builtin/workflows/builtin/ralph-runner.ts +11 -18
  51. package/dist/builtin/workflows/builtin/shared-prompts.ts +1 -1
  52. package/dist/builtin/workflows/package.json +1 -1
  53. package/dist/builtin/workflows/src/extension/config-loader.ts +35 -15
  54. package/dist/builtin/workflows/src/extension/discovery.ts +20 -8
  55. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +1 -2
  56. package/dist/builtin/workflows/src/extension/wiring.ts +1 -1
  57. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +11 -10
  58. package/dist/cli/args.d.ts.map +1 -1
  59. package/dist/cli/args.js +9 -9
  60. package/dist/cli/args.js.map +1 -1
  61. package/dist/config-self-update.d.ts.map +1 -1
  62. package/dist/config-self-update.js +3 -4
  63. package/dist/config-self-update.js.map +1 -1
  64. package/dist/config.d.ts.map +1 -1
  65. package/dist/config.js +4 -5
  66. package/dist/config.js.map +1 -1
  67. package/dist/core/agent-session-bash.d.ts +1 -0
  68. package/dist/core/agent-session-bash.d.ts.map +1 -1
  69. package/dist/core/agent-session-bash.js +1 -0
  70. package/dist/core/agent-session-bash.js.map +1 -1
  71. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  72. package/dist/core/agent-session-tool-registry.js +23 -0
  73. package/dist/core/agent-session-tool-registry.js.map +1 -1
  74. package/dist/core/bash-executor.d.ts +2 -0
  75. package/dist/core/bash-executor.d.ts.map +1 -1
  76. package/dist/core/bash-executor.js +1 -0
  77. package/dist/core/bash-executor.js.map +1 -1
  78. package/dist/core/compaction/compaction.d.ts +29 -0
  79. package/dist/core/compaction/compaction.d.ts.map +1 -1
  80. package/dist/core/compaction/compaction.js +36 -1
  81. package/dist/core/compaction/compaction.js.map +1 -1
  82. package/dist/core/compaction/context-compaction-metrics.d.ts +14 -2
  83. package/dist/core/compaction/context-compaction-metrics.d.ts.map +1 -1
  84. package/dist/core/compaction/context-compaction-metrics.js +50 -1
  85. package/dist/core/compaction/context-compaction-metrics.js.map +1 -1
  86. package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
  87. package/dist/core/compaction/context-compaction-prompt.js +2 -0
  88. package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
  89. package/dist/core/compaction/context-compaction-runner.d.ts.map +1 -1
  90. package/dist/core/compaction/context-compaction-runner.js +1 -1
  91. package/dist/core/compaction/context-compaction-runner.js.map +1 -1
  92. package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
  93. package/dist/core/compaction/context-deletion-application.js +5 -5
  94. package/dist/core/compaction/context-deletion-application.js.map +1 -1
  95. package/dist/core/compaction/context-deletion-targets.d.ts +2 -0
  96. package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
  97. package/dist/core/compaction/context-deletion-targets.js +23 -3
  98. package/dist/core/compaction/context-deletion-targets.js.map +1 -1
  99. package/dist/core/compaction/context-deletion-tool-definitions.d.ts +6 -0
  100. package/dist/core/compaction/context-deletion-tool-definitions.d.ts.map +1 -1
  101. package/dist/core/compaction/context-deletion-tool-definitions.js.map +1 -1
  102. package/dist/core/compaction/context-deletion-tools.d.ts.map +1 -1
  103. package/dist/core/compaction/context-deletion-tools.js +18 -10
  104. package/dist/core/compaction/context-deletion-tools.js.map +1 -1
  105. package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
  106. package/dist/core/compaction/context-transcript-analysis.js +2 -4
  107. package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
  108. package/dist/core/copilot-gemini-tool-arguments.d.ts.map +1 -1
  109. package/dist/core/copilot-gemini-tool-arguments.js +2 -60
  110. package/dist/core/copilot-gemini-tool-arguments.js.map +1 -1
  111. package/dist/core/extensions/context-types.d.ts +2 -0
  112. package/dist/core/extensions/context-types.d.ts.map +1 -1
  113. package/dist/core/extensions/context-types.js.map +1 -1
  114. package/dist/core/extensions/index.d.ts +2 -2
  115. package/dist/core/extensions/index.d.ts.map +1 -1
  116. package/dist/core/extensions/index.js +1 -1
  117. package/dist/core/extensions/index.js.map +1 -1
  118. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  119. package/dist/core/extensions/loader-virtual-modules.js +11 -3
  120. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  121. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  122. package/dist/core/extensions/runner-context.js +11 -0
  123. package/dist/core/extensions/runner-context.js.map +1 -1
  124. package/dist/core/extensions/tool-events.d.ts +13 -13
  125. package/dist/core/extensions/tool-events.d.ts.map +1 -1
  126. package/dist/core/extensions/tool-events.js +3 -3
  127. package/dist/core/extensions/tool-events.js.map +1 -1
  128. package/dist/core/extensions/types.d.ts +1 -1
  129. package/dist/core/extensions/types.d.ts.map +1 -1
  130. package/dist/core/extensions/types.js +1 -1
  131. package/dist/core/extensions/types.js.map +1 -1
  132. package/dist/core/flattened-tool-arguments.d.ts +18 -0
  133. package/dist/core/flattened-tool-arguments.d.ts.map +1 -1
  134. package/dist/core/flattened-tool-arguments.js +104 -0
  135. package/dist/core/flattened-tool-arguments.js.map +1 -1
  136. package/dist/core/sdk-exports.d.ts +1 -1
  137. package/dist/core/sdk-exports.d.ts.map +1 -1
  138. package/dist/core/sdk-exports.js +1 -1
  139. package/dist/core/sdk-exports.js.map +1 -1
  140. package/dist/core/sdk-types.d.ts +2 -2
  141. package/dist/core/sdk-types.d.ts.map +1 -1
  142. package/dist/core/sdk-types.js.map +1 -1
  143. package/dist/core/settings-manager-basic-accessors.d.ts +4 -0
  144. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  145. package/dist/core/settings-manager-basic-accessors.js +18 -0
  146. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  147. package/dist/core/settings-manager-resource-accessors.d.ts +4 -0
  148. package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
  149. package/dist/core/settings-manager-resource-accessors.js +15 -0
  150. package/dist/core/settings-manager-resource-accessors.js.map +1 -1
  151. package/dist/core/settings-types.d.ts +11 -0
  152. package/dist/core/settings-types.d.ts.map +1 -1
  153. package/dist/core/settings-types.js.map +1 -1
  154. package/dist/core/system-prompt.d.ts +1 -1
  155. package/dist/core/system-prompt.d.ts.map +1 -1
  156. package/dist/core/system-prompt.js +3 -2
  157. package/dist/core/system-prompt.js.map +1 -1
  158. package/dist/core/tools/artifact-protocol.d.ts +11 -0
  159. package/dist/core/tools/artifact-protocol.d.ts.map +1 -0
  160. package/dist/core/tools/artifact-protocol.js +76 -0
  161. package/dist/core/tools/artifact-protocol.js.map +1 -0
  162. package/dist/core/tools/artifacts.d.ts +18 -0
  163. package/dist/core/tools/artifacts.d.ts.map +1 -0
  164. package/dist/core/tools/artifacts.js +90 -0
  165. package/dist/core/tools/artifacts.js.map +1 -0
  166. package/dist/core/tools/bash-async-jobs.d.ts +20 -0
  167. package/dist/core/tools/bash-async-jobs.d.ts.map +1 -0
  168. package/dist/core/tools/bash-async-jobs.js +59 -0
  169. package/dist/core/tools/bash-async-jobs.js.map +1 -0
  170. package/dist/core/tools/bash-async-output.d.ts +10 -0
  171. package/dist/core/tools/bash-async-output.d.ts.map +1 -0
  172. package/dist/core/tools/bash-async-output.js +80 -0
  173. package/dist/core/tools/bash-async-output.js.map +1 -0
  174. package/dist/core/tools/bash-interceptor.d.ts +10 -0
  175. package/dist/core/tools/bash-interceptor.d.ts.map +1 -0
  176. package/dist/core/tools/bash-interceptor.js +39 -0
  177. package/dist/core/tools/bash-interceptor.js.map +1 -0
  178. package/dist/core/tools/bash-leading-cd.d.ts +7 -0
  179. package/dist/core/tools/bash-leading-cd.d.ts.map +1 -0
  180. package/dist/core/tools/bash-leading-cd.js +59 -0
  181. package/dist/core/tools/bash-leading-cd.js.map +1 -0
  182. package/dist/core/tools/bash-pty-native.d.ts +14 -0
  183. package/dist/core/tools/bash-pty-native.d.ts.map +1 -0
  184. package/dist/core/tools/bash-pty-native.js +71 -0
  185. package/dist/core/tools/bash-pty-native.js.map +1 -0
  186. package/dist/core/tools/bash.d.ts +28 -17
  187. package/dist/core/tools/bash.d.ts.map +1 -1
  188. package/dist/core/tools/bash.js +152 -35
  189. package/dist/core/tools/bash.js.map +1 -1
  190. package/dist/core/tools/block-resolver.d.ts +16 -0
  191. package/dist/core/tools/block-resolver.d.ts.map +1 -0
  192. package/dist/core/tools/block-resolver.js +74 -0
  193. package/dist/core/tools/block-resolver.js.map +1 -0
  194. package/dist/core/tools/conflict-registry.d.ts +16 -0
  195. package/dist/core/tools/conflict-registry.d.ts.map +1 -0
  196. package/dist/core/tools/conflict-registry.js +44 -0
  197. package/dist/core/tools/conflict-registry.js.map +1 -0
  198. package/dist/core/tools/directory-tree.d.ts +13 -0
  199. package/dist/core/tools/directory-tree.d.ts.map +1 -0
  200. package/dist/core/tools/directory-tree.js +81 -0
  201. package/dist/core/tools/directory-tree.js.map +1 -0
  202. package/dist/core/tools/edit.d.ts +4 -29
  203. package/dist/core/tools/edit.d.ts.map +1 -1
  204. package/dist/core/tools/edit.js +136 -228
  205. package/dist/core/tools/edit.js.map +1 -1
  206. package/dist/core/tools/fetch-url.d.ts +74 -0
  207. package/dist/core/tools/fetch-url.d.ts.map +1 -0
  208. package/dist/core/tools/fetch-url.js +518 -0
  209. package/dist/core/tools/fetch-url.js.map +1 -0
  210. package/dist/core/tools/find.d.ts +27 -9
  211. package/dist/core/tools/find.d.ts.map +1 -1
  212. package/dist/core/tools/find.js +400 -176
  213. package/dist/core/tools/find.js.map +1 -1
  214. package/dist/core/tools/glob-path-utils.d.ts +8 -0
  215. package/dist/core/tools/glob-path-utils.d.ts.map +1 -0
  216. package/dist/core/tools/glob-path-utils.js +26 -0
  217. package/dist/core/tools/glob-path-utils.js.map +1 -0
  218. package/dist/core/tools/grep.d.ts +12 -0
  219. package/dist/core/tools/grep.d.ts.map +1 -1
  220. package/dist/core/tools/grep.js +141 -17
  221. package/dist/core/tools/grep.js.map +1 -1
  222. package/dist/core/tools/hashline-engine/apply.d.ts +11 -0
  223. package/dist/core/tools/hashline-engine/apply.d.ts.map +1 -0
  224. package/dist/core/tools/hashline-engine/apply.js +752 -0
  225. package/dist/core/tools/hashline-engine/apply.js.map +1 -0
  226. package/dist/core/tools/hashline-engine/block.d.ts +40 -0
  227. package/dist/core/tools/hashline-engine/block.d.ts.map +1 -0
  228. package/dist/core/tools/hashline-engine/block.js +117 -0
  229. package/dist/core/tools/hashline-engine/block.js.map +1 -0
  230. package/dist/core/tools/hashline-engine/diff-preview.d.ts +15 -0
  231. package/dist/core/tools/hashline-engine/diff-preview.d.ts.map +1 -0
  232. package/dist/core/tools/hashline-engine/diff-preview.js +98 -0
  233. package/dist/core/tools/hashline-engine/diff-preview.js.map +1 -0
  234. package/dist/core/tools/hashline-engine/format.d.ts +71 -0
  235. package/dist/core/tools/hashline-engine/format.d.ts.map +1 -0
  236. package/dist/core/tools/hashline-engine/format.js +178 -0
  237. package/dist/core/tools/hashline-engine/format.js.map +1 -0
  238. package/dist/core/tools/hashline-engine/fs.d.ts +81 -0
  239. package/dist/core/tools/hashline-engine/fs.d.ts.map +1 -0
  240. package/dist/core/tools/hashline-engine/fs.js +143 -0
  241. package/dist/core/tools/hashline-engine/fs.js.map +1 -0
  242. package/dist/core/tools/hashline-engine/index.d.ts +18 -0
  243. package/dist/core/tools/hashline-engine/index.d.ts.map +1 -0
  244. package/dist/core/tools/hashline-engine/index.js +20 -0
  245. package/dist/core/tools/hashline-engine/index.js.map +1 -0
  246. package/dist/core/tools/hashline-engine/input.d.ts +101 -0
  247. package/dist/core/tools/hashline-engine/input.d.ts.map +1 -0
  248. package/dist/core/tools/hashline-engine/input.js +398 -0
  249. package/dist/core/tools/hashline-engine/input.js.map +1 -0
  250. package/dist/core/tools/hashline-engine/messages.d.ts +99 -0
  251. package/dist/core/tools/hashline-engine/messages.d.ts.map +1 -0
  252. package/dist/core/tools/hashline-engine/messages.js +144 -0
  253. package/dist/core/tools/hashline-engine/messages.js.map +1 -0
  254. package/dist/core/tools/hashline-engine/mismatch.d.ts +45 -0
  255. package/dist/core/tools/hashline-engine/mismatch.d.ts.map +1 -0
  256. package/dist/core/tools/hashline-engine/mismatch.js +90 -0
  257. package/dist/core/tools/hashline-engine/mismatch.js.map +1 -0
  258. package/dist/core/tools/hashline-engine/normalize.d.ts +21 -0
  259. package/dist/core/tools/hashline-engine/normalize.d.ts.map +1 -0
  260. package/dist/core/tools/hashline-engine/normalize.js +33 -0
  261. package/dist/core/tools/hashline-engine/normalize.js.map +1 -0
  262. package/dist/core/tools/hashline-engine/parser.d.ts +24 -0
  263. package/dist/core/tools/hashline-engine/parser.d.ts.map +1 -0
  264. package/dist/core/tools/hashline-engine/parser.js +381 -0
  265. package/dist/core/tools/hashline-engine/parser.js.map +1 -0
  266. package/dist/core/tools/hashline-engine/patcher.d.ts +118 -0
  267. package/dist/core/tools/hashline-engine/patcher.d.ts.map +1 -0
  268. package/dist/core/tools/hashline-engine/patcher.js +341 -0
  269. package/dist/core/tools/hashline-engine/patcher.js.map +1 -0
  270. package/dist/core/tools/hashline-engine/prefixes.d.ts +43 -0
  271. package/dist/core/tools/hashline-engine/prefixes.d.ts.map +1 -0
  272. package/dist/core/tools/hashline-engine/prefixes.js +135 -0
  273. package/dist/core/tools/hashline-engine/prefixes.js.map +1 -0
  274. package/dist/core/tools/hashline-engine/recovery.d.ts +41 -0
  275. package/dist/core/tools/hashline-engine/recovery.d.ts.map +1 -0
  276. package/dist/core/tools/hashline-engine/recovery.js +168 -0
  277. package/dist/core/tools/hashline-engine/recovery.js.map +1 -0
  278. package/dist/core/tools/hashline-engine/snapshots.d.ts +65 -0
  279. package/dist/core/tools/hashline-engine/snapshots.d.ts.map +1 -0
  280. package/dist/core/tools/hashline-engine/snapshots.js +108 -0
  281. package/dist/core/tools/hashline-engine/snapshots.js.map +1 -0
  282. package/dist/core/tools/hashline-engine/stream.d.ts +3 -0
  283. package/dist/core/tools/hashline-engine/stream.d.ts.map +1 -0
  284. package/dist/core/tools/hashline-engine/stream.js +111 -0
  285. package/dist/core/tools/hashline-engine/stream.js.map +1 -0
  286. package/dist/core/tools/hashline-engine/tokenizer.d.ts +69 -0
  287. package/dist/core/tools/hashline-engine/tokenizer.d.ts.map +1 -0
  288. package/dist/core/tools/hashline-engine/tokenizer.js +430 -0
  289. package/dist/core/tools/hashline-engine/tokenizer.js.map +1 -0
  290. package/dist/core/tools/hashline-engine/types.d.ts +166 -0
  291. package/dist/core/tools/hashline-engine/types.d.ts.map +1 -0
  292. package/dist/core/tools/hashline-engine/types.js +9 -0
  293. package/dist/core/tools/hashline-engine/types.js.map +1 -0
  294. package/dist/core/tools/hashline.d.ts +29 -0
  295. package/dist/core/tools/hashline.d.ts.map +1 -0
  296. package/dist/core/tools/hashline.js +110 -0
  297. package/dist/core/tools/hashline.js.map +1 -0
  298. package/dist/core/tools/index.d.ts +6 -4
  299. package/dist/core/tools/index.d.ts.map +1 -1
  300. package/dist/core/tools/index.js +52 -35
  301. package/dist/core/tools/index.js.map +1 -1
  302. package/dist/core/tools/notebook.d.ts +38 -0
  303. package/dist/core/tools/notebook.d.ts.map +1 -0
  304. package/dist/core/tools/notebook.js +125 -0
  305. package/dist/core/tools/notebook.js.map +1 -0
  306. package/dist/core/tools/read-document-extract.d.ts +9 -0
  307. package/dist/core/tools/read-document-extract.d.ts.map +1 -0
  308. package/dist/core/tools/read-document-extract.js +212 -0
  309. package/dist/core/tools/read-document-extract.js.map +1 -0
  310. package/dist/core/tools/read-selectors.d.ts +24 -0
  311. package/dist/core/tools/read-selectors.d.ts.map +1 -0
  312. package/dist/core/tools/read-selectors.js +277 -0
  313. package/dist/core/tools/read-selectors.js.map +1 -0
  314. package/dist/core/tools/read-url.d.ts +37 -0
  315. package/dist/core/tools/read-url.d.ts.map +1 -0
  316. package/dist/core/tools/read-url.js +39 -0
  317. package/dist/core/tools/read-url.js.map +1 -0
  318. package/dist/core/tools/read.d.ts +11 -11
  319. package/dist/core/tools/read.d.ts.map +1 -1
  320. package/dist/core/tools/read.js +224 -94
  321. package/dist/core/tools/read.js.map +1 -1
  322. package/dist/core/tools/resource-selectors.d.ts +44 -0
  323. package/dist/core/tools/resource-selectors.d.ts.map +1 -0
  324. package/dist/core/tools/resource-selectors.js +808 -0
  325. package/dist/core/tools/resource-selectors.js.map +1 -0
  326. package/dist/core/tools/search-details.d.ts +26 -0
  327. package/dist/core/tools/search-details.d.ts.map +1 -0
  328. package/dist/core/tools/search-details.js +24 -0
  329. package/dist/core/tools/search-details.js.map +1 -0
  330. package/dist/core/tools/search-line-ranges.d.ts +11 -0
  331. package/dist/core/tools/search-line-ranges.d.ts.map +1 -0
  332. package/dist/core/tools/search-line-ranges.js +65 -0
  333. package/dist/core/tools/search-line-ranges.js.map +1 -0
  334. package/dist/core/tools/search-native.d.ts +97 -0
  335. package/dist/core/tools/search-native.d.ts.map +1 -0
  336. package/dist/core/tools/search-native.js +27 -0
  337. package/dist/core/tools/search-native.js.map +1 -0
  338. package/dist/core/tools/search.d.ts +24 -0
  339. package/dist/core/tools/search.d.ts.map +1 -0
  340. package/dist/core/tools/search.js +573 -0
  341. package/dist/core/tools/search.js.map +1 -0
  342. package/dist/core/tools/truncate.d.ts +4 -4
  343. package/dist/core/tools/truncate.d.ts.map +1 -1
  344. package/dist/core/tools/truncate.js +3 -3
  345. package/dist/core/tools/truncate.js.map +1 -1
  346. package/dist/core/tools/url-ip-guards.d.ts +4 -0
  347. package/dist/core/tools/url-ip-guards.d.ts.map +1 -0
  348. package/dist/core/tools/url-ip-guards.js +126 -0
  349. package/dist/core/tools/url-ip-guards.js.map +1 -0
  350. package/dist/core/tools/write.d.ts +12 -2
  351. package/dist/core/tools/write.d.ts.map +1 -1
  352. package/dist/core/tools/write.js +166 -14
  353. package/dist/core/tools/write.js.map +1 -1
  354. package/dist/core/trust-manager.d.ts.map +1 -1
  355. package/dist/core/trust-manager.js +2 -3
  356. package/dist/core/trust-manager.js.map +1 -1
  357. package/dist/index-extensions.d.ts +2 -2
  358. package/dist/index-extensions.d.ts.map +1 -1
  359. package/dist/index-extensions.js +1 -1
  360. package/dist/index-extensions.js.map +1 -1
  361. package/dist/index.d.ts +3 -3
  362. package/dist/index.d.ts.map +1 -1
  363. package/dist/index.js +3 -3
  364. package/dist/index.js.map +1 -1
  365. package/dist/modes/interactive/components/custom-editor.d.ts +1 -0
  366. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  367. package/dist/modes/interactive/components/custom-editor.js +9 -2
  368. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  369. package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
  370. package/dist/modes/interactive/components/settings-selector-handlers.js +3 -0
  371. package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
  372. package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
  373. package/dist/modes/interactive/components/settings-selector-items.js +7 -0
  374. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  375. package/dist/modes/interactive/components/settings-selector-types.d.ts +2 -0
  376. package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
  377. package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
  378. package/dist/modes/interactive/components/tree-selector-content.d.ts.map +1 -1
  379. package/dist/modes/interactive/components/tree-selector-content.js +0 -5
  380. package/dist/modes/interactive/components/tree-selector-content.js.map +1 -1
  381. package/dist/modes/interactive/interactive-auth-login.d.ts.map +1 -1
  382. package/dist/modes/interactive/interactive-auth-login.js +1 -0
  383. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  384. package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  385. package/dist/modes/interactive/interactive-autocomplete.js +80 -2
  386. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  387. package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
  388. package/dist/modes/interactive/interactive-hotkeys-debug.js +3 -0
  389. package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
  390. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  391. package/dist/modes/interactive/interactive-input-handling.js +51 -0
  392. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  393. package/dist/modes/interactive/interactive-mode-base.d.ts +5 -0
  394. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  395. package/dist/modes/interactive/interactive-mode-base.js +5 -0
  396. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  397. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  398. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  399. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  400. package/dist/modes/interactive/interactive-mode-surface.d.ts +12 -0
  401. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  402. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  403. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  404. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  405. package/dist/modes/interactive/interactive-mode.js +1 -0
  406. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  407. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  408. package/dist/modes/interactive/interactive-model-routing.js +4 -1
  409. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  410. package/dist/modes/interactive/interactive-onboarding.d.ts +11 -0
  411. package/dist/modes/interactive/interactive-onboarding.d.ts.map +1 -0
  412. package/dist/modes/interactive/interactive-onboarding.js +220 -0
  413. package/dist/modes/interactive/interactive-onboarding.js.map +1 -0
  414. package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
  415. package/dist/modes/interactive/interactive-selectors.js +4 -0
  416. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  417. package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
  418. package/dist/modes/interactive/interactive-session-routing.js +6 -0
  419. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  420. package/dist/modes/interactive/interactive-slash-commands.d.ts.map +1 -1
  421. package/dist/modes/interactive/interactive-slash-commands.js +9 -4
  422. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  423. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  424. package/dist/modes/interactive/interactive-startup.js +28 -0
  425. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  426. package/dist/utils/child-process.d.ts.map +1 -1
  427. package/dist/utils/child-process.js +21 -1
  428. package/dist/utils/child-process.js.map +1 -1
  429. package/dist/utils/markit.d.ts +8 -0
  430. package/dist/utils/markit.d.ts.map +1 -0
  431. package/dist/utils/markit.js +53 -0
  432. package/dist/utils/markit.js.map +1 -0
  433. package/dist/utils/paths.d.ts +2 -1
  434. package/dist/utils/paths.d.ts.map +1 -1
  435. package/dist/utils/paths.js +14 -1
  436. package/dist/utils/paths.js.map +1 -1
  437. package/docs/compaction.md +16 -1
  438. package/docs/containerization.md +1 -1
  439. package/docs/docs.json +1 -0
  440. package/docs/extensions.md +25 -36
  441. package/docs/quickstart.md +11 -6
  442. package/docs/sdk.md +5 -5
  443. package/docs/settings.md +7 -0
  444. package/docs/subagents.md +3 -2
  445. package/docs/tools.md +49 -0
  446. package/docs/usage.md +3 -3
  447. package/docs/workflows.md +7 -5
  448. package/examples/extensions/subagent/README.md +5 -5
  449. package/examples/extensions/subagent/agents/planner.md +1 -1
  450. package/examples/extensions/subagent/agents/reviewer.md +1 -1
  451. package/examples/extensions/subagent/agents/scout.md +2 -2
  452. package/examples/extensions/subagent/display.ts +3 -3
  453. package/examples/sdk/05-tools.ts +3 -3
  454. package/examples/sdk/README.md +1 -1
  455. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"find.js","sourceRoot":"","sources":["../../../src/core/tools/find.ts"],"names":[],"mappings":"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","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport { Text } from \"@earendil-works/pi-tui\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport { pathExists, resolveToCwd } from \"./path-utils.ts\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\n\nfunction toPosixPath(value: string): string {\n\treturn value.split(path.sep).join(\"/\");\n}\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(Type.String({ description: \"Directory to search in (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 1000)\" })),\n});\n\nexport type FindToolInput = Static<typeof findSchema>;\n\nconst DEFAULT_LIMIT = 1000;\n\nexport interface FindToolDetails {\n\ttruncation?: TruncationResult;\n\tresultLimitReached?: number;\n}\n\n/**\n * Pluggable operations for the find tool.\n * Override these to delegate file search to remote systems (for example SSH).\n */\nexport interface FindOperations {\n\t/** Check if path exists */\n\texists: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Find files matching glob pattern. Returns relative or absolute paths. */\n\tglob: (pattern: string, cwd: string, options: { ignore: string[]; limit: number }) => Promise<string[]> | string[];\n}\n\nconst defaultFindOperations: FindOperations = {\n\texists: pathExists,\n\t// This is a placeholder. Actual fd execution happens in execute() when no custom glob is provided.\n\tglob: () => [],\n};\n\nexport interface FindToolOptions {\n\t/** Custom operations for find. Default: local filesystem plus fd */\n\toperations?: FindOperations;\n}\n\nfunction formatFindCall(\n\targs: { pattern: string; path?: string; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.ts\").theme,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"find\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", pattern || \"\")) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (limit !== undefined) {\n\t\ttext += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n\t}\n\treturn text;\n}\n\nfunction formatFindResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: FindToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.ts\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 20;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"Expand\")}${theme.fg(\"muted\", \")\")}`;\n\t\t}\n\t}\n\n\tconst resultLimit = result.details?.resultLimitReached;\n\tconst truncation = result.details?.truncation;\n\tif (resultLimit || truncation?.truncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (resultLimit) warnings.push(`${resultLimit} results limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\nexport function createFindToolDefinition(\n\tcwd: string,\n\toptions?: FindToolOptions,\n): ToolDefinition<typeof findSchema, FindToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"find\",\n\t\tlabel: \"find\",\n\t\tdescription: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n\t\tpromptSnippet: \"Find files by glob pattern (respects .gitignore)\",\n\t\tparameters: findSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ pattern, path: searchDir, limit }: { pattern: string; path?: string; limit?: number },\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet settled = false;\n\t\t\t\tlet stopChild: (() => void) | undefined;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (settled) return;\n\t\t\t\t\tsettled = true;\n\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tstopChild = undefined;\n\t\t\t\t\tfn();\n\t\t\t\t};\n\t\t\t\tconst onAbort = () => {\n\t\t\t\t\tstopChild?.();\n\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t};\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\n\t\t\t\t\t\tconst ops = customOps ?? defaultFindOperations;\n\n\t\t\t\t\t\t// If custom operations provide glob(), use that instead of fd.\n\t\t\t\t\t\tif (customOps?.glob) {\n\t\t\t\t\t\t\tif (!(await ops.exists(searchPath))) {\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst results = await ops.glob(pattern, searchPath, {\n\t\t\t\t\t\t\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\t\t\t\t\t\t\tlimit: effectiveLimit,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (results.length === 0) {\n\t\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No files found matching pattern\" }],\n\t\t\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Relativize paths against the search root for stable output.\n\t\t\t\t\t\t\tconst relativized = results.map((p) => {\n\t\t\t\t\t\t\t\tif (p.startsWith(searchPath)) return toPosixPath(p.slice(searchPath.length + 1));\n\t\t\t\t\t\t\t\treturn toPosixPath(path.relative(searchPath, p));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst resultLimitReached = relativized.length >= effectiveLimit;\n\t\t\t\t\t\t\tconst rawOutput = relativized.join(\"\\n\");\n\t\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet resultOutput = truncation.content;\n\t\t\t\t\t\t\tconst details: FindToolDetails = {};\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (resultLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(`${effectiveLimit} results limit reached`);\n\t\t\t\t\t\t\t\tdetails.resultLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\t\tresultOutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: resultOutput }],\n\t\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Default implementation uses fd.\n\t\t\t\t\t\tconst fdPath = await ensureTool(\"fd\", true);\n\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!fdPath) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"fd is not available and could not be downloaded\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Build fd arguments. --no-require-git makes fd apply hierarchical .gitignore\n\t\t\t\t\t\t// semantics whether or not the search path is inside a git repository, without\n\t\t\t\t\t\t// leaking sibling-directory rules the way --ignore-file (a global source) would.\n\t\t\t\t\t\tconst args: string[] = [\n\t\t\t\t\t\t\t\"--glob\",\n\t\t\t\t\t\t\t\"--color=never\",\n\t\t\t\t\t\t\t\"--hidden\",\n\t\t\t\t\t\t\t\"--no-require-git\",\n\t\t\t\t\t\t\t\"--max-results\",\n\t\t\t\t\t\t\tString(effectiveLimit),\n\t\t\t\t\t\t];\n\n\t\t\t\t\t\t// fd --glob matches against the basename unless --full-path is set; in --full-path\n\t\t\t\t\t\t// mode it matches against the absolute candidate path, so a path-containing\n\t\t\t\t\t\t// pattern like 'src/**/*.spec.ts' needs a leading '**/' to match anything.\n\t\t\t\t\t\tlet effectivePattern = pattern;\n\t\t\t\t\t\tif (pattern.includes(\"/\")) {\n\t\t\t\t\t\t\targs.push(\"--full-path\");\n\t\t\t\t\t\t\tif (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\") {\n\t\t\t\t\t\t\t\teffectivePattern = `**/${pattern}`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\targs.push(\"--\", effectivePattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(fdPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tconst lines: string[] = [];\n\n\t\t\t\t\t\tstopChild = () => {\n\t\t\t\t\t\t\tif (!child.killed) {\n\t\t\t\t\t\t\t\tchild.kill();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tlines.push(line);\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Failed to run fd: ${error.message}`)));\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tchild.on(\"close\", (code) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst output = lines.join(\"\\n\");\n\t\t\t\t\t\t\tif (code !== 0) {\n\t\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `fd exited with code ${code}`;\n\t\t\t\t\t\t\t\tif (!output) {\n\t\t\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!output) {\n\t\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No files found matching pattern\" }],\n\t\t\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst relativized: string[] = [];\n\t\t\t\t\t\t\tfor (const rawLine of lines) {\n\t\t\t\t\t\t\t\tconst line = rawLine.replace(/\\r$/, \"\").trim();\n\t\t\t\t\t\t\t\tif (!line) continue;\n\t\t\t\t\t\t\t\tconst hadTrailingSlash = line.endsWith(\"/\") || line.endsWith(\"\\\\\");\n\t\t\t\t\t\t\t\tlet relativePath = line;\n\t\t\t\t\t\t\t\tif (line.startsWith(searchPath)) {\n\t\t\t\t\t\t\t\t\trelativePath = line.slice(searchPath.length + 1);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\trelativePath = path.relative(searchPath, line);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (hadTrailingSlash && !relativePath.endsWith(\"/\")) relativePath += \"/\";\n\t\t\t\t\t\t\t\trelativized.push(toPosixPath(relativePath));\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst resultLimitReached = relativized.length >= effectiveLimit;\n\t\t\t\t\t\t\tconst rawOutput = relativized.join(\"\\n\");\n\t\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet resultOutput = truncation.content;\n\t\t\t\t\t\t\tconst details: FindToolDetails = {};\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (resultLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`${effectiveLimit} results limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.resultLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\t\tresultOutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: resultOutput }],\n\t\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst error = e instanceof Error ? e : new Error(String(e));\n\t\t\t\t\t\tsettle(() => reject(error));\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindResult(result, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createFindTool(cwd: string, options?: FindToolOptions): AgentTool<typeof findSchema> {\n\treturn wrapToolDefinition(createFindToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"find.js","sourceRoot":"","sources":["../../../src/core/tools/find.ts"],"names":[],"mappings":"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","sourcesContent":["import { statSync } from \"node:fs\";\nimport { stat as fsStat } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline\";\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport { Text } from \"@earendil-works/pi-tui\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport { normalizePathLikeInput, splitPathLikeGlob } from \"./glob-path-utils.ts\";\nimport { loadNativeSearchBinding } from \"./search-native.ts\";\nimport { pathExists, resolveToCwd } from \"./path-utils.ts\";\nimport { resolveInternalSelector, type InternalResourceContext } from \"./resource-selectors.ts\";\nimport { getTextOutput } from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\nconst toPosixPath = (value: string): string => value.split(path.sep).join(\"/\");\nconst findSchema = Type.Object({\n\tpaths: Type.Array(Type.String({ description: \"File, directory, or glob path to find.\" }), { description: \"Paths or glob paths to find.\", minItems: 1 }),\n\thidden: Type.Optional(Type.Boolean({ description: \"Include hidden files. Defaults to true.\" })),\n\tgitignore: Type.Optional(Type.Boolean({ description: \"Respect gitignore. Defaults to true.\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of results, clamped to 1-200.\", minimum: 1, maximum: 200 })),\n\ttimeout: Type.Optional(Type.Number({ description: \"Timeout in seconds; default 5, clamped to 0.5..60.\", minimum: 0.5, maximum: 60 })),\n}, { additionalProperties: false });\nexport type FindToolInput = Static<typeof findSchema>;\nconst DEFAULT_LIMIT = 200;\nconst MAX_LIMIT = 200;\nconst DEFAULT_TIMEOUT_MS = 5000;\nconst MIN_TIMEOUT_MS = 500;\nconst MAX_TIMEOUT_MS = 60_000;\ninterface FindTarget { searchPath: string; pattern: string; exactPathInput: boolean; inputPath: string }\nfunction normalizeLimit(limit: number | undefined): number { return limit === undefined || !Number.isFinite(limit) ? DEFAULT_LIMIT : Math.max(1, Math.min(MAX_LIMIT, Math.floor(limit))); }\nfunction normalizeTimeoutMs(timeout: number | undefined): number { return timeout === undefined || !Number.isFinite(timeout) ? DEFAULT_TIMEOUT_MS : Math.max(MIN_TIMEOUT_MS, Math.min(MAX_TIMEOUT_MS, Math.floor(timeout * 1000))); }\nfunction formatTimeoutSeconds(timeoutMs: number): string { const seconds = timeoutMs / 1000; return Number.isInteger(seconds) ? String(seconds) : seconds.toFixed(1); }\nasync function resolveFindInternal(input: string, cwd: string, ctx?: InternalResourceContext): Promise<string> { const parsed = splitPathLikeGlob(input); if (!/^[a-z]+:\\/\\//i.test(parsed.basePath)) return input; for (const resolve of [ctx?.internalRouter?.resolve, ctx?.internalResourceRouter?.resolve, ctx?.resolveInternalUrl]) { const resolved = await resolve?.(parsed.basePath); if (typeof resolved === \"string\") return parsed.glob ? `${resolved}/${parsed.glob}` : resolved; } const fallback = resolveInternalSelector(parsed.basePath, cwd); return fallback ? parsed.glob ? `${fallback}/${parsed.glob}` : fallback : input; }\nfunction isWindowsAbsolutePath(value: string): boolean { return /^[A-Za-z]:[\\\\/]/.test(value) || value.startsWith(\"\\\\\\\\\"); }\nfunction resolveFindBackendPath(input: string, cwd: string, customBackend: boolean): string { if (!customBackend) return resolveToCwd(input, cwd); if (input === \".\" || input === \"\") return cwd; if (input.startsWith(\"/\") || isWindowsAbsolutePath(input)) return input; if (cwd.includes(\"\\\\\") || isWindowsAbsolutePath(cwd)) return path.resolve(cwd, input); return `${cwd.replace(/\\/+$/, \"\")}/${input}`; }\nasync function delimiterInExistingGlobRoot(value: string, cwd: string, ops: FindOperations, customBackend: boolean): Promise<boolean> { const parsed = splitPathLikeGlob(value); return !!parsed.glob && /[;,\\s]/.test(parsed.basePath) && await ops.exists(resolveFindBackendPath(parsed.basePath, cwd, customBackend)); }\nasync function expandDelimitedFindPaths(pathsValue: string[] | undefined, cwd: string, ops: FindOperations, ctx?: InternalResourceContext, customBackend = false): Promise<string[]> {\n\tif (!pathsValue?.length) throw new Error(\"find.paths must include at least one path or glob.\"); const expanded: string[] = [];\n\tfor (const input of pathsValue) { const raw = normalizePathLikeInput(input); if (raw === \"\") throw new Error(\"find.paths entries must not be empty.\"); const resolvedRaw = await resolveFindInternal(raw, cwd, ctx); const rawParsed = splitPathLikeGlob(resolvedRaw);\n\t\tif ((rawParsed.glob === undefined && await ops.exists(resolveFindBackendPath(rawParsed.basePath, cwd, customBackend))) || await delimiterInExistingGlobRoot(resolvedRaw, cwd, ops, customBackend)) { expanded.push(resolvedRaw); continue; }\n\t\tconst parts = await Promise.all(raw.split(/[;,\\s]+/).map(normalizePathLikeInput).filter(Boolean).map((part) => resolveFindInternal(part, cwd, ctx)));\n\t\tconst delimiterCanSplit = /[;,]/.test(raw) ? (await Promise.all(parts.map((part) => ops.exists(resolveFindBackendPath(splitPathLikeGlob(part).basePath, cwd, customBackend))))).some(Boolean) : (await Promise.all(parts.map((part) => ops.exists(resolveFindBackendPath(splitPathLikeGlob(part).basePath, cwd, customBackend))))).every(Boolean);\n\t\tif (parts.length > 1 && delimiterCanSplit) expanded.push(...parts); else expanded.push(resolvedRaw);\n\t}\n\treturn expanded;\n}\nfunction normalizeFindTargets(cwd: string, pathsValue: string[] | undefined, customBackend = false): FindTarget[] {\n\tif (!pathsValue || pathsValue.length === 0) throw new Error(\"find.paths must include at least one path or glob.\");\n\treturn pathsValue.map((searchPath) => {\n\t\tconst parsed = splitPathLikeGlob(searchPath);\n\t\tconst target = { searchPath: resolveFindBackendPath(parsed.basePath, cwd, customBackend), pattern: parsed.glob ?? \"**/*\", exactPathInput: parsed.glob === undefined, inputPath: searchPath };\n\t\tif (path.parse(target.searchPath).root === target.searchPath) throw new Error(\"Refusing to search filesystem root with find; provide a narrower path.\");\n\t\treturn target;\n\t});\n}\nfunction relativizeFoundPath(foundPath: string, searchPath: string): string {\n\tconst hadTrailingSlash = foundPath.endsWith(\"/\") || foundPath.endsWith(\"\\\\\");\n\tconst relativePath = path.relative(searchPath, foundPath) || path.basename(foundPath);\n\tconst outputPath = hadTrailingSlash && !relativePath.endsWith(\"/\") ? `${relativePath}/` : relativePath;\n\treturn toPosixPath(outputPath);\n}\nfunction formatExactFoundPath(foundPath: string, cwd: string): string { return toPosixPath(path.relative(cwd, foundPath) || path.basename(foundPath)); }\nfunction containsHiddenSegment(value: string): boolean { return toPosixPath(value).split(\"/\").some((part) => part.startsWith(\".\") && part.length > 1); }\nfunction findTargetMentionsNodeModules(target: FindTarget): boolean { return target.pattern.includes(\"node_modules\") || toPosixPath(target.searchPath).split(\"/\").includes(\"node_modules\"); }\nfunction formatFoundPath(foundPath: string, searchPath: string, searchPaths: string[], cwd: string): string {\n\tlet absoluteFoundPath = path.isAbsolute(foundPath) ? foundPath : path.resolve(searchPath, foundPath);\n\tif (foundPath.endsWith(\"/\") && !absoluteFoundPath.endsWith(\"/\")) absoluteFoundPath += \"/\";\n\tconst relative = relativizeFoundPath(absoluteFoundPath, searchPath);\n\tif (searchPaths.length <= 1) return relative;\n\tconst rootLabel = toPosixPath(path.relative(cwd, searchPath) || path.basename(searchPath) || \".\");\n\treturn `${rootLabel}/${relative}`;\n}\ninterface FindTreeNode {\n\tfiles: Set<string>;\n\tdirs: Map<string, FindTreeNode>;\n}\nfunction createFindTreeNode(): FindTreeNode { return { files: new Set(), dirs: new Map() }; }\nfunction formatFindTree(relativized: string[]): string {\n\tconst root = createFindTreeNode();\n\tfor (const item of relativized) {\n\t\tconst isDir = item.endsWith(\"/\");\n\t\tconst parts = item.replace(/\\/+$/g, \"\").split(\"/\").filter(Boolean);\n\t\tif (parts.length === 0) continue;\n\t\tlet node = root;\n\t\tconst dirParts = isDir ? parts : parts.slice(0, -1);\n\t\tfor (const dir of dirParts) {\n\t\t\tlet child = node.dirs.get(dir);\n\t\t\tif (!child) {\n\t\t\t\tchild = createFindTreeNode();\n\t\t\t\tnode.dirs.set(dir, child);\n\t\t\t}\n\t\t\tnode = child;\n\t\t}\n\t\tif (!isDir) node.files.add(parts[parts.length - 1]!);\n\t}\n\tconst lines: string[] = [];\n\tconst collapse = (dir: string, node: FindTreeNode): { label: string; node: FindTreeNode } => {\n\t\tconst parts = [dir];\n\t\tlet current = node;\n\t\twhile (current.files.size === 0 && current.dirs.size === 1) {\n\t\t\tconst [[nextDir, nextNode]] = [...current.dirs.entries()];\n\t\t\tparts.push(nextDir!);\n\t\t\tcurrent = nextNode!;\n\t\t}\n\t\treturn { label: parts.join(\"/\"), node: current };\n\t};\n\tconst render = (node: FindTreeNode, depth: number): void => {\n\t\tfor (const file of [...node.files].sort()) lines.push(file);\n\t\tfor (const [dir, child] of [...node.dirs.entries()].sort(([a], [b]) => a.localeCompare(b))) {\n\t\t\tconst folded = collapse(dir, child);\n\t\t\tlines.push(`${\"#\".repeat(depth + 1)} ${folded.label}/`);\n\t\t\trender(folded.node, depth + 1);\n\t\t}\n\t};\n\trender(root, 0);\n\treturn lines.join(\"\\n\");\n}\nexport interface FindToolDetails { truncation?: TruncationResult; resultLimitReached?: number; timedOut?: boolean; truncated?: boolean; skippedMissingPaths?: string[]; missingPaths?: string[]; scopePath?: string; fileCount?: number; files?: string[]; meta?: { limits?: { resultLimit?: number }; truncation?: TruncationResult } }\nfunction buildFindResult(\n\trelativized: string[],\n\teffectiveLimit: number,\n\ttimedOut: boolean,\n\ttimeoutMs: number,\n\tskippedMissingPaths: string[] = [],\n\tresultLimitReached = false,\n): {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tdetails: FindToolDetails | undefined;\n} {\n\tconst rawOutput = relativized.length > 0 ? formatFindTree(relativized) : \"No files found matching pattern\";\n\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\tlet resultOutput = truncation.content;\n\tconst details: FindToolDetails = { scopePath: \".\", fileCount: relativized.length, files: relativized, meta: { limits: { resultLimit: effectiveLimit } } };\n\tconst notices: string[] = [];\n\tif (resultLimitReached) {\n\t\tnotices.push(`${effectiveLimit} results limit reached. Refine pattern or path to narrow results`);\n\t\tdetails.resultLimitReached = effectiveLimit;\n\t}\n\tif (timedOut) { notices.push(`find timed out after ${formatTimeoutSeconds(timeoutMs)}s; returning ${relativized.length} partial matches — increase timeout or narrow pattern`); details.timedOut = true; details.truncated = true; }\n\tif (skippedMissingPaths.length > 0) {\n\t\tnotices.push(`Skipped missing paths: ${skippedMissingPaths.join(\", \")}`);\n\t\tdetails.skippedMissingPaths = skippedMissingPaths;\n\t\tdetails.missingPaths = skippedMissingPaths;\n\t}\n\tif (truncation.truncated) {\n\t\tnotices.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit reached`);\n\t\tdetails.truncation = truncation;\n\t\tdetails.meta = { ...(details.meta ?? {}), truncation };\n\t\tdetails.truncated = true;\n\t}\n\tif (notices.length > 0) {\n\t\tresultOutput += `\\n\\n[${notices.join(\". \")}]`;\n\t}\n\treturn { content: [{ type: \"text\", text: resultOutput }], details };\n}\n/** Pluggable operations for remote/container find backends. */\nexport interface FindOperations {\n\tstat?: (path: string) => Promise<{ isFile: boolean; isDirectory: boolean }> | { isFile: boolean; isDirectory: boolean } | undefined;\n\texists: (path: string) => Promise<boolean> | boolean;\n\tglob: (pattern: string, cwd: string, options: { ignore: string[]; limit: number; hidden: boolean }) => Promise<string[]> | string[];\n}\nconst defaultFindOperations: FindOperations = {\n\texists: pathExists,\n\tglob: () => [],\n};\nexport interface FindToolOptions {\n\t/** Custom operations for find. Default: local filesystem plus fd */\n\toperations?: FindOperations;\n}\nfunction stripTrailingForwardSlashes(value: string): string { let end = value.length; while (end > 0 && value[end - 1] === \"/\") end--; return value.slice(0, end); }\n\nfunction formatFindCall(\n\targs: { paths?: string[]; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.ts\").theme,\n): string {\n\tconst paths = Array.isArray(args?.paths) ? args.paths.map((item) => splitPathLikeGlob(item).glob ? item : `${stripTrailingForwardSlashes(item)}/**/*`).join(\", \") : \"<paths>\";\n\tlet text = `${theme.fg(\"toolTitle\", theme.bold(\"find\"))} ${theme.fg(\"accent\", paths)}`;\n\tif (args?.limit !== undefined) text += theme.fg(\"toolOutput\", ` (limit ${args.limit})`);\n\treturn text;\n}\nfunction formatFindResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: FindToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.ts\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 20;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"Expand\")}${theme.fg(\"muted\", \")\")}`;\n\t\t}\n\t}\n\tconst resultLimit = result.details?.resultLimitReached;\n\tconst truncation = result.details?.truncation;\n\tconst timedOut = result.details?.timedOut;\n\tif (resultLimit || truncation?.truncated || timedOut) {\n\t\tconst warnings: string[] = [];\n\t\tif (resultLimit) warnings.push(`${resultLimit} results limit`);\n\t\tif (timedOut) warnings.push(\"timeout\");\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\nexport function createFindToolDefinition(\n\tcwd: string,\n\toptions?: FindToolOptions,\n): ToolDefinition<typeof findSchema, FindToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"find\",\n\t\tlabel: \"find\",\n\t\tdescription: \"Find filesystem paths by glob; use search when you need content matches instead of path matches.\",\n\t\tpromptSnippet: \"Find filesystem paths by glob.\",\n\t\tparameters: findSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\tparams: FindToolInput,\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tlet stopChild: (() => void) | undefined;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (settled) return;\n\t\t\t\t\tsettled = true;\n\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tstopChild = undefined;\n\t\t\t\t\tfn();\n\t\t\t\t};\n\t\t\t\tconst onAbort = () => {\n\t\t\t\t\tstopChild?.();\n\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t};\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\tconst { limit, hidden, gitignore, timeout } = params;\n\t\t\t\tconst paths = params.paths;\n\t\t\t\tconst resourceCtx = _ctx as InternalResourceContext | undefined;\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst ops = customOps ?? defaultFindOperations;\n\t\t\t\t\t\tconst targets = normalizeFindTargets(cwd, await expandDelimitedFindPaths(paths, cwd, ops, resourceCtx, !!customOps), !!customOps);\n\t\t\t\t\t\tconst searchPaths = targets.map((target) => target.searchPath);\n\t\t\t\t\t\tconst effectiveLimit = normalizeLimit(limit);\n\t\t\t\t\t\tconst timeoutMs = normalizeTimeoutMs(timeout);\n\t\t\t\t\t\tconst emitUpdate = (files: string[]) => _onUpdate?.({ content: [{ type: \"text\", text: files.join(\"\\n\") || \"No files found matching pattern\" }], details: { scopePath: \".\", files, fileCount: files.length, truncated: false } });\n\t\t\t\t\t\tconst exactFileResults: string[] = [];\n\t\t\t\t\t\tconst searchableTargets: FindTarget[] = [];\n\t\t\t\t\t\tconst skippedMissingPaths: string[] = [];\n\t\t\t\t\t\tfor (const target of targets) {\n\t\t\t\t\t\t\tif (target.searchPath === path.parse(target.searchPath).root) throw new Error(\"Refusing to search filesystem root with find; provide a narrower path.\");\n\t\t\t\t\t\t\tconst stat = customOps ? await customOps.stat?.(target.searchPath) : await fsStat(target.searchPath).catch(() => undefined);\n\t\t\t\t\t\t\tif (!stat && targets.length > 1 && !customOps) {\n\t\t\t\t\t\t\t\tskippedMissingPaths.push(target.inputPath);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!stat && targets.length === 1 && !customOps) {\n\t\t\t\t\t\t\t\tthrow new Error(`ENOENT: Path not found: ${target.searchPath}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (target.exactPathInput) {\n\t\t\t\t\t\t\t\tconst isFile = typeof stat?.isFile === \"function\" ? stat.isFile() : stat?.isFile;\n\t\t\t\t\t\t\t\tif (isFile) {\n\t\t\t\t\t\t\t\t\texactFileResults.push(formatExactFoundPath(target.searchPath, cwd));\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsearchableTargets.push(target);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (exactFileResults.length > effectiveLimit || searchableTargets.length === 0) {\n\t\t\t\t\t\t\tconst resultLimitReached = exactFileResults.length > effectiveLimit;\n\t\t\t\t\t\t\tsettle(() => resolve(buildFindResult(exactFileResults.slice(0, effectiveLimit), effectiveLimit, false, timeoutMs, skippedMissingPaths, resultLimitReached)));\n\t\t\t\t\t\t\temitUpdate(exactFileResults.slice(0, effectiveLimit));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (customOps?.glob) {\n\t\t\t\t\t\t\tconst deadline = Date.now() + timeoutMs;\n\t\t\t\t\t\t\tlet timedOut = false;\n\t\t\t\t\t\t\tconst relativized: string[] = [...exactFileResults];\n\t\t\t\t\t\t\tlet customLimitReached = false;\n\t\t\t\t\t\t\tfor (const target of searchableTargets) {\n\t\t\t\t\t\t\t\tif (!(await ops.exists(target.searchPath))) {\n\t\t\t\t\t\t\t\t\tif (targets.length > 1) {\n\t\t\t\t\t\t\t\t\t\tskippedMissingPaths.push(target.inputPath);\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${target.searchPath}`)));\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst remaining = effectiveLimit - relativized.length;\n\t\t\t\t\t\t\t\tconst remainingMs = deadline - Date.now();\n\t\t\t\t\t\t\t\tif (remaining <= 0) {\n\t\t\t\t\t\t\t\t\tconst ignore = findTargetMentionsNodeModules(target) ? [\"**/.git/**\"] : [\"**/node_modules/**\", \"**/.git/**\"];\n\t\t\t\t\t\t\t\t\tconst probe = await Promise.resolve(ops.glob(target.pattern, target.searchPath, { ignore, limit: 1, hidden: hidden !== false }));\n\t\t\t\t\t\t\t\t\tif (probe.some((p) => hidden !== false || !containsHiddenSegment(p))) customLimitReached = true;\n\t\t\t\t\t\t\t\t\tif (customLimitReached) break;\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (remainingMs <= 0) {\n\t\t\t\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst timeoutResult = Symbol(\"find-timeout\");\n\t\t\t\t\t\t\t\tlet raceTimer: ReturnType<typeof setTimeout> | undefined;\n\t\t\t\t\t\t\t\tconst ignore = findTargetMentionsNodeModules(target) ? [\"**/.git/**\"] : [\"**/node_modules/**\", \"**/.git/**\"];\n\t\t\t\t\t\t\t\tconst results = await Promise.race<string[] | symbol>([\n\t\t\t\t\t\t\t\t\tPromise.resolve(ops.glob(target.pattern, target.searchPath, { ignore, limit: remaining + 1, hidden: hidden !== false })),\n\t\t\t\t\t\t\t\t\tnew Promise<typeof timeoutResult>((resolveTimeout) => {\n\t\t\t\t\t\t\t\t\t\traceTimer = setTimeout(() => resolveTimeout(timeoutResult), remainingMs);\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tif (raceTimer) clearTimeout(raceTimer);\n\t\t\t\t\t\t\t\tif (!Array.isArray(results)) {\n\t\t\t\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (target.exactPathInput && results.length === 0) { const stat = await customOps.stat?.(target.searchPath); if (!stat?.isDirectory) relativized.push(formatExactFoundPath(target.searchPath, cwd)); continue; }\n\t\t\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst visible = results.filter((p) => hidden !== false || !containsHiddenSegment(p));\n\t\t\t\t\t\t\t\tif (visible.length > remaining) customLimitReached = true;\n\t\t\t\t\t\t\t\trelativized.push(...visible.slice(0, remaining).map((p) => formatFoundPath(p, target.searchPath, searchPaths, cwd)));\n\t\t\t\t\t\t\t\temitUpdate(relativized);\n\t\t\t\t\t\t\t\tif (customLimitReached) break;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsettle(() => resolve(buildFindResult(relativized, effectiveLimit, timedOut, timeoutMs, skippedMissingPaths, customLimitReached)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst nativeBinding = loadNativeSearchBinding();\n\t\t\t\t\t\tif (nativeBinding) {\n\t\t\t\t\t\t\tconst matches: { path: string; mtime: number }[] = exactFileResults.map((path) => ({ path, mtime: Number.POSITIVE_INFINITY }));\n\t\t\t\t\t\t\tlet timedOut = false;\n\t\t\t\t\t\t\tconst deadline = Date.now() + timeoutMs;\n\t\t\t\t\t\t\tfor (const target of searchableTargets) {\n\t\t\t\t\t\t\t\tconst remainingMs = deadline - Date.now();\n\t\t\t\t\t\t\t\tif (remainingMs <= 0) {\n\t\t\t\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst result = await nativeBinding.glob({\n\t\t\t\t\t\t\t\t\t\tpattern: target.pattern,\n\t\t\t\t\t\t\t\t\t\tpath: target.searchPath,\n\t\t\t\t\t\t\t\t\t\trecursive: false,\n\t\t\t\t\t\t\t\t\t\thidden: hidden !== false,\n\t\t\t\t\t\t\t\t\t\tgitignore: gitignore !== false,\n\t\t\t\t\t\t\t\t\t\tincludeNodeModules: findTargetMentionsNodeModules(target),\n\t\t\t\t\t\t\t\t\t\tmaxResults: effectiveLimit + 1,\n\t\t\t\t\t\t\t\t\t\tcache: false,\n\t\t\t\t\t\t\t\t\t\tsortByMtime: true,\n\t\t\t\t\t\t\t\t\t\ttimeoutMs: remainingMs,\n\t\t\t\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tmatches.push(...result.matches.map((match) => { const fileType = match.fileType ?? (match as { file_type?: number }).file_type; const isDir = (fileType === 2 || fileType === \"Dir\" || (fileType === undefined && statSync(path.resolve(target.searchPath, match.path), { throwIfNoEntry: false })?.isDirectory())) && !match.path.endsWith(\"/\"); const matchPath = isDir ? `${match.path}/` : match.path; return { path: formatFoundPath(matchPath, target.searchPath, searchPaths, cwd), mtime: match.mtime ?? 0 }; }));\n\t\t\t\t\t\t\t\t\temitUpdate(matches.map((match) => match.path));\n\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\tif (String(error).toLowerCase().includes(\"timed out\")) {\n\t\t\t\t\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst uniqueMatches = [...matches.reduce((map, match) => { const previous = map.get(match.path); if (!previous || match.mtime > previous.mtime) map.set(match.path, match); return map; }, new Map<string, { path: string; mtime: number }>()).values()];\n\t\t\t\t\t\t\tuniqueMatches.sort((a, b) => b.mtime - a.mtime || a.path.localeCompare(b.path));\n\t\t\t\t\t\t\tconst resultLimitReached = uniqueMatches.length > effectiveLimit;\n\t\t\t\t\t\t\tsettle(() => resolve(buildFindResult(uniqueMatches.slice(0, effectiveLimit).map((match) => match.path), effectiveLimit, timedOut, timeoutMs, skippedMissingPaths, resultLimitReached)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst fdPath = await ensureTool(\"fd\", true);\n\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!fdPath) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"fd is not available and could not be downloaded\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet timedOut = false;\n\t\t\t\t\t\tconst relativized: string[] = [...exactFileResults];\n\t\t\t\t\t\tconst deadline = Date.now() + timeoutMs;\n\t\t\t\t\t\tconst runFdForTarget = async (target: FindTarget, remaining: number): Promise<boolean> => {\n\t\t\t\t\t\t\tconst args: string[] = [\"--glob\", \"--color=never\", \"--no-require-git\", \"--max-results\", String(remaining + 1)];\n\t\t\t\t\t\t\tif (hidden !== false) args.push(\"--hidden\");\n\t\t\t\t\t\t\tif (gitignore === false) args.push(\"--no-ignore\");\n\t\t\t\t\t\t\tif (!findTargetMentionsNodeModules(target)) args.push(\"--exclude\", \"node_modules\");\n\t\t\t\t\t\t\tlet fdPattern = target.pattern;\n\t\t\t\t\t\t\tif (target.pattern.includes(\"/\")) {\n\t\t\t\t\t\t\t\targs.push(\"--full-path\");\n\t\t\t\t\t\t\t\tif (!target.pattern.startsWith(\"/\") && !target.pattern.startsWith(\"**/\") && target.pattern !== \"**\") fdPattern = `**/${target.pattern}`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\targs.push(\"--\", fdPattern, target.searchPath);\n\t\t\t\t\t\t\tconst remainingMs = deadline - Date.now();\n\t\t\t\t\t\t\tif (remainingMs <= 0) {\n\t\t\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn await new Promise<boolean>((resolveTarget, rejectTarget) => {\n\t\t\t\t\t\t\t\tconst child = spawn(fdPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\t\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\t\t\tconst lines: string[] = [];\n\t\t\t\t\t\t\t\tstopChild = () => {\n\t\t\t\t\t\t\t\t\tif (!child.killed) child.kill();\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tconst targetTimer = setTimeout(() => {\n\t\t\t\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\t\t\t\tstopChild?.();\n\t\t\t\t\t\t\t\t}, remainingMs);\n\t\t\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\t\t\tclearTimeout(targetTimer);\n\t\t\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\trl.on(\"line\", (line) => lines.push(line));\n\t\t\t\t\t\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\t\t\trejectTarget(new Error(`Failed to run fd: ${error.message}`));\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tchild.on(\"close\", (code) => {\n\t\t\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\t\t\t\trejectTarget(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (!timedOut && code !== 0 && lines.length === 0) {\n\t\t\t\t\t\t\t\t\t\trejectTarget(new Error(stderr.trim() || `fd exited with code ${code}`));\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tfor (const rawLine of lines.slice(0, remaining)) {\n\t\t\t\t\t\t\t\t\t\tconst line = rawLine.replace(/\\r$/, \"\").trim();\n\t\t\t\t\t\t\t\t\t\tif (line) { const found = statSync(path.resolve(target.searchPath, line), { throwIfNoEntry: false })?.isDirectory() && !line.endsWith(\"/\") ? `${line}/` : line; relativized.push(formatFoundPath(found, target.searchPath, searchPaths, cwd)); }\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\temitUpdate(relativized);\n\t\t\t\t\t\t\t\t\tresolveTarget(lines.length > Math.max(0, remaining));\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t};\n\t\t\t\t\t\tlet resultLimitReached = false;\n\t\t\t\t\t\tfor (const target of searchableTargets) {\n\t\t\t\t\t\t\tconst remaining = effectiveLimit - relativized.length;\n\t\t\t\t\t\t\tif (timedOut) break;\n\t\t\t\t\t\t\tif (remaining <= 0) { if (await runFdForTarget(target, 0)) { resultLimitReached = true; break; } continue; }\n\t\t\t\t\t\t\tconst targetLimitReached = await runFdForTarget(target, remaining);\n\t\t\t\t\t\t\tif (targetLimitReached) { resultLimitReached = true; break; }\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsettle(() => resolve(buildFindResult(relativized.slice(0, effectiveLimit), effectiveLimit, timedOut, timeoutMs, skippedMissingPaths, resultLimitReached)));\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst error = e instanceof Error ? e : new Error(String(e));\n\t\t\t\t\t\tsettle(() => reject(error));\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindResult(result, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\nexport function createFindTool(cwd: string, options?: FindToolOptions): AgentTool<typeof findSchema> {\n\treturn wrapToolDefinition(createFindToolDefinition(cwd, options));\n}\n"]}
@@ -0,0 +1,8 @@
1
+ export interface PathLikeGlobParts {
2
+ basePath: string;
3
+ glob?: string;
4
+ }
5
+ export declare function normalizePathLikeInput(value: string): string;
6
+ export declare function pathLikeContainsGlob(value: string): boolean;
7
+ export declare function splitPathLikeGlob(input: string): PathLikeGlobParts;
8
+ //# sourceMappingURL=glob-path-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob-path-utils.d.ts","sourceRoot":"","sources":["../../../src/core/tools/glob-path-utils.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,CAalE","sourcesContent":["const GLOB_CHARS = /[*?[{]/;\n\nexport interface PathLikeGlobParts {\n\tbasePath: string;\n\tglob?: string;\n}\n\nexport function normalizePathLikeInput(value: string): string {\n\tlet trimmed = value.trim();\n\tif ((trimmed.startsWith('\"') && trimmed.endsWith('\"')) || (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))) {\n\t\ttrimmed = trimmed.slice(1, -1);\n\t}\n\treturn trimmed;\n}\n\nexport function pathLikeContainsGlob(value: string): boolean {\n\treturn GLOB_CHARS.test(value);\n}\n\nexport function splitPathLikeGlob(input: string): PathLikeGlobParts {\n\tconst value = normalizePathLikeInput(input);\n\tconst normalized = value.replace(/\\\\/g, \"/\");\n\tconst segments = normalized.split(\"/\");\n\tconst firstGlobSegment = segments.findIndex((segment) => pathLikeContainsGlob(segment));\n\tif (firstGlobSegment === -1) return { basePath: value };\n\n\tconst basePath = segments.slice(0, firstGlobSegment).join(\"/\") || \".\";\n\tlet glob = segments.slice(firstGlobSegment).join(\"/\");\n\tif (firstGlobSegment === 0 && glob !== \"**\" && !glob.startsWith(\"**/\")) {\n\t\tglob = `**/${glob}`;\n\t}\n\treturn { basePath, glob };\n}\n"]}
@@ -0,0 +1,26 @@
1
+ const GLOB_CHARS = /[*?[{]/;
2
+ export function normalizePathLikeInput(value) {
3
+ let trimmed = value.trim();
4
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) || (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
5
+ trimmed = trimmed.slice(1, -1);
6
+ }
7
+ return trimmed;
8
+ }
9
+ export function pathLikeContainsGlob(value) {
10
+ return GLOB_CHARS.test(value);
11
+ }
12
+ export function splitPathLikeGlob(input) {
13
+ const value = normalizePathLikeInput(input);
14
+ const normalized = value.replace(/\\/g, "/");
15
+ const segments = normalized.split("/");
16
+ const firstGlobSegment = segments.findIndex((segment) => pathLikeContainsGlob(segment));
17
+ if (firstGlobSegment === -1)
18
+ return { basePath: value };
19
+ const basePath = segments.slice(0, firstGlobSegment).join("/") || ".";
20
+ let glob = segments.slice(firstGlobSegment).join("/");
21
+ if (firstGlobSegment === 0 && glob !== "**" && !glob.startsWith("**/")) {
22
+ glob = `**/${glob}`;
23
+ }
24
+ return { basePath, glob };
25
+ }
26
+ //# sourceMappingURL=glob-path-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob-path-utils.js","sourceRoot":"","sources":["../../../src/core/tools/glob-path-utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG,QAAQ,CAAC;AAO5B,MAAM,UAAU,sBAAsB,CAAC,KAAa;IACnD,IAAI,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC9G,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAa;IACjD,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC9C,MAAM,KAAK,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IACxF,IAAI,gBAAgB,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAExD,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;IACtE,IAAI,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtD,IAAI,gBAAgB,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,IAAI,GAAG,MAAM,IAAI,EAAE,CAAC;IACrB,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC","sourcesContent":["const GLOB_CHARS = /[*?[{]/;\n\nexport interface PathLikeGlobParts {\n\tbasePath: string;\n\tglob?: string;\n}\n\nexport function normalizePathLikeInput(value: string): string {\n\tlet trimmed = value.trim();\n\tif ((trimmed.startsWith('\"') && trimmed.endsWith('\"')) || (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))) {\n\t\ttrimmed = trimmed.slice(1, -1);\n\t}\n\treturn trimmed;\n}\n\nexport function pathLikeContainsGlob(value: string): boolean {\n\treturn GLOB_CHARS.test(value);\n}\n\nexport function splitPathLikeGlob(input: string): PathLikeGlobParts {\n\tconst value = normalizePathLikeInput(input);\n\tconst normalized = value.replace(/\\\\/g, \"/\");\n\tconst segments = normalized.split(\"/\");\n\tconst firstGlobSegment = segments.findIndex((segment) => pathLikeContainsGlob(segment));\n\tif (firstGlobSegment === -1) return { basePath: value };\n\n\tconst basePath = segments.slice(0, firstGlobSegment).join(\"/\") || \".\";\n\tlet glob = segments.slice(firstGlobSegment).join(\"/\");\n\tif (firstGlobSegment === 0 && glob !== \"**\" && !glob.startsWith(\"**/\")) {\n\t\tglob = `**/${glob}`;\n\t}\n\treturn { basePath, glob };\n}\n"]}
@@ -7,9 +7,19 @@ declare const grepSchema: Type.TObject<{
7
7
  path: Type.TOptional<Type.TString>;
8
8
  glob: Type.TOptional<Type.TString>;
9
9
  ignoreCase: Type.TOptional<Type.TBoolean>;
10
+ type: Type.TOptional<Type.TString>;
10
11
  literal: Type.TOptional<Type.TBoolean>;
11
12
  context: Type.TOptional<Type.TNumber>;
13
+ contextBefore: Type.TOptional<Type.TNumber>;
14
+ contextAfter: Type.TOptional<Type.TNumber>;
12
15
  limit: Type.TOptional<Type.TNumber>;
16
+ offset: Type.TOptional<Type.TNumber>;
17
+ mode: Type.TOptional<Type.TUnion<[Type.TLiteral<"content">, Type.TLiteral<"count">, Type.TLiteral<"filesWithMatches">]>>;
18
+ maxCountPerFile: Type.TOptional<Type.TNumber>;
19
+ hidden: Type.TOptional<Type.TBoolean>;
20
+ cache: Type.TOptional<Type.TBoolean>;
21
+ timeoutMs: Type.TOptional<Type.TNumber>;
22
+ gitignore: Type.TOptional<Type.TBoolean>;
13
23
  }>;
14
24
  export type GrepToolInput = Static<typeof grepSchema>;
15
25
  export interface GrepToolDetails {
@@ -30,6 +40,8 @@ export interface GrepOperations {
30
40
  export interface GrepToolOptions {
31
41
  /** Custom operations for grep. Default: local filesystem plus ripgrep */
32
42
  operations?: GrepOperations;
43
+ /** Enable shared native filesystem scan cache. Defaults to false; search callers also disable it to stay fresh across out-of-band filesystem mutations. */
44
+ nativeCache?: boolean;
33
45
  }
34
46
  export declare function createGrepToolDefinition(cwd: string, options?: GrepToolOptions): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined>;
35
47
  export declare function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAI/D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AAItF,OAAO,EAIN,KAAK,gBAAgB,EAGrB,MAAM,eAAe,CAAC;AAEvB,QAAA,MAAM,UAAU;;;;;;;;EAYd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAGtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAeD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,mEAAmE;IACnE,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAClE,2CAA2C;IAC3C,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC7D;AAOD,MAAM,WAAW,eAAe;IAC/B,yEAAyE;IACzE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAyDD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CA+PhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG","sourcesContent":["import { readFile as fsReadFile, stat as fsStat } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline\";\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport { Text } from \"@earendil-works/pi-tui\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from \"./truncate.ts\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\ntype RipgrepMatchEvent = {\n\ttype: \"match\";\n\tdata?: {\n\t\tpath?: { text?: unknown };\n\t\tline_number?: unknown;\n\t\tlines?: { text?: unknown };\n\t};\n};\n\nfunction isRipgrepMatchEvent(event: unknown): event is RipgrepMatchEvent {\n\treturn typeof event === \"object\" && event !== null && \"type\" in event && event.type === \"match\";\n}\n\n/**\n * Pluggable operations for the grep tool.\n * Override these to delegate search to remote systems (for example SSH).\n */\nexport interface GrepOperations {\n\t/** Check if path is a directory. Throws if path does not exist. */\n\tisDirectory: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Read file contents for context lines */\n\treadFile: (absolutePath: string) => Promise<string> | string;\n}\n\nconst defaultGrepOperations: GrepOperations = {\n\tisDirectory: async (p) => (await fsStat(p)).isDirectory(),\n\treadFile: (p) => fsReadFile(p, \"utf-8\"),\n};\n\nexport interface GrepToolOptions {\n\t/** Custom operations for grep. Default: local filesystem plus ripgrep */\n\toperations?: GrepOperations;\n}\n\nfunction formatGrepCall(\n\targs: { pattern: string; path?: string; glob?: string; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.ts\").theme,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: GrepToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.ts\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 15;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"Expand\")}${theme.fg(\"muted\", \")\")}`;\n\t\t}\n\t}\n\n\tconst matchLimit = result.details?.matchLimitReached;\n\tconst truncation = result.details?.truncation;\n\tconst linesTruncated = result.details?.linesTruncated;\n\tif (matchLimit || truncation?.truncated || linesTruncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (matchLimit) warnings.push(`${matchLimit} matches limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\tif (linesTruncated) warnings.push(\"some lines truncated\");\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\nexport function createGrepToolDefinition(\n\tcwd: string,\n\toptions?: GrepToolOptions,\n): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tparameters: grepSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{\n\t\t\t\tpattern,\n\t\t\t\tpath: searchDir,\n\t\t\t\tglob,\n\t\t\t\tignoreCase,\n\t\t\t\tliteral,\n\t\t\t\tcontext,\n\t\t\t\tlimit,\n\t\t\t}: {\n\t\t\t\tpattern: string;\n\t\t\t\tpath?: string;\n\t\t\t\tglob?: string;\n\t\t\t\tignoreCase?: boolean;\n\t\t\t\tliteral?: boolean;\n\t\t\t\tcontext?: number;\n\t\t\t\tlimit?: number;\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (!settled) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tfn();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst rgPath = await ensureTool(\"rg\", true);\n\t\t\t\t\t\tif (!rgPath) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"ripgrep (rg) is not available and could not be downloaded\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst ops = customOps ?? defaultGrepOperations;\n\t\t\t\t\t\tlet isDirectory: boolean;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tisDirectory = await ops.isDirectory(searchPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contextValue = context && context > 0 ? context : 0;\n\t\t\t\t\t\tconst effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n\t\t\t\t\t\tconst formatPath = (filePath: string): string => {\n\t\t\t\t\t\t\tif (isDirectory) {\n\t\t\t\t\t\t\t\tconst relative = path.relative(searchPath, filePath);\n\t\t\t\t\t\t\t\tif (relative && !relative.startsWith(\"..\")) {\n\t\t\t\t\t\t\t\t\treturn relative.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn path.basename(filePath);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst fileCache = new Map<string, string[]>();\n\t\t\t\t\t\tconst getFileLines = async (filePath: string): Promise<string[]> => {\n\t\t\t\t\t\t\tlet lines = fileCache.get(filePath);\n\t\t\t\t\t\t\tif (!lines) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst content = await ops.readFile(filePath);\n\t\t\t\t\t\t\t\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tlines = [];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfileCache.set(filePath, lines);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn lines;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\t\t\t\t\tif (ignoreCase) args.push(\"--ignore-case\");\n\t\t\t\t\t\tif (literal) args.push(\"--fixed-strings\");\n\t\t\t\t\t\tif (glob) args.push(\"--glob\", glob);\n\t\t\t\t\t\targs.push(\"--\", pattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(rgPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tlet matchCount = 0;\n\t\t\t\t\t\tlet matchLimitReached = false;\n\t\t\t\t\t\tlet linesTruncated = false;\n\t\t\t\t\t\tlet aborted = false;\n\t\t\t\t\t\tlet killedDueToLimit = false;\n\t\t\t\t\t\tconst outputLines: string[] = [];\n\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst stopChild = (dueToLimit = false) => {\n\t\t\t\t\t\t\tif (!child.killed) {\n\t\t\t\t\t\t\t\tkilledDueToLimit = dueToLimit;\n\t\t\t\t\t\t\t\tchild.kill();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\tstopChild();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst formatBlock = async (filePath: string, lineNumber: number): Promise<string[]> => {\n\t\t\t\t\t\t\tconst relativePath = formatPath(filePath);\n\t\t\t\t\t\t\tconst lines = await getFileLines(filePath);\n\t\t\t\t\t\t\tif (!lines.length) return [`${relativePath}:${lineNumber}: (unable to read file)`];\n\t\t\t\t\t\t\tconst block: string[] = [];\n\t\t\t\t\t\t\tconst start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n\t\t\t\t\t\t\tconst end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n\t\t\t\t\t\t\tfor (let current = start; current <= end; current++) {\n\t\t\t\t\t\t\t\tconst lineText = lines[current - 1] ?? \"\";\n\t\t\t\t\t\t\t\tconst sanitized = lineText.replace(/\\r/g, \"\");\n\t\t\t\t\t\t\t\tconst isMatchLine = current === lineNumber;\n\t\t\t\t\t\t\t\t// Truncate long lines so grep output stays compact.\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tif (isMatchLine) block.push(`${relativePath}:${current}: ${truncatedText}`);\n\t\t\t\t\t\t\t\telse block.push(`${relativePath}-${current}- ${truncatedText}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect matches during streaming, then format them after rg exits.\n\t\t\t\t\t\tconst matches: Array<{ filePath: string; lineNumber: number; lineText?: string }> = [];\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tif (!line.trim() || matchCount >= effectiveLimit) return;\n\t\t\t\t\t\t\tlet event: unknown;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevent = JSON.parse(line) as unknown;\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (isRipgrepMatchEvent(event)) {\n\t\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t\t\tconst filePath = event.data?.path?.text;\n\t\t\t\t\t\t\t\tconst lineNumber = event.data?.line_number;\n\t\t\t\t\t\t\t\tconst lineText = event.data?.lines?.text;\n\t\t\t\t\t\t\t\tif (typeof filePath === \"string\" && typeof lineNumber === \"number\")\n\t\t\t\t\t\t\t\t\tmatches.push({ filePath, lineNumber, lineText: typeof lineText === \"string\" ? lineText : undefined });\n\t\t\t\t\t\t\t\tif (matchCount >= effectiveLimit) {\n\t\t\t\t\t\t\t\t\tmatchLimitReached = true;\n\t\t\t\t\t\t\t\t\tstopChild(true);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Failed to run ripgrep: ${error.message}`)));\n\t\t\t\t\t\t});\n\t\t\t\t\t\tchild.on(\"close\", async (code) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!killedDueToLimit && code !== 0 && code !== 1) {\n\t\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (matchCount === 0) {\n\t\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Format matches after streaming finishes so custom readFile() backends can be async.\n\t\t\t\t\t\t\tfor (const match of matches) {\n\t\t\t\t\t\t\t\tif (contextValue === 0 && match.lineText !== undefined) {\n\t\t\t\t\t\t\t\t\tconst relativePath = formatPath(match.filePath);\n\t\t\t\t\t\t\t\t\tconst sanitized = match.lineText\n\t\t\t\t\t\t\t\t\t\t.replace(/\\r\\n/g, \"\\n\")\n\t\t\t\t\t\t\t\t\t\t.replace(/\\r/g, \"\")\n\t\t\t\t\t\t\t\t\t\t.replace(/\\n$/, \"\");\n\t\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\t\toutputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedText}`);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tconst block = await formatBlock(match.filePath, match.lineNumber);\n\t\t\t\t\t\t\t\t\toutputLines.push(...block);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst rawOutput = outputLines.join(\"\\n\");\n\t\t\t\t\t\t\t// Apply byte truncation. There is no line limit here because the match limit already capped rows.\n\t\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\t\tconst details: GrepToolDetails = {};\n\t\t\t\t\t\t\t// Build actionable notices for truncation and match limits.\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (matchLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`${effectiveLimit} matches limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.matchLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (linesTruncated) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.linesTruncated = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: output }],\n\t\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsettle(() => reject(err as Error));\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatGrepCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatGrepResult(result, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAI/D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AAKtF,OAAO,EAIN,KAAK,gBAAgB,EAGrB,MAAM,eAAe,CAAC;AAEvB,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;EAsBmB,CAAC;AAEpC,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAGtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAeD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,mEAAmE;IACnE,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAClE,2CAA2C;IAC3C,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC7D;AAOD,MAAM,WAAW,eAAe;IAC/B,yEAAyE;IACzE,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,2JAA2J;IAC3J,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAqED,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAsUhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG","sourcesContent":["import { readFile as fsReadFile, stat as fsStat } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline\";\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport { Text } from \"@earendil-works/pi-tui\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport { loadNativeSearchBinding, type NativeGrepMatch } from \"./search-native.ts\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from \"./truncate.ts\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\ttype: Type.Optional(Type.String({ description: \"File type filter for native grep.\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tcontextBefore: Type.Optional(Type.Number({ description: \"Lines to show before each match.\" })),\n\tcontextAfter: Type.Optional(Type.Number({ description: \"Lines to show after each match.\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n\toffset: Type.Optional(Type.Number({ description: \"Skip first N matches.\" })),\n\tmode: Type.Optional(Type.Union([Type.Literal(\"content\"), Type.Literal(\"count\"), Type.Literal(\"filesWithMatches\")])),\n\tmaxCountPerFile: Type.Optional(Type.Number({ description: \"Maximum matches per file.\" })),\n\thidden: Type.Optional(Type.Boolean({ description: \"Search hidden files (default true).\" })),\n\tcache: Type.Optional(Type.Boolean({ description: \"Use native cache.\" })),\n\ttimeoutMs: Type.Optional(Type.Number({ description: \"Native grep timeout in milliseconds.\" })),\n\tgitignore: Type.Optional(Type.Boolean({ description: \"Respect .gitignore files (default: true)\" })),\n}, { additionalProperties: false });\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\ntype RipgrepMatchEvent = {\n\ttype: \"match\";\n\tdata?: {\n\t\tpath?: { text?: unknown };\n\t\tline_number?: unknown;\n\t\tlines?: { text?: unknown };\n\t};\n};\n\nfunction isRipgrepMatchEvent(event: unknown): event is RipgrepMatchEvent {\n\treturn typeof event === \"object\" && event !== null && \"type\" in event && event.type === \"match\";\n}\n\n/**\n * Pluggable operations for the grep tool.\n * Override these to delegate search to remote systems (for example SSH).\n */\nexport interface GrepOperations {\n\t/** Check if path is a directory. Throws if path does not exist. */\n\tisDirectory: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Read file contents for context lines */\n\treadFile: (absolutePath: string) => Promise<string> | string;\n}\n\nconst defaultGrepOperations: GrepOperations = {\n\tisDirectory: async (p) => (await fsStat(p)).isDirectory(),\n\treadFile: (p) => fsReadFile(p, \"utf-8\"),\n};\n\nexport interface GrepToolOptions {\n\t/** Custom operations for grep. Default: local filesystem plus ripgrep */\n\toperations?: GrepOperations;\n\t/** Enable shared native filesystem scan cache. Defaults to false; search callers also disable it to stay fresh across out-of-band filesystem mutations. */\n\tnativeCache?: boolean;\n}\n\nfunction formatGrepCall(\n\targs: { pattern: string; path?: string; glob?: string; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.ts\").theme,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: GrepToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.ts\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 15;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"Expand\")}${theme.fg(\"muted\", \")\")}`;\n\t\t}\n\t}\n\n\tconst matchLimit = result.details?.matchLimitReached;\n\tconst truncation = result.details?.truncation;\n\tconst linesTruncated = result.details?.linesTruncated;\n\tif (matchLimit || truncation?.truncated || linesTruncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (matchLimit) warnings.push(`${matchLimit} matches limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\tif (linesTruncated) warnings.push(\"some lines truncated\");\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\nfunction formatNativeGrepMatch(match: NativeGrepMatch, displayPath: string): string[] {\n\tconst lines: string[] = [];\n\tfor (const contextLine of match.contextBefore ?? []) {\n\t\tlines.push(`${displayPath}-${contextLine.lineNumber}- ${contextLine.line}`);\n\t}\n\tlines.push(`${displayPath}:${match.lineNumber}: ${match.line}`);\n\tfor (const contextLine of match.contextAfter ?? []) {\n\t\tlines.push(`${displayPath}-${contextLine.lineNumber}- ${contextLine.line}`);\n\t}\n\treturn lines;\n}\n\nexport function createGrepToolDefinition(\n\tcwd: string,\n\toptions?: GrepToolOptions,\n): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tparameters: grepSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{\n\t\t\t\tpattern,\n\t\t\t\tpath: searchDir,\n\t\t\t\tglob,\n\t\t\t\tignoreCase,\n\t\t\t\tliteral,\n\t\t\t\tcontext,\n\t\t\t\tlimit,\n\t\t\t\tgitignore,\n\t\t\t\ttype,\n\t\t\t\tcontextBefore,\n\t\t\t\tcontextAfter,\n\t\t\t\toffset,\n\t\t\t\tmode,\n\t\t\t\tmaxCountPerFile,\n\t\t\t\thidden,\n\t\t\t\tcache,\n\t\t\t\ttimeoutMs,\n\t\t\t}: GrepToolInput,\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (!settled) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tfn();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst ops = customOps ?? defaultGrepOperations;\n\t\t\t\t\t\tlet isDirectory: boolean;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tisDirectory = await ops.isDirectory(searchPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contextValue = context && context > 0 ? context : 0;\n\t\t\t\t\t\tconst contextBeforeValue = contextBefore ?? contextValue;\n\t\t\t\t\t\tconst contextAfterValue = contextAfter ?? contextValue;\n\t\t\t\t\t\tconst nativeCache = options?.nativeCache === true;\n\t\t\t\t\t\tconst effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n\t\t\t\t\t\tconst formatPath = (filePath: string): string => {\n\t\t\t\t\t\t\tif (isDirectory) {\n\t\t\t\t\t\t\t\tif (!path.isAbsolute(filePath)) return filePath.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t\tconst relative = path.relative(searchPath, filePath);\n\t\t\t\t\t\t\t\tif (relative && !relative.startsWith(\"..\")) return relative.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn path.basename(filePath);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (!customOps && !literal) {\n\t\t\t\t\t\t\tconst nativeBinding = loadNativeSearchBinding();\n\t\t\t\t\t\t\tif (nativeBinding) {\n\t\t\t\t\t\t\t\tconst nativeResult = await nativeBinding.grep({\n\t\t\t\t\t\t\t\t\tpattern,\n\t\t\t\t\t\t\t\t\tpath: searchPath,\n\t\t\t\t\t\t\t\t\tcwd,\n\t\t\t\t\t\t\t\t\tglob,\n\t\t\t\t\t\t\t\t\tignoreCase,\n\t\t\t\t\t\t\t\thidden: hidden ?? true,\n\t\t\t\t\t\t\t\tgitignore: gitignore !== false,\n\t\t\t\t\t\t\t\tcache: cache ?? nativeCache,\n\t\t\t\t\t\t\t\tmaxCount: mode === \"count\" ? undefined : effectiveLimit + 1,\n\t\t\t\t\t\t\t\toffset,\n\t\t\t\t\t\t\t\tcontext: contextBefore === undefined && contextAfter === undefined ? contextValue : undefined,\n\t\t\t\t\t\t\t\tcontextBefore,\n\t\t\t\t\t\t\t\tcontextAfter,\n\t\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\t\tmode,\n\t\t\t\t\t\t\t\tmaxCountPerFile,\n\t\t\t\t\t\t\t\tmaxColumns: GREP_MAX_LINE_LENGTH,\n\t\t\t\t\t\t\t\tmultiline: pattern.includes(\"\\n\") || pattern.includes(\"\\\\n\"),\n\t\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t\ttimeoutMs: timeoutMs ?? 30_000,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tif (nativeResult.error) throw new Error(nativeResult.error);\n\t\t\t\t\t\t\t\tif (nativeResult.matches.length === 0) {\n\t\t\t\t\t\t\t\t\tsettle(() => resolve({ content: [{ type: \"text\", text: mode === \"count\" ? \"0\" : \"No matches found\" }], details: undefined }));\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst visibleMatches = nativeResult.matches.slice(0, effectiveLimit);\n\t\t\t\t\t\t\t\tconst filesOutput = mode === \"filesWithMatches\" && !isDirectory && (offset ?? 0) > 0 ? \"\" : visibleMatches.map((match) => formatPath(match.path)).join(\"\\n\");\n\t\t\t\t\t\t\t\tconst countOutput = String(Math.max(0, nativeResult.totalMatches - (offset ?? 0)));\n\t\t\t\t\t\t\t\tconst rawOutput = mode === \"count\" ? countOutput : mode === \"filesWithMatches\" ? (filesOutput || \"No matches found\") : visibleMatches.flatMap((match) => formatNativeGrepMatch(match, formatPath(match.path))).join(\"\\n\");\n\t\t\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\t\t\tconst details: GrepToolDetails = {};\n\t\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\t\tif (nativeResult.matches.length > effectiveLimit || nativeResult.limitReached) {\n\t\t\t\t\t\t\t\t\tnotices.push(`${effectiveLimit} matches limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`);\n\t\t\t\t\t\t\t\t\tdetails.matchLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (visibleMatches.some((match) => match.truncated)) {\n\t\t\t\t\t\t\t\t\tnotices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`);\n\t\t\t\t\t\t\t\t\tdetails.linesTruncated = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\t\tsettle(() => resolve({ content: [{ type: \"text\", text: output }], details: Object.keys(details).length > 0 ? details : undefined }));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\n\n\t\t\t\t\t\tconst fileCache = new Map<string, string[]>();\n\t\t\t\t\t\tconst getFileLines = async (filePath: string): Promise<string[]> => {\n\t\t\t\t\t\t\tlet lines = fileCache.get(filePath);\n\t\t\t\t\t\t\tif (!lines) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst content = await ops.readFile(filePath);\n\t\t\t\t\t\t\t\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tlines = [];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfileCache.set(filePath, lines);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn lines;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst rgPath = await ensureTool(\"rg\", true);\n\t\t\t\t\t\tif (!rgPath) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"ripgrep (rg) is not available and could not be downloaded\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\"];\n\t\t\t\t\t\tif (hidden !== false) args.push(\"--hidden\");\n\t\t\t\t\t\tif (gitignore === false) args.push(\"--no-ignore\");\n\t\t\t\t\t\tif (ignoreCase) args.push(\"--ignore-case\");\n\t\t\t\t\t\tif (literal) args.push(\"--fixed-strings\");\n\t\t\t\t\t\tif (pattern.includes(\"\\n\") || pattern.includes(\"\\\\n\")) args.push(\"--multiline\");\n\t\t\t\t\t\tif (type) args.push(\"--type\", type);\n\t\t\t\t\t\tif (maxCountPerFile !== undefined) args.push(\"--max-count\", String(maxCountPerFile));\n\t\t\t\t\t\tif (glob) args.push(\"--glob\", glob);\n\t\t\t\t\t\targs.push(\"--\", pattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(rgPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\t\t\t\t\tconst timeoutTimer = timeoutMs !== undefined ? setTimeout(() => stopChild(), timeoutMs) : undefined;\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tlet matchCount = 0;\n\t\t\t\t\t\tlet matchLimitReached = false;\n\t\t\t\t\t\tlet linesTruncated = false;\n\t\t\t\t\t\tlet aborted = false;\n\t\t\t\t\t\tlet killedDueToLimit = false;\n\t\t\t\t\t\tconst outputLines: string[] = [];\n\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\tif (timeoutTimer) clearTimeout(timeoutTimer);\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst stopChild = (dueToLimit = false) => {\n\t\t\t\t\t\t\tif (!child.killed) {\n\t\t\t\t\t\t\t\tkilledDueToLimit = dueToLimit;\n\t\t\t\t\t\t\t\tchild.kill();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\tstopChild();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst formatBlock = async (filePath: string, lineNumber: number): Promise<string[]> => {\n\t\t\t\t\t\t\tconst relativePath = formatPath(filePath);\n\t\t\t\t\t\t\tconst lines = await getFileLines(filePath);\n\t\t\t\t\t\t\tif (!lines.length) return [`${relativePath}:${lineNumber}: (unable to read file)`];\n\t\t\t\t\t\t\tconst block: string[] = [];\n\t\t\t\t\t\t\tconst start = contextBeforeValue > 0 ? Math.max(1, lineNumber - contextBeforeValue) : lineNumber;\n\t\t\t\t\t\t\tconst end = contextAfterValue > 0 ? Math.min(lines.length, lineNumber + contextAfterValue) : lineNumber;\n\t\t\t\t\t\t\tfor (let current = start; current <= end; current++) {\n\t\t\t\t\t\t\t\tconst lineText = lines[current - 1] ?? \"\";\n\t\t\t\t\t\t\t\tconst sanitized = lineText.replace(/\\r/g, \"\");\n\t\t\t\t\t\t\t\tconst isMatchLine = current === lineNumber;\n\t\t\t\t\t\t\t\t// Truncate long lines so grep output stays compact.\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tif (isMatchLine) block.push(`${relativePath}:${current}: ${truncatedText}`);\n\t\t\t\t\t\t\t\telse block.push(`${relativePath}-${current}- ${truncatedText}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect matches during streaming, then format them after rg exits.\n\t\t\t\t\t\tconst matches: Array<{ filePath: string; lineNumber: number; lineText?: string }> = [];\n\t\t\t\t\t\tlet seenMatches = 0, seenFiles = 0; const seenFilePaths = new Set<string>(), filesWithMatches = new Set<string>();\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tif (!line.trim() || (mode !== \"count\" && mode !== \"filesWithMatches\" && matchCount >= effectiveLimit)) return;\n\t\t\t\t\t\t\tlet event: unknown;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevent = JSON.parse(line) as unknown;\n\t\t\t\t\t\t\t} catch { return; }\n\t\t\t\t\t\t\tif (isRipgrepMatchEvent(event)) {\n\t\t\t\t\t\t\t\tconst filePath = event.data?.path?.text;\n\t\t\t\t\t\t\t\tif (mode === \"filesWithMatches\") { if (typeof filePath === \"string\") { const formatted = formatPath(filePath); if (!seenFilePaths.has(formatted)) { seenFilePaths.add(formatted); seenFiles++; if (offset === undefined || seenFiles > offset) filesWithMatches.add(formatted); } } matchCount = filesWithMatches.size; if (matchCount >= effectiveLimit) { matchLimitReached = true; stopChild(true); } return; }\n\t\t\t\t\t\t\t\tseenMatches++;\n\t\t\t\t\t\t\t\tif (mode !== \"count\" && offset !== undefined && seenMatches <= offset) return;\n\t\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t\t\tconst lineNumber = event.data?.line_number;\n\t\t\t\t\t\t\t\tconst lineText = event.data?.lines?.text;\n\t\t\t\t\t\t\t\tif (typeof filePath === \"string\") filesWithMatches.add(formatPath(filePath));\n\t\t\t\t\t\t\t\tif (typeof filePath === \"string\" && typeof lineNumber === \"number\")\n\t\t\t\t\t\t\t\t\tmatches.push({ filePath, lineNumber, lineText: typeof lineText === \"string\" ? lineText : undefined });\n\t\t\t\t\t\t\t\tif (mode !== \"count\" && matchCount >= effectiveLimit) { matchLimitReached = true; stopChild(true); }\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Failed to run ripgrep: ${error.message}`)));\n\t\t\t\t\t\t});\n\t\t\t\t\t\tchild.on(\"close\", async (code) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!killedDueToLimit && code !== 0 && code !== 1) {\n\t\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (matchCount === 0) {\n\t\t\t\t\t\t\t\tsettle(() => resolve({ content: [{ type: \"text\", text: mode === \"count\" ? \"0\" : \"No matches found\" }], details: undefined }));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (mode === \"count\" || mode === \"filesWithMatches\") {\n\t\t\t\t\t\t\t\tsettle(() => resolve({ content: [{ type: \"text\", text: mode === \"count\" ? String(Math.max(0, matchCount - (offset ?? 0))) : ([...filesWithMatches].join(\"\\n\") || \"No matches found\") }], details: matchLimitReached ? { matchLimitReached: effectiveLimit } : undefined }));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Format matches after streaming finishes so custom readFile() backends can be async.\n\t\t\t\t\t\t\tfor (const match of matches) {\n\t\t\t\t\t\t\t\tif (contextBeforeValue === 0 && contextAfterValue === 0 && match.lineText !== undefined) {\n\t\t\t\t\t\t\t\t\tconst relativePath = formatPath(match.filePath);\n\t\t\t\t\t\t\t\t\tconst sanitized = match.lineText\n\t\t\t\t\t\t\t\t\t\t.replace(/\\r\\n/g, \"\\n\")\n\t\t\t\t\t\t\t\t\t\t.replace(/\\r/g, \"\")\n\t\t\t\t\t\t\t\t\t\t.replace(/\\n$/, \"\");\n\t\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\t\toutputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedText}`);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tconst block = await formatBlock(match.filePath, match.lineNumber);\n\t\t\t\t\t\t\t\t\toutputLines.push(...block);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst rawOutput = outputLines.join(\"\\n\");\n\t\t\t\t\t\t\t// Apply byte truncation. There is no line limit here because the match limit already capped rows.\n\t\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\t\tconst details: GrepToolDetails = {};\n\t\t\t\t\t\t\t// Build actionable notices for truncation and match limits.\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (matchLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`${effectiveLimit} matches limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.matchLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (linesTruncated) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.linesTruncated = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: output }],\n\t\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsettle(() => reject(err as Error));\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatGrepCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatGrepResult(result, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n"]}