@crownpeak/dqm-react-component-dev-mcp 1.2.0
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/README.md +138 -0
- package/data/.env.example +22 -0
- package/data/.gitattributes +47 -0
- package/data/.glfrc.json +7 -0
- package/data/.husky/pre-commit +5 -0
- package/data/.nvmrc +1 -0
- package/data/CHANGELOG.md +75 -0
- package/data/CODE_OF_CONDUCT.md +129 -0
- package/data/CONTRIBUTING.md +203 -0
- package/data/DOCS-STRUCTURE.md +307 -0
- package/data/I18N.md +292 -0
- package/data/LICENSE +22 -0
- package/data/README.md +315 -0
- package/data/SECURITY.md +125 -0
- package/data/WIKI-DEPLOYMENT.md +348 -0
- package/data/docs/AI-FEATURES.md +610 -0
- package/data/docs/API-REFERENCE.md +1022 -0
- package/data/docs/AUTHENTICATION.md +301 -0
- package/data/docs/BACKEND-API.md +468 -0
- package/data/docs/DEVELOPMENT.md +375 -0
- package/data/docs/EXAMPLES.md +622 -0
- package/data/docs/MCP-SERVER.md +307 -0
- package/data/docs/MIGRATION-GUIDE.md +367 -0
- package/data/docs/NPM-PUBLISH.md +193 -0
- package/data/docs/QUICKSTART.md +206 -0
- package/data/docs/REDIS-SETUP.md +162 -0
- package/data/docs/SERVER.md +228 -0
- package/data/docs/TROUBLESHOOTING.md +657 -0
- package/data/docs/WIDGET-GUIDE.md +638 -0
- package/data/docs/WIKI-HOME.md +58 -0
- package/data/docs/WIKI-SIDEBAR.md +39 -0
- package/data/package.json +171 -0
- package/data/playwright.config.ts +64 -0
- package/data/probe/.cargo/config.toml +10 -0
- package/data/probe/.claude/commands/performance-review.md +15 -0
- package/data/probe/.clinerules +288 -0
- package/data/probe/.dockerignore +57 -0
- package/data/probe/.githooks/post-commit +11 -0
- package/data/probe/.githooks/pre-commit +99 -0
- package/data/probe/.githooks/pre-commit-vow +9 -0
- package/data/probe/.prompts/engineer.md +41 -0
- package/data/probe/.roomodes +28 -0
- package/data/probe/.windsurfrules +0 -0
- package/data/probe/BASH_TOOL_SUMMARY.md +148 -0
- package/data/probe/BENCHMARKING.md +256 -0
- package/data/probe/CLAUDE.md +226 -0
- package/data/probe/CODE_OF_CONDUCT.md +128 -0
- package/data/probe/CONTRIBUTING.md +193 -0
- package/data/probe/Cargo.toml +120 -0
- package/data/probe/Cross.toml +10 -0
- package/data/probe/DOCKER-README.md +224 -0
- package/data/probe/Dockerfile +32 -0
- package/data/probe/ENHANCED_DEBUG_TELEMETRY.md +188 -0
- package/data/probe/LICENSE +201 -0
- package/data/probe/Makefile +210 -0
- package/data/probe/README.md +824 -0
- package/data/probe/SECURITY.md +67 -0
- package/data/probe/WINDOWS-GUIDE.md +294 -0
- package/data/probe/benches/parsing_benchmarks.rs +370 -0
- package/data/probe/benches/search_benchmarks.rs +599 -0
- package/data/probe/benches/simd_benchmarks.rs +372 -0
- package/data/probe/benches/timing_benchmarks.rs +287 -0
- package/data/probe/build-windows.bat +229 -0
- package/data/probe/codex-config/config.toml +6 -0
- package/data/probe/docs/PERFORMANCE_OPTIMIZATION.md +161 -0
- package/data/probe/examples/cache_demo.rs +46 -0
- package/data/probe/examples/chat/.dockerignore +37 -0
- package/data/probe/examples/chat/ChatSessionManager.js +295 -0
- package/data/probe/examples/chat/Dockerfile +98 -0
- package/data/probe/examples/chat/LICENSE +201 -0
- package/data/probe/examples/chat/LOCAL_IMAGE_SUPPORT.md +195 -0
- package/data/probe/examples/chat/MCP_INTEGRATION.md +400 -0
- package/data/probe/examples/chat/README.md +338 -0
- package/data/probe/examples/chat/TRACING.md +226 -0
- package/data/probe/examples/chat/appTracer.js +968 -0
- package/data/probe/examples/chat/auth.js +76 -0
- package/data/probe/examples/chat/bin/probe-chat.js +13 -0
- package/data/probe/examples/chat/build.js +104 -0
- package/data/probe/examples/chat/cancelRequest.js +84 -0
- package/data/probe/examples/chat/demo-agentic-image-flow.js +88 -0
- package/data/probe/examples/chat/demo-local-images.js +128 -0
- package/data/probe/examples/chat/fileSpanExporter.js +181 -0
- package/data/probe/examples/chat/implement/README.md +228 -0
- package/data/probe/examples/chat/implement/backends/AiderBackend.js +750 -0
- package/data/probe/examples/chat/implement/backends/BaseBackend.js +276 -0
- package/data/probe/examples/chat/implement/backends/ClaudeCodeBackend.js +767 -0
- package/data/probe/examples/chat/implement/backends/MockBackend.js +237 -0
- package/data/probe/examples/chat/implement/backends/registry.js +85 -0
- package/data/probe/examples/chat/implement/core/BackendManager.js +567 -0
- package/data/probe/examples/chat/implement/core/ImplementTool.js +354 -0
- package/data/probe/examples/chat/implement/core/config.js +428 -0
- package/data/probe/examples/chat/implement/core/timeouts.js +58 -0
- package/data/probe/examples/chat/implement/core/utils.js +496 -0
- package/data/probe/examples/chat/implement/types/BackendTypes.js +126 -0
- package/data/probe/examples/chat/index.js +669 -0
- package/data/probe/examples/chat/mcpServer.js +341 -0
- package/data/probe/examples/chat/npm/LICENSE +15 -0
- package/data/probe/examples/chat/npm/README.md +168 -0
- package/data/probe/examples/chat/npm/bin/probe-chat.js +156 -0
- package/data/probe/examples/chat/npm/index.js +259 -0
- package/data/probe/examples/chat/npm/package.json +54 -0
- package/data/probe/examples/chat/package.json +102 -0
- package/data/probe/examples/chat/probeChat.js +456 -0
- package/data/probe/examples/chat/probeTool.js +491 -0
- package/data/probe/examples/chat/storage/JsonChatStorage.js +476 -0
- package/data/probe/examples/chat/telemetry.js +281 -0
- package/data/probe/examples/chat/test/integration/chatFlows.test.js +320 -0
- package/data/probe/examples/chat/test/integration/toolCalling.test.js +471 -0
- package/data/probe/examples/chat/test/mocks/mockLLMProvider.js +269 -0
- package/data/probe/examples/chat/test/test-backends.js +90 -0
- package/data/probe/examples/chat/test/testUtils.js +530 -0
- package/data/probe/examples/chat/test/unit/backendTimeout.test.js +161 -0
- package/data/probe/examples/chat/test/unit/packageFiles.test.js +120 -0
- package/data/probe/examples/chat/test/verify-tests.js +118 -0
- package/data/probe/examples/chat/test-agentic-image-loading.js +294 -0
- package/data/probe/examples/chat/test-ai-sdk-telemetry.js +204 -0
- package/data/probe/examples/chat/test-chat-tracing.js +38 -0
- package/data/probe/examples/chat/test-direct-function.js +49 -0
- package/data/probe/examples/chat/test-file-size-validation.js +103 -0
- package/data/probe/examples/chat/test-full-mcp-integration.js +258 -0
- package/data/probe/examples/chat/test-github-context.txt +12 -0
- package/data/probe/examples/chat/test-hierarchy.js +203 -0
- package/data/probe/examples/chat/test-image-spans.js +37 -0
- package/data/probe/examples/chat/test-local-image-reading.js +176 -0
- package/data/probe/examples/chat/test-mcp-integration.js +136 -0
- package/data/probe/examples/chat/test-mcp-probe-server.js +161 -0
- package/data/probe/examples/chat/test-mcp-with-ai.js +279 -0
- package/data/probe/examples/chat/test-multiple-allowed-dirs.js +111 -0
- package/data/probe/examples/chat/test-probe-mcp-server.js +110 -0
- package/data/probe/examples/chat/test-security-validation.js +145 -0
- package/data/probe/examples/chat/test-simple-tracing.js +32 -0
- package/data/probe/examples/chat/test-trace-verification.js +235 -0
- package/data/probe/examples/chat/test-tracing.js +114 -0
- package/data/probe/examples/chat/tokenCounter.js +419 -0
- package/data/probe/examples/chat/tokenUsageDisplay.js +134 -0
- package/data/probe/examples/chat/webServer.js +1103 -0
- package/data/probe/examples/reranker/Cargo.toml +33 -0
- package/data/probe/examples/reranker/DEBUG_OUTPUT_ANALYSIS.md +71 -0
- package/data/probe/examples/reranker/MODELS.md +66 -0
- package/data/probe/examples/reranker/MODEL_COMPARISON.md +60 -0
- package/data/probe/examples/reranker/MULTI_MODEL_ANALYSIS.md +176 -0
- package/data/probe/examples/reranker/PERFORMANCE_SUMMARY.md +156 -0
- package/data/probe/examples/reranker/README.md +347 -0
- package/data/probe/examples/reranker/RUST_BERT_COMPARISON.md +82 -0
- package/data/probe/examples/reranker/TOKENIZATION_GUIDE.md +120 -0
- package/data/probe/examples/reranker/check_rust_tokenizer.py +108 -0
- package/data/probe/examples/reranker/convert_to_torchscript.py +109 -0
- package/data/probe/examples/reranker/debug_scoring.py +189 -0
- package/data/probe/examples/reranker/debug_tokenization.py +154 -0
- package/data/probe/examples/reranker/download_models.sh +73 -0
- package/data/probe/examples/reranker/requirements.txt +13 -0
- package/data/probe/examples/reranker/run_comprehensive_benchmark.sh +83 -0
- package/data/probe/examples/reranker/rust_bert_test/Cargo.toml +12 -0
- package/data/probe/examples/reranker/rust_bert_test/README.md +54 -0
- package/data/probe/examples/reranker/simple_test.py +50 -0
- package/data/probe/examples/reranker/test_all_models.sh +63 -0
- package/data/probe/examples/reranker/test_bert_results.sh +44 -0
- package/data/probe/examples/reranker/test_cross_encoder.py +334 -0
- package/data/probe/examples/reranker/test_cross_encoder.sh +80 -0
- package/data/probe/examples/reranker/test_exact_comparison.py +151 -0
- package/data/probe/examples/reranker/test_parallel_performance.sh +56 -0
- package/data/probe/examples/reranker/test_scores.py +132 -0
- package/data/probe/install.ps1 +508 -0
- package/data/probe/install.sh +460 -0
- package/data/probe/npm/CLONE_METHOD_EXAMPLES.md +596 -0
- package/data/probe/npm/CONTEXT_COMPACTION.md +303 -0
- package/data/probe/npm/DELEGATE_TOOL_README.md +166 -0
- package/data/probe/npm/MAID_INTEGRATION.md +313 -0
- package/data/probe/npm/MCP_INTEGRATION_SUMMARY.md +241 -0
- package/data/probe/npm/README.md +824 -0
- package/data/probe/npm/bin/.gitignore +7 -0
- package/data/probe/npm/bin/.gitkeep +0 -0
- package/data/probe/npm/bin/README.md +12 -0
- package/data/probe/npm/bin/probe +167 -0
- package/data/probe/npm/docs/CLAUDE_CODE_INTEGRATION.md +414 -0
- package/data/probe/npm/docs/CODEX_INTEGRATION.md +502 -0
- package/data/probe/npm/docs/EDIT_CREATE_TOOLS.md +233 -0
- package/data/probe/npm/docs/RETRY_AND_FALLBACK.md +674 -0
- package/data/probe/npm/example-usage.js +335 -0
- package/data/probe/npm/examples/multi-engine-demo.js +117 -0
- package/data/probe/npm/examples/probe-agent-cli.js +113 -0
- package/data/probe/npm/examples/test-agent-edit.js +114 -0
- package/data/probe/npm/examples/test-edit-create.js +120 -0
- package/data/probe/npm/examples/test-edit-direct.js +114 -0
- package/data/probe/npm/index.d.ts +744 -0
- package/data/probe/npm/jest.config.js +52 -0
- package/data/probe/npm/package.json +117 -0
- package/data/probe/npm/scripts/build-agent.cjs +75 -0
- package/data/probe/npm/scripts/build-cjs.js +124 -0
- package/data/probe/npm/scripts/build-mcp.cjs +36 -0
- package/data/probe/npm/scripts/postinstall.js +216 -0
- package/data/probe/npm/test-codex-e2e.js +78 -0
- package/data/probe/npm/test-download-lock.js +109 -0
- package/data/probe/npm/test-grep-security.js +94 -0
- package/data/probe/npm/test-grep-simplified.js +63 -0
- package/data/probe/npm/test-grep.js +51 -0
- package/data/probe/npm/tests/README.md +96 -0
- package/data/probe/npm/tests/agent-compact-history.test.js +174 -0
- package/data/probe/npm/tests/allow-tests-default.test.js +151 -0
- package/data/probe/npm/tests/contextCompactor.test.js +498 -0
- package/data/probe/npm/tests/delegate-config.test.js +353 -0
- package/data/probe/npm/tests/delegate-integration.test.js +348 -0
- package/data/probe/npm/tests/extractor-integration.test.js +162 -0
- package/data/probe/npm/tests/extractor.test.js +317 -0
- package/data/probe/npm/tests/fixtures/sampleDiagrams.js +267 -0
- package/data/probe/npm/tests/integration/claude-code-auto-fallback.spec.js +148 -0
- package/data/probe/npm/tests/integration/claude-code-multi-step.spec.js +127 -0
- package/data/probe/npm/tests/integration/claude-code-tool-events.spec.js +163 -0
- package/data/probe/npm/tests/integration/codex-auto-fallback.spec.js +191 -0
- package/data/probe/npm/tests/integration/codex-tool-events.spec.js +147 -0
- package/data/probe/npm/tests/integration/examplesChatMcp.test.js +402 -0
- package/data/probe/npm/tests/integration/mcpDotenvSupport.test.js +174 -0
- package/data/probe/npm/tests/integration/mcpErrorHandling.test.js +566 -0
- package/data/probe/npm/tests/integration/mcpRobustness.test.js +564 -0
- package/data/probe/npm/tests/integration/mcpStdoutPurity.test.js +355 -0
- package/data/probe/npm/tests/integration/probeAgentMcp.test.js +398 -0
- package/data/probe/npm/tests/integration/retryFallback.test.js +368 -0
- package/data/probe/npm/tests/integration/schema-in-initial-message.test.js +318 -0
- package/data/probe/npm/tests/integration/schema-validation-loop-prevention.test.js +244 -0
- package/data/probe/npm/tests/integration/schemaRetryLogic.test.js +94 -0
- package/data/probe/npm/tests/integration/validationFlow.test.js +329 -0
- package/data/probe/npm/tests/manual/test-codex-basic.js +110 -0
- package/data/probe/npm/tests/mcp/mcpClientManager.test.js +614 -0
- package/data/probe/npm/tests/mcp/mcpConfig.test.js +359 -0
- package/data/probe/npm/tests/mcp/mcpXmlBridge.test.js +436 -0
- package/data/probe/npm/tests/mcp/mockMcpServer.js +510 -0
- package/data/probe/npm/tests/mcp-strict-syntax.test.js +319 -0
- package/data/probe/npm/tests/mermaidQuoteEscaping.test.js +214 -0
- package/data/probe/npm/tests/nestedQuoteFix.test.js +40 -0
- package/data/probe/npm/tests/setup.js +46 -0
- package/data/probe/npm/tests/unit/allowed-tools.test.js +513 -0
- package/data/probe/npm/tests/unit/attempt-completion-closing-tag-in-content.test.js +188 -0
- package/data/probe/npm/tests/unit/attemptCompletionJsonFix.test.js +238 -0
- package/data/probe/npm/tests/unit/attemptCompletionJsonIssue.test.js +128 -0
- package/data/probe/npm/tests/unit/backtickAutoFix.test.js +35 -0
- package/data/probe/npm/tests/unit/bash-probe-agent-integration.test.js +389 -0
- package/data/probe/npm/tests/unit/bash-simple-commands.test.js +324 -0
- package/data/probe/npm/tests/unit/bash-tool-comprehensive.test.js +371 -0
- package/data/probe/npm/tests/unit/bash-tool-integration.test.js +310 -0
- package/data/probe/npm/tests/unit/bash-tool.test.js +341 -0
- package/data/probe/npm/tests/unit/completion-prompt.test.js +379 -0
- package/data/probe/npm/tests/unit/cwd-path-options.test.js +287 -0
- package/data/probe/npm/tests/unit/delegate-limits.test.js +422 -0
- package/data/probe/npm/tests/unit/direct-content-attempt-completion.test.js +235 -0
- package/data/probe/npm/tests/unit/edit-create-tools.test.js +609 -0
- package/data/probe/npm/tests/unit/enhancedMermaidValidation.test.js +577 -0
- package/data/probe/npm/tests/unit/extract-content.test.js +83 -0
- package/data/probe/npm/tests/unit/extract-multiple-targets.test.js +89 -0
- package/data/probe/npm/tests/unit/fallbackManager.test.js +442 -0
- package/data/probe/npm/tests/unit/githubCompatibilityValidation.test.js +258 -0
- package/data/probe/npm/tests/unit/imageConfig.test.js +149 -0
- package/data/probe/npm/tests/unit/imagePathResolution.test.js +345 -0
- package/data/probe/npm/tests/unit/json-fixing-agent.test.js +238 -0
- package/data/probe/npm/tests/unit/json-validation-enhanced-errors.test.js +199 -0
- package/data/probe/npm/tests/unit/jsonValidationInfiniteLoopFix.test.js +228 -0
- package/data/probe/npm/tests/unit/maidIntegration.test.js +139 -0
- package/data/probe/npm/tests/unit/maxIterationsWarning.test.js +195 -0
- package/data/probe/npm/tests/unit/mermaidEdgeLabelFix.test.js +161 -0
- package/data/probe/npm/tests/unit/mermaidHtmlEntities.test.js +76 -0
- package/data/probe/npm/tests/unit/mermaidInfiniteLoopFix.test.js +64 -0
- package/data/probe/npm/tests/unit/mermaidValidation.test.js +723 -0
- package/data/probe/npm/tests/unit/mermaidValidationVisorExample.test.js +309 -0
- package/data/probe/npm/tests/unit/probe-agent-clone-realistic.test.js +643 -0
- package/data/probe/npm/tests/unit/probe-agent-clone.test.js +476 -0
- package/data/probe/npm/tests/unit/probe-agent-delegate.test.js +400 -0
- package/data/probe/npm/tests/unit/probe-agent-model-option.test.js +118 -0
- package/data/probe/npm/tests/unit/probeTool-security.test.js +283 -0
- package/data/probe/npm/tests/unit/readImageTool.test.js +418 -0
- package/data/probe/npm/tests/unit/retryManager.test.js +317 -0
- package/data/probe/npm/tests/unit/schema-aware-reminders.test.js +288 -0
- package/data/probe/npm/tests/unit/schemaDefinitionDetection.test.js +115 -0
- package/data/probe/npm/tests/unit/schemaUtils.test.js +1268 -0
- package/data/probe/npm/tests/unit/simpleTelemetry.test.js +282 -0
- package/data/probe/npm/tests/unit/simplified-attempt-completion.test.js +274 -0
- package/data/probe/npm/tests/unit/single-quote-json-bug.test.js +231 -0
- package/data/probe/npm/tests/unit/subgraphAutoFix.test.js +110 -0
- package/data/probe/npm/tests/unit/system-prompt.test.js +32 -0
- package/data/probe/npm/tests/unit/types-probe-agent-options.test.js +42 -0
- package/data/probe/npm/tests/unit/xmlParsing.test.js +720 -0
- package/data/probe/npm/tsconfig.json +21 -0
- package/data/probe/result1.txt +19 -0
- package/data/probe/result2.txt +26 -0
- package/data/probe/scripts/benchmark.sh +270 -0
- package/data/probe/scripts/cache_memory_analysis.rs +844 -0
- package/data/probe/scripts/claude-hook-wrapper.sh +56 -0
- package/data/probe/site/.env.example +10 -0
- package/data/probe/site/DEPLOYMENT.md +86 -0
- package/data/probe/site/README.md +183 -0
- package/data/probe/site/adding-languages.md +135 -0
- package/data/probe/site/ai-chat.md +427 -0
- package/data/probe/site/ai-integration.md +1488 -0
- package/data/probe/site/blog/agentic-flow-custom-xml-protocol.md +407 -0
- package/data/probe/site/blog/index.md +118 -0
- package/data/probe/site/blog/v0.6.0-release.md +426 -0
- package/data/probe/site/blog.md +8 -0
- package/data/probe/site/changelog.md +200 -0
- package/data/probe/site/cli-mode.md +437 -0
- package/data/probe/site/code-extraction.md +436 -0
- package/data/probe/site/contributing/README.md +9 -0
- package/data/probe/site/contributing/documentation-cross-references.md +215 -0
- package/data/probe/site/contributing/documentation-maintenance.md +275 -0
- package/data/probe/site/contributing/documentation-structure.md +75 -0
- package/data/probe/site/documentation-cross-references.md +215 -0
- package/data/probe/site/documentation-guide.md +132 -0
- package/data/probe/site/documentation-maintenance.md +275 -0
- package/data/probe/site/features.md +147 -0
- package/data/probe/site/how-it-works.md +118 -0
- package/data/probe/site/index.md +175 -0
- package/data/probe/site/index.md.bak +133 -0
- package/data/probe/site/installation.md +235 -0
- package/data/probe/site/integrations/docker.md +248 -0
- package/data/probe/site/integrations/github-actions.md +413 -0
- package/data/probe/site/language-support-overview.md +168 -0
- package/data/probe/site/mcp-integration.md +587 -0
- package/data/probe/site/mcp-server.md +304 -0
- package/data/probe/site/navigation-structure.md +76 -0
- package/data/probe/site/nodejs-sdk.md +798 -0
- package/data/probe/site/output-formats.md +625 -0
- package/data/probe/site/package.json +21 -0
- package/data/probe/site/public/_headers +28 -0
- package/data/probe/site/public/_redirects +11 -0
- package/data/probe/site/quick-start.md +289 -0
- package/data/probe/site/search-functionality.md +291 -0
- package/data/probe/site/search-reference.md +291 -0
- package/data/probe/site/supported-languages.md +215 -0
- package/data/probe/site/use-cases/README.md +8 -0
- package/data/probe/site/use-cases/advanced-cli.md +253 -0
- package/data/probe/site/use-cases/ai-code-editors.md +239 -0
- package/data/probe/site/use-cases/building-ai-tools.md +529 -0
- package/data/probe/site/use-cases/cli-ai-workflows.md +285 -0
- package/data/probe/site/use-cases/deploying-probe-web-interface.md +255 -0
- package/data/probe/site/use-cases/integrating-probe-into-ai-code-editors.md +161 -0
- package/data/probe/site/use-cases/nodejs-sdk.md +596 -0
- package/data/probe/site/use-cases/team-chat.md +350 -0
- package/data/probe/site/web-interface.md +434 -0
- package/data/probe/site/wrangler.toml +9 -0
- package/data/probe/test-api-key.sh +1 -0
- package/data/probe/test-probe-implementation/hello.js +7 -0
- package/data/probe/test_cases/demonstrate_early_termination_issues.sh +176 -0
- package/data/probe/test_cases/early_termination_issues.rs +533 -0
- package/data/probe/test_data/test_nested_struct.go +26 -0
- package/data/probe/tests/README.md +286 -0
- package/data/probe/tests/README_search_determinism_tests.md +116 -0
- package/data/probe/tests/adjacent_comment_test.rs +152 -0
- package/data/probe/tests/apostrophe_handling_tests.rs +132 -0
- package/data/probe/tests/block_filtering_with_ast_tests.rs +669 -0
- package/data/probe/tests/block_merging_tests.rs +396 -0
- package/data/probe/tests/c_outline_format_tests.rs +2179 -0
- package/data/probe/tests/cache_invalidation_issues.rs.disabled +682 -0
- package/data/probe/tests/cache_order_tests.rs +147 -0
- package/data/probe/tests/cache_query_scoping_tests.rs +221 -0
- package/data/probe/tests/cli_tests.rs +680 -0
- package/data/probe/tests/comment_context_integration_test.rs +240 -0
- package/data/probe/tests/common.rs +33 -0
- package/data/probe/tests/complex_block_merging_tests.rs +599 -0
- package/data/probe/tests/complex_query_block_filtering_tests.rs +422 -0
- package/data/probe/tests/control_flow_closing_braces_test.rs +91 -0
- package/data/probe/tests/cpp_outline_format_tests.rs +1507 -0
- package/data/probe/tests/csharp_outline_format_tests.rs +941 -0
- package/data/probe/tests/elastic_query_integration_tests.rs +922 -0
- package/data/probe/tests/extract_command_tests.rs +1848 -0
- package/data/probe/tests/extract_deduplication_tests.rs +146 -0
- package/data/probe/tests/extract_input_file_tests.rs +84 -0
- package/data/probe/tests/extract_prompt_tests.rs +102 -0
- package/data/probe/tests/filename_search_tests.rs +96 -0
- package/data/probe/tests/fixtures/user/AssemblyInfo.cs +3 -0
- package/data/probe/tests/github_extract_tests.rs +234 -0
- package/data/probe/tests/go_comment_test.rs +253 -0
- package/data/probe/tests/go_outline_format_tests.rs +2587 -0
- package/data/probe/tests/go_path_resolver_tests.rs +96 -0
- package/data/probe/tests/html_outline_format_tests.rs +637 -0
- package/data/probe/tests/integration_tests.rs +837 -0
- package/data/probe/tests/ip_whitelist_test.rs +148 -0
- package/data/probe/tests/java_outline_format_tests.rs +1611 -0
- package/data/probe/tests/javascript_extract_tests.rs +315 -0
- package/data/probe/tests/javascript_outline_format_tests.rs +1464 -0
- package/data/probe/tests/json_format_tests.rs +436 -0
- package/data/probe/tests/json_schema_validation_tests.rs +450 -0
- package/data/probe/tests/lib_usage.rs +60 -0
- package/data/probe/tests/line_comment_context_extension_test.rs +459 -0
- package/data/probe/tests/line_map_cache_tests.rs +114 -0
- package/data/probe/tests/markdown_integration_tests.rs +190 -0
- package/data/probe/tests/mocks/test_ip_whitelist.go +11 -0
- package/data/probe/tests/mocks/test_object.js +27 -0
- package/data/probe/tests/mocks/test_struct.go +50 -0
- package/data/probe/tests/multi_keyword_pattern_tests.rs +464 -0
- package/data/probe/tests/multi_language_syntax_integration_tests.rs +218 -0
- package/data/probe/tests/multiple_capture_groups_tests.rs +169 -0
- package/data/probe/tests/negative_compound_word_tests.rs +246 -0
- package/data/probe/tests/nested_symbol_extraction_tests.rs +99 -0
- package/data/probe/tests/outline_cross_file_interference_test.rs +335 -0
- package/data/probe/tests/outline_keyword_preservation_test.rs +67 -0
- package/data/probe/tests/output_format_edge_cases_tests.rs +693 -0
- package/data/probe/tests/parallel_extraction_tests.rs +178 -0
- package/data/probe/tests/parallel_search_tests.rs +355 -0
- package/data/probe/tests/path_resolver_tests.rs +698 -0
- package/data/probe/tests/php_outline_format_extended_tests.rs +928 -0
- package/data/probe/tests/php_outline_format_tests.rs +768 -0
- package/data/probe/tests/property_tests.proptest-regressions +9 -0
- package/data/probe/tests/property_tests.rs +118 -0
- package/data/probe/tests/python_outline_format_tests.rs +1538 -0
- package/data/probe/tests/query_command_json_tests.rs +438 -0
- package/data/probe/tests/query_command_tests.rs +232 -0
- package/data/probe/tests/query_command_xml_tests.rs +569 -0
- package/data/probe/tests/quoted_term_with_negative_keyword_tests.rs +216 -0
- package/data/probe/tests/required_terms_filename_tests.rs +116 -0
- package/data/probe/tests/ruby_outline_format_tests.rs +1011 -0
- package/data/probe/tests/rust_line_comment_context_test.rs +151 -0
- package/data/probe/tests/rust_outline_format_enhanced_tests.rs +725 -0
- package/data/probe/tests/rust_outline_format_tests.rs +843 -0
- package/data/probe/tests/schemas/xml_output_schema.xsd +38 -0
- package/data/probe/tests/search_determinism_tests.rs +451 -0
- package/data/probe/tests/search_hints_tests.rs +253 -0
- package/data/probe/tests/special_character_escaping_tests.rs +417 -0
- package/data/probe/tests/stemming_compound_word_filtering_tests.rs +535 -0
- package/data/probe/tests/strict_elastic_syntax_tests.rs +404 -0
- package/data/probe/tests/swift_outline_format_tests.rs +3319 -0
- package/data/probe/tests/symbols_tests.rs +166 -0
- package/data/probe/tests/test_file.rs +45 -0
- package/data/probe/tests/test_tokenize.rs +28 -0
- package/data/probe/tests/timeout_tests.rs +82 -0
- package/data/probe/tests/tokenization_tests.rs +195 -0
- package/data/probe/tests/tokenized_block_filtering_tests.rs +174 -0
- package/data/probe/tests/typescript_extract_tests.rs +214 -0
- package/data/probe/tests/typescript_outline_format_tests.rs +2188 -0
- package/data/probe/tests/xml_format_tests.rs +568 -0
- package/data/probe/tests/xml_schema_validation_tests.rs +497 -0
- package/data/scripts/postinstall.mjs +9 -0
- package/data/scripts/set-version.js +0 -0
- package/data/scripts/wiki-build.sh +111 -0
- package/data/scripts/wiki-deploy.sh +73 -0
- package/data/serve.json +12 -0
- package/data/test/demo-dynamic.html +134 -0
- package/data/test/demo-esm.html +105 -0
- package/data/test/demo-iife.html +78 -0
- package/data/tsconfig.json +7 -0
- package/data/vite.server.ts +483 -0
- package/data/vitest.config.ts +40 -0
- package/data/wiki/Home.md +58 -0
- package/data/wiki/_Sidebar.md +39 -0
- package/docs-mcp.config.json +20 -0
- package/package.json +56 -0
- package/src/config.js +111 -0
- package/src/index.js +395 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive integration test for the complete bash tool feature
|
|
3
|
+
* This test validates the entire bash tool implementation from CLI to execution
|
|
4
|
+
* @module tests/unit/bash-tool-comprehensive
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { jest, describe, test, expect, beforeEach } from '@jest/globals';
|
|
8
|
+
|
|
9
|
+
// Mock external dependencies
|
|
10
|
+
jest.mock('ai', () => ({
|
|
11
|
+
tool: jest.fn((config) => ({
|
|
12
|
+
name: config.name,
|
|
13
|
+
description: config.description,
|
|
14
|
+
inputSchema: config.inputSchema,
|
|
15
|
+
execute: config.execute
|
|
16
|
+
}))
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
// Import the components we want to test
|
|
20
|
+
import { BashPermissionChecker } from '../../src/agent/bashPermissions.js';
|
|
21
|
+
import { executeBashCommand, formatExecutionResult } from '../../src/agent/bashExecutor.js';
|
|
22
|
+
import { DEFAULT_ALLOW_PATTERNS, DEFAULT_DENY_PATTERNS } from '../../src/agent/bashDefaults.js';
|
|
23
|
+
import { bashTool } from '../../src/tools/bash.js';
|
|
24
|
+
|
|
25
|
+
describe('Bash Tool - End-to-End Integration', () => {
|
|
26
|
+
describe('Complete Permission Flow', () => {
|
|
27
|
+
test('should implement secure-by-default approach', async () => {
|
|
28
|
+
// Create a bash tool with default security settings
|
|
29
|
+
const tool = bashTool({
|
|
30
|
+
debug: false,
|
|
31
|
+
bashConfig: { timeout: 5000 }
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Test that safe commands are allowed
|
|
35
|
+
const safeCommands = [
|
|
36
|
+
'ls -la',
|
|
37
|
+
'pwd',
|
|
38
|
+
'echo hello',
|
|
39
|
+
'git status',
|
|
40
|
+
'cat package.json',
|
|
41
|
+
'grep "test" package.json', // Changed from recursive to specific file
|
|
42
|
+
'find ./src -name "*.js" -maxdepth 2', // Limited depth to avoid timeout
|
|
43
|
+
'npm list --depth=0' // Limited depth for faster execution
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
for (const command of safeCommands) {
|
|
47
|
+
const result = await tool.execute({ command });
|
|
48
|
+
expect(result).not.toContain('Permission denied');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Test that dangerous commands are blocked
|
|
52
|
+
const dangerousCommands = [
|
|
53
|
+
'rm -rf /',
|
|
54
|
+
'sudo apt-get install',
|
|
55
|
+
'chmod 777 /',
|
|
56
|
+
'npm install express',
|
|
57
|
+
'git push origin main',
|
|
58
|
+
'killall node',
|
|
59
|
+
'shutdown now'
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
for (const command of dangerousCommands) {
|
|
63
|
+
const result = await tool.execute({ command });
|
|
64
|
+
expect(result).toContain('Permission denied');
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('should support custom configuration patterns', async () => {
|
|
69
|
+
// Create tool with custom allow/deny patterns
|
|
70
|
+
const tool = bashTool({
|
|
71
|
+
debug: false,
|
|
72
|
+
bashConfig: {
|
|
73
|
+
allow: ['docker:ps', 'make:help'],
|
|
74
|
+
deny: ['echo:dangerous'],
|
|
75
|
+
timeout: 5000
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Custom allow should work
|
|
80
|
+
const result1 = await tool.execute({ command: 'docker ps' });
|
|
81
|
+
expect(result1).not.toContain('Permission denied');
|
|
82
|
+
|
|
83
|
+
// Custom deny should work
|
|
84
|
+
const result2 = await tool.execute({ command: 'echo dangerous' });
|
|
85
|
+
expect(result2).toContain('Permission denied');
|
|
86
|
+
|
|
87
|
+
// Default allows should still work
|
|
88
|
+
const result3 = await tool.execute({ command: 'ls' });
|
|
89
|
+
expect(result3).not.toContain('Permission denied');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('should support override modes', async () => {
|
|
93
|
+
// Create tool with custom-only patterns
|
|
94
|
+
const tool = bashTool({
|
|
95
|
+
debug: false,
|
|
96
|
+
bashConfig: {
|
|
97
|
+
allow: ['echo', 'pwd'],
|
|
98
|
+
deny: ['pwd:bad'],
|
|
99
|
+
disableDefaultAllow: true,
|
|
100
|
+
disableDefaultDeny: true,
|
|
101
|
+
timeout: 5000
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Only custom allows should work
|
|
106
|
+
const result1 = await tool.execute({ command: 'echo hello' });
|
|
107
|
+
expect(result1).not.toContain('Permission denied');
|
|
108
|
+
|
|
109
|
+
// Default allows should be denied
|
|
110
|
+
const result2 = await tool.execute({ command: 'ls' });
|
|
111
|
+
expect(result2).toContain('not in allow list');
|
|
112
|
+
|
|
113
|
+
// Custom deny should work
|
|
114
|
+
const result3 = await tool.execute({ command: 'pwd bad' });
|
|
115
|
+
expect(result3).toContain('Permission denied');
|
|
116
|
+
|
|
117
|
+
// Default dangerous commands should be allowed (if in custom allow)
|
|
118
|
+
const result4 = await tool.execute({ command: 'rm -rf /' });
|
|
119
|
+
expect(result4).toContain('not in allow list'); // Not in custom allow
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
describe('Real Command Execution Integration', () => {
|
|
124
|
+
test('should execute real safe commands end-to-end', async () => {
|
|
125
|
+
const tool = bashTool({
|
|
126
|
+
debug: false,
|
|
127
|
+
bashConfig: { timeout: 10000 }
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Test a simple, guaranteed-safe command
|
|
131
|
+
const result = await tool.execute({ command: 'echo "integration test"' });
|
|
132
|
+
|
|
133
|
+
expect(result).not.toContain('Permission denied');
|
|
134
|
+
expect(result).not.toContain('Error:');
|
|
135
|
+
expect(result).toContain('integration test');
|
|
136
|
+
}, 15000);
|
|
137
|
+
|
|
138
|
+
test('should handle command failures gracefully', async () => {
|
|
139
|
+
const tool = bashTool({
|
|
140
|
+
debug: false,
|
|
141
|
+
bashConfig: { timeout: 5000 }
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Test a command that will fail but is allowed
|
|
145
|
+
const result = await tool.execute({ command: 'ls /this/does/not/exist/surely' });
|
|
146
|
+
|
|
147
|
+
expect(result).not.toContain('Permission denied');
|
|
148
|
+
// Should indicate failure but not crash
|
|
149
|
+
expect(result).toContain('Command failed') || expect(result).toContain('No such file');
|
|
150
|
+
}, 10000);
|
|
151
|
+
|
|
152
|
+
test('should respect timeout settings', async () => {
|
|
153
|
+
const tool = bashTool({
|
|
154
|
+
debug: false,
|
|
155
|
+
bashConfig: { timeout: 1000 } // Very short timeout
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Test a command that would take longer than timeout
|
|
159
|
+
const result = await tool.execute({ command: 'sleep 2' });
|
|
160
|
+
|
|
161
|
+
expect(result).not.toContain('Permission denied');
|
|
162
|
+
expect(result).toContain('timed out') || expect(result).toContain('Command failed');
|
|
163
|
+
}, 5000);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
describe('Pattern Matching Accuracy', () => {
|
|
167
|
+
test('should match patterns precisely', () => {
|
|
168
|
+
const checker = new BashPermissionChecker({ debug: false });
|
|
169
|
+
|
|
170
|
+
// Test exact patterns
|
|
171
|
+
expect(checker.check('ls').allowed).toBe(true);
|
|
172
|
+
expect(checker.check('ls -la').allowed).toBe(true); // ls pattern allows any ls args
|
|
173
|
+
|
|
174
|
+
// Test wildcard patterns
|
|
175
|
+
expect(checker.check('git status').allowed).toBe(true);
|
|
176
|
+
expect(checker.check('git log --oneline').allowed).toBe(true);
|
|
177
|
+
expect(checker.check('git push origin main').allowed).toBe(false);
|
|
178
|
+
|
|
179
|
+
// Test complex patterns
|
|
180
|
+
expect(checker.check('npm list').allowed).toBe(true);
|
|
181
|
+
expect(checker.check('npm install').allowed).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test('should have comprehensive default patterns', () => {
|
|
185
|
+
// Verify we have substantial coverage
|
|
186
|
+
expect(DEFAULT_ALLOW_PATTERNS.length).toBeGreaterThan(200);
|
|
187
|
+
expect(DEFAULT_DENY_PATTERNS.length).toBeGreaterThan(100);
|
|
188
|
+
|
|
189
|
+
// Spot check critical patterns
|
|
190
|
+
expect(DEFAULT_ALLOW_PATTERNS).toContain('ls');
|
|
191
|
+
expect(DEFAULT_ALLOW_PATTERNS).toContain('cat:*');
|
|
192
|
+
expect(DEFAULT_ALLOW_PATTERNS).toContain('git:status');
|
|
193
|
+
|
|
194
|
+
expect(DEFAULT_DENY_PATTERNS).toContain('rm:-rf');
|
|
195
|
+
expect(DEFAULT_DENY_PATTERNS).toContain('sudo:*');
|
|
196
|
+
expect(DEFAULT_DENY_PATTERNS).toContain('npm:install');
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
describe('Error Handling and Validation', () => {
|
|
201
|
+
test('should validate input parameters thoroughly', async () => {
|
|
202
|
+
const tool = bashTool({ debug: false });
|
|
203
|
+
|
|
204
|
+
// Test various invalid inputs
|
|
205
|
+
const invalidInputs = [
|
|
206
|
+
{ command: '' },
|
|
207
|
+
{ command: null },
|
|
208
|
+
{ command: undefined },
|
|
209
|
+
{ command: ' ' },
|
|
210
|
+
{},
|
|
211
|
+
{ command: 'echo hello', timeout: 'invalid' },
|
|
212
|
+
{ command: 'echo hello', timeout: -1 }
|
|
213
|
+
];
|
|
214
|
+
|
|
215
|
+
for (const input of invalidInputs) {
|
|
216
|
+
const result = await tool.execute(input);
|
|
217
|
+
expect(result).toContain('Error');
|
|
218
|
+
expect(typeof result).toBe('string');
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test('should handle working directory restrictions', async () => {
|
|
223
|
+
const tool = bashTool({
|
|
224
|
+
debug: false,
|
|
225
|
+
allowedFolders: ['/tmp'],
|
|
226
|
+
bashConfig: { timeout: 5000 }
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Should work within allowed folder
|
|
230
|
+
const result1 = await tool.execute({
|
|
231
|
+
command: 'pwd',
|
|
232
|
+
workingDirectory: '/tmp'
|
|
233
|
+
});
|
|
234
|
+
expect(result1).not.toContain('not within allowed folders');
|
|
235
|
+
|
|
236
|
+
// Should fail outside allowed folders
|
|
237
|
+
const result2 = await tool.execute({
|
|
238
|
+
command: 'pwd',
|
|
239
|
+
workingDirectory: '/usr'
|
|
240
|
+
});
|
|
241
|
+
expect(result2).toContain('not within allowed folders');
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test('should provide helpful error messages', async () => {
|
|
245
|
+
const tool = bashTool({ debug: false });
|
|
246
|
+
|
|
247
|
+
const result = await tool.execute({ command: 'sudo rm -rf /' });
|
|
248
|
+
|
|
249
|
+
expect(result).toContain('Permission denied');
|
|
250
|
+
expect(result).toContain('Common reasons');
|
|
251
|
+
expect(result).toContain('--bash-allow');
|
|
252
|
+
expect(result).toContain('safe alternatives');
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
describe('Configuration Flexibility', () => {
|
|
257
|
+
test('should work with minimal configuration', () => {
|
|
258
|
+
const tool = bashTool();
|
|
259
|
+
|
|
260
|
+
expect(tool.name).toBe('bash');
|
|
261
|
+
expect(typeof tool.execute).toBe('function');
|
|
262
|
+
expect(tool.inputSchema).toBeDefined();
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
test('should work with maximal configuration', () => {
|
|
266
|
+
const tool = bashTool({
|
|
267
|
+
debug: true,
|
|
268
|
+
cwd: '/project',
|
|
269
|
+
allowedFolders: ['/project', '/tmp'],
|
|
270
|
+
bashConfig: {
|
|
271
|
+
allow: ['docker:*', 'make:*'],
|
|
272
|
+
deny: ['rm:*', 'chmod:*'],
|
|
273
|
+
disableDefaultAllow: false,
|
|
274
|
+
disableDefaultDeny: false,
|
|
275
|
+
timeout: 120000,
|
|
276
|
+
workingDirectory: '/project',
|
|
277
|
+
env: {
|
|
278
|
+
NODE_ENV: 'test',
|
|
279
|
+
DEBUG: '1'
|
|
280
|
+
},
|
|
281
|
+
maxBuffer: 50 * 1024 * 1024
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
expect(tool.name).toBe('bash');
|
|
286
|
+
expect(typeof tool.execute).toBe('function');
|
|
287
|
+
expect(tool.inputSchema).toBeDefined();
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
describe('Performance and Resource Management', () => {
|
|
292
|
+
test('should handle multiple concurrent executions', async () => {
|
|
293
|
+
const tool = bashTool({
|
|
294
|
+
debug: false,
|
|
295
|
+
bashConfig: { timeout: 5000 }
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Execute multiple commands concurrently
|
|
299
|
+
const promises = Array.from({ length: 5 }, (_, i) =>
|
|
300
|
+
tool.execute({ command: `echo "test ${i}"` })
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
const results = await Promise.all(promises);
|
|
304
|
+
|
|
305
|
+
// All should succeed
|
|
306
|
+
results.forEach((result, i) => {
|
|
307
|
+
expect(result).not.toContain('Permission denied');
|
|
308
|
+
expect(result).toContain(`test ${i}`);
|
|
309
|
+
});
|
|
310
|
+
}, 15000);
|
|
311
|
+
|
|
312
|
+
test('should handle resource limits appropriately', () => {
|
|
313
|
+
const result = formatExecutionResult({
|
|
314
|
+
success: true,
|
|
315
|
+
stdout: 'x'.repeat(1000),
|
|
316
|
+
stderr: '',
|
|
317
|
+
exitCode: 0,
|
|
318
|
+
command: 'echo',
|
|
319
|
+
duration: 123
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
expect(result).toContain('x'.repeat(1000));
|
|
323
|
+
expect(typeof result).toBe('string');
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
describe('CLI Integration Simulation', () => {
|
|
329
|
+
test('should simulate complete CLI workflow', () => {
|
|
330
|
+
// Simulate CLI argument parsing
|
|
331
|
+
const cliArgs = {
|
|
332
|
+
enableBash: true,
|
|
333
|
+
bashAllow: 'docker:ps,npm:run:*',
|
|
334
|
+
bashDeny: 'rm:*,sudo:*',
|
|
335
|
+
bashTimeout: '60000',
|
|
336
|
+
defaultBashAllow: true,
|
|
337
|
+
defaultBashDeny: true
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
// Process arguments like CLI would
|
|
341
|
+
const bashConfig = {};
|
|
342
|
+
|
|
343
|
+
if (cliArgs.bashAllow) {
|
|
344
|
+
bashConfig.allow = cliArgs.bashAllow.split(',').map(p => p.trim()).filter(p => p.length > 0);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (cliArgs.bashDeny) {
|
|
348
|
+
bashConfig.deny = cliArgs.bashDeny.split(',').map(p => p.trim()).filter(p => p.length > 0);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (cliArgs.bashTimeout) {
|
|
352
|
+
const timeout = parseInt(cliArgs.bashTimeout, 10);
|
|
353
|
+
if (!isNaN(timeout)) {
|
|
354
|
+
bashConfig.timeout = timeout;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
bashConfig.disableDefaultAllow = cliArgs.defaultBashAllow === false;
|
|
359
|
+
bashConfig.disableDefaultDeny = cliArgs.defaultBashDeny === false;
|
|
360
|
+
|
|
361
|
+
// Create tool with processed config
|
|
362
|
+
const tool = bashTool({
|
|
363
|
+
debug: false,
|
|
364
|
+
bashConfig
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
// Verify configuration was applied
|
|
368
|
+
expect(tool.name).toBe('bash');
|
|
369
|
+
expect(typeof tool.execute).toBe('function');
|
|
370
|
+
});
|
|
371
|
+
});
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for bash tool with Vercel AI SDK
|
|
3
|
+
* @module tests/unit/bash-tool-integration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { jest, describe, test, expect, beforeEach } from '@jest/globals';
|
|
7
|
+
|
|
8
|
+
// Mock the 'ai' package since it may not be available in test environment
|
|
9
|
+
jest.mock('ai', () => ({
|
|
10
|
+
tool: jest.fn((config) => ({
|
|
11
|
+
name: config.name,
|
|
12
|
+
description: config.description,
|
|
13
|
+
inputSchema: config.inputSchema,
|
|
14
|
+
execute: config.execute
|
|
15
|
+
}))
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
// Import after mocking
|
|
19
|
+
import { bashTool } from '../../src/tools/bash.js';
|
|
20
|
+
|
|
21
|
+
describe('Bash Tool Integration', () => {
|
|
22
|
+
let tool;
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
tool = bashTool({
|
|
26
|
+
debug: false,
|
|
27
|
+
bashConfig: {
|
|
28
|
+
timeout: 5000
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('Tool Configuration', () => {
|
|
34
|
+
test('should have correct name and description', () => {
|
|
35
|
+
expect(tool.name).toBe('bash');
|
|
36
|
+
expect(tool.description).toContain('Execute bash commands');
|
|
37
|
+
expect(tool.description).toContain('security');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('should have correct input schema', () => {
|
|
41
|
+
expect(tool.inputSchema.type).toBe('object');
|
|
42
|
+
expect(tool.inputSchema.properties.command).toBeDefined();
|
|
43
|
+
expect(tool.inputSchema.properties.command.type).toBe('string');
|
|
44
|
+
expect(tool.inputSchema.required).toContain('command');
|
|
45
|
+
|
|
46
|
+
// Optional parameters
|
|
47
|
+
expect(tool.inputSchema.properties.workingDirectory).toBeDefined();
|
|
48
|
+
expect(tool.inputSchema.properties.timeout).toBeDefined();
|
|
49
|
+
expect(tool.inputSchema.properties.env).toBeDefined();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('should have execute function', () => {
|
|
53
|
+
expect(typeof tool.execute).toBe('function');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('Command Validation', () => {
|
|
58
|
+
test('should reject empty commands', async () => {
|
|
59
|
+
const result = await tool.execute({ command: '' });
|
|
60
|
+
expect(result).toContain('Error: Command cannot be empty');
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('should reject null commands', async () => {
|
|
64
|
+
const result = await tool.execute({ command: null });
|
|
65
|
+
expect(result).toContain('Error: Command is required');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('should reject undefined commands', async () => {
|
|
69
|
+
const result = await tool.execute({});
|
|
70
|
+
expect(result).toContain('Error: Command is required');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('should reject whitespace-only commands', async () => {
|
|
74
|
+
const result = await tool.execute({ command: ' ' });
|
|
75
|
+
expect(result).toContain('Error: Command cannot be empty');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('Permission Enforcement', () => {
|
|
80
|
+
test('should deny dangerous commands', async () => {
|
|
81
|
+
const dangerousCommands = [
|
|
82
|
+
'rm -rf /',
|
|
83
|
+
'sudo apt-get install something',
|
|
84
|
+
'chmod 777 /',
|
|
85
|
+
'npm install express',
|
|
86
|
+
'git push origin main',
|
|
87
|
+
'killall node'
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
for (const command of dangerousCommands) {
|
|
91
|
+
const result = await tool.execute({ command });
|
|
92
|
+
expect(result).toContain('Permission denied');
|
|
93
|
+
expect(result).not.toContain('Command completed');
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('should provide helpful error messages for denied commands', async () => {
|
|
98
|
+
const result = await tool.execute({ command: 'rm -rf /' });
|
|
99
|
+
|
|
100
|
+
expect(result).toContain('Permission denied');
|
|
101
|
+
expect(result).toContain('potentially dangerous');
|
|
102
|
+
expect(result).toContain('Common reasons');
|
|
103
|
+
expect(result).toContain('--bash-allow');
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe('Safe Command Execution', () => {
|
|
108
|
+
test('should execute safe commands', async () => {
|
|
109
|
+
const result = await tool.execute({ command: 'echo "test"' });
|
|
110
|
+
|
|
111
|
+
// Should not be a permission error
|
|
112
|
+
expect(result).not.toContain('Permission denied');
|
|
113
|
+
|
|
114
|
+
// Should contain the output or indicate successful execution
|
|
115
|
+
expect(result).toContain('test');
|
|
116
|
+
}, 10000);
|
|
117
|
+
|
|
118
|
+
test('should handle command execution errors gracefully', async () => {
|
|
119
|
+
const result = await tool.execute({ command: 'ls /nonexistent/path/12345' });
|
|
120
|
+
|
|
121
|
+
// Should not be a permission error
|
|
122
|
+
expect(result).not.toContain('Permission denied');
|
|
123
|
+
|
|
124
|
+
// Should indicate execution failure
|
|
125
|
+
expect(result).toMatch(/Command failed|Error executing/);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe('Custom Configuration', () => {
|
|
130
|
+
test('should use custom allow patterns', async () => {
|
|
131
|
+
const customTool = bashTool({
|
|
132
|
+
debug: false,
|
|
133
|
+
bashConfig: {
|
|
134
|
+
allow: ['docker:ps'],
|
|
135
|
+
timeout: 5000
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const result = await customTool.execute({ command: 'docker ps' });
|
|
140
|
+
|
|
141
|
+
// Should not be denied by permissions (might fail due to docker not being available)
|
|
142
|
+
expect(result).not.toContain('Permission denied');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('should use custom deny patterns', async () => {
|
|
146
|
+
const customTool = bashTool({
|
|
147
|
+
debug: false,
|
|
148
|
+
bashConfig: {
|
|
149
|
+
deny: ['echo'],
|
|
150
|
+
timeout: 5000
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const result = await customTool.execute({ command: 'echo hello' });
|
|
155
|
+
expect(result).toContain('Permission denied');
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test('should disable default patterns when requested', async () => {
|
|
159
|
+
const customTool = bashTool({
|
|
160
|
+
debug: false,
|
|
161
|
+
bashConfig: {
|
|
162
|
+
allow: ['echo'],
|
|
163
|
+
disableDefaultAllow: true,
|
|
164
|
+
disableDefaultDeny: true,
|
|
165
|
+
timeout: 5000
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Echo should work
|
|
170
|
+
let result = await customTool.execute({ command: 'echo hello' });
|
|
171
|
+
expect(result).not.toContain('Permission denied');
|
|
172
|
+
|
|
173
|
+
// ls should be denied (not in custom allow list)
|
|
174
|
+
result = await customTool.execute({ command: 'ls' });
|
|
175
|
+
expect(result).toContain('not in allow list');
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
describe('Working Directory and Options', () => {
|
|
180
|
+
test('should handle working directory parameter', async () => {
|
|
181
|
+
const result = await tool.execute({
|
|
182
|
+
command: 'pwd',
|
|
183
|
+
workingDirectory: '/tmp'
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
expect(result).not.toContain('Permission denied');
|
|
187
|
+
|
|
188
|
+
// Should either succeed or fail gracefully
|
|
189
|
+
if (!result.includes('Error:')) {
|
|
190
|
+
expect(result).toContain('/tmp');
|
|
191
|
+
}
|
|
192
|
+
}, 10000);
|
|
193
|
+
|
|
194
|
+
test('should handle timeout parameter', async () => {
|
|
195
|
+
const result = await tool.execute({
|
|
196
|
+
command: 'echo hello',
|
|
197
|
+
timeout: 1000
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
expect(result).not.toContain('Permission denied');
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test('should handle env parameter', async () => {
|
|
204
|
+
const result = await tool.execute({
|
|
205
|
+
command: 'printenv TEST_VAR',
|
|
206
|
+
env: { TEST_VAR: 'test_value' }
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
expect(result).not.toContain('Permission denied');
|
|
210
|
+
|
|
211
|
+
if (!result.includes('Error:')) {
|
|
212
|
+
expect(result).toContain('test_value');
|
|
213
|
+
}
|
|
214
|
+
}, 10000);
|
|
215
|
+
|
|
216
|
+
test('should reject invalid timeout values', async () => {
|
|
217
|
+
const result = await tool.execute({
|
|
218
|
+
command: 'echo hello',
|
|
219
|
+
timeout: 'invalid'
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
expect(result).toContain('Error: Invalid execution options');
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
describe('Folder Restrictions', () => {
|
|
227
|
+
test('should respect allowedFolders configuration', async () => {
|
|
228
|
+
const restrictedTool = bashTool({
|
|
229
|
+
debug: false,
|
|
230
|
+
allowedFolders: ['/tmp'],
|
|
231
|
+
bashConfig: { timeout: 5000 }
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Should allow execution in allowed folder
|
|
235
|
+
let result = await restrictedTool.execute({
|
|
236
|
+
command: 'pwd',
|
|
237
|
+
workingDirectory: '/tmp'
|
|
238
|
+
});
|
|
239
|
+
expect(result).not.toContain('not within allowed folders');
|
|
240
|
+
|
|
241
|
+
// Should deny execution outside allowed folders
|
|
242
|
+
result = await restrictedTool.execute({
|
|
243
|
+
command: 'pwd',
|
|
244
|
+
workingDirectory: '/usr'
|
|
245
|
+
});
|
|
246
|
+
expect(result).toContain('not within allowed folders');
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
describe('Error Handling', () => {
|
|
251
|
+
test('should handle tool execution errors gracefully', async () => {
|
|
252
|
+
// Mock an execution error by providing invalid parameters
|
|
253
|
+
const result = await tool.execute({
|
|
254
|
+
command: 'echo hello',
|
|
255
|
+
timeout: -1 // Invalid timeout
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
expect(typeof result).toBe('string');
|
|
259
|
+
expect(result).toContain('Error');
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
test('should handle permission checker errors', async () => {
|
|
263
|
+
// This should still work as permission checker is robust
|
|
264
|
+
const result = await tool.execute({ command: 'ls' });
|
|
265
|
+
expect(typeof result).toBe('string');
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
describe('Bash Tool with Different Configurations', () => {
|
|
271
|
+
test('should work with minimal configuration', () => {
|
|
272
|
+
const minimalTool = bashTool();
|
|
273
|
+
|
|
274
|
+
expect(minimalTool.name).toBe('bash');
|
|
275
|
+
expect(typeof minimalTool.execute).toBe('function');
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
test('should work with full configuration', () => {
|
|
279
|
+
const fullTool = bashTool({
|
|
280
|
+
debug: true,
|
|
281
|
+
cwd: '/home/test',
|
|
282
|
+
allowedFolders: ['/home/test', '/tmp'],
|
|
283
|
+
bashConfig: {
|
|
284
|
+
allow: ['docker:*'],
|
|
285
|
+
deny: ['rm:*'],
|
|
286
|
+
disableDefaultAllow: false,
|
|
287
|
+
disableDefaultDeny: false,
|
|
288
|
+
timeout: 60000,
|
|
289
|
+
workingDirectory: '/home/test',
|
|
290
|
+
env: { NODE_ENV: 'test' },
|
|
291
|
+
maxBuffer: 5 * 1024 * 1024
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
expect(fullTool.name).toBe('bash');
|
|
296
|
+
expect(typeof fullTool.execute).toBe('function');
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
test('should handle debug mode', () => {
|
|
300
|
+
const debugTool = bashTool({
|
|
301
|
+
debug: true,
|
|
302
|
+
bashConfig: { timeout: 5000 }
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
expect(debugTool.name).toBe('bash');
|
|
306
|
+
|
|
307
|
+
// Debug mode should not affect basic functionality
|
|
308
|
+
expect(typeof debugTool.execute).toBe('function');
|
|
309
|
+
});
|
|
310
|
+
});
|