cg-code-graph 0.23.2__tar.gz → 0.23.4__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 (407) hide show
  1. {cg_code_graph-0.23.2/cg_code_graph.egg-info → cg_code_graph-0.23.4}/PKG-INFO +2 -2
  2. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/__init__.py +1 -1
  3. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/cli.py +2 -1
  4. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/mcp_server.py +36 -10
  5. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/platforms.py +62 -2
  6. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/swift/exact.py +8 -1
  7. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/swift/plugin.py +75 -12
  8. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/query.py +68 -4
  9. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4/cg_code_graph.egg-info}/PKG-INFO +2 -2
  10. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph.egg-info/SOURCES.txt +4 -0
  11. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph.egg-info/requires.txt +1 -1
  12. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/pyproject.toml +1 -1
  13. cg_code_graph-0.23.4/tests/test_issue_201.py +137 -0
  14. cg_code_graph-0.23.4/tests/test_issue_204.py +79 -0
  15. cg_code_graph-0.23.4/tests/test_issue_212.py +82 -0
  16. cg_code_graph-0.23.4/tests/test_issue_219.py +125 -0
  17. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_binding.py +1 -1
  18. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_parse_errors.py +6 -1
  19. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/LICENSE +0 -0
  20. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/MANIFEST.in +0 -0
  21. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/README.md +0 -0
  22. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/__main__.py +0 -0
  23. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/affected.py +0 -0
  24. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/agent_rules.py +0 -0
  25. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/agents.py +0 -0
  26. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/aitools.py +0 -0
  27. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/android_ipc.py +0 -0
  28. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/apple_ipc.py +0 -0
  29. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/apps.py +0 -0
  30. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/blindspots.py +0 -0
  31. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/bridges.py +0 -0
  32. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/brokers.py +0 -0
  33. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/concepts.py +0 -0
  34. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/config.py +0 -0
  35. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/__init__.py +0 -0
  36. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/cache.py +0 -0
  37. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/detect.py +0 -0
  38. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/env.py +0 -0
  39. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/extractors.py +0 -0
  40. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/fsutil.py +0 -0
  41. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/generated.py +0 -0
  42. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/model.py +0 -0
  43. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/paths.py +0 -0
  44. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/plugin.py +0 -0
  45. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/redact.py +0 -0
  46. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/store.py +0 -0
  47. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/core/syntax_errors.py +0 -0
  48. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/coverage.py +0 -0
  49. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/dart_isolates.py +0 -0
  50. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/doctor.py +0 -0
  51. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/explore.py +0 -0
  52. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/external.py +0 -0
  53. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/graphql.py +0 -0
  54. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/guard_facts.py +0 -0
  55. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/hooks.py +0 -0
  56. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/indexer.py +0 -0
  57. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/insecure_transport.py +0 -0
  58. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/install_rules.py +0 -0
  59. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/jobs.py +0 -0
  60. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/link.py +0 -0
  61. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/lint_async.py +0 -0
  62. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/local_ipc.py +0 -0
  63. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/local_sockets.py +0 -0
  64. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/mcp_graphs.py +0 -0
  65. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/mcp_install.py +0 -0
  66. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/parity.py +0 -0
  67. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/parity_structure.py +0 -0
  68. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/payload.py +0 -0
  69. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plans.py +0 -0
  70. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/platform_scan.py +0 -0
  71. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/__init__.py +0 -0
  72. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/astro/__init__.py +0 -0
  73. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/astro/content.py +0 -0
  74. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/astro/plugin.py +0 -0
  75. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/cfamily/__init__.py +0 -0
  76. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/cfamily/plugin.py +0 -0
  77. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/cfamily/syntax.py +0 -0
  78. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/dart/__init__.py +0 -0
  79. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/dart/bridges.py +0 -0
  80. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/dart/extractor/bin/extract.dart +0 -0
  81. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/dart/extractor/pubspec.lock +0 -0
  82. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/dart/extractor/pubspec.yaml +0 -0
  83. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/dart/http.py +0 -0
  84. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/dart/models.py +0 -0
  85. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/dart/plugin.py +0 -0
  86. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/dart/program.py +0 -0
  87. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/django/__init__.py +0 -0
  88. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/django/extras.py +0 -0
  89. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/django/models.py +0 -0
  90. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/django/plugin.py +0 -0
  91. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/django/schemas.py +0 -0
  92. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/django/shapes.py +0 -0
  93. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/django/urls.py +0 -0
  94. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/express/__init__.py +0 -0
  95. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/express/plugin.py +0 -0
  96. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/flutter/__init__.py +0 -0
  97. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/flutter/plugin.py +0 -0
  98. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/java/__init__.py +0 -0
  99. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/java/exact.py +0 -0
  100. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/java/plugin.py +0 -0
  101. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/jvm/__init__.py +0 -0
  102. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/jvm/interop.py +0 -0
  103. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/jvm/spring.py +0 -0
  104. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/kotlin/__init__.py +0 -0
  105. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/kotlin/exact.py +0 -0
  106. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/kotlin/plugin.py +0 -0
  107. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/kotlin/reparse.py +0 -0
  108. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/laravel/__init__.py +0 -0
  109. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/laravel/broadcast.py +0 -0
  110. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/laravel/massassign.py +0 -0
  111. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/laravel/plugin.py +0 -0
  112. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/laravel/tests.py +0 -0
  113. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/laravel/values.py +0 -0
  114. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/native/__init__.py +0 -0
  115. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/native/gates.py +0 -0
  116. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/native/runner.py +0 -0
  117. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/native/scipread.py +0 -0
  118. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/native/ts.py +0 -0
  119. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/nest/__init__.py +0 -0
  120. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/nest/plugin.py +0 -0
  121. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/nextjs/__init__.py +0 -0
  122. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/nextjs/plugin.py +0 -0
  123. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/nuxt/__init__.py +0 -0
  124. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/nuxt/plugin.py +0 -0
  125. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/php/__init__.py +0 -0
  126. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/php/external.py +0 -0
  127. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/php/extractor/composer.json +0 -0
  128. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/php/extractor/composer.lock +0 -0
  129. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/php/extractor/extract.php +0 -0
  130. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/php/gating.py +0 -0
  131. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/php/http_client.py +0 -0
  132. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/php/inline_guards.py +0 -0
  133. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/php/plugin.py +0 -0
  134. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/php/strings.py +0 -0
  135. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/python/__init__.py +0 -0
  136. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/python/aitools.py +0 -0
  137. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/python/external.py +0 -0
  138. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/python/fields.py +0 -0
  139. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/python/plugin.py +0 -0
  140. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/python/refs.py +0 -0
  141. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/python/roots.py +0 -0
  142. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/python/socketio.py +0 -0
  143. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/python/subproc.py +0 -0
  144. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/python/tests.py +0 -0
  145. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/python/values.py +0 -0
  146. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/pyweb/__init__.py +0 -0
  147. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/pyweb/plugin.py +0 -0
  148. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/pyweb/values.py +0 -0
  149. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/rust/__init__.py +0 -0
  150. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/rust/cargo.py +0 -0
  151. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/rust/plugin.py +0 -0
  152. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/rust/syntax.py +0 -0
  153. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/scip/__init__.py +0 -0
  154. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/scip/importer.py +0 -0
  155. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/scip/scip.proto +0 -0
  156. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/scip/scip_pb2.py +0 -0
  157. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/stubs/__init__.py +0 -0
  158. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/stubs/plugins.py +0 -0
  159. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/swift/__init__.py +0 -0
  160. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/swift/baseurl.py +0 -0
  161. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/swift/indexstore.py +0 -0
  162. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/swift/packages.py +0 -0
  163. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/ts/__init__.py +0 -0
  164. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/ts/baseurl.py +0 -0
  165. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/ts/extractor/extract.mjs +0 -0
  166. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/ts/extractor/fw.mjs +0 -0
  167. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/ts/extractor/package-lock.json +0 -0
  168. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/ts/extractor/package.json +0 -0
  169. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/ts/extractor/rr.mjs +0 -0
  170. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/ts/nav.py +0 -0
  171. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/ts/plugin.py +0 -0
  172. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/ts/react_router.py +0 -0
  173. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/tsweb/__init__.py +0 -0
  174. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/tsweb/common.py +0 -0
  175. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/plugins/tsweb/data.py +0 -0
  176. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/__init__.py +0 -0
  177. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/c_cpp.yaml +0 -0
  178. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/common.yaml +0 -0
  179. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/dart.yaml +0 -0
  180. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/django-ninja.yaml +0 -0
  181. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/django.yaml +0 -0
  182. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/djangorestframework.yaml +0 -0
  183. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/express.yaml +0 -0
  184. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/java.yaml +0 -0
  185. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/kotlin.yaml +0 -0
  186. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/laravel.yaml +0 -0
  187. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/nest.yaml +0 -0
  188. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/nextjs.yaml +0 -0
  189. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/nuxt.yaml +0 -0
  190. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/php.yaml +0 -0
  191. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/python.yaml +0 -0
  192. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/react-router.yaml +0 -0
  193. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/rust.yaml +0 -0
  194. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/spring.yaml +0 -0
  195. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/swift.yaml +0 -0
  196. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/presets/typescript.yaml +0 -0
  197. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/process_runs.py +0 -0
  198. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/protocols/__init__.py +0 -0
  199. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/protocols/builtin.py +0 -0
  200. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/protocols/matchers.py +0 -0
  201. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/protocols/view.py +0 -0
  202. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/realtime.py +0 -0
  203. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/realtime_events.py +0 -0
  204. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/realtime_native.py +0 -0
  205. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/realtime_ws.py +0 -0
  206. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/roundtrip.py +0 -0
  207. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/routes.py +0 -0
  208. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/rpc.py +0 -0
  209. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/sdk_systems.py +0 -0
  210. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/sockets.py +0 -0
  211. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/ssrf_input.py +0 -0
  212. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/starters.py +0 -0
  213. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/surface.py +0 -0
  214. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/tests_index.py +0 -0
  215. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/udp_apps.py +0 -0
  216. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/update_check.py +0 -0
  217. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/__init__.py +0 -0
  218. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/graph.py +0 -0
  219. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/server.py +0 -0
  220. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/static/app.css +0 -0
  221. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/static/app.js +0 -0
  222. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/static/index.html +0 -0
  223. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/static/layered.js +0 -0
  224. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/static/vendor/VERSIONS.txt +0 -0
  225. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/static/vendor/cose-base.js +0 -0
  226. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/static/vendor/cytoscape-fcose.js +0 -0
  227. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/static/vendor/cytoscape.min.js +0 -0
  228. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/static/vendor/layout-base.js +0 -0
  229. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/tools/package-lock.json +0 -0
  230. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/tools/package.json +0 -0
  231. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/viz/tools/shoot.mjs +0 -0
  232. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/watch.py +0 -0
  233. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/webhook_subs.py +0 -0
  234. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/webhooks.py +0 -0
  235. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph/xcode.py +0 -0
  236. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph.egg-info/dependency_links.txt +0 -0
  237. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph.egg-info/entry_points.txt +0 -0
  238. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/cg_code_graph.egg-info/top_level.txt +0 -0
  239. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/setup.cfg +0 -0
  240. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_affected.py +0 -0
  241. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_agents_install.py +0 -0
  242. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_agents_md.py +0 -0
  243. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_ai_tools.py +0 -0
  244. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_android_ipc.py +0 -0
  245. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_apple_ipc.py +0 -0
  246. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_astro.py +0 -0
  247. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_astro_content.py +0 -0
  248. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_astro_server.py +0 -0
  249. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_bridges.py +0 -0
  250. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_bridges_pigeon_monorepo.py +0 -0
  251. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_brokers.py +0 -0
  252. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_cache_clean.py +0 -0
  253. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_cache_invalidation.py +0 -0
  254. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_cache_migration.py +0 -0
  255. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_channels_tests.py +0 -0
  256. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_cli_output.py +0 -0
  257. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_completeness.py +0 -0
  258. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_config_extras.py +0 -0
  259. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_coverage.py +0 -0
  260. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_coverage_ts_hint.py +0 -0
  261. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_dart_isolates.py +0 -0
  262. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_db_connections.py +0 -0
  263. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_dead_wrappers.py +0 -0
  264. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_dispatch_interfaces.py +0 -0
  265. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_django_flutter.py +0 -0
  266. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_docs_languages.py +0 -0
  267. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_docs_links.py +0 -0
  268. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_echo_ref.py +0 -0
  269. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_echo_wrapper.py +0 -0
  270. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_elysia.py +0 -0
  271. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_enum_constants.py +0 -0
  272. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_env.py +0 -0
  273. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_explore.py +0 -0
  274. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_external.py +0 -0
  275. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_fp_batch.py +0 -0
  276. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_gating.py +0 -0
  277. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_generated.py +0 -0
  278. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_graphql.py +0 -0
  279. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_hooks.py +0 -0
  280. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_impact_overrides.py +0 -0
  281. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_index_isolation.py +0 -0
  282. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_inherited_overrides.py +0 -0
  283. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_inline_guards.py +0 -0
  284. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_install_rules.py +0 -0
  285. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_issue_192.py +0 -0
  286. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_issue_202.py +0 -0
  287. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_issue_203.py +0 -0
  288. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_issue_205.py +0 -0
  289. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_issue_206.py +0 -0
  290. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_issue_207.py +0 -0
  291. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_issue_208.py +0 -0
  292. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_issue_209.py +0 -0
  293. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_issue_210.py +0 -0
  294. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_issue_211.py +0 -0
  295. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_issue_211_used_at.py +0 -0
  296. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_java.py +0 -0
  297. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_java_exact.py +0 -0
  298. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_jobs.py +0 -0
  299. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_js_refs.py +0 -0
  300. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_js_runtime.py +0 -0
  301. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_kotlin.py +0 -0
  302. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_kotlin_binding.py +0 -0
  303. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_kotlin_exact.py +0 -0
  304. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_kotlin_fields.py +0 -0
  305. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_kotlin_mixed.py +0 -0
  306. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_kotlin_nav_consts.py +0 -0
  307. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_kotlin_props.py +0 -0
  308. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_laravel_determinism.py +0 -0
  309. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_laravel_resources.py +0 -0
  310. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_link_origin.py +0 -0
  311. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_lint_async.py +0 -0
  312. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_listing_files.py +0 -0
  313. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_local_ipc.py +0 -0
  314. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_local_sockets.py +0 -0
  315. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_mass_assignment.py +0 -0
  316. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_mcp.py +0 -0
  317. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_mcp_index.py +0 -0
  318. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_mcp_install.py +0 -0
  319. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_mcp_instructions.py +0 -0
  320. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_mcp_multi_graph.py +0 -0
  321. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_native_cfamily.py +0 -0
  322. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_native_concurrency.py +0 -0
  323. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_native_rust.py +0 -0
  324. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_nuxt_i18n.py +0 -0
  325. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_nuxt_import_dirs.py +0 -0
  326. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_nuxt_nitro.py +0 -0
  327. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_nuxt_rootsrc.py +0 -0
  328. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_nuxt_side_dirs.py +0 -0
  329. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_packaging.py +0 -0
  330. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_parity.py +0 -0
  331. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_parity_structure.py +0 -0
  332. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_php_http.py +0 -0
  333. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_php_props.py +0 -0
  334. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_plain_js.py +0 -0
  335. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_plans.py +0 -0
  336. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_platform_gaps.py +0 -0
  337. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_platform_type_variants.py +0 -0
  338. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_platforms.py +0 -0
  339. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_platforms_apple.py +0 -0
  340. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_presets_config.py +0 -0
  341. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_process_ipc.py +0 -0
  342. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_process_runs.py +0 -0
  343. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_protocols.py +0 -0
  344. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_app_tests_module.py +0 -0
  345. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_collection_chains.py +0 -0
  346. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_compat.py +0 -0
  347. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_entry_refs.py +0 -0
  348. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_fields.py +0 -0
  349. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_infer_cycles.py +0 -0
  350. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_roots.py +0 -0
  351. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_subprocess_tests.py +0 -0
  352. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_tests.py +0 -0
  353. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_web_hosts.py +0 -0
  354. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_web_routes.py +0 -0
  355. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_python_web_routes_more.py +0 -0
  356. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_react_router.py +0 -0
  357. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_readers_writers_specs.py +0 -0
  358. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_realtime.py +0 -0
  359. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_realtime_native.py +0 -0
  360. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_redact_salt.py +0 -0
  361. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_request_keys.py +0 -0
  362. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_roundtrip.py +0 -0
  363. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_route_specs.py +0 -0
  364. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_route_tables.py +0 -0
  365. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_routes_search_explain.py +0 -0
  366. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_rpc.py +0 -0
  367. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_scip_health.py +0 -0
  368. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_sdk_external.py +0 -0
  369. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_sdk_external_infra.py +0 -0
  370. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_sdk_external_mail.py +0 -0
  371. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_snippet.py +0 -0
  372. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_sockets.py +0 -0
  373. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_spring.py +0 -0
  374. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_ssrf.py +0 -0
  375. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_starters_budget.py +0 -0
  376. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_surface.py +0 -0
  377. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_surface_transport.py +0 -0
  378. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift.py +0 -0
  379. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_exact.py +0 -0
  380. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_facts.py +0 -0
  381. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_fields.py +0 -0
  382. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_modules.py +0 -0
  383. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_more.py +0 -0
  384. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_nav_values.py +0 -0
  385. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_props.py +0 -0
  386. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_sdk.py +0 -0
  387. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_testing.py +0 -0
  388. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_swift_values.py +0 -0
  389. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_tests_scope.py +0 -0
  390. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_ts_fields.py +0 -0
  391. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_ts_fields_js_vue.py +0 -0
  392. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_ts_file_specs.py +0 -0
  393. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_ts_frameworks.py +0 -0
  394. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_ts_node_http.py +0 -0
  395. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_ts_nuxt.py +0 -0
  396. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_ts_src_tsconfig.py +0 -0
  397. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_unguarded.py +0 -0
  398. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_update_check.py +0 -0
  399. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_values.py +0 -0
  400. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_viz.py +0 -0
  401. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_vue_nav.py +0 -0
  402. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_watch.py +0 -0
  403. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_webhooks.py +0 -0
  404. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_webhooks_152.py +0 -0
  405. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_webhooks_152b.py +0 -0
  406. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_websockets.py +0 -0
  407. {cg_code_graph-0.23.2 → cg_code_graph-0.23.4}/tests/test_workspace_link.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cg-code-graph
3
- Version: 0.23.2
3
+ Version: 0.23.4
4
4
  Summary: cg: a code graph of routes, calls, data access and platform boundaries for agents and humans (CLI + MCP server)
5
5
  Author: cyberchronos00
6
6
  License-Expression: MIT
@@ -18,7 +18,7 @@ Requires-Dist: tree-sitter-c>=0.23
18
18
  Requires-Dist: tree-sitter-cpp>=0.23
19
19
  Requires-Dist: tree-sitter-kotlin>=1.0
20
20
  Requires-Dist: tree-sitter-java>=0.23
21
- Requires-Dist: tree-sitter-swift<0.7.4,>=0.6
21
+ Requires-Dist: tree-sitter-swift<0.8,>=0.6
22
22
  Provides-Extra: dev
23
23
  Requires-Dist: pytest>=8; extra == "dev"
24
24
  Provides-Extra: watch
@@ -1,2 +1,2 @@
1
1
  """code-graph: deterministic code knowledge graph (beta)."""
2
- __version__ = "0.23.2"
2
+ __version__ = "0.23.4"
@@ -733,7 +733,8 @@ def main(argv=None):
733
733
  print(Q.connections_line(res["connections"]))
734
734
  if not res["callers"] and not res["entry_points"]:
735
735
  print(Q.explain_no_callers(st, a.spec, res["targets"], a.min_confidence)); return
736
- print(f"callers (transitive): {len(res['callers'])}")
736
+ nc = res.get("callers_candidate") or 0
737
+ print(f"callers (transitive): {len(res['callers']) - nc}" + (f" (+{nc} candidate)" if nc else ""))
737
738
  caller_names = _impact_labels(res["callers"], lambda c: c.get("fqn") or c["id"], lambda c: c.get("module") or c.get("kind"))
738
739
  for c, nm in zip(res["callers"], caller_names):
739
740
  loc = f" @ {c['file']}:{c['line']}" if Q.NATIVE_FILE_RE.search(c.get("file") or "") else ""
@@ -601,7 +601,9 @@ def impact(method: str, min_confidence: str = "heuristic", max_items: int = 60,
601
601
  dropped_line = [f"not built for {pf}: {', '.join(short(t) for t in dropped[:6])}"] if pf and dropped else []
602
602
  out = pline + dropped_line + [f"targets: {', '.join(short(t) for t in r['targets'][:5])}", *via_default, *Q.override_lines(r),
603
603
  *([Q.connections_line(r["connections"])] if r.get("connections") else []),
604
- f"transitive callers: {len(r['callers'])}; entry points: {len(r['entry_points'])}"]
604
+ f"transitive callers: {r.get('callers_resolved', len(r['callers']))}"
605
+ + (f" (+{r['callers_candidate']} candidate)" if r.get("callers_candidate") else "")
606
+ + f"; entry points: {len(r['entry_points'])}"]
605
607
  if not r["callers"] and not r["entry_points"]:
606
608
  return "\n".join(out + [Q.explain_no_callers(st, method, r["targets"], min_confidence)])
607
609
  byk = defaultdict(list)
@@ -619,7 +621,7 @@ def impact(method: str, min_confidence: str = "heuristic", max_items: int = 60,
619
621
  out.append(f" {lab}{Q.CANDIDATE_LABEL if e.get('candidate') else ''}{Q.platform_label(e)}{hop}")
620
622
  bymod = defaultdict(list)
621
623
  for c in r["callers"]:
622
- bymod[c.get("module") or "?"].append(c)
624
+ bymod[Q.caller_group(c)].append(c)
623
625
  dup_lines = []
624
626
  for mod in sorted(bymod):
625
627
  cs = bymod[mod]
@@ -631,8 +633,10 @@ def impact(method: str, min_confidence: str = "heuristic", max_items: int = 60,
631
633
  out.append("same name in one module: " + "; ".join(dup_lines))
632
634
  mods = defaultdict(int)
633
635
  for c in r["callers"]:
634
- mods[c.get("module") or "?"] += 1
635
- out.append("\ncallers by module: " + ", ".join(f"{m}×{c}" for m, c in sorted(mods.items(), key=lambda x: -x[1])))
636
+ if not c.get("candidate"): # candidates are listed on their own below (#204)
637
+ mods[Q.caller_group(c)] += 1
638
+ if mods:
639
+ out.append("\ncallers by module: " + ", ".join(f"{m}×{c}" for m, c in sorted(mods.items(), key=lambda x: -x[1])))
636
640
  gen = [c for c in r["callers"] if c.get("generated")]
637
641
  if gen: # indexed with --include-generated: callers in files a generator writes
638
642
  out.append(f"in generated / copied files ({len(gen)}): " + ", ".join(f"{short(c['id'])} [{c['generated']}]" for c in gen[:8])
@@ -648,8 +652,13 @@ def impact(method: str, min_confidence: str = "heuristic", max_items: int = 60,
648
652
  for c in vo[:8]) + (f" …+{len(vo) - 8}" if len(vo) > 8 else ""))
649
653
  cand = [c for c in r["callers"] if c.get("candidate")]
650
654
  if cand or any(e.get("candidate") for e in r["entry_points"]): # reached through a candidate call edge (#83)
651
- out.append(f"candidate callers ({len(cand)}): " + ", ".join(short(c["id"]) for c in cand[:12])
655
+ out.append(f"candidate callers ({len(cand)}): " + ", ".join(short(c["id"]) + Q.fanout_text(c) for c in cand[:12])
652
656
  + (f" …+{len(cand) - 12}" if len(cand) > 12 else "") + "\n" + Q.CANDIDATE_NOTE)
657
+ od = [c for c in r["callers"] if c.get("omits_default")]
658
+ if od: # calls that leave out a defaulted argument and so run its default (#212)
659
+ out.append(f"through an omitted default argument ({len(od)}): "
660
+ + ", ".join(f"{short(c['id'])} ({c['omits_default']}: of {short(c.get('default_of'))})" for c in od[:8])
661
+ + (f" …+{len(od) - 8}" if len(od) > 8 else ""))
653
662
  vb = [c for c in r["callers"] if c.get("via_base")]
654
663
  if vb: # calls the base declaration; the target is reached through the override
655
664
  out.append(f"via base ({len(vb)}): " + ", ".join(f"{short(c['id'])} -> {c['via_base']}" for c in vb[:8])
@@ -702,12 +711,26 @@ def callers(symbol: str, min_confidence: str = "heuristic", limit: int = 60) ->
702
711
  if not rows:
703
712
  return head + f"\nno direct callers of {symbol!r} in indexed code (min_confidence={min_confidence}). try: impact() for " \
704
713
  f"entry points, reaches() for every dependent over all edge kinds, node() for its other edges"
705
- out = [head, f"direct callers: {len({r['src'] for r in rows})} ({len(rows)} sites)"]
706
- for r in rows[:limit]:
714
+ # one row per call site: a site linked to several per-platform definitions of the target is one site (#201)
715
+ seen, uniq = set(), []
716
+ for r in rows:
717
+ if (r["src"], r["kind"], r["file"], r["line"]) not in seen:
718
+ seen.add((r["src"], r["kind"], r["file"], r["line"]))
719
+ uniq.append(r)
720
+ rows = uniq
721
+ is_cand = [bool(r["attrs"] and '"binding": "candidate"' in r["attrs"]) for r in rows]
722
+ res = [r for r, cd in zip(rows, is_cand) if not cd]
723
+ cands = [r for r, cd in zip(rows, is_cand) if cd]
724
+ # selector-only candidates (receiver type unknown) are counted apart from resolved callers (#204)
725
+ out = [head, f"direct callers: {len({r['src'] for r in res})} ({len(res)} sites)"
726
+ + (f"; candidate callers: {len({r['src'] for r in cands})} ({len(cands)} site{'' if len(cands) == 1 else 's'}, receiver type unknown)"
727
+ if cands else "")]
728
+ for r in (res + cands)[:limit]:
707
729
  c = "" if r["confidence"] == "exact" else f" ~{r['confidence'][0]}"
708
730
  k = "ref" if r["kind"] == "REFERENCES_FN" else r["kind"]
709
- cand = Q.CANDIDATE_LABEL if r["attrs"] and '"binding": "candidate"' in r["attrs"] else ""
710
- out.append(f" {short(r['src'])} {k}@{at((r['file'] or '?') + ':' + str(r['line']))}{c}{cand}")
731
+ cand = Q.candidate_label(r["attrs"], r["dst"]) if r in cands else ""
732
+ out.append(f" {short(r['src'])} {k}@{at((r['file'] or '?') + ':' + str(r['line']))}{c}{cand}"
733
+ + Q.omitted_default_label(r["attrs"]))
711
734
  if len(rows) > limit:
712
735
  out.append(f" … +{len(rows) - limit} more (raise limit)")
713
736
  return "\n".join(out)
@@ -762,6 +785,8 @@ def _prop_lines(rows: list, limit: int) -> list[str]:
762
785
  for r in rows[:limit]:
763
786
  a = r.get("attrs") or {}
764
787
  ex = " ".join(f"{k}={a[k]}" for k in ("receiver", "accessor", "storage") if k in a)
788
+ if a.get("variant_platforms"): # one of a property's per-platform declarations (#219)
789
+ ex = f"{ex} platforms={','.join(a['variant_platforms'])}".strip()
765
790
  ek = ",".join(sorted(r["entry_kinds"])) or "-"
766
791
  out.append(f" {'[test] ' if r.get('test') else ''}{r['fqn']} @{os.path.basename(r['file'] or '?')}:{r['line']}"
767
792
  f" {ex} entries: {ek}")
@@ -1086,7 +1111,8 @@ def node(id_or_symbol: str) -> str:
1086
1111
  for k, v in sorted(byk.items()):
1087
1112
  if k == "CONTAINS":
1088
1113
  continue
1089
- s = "; ".join(f"{short(r['o'])}@{r['line']}{'!g' if r['gate'] else ''}" for r in v[:6])
1114
+ # `<id> :<line>`: a variant id carries its own `@N` (`refreshStatus@24 :12`, #201)
1115
+ s = "; ".join(f"{short(r['o'])} :{r['line']}{'!g' if r['gate'] else ''}" for r in v[:6])
1090
1116
  out.append(f" {k}: {s}{' …' if len(v) > 6 else ''}")
1091
1117
  return "\n".join(out)
1092
1118
 
@@ -29,6 +29,7 @@ on any target follow the implementation that target builds.
29
29
  """
30
30
  from __future__ import annotations
31
31
 
32
+ import dataclasses
32
33
  import fnmatch
33
34
  import json
34
35
  import os
@@ -658,11 +659,13 @@ def apply(project, builder) -> dict:
658
659
  etag[k] = hit
659
660
  targets, tsrc = declared_targets(root, cfg, marks, set(langs) | ({"c_cpp"} if langs & {"c", "cpp"} else set()))
660
661
  _write_attrs(builder, ntag, nvals, etag, targets)
662
+ narrowed = _narrow_variant_edges(builder, nvals, etag)
661
663
  _variant_platforms(builder, nvals, targets)
662
664
  unknown = [m for m in marks if any(m["cond"].values().get(p) is None for p in targets)]
663
665
  tagged_files = sorted({m["file"] for m in marks})
664
666
  st = {"targets": targets, "target_sources": tsrc, "conditions": len(marks), "files_with_conditions": len(tagged_files),
665
- "tagged_nodes": len(ntag), "tagged_edges": len(etag), "variant_edges": mirrored, "text_scanned_files": scanned,
667
+ "tagged_nodes": len(ntag), "tagged_edges": len(etag), "variant_edges": mirrored,
668
+ "variant_edges_narrowed": narrowed, "text_scanned_files": scanned,
666
669
  "unevaluated_conditions": len(unknown),
667
670
  "unevaluated_per_target": {p: sum(1 for m in unknown if m["cond"].values().get(p) is None) for p in targets},
668
671
  "unevaluated_samples": sorted({f"{m['cond'].text} @ {m['file']}:{m['line']}" for m in unknown})[:8]}
@@ -824,6 +827,63 @@ def _write_attrs(builder, ntag, nvals, etag, targets=None) -> None:
824
827
  put(e.attrs, ms, _combine([m["cond"].values() for m in ms]))
825
828
 
826
829
 
830
+ def _narrow_variant_edges(builder, nvals: dict, etag: dict) -> int:
831
+ """A reference made where only some targets build (`#if os(macOS)` around the caller or the call) reaches only the
832
+ per-platform definitions built on one of those targets (#201): a macOS-only call of `refreshStatus()` links the
833
+ macOS definition, not the `#else` stub. A reference whose definition is not built anywhere the site is moves to the
834
+ sibling definitions that are (the `#else` type's `Self()` names its own type), and a Swift `init` of a sibling
835
+ variant type that declares no initializer of its own (the implicit one) is no reference at all. References from
836
+ code built everywhere keep linking every definition."""
837
+ alts = {}
838
+ for ids in _alt_groups(builder, nvals).values():
839
+ if len(ids) > 1 and any(i in nvals for i in ids):
840
+ for i in ids:
841
+ alts[i] = ids
842
+ inits: dict[str, list] = defaultdict(list) # Swift type -> its init nodes
843
+ parent: dict[str, str] = {}
844
+ for e in builder.edges.values():
845
+ if e.kind == "CONTAINS" and e.src.startswith("class:"):
846
+ parent[e.dst] = e.src
847
+ dn = builder.nodes.get(e.dst)
848
+ if dn is not None and dn.name == "init":
849
+ inits[e.src].append(e.dst)
850
+
851
+ def avail(i):
852
+ return {p for p in KNOWN if _avail(nvals.get(i), p)}
853
+
854
+ drop, adds = [], []
855
+ for k, e in builder.edges.items():
856
+ if e.kind in ("CONTAINS", "DEFINES", "GATED_BY"):
857
+ continue
858
+ vals = ([nvals[e.src]] if e.src in nvals else []) + [m["cond"].values() for m in etag.get(k, ())]
859
+ if not vals:
860
+ continue
861
+ site = {p for p, v in _combine(vals).items() if v is not False}
862
+ if not site or avail(e.dst) & site:
863
+ continue
864
+ ids = alts.get(e.dst)
865
+ if ids:
866
+ other = [i for i in ids if i != e.dst and avail(i) & site]
867
+ if other:
868
+ drop.append(k)
869
+ adds += [(e, i) for i in other]
870
+ continue
871
+ dn = builder.nodes.get(e.dst)
872
+ if dn is None or dn.lang != "swift" or dn.name != "init" or e.dst not in parent:
873
+ continue
874
+ own = parent[e.dst]
875
+ sib = [v for v in alts.get(own) or () if v != own and avail(v) & site]
876
+ if sib and all(not inits.get(v) for v in sib):
877
+ drop.append(k) # the sibling variant type's implicit initializer
878
+ for k in drop:
879
+ builder.edges.pop(k, None)
880
+ for e, nid in adds:
881
+ key = (e.src, nid, e.kind, e.file, e.line, e.gate)
882
+ if key not in builder.edges:
883
+ builder.edges[key] = dataclasses.replace(e, dst=nid, attrs={**(e.attrs or {}), "platform_variant_of": e.dst})
884
+ return len(drop)
885
+
886
+
827
887
  def _variant_platforms(builder, nvals: dict, targets) -> int:
828
888
  """A reference into one of a symbol's per-platform definitions (Rust / C / C++ / Swift `#if` branches) carries
829
889
  `variant_platforms`: the targets that definition is built for. Every definition is linked (_mirror), so a caller
@@ -935,7 +995,7 @@ def _alt_groups(builder, nvals: dict) -> dict[str, list[str]]:
935
995
  """Rust / C / C++ / Swift alternative definitions of one symbol (one per `cfg` / `#if` branch), keyed by _vkey."""
936
996
  alts: dict[str, list[str]] = defaultdict(list)
937
997
  for nid, n in builder.nodes.items():
938
- if n.lang in ("rust", "c", "cpp", "swift") and n.kind in ALT_KINDS:
998
+ if n.lang in ("rust", "c", "cpp", "swift") and n.kind in ALT_KINDS or n.lang == "swift" and n.kind == "field":
939
999
  alts[_vkey(nid, n, nvals)].append(nid)
940
1000
  # a static C function and a macro / function of the same name visible in its file are variants too
941
1001
  for k in [k for k in alts if k.startswith("c-fn:") and "#" in k]:
@@ -318,8 +318,10 @@ class ExactLayer:
318
318
  acc = {**acc, "property": "read" if accessor_kind.get(o.usr) == "getter" else "write"}
319
319
  br = self.p.branch_at.get((rel, o.line, self.b.nodes[dst].name), {}) \
320
320
  if kind == "INSTANTIATES" else {}
321
+ da = self.default_args.get((dst, rel, o.line)) if kind == "CALLS" else None
321
322
  self.b.add_edge(src, dst, kind, rel, o.line, EXACT, source="indexstore",
322
- **({"dynamic": True} if o.roles & ix.DYNAMIC else {}), **acc, **br)
323
+ **({"dynamic": True} if o.roles & ix.DYNAMIC else {}), **acc, **br,
324
+ **({"default_arg": da} if da else {}))
323
325
  exact.add((src, dst, kind))
324
326
  refs += 1
325
327
  st["index_references"] = refs
@@ -410,17 +412,22 @@ class ExactLayer:
410
412
  it is kept, marked `via: not-compiled`, and left out of the comparison. Candidate edges (#83) go to
411
413
  self.candidates, compared on their own."""
412
414
  out, cand, kept = set(), set(), 0
415
+ self.default_args = {} # (callee, file, line) -> parameter label of a default-argument call (#208)
413
416
  for key, e in list(self.b.edges.items()):
414
417
  if e.confidence != HEURISTIC or e.file not in covered or e.kind not in CALL_KINDS:
415
418
  continue
416
419
  n = self.b.nodes.get(e.src)
417
420
  if n is None or n.lang != "swift":
418
421
  continue
422
+ if e.attrs.get("omits_default"):
423
+ continue # the call runs a default the compiler records at the declaration only (#212)
419
424
  if (e.file, e.line) not in seen_lines:
420
425
  e.attrs["via"] = "not-compiled"
421
426
  kept += 1
422
427
  continue
423
428
  (cand if e.attrs.get("binding") == "candidate" else out).add((e.src, e.dst, e.kind))
429
+ if e.attrs.get("default_arg"):
430
+ self.default_args[(e.dst, e.file, e.line)] = e.attrs["default_arg"]
424
431
  del self.b.edges[key]
425
432
  self.candidates = cand
426
433
  return out, kept
@@ -492,6 +492,8 @@ class SwiftPlugin(LanguagePlugin):
492
492
  self.stored_names: set[str] = set() # names of plain stored properties anywhere in the project
493
493
  self.stored_in: dict[str, set[str]] = defaultdict(set) # type fqn -> its stored property names
494
494
  self.fields: dict[str, dict[str, str]] = defaultdict(dict) # type fqn -> stored instance property -> field id
495
+ self._vfields: dict[tuple, str] = {} # (type decl id, stored property) -> field id of that `#if` variant
496
+ self._field_owner: dict[str, str | None] = {} # field id -> the variant type declaring it (#219)
495
497
  self.field_names: set[str] = set()
496
498
  self.mutating_names: set[str] = set()
497
499
  self.branch_of: dict[tuple, dict] = {} # (owner, line, type name) -> enclosing branch of a construction
@@ -565,6 +567,7 @@ class SwiftPlugin(LanguagePlugin):
565
567
  self._available(sf)
566
568
  self._resolve_calls()
567
569
  self._resolve_props()
570
+ self._omitted_defaults()
568
571
  self._at = None
569
572
  self._hierarchy()
570
573
  self._fluent_migrations(sfiles)
@@ -928,9 +931,18 @@ class SwiftPlugin(LanguagePlugin):
928
931
  def _field(self, cls: Decl, nm: str, sf: SFile, c, attrs: list):
929
932
  """A stored instance property (`var count = 0`, `@State private var value`, `@Published var items`) is a
930
933
  `field:<Type>.<name>` node (#88): reads and writes of it are READS_PROP / WRITES_PROP edges, for `cg readers` /
931
- `cg writers Type.prop`. Its property wrapper, if any, is attrs.wrapper."""
932
- if nm in self.fields.get(cls.fqn, {}):
933
- return
934
+ `cg writers Type.prop`. Its property wrapper, if any, is attrs.wrapper. The same property declared again in
935
+ another `#if` branch (in the type, or in a per-branch variant of the type) is a node of its own,
936
+ `field:<Type>.<name>@<line>` (#219); the platform pass narrows references to the one built where they are."""
937
+ key = f"{cls.fqn}.{nm}"
938
+ line = c.start_point[0] + 1
939
+ prev_id = self.fields.get(cls.fqn, {}).get(nm)
940
+ if prev_id:
941
+ pn = self.b.nodes[prev_id]
942
+ prev = SimpleNamespace(file=pn.file, line=pn.line, owner=self._field_owner.get(prev_id))
943
+ if not self._branch_variant(prev, sf, c, cls):
944
+ return
945
+ key = f"{key}@{line}"
934
946
  kw = next((self.t(x).split()[0] for x in c.children if x.type == "value_binding_pattern" and self.t(x).strip()), "var")
935
947
  a = {"property": "stored", "binding": "let" if kw == "let" else "var"}
936
948
  wrappers = [x for x in attrs if x not in ("MainActor", "objc", "IBOutlet", "IBInspectable", "available", "nonobjc")]
@@ -942,15 +954,16 @@ class SwiftPlugin(LanguagePlugin):
942
954
  a["key"] = m.group(1)
943
955
  if sf.test:
944
956
  a["test"] = True
945
- fid = self.b.add_node("field", f"{cls.fqn}.{nm}", name=nm, fqn=f"{cls.fqn}.{nm}", file=sf.rel,
946
- line=c.start_point[0] + 1, end_line=c.end_point[0] + 1,
957
+ fid = self.b.add_node("field", key, name=nm, fqn=f"{cls.fqn}.{nm}", file=sf.rel,
958
+ line=line, end_line=c.end_point[0] + 1,
947
959
  module=getattr(self.b.nodes.get(cls.id), "module", None), lang="swift", attrs=a)
948
- self.b.add_edge(cls.id, fid, "CONTAINS", sf.rel, c.start_point[0] + 1, EXACT)
949
- self.fields[cls.fqn][nm] = fid
950
- self.field_names.add(nm)
951
- if wrappers: # `_value = State(initialValue: x)`: the wrapper's storage is the same property
952
- self.fields[cls.fqn]["_" + nm] = fid
953
- self.field_names.add("_" + nm)
960
+ self.b.add_edge(cls.id, fid, "CONTAINS", sf.rel, line, EXACT)
961
+ self._field_owner[fid] = self._owner(cls)
962
+ names = [nm] + (["_" + nm] if wrappers else []) # `_value = State(initialValue: x)`: the wrapper's storage
963
+ for x in names:
964
+ self.fields[cls.fqn].setdefault(x, fid)
965
+ self._vfields[(cls.id, x)] = fid
966
+ self.field_names.add(x)
954
967
  self.st["stored_property_nodes"] += 1
955
968
 
956
969
  def _prop_decl(self, c, nm: str, sf: SFile, cls: Decl):
@@ -1437,6 +1450,11 @@ class SwiftPlugin(LanguagePlugin):
1437
1450
  # `a + weight(forExtraIndex: 2)` parses as `(a + weight)(forExtraIndex: 2)`: the callee is the right operand
1438
1451
  f = f.child_by_field_name("rhs")
1439
1452
  line = f.start_point[0] + 1
1453
+ while f.type == "prefix_expression" and len(f.children) == 2 and self.t(f.children[0]) in ("!", "-", "~", "+") \
1454
+ and f.children[1].type in ("navigation_expression", "simple_identifier"):
1455
+ # tree-sitter-swift 0.7.4 parses `!Preview.matches(a, b)` as `(!Preview.matches)(a, b)`; 0.7.3 as
1456
+ # `(!Preview).matches(a, b)` (handled below): either way the operator applies to the result (#199)
1457
+ f = f.children[1]
1440
1458
  suf = next((x for x in c.children if x.type == "call_suffix"), None)
1441
1459
  args = next((x for x in suf.children if x.type == "value_arguments"), None) if suf is not None else None
1442
1460
  lam = next((x for x in suf.children if x.type in ("lambda_literal", "annotated_lambda")), None) if suf is not None else None
@@ -2122,6 +2140,8 @@ class SwiftPlugin(LanguagePlugin):
2122
2140
  return self._qext
2123
2141
 
2124
2142
  def _resolve_calls(self):
2143
+ self._default_edges: dict[str, list] = defaultdict(list) # function -> [(label, callee, attrs)] (#208)
2144
+ self._call_sites: list = [] # (caller, callee, file, line, labels, trailing)
2125
2145
  for rec in self.calls:
2126
2146
  owner, name, recv, line, sf, decl, labels, trailing = rec[:8]
2127
2147
  default_arg = rec[8] if len(rec) > 8 else None
@@ -2151,15 +2171,57 @@ class SwiftPlugin(LanguagePlugin):
2151
2171
  **self.branch_of.get((owner, line, name), {}))
2152
2172
  for m in hit:
2153
2173
  self.b.add_edge(owner, m.id, "CALLS", sf.rel, line, HEURISTIC)
2174
+ self._call_sites.append((owner, m.id, sf.rel, line, labels, trailing))
2154
2175
  else:
2155
2176
  if default_arg:
2156
2177
  how = {**how, "default_arg": default_arg}
2178
+ self._default_edges[owner].append((default_arg, t.id, {}))
2179
+ elif self._how != "candidate":
2180
+ self._call_sites.append((owner, t.id, sf.rel, line, labels, trailing))
2157
2181
  self.b.add_edge(owner, t.id, "CALLS", sf.rel, line, HEURISTIC, **how, **self._accessor_attr(decl, line))
2158
2182
  if how:
2159
2183
  self.st["calls_by_name_only" if self._how == "name" else "call_candidate_edges"] += 1
2160
2184
  done = True
2161
2185
  self.st["calls_resolved" if done else "calls_unresolved"] += 1
2162
2186
 
2187
+ def _omitted_defaults(self):
2188
+ """A call that leaves out a defaulted argument runs the default expression: an edge from the caller to what
2189
+ the default calls, at the call site, with `omits_default` (the parameter label) and `default_of` (#212). A
2190
+ call that passes the argument gets none. The declaration's own `default_arg` edge stays (#208)."""
2191
+ if not self._default_edges:
2192
+ return
2193
+ n = 0
2194
+ for owner, did, rel, line, labels, trailing in self._call_sites:
2195
+ defs = self._default_edges.get(did)
2196
+ if not defs:
2197
+ continue
2198
+ left = self._left_out(did, labels, trailing)
2199
+ for label, callee, extra in defs:
2200
+ if label in left and callee != owner:
2201
+ self.b.add_edge(owner, callee, "CALLS", rel, line, HEURISTIC, omits_default=label, default_of=did,
2202
+ **extra)
2203
+ n += 1
2204
+ if n:
2205
+ self.st["default_argument_sites"] = n
2206
+
2207
+ def _left_out(self, did: str, labels: tuple, trailing: bool) -> set:
2208
+ """Labels of the defaulted / optional parameters the call leaves out, by the first signature it fits."""
2209
+ for sig in self.sigs.get(did) or ():
2210
+ i, ok, left, tr = 0, True, set(), trailing
2211
+ for k, (lab, opt) in enumerate(sig):
2212
+ if i < len(labels) and labels[i] == lab:
2213
+ i += 1
2214
+ elif tr and i == len(labels) and all(o for _l, o in sig[k + 1:]):
2215
+ tr = False
2216
+ elif opt:
2217
+ left.add(lab)
2218
+ else:
2219
+ ok = False
2220
+ break
2221
+ if ok and i == len(labels):
2222
+ return left
2223
+ return set()
2224
+
2163
2225
  def _prop_member(self, cls: Decl | None, name: str, depth: int = 0) -> list[Decl]:
2164
2226
  """Property nodes named `name` of a type, its extensions and its supertypes (protocol extensions too)."""
2165
2227
  if cls is None or name in self.stored_in.get(cls.fqn, ()):
@@ -2241,6 +2303,7 @@ class SwiftPlugin(LanguagePlugin):
2241
2303
  continue
2242
2304
  if default_arg:
2243
2305
  how = {**how, "default_arg": default_arg}
2306
+ self._default_edges[owner].append((default_arg, t.id, {"property": "write" if write else "read"}))
2244
2307
  self.b.add_edge(owner, t.id, "CALLS", sf.rel, line, HEURISTIC, property="write" if write else "read",
2245
2308
  **how, **self._accessor_attr(decl, line))
2246
2309
  done = True
@@ -2252,7 +2315,7 @@ class SwiftPlugin(LanguagePlugin):
2252
2315
  """The field node of a stored property `name` of a type or its superclasses."""
2253
2316
  if cls is None or depth > 6:
2254
2317
  return None
2255
- fid = self.fields.get(cls.fqn, {}).get(name)
2318
+ fid = self._vfields.get((cls.id, name)) or self.fields.get(cls.fqn, {}).get(name)
2256
2319
  if fid:
2257
2320
  return fid
2258
2321
  for s in cls.supers:
@@ -981,6 +981,9 @@ def _hop_of(e) -> dict:
981
981
  a = json.loads(e["attrs"])
982
982
  if a.get("binding") == "candidate": # one of several same-name methods, receiver type unknown (#83)
983
983
  hop["candidate"] = a.get("candidates") or True
984
+ if e["kind"] in ("CALLS", "TEST_CALLS") and e["attrs"] and '"omits_default"' in e["attrs"]:
985
+ a = json.loads(e["attrs"]) # the call leaves out a defaulted argument and runs its default (#212)
986
+ hop["omits_default"], hop["default_of"] = a.get("omits_default"), a.get("default_of")
984
987
  if e["kind"] in ("CALLS", "TEST_CALLS") and e["attrs"] and '"accessor"' in e["attrs"]:
985
988
  hop["accessor"] = json.loads(e["attrs"]).get("accessor") # inside `didSet { }` / `get { }` (Swift, #72)
986
989
  if e["gate"]:
@@ -1253,7 +1256,7 @@ def render_reaches(res: dict, show_paths=True, kinds=CODE_KINDS + ENTRY_NODE_KIN
1253
1256
  out.append(f"== {labels[cls]}: {len(group)} functions/methods")
1254
1257
  bymod = defaultdict(list)
1255
1258
  for i in group:
1256
- bymod[i.get("module") or "?"].append(i)
1259
+ bymod[caller_group(i)].append(i)
1257
1260
  for mod in sorted(bymod):
1258
1261
  out.append(f" [{mod}]")
1259
1262
  for i in bymod[mod]:
@@ -1270,7 +1273,7 @@ def render_reaches(res: dict, show_paths=True, kinds=CODE_KINDS + ENTRY_NODE_KIN
1270
1273
  out.append(f"== GATED UNDER SCENARIO '{res.get('gate')}' (dead when the scenario holds; live otherwise): {len(gated)} functions/methods")
1271
1274
  bymod = defaultdict(list)
1272
1275
  for i in gated:
1273
- bymod[i.get("module") or "?"].append(i)
1276
+ bymod[caller_group(i)].append(i)
1274
1277
  for mod in sorted(bymod):
1275
1278
  out.append(f" [{mod}]")
1276
1279
  for i in bymod[mod]:
@@ -1304,7 +1307,8 @@ def _first_hop(path: list[dict] | None) -> dict:
1304
1307
  return {}
1305
1308
  h = path[0]
1306
1309
  return {"edge": h["kind"], **({"how": h["how"]} if h.get("how") else {}), **({"via": h["via"]} if h.get("via") else {}),
1307
- **({"accessor": h["accessor"]} if h.get("accessor") else {})}
1310
+ **({"accessor": h["accessor"]} if h.get("accessor") else {}),
1311
+ **({"omits_default": h["omits_default"], "default_of": h.get("default_of")} if h.get("omits_default") else {})}
1308
1312
 
1309
1313
 
1310
1314
  def with_generated(row: dict) -> dict:
@@ -1348,6 +1352,54 @@ def generated_label(n: dict) -> str:
1348
1352
 
1349
1353
 
1350
1354
  CANDIDATE_LABEL = " (candidate)"
1355
+
1356
+
1357
+ def _node_name(nid: str) -> str:
1358
+ """`method:PrinterBridge.refreshStatus@24` -> `refreshStatus`."""
1359
+ return nid.split(":", 1)[-1].split("@", 1)[0].rsplit(".", 1)[-1].rsplit("::", 1)[-1].rsplit("#", 1)[-1]
1360
+
1361
+
1362
+ def caller_group(c: dict) -> str:
1363
+ """Module of a caller; a caller without one (a free function, a top-level script) is grouped by its file,
1364
+ never as `?` (#204)."""
1365
+ if c.get("module"):
1366
+ return c["module"]
1367
+ f = c.get("file")
1368
+ return f"{os.path.basename(f)} (top level)" if f else "?"
1369
+
1370
+
1371
+ def fanout_text(c: dict) -> str:
1372
+ """' (1 of 4 methods named refreshStatus)' for a selector-only candidate caller (#204), else ''."""
1373
+ co = c.get("candidate_of") or {}
1374
+ return f" (1 of {co['count']} methods named {co['name']})" if co.get("count") else ""
1375
+
1376
+
1377
+ def candidate_label(attrs: str | None, dst: str) -> str:
1378
+ """' (candidate, 1 of 3 methods named refreshStatus)' for a candidate call edge (#204)."""
1379
+ try:
1380
+ a = json.loads(attrs or "{}") or {}
1381
+ except ValueError:
1382
+ a = {}
1383
+ n = a.get("candidates")
1384
+ if isinstance(n, int) and not isinstance(n, bool) and n > 1:
1385
+ return f" (candidate, 1 of {n} methods named {_node_name(dst)})"
1386
+ return CANDIDATE_LABEL
1387
+
1388
+
1389
+ def omitted_default_label(attrs: str | None) -> str:
1390
+ """' (runs the default of gamut: in render)' for a call site that leaves out a defaulted argument (#212)."""
1391
+ if attrs and '"default_arg"' in attrs:
1392
+ try:
1393
+ return f" (parameter default {(json.loads(attrs) or {}).get('default_arg')}:)"
1394
+ except ValueError:
1395
+ return ""
1396
+ if not attrs or '"omits_default"' not in attrs:
1397
+ return ""
1398
+ try:
1399
+ a = json.loads(attrs) or {}
1400
+ except ValueError:
1401
+ return ""
1402
+ return f" (runs the default of {a.get('omits_default')}: in {_node_name(a.get('default_of') or '?')})"
1351
1403
  CANDIDATE_NOTE = ("(candidate): through a call whose receiver type is unknown, bound to each project method with that "
1352
1404
  "selector; it may reach a same-name sibling instead")
1353
1405
 
@@ -1418,7 +1470,10 @@ def caller_label(c: dict) -> str:
1418
1470
  if c.get("in_property"): # a type node: the call is in a property of that type (#72)
1419
1471
  lab += " (in a property)"
1420
1472
  if c.get("candidate"):
1421
- lab += CANDIDATE_LABEL
1473
+ co = c.get("candidate_of") or {}
1474
+ lab += f" (candidate, 1 of {co['count']} methods named {co['name']})" if co.get("count") else CANDIDATE_LABEL
1475
+ if c.get("omits_default"):
1476
+ lab += f" (runs the default of {c['omits_default']}: in {_node_name(c.get('default_of') or '?')})"
1422
1477
  if c.get("via_override"):
1423
1478
  v = c["via_override"]
1424
1479
  lab += f" (via override {v[0]}" + (f" +{len(v) - 1}" if len(v) > 1 else "") + ")"
@@ -1655,6 +1710,10 @@ def _impact(st: GraphStore, spec: str, min_conf: str, platform: str | None) -> d
1655
1710
  p = paths.get(n) or []
1656
1711
  if path_candidate(p):
1657
1712
  c["candidate"] = True
1713
+ fan = next((h for h in p if h.get("candidate")), {})
1714
+ if isinstance(fan.get("candidate"), int) and not isinstance(fan.get("candidate"), bool):
1715
+ # one of N project methods sharing the selector (#204)
1716
+ c["candidate_of"] = {"count": fan["candidate"], "name": _node_name(fan["to"])}
1658
1717
  if p and p[0]["to"] in bases: # calls the base declaration; reaches the target through the override
1659
1718
  c["via_base"] = fq.get(p[0]["to"], p[0]["to"])
1660
1719
  if n in direct: # calls an override (not the target itself): reaches the target's API through it
@@ -1662,6 +1721,9 @@ def _impact(st: GraphStore, spec: str, min_conf: str, platform: str | None) -> d
1662
1721
  callers.append(c)
1663
1722
  out = {"targets": targets, "entry_points": sorted(entries, key=lambda x: (x["entry_kind"], x["name"])),
1664
1723
  "callers": sorted(callers, key=lambda x: (x["depth"], x["fqn"] or "")), **rel}
1724
+ # selector-only candidates (receiver type unknown, #83) are counted apart from resolved callers (#204)
1725
+ out["callers_candidate"] = sum(1 for c in callers if c.get("candidate"))
1726
+ out["callers_resolved"] = len(callers) - out["callers_candidate"]
1665
1727
  defaults = _default_arguments(st, targets)
1666
1728
  if defaults:
1667
1729
  out["default_arguments"] = defaults
@@ -1719,6 +1781,8 @@ def prop_fields(st: GraphStore, spec: str) -> list[str]:
1719
1781
  spec = spec[len("property:"):] if spec.startswith("property:") else spec
1720
1782
  if ("." not in spec and "::" not in spec) or spec.startswith(("table:", "column:")):
1721
1783
  return []
1784
+ if "@" in spec: # `field:Type.prop@<line>`: one per-platform declaration (#219)
1785
+ return [r["id"] for r in st.q("SELECT id FROM nodes WHERE id=? AND kind='field'", (f"field:{spec}",))]
1722
1786
  # PHP: `User.name`, `User::$name`, `App\Models\User::$name` -> the `property:` node (fqn `App\Models\User::$name`)
1723
1787
  cls, _, prop = spec.replace("::$", "::").replace("::", ".").rpartition(".")
1724
1788
  php = f"{cls}::${prop.lstrip('$')}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cg-code-graph
3
- Version: 0.23.2
3
+ Version: 0.23.4
4
4
  Summary: cg: a code graph of routes, calls, data access and platform boundaries for agents and humans (CLI + MCP server)
5
5
  Author: cyberchronos00
6
6
  License-Expression: MIT
@@ -18,7 +18,7 @@ Requires-Dist: tree-sitter-c>=0.23
18
18
  Requires-Dist: tree-sitter-cpp>=0.23
19
19
  Requires-Dist: tree-sitter-kotlin>=1.0
20
20
  Requires-Dist: tree-sitter-java>=0.23
21
- Requires-Dist: tree-sitter-swift<0.7.4,>=0.6
21
+ Requires-Dist: tree-sitter-swift<0.8,>=0.6
22
22
  Provides-Extra: dev
23
23
  Requires-Dist: pytest>=8; extra == "dev"
24
24
  Provides-Extra: watch
@@ -275,8 +275,10 @@ tests/test_inherited_overrides.py
275
275
  tests/test_inline_guards.py
276
276
  tests/test_install_rules.py
277
277
  tests/test_issue_192.py
278
+ tests/test_issue_201.py
278
279
  tests/test_issue_202.py
279
280
  tests/test_issue_203.py
281
+ tests/test_issue_204.py
280
282
  tests/test_issue_205.py
281
283
  tests/test_issue_206.py
282
284
  tests/test_issue_207.py
@@ -285,6 +287,8 @@ tests/test_issue_209.py
285
287
  tests/test_issue_210.py
286
288
  tests/test_issue_211.py
287
289
  tests/test_issue_211_used_at.py
290
+ tests/test_issue_212.py
291
+ tests/test_issue_219.py
288
292
  tests/test_java.py
289
293
  tests/test_java_exact.py
290
294
  tests/test_jobs.py
@@ -7,7 +7,7 @@ tree-sitter-c>=0.23
7
7
  tree-sitter-cpp>=0.23
8
8
  tree-sitter-kotlin>=1.0
9
9
  tree-sitter-java>=0.23
10
- tree-sitter-swift<0.7.4,>=0.6
10
+ tree-sitter-swift<0.8,>=0.6
11
11
 
12
12
  [dev]
13
13
  pytest>=8
@@ -20,7 +20,7 @@ dependencies = [
20
20
  "tree-sitter-cpp>=0.23",
21
21
  "tree-sitter-kotlin>=1.0",
22
22
  "tree-sitter-java>=0.23",
23
- "tree-sitter-swift>=0.6,<0.7.4", # 0.7.4 (2026-10-04) changes the parse of two recovered shapes (#133)
23
+ "tree-sitter-swift>=0.6,<0.8",
24
24
  ]
25
25
 
26
26
  [project.optional-dependencies]