cg-code-graph 0.23.0__tar.gz → 0.23.2__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 (404) hide show
  1. {cg_code_graph-0.23.0/cg_code_graph.egg-info → cg_code_graph-0.23.2}/PKG-INFO +2 -2
  2. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/README.md +1 -1
  3. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/__init__.py +1 -1
  4. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/cli.py +26 -1
  5. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/model.py +1 -1
  6. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/coverage.py +13 -0
  7. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/doctor.py +13 -0
  8. cg_code_graph-0.23.2/cg_code_graph/install_rules.py +88 -0
  9. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/link.py +22 -5
  10. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/mcp_install.py +18 -1
  11. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/mcp_server.py +36 -19
  12. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/nuxt/plugin.py +369 -21
  13. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/ts/extractor/extract.mjs +23 -3
  14. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/query.py +36 -5
  15. cg_code_graph-0.23.2/cg_code_graph/update_check.py +122 -0
  16. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2/cg_code_graph.egg-info}/PKG-INFO +2 -2
  17. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph.egg-info/SOURCES.txt +8 -0
  18. cg_code_graph-0.23.2/tests/test_install_rules.py +82 -0
  19. cg_code_graph-0.23.2/tests/test_link_origin.py +80 -0
  20. cg_code_graph-0.23.2/tests/test_mcp_instructions.py +35 -0
  21. cg_code_graph-0.23.2/tests/test_nuxt_i18n.py +89 -0
  22. cg_code_graph-0.23.2/tests/test_nuxt_nitro.py +103 -0
  23. cg_code_graph-0.23.2/tests/test_nuxt_side_dirs.py +76 -0
  24. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_snippet.py +4 -1
  25. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_ts_nuxt.py +1 -1
  26. cg_code_graph-0.23.2/tests/test_update_check.py +96 -0
  27. cg_code_graph-0.23.0/tests/test_link_origin.py +0 -39
  28. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/LICENSE +0 -0
  29. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/MANIFEST.in +0 -0
  30. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/__main__.py +0 -0
  31. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/affected.py +0 -0
  32. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/agent_rules.py +0 -0
  33. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/agents.py +0 -0
  34. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/aitools.py +0 -0
  35. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/android_ipc.py +0 -0
  36. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/apple_ipc.py +0 -0
  37. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/apps.py +0 -0
  38. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/blindspots.py +0 -0
  39. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/bridges.py +0 -0
  40. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/brokers.py +0 -0
  41. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/concepts.py +0 -0
  42. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/config.py +0 -0
  43. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/__init__.py +0 -0
  44. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/cache.py +0 -0
  45. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/detect.py +0 -0
  46. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/env.py +0 -0
  47. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/extractors.py +0 -0
  48. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/fsutil.py +0 -0
  49. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/generated.py +0 -0
  50. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/paths.py +0 -0
  51. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/plugin.py +0 -0
  52. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/redact.py +0 -0
  53. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/store.py +0 -0
  54. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/core/syntax_errors.py +0 -0
  55. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/dart_isolates.py +0 -0
  56. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/explore.py +0 -0
  57. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/external.py +0 -0
  58. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/graphql.py +0 -0
  59. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/guard_facts.py +0 -0
  60. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/hooks.py +0 -0
  61. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/indexer.py +0 -0
  62. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/insecure_transport.py +0 -0
  63. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/jobs.py +0 -0
  64. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/lint_async.py +0 -0
  65. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/local_ipc.py +0 -0
  66. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/local_sockets.py +0 -0
  67. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/mcp_graphs.py +0 -0
  68. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/parity.py +0 -0
  69. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/parity_structure.py +0 -0
  70. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/payload.py +0 -0
  71. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plans.py +0 -0
  72. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/platform_scan.py +0 -0
  73. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/platforms.py +0 -0
  74. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/__init__.py +0 -0
  75. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/astro/__init__.py +0 -0
  76. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/astro/content.py +0 -0
  77. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/astro/plugin.py +0 -0
  78. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/cfamily/__init__.py +0 -0
  79. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/cfamily/plugin.py +0 -0
  80. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/cfamily/syntax.py +0 -0
  81. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/dart/__init__.py +0 -0
  82. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/dart/bridges.py +0 -0
  83. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/dart/extractor/bin/extract.dart +0 -0
  84. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/dart/extractor/pubspec.lock +0 -0
  85. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/dart/extractor/pubspec.yaml +0 -0
  86. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/dart/http.py +0 -0
  87. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/dart/models.py +0 -0
  88. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/dart/plugin.py +0 -0
  89. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/dart/program.py +0 -0
  90. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/django/__init__.py +0 -0
  91. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/django/extras.py +0 -0
  92. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/django/models.py +0 -0
  93. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/django/plugin.py +0 -0
  94. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/django/schemas.py +0 -0
  95. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/django/shapes.py +0 -0
  96. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/django/urls.py +0 -0
  97. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/express/__init__.py +0 -0
  98. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/express/plugin.py +0 -0
  99. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/flutter/__init__.py +0 -0
  100. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/flutter/plugin.py +0 -0
  101. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/java/__init__.py +0 -0
  102. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/java/exact.py +0 -0
  103. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/java/plugin.py +0 -0
  104. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/jvm/__init__.py +0 -0
  105. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/jvm/interop.py +0 -0
  106. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/jvm/spring.py +0 -0
  107. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/kotlin/__init__.py +0 -0
  108. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/kotlin/exact.py +0 -0
  109. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/kotlin/plugin.py +0 -0
  110. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/kotlin/reparse.py +0 -0
  111. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/laravel/__init__.py +0 -0
  112. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/laravel/broadcast.py +0 -0
  113. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/laravel/massassign.py +0 -0
  114. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/laravel/plugin.py +0 -0
  115. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/laravel/tests.py +0 -0
  116. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/laravel/values.py +0 -0
  117. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/native/__init__.py +0 -0
  118. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/native/gates.py +0 -0
  119. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/native/runner.py +0 -0
  120. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/native/scipread.py +0 -0
  121. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/native/ts.py +0 -0
  122. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/nest/__init__.py +0 -0
  123. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/nest/plugin.py +0 -0
  124. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/nextjs/__init__.py +0 -0
  125. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/nextjs/plugin.py +0 -0
  126. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/nuxt/__init__.py +0 -0
  127. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/php/__init__.py +0 -0
  128. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/php/external.py +0 -0
  129. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/php/extractor/composer.json +0 -0
  130. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/php/extractor/composer.lock +0 -0
  131. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/php/extractor/extract.php +0 -0
  132. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/php/gating.py +0 -0
  133. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/php/http_client.py +0 -0
  134. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/php/inline_guards.py +0 -0
  135. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/php/plugin.py +0 -0
  136. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/php/strings.py +0 -0
  137. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/python/__init__.py +0 -0
  138. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/python/aitools.py +0 -0
  139. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/python/external.py +0 -0
  140. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/python/fields.py +0 -0
  141. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/python/plugin.py +0 -0
  142. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/python/refs.py +0 -0
  143. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/python/roots.py +0 -0
  144. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/python/socketio.py +0 -0
  145. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/python/subproc.py +0 -0
  146. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/python/tests.py +0 -0
  147. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/python/values.py +0 -0
  148. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/pyweb/__init__.py +0 -0
  149. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/pyweb/plugin.py +0 -0
  150. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/pyweb/values.py +0 -0
  151. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/rust/__init__.py +0 -0
  152. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/rust/cargo.py +0 -0
  153. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/rust/plugin.py +0 -0
  154. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/rust/syntax.py +0 -0
  155. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/scip/__init__.py +0 -0
  156. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/scip/importer.py +0 -0
  157. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/scip/scip.proto +0 -0
  158. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/scip/scip_pb2.py +0 -0
  159. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/stubs/__init__.py +0 -0
  160. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/stubs/plugins.py +0 -0
  161. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/swift/__init__.py +0 -0
  162. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/swift/baseurl.py +0 -0
  163. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/swift/exact.py +0 -0
  164. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/swift/indexstore.py +0 -0
  165. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/swift/packages.py +0 -0
  166. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/swift/plugin.py +0 -0
  167. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/ts/__init__.py +0 -0
  168. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/ts/baseurl.py +0 -0
  169. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/ts/extractor/fw.mjs +0 -0
  170. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/ts/extractor/package-lock.json +0 -0
  171. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/ts/extractor/package.json +0 -0
  172. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/ts/extractor/rr.mjs +0 -0
  173. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/ts/nav.py +0 -0
  174. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/ts/plugin.py +0 -0
  175. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/ts/react_router.py +0 -0
  176. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/tsweb/__init__.py +0 -0
  177. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/tsweb/common.py +0 -0
  178. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/plugins/tsweb/data.py +0 -0
  179. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/__init__.py +0 -0
  180. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/c_cpp.yaml +0 -0
  181. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/common.yaml +0 -0
  182. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/dart.yaml +0 -0
  183. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/django-ninja.yaml +0 -0
  184. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/django.yaml +0 -0
  185. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/djangorestframework.yaml +0 -0
  186. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/express.yaml +0 -0
  187. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/java.yaml +0 -0
  188. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/kotlin.yaml +0 -0
  189. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/laravel.yaml +0 -0
  190. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/nest.yaml +0 -0
  191. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/nextjs.yaml +0 -0
  192. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/nuxt.yaml +0 -0
  193. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/php.yaml +0 -0
  194. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/python.yaml +0 -0
  195. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/react-router.yaml +0 -0
  196. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/rust.yaml +0 -0
  197. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/spring.yaml +0 -0
  198. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/swift.yaml +0 -0
  199. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/presets/typescript.yaml +0 -0
  200. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/process_runs.py +0 -0
  201. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/protocols/__init__.py +0 -0
  202. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/protocols/builtin.py +0 -0
  203. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/protocols/matchers.py +0 -0
  204. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/protocols/view.py +0 -0
  205. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/realtime.py +0 -0
  206. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/realtime_events.py +0 -0
  207. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/realtime_native.py +0 -0
  208. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/realtime_ws.py +0 -0
  209. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/roundtrip.py +0 -0
  210. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/routes.py +0 -0
  211. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/rpc.py +0 -0
  212. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/sdk_systems.py +0 -0
  213. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/sockets.py +0 -0
  214. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/ssrf_input.py +0 -0
  215. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/starters.py +0 -0
  216. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/surface.py +0 -0
  217. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/tests_index.py +0 -0
  218. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/udp_apps.py +0 -0
  219. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/__init__.py +0 -0
  220. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/graph.py +0 -0
  221. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/server.py +0 -0
  222. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/static/app.css +0 -0
  223. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/static/app.js +0 -0
  224. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/static/index.html +0 -0
  225. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/static/layered.js +0 -0
  226. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/static/vendor/VERSIONS.txt +0 -0
  227. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/static/vendor/cose-base.js +0 -0
  228. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/static/vendor/cytoscape-fcose.js +0 -0
  229. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/static/vendor/cytoscape.min.js +0 -0
  230. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/static/vendor/layout-base.js +0 -0
  231. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/tools/package-lock.json +0 -0
  232. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/tools/package.json +0 -0
  233. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/viz/tools/shoot.mjs +0 -0
  234. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/watch.py +0 -0
  235. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/webhook_subs.py +0 -0
  236. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/webhooks.py +0 -0
  237. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph/xcode.py +0 -0
  238. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph.egg-info/dependency_links.txt +0 -0
  239. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph.egg-info/entry_points.txt +0 -0
  240. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph.egg-info/requires.txt +0 -0
  241. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/cg_code_graph.egg-info/top_level.txt +0 -0
  242. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/pyproject.toml +0 -0
  243. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/setup.cfg +0 -0
  244. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_affected.py +0 -0
  245. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_agents_install.py +0 -0
  246. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_agents_md.py +0 -0
  247. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_ai_tools.py +0 -0
  248. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_android_ipc.py +0 -0
  249. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_apple_ipc.py +0 -0
  250. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_astro.py +0 -0
  251. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_astro_content.py +0 -0
  252. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_astro_server.py +0 -0
  253. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_bridges.py +0 -0
  254. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_bridges_pigeon_monorepo.py +0 -0
  255. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_brokers.py +0 -0
  256. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_cache_clean.py +0 -0
  257. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_cache_invalidation.py +0 -0
  258. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_cache_migration.py +0 -0
  259. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_channels_tests.py +0 -0
  260. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_cli_output.py +0 -0
  261. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_completeness.py +0 -0
  262. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_config_extras.py +0 -0
  263. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_coverage.py +0 -0
  264. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_coverage_ts_hint.py +0 -0
  265. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_dart_isolates.py +0 -0
  266. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_db_connections.py +0 -0
  267. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_dead_wrappers.py +0 -0
  268. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_dispatch_interfaces.py +0 -0
  269. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_django_flutter.py +0 -0
  270. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_docs_languages.py +0 -0
  271. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_docs_links.py +0 -0
  272. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_echo_ref.py +0 -0
  273. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_echo_wrapper.py +0 -0
  274. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_elysia.py +0 -0
  275. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_enum_constants.py +0 -0
  276. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_env.py +0 -0
  277. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_explore.py +0 -0
  278. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_external.py +0 -0
  279. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_fp_batch.py +0 -0
  280. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_gating.py +0 -0
  281. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_generated.py +0 -0
  282. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_graphql.py +0 -0
  283. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_hooks.py +0 -0
  284. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_impact_overrides.py +0 -0
  285. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_index_isolation.py +0 -0
  286. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_inherited_overrides.py +0 -0
  287. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_inline_guards.py +0 -0
  288. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_issue_192.py +0 -0
  289. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_issue_202.py +0 -0
  290. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_issue_203.py +0 -0
  291. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_issue_205.py +0 -0
  292. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_issue_206.py +0 -0
  293. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_issue_207.py +0 -0
  294. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_issue_208.py +0 -0
  295. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_issue_209.py +0 -0
  296. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_issue_210.py +0 -0
  297. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_issue_211.py +0 -0
  298. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_issue_211_used_at.py +0 -0
  299. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_java.py +0 -0
  300. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_java_exact.py +0 -0
  301. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_jobs.py +0 -0
  302. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_js_refs.py +0 -0
  303. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_js_runtime.py +0 -0
  304. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_kotlin.py +0 -0
  305. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_kotlin_binding.py +0 -0
  306. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_kotlin_exact.py +0 -0
  307. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_kotlin_fields.py +0 -0
  308. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_kotlin_mixed.py +0 -0
  309. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_kotlin_nav_consts.py +0 -0
  310. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_kotlin_props.py +0 -0
  311. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_laravel_determinism.py +0 -0
  312. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_laravel_resources.py +0 -0
  313. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_lint_async.py +0 -0
  314. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_listing_files.py +0 -0
  315. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_local_ipc.py +0 -0
  316. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_local_sockets.py +0 -0
  317. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_mass_assignment.py +0 -0
  318. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_mcp.py +0 -0
  319. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_mcp_index.py +0 -0
  320. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_mcp_install.py +0 -0
  321. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_mcp_multi_graph.py +0 -0
  322. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_native_cfamily.py +0 -0
  323. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_native_concurrency.py +0 -0
  324. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_native_rust.py +0 -0
  325. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_nuxt_import_dirs.py +0 -0
  326. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_nuxt_rootsrc.py +0 -0
  327. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_packaging.py +0 -0
  328. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_parity.py +0 -0
  329. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_parity_structure.py +0 -0
  330. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_php_http.py +0 -0
  331. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_php_props.py +0 -0
  332. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_plain_js.py +0 -0
  333. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_plans.py +0 -0
  334. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_platform_gaps.py +0 -0
  335. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_platform_type_variants.py +0 -0
  336. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_platforms.py +0 -0
  337. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_platforms_apple.py +0 -0
  338. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_presets_config.py +0 -0
  339. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_process_ipc.py +0 -0
  340. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_process_runs.py +0 -0
  341. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_protocols.py +0 -0
  342. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_app_tests_module.py +0 -0
  343. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_collection_chains.py +0 -0
  344. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_compat.py +0 -0
  345. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_entry_refs.py +0 -0
  346. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_fields.py +0 -0
  347. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_infer_cycles.py +0 -0
  348. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_roots.py +0 -0
  349. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_subprocess_tests.py +0 -0
  350. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_tests.py +0 -0
  351. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_web_hosts.py +0 -0
  352. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_web_routes.py +0 -0
  353. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_python_web_routes_more.py +0 -0
  354. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_react_router.py +0 -0
  355. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_readers_writers_specs.py +0 -0
  356. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_realtime.py +0 -0
  357. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_realtime_native.py +0 -0
  358. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_redact_salt.py +0 -0
  359. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_request_keys.py +0 -0
  360. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_roundtrip.py +0 -0
  361. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_route_specs.py +0 -0
  362. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_route_tables.py +0 -0
  363. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_routes_search_explain.py +0 -0
  364. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_rpc.py +0 -0
  365. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_scip_health.py +0 -0
  366. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_sdk_external.py +0 -0
  367. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_sdk_external_infra.py +0 -0
  368. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_sdk_external_mail.py +0 -0
  369. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_sockets.py +0 -0
  370. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_spring.py +0 -0
  371. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_ssrf.py +0 -0
  372. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_starters_budget.py +0 -0
  373. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_surface.py +0 -0
  374. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_surface_transport.py +0 -0
  375. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift.py +0 -0
  376. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_binding.py +0 -0
  377. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_exact.py +0 -0
  378. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_facts.py +0 -0
  379. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_fields.py +0 -0
  380. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_modules.py +0 -0
  381. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_more.py +0 -0
  382. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_nav_values.py +0 -0
  383. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_parse_errors.py +0 -0
  384. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_props.py +0 -0
  385. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_sdk.py +0 -0
  386. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_testing.py +0 -0
  387. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_swift_values.py +0 -0
  388. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_tests_scope.py +0 -0
  389. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_ts_fields.py +0 -0
  390. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_ts_fields_js_vue.py +0 -0
  391. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_ts_file_specs.py +0 -0
  392. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_ts_frameworks.py +0 -0
  393. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_ts_node_http.py +0 -0
  394. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_ts_src_tsconfig.py +0 -0
  395. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_unguarded.py +0 -0
  396. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_values.py +0 -0
  397. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_viz.py +0 -0
  398. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_vue_nav.py +0 -0
  399. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_watch.py +0 -0
  400. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_webhooks.py +0 -0
  401. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_webhooks_152.py +0 -0
  402. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_webhooks_152b.py +0 -0
  403. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/tests/test_websockets.py +0 -0
  404. {cg_code_graph-0.23.0 → cg_code_graph-0.23.2}/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.0
3
+ Version: 0.23.2
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
@@ -48,7 +48,7 @@ For you and your AI agent (CLI + MCP). No LLM in the graph.
48
48
  ```bash
49
49
  pipx install cg-code-graph # or: uv tool install cg-code-graph
50
50
  cg index . --db out/graph.db # prints starter queries for your repo
51
- cg install --host cursor # or claude, codex, vscode, …: registers the MCP server
51
+ cg install --host cursor # or claude, codex, vscode, …: registers the MCP server and a "use cg first" agent rule
52
52
  cg reaches table:orders --db out/graph.db # any table, connection or config key
53
53
  ```
54
54
 
@@ -21,7 +21,7 @@ For you and your AI agent (CLI + MCP). No LLM in the graph.
21
21
  ```bash
22
22
  pipx install cg-code-graph # or: uv tool install cg-code-graph
23
23
  cg index . --db out/graph.db # prints starter queries for your repo
24
- cg install --host cursor # or claude, codex, vscode, …: registers the MCP server
24
+ cg install --host cursor # or claude, codex, vscode, …: registers the MCP server and a "use cg first" agent rule
25
25
  cg reaches table:orders --db out/graph.db # any table, connection or config key
26
26
  ```
27
27
 
@@ -1,2 +1,2 @@
1
1
  """code-graph: deterministic code knowledge graph (beta)."""
2
- __version__ = "0.23.0"
2
+ __version__ = "0.23.2"
@@ -73,6 +73,10 @@ def _add_install_parser(sub, uninstall: bool):
73
73
  p.add_argument("--uninstall", action="store_true", help="remove the entry instead of writing it")
74
74
  p.add_argument("--dry-run", action="store_true", help="print the exact changes and write nothing")
75
75
  p.add_argument("--yes", action="store_true", help="skip the confirmation prompt")
76
+ p.add_argument("--no-rules", dest="rules", action="store_false",
77
+ help=("leave AGENTS.md and .cursor/rules/cg.mdc alone" if uninstall else
78
+ "do not write the 'use cg first' agent rules (AGENTS.md section, .cursor/rules/cg.mdc); "
79
+ "project scope only"))
76
80
  if not uninstall:
77
81
  p.add_argument("--registry", action="store_true",
78
82
  help="global single entry: cg-mcp with no --db; graphs come from the registry")
@@ -96,9 +100,24 @@ def _impact_labels(rows: list[dict], name_of, group_of) -> list[str]:
96
100
  return labels
97
101
 
98
102
 
103
+ def _version_text(version: str) -> str:
104
+ """`cg X.Y.Z`, plus a second line when the cached newer-release check (written by `cg doctor`) knows of a newer
105
+ release. Reads the cache only: never connects (#98)."""
106
+ try:
107
+ from .update_check import check, notice
108
+ n = notice(check(version, network=False))
109
+ except Exception:
110
+ n = None
111
+ return f"cg {version}" + (f"\n{n}" if n else "")
112
+
113
+
99
114
  def main(argv=None):
100
115
  from . import __version__
101
116
  ap = argparse.ArgumentParser(prog="cg")
117
+ args_in = sys.argv[1:] if argv is None else list(argv)
118
+ if args_in[:1] == ["--version"]:
119
+ print(_version_text(__version__)) # printed here: argparse's version action re-wraps a second line
120
+ return 0
102
121
  ap.add_argument("--version", action="version", version=f"cg {__version__}")
103
122
  sub = ap.add_subparsers(dest="cmd", required=True)
104
123
  p = sub.add_parser("index", help="detect languages / frameworks under ROOT and build the graph DB (stats JSON on stdout, coverage on stderr)"); p.add_argument("root"); p.add_argument("--db", required=True); p.add_argument("--name"); p.add_argument("--scip", action="append"); p.add_argument("--gates", help="gate scenarios JSON (e.g. examples/bookstore.gates.json)")
@@ -520,7 +539,8 @@ def main(argv=None):
520
539
  return run_install(a.host, scope="global" if a.glob else "project", root=a.dir, db=a.db,
521
540
  tools=a.tools, portable=a.portable, remove=a.cmd == "uninstall" or a.uninstall,
522
541
  dry_run=a.dry_run, assume_yes=a.yes, registry=registry, migrate=migrate,
523
- apply=bool(getattr(a, "apply", False)), graphs=getattr(a, "graphs", None))
542
+ apply=bool(getattr(a, "apply", False)), graphs=getattr(a, "graphs", None),
543
+ rules=a.rules)
524
544
  if a.cmd == "hooks":
525
545
  from . import hooks as HK
526
546
  return HK.run(a.action, root=a.dir, db=a.db, dry_run=a.dry_run, assume_yes=a.yes)
@@ -857,6 +877,11 @@ def render_node(d: dict) -> str:
857
877
  unk = at.get("platform_unknown") or []
858
878
  ps = ", ".join(p + ("?" if p in unk else "") for p in at["platforms"]) or "none of the targets"
859
879
  out.append(f" platforms: {ps}" + (f" ({at['platform_expr']})" if at.get("platform_expr") else ""))
880
+ if n.get("kind") == "i18n" and at.get("definitions"):
881
+ out.append(" definitions: " + ", ".join(f"{x.get('locale') or '-'} {x['file']}:{x['line']}" for x in at["definitions"]))
882
+ if at.get("missing_locales"):
883
+ out.append(" missing locales: " + ", ".join(at["missing_locales"]))
884
+ at = {k: v for k, v in at.items() if k not in ("definitions", "defined_in", "missing_locales")}
860
885
  rest = {k: v for k, v in at.items() if k not in ("platforms", "platform_unknown", "platform_expr", "platform_at", "platforms_other")}
861
886
  if rest:
862
887
  out.append(" attrs: " + ", ".join(f"{k}={v if isinstance(v, str) else json.dumps(v, default=str, ensure_ascii=False)}"
@@ -56,7 +56,7 @@ EDGE_KINDS: dict[str, tuple[bool, str]] = {
56
56
  "HTTP_CALLS": (True, "client code calls an HTTP endpoint (method + path template)"),
57
57
  "MATCHES_ROUTE": (True, "client endpoint matched to a backend route (cross-repo link)"),
58
58
  "USES_LAYOUT": (False, "page uses layout"),
59
- "USES_I18N": (False, "code/template uses i18n key"),
59
+ "USES_I18N": (True, "code/template uses i18n key (propagating: a key's users are its dependents in reaches / impact, #182)"),
60
60
  "REFERENCES_TYPE": (False, "code references a type/interface"),
61
61
  # value facts
62
62
  "READS_SETTING": (True, "code reads a JSON settings key (getSetting('a.b', default))"),
@@ -344,6 +344,9 @@ def compute(root: str | Path, plugins: dict, scip_imported: bool = False, report
344
344
  elif not e["files_complete"] and lang == "typescript" and e.get("unmapped"):
345
345
  e["hint"] = ("files outside the source dirs and test trees were not read: list the directories that hold "
346
346
  "source in .cg.yaml `include` (or a tsconfig.json `include`) and re-index")
347
+ if (nx := _nuxt_dirs(root)):
348
+ # Nuxt: name the dirs that were read, so a layer or module dir outside them is explained (#214)
349
+ e["hint"] = f"Nuxt project: the source dirs read are the srcDir plus server/ and shared/ ({nx}); " + e["hint"]
347
350
  se = (rep or {}).get("syntax_errors")
348
351
  if isinstance(se, list) and se and status not in ("skipped", "not_indexed"):
349
352
  # files parsed with syntax errors (#73): error spans and the declarations lost there
@@ -434,6 +437,16 @@ def _ts_not_run(root, with_php: bool) -> tuple[str, str]:
434
437
  return reason, hint
435
438
 
436
439
 
440
+ def _nuxt_dirs(root) -> str | None:
441
+ """'app/, server/, shared/' for a Nuxt project (the dirs the Nuxt plugin reads), else None."""
442
+ from .plugins.nuxt.plugin import _CFG_NAMES, find_src_dir, side_dirs
443
+ r = Path(root)
444
+ if not any((r / n).exists() for n in _CFG_NAMES):
445
+ return None
446
+ src = find_src_dir(r)
447
+ return ", ".join(["the project root" if src == "." else f"{src}/", *(f"{d}/" for d in side_dirs(r, src))])
448
+
449
+
437
450
  def _python_unmapped_hint(st: dict) -> str:
438
451
  if st.get("roots_mode") in ("configured", "flag"):
439
452
  where = "python.source_roots in .cg.yaml" if st["roots_mode"] == "configured" else "--python-root"
@@ -407,12 +407,25 @@ def report(root: str | Path | None = None, scip: list | None = None) -> dict:
407
407
  "legacy_cache": cache.legacy_report(),
408
408
  **({"hooks_outdated": _outdated_hooks(rootp)} if rootp is not None else {}),
409
409
  "update": "uv tool upgrade cg-code-graph | pipx upgrade cg-code-graph | install.sh --update",
410
+ "latest": _latest(),
410
411
  **({"scip": [scip_health(x) for x in scip]} if scip else {}),
411
412
  }
412
413
 
413
414
 
415
+ def _latest() -> dict:
416
+ """Newer-release check (#98): PyPI at most once a day, cached; never fails or blocks for long."""
417
+ from .update_check import check
418
+ try:
419
+ return check()
420
+ except Exception:
421
+ return {"current": __version__, "latest": None, "newer": False, "source": "none", "disabled": None}
422
+
423
+
414
424
  def render(r: dict) -> str:
415
425
  out = [f"cg {r['cg']} (Python {r['python']}, {r['os']}; {r['package']}{', checkout' if r['checkout'] else ''})"]
426
+ from .update_check import notice
427
+ if (n := notice(r.get("latest") or {})):
428
+ out.append(f"newer release: {n}")
416
429
  out.append("tools:")
417
430
  for k, v in r["tools"].items():
418
431
  out.append(f" {k:<14} {v['version'] or 'not found'}" + (f" ({v['path']})" if v["path"] else "")
@@ -0,0 +1,88 @@
1
+ """Agent rules written by `cg install` (project scope, on by default, `--no-rules` skips): a short "use cg first"
2
+ section in AGENTS.md (Claude Code, Codex and other agents read it) and an alwaysApply Cursor rule at
3
+ .cursor/rules/cg.mdc. Only the `<!-- cg:start --> ... <!-- cg:end -->` section is ever written: a re-run replaces
4
+ it in place, content around it is kept, and `cg uninstall` removes it."""
5
+ from __future__ import annotations
6
+
7
+ import re
8
+ from pathlib import Path
9
+
10
+ START = "<!-- cg:start -->"
11
+ END = "<!-- cg:end -->"
12
+ AGENTS_FILE = "AGENTS.md"
13
+ CURSOR_FILE = ".cursor/rules/cg.mdc"
14
+ MDC_HEADER = "---\ndescription: Use the cg code graph before grep or opening whole files\nalwaysApply: true\n---\n"
15
+ _SECTION = re.compile(re.escape(START) + r".*?" + re.escape(END), re.S)
16
+
17
+
18
+ def body(db: str = "out/graph.db") -> str:
19
+ return (
20
+ "## Code graph (cg)\n\n"
21
+ "This repo has a cg code graph (MCP server `cg`). Use it before grep or opening whole files:\n"
22
+ "- `search` to find a symbol (file:line);\n"
23
+ "- `impact` before editing a function (or `reaches` for a table, column or env key) to see what the change affects;\n"
24
+ "- `snippet` to read one symbol instead of a whole file;\n"
25
+ "- `graphs` if unsure which graph to query.\n\n"
26
+ "Use normal search only for what cg reports as not covered (`coverage`). Without MCP: "
27
+ f"`cg search|impact|snippet <symbol> --db {db}`.\n")
28
+
29
+
30
+ def section(db: str = "out/graph.db") -> str:
31
+ return f"{START}\n{body(db)}{END}"
32
+
33
+
34
+ def _plan(path: Path, new: str | None, old: str, delete: bool = False) -> dict:
35
+ if delete:
36
+ return {"path": str(path), "kind": "text", "action": "remove", "old": old, "new": "", "delete_file": True}
37
+ if new == old:
38
+ return {"path": str(path), "kind": "text", "action": "noop", "old": old, "new": old, "current": True}
39
+ action = "insert" if not _SECTION.search(old) else ("remove" if not _SECTION.search(new) else "update")
40
+ return {"path": str(path), "kind": "text", "action": action, "old": old, "new": new}
41
+
42
+
43
+ def _with_section(old: str, sec: str) -> str:
44
+ if _SECTION.search(old):
45
+ return _SECTION.sub(lambda _m: sec, old, count=1)
46
+ if not old:
47
+ return sec + "\n"
48
+ return old + ("" if old.endswith("\n\n") else "\n" if old.endswith("\n") else "\n\n") + sec + "\n"
49
+
50
+
51
+ def _without_section(old: str) -> str:
52
+ m = _SECTION.search(old)
53
+ if not m:
54
+ return old
55
+ s, e = m.start(), m.end()
56
+ while e < len(old) and old[e] == "\n":
57
+ e += 1
58
+ while s > 0 and old[s - 1] == "\n":
59
+ s -= 1
60
+ head = old[:s]
61
+ return (head + "\n" + old[e:]) if head and old[e:] else (head + "\n" if head else old[e:])
62
+
63
+
64
+ def plans(root: Path, remove: bool = False, db: str = "out/graph.db") -> list[dict]:
65
+ """One text plan per rules file (the shape `cg agents` previews and `cg install` applies)."""
66
+ out = []
67
+ sec = section(db)
68
+ agents = root / AGENTS_FILE
69
+ old = agents.read_text(encoding="utf-8") if agents.exists() else ""
70
+ if remove:
71
+ rest = _without_section(old)
72
+ out.append(_plan(agents, None, old, delete=True) if _SECTION.search(old) and not rest.strip() else _plan(agents, rest, old))
73
+ else:
74
+ out.append(_plan(agents, _with_section(old, sec), old))
75
+ mdc = root / CURSOR_FILE
76
+ old = mdc.read_text(encoding="utf-8") if mdc.exists() else ""
77
+ if remove:
78
+ rest = _without_section(old)
79
+ if mdc.exists() and _SECTION.search(old) and rest.strip() in ("", MDC_HEADER.strip()):
80
+ out.append(_plan(mdc, None, old, delete=True))
81
+ else:
82
+ out.append(_plan(mdc, rest, old))
83
+ else:
84
+ new = _with_section(old, sec)
85
+ if not new.startswith("---\n"):
86
+ new = MDC_HEADER + new # an alwaysApply header, added once in front of whatever is there
87
+ out.append(_plan(mdc, new, old))
88
+ return [p for p in out if not (remove and p["action"] == "noop" and not p["old"])]
@@ -137,7 +137,10 @@ def known_origin_text(attrs: dict) -> str | None:
137
137
  return None
138
138
 
139
139
 
140
- _GENERIC_ORIGIN = {"env", "base", "url", "api", "app", "http", "https", "host", "origin", "endpoint", "service", "internal"}
140
+ _GENERIC_ORIGIN = {"env", "base", "url", "uri", "api", "app", "http", "https", "host", "origin", "endpoint", "service",
141
+ "internal", "server", "backend", "public", "private", "remote", "domain", "root", "prefix", "path",
142
+ "address", "addr", "runtime", "config", "runtimeconfig", "process", "import", "meta", "window",
143
+ "location", "nuxt", "next", "vite", "react", "expo", "vue", "localhost", "www", "com"}
141
144
 
142
145
 
143
146
  def repos_for_origin(text: str, servers: list[str]) -> list[str] | None:
@@ -146,17 +149,20 @@ def repos_for_origin(text: str, servers: list[str]) -> list[str] | None:
146
149
  ``None`` when the origin is a generic API base (``API_BASE_URL``) and does not name a repo:
147
150
  matching stays as it was. ``[]`` when it names a service that is not one of ``servers``.
148
151
  """
149
- low = text.lower()
152
+ # camelCase splits (runtimeConfig.public.apiBase -> runtime config public api base); `-`, `_` and `.` all separate,
153
+ # so ORDERS_API_URL names an orders-api repo
154
+ split = re.sub(r"([a-z0-9])([A-Z])", r"\1 \2", text).lower()
155
+ norm = "-" + "-".join(re.findall(r"[a-z0-9]+", split)) + "-"
150
156
  hits = []
151
157
  for name in servers:
152
- token = name.lower()
158
+ token = "-".join(re.findall(r"[a-z0-9]+", re.sub(r"([a-z0-9])([A-Z])", r"\1 \2", name).lower()))
153
159
  if len(token) < 3:
154
160
  continue
155
- if re.search(rf"(^|[^a-z0-9]){re.escape(token)}([^a-z0-9]|$)", low):
161
+ if f"-{token}-" in norm:
156
162
  hits.append(name)
157
163
  if hits:
158
164
  return hits
159
- tokens = [t for t in re.findall(r"[a-z][a-z0-9]+", low) if t not in _GENERIC_ORIGIN]
165
+ tokens = [t for t in re.findall(r"[a-z][a-z0-9]+", split) if t not in _GENERIC_ORIGIN]
160
166
  if not tokens:
161
167
  return None
162
168
  return []
@@ -431,6 +437,7 @@ def link_many(repos: list[tuple[str, str, str]], out_db: str, *, allow: dict | N
431
437
  by_server[rt["server"]].append(rt)
432
438
  results = []
433
439
  new_edges = []
440
+ matched_origins: set[tuple[str, str]] = set()
434
441
  for client, ep_id, a, _test in http_rows:
435
442
  targets = [s for s in server_names if (s != client or folded_self) and (client not in allow or s in allow[client])]
436
443
  pool = [rt for s in targets for rt in by_server[s]]
@@ -443,7 +450,11 @@ def link_many(repos: list[tuple[str, str, str]], out_db: str, *, allow: dict | N
443
450
  if origin_text and owners == [] and not res.get("matched") and a.get("origin_kind") != "other":
444
451
  reason = res.get("reason") or ""
445
452
  if reason.startswith(("no backend route", "not a backend URL")) or "suffix" in reason:
453
+ res["_reason_before_external"] = reason
454
+ res["_origin_text"] = origin_text
446
455
  res["reason"] = "external (other origin)"
456
+ elif origin_text and res.get("matched"):
457
+ matched_origins.add((client, origin_text))
447
458
  res.update({"endpoint": ep_id, "method": a["method"], "calls": calls_by_ep.get(ep_id, []),
448
459
  "_client": client, "_servers": targets})
449
460
  results.append(res)
@@ -452,6 +463,12 @@ def link_many(repos: list[tuple[str, str, str]], out_db: str, *, allow: dict | N
452
463
  rr = rmap[m["route"]]
453
464
  new_edges.append((ep_id, m["route"], "MATCHES_ROUTE", rr["file"], rr["line"], m["confidence"], CONFIDENCE_RANK[m["confidence"]],
454
465
  json.dumps({"client_path": a["path"], "uri_variant": m["uri_variant"], "segments": m["segments"]}), None))
466
+ for res in results:
467
+ # an origin whose other calls from this client matched a linked server is that backend, not an external one
468
+ before = res.pop("_reason_before_external", None)
469
+ if before is not None and (res["_client"], res.pop("_origin_text")) in matched_origins:
470
+ res["reason"] = before
471
+ res.pop("_origin_text", None)
455
472
  db.executemany("INSERT INTO edges(src,dst,kind,file,line,confidence,conf_rank,attrs,gate) VALUES (?,?,?,?,?,?,?,?,?)", new_edges)
456
473
  db.commit()
457
474
  subscriptions = pair_subscriber_urls(db, routes, server_names, allow, folded_self)
@@ -781,6 +781,9 @@ def _apply_file(plan: dict) -> None:
781
781
  if path.exists():
782
782
  path.unlink()
783
783
  parent = path.parent
784
+ if parent.name == "rules" and parent.parent.name == ".cursor" and parent.exists() and not any(parent.iterdir()):
785
+ parent.rmdir() # .cursor/rules/cg.mdc was the only rule
786
+ parent = parent.parent
784
787
  if parent.name in _EMPTY_PARENTS and parent.exists() and not any(parent.iterdir()):
785
788
  parent.rmdir()
786
789
  return
@@ -1023,7 +1026,7 @@ def run(hosts: list[str] | None, *, scope: str, root: str = ".", db: str | None
1023
1026
  tools: str | None = None, portable: bool = False, remove: bool = False,
1024
1027
  dry_run: bool = False, assume_yes: bool = False, input_fn=input, out=print,
1025
1028
  registry: bool = False, migrate: bool = False, apply: bool = False,
1026
- graphs: str | None = None) -> int:
1029
+ graphs: str | None = None, rules: bool = True) -> int:
1027
1030
  if migrate:
1028
1031
  return run_migrate(hosts, scope=scope, root=root, tools=tools, graphs=graphs, apply=apply and not dry_run, out=out)
1029
1032
  rootp = Path(root).resolve()
@@ -1050,6 +1053,16 @@ def run(hosts: list[str] | None, *, scope: str, root: str = ".", db: str | None
1050
1053
  dbp = None
1051
1054
  plans = iter_plans(expanded, scope=scope, root=rootp, db=dbp, tools=tools, portable=portable, remove=remove,
1052
1055
  registry=registry)
1056
+ if rules and scope == "project" and not registry:
1057
+ # "use cg first" rules for agents: AGENTS.md section + alwaysApply Cursor rule (cg_code_graph/install_rules.py)
1058
+ from . import install_rules as IR
1059
+ shown = "out/graph.db"
1060
+ if dbp is not None and not portable:
1061
+ try:
1062
+ shown = dbp.relative_to(rootp).as_posix()
1063
+ except ValueError:
1064
+ shown = str(dbp)
1065
+ plans = [*plans, *IR.plans(rootp, remove=remove, db=shown)]
1053
1066
  if not portable and not remove and uses_module_fallback():
1054
1067
  out(_FALLBACK_NOTE)
1055
1068
  for plan in plans:
@@ -1088,6 +1101,10 @@ def run(hosts: list[str] | None, *, scope: str, root: str = ".", db: str | None
1088
1101
  _apply_file(plan)
1089
1102
  if plan.get("delete_file"):
1090
1103
  out(f"removed {plan['path']}")
1104
+ elif plan.get("kind") == "text" and plan["action"] == "remove":
1105
+ out(f"removed the cg section from {plan['path']}")
1106
+ elif plan.get("kind") == "text":
1107
+ out(f"wrote {plan['path']} (cg agent rules, {plan['action']})")
1091
1108
  else:
1092
1109
  out(f"wrote {plan['path']} ({plan['action']})")
1093
1110
  return 0
@@ -62,9 +62,9 @@ STATE = _State({"db": str(ROOT / "out" / "graph.db"), "root": None, "gates": Non
62
62
  "graph_entry": None, "graph_name": None, "graph_arg": False})
63
63
  _MCP_ROOTS: contextvars.ContextVar[list[str] | None] = contextvars.ContextVar("cg_mcp_roots", default=None)
64
64
 
65
- server = MCPServer(
66
- name="code-graph",
67
- instructions=(
65
+ # Reference text (stacks, spec forms, per-feature notes): the MCP resource cg://guide. The initialize
66
+ # `instructions` stay short and directive so agents use cg before grep / file reads.
67
+ GUIDE = (
68
68
  "Code graph of a project: classes, functions, routes, commands, jobs, pages, DB tables/columns, connections, "
69
69
  "config/env keys, each edge with file:line evidence and a confidence (exact / resolved / heuristic). Stacks: "
70
70
  "For a broad question ('how does X work') start with `explore`: source, entry points, call paths and blast radius in one call. "
@@ -119,8 +119,23 @@ server = MCPServer(
119
119
  "issue links) and overlays the graph without changing it. Workflow: write the plan -> `plan_check` (compact "
120
120
  "summary with counts and the top items; details=true for every item with file:line, forbidden paths and open "
121
121
  "findings) -> refine the plan -> `plan_baseline` -> implement -> `index` -> `plan_check(verify=true)` (planned "
122
- "nodes/edges exist, forbidden paths gone or guarded, modified targets changed)."),
123
- )
122
+ "nodes/edges exist, forbidden paths gone or guarded, modified targets changed).")
123
+
124
+ INSTRUCTIONS = (
125
+ "Use cg before grep or opening files for questions about where code is, what calls what, or what a change "
126
+ "affects. `search` finds a symbol; before editing, `impact` (callers up to entry points) or `reaches` (every "
127
+ "dependent) shows what the change affects; `snippet` reads one symbol instead of a whole file; `explore` answers "
128
+ "a broad 'how does X work' in one call. Unsure which graph? Call `graphs`. Fall back to normal search only for "
129
+ "what cg reports as not covered (`coverage`, a `coverage note:` line). Spec forms and stack notes: resource "
130
+ "cg://guide.")
131
+
132
+ server = MCPServer(name="code-graph", instructions=INSTRUCTIONS)
133
+
134
+
135
+ @server.resource("cg://guide", name="guide", description="cg reference: stacks, spec forms, per-feature notes",
136
+ mime_type="text/plain")
137
+ def guide() -> str:
138
+ return GUIDE
124
139
 
125
140
 
126
141
  def _rel_text(txt: str) -> str:
@@ -451,7 +466,8 @@ def _ename(e: dict) -> str:
451
466
  def reaches(targets: list[str], min_confidence: str = "heuristic", group_by: str = "module",
452
467
  include_gated: bool = True, max_per_group: int = 25, paths: bool = True, platform: str | None = None,
453
468
  connection: str | None = None) -> str:
454
- """Reverse transitive dependents of one or more targets (union), e.g.
469
+ """Use before changing a column, table, connection, env key or symbol: everything that depends on it.
470
+ Reverse transitive dependents of one or more targets (union), e.g.
455
471
  ["orders.customer_id", "connection:warehouse", "connection:tenant_*"].
456
472
 
457
473
  Groups: RUNTIME (live; reached from http routes/schedules/jobs/listeners, or main()/exported FFI symbols in
@@ -489,7 +505,7 @@ def reaches(targets: list[str], min_confidence: str = "heuristic", group_by: str
489
505
  route_lines = [Q.route_failure(st, s)["text"] for s in missing if Q.route_failure(st, s)]
490
506
  if route_lines and len(route_lines) == len(missing):
491
507
  return "\n".join(route_lines)
492
- return "\n".join(pline + [f"targets: {tl}"]) + f"\nno node matches {', '.join(map(repr, missing))}; try search() with part of the name (spec forms are listed in the server instructions)"
508
+ return "\n".join(pline + [f"targets: {tl}"]) + f"\nno node matches {', '.join(map(repr, missing))}; try search() with part of the name (spec forms: resource cg://guide)"
493
509
  if not items and connection:
494
510
  return "\n".join(pline + [f"targets: {tl}", f"no dependents recorded for {', '.join(res['targets'])} on connection {connection!r} "
495
511
  f"(connections seen: {Q.seen_text(res.get('connections_seen') or [])})."])
@@ -550,7 +566,7 @@ def reaches(targets: list[str], min_confidence: str = "heuristic", group_by: str
550
566
  @tool
551
567
  def impact(method: str, min_confidence: str = "heuristic", max_items: int = 60, platform: str | None = None,
552
568
  paths: bool = True) -> str:
553
- """Reverse callers of a method (Class::method, short or FQN) up to entry points, with the shortest call path
569
+ """Use before editing a function: what a change to it affects. Reverse callers of a method (Class::method, short or FQN) up to entry points, with the shortest call path
554
570
  from each entry point.
555
571
  platform: only code built for that target (windows, linux, macos, ios, android, web): code under a platform
556
572
  condition that is false there (#[cfg], #if, Platform.OS / Platform.isX, kIsWeb, .ios.ts / .android.ts files,
@@ -666,7 +682,7 @@ CALLER_KINDS = ("CALLS", "INSTANTIATES", "IMPLEMENTED_BY", "OVERRIDDEN_BY", "BOU
666
682
 
667
683
  @tool
668
684
  def callers(symbol: str, min_confidence: str = "heuristic", limit: int = 60) -> str:
669
- """Direct callers of a function / method / class (one level: CALLS, INSTANTIATES, dispatch and framework edges
685
+ """Use to see who calls X right now. Direct callers of a function / method / class (one level: CALLS, INSTANTIATES, dispatch and framework edges
670
686
  into it), each with the call site file:line and confidence. For the full chain up to entry points use impact()."""
671
687
  st = _st()
672
688
  ids = Q.resolve_targets(st, symbol)
@@ -1042,8 +1058,9 @@ def affected(files: list[str] | None = None, base: str | None = None, max_depth:
1042
1058
 
1043
1059
  @tool
1044
1060
  def node(id_or_symbol: str) -> str:
1045
- """Details of one node: kind, FQN, file:line span, module, entry kinds, docblock (PHPDoc), and edge counts
1046
- by kind (in/out) with a few neighbours."""
1061
+ """Use to inspect a symbol without reading its file. Details of one node: kind, FQN, file:line span, module, entry kinds, docblock (PHPDoc), and edge counts
1062
+ by kind (in/out) with a few neighbours. Specs: Class::method | file#name | table.column | table:<t> |
1063
+ route:<METHOD> <uri> | env:<KEY> | page:/path (more: resource cg://guide)."""
1047
1064
  st = _st()
1048
1065
  n = st.node(id_or_symbol)
1049
1066
  if not n:
@@ -1076,7 +1093,7 @@ def node(id_or_symbol: str) -> str:
1076
1093
 
1077
1094
  @tool
1078
1095
  def snippet(id_or_symbol: str, context: int = 0, max_lines: int = 200) -> str:
1079
- """Source of one symbol: a `path:start-end` header then the body with line numbers. Resolves a
1096
+ """Use instead of opening a whole file. Source of one symbol: a `path:start-end` header then the body with line numbers. Resolves a
1080
1097
  node id or a symbol / FQN (as node() and search() do); an ambiguous name lists the candidates
1081
1098
  instead of guessing. context adds lines around the span; max_lines caps the body (truncation noted)."""
1082
1099
  return Q.render_snippet(Q.snippet(_st(), id_or_symbol, context=context, max_lines=max_lines))
@@ -1084,7 +1101,7 @@ def snippet(id_or_symbol: str, context: int = 0, max_lines: int = 200) -> str:
1084
1101
 
1085
1102
  @tool
1086
1103
  def search(name: str, kind: str | None = None, limit: int = 20, platform: str | None = None) -> str:
1087
- """Find nodes by name / FQN substring (case-insensitive), optionally filtered by kind
1104
+ """Use first to find a symbol instead of grep. Finds nodes by name / FQN substring (case-insensitive), optionally filtered by kind
1088
1105
  (class, method, route, command, table, column, connection, config, env, job, admin...). Also matches route
1089
1106
  middleware, guards, auth and access checks (e.g. "auth" finds `auth:api`, `ApiKeyGuard`, `IsAuthenticated`) and
1090
1107
  lists the routes that carry them. Platform-specific symbols carry their targets, e.g. `[ios, android]`.
@@ -1115,7 +1132,7 @@ def explore(query: str, budget_tokens: int = 3000, max_symbols: int = 4) -> str:
1115
1132
  def routes(writes: str | None = None, reaches: list[str] | None = None, missing: str | None = None,
1116
1133
  unguarded: bool = False, strict: bool = False, auth_pattern: str | None = None, max_items: int = 40, paths: bool = True,
1117
1134
  min_confidence: str = "heuristic", platform: str | None = None) -> str:
1118
- """Routes with their middleware / guards / auth, in one call. Optional scope: writes="*" (routes that reach any
1135
+ """Use for route, auth and middleware questions. Routes with their middleware / guards / auth, in one call. Optional scope: writes="*" (routes that reach any
1119
1136
  DB write) or writes="<table>", reaches=[specs] (routes that reach any of these nodes: table, column, connection,
1120
1137
  method, env key...). Optional filters: missing="<name>" keeps routes with no guard whose name contains it (e.g.
1121
1138
  "auth:api", "ApiKeyGuard"), unguarded=true keeps routes with no auth guard (the framework presets' auth guards and
@@ -1154,7 +1171,7 @@ def doctor(root: str | None = None, scip: list[str] | None = None, json_output:
1154
1171
 
1155
1172
  @tool
1156
1173
  def coverage(path: str | None = None, all_files: bool = False, json_output: bool = False) -> str:
1157
- """Which languages and files this index covers. Per language: parser mode (exact, heuristic only when an
1174
+ """Use when cg finds nothing or you need to know if a file is indexed. Which languages and files this index covers. Per language: parser mode (exact, heuristic only when an
1158
1175
  exact-mode indexer such as rust-analyzer or scip-clang is missing, skipped when the toolchain is missing, with the
1159
1176
  install hint) and file completeness (discovered vs indexed, with parse failures, files over the size limit,
1160
1177
  unmapped files outside the source roots, excluded files); unsupported source types by extension or shebang
@@ -1242,7 +1259,7 @@ def stats() -> str:
1242
1259
  @tool
1243
1260
  def downstream(target: str, max_per_kind: int = 25, paths: bool = True, min_confidence: str = "heuristic",
1244
1261
  platform: str | None = None) -> str:
1245
- """Forward dependencies of a node: what it ends up calling/reading. On a combined graph a frontend page goes
1262
+ """Use to see what X ends up calling or reading (page -> routes -> tables). Forward dependencies of a node. On a combined graph a frontend page goes
1246
1263
  page -> composables/components -> HTTP endpoints -> backend routes -> controllers/services -> tables.
1247
1264
  Lists backend routes, tables touched (directly or via columns), columns, connections, config/env keys, each
1248
1265
  with one shortest evidence path. target: page:/reports/:id | app/pages/x.vue | Class::method | ...
@@ -1288,7 +1305,7 @@ def downstream(target: str, max_per_kind: int = 25, paths: bool = True, min_conf
1288
1305
 
1289
1306
  @tool
1290
1307
  def path(source: str, target: str, min_confidence: str = "heuristic", platform: str | None = None) -> str:
1291
- """Shortest forward evidence chain from source to target (e.g. page:/reports/:id ->
1308
+ """Use to answer "how does A reach B". Shortest forward evidence chain from source to target (e.g. page:/reports/:id ->
1292
1309
  SalesReportService::report), one hop per line with file:line and confidence.
1293
1310
  platform: only code built for that target (windows, linux, macos, ios, android, web): code under a platform
1294
1311
  condition that is false there (#[cfg], #if, Platform.OS / Platform.isX, kIsWeb, .ios.ts / .android.ts files,
@@ -1601,7 +1618,7 @@ def _index(root: str | None = None, gates: str | None = None, repo: str | None =
1601
1618
 
1602
1619
  @tool
1603
1620
  def index(root: str | None = None, gates: str | None = None, repo: str | None = None) -> str:
1604
- """Re-index after editing (static analysis only: never boots the app or touches a database).
1621
+ """Use after editing so later answers see the change. Re-index (static analysis only: never boots the app or touches a database).
1605
1622
  On a combined graph (any number of repos): with no arguments every repo is re-indexed from its recorded root and the
1606
1623
  cross-repo link is rebuilt; repo (a name used at link time) re-indexes just that repo; root is matched to the
1607
1624
  recorded repo roots (a repo directory, a path inside one, or a parent of several). A root that matches no repo, or
@@ -1623,7 +1640,7 @@ def index(root: str | None = None, gates: str | None = None, repo: str | None =
1623
1640
 
1624
1641
  @tool
1625
1642
  def graphs() -> str:
1626
- """List the graphs this server can query: name, repo roots, languages, indexed commit and freshness.
1643
+ """Use when unsure which graph a question belongs to. Lists the graphs this server can query: name, repo roots, languages, indexed commit and freshness.
1627
1644
  One `cg-mcp` process serves every registered graph. Pass `graph` to other tools to choose one, or omit it
1628
1645
  and the server resolves from a path in the call, then MCP roots or the working directory, then the configured
1629
1646
  default. An ambiguous choice returns the list instead of guessing."""