codegraphcontext 0.4.6__tar.gz → 0.4.7__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 (161) hide show
  1. {codegraphcontext-0.4.6/src/codegraphcontext.egg-info → codegraphcontext-0.4.7}/PKG-INFO +3 -3
  2. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/README.md +1 -1
  3. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/pyproject.toml +2 -2
  4. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/cli/cli_helpers.py +38 -6
  5. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/cli/config_manager.py +39 -0
  6. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/cli/main.py +308 -37
  7. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/cli/setup_wizard.py +104 -4
  8. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/database.py +117 -44
  9. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/database_kuzu.py +299 -26
  10. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/watcher.py +42 -0
  11. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/server.py +30 -0
  12. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tool_definitions.py +59 -0
  13. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/code_finder.py +2 -2
  14. codegraphcontext-0.4.7/src/codegraphcontext/tools/datasources/__init__.py +1 -0
  15. codegraphcontext-0.4.7/src/codegraphcontext/tools/datasources/cassandra_ingester.py +99 -0
  16. codegraphcontext-0.4.7/src/codegraphcontext/tools/datasources/mysql_ingester.py +120 -0
  17. codegraphcontext-0.4.7/src/codegraphcontext/tools/datasources/redis_ingester.py +122 -0
  18. codegraphcontext-0.4.7/src/codegraphcontext/tools/graph_builder.py +1055 -0
  19. codegraphcontext-0.4.7/src/codegraphcontext/tools/handlers/analysis_handlers.py +324 -0
  20. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/handlers/indexing_handlers.py +46 -1
  21. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/handlers/query_handlers.py +11 -2
  22. codegraphcontext-0.4.7/src/codegraphcontext/tools/indexing/embeddings.py +266 -0
  23. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/persistence/writer.py +507 -25
  24. codegraphcontext-0.4.7/src/codegraphcontext/tools/indexing/pipeline.py +192 -0
  25. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/resolution/calls.py +95 -35
  26. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/resolution/inheritance.py +1 -0
  27. codegraphcontext-0.4.7/src/codegraphcontext/tools/indexing/resolution/post_resolution.py +205 -0
  28. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/schema_contract.py +24 -0
  29. codegraphcontext-0.4.7/src/codegraphcontext/tools/indexing/vector_resolver.py +137 -0
  30. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/csharp.py +5 -0
  31. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/go.py +6 -5
  32. codegraphcontext-0.4.7/src/codegraphcontext/tools/languages/gradle.py +115 -0
  33. codegraphcontext-0.4.7/src/codegraphcontext/tools/languages/java.py +994 -0
  34. codegraphcontext-0.4.7/src/codegraphcontext/tools/languages/maven.py +165 -0
  35. codegraphcontext-0.4.7/src/codegraphcontext/tools/languages/mybatis.py +185 -0
  36. codegraphcontext-0.4.7/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +252 -0
  37. codegraphcontext-0.4.7/src/codegraphcontext/tools/report_generator.py +368 -0
  38. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/scip_indexer.py +158 -28
  39. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/system.py +6 -2
  40. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/server.py +37 -3
  41. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7/src/codegraphcontext.egg-info}/PKG-INFO +3 -3
  42. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext.egg-info/SOURCES.txt +11 -0
  43. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext.egg-info/requires.txt +1 -1
  44. codegraphcontext-0.4.6/src/codegraphcontext/tools/graph_builder.py +0 -350
  45. codegraphcontext-0.4.6/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -151
  46. codegraphcontext-0.4.6/src/codegraphcontext/tools/indexing/pipeline.py +0 -89
  47. codegraphcontext-0.4.6/src/codegraphcontext/tools/languages/java.py +0 -500
  48. codegraphcontext-0.4.6/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -5
  49. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/LICENSE +0 -0
  50. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/MANIFEST.in +0 -0
  51. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/setup.cfg +0 -0
  52. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/__init__.py +0 -0
  53. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/__main__.py +0 -0
  54. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/cli/__init__.py +0 -0
  55. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/cli/registry_commands.py +0 -0
  56. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/cli/setup_macos.py +0 -0
  57. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/cli/visualizer.py +0 -0
  58. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/__init__.py +0 -0
  59. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/bundle_registry.py +0 -0
  60. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/cgc_bundle.py +0 -0
  61. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/cgcignore.py +0 -0
  62. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/database_falkordb.py +0 -0
  63. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/database_falkordb_remote.py +0 -0
  64. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/database_nornic.py +0 -0
  65. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/falkor_worker.py +0 -0
  66. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/core/jobs.py +0 -0
  67. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/prompts.py +0 -0
  68. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/__init__.py +0 -0
  69. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
  70. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/handlers/management_handlers.py +0 -0
  71. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/handlers/watcher_handlers.py +0 -0
  72. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/__init__.py +0 -0
  73. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/constants.py +0 -0
  74. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/discovery.py +0 -0
  75. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/persistence/__init__.py +0 -0
  76. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/pre_scan.py +0 -0
  77. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/resolution/__init__.py +0 -0
  78. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/sanitize.py +0 -0
  79. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/schema.py +0 -0
  80. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/indexing/scip_pipeline.py +0 -0
  81. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/c.py +0 -0
  82. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/cpp.py +0 -0
  83. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/css.py +0 -0
  84. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/dart.py +0 -0
  85. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/elixir.py +0 -0
  86. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/haskell.py +0 -0
  87. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/html.py +0 -0
  88. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/javascript.py +0 -0
  89. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
  90. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/lua.py +0 -0
  91. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/perl.py +0 -0
  92. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/php.py +0 -0
  93. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/python.py +0 -0
  94. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/ruby.py +0 -0
  95. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/rust.py +0 -0
  96. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/scala.py +0 -0
  97. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/swift.py +0 -0
  98. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/typescript.py +0 -0
  99. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
  100. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/package_resolver.py +0 -0
  101. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
  102. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
  103. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
  104. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
  105. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
  106. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
  107. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
  108. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
  109. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
  110. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
  111. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
  112. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
  113. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
  114. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
  115. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/scip_pb2.py +0 -0
  116. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/tools/tree_sitter_parser.py +0 -0
  117. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/utils/debug_log.py +0 -0
  118. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/utils/git_utils.py +0 -0
  119. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/utils/path_ignore.py +0 -0
  120. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/utils/repo_path.py +0 -0
  121. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/utils/tool_limits.py +0 -0
  122. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
  123. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/utils/visualize_graph.py +0 -0
  124. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/assets/__vite-browser-external-9wXp6ZBx.js +0 -0
  125. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/assets/function-calls-BtRHrqa2.png +0 -0
  126. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/assets/graph-total-D1fBAugo.png +0 -0
  127. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/assets/hero-graph-2voMJp2a.jpg +0 -0
  128. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/assets/hierarchy-DGADo0YT.png +0 -0
  129. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/assets/index-BJT3EMmQ.js +0 -0
  130. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/assets/index-DjDPHWki.css +0 -0
  131. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/assets/parser.worker-CZgm11E5.js +0 -0
  132. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/assets/tree-sitter-qKYAACSa.wasm +0 -0
  133. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/favicon.ico +0 -0
  134. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/index.html +0 -0
  135. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/placeholder.svg +0 -0
  136. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/preview-image.png +0 -0
  137. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/robots.txt +0 -0
  138. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-c.wasm +0 -0
  139. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-c_sharp.wasm +0 -0
  140. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-core.js +0 -0
  141. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-cpp.wasm +0 -0
  142. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-dart.wasm +0 -0
  143. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-go.wasm +0 -0
  144. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-java.wasm +0 -0
  145. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-javascript.wasm +0 -0
  146. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-kotlin.wasm +0 -0
  147. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-perl.wasm +0 -0
  148. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-php.wasm +0 -0
  149. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-python.wasm +0 -0
  150. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-ruby.wasm +0 -0
  151. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-rust.wasm +0 -0
  152. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-swift.wasm +0 -0
  153. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-tsx.wasm +0 -0
  154. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter-typescript.wasm +0 -0
  155. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/tree-sitter.wasm +0 -0
  156. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.js +0 -0
  157. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.wasm +0 -0
  158. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
  159. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
  160. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/src/codegraphcontext.egg-info/top_level.txt +0 -0
  161. {codegraphcontext-0.4.6 → codegraphcontext-0.4.7}/tests/test_issue_806_fix.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codegraphcontext
3
- Version: 0.4.6
3
+ Version: 0.4.7
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
@@ -54,7 +54,7 @@ Requires-Dist: falkordb>=0.1.0
54
54
  Requires-Dist: requests>=2.28.0
55
55
  Requires-Dist: protobuf<3.21,>=3.20
56
56
  Requires-Dist: falkordblite>=0.1.0; sys_platform != "win32" and python_version >= "3.12"
57
- Requires-Dist: real_ladybug; sys_platform == "win32" or (sys_platform != "win32" and python_version >= "3.10")
57
+ Requires-Dist: kuzu; sys_platform == "win32" or (sys_platform != "win32" and python_version >= "3.10")
58
58
  Requires-Dist: fastapi>=0.100.0
59
59
  Requires-Dist: uvicorn>=0.22.0
60
60
  Provides-Extra: parsing
@@ -166,7 +166,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
166
166
  ---
167
167
 
168
168
  ## Project Details
169
- - **Version:** 0.4.6
169
+ - **Version:** 0.4.7
170
170
  - **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
171
171
  - **License:** MIT License (See [LICENSE](LICENSE) for details)
172
172
  - **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
@@ -97,7 +97,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
97
97
  ---
98
98
 
99
99
  ## Project Details
100
- - **Version:** 0.4.6
100
+ - **Version:** 0.4.7
101
101
  - **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
102
102
  - **License:** MIT License (See [LICENSE](LICENSE) for details)
103
103
  - **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codegraphcontext"
3
- version = "0.4.6"
3
+ version = "0.4.7"
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"
@@ -33,7 +33,7 @@ dependencies = [
33
33
  "requests>=2.28.0",
34
34
  "protobuf>=3.20,<3.21",
35
35
  "falkordblite>=0.1.0; sys_platform != 'win32' and python_version >= '3.12'",
36
- "real_ladybug; sys_platform == 'win32' or (sys_platform != 'win32' and python_version >= '3.10')",
36
+ "kuzu; sys_platform == 'win32' or (sys_platform != 'win32' and python_version >= '3.10')",
37
37
  "fastapi>=0.100.0",
38
38
  "uvicorn>=0.22.0"
39
39
  ]
@@ -24,6 +24,7 @@ from ..tools.code_finder import CodeFinder
24
24
  from ..tools.graph_builder import GraphBuilder
25
25
  from ..tools.package_resolver import get_local_package_path
26
26
  from ..utils.debug_log import info_logger, warning_logger
27
+ from ..core.database import Neo4jConnectionError
27
28
  from ..utils.repo_path import any_repo_matches_path
28
29
  from .config_manager import resolve_context, ResolvedContext, register_repo_in_context, ensure_first_run_bootstrap
29
30
 
@@ -50,9 +51,14 @@ def _initialize_services(cli_context_flag: Optional[str] = None) -> tuple[Any, A
50
51
 
51
52
  console.print("[dim]Initializing services and database connection...[/dim]")
52
53
  try:
53
- # Override the database backend with the context's specific choice
54
- if ctx.database:
55
- os.environ['CGC_RUNTIME_DB_TYPE'] = ctx.database
54
+ # Respect runtime/backend overrides. Context DB is only a default when
55
+ # neither runtime override nor DEFAULT_DATABASE is already set.
56
+ if (
57
+ ctx.database
58
+ and not os.getenv("CGC_RUNTIME_DB_TYPE")
59
+ and not os.getenv("DEFAULT_DATABASE")
60
+ ):
61
+ os.environ["DEFAULT_DATABASE"] = ctx.database
56
62
 
57
63
  # Pass the exact DB path resolved from the context
58
64
  db_manager = get_database_manager(db_path=ctx.db_path)
@@ -85,9 +91,35 @@ def _initialize_services(cli_context_flag: Optional[str] = None) -> tuple[Any, A
85
91
  console.print(f"[bold red]Critical Error:[/bold red] Both FalkorDB and KùzuDB failed: {kuzu_e}")
86
92
  return None, None, None, ctx
87
93
  else:
88
- console.print(f"[bold red]Database Connection Error:[/bold red] {e}")
89
- console.print("Please ensure your database is configured correctly or run 'cgc doctor'.")
90
- return None, None, None, ctx
94
+ selected_db = (
95
+ os.environ.get("CGC_RUNTIME_DB_TYPE")
96
+ or os.environ.get("DATABASE_TYPE")
97
+ or os.environ.get("DEFAULT_DATABASE")
98
+ or ""
99
+ ).lower()
100
+
101
+ if isinstance(e, Neo4jConnectionError):
102
+ console.print(f"[bold red]{e}[/bold red]")
103
+ allow_fallback = os.environ.get("CGC_ALLOW_NEO4J_FALLBACK", "false").lower() in {"1", "true", "yes", "on"}
104
+
105
+ if selected_db == "neo4j" and allow_fallback:
106
+ console.print("[cyan]Neo4j failed and CGC_ALLOW_NEO4J_FALLBACK=true. Falling back to KuzuDB...[/cyan]")
107
+ try:
108
+ from ..core.database_kuzu import KuzuDBManager
109
+ db_manager = KuzuDBManager()
110
+ db_manager.get_driver()
111
+ console.print("[green]✓[/green] Successfully switched to KuzuDB fallback")
112
+ except Exception as kuzu_e:
113
+ console.print(f"[bold red]Critical Error:[/bold red] Neo4j failed and KuzuDB fallback failed: {kuzu_e}")
114
+ return None, None, None, ctx
115
+ else:
116
+ if selected_db == "neo4j":
117
+ console.print("[yellow]Tip:[/yellow] To continue without Neo4j, rerun with --db kuzudb")
118
+ return None, None, None, ctx
119
+ else:
120
+ console.print(f"[bold red]Database Connection Error:[/bold red] {e}")
121
+ console.print("Please ensure your database is configured correctly or run 'cgc doctor'.")
122
+ return None, None, None, ctx
91
123
 
92
124
  # The GraphBuilder requires an event loop, even for synchronous-style execution
93
125
  try:
@@ -55,6 +55,11 @@ DEFAULT_CONFIG = {
55
55
  # JSON object mapping tool names to integer result-count limits.
56
56
  # Example: {"find_code": 20, "analyze_code_relationships": 10, "find_dead_code": 30}
57
57
  "TOOL_RESULT_LIMITS": "{}",
58
+ # Post-indexing resolution phases (default off)
59
+ "ENABLE_INHERIT_RESOLVE": "false",
60
+ "ENABLE_VECTOR_RESOLVE": "false",
61
+ "CGC_EMBEDDING_MODEL": "local",
62
+ "CGC_EMBEDDING_BATCH_SIZE": "256",
58
63
  }
59
64
 
60
65
  # Configuration key descriptions
@@ -84,6 +89,37 @@ CONFIG_DESCRIPTIONS = {
84
89
  "SKIP_EXTERNAL_RESOLUTION": "Skip resolution attempts for external library method calls (recommended for enterprise large Java/Spring codebases)",
85
90
  "MAX_TOOL_RESPONSE_TOKENS": "Maximum tokens per MCP tool response (0 = unlimited). Truncates oversized payloads and appends a notice.",
86
91
  "TOOL_RESULT_LIMITS": "JSON object mapping tool names to max result counts, e.g. {\"find_code\": 20, \"analyze_code_relationships\": 10}. Missing keys use built-in defaults.",
92
+ # Post-indexing resolution phases
93
+ "ENABLE_INHERIT_RESOLVE": (
94
+ "[Phase 5] Re-resolve ambiguous same-file CALLS edges using the inheritance graph (INHERITS relationships). "
95
+ "When enabled, methods called on an interface or abstract class are re-pointed to the correct concrete "
96
+ "implementation based on the class hierarchy, reducing tier-7 fallback edges. "
97
+ "WHEN TO ENABLE: any Java/Kotlin/C# codebase that uses inheritance or interface-based DI (e.g. Spring, OSGi). "
98
+ "PREREQUISITES: run 'cgc index' first so INHERITS edges exist in the graph. No extra tools needed. "
99
+ "COST: adds ~1-5 min per 50K functions at the end of each 'cgc index' run. Safe to toggle on/off — only adds new edges, never removes existing ones."
100
+ ),
101
+ "ENABLE_VECTOR_RESOLVE": (
102
+ "[Phase 4 + Phase 5 tiebreaker] Generate semantic embeddings for all Function nodes and use vector "
103
+ "similarity as a tiebreaker when inheritance resolution alone cannot distinguish between multiple candidates. "
104
+ "Phase 4 writes a 384-dim embedding to every Function node; Phase 5 queries those embeddings during re-resolution. "
105
+ "WHEN TO ENABLE: large codebases (>10K functions) where inheritance alone leaves many ambiguous calls "
106
+ "(tier-7 fallbacks still high after ENABLE_INHERIT_RESOLVE). Also useful for cross-language repos. "
107
+ "PREREQUISITES: (1) fastembed must be installed — run 'pip install fastembed'. "
108
+ "(2) Neo4j must be the active database (vector index not supported on FalkorDB/KuzuDB). "
109
+ "(3) ENABLE_INHERIT_RESOLVE should also be true — vector is a tiebreaker for Phase 5, not a replacement. "
110
+ "COST: Phase 4 takes ~15 min per 50K functions on CPU (first run only; incremental updates are fast). "
111
+ "Embedding model (~40 MB) is downloaded automatically on first use from HuggingFace."
112
+ ),
113
+ "CGC_EMBEDDING_MODEL": (
114
+ "Embedding backend for ENABLE_VECTOR_RESOLVE. "
115
+ "'local' uses fastembed (BAAI/bge-small-en-v1.5, 384-dim, runs on CPU, no GPU or API key needed). "
116
+ "'openai' uses OpenAI text-embedding-3-small (requires OPENAI_API_KEY env var, costs money per token). "
117
+ "Default: local"
118
+ ),
119
+ "CGC_EMBEDDING_BATCH_SIZE": (
120
+ "Number of function texts to embed per batch when ENABLE_VECTOR_RESOLVE=true. "
121
+ "Larger values are faster but use more RAM. Default: 256. Reduce to 64 if you hit memory errors."
122
+ ),
87
123
  }
88
124
 
89
125
  # Valid values for each config key
@@ -101,6 +137,9 @@ CONFIG_VALIDATORS = {
101
137
  "INDEX_SOURCE": ["true", "false"],
102
138
  "SCIP_INDEXER": ["true", "false"],
103
139
  "SKIP_EXTERNAL_RESOLUTION": ["true", "false"],
140
+ "ENABLE_INHERIT_RESOLVE": ["true", "false"],
141
+ "ENABLE_VECTOR_RESOLVE": ["true", "false"],
142
+ "CGC_EMBEDDING_MODEL": ["local", "openai"],
104
143
  }
105
144
  DEFAULT_CGCIGNORE_PATTERNS = """\
106
145
  # Default .cgcignore patterns
@@ -109,7 +109,7 @@ def mcp_setup():
109
109
  Sets up CodeGraphContext integration with your IDE or CLI tool:
110
110
  - VS Code, Cursor, Windsurf
111
111
  - Claude Desktop, Gemini CLI
112
- - Cline, RooCode, Amazon Q Developer
112
+ - Cline, RooCode, Amazon Q Developer, Goose
113
113
  - OpenCode (prints stdio config + link to vendor docs)
114
114
 
115
115
  Works with FalkorDB by default (no database setup needed).
@@ -289,6 +289,10 @@ def _load_credentials():
289
289
  Loads configuration and credentials from various sources into environment variables.
290
290
  Uses per-variable precedence - each variable is loaded from the highest priority source.
291
291
  Priority order (highest to lowest):
292
+ 1. Runtime environment variables (shell/CI)
293
+ 2. Local `.env` in project directory (project-specific overrides)
294
+ 3. Global `~/.codegraphcontext/.env` (user defaults, including `cgc config set`)
295
+ 4. Local `mcp.json` env vars (project defaults)
292
296
  1. Local `mcp.json` env vars (highest - explicit MCP server config)
293
297
  2. ``<cwd>/.codegraphcontext/.env`` only (no parent-directory walk)
294
298
  3. Global `~/.codegraphcontext/.env` (lowest - user defaults)
@@ -305,19 +309,54 @@ def _load_credentials():
305
309
  # Ensure config directory exists (lazy initialization)
306
310
  ensure_config_dir()
307
311
 
308
- # Collect all config sources in reverse priority order (lowest to highest)
312
+ # Snapshot runtime environment BEFORE merging config files.
313
+ # These values must remain highest priority.
314
+ runtime_env = dict(os.environ)
315
+
316
+ # Collect all config sources in precedence order (lowest to highest)
309
317
  config_sources = []
310
318
  config_source_names = []
319
+ key_source_map = {}
320
+ key_defined_in = {}
321
+
322
+ def _append_source(source_name: str, source_values: dict):
323
+ if not source_values:
324
+ return
325
+ config_sources.append(source_values)
326
+ config_source_names.append(source_name)
327
+ for k, v in source_values.items():
328
+ if v is None:
329
+ continue
330
+ key_source_map[k] = source_name
331
+ key_defined_in.setdefault(k, []).append(source_name)
332
+
333
+ # 4. Local mcp.json (lowest priority - project defaults)
334
+ mcp_file_path = Path.cwd() / "mcp.json"
335
+ if mcp_file_path.exists():
336
+ try:
337
+ with open(mcp_file_path, "r") as f:
338
+ mcp_config = json.load(f)
339
+ server_env = mcp_config.get("mcpServers", {}).get("CodeGraphContext", {}).get("env", {})
340
+ _append_source("mcp.json", server_env)
341
+ except Exception as e:
342
+ console.print(f"[yellow]Warning: Could not load mcp.json: {e}[/yellow]")
311
343
 
312
- # 3. Global .env file (lowest priority - user defaults)
344
+ # 3. Global .env file (user defaults)
313
345
  global_env_path = Path.home() / ".codegraphcontext" / ".env"
314
346
  if global_env_path.exists():
315
347
  try:
316
- config_sources.append(dotenv_values(str(global_env_path)))
317
- config_source_names.append(str(global_env_path))
348
+ _append_source(str(global_env_path), dotenv_values(str(global_env_path)))
318
349
  except Exception as e:
319
350
  console.print(f"[yellow]Warning: Could not load global .env: {e}[/yellow]")
320
351
 
352
+ # 2. Local project .env (project-specific overrides)
353
+ try:
354
+ dotenv_path = find_dotenv(usecwd=True, raise_error_if_not_found=False)
355
+ if dotenv_path:
356
+ _append_source(str(dotenv_path), dotenv_values(dotenv_path))
357
+ except Exception as e:
358
+ console.print(f"[yellow]Warning: Could not load .env from current directory: {e}[/yellow]")
359
+
321
360
  # 2. <cwd>/.codegraphcontext/.env only (overrides global when distinct)
322
361
  try:
323
362
  local_cgc_env = codegraphcontext_dotenv_at_cwd(Path.cwd())
@@ -329,24 +368,12 @@ def _load_credentials():
329
368
  f"[yellow]Warning: Could not load .codegraphcontext/.env at cwd: {e}[/yellow]"
330
369
  )
331
370
 
332
- # 1. Local mcp.json (highest priority - explicit MCP server config)
333
- mcp_file_path = Path.cwd() / "mcp.json"
334
- if mcp_file_path.exists():
335
- try:
336
- with open(mcp_file_path, "r") as f:
337
- mcp_config = json.load(f)
338
- server_env = mcp_config.get("mcpServers", {}).get("CodeGraphContext", {}).get("env", {})
339
- if server_env:
340
- config_sources.append(server_env)
341
- config_source_names.append("mcp.json")
342
- except Exception as e:
343
- console.print(f"[yellow]Warning: Could not load mcp.json: {e}[/yellow]")
344
-
345
371
  # Merge all configs with proper precedence (later sources override earlier ones)
346
372
  merged_config = {}
347
373
  for config in config_sources:
348
374
  merged_config.update(config)
349
375
 
376
+ # Apply merged config to environment, but never override runtime env.
350
377
  # Apply merged config to environment.
351
378
  # IMPORTANT: DB-selection keys set in the shell must win over .env defaults.
352
379
  # E.g. `DEFAULT_DATABASE=falkordb cgc index …` must not be overridden by
@@ -354,8 +381,7 @@ def _load_credentials():
354
381
  DB_OVERRIDE_KEYS = {"CGC_RUNTIME_DB_TYPE", "DEFAULT_DATABASE"}
355
382
  for key, value in merged_config.items():
356
383
  if value is not None: # Only set non-None values
357
- # Never let .env clobber a DB-type key that the user already set in the shell
358
- if key in DB_OVERRIDE_KEYS and key in os.environ:
384
+ if key in runtime_env:
359
385
  continue
360
386
  os.environ[key] = str(value)
361
387
 
@@ -364,15 +390,43 @@ def _load_credentials():
364
390
  if len(config_source_names) == 1:
365
391
  console.print(f"[dim]Loaded configuration from: {config_source_names[-1]}[/dim]")
366
392
  else:
367
- console.print(f"[dim]Loaded configuration from: {', '.join(config_source_names)} (highest priority: {config_source_names[-1]})[/dim]")
393
+ console.print(f"[dim]Loaded configuration from: {', '.join(config_source_names)}[/dim]")
368
394
  else:
369
395
  console.print("[yellow]No configuration file found. Using defaults.[/yellow]")
396
+
397
+ default_db_sources = list(key_defined_in.get("DEFAULT_DATABASE", []))
398
+ if "DEFAULT_DATABASE" in runtime_env:
399
+ default_db_sources.append("environment")
400
+
401
+ if len(default_db_sources) > 1:
402
+ winners = "environment" if "DEFAULT_DATABASE" in runtime_env else key_source_map.get("DEFAULT_DATABASE", "defaults")
403
+ console.print(
404
+ "[dim]DEFAULT_DATABASE defined in multiple sources: "
405
+ f"{', '.join(default_db_sources)}; using: {winners}[/dim]"
406
+ )
370
407
 
371
408
 
372
409
  # Show which database is actually being used.
373
410
  # When CGC_RUNTIME_DB_TYPE or DEFAULT_DATABASE is set, trust it. Otherwise
374
411
  # call get_database_manager() so the banner matches factory fallbacks.
375
412
  runtime_db = os.environ.get("CGC_RUNTIME_DB_TYPE")
413
+ database_type = os.environ.get("DATABASE_TYPE")
414
+ default_database = os.environ.get("DEFAULT_DATABASE")
415
+
416
+ explicit_db = runtime_db or database_type or default_database
417
+
418
+ if runtime_db:
419
+ db_source = "runtime-env (CGC_RUNTIME_DB_TYPE)"
420
+ elif "DATABASE_TYPE" in runtime_env:
421
+ db_source = "environment (DATABASE_TYPE)"
422
+ elif "DEFAULT_DATABASE" in runtime_env:
423
+ db_source = "environment (DEFAULT_DATABASE)"
424
+ elif database_type and "DATABASE_TYPE" in key_source_map:
425
+ db_source = key_source_map["DATABASE_TYPE"]
426
+ elif default_database and "DEFAULT_DATABASE" in key_source_map:
427
+ db_source = key_source_map["DEFAULT_DATABASE"]
428
+ else:
429
+ db_source = "auto-detect"
376
430
  explicit_db = runtime_db or os.environ.get("DEFAULT_DATABASE")
377
431
 
378
432
  if explicit_db:
@@ -387,6 +441,7 @@ def _load_credentials():
387
441
  # Factory failed entirely — still show a best-guess
388
442
  from codegraphcontext.core import _is_falkordb_available
389
443
  default_db = "falkordb" if _is_falkordb_available() else "kuzudb"
444
+ db_source = "auto-detect"
390
445
 
391
446
  if default_db == "neo4j":
392
447
  has_neo4j_creds = all([
@@ -397,25 +452,35 @@ def _load_credentials():
397
452
  if has_neo4j_creds:
398
453
  neo4j_db = os.environ.get("NEO4J_DATABASE")
399
454
  if neo4j_db:
400
- console.print(f"[cyan]Using database: Neo4j (database: {neo4j_db})[/cyan]")
455
+ console.print(f"[cyan]Using database: neo4j (source: {db_source}, database: {neo4j_db})[/cyan]")
401
456
  else:
402
- console.print("[cyan]Using database: Neo4j[/cyan]")
457
+ console.print(f"[cyan]Using database: neo4j (source: {db_source})[/cyan]")
403
458
  else:
404
459
  console.print("[yellow]⚠ DEFAULT_DATABASE=neo4j but credentials not found. Falling back to default.[/yellow]")
405
460
  elif default_db == "falkordb":
406
- console.print("[cyan]Using database: FalkorDB Lite[/cyan]")
461
+ console.print(f"[cyan]Using database: falkordb (source: {db_source})[/cyan]")
407
462
  elif default_db == "kuzudb":
408
- console.print("[cyan]Using database: KùzuDB[/cyan]")
463
+ console.print(f"[cyan]Using database: kuzudb (source: {db_source})[/cyan]")
409
464
  elif default_db == "falkordb-remote":
410
465
  host = os.environ.get("FALKORDB_HOST")
411
466
  if host:
412
- console.print(f"[cyan]Using database: FalkorDB Remote ({host})[/cyan]")
467
+ console.print(f"[cyan]Using database: falkordb-remote (source: {db_source}, host: {host})[/cyan]")
413
468
  else:
469
+ console.print("[yellow]⚠ DATABASE_TYPE=falkordb-remote but FALKORDB_HOST not set.[/yellow]")
470
+ elif default_db == "falkordb":
471
+ if os.environ.get("FALKORDB_HOST"):
472
+ console.print(f"[cyan]Using database: falkordb-remote (source: {db_source}, host: {os.environ.get('FALKORDB_HOST')})[/cyan]")
473
+ else:
474
+ console.print(f"[cyan]Using database: falkordb (source: {db_source})[/cyan]")
414
475
  console.print(
415
476
  "[yellow]⚠ DEFAULT_DATABASE=falkordb-remote but FALKORDB_HOST not set.[/yellow]"
416
477
  )
417
478
  else:
418
- console.print(f"[cyan]Using database: {default_db}[/cyan]")
479
+ console.print(f"[cyan]Using database: {default_db} (source: {db_source})[/cyan]")
480
+
481
+ # Persist selection metadata for downstream diagnostics and error messages.
482
+ os.environ["CGC_SELECTED_DATABASE"] = default_db
483
+ os.environ["CGC_DB_SELECTION_SOURCE"] = db_source
419
484
 
420
485
 
421
486
 
@@ -833,24 +898,45 @@ def doctor():
833
898
  console.print("\n[bold]2. Checking Database Connection...[/bold]")
834
899
  try:
835
900
  _load_credentials()
836
- default_db = config.get("DEFAULT_DATABASE", "falkordb")
837
- console.print(f" Default database: {default_db}")
901
+ default_db = os.environ.get("CGC_SELECTED_DATABASE") or config.get("DEFAULT_DATABASE", "falkordb")
902
+ db_source = os.environ.get("CGC_DB_SELECTION_SOURCE", "unknown")
903
+ console.print(f" Default database: {default_db} (source: {db_source})")
838
904
 
839
905
  if default_db == "neo4j":
840
906
  uri = os.environ.get("NEO4J_URI")
841
907
  username = os.environ.get("NEO4J_USERNAME")
842
908
  password = os.environ.get("NEO4J_PASSWORD")
843
-
844
- if uri and username and password:
845
- console.print(f" [cyan]Testing Neo4j connection to {uri}...[/cyan]")
846
- is_connected, error_msg = DatabaseManager.test_connection(uri, username, password, database=os.environ.get("NEO4J_DATABASE"))
909
+ database_name = os.environ.get("NEO4J_DATABASE")
910
+
911
+ missing = DatabaseManager.get_missing_credentials(uri, username, password)
912
+ console.print(f" [cyan]Credential check:[/cyan] {'OK' if not missing else 'Missing ' + ', '.join(missing)}")
913
+ if missing:
914
+ console.print(" [red]✗[/red] Neo4j credentials not configured")
915
+ console.print(" Run:")
916
+ console.print(" cgc config set NEO4J_URI bolt://localhost:7687")
917
+ console.print(" cgc config set NEO4J_USERNAME neo4j")
918
+ console.print(" cgc config set NEO4J_PASSWORD <your-password>")
919
+ all_checks_passed = False
920
+ else:
921
+ host, port = DatabaseManager.extract_host_port(uri)
922
+ console.print(f" [cyan]Endpoint:[/cyan] {host}:{port}")
923
+
924
+ is_reachable, reachability_msg = DatabaseManager.check_port_reachable(uri)
925
+ if is_reachable:
926
+ console.print(f" [green]✓[/green] Port {port} is reachable")
927
+ else:
928
+ console.print(f" [red]✗[/red] Port check failed: {reachability_msg}")
929
+ console.print(" Start Neo4j Desktop or run: docker run -d -p 7687:7687 -p 7474:7474 neo4j")
930
+ all_checks_passed = False
931
+
932
+ console.print(f" [cyan]Testing Neo4j authentication/query...[/cyan]")
933
+ is_connected, error_msg = DatabaseManager.test_connection(uri, username, password, database=database_name)
847
934
  if is_connected:
848
935
  console.print(f" [green]✓[/green] Neo4j connection successful")
849
936
  else:
850
- console.print(f"[red]✗[/red] Neo4j connection failed: {error_msg}")
937
+ console.print(f" [red]✗[/red] Neo4j connection failed (source: {db_source})")
938
+ console.print(f" Reason: {error_msg}")
851
939
  all_checks_passed = False
852
- else:
853
- console.print(f" [yellow]⚠[/yellow] Neo4j credentials not set. Run 'cgc neo4j setup'")
854
940
  elif default_db == "kuzudb":
855
941
  from importlib.util import find_spec
856
942
 
@@ -1093,6 +1179,46 @@ def delete(
1093
1179
 
1094
1180
  delete_helper(path, context)
1095
1181
 
1182
+
1183
+ @app.command()
1184
+ def report(
1185
+ output: Optional[str] = typer.Option(None, "--output", "-o", help="Output file path. Defaults to CGC_REPORT.md in the current directory."),
1186
+ java: bool = typer.Option(False, "--java", "-j", help="Include Spring/Maven Java sections."),
1187
+ context: Optional[str] = typer.Option(None, "--context", "-c", help="Specific context to use"),
1188
+ ):
1189
+ """
1190
+ Generate a CGC_REPORT.md with god nodes, complexity, cross-module connections, and suggested queries.
1191
+
1192
+ Use --java to also include Spring endpoint tables, bean stereotype counts,
1193
+ and Maven module dependency summaries.
1194
+
1195
+ Examples:
1196
+ cgc report
1197
+ cgc report --output /tmp/my_report.md
1198
+ cgc report --java
1199
+ """
1200
+ _load_credentials()
1201
+ output_path = Path(output) if output else Path.cwd() / "CGC_REPORT.md"
1202
+ db_manager, _, _ = _initialize_services(context)
1203
+ try:
1204
+ from codegraphcontext.tools.report_generator import generate_report
1205
+ report_text = generate_report(db_manager, output_path=output_path, include_java=java)
1206
+ console.print(f"[green]✓[/green] Report written to [bold]{output_path}[/bold]")
1207
+ # Print a short preview (first ~40 lines)
1208
+ preview_lines = report_text.splitlines()[:40]
1209
+ console.print("\n".join(preview_lines))
1210
+ if len(report_text.splitlines()) > 40:
1211
+ console.print(f"[dim]... ({len(report_text.splitlines())} lines total, see {output_path})[/dim]")
1212
+ except Exception as exc:
1213
+ console.print(f"[red]Report generation failed:[/red] {exc}")
1214
+ raise typer.Exit(code=1)
1215
+ finally:
1216
+ try:
1217
+ db_manager.close_driver()
1218
+ except Exception:
1219
+ pass
1220
+
1221
+
1096
1222
  @app.command()
1097
1223
  def visualize(
1098
1224
  repo: Optional[str] = typer.Option(None, "--repo", "-r", help="Path to the repository to visualize."),
@@ -1177,7 +1303,7 @@ def unwatch(
1177
1303
  _load_credentials()
1178
1304
  unwatch_helper(path)
1179
1305
 
1180
- @app.command()
1306
+ @app.command("watching")
1181
1307
  def watching(
1182
1308
  context: Optional[str] = typer.Option(None, "--context", "-c", help="Specific context to use"),
1183
1309
  ):
@@ -2321,6 +2447,7 @@ def main(
2321
2447
  database: Optional[str] = typer.Option(
2322
2448
  None,
2323
2449
  "--database",
2450
+ "--db",
2324
2451
  "-db",
2325
2452
  help="[Global] Temporarily override database backend (falkordb, falkordb-remote, neo4j, or kuzudb) for any command"
2326
2453
  ),
@@ -2382,5 +2509,149 @@ def main(
2382
2509
  console.print("👉 Running [green]codegraphcontext[/green] works the same as using [green]cgc[/green]")
2383
2510
 
2384
2511
 
2512
+ # ============================================================================
2513
+ # DATASOURCE COMMAND GROUP — Index external data sources (#843)
2514
+ # ============================================================================
2515
+
2516
+ datasource_app = typer.Typer(help="Index external data sources (Redis, Cassandra, Aurora MySQL) into the code graph")
2517
+ app.add_typer(datasource_app, name="datasource")
2518
+
2519
+
2520
+ @datasource_app.command("mysql")
2521
+ def datasource_mysql(
2522
+ ctx: typer.Context,
2523
+ host: str = typer.Option(..., "--host", "-H", help="MySQL host / Aurora endpoint"),
2524
+ port: int = typer.Option(3306, "--port", "-p", help="MySQL port"),
2525
+ user: str = typer.Option(..., "--user", "-u", help="MySQL username"),
2526
+ password: str = typer.Option(..., "--password", "-P", help="MySQL password", hide_input=True),
2527
+ database: str = typer.Option(..., "--database", "-d", help="Database / schema name"),
2528
+ name: Optional[str] = typer.Option(None, "--name", "-n", help="Logical datasource name (default: mysql-<database>)"),
2529
+ env: str = typer.Option("production", "--env", "-e", help="Deployment environment label"),
2530
+ context: Optional[str] = typer.Option(None, "--context", "-c", help="CGC context to use"),
2531
+ ):
2532
+ """Ingest Aurora MySQL schema (tables + columns) and write to the code graph.
2533
+
2534
+ Requires: pip install PyMySQL
2535
+ """
2536
+ try:
2537
+ from codegraphcontext.tools.datasources.mysql_ingester import ingest as mysql_ingest
2538
+ except ImportError as e:
2539
+ console.print(f"[red]Import error:[/red] {e}")
2540
+ raise typer.Exit(1)
2541
+
2542
+ if context:
2543
+ config_manager.set_config_value("CONTEXT", context)
2544
+
2545
+ console.print(f"[cyan]Connecting to Aurora MySQL at {host}:{port}/{database}...[/cyan]")
2546
+ try:
2547
+ result = mysql_ingest(host=host, port=port, user=user, password=password,
2548
+ database=database, name=name, env=env)
2549
+ except Exception as exc:
2550
+ console.print(f"[red]Failed to connect / ingest:[/red] {exc}")
2551
+ raise typer.Exit(1)
2552
+
2553
+ _write_datasource_graph(result)
2554
+ console.print(
2555
+ f"[green]✓ MySQL datasource[/green] [bold]{result['datasource']['name']}[/bold] indexed: "
2556
+ f"{len(result.get('tables', []))} tables, {len(result.get('columns', []))} columns"
2557
+ )
2558
+
2559
+
2560
+ @datasource_app.command("cassandra")
2561
+ def datasource_cassandra(
2562
+ ctx: typer.Context,
2563
+ host: str = typer.Option(..., "--host", "-H", help="Cassandra contact point (comma-separated for multiple)"),
2564
+ port: int = typer.Option(9042, "--port", "-p", help="Cassandra native transport port"),
2565
+ keyspace: str = typer.Option(..., "--keyspace", "-k", help="Keyspace to ingest"),
2566
+ username: Optional[str] = typer.Option(None, "--user", "-u", help="Cassandra username"),
2567
+ password: Optional[str] = typer.Option(None, "--password", "-P", help="Cassandra password", hide_input=True),
2568
+ name: Optional[str] = typer.Option(None, "--name", "-n", help="Logical datasource name (default: cassandra-<keyspace>)"),
2569
+ env: str = typer.Option("production", "--env", "-e", help="Deployment environment label"),
2570
+ context: Optional[str] = typer.Option(None, "--context", "-c", help="CGC context to use"),
2571
+ ):
2572
+ """Ingest Cassandra keyspace schema (tables + columns) and write to the code graph.
2573
+
2574
+ Requires: pip install cassandra-driver
2575
+ """
2576
+ try:
2577
+ from codegraphcontext.tools.datasources.cassandra_ingester import ingest as cassandra_ingest
2578
+ except ImportError as e:
2579
+ console.print(f"[red]Import error:[/red] {e}")
2580
+ raise typer.Exit(1)
2581
+
2582
+ if context:
2583
+ config_manager.set_config_value("CONTEXT", context)
2584
+
2585
+ hosts = [h.strip() for h in host.split(",")]
2586
+ console.print(f"[cyan]Connecting to Cassandra at {hosts}/{keyspace}...[/cyan]")
2587
+ try:
2588
+ result = cassandra_ingest(hosts=hosts, port=port, keyspace=keyspace,
2589
+ username=username, password=password, name=name, env=env)
2590
+ except Exception as exc:
2591
+ console.print(f"[red]Failed to connect / ingest:[/red] {exc}")
2592
+ raise typer.Exit(1)
2593
+
2594
+ _write_datasource_graph(result)
2595
+ console.print(
2596
+ f"[green]✓ Cassandra datasource[/green] [bold]{result['datasource']['name']}[/bold] indexed: "
2597
+ f"{len(result.get('tables', []))} tables, {len(result.get('columns', []))} columns"
2598
+ )
2599
+
2600
+
2601
+ @datasource_app.command("redis")
2602
+ def datasource_redis(
2603
+ ctx: typer.Context,
2604
+ host: str = typer.Option(..., "--host", "-H", help="Redis host"),
2605
+ port: int = typer.Option(6379, "--port", "-p", help="Redis port"),
2606
+ db: int = typer.Option(0, "--db", help="Redis database index"),
2607
+ password: Optional[str] = typer.Option(None, "--password", "-P", help="Redis AUTH password", hide_input=True),
2608
+ name: Optional[str] = typer.Option(None, "--name", "-n", help="Logical datasource name"),
2609
+ env: str = typer.Option("production", "--env", "-e", help="Deployment environment label"),
2610
+ max_keys: int = typer.Option(10000, "--max-keys", help="Maximum keys to scan (avoid full scan in large clusters)"),
2611
+ context: Optional[str] = typer.Option(None, "--context", "-c", help="CGC context to use"),
2612
+ ):
2613
+ """Discover Redis key patterns and write to the code graph.
2614
+
2615
+ Scans up to --max-keys keys and groups them into patterns (e.g. user:*).
2616
+
2617
+ Requires: pip install redis
2618
+ """
2619
+ try:
2620
+ from codegraphcontext.tools.datasources.redis_ingester import ingest as redis_ingest
2621
+ except ImportError as e:
2622
+ console.print(f"[red]Import error:[/red] {e}")
2623
+ raise typer.Exit(1)
2624
+
2625
+ if context:
2626
+ config_manager.set_config_value("CONTEXT", context)
2627
+
2628
+ console.print(f"[cyan]Connecting to Redis at {host}:{port}/{db}...[/cyan]")
2629
+ try:
2630
+ result = redis_ingest(host=host, port=port, db=db, password=password,
2631
+ name=name, env=env, max_keys=max_keys)
2632
+ except Exception as exc:
2633
+ console.print(f"[red]Failed to connect / ingest:[/red] {exc}")
2634
+ raise typer.Exit(1)
2635
+
2636
+ _write_datasource_graph(result)
2637
+ console.print(
2638
+ f"[green]✓ Redis datasource[/green] [bold]{result['datasource']['name']}[/bold] indexed: "
2639
+ f"{len(result.get('key_patterns', []))} key patterns"
2640
+ )
2641
+
2642
+
2643
+ def _write_datasource_graph(ingested: dict) -> None:
2644
+ """Shared helper: write ingested datasource dict to the active graph."""
2645
+ from codegraphcontext.core.database import DatabaseManager
2646
+ dm = DatabaseManager()
2647
+ driver = dm.get_driver()
2648
+ if driver is None:
2649
+ console.print("[red]No active graph connection. Run[/red] cgc context switch <name> [red]first.[/red]")
2650
+ raise typer.Exit(1)
2651
+
2652
+ from codegraphcontext.tools.indexing.persistence.writer import GraphWriter
2653
+ GraphWriter(driver).write_datasource_graph(ingested)
2654
+
2655
+
2385
2656
  if __name__ == "__main__":
2386
2657
  app()