@machina.ai/cell-cli-core 1.13.0-rc5 → 1.16.0-rc2
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/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/src/agents/codebase-investigator.test.d.ts +6 -0
- package/dist/src/agents/codebase-investigator.test.js +35 -0
- package/dist/src/agents/codebase-investigator.test.js.map +1 -0
- package/dist/src/agents/executor.d.ts +3 -0
- package/dist/src/agents/executor.js +21 -0
- package/dist/src/agents/executor.js.map +1 -1
- package/dist/src/agents/executor.test.js +358 -3
- package/dist/src/agents/executor.test.js.map +1 -1
- package/dist/src/code_assist/codeAssist.test.d.ts +6 -0
- package/dist/src/code_assist/codeAssist.test.js +99 -0
- package/dist/src/code_assist/codeAssist.test.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.d.ts +6 -0
- package/dist/src/code_assist/experiments/client_metadata.test.js +99 -0
- package/dist/src/code_assist/experiments/client_metadata.test.js.map +1 -0
- package/dist/src/code_assist/experiments/experiments.js +2 -2
- package/dist/src/code_assist/experiments/experiments.js.map +1 -1
- package/dist/src/code_assist/experiments/experiments.test.d.ts +6 -0
- package/dist/src/code_assist/experiments/experiments.test.js +92 -0
- package/dist/src/code_assist/experiments/experiments.test.js.map +1 -0
- package/dist/src/code_assist/experiments/flagNames.d.ts +13 -0
- package/dist/src/code_assist/experiments/flagNames.js +13 -0
- package/dist/src/code_assist/experiments/flagNames.js.map +1 -0
- package/dist/src/code_assist/experiments/types.d.ts +1 -1
- package/dist/src/code_assist/oauth-credential-storage.test.js +49 -0
- package/dist/src/code_assist/oauth-credential-storage.test.js.map +1 -1
- package/dist/src/code_assist/server.js +5 -8
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/code_assist/server.test.js +109 -28
- package/dist/src/code_assist/server.test.js.map +1 -1
- package/dist/src/config/config.d.ts +34 -2
- package/dist/src/config/config.js +147 -26
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +436 -19
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/defaultModelConfigs.d.ts +7 -0
- package/dist/src/config/defaultModelConfigs.js +158 -0
- package/dist/src/config/defaultModelConfigs.js.map +1 -0
- package/dist/src/config/models.d.ts +22 -1
- package/dist/src/config/models.js +49 -6
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/models.test.js +71 -10
- package/dist/src/config/models.test.js.map +1 -1
- package/dist/src/confirmation-bus/message-bus.d.ts +1 -1
- package/dist/src/confirmation-bus/message-bus.js +2 -2
- package/dist/src/confirmation-bus/message-bus.js.map +1 -1
- package/dist/src/confirmation-bus/message-bus.test.js +30 -24
- package/dist/src/confirmation-bus/message-bus.test.js.map +1 -1
- package/dist/src/confirmation-bus/types.d.ts +1 -0
- package/dist/src/core/baseLlmClient.d.ts +4 -8
- package/dist/src/core/baseLlmClient.js +3 -8
- package/dist/src/core/baseLlmClient.js.map +1 -1
- package/dist/src/core/baseLlmClient.test.js +22 -27
- package/dist/src/core/baseLlmClient.test.js.map +1 -1
- package/dist/src/core/client.d.ts +6 -5
- package/dist/src/core/client.js +33 -33
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +40 -22
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/coreToolScheduler.js +7 -1
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +151 -357
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +6 -4
- package/dist/src/core/geminiChat.js +106 -29
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +317 -16
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/logger.d.ts +7 -2
- package/dist/src/core/logger.js +15 -9
- package/dist/src/core/logger.js.map +1 -1
- package/dist/src/core/logger.test.js +31 -16
- package/dist/src/core/logger.test.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.test.d.ts +6 -0
- package/dist/src/core/loggingContentGenerator.test.js +180 -0
- package/dist/src/core/loggingContentGenerator.test.js.map +1 -0
- package/dist/src/core/nonInteractiveToolExecutor.test.js +1 -0
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/prompts.js +8 -11
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/tokenLimits.test.d.ts +6 -0
- package/dist/src/core/tokenLimits.test.js +26 -0
- package/dist/src/core/tokenLimits.test.js.map +1 -0
- package/dist/src/fallback/handler.js +52 -7
- package/dist/src/fallback/handler.js.map +1 -1
- package/dist/src/fallback/handler.test.js +69 -16
- package/dist/src/fallback/handler.test.js.map +1 -1
- package/dist/src/fallback/types.d.ts +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/hooks/hookAggregator.d.ts +68 -0
- package/dist/src/hooks/hookAggregator.js +262 -0
- package/dist/src/hooks/hookAggregator.js.map +1 -0
- package/dist/src/hooks/hookAggregator.test.d.ts +6 -0
- package/dist/src/hooks/hookAggregator.test.js +387 -0
- package/dist/src/hooks/hookAggregator.test.js.map +1 -0
- package/dist/src/hooks/hookRunner.d.ts +42 -0
- package/dist/src/hooks/hookRunner.js +272 -0
- package/dist/src/hooks/hookRunner.js.map +1 -0
- package/dist/src/hooks/hookRunner.test.d.ts +6 -0
- package/dist/src/hooks/hookRunner.test.js +468 -0
- package/dist/src/hooks/hookRunner.test.js.map +1 -0
- package/dist/src/hooks/hookTranslator.d.ts +3 -3
- package/dist/src/hooks/types.js +1 -1
- package/dist/src/hooks/types.js.map +1 -1
- package/dist/src/hooks/types.test.js +280 -2
- 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 +6 -1
- package/dist/src/ide/detect-ide.js.map +1 -1
- package/dist/src/ide/detect-ide.test.js +5 -0
- package/dist/src/ide/detect-ide.test.js.map +1 -1
- package/dist/src/ide/ide-client.d.ts +3 -1
- package/dist/src/ide/ide-client.js +66 -59
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ide-client.test.js +159 -0
- package/dist/src/ide/ide-client.test.js.map +1 -1
- package/dist/src/ide/ide-installer.js +71 -21
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/ide-installer.test.js +42 -1
- package/dist/src/ide/ide-installer.test.js.map +1 -1
- package/dist/src/ide/process-utils.js +16 -0
- package/dist/src/ide/process-utils.js.map +1 -1
- package/dist/src/ide/process-utils.test.js +3 -3
- package/dist/src/ide/process-utils.test.js.map +1 -1
- package/dist/src/ide/types.d.ts +1 -1
- package/dist/src/ide/types.js +1 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/google-auth-provider.js +1 -1
- package/dist/src/mcp/google-auth-provider.js.map +1 -1
- package/dist/src/mcp/oauth-provider.js +2 -2
- package/dist/src/mcp/oauth-provider.js.map +1 -1
- package/dist/src/mcp/oauth-provider.test.js +177 -0
- package/dist/src/mcp/oauth-provider.test.js.map +1 -1
- package/dist/src/mcp/sa-impersonation-provider.js +1 -1
- package/dist/src/mcp/sa-impersonation-provider.js.map +1 -1
- package/dist/src/policy/config.js +3 -1
- package/dist/src/policy/config.js.map +1 -1
- package/dist/src/policy/config.test.js +135 -1
- package/dist/src/policy/config.test.js.map +1 -1
- package/dist/src/policy/policies/discovered.toml +8 -0
- package/dist/src/policy/policies/write.toml +10 -0
- package/dist/src/policy/policy-engine.d.ts +12 -3
- package/dist/src/policy/policy-engine.js +71 -9
- package/dist/src/policy/policy-engine.js.map +1 -1
- package/dist/src/policy/policy-engine.test.js +460 -76
- package/dist/src/policy/policy-engine.test.js.map +1 -1
- package/dist/src/policy/toml-loader.d.ts +2 -1
- package/dist/src/policy/toml-loader.js +103 -6
- package/dist/src/policy/toml-loader.js.map +1 -1
- package/dist/src/policy/toml-loader.test.js +222 -368
- package/dist/src/policy/toml-loader.test.js.map +1 -1
- package/dist/src/policy/types.d.ts +65 -0
- package/dist/src/policy/types.js +4 -0
- package/dist/src/policy/types.js.map +1 -1
- package/dist/src/prompts/mcp-prompts.test.d.ts +6 -0
- package/dist/src/prompts/mcp-prompts.test.js +40 -0
- package/dist/src/prompts/mcp-prompts.test.js.map +1 -0
- package/dist/src/prompts/prompt-registry.test.d.ts +6 -0
- package/dist/src/prompts/prompt-registry.test.js +111 -0
- package/dist/src/prompts/prompt-registry.test.js.map +1 -0
- package/dist/src/routing/modelRouterService.js +15 -0
- package/dist/src/routing/modelRouterService.js.map +1 -1
- package/dist/src/routing/modelRouterService.test.js +62 -0
- package/dist/src/routing/modelRouterService.test.js.map +1 -1
- package/dist/src/routing/strategies/classifierStrategy.d.ts +1 -1
- package/dist/src/routing/strategies/classifierStrategy.js +6 -14
- package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
- package/dist/src/routing/strategies/classifierStrategy.test.js +13 -10
- package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.js +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.test.js +4 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/overrideStrategy.js +2 -2
- package/dist/src/routing/strategies/overrideStrategy.js.map +1 -1
- package/dist/src/routing/strategies/overrideStrategy.test.js +3 -0
- package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -1
- package/dist/src/safety/built-in.d.ts +21 -0
- package/dist/src/safety/built-in.js +106 -0
- package/dist/src/safety/built-in.js.map +1 -0
- package/dist/src/safety/built-in.test.d.ts +6 -0
- package/dist/src/safety/built-in.test.js +199 -0
- package/dist/src/safety/built-in.test.js.map +1 -0
- package/dist/src/safety/checker-runner.d.ts +48 -0
- package/dist/src/safety/checker-runner.js +208 -0
- package/dist/src/safety/checker-runner.js.map +1 -0
- package/dist/src/safety/checker-runner.test.d.ts +6 -0
- package/dist/src/safety/checker-runner.test.js +238 -0
- package/dist/src/safety/checker-runner.test.js.map +1 -0
- package/dist/src/safety/context-builder.d.ts +23 -0
- package/dist/src/safety/context-builder.js +47 -0
- package/dist/src/safety/context-builder.js.map +1 -0
- package/dist/src/safety/context-builder.test.d.ts +6 -0
- package/dist/src/safety/context-builder.test.js +49 -0
- package/dist/src/safety/context-builder.test.js.map +1 -0
- package/dist/src/safety/protocol.d.ts +88 -0
- package/dist/src/safety/protocol.js +15 -0
- package/dist/src/safety/protocol.js.map +1 -0
- package/dist/src/safety/registry.d.ts +26 -0
- package/dist/src/safety/registry.js +65 -0
- package/dist/src/safety/registry.js.map +1 -0
- package/dist/src/safety/registry.test.d.ts +6 -0
- package/dist/src/safety/registry.test.js +31 -0
- package/dist/src/safety/registry.test.js.map +1 -0
- package/dist/src/services/chatCompressionService.test.js +1 -0
- package/dist/src/services/chatCompressionService.test.js.map +1 -1
- package/dist/src/services/gitService.js +1 -1
- package/dist/src/services/gitService.js.map +1 -1
- package/dist/src/services/gitService.test.js +1 -1
- package/dist/src/services/gitService.test.js.map +1 -1
- package/dist/src/services/loopDetectionService.d.ts +3 -0
- package/dist/src/services/loopDetectionService.js +81 -42
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/loopDetectionService.test.js +101 -1
- package/dist/src/services/loopDetectionService.test.js.map +1 -1
- package/dist/src/services/modelConfig.golden.test.d.ts +6 -0
- package/dist/src/services/modelConfig.golden.test.js +42 -0
- package/dist/src/services/modelConfig.golden.test.js.map +1 -0
- package/dist/src/services/modelConfig.integration.test.d.ts +6 -0
- package/dist/src/services/modelConfig.integration.test.js +213 -0
- package/dist/src/services/modelConfig.integration.test.js.map +1 -0
- package/dist/src/services/modelConfigService.d.ts +46 -0
- package/dist/src/services/modelConfigService.js +146 -0
- package/dist/src/services/modelConfigService.js.map +1 -0
- package/dist/src/services/modelConfigService.test.d.ts +6 -0
- package/dist/src/services/modelConfigService.test.js +509 -0
- package/dist/src/services/modelConfigService.test.js.map +1 -0
- package/dist/src/services/test-data/resolved-aliases.golden.json +169 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +11 -9
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +174 -150
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +1 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +76 -20
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +6 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +18 -5
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +2 -2
- package/dist/src/telemetry/index.js +2 -2
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +7 -7
- package/dist/src/telemetry/loggers.js +23 -23
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.circular.js +0 -1
- package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +72 -18
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +8 -4
- package/dist/src/telemetry/metrics.js +10 -4
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js +42 -0
- package/dist/src/telemetry/metrics.test.js.map +1 -1
- package/dist/src/telemetry/telemetryAttributes.js +1 -0
- package/dist/src/telemetry/telemetryAttributes.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +17 -11
- package/dist/src/telemetry/types.js +53 -28
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/tools/base-tool-invocation.test.d.ts +6 -0
- package/dist/src/tools/base-tool-invocation.test.js +85 -0
- package/dist/src/tools/base-tool-invocation.test.js.map +1 -0
- package/dist/src/tools/edit.d.ts +1 -1
- package/dist/src/tools/edit.js +31 -33
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +31 -20
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/glob.d.ts +1 -1
- package/dist/src/tools/glob.js +7 -7
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +20 -17
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/grep.d.ts +1 -1
- package/dist/src/tools/grep.js +9 -9
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/grep.test.js +15 -12
- package/dist/src/tools/grep.test.js.map +1 -1
- package/dist/src/tools/ls.d.ts +1 -1
- package/dist/src/tools/ls.js +14 -15
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/ls.test.js +32 -33
- package/dist/src/tools/ls.test.js.map +1 -1
- package/dist/src/tools/mcp-client.js +24 -52
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +18 -0
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +1 -0
- package/dist/src/tools/mcp-tool.js +5 -2
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/memoryTool.js +1 -1
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/memoryTool.test.js +1 -1
- package/dist/src/tools/memoryTool.test.js.map +1 -1
- package/dist/src/tools/modifiable-tool.d.ts +5 -1
- package/dist/src/tools/modifiable-tool.js +34 -13
- package/dist/src/tools/modifiable-tool.js.map +1 -1
- package/dist/src/tools/modifiable-tool.test.js +56 -22
- 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 +20 -24
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +63 -51
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.d.ts +2 -9
- package/dist/src/tools/read-many-files.js +10 -21
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/read-many-files.test.js +37 -35
- package/dist/src/tools/read-many-files.test.js.map +1 -1
- package/dist/src/tools/ripGrep.d.ts +25 -8
- package/dist/src/tools/ripGrep.js +148 -176
- package/dist/src/tools/ripGrep.js.map +1 -1
- package/dist/src/tools/ripGrep.test.js +383 -58
- package/dist/src/tools/ripGrep.test.js.map +1 -1
- package/dist/src/tools/shell.d.ts +1 -1
- package/dist/src/tools/shell.js +17 -15
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +66 -36
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/smart-edit.d.ts +6 -1
- package/dist/src/tools/smart-edit.js +18 -17
- package/dist/src/tools/smart-edit.js.map +1 -1
- package/dist/src/tools/smart-edit.test.js +49 -24
- package/dist/src/tools/smart-edit.test.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +29 -4
- package/dist/src/tools/tool-registry.js +108 -29
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +134 -4
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +2 -1
- package/dist/src/tools/tools.js +5 -2
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/web-fetch.js +2 -4
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +11 -4
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/web-search.js +1 -2
- package/dist/src/tools/web-search.js.map +1 -1
- package/dist/src/tools/web-search.test.js +11 -5
- package/dist/src/tools/web-search.test.js.map +1 -1
- package/dist/src/tools/write-file.js +31 -31
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +24 -5
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/tools/write-todos.d.ts +29 -0
- package/dist/src/tools/write-todos.js +34 -1
- package/dist/src/tools/write-todos.js.map +1 -1
- package/dist/src/utils/editCorrector.js +4 -15
- package/dist/src/utils/editCorrector.js.map +1 -1
- package/dist/src/utils/editCorrector.test.js +16 -0
- package/dist/src/utils/editCorrector.test.js.map +1 -1
- package/dist/src/utils/editor.d.ts +3 -1
- package/dist/src/utils/editor.js +18 -1
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/editor.test.js +11 -0
- package/dist/src/utils/editor.test.js.map +1 -1
- package/dist/src/utils/environmentContext.js +3 -1
- package/dist/src/utils/environmentContext.js.map +1 -1
- package/dist/src/utils/environmentContext.test.js +6 -0
- package/dist/src/utils/environmentContext.test.js.map +1 -1
- package/dist/src/utils/events.d.ts +14 -11
- package/dist/src/utils/events.js +1 -14
- package/dist/src/utils/events.js.map +1 -1
- package/dist/src/utils/extensionLoader.d.ts +8 -0
- package/dist/src/utils/extensionLoader.js +61 -15
- package/dist/src/utils/extensionLoader.js.map +1 -1
- package/dist/src/utils/extensionLoader.test.js +83 -19
- package/dist/src/utils/extensionLoader.test.js.map +1 -1
- package/dist/src/utils/fileUtils.test.js +75 -60
- package/dist/src/utils/fileUtils.test.js.map +1 -1
- package/dist/src/utils/flashFallback.test.js +2 -2
- package/dist/src/utils/flashFallback.test.js.map +1 -1
- package/dist/src/utils/googleQuotaErrors.d.ts +2 -1
- package/dist/src/utils/googleQuotaErrors.js +20 -12
- package/dist/src/utils/googleQuotaErrors.js.map +1 -1
- package/dist/src/utils/httpErrors.d.ts +18 -0
- package/dist/src/utils/httpErrors.js +36 -0
- package/dist/src/utils/httpErrors.js.map +1 -0
- package/dist/src/utils/llm-edit-fixer.js +1 -2
- package/dist/src/utils/llm-edit-fixer.js.map +1 -1
- package/dist/src/utils/llm-edit-fixer.test.js +16 -1
- package/dist/src/utils/llm-edit-fixer.test.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.d.ts +8 -0
- package/dist/src/utils/memoryDiscovery.js +24 -0
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +43 -1
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/nextSpeakerChecker.js +1 -2
- package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
- package/dist/src/utils/nextSpeakerChecker.test.js +10 -4
- package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
- package/dist/src/utils/pathReader.js +4 -4
- package/dist/src/utils/pathReader.js.map +1 -1
- package/dist/src/utils/pathReader.test.js +44 -1
- package/dist/src/utils/pathReader.test.js.map +1 -1
- package/dist/src/utils/paths.d.ts +1 -1
- package/dist/src/utils/paths.js +5 -3
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/retry.d.ts +0 -9
- package/dist/src/utils/retry.js +24 -28
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/retry.test.js +51 -0
- package/dist/src/utils/retry.test.js.map +1 -1
- package/dist/src/utils/shell-utils.js +5 -3
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.test.js +9 -9
- package/dist/src/utils/shell-utils.test.js.map +1 -1
- package/dist/src/utils/summarizer.d.ts +4 -2
- package/dist/src/utils/summarizer.js +6 -8
- package/dist/src/utils/summarizer.js.map +1 -1
- package/dist/src/utils/summarizer.test.js +32 -11
- package/dist/src/utils/summarizer.test.js.map +1 -1
- package/dist/src/utils/workspaceContext.d.ts +4 -3
- package/dist/src/utils/workspaceContext.js +10 -11
- package/dist/src/utils/workspaceContext.js.map +1 -1
- 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 +1 -1
|
@@ -7,7 +7,7 @@ import { describe, it, expect, beforeEach, afterEach, afterAll, vi, } from 'vite
|
|
|
7
7
|
import { canUseRipgrep, RipGrepTool, ensureRgPath } from './ripGrep.js';
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
import fs from 'node:fs/promises';
|
|
10
|
-
import os
|
|
10
|
+
import os from 'node:os';
|
|
11
11
|
import { Storage } from '../config/storage.js';
|
|
12
12
|
import { createMockWorkspaceContext } from '../test-utils/mockWorkspaceContext.js';
|
|
13
13
|
import { spawn } from 'node:child_process';
|
|
@@ -215,19 +215,19 @@ describe('RipGrepTool', () => {
|
|
|
215
215
|
expect(grepTool.validateToolParams(params)).toBeNull();
|
|
216
216
|
});
|
|
217
217
|
it('should return null for valid params (pattern and path)', () => {
|
|
218
|
-
const params = { pattern: 'hello',
|
|
218
|
+
const params = { pattern: 'hello', dir_path: '.' };
|
|
219
219
|
expect(grepTool.validateToolParams(params)).toBeNull();
|
|
220
220
|
});
|
|
221
221
|
it('should return null for valid params (pattern, path, and include)', () => {
|
|
222
222
|
const params = {
|
|
223
223
|
pattern: 'hello',
|
|
224
|
-
|
|
224
|
+
dir_path: '.',
|
|
225
225
|
include: '*.txt',
|
|
226
226
|
};
|
|
227
227
|
expect(grepTool.validateToolParams(params)).toBeNull();
|
|
228
228
|
});
|
|
229
229
|
it('should return error if pattern is missing', () => {
|
|
230
|
-
const params = {
|
|
230
|
+
const params = { dir_path: '.' };
|
|
231
231
|
expect(grepTool.validateToolParams(params)).toBe(`params must have required property 'pattern'`);
|
|
232
232
|
});
|
|
233
233
|
it('should return null for what would be an invalid regex pattern', () => {
|
|
@@ -237,28 +237,57 @@ describe('RipGrepTool', () => {
|
|
|
237
237
|
it('should return error if path does not exist', () => {
|
|
238
238
|
const params = {
|
|
239
239
|
pattern: 'hello',
|
|
240
|
-
|
|
240
|
+
dir_path: 'nonexistent',
|
|
241
241
|
};
|
|
242
242
|
// Check for the core error message, as the full path might vary
|
|
243
|
-
expect(grepTool.validateToolParams(params)).toContain('
|
|
243
|
+
expect(grepTool.validateToolParams(params)).toContain('Path does not exist');
|
|
244
244
|
expect(grepTool.validateToolParams(params)).toContain('nonexistent');
|
|
245
245
|
});
|
|
246
|
-
it('should
|
|
246
|
+
it('should allow path to be a file', async () => {
|
|
247
247
|
const filePath = path.join(tempRootDir, 'fileA.txt');
|
|
248
|
-
const params = {
|
|
249
|
-
|
|
248
|
+
const params = {
|
|
249
|
+
pattern: 'hello',
|
|
250
|
+
dir_path: filePath,
|
|
251
|
+
};
|
|
252
|
+
expect(grepTool.validateToolParams(params)).toBeNull();
|
|
250
253
|
});
|
|
251
254
|
});
|
|
252
255
|
describe('execute', () => {
|
|
253
256
|
it('should find matches for a simple pattern in all files', async () => {
|
|
254
257
|
mockSpawn.mockImplementationOnce(createMockSpawn({
|
|
255
|
-
outputData:
|
|
258
|
+
outputData: JSON.stringify({
|
|
259
|
+
type: 'match',
|
|
260
|
+
data: {
|
|
261
|
+
path: { text: 'fileA.txt' },
|
|
262
|
+
line_number: 1,
|
|
263
|
+
lines: { text: 'hello world\n' },
|
|
264
|
+
},
|
|
265
|
+
}) +
|
|
266
|
+
'\n' +
|
|
267
|
+
JSON.stringify({
|
|
268
|
+
type: 'match',
|
|
269
|
+
data: {
|
|
270
|
+
path: { text: 'fileA.txt' },
|
|
271
|
+
line_number: 2,
|
|
272
|
+
lines: { text: 'second line with world\n' },
|
|
273
|
+
},
|
|
274
|
+
}) +
|
|
275
|
+
'\n' +
|
|
276
|
+
JSON.stringify({
|
|
277
|
+
type: 'match',
|
|
278
|
+
data: {
|
|
279
|
+
path: { text: 'sub/fileC.txt' },
|
|
280
|
+
line_number: 1,
|
|
281
|
+
lines: { text: 'another world in sub dir\n' },
|
|
282
|
+
},
|
|
283
|
+
}) +
|
|
284
|
+
'\n',
|
|
256
285
|
exitCode: 0,
|
|
257
286
|
}));
|
|
258
287
|
const params = { pattern: 'world' };
|
|
259
288
|
const invocation = grepTool.build(params);
|
|
260
289
|
const result = await invocation.execute(abortSignal);
|
|
261
|
-
expect(result.llmContent).toContain('Found 3 matches for pattern "world" in
|
|
290
|
+
expect(result.llmContent).toContain('Found 3 matches for pattern "world" in path "."');
|
|
262
291
|
expect(result.llmContent).toContain('File: fileA.txt');
|
|
263
292
|
expect(result.llmContent).toContain('L1: hello world');
|
|
264
293
|
expect(result.llmContent).toContain('L2: second line with world');
|
|
@@ -269,10 +298,17 @@ describe('RipGrepTool', () => {
|
|
|
269
298
|
it('should find matches in a specific path', async () => {
|
|
270
299
|
// Setup specific mock for this test - searching in 'sub' should only return matches from that directory
|
|
271
300
|
mockSpawn.mockImplementationOnce(createMockSpawn({
|
|
272
|
-
outputData:
|
|
301
|
+
outputData: JSON.stringify({
|
|
302
|
+
type: 'match',
|
|
303
|
+
data: {
|
|
304
|
+
path: { text: 'fileC.txt' },
|
|
305
|
+
line_number: 1,
|
|
306
|
+
lines: { text: 'another world in sub dir\n' },
|
|
307
|
+
},
|
|
308
|
+
}) + '\n',
|
|
273
309
|
exitCode: 0,
|
|
274
310
|
}));
|
|
275
|
-
const params = { pattern: 'world',
|
|
311
|
+
const params = { pattern: 'world', dir_path: 'sub' };
|
|
276
312
|
const invocation = grepTool.build(params);
|
|
277
313
|
const result = await invocation.execute(abortSignal);
|
|
278
314
|
expect(result.llmContent).toContain('Found 1 match for pattern "world" in path "sub"');
|
|
@@ -283,13 +319,20 @@ describe('RipGrepTool', () => {
|
|
|
283
319
|
it('should find matches with an include glob', async () => {
|
|
284
320
|
// Setup specific mock for this test
|
|
285
321
|
mockSpawn.mockImplementationOnce(createMockSpawn({
|
|
286
|
-
outputData:
|
|
322
|
+
outputData: JSON.stringify({
|
|
323
|
+
type: 'match',
|
|
324
|
+
data: {
|
|
325
|
+
path: { text: 'fileB.js' },
|
|
326
|
+
line_number: 2,
|
|
327
|
+
lines: { text: 'function baz() { return "hello"; }\n' },
|
|
328
|
+
},
|
|
329
|
+
}) + '\n',
|
|
287
330
|
exitCode: 0,
|
|
288
331
|
}));
|
|
289
332
|
const params = { pattern: 'hello', include: '*.js' };
|
|
290
333
|
const invocation = grepTool.build(params);
|
|
291
334
|
const result = await invocation.execute(abortSignal);
|
|
292
|
-
expect(result.llmContent).toContain('Found 1 match for pattern "hello" in
|
|
335
|
+
expect(result.llmContent).toContain('Found 1 match for pattern "hello" in path "." (filter: "*.js"):');
|
|
293
336
|
expect(result.llmContent).toContain('File: fileB.js');
|
|
294
337
|
expect(result.llmContent).toContain('L2: function baz() { return "hello"; }');
|
|
295
338
|
expect(result.returnDisplay).toBe('Found 1 match');
|
|
@@ -316,7 +359,14 @@ describe('RipGrepTool', () => {
|
|
|
316
359
|
const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
|
|
317
360
|
if (onData) {
|
|
318
361
|
// Only return match from the .js file in sub directory
|
|
319
|
-
onData(Buffer.from(
|
|
362
|
+
onData(Buffer.from(JSON.stringify({
|
|
363
|
+
type: 'match',
|
|
364
|
+
data: {
|
|
365
|
+
path: { text: 'another.js' },
|
|
366
|
+
line_number: 1,
|
|
367
|
+
lines: { text: 'const greeting = "hello";\n' },
|
|
368
|
+
},
|
|
369
|
+
}) + '\n'));
|
|
320
370
|
}
|
|
321
371
|
if (onClose) {
|
|
322
372
|
onClose(0);
|
|
@@ -326,7 +376,7 @@ describe('RipGrepTool', () => {
|
|
|
326
376
|
});
|
|
327
377
|
const params = {
|
|
328
378
|
pattern: 'hello',
|
|
329
|
-
|
|
379
|
+
dir_path: 'sub',
|
|
330
380
|
include: '*.js',
|
|
331
381
|
};
|
|
332
382
|
const invocation = grepTool.build(params);
|
|
@@ -344,7 +394,7 @@ describe('RipGrepTool', () => {
|
|
|
344
394
|
const params = { pattern: 'nonexistentpattern' };
|
|
345
395
|
const invocation = grepTool.build(params);
|
|
346
396
|
const result = await invocation.execute(abortSignal);
|
|
347
|
-
expect(result.llmContent).toContain('No matches found for pattern "nonexistentpattern" in
|
|
397
|
+
expect(result.llmContent).toContain('No matches found for pattern "nonexistentpattern" in path ".".');
|
|
348
398
|
expect(result.returnDisplay).toBe('No matches found');
|
|
349
399
|
});
|
|
350
400
|
it('should return an error from ripgrep for invalid regex pattern', async () => {
|
|
@@ -378,7 +428,14 @@ describe('RipGrepTool', () => {
|
|
|
378
428
|
const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
|
|
379
429
|
if (onData) {
|
|
380
430
|
// Return match for the regex pattern
|
|
381
|
-
onData(Buffer.from(
|
|
431
|
+
onData(Buffer.from(JSON.stringify({
|
|
432
|
+
type: 'match',
|
|
433
|
+
data: {
|
|
434
|
+
path: { text: 'fileB.js' },
|
|
435
|
+
line_number: 1,
|
|
436
|
+
lines: { text: 'const foo = "bar";\n' },
|
|
437
|
+
},
|
|
438
|
+
}) + '\n'));
|
|
382
439
|
}
|
|
383
440
|
if (onClose) {
|
|
384
441
|
onClose(0);
|
|
@@ -389,7 +446,7 @@ describe('RipGrepTool', () => {
|
|
|
389
446
|
const params = { pattern: 'foo.*bar' }; // Matches 'const foo = "bar";'
|
|
390
447
|
const invocation = grepTool.build(params);
|
|
391
448
|
const result = await invocation.execute(abortSignal);
|
|
392
|
-
expect(result.llmContent).toContain('Found 1 match for pattern "foo.*bar" in
|
|
449
|
+
expect(result.llmContent).toContain('Found 1 match for pattern "foo.*bar" in path ".":');
|
|
393
450
|
expect(result.llmContent).toContain('File: fileB.js');
|
|
394
451
|
expect(result.llmContent).toContain('L1: const foo = "bar";');
|
|
395
452
|
});
|
|
@@ -414,7 +471,24 @@ describe('RipGrepTool', () => {
|
|
|
414
471
|
const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
|
|
415
472
|
if (onData) {
|
|
416
473
|
// Return case-insensitive matches for 'HELLO'
|
|
417
|
-
onData(Buffer.from(
|
|
474
|
+
onData(Buffer.from(JSON.stringify({
|
|
475
|
+
type: 'match',
|
|
476
|
+
data: {
|
|
477
|
+
path: { text: 'fileA.txt' },
|
|
478
|
+
line_number: 1,
|
|
479
|
+
lines: { text: 'hello world\n' },
|
|
480
|
+
},
|
|
481
|
+
}) +
|
|
482
|
+
'\n' +
|
|
483
|
+
JSON.stringify({
|
|
484
|
+
type: 'match',
|
|
485
|
+
data: {
|
|
486
|
+
path: { text: 'fileB.js' },
|
|
487
|
+
line_number: 2,
|
|
488
|
+
lines: { text: 'function baz() { return "hello"; }\n' },
|
|
489
|
+
},
|
|
490
|
+
}) +
|
|
491
|
+
'\n'));
|
|
418
492
|
}
|
|
419
493
|
if (onClose) {
|
|
420
494
|
onClose(0);
|
|
@@ -425,14 +499,14 @@ describe('RipGrepTool', () => {
|
|
|
425
499
|
const params = { pattern: 'HELLO' };
|
|
426
500
|
const invocation = grepTool.build(params);
|
|
427
501
|
const result = await invocation.execute(abortSignal);
|
|
428
|
-
expect(result.llmContent).toContain('Found 2 matches for pattern "HELLO" in
|
|
502
|
+
expect(result.llmContent).toContain('Found 2 matches for pattern "HELLO" in path ".":');
|
|
429
503
|
expect(result.llmContent).toContain('File: fileA.txt');
|
|
430
504
|
expect(result.llmContent).toContain('L1: hello world');
|
|
431
505
|
expect(result.llmContent).toContain('File: fileB.js');
|
|
432
506
|
expect(result.llmContent).toContain('L2: function baz() { return "hello"; }');
|
|
433
507
|
});
|
|
434
508
|
it('should throw an error if params are invalid', async () => {
|
|
435
|
-
const params = {
|
|
509
|
+
const params = { dir_path: '.' }; // Invalid: pattern missing
|
|
436
510
|
expect(() => grepTool.build(params)).toThrow(/params must have required property 'pattern'/);
|
|
437
511
|
});
|
|
438
512
|
it('should throw an error if ripgrep is not available', async () => {
|
|
@@ -447,7 +521,7 @@ describe('RipGrepTool', () => {
|
|
|
447
521
|
});
|
|
448
522
|
});
|
|
449
523
|
describe('multi-directory workspace', () => {
|
|
450
|
-
it('should search
|
|
524
|
+
it('should search only CWD when no path is specified (default behavior)', async () => {
|
|
451
525
|
// Create additional directory with test files
|
|
452
526
|
const secondDir = await fs.mkdtemp(path.join(os.tmpdir(), 'grep-tool-second-'));
|
|
453
527
|
await fs.writeFile(path.join(secondDir, 'other.txt'), 'hello from second directory\nworld in second');
|
|
@@ -483,19 +557,55 @@ describe('RipGrepTool', () => {
|
|
|
483
557
|
if (callCount === 1) {
|
|
484
558
|
// First directory (tempRootDir)
|
|
485
559
|
outputData =
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
560
|
+
JSON.stringify({
|
|
561
|
+
type: 'match',
|
|
562
|
+
data: {
|
|
563
|
+
path: { text: 'fileA.txt' },
|
|
564
|
+
line_number: 1,
|
|
565
|
+
lines: { text: 'hello world\n' },
|
|
566
|
+
},
|
|
567
|
+
}) +
|
|
568
|
+
'\n' +
|
|
569
|
+
JSON.stringify({
|
|
570
|
+
type: 'match',
|
|
571
|
+
data: {
|
|
572
|
+
path: { text: 'fileA.txt' },
|
|
573
|
+
line_number: 2,
|
|
574
|
+
lines: { text: 'second line with world\n' },
|
|
575
|
+
},
|
|
576
|
+
}) +
|
|
577
|
+
'\n' +
|
|
578
|
+
JSON.stringify({
|
|
579
|
+
type: 'match',
|
|
580
|
+
data: {
|
|
581
|
+
path: { text: 'sub/fileC.txt' },
|
|
582
|
+
line_number: 1,
|
|
583
|
+
lines: { text: 'another world in sub dir\n' },
|
|
584
|
+
},
|
|
585
|
+
}) +
|
|
586
|
+
'\n';
|
|
491
587
|
}
|
|
492
588
|
else if (callCount === 2) {
|
|
493
589
|
// Second directory (secondDir)
|
|
494
590
|
outputData =
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
591
|
+
JSON.stringify({
|
|
592
|
+
type: 'match',
|
|
593
|
+
data: {
|
|
594
|
+
path: { text: 'other.txt' },
|
|
595
|
+
line_number: 2,
|
|
596
|
+
lines: { text: 'world in second\n' },
|
|
597
|
+
},
|
|
598
|
+
}) +
|
|
599
|
+
'\n' +
|
|
600
|
+
JSON.stringify({
|
|
601
|
+
type: 'match',
|
|
602
|
+
data: {
|
|
603
|
+
path: { text: 'another.js' },
|
|
604
|
+
line_number: 1,
|
|
605
|
+
lines: { text: 'function world() { return "test"; }\n' },
|
|
606
|
+
},
|
|
607
|
+
}) +
|
|
608
|
+
'\n';
|
|
499
609
|
}
|
|
500
610
|
if (stdoutDataHandler && outputData) {
|
|
501
611
|
stdoutDataHandler(Buffer.from(outputData));
|
|
@@ -510,19 +620,19 @@ describe('RipGrepTool', () => {
|
|
|
510
620
|
const params = { pattern: 'world' };
|
|
511
621
|
const invocation = multiDirGrepTool.build(params);
|
|
512
622
|
const result = await invocation.execute(abortSignal);
|
|
513
|
-
// Should find matches in
|
|
514
|
-
expect(result.llmContent).toContain('Found
|
|
623
|
+
// Should find matches in CWD only (default behavior now)
|
|
624
|
+
expect(result.llmContent).toContain('Found 3 matches for pattern "world" in path "."');
|
|
515
625
|
// Matches from first directory
|
|
516
626
|
expect(result.llmContent).toContain('fileA.txt');
|
|
517
627
|
expect(result.llmContent).toContain('L1: hello world');
|
|
518
628
|
expect(result.llmContent).toContain('L2: second line with world');
|
|
519
629
|
expect(result.llmContent).toContain('fileC.txt');
|
|
520
630
|
expect(result.llmContent).toContain('L1: another world in sub dir');
|
|
521
|
-
//
|
|
522
|
-
expect(result.llmContent).toContain('other.txt');
|
|
523
|
-
expect(result.llmContent).toContain('
|
|
524
|
-
expect(result.llmContent).toContain('another.js');
|
|
525
|
-
expect(result.llmContent).toContain('
|
|
631
|
+
// Should NOT find matches from second directory
|
|
632
|
+
expect(result.llmContent).not.toContain('other.txt');
|
|
633
|
+
expect(result.llmContent).not.toContain('world in second');
|
|
634
|
+
expect(result.llmContent).not.toContain('another.js');
|
|
635
|
+
expect(result.llmContent).not.toContain('function world()');
|
|
526
636
|
// Clean up
|
|
527
637
|
await fs.rm(secondDir, { recursive: true, force: true });
|
|
528
638
|
mockSpawn.mockClear();
|
|
@@ -557,7 +667,14 @@ describe('RipGrepTool', () => {
|
|
|
557
667
|
const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
|
|
558
668
|
const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
|
|
559
669
|
if (onData) {
|
|
560
|
-
onData(Buffer.from(
|
|
670
|
+
onData(Buffer.from(JSON.stringify({
|
|
671
|
+
type: 'match',
|
|
672
|
+
data: {
|
|
673
|
+
path: { text: 'fileC.txt' },
|
|
674
|
+
line_number: 1,
|
|
675
|
+
lines: { text: 'another world in sub dir\n' },
|
|
676
|
+
},
|
|
677
|
+
}) + '\n'));
|
|
561
678
|
}
|
|
562
679
|
if (onClose) {
|
|
563
680
|
onClose(0);
|
|
@@ -567,7 +684,7 @@ describe('RipGrepTool', () => {
|
|
|
567
684
|
});
|
|
568
685
|
const multiDirGrepTool = new RipGrepTool(multiDirConfig);
|
|
569
686
|
// Search only in the 'sub' directory of the first workspace
|
|
570
|
-
const params = { pattern: 'world',
|
|
687
|
+
const params = { pattern: 'world', dir_path: 'sub' };
|
|
571
688
|
const invocation = multiDirGrepTool.build(params);
|
|
572
689
|
const result = await invocation.execute(abortSignal);
|
|
573
690
|
// Should only find matches in the specified sub directory
|
|
@@ -627,7 +744,10 @@ describe('RipGrepTool', () => {
|
|
|
627
744
|
});
|
|
628
745
|
describe('error handling and edge cases', () => {
|
|
629
746
|
it('should handle workspace boundary violations', () => {
|
|
630
|
-
const params = {
|
|
747
|
+
const params = {
|
|
748
|
+
pattern: 'test',
|
|
749
|
+
dir_path: '../outside',
|
|
750
|
+
};
|
|
631
751
|
expect(() => grepTool.build(params)).toThrow(/Path validation failed/);
|
|
632
752
|
});
|
|
633
753
|
it('should handle empty directories gracefully', async () => {
|
|
@@ -656,7 +776,7 @@ describe('RipGrepTool', () => {
|
|
|
656
776
|
}, 0);
|
|
657
777
|
return mockProcess;
|
|
658
778
|
});
|
|
659
|
-
const params = { pattern: 'test',
|
|
779
|
+
const params = { pattern: 'test', dir_path: 'empty' };
|
|
660
780
|
const invocation = grepTool.build(params);
|
|
661
781
|
const result = await invocation.execute(abortSignal);
|
|
662
782
|
expect(result.llmContent).toContain('No matches found');
|
|
@@ -714,7 +834,14 @@ describe('RipGrepTool', () => {
|
|
|
714
834
|
const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
|
|
715
835
|
const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
|
|
716
836
|
if (onData) {
|
|
717
|
-
onData(Buffer.from(
|
|
837
|
+
onData(Buffer.from(JSON.stringify({
|
|
838
|
+
type: 'match',
|
|
839
|
+
data: {
|
|
840
|
+
path: { text: specialFileName },
|
|
841
|
+
line_number: 1,
|
|
842
|
+
lines: { text: 'hello world with special chars\n' },
|
|
843
|
+
},
|
|
844
|
+
}) + '\n'));
|
|
718
845
|
}
|
|
719
846
|
if (onClose) {
|
|
720
847
|
onClose(0);
|
|
@@ -751,7 +878,14 @@ describe('RipGrepTool', () => {
|
|
|
751
878
|
const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
|
|
752
879
|
const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
|
|
753
880
|
if (onData) {
|
|
754
|
-
onData(Buffer.from(
|
|
881
|
+
onData(Buffer.from(JSON.stringify({
|
|
882
|
+
type: 'match',
|
|
883
|
+
data: {
|
|
884
|
+
path: { text: 'a/b/c/d/e/deep.txt' },
|
|
885
|
+
line_number: 1,
|
|
886
|
+
lines: { text: 'content in deep directory\n' },
|
|
887
|
+
},
|
|
888
|
+
}) + '\n'));
|
|
755
889
|
}
|
|
756
890
|
if (onClose) {
|
|
757
891
|
onClose(0);
|
|
@@ -788,7 +922,14 @@ describe('RipGrepTool', () => {
|
|
|
788
922
|
const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
|
|
789
923
|
const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
|
|
790
924
|
if (onData) {
|
|
791
|
-
onData(Buffer.from(
|
|
925
|
+
onData(Buffer.from(JSON.stringify({
|
|
926
|
+
type: 'match',
|
|
927
|
+
data: {
|
|
928
|
+
path: { text: 'code.js' },
|
|
929
|
+
line_number: 1,
|
|
930
|
+
lines: { text: 'function getName() { return "test"; }\n' },
|
|
931
|
+
},
|
|
932
|
+
}) + '\n'));
|
|
792
933
|
}
|
|
793
934
|
if (onClose) {
|
|
794
935
|
onClose(0);
|
|
@@ -823,7 +964,33 @@ describe('RipGrepTool', () => {
|
|
|
823
964
|
const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
|
|
824
965
|
const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
|
|
825
966
|
if (onData) {
|
|
826
|
-
onData(Buffer.from(
|
|
967
|
+
onData(Buffer.from(JSON.stringify({
|
|
968
|
+
type: 'match',
|
|
969
|
+
data: {
|
|
970
|
+
path: { text: 'case.txt' },
|
|
971
|
+
line_number: 1,
|
|
972
|
+
lines: { text: 'Hello World\n' },
|
|
973
|
+
},
|
|
974
|
+
}) +
|
|
975
|
+
'\n' +
|
|
976
|
+
JSON.stringify({
|
|
977
|
+
type: 'match',
|
|
978
|
+
data: {
|
|
979
|
+
path: { text: 'case.txt' },
|
|
980
|
+
line_number: 2,
|
|
981
|
+
lines: { text: 'hello world\n' },
|
|
982
|
+
},
|
|
983
|
+
}) +
|
|
984
|
+
'\n' +
|
|
985
|
+
JSON.stringify({
|
|
986
|
+
type: 'match',
|
|
987
|
+
data: {
|
|
988
|
+
path: { text: 'case.txt' },
|
|
989
|
+
line_number: 3,
|
|
990
|
+
lines: { text: 'HELLO WORLD\n' },
|
|
991
|
+
},
|
|
992
|
+
}) +
|
|
993
|
+
'\n'));
|
|
827
994
|
}
|
|
828
995
|
if (onClose) {
|
|
829
996
|
onClose(0);
|
|
@@ -859,7 +1026,14 @@ describe('RipGrepTool', () => {
|
|
|
859
1026
|
const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
|
|
860
1027
|
const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
|
|
861
1028
|
if (onData) {
|
|
862
|
-
onData(Buffer.from(
|
|
1029
|
+
onData(Buffer.from(JSON.stringify({
|
|
1030
|
+
type: 'match',
|
|
1031
|
+
data: {
|
|
1032
|
+
path: { text: 'special.txt' },
|
|
1033
|
+
line_number: 1,
|
|
1034
|
+
lines: { text: 'Price: $19.99\n' },
|
|
1035
|
+
},
|
|
1036
|
+
}) + '\n'));
|
|
863
1037
|
}
|
|
864
1038
|
if (onClose) {
|
|
865
1039
|
onClose(0);
|
|
@@ -899,7 +1073,24 @@ describe('RipGrepTool', () => {
|
|
|
899
1073
|
const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
|
|
900
1074
|
const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
|
|
901
1075
|
if (onData) {
|
|
902
|
-
onData(Buffer.from(
|
|
1076
|
+
onData(Buffer.from(JSON.stringify({
|
|
1077
|
+
type: 'match',
|
|
1078
|
+
data: {
|
|
1079
|
+
path: { text: 'test.ts' },
|
|
1080
|
+
line_number: 1,
|
|
1081
|
+
lines: { text: 'typescript content\n' },
|
|
1082
|
+
},
|
|
1083
|
+
}) +
|
|
1084
|
+
'\n' +
|
|
1085
|
+
JSON.stringify({
|
|
1086
|
+
type: 'match',
|
|
1087
|
+
data: {
|
|
1088
|
+
path: { text: 'test.tsx' },
|
|
1089
|
+
line_number: 1,
|
|
1090
|
+
lines: { text: 'tsx content\n' },
|
|
1091
|
+
},
|
|
1092
|
+
}) +
|
|
1093
|
+
'\n'));
|
|
903
1094
|
}
|
|
904
1095
|
if (onClose) {
|
|
905
1096
|
onClose(0);
|
|
@@ -941,7 +1132,14 @@ describe('RipGrepTool', () => {
|
|
|
941
1132
|
const onData = mockProcess.stdout.on.mock.calls.find((call) => call[0] === 'data')?.[1];
|
|
942
1133
|
const onClose = mockProcess.on.mock.calls.find((call) => call[0] === 'close')?.[1];
|
|
943
1134
|
if (onData) {
|
|
944
|
-
onData(Buffer.from(
|
|
1135
|
+
onData(Buffer.from(JSON.stringify({
|
|
1136
|
+
type: 'match',
|
|
1137
|
+
data: {
|
|
1138
|
+
path: { text: 'src/main.ts' },
|
|
1139
|
+
line_number: 1,
|
|
1140
|
+
lines: { text: 'source code\n' },
|
|
1141
|
+
},
|
|
1142
|
+
}) + '\n'));
|
|
945
1143
|
}
|
|
946
1144
|
if (onClose) {
|
|
947
1145
|
onClose(0);
|
|
@@ -959,11 +1157,135 @@ describe('RipGrepTool', () => {
|
|
|
959
1157
|
expect(result.llmContent).not.toContain('other.ts');
|
|
960
1158
|
});
|
|
961
1159
|
});
|
|
1160
|
+
describe('advanced search options', () => {
|
|
1161
|
+
it('should handle case_sensitive parameter', async () => {
|
|
1162
|
+
// Case-insensitive search (default)
|
|
1163
|
+
mockSpawn.mockImplementationOnce(createMockSpawn({
|
|
1164
|
+
outputData: JSON.stringify({
|
|
1165
|
+
type: 'match',
|
|
1166
|
+
data: {
|
|
1167
|
+
path: { text: 'fileA.txt' },
|
|
1168
|
+
line_number: 1,
|
|
1169
|
+
lines: { text: 'hello world\n' },
|
|
1170
|
+
},
|
|
1171
|
+
}) + '\n',
|
|
1172
|
+
exitCode: 0,
|
|
1173
|
+
}));
|
|
1174
|
+
let params = { pattern: 'HELLO' };
|
|
1175
|
+
let invocation = grepTool.build(params);
|
|
1176
|
+
let result = await invocation.execute(abortSignal);
|
|
1177
|
+
expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining(['--ignore-case']), expect.anything());
|
|
1178
|
+
expect(result.llmContent).toContain('Found 1 match for pattern "HELLO"');
|
|
1179
|
+
expect(result.llmContent).toContain('L1: hello world');
|
|
1180
|
+
// Case-sensitive search
|
|
1181
|
+
mockSpawn.mockImplementationOnce(createMockSpawn({
|
|
1182
|
+
outputData: JSON.stringify({
|
|
1183
|
+
type: 'match',
|
|
1184
|
+
data: {
|
|
1185
|
+
path: { text: 'fileA.txt' },
|
|
1186
|
+
line_number: 1,
|
|
1187
|
+
lines: { text: 'HELLO world\n' },
|
|
1188
|
+
},
|
|
1189
|
+
}) + '\n',
|
|
1190
|
+
exitCode: 0,
|
|
1191
|
+
}));
|
|
1192
|
+
params = { pattern: 'HELLO', case_sensitive: true };
|
|
1193
|
+
invocation = grepTool.build(params);
|
|
1194
|
+
result = await invocation.execute(abortSignal);
|
|
1195
|
+
expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.not.arrayContaining(['--ignore-case']), expect.anything());
|
|
1196
|
+
expect(result.llmContent).toContain('Found 1 match for pattern "HELLO"');
|
|
1197
|
+
expect(result.llmContent).toContain('L1: HELLO world');
|
|
1198
|
+
});
|
|
1199
|
+
it('should handle fixed_strings parameter', async () => {
|
|
1200
|
+
mockSpawn.mockImplementationOnce(createMockSpawn({
|
|
1201
|
+
outputData: JSON.stringify({
|
|
1202
|
+
type: 'match',
|
|
1203
|
+
data: {
|
|
1204
|
+
path: { text: 'fileA.txt' },
|
|
1205
|
+
line_number: 1,
|
|
1206
|
+
lines: { text: 'hello.world\n' },
|
|
1207
|
+
},
|
|
1208
|
+
}) + '\n',
|
|
1209
|
+
exitCode: 0,
|
|
1210
|
+
}));
|
|
1211
|
+
const params = {
|
|
1212
|
+
pattern: 'hello.world',
|
|
1213
|
+
fixed_strings: true,
|
|
1214
|
+
};
|
|
1215
|
+
const invocation = grepTool.build(params);
|
|
1216
|
+
const result = await invocation.execute(abortSignal);
|
|
1217
|
+
expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining(['--fixed-strings']), expect.anything());
|
|
1218
|
+
expect(result.llmContent).toContain('Found 1 match for pattern "hello.world"');
|
|
1219
|
+
expect(result.llmContent).toContain('L1: hello.world');
|
|
1220
|
+
});
|
|
1221
|
+
it('should handle no_ignore parameter', async () => {
|
|
1222
|
+
mockSpawn.mockImplementationOnce(createMockSpawn({
|
|
1223
|
+
outputData: JSON.stringify({
|
|
1224
|
+
type: 'match',
|
|
1225
|
+
data: {
|
|
1226
|
+
path: { text: 'ignored.log' },
|
|
1227
|
+
line_number: 1,
|
|
1228
|
+
lines: { text: 'secret log entry\n' },
|
|
1229
|
+
},
|
|
1230
|
+
}) + '\n',
|
|
1231
|
+
exitCode: 0,
|
|
1232
|
+
}));
|
|
1233
|
+
const params = { pattern: 'secret', no_ignore: true };
|
|
1234
|
+
const invocation = grepTool.build(params);
|
|
1235
|
+
const result = await invocation.execute(abortSignal);
|
|
1236
|
+
// Should have --no-ignore
|
|
1237
|
+
expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining(['--no-ignore']), expect.anything());
|
|
1238
|
+
// Should NOT have default excludes when no_ignore is true
|
|
1239
|
+
expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.not.arrayContaining(['--glob', '!node_modules']), expect.anything());
|
|
1240
|
+
expect(result.llmContent).toContain('Found 1 match for pattern "secret"');
|
|
1241
|
+
expect(result.llmContent).toContain('File: ignored.log');
|
|
1242
|
+
expect(result.llmContent).toContain('L1: secret log entry');
|
|
1243
|
+
});
|
|
1244
|
+
it('should handle context parameters', async () => {
|
|
1245
|
+
mockSpawn.mockImplementationOnce(createMockSpawn({
|
|
1246
|
+
outputData: JSON.stringify({
|
|
1247
|
+
type: 'match',
|
|
1248
|
+
data: {
|
|
1249
|
+
path: { text: 'fileA.txt' },
|
|
1250
|
+
line_number: 2,
|
|
1251
|
+
lines: { text: 'second line with world\n' },
|
|
1252
|
+
lines_before: [{ text: 'hello world\n' }],
|
|
1253
|
+
lines_after: [
|
|
1254
|
+
{ text: 'third line\n' },
|
|
1255
|
+
{ text: 'fourth line\n' },
|
|
1256
|
+
],
|
|
1257
|
+
},
|
|
1258
|
+
}) + '\n',
|
|
1259
|
+
exitCode: 0,
|
|
1260
|
+
}));
|
|
1261
|
+
const params = {
|
|
1262
|
+
pattern: 'world',
|
|
1263
|
+
context: 1,
|
|
1264
|
+
after: 2,
|
|
1265
|
+
before: 1,
|
|
1266
|
+
};
|
|
1267
|
+
const invocation = grepTool.build(params);
|
|
1268
|
+
const result = await invocation.execute(abortSignal);
|
|
1269
|
+
expect(mockSpawn).toHaveBeenLastCalledWith(expect.anything(), expect.arrayContaining([
|
|
1270
|
+
'--context',
|
|
1271
|
+
'1',
|
|
1272
|
+
'--after-context',
|
|
1273
|
+
'2',
|
|
1274
|
+
'--before-context',
|
|
1275
|
+
'1',
|
|
1276
|
+
]), expect.anything());
|
|
1277
|
+
expect(result.llmContent).toContain('Found 1 match for pattern "world"');
|
|
1278
|
+
expect(result.llmContent).toContain('File: fileA.txt');
|
|
1279
|
+
expect(result.llmContent).toContain('L2: second line with world');
|
|
1280
|
+
// Note: Ripgrep JSON output for context lines doesn't include line numbers for context lines directly
|
|
1281
|
+
// The current parsing only extracts the matched line, so we only assert on that.
|
|
1282
|
+
});
|
|
1283
|
+
});
|
|
962
1284
|
describe('getDescription', () => {
|
|
963
1285
|
it('should generate correct description with pattern only', () => {
|
|
964
1286
|
const params = { pattern: 'testPattern' };
|
|
965
1287
|
const invocation = grepTool.build(params);
|
|
966
|
-
expect(invocation.getDescription()).toBe("'testPattern'");
|
|
1288
|
+
expect(invocation.getDescription()).toBe("'testPattern' within ./");
|
|
967
1289
|
});
|
|
968
1290
|
it('should generate correct description with pattern and include', () => {
|
|
969
1291
|
const params = {
|
|
@@ -971,21 +1293,21 @@ describe('RipGrepTool', () => {
|
|
|
971
1293
|
include: '*.ts',
|
|
972
1294
|
};
|
|
973
1295
|
const invocation = grepTool.build(params);
|
|
974
|
-
expect(invocation.getDescription()).toBe("'testPattern' in *.ts");
|
|
1296
|
+
expect(invocation.getDescription()).toBe("'testPattern' in *.ts within ./");
|
|
975
1297
|
});
|
|
976
1298
|
it('should generate correct description with pattern and path', async () => {
|
|
977
1299
|
const dirPath = path.join(tempRootDir, 'src', 'app');
|
|
978
1300
|
await fs.mkdir(dirPath, { recursive: true });
|
|
979
1301
|
const params = {
|
|
980
1302
|
pattern: 'testPattern',
|
|
981
|
-
|
|
1303
|
+
dir_path: path.join('src', 'app'),
|
|
982
1304
|
};
|
|
983
1305
|
const invocation = grepTool.build(params);
|
|
984
1306
|
// The path will be relative to the tempRootDir, so we check for containment.
|
|
985
1307
|
expect(invocation.getDescription()).toContain("'testPattern' within");
|
|
986
1308
|
expect(invocation.getDescription()).toContain(path.join('src', 'app'));
|
|
987
1309
|
});
|
|
988
|
-
it('should
|
|
1310
|
+
it('should use ./ when no path is specified (defaults to CWD)', () => {
|
|
989
1311
|
// Create a mock config with multiple directories
|
|
990
1312
|
const multiDirConfig = {
|
|
991
1313
|
getTargetDir: () => tempRootDir,
|
|
@@ -995,7 +1317,7 @@ describe('RipGrepTool', () => {
|
|
|
995
1317
|
const multiDirGrepTool = new RipGrepTool(multiDirConfig);
|
|
996
1318
|
const params = { pattern: 'testPattern' };
|
|
997
1319
|
const invocation = multiDirGrepTool.build(params);
|
|
998
|
-
expect(invocation.getDescription()).toBe("'testPattern'
|
|
1320
|
+
expect(invocation.getDescription()).toBe("'testPattern' within ./");
|
|
999
1321
|
});
|
|
1000
1322
|
it('should generate correct description with pattern, include, and path', async () => {
|
|
1001
1323
|
const dirPath = path.join(tempRootDir, 'src', 'app');
|
|
@@ -1003,14 +1325,17 @@ describe('RipGrepTool', () => {
|
|
|
1003
1325
|
const params = {
|
|
1004
1326
|
pattern: 'testPattern',
|
|
1005
1327
|
include: '*.ts',
|
|
1006
|
-
|
|
1328
|
+
dir_path: path.join('src', 'app'),
|
|
1007
1329
|
};
|
|
1008
1330
|
const invocation = grepTool.build(params);
|
|
1009
1331
|
expect(invocation.getDescription()).toContain("'testPattern' in *.ts within");
|
|
1010
1332
|
expect(invocation.getDescription()).toContain(path.join('src', 'app'));
|
|
1011
1333
|
});
|
|
1012
1334
|
it('should use ./ for root path in description', () => {
|
|
1013
|
-
const params = {
|
|
1335
|
+
const params = {
|
|
1336
|
+
pattern: 'testPattern',
|
|
1337
|
+
dir_path: '.',
|
|
1338
|
+
};
|
|
1014
1339
|
const invocation = grepTool.build(params);
|
|
1015
1340
|
expect(invocation.getDescription()).toBe("'testPattern' within ./");
|
|
1016
1341
|
});
|