@bastani/atomic 0.9.2 → 0.9.3-alpha.2

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 (606) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +2 -2
  3. package/dist/builtin/cursor/CHANGELOG.md +15 -0
  4. package/dist/builtin/cursor/README.md +2 -1
  5. package/dist/builtin/cursor/package.json +2 -2
  6. package/dist/builtin/cursor/src/cursor-models-raw.json +2 -9
  7. package/dist/builtin/cursor/src/model-mapper.ts +14 -3
  8. package/dist/builtin/cursor/src/proto/protobuf-codec-base64.ts +22 -0
  9. package/dist/builtin/cursor/src/proto/protobuf-codec-request.ts +53 -13
  10. package/dist/builtin/cursor/src/proto/protobuf-codec-wire.ts +24 -7
  11. package/dist/builtin/cursor/src/proto/protobuf-codec.ts +3 -2
  12. package/dist/builtin/cursor/src/stream.ts +5 -11
  13. package/dist/builtin/cursor/src/transport-types.ts +3 -0
  14. package/dist/builtin/cursor/src/transport.ts +1 -0
  15. package/dist/builtin/intercom/package.json +1 -1
  16. package/dist/builtin/mcp/CHANGELOG.md +6 -0
  17. package/dist/builtin/mcp/direct-tools.ts +4 -2
  18. package/dist/builtin/mcp/package.json +1 -1
  19. package/dist/builtin/mcp/proxy-call.ts +3 -1
  20. package/dist/builtin/mcp/utils.ts +18 -7
  21. package/dist/builtin/subagents/CHANGELOG.md +20 -0
  22. package/dist/builtin/subagents/README.md +6 -6
  23. package/dist/builtin/subagents/agents/code-simplifier.md +7 -6
  24. package/dist/builtin/subagents/agents/codebase-analyzer.md +5 -4
  25. package/dist/builtin/subagents/agents/codebase-locator.md +3 -3
  26. package/dist/builtin/subagents/agents/codebase-online-researcher.md +10 -10
  27. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +4 -4
  28. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +3 -3
  29. package/dist/builtin/subagents/agents/codebase-research-locator.md +4 -4
  30. package/dist/builtin/subagents/agents/debugger.md +5 -5
  31. package/dist/builtin/subagents/agents/worker.md +56 -0
  32. package/dist/builtin/subagents/package.json +1 -1
  33. package/dist/builtin/subagents/skills/subagent/SKILL.md +11 -11
  34. package/dist/builtin/subagents/src/agents/agent-loaders.ts +3 -5
  35. package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +3 -3
  36. package/dist/builtin/subagents/src/extension/fanout-child.ts +1 -0
  37. package/dist/builtin/subagents/src/extension/index.ts +6 -3
  38. package/dist/builtin/subagents/src/extension/schemas.ts +2 -7
  39. package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -3
  40. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -4
  41. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +15 -1
  42. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +35 -1
  43. package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +1 -1
  44. package/dist/builtin/subagents/src/runs/shared/nested-render.ts +2 -2
  45. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -1
  46. package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +4 -2
  47. package/dist/builtin/subagents/src/shared/types-async.ts +1 -0
  48. package/dist/builtin/subagents/src/shared/types-depth.ts +5 -5
  49. package/dist/builtin/subagents/src/shared/types-runtime.ts +2 -1
  50. package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +27 -5
  51. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -2
  52. package/dist/builtin/subagents/src/tui/render-layout.ts +27 -4
  53. package/dist/builtin/subagents/src/tui/render-result-animation.ts +22 -31
  54. package/dist/builtin/subagents/src/tui/render-result-compact.ts +6 -6
  55. package/dist/builtin/subagents/src/tui/render-result.ts +20 -19
  56. package/dist/builtin/subagents/src/tui/render-status-progress.ts +3 -3
  57. package/dist/builtin/subagents/src/tui/render-widget.ts +46 -7
  58. package/dist/builtin/subagents/src/tui/render.ts +2 -2
  59. package/dist/builtin/web-access/package.json +1 -1
  60. package/dist/builtin/workflows/CHANGELOG.md +56 -0
  61. package/dist/builtin/workflows/README.md +3 -3
  62. package/dist/builtin/workflows/builtin/goal-artifacts.ts +11 -6
  63. package/dist/builtin/workflows/builtin/goal-ledger.ts +33 -1
  64. package/dist/builtin/workflows/builtin/goal-prompts.ts +23 -28
  65. package/dist/builtin/workflows/builtin/goal-reducer.ts +2 -2
  66. package/dist/builtin/workflows/builtin/goal-reports.ts +2 -5
  67. package/dist/builtin/workflows/builtin/goal-review.ts +1 -1
  68. package/dist/builtin/workflows/builtin/goal-runner.ts +10 -17
  69. package/dist/builtin/workflows/builtin/open-claude-design-feedback.ts +3 -3
  70. package/dist/builtin/workflows/builtin/open-claude-design-phases.ts +1 -3
  71. package/dist/builtin/workflows/builtin/open-claude-design-setup.ts +1 -1
  72. package/dist/builtin/workflows/builtin/ralph-core.ts +7 -17
  73. package/dist/builtin/workflows/builtin/ralph-runner.ts +11 -18
  74. package/dist/builtin/workflows/builtin/shared-prompts.ts +1 -1
  75. package/dist/builtin/workflows/package.json +1 -1
  76. package/dist/builtin/workflows/src/authoring.d.ts +1 -1
  77. package/dist/builtin/workflows/src/durable/backend.ts +343 -0
  78. package/dist/builtin/workflows/src/durable/child-primitive.ts +79 -0
  79. package/dist/builtin/workflows/src/durable/dbos-backend.ts +421 -0
  80. package/dist/builtin/workflows/src/durable/dbos-envelope.ts +171 -0
  81. package/dist/builtin/workflows/src/durable/factory.ts +96 -0
  82. package/dist/builtin/workflows/src/durable/file-backend.ts +433 -0
  83. package/dist/builtin/workflows/src/durable/index.ts +73 -0
  84. package/dist/builtin/workflows/src/durable/resume-catalog.ts +217 -0
  85. package/dist/builtin/workflows/src/durable/resume-runtime.ts +299 -0
  86. package/dist/builtin/workflows/src/durable/scoped-backend.ts +171 -0
  87. package/dist/builtin/workflows/src/durable/stage-primitive.ts +284 -0
  88. package/dist/builtin/workflows/src/durable/tool-primitive.ts +180 -0
  89. package/dist/builtin/workflows/src/durable/types.ts +168 -0
  90. package/dist/builtin/workflows/src/durable/ui-primitive.ts +96 -0
  91. package/dist/builtin/workflows/src/engine/options.ts +3 -0
  92. package/dist/builtin/workflows/src/engine/primitives/parallel.ts +2 -2
  93. package/dist/builtin/workflows/src/engine/primitives/task.ts +4 -4
  94. package/dist/builtin/workflows/src/engine/primitives/ui.ts +22 -8
  95. package/dist/builtin/workflows/src/engine/primitives/workflow.ts +8 -0
  96. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +69 -0
  97. package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +31 -0
  98. package/dist/builtin/workflows/src/engine/run.ts +148 -6
  99. package/dist/builtin/workflows/src/engine/runtime.ts +8 -2
  100. package/dist/builtin/workflows/src/extension/config-loader.ts +35 -15
  101. package/dist/builtin/workflows/src/extension/discovery.ts +20 -8
  102. package/dist/builtin/workflows/src/extension/extension-factory.ts +6 -12
  103. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +5 -1
  104. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +4 -2
  105. package/dist/builtin/workflows/src/extension/runtime.ts +48 -9
  106. package/dist/builtin/workflows/src/extension/wiring.ts +1 -1
  107. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +143 -4
  108. package/dist/builtin/workflows/src/runs/background/quit.ts +61 -0
  109. package/dist/builtin/workflows/src/runs/background/status.ts +1 -0
  110. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +5 -5
  111. package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +74 -33
  112. package/dist/builtin/workflows/src/runs/foreground/executor-stage-context.ts +20 -1
  113. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +8 -7
  114. package/dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts +1 -0
  115. package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +1 -1
  116. package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +19 -2
  117. package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +4 -0
  118. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +10 -10
  119. package/dist/builtin/workflows/src/runs/foreground/stage-runner-options.ts +5 -1
  120. package/dist/builtin/workflows/src/runs/foreground/stage-runner-send-user-message.ts +25 -0
  121. package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +3 -0
  122. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +16 -0
  123. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +20 -0
  124. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +23 -1
  125. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +30 -1
  126. package/dist/builtin/workflows/src/shared/store-public-types.ts +6 -2
  127. package/dist/builtin/workflows/src/shared/store-run-methods.ts +12 -6
  128. package/dist/builtin/workflows/src/shared/types.ts +55 -0
  129. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +11 -10
  130. package/dist/builtin/workflows/src/tui/graph-view-constants.ts +1 -1
  131. package/dist/builtin/workflows/src/tui/graph-view-graph-render.ts +41 -0
  132. package/dist/builtin/workflows/src/tui/graph-view-input.ts +82 -24
  133. package/dist/builtin/workflows/src/tui/graph-view-render.ts +7 -0
  134. package/dist/builtin/workflows/src/tui/graph-view-state.ts +22 -2
  135. package/dist/builtin/workflows/src/tui/graph-view-types.ts +4 -5
  136. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +9 -11
  137. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +9 -3
  138. package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +11 -2
  139. package/dist/builtin/workflows/src/tui/stage-chat-view-live-events.ts +35 -0
  140. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +51 -17
  141. package/dist/builtin/workflows/src/tui/stage-chat-view-status.ts +36 -0
  142. package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +5 -1
  143. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +3 -1
  144. package/dist/builtin/workflows/src/tui/status-list.ts +14 -2
  145. package/dist/builtin/workflows/src/tui/widget.ts +23 -8
  146. package/dist/builtin/workflows/src/tui/workflow-attach-pane-types.ts +5 -4
  147. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +8 -8
  148. package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +151 -0
  149. package/dist/cli/args.d.ts.map +1 -1
  150. package/dist/cli/args.js +9 -9
  151. package/dist/cli/args.js.map +1 -1
  152. package/dist/config-self-update.d.ts.map +1 -1
  153. package/dist/config-self-update.js +3 -4
  154. package/dist/config-self-update.js.map +1 -1
  155. package/dist/config.d.ts.map +1 -1
  156. package/dist/config.js +4 -5
  157. package/dist/config.js.map +1 -1
  158. package/dist/core/agent-session-bash.d.ts +1 -0
  159. package/dist/core/agent-session-bash.d.ts.map +1 -1
  160. package/dist/core/agent-session-bash.js +1 -0
  161. package/dist/core/agent-session-bash.js.map +1 -1
  162. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  163. package/dist/core/agent-session-tool-registry.js +23 -0
  164. package/dist/core/agent-session-tool-registry.js.map +1 -1
  165. package/dist/core/bash-executor.d.ts +2 -0
  166. package/dist/core/bash-executor.d.ts.map +1 -1
  167. package/dist/core/bash-executor.js +1 -0
  168. package/dist/core/bash-executor.js.map +1 -1
  169. package/dist/core/compaction/compaction.d.ts +29 -0
  170. package/dist/core/compaction/compaction.d.ts.map +1 -1
  171. package/dist/core/compaction/compaction.js +36 -1
  172. package/dist/core/compaction/compaction.js.map +1 -1
  173. package/dist/core/compaction/context-compaction-metrics.d.ts +14 -2
  174. package/dist/core/compaction/context-compaction-metrics.d.ts.map +1 -1
  175. package/dist/core/compaction/context-compaction-metrics.js +50 -1
  176. package/dist/core/compaction/context-compaction-metrics.js.map +1 -1
  177. package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
  178. package/dist/core/compaction/context-compaction-prompt.js +2 -0
  179. package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
  180. package/dist/core/compaction/context-compaction-runner.d.ts.map +1 -1
  181. package/dist/core/compaction/context-compaction-runner.js +1 -1
  182. package/dist/core/compaction/context-compaction-runner.js.map +1 -1
  183. package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
  184. package/dist/core/compaction/context-deletion-application.js +5 -5
  185. package/dist/core/compaction/context-deletion-application.js.map +1 -1
  186. package/dist/core/compaction/context-deletion-targets.d.ts +2 -0
  187. package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
  188. package/dist/core/compaction/context-deletion-targets.js +23 -3
  189. package/dist/core/compaction/context-deletion-targets.js.map +1 -1
  190. package/dist/core/compaction/context-deletion-tool-definitions.d.ts +6 -0
  191. package/dist/core/compaction/context-deletion-tool-definitions.d.ts.map +1 -1
  192. package/dist/core/compaction/context-deletion-tool-definitions.js.map +1 -1
  193. package/dist/core/compaction/context-deletion-tools.d.ts.map +1 -1
  194. package/dist/core/compaction/context-deletion-tools.js +18 -10
  195. package/dist/core/compaction/context-deletion-tools.js.map +1 -1
  196. package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
  197. package/dist/core/compaction/context-transcript-analysis.js +2 -4
  198. package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
  199. package/dist/core/copilot-gemini-tool-arguments.d.ts.map +1 -1
  200. package/dist/core/copilot-gemini-tool-arguments.js +2 -60
  201. package/dist/core/copilot-gemini-tool-arguments.js.map +1 -1
  202. package/dist/core/extensions/context-types.d.ts +2 -0
  203. package/dist/core/extensions/context-types.d.ts.map +1 -1
  204. package/dist/core/extensions/context-types.js.map +1 -1
  205. package/dist/core/extensions/index.d.ts +2 -2
  206. package/dist/core/extensions/index.d.ts.map +1 -1
  207. package/dist/core/extensions/index.js +1 -1
  208. package/dist/core/extensions/index.js.map +1 -1
  209. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  210. package/dist/core/extensions/loader-virtual-modules.js +57 -32
  211. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  212. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  213. package/dist/core/extensions/runner-context.js +11 -0
  214. package/dist/core/extensions/runner-context.js.map +1 -1
  215. package/dist/core/extensions/tool-events.d.ts +13 -13
  216. package/dist/core/extensions/tool-events.d.ts.map +1 -1
  217. package/dist/core/extensions/tool-events.js +3 -3
  218. package/dist/core/extensions/tool-events.js.map +1 -1
  219. package/dist/core/extensions/types.d.ts +1 -1
  220. package/dist/core/extensions/types.d.ts.map +1 -1
  221. package/dist/core/extensions/types.js +1 -1
  222. package/dist/core/extensions/types.js.map +1 -1
  223. package/dist/core/flattened-tool-arguments.d.ts +18 -0
  224. package/dist/core/flattened-tool-arguments.d.ts.map +1 -1
  225. package/dist/core/flattened-tool-arguments.js +104 -0
  226. package/dist/core/flattened-tool-arguments.js.map +1 -1
  227. package/dist/core/messages.d.ts +1 -0
  228. package/dist/core/messages.d.ts.map +1 -1
  229. package/dist/core/messages.js +46 -1
  230. package/dist/core/messages.js.map +1 -1
  231. package/dist/core/sdk-exports.d.ts +1 -1
  232. package/dist/core/sdk-exports.d.ts.map +1 -1
  233. package/dist/core/sdk-exports.js +1 -1
  234. package/dist/core/sdk-exports.js.map +1 -1
  235. package/dist/core/sdk-types.d.ts +2 -2
  236. package/dist/core/sdk-types.d.ts.map +1 -1
  237. package/dist/core/sdk-types.js.map +1 -1
  238. package/dist/core/sdk.d.ts.map +1 -1
  239. package/dist/core/sdk.js +12 -0
  240. package/dist/core/sdk.js.map +1 -1
  241. package/dist/core/session-manager-core.d.ts +15 -7
  242. package/dist/core/session-manager-core.d.ts.map +1 -1
  243. package/dist/core/session-manager-core.js +20 -9
  244. package/dist/core/session-manager-core.js.map +1 -1
  245. package/dist/core/session-manager-entries.d.ts +2 -2
  246. package/dist/core/session-manager-entries.d.ts.map +1 -1
  247. package/dist/core/session-manager-entries.js +9 -3
  248. package/dist/core/session-manager-entries.js.map +1 -1
  249. package/dist/core/session-manager-history.d.ts.map +1 -1
  250. package/dist/core/session-manager-history.js +2 -1
  251. package/dist/core/session-manager-history.js.map +1 -1
  252. package/dist/core/session-manager-list.d.ts +3 -3
  253. package/dist/core/session-manager-list.d.ts.map +1 -1
  254. package/dist/core/session-manager-list.js +27 -8
  255. package/dist/core/session-manager-list.js.map +1 -1
  256. package/dist/core/session-manager-storage.d.ts +3 -1
  257. package/dist/core/session-manager-storage.d.ts.map +1 -1
  258. package/dist/core/session-manager-storage.js +55 -12
  259. package/dist/core/session-manager-storage.js.map +1 -1
  260. package/dist/core/session-manager-tool-dependencies.d.ts +10 -0
  261. package/dist/core/session-manager-tool-dependencies.d.ts.map +1 -0
  262. package/dist/core/session-manager-tool-dependencies.js +133 -0
  263. package/dist/core/session-manager-tool-dependencies.js.map +1 -0
  264. package/dist/core/session-manager-types.d.ts +22 -0
  265. package/dist/core/session-manager-types.d.ts.map +1 -1
  266. package/dist/core/session-manager-types.js.map +1 -1
  267. package/dist/core/session-manager.d.ts +2 -2
  268. package/dist/core/session-manager.d.ts.map +1 -1
  269. package/dist/core/session-manager.js +1 -1
  270. package/dist/core/session-manager.js.map +1 -1
  271. package/dist/core/settings-manager-basic-accessors.d.ts +4 -0
  272. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  273. package/dist/core/settings-manager-basic-accessors.js +18 -0
  274. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  275. package/dist/core/settings-manager-resource-accessors.d.ts +4 -0
  276. package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
  277. package/dist/core/settings-manager-resource-accessors.js +15 -0
  278. package/dist/core/settings-manager-resource-accessors.js.map +1 -1
  279. package/dist/core/settings-types.d.ts +11 -0
  280. package/dist/core/settings-types.d.ts.map +1 -1
  281. package/dist/core/settings-types.js.map +1 -1
  282. package/dist/core/system-prompt.d.ts +1 -1
  283. package/dist/core/system-prompt.d.ts.map +1 -1
  284. package/dist/core/system-prompt.js +3 -2
  285. package/dist/core/system-prompt.js.map +1 -1
  286. package/dist/core/tools/artifact-protocol.d.ts +11 -0
  287. package/dist/core/tools/artifact-protocol.d.ts.map +1 -0
  288. package/dist/core/tools/artifact-protocol.js +76 -0
  289. package/dist/core/tools/artifact-protocol.js.map +1 -0
  290. package/dist/core/tools/artifacts.d.ts +18 -0
  291. package/dist/core/tools/artifacts.d.ts.map +1 -0
  292. package/dist/core/tools/artifacts.js +90 -0
  293. package/dist/core/tools/artifacts.js.map +1 -0
  294. package/dist/core/tools/bash-async-jobs.d.ts +20 -0
  295. package/dist/core/tools/bash-async-jobs.d.ts.map +1 -0
  296. package/dist/core/tools/bash-async-jobs.js +59 -0
  297. package/dist/core/tools/bash-async-jobs.js.map +1 -0
  298. package/dist/core/tools/bash-async-output.d.ts +10 -0
  299. package/dist/core/tools/bash-async-output.d.ts.map +1 -0
  300. package/dist/core/tools/bash-async-output.js +80 -0
  301. package/dist/core/tools/bash-async-output.js.map +1 -0
  302. package/dist/core/tools/bash-interceptor.d.ts +10 -0
  303. package/dist/core/tools/bash-interceptor.d.ts.map +1 -0
  304. package/dist/core/tools/bash-interceptor.js +39 -0
  305. package/dist/core/tools/bash-interceptor.js.map +1 -0
  306. package/dist/core/tools/bash-leading-cd.d.ts +7 -0
  307. package/dist/core/tools/bash-leading-cd.d.ts.map +1 -0
  308. package/dist/core/tools/bash-leading-cd.js +59 -0
  309. package/dist/core/tools/bash-leading-cd.js.map +1 -0
  310. package/dist/core/tools/bash-pty-native.d.ts +14 -0
  311. package/dist/core/tools/bash-pty-native.d.ts.map +1 -0
  312. package/dist/core/tools/bash-pty-native.js +71 -0
  313. package/dist/core/tools/bash-pty-native.js.map +1 -0
  314. package/dist/core/tools/bash.d.ts +28 -17
  315. package/dist/core/tools/bash.d.ts.map +1 -1
  316. package/dist/core/tools/bash.js +152 -35
  317. package/dist/core/tools/bash.js.map +1 -1
  318. package/dist/core/tools/block-resolver.d.ts +16 -0
  319. package/dist/core/tools/block-resolver.d.ts.map +1 -0
  320. package/dist/core/tools/block-resolver.js +74 -0
  321. package/dist/core/tools/block-resolver.js.map +1 -0
  322. package/dist/core/tools/conflict-registry.d.ts +16 -0
  323. package/dist/core/tools/conflict-registry.d.ts.map +1 -0
  324. package/dist/core/tools/conflict-registry.js +44 -0
  325. package/dist/core/tools/conflict-registry.js.map +1 -0
  326. package/dist/core/tools/directory-tree.d.ts +13 -0
  327. package/dist/core/tools/directory-tree.d.ts.map +1 -0
  328. package/dist/core/tools/directory-tree.js +81 -0
  329. package/dist/core/tools/directory-tree.js.map +1 -0
  330. package/dist/core/tools/edit.d.ts +4 -29
  331. package/dist/core/tools/edit.d.ts.map +1 -1
  332. package/dist/core/tools/edit.js +136 -228
  333. package/dist/core/tools/edit.js.map +1 -1
  334. package/dist/core/tools/fetch-url.d.ts +74 -0
  335. package/dist/core/tools/fetch-url.d.ts.map +1 -0
  336. package/dist/core/tools/fetch-url.js +518 -0
  337. package/dist/core/tools/fetch-url.js.map +1 -0
  338. package/dist/core/tools/find.d.ts +27 -9
  339. package/dist/core/tools/find.d.ts.map +1 -1
  340. package/dist/core/tools/find.js +400 -176
  341. package/dist/core/tools/find.js.map +1 -1
  342. package/dist/core/tools/glob-path-utils.d.ts +8 -0
  343. package/dist/core/tools/glob-path-utils.d.ts.map +1 -0
  344. package/dist/core/tools/glob-path-utils.js +26 -0
  345. package/dist/core/tools/glob-path-utils.js.map +1 -0
  346. package/dist/core/tools/grep.d.ts +12 -0
  347. package/dist/core/tools/grep.d.ts.map +1 -1
  348. package/dist/core/tools/grep.js +141 -17
  349. package/dist/core/tools/grep.js.map +1 -1
  350. package/dist/core/tools/hashline-engine/apply.d.ts +11 -0
  351. package/dist/core/tools/hashline-engine/apply.d.ts.map +1 -0
  352. package/dist/core/tools/hashline-engine/apply.js +752 -0
  353. package/dist/core/tools/hashline-engine/apply.js.map +1 -0
  354. package/dist/core/tools/hashline-engine/block.d.ts +40 -0
  355. package/dist/core/tools/hashline-engine/block.d.ts.map +1 -0
  356. package/dist/core/tools/hashline-engine/block.js +117 -0
  357. package/dist/core/tools/hashline-engine/block.js.map +1 -0
  358. package/dist/core/tools/hashline-engine/diff-preview.d.ts +15 -0
  359. package/dist/core/tools/hashline-engine/diff-preview.d.ts.map +1 -0
  360. package/dist/core/tools/hashline-engine/diff-preview.js +98 -0
  361. package/dist/core/tools/hashline-engine/diff-preview.js.map +1 -0
  362. package/dist/core/tools/hashline-engine/format.d.ts +71 -0
  363. package/dist/core/tools/hashline-engine/format.d.ts.map +1 -0
  364. package/dist/core/tools/hashline-engine/format.js +178 -0
  365. package/dist/core/tools/hashline-engine/format.js.map +1 -0
  366. package/dist/core/tools/hashline-engine/fs.d.ts +81 -0
  367. package/dist/core/tools/hashline-engine/fs.d.ts.map +1 -0
  368. package/dist/core/tools/hashline-engine/fs.js +143 -0
  369. package/dist/core/tools/hashline-engine/fs.js.map +1 -0
  370. package/dist/core/tools/hashline-engine/index.d.ts +18 -0
  371. package/dist/core/tools/hashline-engine/index.d.ts.map +1 -0
  372. package/dist/core/tools/hashline-engine/index.js +20 -0
  373. package/dist/core/tools/hashline-engine/index.js.map +1 -0
  374. package/dist/core/tools/hashline-engine/input.d.ts +101 -0
  375. package/dist/core/tools/hashline-engine/input.d.ts.map +1 -0
  376. package/dist/core/tools/hashline-engine/input.js +398 -0
  377. package/dist/core/tools/hashline-engine/input.js.map +1 -0
  378. package/dist/core/tools/hashline-engine/messages.d.ts +99 -0
  379. package/dist/core/tools/hashline-engine/messages.d.ts.map +1 -0
  380. package/dist/core/tools/hashline-engine/messages.js +144 -0
  381. package/dist/core/tools/hashline-engine/messages.js.map +1 -0
  382. package/dist/core/tools/hashline-engine/mismatch.d.ts +45 -0
  383. package/dist/core/tools/hashline-engine/mismatch.d.ts.map +1 -0
  384. package/dist/core/tools/hashline-engine/mismatch.js +90 -0
  385. package/dist/core/tools/hashline-engine/mismatch.js.map +1 -0
  386. package/dist/core/tools/hashline-engine/normalize.d.ts +21 -0
  387. package/dist/core/tools/hashline-engine/normalize.d.ts.map +1 -0
  388. package/dist/core/tools/hashline-engine/normalize.js +33 -0
  389. package/dist/core/tools/hashline-engine/normalize.js.map +1 -0
  390. package/dist/core/tools/hashline-engine/parser.d.ts +24 -0
  391. package/dist/core/tools/hashline-engine/parser.d.ts.map +1 -0
  392. package/dist/core/tools/hashline-engine/parser.js +381 -0
  393. package/dist/core/tools/hashline-engine/parser.js.map +1 -0
  394. package/dist/core/tools/hashline-engine/patcher.d.ts +118 -0
  395. package/dist/core/tools/hashline-engine/patcher.d.ts.map +1 -0
  396. package/dist/core/tools/hashline-engine/patcher.js +341 -0
  397. package/dist/core/tools/hashline-engine/patcher.js.map +1 -0
  398. package/dist/core/tools/hashline-engine/prefixes.d.ts +43 -0
  399. package/dist/core/tools/hashline-engine/prefixes.d.ts.map +1 -0
  400. package/dist/core/tools/hashline-engine/prefixes.js +135 -0
  401. package/dist/core/tools/hashline-engine/prefixes.js.map +1 -0
  402. package/dist/core/tools/hashline-engine/recovery.d.ts +41 -0
  403. package/dist/core/tools/hashline-engine/recovery.d.ts.map +1 -0
  404. package/dist/core/tools/hashline-engine/recovery.js +168 -0
  405. package/dist/core/tools/hashline-engine/recovery.js.map +1 -0
  406. package/dist/core/tools/hashline-engine/snapshots.d.ts +65 -0
  407. package/dist/core/tools/hashline-engine/snapshots.d.ts.map +1 -0
  408. package/dist/core/tools/hashline-engine/snapshots.js +108 -0
  409. package/dist/core/tools/hashline-engine/snapshots.js.map +1 -0
  410. package/dist/core/tools/hashline-engine/stream.d.ts +3 -0
  411. package/dist/core/tools/hashline-engine/stream.d.ts.map +1 -0
  412. package/dist/core/tools/hashline-engine/stream.js +111 -0
  413. package/dist/core/tools/hashline-engine/stream.js.map +1 -0
  414. package/dist/core/tools/hashline-engine/tokenizer.d.ts +69 -0
  415. package/dist/core/tools/hashline-engine/tokenizer.d.ts.map +1 -0
  416. package/dist/core/tools/hashline-engine/tokenizer.js +430 -0
  417. package/dist/core/tools/hashline-engine/tokenizer.js.map +1 -0
  418. package/dist/core/tools/hashline-engine/types.d.ts +166 -0
  419. package/dist/core/tools/hashline-engine/types.d.ts.map +1 -0
  420. package/dist/core/tools/hashline-engine/types.js +9 -0
  421. package/dist/core/tools/hashline-engine/types.js.map +1 -0
  422. package/dist/core/tools/hashline.d.ts +29 -0
  423. package/dist/core/tools/hashline.d.ts.map +1 -0
  424. package/dist/core/tools/hashline.js +110 -0
  425. package/dist/core/tools/hashline.js.map +1 -0
  426. package/dist/core/tools/index.d.ts +6 -4
  427. package/dist/core/tools/index.d.ts.map +1 -1
  428. package/dist/core/tools/index.js +52 -35
  429. package/dist/core/tools/index.js.map +1 -1
  430. package/dist/core/tools/notebook.d.ts +38 -0
  431. package/dist/core/tools/notebook.d.ts.map +1 -0
  432. package/dist/core/tools/notebook.js +125 -0
  433. package/dist/core/tools/notebook.js.map +1 -0
  434. package/dist/core/tools/read-document-extract.d.ts +9 -0
  435. package/dist/core/tools/read-document-extract.d.ts.map +1 -0
  436. package/dist/core/tools/read-document-extract.js +212 -0
  437. package/dist/core/tools/read-document-extract.js.map +1 -0
  438. package/dist/core/tools/read-selectors.d.ts +24 -0
  439. package/dist/core/tools/read-selectors.d.ts.map +1 -0
  440. package/dist/core/tools/read-selectors.js +277 -0
  441. package/dist/core/tools/read-selectors.js.map +1 -0
  442. package/dist/core/tools/read-url.d.ts +37 -0
  443. package/dist/core/tools/read-url.d.ts.map +1 -0
  444. package/dist/core/tools/read-url.js +39 -0
  445. package/dist/core/tools/read-url.js.map +1 -0
  446. package/dist/core/tools/read.d.ts +11 -11
  447. package/dist/core/tools/read.d.ts.map +1 -1
  448. package/dist/core/tools/read.js +224 -94
  449. package/dist/core/tools/read.js.map +1 -1
  450. package/dist/core/tools/resource-selectors.d.ts +44 -0
  451. package/dist/core/tools/resource-selectors.d.ts.map +1 -0
  452. package/dist/core/tools/resource-selectors.js +808 -0
  453. package/dist/core/tools/resource-selectors.js.map +1 -0
  454. package/dist/core/tools/search-details.d.ts +26 -0
  455. package/dist/core/tools/search-details.d.ts.map +1 -0
  456. package/dist/core/tools/search-details.js +24 -0
  457. package/dist/core/tools/search-details.js.map +1 -0
  458. package/dist/core/tools/search-line-ranges.d.ts +11 -0
  459. package/dist/core/tools/search-line-ranges.d.ts.map +1 -0
  460. package/dist/core/tools/search-line-ranges.js +65 -0
  461. package/dist/core/tools/search-line-ranges.js.map +1 -0
  462. package/dist/core/tools/search-native.d.ts +97 -0
  463. package/dist/core/tools/search-native.d.ts.map +1 -0
  464. package/dist/core/tools/search-native.js +27 -0
  465. package/dist/core/tools/search-native.js.map +1 -0
  466. package/dist/core/tools/search.d.ts +24 -0
  467. package/dist/core/tools/search.d.ts.map +1 -0
  468. package/dist/core/tools/search.js +573 -0
  469. package/dist/core/tools/search.js.map +1 -0
  470. package/dist/core/tools/truncate.d.ts +4 -4
  471. package/dist/core/tools/truncate.d.ts.map +1 -1
  472. package/dist/core/tools/truncate.js +3 -3
  473. package/dist/core/tools/truncate.js.map +1 -1
  474. package/dist/core/tools/url-ip-guards.d.ts +4 -0
  475. package/dist/core/tools/url-ip-guards.d.ts.map +1 -0
  476. package/dist/core/tools/url-ip-guards.js +126 -0
  477. package/dist/core/tools/url-ip-guards.js.map +1 -0
  478. package/dist/core/tools/write.d.ts +12 -2
  479. package/dist/core/tools/write.d.ts.map +1 -1
  480. package/dist/core/tools/write.js +166 -14
  481. package/dist/core/tools/write.js.map +1 -1
  482. package/dist/core/trust-manager.d.ts.map +1 -1
  483. package/dist/core/trust-manager.js +2 -3
  484. package/dist/core/trust-manager.js.map +1 -1
  485. package/dist/index-extensions.d.ts +2 -2
  486. package/dist/index-extensions.d.ts.map +1 -1
  487. package/dist/index-extensions.js +1 -1
  488. package/dist/index-extensions.js.map +1 -1
  489. package/dist/index.d.ts +3 -3
  490. package/dist/index.d.ts.map +1 -1
  491. package/dist/index.js +3 -3
  492. package/dist/index.js.map +1 -1
  493. package/dist/modes/interactive/components/chat-session-host-runtime.d.ts +1 -0
  494. package/dist/modes/interactive/components/chat-session-host-runtime.d.ts.map +1 -1
  495. package/dist/modes/interactive/components/chat-session-host-runtime.js +12 -0
  496. package/dist/modes/interactive/components/chat-session-host-runtime.js.map +1 -1
  497. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.d.ts +4 -0
  498. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.d.ts.map +1 -0
  499. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.js +131 -0
  500. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.js.map +1 -0
  501. package/dist/modes/interactive/components/chat-session-host.d.ts +2 -0
  502. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  503. package/dist/modes/interactive/components/chat-session-host.js +7 -1
  504. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  505. package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -1
  506. package/dist/modes/interactive/components/chat-transcript.js +15 -4
  507. package/dist/modes/interactive/components/chat-transcript.js.map +1 -1
  508. package/dist/modes/interactive/components/custom-editor.d.ts +1 -0
  509. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  510. package/dist/modes/interactive/components/custom-editor.js +9 -2
  511. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  512. package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
  513. package/dist/modes/interactive/components/settings-selector-handlers.js +3 -0
  514. package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
  515. package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
  516. package/dist/modes/interactive/components/settings-selector-items.js +7 -0
  517. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  518. package/dist/modes/interactive/components/settings-selector-types.d.ts +2 -0
  519. package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
  520. package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
  521. package/dist/modes/interactive/components/tool-execution.d.ts +3 -0
  522. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  523. package/dist/modes/interactive/components/tool-execution.js +26 -0
  524. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  525. package/dist/modes/interactive/components/tree-selector-content.d.ts.map +1 -1
  526. package/dist/modes/interactive/components/tree-selector-content.js +0 -5
  527. package/dist/modes/interactive/components/tree-selector-content.js.map +1 -1
  528. package/dist/modes/interactive/interactive-auth-login.d.ts.map +1 -1
  529. package/dist/modes/interactive/interactive-auth-login.js +1 -0
  530. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  531. package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  532. package/dist/modes/interactive/interactive-autocomplete.js +80 -2
  533. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  534. package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
  535. package/dist/modes/interactive/interactive-hotkeys-debug.js +3 -0
  536. package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
  537. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  538. package/dist/modes/interactive/interactive-input-handling.js +51 -0
  539. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  540. package/dist/modes/interactive/interactive-mode-base.d.ts +5 -0
  541. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  542. package/dist/modes/interactive/interactive-mode-base.js +5 -0
  543. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  544. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  545. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  546. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  547. package/dist/modes/interactive/interactive-mode-surface.d.ts +12 -0
  548. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  549. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  550. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  551. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  552. package/dist/modes/interactive/interactive-mode.js +1 -0
  553. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  554. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  555. package/dist/modes/interactive/interactive-model-routing.js +4 -1
  556. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  557. package/dist/modes/interactive/interactive-onboarding.d.ts +11 -0
  558. package/dist/modes/interactive/interactive-onboarding.d.ts.map +1 -0
  559. package/dist/modes/interactive/interactive-onboarding.js +220 -0
  560. package/dist/modes/interactive/interactive-onboarding.js.map +1 -0
  561. package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
  562. package/dist/modes/interactive/interactive-selectors.js +4 -0
  563. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  564. package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
  565. package/dist/modes/interactive/interactive-session-routing.js +6 -0
  566. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  567. package/dist/modes/interactive/interactive-slash-commands.d.ts.map +1 -1
  568. package/dist/modes/interactive/interactive-slash-commands.js +9 -4
  569. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  570. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  571. package/dist/modes/interactive/interactive-startup.js +28 -0
  572. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  573. package/dist/utils/child-process.d.ts.map +1 -1
  574. package/dist/utils/child-process.js +21 -1
  575. package/dist/utils/child-process.js.map +1 -1
  576. package/dist/utils/markit.d.ts +8 -0
  577. package/dist/utils/markit.d.ts.map +1 -0
  578. package/dist/utils/markit.js +53 -0
  579. package/dist/utils/markit.js.map +1 -0
  580. package/dist/utils/paths.d.ts +2 -1
  581. package/dist/utils/paths.d.ts.map +1 -1
  582. package/dist/utils/paths.js +14 -1
  583. package/dist/utils/paths.js.map +1 -1
  584. package/docs/compaction.md +18 -1
  585. package/docs/containerization.md +1 -1
  586. package/docs/docs.json +1 -0
  587. package/docs/extensions.md +25 -36
  588. package/docs/models.md +1 -1
  589. package/docs/providers.md +2 -1
  590. package/docs/quickstart.md +11 -6
  591. package/docs/sdk.md +5 -5
  592. package/docs/session-format.md +6 -0
  593. package/docs/sessions.md +6 -0
  594. package/docs/settings.md +7 -0
  595. package/docs/subagents.md +3 -2
  596. package/docs/tools.md +49 -0
  597. package/docs/usage.md +3 -3
  598. package/docs/workflows.md +112 -8
  599. package/examples/extensions/subagent/README.md +5 -5
  600. package/examples/extensions/subagent/agents/planner.md +1 -1
  601. package/examples/extensions/subagent/agents/reviewer.md +1 -1
  602. package/examples/extensions/subagent/agents/scout.md +2 -2
  603. package/examples/extensions/subagent/display.ts +3 -3
  604. package/examples/sdk/05-tools.ts +3 -3
  605. package/examples/sdk/README.md +1 -1
  606. package/package.json +5 -3
@@ -1,3 +1,5 @@
1
+ import { statSync } from "node:fs";
2
+ import { stat as fsStat } from "node:fs/promises";
1
3
  import { createInterface } from "node:readline";
2
4
  import { Text } from "@earendil-works/pi-tui";
3
5
  import { spawn } from "child_process";
@@ -5,39 +7,181 @@ import path from "path";
5
7
  import { Type } from "typebox";
6
8
  import { keyHint } from "../../modes/interactive/components/keybinding-hints.js";
7
9
  import { ensureTool } from "../../utils/tools-manager.js";
10
+ import { normalizePathLikeInput, splitPathLikeGlob } from "./glob-path-utils.js";
11
+ import { loadNativeSearchBinding } from "./search-native.js";
8
12
  import { pathExists, resolveToCwd } from "./path-utils.js";
9
- import { getTextOutput, invalidArgText, shortenPath, str } from "./render-utils.js";
13
+ import { resolveInternalSelector } from "./resource-selectors.js";
14
+ import { getTextOutput } from "./render-utils.js";
10
15
  import { wrapToolDefinition } from "./tool-definition-wrapper.js";
11
16
  import { DEFAULT_MAX_BYTES, formatSize, truncateHead } from "./truncate.js";
12
- function toPosixPath(value) {
13
- return value.split(path.sep).join("/");
14
- }
17
+ const toPosixPath = (value) => value.split(path.sep).join("/");
15
18
  const findSchema = Type.Object({
16
- pattern: Type.String({
17
- description: "Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'",
18
- }),
19
- path: Type.Optional(Type.String({ description: "Directory to search in (default: current directory)" })),
20
- limit: Type.Optional(Type.Number({ description: "Maximum number of results (default: 1000)" })),
21
- });
22
- const DEFAULT_LIMIT = 1000;
19
+ paths: Type.Array(Type.String({ description: "File, directory, or glob path to find." }), { description: "Paths or glob paths to find.", minItems: 1 }),
20
+ hidden: Type.Optional(Type.Boolean({ description: "Include hidden files. Defaults to true." })),
21
+ gitignore: Type.Optional(Type.Boolean({ description: "Respect gitignore. Defaults to true." })),
22
+ limit: Type.Optional(Type.Number({ description: "Maximum number of results, clamped to 1-200.", minimum: 1, maximum: 200 })),
23
+ timeout: Type.Optional(Type.Number({ description: "Timeout in seconds; default 5, clamped to 0.5..60.", minimum: 0.5, maximum: 60 })),
24
+ }, { additionalProperties: false });
25
+ const DEFAULT_LIMIT = 200;
26
+ const MAX_LIMIT = 200;
27
+ const DEFAULT_TIMEOUT_MS = 5000;
28
+ const MIN_TIMEOUT_MS = 500;
29
+ const MAX_TIMEOUT_MS = 60_000;
30
+ function normalizeLimit(limit) { return limit === undefined || !Number.isFinite(limit) ? DEFAULT_LIMIT : Math.max(1, Math.min(MAX_LIMIT, Math.floor(limit))); }
31
+ function normalizeTimeoutMs(timeout) { return timeout === undefined || !Number.isFinite(timeout) ? DEFAULT_TIMEOUT_MS : Math.max(MIN_TIMEOUT_MS, Math.min(MAX_TIMEOUT_MS, Math.floor(timeout * 1000))); }
32
+ function formatTimeoutSeconds(timeoutMs) { const seconds = timeoutMs / 1000; return Number.isInteger(seconds) ? String(seconds) : seconds.toFixed(1); }
33
+ async function resolveFindInternal(input, cwd, ctx) { const parsed = splitPathLikeGlob(input); if (!/^[a-z]+:\/\//i.test(parsed.basePath))
34
+ return input; for (const resolve of [ctx?.internalRouter?.resolve, ctx?.internalResourceRouter?.resolve, ctx?.resolveInternalUrl]) {
35
+ const resolved = await resolve?.(parsed.basePath);
36
+ if (typeof resolved === "string")
37
+ return parsed.glob ? `${resolved}/${parsed.glob}` : resolved;
38
+ } const fallback = resolveInternalSelector(parsed.basePath, cwd); return fallback ? parsed.glob ? `${fallback}/${parsed.glob}` : fallback : input; }
39
+ function isWindowsAbsolutePath(value) { return /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\"); }
40
+ function resolveFindBackendPath(input, cwd, customBackend) { if (!customBackend)
41
+ return resolveToCwd(input, cwd); if (input === "." || input === "")
42
+ return cwd; if (input.startsWith("/") || isWindowsAbsolutePath(input))
43
+ return input; if (cwd.includes("\\") || isWindowsAbsolutePath(cwd))
44
+ return path.resolve(cwd, input); return `${cwd.replace(/\/+$/, "")}/${input}`; }
45
+ async function delimiterInExistingGlobRoot(value, cwd, ops, customBackend) { const parsed = splitPathLikeGlob(value); return !!parsed.glob && /[;,\s]/.test(parsed.basePath) && await ops.exists(resolveFindBackendPath(parsed.basePath, cwd, customBackend)); }
46
+ async function expandDelimitedFindPaths(pathsValue, cwd, ops, ctx, customBackend = false) {
47
+ if (!pathsValue?.length)
48
+ throw new Error("find.paths must include at least one path or glob.");
49
+ const expanded = [];
50
+ for (const input of pathsValue) {
51
+ const raw = normalizePathLikeInput(input);
52
+ if (raw === "")
53
+ throw new Error("find.paths entries must not be empty.");
54
+ const resolvedRaw = await resolveFindInternal(raw, cwd, ctx);
55
+ const rawParsed = splitPathLikeGlob(resolvedRaw);
56
+ if ((rawParsed.glob === undefined && await ops.exists(resolveFindBackendPath(rawParsed.basePath, cwd, customBackend))) || await delimiterInExistingGlobRoot(resolvedRaw, cwd, ops, customBackend)) {
57
+ expanded.push(resolvedRaw);
58
+ continue;
59
+ }
60
+ const parts = await Promise.all(raw.split(/[;,\s]+/).map(normalizePathLikeInput).filter(Boolean).map((part) => resolveFindInternal(part, cwd, ctx)));
61
+ const 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);
62
+ if (parts.length > 1 && delimiterCanSplit)
63
+ expanded.push(...parts);
64
+ else
65
+ expanded.push(resolvedRaw);
66
+ }
67
+ return expanded;
68
+ }
69
+ function normalizeFindTargets(cwd, pathsValue, customBackend = false) {
70
+ if (!pathsValue || pathsValue.length === 0)
71
+ throw new Error("find.paths must include at least one path or glob.");
72
+ return pathsValue.map((searchPath) => {
73
+ const parsed = splitPathLikeGlob(searchPath);
74
+ const target = { searchPath: resolveFindBackendPath(parsed.basePath, cwd, customBackend), pattern: parsed.glob ?? "**/*", exactPathInput: parsed.glob === undefined, inputPath: searchPath };
75
+ if (path.parse(target.searchPath).root === target.searchPath)
76
+ throw new Error("Refusing to search filesystem root with find; provide a narrower path.");
77
+ return target;
78
+ });
79
+ }
80
+ function relativizeFoundPath(foundPath, searchPath) {
81
+ const hadTrailingSlash = foundPath.endsWith("/") || foundPath.endsWith("\\");
82
+ const relativePath = path.relative(searchPath, foundPath) || path.basename(foundPath);
83
+ const outputPath = hadTrailingSlash && !relativePath.endsWith("/") ? `${relativePath}/` : relativePath;
84
+ return toPosixPath(outputPath);
85
+ }
86
+ function formatExactFoundPath(foundPath, cwd) { return toPosixPath(path.relative(cwd, foundPath) || path.basename(foundPath)); }
87
+ function containsHiddenSegment(value) { return toPosixPath(value).split("/").some((part) => part.startsWith(".") && part.length > 1); }
88
+ function findTargetMentionsNodeModules(target) { return target.pattern.includes("node_modules") || toPosixPath(target.searchPath).split("/").includes("node_modules"); }
89
+ function formatFoundPath(foundPath, searchPath, searchPaths, cwd) {
90
+ let absoluteFoundPath = path.isAbsolute(foundPath) ? foundPath : path.resolve(searchPath, foundPath);
91
+ if (foundPath.endsWith("/") && !absoluteFoundPath.endsWith("/"))
92
+ absoluteFoundPath += "/";
93
+ const relative = relativizeFoundPath(absoluteFoundPath, searchPath);
94
+ if (searchPaths.length <= 1)
95
+ return relative;
96
+ const rootLabel = toPosixPath(path.relative(cwd, searchPath) || path.basename(searchPath) || ".");
97
+ return `${rootLabel}/${relative}`;
98
+ }
99
+ function createFindTreeNode() { return { files: new Set(), dirs: new Map() }; }
100
+ function formatFindTree(relativized) {
101
+ const root = createFindTreeNode();
102
+ for (const item of relativized) {
103
+ const isDir = item.endsWith("/");
104
+ const parts = item.replace(/\/+$/g, "").split("/").filter(Boolean);
105
+ if (parts.length === 0)
106
+ continue;
107
+ let node = root;
108
+ const dirParts = isDir ? parts : parts.slice(0, -1);
109
+ for (const dir of dirParts) {
110
+ let child = node.dirs.get(dir);
111
+ if (!child) {
112
+ child = createFindTreeNode();
113
+ node.dirs.set(dir, child);
114
+ }
115
+ node = child;
116
+ }
117
+ if (!isDir)
118
+ node.files.add(parts[parts.length - 1]);
119
+ }
120
+ const lines = [];
121
+ const collapse = (dir, node) => {
122
+ const parts = [dir];
123
+ let current = node;
124
+ while (current.files.size === 0 && current.dirs.size === 1) {
125
+ const [[nextDir, nextNode]] = [...current.dirs.entries()];
126
+ parts.push(nextDir);
127
+ current = nextNode;
128
+ }
129
+ return { label: parts.join("/"), node: current };
130
+ };
131
+ const render = (node, depth) => {
132
+ for (const file of [...node.files].sort())
133
+ lines.push(file);
134
+ for (const [dir, child] of [...node.dirs.entries()].sort(([a], [b]) => a.localeCompare(b))) {
135
+ const folded = collapse(dir, child);
136
+ lines.push(`${"#".repeat(depth + 1)} ${folded.label}/`);
137
+ render(folded.node, depth + 1);
138
+ }
139
+ };
140
+ render(root, 0);
141
+ return lines.join("\n");
142
+ }
143
+ function buildFindResult(relativized, effectiveLimit, timedOut, timeoutMs, skippedMissingPaths = [], resultLimitReached = false) {
144
+ const rawOutput = relativized.length > 0 ? formatFindTree(relativized) : "No files found matching pattern";
145
+ const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
146
+ let resultOutput = truncation.content;
147
+ const details = { scopePath: ".", fileCount: relativized.length, files: relativized, meta: { limits: { resultLimit: effectiveLimit } } };
148
+ const notices = [];
149
+ if (resultLimitReached) {
150
+ notices.push(`${effectiveLimit} results limit reached. Refine pattern or path to narrow results`);
151
+ details.resultLimitReached = effectiveLimit;
152
+ }
153
+ if (timedOut) {
154
+ notices.push(`find timed out after ${formatTimeoutSeconds(timeoutMs)}s; returning ${relativized.length} partial matches — increase timeout or narrow pattern`);
155
+ details.timedOut = true;
156
+ details.truncated = true;
157
+ }
158
+ if (skippedMissingPaths.length > 0) {
159
+ notices.push(`Skipped missing paths: ${skippedMissingPaths.join(", ")}`);
160
+ details.skippedMissingPaths = skippedMissingPaths;
161
+ details.missingPaths = skippedMissingPaths;
162
+ }
163
+ if (truncation.truncated) {
164
+ notices.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit reached`);
165
+ details.truncation = truncation;
166
+ details.meta = { ...(details.meta ?? {}), truncation };
167
+ details.truncated = true;
168
+ }
169
+ if (notices.length > 0) {
170
+ resultOutput += `\n\n[${notices.join(". ")}]`;
171
+ }
172
+ return { content: [{ type: "text", text: resultOutput }], details };
173
+ }
23
174
  const defaultFindOperations = {
24
175
  exists: pathExists,
25
- // This is a placeholder. Actual fd execution happens in execute() when no custom glob is provided.
26
176
  glob: () => [],
27
177
  };
178
+ function stripTrailingForwardSlashes(value) { let end = value.length; while (end > 0 && value[end - 1] === "/")
179
+ end--; return value.slice(0, end); }
28
180
  function formatFindCall(args, theme) {
29
- const pattern = str(args?.pattern);
30
- const rawPath = str(args?.path);
31
- const path = rawPath !== null ? shortenPath(rawPath || ".") : null;
32
- const limit = args?.limit;
33
- const invalidArg = invalidArgText(theme);
34
- let text = theme.fg("toolTitle", theme.bold("find")) +
35
- " " +
36
- (pattern === null ? invalidArg : theme.fg("accent", pattern || "")) +
37
- theme.fg("toolOutput", ` in ${path === null ? invalidArg : path}`);
38
- if (limit !== undefined) {
39
- text += theme.fg("toolOutput", ` (limit ${limit})`);
40
- }
181
+ const paths = Array.isArray(args?.paths) ? args.paths.map((item) => splitPathLikeGlob(item).glob ? item : `${stripTrailingForwardSlashes(item)}/**/*`).join(", ") : "<paths>";
182
+ let text = `${theme.fg("toolTitle", theme.bold("find"))} ${theme.fg("accent", paths)}`;
183
+ if (args?.limit !== undefined)
184
+ text += theme.fg("toolOutput", ` (limit ${args.limit})`);
41
185
  return text;
42
186
  }
43
187
  function formatFindResult(result, options, theme, showImages) {
@@ -55,10 +199,13 @@ function formatFindResult(result, options, theme, showImages) {
55
199
  }
56
200
  const resultLimit = result.details?.resultLimitReached;
57
201
  const truncation = result.details?.truncation;
58
- if (resultLimit || truncation?.truncated) {
202
+ const timedOut = result.details?.timedOut;
203
+ if (resultLimit || truncation?.truncated || timedOut) {
59
204
  const warnings = [];
60
205
  if (resultLimit)
61
206
  warnings.push(`${resultLimit} results limit`);
207
+ if (timedOut)
208
+ warnings.push("timeout");
62
209
  if (truncation?.truncated)
63
210
  warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
64
211
  text += `\n${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
@@ -70,10 +217,10 @@ export function createFindToolDefinition(cwd, options) {
70
217
  return {
71
218
  name: "find",
72
219
  label: "find",
73
- description: `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).`,
74
- promptSnippet: "Find files by glob pattern (respects .gitignore)",
220
+ description: "Find filesystem paths by glob; use search when you need content matches instead of path matches.",
221
+ promptSnippet: "Find filesystem paths by glob.",
75
222
  parameters: findSchema,
76
- async execute(_toolCallId, { pattern, path: searchDir, limit }, signal, _onUpdate, _ctx) {
223
+ async execute(_toolCallId, params, signal, _onUpdate, _ctx) {
77
224
  return new Promise((resolve, reject) => {
78
225
  if (signal?.aborted) {
79
226
  reject(new Error("Operation aborted"));
@@ -94,66 +241,158 @@ export function createFindToolDefinition(cwd, options) {
94
241
  settle(() => reject(new Error("Operation aborted")));
95
242
  };
96
243
  signal?.addEventListener("abort", onAbort, { once: true });
244
+ const { limit, hidden, gitignore, timeout } = params;
245
+ const paths = params.paths;
246
+ const resourceCtx = _ctx;
97
247
  (async () => {
98
248
  try {
99
- const searchPath = resolveToCwd(searchDir || ".", cwd);
100
- const effectiveLimit = limit ?? DEFAULT_LIMIT;
101
249
  const ops = customOps ?? defaultFindOperations;
102
- // If custom operations provide glob(), use that instead of fd.
103
- if (customOps?.glob) {
104
- if (!(await ops.exists(searchPath))) {
105
- settle(() => reject(new Error(`Path not found: ${searchPath}`)));
106
- return;
250
+ const targets = normalizeFindTargets(cwd, await expandDelimitedFindPaths(paths, cwd, ops, resourceCtx, !!customOps), !!customOps);
251
+ const searchPaths = targets.map((target) => target.searchPath);
252
+ const effectiveLimit = normalizeLimit(limit);
253
+ const timeoutMs = normalizeTimeoutMs(timeout);
254
+ const emitUpdate = (files) => _onUpdate?.({ content: [{ type: "text", text: files.join("\n") || "No files found matching pattern" }], details: { scopePath: ".", files, fileCount: files.length, truncated: false } });
255
+ const exactFileResults = [];
256
+ const searchableTargets = [];
257
+ const skippedMissingPaths = [];
258
+ for (const target of targets) {
259
+ if (target.searchPath === path.parse(target.searchPath).root)
260
+ throw new Error("Refusing to search filesystem root with find; provide a narrower path.");
261
+ const stat = customOps ? await customOps.stat?.(target.searchPath) : await fsStat(target.searchPath).catch(() => undefined);
262
+ if (!stat && targets.length > 1 && !customOps) {
263
+ skippedMissingPaths.push(target.inputPath);
264
+ continue;
107
265
  }
108
- if (signal?.aborted) {
109
- settle(() => reject(new Error("Operation aborted")));
110
- return;
111
- }
112
- const results = await ops.glob(pattern, searchPath, {
113
- ignore: ["**/node_modules/**", "**/.git/**"],
114
- limit: effectiveLimit,
115
- });
116
- if (signal?.aborted) {
117
- settle(() => reject(new Error("Operation aborted")));
118
- return;
266
+ if (!stat && targets.length === 1 && !customOps) {
267
+ throw new Error(`ENOENT: Path not found: ${target.searchPath}`);
119
268
  }
120
- if (results.length === 0) {
121
- settle(() => resolve({
122
- content: [{ type: "text", text: "No files found matching pattern" }],
123
- details: undefined,
124
- }));
125
- return;
126
- }
127
- // Relativize paths against the search root for stable output.
128
- const relativized = results.map((p) => {
129
- if (p.startsWith(searchPath))
130
- return toPosixPath(p.slice(searchPath.length + 1));
131
- return toPosixPath(path.relative(searchPath, p));
132
- });
133
- const resultLimitReached = relativized.length >= effectiveLimit;
134
- const rawOutput = relativized.join("\n");
135
- const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
136
- let resultOutput = truncation.content;
137
- const details = {};
138
- const notices = [];
139
- if (resultLimitReached) {
140
- notices.push(`${effectiveLimit} results limit reached`);
141
- details.resultLimitReached = effectiveLimit;
269
+ if (target.exactPathInput) {
270
+ const isFile = typeof stat?.isFile === "function" ? stat.isFile() : stat?.isFile;
271
+ if (isFile) {
272
+ exactFileResults.push(formatExactFoundPath(target.searchPath, cwd));
273
+ continue;
274
+ }
142
275
  }
143
- if (truncation.truncated) {
144
- notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
145
- details.truncation = truncation;
276
+ searchableTargets.push(target);
277
+ }
278
+ if (exactFileResults.length > effectiveLimit || searchableTargets.length === 0) {
279
+ const resultLimitReached = exactFileResults.length > effectiveLimit;
280
+ settle(() => resolve(buildFindResult(exactFileResults.slice(0, effectiveLimit), effectiveLimit, false, timeoutMs, skippedMissingPaths, resultLimitReached)));
281
+ emitUpdate(exactFileResults.slice(0, effectiveLimit));
282
+ return;
283
+ }
284
+ if (customOps?.glob) {
285
+ const deadline = Date.now() + timeoutMs;
286
+ let timedOut = false;
287
+ const relativized = [...exactFileResults];
288
+ let customLimitReached = false;
289
+ for (const target of searchableTargets) {
290
+ if (!(await ops.exists(target.searchPath))) {
291
+ if (targets.length > 1) {
292
+ skippedMissingPaths.push(target.inputPath);
293
+ continue;
294
+ }
295
+ settle(() => reject(new Error(`Path not found: ${target.searchPath}`)));
296
+ return;
297
+ }
298
+ if (signal?.aborted) {
299
+ settle(() => reject(new Error("Operation aborted")));
300
+ return;
301
+ }
302
+ const remaining = effectiveLimit - relativized.length;
303
+ const remainingMs = deadline - Date.now();
304
+ if (remaining <= 0) {
305
+ const ignore = findTargetMentionsNodeModules(target) ? ["**/.git/**"] : ["**/node_modules/**", "**/.git/**"];
306
+ const probe = await Promise.resolve(ops.glob(target.pattern, target.searchPath, { ignore, limit: 1, hidden: hidden !== false }));
307
+ if (probe.some((p) => hidden !== false || !containsHiddenSegment(p)))
308
+ customLimitReached = true;
309
+ if (customLimitReached)
310
+ break;
311
+ continue;
312
+ }
313
+ if (remainingMs <= 0) {
314
+ timedOut = true;
315
+ break;
316
+ }
317
+ const timeoutResult = Symbol("find-timeout");
318
+ let raceTimer;
319
+ const ignore = findTargetMentionsNodeModules(target) ? ["**/.git/**"] : ["**/node_modules/**", "**/.git/**"];
320
+ const results = await Promise.race([
321
+ Promise.resolve(ops.glob(target.pattern, target.searchPath, { ignore, limit: remaining + 1, hidden: hidden !== false })),
322
+ new Promise((resolveTimeout) => {
323
+ raceTimer = setTimeout(() => resolveTimeout(timeoutResult), remainingMs);
324
+ }),
325
+ ]);
326
+ if (raceTimer)
327
+ clearTimeout(raceTimer);
328
+ if (!Array.isArray(results)) {
329
+ timedOut = true;
330
+ break;
331
+ }
332
+ if (target.exactPathInput && results.length === 0) {
333
+ const stat = await customOps.stat?.(target.searchPath);
334
+ if (!stat?.isDirectory)
335
+ relativized.push(formatExactFoundPath(target.searchPath, cwd));
336
+ continue;
337
+ }
338
+ if (signal?.aborted) {
339
+ settle(() => reject(new Error("Operation aborted")));
340
+ return;
341
+ }
342
+ const visible = results.filter((p) => hidden !== false || !containsHiddenSegment(p));
343
+ if (visible.length > remaining)
344
+ customLimitReached = true;
345
+ relativized.push(...visible.slice(0, remaining).map((p) => formatFoundPath(p, target.searchPath, searchPaths, cwd)));
346
+ emitUpdate(relativized);
347
+ if (customLimitReached)
348
+ break;
146
349
  }
147
- if (notices.length > 0) {
148
- resultOutput += `\n\n[${notices.join(". ")}]`;
350
+ settle(() => resolve(buildFindResult(relativized, effectiveLimit, timedOut, timeoutMs, skippedMissingPaths, customLimitReached)));
351
+ return;
352
+ }
353
+ const nativeBinding = loadNativeSearchBinding();
354
+ if (nativeBinding) {
355
+ const matches = exactFileResults.map((path) => ({ path, mtime: Number.POSITIVE_INFINITY }));
356
+ let timedOut = false;
357
+ const deadline = Date.now() + timeoutMs;
358
+ for (const target of searchableTargets) {
359
+ const remainingMs = deadline - Date.now();
360
+ if (remainingMs <= 0) {
361
+ timedOut = true;
362
+ break;
363
+ }
364
+ try {
365
+ const result = await nativeBinding.glob({
366
+ pattern: target.pattern,
367
+ path: target.searchPath,
368
+ recursive: false,
369
+ hidden: hidden !== false,
370
+ gitignore: gitignore !== false,
371
+ includeNodeModules: findTargetMentionsNodeModules(target),
372
+ maxResults: effectiveLimit + 1,
373
+ cache: false,
374
+ sortByMtime: true,
375
+ timeoutMs: remainingMs,
376
+ signal,
377
+ });
378
+ matches.push(...result.matches.map((match) => { const fileType = match.fileType ?? match.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 }; }));
379
+ emitUpdate(matches.map((match) => match.path));
380
+ }
381
+ catch (error) {
382
+ if (String(error).toLowerCase().includes("timed out")) {
383
+ timedOut = true;
384
+ break;
385
+ }
386
+ throw error;
387
+ }
149
388
  }
150
- settle(() => resolve({
151
- content: [{ type: "text", text: resultOutput }],
152
- details: Object.keys(details).length > 0 ? details : undefined,
153
- }));
389
+ const uniqueMatches = [...matches.reduce((map, match) => { const previous = map.get(match.path); if (!previous || match.mtime > previous.mtime)
390
+ map.set(match.path, match); return map; }, new Map()).values()];
391
+ uniqueMatches.sort((a, b) => b.mtime - a.mtime || a.path.localeCompare(b.path));
392
+ const resultLimitReached = uniqueMatches.length > effectiveLimit;
393
+ settle(() => resolve(buildFindResult(uniqueMatches.slice(0, effectiveLimit).map((match) => match.path), effectiveLimit, timedOut, timeoutMs, skippedMissingPaths, resultLimitReached)));
154
394
  return;
155
395
  }
156
- // Default implementation uses fd.
157
396
  const fdPath = await ensureTool("fd", true);
158
397
  if (signal?.aborted) {
159
398
  settle(() => reject(new Error("Operation aborted")));
@@ -163,110 +402,95 @@ export function createFindToolDefinition(cwd, options) {
163
402
  settle(() => reject(new Error("fd is not available and could not be downloaded")));
164
403
  return;
165
404
  }
166
- // Build fd arguments. --no-require-git makes fd apply hierarchical .gitignore
167
- // semantics whether or not the search path is inside a git repository, without
168
- // leaking sibling-directory rules the way --ignore-file (a global source) would.
169
- const args = [
170
- "--glob",
171
- "--color=never",
172
- "--hidden",
173
- "--no-require-git",
174
- "--max-results",
175
- String(effectiveLimit),
176
- ];
177
- // fd --glob matches against the basename unless --full-path is set; in --full-path
178
- // mode it matches against the absolute candidate path, so a path-containing
179
- // pattern like 'src/**/*.spec.ts' needs a leading '**/' to match anything.
180
- let effectivePattern = pattern;
181
- if (pattern.includes("/")) {
182
- args.push("--full-path");
183
- if (!pattern.startsWith("/") && !pattern.startsWith("**/") && pattern !== "**") {
184
- effectivePattern = `**/${pattern}`;
405
+ let timedOut = false;
406
+ const relativized = [...exactFileResults];
407
+ const deadline = Date.now() + timeoutMs;
408
+ const runFdForTarget = async (target, remaining) => {
409
+ const args = ["--glob", "--color=never", "--no-require-git", "--max-results", String(remaining + 1)];
410
+ if (hidden !== false)
411
+ args.push("--hidden");
412
+ if (gitignore === false)
413
+ args.push("--no-ignore");
414
+ if (!findTargetMentionsNodeModules(target))
415
+ args.push("--exclude", "node_modules");
416
+ let fdPattern = target.pattern;
417
+ if (target.pattern.includes("/")) {
418
+ args.push("--full-path");
419
+ if (!target.pattern.startsWith("/") && !target.pattern.startsWith("**/") && target.pattern !== "**")
420
+ fdPattern = `**/${target.pattern}`;
185
421
  }
186
- }
187
- args.push("--", effectivePattern, searchPath);
188
- const child = spawn(fdPath, args, { stdio: ["ignore", "pipe", "pipe"] });
189
- const rl = createInterface({ input: child.stdout });
190
- let stderr = "";
191
- const lines = [];
192
- stopChild = () => {
193
- if (!child.killed) {
194
- child.kill();
422
+ args.push("--", fdPattern, target.searchPath);
423
+ const remainingMs = deadline - Date.now();
424
+ if (remainingMs <= 0) {
425
+ timedOut = true;
426
+ return false;
195
427
  }
428
+ return await new Promise((resolveTarget, rejectTarget) => {
429
+ const child = spawn(fdPath, args, { stdio: ["ignore", "pipe", "pipe"] });
430
+ const rl = createInterface({ input: child.stdout });
431
+ let stderr = "";
432
+ const lines = [];
433
+ stopChild = () => {
434
+ if (!child.killed)
435
+ child.kill();
436
+ };
437
+ const targetTimer = setTimeout(() => {
438
+ timedOut = true;
439
+ stopChild?.();
440
+ }, remainingMs);
441
+ const cleanup = () => {
442
+ clearTimeout(targetTimer);
443
+ rl.close();
444
+ };
445
+ child.stderr?.on("data", (chunk) => {
446
+ stderr += chunk.toString();
447
+ });
448
+ rl.on("line", (line) => lines.push(line));
449
+ child.on("error", (error) => {
450
+ cleanup();
451
+ rejectTarget(new Error(`Failed to run fd: ${error.message}`));
452
+ });
453
+ child.on("close", (code) => {
454
+ cleanup();
455
+ if (signal?.aborted) {
456
+ rejectTarget(new Error("Operation aborted"));
457
+ return;
458
+ }
459
+ if (!timedOut && code !== 0 && lines.length === 0) {
460
+ rejectTarget(new Error(stderr.trim() || `fd exited with code ${code}`));
461
+ return;
462
+ }
463
+ for (const rawLine of lines.slice(0, remaining)) {
464
+ const line = rawLine.replace(/\r$/, "").trim();
465
+ if (line) {
466
+ const found = statSync(path.resolve(target.searchPath, line), { throwIfNoEntry: false })?.isDirectory() && !line.endsWith("/") ? `${line}/` : line;
467
+ relativized.push(formatFoundPath(found, target.searchPath, searchPaths, cwd));
468
+ }
469
+ }
470
+ emitUpdate(relativized);
471
+ resolveTarget(lines.length > Math.max(0, remaining));
472
+ });
473
+ });
196
474
  };
197
- const cleanup = () => {
198
- rl.close();
199
- };
200
- child.stderr?.on("data", (chunk) => {
201
- stderr += chunk.toString();
202
- });
203
- rl.on("line", (line) => {
204
- lines.push(line);
205
- });
206
- child.on("error", (error) => {
207
- cleanup();
208
- settle(() => reject(new Error(`Failed to run fd: ${error.message}`)));
209
- });
210
- child.on("close", (code) => {
211
- cleanup();
212
- if (signal?.aborted) {
213
- settle(() => reject(new Error("Operation aborted")));
214
- return;
215
- }
216
- const output = lines.join("\n");
217
- if (code !== 0) {
218
- const errorMsg = stderr.trim() || `fd exited with code ${code}`;
219
- if (!output) {
220
- settle(() => reject(new Error(errorMsg)));
221
- return;
475
+ let resultLimitReached = false;
476
+ for (const target of searchableTargets) {
477
+ const remaining = effectiveLimit - relativized.length;
478
+ if (timedOut)
479
+ break;
480
+ if (remaining <= 0) {
481
+ if (await runFdForTarget(target, 0)) {
482
+ resultLimitReached = true;
483
+ break;
222
484
  }
485
+ continue;
223
486
  }
224
- if (!output) {
225
- settle(() => resolve({
226
- content: [{ type: "text", text: "No files found matching pattern" }],
227
- details: undefined,
228
- }));
229
- return;
487
+ const targetLimitReached = await runFdForTarget(target, remaining);
488
+ if (targetLimitReached) {
489
+ resultLimitReached = true;
490
+ break;
230
491
  }
231
- const relativized = [];
232
- for (const rawLine of lines) {
233
- const line = rawLine.replace(/\r$/, "").trim();
234
- if (!line)
235
- continue;
236
- const hadTrailingSlash = line.endsWith("/") || line.endsWith("\\");
237
- let relativePath = line;
238
- if (line.startsWith(searchPath)) {
239
- relativePath = line.slice(searchPath.length + 1);
240
- }
241
- else {
242
- relativePath = path.relative(searchPath, line);
243
- }
244
- if (hadTrailingSlash && !relativePath.endsWith("/"))
245
- relativePath += "/";
246
- relativized.push(toPosixPath(relativePath));
247
- }
248
- const resultLimitReached = relativized.length >= effectiveLimit;
249
- const rawOutput = relativized.join("\n");
250
- const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
251
- let resultOutput = truncation.content;
252
- const details = {};
253
- const notices = [];
254
- if (resultLimitReached) {
255
- notices.push(`${effectiveLimit} results limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`);
256
- details.resultLimitReached = effectiveLimit;
257
- }
258
- if (truncation.truncated) {
259
- notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
260
- details.truncation = truncation;
261
- }
262
- if (notices.length > 0) {
263
- resultOutput += `\n\n[${notices.join(". ")}]`;
264
- }
265
- settle(() => resolve({
266
- content: [{ type: "text", text: resultOutput }],
267
- details: Object.keys(details).length > 0 ? details : undefined,
268
- }));
269
- });
492
+ }
493
+ settle(() => resolve(buildFindResult(relativized.slice(0, effectiveLimit), effectiveLimit, timedOut, timeoutMs, skippedMissingPaths, resultLimitReached)));
270
494
  }
271
495
  catch (e) {
272
496
  if (signal?.aborted) {