codegraphcontext 0.6.1__tar.gz → 0.6.3__tar.gz

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 (190) hide show
  1. {codegraphcontext-0.6.1/src/codegraphcontext.egg-info → codegraphcontext-0.6.3}/PKG-INFO +1 -1
  2. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/pyproject.toml +1 -1
  3. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/cli/cli_helpers.py +4 -0
  4. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/cli/config_manager.py +15 -0
  5. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/cli/main.py +208 -14
  6. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/database_embedded_kuzu.py +21 -10
  7. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/watcher.py +20 -8
  8. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/code_finder.py +162 -9
  9. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/embeddings.py +32 -0
  10. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/persistence/writer.py +17 -2
  11. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/pipeline.py +50 -14
  12. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/cpp.py +9 -5
  13. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3/src/codegraphcontext.egg-info}/PKG-INFO +1 -1
  14. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/LICENSE +0 -0
  15. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/MANIFEST.in +0 -0
  16. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/README.md +0 -0
  17. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/setup.cfg +0 -0
  18. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/__init__.py +0 -0
  19. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/__main__.py +0 -0
  20. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/api/__init__.py +0 -0
  21. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/api/app.py +0 -0
  22. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/api/auth.py +0 -0
  23. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/api/mcp_sse.py +0 -0
  24. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/api/router.py +0 -0
  25. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/api/schemas.py +0 -0
  26. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/cli/__init__.py +0 -0
  27. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/cli/hook_manager.py +0 -0
  28. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/cli/project_config.py +0 -0
  29. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/cli/registry_commands.py +0 -0
  30. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/cli/setup_macos.py +0 -0
  31. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/cli/setup_wizard.py +0 -0
  32. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/cli/simulator.py +0 -0
  33. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/cli/visualizer.py +0 -0
  34. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/__init__.py +0 -0
  35. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/bundle_registry.py +0 -0
  36. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/cgc_bundle.py +0 -0
  37. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/cgcignore.py +0 -0
  38. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/database.py +0 -0
  39. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/database_falkordb.py +0 -0
  40. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/database_falkordb_remote.py +0 -0
  41. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/database_kuzu.py +0 -0
  42. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/database_ladybug.py +0 -0
  43. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/database_nornic.py +0 -0
  44. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/falkor_worker.py +0 -0
  45. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/graph_query.py +0 -0
  46. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/jobs.py +0 -0
  47. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/core/simulator.py +0 -0
  48. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/prompts.py +0 -0
  49. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/server.py +0 -0
  50. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/stdlibs.py +0 -0
  51. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tool_definitions.py +0 -0
  52. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/__init__.py +0 -0
  53. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
  54. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/datasources/__init__.py +0 -0
  55. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/datasources/cassandra_ingester.py +0 -0
  56. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/datasources/mysql_ingester.py +0 -0
  57. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/datasources/redis_ingester.py +0 -0
  58. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/graph_builder.py +0 -0
  59. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -0
  60. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/handlers/indexing_handlers.py +0 -0
  61. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/handlers/management_handlers.py +0 -0
  62. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/handlers/query_handlers.py +0 -0
  63. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/handlers/watcher_handlers.py +0 -0
  64. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/__init__.py +0 -0
  65. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/constants.py +0 -0
  66. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/discovery.py +0 -0
  67. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/persistence/__init__.py +0 -0
  68. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/persistence/utils.py +0 -0
  69. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/pre_scan.py +0 -0
  70. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/resolution/__init__.py +0 -0
  71. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/resolution/calls.py +0 -0
  72. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/resolution/inheritance.py +0 -0
  73. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/resolution/post_resolution.py +0 -0
  74. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/sanitize.py +0 -0
  75. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/schema.py +0 -0
  76. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/schema_contract.py +0 -0
  77. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/scip_pipeline.py +0 -0
  78. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/indexing/vector_resolver.py +0 -0
  79. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/c.py +0 -0
  80. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/csharp.py +0 -0
  81. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/css.py +0 -0
  82. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/dart.py +0 -0
  83. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/elisp.py +0 -0
  84. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/elixir.py +0 -0
  85. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/go.py +0 -0
  86. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/gradle.py +0 -0
  87. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/haskell.py +0 -0
  88. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/html.py +0 -0
  89. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/java.py +0 -0
  90. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/javascript.py +0 -0
  91. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
  92. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/lua.py +0 -0
  93. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/maven.py +0 -0
  94. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/mybatis.py +0 -0
  95. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/perl.py +0 -0
  96. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/php.py +0 -0
  97. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/python.py +0 -0
  98. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/ruby.py +0 -0
  99. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/rust.py +0 -0
  100. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/scala.py +0 -0
  101. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/sfc_common.py +0 -0
  102. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/solidity.py +0 -0
  103. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/solidity_remappings.py +0 -0
  104. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/svelte.py +0 -0
  105. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/swift.py +0 -0
  106. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/typescript.py +0 -0
  107. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
  108. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/languages/vue.py +0 -0
  109. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/package_resolver.py +0 -0
  110. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
  111. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
  112. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
  113. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
  114. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/elisp_toolkit.py +0 -0
  115. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
  116. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
  117. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
  118. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
  119. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
  120. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
  121. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
  122. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
  123. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
  124. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/solidity_toolkit.py +0 -0
  125. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
  126. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
  127. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/report_generator.py +0 -0
  128. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/scip_indexer.py +0 -0
  129. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/scip_pb2.py +0 -0
  130. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/system.py +0 -0
  131. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/tree_sitter_parser.py +0 -0
  132. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/tools/type_utils.py +0 -0
  133. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/cypher_ddl.py +0 -0
  134. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/cypher_readonly.py +0 -0
  135. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/debug_log.py +0 -0
  136. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/gcf_encoder.py +0 -0
  137. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/git_utils.py +0 -0
  138. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/path_ignore.py +0 -0
  139. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/path_sandbox.py +0 -0
  140. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/repo_path.py +0 -0
  141. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/secret_scanner.py +0 -0
  142. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/tool_limits.py +0 -0
  143. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
  144. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/utils/visualize_graph.py +0 -0
  145. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/assets/__vite-browser-external-9wXp6ZBx.js +0 -0
  146. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/assets/function-calls-BtRHrqa2.png +0 -0
  147. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/assets/graph-total-D1fBAugo.png +0 -0
  148. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/assets/hero-graph-2voMJp2a.jpg +0 -0
  149. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/assets/hierarchy-DGADo0YT.png +0 -0
  150. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/assets/index-C-187lf0.js +0 -0
  151. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/assets/index-fNAa6jgv.css +0 -0
  152. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/assets/parser-pyodide.worker-BgsDfaad.js +0 -0
  153. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/assets/parser.worker-_nvrecvj.js +0 -0
  154. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/assets/tree-sitter-qKYAACSa.wasm +0 -0
  155. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/cgcIcon.png +0 -0
  156. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/favicon.ico +0 -0
  157. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/index.html +0 -0
  158. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/logo-icon.svg +0 -0
  159. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/logo.svg +0 -0
  160. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/placeholder.svg +0 -0
  161. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/preview-image.png +0 -0
  162. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/robots.txt +0 -0
  163. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-c.wasm +0 -0
  164. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-c_sharp.wasm +0 -0
  165. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-core.js +0 -0
  166. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-cpp.wasm +0 -0
  167. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-dart.wasm +0 -0
  168. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-go.wasm +0 -0
  169. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-java.wasm +0 -0
  170. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-javascript.wasm +0 -0
  171. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-kotlin.wasm +0 -0
  172. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-perl.wasm +0 -0
  173. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-php.wasm +0 -0
  174. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-python.wasm +0 -0
  175. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-ruby.wasm +0 -0
  176. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-rust.wasm +0 -0
  177. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-swift.wasm +0 -0
  178. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-tsx.wasm +0 -0
  179. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter-typescript.wasm +0 -0
  180. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/tree-sitter.wasm +0 -0
  181. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.js +0 -0
  182. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.wasm +0 -0
  183. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext/viz/server.py +0 -0
  184. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext.egg-info/SOURCES.txt +0 -0
  185. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
  186. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
  187. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext.egg-info/requires.txt +0 -0
  188. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/src/codegraphcontext.egg-info/top_level.txt +0 -0
  189. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/tests/test_issue_806_fix.py +0 -0
  190. {codegraphcontext-0.6.1 → codegraphcontext-0.6.3}/tests/test_mcp_sse.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codegraphcontext
3
- Version: 0.6.1
3
+ Version: 0.6.3
4
4
  Summary: An MCP server that indexes local code into a graph database to provide context to AI assistants.
5
5
  Author-email: Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
6
6
  License: MIT License
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codegraphcontext"
3
- version = "0.6.1"
3
+ version = "0.6.3"
4
4
  description = "An MCP server that indexes local code into a graph database to provide context to AI assistants."
5
5
  authors = [{ name = "Shashank Shekhar Singh", email = "shashankshekharsingh1205@gmail.com" }]
6
6
  readme = "README.md"
@@ -123,6 +123,10 @@ def _print_index_execution_summary(graph_builder: GraphBuilder) -> None:
123
123
  f"{summary.get('serialization_seconds', 0.0):.2f}",
124
124
  )
125
125
  console.print(table)
126
+ # Always-visible warnings (#1597): these describe an explicitly enabled
127
+ # feature that did NOT run — they must not depend on the log level.
128
+ for warning in summary.get("warnings", []):
129
+ console.print(f"[bold yellow]⚠ {warning}[/bold yellow]")
126
130
 
127
131
 
128
132
  def _initialize_services(
@@ -685,6 +685,21 @@ def set_config_value(key: str, value: str) -> bool:
685
685
  save_config(config)
686
686
 
687
687
  console.print(f"[green]✅ Set {key} = {value}[/green]")
688
+
689
+ # Surface a missing embedding backend at the moment of intent, not after
690
+ # an index run that silently generated nothing (#1597).
691
+ if key == "ENABLE_VECTOR_RESOLVE" and value.lower() == "true":
692
+ try:
693
+ from codegraphcontext.tools.indexing.embeddings import probe_embedding_backend
694
+ ok, detail = probe_embedding_backend()
695
+ if not ok:
696
+ console.print(
697
+ f"[bold yellow]⚠ Vector resolve is enabled but cannot run yet: "
698
+ f"{detail}. Indexing will proceed without embeddings until "
699
+ f"this is installed.[/bold yellow]"
700
+ )
701
+ except Exception:
702
+ pass
688
703
  return True
689
704
 
690
705
 
@@ -1149,6 +1149,96 @@ def export_shortcut(
1149
1149
  context=context,
1150
1150
  )
1151
1151
 
1152
+ @app.command("diagram")
1153
+ def diagram(
1154
+ path: Optional[str] = typer.Argument(None, help="Repository path to scope the diagram to"),
1155
+ output_format: str = typer.Option("mermaid", "--format", help="Diagram format: mermaid or dot (#1287)"),
1156
+ level: str = typer.Option("file", "--level", help="Granularity: 'file' (file→module imports) or 'call' (function call graph)"),
1157
+ output: Optional[str] = typer.Option(None, "--output", "-o", help="Write to a file instead of stdout"),
1158
+ limit: int = typer.Option(300, "--limit", "-l", help="Maximum edges to include (truncation is reported in the diagram)"),
1159
+ context: Optional[str] = typer.Option(None, "--context", "-c", help="Specific context to use"),
1160
+ ):
1161
+ """
1162
+ Export the context graph as a Mermaid or Graphviz DOT diagram.
1163
+
1164
+ Mermaid output pastes straight into GitHub Markdown / Notion; DOT renders
1165
+ locally with graphviz. The diagram is a generated artifact of the current
1166
+ index — regenerate it after refactors rather than committing it as
1167
+ documentation.
1168
+
1169
+ Example:
1170
+ cgc diagram . > architecture.mmd
1171
+ cgc diagram . --format dot -o graph.dot && dot -Tsvg graph.dot -o graph.svg
1172
+ cgc diagram . --level call --limit 100
1173
+ """
1174
+ output_format = output_format.lower()
1175
+ if output_format not in ("mermaid", "dot"):
1176
+ console.print(f"[red]Unknown --format '{output_format}' (expected mermaid or dot)[/red]")
1177
+ raise typer.Exit(code=2)
1178
+ if level not in ("file", "call"):
1179
+ console.print(f"[red]Unknown --level '{level}' (expected file or call)[/red]")
1180
+ raise typer.Exit(code=2)
1181
+ if output is None:
1182
+ # stdout carries only the diagram; init chatter goes to stderr.
1183
+ import sys as _sys
1184
+ from . import cli_helpers as _cli_helpers
1185
+ _cli_helpers.console.file = _sys.stderr
1186
+
1187
+ _load_credentials()
1188
+ services = _initialize_services(context)
1189
+ if not all(services[:3]):
1190
+ raise typer.Exit(code=1)
1191
+ db_manager, graph_builder, code_finder = services[:3]
1192
+
1193
+ try:
1194
+ repo_path = Path(path).resolve().as_posix() if path else None
1195
+ result = code_finder.export_diagram_edges(level=level, repo_path=repo_path, limit=limit)
1196
+ finally:
1197
+ db_manager.close_driver()
1198
+
1199
+ edges = result["edges"]
1200
+ ids: dict = {}
1201
+
1202
+ def _node_id(name: str) -> str:
1203
+ if name not in ids:
1204
+ ids[name] = f"n{len(ids)}"
1205
+ return ids[name]
1206
+
1207
+ lines = []
1208
+ if output_format == "mermaid":
1209
+ lines.append("graph LR")
1210
+ if result["truncated"]:
1211
+ lines.append(f" %% truncated: showing {len(edges)} of {result['total_count']} edges (raise --limit)")
1212
+ for src, dst in edges:
1213
+ sid, did = _node_id(src), _node_id(dst)
1214
+ s_label = src.replace('"', "'")
1215
+ d_label = dst.replace('"', "'")
1216
+ lines.append(f' {sid}["{s_label}"] --> {did}["{d_label}"]')
1217
+ if not edges:
1218
+ lines.append(" %% no edges found for this scope")
1219
+ else:
1220
+ lines.append("digraph cgc {")
1221
+ lines.append(" rankdir=LR;")
1222
+ if result["truncated"]:
1223
+ lines.append(f" // truncated: showing {len(edges)} of {result['total_count']} edges (raise --limit)")
1224
+ for src, dst in edges:
1225
+ sid, did = _node_id(src), _node_id(dst)
1226
+ lines.append(f' {sid} -> {did};')
1227
+ for name, nid in ids.items():
1228
+ label = name.replace('"', "'")
1229
+ lines.append(f' {nid} [label="{label}"];')
1230
+ lines.append("}")
1231
+
1232
+ text = "\n".join(lines) + "\n"
1233
+ if output:
1234
+ Path(output).write_text(text, encoding="utf-8")
1235
+ console.print(f"[green]✅ Wrote {output_format} diagram ({len(edges)} edges) to {output}[/green]")
1236
+ if result["truncated"]:
1237
+ console.print(f"[yellow]⚠ Truncated: {result['total_count']} total edges; raise --limit to include all[/yellow]")
1238
+ else:
1239
+ print(text, end="")
1240
+
1241
+
1152
1242
  @app.command("load", rich_help_panel="Bundle Shortcuts")
1153
1243
  def load_shortcut(
1154
1244
  bundle_name: str = typer.Argument(..., help="Bundle name or path to load"),
@@ -2905,9 +2995,11 @@ def analyze_inheritance_tree(
2905
2995
  def analyze_complexity(
2906
2996
  path: Optional[str] = typer.Argument(None, help="Function name or file path to analyze"),
2907
2997
  threshold: Optional[int] = typer.Option(None, "--threshold", "-t", help="Complexity threshold for warnings (default: from config or 10)"),
2908
- limit: int = typer.Option(20, "--limit", "-l", help="Maximum results to show"),
2998
+ limit: Optional[int] = typer.Option(None, "--limit", "-l", help="Maximum results to show (default 20 for text; unlimited for json/csv)"),
2909
2999
  file: Optional[str] = typer.Option(None, "--file", "-f", help="Specific file path to scope analysis"),
2910
3000
  context: Optional[str] = typer.Option(None, "--context", "-c", help="Specific context to use"),
3001
+ output_format: str = typer.Option("text", "--format", help="Output format: text, json or csv (#1333)"),
3002
+ fail_on_violations: bool = typer.Option(False, "--fail-on-violations", help="Exit with code 1 when any function exceeds the threshold (CI gate)"),
2911
3003
  ):
2912
3004
  """
2913
3005
  Show cyclomatic complexity for functions.
@@ -2920,7 +3012,19 @@ def analyze_complexity(
2920
3012
  cgc analyze complexity src/main.py # Most complex functions in file
2921
3013
  cgc analyze complexity main.py # Most complex functions in file
2922
3014
  cgc analyze complexity --file src/main.py # Alternative file syntax
2923
- """
3015
+ cgc analyze complexity -t 10 --format json --fail-on-violations # CI gate
3016
+ """
3017
+ output_format = output_format.lower()
3018
+ if output_format not in ("text", "json", "csv"):
3019
+ console.print(f"[red]Unknown --format '{output_format}' (expected text, json or csv)[/red]")
3020
+ raise typer.Exit(code=2)
3021
+ if output_format in ("json", "csv"):
3022
+ # stdout must carry ONLY the parseable document: the service-init
3023
+ # chatter from cli_helpers prints to stdout, so reroute that console
3024
+ # to stderr before initializing anything (`--format json | jq .`).
3025
+ import sys as _sys
3026
+ from . import cli_helpers as _cli_helpers
3027
+ _cli_helpers.console.file = _sys.stderr
2924
3028
  _load_credentials()
2925
3029
  services = _initialize_services(context)
2926
3030
  if not all(services[:3]):
@@ -2938,6 +3042,47 @@ def analyze_complexity(
2938
3042
  else:
2939
3043
  threshold = 10
2940
3044
 
3045
+ machine_output = output_format in ("json", "csv")
3046
+ # Enforcement and export need the full set: a display page must never
3047
+ # truncate the violation count a CI gate acts on (#1333).
3048
+ effective_limit = limit if limit is not None else (None if (machine_output or fail_on_violations) else 20)
3049
+
3050
+ def _violations_from(results):
3051
+ rows = []
3052
+ for func in results or []:
3053
+ # The synthetic `<module>` frame is the attribution target for
3054
+ # module-level calls, not a function anyone can refactor.
3055
+ if func.get("function_name") == "<module>":
3056
+ continue
3057
+ complexity = func.get("complexity", 0) or 0
3058
+ if complexity > threshold:
3059
+ rows.append({
3060
+ "function": func.get("function_name", ""),
3061
+ "file": func.get("path", ""),
3062
+ "line": func.get("line_number"),
3063
+ "complexity": complexity,
3064
+ "exceeds_by": complexity - threshold,
3065
+ })
3066
+ return rows
3067
+
3068
+ def _emit_machine(violations):
3069
+ import csv as _csv
3070
+ import io as _io
3071
+ import json as _json
3072
+ if output_format == "json":
3073
+ print(_json.dumps({
3074
+ "threshold": threshold,
3075
+ "violations_count": len(violations),
3076
+ "violations": violations,
3077
+ }, indent=2))
3078
+ else:
3079
+ buf = _io.StringIO()
3080
+ w = _csv.writer(buf)
3081
+ w.writerow(["function", "file", "line", "complexity", "exceeds_by"])
3082
+ for v in violations:
3083
+ w.writerow([v["function"], v["file"], v["line"], v["complexity"], v["exceeds_by"]])
3084
+ print(buf.getvalue(), end="")
3085
+
2941
3086
  _FILE_EXTENSIONS = ('.py', '.js', '.ts', '.jsx', '.tsx', '.go', '.rs', '.rb',
2942
3087
  '.java', '.cpp', '.c', '.cs', '.swift', '.kt', '.scala',
2943
3088
  '.php', '.lua', '.zig', '.ex', '.exs', '.r', '.m', '.sh')
@@ -2970,15 +3115,31 @@ def analyze_complexity(
2970
3115
  console.print(table)
2971
3116
  console.print(f"\n[dim]{len([f for f in results if f.get('complexity', 0) > threshold])} function(s) exceed threshold[/dim]")
2972
3117
 
3118
+ violations = None
2973
3119
  try:
2974
3120
  if path and _is_file_path(path):
2975
3121
  # File path provided as positional argument
2976
- results = code_finder.find_most_complex_functions_in_file(path, limit)
2977
- _render_complexity_table(results, f"Most Complex Functions in '{path}' (threshold: {threshold}):")
3122
+ results = code_finder.find_most_complex_functions_in_file(path, effective_limit)
3123
+ violations = _violations_from(results)
3124
+ if machine_output:
3125
+ _emit_machine(violations)
3126
+ else:
3127
+ _render_complexity_table(results, f"Most Complex Functions in '{path}' (threshold: {threshold}):")
2978
3128
  elif path:
2979
3129
  # Specific function name
2980
3130
  result = code_finder.get_cyclomatic_complexity(path, file)
3131
+ single = []
2981
3132
  if result:
3133
+ single = [{
3134
+ "function_name": path,
3135
+ "path": result.get("path", ""),
3136
+ "line_number": result.get("line_number"),
3137
+ "complexity": result.get("complexity", 0) or 0,
3138
+ }]
3139
+ violations = _violations_from(single)
3140
+ if machine_output:
3141
+ _emit_machine(violations)
3142
+ elif result:
2982
3143
  console.print(f"\n[bold cyan]Complexity for '{path}':[/bold cyan]")
2983
3144
  console.print(f" Cyclomatic Complexity: [yellow]{result.get('complexity', 'N/A')}[/yellow]")
2984
3145
  console.print(f" File: [dim]{result.get('path', '')}[/dim]")
@@ -2987,20 +3148,36 @@ def analyze_complexity(
2987
3148
  console.print(f"[yellow]Function '{path}' not found or has no complexity data[/yellow]")
2988
3149
  elif file:
2989
3150
  # --file option without positional arg
2990
- results = code_finder.find_most_complex_functions_in_file(file, limit)
2991
- _render_complexity_table(results, f"Most Complex Functions in '{file}' (threshold: {threshold}):")
3151
+ results = code_finder.find_most_complex_functions_in_file(file, effective_limit)
3152
+ violations = _violations_from(results)
3153
+ if machine_output:
3154
+ _emit_machine(violations)
3155
+ else:
3156
+ _render_complexity_table(results, f"Most Complex Functions in '{file}' (threshold: {threshold}):")
2992
3157
  else:
2993
3158
  # Global - most complex functions
2994
- results = code_finder.find_most_complex_functions(limit)
2995
- _render_complexity_table(results, f"Most Complex Functions (threshold: {threshold}):")
3159
+ results = code_finder.find_most_complex_functions(effective_limit)
3160
+ violations = _violations_from(results)
3161
+ if machine_output:
3162
+ _emit_machine(violations)
3163
+ else:
3164
+ _render_complexity_table(results, f"Most Complex Functions (threshold: {threshold}):")
2996
3165
  finally:
2997
3166
  db_manager.close_driver()
2998
3167
 
3168
+ # CI gate (#1333): explicit opt-in keeps exploratory usage exit-0 —
3169
+ # the config default threshold means most codebases have *some*
3170
+ # function above it, and failing every casual invocation would break
3171
+ # innocent `cgc analyze complexity && …` chains.
3172
+ if fail_on_violations and violations:
3173
+ raise typer.Exit(code=1)
3174
+
2999
3175
  @analyze_app.command("dead-code")
3000
3176
  def analyze_dead_code(
3001
3177
  path: Optional[str] = typer.Argument(None, help="Repository path to scope the analysis to"),
3002
3178
  exclude_decorators: Optional[str] = typer.Option(None, "--exclude", "-e", help="Comma-separated decorators to exclude"),
3003
3179
  context: Optional[str] = typer.Option(None, "--context", "-c", help="Specific context to use"),
3180
+ show_all: bool = typer.Option(False, "--show-all", help="Include low-confidence rows (dunders, test hooks, entry-point names) normally hidden (#1332)"),
3004
3181
  ):
3005
3182
  """
3006
3183
  Find potentially unused functions.
@@ -3030,7 +3207,8 @@ def analyze_dead_code(
3030
3207
  # of table rows. The true count comes from total_count below (#1606).
3031
3208
  display_limit = get_tool_result_limit("find_dead_code")
3032
3209
  results = code_finder.find_dead_code(
3033
- exclude_list, repo_path=repo_path, limit=display_limit
3210
+ exclude_list, repo_path=repo_path, limit=display_limit,
3211
+ include_low_confidence=show_all,
3034
3212
  )
3035
3213
 
3036
3214
  unused_funcs = results.get('potentially_unused_functions', [])
@@ -3042,16 +3220,22 @@ def analyze_dead_code(
3042
3220
 
3043
3221
  table = Table(show_header=True, header_style="bold magenta", box=box.ROUNDED)
3044
3222
  table.add_column("Function", style="cyan")
3223
+ table.add_column("Confidence", justify="center")
3045
3224
  table.add_column("Location", style="dim", overflow="fold")
3046
-
3225
+
3226
+ _conf_render = {
3227
+ "high": "[red]● high[/red]",
3228
+ "medium": "[yellow]● medium[/yellow]",
3229
+ "low": "[dim]● low[/dim]",
3230
+ }
3047
3231
  for func in unused_funcs:
3048
- path = func.get('path', '')
3232
+ fpath = func.get('path', '')
3049
3233
  line_str = str(func.get('line_number', ''))
3050
- location_str = f"{path}:{line_str}" if line_str else path
3051
-
3234
+ location_str = f"{fpath}:{line_str}" if line_str else fpath
3052
3235
  table.add_row(
3053
3236
  func.get('function_name', ''),
3054
- location_str
3237
+ _conf_render.get(func.get('confidence', 'high'), func.get('confidence', '')),
3238
+ location_str,
3055
3239
  )
3056
3240
 
3057
3241
  console.print("\n[bold yellow]⚠️ Potentially Unused Functions:[/bold yellow]")
@@ -3063,6 +3247,16 @@ def analyze_dead_code(
3063
3247
  )
3064
3248
  else:
3065
3249
  console.print(f"\n[dim]Total: {total_count} function(s)[/dim]")
3250
+ counts = results.get('confidence_counts') or {}
3251
+ if counts:
3252
+ summary = (
3253
+ f"[red]{counts.get('high', 0)} high[/red], "
3254
+ f"[yellow]{counts.get('medium', 0)} medium[/yellow], "
3255
+ f"[dim]{counts.get('low', 0)} low[/dim] confidence"
3256
+ )
3257
+ if not show_all:
3258
+ summary += " [dim](low-confidence categories are hidden — use --show-all)[/dim]"
3259
+ console.print(summary)
3066
3260
  console.print(f"[dim]Note: {results.get('note', '')}[/dim]")
3067
3261
  finally:
3068
3262
  db_manager.close_driver()
@@ -798,21 +798,32 @@ class EmbeddedSessionWrapper:
798
798
  translated_query, translated_params = self._translate_query(query, parameters)
799
799
  debug_log(f"Translated Query: {translated_query[:200]}")
800
800
  try:
801
- # Force loop fallback for relationship writes inside UNWIND to avoid Kuzu query planner bugs
802
- # which can incorrectly bind/corrupt relationship endpoints across rows in the batch.
803
- # Only force it for `UNWIND $param AS row`, the single shape the
804
- # recovery path below can rewrite into a per-row loop. Read queries
805
- # that unwind a bound list (`WITH relationships(p) AS rels UNWIND
806
- # rels AS r`, used by find_all_callers/find_all_callees and the
807
- # visualizer) matched this guard too, but no `$`-UNWIND for the
808
- # fallback to latch onto so the fabricated exception fell through
809
- # every handler and surfaced to the caller as a hard failure.
801
+ # Force the per-row loop fallback ONLY for UNWIND batches containing a
802
+ # node-MERGE. Kùzu's MERGE pipeline mis-binds when a merged node's key
803
+ # value repeats NON-adjacently across the batch: in
804
+ # [(A,P), (B,X), (C,P)] the C row binds to X's node instead of
805
+ # re-matching P (reproduced on Kùzu 0.11.3; see #1605). Relationship-only
806
+ # MERGEs (MATCH … MATCH … MERGE (a)-[r]->(b)) do not exhibit the bug —
807
+ # verified with interleaved duplicate endpoint keys and duplicate pairs
808
+ # so they now run batched, which removes the bulk of the per-row planner
809
+ # overhead (~2.4x on a full index of the Python sample project).
810
+ # Only `UNWIND $param AS row` shapes are guarded — that is the single
811
+ # shape the recovery path below can rewrite into a per-row loop. Read
812
+ # queries that unwind a bound list (`WITH relationships(p) AS rels
813
+ # UNWIND rels AS r`) must not match, or the fabricated exception would
814
+ # surface to the caller as a hard failure.
815
+ # Node-only UNWIND writes (`MERGE (n:Label {…}) SET n += row`, no
816
+ # relationship pattern) have always batched through the SET-expansion
817
+ # path and the per-row rewriter cannot handle their bare `SET n += row`,
818
+ # so the guard additionally requires a relationship pattern.
819
+ _has_node_merge = re.search(r"MERGE\s*\(\s*\w+\s*:", query)
810
820
  if (
811
821
  re.search(r"UNWIND\s+\$\w+\s+AS\s+\w+", query)
812
822
  and ("-[" in query or "]->" in query)
823
+ and _has_node_merge
813
824
  and not getattr(self, "_skip_unwind_fallback", False)
814
825
  ):
815
- raise Exception("unordered_map::at (forced fallback to avoid relationship UNWIND planner bugs)")
826
+ raise Exception("unordered_map::at (forced fallback: node-MERGE inside UNWIND mis-binds repeated keys)")
816
827
 
817
828
  # 2. Execute under the lock. _write_lock (name kept for backward
818
829
  # compat) now serializes ALL access, reads included: kuzu.Connection
@@ -324,14 +324,26 @@ class RepositoryEventHandler(FileSystemEventHandler):
324
324
  _inherit_enabled = False
325
325
 
326
326
  if _vector_enabled:
327
- try:
328
- from codegraphcontext.tools.indexing.embeddings import EmbeddingPipeline
329
- embed_pipeline = EmbeddingPipeline(self.graph_builder.driver)
330
- embed_pipeline.invalidate_for_file(changed_path_str)
331
- embed_pipeline.run(str(self.repo_path))
332
- info_logger(f"[EMBED] Incremental embedding complete for {changed_path_str}")
333
- except Exception as _e:
334
- warning_logger(f"[EMBED] Incremental embedding failed: {_e}")
327
+ # Probe once per handler: with no backend installed, the old code
328
+ # re-attempted (and re-failed) the import on every file event and
329
+ # only said so at a suppressed log level (#1597).
330
+ if not hasattr(self, "_embed_backend_ok"):
331
+ from codegraphcontext.tools.indexing.embeddings import probe_embedding_backend
332
+ self._embed_backend_ok, _detail = probe_embedding_backend()
333
+ if not self._embed_backend_ok:
334
+ error_logger(
335
+ f"[EMBED] ENABLE_VECTOR_RESOLVE=true but incremental embeddings "
336
+ f"cannot run: {_detail} (reported once; further file events skip this)"
337
+ )
338
+ if self._embed_backend_ok:
339
+ try:
340
+ from codegraphcontext.tools.indexing.embeddings import EmbeddingPipeline
341
+ embed_pipeline = EmbeddingPipeline(self.graph_builder.driver)
342
+ embed_pipeline.invalidate_for_file(changed_path_str)
343
+ embed_pipeline.run(str(self.repo_path))
344
+ info_logger(f"[EMBED] Incremental embedding complete for {changed_path_str}")
345
+ except Exception as _e:
346
+ warning_logger(f"[EMBED] Incremental embedding failed: {_e}")
335
347
 
336
348
  if _inherit_enabled:
337
349
  try: