@sheason/pi-coding-agent 0.74.1-sheason.0 → 0.78.0-sheason.0.6.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +256 -4
- package/README.md +16 -8
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js.map +1 -1
- package/dist/cli/args.d.ts +7 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +49 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts +2 -2
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -3
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/initial-message.d.ts +1 -1
- package/dist/cli/initial-message.d.ts.map +1 -1
- package/dist/cli/initial-message.js.map +1 -1
- package/dist/cli/list-models.d.ts +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/session-picker.d.ts +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -6
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +61 -32
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-proxy.d.ts +268 -0
- package/dist/core/agent-session-proxy.d.ts.map +1 -0
- package/dist/core/agent-session-proxy.js +2 -0
- package/dist/core/agent-session-proxy.js.map +1 -0
- package/dist/core/agent-session-runtime.d.ts +10 -10
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +14 -14
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +8 -7
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +4 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +60 -27
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +303 -177
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/auth-storage.d.ts +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -2
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +3 -3
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +5 -5
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -37
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts +3 -3
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/index.d.ts +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +8 -6
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.js +23 -6
- package/dist/core/export-html/tool-renderer.d.ts +2 -2
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +8 -8
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +2 -2
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +17 -34
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +12 -7
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +36 -2
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +26 -24
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +2 -2
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +3 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +4 -0
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts +21 -0
- package/dist/core/http-dispatcher.d.ts.map +1 -0
- package/dist/core/http-dispatcher.js +48 -0
- package/dist/core/http-dispatcher.js.map +1 -0
- package/dist/core/index.d.ts +8 -8
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/local-agent-session-proxy.d.ts +82 -0
- package/dist/core/local-agent-session-proxy.d.ts.map +1 -0
- package/dist/core/local-agent-session-proxy.js +531 -0
- package/dist/core/local-agent-session-proxy.js.map +1 -0
- package/dist/core/messages.d.ts +0 -9
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +0 -10
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry.d.ts +4 -4
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +72 -16
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/output-guard.d.ts +1 -0
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js +52 -22
- package/dist/core/output-guard.js.map +1 -1
- package/dist/core/package-manager.d.ts +7 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +129 -64
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +12 -24
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +0 -1
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts +9 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +134 -11
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts +13 -10
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +41 -33
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +15 -13
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +24 -17
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +20 -10
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +201 -106
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +5 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +31 -13
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +2 -2
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +10 -27
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/source-info.d.ts +1 -1
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js.map +1 -1
- package/dist/core/system-prompt.d.ts +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +16 -9
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +55 -54
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +3 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +8 -1
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +5 -3
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +51 -91
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +27 -12
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts +2 -2
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +2 -3
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +2 -2
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +3 -3
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +17 -17
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +2 -2
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +10 -12
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +3 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +9 -3
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts +2 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js +39 -21
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/read.d.ts +2 -2
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +15 -15
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +5 -2
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +17 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js +12 -2
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/tools/write.d.ts +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +25 -41
- package/dist/core/tools/write.js.map +1 -1
- package/dist/d-pi-worker.d.ts +12 -0
- package/dist/d-pi-worker.d.ts.map +1 -0
- package/dist/d-pi-worker.js +9 -0
- package/dist/d-pi-worker.js.map +1 -0
- package/dist/index.d.ts +30 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +100 -39
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +118 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/connect/auth-headers.d.ts +2 -0
- package/dist/modes/connect/auth-headers.d.ts.map +1 -0
- package/dist/modes/connect/auth-headers.js +2 -0
- package/dist/modes/connect/auth-headers.js.map +1 -0
- package/dist/modes/connect/client-extension-sync.d.ts +13 -0
- package/dist/modes/connect/client-extension-sync.d.ts.map +1 -0
- package/dist/modes/connect/client-extension-sync.js +51 -0
- package/dist/modes/connect/client-extension-sync.js.map +1 -0
- package/dist/modes/connect/connect-mode.d.ts +6 -0
- package/dist/modes/connect/connect-mode.d.ts.map +1 -0
- package/dist/modes/connect/connect-mode.js +29 -0
- package/dist/modes/connect/connect-mode.js.map +1 -0
- package/dist/modes/connect/remote-agent-session-proxy.d.ts +81 -0
- package/dist/modes/connect/remote-agent-session-proxy.d.ts.map +1 -0
- package/dist/modes/connect/remote-agent-session-proxy.js +326 -0
- package/dist/modes/connect/remote-agent-session-proxy.js.map +1 -0
- package/dist/modes/connect/sse-client.d.ts +18 -0
- package/dist/modes/connect/sse-client.d.ts.map +1 -0
- package/dist/modes/connect/sse-client.js +90 -0
- package/dist/modes/connect/sse-client.js.map +1 -0
- package/dist/modes/index.d.ts +5 -5
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts +4 -4
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +8 -5
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts +2 -2
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js +2 -2
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +2 -2
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +0 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +14 -6
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +15 -4
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +126 -8
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +31 -31
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +7 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +28 -5
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +2 -2
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +3 -3
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +15 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +53 -7
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1247 -205
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +5 -4
- package/dist/modes/interactive/theme/light.json +5 -4
- package/dist/modes/interactive/theme/theme.d.ts +22 -3
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +130 -69
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +8 -5
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +65 -8
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +2 -2
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +18 -4
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +5 -4
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/serve/api-handlers.d.ts +4 -0
- package/dist/modes/serve/api-handlers.d.ts.map +1 -0
- package/dist/modes/serve/api-handlers.js +324 -0
- package/dist/modes/serve/api-handlers.js.map +1 -0
- package/dist/modes/serve/http-server.d.ts +14 -0
- package/dist/modes/serve/http-server.d.ts.map +1 -0
- package/dist/modes/serve/http-server.js +94 -0
- package/dist/modes/serve/http-server.js.map +1 -0
- package/dist/modes/serve/serve-mode.d.ts +10 -0
- package/dist/modes/serve/serve-mode.d.ts.map +1 -0
- package/dist/modes/serve/serve-mode.js +217 -0
- package/dist/modes/serve/serve-mode.js.map +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +62 -7
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js +47 -72
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/changelog.d.ts +1 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/child-process.d.ts +5 -2
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js +9 -7
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +3 -1
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js +14 -8
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/deprecation.d.ts +4 -0
- package/dist/utils/deprecation.d.ts.map +1 -0
- package/dist/utils/deprecation.js +13 -0
- package/dist/utils/deprecation.js.map +1 -0
- package/dist/utils/exif-orientation.d.ts +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/html.d.ts +7 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +40 -0
- package/dist/utils/html.js.map +1 -0
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts +30 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -0
- package/dist/utils/image-resize-core.js +124 -0
- package/dist/utils/image-resize-core.js.map +1 -0
- package/dist/utils/image-resize-worker.d.ts +2 -0
- package/dist/utils/image-resize-worker.d.ts.map +1 -0
- package/dist/utils/image-resize-worker.js +31 -0
- package/dist/utils/image-resize-worker.js.map +1 -0
- package/dist/utils/image-resize.d.ts +7 -27
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +75 -131
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/json.d.ts +3 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +7 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/paths.d.ts +16 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +49 -7
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +6 -1
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +12 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -0
- package/dist/utils/syntax-highlight.js +118 -0
- package/dist/utils/syntax-highlight.js.map +1 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +4 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +2 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +9 -4
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts +3 -0
- package/dist/utils/windows-self-update.d.ts.map +1 -0
- package/dist/utils/windows-self-update.js +77 -0
- package/dist/utils/windows-self-update.js.map +1 -0
- package/docs/custom-provider.md +111 -21
- package/docs/development.md +1 -1
- package/docs/extensions.md +13 -7
- package/docs/index.md +13 -3
- package/docs/models.md +32 -13
- package/docs/packages.md +9 -6
- package/docs/providers.md +13 -5
- package/docs/quickstart.md +24 -1
- package/docs/rpc.md +2 -1
- package/docs/sdk.md +8 -0
- package/docs/session-format.md +1 -1
- package/docs/sessions.md +8 -0
- package/docs/settings.md +8 -6
- package/docs/skills.md +3 -4
- package/docs/terminal-setup.md +8 -0
- package/docs/termux.md +3 -3
- package/docs/tui.md +2 -2
- package/docs/usage.md +13 -2
- package/examples/extensions/README.md +1 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +54 -3
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +1 -1
- package/examples/extensions/doom-overlay/doom-component.ts +2 -2
- package/examples/extensions/doom-overlay/index.ts +3 -3
- package/examples/extensions/git-merge-and-resolve.ts +115 -0
- package/examples/extensions/input-transform-streaming.ts +39 -0
- package/examples/extensions/overlay-qa-tests.ts +97 -66
- package/examples/extensions/overlay-test.ts +7 -4
- package/examples/extensions/plan-mode/index.ts +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +2 -2
- package/examples/extensions/subagent/README.md +3 -0
- package/examples/extensions/subagent/index.ts +42 -20
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +3 -3
- package/npm-shrinkwrap.json +1790 -0
- package/package.json +39 -32
- package/dist/utils/uuid.d.ts +0 -2
- package/dist/utils/uuid.d.ts.map +0 -1
- package/dist/utils/uuid.js +0 -40
- package/dist/utils/uuid.js.map +0 -1
|
@@ -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;AACxD,OAAO,EAAE,GAAG,EAA2B,MAAM,iBAAiB,CAAC;AAG/D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAKN,KAAK,aAAa,EAClB,KAAK,cAAc,EAKnB,MAAM,gBAAgB,CAAC;AAMxB,KAAK,WAAW,GAAG,cAAc,GAAG,aAAa,CAAC;AAElD,KAAK,eAAe,GAAG;IACtB,aAAa,CAAC,EAAE,uBAAuB,CAAC;CACxC,CAAC;AAaF,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;AAgDD,KAAK,uBAAuB,GAAG,GAAG,GAAG;IACpC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAmJF,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,EAAE,eAAe,CAAC,CAkMjF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG","sourcesContent":["import type { AgentTool } from \"@sheason/pi-agent-core\";\nimport { Box, Container, Spacer, Text } from \"@sheason/pi-tui\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from \"fs/promises\";\nimport { type Static, Type } from \"typebox\";\nimport { renderDiff } from \"../../modes/interactive/components/diff.js\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport {\n\tapplyEditsToNormalizedContent,\n\tcomputeEditsDiff,\n\tdetectLineEnding,\n\ttype Edit,\n\ttype EditDiffError,\n\ttype EditDiffResult,\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 EditPreview = EditDiffResult | EditDiffError;\n\ntype EditRenderState = {\n\tcallComponent?: EditCallRenderComponent;\n};\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 Record<string, unknown>;\n\n\t// Some models (Opus 4.6, GLM-5.1) send edits as a JSON string instead of an array\n\tif (typeof args.edits === \"string\") {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(args.edits);\n\t\t\tif (Array.isArray(parsed)) args.edits = parsed;\n\t\t} catch {}\n\t}\n\n\tconst legacy = args as LegacyEditToolInput;\n\tif (typeof legacy.oldText !== \"string\" || typeof legacy.newText !== \"string\") {\n\t\treturn args as EditToolInput;\n\t}\n\n\tconst edits = Array.isArray(legacy.edits) ? [...legacy.edits] : [];\n\tedits.push({ oldText: legacy.oldText, newText: legacy.newText });\n\tconst { oldText: _oldText, newText: _newText, ...rest } = legacy;\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\ntype EditToolResultLike = {\n\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\tdetails?: EditToolDetails;\n};\n\ntype EditCallRenderComponent = Box & {\n\tpreview?: EditPreview;\n\tpreviewArgsKey?: string;\n\tpreviewPending?: boolean;\n\tsettledError?: boolean;\n};\n\nfunction createEditCallRenderComponent(): EditCallRenderComponent {\n\treturn Object.assign(new Box(1, 1, (text: string) => text), {\n\t\tpreview: undefined as EditPreview | undefined,\n\t\tpreviewArgsKey: undefined as string | undefined,\n\t\tpreviewPending: false,\n\t\tsettledError: false,\n\t});\n}\n\nfunction getEditCallRenderComponent(state: EditRenderState, lastComponent: unknown): EditCallRenderComponent {\n\tif (lastComponent instanceof Box) {\n\t\tconst component = lastComponent as EditCallRenderComponent;\n\t\tstate.callComponent = component;\n\t\treturn component;\n\t}\n\tif (state.callComponent) {\n\t\treturn state.callComponent;\n\t}\n\tconst component = createEditCallRenderComponent();\n\tstate.callComponent = component;\n\treturn component;\n}\n\nfunction getRenderablePreviewInput(args: RenderableEditArgs | undefined): { path: string; edits: Edit[] } | null {\n\tif (!args) {\n\t\treturn null;\n\t}\n\n\tconst path = typeof args.path === \"string\" ? args.path : typeof args.file_path === \"string\" ? args.file_path : null;\n\tif (!path) {\n\t\treturn null;\n\t}\n\n\tif (\n\t\tArray.isArray(args.edits) &&\n\t\targs.edits.length > 0 &&\n\t\targs.edits.every((edit) => typeof edit?.oldText === \"string\" && typeof edit?.newText === \"string\")\n\t) {\n\t\treturn { path, edits: args.edits };\n\t}\n\n\tif (typeof args.oldText === \"string\" && typeof args.newText === \"string\") {\n\t\treturn { path, edits: [{ oldText: args.oldText, newText: args.newText }] };\n\t}\n\n\treturn null;\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\tpreview: EditPreview | undefined,\n\tresult: EditToolResultLike,\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\tconst previewDiff = preview && !(\"error\" in preview) ? preview.diff : undefined;\n\tconst previewError = preview && \"error\" in preview ? preview.error : undefined;\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 || errorText === previewError) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn theme.fg(\"error\", errorText);\n\t}\n\n\tconst resultDiff = result.details?.diff;\n\tif (resultDiff && resultDiff !== previewDiff) {\n\t\treturn renderDiff(resultDiff, { filePath: rawPath ?? undefined });\n\t}\n\n\treturn undefined;\n}\n\nfunction getEditHeaderBg(\n\tpreview: EditPreview | undefined,\n\tsettledError: boolean | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): (text: string) => string {\n\tif (preview) {\n\t\tif (\"error\" in preview) {\n\t\t\treturn (text: string) => theme.bg(\"toolErrorBg\", text);\n\t\t}\n\t\treturn (text: string) => theme.bg(\"toolSuccessBg\", text);\n\t}\n\tif (settledError) {\n\t\treturn (text: string) => theme.bg(\"toolErrorBg\", text);\n\t}\n\treturn (text: string) => theme.bg(\"toolPendingBg\", text);\n}\n\nfunction buildEditCallComponent(\n\tcomponent: EditCallRenderComponent,\n\targs: RenderableEditArgs | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): EditCallRenderComponent {\n\tcomponent.setBgFn(getEditHeaderBg(component.preview, component.settledError, theme));\n\tcomponent.clear();\n\tcomponent.addChild(new Text(formatEditCall(args, theme), 0, 0));\n\n\tif (!component.preview) {\n\t\treturn component;\n\t}\n\n\tconst body =\n\t\t\"error\" in component.preview ? theme.fg(\"error\", component.preview.error) : renderDiff(component.preview.diff);\n\tcomponent.addChild(new Spacer(1));\n\tcomponent.addChild(new Text(body, 0, 0));\n\treturn component;\n}\n\nfunction setEditPreview(\n\tcomponent: EditCallRenderComponent,\n\tpreview: EditPreview,\n\targsKey: string | undefined,\n): boolean {\n\tconst current = component.preview;\n\tconst changed =\n\t\tcurrent === undefined ||\n\t\t(\"error\" in current && \"error\" in preview\n\t\t\t? current.error !== preview.error\n\t\t\t: \"error\" in current !== \"error\" in preview) ||\n\t\t(!(\"error\" in current) &&\n\t\t\t!(\"error\" in preview) &&\n\t\t\t(current.diff !== preview.diff || current.firstChangedLine !== preview.firstChangedLine));\n\tcomponent.preview = preview;\n\tcomponent.previewArgsKey = argsKey;\n\tcomponent.previewPending = false;\n\treturn changed;\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\trenderShell: \"self\",\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 (error: unknown) {\n\t\t\t\t\t\t\t\t\tconst errorMessage =\n\t\t\t\t\t\t\t\t\t\terror instanceof Error && \"code\" in error ? `Error code: ${error.code}` : String(error);\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(`Could not edit file: ${path}. ${errorMessage}.`));\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 component = getEditCallRenderComponent(context.state, context.lastComponent);\n\t\t\tconst previewInput = getRenderablePreviewInput(args as RenderableEditArgs | undefined);\n\t\t\tconst argsKey = previewInput\n\t\t\t\t? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n\t\t\t\t: undefined;\n\n\t\t\tif (component.previewArgsKey !== argsKey) {\n\t\t\t\tcomponent.preview = undefined;\n\t\t\t\tcomponent.previewArgsKey = argsKey;\n\t\t\t\tcomponent.previewPending = false;\n\t\t\t\tcomponent.settledError = false;\n\t\t\t}\n\n\t\t\tif (context.argsComplete && previewInput && !component.preview && !component.previewPending) {\n\t\t\t\tcomponent.previewPending = true;\n\t\t\t\tconst requestKey = argsKey;\n\t\t\t\tvoid computeEditsDiff(previewInput.path, previewInput.edits, context.cwd).then((preview) => {\n\t\t\t\t\tif (component.previewArgsKey === requestKey) {\n\t\t\t\t\t\tsetEditPreview(component, preview, requestKey);\n\t\t\t\t\t\tcontext.invalidate();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn buildEditCallComponent(component, args, theme);\n\t\t},\n\t\trenderResult(result, _options, theme, context) {\n\t\t\tconst callComponent = context.state.callComponent;\n\t\t\tconst previewInput = getRenderablePreviewInput(context.args as RenderableEditArgs | undefined);\n\t\t\tconst argsKey = previewInput\n\t\t\t\t? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n\t\t\t\t: undefined;\n\t\t\tconst typedResult = result as EditToolResultLike;\n\t\t\tconst resultDiff = !context.isError ? typedResult.details?.diff : undefined;\n\t\t\tlet changed = false;\n\t\t\tif (callComponent) {\n\t\t\t\tif (typeof resultDiff === \"string\") {\n\t\t\t\t\tchanged =\n\t\t\t\t\t\tsetEditPreview(\n\t\t\t\t\t\t\tcallComponent,\n\t\t\t\t\t\t\t{ diff: resultDiff, firstChangedLine: typedResult.details?.firstChangedLine },\n\t\t\t\t\t\t\targsKey,\n\t\t\t\t\t\t) || changed;\n\t\t\t\t}\n\t\t\t\tif (callComponent.settledError !== context.isError) {\n\t\t\t\t\tcallComponent.settledError = context.isError;\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t\tif (changed) {\n\t\t\t\t\tbuildEditCallComponent(callComponent, context.args as RenderableEditArgs | undefined, theme);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst output = formatEditResult(context.args, callComponent?.preview, typedResult, theme, context.isError);\n\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\tcomponent.clear();\n\t\t\tif (!output) {\n\t\t\t\treturn component;\n\t\t\t}\n\t\t\tcomponent.addChild(new Spacer(1));\n\t\t\tcomponent.addChild(new Text(output, 1, 0));\n\t\t\treturn component;\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"]}
|
|
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;AACxD,OAAO,EAAE,GAAG,EAA2B,MAAM,iBAAiB,CAAC;AAG/D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAKN,KAAK,aAAa,EAClB,KAAK,cAAc,EAMnB,MAAM,gBAAgB,CAAC;AAMxB,KAAK,WAAW,GAAG,cAAc,GAAG,aAAa,CAAC;AAElD,KAAK,eAAe,GAAG;IACtB,aAAa,CAAC,EAAE,uBAAuB,CAAC;CACxC,CAAC;AAaF,QAAA,MAAM,UAAU;;;;;;EASf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAMtD,MAAM,WAAW,eAAe;IAC/B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,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;AAgDD,KAAK,uBAAuB,GAAG,GAAG,GAAG;IACpC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AA8IF,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","sourcesContent":["import type { AgentTool } from \"@sheason/pi-agent-core\";\nimport { Box, Container, Spacer, Text } from \"@sheason/pi-tui\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from \"fs/promises\";\nimport { type Static, Type } from \"typebox\";\nimport { renderDiff } from \"../../modes/interactive/components/diff.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport {\n\tapplyEditsToNormalizedContent,\n\tcomputeEditsDiff,\n\tdetectLineEnding,\n\ttype Edit,\n\ttype EditDiffError,\n\ttype EditDiffResult,\n\tgenerateDiffString,\n\tgenerateUnifiedPatch,\n\tnormalizeToLF,\n\trestoreLineEndings,\n\tstripBom,\n} from \"./edit-diff.ts\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport { renderToolPath, str } from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\ntype EditPreview = EditDiffResult | EditDiffError;\n\ntype EditRenderState = {\n\tcallComponent?: EditCallRenderComponent;\n};\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/** Display-oriented diff of the changes made */\n\tdiff: string;\n\t/** Standard unified patch of the changes made */\n\tpatch: 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 Record<string, unknown>;\n\n\t// Some models (Opus 4.6, GLM-5.1) send edits as a JSON string instead of an array\n\tif (typeof args.edits === \"string\") {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(args.edits);\n\t\t\tif (Array.isArray(parsed)) args.edits = parsed;\n\t\t} catch {}\n\t}\n\n\tconst legacy = args as LegacyEditToolInput;\n\tif (typeof legacy.oldText !== \"string\" || typeof legacy.newText !== \"string\") {\n\t\treturn args as EditToolInput;\n\t}\n\n\tconst edits = Array.isArray(legacy.edits) ? [...legacy.edits] : [];\n\tedits.push({ oldText: legacy.oldText, newText: legacy.newText });\n\tconst { oldText: _oldText, newText: _newText, ...rest } = legacy;\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\ntype EditToolResultLike = {\n\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\tdetails?: EditToolDetails;\n};\n\ntype EditCallRenderComponent = Box & {\n\tpreview?: EditPreview;\n\tpreviewArgsKey?: string;\n\tpreviewPending?: boolean;\n\tsettledError?: boolean;\n};\n\nfunction createEditCallRenderComponent(): EditCallRenderComponent {\n\treturn Object.assign(new Box(1, 1, (text: string) => text), {\n\t\tpreview: undefined as EditPreview | undefined,\n\t\tpreviewArgsKey: undefined as string | undefined,\n\t\tpreviewPending: false,\n\t\tsettledError: false,\n\t});\n}\n\nfunction getEditCallRenderComponent(state: EditRenderState, lastComponent: unknown): EditCallRenderComponent {\n\tif (lastComponent instanceof Box) {\n\t\tconst component = lastComponent as EditCallRenderComponent;\n\t\tstate.callComponent = component;\n\t\treturn component;\n\t}\n\tif (state.callComponent) {\n\t\treturn state.callComponent;\n\t}\n\tconst component = createEditCallRenderComponent();\n\tstate.callComponent = component;\n\treturn component;\n}\n\nfunction getRenderablePreviewInput(args: RenderableEditArgs | undefined): { path: string; edits: Edit[] } | null {\n\tif (!args) {\n\t\treturn null;\n\t}\n\n\tconst path = typeof args.path === \"string\" ? args.path : typeof args.file_path === \"string\" ? args.file_path : null;\n\tif (!path) {\n\t\treturn null;\n\t}\n\n\tif (\n\t\tArray.isArray(args.edits) &&\n\t\targs.edits.length > 0 &&\n\t\targs.edits.every((edit) => typeof edit?.oldText === \"string\" && typeof edit?.newText === \"string\")\n\t) {\n\t\treturn { path, edits: args.edits };\n\t}\n\n\tif (typeof args.oldText === \"string\" && typeof args.newText === \"string\") {\n\t\treturn { path, edits: [{ oldText: args.oldText, newText: args.newText }] };\n\t}\n\n\treturn null;\n}\n\nfunction formatEditCall(args: RenderableEditArgs | undefined, theme: Theme, cwd: string): string {\n\tconst pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);\n\treturn `${theme.fg(\"toolTitle\", theme.bold(\"edit\"))} ${pathDisplay}`;\n}\n\nfunction formatEditResult(\n\targs: RenderableEditArgs | undefined,\n\tpreview: EditPreview | undefined,\n\tresult: EditToolResultLike,\n\ttheme: Theme,\n\tisError: boolean,\n): string | undefined {\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tconst previewDiff = preview && !(\"error\" in preview) ? preview.diff : undefined;\n\tconst previewError = preview && \"error\" in preview ? preview.error : undefined;\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 || errorText === previewError) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn theme.fg(\"error\", errorText);\n\t}\n\n\tconst resultDiff = result.details?.diff;\n\tif (resultDiff && resultDiff !== previewDiff) {\n\t\treturn renderDiff(resultDiff, { filePath: rawPath ?? undefined });\n\t}\n\n\treturn undefined;\n}\n\nfunction getEditHeaderBg(\n\tpreview: EditPreview | undefined,\n\tsettledError: boolean | undefined,\n\ttheme: Theme,\n): (text: string) => string {\n\tif (preview) {\n\t\tif (\"error\" in preview) {\n\t\t\treturn (text: string) => theme.bg(\"toolErrorBg\", text);\n\t\t}\n\t\treturn (text: string) => theme.bg(\"toolSuccessBg\", text);\n\t}\n\tif (settledError) {\n\t\treturn (text: string) => theme.bg(\"toolErrorBg\", text);\n\t}\n\treturn (text: string) => theme.bg(\"toolPendingBg\", text);\n}\n\nfunction buildEditCallComponent(\n\tcomponent: EditCallRenderComponent,\n\targs: RenderableEditArgs | undefined,\n\ttheme: Theme,\n\tcwd: string,\n): EditCallRenderComponent {\n\tcomponent.setBgFn(getEditHeaderBg(component.preview, component.settledError, theme));\n\tcomponent.clear();\n\tcomponent.addChild(new Text(formatEditCall(args, theme, cwd), 0, 0));\n\n\tif (!component.preview) {\n\t\treturn component;\n\t}\n\n\tconst body =\n\t\t\"error\" in component.preview ? theme.fg(\"error\", component.preview.error) : renderDiff(component.preview.diff);\n\tcomponent.addChild(new Spacer(1));\n\tcomponent.addChild(new Text(body, 0, 0));\n\treturn component;\n}\n\nfunction setEditPreview(\n\tcomponent: EditCallRenderComponent,\n\tpreview: EditPreview,\n\targsKey: string | undefined,\n): boolean {\n\tconst current = component.preview;\n\tconst changed =\n\t\tcurrent === undefined ||\n\t\t(\"error\" in current && \"error\" in preview\n\t\t\t? current.error !== preview.error\n\t\t\t: \"error\" in current !== \"error\" in preview) ||\n\t\t(!(\"error\" in current) &&\n\t\t\t!(\"error\" in preview) &&\n\t\t\t(current.diff !== preview.diff || current.firstChangedLine !== preview.firstChangedLine));\n\tcomponent.preview = preview;\n\tcomponent.previewArgsKey = argsKey;\n\tcomponent.previewPending = false;\n\treturn changed;\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\trenderShell: \"self\",\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(absolutePath, async () => {\n\t\t\t\t// Do not reject from an abort event listener here: that would release the\n\t\t\t\t// mutation queue while an in-flight filesystem operation may still finish.\n\t\t\t\t// Checking signal.aborted after each await observes the same aborts while\n\t\t\t\t// keeping the queue locked until the current operation has settled.\n\t\t\t\tconst throwIfAborted = (): void => {\n\t\t\t\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\t\t\t};\n\n\t\t\t\tthrowIfAborted();\n\n\t\t\t\t// Check if file exists.\n\t\t\t\ttry {\n\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\tthrowIfAborted();\n\t\t\t\t\tconst errorMessage =\n\t\t\t\t\t\terror instanceof Error && \"code\" in error ? `Error code: ${error.code}` : String(error);\n\t\t\t\t\tthrow new Error(`Could not edit file: ${path}. ${errorMessage}.`);\n\t\t\t\t}\n\t\t\t\tthrowIfAborted();\n\n\t\t\t\t// Read the file.\n\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\tconst rawContent = buffer.toString(\"utf-8\");\n\t\t\t\tthrowIfAborted();\n\n\t\t\t\t// Strip BOM before matching. The model will not include an invisible BOM in oldText.\n\t\t\t\tconst { bom, text: content } = stripBom(rawContent);\n\t\t\t\tconst originalEnding = detectLineEnding(content);\n\t\t\t\tconst normalizedContent = normalizeToLF(content);\n\t\t\t\tconst { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);\n\t\t\t\tthrowIfAborted();\n\n\t\t\t\tconst finalContent = bom + restoreLineEndings(newContent, originalEnding);\n\t\t\t\tawait ops.writeFile(absolutePath, finalContent);\n\t\t\t\tthrowIfAborted();\n\n\t\t\t\tconst diffResult = generateDiffString(baseContent, newContent);\n\t\t\t\tconst patch = generateUnifiedPatch(path, baseContent, newContent);\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Successfully replaced ${edits.length} block(s) in ${path}.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: { diff: diffResult.diff, patch, firstChangedLine: diffResult.firstChangedLine },\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst component = getEditCallRenderComponent(context.state, context.lastComponent);\n\t\t\tconst previewInput = getRenderablePreviewInput(args as RenderableEditArgs | undefined);\n\t\t\tconst argsKey = previewInput\n\t\t\t\t? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n\t\t\t\t: undefined;\n\n\t\t\tif (component.previewArgsKey !== argsKey) {\n\t\t\t\tcomponent.preview = undefined;\n\t\t\t\tcomponent.previewArgsKey = argsKey;\n\t\t\t\tcomponent.previewPending = false;\n\t\t\t\tcomponent.settledError = false;\n\t\t\t}\n\n\t\t\tif (context.argsComplete && previewInput && !component.preview && !component.previewPending) {\n\t\t\t\tcomponent.previewPending = true;\n\t\t\t\tconst requestKey = argsKey;\n\t\t\t\tvoid computeEditsDiff(previewInput.path, previewInput.edits, context.cwd).then((preview) => {\n\t\t\t\t\tif (component.previewArgsKey === requestKey) {\n\t\t\t\t\t\tsetEditPreview(component, preview, requestKey);\n\t\t\t\t\t\tcontext.invalidate();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn buildEditCallComponent(component, args, theme, context.cwd);\n\t\t},\n\t\trenderResult(result, _options, theme, context) {\n\t\t\tconst callComponent = context.state.callComponent;\n\t\t\tconst previewInput = getRenderablePreviewInput(context.args as RenderableEditArgs | undefined);\n\t\t\tconst argsKey = previewInput\n\t\t\t\t? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n\t\t\t\t: undefined;\n\t\t\tconst typedResult = result as EditToolResultLike;\n\t\t\tconst resultDiff = !context.isError ? typedResult.details?.diff : undefined;\n\t\t\tlet changed = false;\n\t\t\tif (callComponent) {\n\t\t\t\tif (typeof resultDiff === \"string\") {\n\t\t\t\t\tchanged =\n\t\t\t\t\t\tsetEditPreview(\n\t\t\t\t\t\t\tcallComponent,\n\t\t\t\t\t\t\t{ diff: resultDiff, firstChangedLine: typedResult.details?.firstChangedLine },\n\t\t\t\t\t\t\targsKey,\n\t\t\t\t\t\t) || changed;\n\t\t\t\t}\n\t\t\t\tif (callComponent.settledError !== context.isError) {\n\t\t\t\t\tcallComponent.settledError = context.isError;\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t\tif (changed) {\n\t\t\t\t\tbuildEditCallComponent(\n\t\t\t\t\t\tcallComponent,\n\t\t\t\t\t\tcontext.args as RenderableEditArgs | undefined,\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t\tcontext.cwd,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst output = formatEditResult(context.args, callComponent?.preview, typedResult, theme, context.isError);\n\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\tcomponent.clear();\n\t\t\tif (!output) {\n\t\t\t\treturn component;\n\t\t\t}\n\t\t\tcomponent.addChild(new Spacer(1));\n\t\t\tcomponent.addChild(new Text(output, 1, 0));\n\t\t\treturn component;\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"]}
|
package/dist/core/tools/edit.js
CHANGED
|
@@ -3,10 +3,10 @@ import { constants } from "fs";
|
|
|
3
3
|
import { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from "fs/promises";
|
|
4
4
|
import { Type } from "typebox";
|
|
5
5
|
import { renderDiff } from "../../modes/interactive/components/diff.js";
|
|
6
|
-
import { applyEditsToNormalizedContent, computeEditsDiff, detectLineEnding, generateDiffString, normalizeToLF, restoreLineEndings, stripBom, } from "./edit-diff.js";
|
|
6
|
+
import { applyEditsToNormalizedContent, computeEditsDiff, detectLineEnding, generateDiffString, generateUnifiedPatch, normalizeToLF, restoreLineEndings, stripBom, } from "./edit-diff.js";
|
|
7
7
|
import { withFileMutationQueue } from "./file-mutation-queue.js";
|
|
8
8
|
import { resolveToCwd } from "./path-utils.js";
|
|
9
|
-
import {
|
|
9
|
+
import { renderToolPath, str } from "./render-utils.js";
|
|
10
10
|
import { wrapToolDefinition } from "./tool-definition-wrapper.js";
|
|
11
11
|
const replaceEditSchema = Type.Object({
|
|
12
12
|
oldText: Type.String({
|
|
@@ -93,11 +93,8 @@ function getRenderablePreviewInput(args) {
|
|
|
93
93
|
}
|
|
94
94
|
return null;
|
|
95
95
|
}
|
|
96
|
-
function formatEditCall(args, theme) {
|
|
97
|
-
const
|
|
98
|
-
const rawPath = str(args?.file_path ?? args?.path);
|
|
99
|
-
const path = rawPath !== null ? shortenPath(rawPath) : null;
|
|
100
|
-
const pathDisplay = path === null ? invalidArg : path ? theme.fg("accent", path) : theme.fg("toolOutput", "...");
|
|
96
|
+
function formatEditCall(args, theme, cwd) {
|
|
97
|
+
const pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);
|
|
101
98
|
return `${theme.fg("toolTitle", theme.bold("edit"))} ${pathDisplay}`;
|
|
102
99
|
}
|
|
103
100
|
function formatEditResult(args, preview, result, theme, isError) {
|
|
@@ -132,10 +129,10 @@ function getEditHeaderBg(preview, settledError, theme) {
|
|
|
132
129
|
}
|
|
133
130
|
return (text) => theme.bg("toolPendingBg", text);
|
|
134
131
|
}
|
|
135
|
-
function buildEditCallComponent(component, args, theme) {
|
|
132
|
+
function buildEditCallComponent(component, args, theme, cwd) {
|
|
136
133
|
component.setBgFn(getEditHeaderBg(component.preview, component.settledError, theme));
|
|
137
134
|
component.clear();
|
|
138
|
-
component.addChild(new Text(formatEditCall(args, theme), 0, 0));
|
|
135
|
+
component.addChild(new Text(formatEditCall(args, theme, cwd), 0, 0));
|
|
139
136
|
if (!component.preview) {
|
|
140
137
|
return component;
|
|
141
138
|
}
|
|
@@ -177,88 +174,51 @@ export function createEditToolDefinition(cwd, options) {
|
|
|
177
174
|
async execute(_toolCallId, input, signal, _onUpdate, _ctx) {
|
|
178
175
|
const { path, edits } = validateEditInput(input);
|
|
179
176
|
const absolutePath = resolveToCwd(path, cwd);
|
|
180
|
-
return withFileMutationQueue(absolutePath,
|
|
181
|
-
//
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const onAbort = () => {
|
|
189
|
-
aborted = true;
|
|
190
|
-
reject(new Error("Operation aborted"));
|
|
177
|
+
return withFileMutationQueue(absolutePath, async () => {
|
|
178
|
+
// Do not reject from an abort event listener here: that would release the
|
|
179
|
+
// mutation queue while an in-flight filesystem operation may still finish.
|
|
180
|
+
// Checking signal.aborted after each await observes the same aborts while
|
|
181
|
+
// keeping the queue locked until the current operation has settled.
|
|
182
|
+
const throwIfAborted = () => {
|
|
183
|
+
if (signal?.aborted)
|
|
184
|
+
throw new Error("Operation aborted");
|
|
191
185
|
};
|
|
192
|
-
|
|
193
|
-
|
|
186
|
+
throwIfAborted();
|
|
187
|
+
// Check if file exists.
|
|
188
|
+
try {
|
|
189
|
+
await ops.access(absolutePath);
|
|
194
190
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
// Check if aborted before writing.
|
|
227
|
-
if (aborted) {
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
const finalContent = bom + restoreLineEndings(newContent, originalEnding);
|
|
231
|
-
await ops.writeFile(absolutePath, finalContent);
|
|
232
|
-
// Check if aborted after writing.
|
|
233
|
-
if (aborted) {
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
// Clean up abort handler.
|
|
237
|
-
if (signal) {
|
|
238
|
-
signal.removeEventListener("abort", onAbort);
|
|
239
|
-
}
|
|
240
|
-
const diffResult = generateDiffString(baseContent, newContent);
|
|
241
|
-
resolve({
|
|
242
|
-
content: [
|
|
243
|
-
{
|
|
244
|
-
type: "text",
|
|
245
|
-
text: `Successfully replaced ${edits.length} block(s) in ${path}.`,
|
|
246
|
-
},
|
|
247
|
-
],
|
|
248
|
-
details: { diff: diffResult.diff, firstChangedLine: diffResult.firstChangedLine },
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
catch (error) {
|
|
252
|
-
// Clean up abort handler.
|
|
253
|
-
if (signal) {
|
|
254
|
-
signal.removeEventListener("abort", onAbort);
|
|
255
|
-
}
|
|
256
|
-
if (!aborted) {
|
|
257
|
-
reject(error instanceof Error ? error : new Error(String(error)));
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
})();
|
|
261
|
-
}));
|
|
191
|
+
catch (error) {
|
|
192
|
+
throwIfAborted();
|
|
193
|
+
const errorMessage = error instanceof Error && "code" in error ? `Error code: ${error.code}` : String(error);
|
|
194
|
+
throw new Error(`Could not edit file: ${path}. ${errorMessage}.`);
|
|
195
|
+
}
|
|
196
|
+
throwIfAborted();
|
|
197
|
+
// Read the file.
|
|
198
|
+
const buffer = await ops.readFile(absolutePath);
|
|
199
|
+
const rawContent = buffer.toString("utf-8");
|
|
200
|
+
throwIfAborted();
|
|
201
|
+
// Strip BOM before matching. The model will not include an invisible BOM in oldText.
|
|
202
|
+
const { bom, text: content } = stripBom(rawContent);
|
|
203
|
+
const originalEnding = detectLineEnding(content);
|
|
204
|
+
const normalizedContent = normalizeToLF(content);
|
|
205
|
+
const { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);
|
|
206
|
+
throwIfAborted();
|
|
207
|
+
const finalContent = bom + restoreLineEndings(newContent, originalEnding);
|
|
208
|
+
await ops.writeFile(absolutePath, finalContent);
|
|
209
|
+
throwIfAborted();
|
|
210
|
+
const diffResult = generateDiffString(baseContent, newContent);
|
|
211
|
+
const patch = generateUnifiedPatch(path, baseContent, newContent);
|
|
212
|
+
return {
|
|
213
|
+
content: [
|
|
214
|
+
{
|
|
215
|
+
type: "text",
|
|
216
|
+
text: `Successfully replaced ${edits.length} block(s) in ${path}.`,
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
details: { diff: diffResult.diff, patch, firstChangedLine: diffResult.firstChangedLine },
|
|
220
|
+
};
|
|
221
|
+
});
|
|
262
222
|
},
|
|
263
223
|
renderCall(args, theme, context) {
|
|
264
224
|
const component = getEditCallRenderComponent(context.state, context.lastComponent);
|
|
@@ -282,7 +242,7 @@ export function createEditToolDefinition(cwd, options) {
|
|
|
282
242
|
}
|
|
283
243
|
});
|
|
284
244
|
}
|
|
285
|
-
return buildEditCallComponent(component, args, theme);
|
|
245
|
+
return buildEditCallComponent(component, args, theme, context.cwd);
|
|
286
246
|
},
|
|
287
247
|
renderResult(result, _options, theme, context) {
|
|
288
248
|
const callComponent = context.state.callComponent;
|
|
@@ -303,7 +263,7 @@ export function createEditToolDefinition(cwd, options) {
|
|
|
303
263
|
changed = true;
|
|
304
264
|
}
|
|
305
265
|
if (changed) {
|
|
306
|
-
buildEditCallComponent(callComponent, context.args, theme);
|
|
266
|
+
buildEditCallComponent(callComponent, context.args, theme, context.cwd);
|
|
307
267
|
}
|
|
308
268
|
}
|
|
309
269
|
const output = formatEditResult(context.args, callComponent?.preview, typedResult, theme, context.isError);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC/D,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,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,4CAA4C,CAAC;AAExE,OAAO,EACN,6BAA6B,EAC7B,gBAAgB,EAChB,gBAAgB,EAIhB,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;AAQlE,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,EAAiB;IAC5D,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACzC,OAAO,KAAsB,CAAC;IAC/B,CAAC;IAED,MAAM,IAAI,GAAG,KAAgC,CAAC;IAE9C,kFAAkF;IAClF,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACpC,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,IAA2B,CAAC;IAC3C,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC9E,OAAO,IAAqB,CAAC;IAC9B,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACjE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IACjE,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAmB,CAAC;AAAA,CAC3C;AAED,SAAS,iBAAiB,CAAC,KAAoB,EAAmC;IACjF,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;AAAA,CAChD;AAsBD,SAAS,6BAA6B,GAA4B;IACjE,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE;QAC3D,OAAO,EAAE,SAAoC;QAC7C,cAAc,EAAE,SAA+B;QAC/C,cAAc,EAAE,KAAK;QACrB,YAAY,EAAE,KAAK;KACnB,CAAC,CAAC;AAAA,CACH;AAED,SAAS,0BAA0B,CAAC,KAAsB,EAAE,aAAsB,EAA2B;IAC5G,IAAI,aAAa,YAAY,GAAG,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,aAAwC,CAAC;QAC3D,KAAK,CAAC,aAAa,GAAG,SAAS,CAAC;QAChC,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,aAAa,CAAC;IAC5B,CAAC;IACD,MAAM,SAAS,GAAG,6BAA6B,EAAE,CAAC;IAClD,KAAK,CAAC,aAAa,GAAG,SAAS,CAAC;IAChC,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,yBAAyB,CAAC,IAAoC,EAA0C;IAChH,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IACpH,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IACC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;QACrB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,EAAE,OAAO,KAAK,QAAQ,CAAC,EACjG,CAAC;QACF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IACpC,CAAC;IAED,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC1E,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;IAC5E,CAAC;IAED,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,SAAS,cAAc,CACtB,IAAoC,EACpC,KAAoE,EAC3D;IACT,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;AAAA,CACrE;AAED,SAAS,gBAAgB,CACxB,IAAoC,EACpC,OAAgC,EAChC,MAA0B,EAC1B,KAAoE,EACpE,OAAgB,EACK;IACrB,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC;IACnD,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAChF,MAAM,YAAY,GAAG,OAAO,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,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,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;YAC9C,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,OAAO,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC;IACxC,IAAI,UAAU,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QAC9C,OAAO,UAAU,CAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,OAAO,IAAI,SAAS,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,eAAe,CACvB,OAAgC,EAChC,YAAiC,EACjC,KAAoE,EACzC;IAC3B,IAAI,OAAO,EAAE,CAAC;QACb,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;YACxB,OAAO,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;AAAA,CACzD;AAED,SAAS,sBAAsB,CAC9B,SAAkC,EAClC,IAAoC,EACpC,KAAoE,EAC1C;IAC1B,SAAS,CAAC,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC;IACrF,SAAS,CAAC,KAAK,EAAE,CAAC;IAClB,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEhE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GACT,OAAO,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAChH,SAAS,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,cAAc,CACtB,SAAkC,EAClC,OAAoB,EACpB,OAA2B,EACjB;IACV,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;IAClC,MAAM,OAAO,GACZ,OAAO,KAAK,SAAS;QACrB,CAAC,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO;YACxC,CAAC,CAAC,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK;YACjC,CAAC,CAAC,OAAO,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC;QAC7C,CAAC,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC;YACrB,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC;YACrB,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,gBAAgB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC5F,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC;IAC5B,SAAS,CAAC,cAAc,GAAG,OAAO,CAAC;IACnC,SAAS,CAAC,cAAc,GAAG,KAAK,CAAC;IACjC,OAAO,OAAO,CAAC;AAAA,CACf;AAED,MAAM,UAAU,wBAAwB,CACvC,GAAW,EACX,OAAyB,EACyD;IAClF,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,WAAW,EAAE,MAAM;QACnB,gBAAgB,EAAE,oBAAoB;QACtC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAoB,EAAE,MAAoB,EAAE,SAAU,EAAE,IAAK,EAAE;YACzF,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,CAAC;gBACvB,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,CAAC;oBACrB,OAAO,GAAG,IAAI,CAAC;oBACf,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBAAA,CACvC,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,CAAC;oBACjB,IAAI,CAAC;wBACJ,wBAAwB;wBACxB,IAAI,CAAC;4BACJ,MAAM,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;wBAChC,CAAC;wBAAC,OAAO,KAAc,EAAE,CAAC;4BACzB,MAAM,YAAY,GACjB,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,eAAe,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;4BACzF,IAAI,MAAM,EAAE,CAAC;gCACZ,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;4BAC9C,CAAC;4BACD,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,IAAI,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC;4BACpE,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;gBAAA,CACD,CAAC,EAAE,CAAC;YAAA,CACL,CAAC,CACH,CAAC;QAAA,CACF;QACD,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE;YAChC,MAAM,SAAS,GAAG,0BAA0B,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;YACnF,MAAM,YAAY,GAAG,yBAAyB,CAAC,IAAsC,CAAC,CAAC;YACvF,MAAM,OAAO,GAAG,YAAY;gBAC3B,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,CAAC;gBACxE,CAAC,CAAC,SAAS,CAAC;YAEb,IAAI,SAAS,CAAC,cAAc,KAAK,OAAO,EAAE,CAAC;gBAC1C,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC;gBAC9B,SAAS,CAAC,cAAc,GAAG,OAAO,CAAC;gBACnC,SAAS,CAAC,cAAc,GAAG,KAAK,CAAC;gBACjC,SAAS,CAAC,YAAY,GAAG,KAAK,CAAC;YAChC,CAAC;YAED,IAAI,OAAO,CAAC,YAAY,IAAI,YAAY,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;gBAC7F,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC;gBAChC,MAAM,UAAU,GAAG,OAAO,CAAC;gBAC3B,KAAK,gBAAgB,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;oBAC3F,IAAI,SAAS,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;wBAC7C,cAAc,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;wBAC/C,OAAO,CAAC,UAAU,EAAE,CAAC;oBACtB,CAAC;gBAAA,CACD,CAAC,CAAC;YACJ,CAAC;YAED,OAAO,sBAAsB,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAAA,CACtD;QACD,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE;YAC9C,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC;YAClD,MAAM,YAAY,GAAG,yBAAyB,CAAC,OAAO,CAAC,IAAsC,CAAC,CAAC;YAC/F,MAAM,OAAO,GAAG,YAAY;gBAC3B,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,CAAC;gBACxE,CAAC,CAAC,SAAS,CAAC;YACb,MAAM,WAAW,GAAG,MAA4B,CAAC;YACjD,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAC5E,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,aAAa,EAAE,CAAC;gBACnB,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;oBACpC,OAAO;wBACN,cAAc,CACb,aAAa,EACb,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAC7E,OAAO,CACP,IAAI,OAAO,CAAC;gBACf,CAAC;gBACD,IAAI,aAAa,CAAC,YAAY,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;oBACpD,aAAa,CAAC,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;oBAC7C,OAAO,GAAG,IAAI,CAAC;gBAChB,CAAC;gBACD,IAAI,OAAO,EAAE,CAAC;oBACb,sBAAsB,CAAC,aAAa,EAAE,OAAO,CAAC,IAAsC,EAAE,KAAK,CAAC,CAAC;gBAC9F,CAAC;YACF,CAAC;YAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAC3G,MAAM,SAAS,GAAI,OAAO,CAAC,aAAuC,IAAI,IAAI,SAAS,EAAE,CAAC;YACtF,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,EAAE,CAAC;gBACb,OAAO,SAAS,CAAC;YAClB,CAAC;YACD,SAAS,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3C,OAAO,SAAS,CAAC;QAAA,CACjB;KACD,CAAC;AAAA,CACF;AAED,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,OAAyB,EAAgC;IACpG,OAAO,kBAAkB,CAAC,wBAAwB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AAAA,CAClE","sourcesContent":["import type { AgentTool } from \"@sheason/pi-agent-core\";\nimport { Box, Container, Spacer, Text } from \"@sheason/pi-tui\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from \"fs/promises\";\nimport { type Static, Type } from \"typebox\";\nimport { renderDiff } from \"../../modes/interactive/components/diff.js\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport {\n\tapplyEditsToNormalizedContent,\n\tcomputeEditsDiff,\n\tdetectLineEnding,\n\ttype Edit,\n\ttype EditDiffError,\n\ttype EditDiffResult,\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 EditPreview = EditDiffResult | EditDiffError;\n\ntype EditRenderState = {\n\tcallComponent?: EditCallRenderComponent;\n};\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 Record<string, unknown>;\n\n\t// Some models (Opus 4.6, GLM-5.1) send edits as a JSON string instead of an array\n\tif (typeof args.edits === \"string\") {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(args.edits);\n\t\t\tif (Array.isArray(parsed)) args.edits = parsed;\n\t\t} catch {}\n\t}\n\n\tconst legacy = args as LegacyEditToolInput;\n\tif (typeof legacy.oldText !== \"string\" || typeof legacy.newText !== \"string\") {\n\t\treturn args as EditToolInput;\n\t}\n\n\tconst edits = Array.isArray(legacy.edits) ? [...legacy.edits] : [];\n\tedits.push({ oldText: legacy.oldText, newText: legacy.newText });\n\tconst { oldText: _oldText, newText: _newText, ...rest } = legacy;\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\ntype EditToolResultLike = {\n\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\tdetails?: EditToolDetails;\n};\n\ntype EditCallRenderComponent = Box & {\n\tpreview?: EditPreview;\n\tpreviewArgsKey?: string;\n\tpreviewPending?: boolean;\n\tsettledError?: boolean;\n};\n\nfunction createEditCallRenderComponent(): EditCallRenderComponent {\n\treturn Object.assign(new Box(1, 1, (text: string) => text), {\n\t\tpreview: undefined as EditPreview | undefined,\n\t\tpreviewArgsKey: undefined as string | undefined,\n\t\tpreviewPending: false,\n\t\tsettledError: false,\n\t});\n}\n\nfunction getEditCallRenderComponent(state: EditRenderState, lastComponent: unknown): EditCallRenderComponent {\n\tif (lastComponent instanceof Box) {\n\t\tconst component = lastComponent as EditCallRenderComponent;\n\t\tstate.callComponent = component;\n\t\treturn component;\n\t}\n\tif (state.callComponent) {\n\t\treturn state.callComponent;\n\t}\n\tconst component = createEditCallRenderComponent();\n\tstate.callComponent = component;\n\treturn component;\n}\n\nfunction getRenderablePreviewInput(args: RenderableEditArgs | undefined): { path: string; edits: Edit[] } | null {\n\tif (!args) {\n\t\treturn null;\n\t}\n\n\tconst path = typeof args.path === \"string\" ? args.path : typeof args.file_path === \"string\" ? args.file_path : null;\n\tif (!path) {\n\t\treturn null;\n\t}\n\n\tif (\n\t\tArray.isArray(args.edits) &&\n\t\targs.edits.length > 0 &&\n\t\targs.edits.every((edit) => typeof edit?.oldText === \"string\" && typeof edit?.newText === \"string\")\n\t) {\n\t\treturn { path, edits: args.edits };\n\t}\n\n\tif (typeof args.oldText === \"string\" && typeof args.newText === \"string\") {\n\t\treturn { path, edits: [{ oldText: args.oldText, newText: args.newText }] };\n\t}\n\n\treturn null;\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\tpreview: EditPreview | undefined,\n\tresult: EditToolResultLike,\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\tconst previewDiff = preview && !(\"error\" in preview) ? preview.diff : undefined;\n\tconst previewError = preview && \"error\" in preview ? preview.error : undefined;\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 || errorText === previewError) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn theme.fg(\"error\", errorText);\n\t}\n\n\tconst resultDiff = result.details?.diff;\n\tif (resultDiff && resultDiff !== previewDiff) {\n\t\treturn renderDiff(resultDiff, { filePath: rawPath ?? undefined });\n\t}\n\n\treturn undefined;\n}\n\nfunction getEditHeaderBg(\n\tpreview: EditPreview | undefined,\n\tsettledError: boolean | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): (text: string) => string {\n\tif (preview) {\n\t\tif (\"error\" in preview) {\n\t\t\treturn (text: string) => theme.bg(\"toolErrorBg\", text);\n\t\t}\n\t\treturn (text: string) => theme.bg(\"toolSuccessBg\", text);\n\t}\n\tif (settledError) {\n\t\treturn (text: string) => theme.bg(\"toolErrorBg\", text);\n\t}\n\treturn (text: string) => theme.bg(\"toolPendingBg\", text);\n}\n\nfunction buildEditCallComponent(\n\tcomponent: EditCallRenderComponent,\n\targs: RenderableEditArgs | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): EditCallRenderComponent {\n\tcomponent.setBgFn(getEditHeaderBg(component.preview, component.settledError, theme));\n\tcomponent.clear();\n\tcomponent.addChild(new Text(formatEditCall(args, theme), 0, 0));\n\n\tif (!component.preview) {\n\t\treturn component;\n\t}\n\n\tconst body =\n\t\t\"error\" in component.preview ? theme.fg(\"error\", component.preview.error) : renderDiff(component.preview.diff);\n\tcomponent.addChild(new Spacer(1));\n\tcomponent.addChild(new Text(body, 0, 0));\n\treturn component;\n}\n\nfunction setEditPreview(\n\tcomponent: EditCallRenderComponent,\n\tpreview: EditPreview,\n\targsKey: string | undefined,\n): boolean {\n\tconst current = component.preview;\n\tconst changed =\n\t\tcurrent === undefined ||\n\t\t(\"error\" in current && \"error\" in preview\n\t\t\t? current.error !== preview.error\n\t\t\t: \"error\" in current !== \"error\" in preview) ||\n\t\t(!(\"error\" in current) &&\n\t\t\t!(\"error\" in preview) &&\n\t\t\t(current.diff !== preview.diff || current.firstChangedLine !== preview.firstChangedLine));\n\tcomponent.preview = preview;\n\tcomponent.previewArgsKey = argsKey;\n\tcomponent.previewPending = false;\n\treturn changed;\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\trenderShell: \"self\",\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 (error: unknown) {\n\t\t\t\t\t\t\t\t\tconst errorMessage =\n\t\t\t\t\t\t\t\t\t\terror instanceof Error && \"code\" in error ? `Error code: ${error.code}` : String(error);\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(`Could not edit file: ${path}. ${errorMessage}.`));\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 component = getEditCallRenderComponent(context.state, context.lastComponent);\n\t\t\tconst previewInput = getRenderablePreviewInput(args as RenderableEditArgs | undefined);\n\t\t\tconst argsKey = previewInput\n\t\t\t\t? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n\t\t\t\t: undefined;\n\n\t\t\tif (component.previewArgsKey !== argsKey) {\n\t\t\t\tcomponent.preview = undefined;\n\t\t\t\tcomponent.previewArgsKey = argsKey;\n\t\t\t\tcomponent.previewPending = false;\n\t\t\t\tcomponent.settledError = false;\n\t\t\t}\n\n\t\t\tif (context.argsComplete && previewInput && !component.preview && !component.previewPending) {\n\t\t\t\tcomponent.previewPending = true;\n\t\t\t\tconst requestKey = argsKey;\n\t\t\t\tvoid computeEditsDiff(previewInput.path, previewInput.edits, context.cwd).then((preview) => {\n\t\t\t\t\tif (component.previewArgsKey === requestKey) {\n\t\t\t\t\t\tsetEditPreview(component, preview, requestKey);\n\t\t\t\t\t\tcontext.invalidate();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn buildEditCallComponent(component, args, theme);\n\t\t},\n\t\trenderResult(result, _options, theme, context) {\n\t\t\tconst callComponent = context.state.callComponent;\n\t\t\tconst previewInput = getRenderablePreviewInput(context.args as RenderableEditArgs | undefined);\n\t\t\tconst argsKey = previewInput\n\t\t\t\t? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n\t\t\t\t: undefined;\n\t\t\tconst typedResult = result as EditToolResultLike;\n\t\t\tconst resultDiff = !context.isError ? typedResult.details?.diff : undefined;\n\t\t\tlet changed = false;\n\t\t\tif (callComponent) {\n\t\t\t\tif (typeof resultDiff === \"string\") {\n\t\t\t\t\tchanged =\n\t\t\t\t\t\tsetEditPreview(\n\t\t\t\t\t\t\tcallComponent,\n\t\t\t\t\t\t\t{ diff: resultDiff, firstChangedLine: typedResult.details?.firstChangedLine },\n\t\t\t\t\t\t\targsKey,\n\t\t\t\t\t\t) || changed;\n\t\t\t\t}\n\t\t\t\tif (callComponent.settledError !== context.isError) {\n\t\t\t\t\tcallComponent.settledError = context.isError;\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t\tif (changed) {\n\t\t\t\t\tbuildEditCallComponent(callComponent, context.args as RenderableEditArgs | undefined, theme);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst output = formatEditResult(context.args, callComponent?.preview, typedResult, theme, context.isError);\n\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\tcomponent.clear();\n\t\t\tif (!output) {\n\t\t\t\treturn component;\n\t\t\t}\n\t\t\tcomponent.addChild(new Spacer(1));\n\t\t\tcomponent.addChild(new Text(output, 1, 0));\n\t\t\treturn component;\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"]}
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@sheason/pi-agent-core\";\nimport { Box, Container, Spacer, Text } from \"@sheason/pi-tui\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from \"fs/promises\";\nimport { type Static, Type } from \"typebox\";\nimport { renderDiff } from \"../../modes/interactive/components/diff.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport {\n\tapplyEditsToNormalizedContent,\n\tcomputeEditsDiff,\n\tdetectLineEnding,\n\ttype Edit,\n\ttype EditDiffError,\n\ttype EditDiffResult,\n\tgenerateDiffString,\n\tgenerateUnifiedPatch,\n\tnormalizeToLF,\n\trestoreLineEndings,\n\tstripBom,\n} from \"./edit-diff.ts\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport { renderToolPath, str } from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\ntype EditPreview = EditDiffResult | EditDiffError;\n\ntype EditRenderState = {\n\tcallComponent?: EditCallRenderComponent;\n};\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/** Display-oriented diff of the changes made */\n\tdiff: string;\n\t/** Standard unified patch of the changes made */\n\tpatch: 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 Record<string, unknown>;\n\n\t// Some models (Opus 4.6, GLM-5.1) send edits as a JSON string instead of an array\n\tif (typeof args.edits === \"string\") {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(args.edits);\n\t\t\tif (Array.isArray(parsed)) args.edits = parsed;\n\t\t} catch {}\n\t}\n\n\tconst legacy = args as LegacyEditToolInput;\n\tif (typeof legacy.oldText !== \"string\" || typeof legacy.newText !== \"string\") {\n\t\treturn args as EditToolInput;\n\t}\n\n\tconst edits = Array.isArray(legacy.edits) ? [...legacy.edits] : [];\n\tedits.push({ oldText: legacy.oldText, newText: legacy.newText });\n\tconst { oldText: _oldText, newText: _newText, ...rest } = legacy;\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\ntype EditToolResultLike = {\n\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\tdetails?: EditToolDetails;\n};\n\ntype EditCallRenderComponent = Box & {\n\tpreview?: EditPreview;\n\tpreviewArgsKey?: string;\n\tpreviewPending?: boolean;\n\tsettledError?: boolean;\n};\n\nfunction createEditCallRenderComponent(): EditCallRenderComponent {\n\treturn Object.assign(new Box(1, 1, (text: string) => text), {\n\t\tpreview: undefined as EditPreview | undefined,\n\t\tpreviewArgsKey: undefined as string | undefined,\n\t\tpreviewPending: false,\n\t\tsettledError: false,\n\t});\n}\n\nfunction getEditCallRenderComponent(state: EditRenderState, lastComponent: unknown): EditCallRenderComponent {\n\tif (lastComponent instanceof Box) {\n\t\tconst component = lastComponent as EditCallRenderComponent;\n\t\tstate.callComponent = component;\n\t\treturn component;\n\t}\n\tif (state.callComponent) {\n\t\treturn state.callComponent;\n\t}\n\tconst component = createEditCallRenderComponent();\n\tstate.callComponent = component;\n\treturn component;\n}\n\nfunction getRenderablePreviewInput(args: RenderableEditArgs | undefined): { path: string; edits: Edit[] } | null {\n\tif (!args) {\n\t\treturn null;\n\t}\n\n\tconst path = typeof args.path === \"string\" ? args.path : typeof args.file_path === \"string\" ? args.file_path : null;\n\tif (!path) {\n\t\treturn null;\n\t}\n\n\tif (\n\t\tArray.isArray(args.edits) &&\n\t\targs.edits.length > 0 &&\n\t\targs.edits.every((edit) => typeof edit?.oldText === \"string\" && typeof edit?.newText === \"string\")\n\t) {\n\t\treturn { path, edits: args.edits };\n\t}\n\n\tif (typeof args.oldText === \"string\" && typeof args.newText === \"string\") {\n\t\treturn { path, edits: [{ oldText: args.oldText, newText: args.newText }] };\n\t}\n\n\treturn null;\n}\n\nfunction formatEditCall(args: RenderableEditArgs | undefined, theme: Theme, cwd: string): string {\n\tconst pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);\n\treturn `${theme.fg(\"toolTitle\", theme.bold(\"edit\"))} ${pathDisplay}`;\n}\n\nfunction formatEditResult(\n\targs: RenderableEditArgs | undefined,\n\tpreview: EditPreview | undefined,\n\tresult: EditToolResultLike,\n\ttheme: Theme,\n\tisError: boolean,\n): string | undefined {\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tconst previewDiff = preview && !(\"error\" in preview) ? preview.diff : undefined;\n\tconst previewError = preview && \"error\" in preview ? preview.error : undefined;\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 || errorText === previewError) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn theme.fg(\"error\", errorText);\n\t}\n\n\tconst resultDiff = result.details?.diff;\n\tif (resultDiff && resultDiff !== previewDiff) {\n\t\treturn renderDiff(resultDiff, { filePath: rawPath ?? undefined });\n\t}\n\n\treturn undefined;\n}\n\nfunction getEditHeaderBg(\n\tpreview: EditPreview | undefined,\n\tsettledError: boolean | undefined,\n\ttheme: Theme,\n): (text: string) => string {\n\tif (preview) {\n\t\tif (\"error\" in preview) {\n\t\t\treturn (text: string) => theme.bg(\"toolErrorBg\", text);\n\t\t}\n\t\treturn (text: string) => theme.bg(\"toolSuccessBg\", text);\n\t}\n\tif (settledError) {\n\t\treturn (text: string) => theme.bg(\"toolErrorBg\", text);\n\t}\n\treturn (text: string) => theme.bg(\"toolPendingBg\", text);\n}\n\nfunction buildEditCallComponent(\n\tcomponent: EditCallRenderComponent,\n\targs: RenderableEditArgs | undefined,\n\ttheme: Theme,\n\tcwd: string,\n): EditCallRenderComponent {\n\tcomponent.setBgFn(getEditHeaderBg(component.preview, component.settledError, theme));\n\tcomponent.clear();\n\tcomponent.addChild(new Text(formatEditCall(args, theme, cwd), 0, 0));\n\n\tif (!component.preview) {\n\t\treturn component;\n\t}\n\n\tconst body =\n\t\t\"error\" in component.preview ? theme.fg(\"error\", component.preview.error) : renderDiff(component.preview.diff);\n\tcomponent.addChild(new Spacer(1));\n\tcomponent.addChild(new Text(body, 0, 0));\n\treturn component;\n}\n\nfunction setEditPreview(\n\tcomponent: EditCallRenderComponent,\n\tpreview: EditPreview,\n\targsKey: string | undefined,\n): boolean {\n\tconst current = component.preview;\n\tconst changed =\n\t\tcurrent === undefined ||\n\t\t(\"error\" in current && \"error\" in preview\n\t\t\t? current.error !== preview.error\n\t\t\t: \"error\" in current !== \"error\" in preview) ||\n\t\t(!(\"error\" in current) &&\n\t\t\t!(\"error\" in preview) &&\n\t\t\t(current.diff !== preview.diff || current.firstChangedLine !== preview.firstChangedLine));\n\tcomponent.preview = preview;\n\tcomponent.previewArgsKey = argsKey;\n\tcomponent.previewPending = false;\n\treturn changed;\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\trenderShell: \"self\",\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(absolutePath, async () => {\n\t\t\t\t// Do not reject from an abort event listener here: that would release the\n\t\t\t\t// mutation queue while an in-flight filesystem operation may still finish.\n\t\t\t\t// Checking signal.aborted after each await observes the same aborts while\n\t\t\t\t// keeping the queue locked until the current operation has settled.\n\t\t\t\tconst throwIfAborted = (): void => {\n\t\t\t\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\t\t\t};\n\n\t\t\t\tthrowIfAborted();\n\n\t\t\t\t// Check if file exists.\n\t\t\t\ttry {\n\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\tthrowIfAborted();\n\t\t\t\t\tconst errorMessage =\n\t\t\t\t\t\terror instanceof Error && \"code\" in error ? `Error code: ${error.code}` : String(error);\n\t\t\t\t\tthrow new Error(`Could not edit file: ${path}. ${errorMessage}.`);\n\t\t\t\t}\n\t\t\t\tthrowIfAborted();\n\n\t\t\t\t// Read the file.\n\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\tconst rawContent = buffer.toString(\"utf-8\");\n\t\t\t\tthrowIfAborted();\n\n\t\t\t\t// Strip BOM before matching. The model will not include an invisible BOM in oldText.\n\t\t\t\tconst { bom, text: content } = stripBom(rawContent);\n\t\t\t\tconst originalEnding = detectLineEnding(content);\n\t\t\t\tconst normalizedContent = normalizeToLF(content);\n\t\t\t\tconst { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);\n\t\t\t\tthrowIfAborted();\n\n\t\t\t\tconst finalContent = bom + restoreLineEndings(newContent, originalEnding);\n\t\t\t\tawait ops.writeFile(absolutePath, finalContent);\n\t\t\t\tthrowIfAborted();\n\n\t\t\t\tconst diffResult = generateDiffString(baseContent, newContent);\n\t\t\t\tconst patch = generateUnifiedPatch(path, baseContent, newContent);\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Successfully replaced ${edits.length} block(s) in ${path}.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: { diff: diffResult.diff, patch, firstChangedLine: diffResult.firstChangedLine },\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst component = getEditCallRenderComponent(context.state, context.lastComponent);\n\t\t\tconst previewInput = getRenderablePreviewInput(args as RenderableEditArgs | undefined);\n\t\t\tconst argsKey = previewInput\n\t\t\t\t? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n\t\t\t\t: undefined;\n\n\t\t\tif (component.previewArgsKey !== argsKey) {\n\t\t\t\tcomponent.preview = undefined;\n\t\t\t\tcomponent.previewArgsKey = argsKey;\n\t\t\t\tcomponent.previewPending = false;\n\t\t\t\tcomponent.settledError = false;\n\t\t\t}\n\n\t\t\tif (context.argsComplete && previewInput && !component.preview && !component.previewPending) {\n\t\t\t\tcomponent.previewPending = true;\n\t\t\t\tconst requestKey = argsKey;\n\t\t\t\tvoid computeEditsDiff(previewInput.path, previewInput.edits, context.cwd).then((preview) => {\n\t\t\t\t\tif (component.previewArgsKey === requestKey) {\n\t\t\t\t\t\tsetEditPreview(component, preview, requestKey);\n\t\t\t\t\t\tcontext.invalidate();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn buildEditCallComponent(component, args, theme, context.cwd);\n\t\t},\n\t\trenderResult(result, _options, theme, context) {\n\t\t\tconst callComponent = context.state.callComponent;\n\t\t\tconst previewInput = getRenderablePreviewInput(context.args as RenderableEditArgs | undefined);\n\t\t\tconst argsKey = previewInput\n\t\t\t\t? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n\t\t\t\t: undefined;\n\t\t\tconst typedResult = result as EditToolResultLike;\n\t\t\tconst resultDiff = !context.isError ? typedResult.details?.diff : undefined;\n\t\t\tlet changed = false;\n\t\t\tif (callComponent) {\n\t\t\t\tif (typeof resultDiff === \"string\") {\n\t\t\t\t\tchanged =\n\t\t\t\t\t\tsetEditPreview(\n\t\t\t\t\t\t\tcallComponent,\n\t\t\t\t\t\t\t{ diff: resultDiff, firstChangedLine: typedResult.details?.firstChangedLine },\n\t\t\t\t\t\t\targsKey,\n\t\t\t\t\t\t) || changed;\n\t\t\t\t}\n\t\t\t\tif (callComponent.settledError !== context.isError) {\n\t\t\t\t\tcallComponent.settledError = context.isError;\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t\tif (changed) {\n\t\t\t\t\tbuildEditCallComponent(\n\t\t\t\t\t\tcallComponent,\n\t\t\t\t\t\tcontext.args as RenderableEditArgs | undefined,\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t\tcontext.cwd,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst output = formatEditResult(context.args, callComponent?.preview, typedResult, theme, context.isError);\n\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\tcomponent.clear();\n\t\t\tif (!output) {\n\t\t\t\treturn component;\n\t\t\t}\n\t\t\tcomponent.addChild(new Spacer(1));\n\t\t\tcomponent.addChild(new Text(output, 1, 0));\n\t\t\treturn component;\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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-mutation-queue.d.ts","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-mutation-queue.d.ts","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"AA2BA;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CA6BjG","sourcesContent":["import { realpath } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nconst fileMutationQueues = new Map<string, Promise<void>>();\nlet registrationQueue = Promise.resolve();\n\nfunction isMissingPathError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\t(error.code === \"ENOENT\" || error.code === \"ENOTDIR\")\n\t);\n}\n\nasync function getMutationQueueKey(filePath: string): Promise<string> {\n\tconst resolvedPath = resolve(filePath);\n\ttry {\n\t\treturn await realpath(resolvedPath);\n\t} catch (error) {\n\t\tif (isMissingPathError(error)) {\n\t\t\treturn resolvedPath;\n\t\t}\n\t\tthrow error;\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 registration = registrationQueue.then(async () => {\n\t\tconst key = await getMutationQueueKey(filePath);\n\t\tconst currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();\n\n\t\tlet releaseNext!: () => void;\n\t\tconst nextQueue = new Promise<void>((resolveQueue) => {\n\t\t\treleaseNext = resolveQueue;\n\t\t});\n\t\tconst chainedQueue = currentQueue.then(() => nextQueue);\n\t\tfileMutationQueues.set(key, chainedQueue);\n\n\t\treturn { key, currentQueue, chainedQueue, releaseNext };\n\t});\n\tregistrationQueue = registration.then(\n\t\t() => undefined,\n\t\t() => undefined,\n\t);\n\n\tconst { key, currentQueue, chainedQueue, releaseNext } = await registration;\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,13 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { realpath } from "node:fs/promises";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
const fileMutationQueues = new Map();
|
|
4
|
-
|
|
4
|
+
let registrationQueue = Promise.resolve();
|
|
5
|
+
function isMissingPathError(error) {
|
|
6
|
+
return (typeof error === "object" &&
|
|
7
|
+
error !== null &&
|
|
8
|
+
"code" in error &&
|
|
9
|
+
(error.code === "ENOENT" || error.code === "ENOTDIR"));
|
|
10
|
+
}
|
|
11
|
+
async function getMutationQueueKey(filePath) {
|
|
5
12
|
const resolvedPath = resolve(filePath);
|
|
6
13
|
try {
|
|
7
|
-
return
|
|
14
|
+
return await realpath(resolvedPath);
|
|
8
15
|
}
|
|
9
|
-
catch {
|
|
10
|
-
|
|
16
|
+
catch (error) {
|
|
17
|
+
if (isMissingPathError(error)) {
|
|
18
|
+
return resolvedPath;
|
|
19
|
+
}
|
|
20
|
+
throw error;
|
|
11
21
|
}
|
|
12
22
|
}
|
|
13
23
|
/**
|
|
@@ -15,14 +25,19 @@ function getMutationQueueKey(filePath) {
|
|
|
15
25
|
* Operations for different files still run in parallel.
|
|
16
26
|
*/
|
|
17
27
|
export async function withFileMutationQueue(filePath, fn) {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
const registration = registrationQueue.then(async () => {
|
|
29
|
+
const key = await getMutationQueueKey(filePath);
|
|
30
|
+
const currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();
|
|
31
|
+
let releaseNext;
|
|
32
|
+
const nextQueue = new Promise((resolveQueue) => {
|
|
33
|
+
releaseNext = resolveQueue;
|
|
34
|
+
});
|
|
35
|
+
const chainedQueue = currentQueue.then(() => nextQueue);
|
|
36
|
+
fileMutationQueues.set(key, chainedQueue);
|
|
37
|
+
return { key, currentQueue, chainedQueue, releaseNext };
|
|
23
38
|
});
|
|
24
|
-
|
|
25
|
-
|
|
39
|
+
registrationQueue = registration.then(() => undefined, () => undefined);
|
|
40
|
+
const { key, currentQueue, chainedQueue, releaseNext } = await registration;
|
|
26
41
|
await currentQueue;
|
|
27
42
|
try {
|
|
28
43
|
return await fn();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-mutation-queue.js","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"file-mutation-queue.js","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAyB,CAAC;AAC5D,IAAI,iBAAiB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;AAE1C,SAAS,kBAAkB,CAAC,KAAc,EAAW;IACpD,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CACrD,CAAC;AAAA,CACF;AAED,KAAK,UAAU,mBAAmB,CAAC,QAAgB,EAAmB;IACrE,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC;QACJ,OAAO,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,YAAY,CAAC;QACrB,CAAC;QACD,MAAM,KAAK,CAAC;IACb,CAAC;AAAA,CACD;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAI,QAAgB,EAAE,EAAoB,EAAc;IAClG,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QACvD,MAAM,GAAG,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,YAAY,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAEtE,IAAI,WAAwB,CAAC;QAC7B,MAAM,SAAS,GAAG,IAAI,OAAO,CAAO,CAAC,YAAY,EAAE,EAAE,CAAC;YACrD,WAAW,GAAG,YAAY,CAAC;QAAA,CAC3B,CAAC,CAAC;QACH,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACxD,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAE1C,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;IAAA,CACxD,CAAC,CAAC;IACH,iBAAiB,GAAG,YAAY,CAAC,IAAI,CACpC,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;IAEF,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,MAAM,YAAY,CAAC;IAC5E,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;AAAA,CACD","sourcesContent":["import { realpath } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nconst fileMutationQueues = new Map<string, Promise<void>>();\nlet registrationQueue = Promise.resolve();\n\nfunction isMissingPathError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\t(error.code === \"ENOENT\" || error.code === \"ENOTDIR\")\n\t);\n}\n\nasync function getMutationQueueKey(filePath: string): Promise<string> {\n\tconst resolvedPath = resolve(filePath);\n\ttry {\n\t\treturn await realpath(resolvedPath);\n\t} catch (error) {\n\t\tif (isMissingPathError(error)) {\n\t\t\treturn resolvedPath;\n\t\t}\n\t\tthrow error;\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 registration = registrationQueue.then(async () => {\n\t\tconst key = await getMutationQueueKey(filePath);\n\t\tconst currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();\n\n\t\tlet releaseNext!: () => void;\n\t\tconst nextQueue = new Promise<void>((resolveQueue) => {\n\t\t\treleaseNext = resolveQueue;\n\t\t});\n\t\tconst chainedQueue = currentQueue.then(() => nextQueue);\n\t\tfileMutationQueues.set(key, chainedQueue);\n\n\t\treturn { key, currentQueue, chainedQueue, releaseNext };\n\t});\n\tregistrationQueue = registration.then(\n\t\t() => undefined,\n\t\t() => undefined,\n\t);\n\n\tconst { key, currentQueue, chainedQueue, releaseNext } = await registration;\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,7 +1,7 @@
|
|
|
1
1
|
import type { AgentTool } from "@sheason/pi-agent-core";
|
|
2
2
|
import { type Static, Type } from "typebox";
|
|
3
|
-
import type { ToolDefinition } from "../extensions/types.
|
|
4
|
-
import { type TruncationResult } from "./truncate.
|
|
3
|
+
import type { ToolDefinition } from "../extensions/types.ts";
|
|
4
|
+
import { type TruncationResult } from "./truncate.ts";
|
|
5
5
|
declare const findSchema: Type.TObject<{
|
|
6
6
|
pattern: Type.TString;
|
|
7
7
|
path: Type.TOptional<Type.TString>;
|