@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.
- package/CHANGELOG.md +70 -0
- package/README.md +2 -2
- package/dist/builtin/cursor/CHANGELOG.md +6 -0
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/intercom/CHANGELOG.md +6 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/CHANGELOG.md +12 -0
- package/dist/builtin/mcp/direct-tools.ts +4 -2
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/mcp/proxy-call.ts +3 -1
- package/dist/builtin/mcp/utils.ts +18 -7
- package/dist/builtin/subagents/CHANGELOG.md +17 -0
- package/dist/builtin/subagents/README.md +6 -6
- package/dist/builtin/subagents/agents/code-simplifier.md +7 -6
- package/dist/builtin/subagents/agents/codebase-analyzer.md +5 -4
- package/dist/builtin/subagents/agents/codebase-locator.md +3 -3
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +10 -10
- package/dist/builtin/subagents/agents/codebase-pattern-finder.md +4 -4
- package/dist/builtin/subagents/agents/codebase-research-analyzer.md +3 -3
- package/dist/builtin/subagents/agents/codebase-research-locator.md +4 -4
- package/dist/builtin/subagents/agents/debugger.md +5 -5
- package/dist/builtin/subagents/agents/worker.md +56 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +11 -11
- package/dist/builtin/subagents/src/agents/agent-loaders.ts +3 -5
- package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +3 -3
- package/dist/builtin/subagents/src/extension/schemas.ts +2 -2
- package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -3
- package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +1 -1
- package/dist/builtin/subagents/src/runs/shared/nested-render.ts +2 -2
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -1
- package/dist/builtin/subagents/src/shared/types-depth.ts +5 -5
- package/dist/builtin/subagents/src/shared/types-runtime.ts +2 -1
- package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -2
- package/dist/builtin/web-access/CHANGELOG.md +6 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +21 -0
- package/dist/builtin/workflows/README.md +2 -2
- package/dist/builtin/workflows/builtin/goal-artifacts.ts +11 -6
- package/dist/builtin/workflows/builtin/goal-ledger.ts +33 -1
- package/dist/builtin/workflows/builtin/goal-prompts.ts +23 -28
- package/dist/builtin/workflows/builtin/goal-reducer.ts +2 -2
- package/dist/builtin/workflows/builtin/goal-reports.ts +2 -5
- package/dist/builtin/workflows/builtin/goal-review.ts +1 -1
- package/dist/builtin/workflows/builtin/goal-runner.ts +10 -17
- package/dist/builtin/workflows/builtin/open-claude-design-feedback.ts +3 -3
- package/dist/builtin/workflows/builtin/open-claude-design-phases.ts +1 -3
- package/dist/builtin/workflows/builtin/open-claude-design-setup.ts +1 -1
- package/dist/builtin/workflows/builtin/ralph-core.ts +7 -17
- package/dist/builtin/workflows/builtin/ralph-runner.ts +11 -18
- package/dist/builtin/workflows/builtin/shared-prompts.ts +1 -1
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/config-loader.ts +35 -15
- package/dist/builtin/workflows/src/extension/discovery.ts +20 -8
- package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +1 -2
- package/dist/builtin/workflows/src/extension/wiring.ts +1 -1
- package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +11 -10
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +9 -9
- package/dist/cli/args.js.map +1 -1
- package/dist/config-self-update.d.ts.map +1 -1
- package/dist/config-self-update.js +3 -4
- package/dist/config-self-update.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -5
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-bash.d.ts +1 -0
- package/dist/core/agent-session-bash.d.ts.map +1 -1
- package/dist/core/agent-session-bash.js +1 -0
- package/dist/core/agent-session-bash.js.map +1 -1
- package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
- package/dist/core/agent-session-tool-registry.js +23 -0
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/bash-executor.d.ts +2 -0
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +1 -0
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +29 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +36 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/context-compaction-metrics.d.ts +14 -2
- package/dist/core/compaction/context-compaction-metrics.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-metrics.js +50 -1
- package/dist/core/compaction/context-compaction-metrics.js.map +1 -1
- package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-prompt.js +2 -0
- package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
- package/dist/core/compaction/context-compaction-runner.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-runner.js +1 -1
- package/dist/core/compaction/context-compaction-runner.js.map +1 -1
- package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-application.js +5 -5
- package/dist/core/compaction/context-deletion-application.js.map +1 -1
- package/dist/core/compaction/context-deletion-targets.d.ts +2 -0
- package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-targets.js +23 -3
- package/dist/core/compaction/context-deletion-targets.js.map +1 -1
- package/dist/core/compaction/context-deletion-tool-definitions.d.ts +6 -0
- package/dist/core/compaction/context-deletion-tool-definitions.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-tool-definitions.js.map +1 -1
- package/dist/core/compaction/context-deletion-tools.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-tools.js +18 -10
- package/dist/core/compaction/context-deletion-tools.js.map +1 -1
- package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
- package/dist/core/compaction/context-transcript-analysis.js +2 -4
- package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
- package/dist/core/copilot-gemini-tool-arguments.d.ts.map +1 -1
- package/dist/core/copilot-gemini-tool-arguments.js +2 -60
- package/dist/core/copilot-gemini-tool-arguments.js.map +1 -1
- package/dist/core/extensions/context-types.d.ts +2 -0
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +11 -3
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/runner-context.d.ts.map +1 -1
- package/dist/core/extensions/runner-context.js +11 -0
- package/dist/core/extensions/runner-context.js.map +1 -1
- package/dist/core/extensions/tool-events.d.ts +13 -13
- package/dist/core/extensions/tool-events.d.ts.map +1 -1
- package/dist/core/extensions/tool-events.js +3 -3
- package/dist/core/extensions/tool-events.js.map +1 -1
- package/dist/core/extensions/types.d.ts +1 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/flattened-tool-arguments.d.ts +18 -0
- package/dist/core/flattened-tool-arguments.d.ts.map +1 -1
- package/dist/core/flattened-tool-arguments.js +104 -0
- package/dist/core/flattened-tool-arguments.js.map +1 -1
- package/dist/core/sdk-exports.d.ts +1 -1
- package/dist/core/sdk-exports.d.ts.map +1 -1
- package/dist/core/sdk-exports.js +1 -1
- package/dist/core/sdk-exports.js.map +1 -1
- package/dist/core/sdk-types.d.ts +2 -2
- package/dist/core/sdk-types.d.ts.map +1 -1
- package/dist/core/sdk-types.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +4 -0
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js +18 -0
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-manager-resource-accessors.d.ts +4 -0
- package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-resource-accessors.js +15 -0
- package/dist/core/settings-manager-resource-accessors.js.map +1 -1
- package/dist/core/settings-types.d.ts +11 -0
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/system-prompt.d.ts +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +3 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/artifact-protocol.d.ts +11 -0
- package/dist/core/tools/artifact-protocol.d.ts.map +1 -0
- package/dist/core/tools/artifact-protocol.js +76 -0
- package/dist/core/tools/artifact-protocol.js.map +1 -0
- package/dist/core/tools/artifacts.d.ts +18 -0
- package/dist/core/tools/artifacts.d.ts.map +1 -0
- package/dist/core/tools/artifacts.js +90 -0
- package/dist/core/tools/artifacts.js.map +1 -0
- package/dist/core/tools/bash-async-jobs.d.ts +20 -0
- package/dist/core/tools/bash-async-jobs.d.ts.map +1 -0
- package/dist/core/tools/bash-async-jobs.js +59 -0
- package/dist/core/tools/bash-async-jobs.js.map +1 -0
- package/dist/core/tools/bash-async-output.d.ts +10 -0
- package/dist/core/tools/bash-async-output.d.ts.map +1 -0
- package/dist/core/tools/bash-async-output.js +80 -0
- package/dist/core/tools/bash-async-output.js.map +1 -0
- package/dist/core/tools/bash-interceptor.d.ts +10 -0
- package/dist/core/tools/bash-interceptor.d.ts.map +1 -0
- package/dist/core/tools/bash-interceptor.js +39 -0
- package/dist/core/tools/bash-interceptor.js.map +1 -0
- package/dist/core/tools/bash-leading-cd.d.ts +7 -0
- package/dist/core/tools/bash-leading-cd.d.ts.map +1 -0
- package/dist/core/tools/bash-leading-cd.js +59 -0
- package/dist/core/tools/bash-leading-cd.js.map +1 -0
- package/dist/core/tools/bash-pty-native.d.ts +14 -0
- package/dist/core/tools/bash-pty-native.d.ts.map +1 -0
- package/dist/core/tools/bash-pty-native.js +71 -0
- package/dist/core/tools/bash-pty-native.js.map +1 -0
- package/dist/core/tools/bash.d.ts +28 -17
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +152 -35
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/block-resolver.d.ts +16 -0
- package/dist/core/tools/block-resolver.d.ts.map +1 -0
- package/dist/core/tools/block-resolver.js +74 -0
- package/dist/core/tools/block-resolver.js.map +1 -0
- package/dist/core/tools/conflict-registry.d.ts +16 -0
- package/dist/core/tools/conflict-registry.d.ts.map +1 -0
- package/dist/core/tools/conflict-registry.js +44 -0
- package/dist/core/tools/conflict-registry.js.map +1 -0
- package/dist/core/tools/directory-tree.d.ts +13 -0
- package/dist/core/tools/directory-tree.d.ts.map +1 -0
- package/dist/core/tools/directory-tree.js +81 -0
- package/dist/core/tools/directory-tree.js.map +1 -0
- package/dist/core/tools/edit.d.ts +4 -29
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +136 -228
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/fetch-url.d.ts +74 -0
- package/dist/core/tools/fetch-url.d.ts.map +1 -0
- package/dist/core/tools/fetch-url.js +518 -0
- package/dist/core/tools/fetch-url.js.map +1 -0
- package/dist/core/tools/find.d.ts +27 -9
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +400 -176
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/glob-path-utils.d.ts +8 -0
- package/dist/core/tools/glob-path-utils.d.ts.map +1 -0
- package/dist/core/tools/glob-path-utils.js +26 -0
- package/dist/core/tools/glob-path-utils.js.map +1 -0
- package/dist/core/tools/grep.d.ts +12 -0
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +141 -17
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/hashline-engine/apply.d.ts +11 -0
- package/dist/core/tools/hashline-engine/apply.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/apply.js +752 -0
- package/dist/core/tools/hashline-engine/apply.js.map +1 -0
- package/dist/core/tools/hashline-engine/block.d.ts +40 -0
- package/dist/core/tools/hashline-engine/block.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/block.js +117 -0
- package/dist/core/tools/hashline-engine/block.js.map +1 -0
- package/dist/core/tools/hashline-engine/diff-preview.d.ts +15 -0
- package/dist/core/tools/hashline-engine/diff-preview.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/diff-preview.js +98 -0
- package/dist/core/tools/hashline-engine/diff-preview.js.map +1 -0
- package/dist/core/tools/hashline-engine/format.d.ts +71 -0
- package/dist/core/tools/hashline-engine/format.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/format.js +178 -0
- package/dist/core/tools/hashline-engine/format.js.map +1 -0
- package/dist/core/tools/hashline-engine/fs.d.ts +81 -0
- package/dist/core/tools/hashline-engine/fs.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/fs.js +143 -0
- package/dist/core/tools/hashline-engine/fs.js.map +1 -0
- package/dist/core/tools/hashline-engine/index.d.ts +18 -0
- package/dist/core/tools/hashline-engine/index.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/index.js +20 -0
- package/dist/core/tools/hashline-engine/index.js.map +1 -0
- package/dist/core/tools/hashline-engine/input.d.ts +101 -0
- package/dist/core/tools/hashline-engine/input.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/input.js +398 -0
- package/dist/core/tools/hashline-engine/input.js.map +1 -0
- package/dist/core/tools/hashline-engine/messages.d.ts +99 -0
- package/dist/core/tools/hashline-engine/messages.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/messages.js +144 -0
- package/dist/core/tools/hashline-engine/messages.js.map +1 -0
- package/dist/core/tools/hashline-engine/mismatch.d.ts +45 -0
- package/dist/core/tools/hashline-engine/mismatch.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/mismatch.js +90 -0
- package/dist/core/tools/hashline-engine/mismatch.js.map +1 -0
- package/dist/core/tools/hashline-engine/normalize.d.ts +21 -0
- package/dist/core/tools/hashline-engine/normalize.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/normalize.js +33 -0
- package/dist/core/tools/hashline-engine/normalize.js.map +1 -0
- package/dist/core/tools/hashline-engine/parser.d.ts +24 -0
- package/dist/core/tools/hashline-engine/parser.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/parser.js +381 -0
- package/dist/core/tools/hashline-engine/parser.js.map +1 -0
- package/dist/core/tools/hashline-engine/patcher.d.ts +118 -0
- package/dist/core/tools/hashline-engine/patcher.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/patcher.js +341 -0
- package/dist/core/tools/hashline-engine/patcher.js.map +1 -0
- package/dist/core/tools/hashline-engine/prefixes.d.ts +43 -0
- package/dist/core/tools/hashline-engine/prefixes.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/prefixes.js +135 -0
- package/dist/core/tools/hashline-engine/prefixes.js.map +1 -0
- package/dist/core/tools/hashline-engine/recovery.d.ts +41 -0
- package/dist/core/tools/hashline-engine/recovery.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/recovery.js +168 -0
- package/dist/core/tools/hashline-engine/recovery.js.map +1 -0
- package/dist/core/tools/hashline-engine/snapshots.d.ts +65 -0
- package/dist/core/tools/hashline-engine/snapshots.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/snapshots.js +108 -0
- package/dist/core/tools/hashline-engine/snapshots.js.map +1 -0
- package/dist/core/tools/hashline-engine/stream.d.ts +3 -0
- package/dist/core/tools/hashline-engine/stream.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/stream.js +111 -0
- package/dist/core/tools/hashline-engine/stream.js.map +1 -0
- package/dist/core/tools/hashline-engine/tokenizer.d.ts +69 -0
- package/dist/core/tools/hashline-engine/tokenizer.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/tokenizer.js +430 -0
- package/dist/core/tools/hashline-engine/tokenizer.js.map +1 -0
- package/dist/core/tools/hashline-engine/types.d.ts +166 -0
- package/dist/core/tools/hashline-engine/types.d.ts.map +1 -0
- package/dist/core/tools/hashline-engine/types.js +9 -0
- package/dist/core/tools/hashline-engine/types.js.map +1 -0
- package/dist/core/tools/hashline.d.ts +29 -0
- package/dist/core/tools/hashline.d.ts.map +1 -0
- package/dist/core/tools/hashline.js +110 -0
- package/dist/core/tools/hashline.js.map +1 -0
- package/dist/core/tools/index.d.ts +6 -4
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +52 -35
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/notebook.d.ts +38 -0
- package/dist/core/tools/notebook.d.ts.map +1 -0
- package/dist/core/tools/notebook.js +125 -0
- package/dist/core/tools/notebook.js.map +1 -0
- package/dist/core/tools/read-document-extract.d.ts +9 -0
- package/dist/core/tools/read-document-extract.d.ts.map +1 -0
- package/dist/core/tools/read-document-extract.js +212 -0
- package/dist/core/tools/read-document-extract.js.map +1 -0
- package/dist/core/tools/read-selectors.d.ts +24 -0
- package/dist/core/tools/read-selectors.d.ts.map +1 -0
- package/dist/core/tools/read-selectors.js +277 -0
- package/dist/core/tools/read-selectors.js.map +1 -0
- package/dist/core/tools/read-url.d.ts +37 -0
- package/dist/core/tools/read-url.d.ts.map +1 -0
- package/dist/core/tools/read-url.js +39 -0
- package/dist/core/tools/read-url.js.map +1 -0
- package/dist/core/tools/read.d.ts +11 -11
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +224 -94
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/resource-selectors.d.ts +44 -0
- package/dist/core/tools/resource-selectors.d.ts.map +1 -0
- package/dist/core/tools/resource-selectors.js +808 -0
- package/dist/core/tools/resource-selectors.js.map +1 -0
- package/dist/core/tools/search-details.d.ts +26 -0
- package/dist/core/tools/search-details.d.ts.map +1 -0
- package/dist/core/tools/search-details.js +24 -0
- package/dist/core/tools/search-details.js.map +1 -0
- package/dist/core/tools/search-line-ranges.d.ts +11 -0
- package/dist/core/tools/search-line-ranges.d.ts.map +1 -0
- package/dist/core/tools/search-line-ranges.js +65 -0
- package/dist/core/tools/search-line-ranges.js.map +1 -0
- package/dist/core/tools/search-native.d.ts +97 -0
- package/dist/core/tools/search-native.d.ts.map +1 -0
- package/dist/core/tools/search-native.js +27 -0
- package/dist/core/tools/search-native.js.map +1 -0
- package/dist/core/tools/search.d.ts +24 -0
- package/dist/core/tools/search.d.ts.map +1 -0
- package/dist/core/tools/search.js +573 -0
- package/dist/core/tools/search.js.map +1 -0
- package/dist/core/tools/truncate.d.ts +4 -4
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js +3 -3
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/tools/url-ip-guards.d.ts +4 -0
- package/dist/core/tools/url-ip-guards.d.ts.map +1 -0
- package/dist/core/tools/url-ip-guards.js +126 -0
- package/dist/core/tools/url-ip-guards.js.map +1 -0
- package/dist/core/tools/write.d.ts +12 -2
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +166 -14
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -3
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/index-extensions.d.ts +2 -2
- package/dist/index-extensions.d.ts.map +1 -1
- package/dist/index-extensions.js +1 -1
- package/dist/index-extensions.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +9 -2
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-handlers.js +3 -0
- package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-items.js +7 -0
- package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-types.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector-content.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector-content.js +0 -5
- package/dist/modes/interactive/components/tree-selector-content.js.map +1 -1
- package/dist/modes/interactive/interactive-auth-login.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-auth-login.js +1 -0
- package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.js +80 -2
- package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.js +3 -0
- package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.js +51 -0
- package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +5 -0
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +5 -0
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +12 -0
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +4 -1
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-onboarding.d.ts +11 -0
- package/dist/modes/interactive/interactive-onboarding.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-onboarding.js +220 -0
- package/dist/modes/interactive/interactive-onboarding.js.map +1 -0
- package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-selectors.js +4 -0
- package/dist/modes/interactive/interactive-selectors.js.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.js +6 -0
- package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-slash-commands.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-slash-commands.js +9 -4
- package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +28 -0
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js +21 -1
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/markit.d.ts +8 -0
- package/dist/utils/markit.d.ts.map +1 -0
- package/dist/utils/markit.js +53 -0
- package/dist/utils/markit.js.map +1 -0
- package/dist/utils/paths.d.ts +2 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +14 -1
- package/dist/utils/paths.js.map +1 -1
- package/docs/compaction.md +16 -1
- package/docs/containerization.md +1 -1
- package/docs/docs.json +1 -0
- package/docs/extensions.md +25 -36
- package/docs/quickstart.md +11 -6
- package/docs/sdk.md +5 -5
- package/docs/settings.md +7 -0
- package/docs/subagents.md +3 -2
- package/docs/tools.md +49 -0
- package/docs/usage.md +3 -3
- package/docs/workflows.md +7 -5
- package/examples/extensions/subagent/README.md +5 -5
- package/examples/extensions/subagent/agents/planner.md +1 -1
- package/examples/extensions/subagent/agents/reviewer.md +1 -1
- package/examples/extensions/subagent/agents/scout.md +2 -2
- package/examples/extensions/subagent/display.ts +3 -3
- package/examples/sdk/05-tools.ts +3 -3
- package/examples/sdk/README.md +1 -1
- package/package.json +3 -2
package/dist/core/tools/find.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
13
|
-
return value.split(path.sep).join("/");
|
|
14
|
-
}
|
|
17
|
+
const toPosixPath = (value) => value.split(path.sep).join("/");
|
|
15
18
|
const findSchema = Type.Object({
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}),
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
22
|
-
const DEFAULT_LIMIT =
|
|
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
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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:
|
|
74
|
-
promptSnippet: "Find
|
|
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,
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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 (
|
|
109
|
-
|
|
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 (
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
148
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const
|
|
170
|
-
"--glob",
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}));
|
|
229
|
-
return;
|
|
487
|
+
const targetLimitReached = await runFdForTarget(target, remaining);
|
|
488
|
+
if (targetLimitReached) {
|
|
489
|
+
resultLimitReached = true;
|
|
490
|
+
break;
|
|
230
491
|
}
|
|
231
|
-
|
|
232
|
-
|
|
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) {
|