cg-code-graph 0.14.0__tar.gz → 0.15.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 (324) hide show
  1. {cg_code_graph-0.14.0/cg_code_graph.egg-info → cg_code_graph-0.15.0}/PKG-INFO +2 -2
  2. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/README.md +1 -1
  3. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0/cg_code_graph.egg-info}/PKG-INFO +2 -2
  4. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/cg_code_graph.egg-info/SOURCES.txt +4 -0
  5. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/__init__.py +1 -1
  6. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/config.py +1 -1
  7. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/core/detect.py +3 -0
  8. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/core/extractors.py +58 -3
  9. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/coverage.py +3 -3
  10. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/doctor.py +23 -11
  11. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/indexer.py +2 -1
  12. cg_code_graph-0.15.0/codegraph/plugins/astro/plugin.py +126 -0
  13. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/ts/extractor/extract.mjs +73 -17
  14. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/ts/extractor/fw.mjs +7 -6
  15. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/ts/plugin.py +15 -9
  16. cg_code_graph-0.15.0/codegraph/viz/__init__.py +0 -0
  17. cg_code_graph-0.15.0/tests/test_astro.py +235 -0
  18. cg_code_graph-0.15.0/tests/test_js_runtime.py +182 -0
  19. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_packaging.py +1 -1
  20. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/LICENSE +0 -0
  21. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/MANIFEST.in +0 -0
  22. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/cg_code_graph.egg-info/dependency_links.txt +0 -0
  23. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/cg_code_graph.egg-info/entry_points.txt +0 -0
  24. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/cg_code_graph.egg-info/requires.txt +0 -0
  25. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/cg_code_graph.egg-info/top_level.txt +0 -0
  26. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/affected.py +0 -0
  27. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/agent_rules.py +0 -0
  28. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/agents.py +0 -0
  29. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/aitools.py +0 -0
  30. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/android_ipc.py +0 -0
  31. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/apple_ipc.py +0 -0
  32. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/apps.py +0 -0
  33. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/blindspots.py +0 -0
  34. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/bridges.py +0 -0
  35. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/brokers.py +0 -0
  36. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/cli.py +0 -0
  37. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/concepts.py +0 -0
  38. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/core/__init__.py +0 -0
  39. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/core/cache.py +0 -0
  40. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/core/fsutil.py +0 -0
  41. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/core/generated.py +0 -0
  42. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/core/model.py +0 -0
  43. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/core/paths.py +0 -0
  44. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/core/plugin.py +0 -0
  45. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/core/store.py +0 -0
  46. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/core/syntax_errors.py +0 -0
  47. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/dart_isolates.py +0 -0
  48. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/explore.py +0 -0
  49. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/external.py +0 -0
  50. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/graphql.py +0 -0
  51. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/hooks.py +0 -0
  52. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/jobs.py +0 -0
  53. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/link.py +0 -0
  54. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/lint_async.py +0 -0
  55. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/local_ipc.py +0 -0
  56. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/local_sockets.py +0 -0
  57. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/mcp_server.py +0 -0
  58. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/parity.py +0 -0
  59. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/parity_structure.py +0 -0
  60. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/payload.py +0 -0
  61. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plans.py +0 -0
  62. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/platform_scan.py +0 -0
  63. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/platforms.py +0 -0
  64. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/__init__.py +0 -0
  65. {cg_code_graph-0.14.0/codegraph/plugins/cfamily → cg_code_graph-0.15.0/codegraph/plugins/astro}/__init__.py +0 -0
  66. {cg_code_graph-0.14.0/codegraph/plugins/dart → cg_code_graph-0.15.0/codegraph/plugins/cfamily}/__init__.py +0 -0
  67. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/cfamily/plugin.py +0 -0
  68. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/cfamily/syntax.py +0 -0
  69. {cg_code_graph-0.14.0/codegraph/plugins/django → cg_code_graph-0.15.0/codegraph/plugins/dart}/__init__.py +0 -0
  70. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/dart/bridges.py +0 -0
  71. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/dart/extractor/bin/extract.dart +0 -0
  72. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/dart/extractor/pubspec.lock +0 -0
  73. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/dart/extractor/pubspec.yaml +0 -0
  74. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/dart/http.py +0 -0
  75. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/dart/models.py +0 -0
  76. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/dart/plugin.py +0 -0
  77. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/dart/program.py +0 -0
  78. {cg_code_graph-0.14.0/codegraph/plugins/express → cg_code_graph-0.15.0/codegraph/plugins/django}/__init__.py +0 -0
  79. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/django/extras.py +0 -0
  80. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/django/models.py +0 -0
  81. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/django/plugin.py +0 -0
  82. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/django/schemas.py +0 -0
  83. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/django/shapes.py +0 -0
  84. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/django/urls.py +0 -0
  85. {cg_code_graph-0.14.0/codegraph/plugins/flutter → cg_code_graph-0.15.0/codegraph/plugins/express}/__init__.py +0 -0
  86. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/express/plugin.py +0 -0
  87. {cg_code_graph-0.14.0/codegraph/plugins/kotlin → cg_code_graph-0.15.0/codegraph/plugins/flutter}/__init__.py +0 -0
  88. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/flutter/plugin.py +0 -0
  89. {cg_code_graph-0.14.0/codegraph/plugins/laravel → cg_code_graph-0.15.0/codegraph/plugins/kotlin}/__init__.py +0 -0
  90. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/kotlin/exact.py +0 -0
  91. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/kotlin/plugin.py +0 -0
  92. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/kotlin/reparse.py +0 -0
  93. {cg_code_graph-0.14.0/codegraph/plugins/native → cg_code_graph-0.15.0/codegraph/plugins/laravel}/__init__.py +0 -0
  94. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/laravel/broadcast.py +0 -0
  95. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/laravel/plugin.py +0 -0
  96. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/laravel/tests.py +0 -0
  97. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/laravel/values.py +0 -0
  98. {cg_code_graph-0.14.0/codegraph/plugins/nest → cg_code_graph-0.15.0/codegraph/plugins/native}/__init__.py +0 -0
  99. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/native/gates.py +0 -0
  100. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/native/runner.py +0 -0
  101. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/native/scipread.py +0 -0
  102. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/native/ts.py +0 -0
  103. {cg_code_graph-0.14.0/codegraph/plugins/nextjs → cg_code_graph-0.15.0/codegraph/plugins/nest}/__init__.py +0 -0
  104. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/nest/plugin.py +0 -0
  105. {cg_code_graph-0.14.0/codegraph/plugins/nuxt → cg_code_graph-0.15.0/codegraph/plugins/nextjs}/__init__.py +0 -0
  106. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/nextjs/plugin.py +0 -0
  107. {cg_code_graph-0.14.0/codegraph/plugins/php → cg_code_graph-0.15.0/codegraph/plugins/nuxt}/__init__.py +0 -0
  108. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/nuxt/plugin.py +0 -0
  109. {cg_code_graph-0.14.0/codegraph/plugins/python → cg_code_graph-0.15.0/codegraph/plugins/php}/__init__.py +0 -0
  110. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/php/external.py +0 -0
  111. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/php/extractor/composer.json +0 -0
  112. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/php/extractor/composer.lock +0 -0
  113. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/php/extractor/extract.php +0 -0
  114. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/php/gating.py +0 -0
  115. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/php/plugin.py +0 -0
  116. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/php/strings.py +0 -0
  117. {cg_code_graph-0.14.0/codegraph/plugins/pyweb → cg_code_graph-0.15.0/codegraph/plugins/python}/__init__.py +0 -0
  118. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/python/aitools.py +0 -0
  119. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/python/external.py +0 -0
  120. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/python/fields.py +0 -0
  121. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/python/plugin.py +0 -0
  122. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/python/refs.py +0 -0
  123. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/python/roots.py +0 -0
  124. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/python/socketio.py +0 -0
  125. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/python/subproc.py +0 -0
  126. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/python/tests.py +0 -0
  127. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/python/values.py +0 -0
  128. {cg_code_graph-0.14.0/codegraph/plugins/rust → cg_code_graph-0.15.0/codegraph/plugins/pyweb}/__init__.py +0 -0
  129. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/pyweb/plugin.py +0 -0
  130. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/pyweb/values.py +0 -0
  131. {cg_code_graph-0.14.0/codegraph/plugins/scip → cg_code_graph-0.15.0/codegraph/plugins/rust}/__init__.py +0 -0
  132. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/rust/cargo.py +0 -0
  133. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/rust/plugin.py +0 -0
  134. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/rust/syntax.py +0 -0
  135. {cg_code_graph-0.14.0/codegraph/plugins/stubs → cg_code_graph-0.15.0/codegraph/plugins/scip}/__init__.py +0 -0
  136. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/scip/importer.py +0 -0
  137. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/scip/scip.proto +0 -0
  138. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/scip/scip_pb2.py +0 -0
  139. {cg_code_graph-0.14.0/codegraph/plugins/swift → cg_code_graph-0.15.0/codegraph/plugins/stubs}/__init__.py +0 -0
  140. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/stubs/plugins.py +0 -0
  141. {cg_code_graph-0.14.0/codegraph/plugins/ts → cg_code_graph-0.15.0/codegraph/plugins/swift}/__init__.py +0 -0
  142. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/swift/baseurl.py +0 -0
  143. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/swift/exact.py +0 -0
  144. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/swift/indexstore.py +0 -0
  145. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/swift/packages.py +0 -0
  146. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/swift/plugin.py +0 -0
  147. {cg_code_graph-0.14.0/codegraph/plugins/tsweb → cg_code_graph-0.15.0/codegraph/plugins/ts}/__init__.py +0 -0
  148. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/ts/baseurl.py +0 -0
  149. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/ts/extractor/package-lock.json +0 -0
  150. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/ts/extractor/package.json +0 -0
  151. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/ts/nav.py +0 -0
  152. {cg_code_graph-0.14.0/codegraph/viz → cg_code_graph-0.15.0/codegraph/plugins/tsweb}/__init__.py +0 -0
  153. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/tsweb/common.py +0 -0
  154. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/plugins/tsweb/data.py +0 -0
  155. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/__init__.py +0 -0
  156. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/c_cpp.yaml +0 -0
  157. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/common.yaml +0 -0
  158. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/dart.yaml +0 -0
  159. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/django-ninja.yaml +0 -0
  160. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/django.yaml +0 -0
  161. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/djangorestframework.yaml +0 -0
  162. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/express.yaml +0 -0
  163. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/kotlin.yaml +0 -0
  164. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/laravel.yaml +0 -0
  165. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/nest.yaml +0 -0
  166. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/nextjs.yaml +0 -0
  167. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/nuxt.yaml +0 -0
  168. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/php.yaml +0 -0
  169. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/python.yaml +0 -0
  170. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/rust.yaml +0 -0
  171. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/swift.yaml +0 -0
  172. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/presets/typescript.yaml +0 -0
  173. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/process_runs.py +0 -0
  174. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/protocols/__init__.py +0 -0
  175. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/protocols/builtin.py +0 -0
  176. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/protocols/matchers.py +0 -0
  177. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/protocols/view.py +0 -0
  178. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/query.py +0 -0
  179. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/realtime.py +0 -0
  180. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/realtime_events.py +0 -0
  181. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/realtime_native.py +0 -0
  182. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/realtime_ws.py +0 -0
  183. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/roundtrip.py +0 -0
  184. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/routes.py +0 -0
  185. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/rpc.py +0 -0
  186. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/sdk_systems.py +0 -0
  187. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/sockets.py +0 -0
  188. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/starters.py +0 -0
  189. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/tests_index.py +0 -0
  190. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/udp_apps.py +0 -0
  191. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/graph.py +0 -0
  192. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/server.py +0 -0
  193. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/static/app.css +0 -0
  194. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/static/app.js +0 -0
  195. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/static/index.html +0 -0
  196. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/static/layered.js +0 -0
  197. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/static/vendor/VERSIONS.txt +0 -0
  198. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/static/vendor/cose-base.js +0 -0
  199. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/static/vendor/cytoscape-fcose.js +0 -0
  200. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/static/vendor/cytoscape.min.js +0 -0
  201. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/static/vendor/layout-base.js +0 -0
  202. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/tools/package-lock.json +0 -0
  203. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/tools/package.json +0 -0
  204. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/viz/tools/shoot.mjs +0 -0
  205. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/watch.py +0 -0
  206. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/webhooks.py +0 -0
  207. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/codegraph/xcode.py +0 -0
  208. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/pyproject.toml +0 -0
  209. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/setup.cfg +0 -0
  210. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_affected.py +0 -0
  211. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_agents_install.py +0 -0
  212. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_agents_md.py +0 -0
  213. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_ai_tools.py +0 -0
  214. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_android_ipc.py +0 -0
  215. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_apple_ipc.py +0 -0
  216. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_bridges.py +0 -0
  217. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_bridges_pigeon_monorepo.py +0 -0
  218. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_brokers.py +0 -0
  219. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_cache_clean.py +0 -0
  220. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_cache_invalidation.py +0 -0
  221. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_channels_tests.py +0 -0
  222. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_cli_output.py +0 -0
  223. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_completeness.py +0 -0
  224. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_config_extras.py +0 -0
  225. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_coverage.py +0 -0
  226. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_coverage_ts_hint.py +0 -0
  227. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_dart_isolates.py +0 -0
  228. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_dispatch_interfaces.py +0 -0
  229. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_django_flutter.py +0 -0
  230. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_docs_links.py +0 -0
  231. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_enum_constants.py +0 -0
  232. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_explore.py +0 -0
  233. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_external.py +0 -0
  234. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_gating.py +0 -0
  235. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_generated.py +0 -0
  236. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_graphql.py +0 -0
  237. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_hooks.py +0 -0
  238. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_impact_overrides.py +0 -0
  239. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_index_isolation.py +0 -0
  240. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_inherited_overrides.py +0 -0
  241. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_jobs.py +0 -0
  242. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_js_refs.py +0 -0
  243. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_kotlin.py +0 -0
  244. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_kotlin_binding.py +0 -0
  245. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_kotlin_exact.py +0 -0
  246. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_kotlin_fields.py +0 -0
  247. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_kotlin_mixed.py +0 -0
  248. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_kotlin_nav_consts.py +0 -0
  249. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_kotlin_props.py +0 -0
  250. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_laravel_determinism.py +0 -0
  251. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_laravel_resources.py +0 -0
  252. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_lint_async.py +0 -0
  253. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_local_ipc.py +0 -0
  254. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_local_sockets.py +0 -0
  255. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_mcp.py +0 -0
  256. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_mcp_index.py +0 -0
  257. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_native_cfamily.py +0 -0
  258. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_native_concurrency.py +0 -0
  259. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_native_rust.py +0 -0
  260. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_nuxt_import_dirs.py +0 -0
  261. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_nuxt_rootsrc.py +0 -0
  262. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_parity.py +0 -0
  263. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_parity_structure.py +0 -0
  264. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_php_props.py +0 -0
  265. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_plain_js.py +0 -0
  266. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_plans.py +0 -0
  267. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_platform_gaps.py +0 -0
  268. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_platform_type_variants.py +0 -0
  269. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_platforms.py +0 -0
  270. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_platforms_apple.py +0 -0
  271. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_presets_config.py +0 -0
  272. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_process_ipc.py +0 -0
  273. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_process_runs.py +0 -0
  274. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_protocols.py +0 -0
  275. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_app_tests_module.py +0 -0
  276. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_collection_chains.py +0 -0
  277. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_compat.py +0 -0
  278. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_entry_refs.py +0 -0
  279. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_fields.py +0 -0
  280. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_infer_cycles.py +0 -0
  281. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_roots.py +0 -0
  282. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_subprocess_tests.py +0 -0
  283. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_tests.py +0 -0
  284. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_web_hosts.py +0 -0
  285. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_web_routes.py +0 -0
  286. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_python_web_routes_more.py +0 -0
  287. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_realtime.py +0 -0
  288. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_realtime_native.py +0 -0
  289. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_roundtrip.py +0 -0
  290. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_route_tables.py +0 -0
  291. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_routes_search_explain.py +0 -0
  292. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_rpc.py +0 -0
  293. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_scip_health.py +0 -0
  294. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_sdk_external.py +0 -0
  295. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_snippet.py +0 -0
  296. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_sockets.py +0 -0
  297. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_starters_budget.py +0 -0
  298. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift.py +0 -0
  299. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_binding.py +0 -0
  300. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_exact.py +0 -0
  301. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_facts.py +0 -0
  302. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_fields.py +0 -0
  303. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_modules.py +0 -0
  304. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_more.py +0 -0
  305. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_nav_values.py +0 -0
  306. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_parse_errors.py +0 -0
  307. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_props.py +0 -0
  308. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_sdk.py +0 -0
  309. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_testing.py +0 -0
  310. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_swift_values.py +0 -0
  311. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_tests_scope.py +0 -0
  312. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_ts_fields.py +0 -0
  313. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_ts_fields_js_vue.py +0 -0
  314. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_ts_file_specs.py +0 -0
  315. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_ts_frameworks.py +0 -0
  316. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_ts_nuxt.py +0 -0
  317. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_ts_src_tsconfig.py +0 -0
  318. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_values.py +0 -0
  319. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_viz.py +0 -0
  320. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_vue_nav.py +0 -0
  321. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_watch.py +0 -0
  322. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_webhooks.py +0 -0
  323. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/tests/test_websockets.py +0 -0
  324. {cg_code_graph-0.14.0 → cg_code_graph-0.15.0}/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.14.0
3
+ Version: 0.15.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
@@ -72,7 +72,7 @@ dependents: 18 nodes (code: 6, entry points: 9, other: 3)
72
72
  | Language | Frameworks and facts | Calls | Docs |
73
73
  |---|---|---|---|
74
74
  | ![Python](https://img.shields.io/badge/Python-3776AB?logo=python&logoColor=white) | Django (+ DRF, django-ninja), FastAPI / Starlette, Flask, Celery | exact (stdlib `ast`) | [Python](https://code-graph.cyberchronos00.workers.dev/docs/python) |
75
- | ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white) ![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?logo=javascript&logoColor=black) | Nuxt / Vue, NestJS, Next.js, Express, Fastify, Koa, Hono | exact (TypeScript compiler API) | [TS frameworks](https://code-graph.cyberchronos00.workers.dev/docs/ts-frameworks) |
75
+ | ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white) ![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?logo=javascript&logoColor=black) | Nuxt / Vue, NestJS, Next.js, Astro, Express, Fastify, Koa, Hono | exact (TypeScript compiler API) | [TS frameworks](https://code-graph.cyberchronos00.workers.dev/docs/ts-frameworks) |
76
76
  | ![PHP](https://img.shields.io/badge/PHP-777BB4?logo=php&logoColor=white) | Laravel (routes and middleware, queues, broadcasting) | exact (nikic/php-parser; needs PHP 8.2+) | [PHP](https://code-graph.cyberchronos00.workers.dev/docs/php) |
77
77
  | ![Dart](https://img.shields.io/badge/Dart-0175C2?logo=dart&logoColor=white) | Flutter | exact (Dart analyzer; needs the Dart SDK) | [Platforms](https://code-graph.cyberchronos00.workers.dev/docs/platforms) |
78
78
  | ![Kotlin](https://img.shields.io/badge/Kotlin-7F52FF?logo=kotlin&logoColor=white) | Android, Kotlin Multiplatform | heuristic; exact with scip-java (opt-in) | [Kotlin](https://code-graph.cyberchronos00.workers.dev/docs/kotlin) |
@@ -46,7 +46,7 @@ dependents: 18 nodes (code: 6, entry points: 9, other: 3)
46
46
  | Language | Frameworks and facts | Calls | Docs |
47
47
  |---|---|---|---|
48
48
  | ![Python](https://img.shields.io/badge/Python-3776AB?logo=python&logoColor=white) | Django (+ DRF, django-ninja), FastAPI / Starlette, Flask, Celery | exact (stdlib `ast`) | [Python](https://code-graph.cyberchronos00.workers.dev/docs/python) |
49
- | ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white) ![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?logo=javascript&logoColor=black) | Nuxt / Vue, NestJS, Next.js, Express, Fastify, Koa, Hono | exact (TypeScript compiler API) | [TS frameworks](https://code-graph.cyberchronos00.workers.dev/docs/ts-frameworks) |
49
+ | ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white) ![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?logo=javascript&logoColor=black) | Nuxt / Vue, NestJS, Next.js, Astro, Express, Fastify, Koa, Hono | exact (TypeScript compiler API) | [TS frameworks](https://code-graph.cyberchronos00.workers.dev/docs/ts-frameworks) |
50
50
  | ![PHP](https://img.shields.io/badge/PHP-777BB4?logo=php&logoColor=white) | Laravel (routes and middleware, queues, broadcasting) | exact (nikic/php-parser; needs PHP 8.2+) | [PHP](https://code-graph.cyberchronos00.workers.dev/docs/php) |
51
51
  | ![Dart](https://img.shields.io/badge/Dart-0175C2?logo=dart&logoColor=white) | Flutter | exact (Dart analyzer; needs the Dart SDK) | [Platforms](https://code-graph.cyberchronos00.workers.dev/docs/platforms) |
52
52
  | ![Kotlin](https://img.shields.io/badge/Kotlin-7F52FF?logo=kotlin&logoColor=white) | Android, Kotlin Multiplatform | heuristic; exact with scip-java (opt-in) | [Kotlin](https://code-graph.cyberchronos00.workers.dev/docs/kotlin) |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cg-code-graph
3
- Version: 0.14.0
3
+ Version: 0.15.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
@@ -72,7 +72,7 @@ dependents: 18 nodes (code: 6, entry points: 9, other: 3)
72
72
  | Language | Frameworks and facts | Calls | Docs |
73
73
  |---|---|---|---|
74
74
  | ![Python](https://img.shields.io/badge/Python-3776AB?logo=python&logoColor=white) | Django (+ DRF, django-ninja), FastAPI / Starlette, Flask, Celery | exact (stdlib `ast`) | [Python](https://code-graph.cyberchronos00.workers.dev/docs/python) |
75
- | ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white) ![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?logo=javascript&logoColor=black) | Nuxt / Vue, NestJS, Next.js, Express, Fastify, Koa, Hono | exact (TypeScript compiler API) | [TS frameworks](https://code-graph.cyberchronos00.workers.dev/docs/ts-frameworks) |
75
+ | ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white) ![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?logo=javascript&logoColor=black) | Nuxt / Vue, NestJS, Next.js, Astro, Express, Fastify, Koa, Hono | exact (TypeScript compiler API) | [TS frameworks](https://code-graph.cyberchronos00.workers.dev/docs/ts-frameworks) |
76
76
  | ![PHP](https://img.shields.io/badge/PHP-777BB4?logo=php&logoColor=white) | Laravel (routes and middleware, queues, broadcasting) | exact (nikic/php-parser; needs PHP 8.2+) | [PHP](https://code-graph.cyberchronos00.workers.dev/docs/php) |
77
77
  | ![Dart](https://img.shields.io/badge/Dart-0175C2?logo=dart&logoColor=white) | Flutter | exact (Dart analyzer; needs the Dart SDK) | [Platforms](https://code-graph.cyberchronos00.workers.dev/docs/platforms) |
78
78
  | ![Kotlin](https://img.shields.io/badge/Kotlin-7F52FF?logo=kotlin&logoColor=white) | Android, Kotlin Multiplatform | heuristic; exact with scip-java (opt-in) | [Kotlin](https://code-graph.cyberchronos00.workers.dev/docs/kotlin) |
@@ -71,6 +71,8 @@ codegraph/core/plugin.py
71
71
  codegraph/core/store.py
72
72
  codegraph/core/syntax_errors.py
73
73
  codegraph/plugins/__init__.py
74
+ codegraph/plugins/astro/__init__.py
75
+ codegraph/plugins/astro/plugin.py
74
76
  codegraph/plugins/cfamily/__init__.py
75
77
  codegraph/plugins/cfamily/plugin.py
76
78
  codegraph/plugins/cfamily/syntax.py
@@ -206,6 +208,7 @@ tests/test_agents_md.py
206
208
  tests/test_ai_tools.py
207
209
  tests/test_android_ipc.py
208
210
  tests/test_apple_ipc.py
211
+ tests/test_astro.py
209
212
  tests/test_bridges.py
210
213
  tests/test_bridges_pigeon_monorepo.py
211
214
  tests/test_brokers.py
@@ -233,6 +236,7 @@ tests/test_index_isolation.py
233
236
  tests/test_inherited_overrides.py
234
237
  tests/test_jobs.py
235
238
  tests/test_js_refs.py
239
+ tests/test_js_runtime.py
236
240
  tests/test_kotlin.py
237
241
  tests/test_kotlin_binding.py
238
242
  tests/test_kotlin_exact.py
@@ -1,2 +1,2 @@
1
1
  """code-graph: deterministic code knowledge graph (beta)."""
2
- __version__ = "0.14.0"
2
+ __version__ = "0.15.0"
@@ -61,7 +61,7 @@ KNOWN_KEYS = set(SCHEMA)
61
61
  PYTHON_KEYS = SCHEMA["python"]
62
62
  VIZ_MODES = ("reaches", "impact", "downstream", "path", "plan")
63
63
  # framework plugins of codegraph/indexer.py FRAMEWORK_PLUGINS (frameworks.add / remove also take preset names)
64
- FRAMEWORK_PLUGIN_NAMES = ("laravel", "nuxt", "django", "fastapi", "flask", "flutter", "nest", "nextjs", "express")
64
+ FRAMEWORK_PLUGIN_NAMES = ("laravel", "nuxt", "django", "fastapi", "flask", "flutter", "nest", "nextjs", "express", "astro")
65
65
 
66
66
 
67
67
  class ConfigError(ValueError):
@@ -51,6 +51,9 @@ def detect(root: Path) -> dict:
51
51
  deps = _pkg_deps(root)
52
52
  if "nuxt" in deps or any((root / n).exists() for n in ("nuxt.config.ts", "nuxt.config.js")):
53
53
  fw["nuxt"] = {"version": deps.get("nuxt")}
54
+ if "astro" in deps or any((root / n).exists() for n in (
55
+ "astro.config.mjs", "astro.config.js", "astro.config.ts", "astro.config.mts", "astro.config.cjs")):
56
+ fw["astro"] = {"version": deps.get("astro")}
54
57
  if "vue" in deps:
55
58
  fw["vue"] = {"version": deps.get("vue")}
56
59
  from ..plugins.tsweb.common import SERVER_DEPS # TS / JS servers (NestJS, Next.js, Express / Koa / Fastify / Hono ...)
@@ -103,10 +103,64 @@ def status(lang: str) -> dict:
103
103
  return {"installed": _installed(d, spec), "dir": str(d), "where": "cache"}
104
104
 
105
105
 
106
+ JS_RUNTIME_MISSING = (
107
+ "node not installed (the TypeScript extractor needs Node.js 20+ or Bun on PATH, "
108
+ "or CODEGRAPH_NODE=/path/to/node)"
109
+ )
110
+
111
+
112
+ def _runtime_kind(path: str) -> str:
113
+ """`bun` when the binary (or what a `node` symlink points at, as in Bun images) is Bun, else `node`."""
114
+ names = (Path(path).name, Path(os.path.realpath(path)).name)
115
+ return "bun" if any(n.lower().startswith("bun") for n in names) else "node"
116
+
117
+
118
+ def _override() -> str | None:
119
+ v = (os.environ.get("CODEGRAPH_NODE") or "").strip()
120
+ return os.path.expanduser(v) if v else None
121
+
122
+
123
+ def js_runtime() -> dict | None:
124
+ """Node.js or Bun for the TypeScript extractor.
125
+
126
+ ``CODEGRAPH_NODE`` (a name on PATH or a path) wins, then ``node`` on PATH, then ``bun``.
127
+ """
128
+ override = _override()
129
+ if override:
130
+ path = shutil.which(override)
131
+ if not path:
132
+ return None
133
+ return {"path": path, "kind": _runtime_kind(path), "source": "CODEGRAPH_NODE"}
134
+ node = shutil.which("node")
135
+ if node:
136
+ return {"path": node, "kind": _runtime_kind(node), "source": "PATH"}
137
+ bun = shutil.which("bun")
138
+ if bun:
139
+ return {"path": bun, "kind": "bun", "source": "PATH"}
140
+ return None
141
+
142
+
143
+ def js_runtime_problem() -> str | None:
144
+ """Why the TypeScript extractor cannot start, or None when a runtime resolves."""
145
+ override = _override()
146
+ if override and not shutil.which(override):
147
+ return (f"CODEGRAPH_NODE={os.environ.get('CODEGRAPH_NODE')} is not an executable on PATH or a path to one "
148
+ "(set it to a node or bun binary, or unset it to use node / bun from PATH)")
149
+ if js_runtime() is None:
150
+ return JS_RUNTIME_MISSING
151
+ return None
152
+
153
+
106
154
  def install_command(lang: str, dart: str | None = None) -> list[str]:
107
155
  if lang == "typescript":
108
- npm = shutil.which("npm") or "npm"
109
- return [npm, "ci", "--no-audit", "--no-fund", "--loglevel=error"]
156
+ npm = shutil.which("npm")
157
+ if npm:
158
+ return [npm, "ci", "--no-audit", "--no-fund", "--loglevel=error"]
159
+ rt = js_runtime()
160
+ bun = rt["path"] if rt and rt["kind"] == "bun" else shutil.which("bun")
161
+ if bun:
162
+ return [bun, "install", "--frozen-lockfile", "--no-progress"]
163
+ return ["npm", "ci", "--no-audit", "--no-fund", "--loglevel=error"]
110
164
  if lang == "php":
111
165
  return [shutil.which("composer") or "composer", "install", "--no-dev", "--no-interaction", "--no-progress", "--quiet"]
112
166
  return [dart or shutil.which("dart") or "dart", "pub", "get"]
@@ -180,7 +234,8 @@ def prune(dry_run: bool = False) -> list[tuple[Path, int]]:
180
234
 
181
235
  def _run(cmd: list[str], d: Path, spec: Spec) -> None:
182
236
  if not shutil.which(cmd[0]) and not Path(cmd[0]).exists():
183
- raise RuntimeError(f"{spec.label} extractor dependencies missing and `{spec.tool}` is not installed")
237
+ tool = "`npm` (or `bun`)" if spec.tool == "npm" else f"`{spec.tool}`"
238
+ raise RuntimeError(f"{spec.label} extractor dependencies missing and {tool} is not installed")
184
239
  r = subprocess.run(cmd, cwd=d, capture_output=True, text=True)
185
240
  if r.returncode != 0:
186
241
  raise RuntimeError(f"{spec.label} extractor dependency install failed ({' '.join(cmd[:2])} in {d}): "
@@ -16,7 +16,7 @@ from pathlib import Path
16
16
  # source extensions per language plugin (key = plugin name in stats["plugins"])
17
17
  SUPPORTED = {
18
18
  "php": (".php",),
19
- "typescript": (".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".vue"),
19
+ "typescript": (".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".vue", ".astro"),
20
20
  "python": (".py",),
21
21
  "dart": (".dart",),
22
22
  "rust": (".rs",),
@@ -33,7 +33,7 @@ UNSUPPORTED = {
33
33
  ".pl": "perl", ".pm": "perl", ".clj": "clojure", ".erl": "erlang", ".hrl": "erlang", ".hs": "haskell", ".fs": "fsharp",
34
34
  ".fsx": "fsharp", ".groovy": "groovy", ".r": "r", ".jl": "julia", ".zig": "zig", ".sol": "solidity",
35
35
  ".qml": "qml", ".sh": "sh", ".bash": "sh", ".zsh": "sh", ".ksh": "sh", ".fish": "fish", ".ps1": "powershell",
36
- ".psm1": "powershell", ".bat": "batch", ".cmd": "batch", ".svelte": "svelte", ".astro": "astro",
36
+ ".psm1": "powershell", ".bat": "batch", ".cmd": "batch", ".svelte": "svelte",
37
37
  ".coffee": "coffeescript", ".elm": "elm", ".ml": "ocaml", ".mli": "ocaml", ".nim": "nim", ".cr": "crystal",
38
38
  ".rkt": "racket", ".tcl": "tcl", ".vb": "visual-basic", ".cu": "cuda", ".cuh": "cuda", ".gd": "gdscript",
39
39
  ".hx": "haxe", ".pas": "pascal", ".f90": "fortran", ".f95": "fortran", ".adb": "ada", ".ads": "ada", ".vala": "vala",
@@ -58,7 +58,7 @@ MAX_PATHS = 500 # file paths stored per bucket in the index (counts are alw
58
58
  SHOW_PATHS = 5 # shown per bucket by default (`cg coverage --all-files` / coverage(all_files=true) for all)
59
59
  HINTS = {
60
60
  "php": "install PHP 8.2+ and Composer, then run `cg setup php` (`cg doctor` checks the toolchains)",
61
- "typescript": "install Node.js 20+ (with npm), then run `cg setup typescript` (`cg doctor` checks the toolchains)",
61
+ "typescript": "install Node.js 20+ (with npm) or Bun, or set CODEGRAPH_NODE, then run `cg setup typescript` (`cg doctor` checks the toolchains)",
62
62
  "dart": "install the Dart SDK 3.x (`dart` on PATH or $DART), then run `cg setup dart`",
63
63
  "rust": "exact mode needs rust-analyzer (`rustup component add rust-analyzer`){layer}",
64
64
  "c_cpp": "exact mode needs scip-clang and a compile_commands.json (docs/native.md){layer}",
@@ -104,7 +104,8 @@ def _tools() -> dict:
104
104
  from .plugins.swift.exact import find_swift
105
105
  home = Path.home()
106
106
  found = {
107
- "node": shutil.which("node"), "npm": shutil.which("npm"), "php": shutil.which("php"),
107
+ "node": shutil.which(extractors._override() or "node"),
108
+ "npm": shutil.which("npm"), "bun": shutil.which("bun"), "php": shutil.which("php"),
108
109
  "composer": shutil.which("composer"), "dart": find_dart(),
109
110
  "rust-analyzer": find_tool("CODEGRAPH_RUST_ANALYZER", ["rust-analyzer"], [home / ".cargo" / "bin"]),
110
111
  "cargo": os.environ.get("CODEGRAPH_CARGO") or shutil.which("cargo") or
@@ -143,14 +144,17 @@ def _languages(tools: dict, root: Path | None, cfg: dict) -> list[dict]:
143
144
 
144
145
  add("python", "exact", "built-in parser (Python ast)")
145
146
  st = extractors.status("typescript")
146
- if not has("node"):
147
- add("typescript", "unavailable", "node not installed (Node.js 20+ runs the TypeScript extractor)",
148
- "install Node.js 20+ (https://nodejs.org or your package manager), then `cg setup typescript`")
149
- elif not st["installed"] and not has("npm"):
150
- add("typescript", "unavailable", "extractor dependencies missing and npm not installed", "install npm, then `cg setup typescript`")
147
+ rt = extractors.js_runtime()
148
+ if rt is None:
149
+ add("typescript", "unavailable", extractors.js_runtime_problem(),
150
+ "install Node.js 20+ or Bun (or set CODEGRAPH_NODE), then `cg setup typescript`")
151
+ elif not st["installed"] and not has("npm") and not has("bun"):
152
+ add("typescript", "unavailable", "extractor dependencies missing and npm not installed",
153
+ "install npm, then `cg setup typescript`")
151
154
  else:
152
- add("typescript", "exact", "TypeScript compiler API" + ("" if st["installed"] else
153
- "; its npm dependencies install on the first index (or now: `cg setup typescript`)"))
155
+ add("typescript", "exact", f"TypeScript compiler API (runtime: {rt['kind']} {rt['path']})" + (
156
+ "" if st["installed"] else "; its npm dependencies install on the first index (or now: `cg setup typescript`)"),
157
+ runtime={"kind": rt["kind"], "path": rt["path"], "source": rt["source"]})
154
158
  st = extractors.status("php")
155
159
  if not has("php"):
156
160
  add("php", "unavailable", "php not installed (PHP 8.2+ runs the PHP extractor)", "install PHP 8.2+ and Composer, then `cg setup php`")
@@ -434,9 +438,17 @@ def setup(langs: list[str] | None = None, quiet: bool = False) -> int:
434
438
  tool = {"typescript": "npm", "php": "composer", "dart": None}[lang]
435
439
  need = {"typescript": "node", "php": "php", "dart": None}[lang]
436
440
  dart = find_dart() if lang == "dart" else None
437
- if (need and not shutil.which(need)) or (tool and not shutil.which(tool) and not extractors.status(lang)["installed"]) \
438
- or (lang == "dart" and not dart):
439
- msg = f"{lang}: skipped ({'dart' if lang == 'dart' else need if need and not shutil.which(need) else tool} not installed)"
441
+ if lang == "typescript":
442
+ rt = extractors.js_runtime()
443
+ can_install = extractors.status(lang)["installed"] or bool(shutil.which("npm") or shutil.which("bun"))
444
+ skip = rt is None or not can_install
445
+ detail = extractors.js_runtime_problem() if rt is None else "npm or bun not installed"
446
+ else:
447
+ skip = (need and not shutil.which(need)) or (tool and not shutil.which(tool) and not extractors.status(lang)["installed"]) \
448
+ or (lang == "dart" and not dart)
449
+ detail = f"{'dart' if lang == 'dart' else need if need and not shutil.which(need) else tool} not installed"
450
+ if skip:
451
+ msg = f"{lang}: skipped ({detail})"
440
452
  print(msg, file=sys.stderr)
441
453
  rc = rc or (1 if langs else 0)
442
454
  continue
@@ -26,12 +26,13 @@ from .plugins.flutter.plugin import FlutterPlugin
26
26
  from .plugins.nest.plugin import NestPlugin
27
27
  from .plugins.nextjs.plugin import NextPlugin
28
28
  from .plugins.express.plugin import ExpressPlugin
29
+ from .plugins.astro.plugin import AstroPlugin
29
30
  from .plugins.kotlin.plugin import KotlinPlugin
30
31
  from .plugins.swift.plugin import SwiftPlugin
31
32
 
32
33
  LANGUAGE_PLUGINS = [PhpPlugin(), TypeScriptPlugin(), PythonPlugin(), DartPlugin(), RustPlugin(), CFamilyPlugin(), KotlinPlugin(), SwiftPlugin(),
33
34
  *SCIP_PLUGINS]
34
- FRAMEWORK_PLUGINS = [LaravelPlugin(), NuxtPlugin(), DjangoPlugin(), FastAPIPlugin(), FlaskPlugin(), FlutterPlugin(), NestPlugin(), NextPlugin(), ExpressPlugin()]
35
+ FRAMEWORK_PLUGINS = [LaravelPlugin(), NuxtPlugin(), DjangoPlugin(), FastAPIPlugin(), FlaskPlugin(), FlutterPlugin(), NestPlugin(), NextPlugin(), ExpressPlugin(), AstroPlugin()]
35
36
 
36
37
 
37
38
  def _crash_site(ex: BaseException) -> str | None:
@@ -0,0 +1,126 @@
1
+ """Astro framework layer (on the TypeScript plugin).
2
+
3
+ pages src/pages/**.astro -> page node (route `/`, `/books/{slug}`, `/docs/{rest*}`; entry ui_page).
4
+ A segment starting with `_` is skipped. Frontmatter and <script> blocks are TypeScript at
5
+ their real lines (the extractor); template expressions are not code.
6
+ endpoints src/pages/**.{ts,js,mts,mjs} exporting GET/POST/... (`ALL` -> ANY) -> one route each
7
+ components <Card /> in the template -> RENDERS; imports from .ts and other .astro files resolve
8
+ getStaticPaths recorded as attrs.get_static_paths when the frontmatter exports it (not evaluated)
9
+ is:inline <script is:inline> counted on the file node as attrs.inline_scripts
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import re
14
+
15
+ from ...core.plugin import FrameworkPlugin, GraphBuilder, Project
16
+ from ..tsweb.common import HTTP_VERBS, add_route, finish, fw_facts, merge_extractor_cfg, register, pkg_deps
17
+
18
+ CONFIG_FILES = ("astro.config.mjs", "astro.config.js", "astro.config.ts", "astro.config.mts", "astro.config.cjs")
19
+ _PAGE_EXT = (".astro", ".mts", ".mjs", ".ts", ".js")
20
+ _GSP = re.compile(r"export\s+(?:async\s+)?function\s+getStaticPaths\b|export\s+const\s+getStaticPaths\b")
21
+ _FM_OPEN = re.compile(r"\ufeff?\s*---[ \t]*\r?\n")
22
+ _INLINE = re.compile(r"<script\b([^>]*)>", re.I)
23
+ _CATCHALL = re.compile(r"\[\.\.\.([^\]]+)\]")
24
+ _PARAM = re.compile(r"\[([^\]]+)\]")
25
+ _ENDPOINT = re.compile(r"^src/pages/.+\.(?:ts|js|mts|mjs)$")
26
+
27
+
28
+ def astro_route(rel: str) -> str | None:
29
+ """src/pages path -> `/`, `/books/{slug}`, `/docs/{rest*}`. None when a segment starts with `_`."""
30
+ rel = rel.replace("\\", "/")
31
+ if not rel.startswith("src/pages/") or rel.endswith(".d.ts"):
32
+ return None
33
+ rest = rel[len("src/pages/"):]
34
+ for ext in _PAGE_EXT:
35
+ if rest.endswith(ext):
36
+ rest = rest[: -len(ext)]
37
+ break
38
+ segs = [s for s in rest.split("/") if s]
39
+ if any(s.startswith("_") for s in segs):
40
+ return None
41
+ if segs and segs[-1] == "index":
42
+ segs.pop()
43
+ segs = [_PARAM.sub(r"{\1}", _CATCHALL.sub(r"{\1*}", s)) for s in segs]
44
+ return "/" + "/".join(segs)
45
+
46
+
47
+ def _split(text: str) -> tuple[str, str]:
48
+ """(frontmatter, template), as the extractor reads them: an empty frontmatter counts, an unclosed one runs to
49
+ the end of the file."""
50
+ m = _FM_OPEN.match(text)
51
+ if not m:
52
+ return "", text
53
+ start = m.end()
54
+ end = text.find("\n---", start - 1)
55
+ if end < 0:
56
+ return text[start:], ""
57
+ return text[start:max(start, end)], text[end + 4:]
58
+
59
+
60
+ def _inline_scripts(template: str) -> int:
61
+ return sum(1 for m in _INLINE.finditer(template) if re.search(r"\bis:inline\b", m.group(1)))
62
+
63
+
64
+ class AstroPlugin(FrameworkPlugin):
65
+ name, language = "astro", "typescript"
66
+
67
+ def detect(self, project: Project) -> bool:
68
+ return "astro" in pkg_deps(project.root) or any(project.exists(f) for f in CONFIG_FILES)
69
+
70
+ def register_hooks(self, ctx) -> None:
71
+ root = ctx.project.root
72
+ cfg = ctx.extractor_cfg
73
+ kinds = cfg.setdefault("kinds", [])
74
+ kinds.extend([("src/pages/", "page"), ("src/layouts/", "layout"), ("src/components/", "component")])
75
+ merge_extractor_cfg(cfg, src_dirs=["src"], walk_src=not (root / "tsconfig.json").exists())
76
+ register(ctx, self.name)
77
+
78
+ def contribute(self, project: Project, b: GraphBuilder, ctx) -> dict:
79
+ st = {"pages": 0, "endpoints": 0, "layouts": 0, "components": 0, "inline_scripts": 0, "get_static_paths": 0}
80
+ for n in b.nodes.values():
81
+ if not n.file or not n.file.endswith(".astro") or n.kind not in ("page", "layout", "component"):
82
+ continue
83
+ try:
84
+ text = (project.root / n.file).read_text(encoding="utf-8", errors="replace")
85
+ except OSError:
86
+ text = ""
87
+ if n.kind == "page":
88
+ route = astro_route(n.file)
89
+ if route is not None:
90
+ n.name = n.fqn = route
91
+ n.attrs.update(route=route, uri=route, framework="astro")
92
+ n.entry_kind = "ui_page"
93
+ st["pages"] += 1
94
+ if _GSP.search(_split(text)[0]):
95
+ n.attrs["get_static_paths"] = True
96
+ st["get_static_paths"] += 1
97
+ elif n.kind == "layout":
98
+ st["layouts"] += 1
99
+ else:
100
+ st["components"] += 1
101
+ inline = _inline_scripts(_split(text)[1])
102
+ if inline:
103
+ n.attrs["inline_scripts"] = inline
104
+ st["inline_scripts"] += inline
105
+ mods = (fw_facts(ctx).get("modules") or {})
106
+ for f, mod in mods.items():
107
+ if f.endswith(".d.ts") or not _ENDPOINT.match(f):
108
+ continue
109
+ uri = astro_route(f)
110
+ if uri is None:
111
+ continue
112
+ for ex in mod.get("exports") or []:
113
+ name = ex.get("name") or ""
114
+ if name == "ALL":
115
+ verb = "ANY"
116
+ elif name in HTTP_VERBS:
117
+ verb = name
118
+ else:
119
+ continue
120
+ node = ex.get("node")
121
+ handlers = [node] if node and b.has(node) else []
122
+ add_route(b, verb, uri, handlers, f, ex.get("line") or 1, "astro",
123
+ "exact" if handlers else "resolved", {"file_route": True})
124
+ st["endpoints"] += 1
125
+ st.update(finish(project, b, ctx, self.name))
126
+ return st
@@ -54,6 +54,8 @@ const EXCLUDE_FILES = new Set(cfg.exclude_files || [])
54
54
  const GENERATED_REL = cfg.generated_re ? new RegExp(cfg.generated_re) : null
55
55
  const excludedRel = r => !!(EXCLUDE_REL && EXCLUDE_REL.test(r)) || (!included(r.replace(/\/$/, '')) && (!!(GENERATED_REL && GENERATED_REL.test(r)) || EXCLUDE_FILES.has(r)))
56
56
  const SRC_EXT = /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/
57
+ const SFC_RE = /\.(vue|astro)$/
58
+ const SFC_TS_RE = /\.(vue|astro)\.ts$/
57
59
  // test code (Vitest / Jest / Playwright / Cypress): indexed as test nodes unless cfg.index_tests === false; kept out of
58
60
  // the application graph by the indexer (TEST_* edges)
59
61
  const INDEX_TESTS = cfg.index_tests !== false
@@ -65,7 +67,7 @@ const isTestRel = r => TEST_FILE_RE.test(r) || /(^|\/)__tests__\//.test(r) || TE
65
67
  // ---------- file kinds (from the framework plugin: [[prefix, kind], ...]) ----------
66
68
  function fileKind(r) {
67
69
  for (const [prefix, kind] of cfg.kinds || []) if (r.startsWith(prefix)) return kind
68
- return r.endsWith('.vue') ? 'component' : 'module'
70
+ return SFC_RE.test(r) ? 'component' : 'module'
69
71
  }
70
72
 
71
73
  // ---------- global components (Nuxt .nuxt/types/components.d.ts) ----------
@@ -327,14 +329,15 @@ if (INDEX_TESTS) {
327
329
  if (found.size) process.stderr.write(`codegraph: scripts the tests run: ${[...found].map(rel).sort().join(', ')}\n`)
328
330
  }
329
331
  const vueFiles = allFiles.filter(f => f.endsWith('.vue'))
330
- const vueSet = new Set(vueFiles)
332
+ const astroFiles = allFiles.filter(f => f.endsWith('.astro'))
333
+ const vueSet = new Set([...vueFiles, ...astroFiles])
331
334
 
332
335
  // ---------- virtual sources for .vue ----------
333
336
  const virtual = new Map() // virtual path -> text
334
337
  const lineMaps = new Map() // virtual path -> {virtualLine(1-based): origLine}
335
338
  const sfcInfo = new Map()
336
339
  const sfcI18n = {} // rel vue path -> keys defined in <i18n> blocks // vue abs path -> {templateTags:[...], pageMeta}
337
- const stats = { vue_files: vueFiles.length, ts_files: 0, template_stubs: 0, template_component_tags: 0,
340
+ const stats = { vue_files: vueFiles.length, astro_files: astroFiles.length, ts_files: 0, template_stubs: 0, template_component_tags: 0,
338
341
  sfc_errors: 0, components_global: 0, components_imported: 0, components_external: 0, components_unknown: 0, unknown_tags: {} }
339
342
  const sfcNav = [] // static <NuxtLink to> / <RouterLink to> / <a href>
340
343
  function internalHref(v) {
@@ -458,6 +461,59 @@ function buildVirtualVue(file) {
458
461
  }
459
462
  for (const f of vueFiles) virtual.set(f + '.ts', buildVirtualVue(f))
460
463
 
464
+ // .astro: frontmatter and <script> bodies stay at their real offsets; component tags become
465
+ // __tplc_ stubs with a line map. `export {}` makes a frontmatter with no import/export a module.
466
+ function astroScriptKept(attrs) {
467
+ const m = /\btype\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+))/i.exec(attrs || '')
468
+ if (!m) return true
469
+ const t = (m[1] || m[2] || m[3] || '').trim()
470
+ return /^(?:module|text\/javascript|text\/typescript)$/i.test(t)
471
+ }
472
+ // frontmatter: `---` on the first line, up to the next line starting with `---` (an empty one included); an
473
+ // unclosed fence runs to the end of the file, as in the Astro compiler
474
+ function astroFrontmatter(src) {
475
+ const open = /^\s*---[ \t]*\r?\n/.exec(src)
476
+ if (!open) return null
477
+ const start = open[0].length
478
+ const close = /\n---/g
479
+ close.lastIndex = start - 1
480
+ const c = close.exec(src)
481
+ return c ? { start, end: Math.max(start, c.index), tpl: c.index + 4 } : { start, end: src.length, tpl: src.length }
482
+ }
483
+ function buildVirtualAstro(file) {
484
+ let src
485
+ try { src = fs.readFileSync(file, 'utf8') } catch (e) { process.stderr.write(`codegraph: skipping ${rel(file)}: ${e.code || e}\n`); return '' }
486
+ const keep = []
487
+ const fm = astroFrontmatter(src)
488
+ if (fm) keep.push([fm.start, fm.end])
489
+ // one pass over the template: comments, <script> / <style> (an unclosed one runs to the end) and component tags
490
+ const stubs = []
491
+ let n = 0, line = 1, at = 0
492
+ const lineAt = i => { for (; at < i; at++) if (src.charCodeAt(at) === 10) line++; return line }
493
+ const re = /<!--[\s\S]*?(?:-->|$)|<(script|style)\b([^>]*)>([\s\S]*?)(?:<\/\1\s*>|$)|<([A-Z][\w$]*)/g
494
+ re.lastIndex = fm ? fm.tpl : 0
495
+ let m
496
+ while ((m = re.exec(src))) {
497
+ if (m[1] === 'script' && astroScriptKept(m[2])) {
498
+ const s = m.index + 1 + m[1].length + m[2].length + 1
499
+ keep.push([s, s + m[3].length])
500
+ } else if (m[4]) {
501
+ stubs.push([`function __tplc_${n++}() { return typeof ${m[4]} }`, lineAt(m.index)])
502
+ stats.template_stubs++
503
+ stats.template_component_tags++
504
+ }
505
+ }
506
+ const text = blank(src, keep)
507
+ const baseLines = text.split('\n').length
508
+ const lm = {}
509
+ let out = text
510
+ stubs.forEach(([code, l], i) => { lm[baseLines + 1 + i] = l; out += '\n' + code })
511
+ out += '\nexport {}'
512
+ lineMaps.set(file + '.ts', lm)
513
+ return out
514
+ }
515
+ for (const f of astroFiles) virtual.set(f + '.ts', buildVirtualAstro(f))
516
+
461
517
  // ---------- compiler host ----------
462
518
  const host = ts.createCompilerHost(options, true)
463
519
  const origGetSourceFile = host.getSourceFile.bind(host)
@@ -483,8 +539,8 @@ function resolveVuePath(spec, containing) {
483
539
  }
484
540
  host.resolveModuleNameLiterals = (lits, containing, redirected, opts) => lits.map(l => {
485
541
  const spec = l.text
486
- const containingReal = containing.endsWith('.vue.ts') ? containing.slice(0, -3) : containing
487
- if (spec.endsWith('.vue')) {
542
+ const containingReal = SFC_TS_RE.test(containing) ? containing.slice(0, -3) : containing
543
+ if (SFC_RE.test(spec)) {
488
544
  const p = resolveVuePath(spec, containingReal)
489
545
  if (p) return { resolvedModule: { resolvedFileName: p + '.ts', extension: ts.Extension.Ts, isExternalLibraryImport: false } }
490
546
  }
@@ -515,12 +571,12 @@ const projectSf = sf => {
515
571
  const fn = sf.fileName
516
572
  let v = projectSfMemo.get(fn)
517
573
  if (v !== undefined) return v
518
- const real = fn.endsWith('.vue.ts') ? fn.slice(0, -3) : fn
574
+ const real = SFC_TS_RE.test(fn) ? fn.slice(0, -3) : fn
519
575
  v = testFiles.has(real) || (!sourceSkipped(rel(real)) && (srcFiles.has(real) || srcDirs.some(d => real.startsWith(d + path.sep))) && !SKIP_FILE.test(real) && !real.endsWith('.d.ts') && !(SKIP_REL && SKIP_REL.test(rel(real))) && !excludedRel(rel(real)))
520
576
  projectSfMemo.set(fn, v)
521
577
  return v
522
578
  }
523
- const realFile = sf => sf.fileName.endsWith('.vue.ts') ? sf.fileName.slice(0, -3) : sf.fileName
579
+ const realFile = sf => SFC_TS_RE.test(sf.fileName) ? sf.fileName.slice(0, -3) : sf.fileName
524
580
  function lineOf(node, sf = node.getSourceFile()) {
525
581
  const l = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1
526
582
  const lm = lineMaps.get(sf.fileName)
@@ -1006,7 +1062,7 @@ const implementedIfaces = new Set()
1006
1062
  else if (classOfValue(n)) for (const d of ctorIfaces(n)) addIface(d)
1007
1063
  ts.forEachChild(n, walk)
1008
1064
  }
1009
- for (const sf of sourceFiles) if (!realFile(sf).endsWith('.vue')) walk(sf)
1065
+ for (const sf of sourceFiles) if (!SFC_RE.test(realFile(sf))) walk(sf)
1010
1066
  }
1011
1067
  const isFnType = t => t && (ts.isFunctionTypeNode(t) || (ts.isParenthesizedTypeNode(t) && isFnType(t.type)))
1012
1068
  // members of an interface / object type alias: `method:<file>#Iface.member` (attrs.signature; no body). A call on an
@@ -1037,25 +1093,25 @@ for (const sf of sourceFiles) {
1037
1093
  const txt = sf.text
1038
1094
  testFramework = /@playwright\/test/.test(txt) ? 'playwright' : /from ['"]vitest['"]/.test(txt) ? 'vitest' : /\bcy\./.test(txt) ? 'cypress' : /@jest\/globals|jest\./.test(txt) ? 'jest' : 'test'
1039
1095
  }
1040
- if (!real.endsWith('.vue')) stats.ts_files++
1096
+ if (!SFC_RE.test(real)) stats.ts_files++
1041
1097
  if (sf.parseDiagnostics && sf.parseDiagnostics.length) { // the parser recovers; count files that needed recovery
1042
1098
  stats.syntax_error_files = (stats.syntax_error_files || 0) + 1
1043
1099
  if ((stats.syntax_error_samples ||= []).length < 5) stats.syntax_error_samples.push(r)
1044
1100
  // error lines per file for `cg coverage` (#73); in a .vue file only those of its <script> blocks (the template
1045
1101
  // stubs are appended after the file's own lines)
1046
1102
  let maxLine = Infinity
1047
- if (real.endsWith('.vue')) { try { maxLine = fs.readFileSync(real, 'utf8').split('\n').length } catch (e) { maxLine = 0 } }
1103
+ if (SFC_RE.test(real)) { try { maxLine = fs.readFileSync(real, 'utf8').split('\n').length } catch (e) { maxLine = 0 } }
1048
1104
  const lines = [...new Set(sf.parseDiagnostics.map(d => sf.getLineAndCharacterOfPosition(d.start || 0).line + 1))]
1049
1105
  .filter(l => l <= maxLine).slice(0, 20)
1050
1106
  const se = (stats.syntax_errors ||= {})
1051
1107
  if (lines.length && Object.keys(se).length < 500) se[r] = lines.map(l => [l, l])
1052
1108
  }
1053
- const fid = real.endsWith('.vue') ? `${fk}:${r}` : `module:${r}`
1109
+ const fid = SFC_RE.test(real) ? `${fk}:${r}` : `module:${r}`
1054
1110
  usedIds.add(fid)
1055
1111
  fileNode.set(real, fid)
1056
- nodes.push({ id: fid, kind: real.endsWith('.vue') ? fk : 'module', name: r, file: r, line: 1, end_line: sf.getLineAndCharacterOfPosition(sf.end).line + 1, attrs: { file_kind: fk, ...(isTestSf ? { test: true } : {}) } })
1112
+ nodes.push({ id: fid, kind: SFC_RE.test(real) ? fk : 'module', name: r, file: r, line: 1, end_line: sf.getLineAndCharacterOfPosition(sf.end).line + 1, attrs: { file_kind: fk, ...(isTestSf ? { test: true } : {}) } })
1057
1113
  modNode.set(fid, nodes[nodes.length - 1])
1058
- if (real.endsWith('.vue')) continue // SFC: references are attributed to the component node
1114
+ if (SFC_RE.test(real)) continue // SFC: references are attributed to the file node
1059
1115
  const visit = (node, qual, parentId, inObj) => {
1060
1116
  let name = null, kind = null, body = null, wrapped = null
1061
1117
  if (!qual && !inObj && ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer
@@ -1293,7 +1349,7 @@ function resolveSymbol(sym, conf = 'exact', via = []) {
1293
1349
  if (sym.flags & ts.SymbolFlags.Alias) {
1294
1350
  const ad = (sym.declarations || [])[0]
1295
1351
  const imp = ad && (ts.isImportClause(ad) ? ad.parent : (ts.isImportSpecifier(ad) ? ad.parent.parent.parent : null))
1296
- if (imp && ts.isImportDeclaration(imp) && imp.moduleSpecifier.text.endsWith('.vue')) {
1352
+ if (imp && ts.isImportDeclaration(imp) && SFC_RE.test(imp.moduleSpecifier.text)) {
1297
1353
  const ms = checker.getSymbolAtLocation(imp.moduleSpecifier); const sd = ms && (ms.declarations || [])[0]
1298
1354
  if (sd && ts.isSourceFile(sd) && fileNode.has(realFile(sd))) return { id: fileNode.get(realFile(sd)), conf, via: [...via, 'import'] }
1299
1355
  }
@@ -1850,7 +1906,7 @@ const callSites = []
1850
1906
  // structural: `new X()` where an interface type is expected (`const api: FeedAPI = new X()`, an argument, a return
1851
1907
  // value) and X does not declare `implements` it
1852
1908
  for (const sf of sourceFiles) {
1853
- if (realFile(sf).endsWith('.vue') || !sf.text.includes('new ')) continue
1909
+ if (SFC_RE.test(realFile(sf)) || !sf.text.includes('new ')) continue
1854
1910
  const r = rel(realFile(sf))
1855
1911
  const done = new Set()
1856
1912
  const walk = n => {
@@ -1880,7 +1936,7 @@ const callSites = []
1880
1936
  // constructor of an interface is expected (`register(FollowingFeedAPI)`): structurally, as for `new X()`
1881
1937
  let nol = 0
1882
1938
  for (const sf of sourceFiles) {
1883
- if (realFile(sf).endsWith('.vue')) continue
1939
+ if (SFC_RE.test(realFile(sf))) continue
1884
1940
  const r = rel(realFile(sf))
1885
1941
  const done = new Set()
1886
1942
  const walk = n => {
@@ -2438,7 +2494,7 @@ function edgeKindFor(targetId, isCall) {
2438
2494
  for (const sf of sourceFiles) { const real = realFile(sf); optionsFields(sf, rel(real), fileNode.get(real)) }
2439
2495
  for (const sf of sourceFiles) {
2440
2496
  const real = realFile(sf), r = rel(real), fid = fileNode.get(real)
2441
- const isVue = real.endsWith('.vue')
2497
+ const isVue = SFC_RE.test(real)
2442
2498
  const stack = [fid]
2443
2499
  const fnStack = []
2444
2500
  const visit = node => {