@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.
Files changed (444) hide show
  1. package/README.md +138 -0
  2. package/data/.env.example +22 -0
  3. package/data/.gitattributes +47 -0
  4. package/data/.glfrc.json +7 -0
  5. package/data/.husky/pre-commit +5 -0
  6. package/data/.nvmrc +1 -0
  7. package/data/CHANGELOG.md +75 -0
  8. package/data/CODE_OF_CONDUCT.md +129 -0
  9. package/data/CONTRIBUTING.md +203 -0
  10. package/data/DOCS-STRUCTURE.md +307 -0
  11. package/data/I18N.md +292 -0
  12. package/data/LICENSE +22 -0
  13. package/data/README.md +315 -0
  14. package/data/SECURITY.md +125 -0
  15. package/data/WIKI-DEPLOYMENT.md +348 -0
  16. package/data/docs/AI-FEATURES.md +610 -0
  17. package/data/docs/API-REFERENCE.md +1022 -0
  18. package/data/docs/AUTHENTICATION.md +301 -0
  19. package/data/docs/BACKEND-API.md +468 -0
  20. package/data/docs/DEVELOPMENT.md +375 -0
  21. package/data/docs/EXAMPLES.md +622 -0
  22. package/data/docs/MCP-SERVER.md +307 -0
  23. package/data/docs/MIGRATION-GUIDE.md +367 -0
  24. package/data/docs/NPM-PUBLISH.md +193 -0
  25. package/data/docs/QUICKSTART.md +206 -0
  26. package/data/docs/REDIS-SETUP.md +162 -0
  27. package/data/docs/SERVER.md +228 -0
  28. package/data/docs/TROUBLESHOOTING.md +657 -0
  29. package/data/docs/WIDGET-GUIDE.md +638 -0
  30. package/data/docs/WIKI-HOME.md +58 -0
  31. package/data/docs/WIKI-SIDEBAR.md +39 -0
  32. package/data/package.json +171 -0
  33. package/data/playwright.config.ts +64 -0
  34. package/data/probe/.cargo/config.toml +10 -0
  35. package/data/probe/.claude/commands/performance-review.md +15 -0
  36. package/data/probe/.clinerules +288 -0
  37. package/data/probe/.dockerignore +57 -0
  38. package/data/probe/.githooks/post-commit +11 -0
  39. package/data/probe/.githooks/pre-commit +99 -0
  40. package/data/probe/.githooks/pre-commit-vow +9 -0
  41. package/data/probe/.prompts/engineer.md +41 -0
  42. package/data/probe/.roomodes +28 -0
  43. package/data/probe/.windsurfrules +0 -0
  44. package/data/probe/BASH_TOOL_SUMMARY.md +148 -0
  45. package/data/probe/BENCHMARKING.md +256 -0
  46. package/data/probe/CLAUDE.md +226 -0
  47. package/data/probe/CODE_OF_CONDUCT.md +128 -0
  48. package/data/probe/CONTRIBUTING.md +193 -0
  49. package/data/probe/Cargo.toml +120 -0
  50. package/data/probe/Cross.toml +10 -0
  51. package/data/probe/DOCKER-README.md +224 -0
  52. package/data/probe/Dockerfile +32 -0
  53. package/data/probe/ENHANCED_DEBUG_TELEMETRY.md +188 -0
  54. package/data/probe/LICENSE +201 -0
  55. package/data/probe/Makefile +210 -0
  56. package/data/probe/README.md +824 -0
  57. package/data/probe/SECURITY.md +67 -0
  58. package/data/probe/WINDOWS-GUIDE.md +294 -0
  59. package/data/probe/benches/parsing_benchmarks.rs +370 -0
  60. package/data/probe/benches/search_benchmarks.rs +599 -0
  61. package/data/probe/benches/simd_benchmarks.rs +372 -0
  62. package/data/probe/benches/timing_benchmarks.rs +287 -0
  63. package/data/probe/build-windows.bat +229 -0
  64. package/data/probe/codex-config/config.toml +6 -0
  65. package/data/probe/docs/PERFORMANCE_OPTIMIZATION.md +161 -0
  66. package/data/probe/examples/cache_demo.rs +46 -0
  67. package/data/probe/examples/chat/.dockerignore +37 -0
  68. package/data/probe/examples/chat/ChatSessionManager.js +295 -0
  69. package/data/probe/examples/chat/Dockerfile +98 -0
  70. package/data/probe/examples/chat/LICENSE +201 -0
  71. package/data/probe/examples/chat/LOCAL_IMAGE_SUPPORT.md +195 -0
  72. package/data/probe/examples/chat/MCP_INTEGRATION.md +400 -0
  73. package/data/probe/examples/chat/README.md +338 -0
  74. package/data/probe/examples/chat/TRACING.md +226 -0
  75. package/data/probe/examples/chat/appTracer.js +968 -0
  76. package/data/probe/examples/chat/auth.js +76 -0
  77. package/data/probe/examples/chat/bin/probe-chat.js +13 -0
  78. package/data/probe/examples/chat/build.js +104 -0
  79. package/data/probe/examples/chat/cancelRequest.js +84 -0
  80. package/data/probe/examples/chat/demo-agentic-image-flow.js +88 -0
  81. package/data/probe/examples/chat/demo-local-images.js +128 -0
  82. package/data/probe/examples/chat/fileSpanExporter.js +181 -0
  83. package/data/probe/examples/chat/implement/README.md +228 -0
  84. package/data/probe/examples/chat/implement/backends/AiderBackend.js +750 -0
  85. package/data/probe/examples/chat/implement/backends/BaseBackend.js +276 -0
  86. package/data/probe/examples/chat/implement/backends/ClaudeCodeBackend.js +767 -0
  87. package/data/probe/examples/chat/implement/backends/MockBackend.js +237 -0
  88. package/data/probe/examples/chat/implement/backends/registry.js +85 -0
  89. package/data/probe/examples/chat/implement/core/BackendManager.js +567 -0
  90. package/data/probe/examples/chat/implement/core/ImplementTool.js +354 -0
  91. package/data/probe/examples/chat/implement/core/config.js +428 -0
  92. package/data/probe/examples/chat/implement/core/timeouts.js +58 -0
  93. package/data/probe/examples/chat/implement/core/utils.js +496 -0
  94. package/data/probe/examples/chat/implement/types/BackendTypes.js +126 -0
  95. package/data/probe/examples/chat/index.js +669 -0
  96. package/data/probe/examples/chat/mcpServer.js +341 -0
  97. package/data/probe/examples/chat/npm/LICENSE +15 -0
  98. package/data/probe/examples/chat/npm/README.md +168 -0
  99. package/data/probe/examples/chat/npm/bin/probe-chat.js +156 -0
  100. package/data/probe/examples/chat/npm/index.js +259 -0
  101. package/data/probe/examples/chat/npm/package.json +54 -0
  102. package/data/probe/examples/chat/package.json +102 -0
  103. package/data/probe/examples/chat/probeChat.js +456 -0
  104. package/data/probe/examples/chat/probeTool.js +491 -0
  105. package/data/probe/examples/chat/storage/JsonChatStorage.js +476 -0
  106. package/data/probe/examples/chat/telemetry.js +281 -0
  107. package/data/probe/examples/chat/test/integration/chatFlows.test.js +320 -0
  108. package/data/probe/examples/chat/test/integration/toolCalling.test.js +471 -0
  109. package/data/probe/examples/chat/test/mocks/mockLLMProvider.js +269 -0
  110. package/data/probe/examples/chat/test/test-backends.js +90 -0
  111. package/data/probe/examples/chat/test/testUtils.js +530 -0
  112. package/data/probe/examples/chat/test/unit/backendTimeout.test.js +161 -0
  113. package/data/probe/examples/chat/test/unit/packageFiles.test.js +120 -0
  114. package/data/probe/examples/chat/test/verify-tests.js +118 -0
  115. package/data/probe/examples/chat/test-agentic-image-loading.js +294 -0
  116. package/data/probe/examples/chat/test-ai-sdk-telemetry.js +204 -0
  117. package/data/probe/examples/chat/test-chat-tracing.js +38 -0
  118. package/data/probe/examples/chat/test-direct-function.js +49 -0
  119. package/data/probe/examples/chat/test-file-size-validation.js +103 -0
  120. package/data/probe/examples/chat/test-full-mcp-integration.js +258 -0
  121. package/data/probe/examples/chat/test-github-context.txt +12 -0
  122. package/data/probe/examples/chat/test-hierarchy.js +203 -0
  123. package/data/probe/examples/chat/test-image-spans.js +37 -0
  124. package/data/probe/examples/chat/test-local-image-reading.js +176 -0
  125. package/data/probe/examples/chat/test-mcp-integration.js +136 -0
  126. package/data/probe/examples/chat/test-mcp-probe-server.js +161 -0
  127. package/data/probe/examples/chat/test-mcp-with-ai.js +279 -0
  128. package/data/probe/examples/chat/test-multiple-allowed-dirs.js +111 -0
  129. package/data/probe/examples/chat/test-probe-mcp-server.js +110 -0
  130. package/data/probe/examples/chat/test-security-validation.js +145 -0
  131. package/data/probe/examples/chat/test-simple-tracing.js +32 -0
  132. package/data/probe/examples/chat/test-trace-verification.js +235 -0
  133. package/data/probe/examples/chat/test-tracing.js +114 -0
  134. package/data/probe/examples/chat/tokenCounter.js +419 -0
  135. package/data/probe/examples/chat/tokenUsageDisplay.js +134 -0
  136. package/data/probe/examples/chat/webServer.js +1103 -0
  137. package/data/probe/examples/reranker/Cargo.toml +33 -0
  138. package/data/probe/examples/reranker/DEBUG_OUTPUT_ANALYSIS.md +71 -0
  139. package/data/probe/examples/reranker/MODELS.md +66 -0
  140. package/data/probe/examples/reranker/MODEL_COMPARISON.md +60 -0
  141. package/data/probe/examples/reranker/MULTI_MODEL_ANALYSIS.md +176 -0
  142. package/data/probe/examples/reranker/PERFORMANCE_SUMMARY.md +156 -0
  143. package/data/probe/examples/reranker/README.md +347 -0
  144. package/data/probe/examples/reranker/RUST_BERT_COMPARISON.md +82 -0
  145. package/data/probe/examples/reranker/TOKENIZATION_GUIDE.md +120 -0
  146. package/data/probe/examples/reranker/check_rust_tokenizer.py +108 -0
  147. package/data/probe/examples/reranker/convert_to_torchscript.py +109 -0
  148. package/data/probe/examples/reranker/debug_scoring.py +189 -0
  149. package/data/probe/examples/reranker/debug_tokenization.py +154 -0
  150. package/data/probe/examples/reranker/download_models.sh +73 -0
  151. package/data/probe/examples/reranker/requirements.txt +13 -0
  152. package/data/probe/examples/reranker/run_comprehensive_benchmark.sh +83 -0
  153. package/data/probe/examples/reranker/rust_bert_test/Cargo.toml +12 -0
  154. package/data/probe/examples/reranker/rust_bert_test/README.md +54 -0
  155. package/data/probe/examples/reranker/simple_test.py +50 -0
  156. package/data/probe/examples/reranker/test_all_models.sh +63 -0
  157. package/data/probe/examples/reranker/test_bert_results.sh +44 -0
  158. package/data/probe/examples/reranker/test_cross_encoder.py +334 -0
  159. package/data/probe/examples/reranker/test_cross_encoder.sh +80 -0
  160. package/data/probe/examples/reranker/test_exact_comparison.py +151 -0
  161. package/data/probe/examples/reranker/test_parallel_performance.sh +56 -0
  162. package/data/probe/examples/reranker/test_scores.py +132 -0
  163. package/data/probe/install.ps1 +508 -0
  164. package/data/probe/install.sh +460 -0
  165. package/data/probe/npm/CLONE_METHOD_EXAMPLES.md +596 -0
  166. package/data/probe/npm/CONTEXT_COMPACTION.md +303 -0
  167. package/data/probe/npm/DELEGATE_TOOL_README.md +166 -0
  168. package/data/probe/npm/MAID_INTEGRATION.md +313 -0
  169. package/data/probe/npm/MCP_INTEGRATION_SUMMARY.md +241 -0
  170. package/data/probe/npm/README.md +824 -0
  171. package/data/probe/npm/bin/.gitignore +7 -0
  172. package/data/probe/npm/bin/.gitkeep +0 -0
  173. package/data/probe/npm/bin/README.md +12 -0
  174. package/data/probe/npm/bin/probe +167 -0
  175. package/data/probe/npm/docs/CLAUDE_CODE_INTEGRATION.md +414 -0
  176. package/data/probe/npm/docs/CODEX_INTEGRATION.md +502 -0
  177. package/data/probe/npm/docs/EDIT_CREATE_TOOLS.md +233 -0
  178. package/data/probe/npm/docs/RETRY_AND_FALLBACK.md +674 -0
  179. package/data/probe/npm/example-usage.js +335 -0
  180. package/data/probe/npm/examples/multi-engine-demo.js +117 -0
  181. package/data/probe/npm/examples/probe-agent-cli.js +113 -0
  182. package/data/probe/npm/examples/test-agent-edit.js +114 -0
  183. package/data/probe/npm/examples/test-edit-create.js +120 -0
  184. package/data/probe/npm/examples/test-edit-direct.js +114 -0
  185. package/data/probe/npm/index.d.ts +744 -0
  186. package/data/probe/npm/jest.config.js +52 -0
  187. package/data/probe/npm/package.json +117 -0
  188. package/data/probe/npm/scripts/build-agent.cjs +75 -0
  189. package/data/probe/npm/scripts/build-cjs.js +124 -0
  190. package/data/probe/npm/scripts/build-mcp.cjs +36 -0
  191. package/data/probe/npm/scripts/postinstall.js +216 -0
  192. package/data/probe/npm/test-codex-e2e.js +78 -0
  193. package/data/probe/npm/test-download-lock.js +109 -0
  194. package/data/probe/npm/test-grep-security.js +94 -0
  195. package/data/probe/npm/test-grep-simplified.js +63 -0
  196. package/data/probe/npm/test-grep.js +51 -0
  197. package/data/probe/npm/tests/README.md +96 -0
  198. package/data/probe/npm/tests/agent-compact-history.test.js +174 -0
  199. package/data/probe/npm/tests/allow-tests-default.test.js +151 -0
  200. package/data/probe/npm/tests/contextCompactor.test.js +498 -0
  201. package/data/probe/npm/tests/delegate-config.test.js +353 -0
  202. package/data/probe/npm/tests/delegate-integration.test.js +348 -0
  203. package/data/probe/npm/tests/extractor-integration.test.js +162 -0
  204. package/data/probe/npm/tests/extractor.test.js +317 -0
  205. package/data/probe/npm/tests/fixtures/sampleDiagrams.js +267 -0
  206. package/data/probe/npm/tests/integration/claude-code-auto-fallback.spec.js +148 -0
  207. package/data/probe/npm/tests/integration/claude-code-multi-step.spec.js +127 -0
  208. package/data/probe/npm/tests/integration/claude-code-tool-events.spec.js +163 -0
  209. package/data/probe/npm/tests/integration/codex-auto-fallback.spec.js +191 -0
  210. package/data/probe/npm/tests/integration/codex-tool-events.spec.js +147 -0
  211. package/data/probe/npm/tests/integration/examplesChatMcp.test.js +402 -0
  212. package/data/probe/npm/tests/integration/mcpDotenvSupport.test.js +174 -0
  213. package/data/probe/npm/tests/integration/mcpErrorHandling.test.js +566 -0
  214. package/data/probe/npm/tests/integration/mcpRobustness.test.js +564 -0
  215. package/data/probe/npm/tests/integration/mcpStdoutPurity.test.js +355 -0
  216. package/data/probe/npm/tests/integration/probeAgentMcp.test.js +398 -0
  217. package/data/probe/npm/tests/integration/retryFallback.test.js +368 -0
  218. package/data/probe/npm/tests/integration/schema-in-initial-message.test.js +318 -0
  219. package/data/probe/npm/tests/integration/schema-validation-loop-prevention.test.js +244 -0
  220. package/data/probe/npm/tests/integration/schemaRetryLogic.test.js +94 -0
  221. package/data/probe/npm/tests/integration/validationFlow.test.js +329 -0
  222. package/data/probe/npm/tests/manual/test-codex-basic.js +110 -0
  223. package/data/probe/npm/tests/mcp/mcpClientManager.test.js +614 -0
  224. package/data/probe/npm/tests/mcp/mcpConfig.test.js +359 -0
  225. package/data/probe/npm/tests/mcp/mcpXmlBridge.test.js +436 -0
  226. package/data/probe/npm/tests/mcp/mockMcpServer.js +510 -0
  227. package/data/probe/npm/tests/mcp-strict-syntax.test.js +319 -0
  228. package/data/probe/npm/tests/mermaidQuoteEscaping.test.js +214 -0
  229. package/data/probe/npm/tests/nestedQuoteFix.test.js +40 -0
  230. package/data/probe/npm/tests/setup.js +46 -0
  231. package/data/probe/npm/tests/unit/allowed-tools.test.js +513 -0
  232. package/data/probe/npm/tests/unit/attempt-completion-closing-tag-in-content.test.js +188 -0
  233. package/data/probe/npm/tests/unit/attemptCompletionJsonFix.test.js +238 -0
  234. package/data/probe/npm/tests/unit/attemptCompletionJsonIssue.test.js +128 -0
  235. package/data/probe/npm/tests/unit/backtickAutoFix.test.js +35 -0
  236. package/data/probe/npm/tests/unit/bash-probe-agent-integration.test.js +389 -0
  237. package/data/probe/npm/tests/unit/bash-simple-commands.test.js +324 -0
  238. package/data/probe/npm/tests/unit/bash-tool-comprehensive.test.js +371 -0
  239. package/data/probe/npm/tests/unit/bash-tool-integration.test.js +310 -0
  240. package/data/probe/npm/tests/unit/bash-tool.test.js +341 -0
  241. package/data/probe/npm/tests/unit/completion-prompt.test.js +379 -0
  242. package/data/probe/npm/tests/unit/cwd-path-options.test.js +287 -0
  243. package/data/probe/npm/tests/unit/delegate-limits.test.js +422 -0
  244. package/data/probe/npm/tests/unit/direct-content-attempt-completion.test.js +235 -0
  245. package/data/probe/npm/tests/unit/edit-create-tools.test.js +609 -0
  246. package/data/probe/npm/tests/unit/enhancedMermaidValidation.test.js +577 -0
  247. package/data/probe/npm/tests/unit/extract-content.test.js +83 -0
  248. package/data/probe/npm/tests/unit/extract-multiple-targets.test.js +89 -0
  249. package/data/probe/npm/tests/unit/fallbackManager.test.js +442 -0
  250. package/data/probe/npm/tests/unit/githubCompatibilityValidation.test.js +258 -0
  251. package/data/probe/npm/tests/unit/imageConfig.test.js +149 -0
  252. package/data/probe/npm/tests/unit/imagePathResolution.test.js +345 -0
  253. package/data/probe/npm/tests/unit/json-fixing-agent.test.js +238 -0
  254. package/data/probe/npm/tests/unit/json-validation-enhanced-errors.test.js +199 -0
  255. package/data/probe/npm/tests/unit/jsonValidationInfiniteLoopFix.test.js +228 -0
  256. package/data/probe/npm/tests/unit/maidIntegration.test.js +139 -0
  257. package/data/probe/npm/tests/unit/maxIterationsWarning.test.js +195 -0
  258. package/data/probe/npm/tests/unit/mermaidEdgeLabelFix.test.js +161 -0
  259. package/data/probe/npm/tests/unit/mermaidHtmlEntities.test.js +76 -0
  260. package/data/probe/npm/tests/unit/mermaidInfiniteLoopFix.test.js +64 -0
  261. package/data/probe/npm/tests/unit/mermaidValidation.test.js +723 -0
  262. package/data/probe/npm/tests/unit/mermaidValidationVisorExample.test.js +309 -0
  263. package/data/probe/npm/tests/unit/probe-agent-clone-realistic.test.js +643 -0
  264. package/data/probe/npm/tests/unit/probe-agent-clone.test.js +476 -0
  265. package/data/probe/npm/tests/unit/probe-agent-delegate.test.js +400 -0
  266. package/data/probe/npm/tests/unit/probe-agent-model-option.test.js +118 -0
  267. package/data/probe/npm/tests/unit/probeTool-security.test.js +283 -0
  268. package/data/probe/npm/tests/unit/readImageTool.test.js +418 -0
  269. package/data/probe/npm/tests/unit/retryManager.test.js +317 -0
  270. package/data/probe/npm/tests/unit/schema-aware-reminders.test.js +288 -0
  271. package/data/probe/npm/tests/unit/schemaDefinitionDetection.test.js +115 -0
  272. package/data/probe/npm/tests/unit/schemaUtils.test.js +1268 -0
  273. package/data/probe/npm/tests/unit/simpleTelemetry.test.js +282 -0
  274. package/data/probe/npm/tests/unit/simplified-attempt-completion.test.js +274 -0
  275. package/data/probe/npm/tests/unit/single-quote-json-bug.test.js +231 -0
  276. package/data/probe/npm/tests/unit/subgraphAutoFix.test.js +110 -0
  277. package/data/probe/npm/tests/unit/system-prompt.test.js +32 -0
  278. package/data/probe/npm/tests/unit/types-probe-agent-options.test.js +42 -0
  279. package/data/probe/npm/tests/unit/xmlParsing.test.js +720 -0
  280. package/data/probe/npm/tsconfig.json +21 -0
  281. package/data/probe/result1.txt +19 -0
  282. package/data/probe/result2.txt +26 -0
  283. package/data/probe/scripts/benchmark.sh +270 -0
  284. package/data/probe/scripts/cache_memory_analysis.rs +844 -0
  285. package/data/probe/scripts/claude-hook-wrapper.sh +56 -0
  286. package/data/probe/site/.env.example +10 -0
  287. package/data/probe/site/DEPLOYMENT.md +86 -0
  288. package/data/probe/site/README.md +183 -0
  289. package/data/probe/site/adding-languages.md +135 -0
  290. package/data/probe/site/ai-chat.md +427 -0
  291. package/data/probe/site/ai-integration.md +1488 -0
  292. package/data/probe/site/blog/agentic-flow-custom-xml-protocol.md +407 -0
  293. package/data/probe/site/blog/index.md +118 -0
  294. package/data/probe/site/blog/v0.6.0-release.md +426 -0
  295. package/data/probe/site/blog.md +8 -0
  296. package/data/probe/site/changelog.md +200 -0
  297. package/data/probe/site/cli-mode.md +437 -0
  298. package/data/probe/site/code-extraction.md +436 -0
  299. package/data/probe/site/contributing/README.md +9 -0
  300. package/data/probe/site/contributing/documentation-cross-references.md +215 -0
  301. package/data/probe/site/contributing/documentation-maintenance.md +275 -0
  302. package/data/probe/site/contributing/documentation-structure.md +75 -0
  303. package/data/probe/site/documentation-cross-references.md +215 -0
  304. package/data/probe/site/documentation-guide.md +132 -0
  305. package/data/probe/site/documentation-maintenance.md +275 -0
  306. package/data/probe/site/features.md +147 -0
  307. package/data/probe/site/how-it-works.md +118 -0
  308. package/data/probe/site/index.md +175 -0
  309. package/data/probe/site/index.md.bak +133 -0
  310. package/data/probe/site/installation.md +235 -0
  311. package/data/probe/site/integrations/docker.md +248 -0
  312. package/data/probe/site/integrations/github-actions.md +413 -0
  313. package/data/probe/site/language-support-overview.md +168 -0
  314. package/data/probe/site/mcp-integration.md +587 -0
  315. package/data/probe/site/mcp-server.md +304 -0
  316. package/data/probe/site/navigation-structure.md +76 -0
  317. package/data/probe/site/nodejs-sdk.md +798 -0
  318. package/data/probe/site/output-formats.md +625 -0
  319. package/data/probe/site/package.json +21 -0
  320. package/data/probe/site/public/_headers +28 -0
  321. package/data/probe/site/public/_redirects +11 -0
  322. package/data/probe/site/quick-start.md +289 -0
  323. package/data/probe/site/search-functionality.md +291 -0
  324. package/data/probe/site/search-reference.md +291 -0
  325. package/data/probe/site/supported-languages.md +215 -0
  326. package/data/probe/site/use-cases/README.md +8 -0
  327. package/data/probe/site/use-cases/advanced-cli.md +253 -0
  328. package/data/probe/site/use-cases/ai-code-editors.md +239 -0
  329. package/data/probe/site/use-cases/building-ai-tools.md +529 -0
  330. package/data/probe/site/use-cases/cli-ai-workflows.md +285 -0
  331. package/data/probe/site/use-cases/deploying-probe-web-interface.md +255 -0
  332. package/data/probe/site/use-cases/integrating-probe-into-ai-code-editors.md +161 -0
  333. package/data/probe/site/use-cases/nodejs-sdk.md +596 -0
  334. package/data/probe/site/use-cases/team-chat.md +350 -0
  335. package/data/probe/site/web-interface.md +434 -0
  336. package/data/probe/site/wrangler.toml +9 -0
  337. package/data/probe/test-api-key.sh +1 -0
  338. package/data/probe/test-probe-implementation/hello.js +7 -0
  339. package/data/probe/test_cases/demonstrate_early_termination_issues.sh +176 -0
  340. package/data/probe/test_cases/early_termination_issues.rs +533 -0
  341. package/data/probe/test_data/test_nested_struct.go +26 -0
  342. package/data/probe/tests/README.md +286 -0
  343. package/data/probe/tests/README_search_determinism_tests.md +116 -0
  344. package/data/probe/tests/adjacent_comment_test.rs +152 -0
  345. package/data/probe/tests/apostrophe_handling_tests.rs +132 -0
  346. package/data/probe/tests/block_filtering_with_ast_tests.rs +669 -0
  347. package/data/probe/tests/block_merging_tests.rs +396 -0
  348. package/data/probe/tests/c_outline_format_tests.rs +2179 -0
  349. package/data/probe/tests/cache_invalidation_issues.rs.disabled +682 -0
  350. package/data/probe/tests/cache_order_tests.rs +147 -0
  351. package/data/probe/tests/cache_query_scoping_tests.rs +221 -0
  352. package/data/probe/tests/cli_tests.rs +680 -0
  353. package/data/probe/tests/comment_context_integration_test.rs +240 -0
  354. package/data/probe/tests/common.rs +33 -0
  355. package/data/probe/tests/complex_block_merging_tests.rs +599 -0
  356. package/data/probe/tests/complex_query_block_filtering_tests.rs +422 -0
  357. package/data/probe/tests/control_flow_closing_braces_test.rs +91 -0
  358. package/data/probe/tests/cpp_outline_format_tests.rs +1507 -0
  359. package/data/probe/tests/csharp_outline_format_tests.rs +941 -0
  360. package/data/probe/tests/elastic_query_integration_tests.rs +922 -0
  361. package/data/probe/tests/extract_command_tests.rs +1848 -0
  362. package/data/probe/tests/extract_deduplication_tests.rs +146 -0
  363. package/data/probe/tests/extract_input_file_tests.rs +84 -0
  364. package/data/probe/tests/extract_prompt_tests.rs +102 -0
  365. package/data/probe/tests/filename_search_tests.rs +96 -0
  366. package/data/probe/tests/fixtures/user/AssemblyInfo.cs +3 -0
  367. package/data/probe/tests/github_extract_tests.rs +234 -0
  368. package/data/probe/tests/go_comment_test.rs +253 -0
  369. package/data/probe/tests/go_outline_format_tests.rs +2587 -0
  370. package/data/probe/tests/go_path_resolver_tests.rs +96 -0
  371. package/data/probe/tests/html_outline_format_tests.rs +637 -0
  372. package/data/probe/tests/integration_tests.rs +837 -0
  373. package/data/probe/tests/ip_whitelist_test.rs +148 -0
  374. package/data/probe/tests/java_outline_format_tests.rs +1611 -0
  375. package/data/probe/tests/javascript_extract_tests.rs +315 -0
  376. package/data/probe/tests/javascript_outline_format_tests.rs +1464 -0
  377. package/data/probe/tests/json_format_tests.rs +436 -0
  378. package/data/probe/tests/json_schema_validation_tests.rs +450 -0
  379. package/data/probe/tests/lib_usage.rs +60 -0
  380. package/data/probe/tests/line_comment_context_extension_test.rs +459 -0
  381. package/data/probe/tests/line_map_cache_tests.rs +114 -0
  382. package/data/probe/tests/markdown_integration_tests.rs +190 -0
  383. package/data/probe/tests/mocks/test_ip_whitelist.go +11 -0
  384. package/data/probe/tests/mocks/test_object.js +27 -0
  385. package/data/probe/tests/mocks/test_struct.go +50 -0
  386. package/data/probe/tests/multi_keyword_pattern_tests.rs +464 -0
  387. package/data/probe/tests/multi_language_syntax_integration_tests.rs +218 -0
  388. package/data/probe/tests/multiple_capture_groups_tests.rs +169 -0
  389. package/data/probe/tests/negative_compound_word_tests.rs +246 -0
  390. package/data/probe/tests/nested_symbol_extraction_tests.rs +99 -0
  391. package/data/probe/tests/outline_cross_file_interference_test.rs +335 -0
  392. package/data/probe/tests/outline_keyword_preservation_test.rs +67 -0
  393. package/data/probe/tests/output_format_edge_cases_tests.rs +693 -0
  394. package/data/probe/tests/parallel_extraction_tests.rs +178 -0
  395. package/data/probe/tests/parallel_search_tests.rs +355 -0
  396. package/data/probe/tests/path_resolver_tests.rs +698 -0
  397. package/data/probe/tests/php_outline_format_extended_tests.rs +928 -0
  398. package/data/probe/tests/php_outline_format_tests.rs +768 -0
  399. package/data/probe/tests/property_tests.proptest-regressions +9 -0
  400. package/data/probe/tests/property_tests.rs +118 -0
  401. package/data/probe/tests/python_outline_format_tests.rs +1538 -0
  402. package/data/probe/tests/query_command_json_tests.rs +438 -0
  403. package/data/probe/tests/query_command_tests.rs +232 -0
  404. package/data/probe/tests/query_command_xml_tests.rs +569 -0
  405. package/data/probe/tests/quoted_term_with_negative_keyword_tests.rs +216 -0
  406. package/data/probe/tests/required_terms_filename_tests.rs +116 -0
  407. package/data/probe/tests/ruby_outline_format_tests.rs +1011 -0
  408. package/data/probe/tests/rust_line_comment_context_test.rs +151 -0
  409. package/data/probe/tests/rust_outline_format_enhanced_tests.rs +725 -0
  410. package/data/probe/tests/rust_outline_format_tests.rs +843 -0
  411. package/data/probe/tests/schemas/xml_output_schema.xsd +38 -0
  412. package/data/probe/tests/search_determinism_tests.rs +451 -0
  413. package/data/probe/tests/search_hints_tests.rs +253 -0
  414. package/data/probe/tests/special_character_escaping_tests.rs +417 -0
  415. package/data/probe/tests/stemming_compound_word_filtering_tests.rs +535 -0
  416. package/data/probe/tests/strict_elastic_syntax_tests.rs +404 -0
  417. package/data/probe/tests/swift_outline_format_tests.rs +3319 -0
  418. package/data/probe/tests/symbols_tests.rs +166 -0
  419. package/data/probe/tests/test_file.rs +45 -0
  420. package/data/probe/tests/test_tokenize.rs +28 -0
  421. package/data/probe/tests/timeout_tests.rs +82 -0
  422. package/data/probe/tests/tokenization_tests.rs +195 -0
  423. package/data/probe/tests/tokenized_block_filtering_tests.rs +174 -0
  424. package/data/probe/tests/typescript_extract_tests.rs +214 -0
  425. package/data/probe/tests/typescript_outline_format_tests.rs +2188 -0
  426. package/data/probe/tests/xml_format_tests.rs +568 -0
  427. package/data/probe/tests/xml_schema_validation_tests.rs +497 -0
  428. package/data/scripts/postinstall.mjs +9 -0
  429. package/data/scripts/set-version.js +0 -0
  430. package/data/scripts/wiki-build.sh +111 -0
  431. package/data/scripts/wiki-deploy.sh +73 -0
  432. package/data/serve.json +12 -0
  433. package/data/test/demo-dynamic.html +134 -0
  434. package/data/test/demo-esm.html +105 -0
  435. package/data/test/demo-iife.html +78 -0
  436. package/data/tsconfig.json +7 -0
  437. package/data/vite.server.ts +483 -0
  438. package/data/vitest.config.ts +40 -0
  439. package/data/wiki/Home.md +58 -0
  440. package/data/wiki/_Sidebar.md +39 -0
  441. package/docs-mcp.config.json +20 -0
  442. package/package.json +56 -0
  443. package/src/config.js +111 -0
  444. package/src/index.js +395 -0
@@ -0,0 +1,166 @@
1
+ use probe_code::search::{perform_probe, SearchOptions};
2
+ use std::fs;
3
+ use tempfile::tempdir;
4
+
5
+ #[test]
6
+ fn test_symbols_flag_with_rust_code() {
7
+ // Create a temporary directory and file
8
+ let temp_dir = tempdir().expect("Failed to create temp dir");
9
+ let test_file = temp_dir.path().join("test.rs");
10
+
11
+ // Write Rust code with various symbols
12
+ let rust_code = r#"
13
+ pub struct User {
14
+ pub name: String,
15
+ pub age: u32,
16
+ }
17
+
18
+ impl User {
19
+ pub fn new(name: String, age: u32) -> Self {
20
+ Self { name, age }
21
+ }
22
+
23
+ pub fn greet(&self) -> String {
24
+ format!("Hello, I'm {}", self.name)
25
+ }
26
+ }
27
+
28
+ pub fn main() {
29
+ let user = User::new("Alice".to_string(), 30);
30
+ println!("{}", user.greet());
31
+ }
32
+
33
+ pub const MAX_USERS: usize = 1000;
34
+ "#;
35
+
36
+ fs::write(&test_file, rust_code).expect("Failed to write test file");
37
+
38
+ // Test search with symbols flag enabled
39
+ let options = SearchOptions {
40
+ path: temp_dir.path(),
41
+ queries: &["pub fn".to_string()],
42
+ files_only: false,
43
+ custom_ignores: &[],
44
+ exclude_filenames: false,
45
+ reranker: "bm25",
46
+ frequency_search: true,
47
+ exact: false,
48
+ language: None,
49
+ max_results: Some(10),
50
+ max_bytes: None,
51
+ max_tokens: None,
52
+ allow_tests: false,
53
+ no_merge: false,
54
+ merge_threshold: None,
55
+ dry_run: false,
56
+ session: None,
57
+ timeout: 30,
58
+ question: None,
59
+ no_gitignore: true,
60
+ };
61
+
62
+ let results = perform_probe(&options).expect("Search should succeed");
63
+
64
+ // Verify we got results
65
+ assert!(!results.results.is_empty(), "Should find symbol matches");
66
+
67
+ // Verify that symbol signatures are populated
68
+ let has_symbol_signatures = results.results.iter().any(|r| r.symbol_signature.is_some());
69
+ assert!(
70
+ has_symbol_signatures,
71
+ "At least one result should have a symbol signature"
72
+ );
73
+
74
+ // Test with symbols flag disabled
75
+ let options_no_symbols = SearchOptions { ..options };
76
+
77
+ let results_no_symbols = perform_probe(&options_no_symbols).expect("Search should succeed");
78
+
79
+ // Verify that symbol signatures are not populated when flag is disabled
80
+ let has_symbol_signatures = results_no_symbols
81
+ .results
82
+ .iter()
83
+ .any(|r| r.symbol_signature.is_some());
84
+ assert!(
85
+ !has_symbol_signatures,
86
+ "No results should have symbol signatures when flag is disabled"
87
+ );
88
+ }
89
+
90
+ #[test]
91
+ fn test_symbols_flag_with_python_code() {
92
+ // Create a temporary directory and file
93
+ let temp_dir = tempdir().expect("Failed to create temp dir");
94
+ let test_file = temp_dir.path().join("test.py");
95
+
96
+ // Write Python code with various symbols
97
+ let python_code = r#"
98
+ class User:
99
+ def __init__(self, name: str, age: int):
100
+ self.name = name
101
+ self.age = age
102
+
103
+ def greet(self) -> str:
104
+ return f"Hello, I'm {self.name}"
105
+
106
+ def create_user(name: str, age: int) -> User:
107
+ return User(name, age)
108
+
109
+ async def async_function(data: list) -> dict:
110
+ return {"length": len(data)}
111
+
112
+ MAX_USERS = 1000
113
+ "#;
114
+
115
+ fs::write(&test_file, python_code).expect("Failed to write test file");
116
+
117
+ // Test search with symbols flag enabled
118
+ let options = SearchOptions {
119
+ path: temp_dir.path(),
120
+ queries: &["def ".to_string()],
121
+ files_only: false,
122
+ custom_ignores: &[],
123
+ exclude_filenames: false,
124
+ reranker: "bm25",
125
+ frequency_search: true,
126
+ exact: false,
127
+ language: None,
128
+ max_results: Some(10),
129
+ max_bytes: None,
130
+ max_tokens: None,
131
+ allow_tests: false,
132
+ no_merge: false,
133
+ merge_threshold: None,
134
+ dry_run: false,
135
+ session: None,
136
+ timeout: 30,
137
+ question: None,
138
+ no_gitignore: true,
139
+ };
140
+
141
+ let results = perform_probe(&options).expect("Search should succeed");
142
+
143
+ // Verify we got results
144
+ assert!(!results.results.is_empty(), "Should find symbol matches");
145
+
146
+ // Verify that symbol signatures are populated and contain Python syntax
147
+ let python_symbols: Vec<_> = results
148
+ .results
149
+ .iter()
150
+ .filter_map(|r| r.symbol_signature.as_ref())
151
+ .collect();
152
+
153
+ assert!(
154
+ !python_symbols.is_empty(),
155
+ "Should have Python symbol signatures"
156
+ );
157
+
158
+ // Check that we have recognizable Python function signatures
159
+ let has_python_function = python_symbols
160
+ .iter()
161
+ .any(|sig| sig.contains("def ") && sig.contains("(") && sig.contains(")"));
162
+ assert!(
163
+ has_python_function,
164
+ "Should have Python function signatures"
165
+ );
166
+ }
@@ -0,0 +1,45 @@
1
+ // This is a test file for probe
2
+
3
+ #[allow(dead_code)]
4
+ fn function1() {
5
+ println!("This is function 1");
6
+ // Some code here
7
+ let x = 10;
8
+ let y = 20;
9
+ println!("Sum: {}", x + y);
10
+ }
11
+
12
+ // This comment is between function1 and function2
13
+ // Only a few lines of separation
14
+
15
+ #[allow(dead_code)]
16
+ fn function2() {
17
+ println!("This is function 2");
18
+ // Some code here
19
+ let a = 30;
20
+ let b = 40;
21
+ println!("Product: {}", a * b);
22
+ }
23
+
24
+ // This is a larger gap between functions
25
+
26
+ // More comments
27
+ // More comments
28
+ // More comments
29
+ // More comments
30
+ // More comments
31
+ // More comments
32
+ // More comments
33
+ // More comments
34
+ // More comments
35
+ // More comments
36
+ // More comments
37
+
38
+ #[allow(dead_code)]
39
+ fn function3() {
40
+ println!("This is function 3");
41
+ // Some code here
42
+ let c = 50;
43
+ let d = 60;
44
+ println!("Difference: {}", d - c);
45
+ }
@@ -0,0 +1,28 @@
1
+ fn main() {
2
+ // Import the tokenize function from our probe crate
3
+ use probe_code::ranking::tokenize;
4
+
5
+ // Test strings
6
+ let test_strings = ["The quick brown fox jumps over the lazy dog",
7
+ "function calculateTotal(items) { return items.reduce((sum, item) => sum + item.price, 0); }",
8
+ "class UserController extends BaseController implements UserInterface",
9
+ "Searching for files containing important information",
10
+ "Fruitlessly searching for the missing variable in the codebase"];
11
+
12
+ println!("Testing tokenization with stop word removal and stemming:\n");
13
+
14
+ for (i, test_str) in test_strings.iter().enumerate() {
15
+ println!("Original text {}:\n{}", i + 1, test_str);
16
+
17
+ // Tokenize with stop word removal and stemming
18
+ let tokens = tokenize(test_str);
19
+
20
+ println!("Tokens after stop word removal and stemming:");
21
+ println!("{tokens:?}");
22
+ println!("Number of tokens: {}\n", tokens.len());
23
+ }
24
+
25
+ // Specific test for stemming
26
+ println!("Specific stemming test:");
27
+ println!("'fruitlessly' stems to: {}", tokenize("fruitlessly")[0]);
28
+ }
@@ -0,0 +1,82 @@
1
+ use std::path::Path;
2
+ use std::process::Command;
3
+ use std::time::Instant;
4
+ use tempfile::TempDir;
5
+
6
+ /// Create a large test file that will take time to process
7
+ fn create_large_test_file(temp_dir: &Path) {
8
+ let file_path = temp_dir.join("large_file.rs");
9
+
10
+ // Create a very large file with many lines to ensure the search takes longer than the timeout
11
+ let mut content = String::new();
12
+ for i in 0..500000 {
13
+ // Increased to 500,000 lines
14
+ content.push_str(&format!("// Line {i} with searchable content\n"));
15
+ content.push_str(&format!("fn function_{i}() {{\n"));
16
+ content.push_str(&format!(" let search_term = {i};\n"));
17
+ content.push_str(" println!(\"Found: {}\", search_term);\n");
18
+ content.push_str("}\n\n");
19
+ }
20
+
21
+ // Write the file
22
+ std::fs::write(file_path, content).expect("Failed to write large test file");
23
+ }
24
+
25
+ /// Test that the search operation times out after the specified timeout
26
+ /// This test runs the search command in a separate process since our timeout
27
+ /// implementation calls std::process::exit(1)
28
+ #[test]
29
+ fn test_search_timeout() {
30
+ // Create a temporary directory
31
+ let temp_dir = TempDir::new().expect("Failed to create temp dir");
32
+
33
+ // Create a large test file
34
+ create_large_test_file(temp_dir.path());
35
+
36
+ // Measure the time it takes to run the search
37
+ let start_time = Instant::now();
38
+
39
+ // Run the search command with a very short timeout using cargo run
40
+ let output = Command::new("cargo")
41
+ .arg("run")
42
+ .arg("--")
43
+ .arg("search")
44
+ .arg("search_term") // This term appears in every function
45
+ .arg("/")
46
+ .arg("--timeout")
47
+ .arg("1") // 1 second timeout should be short enough to trigger
48
+ .output()
49
+ .expect("Failed to execute command");
50
+
51
+ // Check how long it took
52
+ let elapsed = start_time.elapsed();
53
+
54
+ // Print the output for debugging
55
+ println!(
56
+ "Command output: {}",
57
+ String::from_utf8_lossy(&output.stdout)
58
+ );
59
+ println!("Command error: {}", String::from_utf8_lossy(&output.stderr));
60
+
61
+ // The command should have failed (non-zero exit code)
62
+ assert_ne!(
63
+ output.status.code().unwrap_or(-1),
64
+ 0,
65
+ "Command should have failed with a non-zero exit code"
66
+ );
67
+
68
+ // The error output should mention timeout
69
+ let stderr = String::from_utf8_lossy(&output.stderr);
70
+ assert!(
71
+ stderr.contains("timeout") || stderr.contains("timed out"),
72
+ "Error output should mention timeout: {stderr}"
73
+ );
74
+
75
+ // The elapsed time should be close to the timeout value
76
+ assert!(
77
+ elapsed.as_secs() >= 1 && elapsed.as_secs() <= 5,
78
+ "Search should have timed out after about 1 second, but took {elapsed:?}"
79
+ );
80
+
81
+ println!("✓ Search timed out correctly after {elapsed:?}");
82
+ }
@@ -0,0 +1,195 @@
1
+ use probe_code::search::elastic_query::parse_query_test as parse_query;
2
+
3
+ use probe_code::search::query::{create_query_plan, create_structured_patterns};
4
+ use probe_code::search::tokenization::{load_vocabulary, split_camel_case, split_compound_word};
5
+
6
+ #[test]
7
+ fn test_camel_case_splitting() {
8
+ // Test camelCase splitting with "RPCStorageHandler"
9
+ let input = "RPCStorageHandler";
10
+ let camel_parts = split_camel_case(input);
11
+
12
+ println!("Direct camelCase split of '{input}': {camel_parts:?}");
13
+
14
+ // We expect "RPCStorageHandler" to be split into ["rpc", "storage", "handler"]
15
+ assert!(camel_parts.contains(&"rpc".to_string()));
16
+ assert!(camel_parts.contains(&"storage".to_string()));
17
+ assert!(camel_parts.contains(&"handler".to_string()));
18
+ }
19
+
20
+ #[test]
21
+ fn test_compound_word_splitting() {
22
+ // Test compound word splitting with "whitelist"
23
+ let vocab = load_vocabulary();
24
+ let mut enhanced_vocab = vocab.clone();
25
+
26
+ // Add specific programming terms to the vocabulary
27
+ for term in [
28
+ "rpc", "storage", "handler", "client", "server", "api", "service", "http", "handler",
29
+ ] {
30
+ enhanced_vocab.insert(term.to_string());
31
+ }
32
+
33
+ let input = "httpHandler";
34
+ let compound_parts = split_compound_word(input, &enhanced_vocab);
35
+
36
+ println!("Compound split of '{input}': {compound_parts:?}");
37
+
38
+ assert!(compound_parts.contains(&"http".to_string()));
39
+ assert!(compound_parts.contains(&"Handler".to_string()));
40
+ }
41
+
42
+ #[test]
43
+ fn test_query_preprocessing() {
44
+ // Test query preprocessing with "RPCStorageHandler"
45
+ let query = "RPCStorageHandler";
46
+ let plan = create_query_plan(query, false).expect("Failed to create query plan");
47
+
48
+ println!("Query plan for '{query}': {plan:?}");
49
+
50
+ // Check if the term_indices include the expected parts
51
+ let term_strings: Vec<String> = plan.term_indices.keys().cloned().collect();
52
+
53
+ // We expect to see "rpc", "storage", "handler" in the terms
54
+ assert!(
55
+ term_strings.contains(&"rpc".to_string())
56
+ || term_strings.contains(&"storage".to_string())
57
+ || term_strings.contains(&"handler".to_string()),
58
+ "Expected at least one of 'rpc', 'storage', or 'handler' in {term_strings:?}"
59
+ );
60
+ }
61
+
62
+ #[test]
63
+ fn test_pattern_generation() {
64
+ // Test pattern generation with "RPCStorageHandler"
65
+ let query = "RPCStorageHandler";
66
+ let plan = create_query_plan(query, false).expect("Failed to create query plan");
67
+ let patterns = create_structured_patterns(&plan);
68
+
69
+ println!("Generated patterns:");
70
+ for (i, (pattern, indices)) in patterns.iter().enumerate() {
71
+ println!("Pattern {i}: {pattern} - Indices: {indices:?}");
72
+ }
73
+
74
+ // Check that we have patterns for the expected terms
75
+ let term_indices = &plan.term_indices;
76
+
77
+ // Verify that each term in the plan has at least one pattern
78
+ for (term, &idx) in term_indices {
79
+ if !plan.excluded_terms.contains(term) {
80
+ let has_pattern = patterns.iter().any(|(_, indices)| indices.contains(&idx));
81
+ assert!(
82
+ has_pattern,
83
+ "No pattern found for term '{term}' at index {idx}"
84
+ );
85
+ }
86
+ }
87
+
88
+ // Check that all patterns are valid regexes
89
+ for (pattern, _) in &patterns {
90
+ assert!(
91
+ regex::Regex::new(pattern).is_ok(),
92
+ "Invalid regex pattern: {pattern}"
93
+ );
94
+ }
95
+ }
96
+
97
+ #[test]
98
+ fn test_multiple_word_query() {
99
+ // Test multiple words with "ip whitelist"
100
+ let query = "ip whitelist";
101
+ let plan = create_query_plan(query, false).expect("Failed to create query plan");
102
+
103
+ println!("Query plan for '{query}': {plan:?}");
104
+
105
+ // Check if the terms include the expected parts
106
+ let term_strings: Vec<String> = plan.term_indices.keys().cloned().collect();
107
+
108
+ // We expect to see "ip", "white", "list" in the terms
109
+ assert!(term_strings.contains(&"ip".to_string()));
110
+
111
+ // Either "white" and "list" separately, or "whitelist" as a whole
112
+ let has_white_and_list =
113
+ term_strings.contains(&"white".to_string()) && term_strings.contains(&"list".to_string());
114
+ let has_whitelist = term_strings.contains(&"whitelist".to_string());
115
+
116
+ assert!(
117
+ has_white_and_list || has_whitelist,
118
+ "Expected either both 'white' and 'list', or 'whitelist' in {term_strings:?}"
119
+ );
120
+ }
121
+
122
+ #[test]
123
+ fn test_underscore_handling() {
124
+ use probe_code::search::elastic_query;
125
+
126
+ // Test tokenization with underscores
127
+ let query = "keyword_underscore";
128
+ let plan = create_query_plan(query, false).expect("Failed to create query plan");
129
+
130
+ println!("Query plan for '{query}': {plan:?}");
131
+
132
+ // Check if the term is preserved with the underscore in the term_indices
133
+ let term_strings: Vec<String> = plan.term_indices.keys().cloned().collect();
134
+
135
+ // We expect to see "keyword_underscore" or its tokenized parts
136
+ let has_tokenized_parts = term_strings.contains(&"key".to_string())
137
+ || term_strings.contains(&"word".to_string())
138
+ || term_strings.contains(&"score".to_string());
139
+
140
+ assert!(
141
+ has_tokenized_parts,
142
+ "Expected tokenized parts of 'keyword_underscore' in {term_strings:?}"
143
+ );
144
+
145
+ // Check if the term is properly tokenized in the elastic query parser
146
+ // This is already done in the create_query_plan function, but we'll verify the AST
147
+ if let elastic_query::Expr::Term { keywords, .. } = &plan.ast {
148
+ // The term should be tokenized into ["key", "word", "under", "score"]
149
+ // Note: "under" might be filtered out as a stop word
150
+ assert!(
151
+ keywords.contains(&"key".to_string()),
152
+ "Expected 'key' in keywords: {keywords:?}"
153
+ );
154
+ assert!(
155
+ keywords.contains(&"word".to_string()),
156
+ "Expected 'word' in keywords: {keywords:?}"
157
+ );
158
+ assert!(
159
+ keywords.contains(&"score".to_string()),
160
+ "Expected 'score' in keywords: {keywords:?}"
161
+ );
162
+ } else {
163
+ panic!("Expected Term expression");
164
+ }
165
+ }
166
+
167
+ #[test]
168
+ fn test_underscore_in_elastic_query() {
169
+ use probe_code::search::elastic_query;
170
+
171
+ // Test that the elastic query parser preserves underscores
172
+ let query = "keyword_underscore";
173
+ // Use parse_query with standard Elasticsearch behavior (AND for implicit combinations)
174
+ let ast = parse_query(query).unwrap();
175
+
176
+ // Check that the AST contains the tokenized terms from "keyword_underscore"
177
+ if let elastic_query::Expr::Term { keywords, .. } = ast {
178
+ // The term should be tokenized into ["key", "word", "under", "score"]
179
+ // Note: "under" might be filtered out as a stop word
180
+ assert!(
181
+ keywords.contains(&"key".to_string()),
182
+ "Expected 'key' in keywords: {keywords:?}"
183
+ );
184
+ assert!(
185
+ keywords.contains(&"word".to_string()),
186
+ "Expected 'word' in keywords: {keywords:?}"
187
+ );
188
+ assert!(
189
+ keywords.contains(&"score".to_string()),
190
+ "Expected 'score' in keywords: {keywords:?}"
191
+ );
192
+ } else {
193
+ panic!("Expected Term expression");
194
+ }
195
+ }
@@ -0,0 +1,174 @@
1
+ use probe_code::search::file_processing::filter_tokenized_block;
2
+ use probe_code::search::query::create_query_plan;
3
+ use std::collections::{HashMap, HashSet};
4
+
5
+ /// Test direct usage of filter_tokenized_block with various complex queries
6
+ #[test]
7
+ fn test_filter_tokenized_block_basic() {
8
+ // Create a simple tokenized content
9
+ let tokenized_content = vec![
10
+ "ip".to_string(),
11
+ "whitelist".to_string(),
12
+ "config".to_string(),
13
+ ];
14
+
15
+ // Test with a simple AND query
16
+ let query = "ip AND whitelist";
17
+ let plan = create_query_plan(query, false).unwrap();
18
+
19
+ // Test filtering
20
+ let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
21
+ assert!(
22
+ result,
23
+ "Block with 'ip' and 'whitelist' should match the AND query"
24
+ );
25
+
26
+ // Test with a simple OR query
27
+ let query = "ip OR port";
28
+ let plan = create_query_plan(query, false).unwrap();
29
+
30
+ // Test filtering
31
+ let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
32
+ assert!(
33
+ result,
34
+ "Block with 'ip' should match the OR query even without 'port'"
35
+ );
36
+
37
+ // Test with a more complex query
38
+ let query = "(ip OR port) AND config";
39
+ let plan = create_query_plan(query, false).unwrap();
40
+
41
+ // Test filtering
42
+ let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
43
+ assert!(
44
+ result,
45
+ "Block with 'ip' and 'config' should match the complex query"
46
+ );
47
+ }
48
+
49
+ #[test]
50
+ fn test_filter_tokenized_block_with_excluded_terms() {
51
+ // Create a tokenized content with some terms
52
+ let tokenized_content = vec![
53
+ "ip".to_string(),
54
+ "whitelist".to_string(),
55
+ "config".to_string(),
56
+ ];
57
+
58
+ // Test with a query that has excluded terms
59
+ let query = "ip -test";
60
+ let plan = create_query_plan(query, false).unwrap();
61
+
62
+ // Test filtering
63
+ let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
64
+ assert!(result, "Block with 'ip' but without 'test' should match");
65
+
66
+ // Create a tokenized content with the excluded term
67
+ let tokenized_content_with_excluded = vec![
68
+ "ip".to_string(),
69
+ "whitelist".to_string(),
70
+ "test".to_string(),
71
+ ];
72
+
73
+ // Test filtering with the excluded term present
74
+ let result = filter_tokenized_block(
75
+ &tokenized_content_with_excluded,
76
+ &plan.term_indices,
77
+ &plan,
78
+ true,
79
+ );
80
+ assert!(
81
+ !result,
82
+ "Block with 'ip' and 'test' should NOT match because 'test' is excluded"
83
+ );
84
+ }
85
+
86
+ #[test]
87
+ fn test_filter_tokenized_block_with_complex_queries() {
88
+ // Create a tokenized content
89
+ let tokenized_content = vec![
90
+ "ip".to_string(),
91
+ "whitelist".to_string(),
92
+ "config".to_string(),
93
+ "server".to_string(),
94
+ ];
95
+
96
+ // Test with a complex query with AND, OR, and excluded terms
97
+ let query = "(ip OR port) AND (whitelist OR config) -test";
98
+ let plan = create_query_plan(query, false).unwrap();
99
+
100
+ // Test filtering
101
+ let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
102
+ assert!(
103
+ result,
104
+ "Block with 'ip', 'whitelist', and 'config' but without 'test' should match"
105
+ );
106
+
107
+ // Test with a different tokenized content that doesn't match
108
+ let tokenized_content_missing_required = vec!["port".to_string(), "server".to_string()];
109
+
110
+ // Test filtering
111
+ let result = filter_tokenized_block(
112
+ &tokenized_content_missing_required,
113
+ &plan.term_indices,
114
+ &plan,
115
+ true,
116
+ );
117
+ assert!(
118
+ !result,
119
+ "Block with only 'port' and 'server' should NOT match because it's missing 'whitelist' or 'config'"
120
+ );
121
+ }
122
+
123
+ #[test]
124
+ fn test_filter_tokenized_block_empty_content() {
125
+ // Create an empty tokenized content
126
+ let tokenized_content: Vec<String> = vec![];
127
+
128
+ // Test with a simple query
129
+ let query = "ip AND whitelist";
130
+ let plan = create_query_plan(query, false).unwrap();
131
+
132
+ // Test filtering
133
+ let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
134
+ assert!(!result, "Empty block should not match any query");
135
+ }
136
+
137
+ #[test]
138
+ fn test_filter_tokenized_block_comparison_with_line_based() {
139
+ // This test compares the behavior of filter_tokenized_block with filter_code_block_with_ast
140
+ // to ensure they produce the same results for equivalent inputs
141
+
142
+ // Create a tokenized content
143
+ let tokenized_content = vec![
144
+ "ip".to_string(),
145
+ "whitelist".to_string(),
146
+ "config".to_string(),
147
+ ];
148
+
149
+ // Create a query
150
+ let query = "ip AND whitelist";
151
+ let plan = create_query_plan(query, false).unwrap();
152
+
153
+ // Test tokenized filtering
154
+ let tokenized_result =
155
+ filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
156
+
157
+ // Import the line-based filtering function for comparison
158
+ use probe_code::search::file_processing::filter_code_block_with_ast;
159
+
160
+ // Create equivalent line-based term matches
161
+ let mut term_matches = HashMap::new();
162
+ term_matches.insert(0, HashSet::from([1])); // ip on line 1
163
+ term_matches.insert(1, HashSet::from([1])); // whitelist on line 1
164
+ term_matches.insert(2, HashSet::from([1])); // config on line 1
165
+
166
+ // Test line-based filtering
167
+ let line_based_result = filter_code_block_with_ast((1, 1), &term_matches, &plan, true);
168
+
169
+ // Compare results
170
+ assert_eq!(
171
+ tokenized_result, line_based_result,
172
+ "Tokenized filtering and line-based filtering should produce the same result"
173
+ );
174
+ }