@backthread/extractor 0.1.0

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 (379) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -0
  3. package/dist/cluster/domain-grouping.d.ts +113 -0
  4. package/dist/cluster/domain-grouping.d.ts.map +1 -0
  5. package/dist/cluster/domain-grouping.js +277 -0
  6. package/dist/cluster/domain-grouping.js.map +1 -0
  7. package/dist/cluster/grouping-gate.d.ts +54 -0
  8. package/dist/cluster/grouping-gate.d.ts.map +1 -0
  9. package/dist/cluster/grouping-gate.js +0 -0
  10. package/dist/cluster/grouping-gate.js.map +1 -0
  11. package/dist/cluster/louvain.d.ts +88 -0
  12. package/dist/cluster/louvain.d.ts.map +1 -0
  13. package/dist/cluster/louvain.js +674 -0
  14. package/dist/cluster/louvain.js.map +1 -0
  15. package/dist/cluster/overrides.d.ts +19 -0
  16. package/dist/cluster/overrides.d.ts.map +1 -0
  17. package/dist/cluster/overrides.js +32 -0
  18. package/dist/cluster/overrides.js.map +1 -0
  19. package/dist/cluster/subsystem.d.ts +45 -0
  20. package/dist/cluster/subsystem.d.ts.map +1 -0
  21. package/dist/cluster/subsystem.js +299 -0
  22. package/dist/cluster/subsystem.js.map +1 -0
  23. package/dist/cluster/workspaces.d.ts +64 -0
  24. package/dist/cluster/workspaces.d.ts.map +1 -0
  25. package/dist/cluster/workspaces.js +739 -0
  26. package/dist/cluster/workspaces.js.map +1 -0
  27. package/dist/extract.d.ts +52 -0
  28. package/dist/extract.d.ts.map +1 -0
  29. package/dist/extract.js +48 -0
  30. package/dist/extract.js.map +1 -0
  31. package/dist/framework/celery/celery.d.ts +17 -0
  32. package/dist/framework/celery/celery.d.ts.map +1 -0
  33. package/dist/framework/celery/celery.js +524 -0
  34. package/dist/framework/celery/celery.js.map +1 -0
  35. package/dist/framework/contribute-step.d.ts +38 -0
  36. package/dist/framework/contribute-step.d.ts.map +1 -0
  37. package/dist/framework/contribute-step.js +403 -0
  38. package/dist/framework/contribute-step.js.map +1 -0
  39. package/dist/framework/detect-step.d.ts +8 -0
  40. package/dist/framework/detect-step.d.ts.map +1 -0
  41. package/dist/framework/detect-step.js +54 -0
  42. package/dist/framework/detect-step.js.map +1 -0
  43. package/dist/framework/detect-util.d.ts +24 -0
  44. package/dist/framework/detect-util.d.ts.map +1 -0
  45. package/dist/framework/detect-util.js +59 -0
  46. package/dist/framework/detect-util.js.map +1 -0
  47. package/dist/framework/django/django.d.ts +22 -0
  48. package/dist/framework/django/django.d.ts.map +1 -0
  49. package/dist/framework/django/django.js +940 -0
  50. package/dist/framework/django/django.js.map +1 -0
  51. package/dist/framework/fastapi/fastapi.d.ts +27 -0
  52. package/dist/framework/fastapi/fastapi.d.ts.map +1 -0
  53. package/dist/framework/fastapi/fastapi.js +477 -0
  54. package/dist/framework/fastapi/fastapi.js.map +1 -0
  55. package/dist/framework/faststream/faststream.d.ts +19 -0
  56. package/dist/framework/faststream/faststream.d.ts.map +1 -0
  57. package/dist/framework/faststream/faststream.js +765 -0
  58. package/dist/framework/faststream/faststream.js.map +1 -0
  59. package/dist/framework/flask/flask.d.ts +17 -0
  60. package/dist/framework/flask/flask.d.ts.map +1 -0
  61. package/dist/framework/flask/flask.js +507 -0
  62. package/dist/framework/flask/flask.js.map +1 -0
  63. package/dist/framework/graphql/graphql.d.ts +17 -0
  64. package/dist/framework/graphql/graphql.d.ts.map +1 -0
  65. package/dist/framework/graphql/graphql.js +708 -0
  66. package/dist/framework/graphql/graphql.js.map +1 -0
  67. package/dist/framework/grpc/grpc.d.ts +22 -0
  68. package/dist/framework/grpc/grpc.d.ts.map +1 -0
  69. package/dist/framework/grpc/grpc.js +618 -0
  70. package/dist/framework/grpc/grpc.js.map +1 -0
  71. package/dist/framework/litestar/litestar.d.ts +17 -0
  72. package/dist/framework/litestar/litestar.d.ts.map +1 -0
  73. package/dist/framework/litestar/litestar.js +536 -0
  74. package/dist/framework/litestar/litestar.js.map +1 -0
  75. package/dist/framework/nest/nest.d.ts +19 -0
  76. package/dist/framework/nest/nest.d.ts.map +1 -0
  77. package/dist/framework/nest/nest.js +613 -0
  78. package/dist/framework/nest/nest.js.map +1 -0
  79. package/dist/framework/next/next.d.ts +22 -0
  80. package/dist/framework/next/next.d.ts.map +1 -0
  81. package/dist/framework/next/next.js +449 -0
  82. package/dist/framework/next/next.js.map +1 -0
  83. package/dist/framework/node/node.d.ts +24 -0
  84. package/dist/framework/node/node.d.ts.map +1 -0
  85. package/dist/framework/node/node.js +1009 -0
  86. package/dist/framework/node/node.js.map +1 -0
  87. package/dist/framework/orchestrator/orchestrator.d.ts +34 -0
  88. package/dist/framework/orchestrator/orchestrator.d.ts.map +1 -0
  89. package/dist/framework/orchestrator/orchestrator.js +691 -0
  90. package/dist/framework/orchestrator/orchestrator.js.map +1 -0
  91. package/dist/framework/orm/orm.d.ts +61 -0
  92. package/dist/framework/orm/orm.d.ts.map +1 -0
  93. package/dist/framework/orm/orm.js +620 -0
  94. package/dist/framework/orm/orm.js.map +1 -0
  95. package/dist/framework/python/analyze.d.ts +38 -0
  96. package/dist/framework/python/analyze.d.ts.map +1 -0
  97. package/dist/framework/python/analyze.js +98 -0
  98. package/dist/framework/python/analyze.js.map +1 -0
  99. package/dist/framework/python/py-ast.d.ts +130 -0
  100. package/dist/framework/python/py-ast.d.ts.map +1 -0
  101. package/dist/framework/python/py-ast.js +344 -0
  102. package/dist/framework/python/py-ast.js.map +1 -0
  103. package/dist/framework/python-orm/python-orm.d.ts +19 -0
  104. package/dist/framework/python-orm/python-orm.d.ts.map +1 -0
  105. package/dist/framework/python-orm/python-orm.js +516 -0
  106. package/dist/framework/python-orm/python-orm.js.map +1 -0
  107. package/dist/framework/react-native/react-native.d.ts +35 -0
  108. package/dist/framework/react-native/react-native.d.ts.map +1 -0
  109. package/dist/framework/react-native/react-native.js +1181 -0
  110. package/dist/framework/react-native/react-native.js.map +1 -0
  111. package/dist/framework/register.d.ts +2 -0
  112. package/dist/framework/register.d.ts.map +1 -0
  113. package/dist/framework/register.js +59 -0
  114. package/dist/framework/register.js.map +1 -0
  115. package/dist/framework/registry.d.ts +31 -0
  116. package/dist/framework/registry.d.ts.map +1 -0
  117. package/dist/framework/registry.js +70 -0
  118. package/dist/framework/registry.js.map +1 -0
  119. package/dist/framework/routing/expo-router.d.ts +31 -0
  120. package/dist/framework/routing/expo-router.d.ts.map +1 -0
  121. package/dist/framework/routing/expo-router.js +356 -0
  122. package/dist/framework/routing/expo-router.js.map +1 -0
  123. package/dist/framework/routing/index.d.ts +4 -0
  124. package/dist/framework/routing/index.d.ts.map +1 -0
  125. package/dist/framework/routing/index.js +16 -0
  126. package/dist/framework/routing/index.js.map +1 -0
  127. package/dist/framework/routing/next-router.d.ts +45 -0
  128. package/dist/framework/routing/next-router.d.ts.map +1 -0
  129. package/dist/framework/routing/next-router.js +378 -0
  130. package/dist/framework/routing/next-router.js.map +1 -0
  131. package/dist/framework/routing/route-tree.d.ts +73 -0
  132. package/dist/framework/routing/route-tree.d.ts.map +1 -0
  133. package/dist/framework/routing/route-tree.js +120 -0
  134. package/dist/framework/routing/route-tree.js.map +1 -0
  135. package/dist/framework/types.d.ts +230 -0
  136. package/dist/framework/types.d.ts.map +1 -0
  137. package/dist/framework/types.js +25 -0
  138. package/dist/framework/types.js.map +1 -0
  139. package/dist/graph/cross-language.d.ts +11 -0
  140. package/dist/graph/cross-language.d.ts.map +1 -0
  141. package/dist/graph/cross-language.js +123 -0
  142. package/dist/graph/cross-language.js.map +1 -0
  143. package/dist/graph/extract.d.ts +13 -0
  144. package/dist/graph/extract.d.ts.map +1 -0
  145. package/dist/graph/extract.js +79 -0
  146. package/dist/graph/extract.js.map +1 -0
  147. package/dist/graph/file-graph.d.ts +186 -0
  148. package/dist/graph/file-graph.d.ts.map +1 -0
  149. package/dist/graph/file-graph.js +427 -0
  150. package/dist/graph/file-graph.js.map +1 -0
  151. package/dist/graph/http-callsites.d.ts +14 -0
  152. package/dist/graph/http-callsites.d.ts.map +1 -0
  153. package/dist/graph/http-callsites.js +107 -0
  154. package/dist/graph/http-callsites.js.map +1 -0
  155. package/dist/graph/incremental.d.ts +122 -0
  156. package/dist/graph/incremental.d.ts.map +1 -0
  157. package/dist/graph/incremental.js +448 -0
  158. package/dist/graph/incremental.js.map +1 -0
  159. package/dist/graph/language.d.ts +31 -0
  160. package/dist/graph/language.d.ts.map +1 -0
  161. package/dist/graph/language.js +146 -0
  162. package/dist/graph/language.js.map +1 -0
  163. package/dist/graph/noise-filter.d.ts +46 -0
  164. package/dist/graph/noise-filter.d.ts.map +1 -0
  165. package/dist/graph/noise-filter.js +199 -0
  166. package/dist/graph/noise-filter.js.map +1 -0
  167. package/dist/graph/python-adapter.d.ts +36 -0
  168. package/dist/graph/python-adapter.d.ts.map +1 -0
  169. package/dist/graph/python-adapter.js +402 -0
  170. package/dist/graph/python-adapter.js.map +1 -0
  171. package/dist/graph/python-manifest.d.ts +22 -0
  172. package/dist/graph/python-manifest.d.ts.map +1 -0
  173. package/dist/graph/python-manifest.js +137 -0
  174. package/dist/graph/python-manifest.js.map +1 -0
  175. package/dist/graph/python-stdlib.d.ts +2 -0
  176. package/dist/graph/python-stdlib.d.ts.map +1 -0
  177. package/dist/graph/python-stdlib.js +53 -0
  178. package/dist/graph/python-stdlib.js.map +1 -0
  179. package/dist/graph/ts-morph-adapter.d.ts +65 -0
  180. package/dist/graph/ts-morph-adapter.d.ts.map +1 -0
  181. package/dist/graph/ts-morph-adapter.js +265 -0
  182. package/dist/graph/ts-morph-adapter.js.map +1 -0
  183. package/dist/graph/types.d.ts +37 -0
  184. package/dist/graph/types.d.ts.map +1 -0
  185. package/dist/graph/types.js +50 -0
  186. package/dist/graph/types.js.map +1 -0
  187. package/dist/index.d.ts +45 -0
  188. package/dist/index.d.ts.map +1 -0
  189. package/dist/index.js +51 -0
  190. package/dist/index.js.map +1 -0
  191. package/dist/infra/aws/aws-parse.d.ts +39 -0
  192. package/dist/infra/aws/aws-parse.d.ts.map +1 -0
  193. package/dist/infra/aws/aws-parse.js +149 -0
  194. package/dist/infra/aws/aws-parse.js.map +1 -0
  195. package/dist/infra/aws/aws.d.ts +6 -0
  196. package/dist/infra/aws/aws.d.ts.map +1 -0
  197. package/dist/infra/aws/aws.js +425 -0
  198. package/dist/infra/aws/aws.js.map +1 -0
  199. package/dist/infra/azure/azure-parse.d.ts +73 -0
  200. package/dist/infra/azure/azure-parse.d.ts.map +1 -0
  201. package/dist/infra/azure/azure-parse.js +178 -0
  202. package/dist/infra/azure/azure-parse.js.map +1 -0
  203. package/dist/infra/azure/azure.d.ts +12 -0
  204. package/dist/infra/azure/azure.d.ts.map +1 -0
  205. package/dist/infra/azure/azure.js +673 -0
  206. package/dist/infra/azure/azure.js.map +1 -0
  207. package/dist/infra/cloudflare/cloudflare.d.ts +50 -0
  208. package/dist/infra/cloudflare/cloudflare.d.ts.map +1 -0
  209. package/dist/infra/cloudflare/cloudflare.js +382 -0
  210. package/dist/infra/cloudflare/cloudflare.js.map +1 -0
  211. package/dist/infra/cloudflare/wrangler-parse.d.ts +6 -0
  212. package/dist/infra/cloudflare/wrangler-parse.d.ts.map +1 -0
  213. package/dist/infra/cloudflare/wrangler-parse.js +278 -0
  214. package/dist/infra/cloudflare/wrangler-parse.js.map +1 -0
  215. package/dist/infra/compose/compose-parse.d.ts +24 -0
  216. package/dist/infra/compose/compose-parse.d.ts.map +1 -0
  217. package/dist/infra/compose/compose-parse.js +77 -0
  218. package/dist/infra/compose/compose-parse.js.map +1 -0
  219. package/dist/infra/compose/compose.d.ts +12 -0
  220. package/dist/infra/compose/compose.d.ts.map +1 -0
  221. package/dist/infra/compose/compose.js +201 -0
  222. package/dist/infra/compose/compose.js.map +1 -0
  223. package/dist/infra/convex/convex-parse.d.ts +28 -0
  224. package/dist/infra/convex/convex-parse.d.ts.map +1 -0
  225. package/dist/infra/convex/convex-parse.js +74 -0
  226. package/dist/infra/convex/convex-parse.js.map +1 -0
  227. package/dist/infra/convex/convex.d.ts +18 -0
  228. package/dist/infra/convex/convex.d.ts.map +1 -0
  229. package/dist/infra/convex/convex.js +199 -0
  230. package/dist/infra/convex/convex.js.map +1 -0
  231. package/dist/infra/digitalocean/digitalocean.d.ts +33 -0
  232. package/dist/infra/digitalocean/digitalocean.d.ts.map +1 -0
  233. package/dist/infra/digitalocean/digitalocean.js +204 -0
  234. package/dist/infra/digitalocean/digitalocean.js.map +1 -0
  235. package/dist/infra/firebase/firebase.d.ts +43 -0
  236. package/dist/infra/firebase/firebase.d.ts.map +1 -0
  237. package/dist/infra/firebase/firebase.js +271 -0
  238. package/dist/infra/firebase/firebase.js.map +1 -0
  239. package/dist/infra/fly/fly-parse.d.ts +52 -0
  240. package/dist/infra/fly/fly-parse.d.ts.map +1 -0
  241. package/dist/infra/fly/fly-parse.js +114 -0
  242. package/dist/infra/fly/fly-parse.js.map +1 -0
  243. package/dist/infra/fly/fly.d.ts +15 -0
  244. package/dist/infra/fly/fly.d.ts.map +1 -0
  245. package/dist/infra/fly/fly.js +265 -0
  246. package/dist/infra/fly/fly.js.map +1 -0
  247. package/dist/infra/gcp/gcp-parse.d.ts +24 -0
  248. package/dist/infra/gcp/gcp-parse.d.ts.map +1 -0
  249. package/dist/infra/gcp/gcp-parse.js +123 -0
  250. package/dist/infra/gcp/gcp-parse.js.map +1 -0
  251. package/dist/infra/gcp/gcp.d.ts +10 -0
  252. package/dist/infra/gcp/gcp.d.ts.map +1 -0
  253. package/dist/infra/gcp/gcp.js +502 -0
  254. package/dist/infra/gcp/gcp.js.map +1 -0
  255. package/dist/infra/heroku/heroku-parse.d.ts +33 -0
  256. package/dist/infra/heroku/heroku-parse.d.ts.map +1 -0
  257. package/dist/infra/heroku/heroku-parse.js +63 -0
  258. package/dist/infra/heroku/heroku-parse.js.map +1 -0
  259. package/dist/infra/heroku/heroku.d.ts +24 -0
  260. package/dist/infra/heroku/heroku.d.ts.map +1 -0
  261. package/dist/infra/heroku/heroku.js +253 -0
  262. package/dist/infra/heroku/heroku.js.map +1 -0
  263. package/dist/infra/image-resolve.d.ts +56 -0
  264. package/dist/infra/image-resolve.d.ts.map +1 -0
  265. package/dist/infra/image-resolve.js +229 -0
  266. package/dist/infra/image-resolve.js.map +1 -0
  267. package/dist/infra/infra-step.d.ts +39 -0
  268. package/dist/infra/infra-step.d.ts.map +1 -0
  269. package/dist/infra/infra-step.js +57 -0
  270. package/dist/infra/infra-step.js.map +1 -0
  271. package/dist/infra/k8s/index.d.ts +78 -0
  272. package/dist/infra/k8s/index.d.ts.map +1 -0
  273. package/dist/infra/k8s/index.js +251 -0
  274. package/dist/infra/k8s/index.js.map +1 -0
  275. package/dist/infra/kamal/kamal-parse.d.ts +23 -0
  276. package/dist/infra/kamal/kamal-parse.d.ts.map +1 -0
  277. package/dist/infra/kamal/kamal-parse.js +66 -0
  278. package/dist/infra/kamal/kamal-parse.js.map +1 -0
  279. package/dist/infra/kamal/kamal.d.ts +17 -0
  280. package/dist/infra/kamal/kamal.d.ts.map +1 -0
  281. package/dist/infra/kamal/kamal.js +162 -0
  282. package/dist/infra/kamal/kamal.js.map +1 -0
  283. package/dist/infra/netlify/netlify.d.ts +33 -0
  284. package/dist/infra/netlify/netlify.d.ts.map +1 -0
  285. package/dist/infra/netlify/netlify.js +247 -0
  286. package/dist/infra/netlify/netlify.js.map +1 -0
  287. package/dist/infra/opentofu/opentofu.d.ts +3 -0
  288. package/dist/infra/opentofu/opentofu.d.ts.map +1 -0
  289. package/dist/infra/opentofu/opentofu.js +157 -0
  290. package/dist/infra/opentofu/opentofu.js.map +1 -0
  291. package/dist/infra/pulumi/pulumi-parse.d.ts +60 -0
  292. package/dist/infra/pulumi/pulumi-parse.d.ts.map +1 -0
  293. package/dist/infra/pulumi/pulumi-parse.js +155 -0
  294. package/dist/infra/pulumi/pulumi-parse.js.map +1 -0
  295. package/dist/infra/pulumi/pulumi.d.ts +23 -0
  296. package/dist/infra/pulumi/pulumi.d.ts.map +1 -0
  297. package/dist/infra/pulumi/pulumi.js +260 -0
  298. package/dist/infra/pulumi/pulumi.js.map +1 -0
  299. package/dist/infra/railway/railway-parse.d.ts +54 -0
  300. package/dist/infra/railway/railway-parse.d.ts.map +1 -0
  301. package/dist/infra/railway/railway-parse.js +200 -0
  302. package/dist/infra/railway/railway-parse.js.map +1 -0
  303. package/dist/infra/railway/railway.d.ts +19 -0
  304. package/dist/infra/railway/railway.d.ts.map +1 -0
  305. package/dist/infra/railway/railway.js +397 -0
  306. package/dist/infra/railway/railway.js.map +1 -0
  307. package/dist/infra/register.d.ts +2 -0
  308. package/dist/infra/register.d.ts.map +1 -0
  309. package/dist/infra/register.js +81 -0
  310. package/dist/infra/register.js.map +1 -0
  311. package/dist/infra/registry.d.ts +64 -0
  312. package/dist/infra/registry.d.ts.map +1 -0
  313. package/dist/infra/registry.js +205 -0
  314. package/dist/infra/registry.js.map +1 -0
  315. package/dist/infra/relevance.d.ts +16 -0
  316. package/dist/infra/relevance.d.ts.map +1 -0
  317. package/dist/infra/relevance.js +132 -0
  318. package/dist/infra/relevance.js.map +1 -0
  319. package/dist/infra/render/render-parse.d.ts +76 -0
  320. package/dist/infra/render/render-parse.d.ts.map +1 -0
  321. package/dist/infra/render/render-parse.js +155 -0
  322. package/dist/infra/render/render-parse.js.map +1 -0
  323. package/dist/infra/render/render.d.ts +11 -0
  324. package/dist/infra/render/render.d.ts.map +1 -0
  325. package/dist/infra/render/render.js +303 -0
  326. package/dist/infra/render/render.js.map +1 -0
  327. package/dist/infra/sst/sst-parse.d.ts +25 -0
  328. package/dist/infra/sst/sst-parse.d.ts.map +1 -0
  329. package/dist/infra/sst/sst-parse.js +45 -0
  330. package/dist/infra/sst/sst-parse.js.map +1 -0
  331. package/dist/infra/sst/sst.d.ts +19 -0
  332. package/dist/infra/sst/sst.d.ts.map +1 -0
  333. package/dist/infra/sst/sst.js +236 -0
  334. package/dist/infra/sst/sst.js.map +1 -0
  335. package/dist/infra/supabase/supabase-parse.d.ts +34 -0
  336. package/dist/infra/supabase/supabase-parse.d.ts.map +1 -0
  337. package/dist/infra/supabase/supabase-parse.js +113 -0
  338. package/dist/infra/supabase/supabase-parse.js.map +1 -0
  339. package/dist/infra/supabase/supabase.d.ts +15 -0
  340. package/dist/infra/supabase/supabase.d.ts.map +1 -0
  341. package/dist/infra/supabase/supabase.js +198 -0
  342. package/dist/infra/supabase/supabase.js.map +1 -0
  343. package/dist/infra/terraform/hcl-parse.d.ts +34 -0
  344. package/dist/infra/terraform/hcl-parse.d.ts.map +1 -0
  345. package/dist/infra/terraform/hcl-parse.js +203 -0
  346. package/dist/infra/terraform/hcl-parse.js.map +1 -0
  347. package/dist/infra/terraform/terraform.d.ts +14 -0
  348. package/dist/infra/terraform/terraform.d.ts.map +1 -0
  349. package/dist/infra/terraform/terraform.js +264 -0
  350. package/dist/infra/terraform/terraform.js.map +1 -0
  351. package/dist/infra/types.d.ts +151 -0
  352. package/dist/infra/types.d.ts.map +1 -0
  353. package/dist/infra/types.js +14 -0
  354. package/dist/infra/types.js.map +1 -0
  355. package/dist/infra/vercel/vercel-parse.d.ts +70 -0
  356. package/dist/infra/vercel/vercel-parse.d.ts.map +1 -0
  357. package/dist/infra/vercel/vercel-parse.js +194 -0
  358. package/dist/infra/vercel/vercel-parse.js.map +1 -0
  359. package/dist/infra/vercel/vercel.d.ts +30 -0
  360. package/dist/infra/vercel/vercel.d.ts.map +1 -0
  361. package/dist/infra/vercel/vercel.js +523 -0
  362. package/dist/infra/vercel/vercel.js.map +1 -0
  363. package/dist/infra/walk.d.ts +36 -0
  364. package/dist/infra/walk.d.ts.map +1 -0
  365. package/dist/infra/walk.js +85 -0
  366. package/dist/infra/walk.js.map +1 -0
  367. package/dist/safety.d.ts +13 -0
  368. package/dist/safety.d.ts.map +1 -0
  369. package/dist/safety.js +67 -0
  370. package/dist/safety.js.map +1 -0
  371. package/dist/types.d.ts +47 -0
  372. package/dist/types.d.ts.map +1 -0
  373. package/dist/types.js +111 -0
  374. package/dist/types.js.map +1 -0
  375. package/dist/version.d.ts +2 -0
  376. package/dist/version.d.ts.map +1 -0
  377. package/dist/version.js +35 -0
  378. package/dist/version.js.map +1 -0
  379. package/package.json +65 -0
@@ -0,0 +1,230 @@
1
+ import type { EdgeKind, ModuleKind } from '../types.js';
2
+ import type { NormalizedGraph } from '../graph/types.js';
3
+ /**
4
+ * Input to `detect()`. Cheap by construction — an adapter reads package.json
5
+ * deps + config-file EXISTENCE only, never source content (never-store-source;
6
+ * the trust claim covers the extractor too).
7
+ */
8
+ export interface FrameworkDetectContext {
9
+ /** Absolute repo dir. */
10
+ repoDir: string;
11
+ /**
12
+ * Optional absolute path to a workspace package within the repo. When set,
13
+ * `detect()` scopes its manifest/config reads to this package — the
14
+ * per-package fan-out. Absent ⇒ scan the repo root (the thin
15
+ * single-root pass this slice ships).
16
+ */
17
+ packageDir?: string;
18
+ }
19
+ /**
20
+ * One adapter's positive detection. `null` (not this type) means "no match —
21
+ * fall through to generic-TS behavior."
22
+ */
23
+ export interface DetectMatch {
24
+ /**
25
+ * The adapter that produced this match (e.g. 'react-native'). The registry
26
+ * stamps this from the adapter's `name` so manifest consumers can trust it
27
+ * regardless of what the adapter set.
28
+ */
29
+ adapter: string;
30
+ /**
31
+ * 0–1 DETERMINISTIC confidence — a fixed per-adapter rubric, NOT an LLM score.
32
+ * A primary signal (the framework dep in package.json) scores high; a weak /
33
+ * secondary signal (only a config file, no dep) scores lower.
34
+ */
35
+ confidence: number;
36
+ /**
37
+ * The repo-relative posix root this match applies to ('' = repo root).
38
+ * Per-workspace capable: a monorepo with an Expo app under `apps/mobile`
39
+ * reports `rootPath: 'apps/mobile'`. The thin single-root pass this slice
40
+ * ships always reports '' (repo root); per-package fan-out is .
41
+ */
42
+ rootPath: string;
43
+ /**
44
+ * Adapter-specific shape — which signals fired, the framework variant
45
+ * (Expo vs bare RN), etc. Not consumed downstream yet; feeds the detection
46
+ * log + debugging. Keep small (< ~500 bytes).
47
+ */
48
+ metadata?: Record<string, unknown>;
49
+ }
50
+ /**
51
+ * The detected-stack manifest for a repo (or a workspace package). Multiple
52
+ * adapters co-apply (a Turborepo with a Next app + a Nest API + an Expo app),
53
+ * so `matches` is an ORDERED list (registration order = priority). Empty ⇒ no
54
+ * framework detected → generic-TS fallthrough, byte-for-byte unchanged.
55
+ */
56
+ export interface FrameworkManifest {
57
+ /** Absolute repo dir the manifest was detected from (provenance). */
58
+ root: string;
59
+ /** Matched stacks in registration order. Empty ⇒ generic TS. */
60
+ matches: DetectMatch[];
61
+ }
62
+ /**
63
+ * A POST-CLUSTER view of the clustering result, the seam between file-id space
64
+ * (where a framework hook works — it greps source) and module-id space (what
65
+ * the diagram renders). firmed this onto the context (Slice 1 deferred
66
+ * it): the `syntheticEdges`/`roleTags` hooks emit contributions in the graph
67
+ * FILE-ID space (repo-relative posix paths), and the contribution step
68
+ * (contribute-step.ts) resolves them to MODULE ids through `fileModuleMap`. The
69
+ * view is carried on the context so a hook that wants module-level precision
70
+ * (a future grouping-aware adapter) can resolve itself; the RN adapter does NOT
71
+ * need it (it stays in file-id space and lets the step resolve).
72
+ */
73
+ export interface FrameworkClusterView {
74
+ /** fileId (repo-relative posix) → moduleId — the post-cluster join key. */
75
+ fileModuleMap: Readonly<Record<string, string>>;
76
+ /** Every materialized module id (internal + external + infra-namespaced). */
77
+ moduleIds: ReadonlySet<string>;
78
+ }
79
+ /**
80
+ * Context for the multi-stage contribution hooks. Carries the detect match +
81
+ * repo (so a hook can re-read config), the structural code graph the
82
+ * contributions reference (file ids = repo-relative posix paths), and the
83
+ * POST-CLUSTER module view so the step + any module-aware hook can
84
+ * resolve file ids to modules. Slice 1's comment promised the shape "firms up
85
+ * as + implements the first real hooks" — `cluster` is that firming.
86
+ */
87
+ export interface FrameworkContext {
88
+ repoDir: string;
89
+ /** The repo-relative posix root this adapter matched (DetectMatch.rootPath). */
90
+ rootPath: string;
91
+ /** The detect match that selected this adapter. */
92
+ match: DetectMatch;
93
+ /** The structural code graph (file ids = repo-relative posix paths). */
94
+ graph: NormalizedGraph;
95
+ /** the post-cluster file→module view (the render-side join key). */
96
+ cluster: FrameworkClusterView;
97
+ }
98
+ /**
99
+ * A pre-cluster grouping hint: a named group of code FILE ids the clustering
100
+ * step should keep together (a framework's natural module boundary — an Expo
101
+ * Router route tree, a NestJS @Module). Feeds `clusterGraph` BEFORE Louvain
102
+ * runs, so it's a PRIOR, not a post-hoc relabel — which is why this is a
103
+ * sibling of (not a reuse of) the infra seam.
104
+ *
105
+ * `id` is NAMESPACED by adapter when consumed downstream (`<adapter>:<id>`),
106
+ * mirroring the infra registry's id discipline, so two adapters' groups never
107
+ * collide. It MUST be deterministic (the snapshot-stability invariant — module
108
+ * ids must not reshuffle across snapshots), so it derives from the path/route,
109
+ * never a Louvain index.
110
+ */
111
+ export interface FrameworkGroup {
112
+ id: string;
113
+ /** Humanized group name (feeds the subsystem label). */
114
+ label: string;
115
+ /** Repo-relative posix file ids (graph file-id space) in this group. */
116
+ fileIds: string[];
117
+ }
118
+ export interface FrameworkGroupingPrior {
119
+ groups: FrameworkGroup[];
120
+ /**
121
+ * Any label a hook cannot statically map is DEFERRED here, never resolved by
122
+ * an inline LLM call (mirror the infra `classificationsNeeded` pattern). The
123
+ * cost-optimal rule: adapters are deterministic; the only LLM touch is a
124
+ * deferred, cached, batched classification.
125
+ */
126
+ classificationsNeeded?: FrameworkClassificationRef[];
127
+ }
128
+ /**
129
+ * A framework-derived edge the structural import/call graph can't see — a
130
+ * navigation edge (a screen `calls` another via React Navigation), an
131
+ * RSC→client boundary, a Route Handler → service call.
132
+ *
133
+ * `source`/`target` are CODE module/file ids (the graph file-id space =
134
+ * repo-relative posix paths), and `kind` is the 8-verb `EdgeKind` from
135
+ * src/types. The taxonomy is law: NEVER `imports` / `depends-on` / `uses` — a
136
+ * framework edge is still one of the eight verbs.
137
+ */
138
+ export interface FrameworkEdge {
139
+ source: string;
140
+ target: string;
141
+ kind: EdgeKind;
142
+ metadata?: Record<string, unknown>;
143
+ }
144
+ /**
145
+ * A framework ROLE annotation for an EXISTING code module/file — 'screen',
146
+ * 'route-handler', 'server-action', 'navigator', etc.
147
+ *
148
+ * It is METADATA, NOT a new Module-kind. The locked discipline ("fix the
149
+ * classifier, never weaken the enum") holds: a screen maps onto `frontend`, a
150
+ * controller/route handler onto `gateway`/`service`, a queue/cron worker onto
151
+ * `job`. The finer role lives in `role`; `kind` MUST be a value from the locked
152
+ * `MODULE_KINDS` enum — never a new one. The renderer surfaces `role` via the
153
+ * label/metadata; the module's `kind` is unchanged.
154
+ */
155
+ export interface RoleTag {
156
+ role: string;
157
+ kind: ModuleKind;
158
+ /**
159
+ * deterministic collapse priority (higher wins) for the two places a
160
+ * role must collapse to a single value: (1) one FILE matching several role
161
+ * detectors, and (2) several files of different roles landing in one MODULE
162
+ * after clustering. The contribution step keeps the highest-priority role per
163
+ * module, lexical role tiebreak, and LOGS a collapse — no silent pick. Absent
164
+ * ⇒ 0. The merge stays GENERIC (driven by this number), so the step needs no
165
+ * per-framework role knowledge.
166
+ */
167
+ priority?: number;
168
+ metadata?: Record<string, unknown>;
169
+ }
170
+ /**
171
+ * A deferred classification (mirror infra's ClassificationRef). The registry
172
+ * collects these from every adapter, dedupes, and runs them through the
173
+ * cached/batched classifier — so a non-deterministic label is decided ONCE,
174
+ * globally, never by an inline per-adapter LLM call.
175
+ */
176
+ export interface FrameworkClassificationRef {
177
+ /** The classification domain (e.g. 'react-native/screen-role'). */
178
+ provider: string;
179
+ /** The thing to classify (a role/group the adapter can't statically map). */
180
+ subject: string;
181
+ /** The code module/file id whose attribute this classification will populate. */
182
+ forId: string;
183
+ }
184
+ /**
185
+ * A discovery + contribution surface for one framework/runtime stack.
186
+ * Implementations live next to their detector (e.g.
187
+ * scripts/ingest/framework/react-native/).
188
+ *
189
+ * `detect()` is cheap + deterministic (manifest deps + config-file existence),
190
+ * runs first against every registered adapter, and yields the detected-stack
191
+ * manifest. The four optional hooks are the framework's contributions to the
192
+ * diagram; each adapter implements only what its stack needs, and a stack that
193
+ * only narrows extraction (no graph contribution) may implement `detect` alone.
194
+ */
195
+ export interface FrameworkAdapter {
196
+ readonly name: string;
197
+ /** Cheap, deterministic. Reads package.json deps + config existence ONLY. */
198
+ detect(ctx: FrameworkDetectContext): Promise<DetectMatch | null>;
199
+ /**
200
+ * PRE-CLUSTER grouping prior fed to `clusterGraph` (RN's lands in ).
201
+ * Declared now; unimplemented for every adapter this slice.
202
+ */
203
+ groupingPrior?(ctx: FrameworkContext): Promise<FrameworkGroupingPrior>;
204
+ /**
205
+ * POST-CLUSTER synthetic edges (8-verb, code-module endpoints). The render-
206
+ * only contribution the infra seam could already express; here so framework
207
+ * nav/boundary edges share one contract. Declared now; unimplemented.
208
+ */
209
+ syntheticEdges?(ctx: FrameworkContext): Promise<FrameworkEdge[]>;
210
+ /**
211
+ * Role tags annotating EXISTING code modules/files — metadata, NO new
212
+ * Module-kind values. Keyed by module-or-file id. Declared now; unimplemented.
213
+ */
214
+ roleTags?(ctx: FrameworkContext): Promise<Map<string, RoleTag>>;
215
+ /**
216
+ * Deferred classifications a hook couldn't statically resolve — never an
217
+ * inline LLM call. Mirror infra. Declared now; unimplemented.
218
+ */
219
+ classificationsNeeded?(ctx: FrameworkContext): Promise<FrameworkClassificationRef[]>;
220
+ /**
221
+ * Mirror of InfraAdapter.scansSourcePath: does any hook read application
222
+ * SOURCE content (not just config/manifest)? `detect()` never does — but a
223
+ * future `groupingPrior`/`syntheticEdges` that greps source MUST declare the
224
+ * paths it reads here so the diff-driven hosted walk re-runs it on a relevant
225
+ * source change instead of carrying a stale contribution. Absent ⇒ the
226
+ * adapter reads only config/manifest.
227
+ */
228
+ scansSourcePath?(path: string): boolean;
229
+ }
230
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/framework/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ // the FrameworkAdapter contract.
2
+ //
3
+ // A SIBLING of the InfraAdapter seam (scripts/ingest/infra/types.ts), not a
4
+ // reuse of it (founder-ratified 2026-06-26, see the contract comment).
5
+ // The infra registry runs at `extractInfra` — AFTER clusterGraph + enrich — and
6
+ // only emits brand-new InfraNodes, so it can natively express only 2 of the 4
7
+ // framework contributions:
8
+ // (a) detect ✅
9
+ // (b) syntheticEdges (post-cluster, render-only) ✅
10
+ // (c) groupingPrior ❌ — must feed clusterGraph, which runs BEFORE infra
11
+ // (d) roleTags on existing code modules ❌ — infra emits new nodes, it can't
12
+ // annotate a module the code extractor already produced
13
+ // (c) and (d) are exactly what makes a framework diagram legible, so they're
14
+ // load-bearing — hence a sibling contract with multi-stage hooks.
15
+ //
16
+ // This contract mirrors the infra seam's proven discipline (cheap `detect`,
17
+ // registration-order priority, namespaced ids, `classificationsNeeded`
18
+ // deferral, `scansSourcePath` source-declaration) but exposes the four hooks.
19
+ //
20
+ // SLICE 1 ships ONLY `detect` + the React Native / Expo adapter. The
21
+ // `groupingPrior` / `syntheticEdges` / `roleTags` / `classificationsNeeded`
22
+ // hooks are DECLARED here so the contract is frozen for the parallel adapter
23
+ // fan-out (/723/…), but every adapter leaves them unimplemented this
24
+ // slice. RN's grouping/edges/roles land in .
25
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/framework/types.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,EAAE;AACF,4EAA4E;AAC5E,wEAAwE;AACxE,gFAAgF;AAChF,8EAA8E;AAC9E,2BAA2B;AAC3B,iBAAiB;AACjB,qDAAqD;AACrD,4EAA4E;AAC5E,8EAA8E;AAC9E,8DAA8D;AAC9D,6EAA6E;AAC7E,kEAAkE;AAClE,EAAE;AACF,4EAA4E;AAC5E,uEAAuE;AACvE,8EAA8E;AAC9E,EAAE;AACF,qEAAqE;AACrE,4EAA4E;AAC5E,6EAA6E;AAC7E,qEAAqE;AACrE,6CAA6C"}
@@ -0,0 +1,11 @@
1
+ import type { NormalizedGraph } from './types.js';
2
+ import type { FrameworkEdge } from '../framework/types.js';
3
+ /**
4
+ * The cross-language frontend→backend edges (file-id space, kind 'calls'). Empty
5
+ * for a single-language repo or a non-FastAPI backend. Deterministic.
6
+ */
7
+ export declare function crossLanguageApiEdges(args: {
8
+ repoDir: string;
9
+ graph: NormalizedGraph;
10
+ }): FrameworkEdge[];
11
+ //# sourceMappingURL=cross-language.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-language.d.ts","sourceRoot":"","sources":["../../src/graph/cross-language.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAuE3D;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,GAAG,aAAa,EAAE,CA2BxG"}
@@ -0,0 +1,123 @@
1
+ // the cross-language API seam of a unified full-stack diagram.
2
+ //
3
+ // A polyglot repo (a TS frontend + a Python/FastAPI backend) extracts as ONE
4
+ // merged graph (extract.ts), but the two languages share no import edge — so
5
+ // without this the frontend and backend render as two disconnected islands. This
6
+ // draws the COARSE, subsystem-level seam the issue scopes for v1: a frontend
7
+ // module that calls an `/api/…` route → the backend gateway/router module it hits.
8
+ // (Per-endpoint route-matched edges are a documented refinement, not v1.)
9
+ //
10
+ // Inputs, both static + install-free: the frontend HTTP call sites
11
+ // (http-callsites.ts) and the FastAPI route surface (fastapi.collectFastApiRouteSurface).
12
+ // Endpoints are repo-relative FILE ids in the graph's file-id space; the generic
13
+ // contribute-step resolves them to MODULE ids, drops self-edges, dedupes, and
14
+ // 8-verb-validates — exactly like a framework adapter's syntheticEdges. Returns []
15
+ // (no seam) for a single-language repo or a non-FastAPI backend, so single-language
16
+ // output is byte-identical.
17
+ import { collectFrontendApiCalls } from './http-callsites.js';
18
+ import { collectFastApiRouteSurface } from '../framework/fastapi/fastapi.js';
19
+ const TS_LANGS = new Set(['ts', 'tsx', 'js', 'jsx', 'mts', 'cts', 'mjs', 'cjs']);
20
+ const PY_LANGS = new Set(['py', 'pyi']);
21
+ // Normalize a URL/path for matching: drop scheme+host, query, and a trailing slash.
22
+ function urlPath(url) {
23
+ let p = url.replace(/^https?:\/\/[^/]+/i, '');
24
+ const q = p.search(/[?#]/);
25
+ if (q >= 0)
26
+ p = p.slice(0, q);
27
+ if (p.length > 1 && p.endsWith('/'))
28
+ p = p.slice(0, -1);
29
+ return p;
30
+ }
31
+ // Does a router `prefix` (e.g. '/users') appear as a whole path segment of `url`?
32
+ function prefixMatches(url, prefix) {
33
+ const pre = prefix.startsWith('/') ? prefix : `/${prefix}`;
34
+ return url === pre || url.startsWith(`${pre}/`) || url.includes(`${pre}/`) || url.endsWith(pre);
35
+ }
36
+ /**
37
+ * The backend file a frontend URL targets: the router whose prefix matches (most
38
+ * specific — longest prefix — wins, lexical fileId tiebreak), else the FastAPI app
39
+ * gateway (the coarse fallback), else the lexically-smallest router. Undefined
40
+ * only when the surface is empty.
41
+ */
42
+ function matchBackend(url, surface) {
43
+ const path = urlPath(url);
44
+ let bestFile;
45
+ let bestLen = -1;
46
+ for (const router of surface.routers) {
47
+ for (const prefix of router.prefixes) {
48
+ if (!prefixMatches(path, prefix) || prefix.length < bestLen)
49
+ continue;
50
+ if (prefix.length > bestLen || (bestFile !== undefined && router.fileId < bestFile)) {
51
+ bestLen = prefix.length;
52
+ bestFile = router.fileId;
53
+ }
54
+ }
55
+ }
56
+ if (bestFile)
57
+ return bestFile;
58
+ if (surface.appFiles.length > 0)
59
+ return surface.appFiles[0];
60
+ return surface.routers.length > 0 ? surface.routers[0].fileId : undefined;
61
+ }
62
+ // Re-attribute a call's file to a SURVIVING module-source file: the file itself if
63
+ // it survived the noise filter, else the lexically-smallest surviving file in the
64
+ // nearest ancestor directory (a generated SDK — src/client/sdk.gen.ts — is dropped,
65
+ // but its client/ siblings survive and carry the same module). Memoized per file.
66
+ function makeSurvivorResolver(surviving) {
67
+ const sortedSurvivors = [...surviving].sort();
68
+ const cache = new Map();
69
+ return (fileId) => {
70
+ if (surviving.has(fileId))
71
+ return fileId;
72
+ if (cache.has(fileId))
73
+ return cache.get(fileId);
74
+ let dir = fileId.includes('/') ? fileId.slice(0, fileId.lastIndexOf('/')) : '';
75
+ let result;
76
+ for (;;) {
77
+ const prefix = dir ? `${dir}/` : '';
78
+ const hit = sortedSurvivors.find((f) => f.startsWith(prefix));
79
+ if (hit) {
80
+ result = hit;
81
+ break;
82
+ }
83
+ if (dir === '')
84
+ break;
85
+ dir = dir.includes('/') ? dir.slice(0, dir.lastIndexOf('/')) : '';
86
+ }
87
+ cache.set(fileId, result);
88
+ return result;
89
+ };
90
+ }
91
+ /**
92
+ * The cross-language frontend→backend edges (file-id space, kind 'calls'). Empty
93
+ * for a single-language repo or a non-FastAPI backend. Deterministic.
94
+ */
95
+ export function crossLanguageApiEdges(args) {
96
+ const { repoDir, graph } = args;
97
+ const tsFiles = graph.files.filter((f) => TS_LANGS.has(f.language)).map((f) => f.id);
98
+ const pyFiles = graph.files.filter((f) => PY_LANGS.has(f.language)).map((f) => f.id);
99
+ if (tsFiles.length === 0 || pyFiles.length === 0)
100
+ return []; // not polyglot
101
+ const surface = collectFastApiRouteSurface(repoDir, pyFiles);
102
+ if (surface.routers.length === 0 && surface.appFiles.length === 0)
103
+ return []; // backend isn't FastAPI
104
+ const calls = collectFrontendApiCalls(repoDir);
105
+ if (calls.length === 0)
106
+ return [];
107
+ const survivorOf = makeSurvivorResolver(new Set(tsFiles));
108
+ const edges = new Map();
109
+ for (const call of calls) {
110
+ const src = survivorOf(call.fileId);
111
+ if (!src)
112
+ continue;
113
+ const target = matchBackend(call.url, surface);
114
+ if (!target || src === target)
115
+ continue;
116
+ const key = `${src}→${target}`;
117
+ if (!edges.has(key)) {
118
+ edges.set(key, { source: src, target, kind: 'calls', metadata: { relation: 'http-api', crossLanguage: true } });
119
+ }
120
+ }
121
+ return [...edges.values()].sort((a, b) => a.source < b.source ? -1 : a.source > b.source ? 1 : a.target < b.target ? -1 : a.target > b.target ? 1 : 0);
122
+ }
123
+ //# sourceMappingURL=cross-language.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-language.js","sourceRoot":"","sources":["../../src/graph/cross-language.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { NormalizedGraph } from './types.js';
2
+ export declare function extractGraph(repoDir: string): Promise<NormalizedGraph>;
3
+ /**
4
+ * Merge several single-language NormalizedGraphs into one. File ids are
5
+ * repo-relative posix paths, globally unique across languages (a TS frontend and
6
+ * a Python backend never share a path), so the union is a plain concatenation —
7
+ * with two determinism guarantees: files are re-sorted by id (Louvain's seeded
8
+ * RNG consumes node insertion order), and externals dedupe by id (a package name
9
+ * shared across ecosystems collapses to one external node, which is the desired
10
+ * rendering). Edges are concatenated in the fixed graph order the caller passes.
11
+ */
12
+ export declare function mergeGraphs(root: string, graphs: readonly NormalizedGraph[]): NormalizedGraph;
13
+ //# sourceMappingURL=extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/graph/extract.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAgC,eAAe,EAAE,MAAM,YAAY,CAAC;AAEhF,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAoB5E;AAmBD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,eAAe,EAAE,GAAG,eAAe,CAQ7F"}
@@ -0,0 +1,79 @@
1
+ // Adapter selection. The registry is the seam:
2
+ // everything downstream consumes the NormalizedGraph contract, so adding a
3
+ // per-language extractor is ADDITIVE — no downstream change. P3 shipped the
4
+ // ts-morph (TS) adapter; added the Pyright (Python) adapter; runs
5
+ // BOTH on a polyglot repo and MERGES their graphs into ONE unified full-stack
6
+ // diagram (a TS frontend + a Python backend as a single connected system).
7
+ import { resolve } from 'node:path';
8
+ import { TsMorphExtractor } from './ts-morph-adapter.js';
9
+ import { filterNoise, summarizeNoise } from './noise-filter.js';
10
+ import { detectRepoLanguages } from './language.js';
11
+ export async function extractGraph(repoDir) {
12
+ const languages = detectRepoLanguages(repoDir);
13
+ if (languages.length === 1) {
14
+ // Single-language repo — byte-identical to the pre behavior.
15
+ return extractOne(repoDir, languages[0]);
16
+ }
17
+ // polyglot repo. Extract each language independently (each adapter +
18
+ // its own noise filter), then MERGE. Downstream (Louvain, enrich, assemble) is
19
+ // language-neutral (the /967 contract), so it consumes the union with no
20
+ // change; cross-language files have no import edges to each other, so they
21
+ // cluster into their own communities and the cross-language seam is drawn later
22
+ // (contribute-step's crossLanguageApiEdges).
23
+ console.log(`→ polyglot repo detected: ${languages.join(' + ')} — extracting + merging`);
24
+ const graphs = [];
25
+ for (const lang of languages)
26
+ graphs.push(await extractOne(repoDir, lang));
27
+ const merged = mergeGraphs(resolve(repoDir), graphs);
28
+ console.log(` ⇒ merged: ${merged.files.length} files · ${merged.edges.length} edges · ${merged.externals.length} external deps`);
29
+ return merged;
30
+ }
31
+ /** Extract + noise-filter ONE language's graph (the original single-language path). */
32
+ async function extractOne(repoDir, language) {
33
+ const adapter = await selectAdapter(language);
34
+ console.log(`→ extracting structure with the ${adapter.language} adapter (install-free) …`);
35
+ const raw = await adapter.extract(repoDir);
36
+ // drop tests/generated/build/config/stories/mocks/types BEFORE
37
+ // clustering so connected repos render fewer, denser DOMAIN boxes. Applied
38
+ // here (not in the adapter / graphFromState) so the raw extract + the
39
+ // equivalence-test ground truth stay unfiltered; deterministic + logged.
40
+ const { graph, dropped } = filterNoise(raw);
41
+ if (dropped.total > 0)
42
+ console.log(` ⊘ ${summarizeNoise(dropped)}`);
43
+ console.log(` ${graph.files.length} files · ${graph.edges.length} edges · ${graph.externals.length} external deps`);
44
+ return graph;
45
+ }
46
+ /**
47
+ * Merge several single-language NormalizedGraphs into one. File ids are
48
+ * repo-relative posix paths, globally unique across languages (a TS frontend and
49
+ * a Python backend never share a path), so the union is a plain concatenation —
50
+ * with two determinism guarantees: files are re-sorted by id (Louvain's seeded
51
+ * RNG consumes node insertion order), and externals dedupe by id (a package name
52
+ * shared across ecosystems collapses to one external node, which is the desired
53
+ * rendering). Edges are concatenated in the fixed graph order the caller passes.
54
+ */
55
+ export function mergeGraphs(root, graphs) {
56
+ const files = graphs.flatMap((g) => g.files).sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
57
+ const edges = graphs.flatMap((g) => g.edges);
58
+ const externals = new Map();
59
+ for (const g of graphs) {
60
+ for (const x of g.externals)
61
+ if (!externals.has(x.id))
62
+ externals.set(x.id, x);
63
+ }
64
+ return { root, files, edges, externals: [...externals.values()] };
65
+ }
66
+ /**
67
+ * Pick the structural adapter for a detected language. The Python adapter is
68
+ * LAZILY imported so a TS ingest never loads `@zzzen/pyright-internal` (keeps the
69
+ * TS path — and the worker's TS bundle — free of the Python toolchain; only a
70
+ * Python repo pays for it). TS stays the default + eager (the pipeline's home turf).
71
+ */
72
+ async function selectAdapter(language) {
73
+ if (language === 'python') {
74
+ const { PythonExtractor } = await import('./python-adapter.js');
75
+ return new PythonExtractor();
76
+ }
77
+ return new TsMorphExtractor();
78
+ }
79
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/graph/extract.ts"],"names":[],"mappings":"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"}