orient-cli 0.3.1 → 0.3.3
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/dist/cli.js +0 -0
- package/dist/integrations/notebooklm/notebooklm-extension.js +3 -8
- package/dist/integrations/notebooklm/notebooklm-extension.js.map +1 -1
- package/dist/integrations/playwright/playwright-extension.js +3 -11
- package/dist/integrations/playwright/playwright-extension.js.map +1 -1
- package/dist/integrations/web-search/bridge.js.map +1 -1
- package/dist/integrations/web-search/web-search-extension.js +0 -3
- package/dist/integrations/web-search/web-search-extension.js.map +1 -1
- package/dist/orient/orient-extension.js +4 -12
- package/dist/orient/orient-extension.js.map +1 -1
- package/package.json +1 -1
- package/vendor/@orient-cli/coding-agent/README.md +618 -0
- package/vendor/@orient-cli/coding-agent/dist/bun/cli.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/bun/cli.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/bun/register-bedrock.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/args.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/args.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/config-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/config-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/file-processor.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/file-processor.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/initial-message.d.ts +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/initial-message.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/initial-message.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/list-models.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/list-models.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/session-picker.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli/session-picker.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/cli.js +0 -0
- package/vendor/@orient-cli/coding-agent/dist/cli.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/config.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/config.js +23 -1
- package/vendor/@orient-cli/coding-agent/dist/config.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/agent-session-runtime.js +0 -5
- package/vendor/@orient-cli/coding-agent/dist/core/agent-session-runtime.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/agent-session-services.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/agent-session-services.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/agent-session.d.ts +32 -0
- package/vendor/@orient-cli/coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/agent-session.js +47 -67
- package/vendor/@orient-cli/coding-agent/dist/core/agent-session.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/auth-storage.d.ts +4 -0
- package/vendor/@orient-cli/coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/auth-storage.js +4 -8
- package/vendor/@orient-cli/coding-agent/dist/core/auth-storage.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/bash-executor.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/bash-executor.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/compaction/index.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/compaction/utils.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/defaults.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/diagnostics.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/event-bus.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/event-bus.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/exec.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/exec.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/export-html/ansi-to-html.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/export-html/index.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/export-html/index.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/export-html/tool-renderer.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/extensions/runner.js +18 -24
- package/vendor/@orient-cli/coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/extensions/types.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/extensions/wrapper.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/footer-data-provider.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/footer-data-provider.js +14 -15
- package/vendor/@orient-cli/coding-agent/dist/core/footer-data-provider.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/index.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/keybindings.d.ts +116 -116
- package/vendor/@orient-cli/coding-agent/dist/core/keybindings.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/keybindings.js +0 -1
- package/vendor/@orient-cli/coding-agent/dist/core/keybindings.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/messages.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/messages.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/model-registry.js +8 -8
- package/vendor/@orient-cli/coding-agent/dist/core/model-registry.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/model-resolver.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/output-guard.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/output-guard.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/package-manager.js +0 -6
- package/vendor/@orient-cli/coding-agent/dist/core/package-manager.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/prompt-templates.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/prompt-templates.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/resolve-config-value.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/resource-loader.js +0 -39
- package/vendor/@orient-cli/coding-agent/dist/core/resource-loader.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/sdk.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/session-cwd.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/session-cwd.js +0 -1
- package/vendor/@orient-cli/coding-agent/dist/core/session-cwd.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/session-manager.js +7 -11
- package/vendor/@orient-cli/coding-agent/dist/core/session-manager.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/settings-manager.js +7 -16
- package/vendor/@orient-cli/coding-agent/dist/core/settings-manager.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/skills.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/skills.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/source-info.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/source-info.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/system-prompt.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/timings.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/timings.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/bash.js +8 -5
- package/vendor/@orient-cli/coding-agent/dist/core/tools/bash.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/edit-diff.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/edit.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/find.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/find.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/grep.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/grep.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/index.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/ls.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/ls.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/path-utils.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/path-utils.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/read.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/render-utils.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/truncate.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/truncate.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/write.js +0 -1
- package/vendor/@orient-cli/coding-agent/dist/core/tools/write.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/index.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/main.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/main.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/migrations.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/migrations.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/index.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/assistant-message.js +0 -5
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/bash-execution.js +4 -9
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/bordered-loader.js +0 -3
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/branch-summary-message.js +1 -3
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/compaction-summary-message.js +1 -3
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/config-selector.js +6 -15
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/countdown-timer.js +0 -5
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/custom-editor.js +1 -8
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/custom-message.js +1 -6
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/dynamic-border.js +0 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/extension-editor.js +1 -6
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/extension-input.js +2 -8
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/extension-selector.js +1 -8
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/footer.js +1 -3
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/index.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/login-dialog.js +3 -9
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/model-selector.js +8 -20
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/oauth-selector.js +2 -7
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/orient-banner.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/orient-banner.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/scoped-models-selector.js +9 -13
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/session-selector.js +33 -58
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/settings-selector.js +0 -2
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/show-images-selector.js +0 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/skill-invocation-message.js +1 -3
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/theme-selector.js +0 -2
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/thinking-selector.js +0 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/tool-execution.js +9 -22
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/tree-selector.js +18 -32
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/user-message-selector.js +3 -6
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/interactive-mode.d.ts +14 -0
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/interactive-mode.js +59 -84
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/theme/theme.js +0 -6
- package/vendor/@orient-cli/coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/print-mode.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/print-mode.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/rpc/jsonl.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/rpc/jsonl.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/rpc/rpc-client.js +6 -7
- package/vendor/@orient-cli/coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/package-manager-cli.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/package-manager-cli.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/changelog.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/changelog.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/child-process.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/child-process.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/clipboard-image.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/clipboard-image.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/clipboard-native.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/clipboard-native.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/clipboard.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/clipboard.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/exif-orientation.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/exif-orientation.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/frontmatter.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/frontmatter.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/git.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/git.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/image-convert.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/image-convert.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/image-resize.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/image-resize.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/mime.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/mime.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/paths.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/paths.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/photon.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/photon.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/shell.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/sleep.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/sleep.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/tools-manager.d.ts.map +1 -1
- package/vendor/@orient-cli/coding-agent/dist/utils/tools-manager.js.map +1 -1
- package/vendor/@orient-cli/coding-agent/docs/compaction.md +394 -0
- package/vendor/@orient-cli/coding-agent/docs/custom-provider.md +596 -0
- package/vendor/@orient-cli/coding-agent/docs/development.md +71 -0
- package/vendor/@orient-cli/coding-agent/docs/extensions.md +2262 -0
- package/vendor/@orient-cli/coding-agent/docs/images/doom-extension.png +0 -0
- package/vendor/@orient-cli/coding-agent/docs/images/exy.png +0 -0
- package/vendor/@orient-cli/coding-agent/docs/images/interactive-mode.png +0 -0
- package/vendor/@orient-cli/coding-agent/docs/images/tree-view.png +0 -0
- package/vendor/@orient-cli/coding-agent/docs/json.md +82 -0
- package/vendor/@orient-cli/coding-agent/docs/keybindings.md +175 -0
- package/vendor/@orient-cli/coding-agent/docs/models.md +392 -0
- package/vendor/@orient-cli/coding-agent/docs/packages.md +218 -0
- package/vendor/@orient-cli/coding-agent/docs/prompt-templates.md +67 -0
- package/vendor/@orient-cli/coding-agent/docs/providers.md +195 -0
- package/vendor/@orient-cli/coding-agent/docs/rpc.md +1377 -0
- package/vendor/@orient-cli/coding-agent/docs/sdk.md +1124 -0
- package/vendor/@orient-cli/coding-agent/docs/session.md +412 -0
- package/vendor/@orient-cli/coding-agent/docs/settings.md +246 -0
- package/vendor/@orient-cli/coding-agent/docs/shell-aliases.md +13 -0
- package/vendor/@orient-cli/coding-agent/docs/skills.md +232 -0
- package/vendor/@orient-cli/coding-agent/docs/terminal-setup.md +106 -0
- package/vendor/@orient-cli/coding-agent/docs/termux.md +127 -0
- package/vendor/@orient-cli/coding-agent/docs/themes.md +295 -0
- package/vendor/@orient-cli/coding-agent/docs/tmux.md +61 -0
- package/vendor/@orient-cli/coding-agent/docs/tree.md +231 -0
- package/vendor/@orient-cli/coding-agent/docs/tui.md +887 -0
- package/vendor/@orient-cli/coding-agent/docs/windows.md +17 -0
- package/vendor/@orient-cli/coding-agent/dist/core/export-html/template.js +0 -1690
- package/vendor/@orient-cli/coding-agent/dist/core/export-html/vendor/highlight.min.js +0 -1213
- package/vendor/@orient-cli/coding-agent/dist/core/export-html/vendor/marked.min.js +0 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit-diff.js","sourceRoot":"","sources":["../../../src/core/tools/edit-diff.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared diff computation utilities for the edit tool.\n * Used by both edit.ts (for execution) and tool-execution.ts (for preview rendering).\n */\n\nimport * as Diff from \"diff\";\nimport { constants } from \"fs\";\nimport { access, readFile } from \"fs/promises\";\nimport { resolveToCwd } from \"./path-utils.js\";\n\nexport function detectLineEnding(content: string): \"\\r\\n\" | \"\\n\" {\n\tconst crlfIdx = content.indexOf(\"\\r\\n\");\n\tconst lfIdx = content.indexOf(\"\\n\");\n\tif (lfIdx === -1) return \"\\n\";\n\tif (crlfIdx === -1) return \"\\n\";\n\treturn crlfIdx < lfIdx ? \"\\r\\n\" : \"\\n\";\n}\n\nexport function normalizeToLF(text: string): string {\n\treturn text.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n}\n\nexport function restoreLineEndings(text: string, ending: \"\\r\\n\" | \"\\n\"): string {\n\treturn ending === \"\\r\\n\" ? text.replace(/\\n/g, \"\\r\\n\") : text;\n}\n\n/**\n * Normalize text for fuzzy matching. Applies progressive transformations:\n * - Strip trailing whitespace from each line\n * - Normalize smart quotes to ASCII equivalents\n * - Normalize Unicode dashes/hyphens to ASCII hyphen\n * - Normalize special Unicode spaces to regular space\n */\nexport function normalizeForFuzzyMatch(text: string): string {\n\treturn (\n\t\ttext\n\t\t\t.normalize(\"NFKC\")\n\t\t\t// Strip trailing whitespace per line\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => line.trimEnd())\n\t\t\t.join(\"\\n\")\n\t\t\t// Smart single quotes → '\n\t\t\t.replace(/[\\u2018\\u2019\\u201A\\u201B]/g, \"'\")\n\t\t\t// Smart double quotes → \"\n\t\t\t.replace(/[\\u201C\\u201D\\u201E\\u201F]/g, '\"')\n\t\t\t// Various dashes/hyphens → -\n\t\t\t// U+2010 hyphen, U+2011 non-breaking hyphen, U+2012 figure dash,\n\t\t\t// U+2013 en-dash, U+2014 em-dash, U+2015 horizontal bar, U+2212 minus\n\t\t\t.replace(/[\\u2010\\u2011\\u2012\\u2013\\u2014\\u2015\\u2212]/g, \"-\")\n\t\t\t// Special spaces → regular space\n\t\t\t// U+00A0 NBSP, U+2002-U+200A various spaces, U+202F narrow NBSP,\n\t\t\t// U+205F medium math space, U+3000 ideographic space\n\t\t\t.replace(/[\\u00A0\\u2002-\\u200A\\u202F\\u205F\\u3000]/g, \" \")\n\t);\n}\n\nexport interface FuzzyMatchResult {\n\t/** Whether a match was found */\n\tfound: boolean;\n\t/** The index where the match starts (in the content that should be used for replacement) */\n\tindex: number;\n\t/** Length of the matched text */\n\tmatchLength: number;\n\t/** Whether fuzzy matching was used (false = exact match) */\n\tusedFuzzyMatch: boolean;\n\t/**\n\t * The content to use for replacement operations.\n\t * When exact match: original content. When fuzzy match: normalized content.\n\t */\n\tcontentForReplacement: string;\n}\n\nexport interface Edit {\n\toldText: string;\n\tnewText: string;\n}\n\ninterface MatchedEdit {\n\teditIndex: number;\n\tmatchIndex: number;\n\tmatchLength: number;\n\tnewText: string;\n}\n\nexport interface AppliedEditsResult {\n\tbaseContent: string;\n\tnewContent: string;\n}\n\n/**\n * Find oldText in content, trying exact match first, then fuzzy match.\n * When fuzzy matching is used, the returned contentForReplacement is the\n * fuzzy-normalized version of the content (trailing whitespace stripped,\n * Unicode quotes/dashes normalized to ASCII).\n */\nexport function fuzzyFindText(content: string, oldText: string): FuzzyMatchResult {\n\t// Try exact match first\n\tconst exactIndex = content.indexOf(oldText);\n\tif (exactIndex !== -1) {\n\t\treturn {\n\t\t\tfound: true,\n\t\t\tindex: exactIndex,\n\t\t\tmatchLength: oldText.length,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\n\t// Try fuzzy match - work entirely in normalized space\n\tconst fuzzyContent = normalizeForFuzzyMatch(content);\n\tconst fuzzyOldText = normalizeForFuzzyMatch(oldText);\n\tconst fuzzyIndex = fuzzyContent.indexOf(fuzzyOldText);\n\n\tif (fuzzyIndex === -1) {\n\t\treturn {\n\t\t\tfound: false,\n\t\t\tindex: -1,\n\t\t\tmatchLength: 0,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\n\t// When fuzzy matching, we work in the normalized space for replacement.\n\t// This means the output will have normalized whitespace/quotes/dashes,\n\t// which is acceptable since we're fixing minor formatting differences anyway.\n\treturn {\n\t\tfound: true,\n\t\tindex: fuzzyIndex,\n\t\tmatchLength: fuzzyOldText.length,\n\t\tusedFuzzyMatch: true,\n\t\tcontentForReplacement: fuzzyContent,\n\t};\n}\n\n/** Strip UTF-8 BOM if present, return both the BOM (if any) and the text without it */\nexport function stripBom(content: string): { bom: string; text: string } {\n\treturn content.startsWith(\"\\uFEFF\") ? { bom: \"\\uFEFF\", text: content.slice(1) } : { bom: \"\", text: content };\n}\n\nfunction countOccurrences(content: string, oldText: string): number {\n\tconst fuzzyContent = normalizeForFuzzyMatch(content);\n\tconst fuzzyOldText = normalizeForFuzzyMatch(oldText);\n\treturn fuzzyContent.split(fuzzyOldText).length - 1;\n}\n\nfunction getNotFoundError(path: string, editIndex: number, totalEdits: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\t\t\t`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`,\n\t\t);\n\t}\n\treturn new Error(\n\t\t`Could not find edits[${editIndex}] in ${path}. The oldText must match exactly including all whitespace and newlines.`,\n\t);\n}\n\nfunction getDuplicateError(path: string, editIndex: number, totalEdits: number, occurrences: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\t\t\t`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`,\n\t\t);\n\t}\n\treturn new Error(\n\t\t`Found ${occurrences} occurrences of edits[${editIndex}] in ${path}. Each oldText must be unique. Please provide more context to make it unique.`,\n\t);\n}\n\nfunction getEmptyOldTextError(path: string, editIndex: number, totalEdits: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(`oldText must not be empty in ${path}.`);\n\t}\n\treturn new Error(`edits[${editIndex}].oldText must not be empty in ${path}.`);\n}\n\nfunction getNoChangeError(path: string, totalEdits: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\t\t\t`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`,\n\t\t);\n\t}\n\treturn new Error(`No changes made to ${path}. The replacements produced identical content.`);\n}\n\n/**\n * Apply one or more exact-text replacements to LF-normalized content.\n *\n * All edits are matched against the same original content. Replacements are\n * then applied in reverse order so offsets remain stable. If any edit needs\n * fuzzy matching, the operation runs in fuzzy-normalized content space to\n * preserve current single-edit behavior.\n */\nexport function applyEditsToNormalizedContent(\n\tnormalizedContent: string,\n\tedits: Edit[],\n\tpath: string,\n): AppliedEditsResult {\n\tconst normalizedEdits = edits.map((edit) => ({\n\t\toldText: normalizeToLF(edit.oldText),\n\t\tnewText: normalizeToLF(edit.newText),\n\t}));\n\n\tfor (let i = 0; i < normalizedEdits.length; i++) {\n\t\tif (normalizedEdits[i].oldText.length === 0) {\n\t\t\tthrow getEmptyOldTextError(path, i, normalizedEdits.length);\n\t\t}\n\t}\n\n\tconst initialMatches = normalizedEdits.map((edit) => fuzzyFindText(normalizedContent, edit.oldText));\n\tconst baseContent = initialMatches.some((match) => match.usedFuzzyMatch)\n\t\t? normalizeForFuzzyMatch(normalizedContent)\n\t\t: normalizedContent;\n\n\tconst matchedEdits: MatchedEdit[] = [];\n\tfor (let i = 0; i < normalizedEdits.length; i++) {\n\t\tconst edit = normalizedEdits[i];\n\t\tconst matchResult = fuzzyFindText(baseContent, edit.oldText);\n\t\tif (!matchResult.found) {\n\t\t\tthrow getNotFoundError(path, i, normalizedEdits.length);\n\t\t}\n\n\t\tconst occurrences = countOccurrences(baseContent, edit.oldText);\n\t\tif (occurrences > 1) {\n\t\t\tthrow getDuplicateError(path, i, normalizedEdits.length, occurrences);\n\t\t}\n\n\t\tmatchedEdits.push({\n\t\t\teditIndex: i,\n\t\t\tmatchIndex: matchResult.index,\n\t\t\tmatchLength: matchResult.matchLength,\n\t\t\tnewText: edit.newText,\n\t\t});\n\t}\n\n\tmatchedEdits.sort((a, b) => a.matchIndex - b.matchIndex);\n\tfor (let i = 1; i < matchedEdits.length; i++) {\n\t\tconst previous = matchedEdits[i - 1];\n\t\tconst current = matchedEdits[i];\n\t\tif (previous.matchIndex + previous.matchLength > current.matchIndex) {\n\t\t\tthrow new Error(\n\t\t\t\t`edits[${previous.editIndex}] and edits[${current.editIndex}] overlap in ${path}. Merge them into one edit or target disjoint regions.`,\n\t\t\t);\n\t\t}\n\t}\n\n\tlet newContent = baseContent;\n\tfor (let i = matchedEdits.length - 1; i >= 0; i--) {\n\t\tconst edit = matchedEdits[i];\n\t\tnewContent =\n\t\t\tnewContent.substring(0, edit.matchIndex) +\n\t\t\tedit.newText +\n\t\t\tnewContent.substring(edit.matchIndex + edit.matchLength);\n\t}\n\n\tif (baseContent === newContent) {\n\t\tthrow getNoChangeError(path, normalizedEdits.length);\n\t}\n\n\treturn { baseContent, newContent };\n}\n\n/**\n * Generate a unified diff string with line numbers and context.\n * Returns both the diff string and the first changed line number (in the new file).\n */\nexport function generateDiffString(\n\toldContent: string,\n\tnewContent: string,\n\tcontextLines = 4,\n): { diff: string; firstChangedLine: number | undefined } {\n\tconst parts = Diff.diffLines(oldContent, newContent);\n\tconst output: string[] = [];\n\n\tconst oldLines = oldContent.split(\"\\n\");\n\tconst newLines = newContent.split(\"\\n\");\n\tconst maxLineNum = Math.max(oldLines.length, newLines.length);\n\tconst lineNumWidth = String(maxLineNum).length;\n\n\tlet oldLineNum = 1;\n\tlet newLineNum = 1;\n\tlet lastWasChange = false;\n\tlet firstChangedLine: number | undefined;\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tconst raw = part.value.split(\"\\n\");\n\t\tif (raw[raw.length - 1] === \"\") {\n\t\t\traw.pop();\n\t\t}\n\n\t\tif (part.added || part.removed) {\n\t\t\t// Capture the first changed line (in the new file)\n\t\t\tif (firstChangedLine === undefined) {\n\t\t\t\tfirstChangedLine = newLineNum;\n\t\t\t}\n\n\t\t\t// Show the change\n\t\t\tfor (const line of raw) {\n\t\t\t\tif (part.added) {\n\t\t\t\t\tconst lineNum = String(newLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`+${lineNum} ${line}`);\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t} else {\n\t\t\t\t\t// removed\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`-${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlastWasChange = true;\n\t\t} else {\n\t\t\t// Context lines - only show a few before/after changes\n\t\t\tconst nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);\n\t\t\tconst hasLeadingChange = lastWasChange;\n\t\t\tconst hasTrailingChange = nextPartIsChange;\n\n\t\t\tif (hasLeadingChange && hasTrailingChange) {\n\t\t\t\tif (raw.length <= contextLines * 2) {\n\t\t\t\t\tfor (const line of raw) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst leadingLines = raw.slice(0, contextLines);\n\t\t\t\t\tconst trailingLines = raw.slice(raw.length - contextLines);\n\t\t\t\t\tconst skippedLines = raw.length - leadingLines.length - trailingLines.length;\n\n\t\t\t\t\tfor (const line of leadingLines) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\n\t\t\t\t\tfor (const line of trailingLines) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (hasLeadingChange) {\n\t\t\t\tconst shownLines = raw.slice(0, contextLines);\n\t\t\t\tconst skippedLines = raw.length - shownLines.length;\n\n\t\t\t\tfor (const line of shownLines) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\n\t\t\t\tif (skippedLines > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\t\t\t\t}\n\t\t\t} else if (hasTrailingChange) {\n\t\t\t\tconst skippedLines = Math.max(0, raw.length - contextLines);\n\t\t\t\tif (skippedLines > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\t\t\t\t}\n\n\t\t\t\tfor (const line of raw.slice(skippedLines)) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Skip these context lines entirely\n\t\t\t\toldLineNum += raw.length;\n\t\t\t\tnewLineNum += raw.length;\n\t\t\t}\n\n\t\t\tlastWasChange = false;\n\t\t}\n\t}\n\n\treturn { diff: output.join(\"\\n\"), firstChangedLine };\n}\n\nexport interface EditDiffResult {\n\tdiff: string;\n\tfirstChangedLine: number | undefined;\n}\n\nexport interface EditDiffError {\n\terror: string;\n}\n\n/**\n * Compute the diff for one or more edit operations without applying them.\n * Used for preview rendering in the TUI before the tool executes.\n */\nexport async function computeEditsDiff(\n\tpath: string,\n\tedits: Edit[],\n\tcwd: string,\n): Promise<EditDiffResult | EditDiffError> {\n\tconst absolutePath = resolveToCwd(path, cwd);\n\n\ttry {\n\t\t// Check if file exists and is readable\n\t\ttry {\n\t\t\tawait access(absolutePath, constants.R_OK);\n\t\t} catch {\n\t\t\treturn { error: `File not found: ${path}` };\n\t\t}\n\n\t\t// Read the file\n\t\tconst rawContent = await readFile(absolutePath, \"utf-8\");\n\n\t\t// Strip BOM before matching (LLM won't include invisible BOM in oldText)\n\t\tconst { text: content } = stripBom(rawContent);\n\t\tconst normalizedContent = normalizeToLF(content);\n\t\tconst { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);\n\n\t\t// Generate the diff\n\t\treturn generateDiffString(baseContent, newContent);\n\t} catch (err) {\n\t\treturn { error: err instanceof Error ? err.message : String(err) };\n\t}\n}\n\n/**\n * Compute the diff for a single edit operation without applying it.\n * Kept as a convenience wrapper for single-edit callers.\n */\nexport async function computeEditDiff(\n\tpath: string,\n\toldText: string,\n\tnewText: string,\n\tcwd: string,\n): Promise<EditDiffResult | EditDiffError> {\n\treturn computeEditsDiff(path, [{ oldText, newText }], cwd);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"edit-diff.js","sourceRoot":"","sources":["../../../src/core/tools/edit-diff.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared diff computation utilities for the edit tool.\n * Used by both edit.ts (for execution) and tool-execution.ts (for preview rendering).\n */\n\nimport * as Diff from \"diff\";\nimport { constants } from \"fs\";\nimport { access, readFile } from \"fs/promises\";\nimport { resolveToCwd } from \"./path-utils.js\";\n\nexport function detectLineEnding(content: string): \"\\r\\n\" | \"\\n\" {\n\tconst crlfIdx = content.indexOf(\"\\r\\n\");\n\tconst lfIdx = content.indexOf(\"\\n\");\n\tif (lfIdx === -1) return \"\\n\";\n\tif (crlfIdx === -1) return \"\\n\";\n\treturn crlfIdx < lfIdx ? \"\\r\\n\" : \"\\n\";\n}\n\nexport function normalizeToLF(text: string): string {\n\treturn text.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n}\n\nexport function restoreLineEndings(text: string, ending: \"\\r\\n\" | \"\\n\"): string {\n\treturn ending === \"\\r\\n\" ? text.replace(/\\n/g, \"\\r\\n\") : text;\n}\n\n/**\n * Normalize text for fuzzy matching. Applies progressive transformations:\n * - Strip trailing whitespace from each line\n * - Normalize smart quotes to ASCII equivalents\n * - Normalize Unicode dashes/hyphens to ASCII hyphen\n * - Normalize special Unicode spaces to regular space\n */\nexport function normalizeForFuzzyMatch(text: string): string {\n\treturn (\n\t\ttext\n\t\t\t.normalize(\"NFKC\")\n\t\t\t// Strip trailing whitespace per line\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => line.trimEnd())\n\t\t\t.join(\"\\n\")\n\t\t\t// Smart single quotes → '\n\t\t\t.replace(/[\\u2018\\u2019\\u201A\\u201B]/g, \"'\")\n\t\t\t// Smart double quotes → \"\n\t\t\t.replace(/[\\u201C\\u201D\\u201E\\u201F]/g, '\"')\n\t\t\t// Various dashes/hyphens → -\n\t\t\t// U+2010 hyphen, U+2011 non-breaking hyphen, U+2012 figure dash,\n\t\t\t// U+2013 en-dash, U+2014 em-dash, U+2015 horizontal bar, U+2212 minus\n\t\t\t.replace(/[\\u2010\\u2011\\u2012\\u2013\\u2014\\u2015\\u2212]/g, \"-\")\n\t\t\t// Special spaces → regular space\n\t\t\t// U+00A0 NBSP, U+2002-U+200A various spaces, U+202F narrow NBSP,\n\t\t\t// U+205F medium math space, U+3000 ideographic space\n\t\t\t.replace(/[\\u00A0\\u2002-\\u200A\\u202F\\u205F\\u3000]/g, \" \")\n\t);\n}\n\nexport interface FuzzyMatchResult {\n\t/** Whether a match was found */\n\tfound: boolean;\n\t/** The index where the match starts (in the content that should be used for replacement) */\n\tindex: number;\n\t/** Length of the matched text */\n\tmatchLength: number;\n\t/** Whether fuzzy matching was used (false = exact match) */\n\tusedFuzzyMatch: boolean;\n\t/**\n\t * The content to use for replacement operations.\n\t * When exact match: original content. When fuzzy match: normalized content.\n\t */\n\tcontentForReplacement: string;\n}\n\nexport interface Edit {\n\toldText: string;\n\tnewText: string;\n}\n\ninterface MatchedEdit {\n\teditIndex: number;\n\tmatchIndex: number;\n\tmatchLength: number;\n\tnewText: string;\n}\n\nexport interface AppliedEditsResult {\n\tbaseContent: string;\n\tnewContent: string;\n}\n\n/**\n * Find oldText in content, trying exact match first, then fuzzy match.\n * When fuzzy matching is used, the returned contentForReplacement is the\n * fuzzy-normalized version of the content (trailing whitespace stripped,\n * Unicode quotes/dashes normalized to ASCII).\n */\nexport function fuzzyFindText(content: string, oldText: string): FuzzyMatchResult {\n\t// Try exact match first\n\tconst exactIndex = content.indexOf(oldText);\n\tif (exactIndex !== -1) {\n\t\treturn {\n\t\t\tfound: true,\n\t\t\tindex: exactIndex,\n\t\t\tmatchLength: oldText.length,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\n\t// Try fuzzy match - work entirely in normalized space\n\tconst fuzzyContent = normalizeForFuzzyMatch(content);\n\tconst fuzzyOldText = normalizeForFuzzyMatch(oldText);\n\tconst fuzzyIndex = fuzzyContent.indexOf(fuzzyOldText);\n\n\tif (fuzzyIndex === -1) {\n\t\treturn {\n\t\t\tfound: false,\n\t\t\tindex: -1,\n\t\t\tmatchLength: 0,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\n\t// When fuzzy matching, we work in the normalized space for replacement.\n\t// This means the output will have normalized whitespace/quotes/dashes,\n\t// which is acceptable since we're fixing minor formatting differences anyway.\n\treturn {\n\t\tfound: true,\n\t\tindex: fuzzyIndex,\n\t\tmatchLength: fuzzyOldText.length,\n\t\tusedFuzzyMatch: true,\n\t\tcontentForReplacement: fuzzyContent,\n\t};\n}\n\n/** Strip UTF-8 BOM if present, return both the BOM (if any) and the text without it */\nexport function stripBom(content: string): { bom: string; text: string } {\n\treturn content.startsWith(\"\\uFEFF\") ? { bom: \"\\uFEFF\", text: content.slice(1) } : { bom: \"\", text: content };\n}\n\nfunction countOccurrences(content: string, oldText: string): number {\n\tconst fuzzyContent = normalizeForFuzzyMatch(content);\n\tconst fuzzyOldText = normalizeForFuzzyMatch(oldText);\n\treturn fuzzyContent.split(fuzzyOldText).length - 1;\n}\n\nfunction getNotFoundError(path: string, editIndex: number, totalEdits: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\t\t\t`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`,\n\t\t);\n\t}\n\treturn new Error(\n\t\t`Could not find edits[${editIndex}] in ${path}. The oldText must match exactly including all whitespace and newlines.`,\n\t);\n}\n\nfunction getDuplicateError(path: string, editIndex: number, totalEdits: number, occurrences: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\t\t\t`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`,\n\t\t);\n\t}\n\treturn new Error(\n\t\t`Found ${occurrences} occurrences of edits[${editIndex}] in ${path}. Each oldText must be unique. Please provide more context to make it unique.`,\n\t);\n}\n\nfunction getEmptyOldTextError(path: string, editIndex: number, totalEdits: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(`oldText must not be empty in ${path}.`);\n\t}\n\treturn new Error(`edits[${editIndex}].oldText must not be empty in ${path}.`);\n}\n\nfunction getNoChangeError(path: string, totalEdits: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\t\t\t`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`,\n\t\t);\n\t}\n\treturn new Error(`No changes made to ${path}. The replacements produced identical content.`);\n}\n\n/**\n * Apply one or more exact-text replacements to LF-normalized content.\n *\n * All edits are matched against the same original content. Replacements are\n * then applied in reverse order so offsets remain stable. If any edit needs\n * fuzzy matching, the operation runs in fuzzy-normalized content space to\n * preserve current single-edit behavior.\n */\nexport function applyEditsToNormalizedContent(\n\tnormalizedContent: string,\n\tedits: Edit[],\n\tpath: string,\n): AppliedEditsResult {\n\tconst normalizedEdits = edits.map((edit) => ({\n\t\toldText: normalizeToLF(edit.oldText),\n\t\tnewText: normalizeToLF(edit.newText),\n\t}));\n\n\tfor (let i = 0; i < normalizedEdits.length; i++) {\n\t\tif (normalizedEdits[i].oldText.length === 0) {\n\t\t\tthrow getEmptyOldTextError(path, i, normalizedEdits.length);\n\t\t}\n\t}\n\n\tconst initialMatches = normalizedEdits.map((edit) => fuzzyFindText(normalizedContent, edit.oldText));\n\tconst baseContent = initialMatches.some((match) => match.usedFuzzyMatch)\n\t\t? normalizeForFuzzyMatch(normalizedContent)\n\t\t: normalizedContent;\n\n\tconst matchedEdits: MatchedEdit[] = [];\n\tfor (let i = 0; i < normalizedEdits.length; i++) {\n\t\tconst edit = normalizedEdits[i];\n\t\tconst matchResult = fuzzyFindText(baseContent, edit.oldText);\n\t\tif (!matchResult.found) {\n\t\t\tthrow getNotFoundError(path, i, normalizedEdits.length);\n\t\t}\n\n\t\tconst occurrences = countOccurrences(baseContent, edit.oldText);\n\t\tif (occurrences > 1) {\n\t\t\tthrow getDuplicateError(path, i, normalizedEdits.length, occurrences);\n\t\t}\n\n\t\tmatchedEdits.push({\n\t\t\teditIndex: i,\n\t\t\tmatchIndex: matchResult.index,\n\t\t\tmatchLength: matchResult.matchLength,\n\t\t\tnewText: edit.newText,\n\t\t});\n\t}\n\n\tmatchedEdits.sort((a, b) => a.matchIndex - b.matchIndex);\n\tfor (let i = 1; i < matchedEdits.length; i++) {\n\t\tconst previous = matchedEdits[i - 1];\n\t\tconst current = matchedEdits[i];\n\t\tif (previous.matchIndex + previous.matchLength > current.matchIndex) {\n\t\t\tthrow new Error(\n\t\t\t\t`edits[${previous.editIndex}] and edits[${current.editIndex}] overlap in ${path}. Merge them into one edit or target disjoint regions.`,\n\t\t\t);\n\t\t}\n\t}\n\n\tlet newContent = baseContent;\n\tfor (let i = matchedEdits.length - 1; i >= 0; i--) {\n\t\tconst edit = matchedEdits[i];\n\t\tnewContent =\n\t\t\tnewContent.substring(0, edit.matchIndex) +\n\t\t\tedit.newText +\n\t\t\tnewContent.substring(edit.matchIndex + edit.matchLength);\n\t}\n\n\tif (baseContent === newContent) {\n\t\tthrow getNoChangeError(path, normalizedEdits.length);\n\t}\n\n\treturn { baseContent, newContent };\n}\n\n/**\n * Generate a unified diff string with line numbers and context.\n * Returns both the diff string and the first changed line number (in the new file).\n */\nexport function generateDiffString(\n\toldContent: string,\n\tnewContent: string,\n\tcontextLines = 4,\n): { diff: string; firstChangedLine: number | undefined } {\n\tconst parts = Diff.diffLines(oldContent, newContent);\n\tconst output: string[] = [];\n\n\tconst oldLines = oldContent.split(\"\\n\");\n\tconst newLines = newContent.split(\"\\n\");\n\tconst maxLineNum = Math.max(oldLines.length, newLines.length);\n\tconst lineNumWidth = String(maxLineNum).length;\n\n\tlet oldLineNum = 1;\n\tlet newLineNum = 1;\n\tlet lastWasChange = false;\n\tlet firstChangedLine: number | undefined;\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tconst raw = part.value.split(\"\\n\");\n\t\tif (raw[raw.length - 1] === \"\") {\n\t\t\traw.pop();\n\t\t}\n\n\t\tif (part.added || part.removed) {\n\t\t\t// Capture the first changed line (in the new file)\n\t\t\tif (firstChangedLine === undefined) {\n\t\t\t\tfirstChangedLine = newLineNum;\n\t\t\t}\n\n\t\t\t// Show the change\n\t\t\tfor (const line of raw) {\n\t\t\t\tif (part.added) {\n\t\t\t\t\tconst lineNum = String(newLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`+${lineNum} ${line}`);\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t} else {\n\t\t\t\t\t// removed\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`-${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlastWasChange = true;\n\t\t} else {\n\t\t\t// Context lines - only show a few before/after changes\n\t\t\tconst nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);\n\t\t\tconst hasLeadingChange = lastWasChange;\n\t\t\tconst hasTrailingChange = nextPartIsChange;\n\n\t\t\tif (hasLeadingChange && hasTrailingChange) {\n\t\t\t\tif (raw.length <= contextLines * 2) {\n\t\t\t\t\tfor (const line of raw) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst leadingLines = raw.slice(0, contextLines);\n\t\t\t\t\tconst trailingLines = raw.slice(raw.length - contextLines);\n\t\t\t\t\tconst skippedLines = raw.length - leadingLines.length - trailingLines.length;\n\n\t\t\t\t\tfor (const line of leadingLines) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\n\t\t\t\t\tfor (const line of trailingLines) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (hasLeadingChange) {\n\t\t\t\tconst shownLines = raw.slice(0, contextLines);\n\t\t\t\tconst skippedLines = raw.length - shownLines.length;\n\n\t\t\t\tfor (const line of shownLines) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\n\t\t\t\tif (skippedLines > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\t\t\t\t}\n\t\t\t} else if (hasTrailingChange) {\n\t\t\t\tconst skippedLines = Math.max(0, raw.length - contextLines);\n\t\t\t\tif (skippedLines > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\t\t\t\t}\n\n\t\t\t\tfor (const line of raw.slice(skippedLines)) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Skip these context lines entirely\n\t\t\t\toldLineNum += raw.length;\n\t\t\t\tnewLineNum += raw.length;\n\t\t\t}\n\n\t\t\tlastWasChange = false;\n\t\t}\n\t}\n\n\treturn { diff: output.join(\"\\n\"), firstChangedLine };\n}\n\nexport interface EditDiffResult {\n\tdiff: string;\n\tfirstChangedLine: number | undefined;\n}\n\nexport interface EditDiffError {\n\terror: string;\n}\n\n/**\n * Compute the diff for one or more edit operations without applying them.\n * Used for preview rendering in the TUI before the tool executes.\n */\nexport async function computeEditsDiff(\n\tpath: string,\n\tedits: Edit[],\n\tcwd: string,\n): Promise<EditDiffResult | EditDiffError> {\n\tconst absolutePath = resolveToCwd(path, cwd);\n\n\ttry {\n\t\t// Check if file exists and is readable\n\t\ttry {\n\t\t\tawait access(absolutePath, constants.R_OK);\n\t\t} catch {\n\t\t\treturn { error: `File not found: ${path}` };\n\t\t}\n\n\t\t// Read the file\n\t\tconst rawContent = await readFile(absolutePath, \"utf-8\");\n\n\t\t// Strip BOM before matching (LLM won't include invisible BOM in oldText)\n\t\tconst { text: content } = stripBom(rawContent);\n\t\tconst normalizedContent = normalizeToLF(content);\n\t\tconst { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);\n\n\t\t// Generate the diff\n\t\treturn generateDiffString(baseContent, newContent);\n\t} catch (err) {\n\t\treturn { error: err instanceof Error ? err.message : String(err) };\n\t}\n}\n\n/**\n * Compute the diff for a single edit operation without applying it.\n * Kept as a convenience wrapper for single-edit callers.\n */\nexport async function computeEditDiff(\n\tpath: string,\n\toldText: string,\n\tnewText: string,\n\tcwd: string,\n): Promise<EditDiffResult | EditDiffError> {\n\treturn computeEditsDiff(path, [{ oldText, newText }], cwd);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAItD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAe7D,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAa7C,QAAA,MAAM,UAAU;;;;;;EASf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAMtD,MAAM,WAAW,eAAe;IAC/B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,qCAAqC;IACrC,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,8BAA8B;IAC9B,SAAS,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,4DAA4D;IAC5D,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAQD,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAwED,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,EAAE,eAAe,CAAC,CA+IjF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG;AAED,yEAAyE;AACzE,eAAO,MAAM,kBAAkB;;;;;;iDAA0C,CAAC;AAC1E,eAAO,MAAM,QAAQ;;;;;;QAAgC,CAAC","sourcesContent":["import type { AgentTool } from \"@orient-cli/agent-core\";\nimport { Container, Text } from \"@orient-cli/tui\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from \"fs/promises\";\nimport { renderDiff } from \"../../modes/interactive/components/diff.js\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport {\n\tapplyEditsToNormalizedContent,\n\tdetectLineEnding,\n\ttype Edit,\n\tgenerateDiffString,\n\tnormalizeToLF,\n\trestoreLineEndings,\n\tstripBom,\n} from \"./edit-diff.js\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\n\ntype EditRenderState = Record<string, never>;\n\nconst replaceEditSchema = Type.Object(\n\t{\n\t\toldText: Type.String({\n\t\t\tdescription:\n\t\t\t\t\"Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call.\",\n\t\t}),\n\t\tnewText: Type.String({ description: \"Replacement text for this targeted edit.\" }),\n\t},\n\t{ additionalProperties: false },\n);\n\nconst editSchema = Type.Object(\n\t{\n\t\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\t\tedits: Type.Array(replaceEditSchema, {\n\t\t\tdescription:\n\t\t\t\t\"One or more targeted replacements. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead.\",\n\t\t}),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type EditToolInput = Static<typeof editSchema>;\ntype LegacyEditToolInput = EditToolInput & {\n\toldText?: unknown;\n\tnewText?: unknown;\n};\n\nexport interface EditToolDetails {\n\t/** Unified diff of the changes made */\n\tdiff: string;\n\t/** Line number of the first change in the new file (for editor navigation) */\n\tfirstChangedLine?: number;\n}\n\n/**\n * Pluggable operations for the edit tool.\n * Override these to delegate file editing to remote systems (for example SSH).\n */\nexport interface EditOperations {\n\t/** Read file contents as a Buffer */\n\treadFile: (absolutePath: string) => Promise<Buffer>;\n\t/** Write content to a file */\n\twriteFile: (absolutePath: string, content: string) => Promise<void>;\n\t/** Check if file is readable and writable (throw if not) */\n\taccess: (absolutePath: string) => Promise<void>;\n}\n\nconst defaultEditOperations: EditOperations = {\n\treadFile: (path) => fsReadFile(path),\n\twriteFile: (path, content) => fsWriteFile(path, content, \"utf-8\"),\n\taccess: (path) => fsAccess(path, constants.R_OK | constants.W_OK),\n};\n\nexport interface EditToolOptions {\n\t/** Custom operations for file editing. Default: local filesystem */\n\toperations?: EditOperations;\n}\n\nfunction prepareEditArguments(input: unknown): EditToolInput {\n\tif (!input || typeof input !== \"object\") {\n\t\treturn input as EditToolInput;\n\t}\n\n\tconst args = input as LegacyEditToolInput;\n\tif (typeof args.oldText !== \"string\" || typeof args.newText !== \"string\") {\n\t\treturn input as EditToolInput;\n\t}\n\n\tconst edits = Array.isArray(args.edits) ? [...args.edits] : [];\n\tedits.push({ oldText: args.oldText, newText: args.newText });\n\tconst { oldText: _oldText, newText: _newText, ...rest } = args;\n\treturn { ...rest, edits } as EditToolInput;\n}\n\nfunction validateEditInput(input: EditToolInput): { path: string; edits: Edit[] } {\n\tif (!Array.isArray(input.edits) || input.edits.length === 0) {\n\t\tthrow new Error(\"Edit tool input is invalid. edits must contain at least one replacement.\");\n\t}\n\treturn { path: input.path, edits: input.edits };\n}\n\ntype RenderableEditArgs = {\n\tpath?: string;\n\tfile_path?: string;\n\tedits?: Edit[];\n\toldText?: string;\n\tnewText?: string;\n};\n\nfunction formatEditCall(\n\targs: RenderableEditArgs | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst invalidArg = invalidArgText(theme);\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath) : null;\n\tconst pathDisplay = path === null ? invalidArg : path ? theme.fg(\"accent\", path) : theme.fg(\"toolOutput\", \"...\");\n\treturn `${theme.fg(\"toolTitle\", theme.bold(\"edit\"))} ${pathDisplay}`;\n}\n\nfunction formatEditResult(\n\targs: RenderableEditArgs | undefined,\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: EditToolDetails;\n\t},\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tisError: boolean,\n): string | undefined {\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tif (isError) {\n\t\tconst errorText = result.content\n\t\t\t.filter((c) => c.type === \"text\")\n\t\t\t.map((c) => c.text || \"\")\n\t\t\t.join(\"\\n\");\n\t\tif (!errorText) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn `\\n${theme.fg(\"error\", errorText)}`;\n\t}\n\n\tconst resultDiff = result.details?.diff;\n\tif (!resultDiff) {\n\t\treturn undefined;\n\t}\n\treturn `\\n${renderDiff(resultDiff, { filePath: rawPath ?? undefined })}`;\n}\n\nexport function createEditToolDefinition(\n\tcwd: string,\n\toptions?: EditToolOptions,\n): ToolDefinition<typeof editSchema, EditToolDetails | undefined, EditRenderState> {\n\tconst ops = options?.operations ?? defaultEditOperations;\n\treturn {\n\t\tname: \"edit\",\n\t\tlabel: \"edit\",\n\t\tdescription:\n\t\t\t\"Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.\",\n\t\tpromptSnippet:\n\t\t\t\"Make precise file edits with exact text replacement, including multiple disjoint edits in one call\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use edit for precise changes (edits[].oldText must match exactly)\",\n\t\t\t\"When changing multiple separate locations in one file, use one edit call with multiple entries in edits[] instead of multiple edit calls\",\n\t\t\t\"Each edits[].oldText is matched against the original file, not after earlier edits are applied. Do not emit overlapping or nested edits. Merge nearby changes into one edit.\",\n\t\t\t\"Keep edits[].oldText as small as possible while still being unique in the file. Do not pad with large unchanged regions.\",\n\t\t],\n\t\tparameters: editSchema,\n\t\tprepareArguments: prepareEditArguments,\n\t\tasync execute(_toolCallId, input: EditToolInput, signal?: AbortSignal, _onUpdate?, _ctx?) {\n\t\t\tconst { path, edits } = validateEditInput(input);\n\t\t\tconst absolutePath = resolveToCwd(path, cwd);\n\n\t\t\treturn withFileMutationQueue(\n\t\t\t\tabsolutePath,\n\t\t\t\t() =>\n\t\t\t\t\tnew Promise<{\n\t\t\t\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\t\t\t\tdetails: EditToolDetails | undefined;\n\t\t\t\t\t}>((resolve, reject) => {\n\t\t\t\t\t\t// Check if already aborted.\n\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet aborted = false;\n\n\t\t\t\t\t\t// Set up abort handler.\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Perform the edit operation.\n\t\t\t\t\t\tvoid (async () => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Check if file exists.\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treject(new Error(`File not found: ${path}`));\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Check if aborted before reading.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Read the file.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tconst rawContent = buffer.toString(\"utf-8\");\n\n\t\t\t\t\t\t\t\t// Check if aborted after reading.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Strip BOM before matching. The model will not include an invisible BOM in oldText.\n\t\t\t\t\t\t\t\tconst { bom, text: content } = stripBom(rawContent);\n\t\t\t\t\t\t\t\tconst originalEnding = detectLineEnding(content);\n\t\t\t\t\t\t\t\tconst normalizedContent = normalizeToLF(content);\n\t\t\t\t\t\t\t\tconst { baseContent, newContent } = applyEditsToNormalizedContent(\n\t\t\t\t\t\t\t\t\tnormalizedContent,\n\t\t\t\t\t\t\t\t\tedits,\n\t\t\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t// Check if aborted before writing.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst finalContent = bom + restoreLineEndings(newContent, originalEnding);\n\t\t\t\t\t\t\t\tawait ops.writeFile(absolutePath, finalContent);\n\n\t\t\t\t\t\t\t\t// Check if aborted after writing.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Clean up abort handler.\n\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst diffResult = generateDiffString(baseContent, newContent);\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\t\ttext: `Successfully replaced ${edits.length} block(s) in ${path}.`,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\tdetails: { diff: diffResult.diff, firstChangedLine: diffResult.firstChangedLine },\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\t\t\t// Clean up abort handler.\n\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (!aborted) {\n\t\t\t\t\t\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})();\n\t\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatEditCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, _options, theme, context) {\n\t\t\tconst output = formatEditResult(context.args, result as any, theme, context.isError);\n\t\t\tif (!output) {\n\t\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\t\tcomponent.clear();\n\t\t\t\treturn component;\n\t\t\t}\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(output);\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createEditTool(cwd: string, options?: EditToolOptions): AgentTool<typeof editSchema> {\n\treturn wrapToolDefinition(createEditToolDefinition(cwd, options));\n}\n\n/** Default edit tool using process.cwd() for backwards compatibility. */\nexport const editToolDefinition = createEditToolDefinition(process.cwd());\nexport const editTool = createEditTool(process.cwd());\n"]}
|
|
1
|
+
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAItD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAe7D,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAa7C,QAAA,MAAM,UAAU;;;;;;EASf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAMtD,MAAM,WAAW,eAAe;IAC/B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,qCAAqC;IACrC,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,8BAA8B;IAC9B,SAAS,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,4DAA4D;IAC5D,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAQD,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAwED,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,EAAE,eAAe,CAAC,CA+IjF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG;AAED,yEAAyE;AACzE,eAAO,MAAM,kBAAkB;;;;;;iDAA0C,CAAC;AAC1E,eAAO,MAAM,QAAQ;;;;;;QAAgC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@orient-cli/agent-core\";\nimport { Container, Text } from \"@orient-cli/tui\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from \"fs/promises\";\nimport { renderDiff } from \"../../modes/interactive/components/diff.js\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport {\n\tapplyEditsToNormalizedContent,\n\tdetectLineEnding,\n\ttype Edit,\n\tgenerateDiffString,\n\tnormalizeToLF,\n\trestoreLineEndings,\n\tstripBom,\n} from \"./edit-diff.js\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\n\ntype EditRenderState = Record<string, never>;\n\nconst replaceEditSchema = Type.Object(\n\t{\n\t\toldText: Type.String({\n\t\t\tdescription:\n\t\t\t\t\"Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call.\",\n\t\t}),\n\t\tnewText: Type.String({ description: \"Replacement text for this targeted edit.\" }),\n\t},\n\t{ additionalProperties: false },\n);\n\nconst editSchema = Type.Object(\n\t{\n\t\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\t\tedits: Type.Array(replaceEditSchema, {\n\t\t\tdescription:\n\t\t\t\t\"One or more targeted replacements. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead.\",\n\t\t}),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type EditToolInput = Static<typeof editSchema>;\ntype LegacyEditToolInput = EditToolInput & {\n\toldText?: unknown;\n\tnewText?: unknown;\n};\n\nexport interface EditToolDetails {\n\t/** Unified diff of the changes made */\n\tdiff: string;\n\t/** Line number of the first change in the new file (for editor navigation) */\n\tfirstChangedLine?: number;\n}\n\n/**\n * Pluggable operations for the edit tool.\n * Override these to delegate file editing to remote systems (for example SSH).\n */\nexport interface EditOperations {\n\t/** Read file contents as a Buffer */\n\treadFile: (absolutePath: string) => Promise<Buffer>;\n\t/** Write content to a file */\n\twriteFile: (absolutePath: string, content: string) => Promise<void>;\n\t/** Check if file is readable and writable (throw if not) */\n\taccess: (absolutePath: string) => Promise<void>;\n}\n\nconst defaultEditOperations: EditOperations = {\n\treadFile: (path) => fsReadFile(path),\n\twriteFile: (path, content) => fsWriteFile(path, content, \"utf-8\"),\n\taccess: (path) => fsAccess(path, constants.R_OK | constants.W_OK),\n};\n\nexport interface EditToolOptions {\n\t/** Custom operations for file editing. Default: local filesystem */\n\toperations?: EditOperations;\n}\n\nfunction prepareEditArguments(input: unknown): EditToolInput {\n\tif (!input || typeof input !== \"object\") {\n\t\treturn input as EditToolInput;\n\t}\n\n\tconst args = input as LegacyEditToolInput;\n\tif (typeof args.oldText !== \"string\" || typeof args.newText !== \"string\") {\n\t\treturn input as EditToolInput;\n\t}\n\n\tconst edits = Array.isArray(args.edits) ? [...args.edits] : [];\n\tedits.push({ oldText: args.oldText, newText: args.newText });\n\tconst { oldText: _oldText, newText: _newText, ...rest } = args;\n\treturn { ...rest, edits } as EditToolInput;\n}\n\nfunction validateEditInput(input: EditToolInput): { path: string; edits: Edit[] } {\n\tif (!Array.isArray(input.edits) || input.edits.length === 0) {\n\t\tthrow new Error(\"Edit tool input is invalid. edits must contain at least one replacement.\");\n\t}\n\treturn { path: input.path, edits: input.edits };\n}\n\ntype RenderableEditArgs = {\n\tpath?: string;\n\tfile_path?: string;\n\tedits?: Edit[];\n\toldText?: string;\n\tnewText?: string;\n};\n\nfunction formatEditCall(\n\targs: RenderableEditArgs | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst invalidArg = invalidArgText(theme);\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath) : null;\n\tconst pathDisplay = path === null ? invalidArg : path ? theme.fg(\"accent\", path) : theme.fg(\"toolOutput\", \"...\");\n\treturn `${theme.fg(\"toolTitle\", theme.bold(\"edit\"))} ${pathDisplay}`;\n}\n\nfunction formatEditResult(\n\targs: RenderableEditArgs | undefined,\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: EditToolDetails;\n\t},\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tisError: boolean,\n): string | undefined {\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tif (isError) {\n\t\tconst errorText = result.content\n\t\t\t.filter((c) => c.type === \"text\")\n\t\t\t.map((c) => c.text || \"\")\n\t\t\t.join(\"\\n\");\n\t\tif (!errorText) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn `\\n${theme.fg(\"error\", errorText)}`;\n\t}\n\n\tconst resultDiff = result.details?.diff;\n\tif (!resultDiff) {\n\t\treturn undefined;\n\t}\n\treturn `\\n${renderDiff(resultDiff, { filePath: rawPath ?? undefined })}`;\n}\n\nexport function createEditToolDefinition(\n\tcwd: string,\n\toptions?: EditToolOptions,\n): ToolDefinition<typeof editSchema, EditToolDetails | undefined, EditRenderState> {\n\tconst ops = options?.operations ?? defaultEditOperations;\n\treturn {\n\t\tname: \"edit\",\n\t\tlabel: \"edit\",\n\t\tdescription:\n\t\t\t\"Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.\",\n\t\tpromptSnippet:\n\t\t\t\"Make precise file edits with exact text replacement, including multiple disjoint edits in one call\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use edit for precise changes (edits[].oldText must match exactly)\",\n\t\t\t\"When changing multiple separate locations in one file, use one edit call with multiple entries in edits[] instead of multiple edit calls\",\n\t\t\t\"Each edits[].oldText is matched against the original file, not after earlier edits are applied. Do not emit overlapping or nested edits. Merge nearby changes into one edit.\",\n\t\t\t\"Keep edits[].oldText as small as possible while still being unique in the file. Do not pad with large unchanged regions.\",\n\t\t],\n\t\tparameters: editSchema,\n\t\tprepareArguments: prepareEditArguments,\n\t\tasync execute(_toolCallId, input: EditToolInput, signal?: AbortSignal, _onUpdate?, _ctx?) {\n\t\t\tconst { path, edits } = validateEditInput(input);\n\t\t\tconst absolutePath = resolveToCwd(path, cwd);\n\n\t\t\treturn withFileMutationQueue(\n\t\t\t\tabsolutePath,\n\t\t\t\t() =>\n\t\t\t\t\tnew Promise<{\n\t\t\t\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\t\t\t\tdetails: EditToolDetails | undefined;\n\t\t\t\t\t}>((resolve, reject) => {\n\t\t\t\t\t\t// Check if already aborted.\n\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet aborted = false;\n\n\t\t\t\t\t\t// Set up abort handler.\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Perform the edit operation.\n\t\t\t\t\t\tvoid (async () => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Check if file exists.\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treject(new Error(`File not found: ${path}`));\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Check if aborted before reading.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Read the file.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tconst rawContent = buffer.toString(\"utf-8\");\n\n\t\t\t\t\t\t\t\t// Check if aborted after reading.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Strip BOM before matching. The model will not include an invisible BOM in oldText.\n\t\t\t\t\t\t\t\tconst { bom, text: content } = stripBom(rawContent);\n\t\t\t\t\t\t\t\tconst originalEnding = detectLineEnding(content);\n\t\t\t\t\t\t\t\tconst normalizedContent = normalizeToLF(content);\n\t\t\t\t\t\t\t\tconst { baseContent, newContent } = applyEditsToNormalizedContent(\n\t\t\t\t\t\t\t\t\tnormalizedContent,\n\t\t\t\t\t\t\t\t\tedits,\n\t\t\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t// Check if aborted before writing.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst finalContent = bom + restoreLineEndings(newContent, originalEnding);\n\t\t\t\t\t\t\t\tawait ops.writeFile(absolutePath, finalContent);\n\n\t\t\t\t\t\t\t\t// Check if aborted after writing.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Clean up abort handler.\n\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst diffResult = generateDiffString(baseContent, newContent);\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\t\ttext: `Successfully replaced ${edits.length} block(s) in ${path}.`,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\tdetails: { diff: diffResult.diff, firstChangedLine: diffResult.firstChangedLine },\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\t\t\t// Clean up abort handler.\n\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (!aborted) {\n\t\t\t\t\t\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})();\n\t\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatEditCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, _options, theme, context) {\n\t\t\tconst output = formatEditResult(context.args, result as any, theme, context.isError);\n\t\t\tif (!output) {\n\t\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\t\tcomponent.clear();\n\t\t\t\treturn component;\n\t\t\t}\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(output);\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createEditTool(cwd: string, options?: EditToolOptions): AgentTool<typeof editSchema> {\n\treturn wrapToolDefinition(createEditToolDefinition(cwd, options));\n}\n\n/** Default edit tool using process.cwd() for backwards compatibility. */\nexport const editToolDefinition = createEditToolDefinition(process.cwd());\nexport const editTool = createEditTool(process.cwd());\n"]}
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAe,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,QAAQ,EAAE,QAAQ,IAAI,UAAU,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,MAAM,4CAA4C,CAAC;AAExE,OAAO,EACN,6BAA6B,EAC7B,gBAAgB,EAEhB,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,QAAQ,GACR,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAIlE,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,CACpC;IACC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;QACpB,WAAW,EACV,uJAAuJ;KACxJ,CAAC;IACF,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,0CAA0C,EAAE,CAAC;CACjF,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AAEF,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAC7B;IACC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;IACrF,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE;QACpC,WAAW,EACV,0OAA0O;KAC3O,CAAC;CACF,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AA4BF,MAAM,qBAAqB,GAAmB;IAC7C,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;IACpC,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC;IACjE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;CACjE,CAAC;AAOF,SAAS,oBAAoB,CAAC,KAAc;IAC3C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACzC,OAAO,KAAsB,CAAC;IAC/B,CAAC;IAED,MAAM,IAAI,GAAG,KAA4B,CAAC;IAC1C,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC1E,OAAO,KAAsB,CAAC;IAC/B,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7D,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IAC/D,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAmB,CAAC;AAC5C,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAoB;IAC9C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;AACjD,CAAC;AAUD,SAAS,cAAc,CACtB,IAAoC,EACpC,KAAoE;IAEpE,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,MAAM,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACjH,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC;AACtE,CAAC;AAED,SAAS,gBAAgB,CACxB,IAAoC,EACpC,MAGC,EACD,KAAoE,EACpE,OAAgB;IAEhB,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC;IACnD,IAAI,OAAO,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO;aAC9B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;aACxB,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,OAAO,KAAK,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC;IACxC,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,UAAU,CAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,OAAO,IAAI,SAAS,EAAE,CAAC,EAAE,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,wBAAwB,CACvC,GAAW,EACX,OAAyB;IAEzB,MAAM,GAAG,GAAG,OAAO,EAAE,UAAU,IAAI,qBAAqB,CAAC;IACzD,OAAO;QACN,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,MAAM;QACb,WAAW,EACV,wUAAwU;QACzU,aAAa,EACZ,oGAAoG;QACrG,gBAAgB,EAAE;YACjB,mEAAmE;YACnE,0IAA0I;YAC1I,8KAA8K;YAC9K,0HAA0H;SAC1H;QACD,UAAU,EAAE,UAAU;QACtB,gBAAgB,EAAE,oBAAoB;QACtC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAoB,EAAE,MAAoB,EAAE,SAAU,EAAE,IAAK;YACvF,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACjD,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAE7C,OAAO,qBAAqB,CAC3B,YAAY,EACZ,GAAG,EAAE,CACJ,IAAI,OAAO,CAGR,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACtB,4BAA4B;gBAC5B,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;oBACrB,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;oBACvC,OAAO;gBACR,CAAC;gBAED,IAAI,OAAO,GAAG,KAAK,CAAC;gBAEpB,wBAAwB;gBACxB,MAAM,OAAO,GAAG,GAAG,EAAE;oBACpB,OAAO,GAAG,IAAI,CAAC;oBACf,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBACxC,CAAC,CAAC;gBAEF,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3D,CAAC;gBAED,8BAA8B;gBAC9B,KAAK,CAAC,KAAK,IAAI,EAAE;oBAChB,IAAI,CAAC;wBACJ,wBAAwB;wBACxB,IAAI,CAAC;4BACJ,MAAM,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;wBAChC,CAAC;wBAAC,MAAM,CAAC;4BACR,IAAI,MAAM,EAAE,CAAC;gCACZ,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;4BAC9C,CAAC;4BACD,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC,CAAC;4BAC7C,OAAO;wBACR,CAAC;wBAED,mCAAmC;wBACnC,IAAI,OAAO,EAAE,CAAC;4BACb,OAAO;wBACR,CAAC;wBAED,iBAAiB;wBACjB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;wBAChD,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;wBAE5C,kCAAkC;wBAClC,IAAI,OAAO,EAAE,CAAC;4BACb,OAAO;wBACR,CAAC;wBAED,qFAAqF;wBACrF,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;wBACpD,MAAM,cAAc,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;wBACjD,MAAM,iBAAiB,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;wBACjD,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,6BAA6B,CAChE,iBAAiB,EACjB,KAAK,EACL,IAAI,CACJ,CAAC;wBAEF,mCAAmC;wBACnC,IAAI,OAAO,EAAE,CAAC;4BACb,OAAO;wBACR,CAAC;wBAED,MAAM,YAAY,GAAG,GAAG,GAAG,kBAAkB,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;wBAC1E,MAAM,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;wBAEhD,kCAAkC;wBAClC,IAAI,OAAO,EAAE,CAAC;4BACb,OAAO;wBACR,CAAC;wBAED,0BAA0B;wBAC1B,IAAI,MAAM,EAAE,CAAC;4BACZ,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;wBAC9C,CAAC;wBAED,MAAM,UAAU,GAAG,kBAAkB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;wBAC/D,OAAO,CAAC;4BACP,OAAO,EAAE;gCACR;oCACC,IAAI,EAAE,MAAM;oCACZ,IAAI,EAAE,yBAAyB,KAAK,CAAC,MAAM,gBAAgB,IAAI,GAAG;iCAClE;6BACD;4BACD,OAAO,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,gBAAgB,EAAE,UAAU,CAAC,gBAAgB,EAAE;yBACjF,CAAC,CAAC;oBACJ,CAAC;oBAAC,OAAO,KAAc,EAAE,CAAC;wBACzB,0BAA0B;wBAC1B,IAAI,MAAM,EAAE,CAAC;4BACZ,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;wBAC9C,CAAC;wBAED,IAAI,CAAC,OAAO,EAAE,CAAC;4BACd,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wBACnE,CAAC;oBACF,CAAC;gBACF,CAAC,CAAC,EAAE,CAAC;YACN,CAAC,CAAC,CACH,CAAC;QACH,CAAC;QACD,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO;YAC9B,MAAM,IAAI,GAAI,OAAO,CAAC,aAAkC,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/E,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC;QACb,CAAC;QACD,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO;YAC5C,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,MAAa,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YACrF,IAAI,CAAC,MAAM,EAAE,CAAC;gBACb,MAAM,SAAS,GAAI,OAAO,CAAC,aAAuC,IAAI,IAAI,SAAS,EAAE,CAAC;gBACtF,SAAS,CAAC,KAAK,EAAE,CAAC;gBAClB,OAAO,SAAS,CAAC;YAClB,CAAC;YACD,MAAM,IAAI,GAAI,OAAO,CAAC,aAAkC,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/E,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACrB,OAAO,IAAI,CAAC;QACb,CAAC;KACD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,OAAyB;IACpE,OAAO,kBAAkB,CAAC,wBAAwB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC","sourcesContent":["import type { AgentTool } from \"@orient-cli/agent-core\";\nimport { Container, Text } from \"@orient-cli/tui\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from \"fs/promises\";\nimport { renderDiff } from \"../../modes/interactive/components/diff.js\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport {\n\tapplyEditsToNormalizedContent,\n\tdetectLineEnding,\n\ttype Edit,\n\tgenerateDiffString,\n\tnormalizeToLF,\n\trestoreLineEndings,\n\tstripBom,\n} from \"./edit-diff.js\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\n\ntype EditRenderState = Record<string, never>;\n\nconst replaceEditSchema = Type.Object(\n\t{\n\t\toldText: Type.String({\n\t\t\tdescription:\n\t\t\t\t\"Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call.\",\n\t\t}),\n\t\tnewText: Type.String({ description: \"Replacement text for this targeted edit.\" }),\n\t},\n\t{ additionalProperties: false },\n);\n\nconst editSchema = Type.Object(\n\t{\n\t\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\t\tedits: Type.Array(replaceEditSchema, {\n\t\t\tdescription:\n\t\t\t\t\"One or more targeted replacements. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead.\",\n\t\t}),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type EditToolInput = Static<typeof editSchema>;\ntype LegacyEditToolInput = EditToolInput & {\n\toldText?: unknown;\n\tnewText?: unknown;\n};\n\nexport interface EditToolDetails {\n\t/** Unified diff of the changes made */\n\tdiff: string;\n\t/** Line number of the first change in the new file (for editor navigation) */\n\tfirstChangedLine?: number;\n}\n\n/**\n * Pluggable operations for the edit tool.\n * Override these to delegate file editing to remote systems (for example SSH).\n */\nexport interface EditOperations {\n\t/** Read file contents as a Buffer */\n\treadFile: (absolutePath: string) => Promise<Buffer>;\n\t/** Write content to a file */\n\twriteFile: (absolutePath: string, content: string) => Promise<void>;\n\t/** Check if file is readable and writable (throw if not) */\n\taccess: (absolutePath: string) => Promise<void>;\n}\n\nconst defaultEditOperations: EditOperations = {\n\treadFile: (path) => fsReadFile(path),\n\twriteFile: (path, content) => fsWriteFile(path, content, \"utf-8\"),\n\taccess: (path) => fsAccess(path, constants.R_OK | constants.W_OK),\n};\n\nexport interface EditToolOptions {\n\t/** Custom operations for file editing. Default: local filesystem */\n\toperations?: EditOperations;\n}\n\nfunction prepareEditArguments(input: unknown): EditToolInput {\n\tif (!input || typeof input !== \"object\") {\n\t\treturn input as EditToolInput;\n\t}\n\n\tconst args = input as LegacyEditToolInput;\n\tif (typeof args.oldText !== \"string\" || typeof args.newText !== \"string\") {\n\t\treturn input as EditToolInput;\n\t}\n\n\tconst edits = Array.isArray(args.edits) ? [...args.edits] : [];\n\tedits.push({ oldText: args.oldText, newText: args.newText });\n\tconst { oldText: _oldText, newText: _newText, ...rest } = args;\n\treturn { ...rest, edits } as EditToolInput;\n}\n\nfunction validateEditInput(input: EditToolInput): { path: string; edits: Edit[] } {\n\tif (!Array.isArray(input.edits) || input.edits.length === 0) {\n\t\tthrow new Error(\"Edit tool input is invalid. edits must contain at least one replacement.\");\n\t}\n\treturn { path: input.path, edits: input.edits };\n}\n\ntype RenderableEditArgs = {\n\tpath?: string;\n\tfile_path?: string;\n\tedits?: Edit[];\n\toldText?: string;\n\tnewText?: string;\n};\n\nfunction formatEditCall(\n\targs: RenderableEditArgs | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst invalidArg = invalidArgText(theme);\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath) : null;\n\tconst pathDisplay = path === null ? invalidArg : path ? theme.fg(\"accent\", path) : theme.fg(\"toolOutput\", \"...\");\n\treturn `${theme.fg(\"toolTitle\", theme.bold(\"edit\"))} ${pathDisplay}`;\n}\n\nfunction formatEditResult(\n\targs: RenderableEditArgs | undefined,\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: EditToolDetails;\n\t},\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tisError: boolean,\n): string | undefined {\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tif (isError) {\n\t\tconst errorText = result.content\n\t\t\t.filter((c) => c.type === \"text\")\n\t\t\t.map((c) => c.text || \"\")\n\t\t\t.join(\"\\n\");\n\t\tif (!errorText) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn `\\n${theme.fg(\"error\", errorText)}`;\n\t}\n\n\tconst resultDiff = result.details?.diff;\n\tif (!resultDiff) {\n\t\treturn undefined;\n\t}\n\treturn `\\n${renderDiff(resultDiff, { filePath: rawPath ?? undefined })}`;\n}\n\nexport function createEditToolDefinition(\n\tcwd: string,\n\toptions?: EditToolOptions,\n): ToolDefinition<typeof editSchema, EditToolDetails | undefined, EditRenderState> {\n\tconst ops = options?.operations ?? defaultEditOperations;\n\treturn {\n\t\tname: \"edit\",\n\t\tlabel: \"edit\",\n\t\tdescription:\n\t\t\t\"Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.\",\n\t\tpromptSnippet:\n\t\t\t\"Make precise file edits with exact text replacement, including multiple disjoint edits in one call\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use edit for precise changes (edits[].oldText must match exactly)\",\n\t\t\t\"When changing multiple separate locations in one file, use one edit call with multiple entries in edits[] instead of multiple edit calls\",\n\t\t\t\"Each edits[].oldText is matched against the original file, not after earlier edits are applied. Do not emit overlapping or nested edits. Merge nearby changes into one edit.\",\n\t\t\t\"Keep edits[].oldText as small as possible while still being unique in the file. Do not pad with large unchanged regions.\",\n\t\t],\n\t\tparameters: editSchema,\n\t\tprepareArguments: prepareEditArguments,\n\t\tasync execute(_toolCallId, input: EditToolInput, signal?: AbortSignal, _onUpdate?, _ctx?) {\n\t\t\tconst { path, edits } = validateEditInput(input);\n\t\t\tconst absolutePath = resolveToCwd(path, cwd);\n\n\t\t\treturn withFileMutationQueue(\n\t\t\t\tabsolutePath,\n\t\t\t\t() =>\n\t\t\t\t\tnew Promise<{\n\t\t\t\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\t\t\t\tdetails: EditToolDetails | undefined;\n\t\t\t\t\t}>((resolve, reject) => {\n\t\t\t\t\t\t// Check if already aborted.\n\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet aborted = false;\n\n\t\t\t\t\t\t// Set up abort handler.\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Perform the edit operation.\n\t\t\t\t\t\tvoid (async () => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Check if file exists.\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treject(new Error(`File not found: ${path}`));\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Check if aborted before reading.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Read the file.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tconst rawContent = buffer.toString(\"utf-8\");\n\n\t\t\t\t\t\t\t\t// Check if aborted after reading.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Strip BOM before matching. The model will not include an invisible BOM in oldText.\n\t\t\t\t\t\t\t\tconst { bom, text: content } = stripBom(rawContent);\n\t\t\t\t\t\t\t\tconst originalEnding = detectLineEnding(content);\n\t\t\t\t\t\t\t\tconst normalizedContent = normalizeToLF(content);\n\t\t\t\t\t\t\t\tconst { baseContent, newContent } = applyEditsToNormalizedContent(\n\t\t\t\t\t\t\t\t\tnormalizedContent,\n\t\t\t\t\t\t\t\t\tedits,\n\t\t\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t// Check if aborted before writing.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst finalContent = bom + restoreLineEndings(newContent, originalEnding);\n\t\t\t\t\t\t\t\tawait ops.writeFile(absolutePath, finalContent);\n\n\t\t\t\t\t\t\t\t// Check if aborted after writing.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Clean up abort handler.\n\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst diffResult = generateDiffString(baseContent, newContent);\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\t\ttext: `Successfully replaced ${edits.length} block(s) in ${path}.`,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\tdetails: { diff: diffResult.diff, firstChangedLine: diffResult.firstChangedLine },\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\t\t\t// Clean up abort handler.\n\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (!aborted) {\n\t\t\t\t\t\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})();\n\t\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatEditCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, _options, theme, context) {\n\t\t\tconst output = formatEditResult(context.args, result as any, theme, context.isError);\n\t\t\tif (!output) {\n\t\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\t\tcomponent.clear();\n\t\t\t\treturn component;\n\t\t\t}\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(output);\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createEditTool(cwd: string, options?: EditToolOptions): AgentTool<typeof editSchema> {\n\treturn wrapToolDefinition(createEditToolDefinition(cwd, options));\n}\n\n/** Default edit tool using process.cwd() for backwards compatibility. */\nexport const editToolDefinition = createEditToolDefinition(process.cwd());\nexport const editTool = createEditTool(process.cwd());\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-mutation-queue.d.ts","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAoBjG"
|
|
1
|
+
{"version":3,"file":"file-mutation-queue.d.ts","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAoBjG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-mutation-queue.js","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAyB,CAAC;AAE5D,SAAS,mBAAmB,CAAC,QAAgB
|
|
1
|
+
{"version":3,"file":"file-mutation-queue.js","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAyB,CAAC;AAE5D,SAAS,mBAAmB,CAAC,QAAgB;IAC5C,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC;QACJ,OAAO,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,YAAY,CAAC;IACrB,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAI,QAAgB,EAAE,EAAoB;IACpF,MAAM,GAAG,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,YAAY,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAEtE,IAAI,WAAwB,CAAC;IAC7B,MAAM,SAAS,GAAG,IAAI,OAAO,CAAO,CAAC,YAAY,EAAE,EAAE;QACpD,WAAW,GAAG,YAAY,CAAC;IAC5B,CAAC,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACxD,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAE1C,MAAM,YAAY,CAAC;IACnB,IAAI,CAAC;QACJ,OAAO,MAAM,EAAE,EAAE,CAAC;IACnB,CAAC;YAAS,CAAC;QACV,WAAW,EAAE,CAAC;QACd,IAAI,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,YAAY,EAAE,CAAC;YAClD,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["import { realpathSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nconst fileMutationQueues = new Map<string, Promise<void>>();\n\nfunction getMutationQueueKey(filePath: string): string {\n\tconst resolvedPath = resolve(filePath);\n\ttry {\n\t\treturn realpathSync.native(resolvedPath);\n\t} catch {\n\t\treturn resolvedPath;\n\t}\n}\n\n/**\n * Serialize file mutation operations targeting the same file.\n * Operations for different files still run in parallel.\n */\nexport async function withFileMutationQueue<T>(filePath: string, fn: () => Promise<T>): Promise<T> {\n\tconst key = getMutationQueueKey(filePath);\n\tconst currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();\n\n\tlet releaseNext!: () => void;\n\tconst nextQueue = new Promise<void>((resolveQueue) => {\n\t\treleaseNext = resolveQueue;\n\t});\n\tconst chainedQueue = currentQueue.then(() => nextQueue);\n\tfileMutationQueues.set(key, chainedQueue);\n\n\tawait currentQueue;\n\ttry {\n\t\treturn await fn();\n\t} finally {\n\t\treleaseNext();\n\t\tif (fileMutationQueues.get(key) === chainedQueue) {\n\t\t\tfileMutationQueues.delete(key);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../src/core/tools/find.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAOtD,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AAItF,OAAO,EAAiC,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAMnG,QAAA,MAAM,UAAU;;;;EAMd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAItD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,2BAA2B;IAC3B,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7D,4EAA4E;IAC5E,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC;CACnH;AAQD,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAuDD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CA+LhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG;AAED,yEAAyE;AACzE,eAAO,MAAM,kBAAkB;;;;qCAA0C,CAAC;AAC1E,eAAO,MAAM,QAAQ;;;;QAAgC,CAAC","sourcesContent":["import type { AgentTool } from \"@orient-cli/agent-core\";\nimport { Text } from \"@orient-cli/tui\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { spawnSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport { globSync } from \"glob\";\nimport path from \"path\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.js\";\nimport { ensureTool } from \"../../utils/tools-manager.js\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.js\";\n\nfunction toPosixPath(value: string): string {\n\treturn value.split(path.sep).join(\"/\");\n}\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(Type.String({ description: \"Directory to search in (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 1000)\" })),\n});\n\nexport type FindToolInput = Static<typeof findSchema>;\n\nconst DEFAULT_LIMIT = 1000;\n\nexport interface FindToolDetails {\n\ttruncation?: TruncationResult;\n\tresultLimitReached?: number;\n}\n\n/**\n * Pluggable operations for the find tool.\n * Override these to delegate file search to remote systems (for example SSH).\n */\nexport interface FindOperations {\n\t/** Check if path exists */\n\texists: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Find files matching glob pattern. Returns relative or absolute paths. */\n\tglob: (pattern: string, cwd: string, options: { ignore: string[]; limit: number }) => Promise<string[]> | string[];\n}\n\nconst defaultFindOperations: FindOperations = {\n\texists: existsSync,\n\t// This is a placeholder. Actual fd execution happens in execute() when no custom glob is provided.\n\tglob: () => [],\n};\n\nexport interface FindToolOptions {\n\t/** Custom operations for find. Default: local filesystem plus fd */\n\toperations?: FindOperations;\n}\n\nfunction formatFindCall(\n\targs: { pattern: string; path?: string; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"find\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", pattern || \"\")) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (limit !== undefined) {\n\t\ttext += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n\t}\n\treturn text;\n}\n\nfunction formatFindResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: FindToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 20;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t}\n\t}\n\n\tconst resultLimit = result.details?.resultLimitReached;\n\tconst truncation = result.details?.truncation;\n\tif (resultLimit || truncation?.truncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (resultLimit) warnings.push(`${resultLimit} results limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\nexport function createFindToolDefinition(\n\tcwd: string,\n\toptions?: FindToolOptions,\n): ToolDefinition<typeof findSchema, FindToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"find\",\n\t\tlabel: \"find\",\n\t\tdescription: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n\t\tpromptSnippet: \"Find files by glob pattern (respects .gitignore)\",\n\t\tparameters: findSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ pattern, path: searchDir, limit }: { pattern: string; path?: string; limit?: number },\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst onAbort = () => reject(new Error(\"Operation aborted\"));\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\n\t\t\t\t\t\tconst ops = customOps ?? defaultFindOperations;\n\n\t\t\t\t\t\t// If custom operations provide glob(), use that instead of fd.\n\t\t\t\t\t\tif (customOps?.glob) {\n\t\t\t\t\t\t\tif (!(await ops.exists(searchPath))) {\n\t\t\t\t\t\t\t\treject(new Error(`Path not found: ${searchPath}`));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst results = await ops.glob(pattern, searchPath, {\n\t\t\t\t\t\t\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\t\t\t\t\t\t\tlimit: effectiveLimit,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tif (results.length === 0) {\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No files found matching pattern\" }],\n\t\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Relativize paths against the search root for stable output.\n\t\t\t\t\t\t\tconst relativized = results.map((p) => {\n\t\t\t\t\t\t\t\tif (p.startsWith(searchPath)) return toPosixPath(p.slice(searchPath.length + 1));\n\t\t\t\t\t\t\t\treturn toPosixPath(path.relative(searchPath, p));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst resultLimitReached = relativized.length >= effectiveLimit;\n\t\t\t\t\t\t\tconst rawOutput = relativized.join(\"\\n\");\n\t\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet resultOutput = truncation.content;\n\t\t\t\t\t\t\tconst details: FindToolDetails = {};\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (resultLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(`${effectiveLimit} results limit reached`);\n\t\t\t\t\t\t\t\tdetails.resultLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\t\tresultOutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: resultOutput }],\n\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Default implementation uses fd.\n\t\t\t\t\t\tconst fdPath = await ensureTool(\"fd\", true);\n\t\t\t\t\t\tif (!fdPath) {\n\t\t\t\t\t\t\treject(new Error(\"fd is not available and could not be downloaded\"));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Build fd arguments.\n\t\t\t\t\t\tconst args: string[] = [\n\t\t\t\t\t\t\t\"--glob\",\n\t\t\t\t\t\t\t\"--color=never\",\n\t\t\t\t\t\t\t\"--hidden\",\n\t\t\t\t\t\t\t\"--max-results\",\n\t\t\t\t\t\t\tString(effectiveLimit),\n\t\t\t\t\t\t];\n\t\t\t\t\t\t// Include .gitignore files from the search tree.\n\t\t\t\t\t\tconst gitignoreFiles = new Set<string>();\n\t\t\t\t\t\tconst rootGitignore = path.join(searchPath, \".gitignore\");\n\t\t\t\t\t\tif (existsSync(rootGitignore)) gitignoreFiles.add(rootGitignore);\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst nestedGitignores = globSync(\"**/.gitignore\", {\n\t\t\t\t\t\t\t\tcwd: searchPath,\n\t\t\t\t\t\t\t\tdot: true,\n\t\t\t\t\t\t\t\tabsolute: true,\n\t\t\t\t\t\t\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tfor (const file of nestedGitignores) gitignoreFiles.add(file);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// ignore\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const gitignorePath of gitignoreFiles) args.push(\"--ignore-file\", gitignorePath);\n\t\t\t\t\t\targs.push(pattern, searchPath);\n\n\t\t\t\t\t\tconst result = spawnSync(fdPath, args, { encoding: \"utf-8\", maxBuffer: 10 * 1024 * 1024 });\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\tif (result.error) {\n\t\t\t\t\t\t\treject(new Error(`Failed to run fd: ${result.error.message}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst output = result.stdout?.trim() || \"\";\n\t\t\t\t\t\tif (result.status !== 0) {\n\t\t\t\t\t\t\tconst errorMsg = result.stderr?.trim() || `fd exited with code ${result.status}`;\n\t\t\t\t\t\t\tif (!output) {\n\t\t\t\t\t\t\t\treject(new Error(errorMsg));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!output) {\n\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No files found matching pattern\" }],\n\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst lines = output.split(\"\\n\");\n\t\t\t\t\t\tconst relativized: string[] = [];\n\t\t\t\t\t\tfor (const rawLine of lines) {\n\t\t\t\t\t\t\tconst line = rawLine.replace(/\\r$/, \"\").trim();\n\t\t\t\t\t\t\tif (!line) continue;\n\t\t\t\t\t\t\tconst hadTrailingSlash = line.endsWith(\"/\") || line.endsWith(\"\\\\\");\n\t\t\t\t\t\t\tlet relativePath = line;\n\t\t\t\t\t\t\tif (line.startsWith(searchPath)) {\n\t\t\t\t\t\t\t\trelativePath = line.slice(searchPath.length + 1);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\trelativePath = path.relative(searchPath, line);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (hadTrailingSlash && !relativePath.endsWith(\"/\")) relativePath += \"/\";\n\t\t\t\t\t\t\trelativized.push(toPosixPath(relativePath));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst resultLimitReached = relativized.length >= effectiveLimit;\n\t\t\t\t\t\tconst rawOutput = relativized.join(\"\\n\");\n\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\tlet resultOutput = truncation.content;\n\t\t\t\t\t\tconst details: FindToolDetails = {};\n\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\tif (resultLimitReached) {\n\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t`${effectiveLimit} results limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tdetails.resultLimitReached = effectiveLimit;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\tresultOutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: resultOutput }],\n\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\treject(e);\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createFindTool(cwd: string, options?: FindToolOptions): AgentTool<typeof findSchema> {\n\treturn wrapToolDefinition(createFindToolDefinition(cwd, options));\n}\n\n/** Default find tool using process.cwd() for backwards compatibility. */\nexport const findToolDefinition = createFindToolDefinition(process.cwd());\nexport const findTool = createFindTool(process.cwd());\n"]}
|
|
1
|
+
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../src/core/tools/find.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAOtD,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AAItF,OAAO,EAAiC,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAMnG,QAAA,MAAM,UAAU;;;;EAMd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAItD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,2BAA2B;IAC3B,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7D,4EAA4E;IAC5E,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC;CACnH;AAQD,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAuDD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CA+LhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG;AAED,yEAAyE;AACzE,eAAO,MAAM,kBAAkB;;;;qCAA0C,CAAC;AAC1E,eAAO,MAAM,QAAQ;;;;QAAgC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../../src/core/tools/find.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@orient-cli/agent-core\";\nimport { Text } from \"@orient-cli/tui\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { spawnSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport { globSync } from \"glob\";\nimport path from \"path\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.js\";\nimport { ensureTool } from \"../../utils/tools-manager.js\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.js\";\n\nfunction toPosixPath(value: string): string {\n\treturn value.split(path.sep).join(\"/\");\n}\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(Type.String({ description: \"Directory to search in (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 1000)\" })),\n});\n\nexport type FindToolInput = Static<typeof findSchema>;\n\nconst DEFAULT_LIMIT = 1000;\n\nexport interface FindToolDetails {\n\ttruncation?: TruncationResult;\n\tresultLimitReached?: number;\n}\n\n/**\n * Pluggable operations for the find tool.\n * Override these to delegate file search to remote systems (for example SSH).\n */\nexport interface FindOperations {\n\t/** Check if path exists */\n\texists: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Find files matching glob pattern. Returns relative or absolute paths. */\n\tglob: (pattern: string, cwd: string, options: { ignore: string[]; limit: number }) => Promise<string[]> | string[];\n}\n\nconst defaultFindOperations: FindOperations = {\n\texists: existsSync,\n\t// This is a placeholder. Actual fd execution happens in execute() when no custom glob is provided.\n\tglob: () => [],\n};\n\nexport interface FindToolOptions {\n\t/** Custom operations for find. Default: local filesystem plus fd */\n\toperations?: FindOperations;\n}\n\nfunction formatFindCall(\n\targs: { pattern: string; path?: string; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"find\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", pattern || \"\")) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (limit !== undefined) {\n\t\ttext += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n\t}\n\treturn text;\n}\n\nfunction formatFindResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: FindToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 20;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t}\n\t}\n\n\tconst resultLimit = result.details?.resultLimitReached;\n\tconst truncation = result.details?.truncation;\n\tif (resultLimit || truncation?.truncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (resultLimit) warnings.push(`${resultLimit} results limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\nexport function createFindToolDefinition(\n\tcwd: string,\n\toptions?: FindToolOptions,\n): ToolDefinition<typeof findSchema, FindToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"find\",\n\t\tlabel: \"find\",\n\t\tdescription: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n\t\tpromptSnippet: \"Find files by glob pattern (respects .gitignore)\",\n\t\tparameters: findSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ pattern, path: searchDir, limit }: { pattern: string; path?: string; limit?: number },\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst onAbort = () => reject(new Error(\"Operation aborted\"));\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\n\t\t\t\t\t\tconst ops = customOps ?? defaultFindOperations;\n\n\t\t\t\t\t\t// If custom operations provide glob(), use that instead of fd.\n\t\t\t\t\t\tif (customOps?.glob) {\n\t\t\t\t\t\t\tif (!(await ops.exists(searchPath))) {\n\t\t\t\t\t\t\t\treject(new Error(`Path not found: ${searchPath}`));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst results = await ops.glob(pattern, searchPath, {\n\t\t\t\t\t\t\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\t\t\t\t\t\t\tlimit: effectiveLimit,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tif (results.length === 0) {\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No files found matching pattern\" }],\n\t\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Relativize paths against the search root for stable output.\n\t\t\t\t\t\t\tconst relativized = results.map((p) => {\n\t\t\t\t\t\t\t\tif (p.startsWith(searchPath)) return toPosixPath(p.slice(searchPath.length + 1));\n\t\t\t\t\t\t\t\treturn toPosixPath(path.relative(searchPath, p));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst resultLimitReached = relativized.length >= effectiveLimit;\n\t\t\t\t\t\t\tconst rawOutput = relativized.join(\"\\n\");\n\t\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet resultOutput = truncation.content;\n\t\t\t\t\t\t\tconst details: FindToolDetails = {};\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (resultLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(`${effectiveLimit} results limit reached`);\n\t\t\t\t\t\t\t\tdetails.resultLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\t\tresultOutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: resultOutput }],\n\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Default implementation uses fd.\n\t\t\t\t\t\tconst fdPath = await ensureTool(\"fd\", true);\n\t\t\t\t\t\tif (!fdPath) {\n\t\t\t\t\t\t\treject(new Error(\"fd is not available and could not be downloaded\"));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Build fd arguments.\n\t\t\t\t\t\tconst args: string[] = [\n\t\t\t\t\t\t\t\"--glob\",\n\t\t\t\t\t\t\t\"--color=never\",\n\t\t\t\t\t\t\t\"--hidden\",\n\t\t\t\t\t\t\t\"--max-results\",\n\t\t\t\t\t\t\tString(effectiveLimit),\n\t\t\t\t\t\t];\n\t\t\t\t\t\t// Include .gitignore files from the search tree.\n\t\t\t\t\t\tconst gitignoreFiles = new Set<string>();\n\t\t\t\t\t\tconst rootGitignore = path.join(searchPath, \".gitignore\");\n\t\t\t\t\t\tif (existsSync(rootGitignore)) gitignoreFiles.add(rootGitignore);\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst nestedGitignores = globSync(\"**/.gitignore\", {\n\t\t\t\t\t\t\t\tcwd: searchPath,\n\t\t\t\t\t\t\t\tdot: true,\n\t\t\t\t\t\t\t\tabsolute: true,\n\t\t\t\t\t\t\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tfor (const file of nestedGitignores) gitignoreFiles.add(file);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// ignore\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const gitignorePath of gitignoreFiles) args.push(\"--ignore-file\", gitignorePath);\n\t\t\t\t\t\targs.push(pattern, searchPath);\n\n\t\t\t\t\t\tconst result = spawnSync(fdPath, args, { encoding: \"utf-8\", maxBuffer: 10 * 1024 * 1024 });\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\tif (result.error) {\n\t\t\t\t\t\t\treject(new Error(`Failed to run fd: ${result.error.message}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst output = result.stdout?.trim() || \"\";\n\t\t\t\t\t\tif (result.status !== 0) {\n\t\t\t\t\t\t\tconst errorMsg = result.stderr?.trim() || `fd exited with code ${result.status}`;\n\t\t\t\t\t\t\tif (!output) {\n\t\t\t\t\t\t\t\treject(new Error(errorMsg));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!output) {\n\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No files found matching pattern\" }],\n\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst lines = output.split(\"\\n\");\n\t\t\t\t\t\tconst relativized: string[] = [];\n\t\t\t\t\t\tfor (const rawLine of lines) {\n\t\t\t\t\t\t\tconst line = rawLine.replace(/\\r$/, \"\").trim();\n\t\t\t\t\t\t\tif (!line) continue;\n\t\t\t\t\t\t\tconst hadTrailingSlash = line.endsWith(\"/\") || line.endsWith(\"\\\\\");\n\t\t\t\t\t\t\tlet relativePath = line;\n\t\t\t\t\t\t\tif (line.startsWith(searchPath)) {\n\t\t\t\t\t\t\t\trelativePath = line.slice(searchPath.length + 1);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\trelativePath = path.relative(searchPath, line);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (hadTrailingSlash && !relativePath.endsWith(\"/\")) relativePath += \"/\";\n\t\t\t\t\t\t\trelativized.push(toPosixPath(relativePath));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst resultLimitReached = relativized.length >= effectiveLimit;\n\t\t\t\t\t\tconst rawOutput = relativized.join(\"\\n\");\n\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\tlet resultOutput = truncation.content;\n\t\t\t\t\t\tconst details: FindToolDetails = {};\n\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\tif (resultLimitReached) {\n\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t`${effectiveLimit} results limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tdetails.resultLimitReached = effectiveLimit;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\tresultOutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: resultOutput }],\n\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\treject(e);\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createFindTool(cwd: string, options?: FindToolOptions): AgentTool<typeof findSchema> {\n\treturn wrapToolDefinition(createFindToolDefinition(cwd, options));\n}\n\n/** Default find tool using process.cwd() for backwards compatibility. */\nexport const findToolDefinition = createFindToolDefinition(process.cwd());\nexport const findTool = createFindTool(process.cwd());\n"]}
|
|
1
|
+
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../../src/core/tools/find.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAe,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,wDAAwD,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAyB,YAAY,EAAE,MAAM,eAAe,CAAC;AAEnG,SAAS,WAAW,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;IAC9B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;QACpB,WAAW,EAAE,8EAA8E;KAC3F,CAAC;IACF,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC,CAAC;IACxG,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC,CAAC;CAC/F,CAAC,CAAC;AAIH,MAAM,aAAa,GAAG,IAAI,CAAC;AAkB3B,MAAM,qBAAqB,GAAmB;IAC7C,MAAM,EAAE,UAAU;IAClB,mGAAmG;IACnG,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE;CACd,CAAC;AAOF,SAAS,cAAc,CACtB,IAAoE,EACpE,KAAoE;IAEpE,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;IAC1B,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,IAAI,GACP,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzC,GAAG;QACH,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QACnE,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACpE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,WAAW,KAAK,GAAG,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,gBAAgB,CACxB,MAGC,EACD,OAAgC,EAChC,KAAoE,EACpE,UAAmB;IAEnB,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;IACxD,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,MAAM,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC9C,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC;QAC1C,IAAI,IAAI,KAAK,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnF,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,SAAS,cAAc,CAAC,IAAI,OAAO,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG,CAAC;QAChH,CAAC;IACF,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACvD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC;IAC9C,IAAI,WAAW,IAAI,UAAU,EAAE,SAAS,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,IAAI,WAAW;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,WAAW,gBAAgB,CAAC,CAAC;QAC/D,IAAI,UAAU,EAAE,SAAS;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,QAAQ,IAAI,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC1G,IAAI,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAC3E,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,UAAU,wBAAwB,CACvC,GAAW,EACX,OAAyB;IAEzB,MAAM,SAAS,GAAG,OAAO,EAAE,UAAU,CAAC;IACtC,OAAO;QACN,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,MAAM;QACb,WAAW,EAAE,+IAA+I,aAAa,eAAe,iBAAiB,GAAG,IAAI,8BAA8B;QAC9O,aAAa,EAAE,kDAAkD;QACjE,UAAU,EAAE,UAAU;QACtB,KAAK,CAAC,OAAO,CACZ,WAAW,EACX,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAsD,EACvF,MAAoB,EACpB,SAAU,EACV,IAAK;YAEL,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACtC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;oBACrB,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;oBACvC,OAAO;gBACR,CAAC;gBAED,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBAC7D,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBAE3D,CAAC,KAAK,IAAI,EAAE;oBACX,IAAI,CAAC;wBACJ,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;wBACvD,MAAM,cAAc,GAAG,KAAK,IAAI,aAAa,CAAC;wBAC9C,MAAM,GAAG,GAAG,SAAS,IAAI,qBAAqB,CAAC;wBAE/C,+DAA+D;wBAC/D,IAAI,SAAS,EAAE,IAAI,EAAE,CAAC;4BACrB,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;gCACrC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAC,CAAC;gCACnD,OAAO;4BACR,CAAC;4BACD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE;gCACnD,MAAM,EAAE,CAAC,oBAAoB,EAAE,YAAY,CAAC;gCAC5C,KAAK,EAAE,cAAc;6BACrB,CAAC,CAAC;4BACH,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;4BAC9C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gCAC1B,OAAO,CAAC;oCACP,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iCAAiC,EAAE,CAAC;oCACpE,OAAO,EAAE,SAAS;iCAClB,CAAC,CAAC;gCACH,OAAO;4BACR,CAAC;4BAED,8DAA8D;4BAC9D,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gCACrC,IAAI,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;oCAAE,OAAO,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;gCACjF,OAAO,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;4BAClD,CAAC,CAAC,CAAC;4BACH,MAAM,kBAAkB,GAAG,WAAW,CAAC,MAAM,IAAI,cAAc,CAAC;4BAChE,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;4BACzC,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;4BAClF,IAAI,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC;4BACtC,MAAM,OAAO,GAAoB,EAAE,CAAC;4BACpC,MAAM,OAAO,GAAa,EAAE,CAAC;4BAC7B,IAAI,kBAAkB,EAAE,CAAC;gCACxB,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,wBAAwB,CAAC,CAAC;gCACxD,OAAO,CAAC,kBAAkB,GAAG,cAAc,CAAC;4BAC7C,CAAC;4BACD,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;gCAC1B,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;gCAC/D,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;4BACjC,CAAC;4BACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCACxB,YAAY,IAAI,QAAQ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;4BAC/C,CAAC;4BACD,OAAO,CAAC;gCACP,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;gCAC/C,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;6BAC9D,CAAC,CAAC;4BACH,OAAO;wBACR,CAAC;wBAED,kCAAkC;wBAClC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;wBAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;4BACb,MAAM,CAAC,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC,CAAC;4BACrE,OAAO;wBACR,CAAC;wBAED,sBAAsB;wBACtB,MAAM,IAAI,GAAa;4BACtB,QAAQ;4BACR,eAAe;4BACf,UAAU;4BACV,eAAe;4BACf,MAAM,CAAC,cAAc,CAAC;yBACtB,CAAC;wBACF,iDAAiD;wBACjD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;wBACzC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;wBAC1D,IAAI,UAAU,CAAC,aAAa,CAAC;4BAAE,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;wBACjE,IAAI,CAAC;4BACJ,MAAM,gBAAgB,GAAG,QAAQ,CAAC,eAAe,EAAE;gCAClD,GAAG,EAAE,UAAU;gCACf,GAAG,EAAE,IAAI;gCACT,QAAQ,EAAE,IAAI;gCACd,MAAM,EAAE,CAAC,oBAAoB,EAAE,YAAY,CAAC;6BAC5C,CAAC,CAAC;4BACH,KAAK,MAAM,IAAI,IAAI,gBAAgB;gCAAE,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;wBAC/D,CAAC;wBAAC,MAAM,CAAC;4BACR,SAAS;wBACV,CAAC;wBACD,KAAK,MAAM,aAAa,IAAI,cAAc;4BAAE,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;wBACtF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;wBAE/B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;wBAC3F,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;wBAC9C,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;4BAClB,MAAM,CAAC,IAAI,KAAK,CAAC,qBAAqB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;4BAC/D,OAAO;wBACR,CAAC;wBAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;wBAC3C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;4BACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,uBAAuB,MAAM,CAAC,MAAM,EAAE,CAAC;4BACjF,IAAI,CAAC,MAAM,EAAE,CAAC;gCACb,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;gCAC5B,OAAO;4BACR,CAAC;wBACF,CAAC;wBACD,IAAI,CAAC,MAAM,EAAE,CAAC;4BACb,OAAO,CAAC;gCACP,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iCAAiC,EAAE,CAAC;gCACpE,OAAO,EAAE,SAAS;6BAClB,CAAC,CAAC;4BACH,OAAO;wBACR,CAAC;wBAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACjC,MAAM,WAAW,GAAa,EAAE,CAAC;wBACjC,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;4BAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;4BAC/C,IAAI,CAAC,IAAI;gCAAE,SAAS;4BACpB,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;4BACnE,IAAI,YAAY,GAAG,IAAI,CAAC;4BACxB,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gCACjC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;4BAClD,CAAC;iCAAM,CAAC;gCACP,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;4BAChD,CAAC;4BACD,IAAI,gBAAgB,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC;gCAAE,YAAY,IAAI,GAAG,CAAC;4BACzE,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC;wBAC7C,CAAC;wBAED,MAAM,kBAAkB,GAAG,WAAW,CAAC,MAAM,IAAI,cAAc,CAAC;wBAChE,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACzC,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;wBAClF,IAAI,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC;wBACtC,MAAM,OAAO,GAAoB,EAAE,CAAC;wBACpC,MAAM,OAAO,GAAa,EAAE,CAAC;wBAC7B,IAAI,kBAAkB,EAAE,CAAC;4BACxB,OAAO,CAAC,IAAI,CACX,GAAG,cAAc,qCAAqC,cAAc,GAAG,CAAC,8BAA8B,CACtG,CAAC;4BACF,OAAO,CAAC,kBAAkB,GAAG,cAAc,CAAC;wBAC7C,CAAC;wBACD,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;4BAC1B,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;4BAC/D,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;wBACjC,CAAC;wBACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BACxB,YAAY,IAAI,QAAQ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;wBAC/C,CAAC;wBACD,OAAO,CAAC;4BACP,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;4BAC/C,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;yBAC9D,CAAC,CAAC;oBACJ,CAAC;oBAAC,OAAO,CAAM,EAAE,CAAC;wBACjB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;wBAC9C,MAAM,CAAC,CAAC,CAAC,CAAC;oBACX,CAAC;gBACF,CAAC,CAAC,EAAE,CAAC;YACN,CAAC,CAAC,CAAC;QACJ,CAAC;QACD,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO;YAC9B,MAAM,IAAI,GAAI,OAAO,CAAC,aAAkC,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/E,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC;QACb,CAAC;QACD,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;YAC3C,MAAM,IAAI,GAAI,OAAO,CAAC,aAAkC,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/E,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAa,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;YAClF,OAAO,IAAI,CAAC;QACb,CAAC;KACD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,OAAyB;IACpE,OAAO,kBAAkB,CAAC,wBAAwB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC","sourcesContent":["import type { AgentTool } from \"@orient-cli/agent-core\";\nimport { Text } from \"@orient-cli/tui\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { spawnSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport { globSync } from \"glob\";\nimport path from \"path\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.js\";\nimport { ensureTool } from \"../../utils/tools-manager.js\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.js\";\n\nfunction toPosixPath(value: string): string {\n\treturn value.split(path.sep).join(\"/\");\n}\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(Type.String({ description: \"Directory to search in (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 1000)\" })),\n});\n\nexport type FindToolInput = Static<typeof findSchema>;\n\nconst DEFAULT_LIMIT = 1000;\n\nexport interface FindToolDetails {\n\ttruncation?: TruncationResult;\n\tresultLimitReached?: number;\n}\n\n/**\n * Pluggable operations for the find tool.\n * Override these to delegate file search to remote systems (for example SSH).\n */\nexport interface FindOperations {\n\t/** Check if path exists */\n\texists: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Find files matching glob pattern. Returns relative or absolute paths. */\n\tglob: (pattern: string, cwd: string, options: { ignore: string[]; limit: number }) => Promise<string[]> | string[];\n}\n\nconst defaultFindOperations: FindOperations = {\n\texists: existsSync,\n\t// This is a placeholder. Actual fd execution happens in execute() when no custom glob is provided.\n\tglob: () => [],\n};\n\nexport interface FindToolOptions {\n\t/** Custom operations for find. Default: local filesystem plus fd */\n\toperations?: FindOperations;\n}\n\nfunction formatFindCall(\n\targs: { pattern: string; path?: string; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"find\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", pattern || \"\")) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (limit !== undefined) {\n\t\ttext += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n\t}\n\treturn text;\n}\n\nfunction formatFindResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: FindToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 20;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t}\n\t}\n\n\tconst resultLimit = result.details?.resultLimitReached;\n\tconst truncation = result.details?.truncation;\n\tif (resultLimit || truncation?.truncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (resultLimit) warnings.push(`${resultLimit} results limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\nexport function createFindToolDefinition(\n\tcwd: string,\n\toptions?: FindToolOptions,\n): ToolDefinition<typeof findSchema, FindToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"find\",\n\t\tlabel: \"find\",\n\t\tdescription: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n\t\tpromptSnippet: \"Find files by glob pattern (respects .gitignore)\",\n\t\tparameters: findSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ pattern, path: searchDir, limit }: { pattern: string; path?: string; limit?: number },\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst onAbort = () => reject(new Error(\"Operation aborted\"));\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\n\t\t\t\t\t\tconst ops = customOps ?? defaultFindOperations;\n\n\t\t\t\t\t\t// If custom operations provide glob(), use that instead of fd.\n\t\t\t\t\t\tif (customOps?.glob) {\n\t\t\t\t\t\t\tif (!(await ops.exists(searchPath))) {\n\t\t\t\t\t\t\t\treject(new Error(`Path not found: ${searchPath}`));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst results = await ops.glob(pattern, searchPath, {\n\t\t\t\t\t\t\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\t\t\t\t\t\t\tlimit: effectiveLimit,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tif (results.length === 0) {\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No files found matching pattern\" }],\n\t\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Relativize paths against the search root for stable output.\n\t\t\t\t\t\t\tconst relativized = results.map((p) => {\n\t\t\t\t\t\t\t\tif (p.startsWith(searchPath)) return toPosixPath(p.slice(searchPath.length + 1));\n\t\t\t\t\t\t\t\treturn toPosixPath(path.relative(searchPath, p));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst resultLimitReached = relativized.length >= effectiveLimit;\n\t\t\t\t\t\t\tconst rawOutput = relativized.join(\"\\n\");\n\t\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet resultOutput = truncation.content;\n\t\t\t\t\t\t\tconst details: FindToolDetails = {};\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (resultLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(`${effectiveLimit} results limit reached`);\n\t\t\t\t\t\t\t\tdetails.resultLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\t\tresultOutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: resultOutput }],\n\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Default implementation uses fd.\n\t\t\t\t\t\tconst fdPath = await ensureTool(\"fd\", true);\n\t\t\t\t\t\tif (!fdPath) {\n\t\t\t\t\t\t\treject(new Error(\"fd is not available and could not be downloaded\"));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Build fd arguments.\n\t\t\t\t\t\tconst args: string[] = [\n\t\t\t\t\t\t\t\"--glob\",\n\t\t\t\t\t\t\t\"--color=never\",\n\t\t\t\t\t\t\t\"--hidden\",\n\t\t\t\t\t\t\t\"--max-results\",\n\t\t\t\t\t\t\tString(effectiveLimit),\n\t\t\t\t\t\t];\n\t\t\t\t\t\t// Include .gitignore files from the search tree.\n\t\t\t\t\t\tconst gitignoreFiles = new Set<string>();\n\t\t\t\t\t\tconst rootGitignore = path.join(searchPath, \".gitignore\");\n\t\t\t\t\t\tif (existsSync(rootGitignore)) gitignoreFiles.add(rootGitignore);\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst nestedGitignores = globSync(\"**/.gitignore\", {\n\t\t\t\t\t\t\t\tcwd: searchPath,\n\t\t\t\t\t\t\t\tdot: true,\n\t\t\t\t\t\t\t\tabsolute: true,\n\t\t\t\t\t\t\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tfor (const file of nestedGitignores) gitignoreFiles.add(file);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// ignore\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const gitignorePath of gitignoreFiles) args.push(\"--ignore-file\", gitignorePath);\n\t\t\t\t\t\targs.push(pattern, searchPath);\n\n\t\t\t\t\t\tconst result = spawnSync(fdPath, args, { encoding: \"utf-8\", maxBuffer: 10 * 1024 * 1024 });\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\tif (result.error) {\n\t\t\t\t\t\t\treject(new Error(`Failed to run fd: ${result.error.message}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst output = result.stdout?.trim() || \"\";\n\t\t\t\t\t\tif (result.status !== 0) {\n\t\t\t\t\t\t\tconst errorMsg = result.stderr?.trim() || `fd exited with code ${result.status}`;\n\t\t\t\t\t\t\tif (!output) {\n\t\t\t\t\t\t\t\treject(new Error(errorMsg));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!output) {\n\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No files found matching pattern\" }],\n\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst lines = output.split(\"\\n\");\n\t\t\t\t\t\tconst relativized: string[] = [];\n\t\t\t\t\t\tfor (const rawLine of lines) {\n\t\t\t\t\t\t\tconst line = rawLine.replace(/\\r$/, \"\").trim();\n\t\t\t\t\t\t\tif (!line) continue;\n\t\t\t\t\t\t\tconst hadTrailingSlash = line.endsWith(\"/\") || line.endsWith(\"\\\\\");\n\t\t\t\t\t\t\tlet relativePath = line;\n\t\t\t\t\t\t\tif (line.startsWith(searchPath)) {\n\t\t\t\t\t\t\t\trelativePath = line.slice(searchPath.length + 1);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\trelativePath = path.relative(searchPath, line);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (hadTrailingSlash && !relativePath.endsWith(\"/\")) relativePath += \"/\";\n\t\t\t\t\t\t\trelativized.push(toPosixPath(relativePath));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst resultLimitReached = relativized.length >= effectiveLimit;\n\t\t\t\t\t\tconst rawOutput = relativized.join(\"\\n\");\n\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\tlet resultOutput = truncation.content;\n\t\t\t\t\t\tconst details: FindToolDetails = {};\n\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\tif (resultLimitReached) {\n\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t`${effectiveLimit} results limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tdetails.resultLimitReached = effectiveLimit;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\tresultOutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: resultOutput }],\n\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\treject(e);\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createFindTool(cwd: string, options?: FindToolOptions): AgentTool<typeof findSchema> {\n\treturn wrapToolDefinition(createFindToolDefinition(cwd, options));\n}\n\n/** Default find tool using process.cwd() for backwards compatibility. */\nexport const findToolDefinition = createFindToolDefinition(process.cwd());\nexport const findTool = createFindTool(process.cwd());\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAMtD,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AAItF,OAAO,EAIN,KAAK,gBAAgB,EAGrB,MAAM,eAAe,CAAC;AAEvB,QAAA,MAAM,UAAU;;;;;;;;EAYd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAGtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,mEAAmE;IACnE,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAClE,2CAA2C;IAC3C,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC7D;AAOD,MAAM,WAAW,eAAe;IAC/B,yEAAyE;IACzE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAyDD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAkPhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG;AAED,yEAAyE;AACzE,eAAO,MAAM,kBAAkB;;;;;;;;qCAA0C,CAAC;AAC1E,eAAO,MAAM,QAAQ;;;;;;;;QAAgC,CAAC","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool } from \"@orient-cli/agent-core\";\nimport { Text } from \"@orient-cli/tui\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { spawn } from \"child_process\";\nimport { readFileSync, statSync } from \"fs\";\nimport path from \"path\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.js\";\nimport { ensureTool } from \"../../utils/tools-manager.js\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from \"./truncate.js\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\n/**\n * Pluggable operations for the grep tool.\n * Override these to delegate search to remote systems (for example SSH).\n */\nexport interface GrepOperations {\n\t/** Check if path is a directory. Throws if path does not exist. */\n\tisDirectory: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Read file contents for context lines */\n\treadFile: (absolutePath: string) => Promise<string> | string;\n}\n\nconst defaultGrepOperations: GrepOperations = {\n\tisDirectory: (p) => statSync(p).isDirectory(),\n\treadFile: (p) => readFileSync(p, \"utf-8\"),\n};\n\nexport interface GrepToolOptions {\n\t/** Custom operations for grep. Default: local filesystem plus ripgrep */\n\toperations?: GrepOperations;\n}\n\nfunction formatGrepCall(\n\targs: { pattern: string; path?: string; glob?: string; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: GrepToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 15;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t}\n\t}\n\n\tconst matchLimit = result.details?.matchLimitReached;\n\tconst truncation = result.details?.truncation;\n\tconst linesTruncated = result.details?.linesTruncated;\n\tif (matchLimit || truncation?.truncated || linesTruncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (matchLimit) warnings.push(`${matchLimit} matches limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\tif (linesTruncated) warnings.push(\"some lines truncated\");\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\nexport function createGrepToolDefinition(\n\tcwd: string,\n\toptions?: GrepToolOptions,\n): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tparameters: grepSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{\n\t\t\t\tpattern,\n\t\t\t\tpath: searchDir,\n\t\t\t\tglob,\n\t\t\t\tignoreCase,\n\t\t\t\tliteral,\n\t\t\t\tcontext,\n\t\t\t\tlimit,\n\t\t\t}: {\n\t\t\t\tpattern: string;\n\t\t\t\tpath?: string;\n\t\t\t\tglob?: string;\n\t\t\t\tignoreCase?: boolean;\n\t\t\t\tliteral?: boolean;\n\t\t\t\tcontext?: number;\n\t\t\t\tlimit?: number;\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (!settled) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tfn();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst rgPath = await ensureTool(\"rg\", true);\n\t\t\t\t\t\tif (!rgPath) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"ripgrep (rg) is not available and could not be downloaded\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst ops = customOps ?? defaultGrepOperations;\n\t\t\t\t\t\tlet isDirectory: boolean;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tisDirectory = await ops.isDirectory(searchPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contextValue = context && context > 0 ? context : 0;\n\t\t\t\t\t\tconst effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n\t\t\t\t\t\tconst formatPath = (filePath: string): string => {\n\t\t\t\t\t\t\tif (isDirectory) {\n\t\t\t\t\t\t\t\tconst relative = path.relative(searchPath, filePath);\n\t\t\t\t\t\t\t\tif (relative && !relative.startsWith(\"..\")) {\n\t\t\t\t\t\t\t\t\treturn relative.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn path.basename(filePath);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst fileCache = new Map<string, string[]>();\n\t\t\t\t\t\tconst getFileLines = async (filePath: string): Promise<string[]> => {\n\t\t\t\t\t\t\tlet lines = fileCache.get(filePath);\n\t\t\t\t\t\t\tif (!lines) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst content = await ops.readFile(filePath);\n\t\t\t\t\t\t\t\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tlines = [];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfileCache.set(filePath, lines);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn lines;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\t\t\t\t\tif (ignoreCase) args.push(\"--ignore-case\");\n\t\t\t\t\t\tif (literal) args.push(\"--fixed-strings\");\n\t\t\t\t\t\tif (glob) args.push(\"--glob\", glob);\n\t\t\t\t\t\targs.push(pattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(rgPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tlet matchCount = 0;\n\t\t\t\t\t\tlet matchLimitReached = false;\n\t\t\t\t\t\tlet linesTruncated = false;\n\t\t\t\t\t\tlet aborted = false;\n\t\t\t\t\t\tlet killedDueToLimit = false;\n\t\t\t\t\t\tconst outputLines: string[] = [];\n\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst stopChild = (dueToLimit = false) => {\n\t\t\t\t\t\t\tif (!child.killed) {\n\t\t\t\t\t\t\t\tkilledDueToLimit = dueToLimit;\n\t\t\t\t\t\t\t\tchild.kill();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\tstopChild();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst formatBlock = async (filePath: string, lineNumber: number): Promise<string[]> => {\n\t\t\t\t\t\t\tconst relativePath = formatPath(filePath);\n\t\t\t\t\t\t\tconst lines = await getFileLines(filePath);\n\t\t\t\t\t\t\tif (!lines.length) return [`${relativePath}:${lineNumber}: (unable to read file)`];\n\t\t\t\t\t\t\tconst block: string[] = [];\n\t\t\t\t\t\t\tconst start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n\t\t\t\t\t\t\tconst end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n\t\t\t\t\t\t\tfor (let current = start; current <= end; current++) {\n\t\t\t\t\t\t\t\tconst lineText = lines[current - 1] ?? \"\";\n\t\t\t\t\t\t\t\tconst sanitized = lineText.replace(/\\r/g, \"\");\n\t\t\t\t\t\t\t\tconst isMatchLine = current === lineNumber;\n\t\t\t\t\t\t\t\t// Truncate long lines so grep output stays compact.\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tif (isMatchLine) block.push(`${relativePath}:${current}: ${truncatedText}`);\n\t\t\t\t\t\t\t\telse block.push(`${relativePath}-${current}- ${truncatedText}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect matches during streaming, then format them after rg exits.\n\t\t\t\t\t\tconst matches: Array<{ filePath: string; lineNumber: number }> = [];\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tif (!line.trim() || matchCount >= effectiveLimit) return;\n\t\t\t\t\t\t\tlet event: any;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevent = JSON.parse(line);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.type === \"match\") {\n\t\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t\t\tconst filePath = event.data?.path?.text;\n\t\t\t\t\t\t\t\tconst lineNumber = event.data?.line_number;\n\t\t\t\t\t\t\t\tif (filePath && typeof lineNumber === \"number\") matches.push({ filePath, lineNumber });\n\t\t\t\t\t\t\t\tif (matchCount >= effectiveLimit) {\n\t\t\t\t\t\t\t\t\tmatchLimitReached = true;\n\t\t\t\t\t\t\t\t\tstopChild(true);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Failed to run ripgrep: ${error.message}`)));\n\t\t\t\t\t\t});\n\t\t\t\t\t\tchild.on(\"close\", async (code) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!killedDueToLimit && code !== 0 && code !== 1) {\n\t\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (matchCount === 0) {\n\t\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Format matches after streaming finishes so custom readFile() backends can be async.\n\t\t\t\t\t\t\tfor (const match of matches) {\n\t\t\t\t\t\t\t\tconst block = await formatBlock(match.filePath, match.lineNumber);\n\t\t\t\t\t\t\t\toutputLines.push(...block);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst rawOutput = outputLines.join(\"\\n\");\n\t\t\t\t\t\t\t// Apply byte truncation. There is no line limit here because the match limit already capped rows.\n\t\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\t\tconst details: GrepToolDetails = {};\n\t\t\t\t\t\t\t// Build actionable notices for truncation and match limits.\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (matchLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`${effectiveLimit} matches limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.matchLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (linesTruncated) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.linesTruncated = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: output }],\n\t\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsettle(() => reject(err as Error));\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatGrepCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatGrepResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n\n/** Default grep tool using process.cwd() for backwards compatibility. */\nexport const grepToolDefinition = createGrepToolDefinition(process.cwd());\nexport const grepTool = createGrepTool(process.cwd());\n"]}
|
|
1
|
+
{"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAMtD,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AAItF,OAAO,EAIN,KAAK,gBAAgB,EAGrB,MAAM,eAAe,CAAC;AAEvB,QAAA,MAAM,UAAU;;;;;;;;EAYd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAGtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,mEAAmE;IACnE,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAClE,2CAA2C;IAC3C,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC7D;AAOD,MAAM,WAAW,eAAe;IAC/B,yEAAyE;IACzE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAyDD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAkPhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG;AAED,yEAAyE;AACzE,eAAO,MAAM,kBAAkB;;;;;;;;qCAA0C,CAAC;AAC1E,eAAO,MAAM,QAAQ;;;;;;;;QAAgC,CAAC"}
|