@machina.ai/cell-cli-core 1.20.2-rc1 → 1.25.0-rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/AFTER_MERGE_PROMPT.md +26 -0
- package/dist/docs/CHANGES.md +124 -0
- package/dist/docs/api-proxy.md +27 -0
- package/dist/docs/architecture.md +80 -0
- package/dist/docs/assets/connected_devtools.png +0 -0
- package/dist/docs/assets/gemini-screenshot.png +0 -0
- package/dist/docs/assets/monitoring-dashboard-logs.png +0 -0
- package/dist/docs/assets/monitoring-dashboard-metrics.png +0 -0
- package/dist/docs/assets/monitoring-dashboard-overview.png +0 -0
- package/dist/docs/assets/release_patch.png +0 -0
- package/dist/docs/assets/theme-ansi-light.png +0 -0
- package/dist/docs/assets/theme-ansi.png +0 -0
- package/dist/docs/assets/theme-atom-one.png +0 -0
- package/dist/docs/assets/theme-ayu-light.png +0 -0
- package/dist/docs/assets/theme-ayu.png +0 -0
- package/dist/docs/assets/theme-custom.png +0 -0
- package/dist/docs/assets/theme-default-light.png +0 -0
- package/dist/docs/assets/theme-default.png +0 -0
- package/dist/docs/assets/theme-dracula.png +0 -0
- package/dist/docs/assets/theme-github-light.png +0 -0
- package/dist/docs/assets/theme-github.png +0 -0
- package/dist/docs/assets/theme-google-light.png +0 -0
- package/dist/docs/assets/theme-xcode-light.png +0 -0
- package/dist/docs/changelogs/index.md +612 -0
- package/dist/docs/changelogs/latest.md +153 -0
- package/dist/docs/changelogs/preview.md +131 -0
- package/dist/docs/changelogs/releases.md +1162 -0
- package/dist/docs/cli/authentication.md +3 -0
- package/dist/docs/cli/checkpointing.md +94 -0
- package/dist/docs/cli/commands.md +357 -0
- package/dist/docs/cli/custom-commands.md +315 -0
- package/dist/docs/cli/enterprise.md +564 -0
- package/dist/docs/cli/gemini-ignore.md +71 -0
- package/dist/docs/cli/gemini-md.md +109 -0
- package/dist/docs/cli/generation-settings.md +210 -0
- package/dist/docs/cli/headless.md +388 -0
- package/dist/docs/cli/index.md +63 -0
- package/dist/docs/cli/keyboard-shortcuts.md +136 -0
- package/dist/docs/cli/model-routing.md +37 -0
- package/dist/docs/cli/model.md +62 -0
- package/dist/docs/cli/sandbox.md +171 -0
- package/dist/docs/cli/session-management.md +158 -0
- package/dist/docs/cli/settings.md +148 -0
- package/dist/docs/cli/skills.md +188 -0
- package/dist/docs/cli/system-prompt.md +94 -0
- package/dist/docs/cli/telemetry.md +813 -0
- package/dist/docs/cli/themes.md +237 -0
- package/dist/docs/cli/token-caching.md +20 -0
- package/dist/docs/cli/trusted-folders.md +95 -0
- package/dist/docs/cli/tutorials/skills-getting-started.md +124 -0
- package/dist/docs/cli/tutorials.md +87 -0
- package/dist/docs/cli/uninstall.md +47 -0
- package/dist/docs/core/index.md +101 -0
- package/dist/docs/core/memport.md +246 -0
- package/dist/docs/core/policy-engine.md +268 -0
- package/dist/docs/core/tools-api.md +131 -0
- package/dist/docs/examples/proxy-script.md +83 -0
- package/dist/docs/extensions/extension-releasing.md +183 -0
- package/dist/docs/extensions/getting-started-extensions.md +244 -0
- package/dist/docs/extensions/index.md +343 -0
- package/dist/docs/faq.md +153 -0
- package/dist/docs/get-started/authentication.md +321 -0
- package/dist/docs/get-started/configuration-v1.md +890 -0
- package/dist/docs/get-started/configuration.md +1643 -0
- package/dist/docs/get-started/examples.md +218 -0
- package/dist/docs/get-started/gemini-3.md +101 -0
- package/dist/docs/get-started/index.md +71 -0
- package/dist/docs/get-started/installation.md +141 -0
- package/dist/docs/hooks/best-practices.md +856 -0
- package/dist/docs/hooks/index.md +723 -0
- package/dist/docs/hooks/reference.md +178 -0
- package/dist/docs/hooks/writing-hooks.md +1044 -0
- package/dist/docs/ide-integration/ide-companion-spec.md +267 -0
- package/dist/docs/ide-integration/index.md +201 -0
- package/dist/docs/index.md +147 -0
- package/dist/docs/integration-tests.md +211 -0
- package/dist/docs/issue-and-pr-automation.md +134 -0
- package/dist/docs/local-development.md +128 -0
- package/dist/docs/mcp_integration.md +160 -0
- package/dist/docs/mermaid/context.mmd +103 -0
- package/dist/docs/mermaid/render-path.mmd +64 -0
- package/dist/docs/npm.md +62 -0
- package/dist/docs/quota-and-pricing.md +158 -0
- package/dist/docs/release-confidence.md +164 -0
- package/dist/docs/releases.md +540 -0
- package/dist/docs/sidebar.json +301 -0
- package/dist/docs/tools/file-system.md +217 -0
- package/dist/docs/tools/index.md +95 -0
- package/dist/docs/tools/mcp-server.md +1045 -0
- package/dist/docs/tools/memory.md +54 -0
- package/dist/docs/tools/shell.md +260 -0
- package/dist/docs/tools/todos.md +56 -0
- package/dist/docs/tools/web-fetch.md +59 -0
- package/dist/docs/tools/web-search.md +42 -0
- package/dist/docs/tos-privacy.md +96 -0
- package/dist/docs/troubleshooting.md +162 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/package.json +7 -4
- package/dist/src/agents/a2a-client-manager.d.ts +82 -0
- package/dist/src/agents/a2a-client-manager.js +295 -0
- package/dist/src/agents/a2a-client-manager.js.map +1 -0
- package/dist/src/agents/a2a-client-manager.test.js +281 -0
- package/dist/src/agents/a2a-client-manager.test.js.map +1 -0
- package/dist/src/agents/a2aUtils.d.ts +29 -0
- package/dist/src/agents/a2aUtils.js +113 -0
- package/dist/src/agents/a2aUtils.js.map +1 -0
- package/dist/src/agents/a2aUtils.test.js +147 -0
- package/dist/src/agents/a2aUtils.test.js.map +1 -0
- package/dist/src/agents/agentLoader.d.ts +68 -0
- package/dist/src/agents/agentLoader.js +255 -0
- package/dist/src/agents/agentLoader.js.map +1 -0
- package/dist/src/agents/agentLoader.test.js +307 -0
- package/dist/src/agents/agentLoader.test.js.map +1 -0
- package/dist/src/agents/cli-help-agent.d.ts +24 -0
- package/dist/src/agents/cli-help-agent.js +85 -0
- package/dist/src/agents/cli-help-agent.js.map +1 -0
- package/dist/src/agents/cli-help-agent.test.d.ts +6 -0
- package/dist/src/agents/cli-help-agent.test.js +65 -0
- package/dist/src/agents/cli-help-agent.test.js.map +1 -0
- package/dist/src/agents/codebase-investigator.d.ts +2 -2
- package/dist/src/agents/codebase-investigator.js +14 -8
- package/dist/src/agents/codebase-investigator.js.map +1 -1
- package/dist/src/agents/delegate-to-agent-tool.d.ts +19 -0
- package/dist/src/agents/delegate-to-agent-tool.js +122 -0
- package/dist/src/agents/delegate-to-agent-tool.js.map +1 -0
- package/dist/src/agents/delegate-to-agent-tool.test.d.ts +6 -0
- package/dist/src/agents/delegate-to-agent-tool.test.js +213 -0
- package/dist/src/agents/delegate-to-agent-tool.test.js.map +1 -0
- package/dist/src/agents/{executor.d.ts → local-executor.d.ts} +5 -11
- package/dist/src/agents/{executor.js → local-executor.js} +124 -63
- package/dist/src/agents/local-executor.js.map +1 -0
- package/dist/src/agents/local-executor.test.d.ts +6 -0
- package/dist/src/agents/{executor.test.js → local-executor.test.js} +136 -58
- package/dist/src/agents/local-executor.test.js.map +1 -0
- package/dist/src/agents/{invocation.d.ts → local-invocation.d.ts} +6 -7
- package/dist/src/agents/{invocation.js → local-invocation.js} +9 -10
- package/dist/src/agents/local-invocation.js.map +1 -0
- package/dist/src/agents/local-invocation.test.d.ts +6 -0
- package/dist/src/agents/{invocation.test.js → local-invocation.test.js} +29 -20
- package/dist/src/agents/local-invocation.test.js.map +1 -0
- package/dist/src/agents/registry.d.ts +37 -1
- package/dist/src/agents/registry.js +240 -27
- package/dist/src/agents/registry.js.map +1 -1
- package/dist/src/agents/registry.test.js +465 -30
- package/dist/src/agents/registry.test.js.map +1 -1
- package/dist/src/agents/remote-invocation.d.ts +35 -0
- package/dist/src/agents/remote-invocation.js +126 -0
- package/dist/src/agents/remote-invocation.js.map +1 -0
- package/dist/src/agents/remote-invocation.test.d.ts +6 -0
- package/dist/src/agents/remote-invocation.test.js +201 -0
- package/dist/src/agents/remote-invocation.test.js.map +1 -0
- package/dist/src/agents/subagent-tool-wrapper.d.ts +2 -2
- package/dist/src/agents/subagent-tool-wrapper.js +11 -6
- package/dist/src/agents/subagent-tool-wrapper.js.map +1 -1
- package/dist/src/agents/subagent-tool-wrapper.test.js +33 -19
- package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -1
- package/dist/src/agents/types.d.ts +21 -15
- package/dist/src/agents/types.js.map +1 -1
- package/dist/src/availability/errorClassification.d.ts +7 -0
- package/dist/src/availability/errorClassification.js +20 -0
- package/dist/src/availability/errorClassification.js.map +1 -0
- package/dist/src/availability/fallbackIntegration.test.d.ts +6 -0
- package/dist/src/availability/fallbackIntegration.test.js +58 -0
- package/dist/src/availability/fallbackIntegration.test.js.map +1 -0
- package/dist/src/availability/modelAvailabilityService.d.ts +3 -1
- package/dist/src/availability/modelAvailabilityService.js +3 -0
- package/dist/src/availability/modelAvailabilityService.js.map +1 -1
- package/dist/src/availability/modelPolicy.d.ts +8 -1
- package/dist/src/availability/policyCatalog.d.ts +1 -0
- package/dist/src/availability/policyCatalog.js +6 -7
- package/dist/src/availability/policyCatalog.js.map +1 -1
- package/dist/src/availability/policyCatalog.test.js +2 -2
- package/dist/src/availability/policyCatalog.test.js.map +1 -1
- package/dist/src/availability/policyHelpers.d.ts +34 -3
- package/dist/src/availability/policyHelpers.js +104 -13
- package/dist/src/availability/policyHelpers.js.map +1 -1
- package/dist/src/availability/policyHelpers.test.js +143 -13
- package/dist/src/availability/policyHelpers.test.js.map +1 -1
- package/dist/src/availability/testUtils.d.ts +10 -0
- package/dist/src/availability/testUtils.js +22 -0
- package/dist/src/availability/testUtils.js.map +1 -0
- package/dist/src/code_assist/experiments/client_metadata.js +2 -1
- package/dist/src/code_assist/experiments/client_metadata.js.map +1 -1
- package/dist/src/code_assist/experiments/client_metadata.test.js +7 -10
- package/dist/src/code_assist/experiments/client_metadata.test.js.map +1 -1
- package/dist/src/code_assist/experiments/experiments.d.ts +1 -1
- package/dist/src/code_assist/experiments/experiments.js +21 -0
- package/dist/src/code_assist/experiments/experiments.js.map +1 -1
- package/dist/src/code_assist/experiments/experiments_local.test.d.ts +6 -0
- package/dist/src/code_assist/experiments/experiments_local.test.js +110 -0
- package/dist/src/code_assist/experiments/experiments_local.test.js.map +1 -0
- package/dist/src/code_assist/oauth-credential-storage.js +3 -4
- package/dist/src/code_assist/oauth-credential-storage.js.map +1 -1
- package/dist/src/code_assist/oauth2.d.ts +2 -0
- package/dist/src/code_assist/oauth2.js +70 -14
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +224 -22
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/code_assist/server.d.ts +9 -1
- package/dist/src/code_assist/server.js +74 -11
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/code_assist/server.test.js +199 -27
- package/dist/src/code_assist/server.test.js.map +1 -1
- package/dist/src/code_assist/setup.js +6 -4
- package/dist/src/code_assist/setup.js.map +1 -1
- package/dist/src/code_assist/setup.test.js +63 -0
- package/dist/src/code_assist/setup.test.js.map +1 -1
- package/dist/src/code_assist/telemetry.d.ts +14 -0
- package/dist/src/code_assist/telemetry.js +157 -0
- package/dist/src/code_assist/telemetry.js.map +1 -0
- package/dist/src/code_assist/telemetry.test.d.ts +6 -0
- package/dist/src/code_assist/telemetry.test.js +301 -0
- package/dist/src/code_assist/telemetry.test.js.map +1 -0
- package/dist/src/code_assist/types.d.ts +77 -1
- package/dist/src/code_assist/types.js +28 -0
- package/dist/src/code_assist/types.js.map +1 -1
- package/dist/src/commands/init.d.ts +7 -0
- package/dist/src/commands/init.js +53 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/init.test.d.ts +6 -0
- package/dist/src/commands/init.test.js +25 -0
- package/dist/src/commands/init.test.js.map +1 -0
- package/dist/src/commands/memory.d.ts +11 -0
- package/dist/src/commands/memory.js +80 -0
- package/dist/src/commands/memory.js.map +1 -0
- package/dist/src/commands/memory.test.d.ts +6 -0
- package/dist/src/commands/memory.test.js +155 -0
- package/dist/src/commands/memory.test.js.map +1 -0
- package/dist/src/commands/restore.d.ts +9 -0
- package/dist/src/commands/restore.js +46 -0
- package/dist/src/commands/restore.js.map +1 -0
- package/dist/src/commands/restore.test.d.ts +6 -0
- package/dist/src/commands/restore.test.js +137 -0
- package/dist/src/commands/restore.test.js.map +1 -0
- package/dist/src/commands/types.d.ts +41 -0
- package/dist/src/commands/types.js +7 -0
- package/dist/src/commands/types.js.map +1 -0
- package/dist/src/config/config.d.ts +145 -25
- package/dist/src/config/config.js +370 -132
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +416 -50
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/defaultModelConfigs.js +21 -0
- package/dist/src/config/defaultModelConfigs.js.map +1 -1
- package/dist/src/config/flashFallback.test.js +11 -35
- package/dist/src/config/flashFallback.test.js.map +1 -1
- package/dist/src/config/models.d.ts +36 -15
- package/dist/src/config/models.js +89 -28
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/models.test.js +107 -77
- package/dist/src/config/models.test.js.map +1 -1
- package/dist/src/config/storage.d.ts +5 -0
- package/dist/src/config/storage.js +17 -2
- package/dist/src/config/storage.js.map +1 -1
- package/dist/src/config/storage.test.js +16 -0
- package/dist/src/config/storage.test.js.map +1 -1
- package/dist/src/confirmation-bus/message-bus.js +3 -1
- package/dist/src/confirmation-bus/message-bus.js.map +1 -1
- package/dist/src/confirmation-bus/types.d.ts +4 -0
- package/dist/src/core/baseLlmClient.d.ts +3 -1
- package/dist/src/core/baseLlmClient.js +60 -22
- package/dist/src/core/baseLlmClient.js.map +1 -1
- package/dist/src/core/baseLlmClient.test.js +177 -7
- package/dist/src/core/baseLlmClient.test.js.map +1 -1
- package/dist/src/core/client.d.ts +7 -1
- package/dist/src/core/client.js +261 -96
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +397 -67
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/clientHookTriggers.js +2 -2
- package/dist/src/core/clientHookTriggers.js.map +1 -1
- package/dist/src/core/contentGenerator.js +6 -4
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +24 -23
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/coreToolHookTriggers.d.ts +9 -5
- package/dist/src/core/coreToolHookTriggers.js +119 -21
- package/dist/src/core/coreToolHookTriggers.js.map +1 -1
- package/dist/src/core/coreToolHookTriggers.test.d.ts +6 -0
- package/dist/src/core/coreToolHookTriggers.test.js +191 -0
- package/dist/src/core/coreToolHookTriggers.test.js.map +1 -0
- package/dist/src/core/coreToolScheduler.d.ts +7 -93
- package/dist/src/core/coreToolScheduler.js +139 -333
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +304 -348
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +26 -1
- package/dist/src/core/geminiChat.js +144 -80
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +334 -253
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/geminiChatHookTriggers.d.ts +8 -4
- package/dist/src/core/geminiChatHookTriggers.js +34 -12
- package/dist/src/core/geminiChatHookTriggers.js.map +1 -1
- package/dist/src/core/geminiChatHookTriggers.test.d.ts +6 -0
- package/dist/src/core/geminiChatHookTriggers.test.js +153 -0
- package/dist/src/core/geminiChatHookTriggers.test.js.map +1 -0
- package/dist/src/core/geminiChat_network_retry.test.d.ts +6 -0
- package/dist/src/core/geminiChat_network_retry.test.js +196 -0
- package/dist/src/core/geminiChat_network_retry.test.js.map +1 -0
- package/dist/src/core/logger.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.js +19 -2
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.test.js +30 -0
- package/dist/src/core/loggingContentGenerator.test.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +7 -8
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/prompts.js +48 -22
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/prompts.test.js +66 -11
- package/dist/src/core/prompts.test.js.map +1 -1
- package/dist/src/core/tokenLimits.js +6 -12
- package/dist/src/core/tokenLimits.js.map +1 -1
- package/dist/src/core/tokenLimits.test.js +8 -4
- package/dist/src/core/tokenLimits.test.js.map +1 -1
- package/dist/src/core/turn.d.ts +21 -21
- package/dist/src/core/turn.js +32 -22
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/core/turn.test.js +79 -5
- package/dist/src/core/turn.test.js.map +1 -1
- package/dist/src/fallback/handler.js +55 -120
- package/dist/src/fallback/handler.js.map +1 -1
- package/dist/src/fallback/handler.test.js +115 -288
- package/dist/src/fallback/handler.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +3 -3
- package/dist/src/generated/git-commit.js +3 -3
- package/dist/src/hooks/hookAggregator.js +7 -0
- package/dist/src/hooks/hookAggregator.js.map +1 -1
- package/dist/src/hooks/hookEventHandler.d.ts +9 -5
- package/dist/src/hooks/hookEventHandler.js +120 -16
- package/dist/src/hooks/hookEventHandler.js.map +1 -1
- package/dist/src/hooks/hookEventHandler.test.js +231 -9
- package/dist/src/hooks/hookEventHandler.test.js.map +1 -1
- package/dist/src/hooks/hookPlanner.d.ts +1 -5
- package/dist/src/hooks/hookPlanner.js +2 -7
- package/dist/src/hooks/hookPlanner.js.map +1 -1
- package/dist/src/hooks/hookPlanner.test.js +62 -2
- package/dist/src/hooks/hookPlanner.test.js.map +1 -1
- package/dist/src/hooks/hookRegistry.d.ts +6 -18
- package/dist/src/hooks/hookRegistry.js +49 -35
- package/dist/src/hooks/hookRegistry.js.map +1 -1
- package/dist/src/hooks/hookRegistry.test.js +167 -8
- package/dist/src/hooks/hookRegistry.test.js.map +1 -1
- package/dist/src/hooks/hookRunner.d.ts +5 -3
- package/dist/src/hooks/hookRunner.js +68 -18
- package/dist/src/hooks/hookRunner.js.map +1 -1
- package/dist/src/hooks/hookRunner.test.js +173 -36
- package/dist/src/hooks/hookRunner.test.js.map +1 -1
- package/dist/src/hooks/hookSystem.d.ts +10 -6
- package/dist/src/hooks/hookSystem.js +36 -16
- package/dist/src/hooks/hookSystem.js.map +1 -1
- package/dist/src/hooks/hookSystem.test.js +123 -18
- package/dist/src/hooks/hookSystem.test.js.map +1 -1
- package/dist/src/hooks/hookTranslator.js +2 -1
- package/dist/src/hooks/hookTranslator.js.map +1 -1
- package/dist/src/hooks/index.d.ts +2 -1
- package/dist/src/hooks/index.js +1 -0
- package/dist/src/hooks/index.js.map +1 -1
- package/dist/src/hooks/trustedHooks.d.ts +28 -0
- package/dist/src/hooks/trustedHooks.js +90 -0
- package/dist/src/hooks/trustedHooks.js.map +1 -0
- package/dist/src/hooks/trustedHooks.test.d.ts +6 -0
- package/dist/src/hooks/trustedHooks.test.js +154 -0
- package/dist/src/hooks/trustedHooks.test.js.map +1 -0
- package/dist/src/hooks/types.d.ts +42 -11
- package/dist/src/hooks/types.js +31 -42
- package/dist/src/hooks/types.js.map +1 -1
- package/dist/src/hooks/types.test.js +9 -52
- package/dist/src/hooks/types.test.js.map +1 -1
- package/dist/src/ide/detect-ide.d.ts +4 -0
- package/dist/src/ide/detect-ide.js +7 -2
- package/dist/src/ide/detect-ide.js.map +1 -1
- package/dist/src/ide/detect-ide.test.js +42 -1
- package/dist/src/ide/detect-ide.test.js.map +1 -1
- package/dist/src/ide/ide-client.js +6 -1
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ide-installer.js +2 -2
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/ide-installer.test.js +12 -3
- package/dist/src/ide/ide-installer.test.js.map +1 -1
- package/dist/src/index.d.ts +23 -1
- package/dist/src/index.js +25 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/oauth-provider.js +7 -3
- package/dist/src/mcp/oauth-provider.js.map +1 -1
- package/dist/src/mcp/oauth-provider.test.js +4 -1
- package/dist/src/mcp/oauth-provider.test.js.map +1 -1
- package/dist/src/mcp/oauth-utils.d.ts +8 -1
- package/dist/src/mcp/oauth-utils.js +31 -2
- package/dist/src/mcp/oauth-utils.js.map +1 -1
- package/dist/src/mcp/oauth-utils.test.js +42 -0
- package/dist/src/mcp/oauth-utils.test.js.map +1 -1
- package/dist/src/mcp/token-storage/file-token-storage.js +2 -2
- package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -1
- package/dist/src/mcp/token-storage/keychain-token-storage.js +1 -1
- package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -1
- package/dist/src/output/json-formatter.d.ts +2 -2
- package/dist/src/output/json-formatter.js +6 -3
- package/dist/src/output/json-formatter.js.map +1 -1
- package/dist/src/output/json-formatter.test.js +37 -9
- package/dist/src/output/json-formatter.test.js.map +1 -1
- package/dist/src/output/stream-json-formatter.js +6 -0
- package/dist/src/output/stream-json-formatter.js.map +1 -1
- package/dist/src/output/stream-json-formatter.test.js +98 -100
- package/dist/src/output/stream-json-formatter.test.js.map +1 -1
- package/dist/src/output/types.d.ts +3 -0
- package/dist/src/output/types.js.map +1 -1
- package/dist/src/policy/config.js +140 -15
- package/dist/src/policy/config.js.map +1 -1
- package/dist/src/policy/config.test.js +24 -2
- package/dist/src/policy/config.test.js.map +1 -1
- package/dist/src/policy/persistence.test.d.ts +6 -0
- package/dist/src/policy/persistence.test.js +154 -0
- package/dist/src/policy/persistence.test.js.map +1 -0
- package/dist/src/policy/policies/agent.toml +31 -0
- package/dist/src/policy/policies/write.toml +5 -0
- package/dist/src/policy/policies/yolo.toml +1 -0
- package/dist/src/policy/policy-engine.d.ts +14 -1
- package/dist/src/policy/policy-engine.js +165 -7
- package/dist/src/policy/policy-engine.js.map +1 -1
- package/dist/src/policy/policy-engine.test.js +315 -3
- package/dist/src/policy/policy-engine.test.js.map +1 -1
- package/dist/src/policy/policy-updater.test.d.ts +6 -0
- package/dist/src/policy/policy-updater.test.js +116 -0
- package/dist/src/policy/policy-updater.test.js.map +1 -0
- package/dist/src/policy/shell-safety.test.d.ts +6 -0
- package/dist/src/policy/shell-safety.test.js +438 -0
- package/dist/src/policy/shell-safety.test.js.map +1 -0
- package/dist/src/policy/toml-loader.d.ts +3 -5
- package/dist/src/policy/toml-loader.js +43 -60
- package/dist/src/policy/toml-loader.js.map +1 -1
- package/dist/src/policy/toml-loader.test.js +41 -7
- package/dist/src/policy/toml-loader.test.js.map +1 -1
- package/dist/src/policy/types.d.ts +25 -0
- package/dist/src/policy/utils.d.ts +21 -0
- package/dist/src/policy/utils.js +45 -0
- package/dist/src/policy/utils.js.map +1 -0
- package/dist/src/policy/utils.test.d.ts +6 -0
- package/dist/src/policy/utils.test.js +92 -0
- package/dist/src/policy/utils.test.js.map +1 -0
- package/dist/src/resources/resource-registry.d.ts +30 -0
- package/dist/src/resources/resource-registry.js +57 -0
- package/dist/src/resources/resource-registry.js.map +1 -0
- package/dist/src/resources/resource-registry.test.d.ts +6 -0
- package/dist/src/resources/resource-registry.test.js +54 -0
- package/dist/src/resources/resource-registry.test.js.map +1 -0
- package/dist/src/routing/modelRouterService.js +0 -15
- package/dist/src/routing/modelRouterService.js.map +1 -1
- package/dist/src/routing/modelRouterService.test.js +0 -62
- package/dist/src/routing/modelRouterService.test.js.map +1 -1
- package/dist/src/routing/routingStrategy.d.ts +2 -0
- package/dist/src/routing/strategies/classifierStrategy.js +10 -21
- package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
- package/dist/src/routing/strategies/classifierStrategy.test.js +18 -1
- package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/compositeStrategy.js +4 -2
- package/dist/src/routing/strategies/compositeStrategy.js.map +1 -1
- package/dist/src/routing/strategies/compositeStrategy.test.js +11 -10
- package/dist/src/routing/strategies/compositeStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.d.ts +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.js +21 -13
- package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.test.js +76 -39
- package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/overrideStrategy.d.ts +1 -1
- package/dist/src/routing/strategies/overrideStrategy.js +5 -4
- package/dist/src/routing/strategies/overrideStrategy.js.map +1 -1
- package/dist/src/routing/strategies/overrideStrategy.test.js +14 -0
- package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -1
- package/dist/src/safety/checker-runner.js +17 -6
- package/dist/src/safety/checker-runner.js.map +1 -1
- package/dist/src/scheduler/tool-executor.d.ts +22 -0
- package/dist/src/scheduler/tool-executor.js +198 -0
- package/dist/src/scheduler/tool-executor.js.map +1 -0
- package/dist/src/scheduler/tool-executor.test.d.ts +6 -0
- package/dist/src/scheduler/tool-executor.test.js +231 -0
- package/dist/src/scheduler/tool-executor.test.js.map +1 -0
- package/dist/src/scheduler/tool-modifier.d.ts +23 -0
- package/dist/src/scheduler/tool-modifier.js +50 -0
- package/dist/src/scheduler/tool-modifier.js.map +1 -0
- package/dist/src/scheduler/tool-modifier.test.d.ts +6 -0
- package/dist/src/scheduler/tool-modifier.test.js +159 -0
- package/dist/src/scheduler/tool-modifier.test.js.map +1 -0
- package/dist/src/scheduler/types.d.ts +95 -0
- package/dist/src/scheduler/types.js +7 -0
- package/dist/src/scheduler/types.js.map +1 -0
- package/dist/src/services/chatCompressionService.js +8 -1
- package/dist/src/services/chatCompressionService.js.map +1 -1
- package/dist/src/services/chatCompressionService.test.js +3 -0
- package/dist/src/services/chatCompressionService.test.js.map +1 -1
- package/dist/src/services/chatRecordingService.d.ts +21 -1
- package/dist/src/services/chatRecordingService.js +57 -2
- package/dist/src/services/chatRecordingService.js.map +1 -1
- package/dist/src/services/chatRecordingService.test.js +43 -0
- package/dist/src/services/chatRecordingService.test.js.map +1 -1
- package/dist/src/services/contextManager.d.ts +5 -11
- package/dist/src/services/contextManager.js +20 -17
- package/dist/src/services/contextManager.js.map +1 -1
- package/dist/src/services/contextManager.test.js +40 -41
- package/dist/src/services/contextManager.test.js.map +1 -1
- package/dist/src/services/environmentSanitization.d.ts +15 -0
- package/dist/src/services/environmentSanitization.js +142 -0
- package/dist/src/services/environmentSanitization.js.map +1 -0
- package/dist/src/services/environmentSanitization.test.d.ts +6 -0
- package/dist/src/services/environmentSanitization.test.js +284 -0
- package/dist/src/services/environmentSanitization.test.js.map +1 -0
- package/dist/src/services/fileSystemService.d.ts +0 -9
- package/dist/src/services/fileSystemService.js +0 -11
- package/dist/src/services/fileSystemService.js.map +1 -1
- package/dist/src/services/gitService.js +15 -1
- package/dist/src/services/gitService.js.map +1 -1
- package/dist/src/services/gitService.test.js +56 -2
- package/dist/src/services/gitService.test.js.map +1 -1
- package/dist/src/services/loopDetectionService.js +4 -3
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/loopDetectionService.test.js +14 -8
- package/dist/src/services/loopDetectionService.test.js.map +1 -1
- package/dist/src/services/modelConfig.golden.test.js +32 -0
- package/dist/src/services/modelConfig.golden.test.js.map +1 -1
- package/dist/src/services/modelConfig.integration.test.js +3 -3
- package/dist/src/services/modelConfig.integration.test.js.map +1 -1
- package/dist/src/services/modelConfigService.d.ts +41 -4
- package/dist/src/services/modelConfigService.js +135 -75
- package/dist/src/services/modelConfigService.js.map +1 -1
- package/dist/src/services/modelConfigService.test.js +226 -0
- package/dist/src/services/modelConfigService.test.js.map +1 -1
- package/dist/src/services/modelConfigServiceTestUtils.d.ts +10 -0
- package/dist/src/services/modelConfigServiceTestUtils.js +17 -0
- package/dist/src/services/modelConfigServiceTestUtils.js.map +1 -0
- package/dist/src/services/sessionSummaryService.d.ts +28 -0
- package/dist/src/services/sessionSummaryService.js +131 -0
- package/dist/src/services/sessionSummaryService.js.map +1 -0
- package/dist/src/services/sessionSummaryService.test.d.ts +6 -0
- package/dist/src/services/sessionSummaryService.test.js +785 -0
- package/dist/src/services/sessionSummaryService.test.js.map +1 -0
- package/dist/src/services/sessionSummaryUtils.d.ts +16 -0
- package/dist/src/services/sessionSummaryUtils.js +129 -0
- package/dist/src/services/sessionSummaryUtils.js.map +1 -0
- package/dist/src/services/sessionSummaryUtils.test.d.ts +6 -0
- package/dist/src/services/sessionSummaryUtils.test.js +137 -0
- package/dist/src/services/sessionSummaryUtils.test.js.map +1 -0
- package/dist/src/services/shellExecutionService.d.ts +2 -0
- package/dist/src/services/shellExecutionService.js +34 -72
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +114 -8
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/services/test-data/resolved-aliases-retry.golden.json +238 -0
- package/dist/src/services/test-data/resolved-aliases.golden.json +16 -0
- package/dist/src/skills/skillLoader.d.ts +31 -0
- package/dist/src/skills/skillLoader.js +77 -0
- package/dist/src/skills/skillLoader.js.map +1 -0
- package/dist/src/skills/skillLoader.test.d.ts +6 -0
- package/dist/src/skills/skillLoader.test.js +75 -0
- package/dist/src/skills/skillLoader.test.js.map +1 -0
- package/dist/src/skills/skillManager.d.ts +69 -0
- package/dist/src/skills/skillManager.js +127 -0
- package/dist/src/skills/skillManager.js.map +1 -0
- package/dist/src/skills/skillManager.test.d.ts +6 -0
- package/dist/src/skills/skillManager.test.js +210 -0
- package/dist/src/skills/skillManager.test.js.map +1 -0
- package/dist/src/telemetry/activity-detector.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +19 -9
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +261 -164
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +223 -27
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +12 -3
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +26 -5
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/config.js +2 -0
- package/dist/src/telemetry/config.js.map +1 -1
- package/dist/src/telemetry/config.test.js +25 -0
- package/dist/src/telemetry/config.test.js.map +1 -1
- package/dist/src/telemetry/gcp-exporters.d.ts +4 -3
- package/dist/src/telemetry/gcp-exporters.js +8 -4
- package/dist/src/telemetry/gcp-exporters.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +1 -1
- package/dist/src/telemetry/index.js +1 -1
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +4 -3
- package/dist/src/telemetry/loggers.js +351 -340
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.circular.js +1 -0
- package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +71 -15
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js.map +1 -1
- package/dist/src/telemetry/sdk.d.ts +9 -2
- package/dist/src/telemetry/sdk.js +142 -17
- package/dist/src/telemetry/sdk.js.map +1 -1
- package/dist/src/telemetry/sdk.test.js +130 -28
- package/dist/src/telemetry/sdk.test.js.map +1 -1
- package/dist/src/telemetry/startupProfiler.js +26 -3
- package/dist/src/telemetry/startupProfiler.js.map +1 -1
- package/dist/src/telemetry/startupProfiler.test.js +49 -7
- package/dist/src/telemetry/startupProfiler.test.js.map +1 -1
- package/dist/src/telemetry/telemetry.test.js +10 -3
- package/dist/src/telemetry/telemetry.test.js.map +1 -1
- package/dist/src/telemetry/trace.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +37 -12
- package/dist/src/telemetry/types.js +61 -20
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.d.ts +1 -0
- package/dist/src/telemetry/uiTelemetry.js +2 -0
- package/dist/src/telemetry/uiTelemetry.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.test.js +4 -0
- package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
- package/dist/src/test-utils/mock-message-bus.d.ts +1 -0
- package/dist/src/test-utils/mock-message-bus.js +29 -0
- package/dist/src/test-utils/mock-message-bus.js.map +1 -1
- package/dist/src/test-utils/mock-tool.d.ts +5 -3
- package/dist/src/test-utils/mock-tool.js +11 -10
- package/dist/src/test-utils/mock-tool.js.map +1 -1
- package/dist/src/tools/activate-skill.d.ts +27 -0
- package/dist/src/tools/activate-skill.js +133 -0
- package/dist/src/tools/activate-skill.js.map +1 -0
- package/dist/src/tools/activate-skill.test.d.ts +6 -0
- package/dist/src/tools/activate-skill.test.js +113 -0
- package/dist/src/tools/activate-skill.test.js.map +1 -0
- package/dist/src/tools/confirmation-policy.test.d.ts +6 -0
- package/dist/src/tools/confirmation-policy.test.js +143 -0
- package/dist/src/tools/confirmation-policy.test.js.map +1 -0
- package/dist/src/tools/edit.d.ts +27 -5
- package/dist/src/tools/edit.js +460 -136
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +292 -526
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/get-internal-docs.d.ts +27 -0
- package/dist/src/tools/get-internal-docs.js +122 -0
- package/dist/src/tools/get-internal-docs.js.map +1 -0
- package/dist/src/tools/get-internal-docs.test.d.ts +6 -0
- package/dist/src/tools/get-internal-docs.test.js +57 -0
- package/dist/src/tools/get-internal-docs.test.js.map +1 -0
- package/dist/src/tools/glob.d.ts +2 -2
- package/dist/src/tools/glob.js +1 -1
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +2 -1
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/grep.d.ts +2 -2
- package/dist/src/tools/grep.js +1 -1
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/grep.test.js +5 -4
- package/dist/src/tools/grep.test.js.map +1 -1
- package/dist/src/tools/ls.d.ts +2 -2
- package/dist/src/tools/ls.js +2 -2
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/ls.test.js +2 -1
- package/dist/src/tools/ls.test.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.d.ts +2 -1
- package/dist/src/tools/mcp-client-manager.js +32 -9
- package/dist/src/tools/mcp-client-manager.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.test.js +41 -10
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
- package/dist/src/tools/mcp-client.d.ts +43 -6
- package/dist/src/tools/mcp-client.js +443 -176
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +664 -39
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +20 -5
- package/dist/src/tools/mcp-tool.js +21 -8
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/mcp-tool.test.js +35 -5
- package/dist/src/tools/mcp-tool.test.js.map +1 -1
- package/dist/src/tools/memoryTool.d.ts +3 -3
- package/dist/src/tools/memoryTool.js +3 -4
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/memoryTool.test.js +5 -2
- package/dist/src/tools/memoryTool.test.js.map +1 -1
- package/dist/src/tools/message-bus-integration.test.js +10 -37
- package/dist/src/tools/message-bus-integration.test.js.map +1 -1
- package/dist/src/tools/modifiable-tool.js.map +1 -1
- package/dist/src/tools/modifiable-tool.test.js +22 -13
- package/dist/src/tools/modifiable-tool.test.js.map +1 -1
- package/dist/src/tools/read-file.d.ts +2 -2
- package/dist/src/tools/read-file.js +2 -2
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +3 -2
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.d.ts +2 -2
- package/dist/src/tools/read-many-files.js +7 -6
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/read-many-files.test.js +4 -3
- package/dist/src/tools/read-many-files.test.js.map +1 -1
- package/dist/src/tools/ripGrep.d.ts +3 -2
- package/dist/src/tools/ripGrep.js +18 -7
- package/dist/src/tools/ripGrep.js.map +1 -1
- package/dist/src/tools/ripGrep.test.js +60 -4
- package/dist/src/tools/ripGrep.test.js.map +1 -1
- package/dist/src/tools/shell.d.ts +5 -7
- package/dist/src/tools/shell.js +35 -49
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +36 -59
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/tool-error.d.ts +6 -1
- package/dist/src/tools/tool-error.js +6 -0
- package/dist/src/tools/tool-error.js.map +1 -1
- package/dist/src/tools/tool-names.d.ts +17 -0
- package/dist/src/tools/tool-names.js +59 -0
- package/dist/src/tools/tool-names.js.map +1 -1
- package/dist/src/tools/tool-names.test.d.ts +6 -0
- package/dist/src/tools/tool-names.test.js +43 -0
- package/dist/src/tools/tool-names.test.js.map +1 -0
- package/dist/src/tools/tool-registry.d.ts +11 -7
- package/dist/src/tools/tool-registry.js +15 -10
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +16 -11
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +27 -6
- package/dist/src/tools/tools.js +44 -25
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/tools.test.js +3 -1
- package/dist/src/tools/tools.test.js.map +1 -1
- package/dist/src/tools/web-fetch.d.ts +2 -2
- package/dist/src/tools/web-fetch.js +21 -8
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +18 -19
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/web-search.d.ts +2 -2
- package/dist/src/tools/web-search.js +5 -5
- package/dist/src/tools/web-search.js.map +1 -1
- package/dist/src/tools/web-search.test.js +2 -1
- package/dist/src/tools/web-search.test.js.map +1 -1
- package/dist/src/tools/write-file.d.ts +2 -2
- package/dist/src/tools/write-file.js +14 -6
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +49 -7
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/tools/write-todos.d.ts +2 -2
- package/dist/src/tools/write-todos.js +5 -4
- package/dist/src/tools/write-todos.js.map +1 -1
- package/dist/src/tools/write-todos.test.js +2 -1
- package/dist/src/tools/write-todos.test.js.map +1 -1
- package/dist/src/utils/apiConversionUtils.d.ts +12 -0
- package/dist/src/utils/apiConversionUtils.js +46 -0
- package/dist/src/utils/apiConversionUtils.js.map +1 -0
- package/dist/src/utils/apiConversionUtils.test.d.ts +6 -0
- package/dist/src/utils/apiConversionUtils.test.js +150 -0
- package/dist/src/utils/apiConversionUtils.test.js.map +1 -0
- package/dist/src/utils/bfsFileSearch.d.ts +8 -0
- package/dist/src/utils/bfsFileSearch.js +63 -23
- package/dist/src/utils/bfsFileSearch.js.map +1 -1
- package/dist/src/utils/bfsFileSearch.test.js +65 -1
- package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
- package/dist/src/utils/checkpointUtils.d.ts +82 -0
- package/dist/src/utils/checkpointUtils.js +117 -0
- package/dist/src/utils/checkpointUtils.js.map +1 -0
- package/dist/src/utils/checkpointUtils.test.d.ts +6 -0
- package/dist/src/utils/checkpointUtils.test.js +229 -0
- package/dist/src/utils/checkpointUtils.test.js.map +1 -0
- package/dist/src/utils/debugLogger.d.ts +3 -0
- package/dist/src/utils/debugLogger.js +28 -0
- package/dist/src/utils/debugLogger.js.map +1 -1
- package/dist/src/utils/editCorrector.d.ts +3 -3
- package/dist/src/utils/editCorrector.js +27 -10
- package/dist/src/utils/editCorrector.js.map +1 -1
- package/dist/src/utils/editCorrector.test.js +27 -23
- package/dist/src/utils/editCorrector.test.js.map +1 -1
- package/dist/src/utils/editor.d.ts +10 -1
- package/dist/src/utils/editor.js +48 -19
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/editor.test.js +27 -4
- package/dist/src/utils/editor.test.js.map +1 -1
- package/dist/src/utils/environmentContext.d.ts +1 -0
- package/dist/src/utils/environmentContext.js +4 -0
- package/dist/src/utils/environmentContext.js.map +1 -1
- package/dist/src/utils/environmentContext.test.js +2 -0
- package/dist/src/utils/environmentContext.test.js.map +1 -1
- package/dist/src/utils/errorReporting.d.ts +1 -1
- package/dist/src/utils/errorReporting.js +13 -12
- package/dist/src/utils/errorReporting.js.map +1 -1
- package/dist/src/utils/errorReporting.test.js +17 -14
- package/dist/src/utils/errorReporting.test.js.map +1 -1
- package/dist/src/utils/errors.d.ts +8 -0
- package/dist/src/utils/errors.js +39 -2
- package/dist/src/utils/errors.js.map +1 -1
- package/dist/src/utils/errors.test.d.ts +6 -0
- package/dist/src/utils/errors.test.js +155 -0
- package/dist/src/utils/errors.test.js.map +1 -0
- package/dist/src/utils/events.d.ts +71 -19
- package/dist/src/utils/events.js +35 -9
- package/dist/src/utils/events.js.map +1 -1
- package/dist/src/utils/events.test.js +25 -0
- package/dist/src/utils/events.test.js.map +1 -1
- package/dist/src/utils/extensionLoader.d.ts +2 -2
- package/dist/src/utils/extensionLoader.js +5 -6
- package/dist/src/utils/extensionLoader.js.map +1 -1
- package/dist/src/utils/extensionLoader.test.js +11 -0
- package/dist/src/utils/extensionLoader.test.js.map +1 -1
- package/dist/src/utils/fetch.d.ts +1 -1
- package/dist/src/utils/fetch.js +3 -3
- package/dist/src/utils/fetch.js.map +1 -1
- package/dist/src/utils/fileDiffUtils.d.ts +18 -0
- package/dist/src/utils/fileDiffUtils.js +37 -0
- package/dist/src/utils/fileDiffUtils.js.map +1 -0
- package/dist/src/utils/fileDiffUtils.test.d.ts +6 -0
- package/dist/src/utils/fileDiffUtils.test.js +84 -0
- package/dist/src/utils/fileDiffUtils.test.js.map +1 -0
- package/dist/src/utils/fileUtils.d.ts +4 -0
- package/dist/src/utils/fileUtils.js +53 -0
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/fileUtils.test.js +127 -1
- package/dist/src/utils/fileUtils.test.js.map +1 -1
- package/dist/src/utils/filesearch/crawlCache.js.map +1 -1
- package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
- package/dist/src/utils/flashFallback.test.js +1 -1
- package/dist/src/utils/flashFallback.test.js.map +1 -1
- package/dist/src/utils/geminiIgnoreParser.d.ts +11 -0
- package/dist/src/utils/geminiIgnoreParser.js +20 -0
- package/dist/src/utils/geminiIgnoreParser.js.map +1 -1
- package/dist/src/utils/geminiIgnoreParser.test.js +48 -0
- package/dist/src/utils/geminiIgnoreParser.test.js.map +1 -1
- package/dist/src/utils/generateContentResponseUtilities.d.ts +3 -1
- package/dist/src/utils/generateContentResponseUtilities.js +106 -0
- package/dist/src/utils/generateContentResponseUtilities.js.map +1 -1
- package/dist/src/utils/generateContentResponseUtilities.test.js +279 -2
- package/dist/src/utils/generateContentResponseUtilities.test.js.map +1 -1
- package/dist/src/utils/getFolderStructure.js +7 -2
- package/dist/src/utils/getFolderStructure.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.js +9 -10
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/googleErrors.js +31 -18
- package/dist/src/utils/googleErrors.js.map +1 -1
- package/dist/src/utils/googleErrors.test.js +10 -2
- package/dist/src/utils/googleErrors.test.js.map +1 -1
- package/dist/src/utils/googleQuotaErrors.d.ts +3 -3
- package/dist/src/utils/googleQuotaErrors.js +32 -6
- package/dist/src/utils/googleQuotaErrors.js.map +1 -1
- package/dist/src/utils/googleQuotaErrors.test.js +94 -2
- package/dist/src/utils/googleQuotaErrors.test.js.map +1 -1
- package/dist/src/utils/installationManager.test.js +11 -3
- package/dist/src/utils/installationManager.test.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.js +3 -4
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +12 -1
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/nextSpeakerChecker.test.js +4 -0
- package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
- package/dist/src/utils/partUtils.js +1 -1
- package/dist/src/utils/partUtils.js.map +1 -1
- package/dist/src/utils/pathCorrector.js +12 -2
- package/dist/src/utils/pathCorrector.js.map +1 -1
- package/dist/src/utils/pathCorrector.test.js +6 -2
- package/dist/src/utils/pathCorrector.test.js.map +1 -1
- package/dist/src/utils/paths.d.ts +10 -0
- package/dist/src/utils/paths.js +20 -1
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/retry.d.ts +12 -0
- package/dist/src/utils/retry.js +70 -17
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/retry.test.js +181 -21
- package/dist/src/utils/retry.test.js.map +1 -1
- package/dist/src/utils/shell-utils.d.ts +16 -47
- package/dist/src/utils/shell-utils.js +98 -194
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.test.js +99 -288
- package/dist/src/utils/shell-utils.test.js.map +1 -1
- package/dist/src/utils/summarizer.test.js +3 -2
- package/dist/src/utils/summarizer.test.js.map +1 -1
- package/dist/src/utils/terminal.d.ts +4 -0
- package/dist/src/utils/terminal.js +12 -0
- package/dist/src/utils/terminal.js.map +1 -1
- package/dist/src/utils/terminalSerializer.test.js +17 -0
- package/dist/src/utils/terminalSerializer.test.js.map +1 -1
- package/dist/src/utils/tokenCalculation.js +20 -5
- package/dist/src/utils/tokenCalculation.js.map +1 -1
- package/dist/src/utils/tokenCalculation.test.js +11 -2
- package/dist/src/utils/tokenCalculation.test.js.map +1 -1
- package/dist/src/utils/tool-utils.d.ts +9 -0
- package/dist/src/utils/tool-utils.js +29 -0
- package/dist/src/utils/tool-utils.js.map +1 -1
- package/dist/src/utils/tool-utils.test.js +17 -2
- package/dist/src/utils/tool-utils.test.js.map +1 -1
- package/dist/src/utils/userAccountManager.test.js +5 -5
- package/dist/src/utils/userAccountManager.test.js.map +1 -1
- package/dist/src/utils/version.d.ts +6 -0
- package/dist/src/utils/version.js +15 -0
- package/dist/src/utils/version.js.map +1 -0
- package/dist/src/utils/version.test.d.ts +6 -0
- package/dist/src/utils/version.test.js +39 -0
- package/dist/src/utils/version.test.js.map +1 -0
- package/dist/src/utils/workspaceContext.test.js +1 -1
- package/dist/src/utils/workspaceContext.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -6
- package/dist/src/agents/executor.js.map +0 -1
- package/dist/src/agents/executor.test.js.map +0 -1
- package/dist/src/agents/invocation.js.map +0 -1
- package/dist/src/agents/invocation.test.js.map +0 -1
- package/dist/src/tools/smart-edit.d.ts +0 -78
- package/dist/src/tools/smart-edit.js +0 -717
- package/dist/src/tools/smart-edit.js.map +0 -1
- package/dist/src/tools/smart-edit.test.js +0 -592
- package/dist/src/tools/smart-edit.test.js.map +0 -1
- /package/dist/src/agents/{executor.test.d.ts → a2a-client-manager.test.d.ts} +0 -0
- /package/dist/src/agents/{invocation.test.d.ts → a2aUtils.test.d.ts} +0 -0
- /package/dist/src/{tools/smart-edit.test.d.ts → agents/agentLoader.test.d.ts} +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
|
-
const
|
|
7
|
+
const mockFixLLMEditWithInstruction = vi.hoisted(() => vi.fn());
|
|
8
8
|
const mockGenerateJson = vi.hoisted(() => vi.fn());
|
|
9
9
|
const mockOpenDiff = vi.hoisted(() => vi.fn());
|
|
10
10
|
import { IdeClient } from '../ide/ide-client.js';
|
|
@@ -13,36 +13,38 @@ vi.mock('../ide/ide-client.js', () => ({
|
|
|
13
13
|
getInstance: vi.fn(),
|
|
14
14
|
},
|
|
15
15
|
}));
|
|
16
|
-
vi.mock('../utils/
|
|
17
|
-
|
|
16
|
+
vi.mock('../utils/llm-edit-fixer.js', () => ({
|
|
17
|
+
FixLLMEditWithInstruction: mockFixLLMEditWithInstruction,
|
|
18
18
|
}));
|
|
19
19
|
vi.mock('../core/client.js', () => ({
|
|
20
20
|
GeminiClient: vi.fn().mockImplementation(() => ({
|
|
21
21
|
generateJson: mockGenerateJson,
|
|
22
|
+
getHistory: vi.fn().mockResolvedValue([]),
|
|
22
23
|
})),
|
|
23
24
|
}));
|
|
24
25
|
vi.mock('../utils/editor.js', () => ({
|
|
25
26
|
openDiff: mockOpenDiff,
|
|
26
27
|
}));
|
|
27
|
-
vi
|
|
28
|
-
|
|
29
|
-
}));
|
|
30
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
31
|
-
import { applyReplacement, EditTool } from './edit.js';
|
|
28
|
+
import { describe, it, expect, beforeEach, afterEach, vi, } from 'vitest';
|
|
29
|
+
import { EditTool, applyReplacement, calculateReplacement, } from './edit.js';
|
|
32
30
|
import { ToolConfirmationOutcome } from './tools.js';
|
|
33
31
|
import { ToolErrorType } from './tool-error.js';
|
|
32
|
+
import { createMockMessageBus, getMockMessageBusInstance, } from '../test-utils/mock-message-bus.js';
|
|
34
33
|
import path from 'node:path';
|
|
35
34
|
import fs from 'node:fs';
|
|
36
35
|
import os from 'node:os';
|
|
37
36
|
import { ApprovalMode } from '../policy/types.js';
|
|
37
|
+
import {} from '../config/config.js';
|
|
38
|
+
import {} from '@google/genai';
|
|
39
|
+
import { createMockWorkspaceContext } from '../test-utils/mockWorkspaceContext.js';
|
|
38
40
|
import { StandardFileSystemService } from '../services/fileSystemService.js';
|
|
39
|
-
import { WorkspaceContext } from '../utils/workspaceContext.js';
|
|
40
41
|
describe('EditTool', () => {
|
|
41
42
|
let tool;
|
|
42
43
|
let tempDir;
|
|
43
44
|
let rootDir;
|
|
44
45
|
let mockConfig;
|
|
45
46
|
let geminiClient;
|
|
47
|
+
let fileSystemService;
|
|
46
48
|
let baseLlmClient;
|
|
47
49
|
beforeEach(() => {
|
|
48
50
|
vi.restoreAllMocks();
|
|
@@ -50,23 +52,26 @@ describe('EditTool', () => {
|
|
|
50
52
|
rootDir = path.join(tempDir, 'root');
|
|
51
53
|
fs.mkdirSync(rootDir);
|
|
52
54
|
geminiClient = {
|
|
53
|
-
generateJson: mockGenerateJson,
|
|
55
|
+
generateJson: mockGenerateJson,
|
|
56
|
+
getHistory: vi.fn().mockResolvedValue([]),
|
|
54
57
|
};
|
|
55
58
|
baseLlmClient = {
|
|
56
|
-
generateJson:
|
|
59
|
+
generateJson: mockGenerateJson,
|
|
57
60
|
};
|
|
61
|
+
fileSystemService = new StandardFileSystemService();
|
|
58
62
|
mockConfig = {
|
|
63
|
+
getUsageStatisticsEnabled: vi.fn(() => true),
|
|
64
|
+
getSessionId: vi.fn(() => 'mock-session-id'),
|
|
65
|
+
getContentGeneratorConfig: vi.fn(() => ({ authType: 'mock' })),
|
|
66
|
+
getProxy: vi.fn(() => undefined),
|
|
59
67
|
getGeminiClient: vi.fn().mockReturnValue(geminiClient),
|
|
60
68
|
getBaseLlmClient: vi.fn().mockReturnValue(baseLlmClient),
|
|
61
69
|
getTargetDir: () => rootDir,
|
|
62
70
|
getApprovalMode: vi.fn(),
|
|
63
71
|
setApprovalMode: vi.fn(),
|
|
64
|
-
getWorkspaceContext: () =>
|
|
65
|
-
getFileSystemService: () =>
|
|
72
|
+
getWorkspaceContext: () => createMockWorkspaceContext(rootDir),
|
|
73
|
+
getFileSystemService: () => fileSystemService,
|
|
66
74
|
getIdeMode: () => false,
|
|
67
|
-
// getGeminiConfig: () => ({ apiKey: 'test-api-key' }), // This was not a real Config method
|
|
68
|
-
// Add other properties/methods of Config if EditTool uses them
|
|
69
|
-
// Minimal other methods to satisfy Config type if needed by EditTool constructor or other direct uses:
|
|
70
75
|
getApiKey: () => 'test-api-key',
|
|
71
76
|
getModel: () => 'test-model',
|
|
72
77
|
getSandbox: () => false,
|
|
@@ -81,34 +86,22 @@ describe('EditTool', () => {
|
|
|
81
86
|
setUserMemory: vi.fn(),
|
|
82
87
|
getGeminiMdFileCount: () => 0,
|
|
83
88
|
setGeminiMdFileCount: vi.fn(),
|
|
84
|
-
getToolRegistry: () => ({}),
|
|
89
|
+
getToolRegistry: () => ({}),
|
|
85
90
|
isInteractive: () => false,
|
|
91
|
+
getDisableLLMCorrection: vi.fn(() => false),
|
|
92
|
+
getExperiments: () => { },
|
|
86
93
|
};
|
|
87
|
-
// Reset mocks before each test
|
|
88
94
|
mockConfig.getApprovalMode.mockClear();
|
|
89
|
-
// Default to not skipping confirmation
|
|
90
95
|
mockConfig.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
let index = currentContent.indexOf(params.old_string);
|
|
98
|
-
while (index !== -1) {
|
|
99
|
-
occurrences++;
|
|
100
|
-
index = currentContent.indexOf(params.old_string, index + 1);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
else if (params.old_string === '') {
|
|
104
|
-
occurrences = 0; // Creating a new file
|
|
105
|
-
}
|
|
106
|
-
return Promise.resolve({ params, occurrences });
|
|
96
|
+
mockFixLLMEditWithInstruction.mockReset();
|
|
97
|
+
mockFixLLMEditWithInstruction.mockResolvedValue({
|
|
98
|
+
noChangesRequired: false,
|
|
99
|
+
search: '',
|
|
100
|
+
replace: '',
|
|
101
|
+
explanation: 'LLM fix failed',
|
|
107
102
|
});
|
|
108
|
-
// Default mock for generateJson to return the snippet unchanged
|
|
109
103
|
mockGenerateJson.mockReset();
|
|
110
104
|
mockGenerateJson.mockImplementation(async (contents, schema) => {
|
|
111
|
-
// The problematic_snippet is the last part of the user's content
|
|
112
105
|
const userContent = contents.find((c) => c.role === 'user');
|
|
113
106
|
let promptText = '';
|
|
114
107
|
if (userContent && userContent.parts) {
|
|
@@ -125,17 +118,17 @@ describe('EditTool', () => {
|
|
|
125
118
|
});
|
|
126
119
|
}
|
|
127
120
|
if (schema.properties?.corrected_new_string) {
|
|
128
|
-
// For new_string correction, we might need more sophisticated logic,
|
|
129
|
-
// but for now, returning original is a safe default if not specified by a test.
|
|
130
121
|
const originalNewStringMatch = promptText.match(/original_new_string \(what was intended to replace original_old_string\):\n```\n([\s\S]*?)\n```/);
|
|
131
122
|
const originalNewString = originalNewStringMatch && originalNewStringMatch[1]
|
|
132
123
|
? originalNewStringMatch[1]
|
|
133
124
|
: '';
|
|
134
125
|
return Promise.resolve({ corrected_new_string: originalNewString });
|
|
135
126
|
}
|
|
136
|
-
return Promise.resolve({});
|
|
127
|
+
return Promise.resolve({});
|
|
137
128
|
});
|
|
138
|
-
|
|
129
|
+
const bus = createMockMessageBus();
|
|
130
|
+
getMockMessageBusInstance(bus).defaultToolDecision = 'ask_user';
|
|
131
|
+
tool = new EditTool(mockConfig, bus);
|
|
139
132
|
});
|
|
140
133
|
afterEach(() => {
|
|
141
134
|
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
@@ -233,180 +226,85 @@ describe('EditTool', () => {
|
|
|
233
226
|
expect(result).toBe(expected);
|
|
234
227
|
});
|
|
235
228
|
});
|
|
229
|
+
describe('calculateReplacement', () => {
|
|
230
|
+
const abortSignal = new AbortController().signal;
|
|
231
|
+
it.each([
|
|
232
|
+
{
|
|
233
|
+
name: 'perform an exact replacement',
|
|
234
|
+
content: 'hello world',
|
|
235
|
+
old_string: 'world',
|
|
236
|
+
new_string: 'moon',
|
|
237
|
+
expected: 'hello moon',
|
|
238
|
+
occurrences: 1,
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: 'perform a flexible, whitespace-insensitive replacement',
|
|
242
|
+
content: ' hello\n world\n',
|
|
243
|
+
old_string: 'hello\nworld',
|
|
244
|
+
new_string: 'goodbye\nmoon',
|
|
245
|
+
expected: ' goodbye\n moon\n',
|
|
246
|
+
occurrences: 1,
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: 'return 0 occurrences if no match is found',
|
|
250
|
+
content: 'hello world',
|
|
251
|
+
old_string: 'nomatch',
|
|
252
|
+
new_string: 'moon',
|
|
253
|
+
expected: 'hello world',
|
|
254
|
+
occurrences: 0,
|
|
255
|
+
},
|
|
256
|
+
])('should $name', async ({ content, old_string, new_string, expected, occurrences }) => {
|
|
257
|
+
const result = await calculateReplacement(mockConfig, {
|
|
258
|
+
params: {
|
|
259
|
+
file_path: 'test.txt',
|
|
260
|
+
instruction: 'test',
|
|
261
|
+
old_string,
|
|
262
|
+
new_string,
|
|
263
|
+
},
|
|
264
|
+
currentContent: content,
|
|
265
|
+
abortSignal,
|
|
266
|
+
});
|
|
267
|
+
expect(result.newContent).toBe(expected);
|
|
268
|
+
expect(result.occurrences).toBe(occurrences);
|
|
269
|
+
});
|
|
270
|
+
it('should perform a regex-based replacement for flexible intra-line whitespace', async () => {
|
|
271
|
+
// This case would fail with the previous exact and line-trimming flexible logic
|
|
272
|
+
// because the whitespace *within* the line is different.
|
|
273
|
+
const content = ' function myFunc( a, b ) {\n return a + b;\n }';
|
|
274
|
+
const result = await calculateReplacement(mockConfig, {
|
|
275
|
+
params: {
|
|
276
|
+
file_path: 'test.js',
|
|
277
|
+
instruction: 'test',
|
|
278
|
+
old_string: 'function myFunc(a, b) {', // Note the normalized whitespace
|
|
279
|
+
new_string: 'const yourFunc = (a, b) => {',
|
|
280
|
+
},
|
|
281
|
+
currentContent: content,
|
|
282
|
+
abortSignal,
|
|
283
|
+
});
|
|
284
|
+
// The indentation from the original line should be preserved and applied to the new string.
|
|
285
|
+
const expectedContent = ' const yourFunc = (a, b) => {\n return a + b;\n }';
|
|
286
|
+
expect(result.newContent).toBe(expectedContent);
|
|
287
|
+
expect(result.occurrences).toBe(1);
|
|
288
|
+
});
|
|
289
|
+
});
|
|
236
290
|
describe('validateToolParams', () => {
|
|
237
291
|
it('should return null for valid params', () => {
|
|
238
292
|
const params = {
|
|
239
293
|
file_path: path.join(rootDir, 'test.txt'),
|
|
294
|
+
instruction: 'An instruction',
|
|
240
295
|
old_string: 'old',
|
|
241
296
|
new_string: 'new',
|
|
242
297
|
};
|
|
243
298
|
expect(tool.validateToolParams(params)).toBeNull();
|
|
244
299
|
});
|
|
245
|
-
it('should return error
|
|
300
|
+
it('should return an error if path is outside the workspace', () => {
|
|
246
301
|
const params = {
|
|
247
|
-
file_path: path.join(
|
|
302
|
+
file_path: path.join(os.tmpdir(), 'outside.txt'),
|
|
303
|
+
instruction: 'An instruction',
|
|
248
304
|
old_string: 'old',
|
|
249
305
|
new_string: 'new',
|
|
250
306
|
};
|
|
251
|
-
|
|
252
|
-
expect(error).toContain('File path must be within one of the workspace directories');
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
describe('shouldConfirmExecute', () => {
|
|
256
|
-
const testFile = 'edit_me.txt';
|
|
257
|
-
let filePath;
|
|
258
|
-
beforeEach(() => {
|
|
259
|
-
filePath = path.join(rootDir, testFile);
|
|
260
|
-
});
|
|
261
|
-
it('should resolve relative path and request confirmation', async () => {
|
|
262
|
-
fs.writeFileSync(filePath, 'some old content here');
|
|
263
|
-
const params = {
|
|
264
|
-
file_path: testFile, // relative path
|
|
265
|
-
old_string: 'old',
|
|
266
|
-
new_string: 'new',
|
|
267
|
-
};
|
|
268
|
-
// ensureCorrectEdit will be called by shouldConfirmExecute
|
|
269
|
-
mockEnsureCorrectEdit.mockResolvedValueOnce({
|
|
270
|
-
params: { ...params, file_path: filePath },
|
|
271
|
-
occurrences: 1,
|
|
272
|
-
});
|
|
273
|
-
const invocation = tool.build(params);
|
|
274
|
-
const confirmation = await invocation.shouldConfirmExecute(new AbortController().signal);
|
|
275
|
-
expect(confirmation).toEqual(expect.objectContaining({
|
|
276
|
-
title: `Confirm Edit: ${testFile}`,
|
|
277
|
-
fileName: testFile,
|
|
278
|
-
fileDiff: expect.any(String),
|
|
279
|
-
}));
|
|
280
|
-
});
|
|
281
|
-
it('should request confirmation for valid edit', async () => {
|
|
282
|
-
fs.writeFileSync(filePath, 'some old content here');
|
|
283
|
-
const params = {
|
|
284
|
-
file_path: filePath,
|
|
285
|
-
old_string: 'old',
|
|
286
|
-
new_string: 'new',
|
|
287
|
-
};
|
|
288
|
-
// ensureCorrectEdit will be called by shouldConfirmExecute
|
|
289
|
-
mockEnsureCorrectEdit.mockResolvedValueOnce({ params, occurrences: 1 });
|
|
290
|
-
const invocation = tool.build(params);
|
|
291
|
-
const confirmation = await invocation.shouldConfirmExecute(new AbortController().signal);
|
|
292
|
-
expect(confirmation).toEqual(expect.objectContaining({
|
|
293
|
-
title: `Confirm Edit: ${testFile}`,
|
|
294
|
-
fileName: testFile,
|
|
295
|
-
fileDiff: expect.any(String),
|
|
296
|
-
}));
|
|
297
|
-
});
|
|
298
|
-
it('should return false if old_string is not found (ensureCorrectEdit returns 0)', async () => {
|
|
299
|
-
fs.writeFileSync(filePath, 'some content here');
|
|
300
|
-
const params = {
|
|
301
|
-
file_path: filePath,
|
|
302
|
-
old_string: 'not_found',
|
|
303
|
-
new_string: 'new',
|
|
304
|
-
};
|
|
305
|
-
mockEnsureCorrectEdit.mockResolvedValueOnce({ params, occurrences: 0 });
|
|
306
|
-
const invocation = tool.build(params);
|
|
307
|
-
const confirmation = await invocation.shouldConfirmExecute(new AbortController().signal);
|
|
308
|
-
expect(confirmation).toBe(false);
|
|
309
|
-
});
|
|
310
|
-
it('should return false if multiple occurrences of old_string are found (ensureCorrectEdit returns > 1)', async () => {
|
|
311
|
-
fs.writeFileSync(filePath, 'old old content here');
|
|
312
|
-
const params = {
|
|
313
|
-
file_path: filePath,
|
|
314
|
-
old_string: 'old',
|
|
315
|
-
new_string: 'new',
|
|
316
|
-
};
|
|
317
|
-
mockEnsureCorrectEdit.mockResolvedValueOnce({ params, occurrences: 2 });
|
|
318
|
-
const invocation = tool.build(params);
|
|
319
|
-
const confirmation = await invocation.shouldConfirmExecute(new AbortController().signal);
|
|
320
|
-
expect(confirmation).toBe(false);
|
|
321
|
-
});
|
|
322
|
-
it('should request confirmation for creating a new file (empty old_string)', async () => {
|
|
323
|
-
const newFileName = 'new_file.txt';
|
|
324
|
-
const newFilePath = path.join(rootDir, newFileName);
|
|
325
|
-
const params = {
|
|
326
|
-
file_path: newFilePath,
|
|
327
|
-
old_string: '',
|
|
328
|
-
new_string: 'new file content',
|
|
329
|
-
};
|
|
330
|
-
// ensureCorrectEdit might not be called if old_string is empty,
|
|
331
|
-
// as shouldConfirmExecute handles this for diff generation.
|
|
332
|
-
// If it is called, it should return 0 occurrences for a new file.
|
|
333
|
-
mockEnsureCorrectEdit.mockResolvedValueOnce({ params, occurrences: 0 });
|
|
334
|
-
const invocation = tool.build(params);
|
|
335
|
-
const confirmation = await invocation.shouldConfirmExecute(new AbortController().signal);
|
|
336
|
-
expect(confirmation).toEqual(expect.objectContaining({
|
|
337
|
-
title: `Confirm Edit: ${newFileName}`,
|
|
338
|
-
fileName: newFileName,
|
|
339
|
-
fileDiff: expect.any(String),
|
|
340
|
-
}));
|
|
341
|
-
});
|
|
342
|
-
it('should use corrected params from ensureCorrectEdit for diff generation', async () => {
|
|
343
|
-
const originalContent = 'This is the original string to be replaced.';
|
|
344
|
-
const originalOldString = 'original string';
|
|
345
|
-
const originalNewString = 'new string';
|
|
346
|
-
const correctedOldString = 'original string to be replaced'; // More specific
|
|
347
|
-
const correctedNewString = 'completely new string'; // Different replacement
|
|
348
|
-
const expectedFinalContent = 'This is the completely new string.';
|
|
349
|
-
fs.writeFileSync(filePath, originalContent);
|
|
350
|
-
const params = {
|
|
351
|
-
file_path: filePath,
|
|
352
|
-
old_string: originalOldString,
|
|
353
|
-
new_string: originalNewString,
|
|
354
|
-
};
|
|
355
|
-
// The main beforeEach already calls mockEnsureCorrectEdit.mockReset()
|
|
356
|
-
// Set a specific mock for this test case
|
|
357
|
-
let mockCalled = false;
|
|
358
|
-
mockEnsureCorrectEdit.mockImplementationOnce(async (_, content, p, client, baseClient) => {
|
|
359
|
-
mockCalled = true;
|
|
360
|
-
expect(content).toBe(originalContent);
|
|
361
|
-
expect(p).toBe(params);
|
|
362
|
-
expect(client).toBe(geminiClient);
|
|
363
|
-
expect(baseClient).toBe(baseLlmClient);
|
|
364
|
-
return {
|
|
365
|
-
params: {
|
|
366
|
-
file_path: filePath,
|
|
367
|
-
old_string: correctedOldString,
|
|
368
|
-
new_string: correctedNewString,
|
|
369
|
-
},
|
|
370
|
-
occurrences: 1,
|
|
371
|
-
};
|
|
372
|
-
});
|
|
373
|
-
const invocation = tool.build(params);
|
|
374
|
-
const confirmation = (await invocation.shouldConfirmExecute(new AbortController().signal));
|
|
375
|
-
expect(mockCalled).toBe(true); // Check if the mock implementation was run
|
|
376
|
-
// expect(mockEnsureCorrectEdit).toHaveBeenCalledWith(originalContent, params, expect.anything()); // Keep this commented for now
|
|
377
|
-
expect(confirmation).toEqual(expect.objectContaining({
|
|
378
|
-
title: `Confirm Edit: ${testFile}`,
|
|
379
|
-
fileName: testFile,
|
|
380
|
-
}));
|
|
381
|
-
// Check that the diff is based on the corrected strings leading to the new state
|
|
382
|
-
expect(confirmation.fileDiff).toContain(`-${originalContent}`);
|
|
383
|
-
expect(confirmation.fileDiff).toContain(`+${expectedFinalContent}`);
|
|
384
|
-
// Verify that applying the correctedOldString and correctedNewString to originalContent
|
|
385
|
-
// indeed produces the expectedFinalContent, which is what the diff should reflect.
|
|
386
|
-
const patchedContent = originalContent.replace(correctedOldString, // This was the string identified by ensureCorrectEdit for replacement
|
|
387
|
-
correctedNewString);
|
|
388
|
-
expect(patchedContent).toBe(expectedFinalContent);
|
|
389
|
-
});
|
|
390
|
-
it('should rethrow calculateEdit errors when the abort signal is triggered', async () => {
|
|
391
|
-
const filePath = path.join(rootDir, 'abort-confirmation.txt');
|
|
392
|
-
const params = {
|
|
393
|
-
file_path: filePath,
|
|
394
|
-
old_string: 'old',
|
|
395
|
-
new_string: 'new',
|
|
396
|
-
};
|
|
397
|
-
const invocation = tool.build(params);
|
|
398
|
-
const abortController = new AbortController();
|
|
399
|
-
const abortError = new Error('Abort requested');
|
|
400
|
-
const calculateSpy = vi
|
|
401
|
-
.spyOn(invocation, 'calculateEdit')
|
|
402
|
-
.mockImplementation(async () => {
|
|
403
|
-
if (!abortController.signal.aborted) {
|
|
404
|
-
abortController.abort();
|
|
405
|
-
}
|
|
406
|
-
throw abortError;
|
|
407
|
-
});
|
|
408
|
-
await expect(invocation.shouldConfirmExecute(abortController.signal)).rejects.toBe(abortError);
|
|
409
|
-
calculateSpy.mockRestore();
|
|
307
|
+
expect(tool.validateToolParams(params)).toMatch(/must be within one of the workspace directories/);
|
|
410
308
|
});
|
|
411
309
|
});
|
|
412
310
|
describe('execute', () => {
|
|
@@ -414,53 +312,17 @@ describe('EditTool', () => {
|
|
|
414
312
|
let filePath;
|
|
415
313
|
beforeEach(() => {
|
|
416
314
|
filePath = path.join(rootDir, testFile);
|
|
417
|
-
// Default for execute tests, can be overridden
|
|
418
|
-
mockEnsureCorrectEdit.mockImplementation(async (_, content, params) => {
|
|
419
|
-
let occurrences = 0;
|
|
420
|
-
if (params.old_string && content) {
|
|
421
|
-
let index = content.indexOf(params.old_string);
|
|
422
|
-
while (index !== -1) {
|
|
423
|
-
occurrences++;
|
|
424
|
-
index = content.indexOf(params.old_string, index + 1);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
else if (params.old_string === '') {
|
|
428
|
-
occurrences = 0;
|
|
429
|
-
}
|
|
430
|
-
return { params, occurrences };
|
|
431
|
-
});
|
|
432
|
-
});
|
|
433
|
-
it('should resolve relative path and execute successfully', async () => {
|
|
434
|
-
const initialContent = 'This is some old text.';
|
|
435
|
-
const newContent = 'This is some new text.';
|
|
436
|
-
fs.writeFileSync(filePath, initialContent, 'utf8');
|
|
437
|
-
const params = {
|
|
438
|
-
file_path: testFile, // relative path
|
|
439
|
-
old_string: 'old',
|
|
440
|
-
new_string: 'new',
|
|
441
|
-
};
|
|
442
|
-
const invocation = tool.build(params);
|
|
443
|
-
const result = await invocation.execute(new AbortController().signal);
|
|
444
|
-
expect(result.llmContent).toMatch(/Successfully modified file/);
|
|
445
|
-
expect(fs.readFileSync(filePath, 'utf8')).toBe(newContent);
|
|
446
|
-
});
|
|
447
|
-
it('should throw error if file path is empty', async () => {
|
|
448
|
-
const params = {
|
|
449
|
-
file_path: '',
|
|
450
|
-
old_string: 'old',
|
|
451
|
-
new_string: 'new',
|
|
452
|
-
};
|
|
453
|
-
expect(() => tool.build(params)).toThrow(/The 'file_path' parameter must be non-empty./);
|
|
454
315
|
});
|
|
455
316
|
it('should reject when calculateEdit fails after an abort signal', async () => {
|
|
456
317
|
const params = {
|
|
457
318
|
file_path: path.join(rootDir, 'abort-execute.txt'),
|
|
319
|
+
instruction: 'Abort during execute',
|
|
458
320
|
old_string: 'old',
|
|
459
321
|
new_string: 'new',
|
|
460
322
|
};
|
|
461
323
|
const invocation = tool.build(params);
|
|
462
324
|
const abortController = new AbortController();
|
|
463
|
-
const abortError = new Error('Abort requested during
|
|
325
|
+
const abortError = new Error('Abort requested during edit execution');
|
|
464
326
|
const calculateSpy = vi
|
|
465
327
|
.spyOn(invocation, 'calculateEdit')
|
|
466
328
|
.mockImplementation(async () => {
|
|
@@ -474,16 +336,14 @@ describe('EditTool', () => {
|
|
|
474
336
|
});
|
|
475
337
|
it('should edit an existing file and return diff with fileName', async () => {
|
|
476
338
|
const initialContent = 'This is some old text.';
|
|
477
|
-
const newContent = 'This is some new text.';
|
|
339
|
+
const newContent = 'This is some new text.';
|
|
478
340
|
fs.writeFileSync(filePath, initialContent, 'utf8');
|
|
479
341
|
const params = {
|
|
480
342
|
file_path: filePath,
|
|
343
|
+
instruction: 'Replace old with new',
|
|
481
344
|
old_string: 'old',
|
|
482
345
|
new_string: 'new',
|
|
483
346
|
};
|
|
484
|
-
// Specific mock for this test's execution path in calculateEdit
|
|
485
|
-
// ensureCorrectEdit is NOT called by calculateEdit, only by shouldConfirmExecute
|
|
486
|
-
// So, the default mockEnsureCorrectEdit should correctly return 1 occurrence for 'old' in initialContent
|
|
487
347
|
const invocation = tool.build(params);
|
|
488
348
|
const result = await invocation.execute(new AbortController().signal);
|
|
489
349
|
expect(result.llmContent).toMatch(/Successfully modified file/);
|
|
@@ -493,196 +353,124 @@ describe('EditTool', () => {
|
|
|
493
353
|
expect(display.fileDiff).toMatch(newContent);
|
|
494
354
|
expect(display.fileName).toBe(testFile);
|
|
495
355
|
});
|
|
496
|
-
it('should create a new file if old_string is empty and file does not exist, and return created message', async () => {
|
|
497
|
-
const newFileName = 'brand_new_file.txt';
|
|
498
|
-
const newFilePath = path.join(rootDir, newFileName);
|
|
499
|
-
const fileContent = 'Content for the new file.';
|
|
500
|
-
const params = {
|
|
501
|
-
file_path: newFilePath,
|
|
502
|
-
old_string: '',
|
|
503
|
-
new_string: fileContent,
|
|
504
|
-
};
|
|
505
|
-
mockConfig.getApprovalMode.mockReturnValueOnce(ApprovalMode.AUTO_EDIT);
|
|
506
|
-
const invocation = tool.build(params);
|
|
507
|
-
const result = await invocation.execute(new AbortController().signal);
|
|
508
|
-
expect(result.llmContent).toMatch(/Created new file/);
|
|
509
|
-
expect(fs.existsSync(newFilePath)).toBe(true);
|
|
510
|
-
expect(fs.readFileSync(newFilePath, 'utf8')).toBe(fileContent);
|
|
511
|
-
const display = result.returnDisplay;
|
|
512
|
-
expect(display.fileDiff).toMatch(/\+Content for the new file\./);
|
|
513
|
-
expect(display.fileName).toBe(newFileName);
|
|
514
|
-
expect(result.returnDisplay.diffStat).toStrictEqual({
|
|
515
|
-
model_added_lines: 1,
|
|
516
|
-
model_removed_lines: 0,
|
|
517
|
-
model_added_chars: 25,
|
|
518
|
-
model_removed_chars: 0,
|
|
519
|
-
user_added_lines: 0,
|
|
520
|
-
user_removed_lines: 0,
|
|
521
|
-
user_added_chars: 0,
|
|
522
|
-
user_removed_chars: 0,
|
|
523
|
-
});
|
|
524
|
-
});
|
|
525
356
|
it('should return error if old_string is not found in file', async () => {
|
|
526
357
|
fs.writeFileSync(filePath, 'Some content.', 'utf8');
|
|
527
358
|
const params = {
|
|
528
359
|
file_path: filePath,
|
|
360
|
+
instruction: 'Replace non-existent text',
|
|
529
361
|
old_string: 'nonexistent',
|
|
530
362
|
new_string: 'replacement',
|
|
531
363
|
};
|
|
532
|
-
// The default mockEnsureCorrectEdit will return 0 occurrences for 'nonexistent'
|
|
533
364
|
const invocation = tool.build(params);
|
|
534
365
|
const result = await invocation.execute(new AbortController().signal);
|
|
535
|
-
expect(result.llmContent).toMatch(/0 occurrences found for old_string
|
|
366
|
+
expect(result.llmContent).toMatch(/0 occurrences found for old_string/);
|
|
536
367
|
expect(result.returnDisplay).toMatch(/Failed to edit, could not find the string to replace./);
|
|
368
|
+
expect(mockFixLLMEditWithInstruction).toHaveBeenCalled();
|
|
537
369
|
});
|
|
538
|
-
it('should
|
|
539
|
-
|
|
540
|
-
const
|
|
541
|
-
|
|
542
|
-
old_string: 'old',
|
|
543
|
-
new_string: 'new',
|
|
544
|
-
};
|
|
545
|
-
// The default mockEnsureCorrectEdit will return 2 occurrences for 'old'
|
|
546
|
-
const invocation = tool.build(params);
|
|
547
|
-
const result = await invocation.execute(new AbortController().signal);
|
|
548
|
-
expect(result.llmContent).toMatch(/Expected 1 occurrence but found 2 for old_string in file/);
|
|
549
|
-
expect(result.returnDisplay).toMatch(/Failed to edit, expected 1 occurrence but found 2/);
|
|
550
|
-
});
|
|
551
|
-
it('should successfully replace multiple occurrences when expected_replacements specified', async () => {
|
|
552
|
-
fs.writeFileSync(filePath, 'old text\nold text\nold text', 'utf8');
|
|
370
|
+
it('should succeed if FixLLMEditWithInstruction corrects the params', async () => {
|
|
371
|
+
const initialContent = 'This is some original text.';
|
|
372
|
+
const finalContent = 'This is some brand new text.';
|
|
373
|
+
fs.writeFileSync(filePath, initialContent, 'utf8');
|
|
553
374
|
const params = {
|
|
554
375
|
file_path: filePath,
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
376
|
+
instruction: 'Replace original with brand new',
|
|
377
|
+
old_string: 'wrong text', // This will fail first
|
|
378
|
+
new_string: 'brand new text',
|
|
558
379
|
};
|
|
380
|
+
mockFixLLMEditWithInstruction.mockResolvedValueOnce({
|
|
381
|
+
noChangesRequired: false,
|
|
382
|
+
search: 'original text', // The corrected search string
|
|
383
|
+
replace: 'brand new text',
|
|
384
|
+
explanation: 'Corrected the search string to match the file content.',
|
|
385
|
+
});
|
|
559
386
|
const invocation = tool.build(params);
|
|
560
387
|
const result = await invocation.execute(new AbortController().signal);
|
|
388
|
+
expect(result.error).toBeUndefined();
|
|
561
389
|
expect(result.llmContent).toMatch(/Successfully modified file/);
|
|
562
|
-
expect(fs.readFileSync(filePath, 'utf8')).toBe(
|
|
563
|
-
|
|
564
|
-
expect(display.fileDiff).toMatch(/-old text\n-old text\n-old text/);
|
|
565
|
-
expect(display.fileDiff).toMatch(/\+new text\n\+new text\n\+new text/);
|
|
566
|
-
expect(display.fileName).toBe(testFile);
|
|
567
|
-
expect(result.returnDisplay.diffStat).toStrictEqual({
|
|
568
|
-
model_added_lines: 3,
|
|
569
|
-
model_removed_lines: 3,
|
|
570
|
-
model_added_chars: 24,
|
|
571
|
-
model_removed_chars: 24,
|
|
572
|
-
user_added_lines: 0,
|
|
573
|
-
user_removed_lines: 0,
|
|
574
|
-
user_added_chars: 0,
|
|
575
|
-
user_removed_chars: 0,
|
|
576
|
-
});
|
|
390
|
+
expect(fs.readFileSync(filePath, 'utf8')).toBe(finalContent);
|
|
391
|
+
expect(mockFixLLMEditWithInstruction).toHaveBeenCalledTimes(1);
|
|
577
392
|
});
|
|
578
|
-
it('should
|
|
579
|
-
|
|
393
|
+
it('should preserve CRLF line endings when editing a file', async () => {
|
|
394
|
+
const initialContent = 'line one\r\nline two\r\n';
|
|
395
|
+
const newContent = 'line one\r\nline three\r\n';
|
|
396
|
+
fs.writeFileSync(filePath, initialContent, 'utf8');
|
|
580
397
|
const params = {
|
|
581
398
|
file_path: filePath,
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
399
|
+
instruction: 'Replace two with three',
|
|
400
|
+
old_string: 'line two',
|
|
401
|
+
new_string: 'line three',
|
|
585
402
|
};
|
|
586
403
|
const invocation = tool.build(params);
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
expect(
|
|
404
|
+
await invocation.execute(new AbortController().signal);
|
|
405
|
+
const finalContent = fs.readFileSync(filePath, 'utf8');
|
|
406
|
+
expect(finalContent).toBe(newContent);
|
|
590
407
|
});
|
|
591
|
-
it('should
|
|
592
|
-
|
|
408
|
+
it('should create a new file with CRLF line endings if new_string has them', async () => {
|
|
409
|
+
const newContentWithCRLF = 'new line one\r\nnew line two\r\n';
|
|
593
410
|
const params = {
|
|
594
411
|
file_path: filePath,
|
|
412
|
+
instruction: 'Create a new file',
|
|
595
413
|
old_string: '',
|
|
596
|
-
new_string:
|
|
414
|
+
new_string: newContentWithCRLF,
|
|
597
415
|
};
|
|
598
416
|
const invocation = tool.build(params);
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
expect(
|
|
417
|
+
await invocation.execute(new AbortController().signal);
|
|
418
|
+
const finalContent = fs.readFileSync(filePath, 'utf8');
|
|
419
|
+
expect(finalContent).toBe(newContentWithCRLF);
|
|
602
420
|
});
|
|
603
|
-
it('should
|
|
604
|
-
const initialContent = '
|
|
421
|
+
it('should return NO_CHANGE if FixLLMEditWithInstruction determines no changes are needed', async () => {
|
|
422
|
+
const initialContent = 'The price is $100.';
|
|
605
423
|
fs.writeFileSync(filePath, initialContent, 'utf8');
|
|
606
424
|
const params = {
|
|
607
425
|
file_path: filePath,
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
ai_proposed_content: 'Line 1\nAI line\nLine 3\nLine 4\nLine 5\n',
|
|
426
|
+
instruction: 'Ensure the price is $100',
|
|
427
|
+
old_string: 'price is $50', // Incorrect old string
|
|
428
|
+
new_string: 'price is $100',
|
|
612
429
|
};
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
model_added_lines: 1,
|
|
619
|
-
model_removed_lines: 1,
|
|
620
|
-
model_added_chars: 7,
|
|
621
|
-
model_removed_chars: 8,
|
|
622
|
-
user_added_lines: 1,
|
|
623
|
-
user_removed_lines: 1,
|
|
624
|
-
user_added_chars: 8,
|
|
625
|
-
user_removed_chars: 7,
|
|
430
|
+
mockFixLLMEditWithInstruction.mockResolvedValueOnce({
|
|
431
|
+
noChangesRequired: true,
|
|
432
|
+
search: '',
|
|
433
|
+
replace: '',
|
|
434
|
+
explanation: 'The price is already correctly set to $100.',
|
|
626
435
|
});
|
|
627
|
-
});
|
|
628
|
-
it.each([
|
|
629
|
-
{
|
|
630
|
-
name: 'modified_by_user is false',
|
|
631
|
-
modifiedByUser: false,
|
|
632
|
-
},
|
|
633
|
-
{
|
|
634
|
-
name: 'modified_by_user is not provided',
|
|
635
|
-
modifiedByUser: undefined,
|
|
636
|
-
},
|
|
637
|
-
])('should not include modification message when $name', async ({ modifiedByUser }) => {
|
|
638
|
-
const initialContent = 'This is some old text.';
|
|
639
|
-
fs.writeFileSync(filePath, initialContent, 'utf8');
|
|
640
|
-
const params = {
|
|
641
|
-
file_path: filePath,
|
|
642
|
-
old_string: 'old',
|
|
643
|
-
new_string: 'new',
|
|
644
|
-
...(modifiedByUser !== undefined && {
|
|
645
|
-
modified_by_user: modifiedByUser,
|
|
646
|
-
}),
|
|
647
|
-
};
|
|
648
|
-
mockConfig.getApprovalMode.mockReturnValueOnce(ApprovalMode.AUTO_EDIT);
|
|
649
436
|
const invocation = tool.build(params);
|
|
650
437
|
const result = await invocation.execute(new AbortController().signal);
|
|
651
|
-
expect(result.
|
|
438
|
+
expect(result.error?.type).toBe(ToolErrorType.EDIT_NO_CHANGE_LLM_JUDGEMENT);
|
|
439
|
+
expect(result.llmContent).toMatch(/A secondary check by an LLM determined/);
|
|
440
|
+
expect(fs.readFileSync(filePath, 'utf8')).toBe(initialContent); // File is unchanged
|
|
652
441
|
});
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
new_string: 'identical',
|
|
660
|
-
};
|
|
661
|
-
const invocation = tool.build(params);
|
|
662
|
-
const result = await invocation.execute(new AbortController().signal);
|
|
663
|
-
expect(result.llmContent).toMatch(/No changes to apply/);
|
|
664
|
-
expect(result.returnDisplay).toMatch(/No changes to apply/);
|
|
442
|
+
});
|
|
443
|
+
describe('self-correction with content refresh to pull in external edits', () => {
|
|
444
|
+
const testFile = 'test.txt';
|
|
445
|
+
let filePath;
|
|
446
|
+
beforeEach(() => {
|
|
447
|
+
filePath = path.join(rootDir, testFile);
|
|
665
448
|
});
|
|
666
|
-
it('should
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
const initialContent = 'line 1\nline 2\nline 3'; // Note the double space
|
|
449
|
+
it('should use refreshed file content for self-correction if file was modified externally', async () => {
|
|
450
|
+
const initialContent = 'This is the original content.';
|
|
451
|
+
const externallyModifiedContent = 'This is the externally modified content.';
|
|
670
452
|
fs.writeFileSync(filePath, initialContent, 'utf8');
|
|
671
453
|
const params = {
|
|
672
454
|
file_path: filePath,
|
|
673
|
-
|
|
674
|
-
old_string: '
|
|
675
|
-
new_string: '
|
|
455
|
+
instruction: 'Replace "externally modified content" with "externally modified string"',
|
|
456
|
+
old_string: 'externally modified content', // This will fail the first attempt, triggering self-correction.
|
|
457
|
+
new_string: 'externally modified string',
|
|
676
458
|
};
|
|
677
|
-
//
|
|
678
|
-
|
|
679
|
-
|
|
459
|
+
// Spy on `readTextFile` to simulate an external file change between reads.
|
|
460
|
+
const readTextFileSpy = vi
|
|
461
|
+
.spyOn(fileSystemService, 'readTextFile')
|
|
462
|
+
.mockResolvedValueOnce(initialContent) // First call in `calculateEdit`
|
|
463
|
+
.mockResolvedValueOnce(externallyModifiedContent); // Second call in `attemptSelfCorrection`
|
|
680
464
|
const invocation = tool.build(params);
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
expect(
|
|
684
|
-
//
|
|
685
|
-
expect(
|
|
465
|
+
await invocation.execute(new AbortController().signal);
|
|
466
|
+
// Assert that the file was read twice (initial read, then re-read for hash comparison).
|
|
467
|
+
expect(readTextFileSpy).toHaveBeenCalledTimes(2);
|
|
468
|
+
// Assert that the self-correction LLM was called with the updated content and a specific message.
|
|
469
|
+
expect(mockFixLLMEditWithInstruction).toHaveBeenCalledWith(expect.any(String), // instruction
|
|
470
|
+
params.old_string, params.new_string, expect.stringContaining('However, the file has been modified by either the user or an external process'), // errorForLlmEditFixer
|
|
471
|
+
externallyModifiedContent, // The new content for correction
|
|
472
|
+
expect.any(Object), // baseLlmClient
|
|
473
|
+
expect.any(Object));
|
|
686
474
|
});
|
|
687
475
|
});
|
|
688
476
|
describe('Error Scenarios', () => {
|
|
@@ -693,163 +481,85 @@ describe('EditTool', () => {
|
|
|
693
481
|
});
|
|
694
482
|
it.each([
|
|
695
483
|
{
|
|
696
|
-
name: 'FILE_NOT_FOUND
|
|
697
|
-
setup: () => { },
|
|
698
|
-
params: {
|
|
484
|
+
name: 'FILE_NOT_FOUND',
|
|
485
|
+
setup: () => { }, // no file created
|
|
486
|
+
params: { old_string: 'any', new_string: 'new' },
|
|
699
487
|
expectedError: ToolErrorType.FILE_NOT_FOUND,
|
|
700
|
-
isAsyncTest: true,
|
|
701
488
|
},
|
|
702
489
|
{
|
|
703
|
-
name: 'ATTEMPT_TO_CREATE_EXISTING_FILE
|
|
490
|
+
name: 'ATTEMPT_TO_CREATE_EXISTING_FILE',
|
|
704
491
|
setup: (fp) => fs.writeFileSync(fp, 'existing content', 'utf8'),
|
|
705
|
-
params: {
|
|
492
|
+
params: { old_string: '', new_string: 'new content' },
|
|
706
493
|
expectedError: ToolErrorType.ATTEMPT_TO_CREATE_EXISTING_FILE,
|
|
707
|
-
isAsyncTest: true,
|
|
708
494
|
},
|
|
709
495
|
{
|
|
710
|
-
name: 'NO_OCCURRENCE_FOUND
|
|
496
|
+
name: 'NO_OCCURRENCE_FOUND',
|
|
711
497
|
setup: (fp) => fs.writeFileSync(fp, 'content', 'utf8'),
|
|
712
|
-
params: {
|
|
498
|
+
params: { old_string: 'not-found', new_string: 'new' },
|
|
713
499
|
expectedError: ToolErrorType.EDIT_NO_OCCURRENCE_FOUND,
|
|
714
|
-
isAsyncTest: true,
|
|
715
500
|
},
|
|
716
501
|
{
|
|
717
|
-
name: 'EXPECTED_OCCURRENCE_MISMATCH
|
|
502
|
+
name: 'EXPECTED_OCCURRENCE_MISMATCH',
|
|
718
503
|
setup: (fp) => fs.writeFileSync(fp, 'one one two', 'utf8'),
|
|
719
|
-
params: {
|
|
720
|
-
file_path: '',
|
|
721
|
-
old_string: 'one',
|
|
722
|
-
new_string: 'new',
|
|
723
|
-
expected_replacements: 3,
|
|
724
|
-
},
|
|
504
|
+
params: { old_string: 'one', new_string: 'new' },
|
|
725
505
|
expectedError: ToolErrorType.EDIT_EXPECTED_OCCURRENCE_MISMATCH,
|
|
726
|
-
isAsyncTest: true,
|
|
727
|
-
},
|
|
728
|
-
{
|
|
729
|
-
name: 'NO_CHANGE error',
|
|
730
|
-
setup: (fp) => fs.writeFileSync(fp, 'content', 'utf8'),
|
|
731
|
-
params: { file_path: '', old_string: 'content', new_string: 'content' },
|
|
732
|
-
expectedError: ToolErrorType.EDIT_NO_CHANGE,
|
|
733
|
-
isAsyncTest: true,
|
|
734
506
|
},
|
|
735
|
-
|
|
736
|
-
name: 'relative path (should not throw)',
|
|
737
|
-
setup: () => { },
|
|
738
|
-
params: {
|
|
739
|
-
file_path: 'relative/path.txt',
|
|
740
|
-
old_string: 'a',
|
|
741
|
-
new_string: 'b',
|
|
742
|
-
},
|
|
743
|
-
expectedError: null,
|
|
744
|
-
isAsyncTest: false,
|
|
745
|
-
},
|
|
746
|
-
{
|
|
747
|
-
name: 'FILE_WRITE_FAILURE on write error',
|
|
748
|
-
setup: (fp) => {
|
|
749
|
-
fs.writeFileSync(fp, 'content', 'utf8');
|
|
750
|
-
fs.chmodSync(fp, '444');
|
|
751
|
-
},
|
|
752
|
-
params: {
|
|
753
|
-
file_path: '',
|
|
754
|
-
old_string: 'content',
|
|
755
|
-
new_string: 'new content',
|
|
756
|
-
},
|
|
757
|
-
expectedError: ToolErrorType.FILE_WRITE_FAILURE,
|
|
758
|
-
isAsyncTest: true,
|
|
759
|
-
},
|
|
760
|
-
])('should return $name', async ({ setup, params, expectedError, isAsyncTest }) => {
|
|
761
|
-
const testParams = {
|
|
762
|
-
...params,
|
|
763
|
-
file_path: params.file_path || filePath,
|
|
764
|
-
};
|
|
507
|
+
])('should return $name error', async ({ setup, params, expectedError }) => {
|
|
765
508
|
setup(filePath);
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
}
|
|
509
|
+
const invocation = tool.build({
|
|
510
|
+
file_path: filePath,
|
|
511
|
+
instruction: 'test',
|
|
512
|
+
...params,
|
|
513
|
+
});
|
|
514
|
+
const result = await invocation.execute(new AbortController().signal);
|
|
515
|
+
expect(result.error?.type).toBe(expectedError);
|
|
774
516
|
});
|
|
775
517
|
});
|
|
776
|
-
describe('
|
|
518
|
+
describe('expected_replacements', () => {
|
|
519
|
+
const testFile = 'replacements_test.txt';
|
|
520
|
+
let filePath;
|
|
521
|
+
beforeEach(() => {
|
|
522
|
+
filePath = path.join(rootDir, testFile);
|
|
523
|
+
});
|
|
777
524
|
it.each([
|
|
778
525
|
{
|
|
779
|
-
name: '
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
},
|
|
785
|
-
{
|
|
786
|
-
name: 'different strings (full)',
|
|
787
|
-
fileName: 'test.txt',
|
|
788
|
-
oldStr: 'this is the old string value',
|
|
789
|
-
newStr: 'this is the new string value',
|
|
790
|
-
expected: 'test.txt: this is the old string value => this is the new string value',
|
|
526
|
+
name: 'succeed when occurrences match expected_replacements',
|
|
527
|
+
content: 'foo foo foo',
|
|
528
|
+
expected: 3,
|
|
529
|
+
shouldSucceed: true,
|
|
530
|
+
finalContent: 'bar bar bar',
|
|
791
531
|
},
|
|
792
532
|
{
|
|
793
|
-
name: '
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
expected: 'short.txt: old => new',
|
|
533
|
+
name: 'fail when occurrences do not match expected_replacements',
|
|
534
|
+
content: 'foo foo foo',
|
|
535
|
+
expected: 2,
|
|
536
|
+
shouldSucceed: false,
|
|
798
537
|
},
|
|
799
538
|
{
|
|
800
|
-
name: '
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
expected: 'long.txt: this is a very long old string... => this is a very long new string...',
|
|
539
|
+
name: 'default to 1 expected replacement if not specified',
|
|
540
|
+
content: 'foo foo',
|
|
541
|
+
expected: undefined,
|
|
542
|
+
shouldSucceed: false,
|
|
805
543
|
},
|
|
806
|
-
])('should
|
|
544
|
+
])('should $name', async ({ content, expected, shouldSucceed, finalContent }) => {
|
|
545
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
807
546
|
const params = {
|
|
808
|
-
file_path:
|
|
809
|
-
|
|
810
|
-
|
|
547
|
+
file_path: filePath,
|
|
548
|
+
instruction: 'Replace all foo with bar',
|
|
549
|
+
old_string: 'foo',
|
|
550
|
+
new_string: 'bar',
|
|
551
|
+
...(expected !== undefined && { expected_replacements: expected }),
|
|
811
552
|
};
|
|
812
553
|
const invocation = tool.build(params);
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
};
|
|
823
|
-
expect(tool.validateToolParams(validPath)).toBeNull();
|
|
824
|
-
});
|
|
825
|
-
it('should reject paths outside workspace root', () => {
|
|
826
|
-
const invalidPath = {
|
|
827
|
-
file_path: '/etc/passwd',
|
|
828
|
-
old_string: 'root',
|
|
829
|
-
new_string: 'hacked',
|
|
830
|
-
};
|
|
831
|
-
const error = tool.validateToolParams(invalidPath);
|
|
832
|
-
expect(error).toContain('File path must be within one of the workspace directories');
|
|
833
|
-
expect(error).toContain(rootDir);
|
|
834
|
-
});
|
|
835
|
-
});
|
|
836
|
-
describe('constructor', () => {
|
|
837
|
-
afterEach(() => {
|
|
838
|
-
vi.restoreAllMocks();
|
|
839
|
-
});
|
|
840
|
-
it('should use windows-style path examples on windows', () => {
|
|
841
|
-
vi.spyOn(process, 'platform', 'get').mockReturnValue('win32');
|
|
842
|
-
const tool = new EditTool({});
|
|
843
|
-
const schema = tool.schema;
|
|
844
|
-
expect(schema.parametersJsonSchema.properties
|
|
845
|
-
.file_path.description).toBe('The path to the file to modify.');
|
|
846
|
-
});
|
|
847
|
-
it('should use unix-style path examples on non-windows platforms', () => {
|
|
848
|
-
vi.spyOn(process, 'platform', 'get').mockReturnValue('linux');
|
|
849
|
-
const tool = new EditTool({});
|
|
850
|
-
const schema = tool.schema;
|
|
851
|
-
expect(schema.parametersJsonSchema.properties
|
|
852
|
-
.file_path.description).toBe('The path to the file to modify.');
|
|
554
|
+
const result = await invocation.execute(new AbortController().signal);
|
|
555
|
+
if (shouldSucceed) {
|
|
556
|
+
expect(result.error).toBeUndefined();
|
|
557
|
+
if (finalContent)
|
|
558
|
+
expect(fs.readFileSync(filePath, 'utf8')).toBe(finalContent);
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
expect(result.error?.type).toBe(ToolErrorType.EDIT_EXPECTED_OCCURRENCE_MISMATCH);
|
|
562
|
+
}
|
|
853
563
|
});
|
|
854
564
|
});
|
|
855
565
|
describe('IDE mode', () => {
|
|
@@ -872,13 +582,10 @@ describe('EditTool', () => {
|
|
|
872
582
|
fs.writeFileSync(filePath, initialContent);
|
|
873
583
|
const params = {
|
|
874
584
|
file_path: filePath,
|
|
585
|
+
instruction: 'test',
|
|
875
586
|
old_string: 'old',
|
|
876
587
|
new_string: 'new',
|
|
877
588
|
};
|
|
878
|
-
mockEnsureCorrectEdit.mockResolvedValueOnce({
|
|
879
|
-
params: { ...params, old_string: 'old', new_string: 'new' },
|
|
880
|
-
occurrences: 1,
|
|
881
|
-
});
|
|
882
589
|
ideClient.openDiff.mockResolvedValueOnce({
|
|
883
590
|
status: 'accepted',
|
|
884
591
|
content: modifiedContent,
|
|
@@ -893,6 +600,30 @@ describe('EditTool', () => {
|
|
|
893
600
|
expect(params.new_string).toBe(modifiedContent);
|
|
894
601
|
});
|
|
895
602
|
});
|
|
603
|
+
describe('shouldConfirmExecute', () => {
|
|
604
|
+
it('should rethrow calculateEdit errors when the abort signal is triggered', async () => {
|
|
605
|
+
const filePath = path.join(rootDir, 'abort-confirmation.txt');
|
|
606
|
+
const params = {
|
|
607
|
+
file_path: filePath,
|
|
608
|
+
instruction: 'Abort during confirmation',
|
|
609
|
+
old_string: 'old',
|
|
610
|
+
new_string: 'new',
|
|
611
|
+
};
|
|
612
|
+
const invocation = tool.build(params);
|
|
613
|
+
const abortController = new AbortController();
|
|
614
|
+
const abortError = new Error('Abort requested during edit confirmation');
|
|
615
|
+
const calculateSpy = vi
|
|
616
|
+
.spyOn(invocation, 'calculateEdit')
|
|
617
|
+
.mockImplementation(async () => {
|
|
618
|
+
if (!abortController.signal.aborted) {
|
|
619
|
+
abortController.abort();
|
|
620
|
+
}
|
|
621
|
+
throw abortError;
|
|
622
|
+
});
|
|
623
|
+
await expect(invocation.shouldConfirmExecute(abortController.signal)).rejects.toBe(abortError);
|
|
624
|
+
calculateSpy.mockRestore();
|
|
625
|
+
});
|
|
626
|
+
});
|
|
896
627
|
describe('multiple file edits', () => {
|
|
897
628
|
it('should perform multiple removals and report correct diff stats', async () => {
|
|
898
629
|
const numFiles = 10;
|
|
@@ -923,8 +654,10 @@ describe('EditTool', () => {
|
|
|
923
654
|
for (const file of files) {
|
|
924
655
|
const params = {
|
|
925
656
|
file_path: file.path,
|
|
657
|
+
instruction: `Remove lines from the file`,
|
|
926
658
|
old_string: file.toRemove,
|
|
927
659
|
new_string: '', // Removing the content
|
|
660
|
+
ai_proposed_content: '',
|
|
928
661
|
};
|
|
929
662
|
const invocation = tool.build(params);
|
|
930
663
|
const result = await invocation.execute(new AbortController().signal);
|
|
@@ -935,7 +668,7 @@ describe('EditTool', () => {
|
|
|
935
668
|
actualLinesRemoved.push(result.returnDisplay.diffStat?.model_removed_lines);
|
|
936
669
|
}
|
|
937
670
|
else if (result.error) {
|
|
938
|
-
|
|
671
|
+
throw result.error;
|
|
939
672
|
}
|
|
940
673
|
}
|
|
941
674
|
// 3. Assert that the content was removed from each file
|
|
@@ -951,5 +684,38 @@ describe('EditTool', () => {
|
|
|
951
684
|
expect(totalActualRemoved).toBe(totalExpectedRemoved);
|
|
952
685
|
});
|
|
953
686
|
});
|
|
687
|
+
describe('disableLLMCorrection', () => {
|
|
688
|
+
it('should NOT call FixLLMEditWithInstruction when disableLLMCorrection is true', async () => {
|
|
689
|
+
const filePath = path.join(rootDir, 'disable_llm_test.txt');
|
|
690
|
+
fs.writeFileSync(filePath, 'Some content.', 'utf8');
|
|
691
|
+
// Enable the setting
|
|
692
|
+
mockConfig.getDisableLLMCorrection.mockReturnValue(true);
|
|
693
|
+
const params = {
|
|
694
|
+
file_path: filePath,
|
|
695
|
+
instruction: 'Replace non-existent text',
|
|
696
|
+
old_string: 'nonexistent',
|
|
697
|
+
new_string: 'replacement',
|
|
698
|
+
};
|
|
699
|
+
const invocation = tool.build(params);
|
|
700
|
+
const result = await invocation.execute(new AbortController().signal);
|
|
701
|
+
expect(result.error?.type).toBe(ToolErrorType.EDIT_NO_OCCURRENCE_FOUND);
|
|
702
|
+
expect(mockFixLLMEditWithInstruction).not.toHaveBeenCalled();
|
|
703
|
+
});
|
|
704
|
+
it('should call FixLLMEditWithInstruction when disableLLMCorrection is false (default)', async () => {
|
|
705
|
+
const filePath = path.join(rootDir, 'enable_llm_test.txt');
|
|
706
|
+
fs.writeFileSync(filePath, 'Some content.', 'utf8');
|
|
707
|
+
// Default is false, but being explicit
|
|
708
|
+
mockConfig.getDisableLLMCorrection.mockReturnValue(false);
|
|
709
|
+
const params = {
|
|
710
|
+
file_path: filePath,
|
|
711
|
+
instruction: 'Replace non-existent text',
|
|
712
|
+
old_string: 'nonexistent',
|
|
713
|
+
new_string: 'replacement',
|
|
714
|
+
};
|
|
715
|
+
const invocation = tool.build(params);
|
|
716
|
+
await invocation.execute(new AbortController().signal);
|
|
717
|
+
expect(mockFixLLMEditWithInstruction).toHaveBeenCalled();
|
|
718
|
+
});
|
|
719
|
+
});
|
|
954
720
|
});
|
|
955
721
|
//# sourceMappingURL=edit.test.js.map
|