@greppleai/grip 0.1.4 → 0.1.6
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 +47 -0
- package/README.md +2 -2
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/embedded-assets.d.ts.map +1 -1
- package/dist/bun/embedded-assets.js.map +1 -1
- package/dist/bun/register-bedrock.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.js.map +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +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.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.map +1 -1
- package/dist/cli/list-models.js.map +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.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +27 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +117 -152
- 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 +4 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +6 -11
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +19 -23
- package/dist/core/bash-executor.js.map +1 -1
- 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.map +1 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/compression-detection-ledger.d.ts.map +1 -1
- package/dist/core/compaction/compression-detection-ledger.js.map +1 -1
- package/dist/core/compaction/compression-detector.d.ts +1 -0
- package/dist/core/compaction/compression-detector.d.ts.map +1 -1
- package/dist/core/compaction/compression-detector.js +10 -21
- package/dist/core/compaction/compression-detector.js.map +1 -1
- package/dist/core/compaction/compression-economics.d.ts.map +1 -1
- package/dist/core/compaction/compression-economics.js.map +1 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/diagnostics.d.ts.map +1 -1
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.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/ansi-to-html.d.ts.map +1 -1
- package/dist/core/export-html/ansi-to-html.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js.map +1 -1
- 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/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +18 -30
- package/dist/core/extensions/runner.js.map +1 -1
- 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.map +1 -1
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +15 -16
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/grip-agent.d.ts.map +1 -1
- package/dist/core/grip-agent.js +11 -23
- package/dist/core/grip-agent.js.map +1 -1
- package/dist/core/grip-manifest.d.ts.map +1 -1
- package/dist/core/grip-manifest.js.map +1 -1
- package/dist/core/hooks/aggregate.d.ts.map +1 -1
- package/dist/core/hooks/aggregate.js.map +1 -1
- package/dist/core/hooks/config.d.ts.map +1 -1
- package/dist/core/hooks/config.js.map +1 -1
- package/dist/core/hooks/executor.d.ts.map +1 -1
- package/dist/core/hooks/executor.js.map +1 -1
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/index.js.map +1 -1
- package/dist/core/hooks/matcher.d.ts.map +1 -1
- package/dist/core/hooks/matcher.js.map +1 -1
- package/dist/core/hooks/trust-store.d.ts.map +1 -1
- package/dist/core/hooks/trust-store.js +0 -3
- package/dist/core/hooks/trust-store.js.map +1 -1
- package/dist/core/hooks/types.d.ts.map +1 -1
- package/dist/core/hooks/types.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/instruction-resource-loader.d.ts.map +1 -1
- package/dist/core/instruction-resource-loader.js +0 -3
- package/dist/core/instruction-resource-loader.js.map +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +0 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/lsp/abort.d.ts.map +1 -1
- package/dist/core/lsp/abort.js.map +1 -1
- package/dist/core/lsp/client.d.ts.map +1 -1
- package/dist/core/lsp/client.js +8 -22
- package/dist/core/lsp/client.js.map +1 -1
- package/dist/core/lsp/config-loader.d.ts.map +1 -1
- package/dist/core/lsp/config-loader.js.map +1 -1
- package/dist/core/lsp/config.d.ts.map +1 -1
- package/dist/core/lsp/config.js.map +1 -1
- package/dist/core/lsp/diagnostics.d.ts.map +1 -1
- package/dist/core/lsp/diagnostics.js.map +1 -1
- package/dist/core/lsp/file-sync.d.ts.map +1 -1
- package/dist/core/lsp/file-sync.js +7 -9
- package/dist/core/lsp/file-sync.js.map +1 -1
- package/dist/core/lsp/integration.d.ts.map +1 -1
- package/dist/core/lsp/integration.js.map +1 -1
- package/dist/core/lsp/language-map.d.ts.map +1 -1
- package/dist/core/lsp/language-map.js +2 -7
- package/dist/core/lsp/language-map.js.map +1 -1
- package/dist/core/lsp/manager.d.ts.map +1 -1
- package/dist/core/lsp/manager.js +18 -29
- package/dist/core/lsp/manager.js.map +1 -1
- package/dist/core/lsp/navigation.d.ts.map +1 -1
- package/dist/core/lsp/navigation.js.map +1 -1
- package/dist/core/lsp/portable-path.d.ts.map +1 -1
- package/dist/core/lsp/portable-path.js.map +1 -1
- package/dist/core/lsp/refactor.d.ts.map +1 -1
- package/dist/core/lsp/refactor.js.map +1 -1
- package/dist/core/lsp/transport.d.ts.map +1 -1
- package/dist/core/lsp/transport.js.map +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +5 -7
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +0 -6
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/remote-workspace-protocol/contract.d.ts.map +1 -1
- package/dist/core/remote-workspace-protocol/contract.js +4 -2
- package/dist/core/remote-workspace-protocol/contract.js.map +1 -1
- package/dist/core/remote-workspace-protocol/guest-shared-client.d.ts.map +1 -1
- package/dist/core/remote-workspace-protocol/guest-shared-client.js +1 -5
- package/dist/core/remote-workspace-protocol/guest-shared-client.js.map +1 -1
- package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.d.ts.map +1 -1
- package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.js +5 -10
- package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.js.map +1 -1
- package/dist/core/remote-workspace-protocol/guest-shared-uplink.d.ts.map +1 -1
- package/dist/core/remote-workspace-protocol/guest-shared-uplink.js +2 -9
- package/dist/core/remote-workspace-protocol/guest-shared-uplink.js.map +1 -1
- package/dist/core/remote-workspace-protocol/lima-owner-directory.d.ts.map +1 -1
- package/dist/core/remote-workspace-protocol/lima-owner-directory.js.map +1 -1
- package/dist/core/remote-workspace-protocol/lima-owner-lock.d.ts.map +1 -1
- package/dist/core/remote-workspace-protocol/lima-owner-lock.js.map +1 -1
- package/dist/core/remote-workspace-protocol/session.d.ts.map +1 -1
- package/dist/core/remote-workspace-protocol/session.js +27 -65
- package/dist/core/remote-workspace-protocol/session.js.map +1 -1
- package/dist/core/remote-workspace-protocol/shared-transport.d.ts.map +1 -1
- package/dist/core/remote-workspace-protocol/shared-transport.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +0 -48
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/rules.d.ts.map +1 -1
- package/dist/core/rules.js.map +1 -1
- package/dist/core/sandbox/command.d.ts.map +1 -1
- package/dist/core/sandbox/command.js.map +1 -1
- package/dist/core/sandbox/config.d.ts.map +1 -1
- package/dist/core/sandbox/config.js.map +1 -1
- package/dist/core/sandbox/lima-guest-binary.d.ts.map +1 -1
- package/dist/core/sandbox/lima-guest-binary.js.map +1 -1
- package/dist/core/sandbox/lima.d.ts +2 -0
- package/dist/core/sandbox/lima.d.ts.map +1 -1
- package/dist/core/sandbox/lima.js +9 -15
- package/dist/core/sandbox/lima.js.map +1 -1
- package/dist/core/sandbox/shared-lima-roots.d.ts.map +1 -1
- package/dist/core/sandbox/shared-lima-roots.js.map +1 -1
- package/dist/core/sandbox/update-shared-guest-binary.d.ts.map +1 -1
- package/dist/core/sandbox/update-shared-guest-binary.js.map +1 -1
- package/dist/core/session/constants.d.ts.map +1 -1
- package/dist/core/session/context-metadata.d.ts.map +1 -1
- package/dist/core/session/context-metadata.js.map +1 -1
- package/dist/core/session/context.d.ts.map +1 -1
- package/dist/core/session/context.js.map +1 -1
- package/dist/core/session/ids.d.ts.map +1 -1
- package/dist/core/session/ids.js.map +1 -1
- package/dist/core/session/in-memory-session-manager.d.ts.map +1 -1
- package/dist/core/session/in-memory-session-manager.js +0 -1
- package/dist/core/session/in-memory-session-manager.js.map +1 -1
- package/dist/core/session/in-memory-session.d.ts.map +1 -1
- package/dist/core/session/in-memory-session.js.map +1 -1
- package/dist/core/session/jsonl-errors.d.ts.map +1 -1
- package/dist/core/session/jsonl-errors.js +0 -11
- package/dist/core/session/jsonl-errors.js.map +1 -1
- package/dist/core/session/jsonl-helpers.d.ts.map +1 -1
- package/dist/core/session/jsonl-helpers.js.map +1 -1
- package/dist/core/session/local-session-manager.d.ts.map +1 -1
- package/dist/core/session/local-session-manager.js +4 -6
- package/dist/core/session/local-session-manager.js.map +1 -1
- package/dist/core/session/local-session.d.ts.map +1 -1
- package/dist/core/session/local-session.js.map +1 -1
- package/dist/core/session/migrations.d.ts.map +1 -1
- package/dist/core/session/migrations.js.map +1 -1
- package/dist/core/session/remote-session-client.d.ts.map +1 -1
- package/dist/core/session/remote-session-client.js +0 -6
- package/dist/core/session/remote-session-client.js.map +1 -1
- package/dist/core/session/remote-session-manager.d.ts.map +1 -1
- package/dist/core/session/remote-session-manager.js +0 -3
- package/dist/core/session/remote-session-manager.js.map +1 -1
- package/dist/core/session/remote-session.d.ts.map +1 -1
- package/dist/core/session/remote-session.js +0 -1
- package/dist/core/session/remote-session.js.map +1 -1
- package/dist/core/session/session-manager.d.ts.map +1 -1
- package/dist/core/session/session.d.ts.map +1 -1
- package/dist/core/session/session.js +1 -5
- package/dist/core/session/session.js.map +1 -1
- package/dist/core/session/stores/in-memory-session-store.d.ts.map +1 -1
- package/dist/core/session/stores/in-memory-session-store.js +7 -6
- package/dist/core/session/stores/in-memory-session-store.js.map +1 -1
- package/dist/core/session/stores/jsonl-session-store.d.ts.map +1 -1
- package/dist/core/session/stores/jsonl-session-store.js +6 -14
- package/dist/core/session/stores/jsonl-session-store.js.map +1 -1
- package/dist/core/session/stores/remote-session-store.d.ts.map +1 -1
- package/dist/core/session/stores/remote-session-store.js +3 -8
- package/dist/core/session/stores/remote-session-store.js.map +1 -1
- package/dist/core/session/stores/session-store.d.ts.map +1 -1
- package/dist/core/session/types.d.ts.map +1 -1
- package/dist/core/session/usage-ledger.d.ts.map +1 -1
- package/dist/core/session/usage-ledger.js.map +1 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js +0 -1
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +9 -17
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +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.map +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +8 -5
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/compress-context.d.ts.map +1 -1
- package/dist/core/tools/compress-context.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/hash-store.d.ts.map +1 -1
- package/dist/core/tools/hash-store.js.map +1 -1
- package/dist/core/tools/hashline/apply.d.ts.map +1 -1
- package/dist/core/tools/hashline/apply.js.map +1 -1
- package/dist/core/tools/hashline/hash.d.ts.map +1 -1
- package/dist/core/tools/hashline/hash.js.map +1 -1
- package/dist/core/tools/hashline/parse.d.ts.map +1 -1
- package/dist/core/tools/hashline/parse.js.map +1 -1
- package/dist/core/tools/hashline/resolve.d.ts.map +1 -1
- package/dist/core/tools/hashline/resolve.js.map +1 -1
- package/dist/core/tools/hashline-utils.d.ts.map +1 -1
- package/dist/core/tools/hashline-utils.js.map +1 -1
- 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.map +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/operations.d.ts +5 -0
- package/dist/core/tools/operations.d.ts.map +1 -1
- package/dist/core/tools/operations.js +26 -24
- package/dist/core/tools/operations.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +12 -18
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/replace-diff.d.ts.map +1 -1
- package/dist/core/tools/replace-diff.js.map +1 -1
- package/dist/core/tools/replace-normalize.d.ts.map +1 -1
- package/dist/core/tools/replace-normalize.js.map +1 -1
- package/dist/core/tools/replace-render.d.ts +1 -1
- package/dist/core/tools/replace-render.d.ts.map +1 -1
- package/dist/core/tools/replace-render.js.map +1 -1
- package/dist/core/tools/runtime.d.ts.map +1 -1
- package/dist/core/tools/runtime.js.map +1 -1
- package/dist/core/tools/session-history.d.ts.map +1 -1
- package/dist/core/tools/session-history.js.map +1 -1
- package/dist/core/tools/subagent-agents.d.ts.map +1 -1
- package/dist/core/tools/subagent-agents.js.map +1 -1
- package/dist/core/tools/subagent.d.ts.map +1 -1
- package/dist/core/tools/subagent.js.map +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.map +1 -1
- package/dist/core/tools/websearch.d.ts.map +1 -1
- package/dist/core/tools/websearch.js.map +1 -1
- package/dist/core/tools/workspace-tool-host.d.ts +1 -0
- package/dist/core/tools/workspace-tool-host.d.ts.map +1 -1
- package/dist/core/tools/workspace-tool-host.js +36 -22
- package/dist/core/tools/workspace-tool-host.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +0 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/workspace-identity.d.ts.map +1 -1
- package/dist/daemon/activity-budget.d.ts.map +1 -1
- package/dist/daemon/activity-budget.js +2 -3
- package/dist/daemon/activity-budget.js.map +1 -1
- package/dist/daemon/command.d.ts.map +1 -1
- package/dist/daemon/command.js.map +1 -1
- package/dist/daemon/config.d.ts +2 -0
- package/dist/daemon/config.d.ts.map +1 -1
- package/dist/daemon/config.js +4 -0
- package/dist/daemon/config.js.map +1 -1
- package/dist/daemon/help.d.ts.map +1 -1
- package/dist/daemon/help.js +4 -3
- package/dist/daemon/help.js.map +1 -1
- package/dist/daemon/lsp-config.d.ts.map +1 -1
- package/dist/daemon/lsp-config.js.map +1 -1
- package/dist/daemon/outbound-budget.d.ts.map +1 -1
- package/dist/daemon/outbound-budget.js +2 -4
- package/dist/daemon/outbound-budget.js.map +1 -1
- package/dist/daemon/security.d.ts.map +1 -1
- package/dist/daemon/security.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/shared-connection.d.ts.map +1 -1
- package/dist/daemon/shared-connection.js +10 -15
- package/dist/daemon/shared-connection.js.map +1 -1
- package/dist/daemon/shared-revision.d.ts.map +1 -1
- package/dist/daemon/shared-revision.js +2 -1
- package/dist/daemon/shared-revision.js.map +1 -1
- package/dist/daemon/shared-roots.d.ts.map +1 -1
- package/dist/daemon/shared-roots.js +0 -1
- package/dist/daemon/shared-roots.js.map +1 -1
- package/dist/daemon/workspace-runtime.d.ts +2 -0
- package/dist/daemon/workspace-runtime.d.ts.map +1 -1
- package/dist/daemon/workspace-runtime.js +43 -15
- package/dist/daemon/workspace-runtime.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +21 -17
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +4 -9
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +0 -3
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +1 -3
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +1 -3
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +6 -16
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js +0 -5
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +1 -8
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +1 -6
- package/dist/modes/interactive/components/custom-message.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 +0 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +1 -7
- 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 +2 -8
- 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 +1 -9
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -3
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/hook-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/hook-execution.js +2 -5
- package/dist/modes/interactive/components/hook-execution.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.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +3 -9
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
- package/dist/modes/interactive/components/mermaid.js.map +1 -1
- package/dist/modes/interactive/components/message-card.d.ts.map +1 -1
- package/dist/modes/interactive/components/message-card.js +0 -1
- package/dist/modes/interactive/components/message-card.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +26 -18
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +223 -210
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +3 -12
- 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 +9 -13
- package/dist/modes/interactive/components/scoped-models-selector.js.map +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.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +33 -58
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +0 -4
- 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 +0 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +1 -3
- 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 +0 -2
- 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 +0 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +9 -24
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +18 -34
- 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 +3 -6
- 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 +0 -4
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +14 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +223 -137
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +0 -7
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js.map +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/jsonl.d.ts.map +1 -1
- package/dist/modes/rpc/jsonl.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +10 -11
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js.map +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.map +1 -1
- 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.map +1 -1
- 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.map +1 -1
- package/dist/utils/deprecation.js.map +1 -1
- package/dist/utils/directory-completions.d.ts.map +1 -1
- package/dist/utils/directory-completions.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js.map +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/grip-user-agent.d.ts.map +1 -1
- package/dist/utils/grip-user-agent.js +1 -1
- package/dist/utils/grip-user-agent.js.map +1 -1
- package/dist/utils/html.d.ts.map +1 -1
- package/dist/utils/html.js.map +1 -1
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-process.d.ts.map +1 -1
- package/dist/utils/image-process.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/image-resize-worker.d.ts.map +1 -1
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/mime.d.ts.map +1 -1
- package/dist/utils/mime.js.map +1 -1
- package/dist/utils/open-browser.d.ts.map +1 -1
- package/dist/utils/open-browser.js.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js +10 -5
- package/dist/utils/photon.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +1 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts.map +1 -1
- package/dist/utils/windows-self-update.js.map +1 -1
- package/docs/keybindings.md +3 -1
- package/docs/providers.md +3 -1
- package/docs/sandbox.md +7 -1
- package/docs/sessions.md +1 -1
- package/docs/usage.md +39 -2
- package/examples/extensions/custom-provider-anthropic/package.json +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +601 -833
- package/package.json +20 -21
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,4BAA4B,CAAC;AAI7E,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AACtF,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAWrE,OAAO,EAIN,KAAK,gBAAgB,EAGrB,MAAM,eAAe,CAAC;AAEvB,QAAA,MAAM,UAAU;;;;;;;;EAYd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAGtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;CAAG;AAuVnC,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAAC;AAEhG,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,kBAAkB,CAuBnH;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAElH","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool, AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { Text } from \"@greppleai/grip-tui\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport type { ToolGrepMatch, ToolOperations } from \"./operations.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport {\n\tformatBackendIcon,\n\tformatHiddenLinesHint,\n\tgetTextOutput,\n\tinvalidArgText,\n\tshortenPath,\n\tstr,\n} from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from \"./truncate.ts\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\nexport interface GrepToolOptions {}\n\nfunction formatGrepCall(args: Partial<GrepToolInput> | undefined, theme: Theme): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: AgentToolResult<GrepToolDetails | undefined>,\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 15;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `\\n\\n${formatHiddenLinesHint(remaining, theme)}`;\n\t\t}\n\t}\n\n\tconst matchLimit = result.details?.matchLimitReached;\n\tconst truncation = result.details?.truncation;\n\tconst linesTruncated = result.details?.linesTruncated;\n\tif (matchLimit || truncation?.truncated || linesTruncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (matchLimit) warnings.push(`${matchLimit} matches limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\tif (linesTruncated) warnings.push(\"some lines truncated\");\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\ninterface GrepFormatState {\n\toperations: ToolOperations;\n\tsearchPath: string;\n\tisDirectory: boolean;\n\tcontext: number;\n\tfileCache: Map<string, string[]>;\n\tlinesTruncated: boolean;\n}\n\ninterface GrepExecutionInput {\n\tpattern: string;\n\tsearchPath: string;\n\tglob?: string;\n\tignoreCase?: boolean;\n\tliteral?: boolean;\n\tcontext: number;\n\tlimit: number;\n}\n\ninterface RipgrepCollectionState {\n\tstderr: string;\n\tmatchCount: number;\n\tmatchLimitReached: boolean;\n\taborted: boolean;\n\tkilledDueToLimit: boolean;\n\tmatches: ToolGrepMatch[];\n}\n\nfunction noGrepMatchesResult(): AgentToolResult<GrepToolDetails | undefined> {\n\treturn { content: [{ type: \"text\", text: \"No matches found\" }], details: undefined };\n}\n\nfunction formatMatchedFilePath(state: GrepFormatState, filePath: string): string {\n\tif (state.isDirectory) {\n\t\tconst relative = path.relative(state.searchPath, filePath);\n\t\tif (relative && !relative.startsWith(\"..\")) return relative.replace(/\\\\/g, \"/\");\n\t}\n\treturn path.basename(filePath);\n}\n\nasync function getGrepFileLines(state: GrepFormatState, filePath: string): Promise<string[]> {\n\tconst cached = state.fileCache.get(filePath);\n\tif (cached) return cached;\n\tlet lines: string[];\n\ttry {\n\t\tconst content = (await state.operations.readFile(filePath)).toString(\"utf-8\");\n\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t} catch {\n\t\tlines = [];\n\t}\n\tstate.fileCache.set(filePath, lines);\n\treturn lines;\n}\n\nasync function formatGrepContextBlock(state: GrepFormatState, match: ToolGrepMatch): Promise<string[]> {\n\tconst relativePath = formatMatchedFilePath(state, match.filePath);\n\tconst lines = await getGrepFileLines(state, match.filePath);\n\tif (!lines.length) return [`${relativePath}:${match.lineNumber}: (unable to read file)`];\n\tconst block: string[] = [];\n\tconst start = state.context > 0 ? Math.max(1, match.lineNumber - state.context) : match.lineNumber;\n\tconst end = state.context > 0 ? Math.min(lines.length, match.lineNumber + state.context) : match.lineNumber;\n\tfor (let current = start; current <= end; current++) {\n\t\tconst sanitized = (lines[current - 1] ?? \"\").replace(/\\r/g, \"\");\n\t\tconst { text, wasTruncated } = truncateLine(sanitized);\n\t\tif (wasTruncated) state.linesTruncated = true;\n\t\tblock.push(\n\t\t\tcurrent === match.lineNumber ? `${relativePath}:${current}: ${text}` : `${relativePath}-${current}- ${text}`,\n\t\t);\n\t}\n\treturn block;\n}\n\nasync function formatGrepMatch(state: GrepFormatState, match: ToolGrepMatch): Promise<string[]> {\n\tif (state.context !== 0 || match.lineText === undefined) return formatGrepContextBlock(state, match);\n\tconst sanitized = match.lineText.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\").replace(/\\n$/, \"\");\n\tconst { text, wasTruncated } = truncateLine(sanitized);\n\tif (wasTruncated) state.linesTruncated = true;\n\treturn [`${formatMatchedFilePath(state, match.filePath)}:${match.lineNumber}: ${text}`];\n}\n\nasync function formatGrepMatches(state: GrepFormatState, matches: ToolGrepMatch[]): Promise<string[]> {\n\tconst outputLines: string[] = [];\n\tfor (const match of matches) outputLines.push(...(await formatGrepMatch(state, match)));\n\treturn outputLines;\n}\n\nfunction buildGrepResult(\n\tstate: GrepFormatState,\n\toutputLines: string[],\n\tmatchLimitReached: number | undefined,\n): AgentToolResult<GrepToolDetails | undefined> {\n\tconst truncation = truncateHead(outputLines.join(\"\\n\"), { maxLines: Number.MAX_SAFE_INTEGER });\n\tlet output = truncation.content;\n\tconst details: GrepToolDetails = {};\n\tconst notices: string[] = [];\n\tif (matchLimitReached !== undefined) {\n\t\tnotices.push(\n\t\t\t`${matchLimitReached} matches limit reached. Use limit=${matchLimitReached * 2} for more, or refine pattern`,\n\t\t);\n\t\tdetails.matchLimitReached = matchLimitReached;\n\t}\n\tif (truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\tdetails.truncation = truncation;\n\t}\n\tif (state.linesTruncated) {\n\t\tnotices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`);\n\t\tdetails.linesTruncated = true;\n\t}\n\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\treturn {\n\t\tcontent: [{ type: \"text\", text: output }],\n\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t};\n}\n\nasync function executeOperationsGrep(\n\toperations: ToolOperations,\n\tinput: GrepExecutionInput,\n\tformatState: GrepFormatState,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\tconst result = await operations.grep!({\n\t\tpattern: input.pattern,\n\t\tpath: input.searchPath,\n\t\tglob: input.glob,\n\t\tignoreCase: input.ignoreCase,\n\t\tliteral: input.literal,\n\t\tlimit: input.limit,\n\t});\n\tformatState.isDirectory = result.isDirectory;\n\tif (result.matches.length === 0) return noGrepMatchesResult();\n\tconst outputLines = await formatGrepMatches(formatState, result.matches);\n\treturn buildGrepResult(formatState, outputLines, result.matches.length >= input.limit ? input.limit : undefined);\n}\n\nfunction buildRipgrepArgs(input: GrepExecutionInput): string[] {\n\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\tif (input.ignoreCase) args.push(\"--ignore-case\");\n\tif (input.literal) args.push(\"--fixed-strings\");\n\tif (input.glob) args.push(\"--glob\", input.glob);\n\targs.push(\"--\", input.pattern, input.searchPath);\n\treturn args;\n}\n\ninterface ParsedRipgrepLine {\n\tmatchedEvent: boolean;\n\tmatch?: ToolGrepMatch;\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction getRecordText(value: unknown): unknown {\n\treturn isUnknownRecord(value) ? value.text : undefined;\n}\n\nfunction parseRipgrepLine(line: string): ParsedRipgrepLine {\n\tif (!line.trim()) return { matchedEvent: false };\n\tlet event: unknown;\n\ttry {\n\t\tevent = JSON.parse(line) as unknown;\n\t} catch {\n\t\treturn { matchedEvent: false };\n\t}\n\tif (!isUnknownRecord(event) || event.type !== \"match\") return { matchedEvent: false };\n\tconst data = isUnknownRecord(event.data) ? event.data : undefined;\n\tconst filePath = getRecordText(data?.path);\n\tconst lineNumber = data?.line_number;\n\tconst lineText = getRecordText(data?.lines);\n\treturn {\n\t\tmatchedEvent: true,\n\t\t...(typeof filePath === \"string\" && typeof lineNumber === \"number\"\n\t\t\t? { match: { filePath, lineNumber, ...(typeof lineText === \"string\" ? { lineText } : {}) } }\n\t\t\t: {}),\n\t};\n}\n\nfunction collectRipgrepLine(\n\tline: string,\n\tstate: RipgrepCollectionState,\n\tlimit: number,\n\tstopChild: (dueToLimit?: boolean) => void,\n): void {\n\tif (state.matchCount >= limit) return;\n\tconst parsed = parseRipgrepLine(line);\n\tif (!parsed.matchedEvent) return;\n\tstate.matchCount++;\n\tif (parsed.match) state.matches.push(parsed.match);\n\tif (state.matchCount >= limit) {\n\t\tstate.matchLimitReached = true;\n\t\tstopChild(true);\n\t}\n}\n\nasync function finishRipgrepExecution(\n\tcode: number | null,\n\tstate: RipgrepCollectionState,\n\tformatState: GrepFormatState,\n\tlimit: number,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\tif (state.aborted) throw new Error(\"Operation aborted\");\n\tif (!state.killedDueToLimit && code !== 0 && code !== 1) {\n\t\tthrow new Error(state.stderr.trim() || `ripgrep exited with code ${code}`);\n\t}\n\tif (state.matchCount === 0) return noGrepMatchesResult();\n\tconst outputLines = await formatGrepMatches(formatState, state.matches);\n\treturn buildGrepResult(formatState, outputLines, state.matchLimitReached ? limit : undefined);\n}\n\nfunction executeRipgrep(\n\trgPath: string,\n\tinput: GrepExecutionInput,\n\tformatState: GrepFormatState,\n\tsignal?: AbortSignal,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = spawn(rgPath, buildRipgrepArgs(input), { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\tconst rl = createInterface({ input: child.stdout });\n\t\tconst state: RipgrepCollectionState = {\n\t\t\tstderr: \"\",\n\t\t\tmatchCount: 0,\n\t\t\tmatchLimitReached: false,\n\t\t\taborted: false,\n\t\t\tkilledDueToLimit: false,\n\t\t\tmatches: [],\n\t\t};\n\t\tconst cleanup = (): void => {\n\t\t\trl.close();\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t};\n\t\tconst stopChild = (dueToLimit = false): void => {\n\t\t\tif (child.killed) return;\n\t\t\tstate.killedDueToLimit = dueToLimit;\n\t\t\tchild.kill();\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\tstate.aborted = true;\n\t\t\tstopChild();\n\t\t};\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\tchild.stderr.on(\"data\", (chunk) => {\n\t\t\tstate.stderr += chunk.toString();\n\t\t});\n\t\trl.on(\"line\", (line) => collectRipgrepLine(line, state, input.limit, stopChild));\n\t\tchild.on(\"error\", (error) => {\n\t\t\tcleanup();\n\t\t\treject(new Error(`Failed to run ripgrep: ${error.message}`));\n\t\t});\n\t\tchild.on(\"close\", (code) => {\n\t\t\tcleanup();\n\t\t\tvoid finishRipgrepExecution(code, state, formatState, input.limit).then(resolve, reject);\n\t\t});\n\t});\n}\n\nasync function executeGrep(\n\toperations: ToolOperations,\n\tcwd: string,\n\tinput: GrepToolInput,\n\tsignal?: AbortSignal,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\tconst searchPath = resolveToCwd(input.path || \".\", cwd);\n\tlet isDirectory: boolean;\n\ttry {\n\t\tisDirectory = (await operations.stat(searchPath)).isDirectory();\n\t} catch {\n\t\tthrow new Error(`Path not found: ${searchPath}`);\n\t}\n\tconst executionInput: GrepExecutionInput = {\n\t\tpattern: input.pattern,\n\t\tsearchPath,\n\t\tglob: input.glob,\n\t\tignoreCase: input.ignoreCase,\n\t\tliteral: input.literal,\n\t\tcontext: input.context && input.context > 0 ? input.context : 0,\n\t\tlimit: Math.max(1, input.limit ?? DEFAULT_LIMIT),\n\t};\n\tconst formatState: GrepFormatState = {\n\t\toperations,\n\t\tsearchPath,\n\t\tisDirectory,\n\t\tcontext: executionInput.context,\n\t\tfileCache: new Map(),\n\t\tlinesTruncated: false,\n\t};\n\tif (operations.grep) return executeOperationsGrep(operations, executionInput, formatState);\n\tconst rgPath = await ensureTool(\"rg\", true);\n\tif (!rgPath) throw new Error(\"ripgrep (rg) is not available and could not be downloaded\");\n\treturn executeRipgrep(rgPath, executionInput, formatState, signal);\n}\n\nexport type GrepToolDefinition = ToolDefinition<typeof grepSchema, GrepToolDetails | undefined>;\n\nexport function createGrepToolDefinition(operations: ToolOperations, _options?: GrepToolOptions): GrepToolDefinition {\n\tconst ops = operations;\n\tconst cwd = operations.cwd;\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tparameters: grepSchema,\n\t\tasync execute(_toolCallId, input: GrepToolInput, signal?: AbortSignal) {\n\t\t\treturn executeGrep(ops, cwd, input, signal);\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatBackendIcon(ops.getBackendInfo?.(), theme) + formatGrepCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatGrepResult(result, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createGrepTool(operations: ToolOperations, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(operations, options));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,4BAA4B,CAAC;AAI7E,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AACtF,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAWrE,OAAO,EAIN,KAAK,gBAAgB,EAGrB,MAAM,eAAe,CAAC;AAEvB,QAAA,MAAM,UAAU;;;;;;;;EAYd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAGtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;CAAG;AAuVnC,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAAC;AAEhG,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,kBAAkB,CAuBnH;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAElH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"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","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool, AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { Text } from \"@greppleai/grip-tui\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport type { ToolGrepMatch, ToolOperations } from \"./operations.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport {\n\tformatBackendIcon,\n\tformatHiddenLinesHint,\n\tgetTextOutput,\n\tinvalidArgText,\n\tshortenPath,\n\tstr,\n} from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from \"./truncate.ts\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\nexport interface GrepToolOptions {}\n\nfunction formatGrepCall(args: Partial<GrepToolInput> | undefined, theme: Theme): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: AgentToolResult<GrepToolDetails | undefined>,\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 15;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `\\n\\n${formatHiddenLinesHint(remaining, theme)}`;\n\t\t}\n\t}\n\n\tconst matchLimit = result.details?.matchLimitReached;\n\tconst truncation = result.details?.truncation;\n\tconst linesTruncated = result.details?.linesTruncated;\n\tif (matchLimit || truncation?.truncated || linesTruncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (matchLimit) warnings.push(`${matchLimit} matches limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\tif (linesTruncated) warnings.push(\"some lines truncated\");\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\ninterface GrepFormatState {\n\toperations: ToolOperations;\n\tsearchPath: string;\n\tisDirectory: boolean;\n\tcontext: number;\n\tfileCache: Map<string, string[]>;\n\tlinesTruncated: boolean;\n}\n\ninterface GrepExecutionInput {\n\tpattern: string;\n\tsearchPath: string;\n\tglob?: string;\n\tignoreCase?: boolean;\n\tliteral?: boolean;\n\tcontext: number;\n\tlimit: number;\n}\n\ninterface RipgrepCollectionState {\n\tstderr: string;\n\tmatchCount: number;\n\tmatchLimitReached: boolean;\n\taborted: boolean;\n\tkilledDueToLimit: boolean;\n\tmatches: ToolGrepMatch[];\n}\n\nfunction noGrepMatchesResult(): AgentToolResult<GrepToolDetails | undefined> {\n\treturn { content: [{ type: \"text\", text: \"No matches found\" }], details: undefined };\n}\n\nfunction formatMatchedFilePath(state: GrepFormatState, filePath: string): string {\n\tif (state.isDirectory) {\n\t\tconst relative = path.relative(state.searchPath, filePath);\n\t\tif (relative && !relative.startsWith(\"..\")) return relative.replace(/\\\\/g, \"/\");\n\t}\n\treturn path.basename(filePath);\n}\n\nasync function getGrepFileLines(state: GrepFormatState, filePath: string): Promise<string[]> {\n\tconst cached = state.fileCache.get(filePath);\n\tif (cached) return cached;\n\tlet lines: string[];\n\ttry {\n\t\tconst content = (await state.operations.readFile(filePath)).toString(\"utf-8\");\n\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t} catch {\n\t\tlines = [];\n\t}\n\tstate.fileCache.set(filePath, lines);\n\treturn lines;\n}\n\nasync function formatGrepContextBlock(state: GrepFormatState, match: ToolGrepMatch): Promise<string[]> {\n\tconst relativePath = formatMatchedFilePath(state, match.filePath);\n\tconst lines = await getGrepFileLines(state, match.filePath);\n\tif (!lines.length) return [`${relativePath}:${match.lineNumber}: (unable to read file)`];\n\tconst block: string[] = [];\n\tconst start = state.context > 0 ? Math.max(1, match.lineNumber - state.context) : match.lineNumber;\n\tconst end = state.context > 0 ? Math.min(lines.length, match.lineNumber + state.context) : match.lineNumber;\n\tfor (let current = start; current <= end; current++) {\n\t\tconst sanitized = (lines[current - 1] ?? \"\").replace(/\\r/g, \"\");\n\t\tconst { text, wasTruncated } = truncateLine(sanitized);\n\t\tif (wasTruncated) state.linesTruncated = true;\n\t\tblock.push(\n\t\t\tcurrent === match.lineNumber ? `${relativePath}:${current}: ${text}` : `${relativePath}-${current}- ${text}`,\n\t\t);\n\t}\n\treturn block;\n}\n\nasync function formatGrepMatch(state: GrepFormatState, match: ToolGrepMatch): Promise<string[]> {\n\tif (state.context !== 0 || match.lineText === undefined) return formatGrepContextBlock(state, match);\n\tconst sanitized = match.lineText.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\").replace(/\\n$/, \"\");\n\tconst { text, wasTruncated } = truncateLine(sanitized);\n\tif (wasTruncated) state.linesTruncated = true;\n\treturn [`${formatMatchedFilePath(state, match.filePath)}:${match.lineNumber}: ${text}`];\n}\n\nasync function formatGrepMatches(state: GrepFormatState, matches: ToolGrepMatch[]): Promise<string[]> {\n\tconst outputLines: string[] = [];\n\tfor (const match of matches) outputLines.push(...(await formatGrepMatch(state, match)));\n\treturn outputLines;\n}\n\nfunction buildGrepResult(\n\tstate: GrepFormatState,\n\toutputLines: string[],\n\tmatchLimitReached: number | undefined,\n): AgentToolResult<GrepToolDetails | undefined> {\n\tconst truncation = truncateHead(outputLines.join(\"\\n\"), { maxLines: Number.MAX_SAFE_INTEGER });\n\tlet output = truncation.content;\n\tconst details: GrepToolDetails = {};\n\tconst notices: string[] = [];\n\tif (matchLimitReached !== undefined) {\n\t\tnotices.push(\n\t\t\t`${matchLimitReached} matches limit reached. Use limit=${matchLimitReached * 2} for more, or refine pattern`,\n\t\t);\n\t\tdetails.matchLimitReached = matchLimitReached;\n\t}\n\tif (truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\tdetails.truncation = truncation;\n\t}\n\tif (state.linesTruncated) {\n\t\tnotices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`);\n\t\tdetails.linesTruncated = true;\n\t}\n\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\treturn {\n\t\tcontent: [{ type: \"text\", text: output }],\n\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t};\n}\n\nasync function executeOperationsGrep(\n\toperations: ToolOperations,\n\tinput: GrepExecutionInput,\n\tformatState: GrepFormatState,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\tconst result = await operations.grep!({\n\t\tpattern: input.pattern,\n\t\tpath: input.searchPath,\n\t\tglob: input.glob,\n\t\tignoreCase: input.ignoreCase,\n\t\tliteral: input.literal,\n\t\tlimit: input.limit,\n\t});\n\tformatState.isDirectory = result.isDirectory;\n\tif (result.matches.length === 0) return noGrepMatchesResult();\n\tconst outputLines = await formatGrepMatches(formatState, result.matches);\n\treturn buildGrepResult(formatState, outputLines, result.matches.length >= input.limit ? input.limit : undefined);\n}\n\nfunction buildRipgrepArgs(input: GrepExecutionInput): string[] {\n\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\tif (input.ignoreCase) args.push(\"--ignore-case\");\n\tif (input.literal) args.push(\"--fixed-strings\");\n\tif (input.glob) args.push(\"--glob\", input.glob);\n\targs.push(\"--\", input.pattern, input.searchPath);\n\treturn args;\n}\n\ninterface ParsedRipgrepLine {\n\tmatchedEvent: boolean;\n\tmatch?: ToolGrepMatch;\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction getRecordText(value: unknown): unknown {\n\treturn isUnknownRecord(value) ? value.text : undefined;\n}\n\nfunction parseRipgrepLine(line: string): ParsedRipgrepLine {\n\tif (!line.trim()) return { matchedEvent: false };\n\tlet event: unknown;\n\ttry {\n\t\tevent = JSON.parse(line) as unknown;\n\t} catch {\n\t\treturn { matchedEvent: false };\n\t}\n\tif (!isUnknownRecord(event) || event.type !== \"match\") return { matchedEvent: false };\n\tconst data = isUnknownRecord(event.data) ? event.data : undefined;\n\tconst filePath = getRecordText(data?.path);\n\tconst lineNumber = data?.line_number;\n\tconst lineText = getRecordText(data?.lines);\n\treturn {\n\t\tmatchedEvent: true,\n\t\t...(typeof filePath === \"string\" && typeof lineNumber === \"number\"\n\t\t\t? { match: { filePath, lineNumber, ...(typeof lineText === \"string\" ? { lineText } : {}) } }\n\t\t\t: {}),\n\t};\n}\n\nfunction collectRipgrepLine(\n\tline: string,\n\tstate: RipgrepCollectionState,\n\tlimit: number,\n\tstopChild: (dueToLimit?: boolean) => void,\n): void {\n\tif (state.matchCount >= limit) return;\n\tconst parsed = parseRipgrepLine(line);\n\tif (!parsed.matchedEvent) return;\n\tstate.matchCount++;\n\tif (parsed.match) state.matches.push(parsed.match);\n\tif (state.matchCount >= limit) {\n\t\tstate.matchLimitReached = true;\n\t\tstopChild(true);\n\t}\n}\n\nasync function finishRipgrepExecution(\n\tcode: number | null,\n\tstate: RipgrepCollectionState,\n\tformatState: GrepFormatState,\n\tlimit: number,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\tif (state.aborted) throw new Error(\"Operation aborted\");\n\tif (!state.killedDueToLimit && code !== 0 && code !== 1) {\n\t\tthrow new Error(state.stderr.trim() || `ripgrep exited with code ${code}`);\n\t}\n\tif (state.matchCount === 0) return noGrepMatchesResult();\n\tconst outputLines = await formatGrepMatches(formatState, state.matches);\n\treturn buildGrepResult(formatState, outputLines, state.matchLimitReached ? limit : undefined);\n}\n\nfunction executeRipgrep(\n\trgPath: string,\n\tinput: GrepExecutionInput,\n\tformatState: GrepFormatState,\n\tsignal?: AbortSignal,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = spawn(rgPath, buildRipgrepArgs(input), { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\tconst rl = createInterface({ input: child.stdout });\n\t\tconst state: RipgrepCollectionState = {\n\t\t\tstderr: \"\",\n\t\t\tmatchCount: 0,\n\t\t\tmatchLimitReached: false,\n\t\t\taborted: false,\n\t\t\tkilledDueToLimit: false,\n\t\t\tmatches: [],\n\t\t};\n\t\tconst cleanup = (): void => {\n\t\t\trl.close();\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t};\n\t\tconst stopChild = (dueToLimit = false): void => {\n\t\t\tif (child.killed) return;\n\t\t\tstate.killedDueToLimit = dueToLimit;\n\t\t\tchild.kill();\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\tstate.aborted = true;\n\t\t\tstopChild();\n\t\t};\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\tchild.stderr.on(\"data\", (chunk) => {\n\t\t\tstate.stderr += chunk.toString();\n\t\t});\n\t\trl.on(\"line\", (line) => collectRipgrepLine(line, state, input.limit, stopChild));\n\t\tchild.on(\"error\", (error) => {\n\t\t\tcleanup();\n\t\t\treject(new Error(`Failed to run ripgrep: ${error.message}`));\n\t\t});\n\t\tchild.on(\"close\", (code) => {\n\t\t\tcleanup();\n\t\t\tvoid finishRipgrepExecution(code, state, formatState, input.limit).then(resolve, reject);\n\t\t});\n\t});\n}\n\nasync function executeGrep(\n\toperations: ToolOperations,\n\tcwd: string,\n\tinput: GrepToolInput,\n\tsignal?: AbortSignal,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\tconst searchPath = resolveToCwd(input.path || \".\", cwd);\n\tlet isDirectory: boolean;\n\ttry {\n\t\tisDirectory = (await operations.stat(searchPath)).isDirectory();\n\t} catch {\n\t\tthrow new Error(`Path not found: ${searchPath}`);\n\t}\n\tconst executionInput: GrepExecutionInput = {\n\t\tpattern: input.pattern,\n\t\tsearchPath,\n\t\tglob: input.glob,\n\t\tignoreCase: input.ignoreCase,\n\t\tliteral: input.literal,\n\t\tcontext: input.context && input.context > 0 ? input.context : 0,\n\t\tlimit: Math.max(1, input.limit ?? DEFAULT_LIMIT),\n\t};\n\tconst formatState: GrepFormatState = {\n\t\toperations,\n\t\tsearchPath,\n\t\tisDirectory,\n\t\tcontext: executionInput.context,\n\t\tfileCache: new Map(),\n\t\tlinesTruncated: false,\n\t};\n\tif (operations.grep) return executeOperationsGrep(operations, executionInput, formatState);\n\tconst rgPath = await ensureTool(\"rg\", true);\n\tif (!rgPath) throw new Error(\"ripgrep (rg) is not available and could not be downloaded\");\n\treturn executeRipgrep(rgPath, executionInput, formatState, signal);\n}\n\nexport type GrepToolDefinition = ToolDefinition<typeof grepSchema, GrepToolDetails | undefined>;\n\nexport function createGrepToolDefinition(operations: ToolOperations, _options?: GrepToolOptions): GrepToolDefinition {\n\tconst ops = operations;\n\tconst cwd = operations.cwd;\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tparameters: grepSchema,\n\t\tasync execute(_toolCallId, input: GrepToolInput, signal?: AbortSignal) {\n\t\t\treturn executeGrep(ops, cwd, input, signal);\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatBackendIcon(ops.getBackendInfo?.(), theme) + formatGrepCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatGrepResult(result, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createGrepTool(operations: ToolOperations, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(operations, options));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"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","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool, AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { Text } from \"@greppleai/grip-tui\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport type { ToolGrepMatch, ToolOperations } from \"./operations.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport {\n\tformatBackendIcon,\n\tformatHiddenLinesHint,\n\tgetTextOutput,\n\tinvalidArgText,\n\tshortenPath,\n\tstr,\n} from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from \"./truncate.ts\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\nexport interface GrepToolOptions {}\n\nfunction formatGrepCall(args: Partial<GrepToolInput> | undefined, theme: Theme): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: AgentToolResult<GrepToolDetails | undefined>,\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 15;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `\\n\\n${formatHiddenLinesHint(remaining, theme)}`;\n\t\t}\n\t}\n\n\tconst matchLimit = result.details?.matchLimitReached;\n\tconst truncation = result.details?.truncation;\n\tconst linesTruncated = result.details?.linesTruncated;\n\tif (matchLimit || truncation?.truncated || linesTruncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (matchLimit) warnings.push(`${matchLimit} matches limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\tif (linesTruncated) warnings.push(\"some lines truncated\");\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\ninterface GrepFormatState {\n\toperations: ToolOperations;\n\tsearchPath: string;\n\tisDirectory: boolean;\n\tcontext: number;\n\tfileCache: Map<string, string[]>;\n\tlinesTruncated: boolean;\n}\n\ninterface GrepExecutionInput {\n\tpattern: string;\n\tsearchPath: string;\n\tglob?: string;\n\tignoreCase?: boolean;\n\tliteral?: boolean;\n\tcontext: number;\n\tlimit: number;\n}\n\ninterface RipgrepCollectionState {\n\tstderr: string;\n\tmatchCount: number;\n\tmatchLimitReached: boolean;\n\taborted: boolean;\n\tkilledDueToLimit: boolean;\n\tmatches: ToolGrepMatch[];\n}\n\nfunction noGrepMatchesResult(): AgentToolResult<GrepToolDetails | undefined> {\n\treturn { content: [{ type: \"text\", text: \"No matches found\" }], details: undefined };\n}\n\nfunction formatMatchedFilePath(state: GrepFormatState, filePath: string): string {\n\tif (state.isDirectory) {\n\t\tconst relative = path.relative(state.searchPath, filePath);\n\t\tif (relative && !relative.startsWith(\"..\")) return relative.replace(/\\\\/g, \"/\");\n\t}\n\treturn path.basename(filePath);\n}\n\nasync function getGrepFileLines(state: GrepFormatState, filePath: string): Promise<string[]> {\n\tconst cached = state.fileCache.get(filePath);\n\tif (cached) return cached;\n\tlet lines: string[];\n\ttry {\n\t\tconst content = (await state.operations.readFile(filePath)).toString(\"utf-8\");\n\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t} catch {\n\t\tlines = [];\n\t}\n\tstate.fileCache.set(filePath, lines);\n\treturn lines;\n}\n\nasync function formatGrepContextBlock(state: GrepFormatState, match: ToolGrepMatch): Promise<string[]> {\n\tconst relativePath = formatMatchedFilePath(state, match.filePath);\n\tconst lines = await getGrepFileLines(state, match.filePath);\n\tif (!lines.length) return [`${relativePath}:${match.lineNumber}: (unable to read file)`];\n\tconst block: string[] = [];\n\tconst start = state.context > 0 ? Math.max(1, match.lineNumber - state.context) : match.lineNumber;\n\tconst end = state.context > 0 ? Math.min(lines.length, match.lineNumber + state.context) : match.lineNumber;\n\tfor (let current = start; current <= end; current++) {\n\t\tconst sanitized = (lines[current - 1] ?? \"\").replace(/\\r/g, \"\");\n\t\tconst { text, wasTruncated } = truncateLine(sanitized);\n\t\tif (wasTruncated) state.linesTruncated = true;\n\t\tblock.push(\n\t\t\tcurrent === match.lineNumber ? `${relativePath}:${current}: ${text}` : `${relativePath}-${current}- ${text}`,\n\t\t);\n\t}\n\treturn block;\n}\n\nasync function formatGrepMatch(state: GrepFormatState, match: ToolGrepMatch): Promise<string[]> {\n\tif (state.context !== 0 || match.lineText === undefined) return formatGrepContextBlock(state, match);\n\tconst sanitized = match.lineText.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\").replace(/\\n$/, \"\");\n\tconst { text, wasTruncated } = truncateLine(sanitized);\n\tif (wasTruncated) state.linesTruncated = true;\n\treturn [`${formatMatchedFilePath(state, match.filePath)}:${match.lineNumber}: ${text}`];\n}\n\nasync function formatGrepMatches(state: GrepFormatState, matches: ToolGrepMatch[]): Promise<string[]> {\n\tconst outputLines: string[] = [];\n\tfor (const match of matches) outputLines.push(...(await formatGrepMatch(state, match)));\n\treturn outputLines;\n}\n\nfunction buildGrepResult(\n\tstate: GrepFormatState,\n\toutputLines: string[],\n\tmatchLimitReached: number | undefined,\n): AgentToolResult<GrepToolDetails | undefined> {\n\tconst truncation = truncateHead(outputLines.join(\"\\n\"), { maxLines: Number.MAX_SAFE_INTEGER });\n\tlet output = truncation.content;\n\tconst details: GrepToolDetails = {};\n\tconst notices: string[] = [];\n\tif (matchLimitReached !== undefined) {\n\t\tnotices.push(\n\t\t\t`${matchLimitReached} matches limit reached. Use limit=${matchLimitReached * 2} for more, or refine pattern`,\n\t\t);\n\t\tdetails.matchLimitReached = matchLimitReached;\n\t}\n\tif (truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\tdetails.truncation = truncation;\n\t}\n\tif (state.linesTruncated) {\n\t\tnotices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`);\n\t\tdetails.linesTruncated = true;\n\t}\n\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\treturn {\n\t\tcontent: [{ type: \"text\", text: output }],\n\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t};\n}\n\nasync function executeOperationsGrep(\n\toperations: ToolOperations,\n\tinput: GrepExecutionInput,\n\tformatState: GrepFormatState,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\tconst result = await operations.grep!({\n\t\tpattern: input.pattern,\n\t\tpath: input.searchPath,\n\t\tglob: input.glob,\n\t\tignoreCase: input.ignoreCase,\n\t\tliteral: input.literal,\n\t\tlimit: input.limit,\n\t});\n\tformatState.isDirectory = result.isDirectory;\n\tif (result.matches.length === 0) return noGrepMatchesResult();\n\tconst outputLines = await formatGrepMatches(formatState, result.matches);\n\treturn buildGrepResult(formatState, outputLines, result.matches.length >= input.limit ? input.limit : undefined);\n}\n\nfunction buildRipgrepArgs(input: GrepExecutionInput): string[] {\n\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\tif (input.ignoreCase) args.push(\"--ignore-case\");\n\tif (input.literal) args.push(\"--fixed-strings\");\n\tif (input.glob) args.push(\"--glob\", input.glob);\n\targs.push(\"--\", input.pattern, input.searchPath);\n\treturn args;\n}\n\ninterface ParsedRipgrepLine {\n\tmatchedEvent: boolean;\n\tmatch?: ToolGrepMatch;\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction getRecordText(value: unknown): unknown {\n\treturn isUnknownRecord(value) ? value.text : undefined;\n}\n\nfunction parseRipgrepLine(line: string): ParsedRipgrepLine {\n\tif (!line.trim()) return { matchedEvent: false };\n\tlet event: unknown;\n\ttry {\n\t\tevent = JSON.parse(line) as unknown;\n\t} catch {\n\t\treturn { matchedEvent: false };\n\t}\n\tif (!isUnknownRecord(event) || event.type !== \"match\") return { matchedEvent: false };\n\tconst data = isUnknownRecord(event.data) ? event.data : undefined;\n\tconst filePath = getRecordText(data?.path);\n\tconst lineNumber = data?.line_number;\n\tconst lineText = getRecordText(data?.lines);\n\treturn {\n\t\tmatchedEvent: true,\n\t\t...(typeof filePath === \"string\" && typeof lineNumber === \"number\"\n\t\t\t? { match: { filePath, lineNumber, ...(typeof lineText === \"string\" ? { lineText } : {}) } }\n\t\t\t: {}),\n\t};\n}\n\nfunction collectRipgrepLine(\n\tline: string,\n\tstate: RipgrepCollectionState,\n\tlimit: number,\n\tstopChild: (dueToLimit?: boolean) => void,\n): void {\n\tif (state.matchCount >= limit) return;\n\tconst parsed = parseRipgrepLine(line);\n\tif (!parsed.matchedEvent) return;\n\tstate.matchCount++;\n\tif (parsed.match) state.matches.push(parsed.match);\n\tif (state.matchCount >= limit) {\n\t\tstate.matchLimitReached = true;\n\t\tstopChild(true);\n\t}\n}\n\nasync function finishRipgrepExecution(\n\tcode: number | null,\n\tstate: RipgrepCollectionState,\n\tformatState: GrepFormatState,\n\tlimit: number,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\tif (state.aborted) throw new Error(\"Operation aborted\");\n\tif (!state.killedDueToLimit && code !== 0 && code !== 1) {\n\t\tthrow new Error(state.stderr.trim() || `ripgrep exited with code ${code}`);\n\t}\n\tif (state.matchCount === 0) return noGrepMatchesResult();\n\tconst outputLines = await formatGrepMatches(formatState, state.matches);\n\treturn buildGrepResult(formatState, outputLines, state.matchLimitReached ? limit : undefined);\n}\n\nfunction executeRipgrep(\n\trgPath: string,\n\tinput: GrepExecutionInput,\n\tformatState: GrepFormatState,\n\tsignal?: AbortSignal,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = spawn(rgPath, buildRipgrepArgs(input), { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\tconst rl = createInterface({ input: child.stdout });\n\t\tconst state: RipgrepCollectionState = {\n\t\t\tstderr: \"\",\n\t\t\tmatchCount: 0,\n\t\t\tmatchLimitReached: false,\n\t\t\taborted: false,\n\t\t\tkilledDueToLimit: false,\n\t\t\tmatches: [],\n\t\t};\n\t\tconst cleanup = (): void => {\n\t\t\trl.close();\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t};\n\t\tconst stopChild = (dueToLimit = false): void => {\n\t\t\tif (child.killed) return;\n\t\t\tstate.killedDueToLimit = dueToLimit;\n\t\t\tchild.kill();\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\tstate.aborted = true;\n\t\t\tstopChild();\n\t\t};\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\tchild.stderr.on(\"data\", (chunk) => {\n\t\t\tstate.stderr += chunk.toString();\n\t\t});\n\t\trl.on(\"line\", (line) => collectRipgrepLine(line, state, input.limit, stopChild));\n\t\tchild.on(\"error\", (error) => {\n\t\t\tcleanup();\n\t\t\treject(new Error(`Failed to run ripgrep: ${error.message}`));\n\t\t});\n\t\tchild.on(\"close\", (code) => {\n\t\t\tcleanup();\n\t\t\tvoid finishRipgrepExecution(code, state, formatState, input.limit).then(resolve, reject);\n\t\t});\n\t});\n}\n\nasync function executeGrep(\n\toperations: ToolOperations,\n\tcwd: string,\n\tinput: GrepToolInput,\n\tsignal?: AbortSignal,\n): Promise<AgentToolResult<GrepToolDetails | undefined>> {\n\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\tconst searchPath = resolveToCwd(input.path || \".\", cwd);\n\tlet isDirectory: boolean;\n\ttry {\n\t\tisDirectory = (await operations.stat(searchPath)).isDirectory();\n\t} catch {\n\t\tthrow new Error(`Path not found: ${searchPath}`);\n\t}\n\tconst executionInput: GrepExecutionInput = {\n\t\tpattern: input.pattern,\n\t\tsearchPath,\n\t\tglob: input.glob,\n\t\tignoreCase: input.ignoreCase,\n\t\tliteral: input.literal,\n\t\tcontext: input.context && input.context > 0 ? input.context : 0,\n\t\tlimit: Math.max(1, input.limit ?? DEFAULT_LIMIT),\n\t};\n\tconst formatState: GrepFormatState = {\n\t\toperations,\n\t\tsearchPath,\n\t\tisDirectory,\n\t\tcontext: executionInput.context,\n\t\tfileCache: new Map(),\n\t\tlinesTruncated: false,\n\t};\n\tif (operations.grep) return executeOperationsGrep(operations, executionInput, formatState);\n\tconst rgPath = await ensureTool(\"rg\", true);\n\tif (!rgPath) throw new Error(\"ripgrep (rg) is not available and could not be downloaded\");\n\treturn executeRipgrep(rgPath, executionInput, formatState, signal);\n}\n\nexport type GrepToolDefinition = ToolDefinition<typeof grepSchema, GrepToolDetails | undefined>;\n\nexport function createGrepToolDefinition(operations: ToolOperations, _options?: GrepToolOptions): GrepToolDefinition {\n\tconst ops = operations;\n\tconst cwd = operations.cwd;\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tparameters: grepSchema,\n\t\tasync execute(_toolCallId, input: GrepToolInput, signal?: AbortSignal) {\n\t\t\treturn executeGrep(ops, cwd, input, signal);\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatBackendIcon(ops.getBackendInfo?.(), theme) + formatGrepCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatGrepResult(result, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createGrepTool(operations: ToolOperations, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(operations, options));\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-store.d.ts","sourceRoot":"","sources":["../../../src/core/tools/hash-store.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACxC;AAUD,wBAAsB,aAAa,IAAI,OAAO,CAAC,SAAS,CAAC,CAiBxD;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnE;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAapE"
|
|
1
|
+
{"version":3,"file":"hash-store.d.ts","sourceRoot":"","sources":["../../../src/core/tools/hash-store.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACxC;AAUD,wBAAsB,aAAa,IAAI,OAAO,CAAC,SAAS,CAAC,CAiBxD;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnE;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAapE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-store.js","sourceRoot":"","sources":["../../../src/core/tools/hash-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAYrC,SAAS,SAAS
|
|
1
|
+
{"version":3,"file":"hash-store.js","sourceRoot":"","sources":["../../../src/core/tools/hash-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAYrC,SAAS,SAAS;IACjB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,wBAAwB,EAAE,iBAAiB,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,QAAQ;IAChB,OAAO,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IAClC,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAuB,CAAC;QACzD,OAAO;YACN,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;SACjC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,MAAM,YAAY,GAAc;YAC/B,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE;SACb,CAAC;QACF,MAAM,SAAS,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;QACpE,OAAO,YAAY,CAAC;IACrB,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAgB;IACnD,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,SAAS,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAgB;IACpD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACjC,OAAO,GAAG,IAAI,CAAC;QAChB,CAAC;IACF,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACb,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;AACF,CAAC","sourcesContent":["import { mkdir, readFile, stat, writeFile } from \"fs/promises\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\n\nexport interface FileSnapshot {\n\tcontent: string;\n\thashes: string[];\n}\n\nexport interface HashStore {\n\tversion: 1;\n\tsnapshots: Record<string, FileSnapshot>;\n}\n\nfunction storePath(): string {\n\treturn join(homedir(), \".config\", \"grip-hashline-edit-pro\", \"hash-store.json\");\n}\n\nfunction storeDir(): string {\n\treturn dirname(storePath());\n}\n\nexport async function loadHashStore(): Promise<HashStore> {\n\ttry {\n\t\tconst content = await readFile(storePath(), \"utf-8\");\n\t\tconst parsed = JSON.parse(content) as Partial<HashStore>;\n\t\treturn {\n\t\t\tversion: 1,\n\t\t\tsnapshots: parsed.snapshots ?? {},\n\t\t};\n\t} catch {\n\t\tawait mkdir(storeDir(), { recursive: true });\n\t\tconst defaultStore: HashStore = {\n\t\t\tversion: 1,\n\t\t\tsnapshots: {},\n\t\t};\n\t\tawait writeFile(storePath(), JSON.stringify(defaultStore), \"utf-8\");\n\t\treturn defaultStore;\n\t}\n}\n\nexport async function saveHashStore(store: HashStore): Promise<void> {\n\tawait mkdir(storeDir(), { recursive: true });\n\tawait writeFile(storePath(), JSON.stringify(store, null, 2), \"utf-8\");\n}\n\nexport async function pruneHashStore(store: HashStore): Promise<void> {\n\tlet changed = false;\n\tfor (const filePath of Object.keys(store.snapshots)) {\n\t\ttry {\n\t\t\tawait stat(filePath);\n\t\t} catch {\n\t\t\tdelete store.snapshots[filePath];\n\t\t\tchanged = true;\n\t\t}\n\t}\n\tif (changed) {\n\t\tawait saveHashStore(store);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/hashline/apply.ts"],"names":[],"mappings":"AAGA,OAAO,EAEN,KAAK,QAAQ,EACb,KAAK,qBAAqB,EAG1B,KAAK,KAAK,EACV,KAAK,KAAK,EAIV,MAAM,cAAc,CAAC;AAEtB,KAAK,IAAI,GAAG;IACX,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAkB9C;AAgBD,UAAU,4BAA4B;IACrC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,UAAU,gBAAgB;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAC;IACnE,eAAe,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAAC;IACjE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;IACpB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,CAAC;CAC9B;AAwID;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,4BAA4B,GAAG,MAAM,CA+B/E;AAED,wBAAgB,UAAU,CACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,EAAE,EACd,MAAM,CAAC,EAAE,WAAW,EACpB,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAC5B,QAAQ,CAAC,EAAE,MAAM,GACf,gBAAgB,CA8ClB;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAKnE;AA0BD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAyCtF","sourcesContent":["import { cntLines } from \"../hashline-utils.ts\";\nimport { abortIf } from \"../runtime.ts\";\nimport { _lineHashesPure, HASH_SEP } from \"./hash.ts\";\nimport {\n\tassertNoBarePrefix,\n\ttype BDupWarn,\n\ttype BoundaryDuplicateKind,\n\tdescEdit,\n\tfmtMismatch,\n\ttype HEdit,\n\ttype NEdit,\n\ttype RHEdit,\n\tvalEdits,\n\twarnUnicodeEsc,\n} from \"./resolve.ts\";\n\ntype LIdx = {\n\tfileLines: string[];\n\tlineStarts: number[];\n\thasTerminalNewline: boolean;\n};\n\nexport function buildIdx(content: string): LIdx {\n\tconst fileLines = content.split(\"\\n\");\n\tconst lineStarts: number[] = [];\n\tlet offset = 0;\n\n\tfor (let index = 0; index < fileLines.length; index++) {\n\t\tlineStarts.push(offset);\n\t\toffset += fileLines[index]!.length;\n\t\tif (index < fileLines.length - 1) {\n\t\t\toffset += 1;\n\t\t}\n\t}\n\n\treturn {\n\t\tfileLines,\n\t\tlineStarts,\n\t\thasTerminalNewline: content.endsWith(\"\\n\"),\n\t};\n}\n\ntype RESpan = {\n\tkind: \"replace\";\n\tindex: number;\n\tlabel: string;\n\tstart: number;\n\tend: number;\n\treplacement: string;\n};\n\ninterface EditConflictSide {\n\tindex: number;\n\tlabel: string;\n}\n\ninterface BoundaryWarningFormatOptions {\n\tkind: BoundaryDuplicateKind;\n\tsurvivingContent: string;\n\tmatchIndex: number;\n\tresultLines: string[];\n\tresultHashes: string[];\n}\n\ninterface ChangedLineRange {\n\tfirstChangedLine: number;\n\tlastChangedLine: number;\n}\n\nexport interface ApplyEditsResult {\n\tcontent: string;\n\tfirstChangedLine: ChangedLineRange[\"firstChangedLine\"] | undefined;\n\tlastChangedLine: ChangedLineRange[\"lastChangedLine\"] | undefined;\n\twarnings?: string[];\n\tnoopEdits?: NEdit[];\n\tboundaryWarnings?: BDupWarn[];\n}\n\nfunction assertNotEmpty(originalContent: string, result: string): void {\n\tif (originalContent.length > 0 && result.length === 0) {\n\t\tthrow new Error(\"[E_WOULD_EMPTY] Cannot empty a non-empty file via edit.\");\n\t}\n}\n\nfunction throwConflict(left: EditConflictSide, right: EditConflictSide, reason: string): never {\n\tthrow new Error(\n\t\t`[E_EDIT_CONFLICT] Edit ${left.index} (${left.label}) and edit ${right.index} (${right.label}) ${reason}.`,\n\t);\n}\n\nfunction resToSpan(edit: RHEdit, index: number, content: string, lineIndex: LIdx, noopEdits: NEdit[]): RESpan | null {\n\tconst { fileLines, lineStarts } = lineIndex;\n\n\tconst startLine = edit.hash_range_inclusive[0].line;\n\tconst endLine = edit.hash_range_inclusive[1].line;\n\tconst originalLines = fileLines.slice(startLine - 1, endLine);\n\tif (\n\t\toriginalLines.length === edit.content_lines.length &&\n\t\toriginalLines.every((line, lineIndex) => line === edit.content_lines[lineIndex])\n\t) {\n\t\tnoopEdits.push({\n\t\t\teditIndex: index,\n\t\t\tloc: edit.hash_range_inclusive[0].hash,\n\t\t\tcurrentContent: originalLines.join(\"\\n\"),\n\t\t});\n\t\treturn null;\n\t}\n\n\tconst label = descEdit(edit);\n\n\tif (edit.content_lines.length > 0) {\n\t\treturn {\n\t\t\tkind: \"replace\",\n\t\t\tindex,\n\t\t\tlabel,\n\t\t\tstart: lineStarts[startLine - 1]!,\n\t\t\tend: lineStarts[endLine - 1]! + fileLines[endLine - 1]!.length,\n\t\t\treplacement: edit.content_lines.join(\"\\n\"),\n\t\t};\n\t}\n\n\tif (startLine === 1 && endLine === fileLines.length) {\n\t\treturn {\n\t\t\tkind: \"replace\",\n\t\t\tindex,\n\t\t\tlabel,\n\t\t\tstart: 0,\n\t\t\tend: content.length,\n\t\t\treplacement: \"\",\n\t\t};\n\t}\n\n\tif (endLine < fileLines.length) {\n\t\treturn {\n\t\t\tkind: \"replace\",\n\t\t\tindex,\n\t\t\tlabel,\n\t\t\tstart: lineStarts[startLine - 1]!,\n\t\t\tend: lineStarts[endLine]!,\n\t\t\treplacement: \"\",\n\t\t};\n\t}\n\n\treturn {\n\t\tkind: \"replace\",\n\t\tindex,\n\t\tlabel,\n\t\tstart: Math.max(0, lineStarts[startLine - 1]! - 1),\n\t\tend: lineStarts[endLine - 1]! + fileLines[endLine - 1]!.length,\n\t\treplacement: \"\",\n\t};\n}\n\nfunction assertNoConflict(spans: RESpan[]): void {\n\tif (spans.length < 2) return;\n\tconst ordered = [...spans].sort(\n\t\t(left, right) => left.start - right.start || right.end - left.end || left.index - right.index,\n\t);\n\tlet furthestEndSpan = ordered[0]!;\n\tfor (let index = 1; index < ordered.length; index++) {\n\t\tconst current = ordered[index]!;\n\t\tif (furthestEndSpan.start < current.end && current.start < furthestEndSpan.end) {\n\t\t\tconst [left, right] =\n\t\t\t\tfurthestEndSpan.index < current.index ? [furthestEndSpan, current] : [current, furthestEndSpan];\n\t\t\tthrowConflict(left, right, \"overlap on the same original line range\");\n\t\t}\n\t\tif (current.end > furthestEndSpan.end) furthestEndSpan = current;\n\t}\n}\n\nfunction resSpans(\n\tedits: RHEdit[],\n\tcontent: string,\n\tlineIndex: LIdx,\n\tnoopEdits: NEdit[],\n\tsignal: AbortSignal | undefined,\n): RESpan[] {\n\tconst seenSpanKeys = new Set<string>();\n\tconst resolvedSpans: RESpan[] = [];\n\tfor (const [index, edit] of edits.entries()) {\n\t\tabortIf(signal);\n\t\tconst span = resToSpan(edit, index, content, lineIndex, noopEdits);\n\t\tif (!span) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst spanKey = `replace:${span.start}:${span.end}:${span.replacement}`;\n\t\tif (seenSpanKeys.has(spanKey)) {\n\t\t\tcontinue;\n\t\t}\n\t\tseenSpanKeys.add(spanKey);\n\t\tresolvedSpans.push(span);\n\t}\n\n\tassertNoConflict(resolvedSpans);\n\treturn [...resolvedSpans].sort((left, right) => {\n\t\tif (right.end !== left.end) {\n\t\t\treturn right.end - left.end;\n\t\t}\n\t\treturn left.index - right.index;\n\t});\n}\n\nfunction assemble(content: string, spans: RESpan[], signal: AbortSignal | undefined): string {\n\tlet result = content;\n\tfor (const span of spans) {\n\t\tabortIf(signal);\n\t\tresult = result.slice(0, span.start) + span.replacement + result.slice(span.end);\n\t}\n\treturn result;\n}\n\n/**\n * Builds the boundary-duplication warning shown after an edit. A minimal header\n * is followed by a hashline-anchored window: 2 lines of context before the\n * duplicated pair, the pair itself, and 2 lines after. The window carries the\n * post-edit hashes the model needs to remove the duplicate in a follow-up\n * `replace` (no `read` round-trip required, since the hashes are current and\n * staleness is per-line). Rows are plain `HASH│content` — no annotations.\n */\nexport function fmtBoundaryWarning(params: BoundaryWarningFormatOptions): string {\n\tconst header =\n\t\tparams.kind === \"trailing\"\n\t\t\t? \"Boundary duplication (trailing): the last replacement line duplicated the next line. This happens when `content_lines` includes a line that was already outside the replaced range. Delete the duplicate — the original line outside the range is still there.\"\n\t\t\t: \"Boundary duplication (leading): the first replacement line duplicated the previous line. This happens when `content_lines` includes a line that was already outside the replaced range. Delete the duplicate — the original line outside the range is still there.\";\n\n\t// Locate the adjacent duplicated pair (two identical neighboring lines). The\n\t// occurrence-based matchIndex usually lands inside the pair; when a file has\n\t// several identical lines we pick the pair nearest matchIndex so the window\n\t// frames the duplication this edit introduced, not an unrelated one.\n\tlet pairStart = -1;\n\tlet bestDist = Infinity;\n\tfor (let i = 0; i < params.resultLines.length - 1; i++) {\n\t\tif (params.resultLines[i] === params.survivingContent && params.resultLines[i + 1] === params.survivingContent) {\n\t\t\tconst dist = Math.abs(i - params.matchIndex);\n\t\t\tif (dist < bestDist) {\n\t\t\t\tbestDist = dist;\n\t\t\t\tpairStart = i;\n\t\t\t}\n\t\t}\n\t}\n\tif (pairStart < 0) pairStart = params.matchIndex;\n\n\tconst winStart = Math.max(0, pairStart - 2);\n\tconst winEnd = Math.min(params.resultLines.length - 1, pairStart + 3);\n\n\tconst rows: string[] = [];\n\tfor (let i = winStart; i <= winEnd; i++) {\n\t\trows.push(`${params.resultHashes[i]}${HASH_SEP}${params.resultLines[i]}`);\n\t}\n\treturn `${header}\\n\\n${rows.join(\"\\n\")}`;\n}\n\nexport function applyEdits(\n\tcontent: string,\n\tedits: HEdit[],\n\tsignal?: AbortSignal,\n\tprecomputedHashes?: string[],\n\tfilePath?: string,\n): ApplyEditsResult {\n\tabortIf(signal);\n\tif (!edits.length)\n\t\treturn {\n\t\t\tcontent,\n\t\t\tfirstChangedLine: undefined,\n\t\t\tlastChangedLine: undefined,\n\t\t};\n\n\tedits = edits.map((edit) =>\n\t\tedit.content_lines.length === 1 && edit.content_lines[0] === \"\" ? { ...edit, content_lines: [] } : edit,\n\t);\n\n\tconst lineIndex = buildIdx(content);\n\tconst fileHashes = precomputedHashes ?? _lineHashesPure(content);\n\tconst noopEdits: NEdit[] = [];\n\tconst warnings: string[] = [];\n\n\tconst { resolved, mismatches, boundaryWarnings } = valEdits(\n\t\tedits,\n\t\tlineIndex.fileLines,\n\t\tfileHashes,\n\t\twarnings,\n\t\tsignal,\n\t);\n\tif (mismatches.length) {\n\t\tthrow new Error(fmtMismatch(mismatches, lineIndex.fileLines, fileHashes, filePath));\n\t}\n\n\tassertNoBarePrefix(edits, lineIndex.fileLines, fileHashes);\n\twarnUnicodeEsc(edits, warnings);\n\n\tconst orderedSpans = resSpans(resolved, content, lineIndex, noopEdits, signal);\n\n\tconst result = assemble(content, orderedSpans, signal);\n\tassertNotEmpty(content, result);\n\tconst range = changedRange(content, result);\n\n\treturn {\n\t\tcontent: result,\n\t\tfirstChangedLine: range?.firstChangedLine,\n\t\tlastChangedLine: range?.lastChangedLine,\n\t\t...(warnings.length ? { warnings } : {}),\n\t\t...(noopEdits.length ? { noopEdits } : {}),\n\t\t...(boundaryWarnings.length ? { boundaryWarnings } : {}),\n\t};\n}\n\nexport function fmtRegion(hashes: string[], lines: string[]): string {\n\tif (hashes.length !== lines.length) {\n\t\tthrow new Error(`fmtRegion: hashes.length (${hashes.length}) must match lines.length (${lines.length}).`);\n\t}\n\treturn lines.map((line, index) => `${hashes[index]}${HASH_SEP}${line}`).join(\"\\n\");\n}\nfunction characterIndexToLineNumber(characterIndex: number, text: string): number {\n\tlet line = 1;\n\tfor (let index = 0; index < characterIndex && index < text.length; index++) {\n\t\tif (text[index] === \"\\n\") line++;\n\t}\n\treturn line;\n}\ninterface ChangedRangeScan {\n\toriginal: string;\n\tresult: string;\n\tfirstDifferenceIndex: number;\n\tlastResultDifferenceIndex: number;\n\tfirstChangedLine: number;\n}\n\nfunction resolveLastChangedLine(scan: ChangedRangeScan): number {\n\tif (scan.lastResultDifferenceIndex < scan.firstDifferenceIndex) {\n\t\treturn scan.result.length === 0 ? 1 : cntLines(scan.result);\n\t}\n\tif (scan.firstDifferenceIndex === 0 && scan.original.length > 0 && scan.result.endsWith(scan.original)) {\n\t\treturn scan.firstChangedLine;\n\t}\n\treturn characterIndexToLineNumber(scan.lastResultDifferenceIndex + 1, scan.result);\n}\n\nexport function changedRange(original: string, result: string): ChangedLineRange | null {\n\tif (original === result) return null;\n\n\tif (original.length === 0) {\n\t\treturn {\n\t\t\tfirstChangedLine: 1,\n\t\t\tlastChangedLine: cntLines(result),\n\t\t};\n\t}\n\n\tif (result.startsWith(original) && original.endsWith(\"\\n\")) {\n\t\treturn {\n\t\t\tfirstChangedLine: cntLines(original) + 1,\n\t\t\tlastChangedLine: cntLines(result),\n\t\t};\n\t}\n\n\tlet firstDiff = 0;\n\tconst minLen = Math.min(original.length, result.length);\n\twhile (firstDiff < minLen && original[firstDiff] === result[firstDiff]) {\n\t\tfirstDiff++;\n\t}\n\tif (firstDiff === minLen && original.length === result.length) return null;\n\n\tlet lastOrig = original.length - 1;\n\tlet lastRes = result.length - 1;\n\twhile (lastOrig >= firstDiff && lastRes >= firstDiff && original[lastOrig] === result[lastRes]) {\n\t\tlastOrig--;\n\t\tlastRes--;\n\t}\n\n\tconst firstChangedLine = characterIndexToLineNumber(firstDiff + 1, result);\n\tconst lastChangedLine = resolveLastChangedLine({\n\t\toriginal,\n\t\tresult,\n\t\tfirstDifferenceIndex: firstDiff,\n\t\tlastResultDifferenceIndex: lastRes,\n\t\tfirstChangedLine,\n\t});\n\n\treturn { firstChangedLine, lastChangedLine };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/hashline/apply.ts"],"names":[],"mappings":"AAGA,OAAO,EAEN,KAAK,QAAQ,EACb,KAAK,qBAAqB,EAG1B,KAAK,KAAK,EACV,KAAK,KAAK,EAIV,MAAM,cAAc,CAAC;AAEtB,KAAK,IAAI,GAAG;IACX,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAkB9C;AAgBD,UAAU,4BAA4B;IACrC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,UAAU,gBAAgB;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAC;IACnE,eAAe,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAAC;IACjE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;IACpB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,CAAC;CAC9B;AAwID;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,4BAA4B,GAAG,MAAM,CA+B/E;AAED,wBAAgB,UAAU,CACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,EAAE,EACd,MAAM,CAAC,EAAE,WAAW,EACpB,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAC5B,QAAQ,CAAC,EAAE,MAAM,GACf,gBAAgB,CA8ClB;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAKnE;AA0BD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAyCtF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../../src/core/tools/hashline/apply.ts"],"names":[],"mappings":"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","sourcesContent":["import { cntLines } from \"../hashline-utils.ts\";\nimport { abortIf } from \"../runtime.ts\";\nimport { _lineHashesPure, HASH_SEP } from \"./hash.ts\";\nimport {\n\tassertNoBarePrefix,\n\ttype BDupWarn,\n\ttype BoundaryDuplicateKind,\n\tdescEdit,\n\tfmtMismatch,\n\ttype HEdit,\n\ttype NEdit,\n\ttype RHEdit,\n\tvalEdits,\n\twarnUnicodeEsc,\n} from \"./resolve.ts\";\n\ntype LIdx = {\n\tfileLines: string[];\n\tlineStarts: number[];\n\thasTerminalNewline: boolean;\n};\n\nexport function buildIdx(content: string): LIdx {\n\tconst fileLines = content.split(\"\\n\");\n\tconst lineStarts: number[] = [];\n\tlet offset = 0;\n\n\tfor (let index = 0; index < fileLines.length; index++) {\n\t\tlineStarts.push(offset);\n\t\toffset += fileLines[index]!.length;\n\t\tif (index < fileLines.length - 1) {\n\t\t\toffset += 1;\n\t\t}\n\t}\n\n\treturn {\n\t\tfileLines,\n\t\tlineStarts,\n\t\thasTerminalNewline: content.endsWith(\"\\n\"),\n\t};\n}\n\ntype RESpan = {\n\tkind: \"replace\";\n\tindex: number;\n\tlabel: string;\n\tstart: number;\n\tend: number;\n\treplacement: string;\n};\n\ninterface EditConflictSide {\n\tindex: number;\n\tlabel: string;\n}\n\ninterface BoundaryWarningFormatOptions {\n\tkind: BoundaryDuplicateKind;\n\tsurvivingContent: string;\n\tmatchIndex: number;\n\tresultLines: string[];\n\tresultHashes: string[];\n}\n\ninterface ChangedLineRange {\n\tfirstChangedLine: number;\n\tlastChangedLine: number;\n}\n\nexport interface ApplyEditsResult {\n\tcontent: string;\n\tfirstChangedLine: ChangedLineRange[\"firstChangedLine\"] | undefined;\n\tlastChangedLine: ChangedLineRange[\"lastChangedLine\"] | undefined;\n\twarnings?: string[];\n\tnoopEdits?: NEdit[];\n\tboundaryWarnings?: BDupWarn[];\n}\n\nfunction assertNotEmpty(originalContent: string, result: string): void {\n\tif (originalContent.length > 0 && result.length === 0) {\n\t\tthrow new Error(\"[E_WOULD_EMPTY] Cannot empty a non-empty file via edit.\");\n\t}\n}\n\nfunction throwConflict(left: EditConflictSide, right: EditConflictSide, reason: string): never {\n\tthrow new Error(\n\t\t`[E_EDIT_CONFLICT] Edit ${left.index} (${left.label}) and edit ${right.index} (${right.label}) ${reason}.`,\n\t);\n}\n\nfunction resToSpan(edit: RHEdit, index: number, content: string, lineIndex: LIdx, noopEdits: NEdit[]): RESpan | null {\n\tconst { fileLines, lineStarts } = lineIndex;\n\n\tconst startLine = edit.hash_range_inclusive[0].line;\n\tconst endLine = edit.hash_range_inclusive[1].line;\n\tconst originalLines = fileLines.slice(startLine - 1, endLine);\n\tif (\n\t\toriginalLines.length === edit.content_lines.length &&\n\t\toriginalLines.every((line, lineIndex) => line === edit.content_lines[lineIndex])\n\t) {\n\t\tnoopEdits.push({\n\t\t\teditIndex: index,\n\t\t\tloc: edit.hash_range_inclusive[0].hash,\n\t\t\tcurrentContent: originalLines.join(\"\\n\"),\n\t\t});\n\t\treturn null;\n\t}\n\n\tconst label = descEdit(edit);\n\n\tif (edit.content_lines.length > 0) {\n\t\treturn {\n\t\t\tkind: \"replace\",\n\t\t\tindex,\n\t\t\tlabel,\n\t\t\tstart: lineStarts[startLine - 1]!,\n\t\t\tend: lineStarts[endLine - 1]! + fileLines[endLine - 1]!.length,\n\t\t\treplacement: edit.content_lines.join(\"\\n\"),\n\t\t};\n\t}\n\n\tif (startLine === 1 && endLine === fileLines.length) {\n\t\treturn {\n\t\t\tkind: \"replace\",\n\t\t\tindex,\n\t\t\tlabel,\n\t\t\tstart: 0,\n\t\t\tend: content.length,\n\t\t\treplacement: \"\",\n\t\t};\n\t}\n\n\tif (endLine < fileLines.length) {\n\t\treturn {\n\t\t\tkind: \"replace\",\n\t\t\tindex,\n\t\t\tlabel,\n\t\t\tstart: lineStarts[startLine - 1]!,\n\t\t\tend: lineStarts[endLine]!,\n\t\t\treplacement: \"\",\n\t\t};\n\t}\n\n\treturn {\n\t\tkind: \"replace\",\n\t\tindex,\n\t\tlabel,\n\t\tstart: Math.max(0, lineStarts[startLine - 1]! - 1),\n\t\tend: lineStarts[endLine - 1]! + fileLines[endLine - 1]!.length,\n\t\treplacement: \"\",\n\t};\n}\n\nfunction assertNoConflict(spans: RESpan[]): void {\n\tif (spans.length < 2) return;\n\tconst ordered = [...spans].sort(\n\t\t(left, right) => left.start - right.start || right.end - left.end || left.index - right.index,\n\t);\n\tlet furthestEndSpan = ordered[0]!;\n\tfor (let index = 1; index < ordered.length; index++) {\n\t\tconst current = ordered[index]!;\n\t\tif (furthestEndSpan.start < current.end && current.start < furthestEndSpan.end) {\n\t\t\tconst [left, right] =\n\t\t\t\tfurthestEndSpan.index < current.index ? [furthestEndSpan, current] : [current, furthestEndSpan];\n\t\t\tthrowConflict(left, right, \"overlap on the same original line range\");\n\t\t}\n\t\tif (current.end > furthestEndSpan.end) furthestEndSpan = current;\n\t}\n}\n\nfunction resSpans(\n\tedits: RHEdit[],\n\tcontent: string,\n\tlineIndex: LIdx,\n\tnoopEdits: NEdit[],\n\tsignal: AbortSignal | undefined,\n): RESpan[] {\n\tconst seenSpanKeys = new Set<string>();\n\tconst resolvedSpans: RESpan[] = [];\n\tfor (const [index, edit] of edits.entries()) {\n\t\tabortIf(signal);\n\t\tconst span = resToSpan(edit, index, content, lineIndex, noopEdits);\n\t\tif (!span) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst spanKey = `replace:${span.start}:${span.end}:${span.replacement}`;\n\t\tif (seenSpanKeys.has(spanKey)) {\n\t\t\tcontinue;\n\t\t}\n\t\tseenSpanKeys.add(spanKey);\n\t\tresolvedSpans.push(span);\n\t}\n\n\tassertNoConflict(resolvedSpans);\n\treturn [...resolvedSpans].sort((left, right) => {\n\t\tif (right.end !== left.end) {\n\t\t\treturn right.end - left.end;\n\t\t}\n\t\treturn left.index - right.index;\n\t});\n}\n\nfunction assemble(content: string, spans: RESpan[], signal: AbortSignal | undefined): string {\n\tlet result = content;\n\tfor (const span of spans) {\n\t\tabortIf(signal);\n\t\tresult = result.slice(0, span.start) + span.replacement + result.slice(span.end);\n\t}\n\treturn result;\n}\n\n/**\n * Builds the boundary-duplication warning shown after an edit. A minimal header\n * is followed by a hashline-anchored window: 2 lines of context before the\n * duplicated pair, the pair itself, and 2 lines after. The window carries the\n * post-edit hashes the model needs to remove the duplicate in a follow-up\n * `replace` (no `read` round-trip required, since the hashes are current and\n * staleness is per-line). Rows are plain `HASH│content` — no annotations.\n */\nexport function fmtBoundaryWarning(params: BoundaryWarningFormatOptions): string {\n\tconst header =\n\t\tparams.kind === \"trailing\"\n\t\t\t? \"Boundary duplication (trailing): the last replacement line duplicated the next line. This happens when `content_lines` includes a line that was already outside the replaced range. Delete the duplicate — the original line outside the range is still there.\"\n\t\t\t: \"Boundary duplication (leading): the first replacement line duplicated the previous line. This happens when `content_lines` includes a line that was already outside the replaced range. Delete the duplicate — the original line outside the range is still there.\";\n\n\t// Locate the adjacent duplicated pair (two identical neighboring lines). The\n\t// occurrence-based matchIndex usually lands inside the pair; when a file has\n\t// several identical lines we pick the pair nearest matchIndex so the window\n\t// frames the duplication this edit introduced, not an unrelated one.\n\tlet pairStart = -1;\n\tlet bestDist = Infinity;\n\tfor (let i = 0; i < params.resultLines.length - 1; i++) {\n\t\tif (params.resultLines[i] === params.survivingContent && params.resultLines[i + 1] === params.survivingContent) {\n\t\t\tconst dist = Math.abs(i - params.matchIndex);\n\t\t\tif (dist < bestDist) {\n\t\t\t\tbestDist = dist;\n\t\t\t\tpairStart = i;\n\t\t\t}\n\t\t}\n\t}\n\tif (pairStart < 0) pairStart = params.matchIndex;\n\n\tconst winStart = Math.max(0, pairStart - 2);\n\tconst winEnd = Math.min(params.resultLines.length - 1, pairStart + 3);\n\n\tconst rows: string[] = [];\n\tfor (let i = winStart; i <= winEnd; i++) {\n\t\trows.push(`${params.resultHashes[i]}${HASH_SEP}${params.resultLines[i]}`);\n\t}\n\treturn `${header}\\n\\n${rows.join(\"\\n\")}`;\n}\n\nexport function applyEdits(\n\tcontent: string,\n\tedits: HEdit[],\n\tsignal?: AbortSignal,\n\tprecomputedHashes?: string[],\n\tfilePath?: string,\n): ApplyEditsResult {\n\tabortIf(signal);\n\tif (!edits.length)\n\t\treturn {\n\t\t\tcontent,\n\t\t\tfirstChangedLine: undefined,\n\t\t\tlastChangedLine: undefined,\n\t\t};\n\n\tedits = edits.map((edit) =>\n\t\tedit.content_lines.length === 1 && edit.content_lines[0] === \"\" ? { ...edit, content_lines: [] } : edit,\n\t);\n\n\tconst lineIndex = buildIdx(content);\n\tconst fileHashes = precomputedHashes ?? _lineHashesPure(content);\n\tconst noopEdits: NEdit[] = [];\n\tconst warnings: string[] = [];\n\n\tconst { resolved, mismatches, boundaryWarnings } = valEdits(\n\t\tedits,\n\t\tlineIndex.fileLines,\n\t\tfileHashes,\n\t\twarnings,\n\t\tsignal,\n\t);\n\tif (mismatches.length) {\n\t\tthrow new Error(fmtMismatch(mismatches, lineIndex.fileLines, fileHashes, filePath));\n\t}\n\n\tassertNoBarePrefix(edits, lineIndex.fileLines, fileHashes);\n\twarnUnicodeEsc(edits, warnings);\n\n\tconst orderedSpans = resSpans(resolved, content, lineIndex, noopEdits, signal);\n\n\tconst result = assemble(content, orderedSpans, signal);\n\tassertNotEmpty(content, result);\n\tconst range = changedRange(content, result);\n\n\treturn {\n\t\tcontent: result,\n\t\tfirstChangedLine: range?.firstChangedLine,\n\t\tlastChangedLine: range?.lastChangedLine,\n\t\t...(warnings.length ? { warnings } : {}),\n\t\t...(noopEdits.length ? { noopEdits } : {}),\n\t\t...(boundaryWarnings.length ? { boundaryWarnings } : {}),\n\t};\n}\n\nexport function fmtRegion(hashes: string[], lines: string[]): string {\n\tif (hashes.length !== lines.length) {\n\t\tthrow new Error(`fmtRegion: hashes.length (${hashes.length}) must match lines.length (${lines.length}).`);\n\t}\n\treturn lines.map((line, index) => `${hashes[index]}${HASH_SEP}${line}`).join(\"\\n\");\n}\nfunction characterIndexToLineNumber(characterIndex: number, text: string): number {\n\tlet line = 1;\n\tfor (let index = 0; index < characterIndex && index < text.length; index++) {\n\t\tif (text[index] === \"\\n\") line++;\n\t}\n\treturn line;\n}\ninterface ChangedRangeScan {\n\toriginal: string;\n\tresult: string;\n\tfirstDifferenceIndex: number;\n\tlastResultDifferenceIndex: number;\n\tfirstChangedLine: number;\n}\n\nfunction resolveLastChangedLine(scan: ChangedRangeScan): number {\n\tif (scan.lastResultDifferenceIndex < scan.firstDifferenceIndex) {\n\t\treturn scan.result.length === 0 ? 1 : cntLines(scan.result);\n\t}\n\tif (scan.firstDifferenceIndex === 0 && scan.original.length > 0 && scan.result.endsWith(scan.original)) {\n\t\treturn scan.firstChangedLine;\n\t}\n\treturn characterIndexToLineNumber(scan.lastResultDifferenceIndex + 1, scan.result);\n}\n\nexport function changedRange(original: string, result: string): ChangedLineRange | null {\n\tif (original === result) return null;\n\n\tif (original.length === 0) {\n\t\treturn {\n\t\t\tfirstChangedLine: 1,\n\t\t\tlastChangedLine: cntLines(result),\n\t\t};\n\t}\n\n\tif (result.startsWith(original) && original.endsWith(\"\\n\")) {\n\t\treturn {\n\t\t\tfirstChangedLine: cntLines(original) + 1,\n\t\t\tlastChangedLine: cntLines(result),\n\t\t};\n\t}\n\n\tlet firstDiff = 0;\n\tconst minLen = Math.min(original.length, result.length);\n\twhile (firstDiff < minLen && original[firstDiff] === result[firstDiff]) {\n\t\tfirstDiff++;\n\t}\n\tif (firstDiff === minLen && original.length === result.length) return null;\n\n\tlet lastOrig = original.length - 1;\n\tlet lastRes = result.length - 1;\n\twhile (lastOrig >= firstDiff && lastRes >= firstDiff && original[lastOrig] === result[lastRes]) {\n\t\tlastOrig--;\n\t\tlastRes--;\n\t}\n\n\tconst firstChangedLine = characterIndexToLineNumber(firstDiff + 1, result);\n\tconst lastChangedLine = resolveLastChangedLine({\n\t\toriginal,\n\t\tresult,\n\t\tfirstDifferenceIndex: firstDiff,\n\t\tlastResultDifferenceIndex: lastRes,\n\t\tfirstChangedLine,\n\t});\n\n\treturn { firstChangedLine, lastChangedLine };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../../src/core/tools/hashline/apply.ts"],"names":[],"mappings":"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","sourcesContent":["import { cntLines } from \"../hashline-utils.ts\";\nimport { abortIf } from \"../runtime.ts\";\nimport { _lineHashesPure, HASH_SEP } from \"./hash.ts\";\nimport {\n\tassertNoBarePrefix,\n\ttype BDupWarn,\n\ttype BoundaryDuplicateKind,\n\tdescEdit,\n\tfmtMismatch,\n\ttype HEdit,\n\ttype NEdit,\n\ttype RHEdit,\n\tvalEdits,\n\twarnUnicodeEsc,\n} from \"./resolve.ts\";\n\ntype LIdx = {\n\tfileLines: string[];\n\tlineStarts: number[];\n\thasTerminalNewline: boolean;\n};\n\nexport function buildIdx(content: string): LIdx {\n\tconst fileLines = content.split(\"\\n\");\n\tconst lineStarts: number[] = [];\n\tlet offset = 0;\n\n\tfor (let index = 0; index < fileLines.length; index++) {\n\t\tlineStarts.push(offset);\n\t\toffset += fileLines[index]!.length;\n\t\tif (index < fileLines.length - 1) {\n\t\t\toffset += 1;\n\t\t}\n\t}\n\n\treturn {\n\t\tfileLines,\n\t\tlineStarts,\n\t\thasTerminalNewline: content.endsWith(\"\\n\"),\n\t};\n}\n\ntype RESpan = {\n\tkind: \"replace\";\n\tindex: number;\n\tlabel: string;\n\tstart: number;\n\tend: number;\n\treplacement: string;\n};\n\ninterface EditConflictSide {\n\tindex: number;\n\tlabel: string;\n}\n\ninterface BoundaryWarningFormatOptions {\n\tkind: BoundaryDuplicateKind;\n\tsurvivingContent: string;\n\tmatchIndex: number;\n\tresultLines: string[];\n\tresultHashes: string[];\n}\n\ninterface ChangedLineRange {\n\tfirstChangedLine: number;\n\tlastChangedLine: number;\n}\n\nexport interface ApplyEditsResult {\n\tcontent: string;\n\tfirstChangedLine: ChangedLineRange[\"firstChangedLine\"] | undefined;\n\tlastChangedLine: ChangedLineRange[\"lastChangedLine\"] | undefined;\n\twarnings?: string[];\n\tnoopEdits?: NEdit[];\n\tboundaryWarnings?: BDupWarn[];\n}\n\nfunction assertNotEmpty(originalContent: string, result: string): void {\n\tif (originalContent.length > 0 && result.length === 0) {\n\t\tthrow new Error(\"[E_WOULD_EMPTY] Cannot empty a non-empty file via edit.\");\n\t}\n}\n\nfunction throwConflict(left: EditConflictSide, right: EditConflictSide, reason: string): never {\n\tthrow new Error(\n\t\t`[E_EDIT_CONFLICT] Edit ${left.index} (${left.label}) and edit ${right.index} (${right.label}) ${reason}.`,\n\t);\n}\n\nfunction resToSpan(edit: RHEdit, index: number, content: string, lineIndex: LIdx, noopEdits: NEdit[]): RESpan | null {\n\tconst { fileLines, lineStarts } = lineIndex;\n\n\tconst startLine = edit.hash_range_inclusive[0].line;\n\tconst endLine = edit.hash_range_inclusive[1].line;\n\tconst originalLines = fileLines.slice(startLine - 1, endLine);\n\tif (\n\t\toriginalLines.length === edit.content_lines.length &&\n\t\toriginalLines.every((line, lineIndex) => line === edit.content_lines[lineIndex])\n\t) {\n\t\tnoopEdits.push({\n\t\t\teditIndex: index,\n\t\t\tloc: edit.hash_range_inclusive[0].hash,\n\t\t\tcurrentContent: originalLines.join(\"\\n\"),\n\t\t});\n\t\treturn null;\n\t}\n\n\tconst label = descEdit(edit);\n\n\tif (edit.content_lines.length > 0) {\n\t\treturn {\n\t\t\tkind: \"replace\",\n\t\t\tindex,\n\t\t\tlabel,\n\t\t\tstart: lineStarts[startLine - 1]!,\n\t\t\tend: lineStarts[endLine - 1]! + fileLines[endLine - 1]!.length,\n\t\t\treplacement: edit.content_lines.join(\"\\n\"),\n\t\t};\n\t}\n\n\tif (startLine === 1 && endLine === fileLines.length) {\n\t\treturn {\n\t\t\tkind: \"replace\",\n\t\t\tindex,\n\t\t\tlabel,\n\t\t\tstart: 0,\n\t\t\tend: content.length,\n\t\t\treplacement: \"\",\n\t\t};\n\t}\n\n\tif (endLine < fileLines.length) {\n\t\treturn {\n\t\t\tkind: \"replace\",\n\t\t\tindex,\n\t\t\tlabel,\n\t\t\tstart: lineStarts[startLine - 1]!,\n\t\t\tend: lineStarts[endLine]!,\n\t\t\treplacement: \"\",\n\t\t};\n\t}\n\n\treturn {\n\t\tkind: \"replace\",\n\t\tindex,\n\t\tlabel,\n\t\tstart: Math.max(0, lineStarts[startLine - 1]! - 1),\n\t\tend: lineStarts[endLine - 1]! + fileLines[endLine - 1]!.length,\n\t\treplacement: \"\",\n\t};\n}\n\nfunction assertNoConflict(spans: RESpan[]): void {\n\tif (spans.length < 2) return;\n\tconst ordered = [...spans].sort(\n\t\t(left, right) => left.start - right.start || right.end - left.end || left.index - right.index,\n\t);\n\tlet furthestEndSpan = ordered[0]!;\n\tfor (let index = 1; index < ordered.length; index++) {\n\t\tconst current = ordered[index]!;\n\t\tif (furthestEndSpan.start < current.end && current.start < furthestEndSpan.end) {\n\t\t\tconst [left, right] =\n\t\t\t\tfurthestEndSpan.index < current.index ? [furthestEndSpan, current] : [current, furthestEndSpan];\n\t\t\tthrowConflict(left, right, \"overlap on the same original line range\");\n\t\t}\n\t\tif (current.end > furthestEndSpan.end) furthestEndSpan = current;\n\t}\n}\n\nfunction resSpans(\n\tedits: RHEdit[],\n\tcontent: string,\n\tlineIndex: LIdx,\n\tnoopEdits: NEdit[],\n\tsignal: AbortSignal | undefined,\n): RESpan[] {\n\tconst seenSpanKeys = new Set<string>();\n\tconst resolvedSpans: RESpan[] = [];\n\tfor (const [index, edit] of edits.entries()) {\n\t\tabortIf(signal);\n\t\tconst span = resToSpan(edit, index, content, lineIndex, noopEdits);\n\t\tif (!span) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst spanKey = `replace:${span.start}:${span.end}:${span.replacement}`;\n\t\tif (seenSpanKeys.has(spanKey)) {\n\t\t\tcontinue;\n\t\t}\n\t\tseenSpanKeys.add(spanKey);\n\t\tresolvedSpans.push(span);\n\t}\n\n\tassertNoConflict(resolvedSpans);\n\treturn [...resolvedSpans].sort((left, right) => {\n\t\tif (right.end !== left.end) {\n\t\t\treturn right.end - left.end;\n\t\t}\n\t\treturn left.index - right.index;\n\t});\n}\n\nfunction assemble(content: string, spans: RESpan[], signal: AbortSignal | undefined): string {\n\tlet result = content;\n\tfor (const span of spans) {\n\t\tabortIf(signal);\n\t\tresult = result.slice(0, span.start) + span.replacement + result.slice(span.end);\n\t}\n\treturn result;\n}\n\n/**\n * Builds the boundary-duplication warning shown after an edit. A minimal header\n * is followed by a hashline-anchored window: 2 lines of context before the\n * duplicated pair, the pair itself, and 2 lines after. The window carries the\n * post-edit hashes the model needs to remove the duplicate in a follow-up\n * `replace` (no `read` round-trip required, since the hashes are current and\n * staleness is per-line). Rows are plain `HASH│content` — no annotations.\n */\nexport function fmtBoundaryWarning(params: BoundaryWarningFormatOptions): string {\n\tconst header =\n\t\tparams.kind === \"trailing\"\n\t\t\t? \"Boundary duplication (trailing): the last replacement line duplicated the next line. This happens when `content_lines` includes a line that was already outside the replaced range. Delete the duplicate — the original line outside the range is still there.\"\n\t\t\t: \"Boundary duplication (leading): the first replacement line duplicated the previous line. This happens when `content_lines` includes a line that was already outside the replaced range. Delete the duplicate — the original line outside the range is still there.\";\n\n\t// Locate the adjacent duplicated pair (two identical neighboring lines). The\n\t// occurrence-based matchIndex usually lands inside the pair; when a file has\n\t// several identical lines we pick the pair nearest matchIndex so the window\n\t// frames the duplication this edit introduced, not an unrelated one.\n\tlet pairStart = -1;\n\tlet bestDist = Infinity;\n\tfor (let i = 0; i < params.resultLines.length - 1; i++) {\n\t\tif (params.resultLines[i] === params.survivingContent && params.resultLines[i + 1] === params.survivingContent) {\n\t\t\tconst dist = Math.abs(i - params.matchIndex);\n\t\t\tif (dist < bestDist) {\n\t\t\t\tbestDist = dist;\n\t\t\t\tpairStart = i;\n\t\t\t}\n\t\t}\n\t}\n\tif (pairStart < 0) pairStart = params.matchIndex;\n\n\tconst winStart = Math.max(0, pairStart - 2);\n\tconst winEnd = Math.min(params.resultLines.length - 1, pairStart + 3);\n\n\tconst rows: string[] = [];\n\tfor (let i = winStart; i <= winEnd; i++) {\n\t\trows.push(`${params.resultHashes[i]}${HASH_SEP}${params.resultLines[i]}`);\n\t}\n\treturn `${header}\\n\\n${rows.join(\"\\n\")}`;\n}\n\nexport function applyEdits(\n\tcontent: string,\n\tedits: HEdit[],\n\tsignal?: AbortSignal,\n\tprecomputedHashes?: string[],\n\tfilePath?: string,\n): ApplyEditsResult {\n\tabortIf(signal);\n\tif (!edits.length)\n\t\treturn {\n\t\t\tcontent,\n\t\t\tfirstChangedLine: undefined,\n\t\t\tlastChangedLine: undefined,\n\t\t};\n\n\tedits = edits.map((edit) =>\n\t\tedit.content_lines.length === 1 && edit.content_lines[0] === \"\" ? { ...edit, content_lines: [] } : edit,\n\t);\n\n\tconst lineIndex = buildIdx(content);\n\tconst fileHashes = precomputedHashes ?? _lineHashesPure(content);\n\tconst noopEdits: NEdit[] = [];\n\tconst warnings: string[] = [];\n\n\tconst { resolved, mismatches, boundaryWarnings } = valEdits(\n\t\tedits,\n\t\tlineIndex.fileLines,\n\t\tfileHashes,\n\t\twarnings,\n\t\tsignal,\n\t);\n\tif (mismatches.length) {\n\t\tthrow new Error(fmtMismatch(mismatches, lineIndex.fileLines, fileHashes, filePath));\n\t}\n\n\tassertNoBarePrefix(edits, lineIndex.fileLines, fileHashes);\n\twarnUnicodeEsc(edits, warnings);\n\n\tconst orderedSpans = resSpans(resolved, content, lineIndex, noopEdits, signal);\n\n\tconst result = assemble(content, orderedSpans, signal);\n\tassertNotEmpty(content, result);\n\tconst range = changedRange(content, result);\n\n\treturn {\n\t\tcontent: result,\n\t\tfirstChangedLine: range?.firstChangedLine,\n\t\tlastChangedLine: range?.lastChangedLine,\n\t\t...(warnings.length ? { warnings } : {}),\n\t\t...(noopEdits.length ? { noopEdits } : {}),\n\t\t...(boundaryWarnings.length ? { boundaryWarnings } : {}),\n\t};\n}\n\nexport function fmtRegion(hashes: string[], lines: string[]): string {\n\tif (hashes.length !== lines.length) {\n\t\tthrow new Error(`fmtRegion: hashes.length (${hashes.length}) must match lines.length (${lines.length}).`);\n\t}\n\treturn lines.map((line, index) => `${hashes[index]}${HASH_SEP}${line}`).join(\"\\n\");\n}\nfunction characterIndexToLineNumber(characterIndex: number, text: string): number {\n\tlet line = 1;\n\tfor (let index = 0; index < characterIndex && index < text.length; index++) {\n\t\tif (text[index] === \"\\n\") line++;\n\t}\n\treturn line;\n}\ninterface ChangedRangeScan {\n\toriginal: string;\n\tresult: string;\n\tfirstDifferenceIndex: number;\n\tlastResultDifferenceIndex: number;\n\tfirstChangedLine: number;\n}\n\nfunction resolveLastChangedLine(scan: ChangedRangeScan): number {\n\tif (scan.lastResultDifferenceIndex < scan.firstDifferenceIndex) {\n\t\treturn scan.result.length === 0 ? 1 : cntLines(scan.result);\n\t}\n\tif (scan.firstDifferenceIndex === 0 && scan.original.length > 0 && scan.result.endsWith(scan.original)) {\n\t\treturn scan.firstChangedLine;\n\t}\n\treturn characterIndexToLineNumber(scan.lastResultDifferenceIndex + 1, scan.result);\n}\n\nexport function changedRange(original: string, result: string): ChangedLineRange | null {\n\tif (original === result) return null;\n\n\tif (original.length === 0) {\n\t\treturn {\n\t\t\tfirstChangedLine: 1,\n\t\t\tlastChangedLine: cntLines(result),\n\t\t};\n\t}\n\n\tif (result.startsWith(original) && original.endsWith(\"\\n\")) {\n\t\treturn {\n\t\t\tfirstChangedLine: cntLines(original) + 1,\n\t\t\tlastChangedLine: cntLines(result),\n\t\t};\n\t}\n\n\tlet firstDiff = 0;\n\tconst minLen = Math.min(original.length, result.length);\n\twhile (firstDiff < minLen && original[firstDiff] === result[firstDiff]) {\n\t\tfirstDiff++;\n\t}\n\tif (firstDiff === minLen && original.length === result.length) return null;\n\n\tlet lastOrig = original.length - 1;\n\tlet lastRes = result.length - 1;\n\twhile (lastOrig >= firstDiff && lastRes >= firstDiff && original[lastOrig] === result[lastRes]) {\n\t\tlastOrig--;\n\t\tlastRes--;\n\t}\n\n\tconst firstChangedLine = characterIndexToLineNumber(firstDiff + 1, result);\n\tconst lastChangedLine = resolveLastChangedLine({\n\t\toriginal,\n\t\tresult,\n\t\tfirstDifferenceIndex: firstDiff,\n\t\tlastResultDifferenceIndex: lastRes,\n\t\tfirstChangedLine,\n\t});\n\n\treturn { firstChangedLine, lastChangedLine };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/hashline/hash.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ,IAAI,CAAC;AAC1B,eAAO,MAAM,UAAU,IAAW,CAAC;AAEnC;;;;GAIG;AACH,eAAO,MAAM,QAAQ,WAAM,CAAC;AAM5B,QAAA,MAAM,OAAO,QAAkC,CAAC;AAChD,eAAO,MAAM,UAAU,QAAgC,CAAC;AAaxD,eAAO,MAAM,YAAY,QAAmD,CAAC;AAC7E,eAAO,MAAM,iBAAiB,QAAuC,CAAC;AACtE,eAAO,MAAM,aAAa,QAAkB,CAAC;AAE7C,eAAO,MAAM,iBAAiB,QAAsC,CAAC;AAErE,KAAK,MAAM,GAAG;IAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAmB5D,wBAAgB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAE5C;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBzD;AAED,UAAU,wBAAwB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,UAAU,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,MAAM,EAAE,CAAC,CA0BnB;AAkGD,OAAO,EAAE,OAAO,EAAE,CAAC"
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/hashline/hash.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ,IAAI,CAAC;AAC1B,eAAO,MAAM,UAAU,IAAW,CAAC;AAEnC;;;;GAIG;AACH,eAAO,MAAM,QAAQ,WAAM,CAAC;AAM5B,QAAA,MAAM,OAAO,QAAkC,CAAC;AAChD,eAAO,MAAM,UAAU,QAAgC,CAAC;AAaxD,eAAO,MAAM,YAAY,QAAmD,CAAC;AAC7E,eAAO,MAAM,iBAAiB,QAAuC,CAAC;AACtE,eAAO,MAAM,aAAa,QAAkB,CAAC;AAE7C,eAAO,MAAM,iBAAiB,QAAsC,CAAC;AAErE,KAAK,MAAM,GAAG;IAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAmB5D,wBAAgB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAE5C;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBzD;AAED,UAAU,wBAAwB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,UAAU,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,MAAM,EAAE,CAAC,CA0BnB;AAkGD,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../../../src/core/tools/hashline/hash.ts"],"names":[],"mappings":"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","sourcesContent":["import xxhash from \"xxhash-wasm\";\nimport { loadHashStore, saveHashStore } from \"../hash-store.ts\";\n\nexport const HASH_LEN = 3;\nexport const ANCHOR_LEN = HASH_LEN;\n\n/**\n * The `│` (U+2502) delimiter between a hash anchor and its line content. This\n * is the wire-format separator in `HASH│content` rows. Kept as a constant so\n * every construction site resolves the same delimiter.\n */\nexport const HASH_SEP = \"│\";\n\nconst ALPH = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\nconst ALPH_BITS = 6;\nconst ALPH_MASK = (1 << ALPH_BITS) - 1;\nconst ALPH_SAFE = ALPH.replace(/-/g, \"\\\\-\");\nconst ALPH_RE = new RegExp(`^[${ALPH_SAFE}]+$`);\nexport const HASH_CLASS = `[${ALPH_SAFE}]{${HASH_LEN}}`;\n\nfunction h2s(h: number): string {\n\tconst totalBits = HASH_LEN * ALPH_BITS;\n\tconst shift = 32 - totalBits;\n\tconst n = h >>> shift;\n\tlet out = \"\";\n\tfor (let j = 0; j < HASH_LEN; j++) {\n\t\tout += ALPH[(n >>> ((HASH_LEN - 1 - j) * ALPH_BITS)) & ALPH_MASK]!;\n\t}\n\treturn out;\n}\n\nexport const HL_PREFIX_RE = new RegExp(`^\\\\s*(?:>>>|>>)?\\\\s*${HASH_CLASS}│`);\nexport const HL_PREFIX_PLUS_RE = new RegExp(`^\\\\+\\\\s*${HASH_CLASS}│`);\nexport const DIFF_MINUS_RE = /^-\\s*\\d+\\s{4}/;\n\nexport const HL_BARE_PREFIX_RE = new RegExp(`^\\\\s*(${HASH_CLASS})│`);\n\ntype Hasher = { h32(input: string, seed?: number): number };\nlet hasherP: Promise<Hasher> | null = null;\nlet hasher: Hasher | null = null;\n\nfunction getH(): Hasher {\n\tif (hasher) return hasher;\n\tthrow new Error(\"xxhash-wasm not initialized yet. This should not happen.\");\n}\n\nhasherP = xxhash()\n\t.then((h) => {\n\t\thasher = h;\n\t\treturn h;\n\t})\n\t.catch((err) => {\n\t\tconsole.error(\"xxhash-wasm initialization failed:\", err);\n\t\tthrow err;\n\t});\n\nexport function initHasher(): Promise<Hasher> {\n\treturn hasherP!;\n}\n\nfunction xxh32(input: string, seed = 0): number {\n\treturn getH().h32(input, seed) >>> 0;\n}\n\nfunction canon(line: string): string {\n\treturn line.replace(/\\r/g, \"\").trimEnd();\n}\n\n/**\n * Pure hash computation — no I/O, no persistence. Used internally by the\n * stable path and as a fallback when no file path is available.\n * Each line is hashed with xxHash32 over its canonical form (trailing\n * whitespace and CR characters stripped). If the base hash collides with a\n * hash already assigned to an earlier line, a retry counter (`:R{retry}`)\n * is appended to the canonical content and the hash is recomputed until a\n * unique anchor is found. This perfect-hashing step guarantees every line\n * in a file receives a distinct anchor, even when multiple lines contain\n * identical text (e.g. repeated `}` or `import` statements).\n */\nexport function _lineHashesPure(content: string): string[] {\n\tconst lines = content.split(\"\\n\");\n\tconst hashes = new Array<string>(lines.length);\n\tconst assigned = new Set<string>();\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tconst c = canon(lines[i]!);\n\t\tlet hash = h2s(xxh32(c));\n\t\tlet retry = 0;\n\t\twhile (assigned.has(hash)) {\n\t\t\tretry++;\n\t\t\thash = h2s(xxh32(`${c}:R${retry}`));\n\t\t}\n\t\tassigned.add(hash);\n\t\thashes[i] = hash;\n\t}\n\treturn hashes;\n}\n\ninterface PreviousLineHashSnapshot {\n\tcontent: string;\n\thashes: string[];\n\tremovedHashes?: Set<string>;\n}\n\n/**\n * Stable, persistent-aware hash computation.\n *\n * When `path` is provided, uses the persistent hash store to preserve\n * hashes for unchanged lines across edits. When `previous` is also\n * provided (called from the replace pipeline), diffs the previous content\n * against the new content and copies hashes for unchanged lines to their\n * new positions. New/changed lines allocate fresh hashes with collision\n * avoidance against the preserved set.\n *\n * When `path` is provided without `previous` (called from read), loads\n * the stored snapshot for that path. If the content matches, returns the\n * saved hashes. Otherwise computes fresh hashes via `_lineHashesPure` and\n * saves a new snapshot.\n *\n * When `path` is not provided, falls back to `_lineHashesPure` (for\n * backward compatibility and tests that don't need persistence).\n */\nexport async function lineHashes(\n\tcontent: string,\n\tpath?: string,\n\tprevious?: PreviousLineHashSnapshot,\n): Promise<string[]> {\n\tif (!path) {\n\t\treturn _lineHashesPure(content);\n\t}\n\n\tconst store = await loadHashStore();\n\n\t// Case 1: previous content provided (replace pipeline) — diff and preserve\n\tif (previous) {\n\t\tconst newHashes = mapStableHashes(previous.content, previous.hashes, content, previous.removedHashes);\n\t\tstore.snapshots[path] = { content, hashes: newHashes };\n\t\tawait saveHashStore(store);\n\t\treturn newHashes;\n\t}\n\n\t// Case 2: no previous — check snapshot or compute fresh\n\tconst snapshot = store.snapshots[path];\n\tif (snapshot && snapshot.content === content) {\n\t\treturn snapshot.hashes;\n\t}\n\n\t// Compute fresh hashes\n\tconst newHashes = _lineHashesPure(content);\n\tstore.snapshots[path] = { content, hashes: newHashes };\n\tawait saveHashStore(store);\n\treturn newHashes;\n}\n\ninterface PreviousLineHashCandidate {\n\tindex: number;\n\thash: string;\n}\n\ninterface ReusedLineHashes {\n\thashes: string[];\n\tused: Set<string>;\n}\n\nfunction buildPreviousLineHashCandidates(\n\toldContent: string,\n\toldHashes: string[],\n): Map<string, PreviousLineHashCandidate[]> {\n\tconst candidatesByContent = new Map<string, PreviousLineHashCandidate[]>();\n\tconst oldLines = oldContent.split(\"\\n\");\n\tfor (let index = 0; index < oldLines.length; index++) {\n\t\tconst line = oldLines[index]!;\n\t\tconst candidate = { index, hash: oldHashes[index]! };\n\t\tconst candidates = candidatesByContent.get(line);\n\t\tif (candidates) candidates.push(candidate);\n\t\telse candidatesByContent.set(line, [candidate]);\n\t}\n\treturn candidatesByContent;\n}\n\nfunction takePreferredPreviousLineHash(\n\tcandidates: PreviousLineHashCandidate[],\n\tremovedHashes: Set<string> | undefined,\n): string {\n\tlet preferredIndex = 0;\n\tif (removedHashes && removedHashes.size > 0) {\n\t\tfor (let index = 0; index < candidates.length; index++) {\n\t\t\tif (!removedHashes.has(candidates[index]!.hash)) {\n\t\t\t\tpreferredIndex = index;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn candidates.splice(preferredIndex, 1)[0]!.hash;\n}\n\nfunction reusePreviousLineHashes(\n\tnewLines: string[],\n\tcandidatesByContent: Map<string, PreviousLineHashCandidate[]>,\n\tremovedHashes: Set<string> | undefined,\n): ReusedLineHashes {\n\tconst hashes = new Array<string>(newLines.length);\n\tconst used = new Set<string>();\n\tfor (let index = 0; index < newLines.length; index++) {\n\t\tconst candidates = candidatesByContent.get(newLines[index]!);\n\t\tif (!candidates || candidates.length === 0) continue;\n\t\tconst hash = takePreferredPreviousLineHash(candidates, removedHashes);\n\t\thashes[index] = hash;\n\t\tused.add(hash);\n\t}\n\treturn { hashes, used };\n}\n\nfunction fillFreshLineHashes(newLines: string[], hashes: string[], used: Set<string>): void {\n\tfor (let index = 0; index < newLines.length; index++) {\n\t\tif (hashes[index]) continue;\n\t\tconst canonicalLine = canon(newLines[index]!);\n\t\tlet retry = 0;\n\t\tlet hash = h2s(xxh32(canonicalLine));\n\t\twhile (used.has(hash)) {\n\t\t\tretry++;\n\t\t\thash = h2s(xxh32(`${canonicalLine}:R${retry}`));\n\t\t}\n\t\tused.add(hash);\n\t\thashes[index] = hash;\n\t}\n}\n\n/**\n * Maps old hashes to new positions using hash-aware content matching.\n * Unlike Diff.diffLines (which is content-only and cannot distinguish\n * identical lines at different positions), this algorithm uses the\n * removedHashes set to disambiguate: when a line appears multiple times\n * in the old content and one occurrence was targeted by the edit,\n * the surviving occurrence is matched to the non-removed hash.\n * New/changed lines allocate fresh hashes with collision avoidance.\n */\nfunction mapStableHashes(\n\toldContent: string,\n\toldHashes: string[],\n\tnewContent: string,\n\tremovedHashes?: Set<string>,\n): string[] {\n\tconst newLines = newContent.split(\"\\n\");\n\tconst candidatesByContent = buildPreviousLineHashCandidates(oldContent, oldHashes);\n\tconst { hashes, used } = reusePreviousLineHashes(newLines, candidatesByContent, removedHashes);\n\tfillFreshLineHashes(newLines, hashes, used);\n\treturn hashes;\n}\n\nexport { ALPH_RE };\n"]}
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../../../src/core/tools/hashline/hash.ts"],"names":[],"mappings":"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","sourcesContent":["import xxhash from \"xxhash-wasm\";\nimport { loadHashStore, saveHashStore } from \"../hash-store.ts\";\n\nexport const HASH_LEN = 3;\nexport const ANCHOR_LEN = HASH_LEN;\n\n/**\n * The `│` (U+2502) delimiter between a hash anchor and its line content. This\n * is the wire-format separator in `HASH│content` rows. Kept as a constant so\n * every construction site resolves the same delimiter.\n */\nexport const HASH_SEP = \"│\";\n\nconst ALPH = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\nconst ALPH_BITS = 6;\nconst ALPH_MASK = (1 << ALPH_BITS) - 1;\nconst ALPH_SAFE = ALPH.replace(/-/g, \"\\\\-\");\nconst ALPH_RE = new RegExp(`^[${ALPH_SAFE}]+$`);\nexport const HASH_CLASS = `[${ALPH_SAFE}]{${HASH_LEN}}`;\n\nfunction h2s(h: number): string {\n\tconst totalBits = HASH_LEN * ALPH_BITS;\n\tconst shift = 32 - totalBits;\n\tconst n = h >>> shift;\n\tlet out = \"\";\n\tfor (let j = 0; j < HASH_LEN; j++) {\n\t\tout += ALPH[(n >>> ((HASH_LEN - 1 - j) * ALPH_BITS)) & ALPH_MASK]!;\n\t}\n\treturn out;\n}\n\nexport const HL_PREFIX_RE = new RegExp(`^\\\\s*(?:>>>|>>)?\\\\s*${HASH_CLASS}│`);\nexport const HL_PREFIX_PLUS_RE = new RegExp(`^\\\\+\\\\s*${HASH_CLASS}│`);\nexport const DIFF_MINUS_RE = /^-\\s*\\d+\\s{4}/;\n\nexport const HL_BARE_PREFIX_RE = new RegExp(`^\\\\s*(${HASH_CLASS})│`);\n\ntype Hasher = { h32(input: string, seed?: number): number };\nlet hasherP: Promise<Hasher> | null = null;\nlet hasher: Hasher | null = null;\n\nfunction getH(): Hasher {\n\tif (hasher) return hasher;\n\tthrow new Error(\"xxhash-wasm not initialized yet. This should not happen.\");\n}\n\nhasherP = xxhash()\n\t.then((h) => {\n\t\thasher = h;\n\t\treturn h;\n\t})\n\t.catch((err) => {\n\t\tconsole.error(\"xxhash-wasm initialization failed:\", err);\n\t\tthrow err;\n\t});\n\nexport function initHasher(): Promise<Hasher> {\n\treturn hasherP!;\n}\n\nfunction xxh32(input: string, seed = 0): number {\n\treturn getH().h32(input, seed) >>> 0;\n}\n\nfunction canon(line: string): string {\n\treturn line.replace(/\\r/g, \"\").trimEnd();\n}\n\n/**\n * Pure hash computation — no I/O, no persistence. Used internally by the\n * stable path and as a fallback when no file path is available.\n * Each line is hashed with xxHash32 over its canonical form (trailing\n * whitespace and CR characters stripped). If the base hash collides with a\n * hash already assigned to an earlier line, a retry counter (`:R{retry}`)\n * is appended to the canonical content and the hash is recomputed until a\n * unique anchor is found. This perfect-hashing step guarantees every line\n * in a file receives a distinct anchor, even when multiple lines contain\n * identical text (e.g. repeated `}` or `import` statements).\n */\nexport function _lineHashesPure(content: string): string[] {\n\tconst lines = content.split(\"\\n\");\n\tconst hashes = new Array<string>(lines.length);\n\tconst assigned = new Set<string>();\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tconst c = canon(lines[i]!);\n\t\tlet hash = h2s(xxh32(c));\n\t\tlet retry = 0;\n\t\twhile (assigned.has(hash)) {\n\t\t\tretry++;\n\t\t\thash = h2s(xxh32(`${c}:R${retry}`));\n\t\t}\n\t\tassigned.add(hash);\n\t\thashes[i] = hash;\n\t}\n\treturn hashes;\n}\n\ninterface PreviousLineHashSnapshot {\n\tcontent: string;\n\thashes: string[];\n\tremovedHashes?: Set<string>;\n}\n\n/**\n * Stable, persistent-aware hash computation.\n *\n * When `path` is provided, uses the persistent hash store to preserve\n * hashes for unchanged lines across edits. When `previous` is also\n * provided (called from the replace pipeline), diffs the previous content\n * against the new content and copies hashes for unchanged lines to their\n * new positions. New/changed lines allocate fresh hashes with collision\n * avoidance against the preserved set.\n *\n * When `path` is provided without `previous` (called from read), loads\n * the stored snapshot for that path. If the content matches, returns the\n * saved hashes. Otherwise computes fresh hashes via `_lineHashesPure` and\n * saves a new snapshot.\n *\n * When `path` is not provided, falls back to `_lineHashesPure` (for\n * backward compatibility and tests that don't need persistence).\n */\nexport async function lineHashes(\n\tcontent: string,\n\tpath?: string,\n\tprevious?: PreviousLineHashSnapshot,\n): Promise<string[]> {\n\tif (!path) {\n\t\treturn _lineHashesPure(content);\n\t}\n\n\tconst store = await loadHashStore();\n\n\t// Case 1: previous content provided (replace pipeline) — diff and preserve\n\tif (previous) {\n\t\tconst newHashes = mapStableHashes(previous.content, previous.hashes, content, previous.removedHashes);\n\t\tstore.snapshots[path] = { content, hashes: newHashes };\n\t\tawait saveHashStore(store);\n\t\treturn newHashes;\n\t}\n\n\t// Case 2: no previous — check snapshot or compute fresh\n\tconst snapshot = store.snapshots[path];\n\tif (snapshot && snapshot.content === content) {\n\t\treturn snapshot.hashes;\n\t}\n\n\t// Compute fresh hashes\n\tconst newHashes = _lineHashesPure(content);\n\tstore.snapshots[path] = { content, hashes: newHashes };\n\tawait saveHashStore(store);\n\treturn newHashes;\n}\n\ninterface PreviousLineHashCandidate {\n\tindex: number;\n\thash: string;\n}\n\ninterface ReusedLineHashes {\n\thashes: string[];\n\tused: Set<string>;\n}\n\nfunction buildPreviousLineHashCandidates(\n\toldContent: string,\n\toldHashes: string[],\n): Map<string, PreviousLineHashCandidate[]> {\n\tconst candidatesByContent = new Map<string, PreviousLineHashCandidate[]>();\n\tconst oldLines = oldContent.split(\"\\n\");\n\tfor (let index = 0; index < oldLines.length; index++) {\n\t\tconst line = oldLines[index]!;\n\t\tconst candidate = { index, hash: oldHashes[index]! };\n\t\tconst candidates = candidatesByContent.get(line);\n\t\tif (candidates) candidates.push(candidate);\n\t\telse candidatesByContent.set(line, [candidate]);\n\t}\n\treturn candidatesByContent;\n}\n\nfunction takePreferredPreviousLineHash(\n\tcandidates: PreviousLineHashCandidate[],\n\tremovedHashes: Set<string> | undefined,\n): string {\n\tlet preferredIndex = 0;\n\tif (removedHashes && removedHashes.size > 0) {\n\t\tfor (let index = 0; index < candidates.length; index++) {\n\t\t\tif (!removedHashes.has(candidates[index]!.hash)) {\n\t\t\t\tpreferredIndex = index;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn candidates.splice(preferredIndex, 1)[0]!.hash;\n}\n\nfunction reusePreviousLineHashes(\n\tnewLines: string[],\n\tcandidatesByContent: Map<string, PreviousLineHashCandidate[]>,\n\tremovedHashes: Set<string> | undefined,\n): ReusedLineHashes {\n\tconst hashes = new Array<string>(newLines.length);\n\tconst used = new Set<string>();\n\tfor (let index = 0; index < newLines.length; index++) {\n\t\tconst candidates = candidatesByContent.get(newLines[index]!);\n\t\tif (!candidates || candidates.length === 0) continue;\n\t\tconst hash = takePreferredPreviousLineHash(candidates, removedHashes);\n\t\thashes[index] = hash;\n\t\tused.add(hash);\n\t}\n\treturn { hashes, used };\n}\n\nfunction fillFreshLineHashes(newLines: string[], hashes: string[], used: Set<string>): void {\n\tfor (let index = 0; index < newLines.length; index++) {\n\t\tif (hashes[index]) continue;\n\t\tconst canonicalLine = canon(newLines[index]!);\n\t\tlet retry = 0;\n\t\tlet hash = h2s(xxh32(canonicalLine));\n\t\twhile (used.has(hash)) {\n\t\t\tretry++;\n\t\t\thash = h2s(xxh32(`${canonicalLine}:R${retry}`));\n\t\t}\n\t\tused.add(hash);\n\t\thashes[index] = hash;\n\t}\n}\n\n/**\n * Maps old hashes to new positions using hash-aware content matching.\n * Unlike Diff.diffLines (which is content-only and cannot distinguish\n * identical lines at different positions), this algorithm uses the\n * removedHashes set to disambiguate: when a line appears multiple times\n * in the old content and one occurrence was targeted by the edit,\n * the surviving occurrence is matched to the non-removed hash.\n * New/changed lines allocate fresh hashes with collision avoidance.\n */\nfunction mapStableHashes(\n\toldContent: string,\n\toldHashes: string[],\n\tnewContent: string,\n\tremovedHashes?: Set<string>,\n): string[] {\n\tconst newLines = newContent.split(\"\\n\");\n\tconst candidatesByContent = buildPreviousLineHashCandidates(oldContent, oldHashes);\n\tconst { hashes, used } = reusePreviousLineHashes(newLines, candidatesByContent, removedHashes);\n\tfillFreshLineHashes(newLines, hashes, used);\n\treturn hashes;\n}\n\nexport { ALPH_RE };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/hashline/parse.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBtC,iBAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQrC;AAED,eAAO,MAAM,YAAY,iBAAW,CAAC;AAarC,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAQlE"
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/hashline/parse.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBtC,iBAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQrC;AAED,eAAO,MAAM,YAAY,iBAAW,CAAC;AAarC,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAQlE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../src/core/tools/hashline/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAIlF,SAAS,OAAO,CAAC,GAAW
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../src/core/tools/hashline/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAIlF,SAAS,OAAO,CAAC,GAAW;IAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAE3B,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACrB,OAAO,2EAA2E,CAAC;IACpF,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1B,OAAO,oGAAoG,CAAC;IAC7G,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,+BAA+B,OAAO,gGAAgG,CAAC;IAC/I,CAAC;IAED,OAAO,+BAA+B,OAAO,kDAAkD,CAAC;AACjG,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC5B,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAE3B,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC;AAErC,SAAS,gBAAgB,CAAC,KAAe;IACxC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,SAAS;QAC3B,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9D,MAAM,IAAI,KAAK,CACd,iIAAiI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,6EAA6E,CAClO,CAAC;QACH,CAAC;IACF,CAAC;AACF,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAA8B;IACvD,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAC7B,MAAM,KAAK,GACV,OAAO,IAAI,KAAK,QAAQ;QACvB,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QACnF,CAAC,CAAC,IAAI,CAAC;IACT,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,KAAK,CAAC;AACd,CAAC","sourcesContent":["import { ALPH_RE, ANCHOR_LEN, DIFF_MINUS_RE, HL_PREFIX_PLUS_RE } from \"./hash.ts\";\n\nexport type Anchor = { hash: string };\n\nfunction diagRef(ref: string): string {\n\tconst trimmed = ref.trim();\n\n\tif (!trimmed.length) {\n\t\treturn `[E_BAD_REF] Invalid anchor. Expected a 3-char base64 anchor (e.g. \"aB3\").`;\n\t}\n\n\tif (/^\\d+/.test(trimmed)) {\n\t\treturn `[E_BAD_REF] Invalid anchor. Use the hash alone (e.g. \"aB3\") — no line numbers or trailing content.`;\n\t}\n\n\tif (trimmed.includes(\"│\")) {\n\t\treturn `[E_BAD_REF] Invalid anchor \"${trimmed}\". hash_range_inclusive must contain the 3-char hash only — remove everything from \"│\" onward.`;\n\t}\n\n\treturn `[E_BAD_REF] Invalid anchor \"${trimmed}\". Expected a 3-char base64 anchor (e.g. \"aB3\").`;\n}\n\nfunction parseRef(ref: string): Anchor {\n\tconst trimmed = ref.trim();\n\n\tif (trimmed.length === ANCHOR_LEN && ALPH_RE.test(trimmed)) {\n\t\treturn { hash: trimmed };\n\t}\n\n\tthrow new Error(diagRef(ref));\n}\n\nexport const parseHashRef = parseRef;\n\nfunction assertNoPrefixes(lines: string[]): void {\n\tfor (const line of lines) {\n\t\tif (!line.length) continue;\n\t\tif (HL_PREFIX_PLUS_RE.test(line) || DIFF_MINUS_RE.test(line)) {\n\t\t\tthrow new Error(\n\t\t\t\t`[E_INVALID_PATCH] \"content_lines\" must contain literal file content. Offending line looks like the diff preview's +HASH│ row: ${JSON.stringify(line)}. Use literal file content only — plain + or - lines are written literally.`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nexport function parseText(edit: string[] | string | null): string[] {\n\tif (edit === null) return [];\n\tconst lines =\n\t\ttypeof edit === \"string\"\n\t\t\t? (edit.endsWith(\"\\n\") ? edit.slice(0, -1) : edit).replaceAll(\"\\r\", \"\").split(\"\\n\")\n\t\t\t: edit;\n\tassertNoPrefixes(lines);\n\treturn lines;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/hashline/resolve.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,MAAM,EAA2B,MAAM,YAAY,CAAC;AAElE,MAAM,MAAM,OAAO,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAAE,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AACxF,MAAM,MAAM,MAAM,GAAG;IACpB,oBAAoB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzC,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF,KAAK,sBAAsB,GAAG,WAAW,GAAG,WAAW,CAAC;AACxD,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,SAAS,CAAC;AAE3D,UAAU,SAAS;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,sBAAsB,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,qBAAqB,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;CAClB;AACD,UAAU,oBAAoB;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,gBAAgB,EAAE,QAAQ,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,KAAK;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,MAAM,GAAG;IACpB,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AA8DF,wBAAgB,WAAW,CAC1B,UAAU,EAAE,SAAS,EAAE,EACvB,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,CAAC,EAAE,MAAM,GACf,MAAM,CAQR;AAmCD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,CAYjD;AAED,iBAAS,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAQhE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,CA2BnG;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AA2BD,wBAAgB,QAAQ,CACvB,KAAK,EAAE,KAAK,EAAE,EACd,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,MAAM,EAAE,EACpB,SAAS,EAAE,MAAM,EAAE,EACnB,MAAM,EAAE,WAAW,GAAG,SAAS,GAC7B,oBAAoB,CAkDtB;AAED,OAAO,EAAE,cAAc,EAAE,CAAC","sourcesContent":["import { rejectUnknownFields } from \"../hashline-utils.ts\";\nimport { abortIf } from \"../runtime.ts\";\nimport { HL_BARE_PREFIX_RE } from \"./hash.ts\";\nimport { type Anchor, parseHashRef, parseText } from \"./parse.ts\";\n\nexport type RAnchor = {\n\tline: number;\n\thash: string;\n\thashMatched: boolean;\n};\n\nexport type HEdit = { hash_range_inclusive: [Anchor, Anchor]; content_lines: string[] };\nexport type RHEdit = {\n\thash_range_inclusive: [RAnchor, RAnchor];\n\tcontent_lines: string[];\n};\n\ntype HashAnchorMismatchKind = \"not_found\" | \"ambiguous\";\nexport type BoundaryDuplicateKind = \"trailing\" | \"leading\";\n\ninterface HMismatch {\n\tref: Anchor;\n\tkind: HashAnchorMismatchKind;\n\tcandidates?: number[];\n}\n\nexport interface BDupWarn {\n\tkind: BoundaryDuplicateKind;\n\tsurvivingLineContent: string;\n\tsurvivingLineIndex: number;\n\toccurrence: number;\n\treplacementLineContent: string;\n\teditIndex: number;\n}\ninterface EditValidationResult {\n\tresolved: RHEdit[];\n\tmismatches: HMismatch[];\n\tboundaryWarnings: BDupWarn[];\n}\n\nexport interface NEdit {\n\teditIndex: number;\n\tloc: string;\n\tcurrentContent: string;\n}\n\nexport type HTEdit = {\n\thash_range_inclusive: [string, string];\n\tcontent_lines: string[];\n};\n\nfunction resAnchor(ref: Anchor, _fileLines: string[], fileHashes: string[]): RAnchor | HMismatch {\n\tconst hashMatches: number[] = [];\n\tfor (let i = 0; i < fileHashes.length; i++) {\n\t\tif (fileHashes[i] === ref.hash) hashMatches.push(i + 1);\n\t}\n\tif (hashMatches.length === 0) {\n\t\treturn { ref, kind: \"not_found\" };\n\t}\n\tif (hashMatches.length === 1) {\n\t\treturn {\n\t\t\tline: hashMatches[0]!,\n\t\t\thash: ref.hash,\n\t\t\thashMatched: true,\n\t\t};\n\t}\n\treturn { ref, kind: \"ambiguous\", candidates: hashMatches };\n}\n\nfunction assertAligned(fileLines: string[], fileHashes: string[], ctx: string): void {\n\tif (fileHashes.length !== fileLines.length) {\n\t\tthrow new Error(\n\t\t\t`${ctx}: fileHashes.length (${fileHashes.length}) must match fileLines.length (${fileLines.length}).`,\n\t\t);\n\t}\n}\n\nfunction formatNotFoundMismatches(mismatches: HMismatch[], filePath: string | undefined): string | undefined {\n\tconst notFound = mismatches.filter((mismatch) => mismatch.kind === \"not_found\");\n\tif (notFound.length === 0) return undefined;\n\tconst references = notFound.map((mismatch) => `\"${mismatch.ref.hash}\"`).join(\", \");\n\treturn `[E_STALE_ANCHOR] ${notFound.length} stale anchor${notFound.length > 1 ? \"s\" : \"\"}${filePath ? ` in ${filePath}` : \"\"}: ${references}. Call read() to get fresh anchors, then copy the 3-char HASH of the start and end of the range you are replacing into hash_range_inclusive of your next replace call.`;\n}\n\nfunction formatAmbiguousMismatchDetail(mismatch: HMismatch, fileLines: string[], fileHashes: string[]): string {\n\tconst sample = (mismatch.candidates ?? []).slice(0, 5);\n\tconst candidateCount = mismatch.candidates?.length ?? 0;\n\tconst more = candidateCount > sample.length ? `, ... (+${candidateCount - sample.length} more)` : \"\";\n\tconst lines = sample\n\t\t.map((line) => {\n\t\t\tconst content = fileLines[line - 1] ?? \"\";\n\t\t\treturn ` ${line}: ${fileHashes[line - 1]}│${content}`;\n\t\t})\n\t\t.join(\"\\n\");\n\treturn ` Hash \"${mismatch.ref.hash}\" matches lines ${sample.join(\", \")}${more}.\\n${lines}`;\n}\n\nfunction formatAmbiguousMismatches(\n\tmismatches: HMismatch[],\n\tfileLines: string[],\n\tfileHashes: string[],\n\tfilePath: string | undefined,\n): string | undefined {\n\tconst ambiguous = mismatches.filter((mismatch) => mismatch.kind === \"ambiguous\");\n\tif (ambiguous.length === 0) return undefined;\n\tconst header = `[E_AMBIGUOUS_ANCHOR] ${ambiguous.length} ambiguous anchor${ambiguous.length > 1 ? \"s\" : \"\"}${filePath ? ` in ${filePath}` : \"\"}. Call read() to get fresh anchors, then copy the 3-char HASH of the start and end of the range you are replacing into hash_range_inclusive of your next replace call.`;\n\treturn [header, ...ambiguous.map((mismatch) => formatAmbiguousMismatchDetail(mismatch, fileLines, fileHashes))].join(\n\t\t\"\\n\",\n\t);\n}\n\nexport function fmtMismatch(\n\tmismatches: HMismatch[],\n\tfileLines: string[],\n\tfileHashes: string[],\n\tfilePath?: string,\n): string {\n\tassertAligned(fileLines, fileHashes, \"fmtMismatch\");\n\treturn [\n\t\tformatNotFoundMismatches(mismatches, filePath),\n\t\tformatAmbiguousMismatches(mismatches, fileLines, fileHashes, filePath),\n\t]\n\t\t.filter((section): section is string => section !== undefined)\n\t\t.join(\"\\n\\n\");\n}\n\nconst ITEM_KS = new Set([\"hash_range_inclusive\", \"content_lines\"]);\n\nfunction isStrArr(value: unknown): value is string[] {\n\treturn Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction isStrPair(value: unknown): value is [string, string] {\n\treturn Array.isArray(value) && value.length === 2 && value.every((item) => typeof item === \"string\");\n}\n\nfunction assertItem(edit: Record<string, unknown>, index: number): void {\n\trejectUnknownFields(edit, ITEM_KS, `Edit ${index}`, \"Each edit takes only { hash_range_inclusive, content_lines }.\");\n\n\tif (\"hash_range_inclusive\" in edit && !isStrPair(edit.hash_range_inclusive)) {\n\t\tthrow new Error(\n\t\t\t`[E_BAD_SHAPE] Edit ${index} field \"hash_range_inclusive\" must be a pair of anchor strings [start, end].`,\n\t\t);\n\t}\n\tif (!(\"content_lines\" in edit)) {\n\t\tthrow new Error(\n\t\t\t`[E_BAD_SHAPE] Edit ${index} requires a \"content_lines\" field. Provide the replacement lines (use [] to delete).`,\n\t\t);\n\t}\n\tif (\"content_lines\" in edit && !isStrArr(edit.content_lines)) {\n\t\tthrow new Error(`[E_BAD_SHAPE] Edit ${index} field \"content_lines\" must be a string array.`);\n\t}\n\tif (!isStrPair(edit.hash_range_inclusive)) {\n\t\tthrow new Error(\n\t\t\t`[E_BAD_SHAPE] Edit ${index} requires an \"hash_range_inclusive\" pair of anchor strings [start, end].`,\n\t\t);\n\t}\n}\n\nexport function resEdits(edits: HTEdit[]): HEdit[] {\n\tconst result: HEdit[] = [];\n\tfor (const [index, edit] of edits.entries()) {\n\t\tassertItem(edit as Record<string, unknown>, index);\n\n\t\tconst replaceLines = parseText(edit.content_lines);\n\t\tresult.push({\n\t\t\thash_range_inclusive: [parseHashRef(edit.hash_range_inclusive[0]), parseHashRef(edit.hash_range_inclusive[1])],\n\t\t\tcontent_lines: replaceLines,\n\t\t});\n\t}\n\treturn result;\n}\n\nfunction warnUnicodeEsc(edits: HEdit[], warnings: string[]): void {\n\tfor (const edit of edits) {\n\t\tif (edit.content_lines.some((line) => /\\\\uDDDD/i.test(line))) {\n\t\t\twarnings.push(\n\t\t\t\t\"Detected literal \\\\uDDDD in edit content; no autocorrection applied. Verify whether this should be a real Unicode escape or plain text.\",\n\t\t\t);\n\t\t}\n\t}\n}\n\nexport function assertNoBarePrefix(edits: HEdit[], _fileLines: string[], fileHashes: string[]): void {\n\tconst suspects: { line: string; hash: string; editIndex: number; lineIndex: number }[] = [];\n\tfor (let editIndex = 0; editIndex < edits.length; editIndex++) {\n\t\tconst edit = edits[editIndex]!;\n\t\tfor (let lineIndex = 0; lineIndex < edit.content_lines.length; lineIndex++) {\n\t\t\tconst line = edit.content_lines[lineIndex]!;\n\t\t\tconst match = line.match(HL_BARE_PREFIX_RE);\n\t\t\tif (match) suspects.push({ line, hash: match[1]!, editIndex, lineIndex });\n\t\t}\n\t}\n\tif (suspects.length === 0) return;\n\tconst locations = suspects.map((s) => `edit ${s.editIndex}, content_lines[${s.lineIndex}]`).join(\"; \");\n\n\tconst fileHashSet = new Set(fileHashes);\n\tconst matched = suspects.filter((s) => fileHashSet.has(s.hash));\n\tconst matchedCount = matched.length;\n\n\tconst exampleLine = `${suspects[0]!.hash}│${suspects[0]!.line}`;\n\n\tconst linesHint =\n\t\tmatchedCount === 0\n\t\t\t? `None match file line hashes.`\n\t\t\t: `${matchedCount} match file line hashes — strong evidence the prefix was copied from read output.`;\n\n\tthrow new Error(\n\t\t`[E_BARE_HASH_PREFIX] ${suspects.length} edit line(s) start with a hash-like prefix (${locations}). Example: ${JSON.stringify(exampleLine)}. ${linesHint} Remove the \"HASH│\" prefix from each affected content_lines entry; keep only the literal line content that appears after \"│\" in read output. Remember: hash_range_inclusive uses hash anchors, content_lines uses file content only.`,\n\t);\n}\n\nexport function descEdit(edit: RHEdit): string {\n\treturn `replace ${edit.hash_range_inclusive[0].hash}-${edit.hash_range_inclusive[1].hash}`;\n}\n\nfunction checkBoundaryDup(\n\tadjacentLine: string | undefined,\n\treplacementEdge: string | undefined,\n\tkind: BoundaryDuplicateKind,\n\tsurvivingLineIndex: number,\n\tfileLines: string[],\n\teditIndex: number,\n): BDupWarn | null {\n\tif (\n\t\tadjacentLine === undefined ||\n\t\treplacementEdge === undefined ||\n\t\treplacementEdge.length === 0 ||\n\t\treplacementEdge !== adjacentLine\n\t)\n\t\treturn null;\n\treturn {\n\t\tkind,\n\t\tsurvivingLineContent: adjacentLine,\n\t\tsurvivingLineIndex,\n\t\toccurrence: fileLines.slice(0, survivingLineIndex).filter((l) => l === adjacentLine).length,\n\t\treplacementLineContent: replacementEdge,\n\t\teditIndex,\n\t};\n}\n\nexport function valEdits(\n\tedits: HEdit[],\n\tfileLines: string[],\n\tfileHashes: string[],\n\t_warnings: string[],\n\tsignal: AbortSignal | undefined,\n): EditValidationResult {\n\tassertAligned(fileLines, fileHashes, \"valEdits\");\n\tconst resolved: RHEdit[] = [];\n\tconst mismatches: HMismatch[] = [];\n\tconst boundaryWarnings: BDupWarn[] = [];\n\n\tconst tryResolve = (ref: Anchor): RAnchor | undefined => {\n\t\tconst result = resAnchor(ref, fileLines, fileHashes);\n\t\tif (\"kind\" in result) {\n\t\t\tmismatches.push(result);\n\t\t\treturn undefined;\n\t\t}\n\t\treturn result;\n\t};\n\n\tfor (const edit of edits) {\n\t\tabortIf(signal);\n\t\tconst startResolved = tryResolve(edit.hash_range_inclusive[0]);\n\t\tconst endResolved = tryResolve(edit.hash_range_inclusive[1]);\n\t\tif (!startResolved || !endResolved) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (startResolved.line > endResolved.line) {\n\t\t\tthrow new Error(\n\t\t\t\t`[E_BAD_OP] Range start line ${startResolved.line} must be <= end line ${endResolved.line} (anchors ${edit.hash_range_inclusive[0].hash} and ${edit.hash_range_inclusive[1].hash}).`,\n\t\t\t);\n\t\t}\n\t\tconst endLine = endResolved.line;\n\t\tconst nextLine = fileLines[endLine];\n\t\tconst replacementLastLine = edit.content_lines.at(-1);\n\t\tconst trailing = checkBoundaryDup(nextLine, replacementLastLine, \"trailing\", endLine, fileLines, resolved.length);\n\t\tif (trailing) boundaryWarnings.push(trailing);\n\t\tconst prevLine = fileLines[startResolved.line - 2];\n\t\tconst replacementFirstLine = edit.content_lines[0];\n\t\tconst leading = checkBoundaryDup(\n\t\t\tprevLine,\n\t\t\treplacementFirstLine,\n\t\t\t\"leading\",\n\t\t\tstartResolved.line - 2,\n\t\t\tfileLines,\n\t\t\tresolved.length,\n\t\t);\n\t\tif (leading) boundaryWarnings.push(leading);\n\t\tresolved.push({\n\t\t\thash_range_inclusive: [startResolved, endResolved],\n\t\t\tcontent_lines: edit.content_lines,\n\t\t});\n\t}\n\n\treturn { resolved, mismatches, boundaryWarnings };\n}\n\nexport { warnUnicodeEsc };\n"]}
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/hashline/resolve.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,MAAM,EAA2B,MAAM,YAAY,CAAC;AAElE,MAAM,MAAM,OAAO,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAAE,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AACxF,MAAM,MAAM,MAAM,GAAG;IACpB,oBAAoB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzC,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF,KAAK,sBAAsB,GAAG,WAAW,GAAG,WAAW,CAAC;AACxD,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,SAAS,CAAC;AAE3D,UAAU,SAAS;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,sBAAsB,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,qBAAqB,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;CAClB;AACD,UAAU,oBAAoB;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,gBAAgB,EAAE,QAAQ,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,KAAK;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,MAAM,GAAG;IACpB,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AA8DF,wBAAgB,WAAW,CAC1B,UAAU,EAAE,SAAS,EAAE,EACvB,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,CAAC,EAAE,MAAM,GACf,MAAM,CAQR;AAmCD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,CAYjD;AAED,iBAAS,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAQhE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,CA2BnG;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AA2BD,wBAAgB,QAAQ,CACvB,KAAK,EAAE,KAAK,EAAE,EACd,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,MAAM,EAAE,EACpB,SAAS,EAAE,MAAM,EAAE,EACnB,MAAM,EAAE,WAAW,GAAG,SAAS,GAC7B,oBAAoB,CAkDtB;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
|