@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,76 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Basic authentication middleware
|
|
5
|
+
* Checks for valid username and password in the Authorization header
|
|
6
|
+
* Can be enabled/disabled via environment variables
|
|
7
|
+
*/
|
|
8
|
+
export function authMiddleware(req, res, next) {
|
|
9
|
+
// Check if authentication is enabled
|
|
10
|
+
const AUTH_ENABLED = process.env.AUTH_ENABLED === '1';
|
|
11
|
+
|
|
12
|
+
// If authentication is not enabled, skip authentication check
|
|
13
|
+
if (!AUTH_ENABLED) {
|
|
14
|
+
return next(req, res);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Get configured username and password from environment variables
|
|
18
|
+
const AUTH_USERNAME = process.env.AUTH_USERNAME || 'admin';
|
|
19
|
+
const AUTH_PASSWORD = process.env.AUTH_PASSWORD || 'password';
|
|
20
|
+
|
|
21
|
+
// Check if request has Authorization header
|
|
22
|
+
const authHeader = req.headers.authorization;
|
|
23
|
+
|
|
24
|
+
if (!authHeader) {
|
|
25
|
+
// No Authorization header, return 401 Unauthorized
|
|
26
|
+
res.writeHead(401, {
|
|
27
|
+
'Content-Type': 'text/plain',
|
|
28
|
+
'WWW-Authenticate': 'Basic realm="Probe Code Search"'
|
|
29
|
+
});
|
|
30
|
+
res.end('Authentication required');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Parse Authorization header
|
|
35
|
+
try {
|
|
36
|
+
// Basic auth format: "Basic base64(username:password)"
|
|
37
|
+
const authParts = authHeader.split(' ');
|
|
38
|
+
if (authParts.length !== 2 || authParts[0] !== 'Basic') {
|
|
39
|
+
throw new Error('Invalid Authorization header format');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Decode base64 credentials
|
|
43
|
+
const credentials = Buffer.from(authParts[1], 'base64').toString('utf-8');
|
|
44
|
+
const [username, password] = credentials.split(':');
|
|
45
|
+
|
|
46
|
+
// Check if credentials match
|
|
47
|
+
if (username === AUTH_USERNAME && password === AUTH_PASSWORD) {
|
|
48
|
+
// Authentication successful, proceed to next middleware
|
|
49
|
+
return next(req, res);
|
|
50
|
+
} else {
|
|
51
|
+
// Invalid credentials, return 401 Unauthorized
|
|
52
|
+
res.writeHead(401, {
|
|
53
|
+
'Content-Type': 'text/plain',
|
|
54
|
+
'WWW-Authenticate': 'Basic realm="Probe Code Search"'
|
|
55
|
+
});
|
|
56
|
+
res.end('Invalid credentials');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
// Error parsing Authorization header, return 400 Bad Request
|
|
61
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
62
|
+
res.end('Invalid Authorization header');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Apply authentication middleware to a request handler
|
|
69
|
+
* @param {Function} handler - The request handler function
|
|
70
|
+
* @returns {Function} - A new handler function with authentication
|
|
71
|
+
*/
|
|
72
|
+
export function withAuth(handler) {
|
|
73
|
+
return (req, res) => {
|
|
74
|
+
authMiddleware(req, res, () => handler(req, res));
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @probelabs/probe-chat CLI
|
|
5
|
+
* Command-line interface for Probe code search chat
|
|
6
|
+
*
|
|
7
|
+
* This is a thin wrapper around the main functionality in index.js
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { main } from '../index.js';
|
|
11
|
+
|
|
12
|
+
// Execute the main function
|
|
13
|
+
main();
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { build } from 'esbuild';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { dirname, join } from 'path';
|
|
6
|
+
import { existsSync, rmSync, mkdirSync, cpSync } from 'fs';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
|
|
11
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
|
12
|
+
|
|
13
|
+
async function buildApp() {
|
|
14
|
+
console.log(`🏗️ Building probe-chat (${isProduction ? 'production' : 'development'})...`);
|
|
15
|
+
|
|
16
|
+
// Clean dist directory
|
|
17
|
+
const distDir = join(__dirname, 'dist');
|
|
18
|
+
if (existsSync(distDir)) {
|
|
19
|
+
rmSync(distDir, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
mkdirSync(distDir, { recursive: true });
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
// Bundle the main CLI application
|
|
25
|
+
await build({
|
|
26
|
+
entryPoints: [join(__dirname, 'index.js')],
|
|
27
|
+
bundle: true,
|
|
28
|
+
platform: 'node',
|
|
29
|
+
target: 'node18',
|
|
30
|
+
format: 'esm',
|
|
31
|
+
outfile: join(distDir, 'index.js'),
|
|
32
|
+
external: [
|
|
33
|
+
// Keep these as external since they have complex ESM/CJS interop issues
|
|
34
|
+
'@opentelemetry/*',
|
|
35
|
+
'@ai-sdk/*',
|
|
36
|
+
'tiktoken',
|
|
37
|
+
// Keep probe as external since it downloads binaries at runtime
|
|
38
|
+
'@probelabs/probe',
|
|
39
|
+
// These have dynamic require issues when bundled
|
|
40
|
+
'dotenv',
|
|
41
|
+
'inquirer',
|
|
42
|
+
'ora',
|
|
43
|
+
'chalk',
|
|
44
|
+
'commander',
|
|
45
|
+
'zod',
|
|
46
|
+
'ai',
|
|
47
|
+
'glob'
|
|
48
|
+
],
|
|
49
|
+
minify: isProduction,
|
|
50
|
+
sourcemap: !isProduction,
|
|
51
|
+
keepNames: true,
|
|
52
|
+
define: {
|
|
53
|
+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
|
|
54
|
+
},
|
|
55
|
+
// Handle ESM imports properly
|
|
56
|
+
mainFields: ['module', 'main'],
|
|
57
|
+
conditions: ['import', 'module', 'default'],
|
|
58
|
+
logLevel: 'info',
|
|
59
|
+
// Preserve shebang from source file
|
|
60
|
+
preserveSymlinks: true
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Copy essential static files
|
|
64
|
+
const staticFiles = [
|
|
65
|
+
'package.json',
|
|
66
|
+
'index.html',
|
|
67
|
+
'logo.png'
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
for (const file of staticFiles) {
|
|
71
|
+
const src = join(__dirname, file);
|
|
72
|
+
const dest = join(distDir, file);
|
|
73
|
+
if (existsSync(src)) {
|
|
74
|
+
cpSync(src, dest);
|
|
75
|
+
console.log(`📄 Copied ${file}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Copy directories that might be needed at runtime
|
|
80
|
+
const staticDirs = [
|
|
81
|
+
'bin',
|
|
82
|
+
'storage',
|
|
83
|
+
'implement'
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
for (const dir of staticDirs) {
|
|
87
|
+
const src = join(__dirname, dir);
|
|
88
|
+
const dest = join(distDir, dir);
|
|
89
|
+
if (existsSync(src)) {
|
|
90
|
+
cpSync(src, dest, { recursive: true });
|
|
91
|
+
console.log(`📁 Copied ${dir}/`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
console.log('✅ Build completed successfully!');
|
|
96
|
+
console.log(`📦 Output: ${distDir}`);
|
|
97
|
+
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error('❌ Build failed:', error);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
buildApp();
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Map to store active requests by session ID
|
|
2
|
+
const activeRequests = new Map();
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Register a request as active
|
|
6
|
+
* @param {string} sessionId - The session ID
|
|
7
|
+
* @param {Object} requestData - Data about the request (can include abort functions, etc.)
|
|
8
|
+
*/
|
|
9
|
+
export function registerRequest(sessionId, requestData) {
|
|
10
|
+
if (!sessionId) {
|
|
11
|
+
console.warn('Attempted to register request without session ID');
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
console.log(`Registering request for session: ${sessionId}`);
|
|
16
|
+
activeRequests.set(sessionId, requestData);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Cancel a request by session ID
|
|
21
|
+
* @param {string} sessionId - The session ID
|
|
22
|
+
* @returns {boolean} - Whether the cancellation was successful
|
|
23
|
+
*/
|
|
24
|
+
export function cancelRequest(sessionId) {
|
|
25
|
+
if (!sessionId) {
|
|
26
|
+
console.warn('Attempted to cancel request without session ID');
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const requestData = activeRequests.get(sessionId);
|
|
31
|
+
if (!requestData) {
|
|
32
|
+
console.warn(`No active request found for session: ${sessionId}`);
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.log(`Cancelling request for session: ${sessionId}`);
|
|
37
|
+
|
|
38
|
+
// Call the abort function if it exists
|
|
39
|
+
if (typeof requestData.abort === 'function') {
|
|
40
|
+
try {
|
|
41
|
+
requestData.abort();
|
|
42
|
+
console.log(`Successfully aborted request for session: ${sessionId}`);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error(`Error aborting request for session ${sessionId}:`, error);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Remove the request from the active requests map
|
|
49
|
+
activeRequests.delete(sessionId);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Check if a request is active
|
|
55
|
+
* @param {string} sessionId - The session ID
|
|
56
|
+
* @returns {boolean} - Whether the request is active
|
|
57
|
+
*/
|
|
58
|
+
export function isRequestActive(sessionId) {
|
|
59
|
+
return activeRequests.has(sessionId);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get all active requests
|
|
64
|
+
* @returns {Map} - Map of all active requests
|
|
65
|
+
*/
|
|
66
|
+
export function getActiveRequests() {
|
|
67
|
+
return activeRequests;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Clear a request from the active requests map
|
|
72
|
+
* @param {string} sessionId - The session ID
|
|
73
|
+
*/
|
|
74
|
+
export function clearRequest(sessionId) {
|
|
75
|
+
if (!sessionId) {
|
|
76
|
+
console.warn('Attempted to clear request without session ID');
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (activeRequests.has(sessionId)) {
|
|
81
|
+
console.log(`Clearing request for session: ${sessionId}`);
|
|
82
|
+
activeRequests.delete(sessionId);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Demo showing how the agentic loop would work with automatic image loading
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { writeFileSync, unlinkSync } from 'fs';
|
|
8
|
+
|
|
9
|
+
console.log('🎬 Agentic Loop Image Loading Demo');
|
|
10
|
+
console.log('=====================================\n');
|
|
11
|
+
|
|
12
|
+
// Create a test image
|
|
13
|
+
const testImage = './architecture-diagram.png';
|
|
14
|
+
const simplePng = Buffer.from([
|
|
15
|
+
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
|
|
16
|
+
0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
|
|
17
|
+
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
|
18
|
+
0x08, 0x06, 0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4,
|
|
19
|
+
0x89, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x44, 0x41,
|
|
20
|
+
0x54, 0x78, 0x9C, 0x62, 0x00, 0x02, 0x00, 0x00,
|
|
21
|
+
0x05, 0x00, 0x01, 0x0D, 0x0A, 0x2D, 0xB4, 0x00,
|
|
22
|
+
0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
|
|
23
|
+
0x42, 0x60, 0x82
|
|
24
|
+
]);
|
|
25
|
+
writeFileSync(testImage, simplePng);
|
|
26
|
+
|
|
27
|
+
console.log('📝 Simulating an agentic conversation...\n');
|
|
28
|
+
|
|
29
|
+
// Simulate an agentic conversation flow
|
|
30
|
+
console.log('👤 USER: "Please analyze the system architecture and identify potential issues."');
|
|
31
|
+
console.log();
|
|
32
|
+
|
|
33
|
+
console.log('🤖 ITERATION 1:');
|
|
34
|
+
console.log(' Assistant: "I need to examine the codebase to understand the architecture."');
|
|
35
|
+
console.log(' 🔍 Tool Call: <search><query>architecture system design</query></search>');
|
|
36
|
+
console.log(' 📊 Tool Result: "Found architecture documentation in ./docs/architecture.md"');
|
|
37
|
+
console.log(' 🖼️ Image Detection: No images mentioned yet');
|
|
38
|
+
console.log();
|
|
39
|
+
|
|
40
|
+
console.log('🤖 ITERATION 2:');
|
|
41
|
+
console.log(' Assistant: "Let me look for architecture diagrams to better understand the system."');
|
|
42
|
+
console.log(' 🔍 Tool Call: <listFiles><directory>./docs</directory><pattern>*.png</pattern></listFiles>');
|
|
43
|
+
console.log(` 📊 Tool Result: "Found diagram: ${testImage}"`);
|
|
44
|
+
console.log(' 🖼️ Image Detection: DETECTED ./architecture-diagram.png → Auto-loading...');
|
|
45
|
+
console.log(' ✅ Image loaded and cached (67 bytes)');
|
|
46
|
+
console.log();
|
|
47
|
+
|
|
48
|
+
console.log('🤖 ITERATION 3:');
|
|
49
|
+
console.log(' Assistant: "I can see the architecture diagram shows the microservices layout."');
|
|
50
|
+
console.log(' 📝 Response: Uses the automatically loaded image to provide analysis');
|
|
51
|
+
console.log(' 🖼️ Image Context: ./architecture-diagram.png now available in AI context');
|
|
52
|
+
console.log(' 💭 AI can now "see" the diagram and analyze it visually');
|
|
53
|
+
console.log();
|
|
54
|
+
|
|
55
|
+
console.log('🤖 ITERATION 4:');
|
|
56
|
+
console.log(' Assistant: "Based on the architecture diagram, I can identify several potential issues..."');
|
|
57
|
+
console.log(' 🔍 Tool Call: <attempt_completion><result>Analysis complete with visual insights</result></attempt_completion>');
|
|
58
|
+
console.log(' ✅ Task completed with image-enhanced understanding');
|
|
59
|
+
console.log();
|
|
60
|
+
|
|
61
|
+
console.log('🎯 Key Benefits:');
|
|
62
|
+
console.log(' ✨ Agent automatically loads images when mentioned');
|
|
63
|
+
console.log(' 🔄 Images persist across iterations within the same conversation');
|
|
64
|
+
console.log(' 🧠 AI gains visual context without explicit user action');
|
|
65
|
+
console.log(' 🔒 Security validation prevents unauthorized file access');
|
|
66
|
+
console.log(' ⚡ Caching prevents reloading the same images');
|
|
67
|
+
console.log();
|
|
68
|
+
|
|
69
|
+
console.log('📋 What the Agent Can Now Do:');
|
|
70
|
+
console.log(' • "Let me check the screenshot.png file" → Auto-loads image');
|
|
71
|
+
console.log(' • "Looking at diagram.jpg shows..." → Image becomes available');
|
|
72
|
+
console.log(' • "The chart in ./charts/metrics.png indicates..." → Visual analysis possible');
|
|
73
|
+
console.log(' • Tool results mentioning images → Automatically processed');
|
|
74
|
+
console.log();
|
|
75
|
+
|
|
76
|
+
console.log('🏗️ How It Works Behind the Scenes:');
|
|
77
|
+
console.log(' 1. 📝 Agent generates text mentioning image files');
|
|
78
|
+
console.log(' 2. 🔍 Pattern detection finds image file references');
|
|
79
|
+
console.log(' 3. 🛡️ Security validation checks file access permissions');
|
|
80
|
+
console.log(' 4. 📁 File system reads and base64-encodes images');
|
|
81
|
+
console.log(' 5. 💾 Images cached to avoid reloading');
|
|
82
|
+
console.log(' 6. 🖼️ Next AI call includes images in multimodal format');
|
|
83
|
+
console.log(' 7. 🧠 AI can now visually analyze the content');
|
|
84
|
+
|
|
85
|
+
// Cleanup
|
|
86
|
+
unlinkSync(testImage);
|
|
87
|
+
console.log('\n🧹 Demo cleanup completed');
|
|
88
|
+
console.log('\n✨ The probe agent can now think about images and automatically load them!');
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Demo script showing local image file support in probe agent
|
|
5
|
+
*
|
|
6
|
+
* NOTE: This is a standalone demo file. The MIME types and regex patterns below
|
|
7
|
+
* are duplicated from @probelabs/probe/agent/imageConfig for self-containment.
|
|
8
|
+
* When modifying image support, update both the shared config and this file.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { writeFileSync, unlinkSync, readFileSync, existsSync } from 'fs';
|
|
12
|
+
import { resolve, isAbsolute } from 'path';
|
|
13
|
+
|
|
14
|
+
// Standalone image extraction function for demo
|
|
15
|
+
// MIME types duplicated from @probelabs/probe/agent/imageConfig (keep in sync!)
|
|
16
|
+
async function extractImageUrls(message, debug = false) {
|
|
17
|
+
const imageUrlPattern = /(?:data:image\/[a-zA-Z]*;base64,[A-Za-z0-9+/=]+|https?:\/\/(?:(?:private-user-images\.githubusercontent\.com|github\.com\/user-attachments\/assets)\/[^\s"'<>]+|[^\s"'<>]+\.(?:png|jpg|jpeg|webp|bmp|svg)(?:\?[^\s"'<>]*)?)|(?:\.?\.?\/)?[^\s"'<>]*\.(?:png|jpg|jpeg|webp|bmp|svg))/gi;
|
|
18
|
+
|
|
19
|
+
const urls = [];
|
|
20
|
+
const foundPatterns = [];
|
|
21
|
+
let match;
|
|
22
|
+
|
|
23
|
+
while ((match = imageUrlPattern.exec(message)) !== null) {
|
|
24
|
+
foundPatterns.push(match[0]);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Process each found pattern
|
|
28
|
+
for (const pattern of foundPatterns) {
|
|
29
|
+
if (pattern.startsWith('http') || pattern.startsWith('data:image/')) {
|
|
30
|
+
urls.push(pattern);
|
|
31
|
+
} else {
|
|
32
|
+
// Local file path - convert to base64
|
|
33
|
+
try {
|
|
34
|
+
const absolutePath = isAbsolute(pattern) ? pattern : resolve(process.cwd(), pattern);
|
|
35
|
+
|
|
36
|
+
if (!existsSync(absolutePath)) continue;
|
|
37
|
+
|
|
38
|
+
const extension = absolutePath.toLowerCase().split('.').pop();
|
|
39
|
+
// MIME types from @probelabs/probe/agent/imageConfig (keep in sync!)
|
|
40
|
+
const mimeTypes = {
|
|
41
|
+
'png': 'image/png', 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg',
|
|
42
|
+
'webp': 'image/webp', 'bmp': 'image/bmp', 'svg': 'image/svg+xml'
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const mimeType = mimeTypes[extension];
|
|
46
|
+
if (!mimeType) continue;
|
|
47
|
+
|
|
48
|
+
const fileBuffer = readFileSync(absolutePath);
|
|
49
|
+
const base64Data = fileBuffer.toString('base64');
|
|
50
|
+
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
51
|
+
urls.push(dataUrl);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
// Skip failed files
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Clean message
|
|
59
|
+
let cleanedMessage = message;
|
|
60
|
+
foundPatterns.forEach(pattern => {
|
|
61
|
+
cleanedMessage = cleanedMessage.replace(pattern, '').trim();
|
|
62
|
+
});
|
|
63
|
+
cleanedMessage = cleanedMessage.replace(/\s+/g, ' ').trim();
|
|
64
|
+
|
|
65
|
+
return { urls, cleanedMessage };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function demo() {
|
|
69
|
+
console.log('🖼️ Probe Agent - Local Image Support Demo\n');
|
|
70
|
+
|
|
71
|
+
// Create a simple test image
|
|
72
|
+
const testImage = './demo-image.png';
|
|
73
|
+
const simplePng = Buffer.from([
|
|
74
|
+
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
|
|
75
|
+
0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
|
|
76
|
+
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
|
77
|
+
0x08, 0x06, 0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4,
|
|
78
|
+
0x89, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x44, 0x41,
|
|
79
|
+
0x54, 0x78, 0x9C, 0x62, 0x00, 0x02, 0x00, 0x00,
|
|
80
|
+
0x05, 0x00, 0x01, 0x0D, 0x0A, 0x2D, 0xB4, 0x00,
|
|
81
|
+
0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
|
|
82
|
+
0x42, 0x60, 0x82
|
|
83
|
+
]);
|
|
84
|
+
writeFileSync(testImage, simplePng);
|
|
85
|
+
|
|
86
|
+
console.log('📝 Example user message:');
|
|
87
|
+
const userMessage = `
|
|
88
|
+
Can you analyze this architecture diagram: ${testImage}
|
|
89
|
+
and compare it with this online example: https://example.com/architecture.png
|
|
90
|
+
`.trim();
|
|
91
|
+
|
|
92
|
+
console.log(`"${userMessage}"\n`);
|
|
93
|
+
|
|
94
|
+
console.log('🔍 Processing with extractImageUrls...\n');
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
const result = await extractImageUrls(userMessage, false);
|
|
98
|
+
|
|
99
|
+
console.log('📊 Results:');
|
|
100
|
+
console.log(`✅ Found ${result.urls.length} images`);
|
|
101
|
+
console.log(`📝 Cleaned message: "${result.cleanedMessage}"`);
|
|
102
|
+
console.log('\n🖼️ Image details:');
|
|
103
|
+
|
|
104
|
+
result.urls.forEach((url, index) => {
|
|
105
|
+
if (url.startsWith('data:image/')) {
|
|
106
|
+
console.log(` ${index + 1}. Local file converted to base64 (${url.length} chars)`);
|
|
107
|
+
console.log(` Preview: ${url.substring(0, 50)}...`);
|
|
108
|
+
} else {
|
|
109
|
+
console.log(` ${index + 1}. URL: ${url}`);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
console.log('\n✨ The probe agent can now seamlessly handle:');
|
|
114
|
+
console.log(' • Local image files (./image.png)');
|
|
115
|
+
console.log(' • Remote URLs (https://example.com/image.jpg)');
|
|
116
|
+
console.log(' • Base64 data URLs (data:image/...)');
|
|
117
|
+
console.log(' • Mixed content in the same message');
|
|
118
|
+
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error('❌ Error:', error.message);
|
|
121
|
+
} finally {
|
|
122
|
+
// Cleanup
|
|
123
|
+
unlinkSync(testImage);
|
|
124
|
+
console.log('\n🧹 Demo cleanup completed');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
demo().catch(console.error);
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { createWriteStream } from 'fs';
|
|
2
|
+
import { ExportResultCode } from '@opentelemetry/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* File exporter for OpenTelemetry spans
|
|
6
|
+
* Exports spans to a file in JSON Lines format (one JSON object per line)
|
|
7
|
+
* Following the OTLP JSON format specification
|
|
8
|
+
*/
|
|
9
|
+
export class FileSpanExporter {
|
|
10
|
+
constructor(filePath = './traces.jsonl') {
|
|
11
|
+
this.filePath = filePath;
|
|
12
|
+
this.stream = createWriteStream(filePath, { flags: 'a' });
|
|
13
|
+
this.stream.on('error', (error) => {
|
|
14
|
+
console.error(`[FileSpanExporter] Stream error: ${error.message}`);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Export spans to file
|
|
20
|
+
* @param {ReadableSpan[]} spans - Array of spans to export
|
|
21
|
+
* @param {function} resultCallback - Callback to call with the export result
|
|
22
|
+
*/
|
|
23
|
+
export(spans, resultCallback) {
|
|
24
|
+
if (!spans || spans.length === 0) {
|
|
25
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const timestamp = Date.now();
|
|
31
|
+
|
|
32
|
+
spans.forEach((span, index) => {
|
|
33
|
+
// Debug: Log first span's properties to understand structure
|
|
34
|
+
if (index === 0 && process.env.DEBUG_CHAT === '1') {
|
|
35
|
+
console.log('[FileSpanExporter] First span properties:');
|
|
36
|
+
const keys = Object.getOwnPropertyNames(span);
|
|
37
|
+
keys.forEach(key => {
|
|
38
|
+
if (key.toLowerCase().includes('parent') || key === '_spanContext' || key === 'parentContext') {
|
|
39
|
+
console.log(` ${key}:`, span[key]);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Extract parent span ID - check various possible properties
|
|
45
|
+
let parentSpanId = undefined;
|
|
46
|
+
|
|
47
|
+
// Check if there's a parent span context in the span
|
|
48
|
+
if (span.parentSpanContext) {
|
|
49
|
+
parentSpanId = span.parentSpanContext.spanId;
|
|
50
|
+
} else if (span._parentSpanContext) {
|
|
51
|
+
parentSpanId = span._parentSpanContext.spanId;
|
|
52
|
+
} else if (span.parent) {
|
|
53
|
+
parentSpanId = span.parent.spanId;
|
|
54
|
+
} else if (span._parent) {
|
|
55
|
+
parentSpanId = span._parent.spanId;
|
|
56
|
+
} else if (span._parentId) {
|
|
57
|
+
parentSpanId = span._parentId;
|
|
58
|
+
} else if (span.parentSpanId) {
|
|
59
|
+
parentSpanId = span.parentSpanId;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Convert span to OTLP JSON format
|
|
63
|
+
const spanData = {
|
|
64
|
+
traceId: span.spanContext().traceId,
|
|
65
|
+
spanId: span.spanContext().spanId,
|
|
66
|
+
parentSpanId: parentSpanId,
|
|
67
|
+
name: span.name,
|
|
68
|
+
kind: span.kind,
|
|
69
|
+
startTimeUnixNano: span.startTime[0] * 1_000_000_000 + span.startTime[1],
|
|
70
|
+
endTimeUnixNano: span.endTime[0] * 1_000_000_000 + span.endTime[1],
|
|
71
|
+
attributes: this.convertAttributes(span.attributes),
|
|
72
|
+
status: span.status,
|
|
73
|
+
events: span.events?.map(event => ({
|
|
74
|
+
timeUnixNano: event.time[0] * 1_000_000_000 + event.time[1],
|
|
75
|
+
name: event.name,
|
|
76
|
+
attributes: this.convertAttributes(event.attributes),
|
|
77
|
+
})) || [],
|
|
78
|
+
links: span.links?.map(link => ({
|
|
79
|
+
traceId: link.context.traceId,
|
|
80
|
+
spanId: link.context.spanId,
|
|
81
|
+
attributes: this.convertAttributes(link.attributes),
|
|
82
|
+
})) || [],
|
|
83
|
+
resource: {
|
|
84
|
+
attributes: this.convertAttributes(span.resource?.attributes || {}),
|
|
85
|
+
},
|
|
86
|
+
instrumentationLibrary: {
|
|
87
|
+
name: span.instrumentationLibrary?.name || 'unknown',
|
|
88
|
+
version: span.instrumentationLibrary?.version || 'unknown',
|
|
89
|
+
},
|
|
90
|
+
timestamp,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// Write as JSON Lines format (one JSON object per line)
|
|
94
|
+
this.stream.write(JSON.stringify(spanData) + '\n');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error(`[FileSpanExporter] Export error: ${error.message}`);
|
|
100
|
+
resultCallback({
|
|
101
|
+
code: ExportResultCode.FAILED,
|
|
102
|
+
error: error
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Convert OpenTelemetry attributes to plain object
|
|
109
|
+
* @param {Object} attributes - OpenTelemetry attributes
|
|
110
|
+
* @returns {Object} Plain object with string values
|
|
111
|
+
*/
|
|
112
|
+
convertAttributes(attributes) {
|
|
113
|
+
if (!attributes) return {};
|
|
114
|
+
|
|
115
|
+
const result = {};
|
|
116
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
117
|
+
// Convert all values to strings for JSON compatibility
|
|
118
|
+
if (typeof value === 'object' && value !== null) {
|
|
119
|
+
result[key] = JSON.stringify(value);
|
|
120
|
+
} else {
|
|
121
|
+
result[key] = String(value);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Shutdown the exporter
|
|
129
|
+
* @returns {Promise<void>}
|
|
130
|
+
*/
|
|
131
|
+
async shutdown() {
|
|
132
|
+
return new Promise((resolve) => {
|
|
133
|
+
if (this.stream) {
|
|
134
|
+
this.stream.end(() => {
|
|
135
|
+
console.log(`[FileSpanExporter] File stream closed: ${this.filePath}`);
|
|
136
|
+
resolve();
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
resolve();
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Force flush any pending spans
|
|
146
|
+
* @returns {Promise<void>}
|
|
147
|
+
*/
|
|
148
|
+
async forceFlush() {
|
|
149
|
+
return new Promise((resolve, reject) => {
|
|
150
|
+
if (this.stream) {
|
|
151
|
+
// CRITICAL FIX: Force the stream to flush all buffered data
|
|
152
|
+
// Use both drain event and explicit cork/uncork to ensure data is written
|
|
153
|
+
const flushTimeout = setTimeout(() => {
|
|
154
|
+
console.warn('[FileSpanExporter] Flush timeout after 5 seconds');
|
|
155
|
+
resolve();
|
|
156
|
+
}, 5000);
|
|
157
|
+
|
|
158
|
+
// Uncork the stream to force buffered writes
|
|
159
|
+
if (this.stream.writableCorked) {
|
|
160
|
+
this.stream.uncork();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// If there's buffered data, wait for drain event
|
|
164
|
+
if (this.stream.writableNeedDrain) {
|
|
165
|
+
this.stream.once('drain', () => {
|
|
166
|
+
clearTimeout(flushTimeout);
|
|
167
|
+
resolve();
|
|
168
|
+
});
|
|
169
|
+
} else {
|
|
170
|
+
// No buffered data, but still give it a moment to ensure writes complete
|
|
171
|
+
setImmediate(() => {
|
|
172
|
+
clearTimeout(flushTimeout);
|
|
173
|
+
resolve();
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
resolve();
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|