codegraphcontext 0.6.4__tar.gz → 0.6.6__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.4/src/codegraphcontext.egg-info → codegraphcontext-0.6.6}/PKG-INFO +7 -2
  2. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/README.md +6 -1
  3. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/pyproject.toml +1 -1
  4. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/persistence/writer.py +48 -7
  5. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/schema.py +29 -0
  6. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/c.py +45 -29
  7. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/csharp.py +27 -8
  8. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/elixir.py +22 -0
  9. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/haskell.py +13 -4
  10. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/java.py +26 -2
  11. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/javascript.py +9 -1
  12. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/php.py +34 -7
  13. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/ruby.py +10 -5
  14. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/rust.py +36 -0
  15. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/swift.py +27 -3
  16. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6/src/codegraphcontext.egg-info}/PKG-INFO +7 -2
  17. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/LICENSE +0 -0
  18. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/MANIFEST.in +0 -0
  19. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/setup.cfg +0 -0
  20. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/__init__.py +0 -0
  21. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/__main__.py +0 -0
  22. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/api/__init__.py +0 -0
  23. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/api/app.py +0 -0
  24. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/api/auth.py +0 -0
  25. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/api/mcp_sse.py +0 -0
  26. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/api/router.py +0 -0
  27. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/api/schemas.py +0 -0
  28. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/cli/__init__.py +0 -0
  29. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/cli/cli_helpers.py +0 -0
  30. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/cli/config_manager.py +0 -0
  31. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/cli/hook_manager.py +0 -0
  32. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/cli/main.py +0 -0
  33. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/cli/project_config.py +0 -0
  34. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/cli/registry_commands.py +0 -0
  35. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/cli/setup_macos.py +0 -0
  36. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/cli/setup_wizard.py +0 -0
  37. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/cli/simulator.py +0 -0
  38. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/cli/visualizer.py +0 -0
  39. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/__init__.py +0 -0
  40. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/bundle_registry.py +0 -0
  41. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/cgc_bundle.py +0 -0
  42. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/cgcignore.py +0 -0
  43. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/database.py +0 -0
  44. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/database_embedded_kuzu.py +0 -0
  45. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/database_falkordb.py +0 -0
  46. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/database_falkordb_remote.py +0 -0
  47. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/database_kuzu.py +0 -0
  48. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/database_ladybug.py +0 -0
  49. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/database_nornic.py +0 -0
  50. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/falkor_worker.py +0 -0
  51. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/graph_query.py +0 -0
  52. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/jobs.py +0 -0
  53. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/simulator.py +0 -0
  54. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/core/watcher.py +0 -0
  55. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/prompts.py +0 -0
  56. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/server.py +0 -0
  57. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/stdlibs.py +0 -0
  58. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tool_definitions.py +0 -0
  59. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/__init__.py +0 -0
  60. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
  61. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/code_finder.py +0 -0
  62. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/datasources/__init__.py +0 -0
  63. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/datasources/cassandra_ingester.py +0 -0
  64. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/datasources/mysql_ingester.py +0 -0
  65. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/datasources/redis_ingester.py +0 -0
  66. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/graph_builder.py +0 -0
  67. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -0
  68. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/handlers/indexing_handlers.py +0 -0
  69. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/handlers/management_handlers.py +0 -0
  70. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/handlers/query_handlers.py +0 -0
  71. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/handlers/watcher_handlers.py +0 -0
  72. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/__init__.py +0 -0
  73. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/constants.py +0 -0
  74. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/discovery.py +0 -0
  75. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/embeddings.py +0 -0
  76. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/persistence/__init__.py +0 -0
  77. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/persistence/utils.py +0 -0
  78. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/pipeline.py +0 -0
  79. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/pre_scan.py +0 -0
  80. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/resolution/__init__.py +0 -0
  81. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/resolution/calls.py +0 -0
  82. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/resolution/inheritance.py +0 -0
  83. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/resolution/post_resolution.py +0 -0
  84. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/sanitize.py +0 -0
  85. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/schema_contract.py +0 -0
  86. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/scip_pipeline.py +0 -0
  87. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/indexing/vector_resolver.py +0 -0
  88. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/cpp.py +0 -0
  89. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/css.py +0 -0
  90. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/dart.py +0 -0
  91. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/elisp.py +0 -0
  92. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/go.py +0 -0
  93. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/gradle.py +0 -0
  94. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/html.py +0 -0
  95. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
  96. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/lua.py +0 -0
  97. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/maven.py +0 -0
  98. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/mybatis.py +0 -0
  99. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/perl.py +0 -0
  100. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/python.py +0 -0
  101. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/scala.py +0 -0
  102. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/sfc_common.py +0 -0
  103. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/solidity.py +0 -0
  104. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/solidity_remappings.py +0 -0
  105. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/svelte.py +0 -0
  106. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/typescript.py +0 -0
  107. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
  108. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/languages/vue.py +0 -0
  109. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/package_resolver.py +0 -0
  110. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
  111. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
  112. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
  113. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
  114. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/elisp_toolkit.py +0 -0
  115. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
  116. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
  117. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
  118. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
  119. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
  120. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
  121. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
  122. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
  123. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
  124. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/solidity_toolkit.py +0 -0
  125. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
  126. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
  127. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/report_generator.py +0 -0
  128. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/scip_indexer.py +0 -0
  129. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/scip_pb2.py +0 -0
  130. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/system.py +0 -0
  131. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/tree_sitter_parser.py +0 -0
  132. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/tools/type_utils.py +0 -0
  133. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/cypher_ddl.py +0 -0
  134. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/cypher_readonly.py +0 -0
  135. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/debug_log.py +0 -0
  136. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/gcf_encoder.py +0 -0
  137. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/git_utils.py +0 -0
  138. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/path_ignore.py +0 -0
  139. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/path_sandbox.py +0 -0
  140. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/repo_path.py +0 -0
  141. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/secret_scanner.py +0 -0
  142. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/tool_limits.py +0 -0
  143. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
  144. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/utils/visualize_graph.py +0 -0
  145. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/assets/__vite-browser-external-9wXp6ZBx.js +0 -0
  146. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/assets/function-calls-BtRHrqa2.png +0 -0
  147. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/assets/graph-total-D1fBAugo.png +0 -0
  148. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/assets/hero-graph-2voMJp2a.jpg +0 -0
  149. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/assets/hierarchy-DGADo0YT.png +0 -0
  150. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/assets/index-C-187lf0.js +0 -0
  151. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/assets/index-fNAa6jgv.css +0 -0
  152. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/assets/parser-pyodide.worker-BgsDfaad.js +0 -0
  153. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/assets/parser.worker-_nvrecvj.js +0 -0
  154. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/assets/tree-sitter-qKYAACSa.wasm +0 -0
  155. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/cgcIcon.png +0 -0
  156. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/favicon.ico +0 -0
  157. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/index.html +0 -0
  158. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/logo-icon.svg +0 -0
  159. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/logo.svg +0 -0
  160. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/placeholder.svg +0 -0
  161. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/preview-image.png +0 -0
  162. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/robots.txt +0 -0
  163. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-c.wasm +0 -0
  164. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-c_sharp.wasm +0 -0
  165. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-core.js +0 -0
  166. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-cpp.wasm +0 -0
  167. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-dart.wasm +0 -0
  168. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-go.wasm +0 -0
  169. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-java.wasm +0 -0
  170. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-javascript.wasm +0 -0
  171. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-kotlin.wasm +0 -0
  172. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-perl.wasm +0 -0
  173. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-php.wasm +0 -0
  174. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-python.wasm +0 -0
  175. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-ruby.wasm +0 -0
  176. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-rust.wasm +0 -0
  177. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-swift.wasm +0 -0
  178. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-tsx.wasm +0 -0
  179. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter-typescript.wasm +0 -0
  180. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/tree-sitter.wasm +0 -0
  181. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.js +0 -0
  182. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.wasm +0 -0
  183. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext/viz/server.py +0 -0
  184. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext.egg-info/SOURCES.txt +0 -0
  185. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
  186. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
  187. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext.egg-info/requires.txt +0 -0
  188. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/src/codegraphcontext.egg-info/top_level.txt +0 -0
  189. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/tests/test_issue_806_fix.py +0 -0
  190. {codegraphcontext-0.6.4 → codegraphcontext-0.6.6}/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.4
3
+ Version: 0.6.6
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
@@ -258,7 +258,12 @@ flowchart LR
258
258
  ---
259
259
 
260
260
  ## Star History
261
- [![Star History Chart](https://api.star-history.com/svg?repos=CodeGraphContext/CodeGraphContext&type=Date)](https://www.star-history.com/#CodeGraphContext/CodeGraphContext&Date)
261
+ [Star History Chart](https://www.star-history.com/#CodeGraphContext/CodeGraphContext&Date)
262
+ <!-- The inline chart image is temporarily removed: api.star-history.com currently
263
+ renders "GitHub restricted access to star data" instead of the chart
264
+ (GitHub-side restriction, see PR #1642). Restore the image once the
265
+ official service recovers:
266
+ [![Star History Chart](https://api.star-history.com/svg?repos=CodeGraphContext/CodeGraphContext&type=Date)](https://www.star-history.com/#CodeGraphContext/CodeGraphContext&Date) -->
262
267
 
263
268
  ---
264
269
 
@@ -159,7 +159,12 @@ flowchart LR
159
159
  ---
160
160
 
161
161
  ## Star History
162
- [![Star History Chart](https://api.star-history.com/svg?repos=CodeGraphContext/CodeGraphContext&type=Date)](https://www.star-history.com/#CodeGraphContext/CodeGraphContext&Date)
162
+ [Star History Chart](https://www.star-history.com/#CodeGraphContext/CodeGraphContext&Date)
163
+ <!-- The inline chart image is temporarily removed: api.star-history.com currently
164
+ renders "GitHub restricted access to star data" instead of the chart
165
+ (GitHub-side restriction, see PR #1642). Restore the image once the
166
+ official service recovers:
167
+ [![Star History Chart](https://api.star-history.com/svg?repos=CodeGraphContext/CodeGraphContext&type=Date)](https://www.star-history.com/#CodeGraphContext/CodeGraphContext&Date) -->
163
168
 
164
169
  ---
165
170
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codegraphcontext"
3
- version = "0.6.4"
3
+ version = "0.6.6"
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"
@@ -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."""
@@ -131,14 +154,30 @@ def _cypher_label(label: str, backend: str) -> str:
131
154
 
132
155
 
133
156
  def _called_context_clause(called_label: str) -> str:
134
- """Match CALLS targets that store scope in context, class_context, or module_context."""
135
- if called_label in ("Function", "Variable"):
157
+ """Match CALLS targets that store scope in context, class_context, or module_context.
158
+
159
+ Resolution stores the resolved scope in `called_context`, but which node
160
+ property carries that scope differs by parser: Python/JS use `context`,
161
+ C++/PHP methods use `class_context`, and Rust functions carry ONLY
162
+ `module_context` (#1510). Matching `context` alone filtered every
163
+ correctly-resolved Rust module-scoped call out at write time.
164
+
165
+ Variable is restricted to `context`: the Kùzu Variable table declares no
166
+ class_context/module_context columns, and referencing a missing column
167
+ binder-errors the whole batch on typed backends.
168
+ """
169
+ if called_label == "Function":
136
170
  return (
137
171
  'AND (row.called_context = "" OR row.called_context IS NULL '
138
172
  "OR called.context = row.called_context "
139
173
  "OR called.class_context = row.called_context "
140
174
  "OR called.module_context = row.called_context)"
141
175
  )
176
+ if called_label == "Variable":
177
+ return (
178
+ 'AND (row.called_context = "" OR row.called_context IS NULL '
179
+ "OR called.context = row.called_context)"
180
+ )
142
181
  return ""
143
182
 
144
183
 
@@ -467,7 +506,7 @@ class GraphWriter:
467
506
  "func_line": item["line_number"],
468
507
  }
469
508
  )
470
- if item.get("context_type") == "function_definition":
509
+ if item.get("context_type") in _FUNCTION_CONTEXT_TYPES:
471
510
  outer_ctx = item.get("context")
472
511
  is_seq = isinstance(outer_ctx, (tuple, list)) and outer_ctx
473
512
  outer_name = outer_ctx[0] if is_seq else outer_ctx
@@ -983,10 +1022,12 @@ class GraphWriter:
983
1022
  precise_batch.append(row)
984
1023
 
985
1024
  # Define which labels have a 'context' property in the schema
986
- labels_with_context = {"Function", "Variable"}
987
- called_context_clause = ""
988
- if called_label in labels_with_context:
989
- called_context_clause = 'AND (row.called_context = "" OR called.context = row.called_context)'
1025
+ # The label-aware helper matches context, class_context or
1026
+ # module_context depending on what the label's parsers emit —
1027
+ # the inline context-only predicate silently dropped Rust
1028
+ # module-scoped calls whose functions carry only
1029
+ # module_context (#1510).
1030
+ called_context_clause = _called_context_clause(called_label)
990
1031
 
991
1032
  # ...and which have a 'line_number'. File and Directory do not:
992
1033
  # the Kùzu File table is (path, name, relative_path, package_name,
@@ -137,6 +137,35 @@ def create_graph_schema(driver: Any, db_manager: Any) -> None:
137
137
  ddl.run(
138
138
  "CREATE CONSTRAINT annotation_unique IF NOT EXISTS FOR (a:Annotation) REQUIRE (a.name, a.path, a.line_number) IS UNIQUE"
139
139
  )
140
+ # The relationship passes and code_finder look these nodes up
141
+ # by (name, path) with no line_number: write_inheritance_links
142
+ # matches `(child:<Label> {name: row.child_name, path:
143
+ # row.path})`, and the same for the parent, for every label
144
+ # pair it enumerates; write_function_call_groups matches the
145
+ # callee by (name, path) in both the batched and the single-row
146
+ # path; and code_finder's who_calls_function,
147
+ # what_does_function_call, find_class_hierarchy,
148
+ # find_all_callers and find_all_callees do the same.
149
+ #
150
+ # Neo4j uses a composite index only when EVERY indexed property
151
+ # has a predicate, so the four-property identity constraints
152
+ # above cannot serve those lookups -- the planner falls back to
153
+ # NodeByLabelScan + Filter, once per row. These plain
154
+ # two-property indexes restore an index seek. They do not
155
+ # collide with the identity constraints: a constraint's backing
156
+ # index covers a different property set, so the two coexist.
157
+ #
158
+ # FalkorDB is excluded (this is inside `not is_falkordb`): it
159
+ # indexes per attribute, not per property tuple, and the
160
+ # composite CREATE INDEX statements in its own branch already
161
+ # cover name and path. A second (name, path) index would add
162
+ # nothing there and only re-issue an index creation FalkorDB
163
+ # rejects as "already indexed".
164
+ for _label, _var in POSITIONAL_IDENTITY_LABELS.items():
165
+ ddl.run(
166
+ f"CREATE INDEX {_label.lower()}_name_path IF NOT EXISTS "
167
+ f"FOR ({_var}:{_label}) ON ({_var}.name, {_var}.path)"
168
+ )
140
169
 
141
170
  ddl.run("CREATE INDEX function_lang IF NOT EXISTS FOR (f:Function) ON (f.lang)")
142
171
  ddl.run("CREATE INDEX class_lang IF NOT EXISTS FOR (c:Class) ON (c.lang)")
@@ -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,
@@ -491,8 +498,11 @@ class CSharpTreeSitterParser:
491
498
  call_name = self._get_node_text(node)
492
499
  line_number = node.start_point[0] + 1
493
500
 
494
- # Avoid duplicates at the same line for the same name
495
- 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)
496
506
  if call_key in seen_calls:
497
507
  continue
498
508
  seen_calls.add(call_key)
@@ -504,7 +514,16 @@ class CSharpTreeSitterParser:
504
514
 
505
515
  # Get context
506
516
  context_name, context_type, context_line = self._get_parent_context(node)
507
- 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
508
527
 
509
528
  call_data = {
510
529
  "name": call_name,
@@ -465,6 +465,28 @@ class ElixirTreeSitterParser:
465
465
  "is_dependency": False,
466
466
  })
467
467
 
468
+ # A `def hello(x) do ... end` is itself a `call` node whose arguments
469
+ # contain the SIGNATURE as a nested call. Recursing blindly recorded
470
+ # every definition head as an invocation — a false self-recursive
471
+ # CALLS edge on every Elixir function (#1538). For definition calls,
472
+ # skip the signature and recurse only into the body.
473
+ if node.type == 'call':
474
+ head_identifier = next(
475
+ (c for c in node.children if c.type == 'identifier'), None
476
+ )
477
+ head_target = self._get_node_text(head_identifier) if head_identifier else None
478
+ if head_target in FUNCTION_KEYWORDS:
479
+ for child in node.children:
480
+ if child.type == 'do_block':
481
+ self._find_calls_recursive(child, calls)
482
+ elif child.type == 'arguments':
483
+ # Skip the signature (the first nested call) but keep
484
+ # the inline `, do: body` keywords — that IS the body.
485
+ for arg in child.children:
486
+ if arg.type != 'call':
487
+ self._find_calls_recursive(arg, calls)
488
+ return
489
+
468
490
  for child in node.children:
469
491
  self._find_calls_recursive(child, calls)
470
492
 
@@ -201,13 +201,17 @@ class HaskellTreeSitterParser:
201
201
  "lang": self.language_name,
202
202
  }
203
203
 
204
- def _apply_callee_name(self, apply_node: Any) -> Optional[str]:
204
+ def _apply_callee(self, apply_node: Any) -> Optional[Any]:
205
205
  fn = apply_node.child_by_field_name("function")
206
206
  while fn and fn.type == "apply":
207
207
  fn = fn.child_by_field_name("function")
208
208
  if not fn or fn.type not in ("variable", "constructor"):
209
209
  return None
210
- return self._get_node_text(fn) or None
210
+ return fn
211
+
212
+ def _apply_callee_name(self, apply_node: Any) -> Optional[str]:
213
+ fn = self._apply_callee(apply_node)
214
+ return (self._get_node_text(fn) or None) if fn is not None else None
211
215
 
212
216
  def _parse_instances(
213
217
  self, captures: List[Tuple[Any, str]], source_code: str, path: Path
@@ -448,10 +452,15 @@ class HaskellTreeSitterParser:
448
452
  for node, cap in captures:
449
453
  if cap != "apply_node" or node.type != "apply":
450
454
  continue
451
- call_name = self._apply_callee_name(node)
455
+ callee = self._apply_callee(node)
456
+ call_name = (self._get_node_text(callee) or None) if callee is not None else None
452
457
  if not call_name:
453
458
  continue
454
- key = (node.start_byte, node.end_byte)
459
+ # Dedupe by the CALLEE node: curried application produces nested
460
+ # apply nodes with distinct spans for one call — `print (addTwo
461
+ # 1 2)` emitted addTwo twice at the same line (#1538). Both
462
+ # applies share the same callee identifier node.
463
+ key = (callee.start_byte, callee.end_byte)
455
464
  if key in seen_calls:
456
465
  continue
457
466
  seen_calls.add(key)
@@ -270,9 +270,28 @@ class JavaTreeSitterParser:
270
270
  "lang": self.language_name,
271
271
  }
272
272
 
273
- def _get_parent_context(self, node: Any) -> Tuple[Optional[str], Optional[str], Optional[int]]:
273
+ def _get_parent_context(self, node: Any, types: Optional[Tuple[str, ...]] = None) -> Tuple[Optional[str], Optional[str], Optional[int]]:
274
+ """First enclosing declaration; pass `types` to look only for those.
275
+
276
+ A call inside a method always has the method as its FIRST enclosing
277
+ declaration, so without `types` the class branch below can never win —
278
+ which left every call's class_context structurally (None, None) and
279
+ the super()/same-name-method resolution paths dead (#1538). Callers
280
+ that want the enclosing class pass types=("class_declaration", ...),
281
+ the same pattern cpp.py uses.
282
+ """
274
283
  curr = node.parent
275
284
  while curr:
285
+ if types is not None:
286
+ if curr.type in types:
287
+ name_node = curr.child_by_field_name("name")
288
+ return (
289
+ self._get_node_text(name_node) if name_node else None,
290
+ curr.type,
291
+ curr.start_point[0] + 1,
292
+ )
293
+ curr = curr.parent
294
+ continue
276
295
  if curr.type in ("method_declaration", "constructor_declaration"):
277
296
  name_node = curr.child_by_field_name("name")
278
297
  return (
@@ -941,6 +960,11 @@ class JavaTreeSitterParser:
941
960
  full_name = self._get_node_text(type_node)
942
961
 
943
962
  ctx_name, ctx_type, ctx_line = self._get_parent_context(node)
963
+ cls_name, cls_type, cls_line = self._get_parent_context(
964
+ node,
965
+ types=("class_declaration", "interface_declaration",
966
+ "enum_declaration", "annotation_type_declaration"),
967
+ )
944
968
 
945
969
  debug_log(f"Found call: {call_name} (full_name: {full_name}, inferred_obj_type: {inferred_obj_type}, args: {args}) in context {ctx_name}")
946
970
 
@@ -951,7 +975,7 @@ class JavaTreeSitterParser:
951
975
  "args": args,
952
976
  "inferred_obj_type": inferred_obj_type,
953
977
  "context": (ctx_name, ctx_type, ctx_line),
954
- "class_context": (ctx_name, ctx_line) if ctx_type in ("class_declaration", "interface_declaration", "enum_declaration", "annotation_type_declaration") else (None, None),
978
+ "class_context": (cls_name, cls_line) if cls_name else None,
955
979
  "lang": self.language_name,
956
980
  "is_dependency": False,
957
981
  }
@@ -298,7 +298,7 @@ class JavascriptTreeSitterParser:
298
298
  args = [self._get_node_text(data['single_param'])]
299
299
 
300
300
  # Context & docstring
301
- context, context_type, _ = self._get_parent_context(func_node)
301
+ context, context_type, context_line = self._get_parent_context(func_node)
302
302
  class_context = context if context_type == 'class_declaration' else None
303
303
  docstring = self._get_jsdoc_comment(func_node)
304
304
 
@@ -314,6 +314,14 @@ class JavascriptTreeSitterParser:
314
314
  "end_line": func_node.end_point[0] + 1,
315
315
  "args": args,
316
316
  "class_context": class_context,
317
+ # context/context_type were computed and then dropped, so a
318
+ # nested function never got a CONTAINS edge to its enclosing
319
+ # function (#1538). Function rows carry context as a BARE NAME
320
+ # plus separate type/line fields — the tuple shape belongs to
321
+ # call rows only (python.py is the reference).
322
+ "context": context,
323
+ "context_type": context_type,
324
+ "context_line": context_line,
317
325
  "lang": self.language_name,
318
326
  "is_dependency": False,
319
327
  "cyclomatic_complexity": self._calculate_complexity(func_node),
@@ -30,6 +30,10 @@ PHP_QUERIES = {
30
30
  (trait_declaration
31
31
  name: (name) @name
32
32
  ) @trait
33
+
34
+ (enum_declaration
35
+ name: (name) @name
36
+ ) @enum
33
37
  """,
34
38
  # A top-level `use App\Models\User;` is a `namespace_use_declaration`.
35
39
  # `use_declaration` is the *trait* use inside a class body (relied on at
@@ -153,7 +157,7 @@ class PhpTreeSitterParser:
153
157
  def _get_parent_context(self, node: Any) -> Tuple[Optional[str], Optional[str], Optional[int]]:
154
158
  curr = node.parent
155
159
  while curr:
156
- if curr.type in ("function_definition", "method_declaration", "class_declaration", "interface_declaration", "trait_declaration"):
160
+ if curr.type in ("function_definition", "method_declaration", "class_declaration", "interface_declaration", "trait_declaration", "enum_declaration"):
157
161
  name_node = curr.child_by_field_name("name")
158
162
  return (
159
163
  self._get_node_text(name_node) if name_node else None,
@@ -166,12 +170,29 @@ class PhpTreeSitterParser:
166
170
  def _get_enclosing_class_name(self, node: Any) -> Optional[str]:
167
171
  curr = node.parent
168
172
  while curr:
169
- if curr.type in ("class_declaration", "interface_declaration", "trait_declaration"):
173
+ if curr.type in ("class_declaration", "interface_declaration", "trait_declaration", "enum_declaration"):
170
174
  name_node = curr.child_by_field_name("name")
171
175
  return self._get_node_text(name_node) if name_node else None
172
176
  curr = curr.parent
173
177
  return None
174
178
 
179
+ def _get_enclosing_class(self, node: Any) -> Optional[Tuple[str, int]]:
180
+ """(name, line) of the enclosing class-like declaration, or None.
181
+
182
+ Calls previously emitted TWO shapes for class_context — a bare string
183
+ for ordinary calls and a dead (None, None) tuple for `new X()` (the
184
+ parent-context type is the enclosing *function*, never a class) — so
185
+ the tuple-consuming resolution paths never fired for PHP (#1538).
186
+ """
187
+ curr = node.parent
188
+ while curr:
189
+ if curr.type in ("class_declaration", "interface_declaration", "trait_declaration", "enum_declaration"):
190
+ name_node = curr.child_by_field_name("name")
191
+ name = self._get_node_text(name_node) if name_node else None
192
+ return (name, curr.start_point[0] + 1) if name else None
193
+ curr = curr.parent
194
+ return None
195
+
175
196
  def _get_node_text(self, node: Any) -> str:
176
197
  if not node: return ""
177
198
  return node.text.decode("utf-8")
@@ -266,7 +287,7 @@ class PhpTreeSitterParser:
266
287
  "lang": self.language_name,
267
288
  "context": context_name,
268
289
  "context_type": context_type,
269
- "class_context": context_name if context_type and ("class" in context_type or "interface" in context_type or "trait" in context_type) else None
290
+ "class_context": context_name if context_type and ("class" in context_type or "interface" in context_type or "trait" in context_type or "enum" in context_type) else None
270
291
  }
271
292
 
272
293
  if self.index_source:
@@ -287,7 +308,7 @@ class PhpTreeSitterParser:
287
308
  seen_nodes = set()
288
309
 
289
310
  for node, capture_name in captures:
290
- if capture_name in ("class", "interface", "trait"):
311
+ if capture_name in ("class", "interface", "trait", "enum"):
291
312
  node_id = (node.start_byte, node.end_byte, node.type)
292
313
  if node_id in seen_nodes:
293
314
  continue
@@ -350,6 +371,12 @@ class PhpTreeSitterParser:
350
371
  interfaces.append(type_data)
351
372
  elif capture_name == "trait":
352
373
  traits.append(type_data)
374
+ elif capture_name == "enum":
375
+ # PHP 8.1 enums are class-likes: without this arm
376
+ # the captured row was silently dropped and enum
377
+ # methods became orphans (#1538).
378
+ type_data["node_type"] = "enum"
379
+ classes.append(type_data)
353
380
 
354
381
  except Exception as e:
355
382
  error_logger(f"Error parsing type in {path}: {e}")
@@ -398,7 +425,7 @@ class PhpTreeSitterParser:
398
425
  "path": str(path),
399
426
  "lang": self.language_name,
400
427
  "context": ctx_name,
401
- "class_context": ctx_name if ctx_type and ("class" in ctx_type or "interface" in ctx_type or "trait" in ctx_type) else None
428
+ "class_context": ctx_name if ctx_type and ("class" in ctx_type or "interface" in ctx_type or "trait" in ctx_type or "enum" in ctx_type) else None
402
429
  })
403
430
  except Exception as e:
404
431
  continue
@@ -558,7 +585,7 @@ class PhpTreeSitterParser:
558
585
  "args": args,
559
586
  "inferred_obj_type": inferred_obj_type,
560
587
  "context": (ctx_name, ctx_type, ctx_line),
561
- "class_context": self._get_enclosing_class_name(node),
588
+ "class_context": self._get_enclosing_class(node),
562
589
  "lang": self.language_name,
563
590
  "is_dependency": False,
564
591
  }
@@ -607,7 +634,7 @@ class PhpTreeSitterParser:
607
634
  "args": args,
608
635
  "inferred_obj_type": None,
609
636
  "context": (ctx_name, ctx_type, ctx_line),
610
- "class_context": (ctx_name, ctx_line) if ctx_type and ("class" in ctx_type or "interface" in ctx_type or "trait" in ctx_type) else (None, None),
637
+ "class_context": self._get_enclosing_class(node),
611
638
  "lang": self.language_name,
612
639
  "is_dependency": False,
613
640
  }
@@ -480,13 +480,18 @@ class RubyTreeSitterParser:
480
480
  captures_by_call[call_id]['name'] = self._get_node_text(node)
481
481
 
482
482
  elif capture_name == 'receiver':
483
- captures_by_call[call_id]['receiver'] = self._get_node_text(node)
483
+ # Field check, like the name branch: byte-range containment
484
+ # alone let nested calls steal each other's receiver —
485
+ # `logger.info(formatter.render(x))` recorded `info` with
486
+ # full_name "formatter.info" (#1538).
487
+ if node == call_node.child_by_field_name('receiver'):
488
+ captures_by_call[call_id]['receiver'] = self._get_node_text(node)
484
489
 
485
490
  elif capture_name == 'args':
486
- # Capture arguments
487
- args_text = self._get_node_text(node)
488
- # Simple heuristic: split by comma
489
- captures_by_call[call_id]['args'] = [a.strip() for a in args_text.strip("()").split(',') if a.strip()]
491
+ if node == call_node.child_by_field_name('arguments'):
492
+ args_text = self._get_node_text(node)
493
+ # Simple heuristic: split by comma
494
+ captures_by_call[call_id]['args'] = [a.strip() for a in args_text.strip("()").split(',') if a.strip()]
490
495
 
491
496
  for call_data in captures_by_call.values():
492
497
  call_node = call_data['node']