codegraphcontext 0.6.3__tar.gz → 0.6.5__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.3/src/codegraphcontext.egg-info → codegraphcontext-0.6.5}/PKG-INFO +1 -1
  2. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/pyproject.toml +1 -1
  3. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/cli/main.py +30 -13
  4. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/persistence/writer.py +119 -39
  5. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/resolution/inheritance.py +83 -6
  6. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/c.py +45 -29
  7. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/csharp.py +47 -9
  8. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/dart.py +12 -5
  9. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/elixir.py +22 -0
  10. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/haskell.py +13 -4
  11. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/java.py +26 -2
  12. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/javascript.py +9 -1
  13. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/php.py +34 -7
  14. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/python.py +9 -1
  15. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/ruby.py +21 -8
  16. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/rust.py +94 -24
  17. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/scala.py +1 -1
  18. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/swift.py +27 -3
  19. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5/src/codegraphcontext.egg-info}/PKG-INFO +1 -1
  20. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/LICENSE +0 -0
  21. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/MANIFEST.in +0 -0
  22. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/README.md +0 -0
  23. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/setup.cfg +0 -0
  24. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/__init__.py +0 -0
  25. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/__main__.py +0 -0
  26. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/api/__init__.py +0 -0
  27. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/api/app.py +0 -0
  28. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/api/auth.py +0 -0
  29. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/api/mcp_sse.py +0 -0
  30. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/api/router.py +0 -0
  31. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/api/schemas.py +0 -0
  32. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/cli/__init__.py +0 -0
  33. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/cli/cli_helpers.py +0 -0
  34. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/cli/config_manager.py +0 -0
  35. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/cli/hook_manager.py +0 -0
  36. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/cli/project_config.py +0 -0
  37. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/cli/registry_commands.py +0 -0
  38. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/cli/setup_macos.py +0 -0
  39. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/cli/setup_wizard.py +0 -0
  40. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/cli/simulator.py +0 -0
  41. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/cli/visualizer.py +0 -0
  42. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/__init__.py +0 -0
  43. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/bundle_registry.py +0 -0
  44. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/cgc_bundle.py +0 -0
  45. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/cgcignore.py +0 -0
  46. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/database.py +0 -0
  47. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/database_embedded_kuzu.py +0 -0
  48. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/database_falkordb.py +0 -0
  49. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/database_falkordb_remote.py +0 -0
  50. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/database_kuzu.py +0 -0
  51. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/database_ladybug.py +0 -0
  52. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/database_nornic.py +0 -0
  53. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/falkor_worker.py +0 -0
  54. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/graph_query.py +0 -0
  55. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/jobs.py +0 -0
  56. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/simulator.py +0 -0
  57. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/core/watcher.py +0 -0
  58. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/prompts.py +0 -0
  59. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/server.py +0 -0
  60. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/stdlibs.py +0 -0
  61. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tool_definitions.py +0 -0
  62. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/__init__.py +0 -0
  63. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
  64. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/code_finder.py +0 -0
  65. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/datasources/__init__.py +0 -0
  66. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/datasources/cassandra_ingester.py +0 -0
  67. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/datasources/mysql_ingester.py +0 -0
  68. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/datasources/redis_ingester.py +0 -0
  69. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/graph_builder.py +0 -0
  70. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -0
  71. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/handlers/indexing_handlers.py +0 -0
  72. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/handlers/management_handlers.py +0 -0
  73. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/handlers/query_handlers.py +0 -0
  74. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/handlers/watcher_handlers.py +0 -0
  75. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/__init__.py +0 -0
  76. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/constants.py +0 -0
  77. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/discovery.py +0 -0
  78. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/embeddings.py +0 -0
  79. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/persistence/__init__.py +0 -0
  80. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/persistence/utils.py +0 -0
  81. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/pipeline.py +0 -0
  82. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/pre_scan.py +0 -0
  83. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/resolution/__init__.py +0 -0
  84. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/resolution/calls.py +0 -0
  85. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/resolution/post_resolution.py +0 -0
  86. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/sanitize.py +0 -0
  87. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/schema.py +0 -0
  88. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/schema_contract.py +0 -0
  89. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/scip_pipeline.py +0 -0
  90. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/indexing/vector_resolver.py +0 -0
  91. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/cpp.py +0 -0
  92. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/css.py +0 -0
  93. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/elisp.py +0 -0
  94. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/go.py +0 -0
  95. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/gradle.py +0 -0
  96. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/html.py +0 -0
  97. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
  98. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/lua.py +0 -0
  99. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/maven.py +0 -0
  100. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/mybatis.py +0 -0
  101. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/perl.py +0 -0
  102. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/sfc_common.py +0 -0
  103. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/solidity.py +0 -0
  104. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/solidity_remappings.py +0 -0
  105. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/svelte.py +0 -0
  106. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/typescript.py +0 -0
  107. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
  108. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/languages/vue.py +0 -0
  109. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/package_resolver.py +0 -0
  110. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
  111. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
  112. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
  113. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
  114. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/elisp_toolkit.py +0 -0
  115. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
  116. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
  117. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
  118. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
  119. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
  120. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
  121. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
  122. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
  123. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
  124. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/solidity_toolkit.py +0 -0
  125. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
  126. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
  127. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/report_generator.py +0 -0
  128. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/scip_indexer.py +0 -0
  129. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/scip_pb2.py +0 -0
  130. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/system.py +0 -0
  131. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/tree_sitter_parser.py +0 -0
  132. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/tools/type_utils.py +0 -0
  133. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/cypher_ddl.py +0 -0
  134. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/cypher_readonly.py +0 -0
  135. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/debug_log.py +0 -0
  136. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/gcf_encoder.py +0 -0
  137. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/git_utils.py +0 -0
  138. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/path_ignore.py +0 -0
  139. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/path_sandbox.py +0 -0
  140. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/repo_path.py +0 -0
  141. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/secret_scanner.py +0 -0
  142. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/tool_limits.py +0 -0
  143. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
  144. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/utils/visualize_graph.py +0 -0
  145. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/assets/__vite-browser-external-9wXp6ZBx.js +0 -0
  146. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/assets/function-calls-BtRHrqa2.png +0 -0
  147. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/assets/graph-total-D1fBAugo.png +0 -0
  148. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/assets/hero-graph-2voMJp2a.jpg +0 -0
  149. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/assets/hierarchy-DGADo0YT.png +0 -0
  150. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/assets/index-C-187lf0.js +0 -0
  151. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/assets/index-fNAa6jgv.css +0 -0
  152. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/assets/parser-pyodide.worker-BgsDfaad.js +0 -0
  153. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/assets/parser.worker-_nvrecvj.js +0 -0
  154. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/assets/tree-sitter-qKYAACSa.wasm +0 -0
  155. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/cgcIcon.png +0 -0
  156. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/favicon.ico +0 -0
  157. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/index.html +0 -0
  158. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/logo-icon.svg +0 -0
  159. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/logo.svg +0 -0
  160. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/placeholder.svg +0 -0
  161. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/preview-image.png +0 -0
  162. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/robots.txt +0 -0
  163. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-c.wasm +0 -0
  164. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-c_sharp.wasm +0 -0
  165. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-core.js +0 -0
  166. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-cpp.wasm +0 -0
  167. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-dart.wasm +0 -0
  168. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-go.wasm +0 -0
  169. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-java.wasm +0 -0
  170. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-javascript.wasm +0 -0
  171. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-kotlin.wasm +0 -0
  172. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-perl.wasm +0 -0
  173. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-php.wasm +0 -0
  174. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-python.wasm +0 -0
  175. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-ruby.wasm +0 -0
  176. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-rust.wasm +0 -0
  177. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-swift.wasm +0 -0
  178. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-tsx.wasm +0 -0
  179. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter-typescript.wasm +0 -0
  180. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/tree-sitter.wasm +0 -0
  181. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.js +0 -0
  182. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.wasm +0 -0
  183. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext/viz/server.py +0 -0
  184. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext.egg-info/SOURCES.txt +0 -0
  185. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
  186. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
  187. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext.egg-info/requires.txt +0 -0
  188. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/src/codegraphcontext.egg-info/top_level.txt +0 -0
  189. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/tests/test_issue_806_fix.py +0 -0
  190. {codegraphcontext-0.6.3 → codegraphcontext-0.6.5}/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.3
3
+ Version: 0.6.5
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.3"
3
+ version = "0.6.5"
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"
@@ -1178,14 +1178,22 @@ def diagram(
1178
1178
  if level not in ("file", "call"):
1179
1179
  console.print(f"[red]Unknown --level '{level}' (expected file or call)[/red]")
1180
1180
  raise typer.Exit(code=2)
1181
+ # stdout carries only the diagram; init chatter goes to stderr for the
1182
+ # init window only (restored after — a permanent rebind leaks a closed
1183
+ # stream into later in-process invocations).
1184
+ import sys as _sys
1185
+ from . import cli_helpers as _cli_helpers
1186
+ # NB: the .file property GETTER materializes the current (possibly
1187
+ # transient, CliRunner-captured) stream; the dynamic state lives in
1188
+ # ._file, which is None while the console follows sys.stdout live.
1189
+ _prev_console_file = _cli_helpers.console._file
1181
1190
  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
1191
  _cli_helpers.console.file = _sys.stderr
1186
-
1187
- _load_credentials()
1188
- services = _initialize_services(context)
1192
+ try:
1193
+ _load_credentials()
1194
+ services = _initialize_services(context)
1195
+ finally:
1196
+ _cli_helpers.console._file = _prev_console_file
1189
1197
  if not all(services[:3]):
1190
1198
  raise typer.Exit(code=1)
1191
1199
  db_manager, graph_builder, code_finder = services[:3]
@@ -3018,15 +3026,24 @@ def analyze_complexity(
3018
3026
  if output_format not in ("text", "json", "csv"):
3019
3027
  console.print(f"[red]Unknown --format '{output_format}' (expected text, json or csv)[/red]")
3020
3028
  raise typer.Exit(code=2)
3029
+ # stdout must carry ONLY the parseable document in machine formats: the
3030
+ # service-init chatter from cli_helpers prints to stdout, so reroute that
3031
+ # console to stderr FOR THE INIT WINDOW ONLY (`--format json | jq .`).
3032
+ # The rebind must be restored — a permanent one leaks a closed stream into
3033
+ # later in-process invocations (CliRunner-based tests).
3034
+ import sys as _sys
3035
+ from . import cli_helpers as _cli_helpers
3036
+ # NB: the .file property GETTER materializes the current (possibly
3037
+ # transient, CliRunner-captured) stream; the dynamic state lives in
3038
+ # ._file, which is None while the console follows sys.stdout live.
3039
+ _prev_console_file = _cli_helpers.console._file
3021
3040
  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
3041
  _cli_helpers.console.file = _sys.stderr
3028
- _load_credentials()
3029
- services = _initialize_services(context)
3042
+ try:
3043
+ _load_credentials()
3044
+ services = _initialize_services(context)
3045
+ finally:
3046
+ _cli_helpers.console._file = _prev_console_file
3030
3047
  if not all(services[:3]):
3031
3048
  raise typer.Exit(code=1)
3032
3049
  db_manager, graph_builder, code_finder = services[:3]
@@ -68,6 +68,29 @@ _NAME_ONLY_MERGE_LABELS = {"Module", "DbTable", "ExternalClass"}
68
68
  # repeated mentions, and merging them is exactly the pre-#1393 behaviour.
69
69
  _COALESCE_SAME_KEY_LABELS = {"Variable"}
70
70
 
71
+ # Node types that mean "the enclosing declaration is a FUNCTION" across the
72
+ # tree-sitter grammars. The nested-function CONTAINS batch used to gate on the
73
+ # literal Python type 'function_definition', which only python.py emits — every
74
+ # other language that populated context_type (TS, and now JS) silently lost its
75
+ # nested-function containment edges (#1538).
76
+ _FUNCTION_CONTEXT_TYPES = {
77
+ "function_definition", # python, cpp, php
78
+ "function_declaration", # js/ts, go, kotlin, lua
79
+ "function_expression", # js/ts
80
+ "arrow_function", # js/ts
81
+ "generator_function", # js/ts
82
+ "generator_function_declaration", # js/ts
83
+ "method_definition", # js/ts
84
+ "method_declaration", # java, csharp, go
85
+ "constructor_declaration", # java
86
+ "local_function_statement", # csharp
87
+ "func_literal", # go
88
+ "function_item", # rust
89
+ "method", # ruby
90
+ "singleton_method", # ruby
91
+ "lambda_expression", # cpp, java
92
+ }
93
+
71
94
 
72
95
  def _coalesce_same_key_items(items: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
73
96
  """Fold records sharing (name, line_number) into one, in write order."""
@@ -467,7 +490,7 @@ class GraphWriter:
467
490
  "func_line": item["line_number"],
468
491
  }
469
492
  )
470
- if item.get("context_type") == "function_definition":
493
+ if item.get("context_type") in _FUNCTION_CONTEXT_TYPES:
471
494
  outer_ctx = item.get("context")
472
495
  is_seq = isinstance(outer_ctx, (tuple, list)) and outer_ctx
473
496
  outer_name = outer_ctx[0] if is_seq else outer_ctx
@@ -1137,6 +1160,8 @@ class GraphWriter:
1137
1160
  )
1138
1161
  batch_size = 500
1139
1162
  backend = get_backend_type(self.driver, self._db_manager)
1163
+ labels = ("Class", "Trait", "Interface", "Struct", "Enum", "Union", "Record", "Mixin", "Extension", "Module", "Object", "Variable")
1164
+
1140
1165
  def _work(session):
1141
1166
  # Dedupe identical rows first: parsers can emit the same
1142
1167
  # (child, parent) record more than once, and while Neo4j's MERGE
@@ -1156,8 +1181,6 @@ class GraphWriter:
1156
1181
  internal_batch = [r for r in deduped_batch if r.get("resolved_parent_file_path") != "__external__"]
1157
1182
  external_batch = [r for r in deduped_batch if r.get("resolved_parent_file_path") == "__external__"]
1158
1183
 
1159
- labels = ("Class", "Trait", "Interface", "Struct", "Enum", "Union", "Record", "Mixin", "Extension", "Module", "Object", "Variable")
1160
-
1161
1184
  def _label_is_populated(label: str) -> bool:
1162
1185
  # An empty node table can never match, so skip the pair entirely.
1163
1186
  # If the existence probe itself fails for any reason, fall back to
@@ -1170,52 +1193,109 @@ class GraphWriter:
1170
1193
  except Exception:
1171
1194
  return True
1172
1195
 
1196
+ # Probed once (~12 queries) and reused by the *fallback* enumerations
1197
+ # further down. Deliberately NOT applied to `pair_groups`: those
1198
+ # (child_label, parent_label) pairs are derived from the rows
1199
+ # themselves, so they are never empty -- probing them would be pure
1200
+ # overhead, and a stale or lazily-created label table would make the
1201
+ # probe silently drop real INHERITS edges.
1173
1202
  populated_labels = {label for label in labels if _label_is_populated(label)}
1174
1203
 
1175
- for child_label in labels:
1176
- if child_label not in populated_labels:
1177
- continue
1204
+ def _chunks(rows):
1205
+ for i in range(0, len(rows), batch_size):
1206
+ yield rows[i:i + batch_size]
1207
+
1208
+ def _run_internal(rows, child_label, parent_label):
1178
1209
  child_cypher = _cypher_label(child_label, backend)
1179
- for parent_label in labels:
1180
- if parent_label not in populated_labels:
1181
- continue
1182
- parent_cypher = _cypher_label(parent_label, backend)
1210
+ parent_cypher = _cypher_label(parent_label, backend)
1211
+ query = f"""
1212
+ UNWIND $batch AS row
1213
+ MATCH (child:{child_cypher} {{name: row.child_name, path: row.path}})
1214
+ MATCH (parent:{parent_cypher} {{name: row.parent_name, path: row.resolved_parent_file_path}})
1215
+ MERGE (child)-[r:INHERITS]->(parent)
1216
+ SET r.confidence_label = coalesce(row.confidence_label, 'EXTRACTED')
1217
+ """
1218
+ for chunk in _chunks(rows):
1183
1219
  try:
1184
- session.run(
1185
- f"""
1186
- UNWIND $batch AS row
1187
- MATCH (child:{child_cypher} {{name: row.child_name, path: row.path}})
1188
- MATCH (parent:{parent_cypher} {{name: row.parent_name, path: row.resolved_parent_file_path}})
1189
- MERGE (child)-[r:INHERITS]->(parent)
1190
- SET r.confidence_label = coalesce(row.confidence_label, 'EXTRACTED')
1191
- """,
1192
- batch=internal_batch,
1193
- )
1220
+ session.run(query, batch=chunk)
1194
1221
  except Exception as e:
1222
+ # A label absent in this backend fails to bind for the whole
1223
+ # (child,parent) group; skip it exactly like the old per-pair loop.
1195
1224
  if _is_binder_exception(e):
1196
- continue
1225
+ return
1197
1226
  raise e
1198
1227
 
1199
- for child_label in labels:
1200
- if child_label not in populated_labels:
1201
- continue
1228
+ def _run_external(rows, child_label):
1202
1229
  child_cypher = _cypher_label(child_label, backend)
1203
- try:
1204
- session.run(
1205
- f"""
1206
- UNWIND $batch AS row
1207
- MATCH (child:{child_cypher} {{name: row.child_name, path: row.path}})
1208
- MERGE (parent:ExternalClass {{name: row.parent_name}})
1209
- MERGE (child)-[r:INHERITS]->(parent)
1210
- SET r.confidence_label = coalesce(row.confidence_label, 'INFERRED')
1211
- """,
1212
- batch=external_batch,
1213
- )
1214
- except Exception as e:
1215
- if _is_binder_exception(e):
1216
- continue
1217
- raise e
1230
+ query = f"""
1231
+ UNWIND $batch AS row
1232
+ MATCH (child:{child_cypher} {{name: row.child_name, path: row.path}})
1233
+ MERGE (parent:ExternalClass {{name: row.parent_name}})
1234
+ MERGE (child)-[r:INHERITS]->(parent)
1235
+ SET r.confidence_label = coalesce(row.confidence_label, 'INFERRED')
1236
+ """
1237
+ for chunk in _chunks(rows):
1238
+ try:
1239
+ session.run(query, batch=chunk)
1240
+ except Exception as e:
1241
+ if _is_binder_exception(e):
1242
+ return
1243
+ raise e
1218
1244
 
1245
+ # Group internal rows by the labels resolution pinned down, so only the
1246
+ # (child_label, parent_label) pairs that actually occur run — instead of a
1247
+ # 12x12 brute force that re-scans the full batch for every combination.
1248
+ # both labels known -> one exact query per (child, parent) pair
1249
+ # child known only -> enumerate parent labels over just those rows
1250
+ # neither -> full 12x12 (rare: ambiguous (name,path) label collision)
1251
+ # Rows never gain a label they wouldn't have matched, and unknown/ambiguous
1252
+ # cases fall back to enumeration, so the produced edge set is unchanged.
1253
+ pair_groups: Dict[tuple, List[Dict[str, Any]]] = {}
1254
+ child_only_groups: Dict[str, List[Dict[str, Any]]] = {}
1255
+ legacy_rows: List[Dict[str, Any]] = []
1256
+ for row in internal_batch:
1257
+ cl = row.get("child_label")
1258
+ pl = row.get("parent_label")
1259
+ if cl and pl:
1260
+ pair_groups.setdefault((cl, pl), []).append(row)
1261
+ elif cl:
1262
+ child_only_groups.setdefault(cl, []).append(row)
1263
+ else:
1264
+ legacy_rows.append(row)
1265
+
1266
+ for (cl, pl), rows in pair_groups.items():
1267
+ _run_internal(rows, cl, pl)
1268
+ for cl, rows in child_only_groups.items():
1269
+ for pl in labels:
1270
+ if pl not in populated_labels:
1271
+ continue
1272
+ _run_internal(rows, cl, pl)
1273
+ if legacy_rows:
1274
+ for cl in labels:
1275
+ if cl not in populated_labels:
1276
+ continue
1277
+ for pl in labels:
1278
+ if pl not in populated_labels:
1279
+ continue
1280
+ _run_internal(legacy_rows, cl, pl)
1281
+
1282
+ # External parents (ExternalClass): group by known child label; fall back to
1283
+ # enumerating child labels for any label-less rows.
1284
+ ext_by_child: Dict[str, List[Dict[str, Any]]] = {}
1285
+ ext_legacy: List[Dict[str, Any]] = []
1286
+ for row in external_batch:
1287
+ cl = row.get("child_label")
1288
+ if cl:
1289
+ ext_by_child.setdefault(cl, []).append(row)
1290
+ else:
1291
+ ext_legacy.append(row)
1292
+ for cl, rows in ext_by_child.items():
1293
+ _run_external(rows, cl)
1294
+ if ext_legacy:
1295
+ for cl in labels:
1296
+ if cl not in populated_labels:
1297
+ continue
1298
+ _run_external(ext_legacy, cl)
1219
1299
 
1220
1300
  for file_data in csharp_files:
1221
1301
  self._create_csharp_inheritance_and_interfaces(session, file_data, imports_map)
@@ -6,6 +6,58 @@ from pathlib import Path
6
6
  from typing import Any, Dict, List, Optional, Tuple
7
7
 
8
8
 
9
+
10
+ # Child construct list -> node label: the 8 kinds that can declare inheritance.
11
+ _INHERIT_KEY_TO_LABEL = {
12
+ "classes": "Class",
13
+ "structs": "Struct",
14
+ "traits": "Trait",
15
+ "interfaces": "Interface",
16
+ "mixins": "Mixin",
17
+ "enums": "Enum",
18
+ "extensions": "Extension",
19
+ "variables": "Variable",
20
+ }
21
+
22
+ # All construct lists whose nodes can be an INHERITS parent, mapped to their label.
23
+ # Matches the 12 labels the writer enumerates. Used to attach exact child/parent
24
+ # labels to rows and to detect the rare (name, path) collisions where more than one
25
+ # node kind shares a name+path — those stay ambiguous so the writer falls back to
26
+ # full enumeration (keeping the produced edge set identical).
27
+ _NODE_KEY_TO_LABEL = {
28
+ "classes": "Class",
29
+ "traits": "Trait",
30
+ "interfaces": "Interface",
31
+ "structs": "Struct",
32
+ "enums": "Enum",
33
+ "unions": "Union",
34
+ "records": "Record",
35
+ "mixins": "Mixin",
36
+ "extensions": "Extension",
37
+ "modules": "Module",
38
+ "objects": "Object",
39
+ "variables": "Variable",
40
+ }
41
+
42
+
43
+ def _build_node_label_index(
44
+ all_file_data: List[Dict[str, Any]],
45
+ ) -> Dict[str, Dict[str, set]]:
46
+ """Map normalized path -> {name -> set(labels)} across all inheritance-eligible
47
+ node kinds. A (path, name) with exactly one label lets the writer target that
48
+ label directly; multiple labels leaves it ambiguous (writer enumerates)."""
49
+ index: Dict[str, Dict[str, set]] = {}
50
+ for file_data in all_file_data:
51
+ fpath = str(Path(file_data["path"]).resolve().as_posix())
52
+ per_file = index.setdefault(fpath, {})
53
+ for key, label in _NODE_KEY_TO_LABEL.items():
54
+ for item in file_data.get(key, []):
55
+ name = item.get("name")
56
+ if name:
57
+ per_file.setdefault(name, set()).add(label)
58
+ return index
59
+
60
+
9
61
  def resolve_inheritance_link(
10
62
  class_item: Dict[str, Any],
11
63
  base_class_str: str,
@@ -13,6 +65,8 @@ def resolve_inheritance_link(
13
65
  local_class_names: set,
14
66
  local_imports: dict,
15
67
  imports_map: dict,
68
+ child_label: Optional[str] = None,
69
+ node_label_index: Optional[Dict[str, Dict[str, set]]] = None,
16
70
  ) -> Optional[Dict[str, Any]]:
17
71
  """Resolve a single inheritance link. Returns row dict or None."""
18
72
  import re
@@ -55,21 +109,41 @@ def resolve_inheritance_link(
55
109
  if len(possible_paths) == 1:
56
110
  resolved_path = possible_paths[0]
57
111
 
112
+ # Pin the child label only when this (path, name) is a single node kind. If more
113
+ # than one kind shares it, leave it off so the writer enumerates (byte-identical).
114
+ child_lbl = None
115
+ if child_label:
116
+ if node_label_index is None:
117
+ child_lbl = child_label
118
+ else:
119
+ present = node_label_index.get(caller_file_path, {}).get(class_item["name"])
120
+ if present and len(present) == 1 and child_label in present:
121
+ child_lbl = child_label
122
+
123
+ def _with_labels(row: Dict[str, Any], parent_path: str) -> Dict[str, Any]:
124
+ if child_lbl:
125
+ row["child_label"] = child_lbl
126
+ if node_label_index is not None:
127
+ plabels = node_label_index.get(parent_path, {}).get(target_class_name)
128
+ if plabels and len(plabels) == 1:
129
+ row["parent_label"] = next(iter(plabels))
130
+ return row
131
+
58
132
  if resolved_path:
59
- return {
133
+ return _with_labels({
60
134
  "child_name": class_item["name"],
61
135
  "path": caller_file_path,
62
136
  "parent_name": target_class_name,
63
137
  "resolved_parent_file_path": resolved_path,
64
138
  "confidence_label": "EXTRACTED",
65
- }
66
- return {
139
+ }, resolved_path)
140
+ return _with_labels({
67
141
  "child_name": class_item["name"],
68
142
  "path": caller_file_path,
69
143
  "parent_name": target_class_name,
70
144
  "resolved_parent_file_path": "__external__",
71
145
  "confidence_label": "INFERRED",
72
- }
146
+ }, "__external__")
73
147
 
74
148
 
75
149
 
@@ -79,6 +153,7 @@ def build_inheritance_and_csharp_files(
79
153
  """Returns (inheritance_batch_rows, csharp_file_data_list)."""
80
154
  inheritance_batch: List[Dict[str, Any]] = []
81
155
  csharp_files: List[Dict[str, Any]] = []
156
+ node_label_index = _build_node_label_index(all_file_data)
82
157
 
83
158
  for file_data in all_file_data:
84
159
  if file_data.get("lang") == "c_sharp":
@@ -87,7 +162,7 @@ def build_inheritance_and_csharp_files(
87
162
 
88
163
  caller_file_path = str(Path(file_data["path"]).resolve().as_posix())
89
164
  local_class_names = set()
90
- for key in ["classes", "structs", "traits", "interfaces", "mixins", "enums", "extensions", "variables"]:
165
+ for key in _INHERIT_KEY_TO_LABEL:
91
166
  for item in file_data.get(key, []):
92
167
  local_class_names.add(item["name"])
93
168
 
@@ -97,7 +172,7 @@ def build_inheritance_and_csharp_files(
97
172
  if imp.get("name")
98
173
  }
99
174
 
100
- for key in ["classes", "structs", "traits", "interfaces", "mixins", "enums", "extensions", "variables"]:
175
+ for key, child_label in _INHERIT_KEY_TO_LABEL.items():
101
176
  for class_item in file_data.get(key, []):
102
177
  if not class_item.get("bases"):
103
178
  continue
@@ -109,6 +184,8 @@ def build_inheritance_and_csharp_files(
109
184
  local_class_names,
110
185
  local_imports,
111
186
  imports_map,
187
+ child_label=child_label,
188
+ node_label_index=node_label_index,
112
189
  )
113
190
  if resolved:
114
191
  inheritance_batch.append(resolved)
@@ -139,9 +139,14 @@ C_QUERIES = {
139
139
  )
140
140
  """,
141
141
  "macros": """
142
- (preproc_def
143
- name: (identifier) @name
144
- ) @macro
142
+ [
143
+ (preproc_def
144
+ name: (identifier) @name
145
+ )
146
+ (preproc_function_def
147
+ name: (identifier) @name
148
+ )
149
+ ] @macro
145
150
  """,
146
151
  }
147
152
 
@@ -512,46 +517,53 @@ class CTreeSitterParser:
512
517
  members: List[Dict[str, Any]] = []
513
518
  seen_names: set[str] = set()
514
519
 
515
- for enum_cls in classes:
516
- if enum_cls.get("type") != "enum":
520
+ # One structural pass over every enum body (#1538). The old version
521
+ # had two compounding bugs: the `(enumerator)*` quantifier made only
522
+ # the FIRST enumerator of each enum match, and the whole-file query
523
+ # re-ran inside a per-enum loop with a global seen set — so the first
524
+ # enum claimed every member (`OK` from `enum Status` was emitted with
525
+ # enum_name 'Color').
526
+ enums_by_line = {
527
+ enum_cls.get("line_number"): enum_cls
528
+ for enum_cls in classes
529
+ if enum_cls.get("type") == "enum" and enum_cls.get("name")
530
+ }
531
+ for match in execute_query(
532
+ self.language, "(enum_specifier) @enum", root_node
533
+ ):
534
+ enum_node = match[0]
535
+ enum_cls = enums_by_line.get(enum_node.start_point[0] + 1)
536
+ if not enum_cls:
517
537
  continue
518
- enum_name = enum_cls.get("name")
519
- if not enum_name:
538
+ enum_name = enum_cls["name"]
539
+ body = enum_node.child_by_field_name("body")
540
+ if body is None:
520
541
  continue
521
-
522
- for match in execute_query(
523
- self.language,
524
- """
525
- (enum_specifier
526
- body: (enumerator_list
527
- (enumerator
528
- name: (identifier) @member
529
- )*
530
- )
531
- )
532
- """,
533
- root_node,
534
- ):
535
- if match[1] != "member":
542
+ for child in body.children:
543
+ if child.type != "enumerator":
544
+ continue
545
+ name_node = child.child_by_field_name("name")
546
+ if name_node is None:
536
547
  continue
537
- member_name = self._get_node_text(match[0])
538
- if member_name in seen_names:
548
+ member_name = self._get_node_text(name_node)
549
+ if (enum_name, member_name) in seen_names:
539
550
  continue
540
- seen_names.add(member_name)
551
+ seen_names.add((enum_name, member_name))
541
552
  members.append({
542
553
  "name": member_name,
543
554
  "enum_name": enum_name,
544
555
  "enum_line_number": enum_cls.get("line_number"),
545
- "line_number": match[0].start_point[0] + 1,
556
+ "line_number": name_node.start_point[0] + 1,
546
557
  "lang": self.language_name,
547
558
  "is_dependency": False,
548
559
  })
549
560
 
550
561
  x_macro_members = self._find_xmacro_enum_members(source_code, classes, macros)
551
562
  for member in x_macro_members:
552
- if member["name"] in seen_names:
563
+ key = (member.get("enum_name"), member["name"])
564
+ if key in seen_names:
553
565
  continue
554
- seen_names.add(member["name"])
566
+ seen_names.add(key)
555
567
  members.append(member)
556
568
 
557
569
  return members
@@ -752,10 +764,14 @@ class CTreeSitterParser:
752
764
 
753
765
  context, context_type, _ = self._get_parent_context(macro_node)
754
766
 
767
+ # A preproc node's end_point includes the trailing newline
768
+ # (lands at column 0 of the NEXT row), so +1 double-counts.
769
+ end_row = macro_node.end_point[0]
770
+ end_col = macro_node.end_point[1]
755
771
  macro_data = {
756
772
  "name": name,
757
773
  "line_number": node.start_point[0] + 1,
758
- "end_line": macro_node.end_point[0] + 1,
774
+ "end_line": end_row if end_col == 0 else end_row + 1,
759
775
  "value": value,
760
776
  "params": params,
761
777
  "context": context,
@@ -230,11 +230,16 @@ class CSharpTreeSitterParser:
230
230
  params_node = params_captures[0][0]
231
231
  parameters = self._extract_parameters(params_node)
232
232
 
233
- # Extract attributes applied to this function
233
+ # Extract attributes applied to this function.
234
+ # attribute_list nodes are CHILDREN of the declaration
235
+ # (never its parent), so the old parent check was
236
+ # always false and attributes stayed [] (#1538).
234
237
  attributes = []
235
- if node.parent and node.parent.type == "attribute_list":
236
- attr_text = self._get_node_text(node.parent)
237
- attributes.append(attr_text)
238
+ for child in node.children:
239
+ if child.type == "attribute_list":
240
+ for attr in child.children:
241
+ if attr.type == "attribute":
242
+ attributes.append(self._get_node_text(attr))
238
243
 
239
244
  # Find containing class/struct/interface
240
245
  class_context = self._find_containing_type(node, source_code)
@@ -245,7 +250,9 @@ class CSharpTreeSitterParser:
245
250
  "name": func_name,
246
251
  "args": parameters,
247
252
  "attributes": attributes,
248
- "line_number": start_line,
253
+ # The declaration line, not the first attribute's
254
+ # (python.py's decorated_definition convention).
255
+ "line_number": name_node.start_point[0] + 1,
249
256
  "end_line": end_line,
250
257
  "path": str(path),
251
258
  "lang": self.language_name,
@@ -308,7 +315,26 @@ class CSharpTreeSitterParser:
308
315
  # Parse base list: ": BaseClass, IInterface1, IInterface2"
309
316
  bases_text = bases_text.strip().lstrip(':').strip()
310
317
  if bases_text:
311
- raw_bases = [b.strip() for b in bases_text.split(',')]
318
+ # Split on TOP-LEVEL commas only: a naive split
319
+ # shredded multi-arg generics —
320
+ # `: Dictionary<string, int>` became two bases,
321
+ # 'Dictionary<string' and 'int>', creating
322
+ # INHERITS edges to nonexistent types (#1538).
323
+ raw_bases = []
324
+ depth = 0
325
+ current = []
326
+ for ch in bases_text:
327
+ if ch in "<([":
328
+ depth += 1
329
+ elif ch in ">)]":
330
+ depth = max(0, depth - 1)
331
+ if ch == "," and depth == 0:
332
+ raw_bases.append("".join(current).strip())
333
+ current = []
334
+ else:
335
+ current.append(ch)
336
+ if current:
337
+ raw_bases.append("".join(current).strip())
312
338
  # records might have base calls like : Person(name, age)
313
339
  # we want just Person
314
340
  for rb in raw_bases:
@@ -472,8 +498,11 @@ class CSharpTreeSitterParser:
472
498
  call_name = self._get_node_text(node)
473
499
  line_number = node.start_point[0] + 1
474
500
 
475
- # Avoid duplicates at the same line for the same name
476
- call_key = f"{call_name}_{line_number}"
501
+ # Dedupe per CALL SITE, not per (name, line): keying on
502
+ # name_line dropped distinct calls to the same function on
503
+ # one line — `Math.Max(Clamp(a), Clamp(b))` recorded ONE
504
+ # Clamp (#1538). The node's byte offset separates them.
505
+ call_key = (call_name, line_number, node.start_byte)
477
506
  if call_key in seen_calls:
478
507
  continue
479
508
  seen_calls.add(call_key)
@@ -485,7 +514,16 @@ class CSharpTreeSitterParser:
485
514
 
486
515
  # Get context
487
516
  context_name, context_type, context_line = self._get_parent_context(node)
488
- class_context = context_name if context_type and 'class' in context_type else None
517
+ # A call's first enclosing declaration is its METHOD, so
518
+ # `'class' in context_type` was always false and every
519
+ # call's class_context was None (#1538). Walk again for
520
+ # class-like ancestors only, cpp-style.
521
+ cls_name, _cls_type, cls_line = self._get_parent_context(
522
+ node,
523
+ types=("class_declaration", "struct_declaration",
524
+ "record_declaration", "interface_declaration"),
525
+ )
526
+ class_context = (cls_name, cls_line) if cls_name else None
489
527
 
490
528
  call_data = {
491
529
  "name": call_name,