cg-code-graph 0.10.1__tar.gz → 0.11.0__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 (269) hide show
  1. {cg_code_graph-0.10.1/cg_code_graph.egg-info → cg_code_graph-0.11.0}/PKG-INFO +7 -6
  2. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/README.md +5 -4
  3. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0/cg_code_graph.egg-info}/PKG-INFO +7 -6
  4. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/cg_code_graph.egg-info/SOURCES.txt +5 -0
  5. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/cg_code_graph.egg-info/requires.txt +1 -1
  6. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/__init__.py +1 -1
  7. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/cli.py +5 -2
  8. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/coverage.py +19 -0
  9. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/indexer.py +12 -0
  10. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/mcp_server.py +4 -3
  11. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/platforms.py +3 -2
  12. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/cfamily/plugin.py +26 -1
  13. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/cfamily/syntax.py +104 -2
  14. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/kotlin/exact.py +10 -0
  15. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/kotlin/plugin.py +248 -32
  16. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/native/scipread.py +9 -1
  17. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/aitools.py +31 -1
  18. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/external.py +36 -7
  19. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/rust/plugin.py +44 -5
  20. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/rust/syntax.py +74 -3
  21. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/extractor/extract.mjs +128 -1
  22. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/extractor/fw.mjs +314 -2
  23. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/plugin.py +115 -1
  24. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/tsweb/data.py +3 -1
  25. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/protocols/builtin.py +25 -1
  26. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/protocols/view.py +33 -4
  27. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/query.py +17 -4
  28. cg_code_graph-0.11.0/codegraph/rpc.py +1217 -0
  29. cg_code_graph-0.11.0/codegraph/sockets.py +1144 -0
  30. cg_code_graph-0.11.0/codegraph/udp_apps.py +389 -0
  31. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/pyproject.toml +1 -1
  32. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ai_tools.py +103 -0
  33. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_coverage_ts_hint.py +27 -0
  34. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_external.py +113 -0
  35. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin.py +31 -0
  36. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_mixed.py +24 -0
  37. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_native_cfamily.py +77 -0
  38. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_native_rust.py +36 -0
  39. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_process_runs.py +38 -5
  40. cg_code_graph-0.11.0/tests/test_rpc.py +185 -0
  41. cg_code_graph-0.11.0/tests/test_sockets.py +169 -0
  42. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/LICENSE +0 -0
  43. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/MANIFEST.in +0 -0
  44. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/cg_code_graph.egg-info/dependency_links.txt +0 -0
  45. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/cg_code_graph.egg-info/entry_points.txt +0 -0
  46. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/cg_code_graph.egg-info/top_level.txt +0 -0
  47. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/aitools.py +0 -0
  48. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/apps.py +0 -0
  49. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/blindspots.py +0 -0
  50. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/bridges.py +0 -0
  51. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/concepts.py +0 -0
  52. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/config.py +0 -0
  53. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/__init__.py +0 -0
  54. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/cache.py +0 -0
  55. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/detect.py +0 -0
  56. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/extractors.py +0 -0
  57. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/fsutil.py +0 -0
  58. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/generated.py +0 -0
  59. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/model.py +0 -0
  60. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/paths.py +0 -0
  61. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/plugin.py +0 -0
  62. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/store.py +0 -0
  63. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/syntax_errors.py +0 -0
  64. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/doctor.py +0 -0
  65. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/external.py +0 -0
  66. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/link.py +0 -0
  67. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/lint_async.py +0 -0
  68. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/parity.py +0 -0
  69. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/parity_structure.py +0 -0
  70. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/payload.py +0 -0
  71. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plans.py +0 -0
  72. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/platform_scan.py +0 -0
  73. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/__init__.py +0 -0
  74. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/cfamily/__init__.py +0 -0
  75. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/__init__.py +0 -0
  76. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/bridges.py +0 -0
  77. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/extractor/bin/extract.dart +0 -0
  78. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/extractor/pubspec.lock +0 -0
  79. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/extractor/pubspec.yaml +0 -0
  80. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/http.py +0 -0
  81. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/models.py +0 -0
  82. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/plugin.py +0 -0
  83. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/program.py +0 -0
  84. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/__init__.py +0 -0
  85. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/extras.py +0 -0
  86. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/models.py +0 -0
  87. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/plugin.py +0 -0
  88. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/schemas.py +0 -0
  89. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/shapes.py +0 -0
  90. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/urls.py +0 -0
  91. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/express/__init__.py +0 -0
  92. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/express/plugin.py +0 -0
  93. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/flutter/__init__.py +0 -0
  94. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/flutter/plugin.py +0 -0
  95. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/kotlin/__init__.py +0 -0
  96. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/kotlin/reparse.py +0 -0
  97. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/laravel/__init__.py +0 -0
  98. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/laravel/broadcast.py +0 -0
  99. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/laravel/plugin.py +0 -0
  100. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/laravel/tests.py +0 -0
  101. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/laravel/values.py +0 -0
  102. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/native/__init__.py +0 -0
  103. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/native/gates.py +0 -0
  104. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/native/runner.py +0 -0
  105. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/native/ts.py +0 -0
  106. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nest/__init__.py +0 -0
  107. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nest/plugin.py +0 -0
  108. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nextjs/__init__.py +0 -0
  109. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nextjs/plugin.py +0 -0
  110. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nuxt/__init__.py +0 -0
  111. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nuxt/plugin.py +0 -0
  112. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/__init__.py +0 -0
  113. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/extractor/composer.json +0 -0
  114. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/extractor/composer.lock +0 -0
  115. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/extractor/extract.php +0 -0
  116. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/gating.py +0 -0
  117. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/plugin.py +0 -0
  118. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/strings.py +0 -0
  119. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/__init__.py +0 -0
  120. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/fields.py +0 -0
  121. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/plugin.py +0 -0
  122. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/refs.py +0 -0
  123. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/roots.py +0 -0
  124. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/socketio.py +0 -0
  125. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/subproc.py +0 -0
  126. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/tests.py +0 -0
  127. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/values.py +0 -0
  128. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/pyweb/__init__.py +0 -0
  129. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/pyweb/plugin.py +0 -0
  130. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/pyweb/values.py +0 -0
  131. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/rust/__init__.py +0 -0
  132. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/rust/cargo.py +0 -0
  133. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/scip/__init__.py +0 -0
  134. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/scip/importer.py +0 -0
  135. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/scip/scip.proto +0 -0
  136. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/scip/scip_pb2.py +0 -0
  137. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/stubs/__init__.py +0 -0
  138. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/stubs/plugins.py +0 -0
  139. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/__init__.py +0 -0
  140. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/baseurl.py +0 -0
  141. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/exact.py +0 -0
  142. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/indexstore.py +0 -0
  143. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/packages.py +0 -0
  144. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/plugin.py +0 -0
  145. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/__init__.py +0 -0
  146. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/baseurl.py +0 -0
  147. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/extractor/package-lock.json +0 -0
  148. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/extractor/package.json +0 -0
  149. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/tsweb/__init__.py +0 -0
  150. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/tsweb/common.py +0 -0
  151. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/__init__.py +0 -0
  152. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/c_cpp.yaml +0 -0
  153. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/common.yaml +0 -0
  154. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/dart.yaml +0 -0
  155. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/django-ninja.yaml +0 -0
  156. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/django.yaml +0 -0
  157. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/djangorestframework.yaml +0 -0
  158. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/express.yaml +0 -0
  159. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/kotlin.yaml +0 -0
  160. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/laravel.yaml +0 -0
  161. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/nest.yaml +0 -0
  162. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/nextjs.yaml +0 -0
  163. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/nuxt.yaml +0 -0
  164. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/php.yaml +0 -0
  165. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/python.yaml +0 -0
  166. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/rust.yaml +0 -0
  167. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/swift.yaml +0 -0
  168. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/typescript.yaml +0 -0
  169. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/process_runs.py +0 -0
  170. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/protocols/__init__.py +0 -0
  171. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/protocols/matchers.py +0 -0
  172. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/realtime.py +0 -0
  173. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/roundtrip.py +0 -0
  174. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/routes.py +0 -0
  175. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/starters.py +0 -0
  176. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/tests_index.py +0 -0
  177. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/__init__.py +0 -0
  178. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/graph.py +0 -0
  179. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/server.py +0 -0
  180. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/app.css +0 -0
  181. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/app.js +0 -0
  182. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/index.html +0 -0
  183. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/layered.js +0 -0
  184. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/vendor/VERSIONS.txt +0 -0
  185. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/vendor/cose-base.js +0 -0
  186. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/vendor/cytoscape-fcose.js +0 -0
  187. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/vendor/cytoscape.min.js +0 -0
  188. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/vendor/layout-base.js +0 -0
  189. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/tools/package-lock.json +0 -0
  190. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/tools/package.json +0 -0
  191. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/tools/shoot.mjs +0 -0
  192. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/xcode.py +0 -0
  193. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/setup.cfg +0 -0
  194. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_bridges.py +0 -0
  195. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_bridges_pigeon_monorepo.py +0 -0
  196. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_cache_clean.py +0 -0
  197. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_cache_invalidation.py +0 -0
  198. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_channels_tests.py +0 -0
  199. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_cli_output.py +0 -0
  200. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_completeness.py +0 -0
  201. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_config_extras.py +0 -0
  202. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_coverage.py +0 -0
  203. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_dispatch_interfaces.py +0 -0
  204. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_django_flutter.py +0 -0
  205. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_enum_constants.py +0 -0
  206. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_gating.py +0 -0
  207. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_generated.py +0 -0
  208. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_impact_overrides.py +0 -0
  209. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_index_isolation.py +0 -0
  210. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_inherited_overrides.py +0 -0
  211. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_binding.py +0 -0
  212. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_exact.py +0 -0
  213. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_fields.py +0 -0
  214. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_nav_consts.py +0 -0
  215. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_props.py +0 -0
  216. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_laravel_determinism.py +0 -0
  217. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_lint_async.py +0 -0
  218. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_mcp.py +0 -0
  219. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_mcp_index.py +0 -0
  220. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_native_concurrency.py +0 -0
  221. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_nuxt_rootsrc.py +0 -0
  222. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_packaging.py +0 -0
  223. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_parity.py +0 -0
  224. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_parity_structure.py +0 -0
  225. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_php_props.py +0 -0
  226. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_plans.py +0 -0
  227. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_platform_gaps.py +0 -0
  228. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_platform_type_variants.py +0 -0
  229. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_platforms.py +0 -0
  230. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_platforms_apple.py +0 -0
  231. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_presets_config.py +0 -0
  232. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_protocols.py +0 -0
  233. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_app_tests_module.py +0 -0
  234. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_collection_chains.py +0 -0
  235. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_compat.py +0 -0
  236. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_entry_refs.py +0 -0
  237. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_fields.py +0 -0
  238. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_infer_cycles.py +0 -0
  239. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_roots.py +0 -0
  240. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_subprocess_tests.py +0 -0
  241. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_tests.py +0 -0
  242. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_web_hosts.py +0 -0
  243. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_web_routes.py +0 -0
  244. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_web_routes_more.py +0 -0
  245. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_roundtrip.py +0 -0
  246. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_routes_search_explain.py +0 -0
  247. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_scip_health.py +0 -0
  248. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_starters_budget.py +0 -0
  249. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift.py +0 -0
  250. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_binding.py +0 -0
  251. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_exact.py +0 -0
  252. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_facts.py +0 -0
  253. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_fields.py +0 -0
  254. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_modules.py +0 -0
  255. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_more.py +0 -0
  256. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_nav_values.py +0 -0
  257. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_parse_errors.py +0 -0
  258. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_props.py +0 -0
  259. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_sdk.py +0 -0
  260. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_testing.py +0 -0
  261. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_values.py +0 -0
  262. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_tests_scope.py +0 -0
  263. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ts_fields.py +0 -0
  264. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ts_fields_js_vue.py +0 -0
  265. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ts_file_specs.py +0 -0
  266. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ts_frameworks.py +0 -0
  267. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ts_nuxt.py +0 -0
  268. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_values.py +0 -0
  269. {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_viz.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cg-code-graph
3
- Version: 0.10.1
3
+ Version: 0.11.0
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
@@ -17,7 +17,7 @@ Requires-Dist: tree-sitter-rust>=0.23
17
17
  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
- Requires-Dist: tree-sitter-swift>=0.6
20
+ Requires-Dist: tree-sitter-swift<0.7.4,>=0.6
21
21
  Provides-Extra: dev
22
22
  Requires-Dist: pytest>=8; extra == "dev"
23
23
  Dynamic: license-file
@@ -93,10 +93,11 @@ other tools; see [Prerequisites per language](#prerequisites-per-language).
93
93
  options and updates):
94
94
 
95
95
  ```bash
96
- curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
97
- # or: uv tool install git+https://github.com/cyberchronos00/code-graph
98
- # or: pipx install git+https://github.com/cyberchronos00/code-graph
99
- # or from PyPI: pip install cg-code-graph (uv tool install cg-code-graph / pipx install cg-code-graph)
96
+ pipx install cg-code-graph # or: uv tool install cg-code-graph (PyPI; the commands are cg and cg-mcp)
97
+ # or the script (also installs exact-mode tools with --with c,rust,...):
98
+ # curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
99
+ # or the latest commit: uv tool install git+https://github.com/cyberchronos00/code-graph
100
+ # or: pipx install git+https://github.com/cyberchronos00/code-graph
100
101
  cg doctor # what indexes exact / heuristic on this machine, and what to install for the rest
101
102
  git clone https://github.com/cyberchronos00/code-graph.git && cd code-graph # the sample apps used below
102
103
  ```
@@ -69,10 +69,11 @@ other tools; see [Prerequisites per language](#prerequisites-per-language).
69
69
  options and updates):
70
70
 
71
71
  ```bash
72
- curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
73
- # or: uv tool install git+https://github.com/cyberchronos00/code-graph
74
- # or: pipx install git+https://github.com/cyberchronos00/code-graph
75
- # or from PyPI: pip install cg-code-graph (uv tool install cg-code-graph / pipx install cg-code-graph)
72
+ pipx install cg-code-graph # or: uv tool install cg-code-graph (PyPI; the commands are cg and cg-mcp)
73
+ # or the script (also installs exact-mode tools with --with c,rust,...):
74
+ # curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
75
+ # or the latest commit: uv tool install git+https://github.com/cyberchronos00/code-graph
76
+ # or: pipx install git+https://github.com/cyberchronos00/code-graph
76
77
  cg doctor # what indexes exact / heuristic on this machine, and what to install for the rest
77
78
  git clone https://github.com/cyberchronos00/code-graph.git && cd code-graph # the sample apps used below
78
79
  ```
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cg-code-graph
3
- Version: 0.10.1
3
+ Version: 0.11.0
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
@@ -17,7 +17,7 @@ Requires-Dist: tree-sitter-rust>=0.23
17
17
  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
- Requires-Dist: tree-sitter-swift>=0.6
20
+ Requires-Dist: tree-sitter-swift<0.7.4,>=0.6
21
21
  Provides-Extra: dev
22
22
  Requires-Dist: pytest>=8; extra == "dev"
23
23
  Dynamic: license-file
@@ -93,10 +93,11 @@ other tools; see [Prerequisites per language](#prerequisites-per-language).
93
93
  options and updates):
94
94
 
95
95
  ```bash
96
- curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
97
- # or: uv tool install git+https://github.com/cyberchronos00/code-graph
98
- # or: pipx install git+https://github.com/cyberchronos00/code-graph
99
- # or from PyPI: pip install cg-code-graph (uv tool install cg-code-graph / pipx install cg-code-graph)
96
+ pipx install cg-code-graph # or: uv tool install cg-code-graph (PyPI; the commands are cg and cg-mcp)
97
+ # or the script (also installs exact-mode tools with --with c,rust,...):
98
+ # curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
99
+ # or the latest commit: uv tool install git+https://github.com/cyberchronos00/code-graph
100
+ # or: pipx install git+https://github.com/cyberchronos00/code-graph
100
101
  cg doctor # what indexes exact / heuristic on this machine, and what to install for the rest
101
102
  git clone https://github.com/cyberchronos00/code-graph.git && cd code-graph # the sample apps used below
102
103
  ```
@@ -34,8 +34,11 @@ codegraph/query.py
34
34
  codegraph/realtime.py
35
35
  codegraph/roundtrip.py
36
36
  codegraph/routes.py
37
+ codegraph/rpc.py
38
+ codegraph/sockets.py
37
39
  codegraph/starters.py
38
40
  codegraph/tests_index.py
41
+ codegraph/udp_apps.py
39
42
  codegraph/xcode.py
40
43
  codegraph/core/__init__.py
41
44
  codegraph/core/cache.py
@@ -237,7 +240,9 @@ tests/test_python_web_routes.py
237
240
  tests/test_python_web_routes_more.py
238
241
  tests/test_roundtrip.py
239
242
  tests/test_routes_search_explain.py
243
+ tests/test_rpc.py
240
244
  tests/test_scip_health.py
245
+ tests/test_sockets.py
241
246
  tests/test_starters_budget.py
242
247
  tests/test_swift.py
243
248
  tests/test_swift_binding.py
@@ -6,7 +6,7 @@ tree-sitter-rust>=0.23
6
6
  tree-sitter-c>=0.23
7
7
  tree-sitter-cpp>=0.23
8
8
  tree-sitter-kotlin>=1.0
9
- tree-sitter-swift>=0.6
9
+ tree-sitter-swift<0.7.4,>=0.6
10
10
 
11
11
  [dev]
12
12
  pytest>=8
@@ -1,2 +1,2 @@
1
1
  """code-graph: deterministic code knowledge graph (beta)."""
2
- __version__ = "0.10.1"
2
+ __version__ = "0.11.0"
@@ -18,7 +18,7 @@
18
18
  python -m codegraph.cli bridges [PATTERN] --db ... [--protocol capacitor] [--unmatched] (web / native bridge calls)
19
19
  python -m codegraph.cli external [PATTERN] --db ... [--protocol P] [--source S] [--tls-off] (databases, caches, brokers, mail ... and who reaches them)
20
20
  python -m codegraph.cli tools [PATTERN] --db ... [--framework F] [--agent A] [--unmatched] (LLM / MCP tools: handler, tables, agents, checks)
21
- python -m codegraph.cli protocols [PATTERN] --db ... [--protocol P] [--side send|receive] [--unmatched] (every protocol endpoint: senders, receivers, checks)
21
+ python -m codegraph.cli protocols [PATTERN] --db ... [--protocol P] [--side send|receive] [--unmatched] [--listeners] (every protocol endpoint: senders, receivers, checks; listening sockets)
22
22
  python -m codegraph.cli platforms [summary|divergence] --db ... [--target ios] (platform-specific code, gaps between variants)
23
23
  reaches / impact / downstream / path / routes / search take --platform TARGET: only code built for that target
24
24
  spec forms: table.column | connection:<name> (glob *) | env:<KEY*> | config:<a.b> | Class.method or Class::method (either
@@ -154,6 +154,8 @@ def main(argv=None):
154
154
  p.add_argument("--side", choices=["send", "receive"]); p.add_argument("--max-items", type=int, default=60)
155
155
  p.add_argument("--unmatched", action="store_true", help="only endpoints with a check (no_receiver, no_sender, ambiguous, "
156
156
  "schema_mismatch, unguarded) or an external peer")
157
+ p.add_argument("--listeners", action="store_true", help="every listening TCP / UDP socket with its bind address, exposure "
158
+ "(all interfaces / loopback / specific) and handler")
157
159
  p = sub.add_parser("external", help="external systems (databases, caches, brokers, mail, directories, file transfer, object "
158
160
  "stores, third-party HTTP hosts): users, entry points, address and credential sources")
159
161
  p.add_argument("pattern", nargs="?", help="external id, substring or glob (`external:postgres:*`, `redis`)")
@@ -429,7 +431,8 @@ def main(argv=None):
429
431
  return
430
432
  if a.cmd == "protocols":
431
433
  from .protocols.view import protocols, render_protocols
432
- res = protocols(st, a.pattern, protocol=a.protocol, side=a.side, unmatched=a.unmatched, max_items=max(a.max_items, 200) if a.json else a.max_items)
434
+ res = protocols(st, a.pattern, protocol=a.protocol, side=a.side, unmatched=a.unmatched, max_items=max(a.max_items, 200) if a.json else a.max_items,
435
+ listeners=a.listeners)
433
436
  print(json.dumps(res, indent=1, default=str) if a.json else render_protocols(res, max_items=a.max_items))
434
437
  return
435
438
  if a.cmd == "tests":
@@ -6,6 +6,7 @@ its normal search and file reading."""
6
6
  from __future__ import annotations
7
7
 
8
8
  import os
9
+ import re
9
10
  from collections import Counter
10
11
 
11
12
  from . import presets
@@ -188,12 +189,27 @@ def scan(root: str | Path) -> Counter:
188
189
  return scan_tree(root).counts
189
190
 
190
191
 
192
+ _TOOL_FILE = re.compile(r"(?:^|/)(?:[^/]*\.config\.[cm]?[jt]sx?|\.[^/]*rc\.[cm]?js|[Gg]runtfile\.js|[Gg]ulpfile\.[cm]?js)$")
193
+ _TEST_NAME = re.compile(r"(?:\.(?:test|spec)\.[cm]?[jt]sx?$|(?:^|/)__tests__/|\.d\.[cm]?ts$)") # + declarations
194
+
195
+
191
196
  def file_completeness(discovered: list[str], report: dict) -> dict:
192
197
  """Bucket every discovered file of one language from the plugin's per-file report
193
198
  ({seen, parse_failed, skipped_oversize, unmapped, excluded}). A discovered file the plugin never looked at
194
199
  (its own skip list) is `excluded`."""
195
200
  sets = {b: set(report.get(b) or ()) for b in BUCKETS}
196
201
  seen = set(report.get("seen") or ())
202
+ roots = report.get("roots")
203
+ if roots is not None:
204
+ # a plugin that reads only some directories (TypeScript: source dirs, bin / script files, test trees): a file
205
+ # outside all of them was never read, so it is unmapped (not indexed), not a deliberate exclusion. Tool
206
+ # configuration (`vite.config.ts`, `.eslintrc.js`) and test files by name stay excluded (#106)
207
+ dirs = tuple(r for r in roots if r.endswith("/"))
208
+ files = {r for r in roots if not r.endswith("/")}
209
+ for f in discovered:
210
+ if f in seen or f in files or f.startswith(dirs) or _TOOL_FILE.search(f) or _TEST_NAME.search(f):
211
+ continue
212
+ sets["unmapped"].add(f)
197
213
  out = {b: [] for b in BUCKETS}
198
214
  indexed = 0
199
215
  for f in sorted(discovered):
@@ -296,6 +312,9 @@ def compute(root: str | Path, plugins: dict, scip_imported: bool = False, report
296
312
  e["files_complete"] = missing_files(e) == 0
297
313
  if not e["files_complete"] and lang == "python" and e.get("unmapped"):
298
314
  e["hint"] = _python_unmapped_hint(st)
315
+ elif not e["files_complete"] and lang == "typescript" and e.get("unmapped"):
316
+ e["hint"] = ("files outside the source dirs and test trees were not read: list the directories that hold "
317
+ "source in .cg.yaml `include` (or a tsconfig.json `include`) and re-index")
299
318
  se = (rep or {}).get("syntax_errors")
300
319
  if isinstance(se, list) and se and status not in ("skipped", "not_indexed"):
301
320
  # files parsed with syntax errors (#73): error spans and the declarations lost there
@@ -234,6 +234,18 @@ def index_project(root: str | Path, db_path: str | Path, name: str | None = None
234
234
  from .process_runs import apply as apply_process_runs
235
235
  if (pr := apply_process_runs(project, builder)):
236
236
  stats["process_runs"] = pr
237
+ # raw TCP / UDP sockets paired by port (#39): endpoint:tcp:<port> / endpoint:udp:<port>
238
+ from .sockets import apply as apply_sockets
239
+ t_so = time.time()
240
+ if (so := apply_sockets(project, builder)):
241
+ so["seconds"] = round(time.time() - t_so, 2)
242
+ stats["sockets"] = so
243
+ # RPC contracts (#33): gRPC services of the .proto files, their implementations and stub calls
244
+ from .rpc import apply as apply_rpc
245
+ t_rpc = time.time()
246
+ if (rp := apply_rpc(project, builder)):
247
+ rp["seconds"] = round(time.time() - t_rpc, 2)
248
+ stats["rpc"] = rp
237
249
  # test code (tests/, *.spec.ts ...) never feeds the application graph: its edges become TEST_* kinds
238
250
  from .tests_index import isolate_tests
239
251
  stats["tests"] = isolate_tests(builder)
@@ -698,20 +698,21 @@ def bridges(pattern: str | None = None, protocol: str | None = None, unmatched:
698
698
 
699
699
  @tool
700
700
  def protocol_links(pattern: str | None = None, protocol: str | None = None, side: str | None = None,
701
- unmatched: bool = False) -> str:
701
+ unmatched: bool = False, listeners: bool = False) -> str:
702
702
  """Every protocol endpoint in one view (#31 model): HTTP client endpoints and routes (http / ws / graphql), Pusher
703
703
  broadcast channels and subscriptions, NestJS microservice messages (nest-rpc / nest-event / nest-ws / grpc), job
704
704
  queues (bull, laravel-queue, celery), application events (laravel-event, nest-event-emitter, django-signal), web /
705
705
  native bridges and desktop IPC (capacitor, react-native, flutter, electron-ipc, tauri ...) and the generic
706
706
  endpoint:<protocol>:<name> nodes (code -SENDS_TO-> endpoint -RECEIVED_BY-> handler, MATCHES_ENDPOINT for
707
- wildcard / template matches; MQTT, NATS, AMQP, Kafka, Redis pub/sub, Socket.IO). Without arguments: one line per
707
+ wildcard / template matches; MQTT, NATS, AMQP, Kafka, Redis pub/sub, Socket.IO, raw TCP / UDP sockets by port).
708
+ listeners: every listening TCP / UDP socket with bind address, exposure and handler. Without arguments: one line per
708
709
  protocol (endpoints, send / receive sides, linked, check counts). With a pattern (name, id, substring or glob) /
709
710
  protocol / side (send | receive) / unmatched: one block per endpoint with senders (and, for a few endpoints, the
710
711
  entry points reaching them), receivers, guards, matches and checks: no_receiver, no_sender, test_sender_only,
711
712
  ambiguous, schema_mismatch, unguarded, external (.cg.yaml protocols.external, third-party origins, bridge
712
713
  packages). impact / reaches / path / downstream follow SENDS_TO / RECEIVED_BY / MATCHES_ENDPOINT as usual."""
713
714
  from .protocols.view import protocols as _pr, render_protocols
714
- return render_protocols(_pr(_st(), pattern, protocol=protocol, side=side, unmatched=unmatched))
715
+ return render_protocols(_pr(_st(), pattern, protocol=protocol, side=side, unmatched=unmatched, listeners=listeners))
715
716
 
716
717
 
717
718
  @tool
@@ -944,11 +944,12 @@ def _alt_groups(builder, nvals: dict) -> dict[str, list[str]]:
944
944
  if g in alts and any(builder.nodes[i].file == file or builder.nodes[i].kind == "macro" for i in alts[g]):
945
945
  alts[g] += alts.pop(k)
946
946
  # same-named functions of separate programs (libuv docs/code/*/main.c `alloc_buffer`, each file with its own
947
- # main()) are not one symbol: members in two or more files that define main() leave the group (#63)
947
+ # main()) are not one symbol: members in two or more files that define main() leave the group (#63); the same
948
+ # holds for the classes and structs of those programs (grpc's examples/cpp: a `GreeterServiceImpl` per server, #131)
948
949
  mains = {n.file for n in builder.nodes.values() if n.lang in ("c", "cpp") and n.kind == "function" and n.name == "main"}
949
950
  if mains:
950
951
  for k, ids in list(alts.items()):
951
- if not k.startswith("c-fn:"):
952
+ if not k.startswith("c-fn:") and not all(builder.nodes[i].lang in ("c", "cpp") for i in ids):
952
953
  continue
953
954
  prog = [i for i in ids if builder.nodes[i].file in mains]
954
955
  if len({builder.nodes[i].file for i in prog}) >= 2:
@@ -655,6 +655,20 @@ class CFamilyPlugin(LanguagePlugin):
655
655
  if it.kind in TYPES:
656
656
  types[it.name].append(it)
657
657
 
658
+ cls_files = defaultdict(set)
659
+ for it in self.items:
660
+ if it.kind in TYPES:
661
+ cls_files[it.qual].add(it.file)
662
+
663
+ def _visible(m, rel) -> bool:
664
+ """A method's class defined only in other source files (not headers) that `rel` does not include is
665
+ out of reach of a member call there (`writer->Write(..)` on a library type is not `HelloReactor::Write`
666
+ of another program's .cc)."""
667
+ files = cls_files.get(m.qual.rsplit("::", 1)[0]) if "::" in m.qual else None
668
+ if not files:
669
+ return True
670
+ return any(f == rel or os.path.splitext(f)[1] in HDR_EXT for f in files) or bool(files & self._included(rel))
671
+
658
672
  def pick(cands, rel):
659
673
  if not cands:
660
674
  return []
@@ -685,7 +699,8 @@ class CFamilyPlugin(LanguagePlugin):
685
699
  if name in macros and macros[name].attrs.get("function_like"):
686
700
  targets = [macros[name]]
687
701
  else:
688
- targets = pick(funcs.get(name), rel) or (pick(methods.get(name), rel) if owner.kind == "method" else [])
702
+ targets = pick(funcs.get(name), rel) or (
703
+ [m for m in pick(methods.get(name), rel) if _visible(m, rel)] if owner.kind == "method" else [])
689
704
  elif form == "qualified":
690
705
  q = quals.get(txt) or next((v for k, v in quals.items() if k.endswith("::" + txt)), None)
691
706
  targets = [q] if q else []
@@ -696,6 +711,12 @@ class CFamilyPlugin(LanguagePlugin):
696
711
  roots = [m for m in c if self._is_virtual(m) and not self._is_override(m)]
697
712
  c = roots if len(roots) == 1 else c
698
713
  targets = c if len(c) == 1 else []
714
+ # the only method of that name, but its class is defined only in another source file: not the
715
+ # receiver here. (Dropping such candidates before the uniqueness test would turn `s.data()` on a
716
+ # std::string into leveldb's `Slice::data`, so it only removes.)
717
+ if targets and not _visible(targets[0], rel):
718
+ stats["heuristic_member_call_class_not_visible"] += 1
719
+ targets = []
699
720
  if not targets:
700
721
  stats["heuristic_unresolved_calls"] += 1
701
722
  continue
@@ -720,6 +741,10 @@ class CFamilyPlugin(LanguagePlugin):
720
741
  if owner is None:
721
742
  continue
722
743
  for x in pick(types.get(name), rel):
744
+ # a type is not linked across files: one defined only in another source file is not this one
745
+ if x.file != rel and os.path.splitext(x.file)[1] not in HDR_EXT and x.file not in self._included(rel):
746
+ stats["heuristic_type_ref_not_visible"] += 1
747
+ continue
723
748
  self._ref_edge(self.nid(owner), self.nid(x), rel, line, HEURISTIC, "", stats)
724
749
 
725
750
  def _is_virtual(self, it) -> bool:
@@ -153,7 +153,17 @@ class Extractor:
153
153
  self.f = CFile(path, lang)
154
154
 
155
155
  def run(self) -> CFile:
156
- tree = parser(self.f.lang).parse(mask_annotations(self.src, self.blank) if self.blank is not None else self.src)
156
+ src = mask_lock_annotations(mask_annotations(self.src, self.blank) if self.blank is not None else self.src)
157
+ tree = parser(self.f.lang).parse(src)
158
+ if tree.root_node.has_error:
159
+ # `ABSL_FLAG(uint16_t, port, 50051, "..");` at file level parses as a broken function definition that
160
+ # runs to the next `}` and swallows the class after it (#131): blank such macro statements and keep
161
+ # the parse that loses fewer lines
162
+ masked = mask_macro_statements(src)
163
+ if masked != src:
164
+ t2 = parser(self.f.lang).parse(masked)
165
+ if _error_lines(t2.root_node) < _error_lines(tree.root_node):
166
+ tree = t2
157
167
  self.f.lines = self.src.decode("utf-8", "replace").split("\n")
158
168
  if tree.root_node.has_error:
159
169
  from ...core.syntax_errors import tree_spans
@@ -200,7 +210,8 @@ class Extractor:
200
210
  sub = Extractor(self.path, chunk.encode("utf-8"), self.f.lang, self.module, self.blank)
201
211
  sub.f = self.f
202
212
  n0 = len(self.f.items)
203
- t = parser(self.f.lang).parse(mask_annotations(sub.src, self.blank) if self.blank is not None else sub.src)
213
+ t = parser(self.f.lang).parse(mask_lock_annotations(
214
+ mask_annotations(sub.src, self.blank) if self.blank is not None else sub.src))
204
215
  if not t.root_node.has_error:
205
216
  sub.container(t.root_node, {"ns": [], "cls": None, "access": None, "anon": False, "extern_c": False})
206
217
  if len(self.f.items) == n0:
@@ -879,3 +890,94 @@ def mask_annotations(src: bytes, rx: re.Pattern) -> bytes:
879
890
  cont = directive and line.rstrip().endswith(b"\\")
880
891
  out.append(line if directive else rx.sub(lambda m: b" " * (m.end() - m.start()), line))
881
892
  return b"\n".join(out)
893
+
894
+
895
+ MACRO_STMT = re.compile(rb"^[A-Z][A-Z0-9_]*[ \t]*\(", re.M)
896
+
897
+
898
+ def mask_macro_statements(src: bytes) -> bytes:
899
+ """File-level `NAME(...);` statements of an upper-case macro starting in column 0 blanked (same length, newlines
900
+ kept). Strings and comments in the arguments are skipped while matching the parentheses."""
901
+ out = bytearray(src)
902
+ for m in MACRO_STMT.finditer(src):
903
+ i, depth, n = m.end() - 1, 0, len(src)
904
+ while i < n:
905
+ ch = src[i:i + 1]
906
+ if ch in (b'"', b"'"):
907
+ j = i + 1
908
+ while j < n and src[j:j + 1] not in (ch, b"\n"):
909
+ j += 2 if src[j:j + 1] == b"\\" else 1
910
+ i = j + 1
911
+ continue
912
+ if src[i:i + 2] == b"/*":
913
+ j = src.find(b"*/", i + 2)
914
+ i = n if j < 0 else j + 2
915
+ continue
916
+ if src[i:i + 2] == b"//":
917
+ j = src.find(b"\n", i)
918
+ i = n if j < 0 else j
919
+ continue
920
+ if ch == b"(":
921
+ depth += 1
922
+ elif ch == b")":
923
+ depth -= 1
924
+ if depth == 0:
925
+ break
926
+ elif ch in (b"{", b"}", b";"):
927
+ i = n
928
+ break
929
+ i += 1
930
+ if i >= n:
931
+ continue
932
+ rest = re.match(rb"[ \t]*;", src[i + 1:i + 40])
933
+ if not rest:
934
+ continue
935
+ end = i + 1 + rest.end()
936
+ for k in range(m.start(), end):
937
+ if out[k] != 10:
938
+ out[k] = 32
939
+ return bytes(out)
940
+
941
+
942
+ def _error_lines(root) -> int:
943
+ from ...core.syntax_errors import tree_spans
944
+ return sum(b - a + 1 for a, b in tree_spans(root))
945
+
946
+
947
+ # Clang thread-safety annotations after a declarator: `void Write() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&mu_) {`,
948
+ # `bool done_ GUARDED_BY(mu_) = false;`, `GTEST_LOCK_EXCLUDED_(mutex_)`. tree-sitter reads them as the declarator
949
+ # (a method `mu_`), so they are blanked (same length) like the name-only annotation macros.
950
+ LOCK_ANNOT = re.compile(
951
+ rb"\b(?:(?:[A-Z][A-Z0-9]*_)*(?:EXCLUSIVE_LOCKS_REQUIRED|SHARED_LOCKS_REQUIRED|LOCKS_EXCLUDED|LOCK_EXCLUDED|"
952
+ rb"LOCK_RETURNED|PT_GUARDED_BY|GUARDED_BY|ACQUIRED_BEFORE|ACQUIRED_AFTER|EXCLUSIVE_LOCK_FUNCTION|SHARED_LOCK_FUNCTION|"
953
+ rb"UNLOCK_FUNCTION|EXCLUSIVE_TRYLOCK_FUNCTION|SHARED_TRYLOCK_FUNCTION|ASSERT_EXCLUSIVE_LOCK|ASSERT_SHARED_LOCK|"
954
+ rb"CAPABILITY)|"
955
+ rb"[A-Z][A-Z0-9]*_(?:REQUIRES_SHARED|REQUIRES|EXCLUDES|ACQUIRE_SHARED|ACQUIRE|RELEASE_SHARED|RELEASE|TRY_ACQUIRE|"
956
+ rb"RETURN_CAPABILITY|ASSERT_CAPABILITY))_?[ \t]*\((?:[^()\n]|\([^()\n]*\))*\)")
957
+
958
+
959
+ LOCK_NAME = re.compile(rb"\b(?:[A-Z][A-Z0-9]*_)*(?:SCOPED_LOCKABLE|LOCKABLE|SCOPED_CAPABILITY|NO_THREAD_SAFETY_ANALYSIS)_?\b(?![ \t]*\()")
960
+
961
+
962
+ def mask_lock_annotations(src: bytes) -> bytes:
963
+ if b"LOCK" not in src and b"GUARDED_BY" not in src and b"_REQUIRES" not in src and b"_EXCLUDES" not in src \
964
+ and b"_ACQUIRE" not in src and b"_RELEASE" not in src and b"CAPABILITY" not in src:
965
+ return src
966
+ out = bytearray(src)
967
+ for m in LOCK_ANNOT.finditer(src):
968
+ ls = src.rfind(b"\n", 0, m.start()) + 1
969
+ before = src[ls:m.start()].rstrip()
970
+ if not before.strip() and ls > 0:
971
+ # on a line of its own after the declarator: `void Mock::Allow(uintptr_t obj)\n GTEST_LOCK_EXCLUDED_(mu) {`
972
+ pl = src[src.rfind(b"\n", 0, ls - 1) + 1:ls - 1].rstrip()
973
+ before = pl if re.search(rb"(?:\)|\bconst|\boverride|\bnoexcept)$", pl) and not pl.lstrip().startswith(b"#") else b""
974
+ if before.lstrip().startswith(b"#") or not before or not re.search(rb"[\w)&*\]]$", before):
975
+ continue # a directive, or not after a declarator (a statement / call of its own)
976
+ if re.search(rb"\b(?:return|if|while|case)\b[^;{}]*$", before):
977
+ continue
978
+ out[m.start():m.end()] = b" " * (m.end() - m.start())
979
+ for m in LOCK_NAME.finditer(src): # `class SCOPED_LOCKABLE MutexLock {`, `void f() NO_THREAD_SAFETY_ANALYSIS {`
980
+ ls = src.rfind(b"\n", 0, m.start()) + 1
981
+ if not src[ls:m.start()].lstrip().startswith(b"#"):
982
+ out[m.start():m.end()] = b" " * (m.end() - m.start())
983
+ return bytes(out)
@@ -40,6 +40,7 @@ CALL_KINDS = ("CALLS", "INSTANTIATES")
40
40
  # `valueOf` / `entries` (`<init>` and `<anonymous object at ...>` start with "<")
41
41
  SYNTHETIC = re.compile(r"copy|component\d+|values|valueOf|entries")
42
42
  FACADE = re.compile(r"(?<=/)\w+Kt#(?=[^#]+\.$)") # the JVM facade class of a Kotlin file's top-level functions
43
+ ACCESSOR = re.compile(r"[gs]et[A-Z]\w*") # a property accessor's JVM name
43
44
 
44
45
 
45
46
  def _has_kotlin_docs(path: str) -> bool:
@@ -301,10 +302,19 @@ class ExactLayer:
301
302
  if d.name == name and d.line <= o.line + 1 <= d.end and (suf == "#") == (d.kind == "class"):
302
303
  nid = d.id
303
304
  break
305
+ if nid is None and suf == "(" and ACCESSOR.fullmatch(name):
306
+ # an explicit `get()` / `set(v)` accessor: scip-java defines `getX().` at the keyword (0.13)
307
+ pn = name[3].lower() + name[4:]
308
+ for d in by_file.get(rel, ()):
309
+ if d.name == pn and d.id in self.p.props and d.line <= o.line + 1 <= d.end:
310
+ nid = d.id
311
+ break
304
312
  if nid is None:
305
313
  if (suf in ("(", "#") and not name.startswith("<") and not SYNTHETIC.fullmatch(name)
306
314
  and (rel, o.line, o.col) not in term_pos):
307
315
  unmatched += 1
316
+ if len(st.setdefault("scip_defs_unmatched_samples", [])) < 10:
317
+ st["scip_defs_unmatched_samples"].append(f"{rel}:{o.line + 1}:{o.col + 1} {name}{suf}")
308
318
  continue
309
319
  sym[s] = nid
310
320
  matched += 1