memor-code-cli 0.2.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 (418) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -0
  3. package/dist/IntentionalStructure/index.d.ts +13 -0
  4. package/dist/IntentionalStructure/index.d.ts.map +1 -0
  5. package/dist/IntentionalStructure/index.js +46 -0
  6. package/dist/IntentionalStructure/index.js.map +1 -0
  7. package/dist/IntentionalStructure/parseCompose.d.ts +13 -0
  8. package/dist/IntentionalStructure/parseCompose.d.ts.map +1 -0
  9. package/dist/IntentionalStructure/parseCompose.js +234 -0
  10. package/dist/IntentionalStructure/parseCompose.js.map +1 -0
  11. package/dist/IntentionalStructure/parseDeployConfigs.d.ts +7 -0
  12. package/dist/IntentionalStructure/parseDeployConfigs.d.ts.map +1 -0
  13. package/dist/IntentionalStructure/parseDeployConfigs.js +168 -0
  14. package/dist/IntentionalStructure/parseDeployConfigs.js.map +1 -0
  15. package/dist/IntentionalStructure/parseEnvWiring.d.ts +7 -0
  16. package/dist/IntentionalStructure/parseEnvWiring.d.ts.map +1 -0
  17. package/dist/IntentionalStructure/parseEnvWiring.js +159 -0
  18. package/dist/IntentionalStructure/parseEnvWiring.js.map +1 -0
  19. package/dist/IntentionalStructure/parseWorkspaces.d.ts +8 -0
  20. package/dist/IntentionalStructure/parseWorkspaces.d.ts.map +1 -0
  21. package/dist/IntentionalStructure/parseWorkspaces.js +179 -0
  22. package/dist/IntentionalStructure/parseWorkspaces.js.map +1 -0
  23. package/dist/IntentionalStructure/types.d.ts +34 -0
  24. package/dist/IntentionalStructure/types.d.ts.map +1 -0
  25. package/dist/IntentionalStructure/types.js +8 -0
  26. package/dist/IntentionalStructure/types.js.map +1 -0
  27. package/dist/RepoTypeDetection/applyRepoModeConsistency.d.ts +11 -0
  28. package/dist/RepoTypeDetection/applyRepoModeConsistency.d.ts.map +1 -0
  29. package/dist/RepoTypeDetection/applyRepoModeConsistency.js +53 -0
  30. package/dist/RepoTypeDetection/applyRepoModeConsistency.js.map +1 -0
  31. package/dist/RepoTypeDetection/detectAppArchetype.d.ts +12 -0
  32. package/dist/RepoTypeDetection/detectAppArchetype.d.ts.map +1 -0
  33. package/dist/RepoTypeDetection/detectAppArchetype.js +162 -0
  34. package/dist/RepoTypeDetection/detectAppArchetype.js.map +1 -0
  35. package/dist/RepoTypeDetection/detectPackageArchetype.d.ts +10 -0
  36. package/dist/RepoTypeDetection/detectPackageArchetype.d.ts.map +1 -0
  37. package/dist/RepoTypeDetection/detectPackageArchetype.js +149 -0
  38. package/dist/RepoTypeDetection/detectPackageArchetype.js.map +1 -0
  39. package/dist/RepoTypeDetection/detectRepoCenterSystems.d.ts +11 -0
  40. package/dist/RepoTypeDetection/detectRepoCenterSystems.d.ts.map +1 -0
  41. package/dist/RepoTypeDetection/detectRepoCenterSystems.js +123 -0
  42. package/dist/RepoTypeDetection/detectRepoCenterSystems.js.map +1 -0
  43. package/dist/RepoTypeDetection/detectRepoMode.d.ts +16 -0
  44. package/dist/RepoTypeDetection/detectRepoMode.d.ts.map +1 -0
  45. package/dist/RepoTypeDetection/detectRepoMode.js +338 -0
  46. package/dist/RepoTypeDetection/detectRepoMode.js.map +1 -0
  47. package/dist/RepoTypeDetection/detectRepoSignals.d.ts +13 -0
  48. package/dist/RepoTypeDetection/detectRepoSignals.d.ts.map +1 -0
  49. package/dist/RepoTypeDetection/detectRepoSignals.js +451 -0
  50. package/dist/RepoTypeDetection/detectRepoSignals.js.map +1 -0
  51. package/dist/RepoTypeDetection/inferSupportRole.d.ts +8 -0
  52. package/dist/RepoTypeDetection/inferSupportRole.d.ts.map +1 -0
  53. package/dist/RepoTypeDetection/inferSupportRole.js +177 -0
  54. package/dist/RepoTypeDetection/inferSupportRole.js.map +1 -0
  55. package/dist/RuntimeInference/detectEnvConsumers.d.ts +7 -0
  56. package/dist/RuntimeInference/detectEnvConsumers.d.ts.map +1 -0
  57. package/dist/RuntimeInference/detectEnvConsumers.js +108 -0
  58. package/dist/RuntimeInference/detectEnvConsumers.js.map +1 -0
  59. package/dist/RuntimeInference/detectHttpEdges.d.ts +4 -0
  60. package/dist/RuntimeInference/detectHttpEdges.d.ts.map +1 -0
  61. package/dist/RuntimeInference/detectHttpEdges.js +146 -0
  62. package/dist/RuntimeInference/detectHttpEdges.js.map +1 -0
  63. package/dist/RuntimeInference/detectOrmConsumers.d.ts +5 -0
  64. package/dist/RuntimeInference/detectOrmConsumers.d.ts.map +1 -0
  65. package/dist/RuntimeInference/detectOrmConsumers.js +117 -0
  66. package/dist/RuntimeInference/detectOrmConsumers.js.map +1 -0
  67. package/dist/RuntimeInference/detectProxyRewrites.d.ts +5 -0
  68. package/dist/RuntimeInference/detectProxyRewrites.d.ts.map +1 -0
  69. package/dist/RuntimeInference/detectProxyRewrites.js +137 -0
  70. package/dist/RuntimeInference/detectProxyRewrites.js.map +1 -0
  71. package/dist/RuntimeInference/detectTrpcEdges.d.ts +4 -0
  72. package/dist/RuntimeInference/detectTrpcEdges.d.ts.map +1 -0
  73. package/dist/RuntimeInference/detectTrpcEdges.js +137 -0
  74. package/dist/RuntimeInference/detectTrpcEdges.js.map +1 -0
  75. package/dist/RuntimeInference/index.d.ts +17 -0
  76. package/dist/RuntimeInference/index.d.ts.map +1 -0
  77. package/dist/RuntimeInference/index.js +32 -0
  78. package/dist/RuntimeInference/index.js.map +1 -0
  79. package/dist/RuntimeInference/types.d.ts +8 -0
  80. package/dist/RuntimeInference/types.d.ts.map +1 -0
  81. package/dist/RuntimeInference/types.js +3 -0
  82. package/dist/RuntimeInference/types.js.map +1 -0
  83. package/dist/SystemSynthesis/index.d.ts +27 -0
  84. package/dist/SystemSynthesis/index.d.ts.map +1 -0
  85. package/dist/SystemSynthesis/index.js +31 -0
  86. package/dist/SystemSynthesis/index.js.map +1 -0
  87. package/dist/SystemSynthesis/mergeLayerOutputs.d.ts +13 -0
  88. package/dist/SystemSynthesis/mergeLayerOutputs.d.ts.map +1 -0
  89. package/dist/SystemSynthesis/mergeLayerOutputs.js +220 -0
  90. package/dist/SystemSynthesis/mergeLayerOutputs.js.map +1 -0
  91. package/dist/SystemSynthesis/stampDeterministic.d.ts +11 -0
  92. package/dist/SystemSynthesis/stampDeterministic.d.ts.map +1 -0
  93. package/dist/SystemSynthesis/stampDeterministic.js +177 -0
  94. package/dist/SystemSynthesis/stampDeterministic.js.map +1 -0
  95. package/dist/SystemSynthesis/synthesize.d.ts +15 -0
  96. package/dist/SystemSynthesis/synthesize.d.ts.map +1 -0
  97. package/dist/SystemSynthesis/synthesize.js +258 -0
  98. package/dist/SystemSynthesis/synthesize.js.map +1 -0
  99. package/dist/SystemSynthesis/types.d.ts +110 -0
  100. package/dist/SystemSynthesis/types.d.ts.map +1 -0
  101. package/dist/SystemSynthesis/types.js +12 -0
  102. package/dist/SystemSynthesis/types.js.map +1 -0
  103. package/dist/amGeneration/buildFlowGraph.d.ts +39 -0
  104. package/dist/amGeneration/buildFlowGraph.d.ts.map +1 -0
  105. package/dist/amGeneration/buildFlowGraph.js +643 -0
  106. package/dist/amGeneration/buildFlowGraph.js.map +1 -0
  107. package/dist/amGeneration/enrichAMEdges.d.ts +16 -0
  108. package/dist/amGeneration/enrichAMEdges.d.ts.map +1 -0
  109. package/dist/amGeneration/enrichAMEdges.js +291 -0
  110. package/dist/amGeneration/enrichAMEdges.js.map +1 -0
  111. package/dist/amGeneration/generateAM.d.ts +23 -0
  112. package/dist/amGeneration/generateAM.d.ts.map +1 -0
  113. package/dist/amGeneration/generateAM.js +131 -0
  114. package/dist/amGeneration/generateAM.js.map +1 -0
  115. package/dist/amGeneration/generateAMForRepo.d.ts +6 -0
  116. package/dist/amGeneration/generateAMForRepo.d.ts.map +1 -0
  117. package/dist/amGeneration/generateAMForRepo.js +130 -0
  118. package/dist/amGeneration/generateAMForRepo.js.map +1 -0
  119. package/dist/amGeneration/generateFlows.d.ts +27 -0
  120. package/dist/amGeneration/generateFlows.d.ts.map +1 -0
  121. package/dist/amGeneration/generateFlows.js +320 -0
  122. package/dist/amGeneration/generateFlows.js.map +1 -0
  123. package/dist/amGeneration/promptBuilder.d.ts +24 -0
  124. package/dist/amGeneration/promptBuilder.d.ts.map +1 -0
  125. package/dist/amGeneration/promptBuilder.js +299 -0
  126. package/dist/amGeneration/promptBuilder.js.map +1 -0
  127. package/dist/amGeneration/selectStrategicFiles.d.ts +42 -0
  128. package/dist/amGeneration/selectStrategicFiles.d.ts.map +1 -0
  129. package/dist/amGeneration/selectStrategicFiles.js +672 -0
  130. package/dist/amGeneration/selectStrategicFiles.js.map +1 -0
  131. package/dist/amGeneration/types.d.ts +83 -0
  132. package/dist/amGeneration/types.d.ts.map +1 -0
  133. package/dist/amGeneration/types.js +9 -0
  134. package/dist/amGeneration/types.js.map +1 -0
  135. package/dist/amSections.d.ts +29 -0
  136. package/dist/amSections.d.ts.map +1 -0
  137. package/dist/amSections.js +424 -0
  138. package/dist/amSections.js.map +1 -0
  139. package/dist/analysis/analysisCache.d.ts +4 -0
  140. package/dist/analysis/analysisCache.d.ts.map +1 -0
  141. package/dist/analysis/analysisCache.js +92 -0
  142. package/dist/analysis/analysisCache.js.map +1 -0
  143. package/dist/analysis/buildBranchStory.d.ts +95 -0
  144. package/dist/analysis/buildBranchStory.d.ts.map +1 -0
  145. package/dist/analysis/buildBranchStory.js +1264 -0
  146. package/dist/analysis/buildBranchStory.js.map +1 -0
  147. package/dist/analysis/buildDetailedFileXRay.d.ts +49 -0
  148. package/dist/analysis/buildDetailedFileXRay.d.ts.map +1 -0
  149. package/dist/analysis/buildDetailedFileXRay.js +607 -0
  150. package/dist/analysis/buildDetailedFileXRay.js.map +1 -0
  151. package/dist/analysis/buildFileXRay.d.ts +35 -0
  152. package/dist/analysis/buildFileXRay.d.ts.map +1 -0
  153. package/dist/analysis/buildFileXRay.js +305 -0
  154. package/dist/analysis/buildFileXRay.js.map +1 -0
  155. package/dist/analysis/classifySilentKiller.d.ts +14 -0
  156. package/dist/analysis/classifySilentKiller.d.ts.map +1 -0
  157. package/dist/analysis/classifySilentKiller.js +235 -0
  158. package/dist/analysis/classifySilentKiller.js.map +1 -0
  159. package/dist/analysis/diffChunks.d.ts +21 -0
  160. package/dist/analysis/diffChunks.d.ts.map +1 -0
  161. package/dist/analysis/diffChunks.js +302 -0
  162. package/dist/analysis/diffChunks.js.map +1 -0
  163. package/dist/analysis/extractRouteMap.d.ts +49 -0
  164. package/dist/analysis/extractRouteMap.d.ts.map +1 -0
  165. package/dist/analysis/extractRouteMap.js +354 -0
  166. package/dist/analysis/extractRouteMap.js.map +1 -0
  167. package/dist/analysis/generateFileInsight.d.ts +19 -0
  168. package/dist/analysis/generateFileInsight.d.ts.map +1 -0
  169. package/dist/analysis/generateFileInsight.js +103 -0
  170. package/dist/analysis/generateFileInsight.js.map +1 -0
  171. package/dist/analysis/llmXRay.d.ts +39 -0
  172. package/dist/analysis/llmXRay.d.ts.map +1 -0
  173. package/dist/analysis/llmXRay.js +208 -0
  174. package/dist/analysis/llmXRay.js.map +1 -0
  175. package/dist/analysis/simulateFailure.d.ts +44 -0
  176. package/dist/analysis/simulateFailure.d.ts.map +1 -0
  177. package/dist/analysis/simulateFailure.js +407 -0
  178. package/dist/analysis/simulateFailure.js.map +1 -0
  179. package/dist/anthropic.d.ts +3 -0
  180. package/dist/anthropic.d.ts.map +1 -0
  181. package/dist/anthropic.js +16 -0
  182. package/dist/anthropic.js.map +1 -0
  183. package/dist/app/buildAppPage.d.ts +34 -0
  184. package/dist/app/buildAppPage.d.ts.map +1 -0
  185. package/dist/app/buildAppPage.js +3085 -0
  186. package/dist/app/buildAppPage.js.map +1 -0
  187. package/dist/app-bundle.js +122 -0
  188. package/dist/buildAppData.d.ts +3 -0
  189. package/dist/buildAppData.d.ts.map +1 -0
  190. package/dist/buildAppData.js +207 -0
  191. package/dist/buildAppData.js.map +1 -0
  192. package/dist/builders/analyzeRepo.d.ts +25 -0
  193. package/dist/builders/analyzeRepo.d.ts.map +1 -0
  194. package/dist/builders/analyzeRepo.js +873 -0
  195. package/dist/builders/analyzeRepo.js.map +1 -0
  196. package/dist/builders/buildSystemConnections.d.ts +3 -0
  197. package/dist/builders/buildSystemConnections.d.ts.map +1 -0
  198. package/dist/builders/buildSystemConnections.js +388 -0
  199. package/dist/builders/buildSystemConnections.js.map +1 -0
  200. package/dist/builders/buildTextSummary.d.ts +61 -0
  201. package/dist/builders/buildTextSummary.d.ts.map +1 -0
  202. package/dist/builders/buildTextSummary.js +178 -0
  203. package/dist/builders/buildTextSummary.js.map +1 -0
  204. package/dist/builders/deriveRecommendedStartPath.d.ts +11 -0
  205. package/dist/builders/deriveRecommendedStartPath.d.ts.map +1 -0
  206. package/dist/builders/deriveRecommendedStartPath.js +140 -0
  207. package/dist/builders/deriveRecommendedStartPath.js.map +1 -0
  208. package/dist/builders/deriveRuntimeRole.d.ts +4 -0
  209. package/dist/builders/deriveRuntimeRole.d.ts.map +1 -0
  210. package/dist/builders/deriveRuntimeRole.js +30 -0
  211. package/dist/builders/deriveRuntimeRole.js.map +1 -0
  212. package/dist/builders/detectRunCommands.d.ts +16 -0
  213. package/dist/builders/detectRunCommands.d.ts.map +1 -0
  214. package/dist/builders/detectRunCommands.js +285 -0
  215. package/dist/builders/detectRunCommands.js.map +1 -0
  216. package/dist/builders/generateSystemNarrative.d.ts +12 -0
  217. package/dist/builders/generateSystemNarrative.d.ts.map +1 -0
  218. package/dist/builders/generateSystemNarrative.js +474 -0
  219. package/dist/builders/generateSystemNarrative.js.map +1 -0
  220. package/dist/builders/gitLogParser.d.ts +15 -0
  221. package/dist/builders/gitLogParser.d.ts.map +1 -0
  222. package/dist/builders/gitLogParser.js +116 -0
  223. package/dist/builders/gitLogParser.js.map +1 -0
  224. package/dist/builders/readRepoContext.d.ts +30 -0
  225. package/dist/builders/readRepoContext.d.ts.map +1 -0
  226. package/dist/builders/readRepoContext.js +323 -0
  227. package/dist/builders/readRepoContext.js.map +1 -0
  228. package/dist/builders/readSystemReadme.d.ts +39 -0
  229. package/dist/builders/readSystemReadme.d.ts.map +1 -0
  230. package/dist/builders/readSystemReadme.js +133 -0
  231. package/dist/builders/readSystemReadme.js.map +1 -0
  232. package/dist/builders/systemRanking.d.ts +24 -0
  233. package/dist/builders/systemRanking.d.ts.map +1 -0
  234. package/dist/builders/systemRanking.js +153 -0
  235. package/dist/builders/systemRanking.js.map +1 -0
  236. package/dist/cli.d.ts +3 -0
  237. package/dist/cli.d.ts.map +1 -0
  238. package/dist/cli.js +170 -0
  239. package/dist/cli.js.map +1 -0
  240. package/dist/detectors/applyRunnableConfidenceGate.d.ts +8 -0
  241. package/dist/detectors/applyRunnableConfidenceGate.d.ts.map +1 -0
  242. package/dist/detectors/applyRunnableConfidenceGate.js +166 -0
  243. package/dist/detectors/applyRunnableConfidenceGate.js.map +1 -0
  244. package/dist/detectors/classifySystemType.d.ts +17 -0
  245. package/dist/detectors/classifySystemType.d.ts.map +1 -0
  246. package/dist/detectors/classifySystemType.js +460 -0
  247. package/dist/detectors/classifySystemType.js.map +1 -0
  248. package/dist/detectors/detectAppInternalUnits.d.ts +20 -0
  249. package/dist/detectors/detectAppInternalUnits.d.ts.map +1 -0
  250. package/dist/detectors/detectAppInternalUnits.js +454 -0
  251. package/dist/detectors/detectAppInternalUnits.js.map +1 -0
  252. package/dist/detectors/detectBlocks.d.ts +6 -0
  253. package/dist/detectors/detectBlocks.d.ts.map +1 -0
  254. package/dist/detectors/detectBlocks.js +354 -0
  255. package/dist/detectors/detectBlocks.js.map +1 -0
  256. package/dist/detectors/detectComposeServices.d.ts +23 -0
  257. package/dist/detectors/detectComposeServices.d.ts.map +1 -0
  258. package/dist/detectors/detectComposeServices.js +255 -0
  259. package/dist/detectors/detectComposeServices.js.map +1 -0
  260. package/dist/detectors/detectEntryPoints.d.ts +6 -0
  261. package/dist/detectors/detectEntryPoints.d.ts.map +1 -0
  262. package/dist/detectors/detectEntryPoints.js +376 -0
  263. package/dist/detectors/detectEntryPoints.js.map +1 -0
  264. package/dist/detectors/detectSubsystems.d.ts +6 -0
  265. package/dist/detectors/detectSubsystems.d.ts.map +1 -0
  266. package/dist/detectors/detectSubsystems.js +376 -0
  267. package/dist/detectors/detectSubsystems.js.map +1 -0
  268. package/dist/detectors/detectSystemCandidates.d.ts +3 -0
  269. package/dist/detectors/detectSystemCandidates.d.ts.map +1 -0
  270. package/dist/detectors/detectSystemCandidates.js +577 -0
  271. package/dist/detectors/detectSystemCandidates.js.map +1 -0
  272. package/dist/devWatcher.d.ts +14 -0
  273. package/dist/devWatcher.d.ts.map +1 -0
  274. package/dist/devWatcher.js +96 -0
  275. package/dist/devWatcher.js.map +1 -0
  276. package/dist/graph/buildCodebaseGraph.d.ts +3 -0
  277. package/dist/graph/buildCodebaseGraph.d.ts.map +1 -0
  278. package/dist/graph/buildCodebaseGraph.js +602 -0
  279. package/dist/graph/buildCodebaseGraph.js.map +1 -0
  280. package/dist/graph/buildLLMPayload.d.ts +89 -0
  281. package/dist/graph/buildLLMPayload.d.ts.map +1 -0
  282. package/dist/graph/buildLLMPayload.js +715 -0
  283. package/dist/graph/buildLLMPayload.js.map +1 -0
  284. package/dist/graph/callLLM.d.ts +16 -0
  285. package/dist/graph/callLLM.d.ts.map +1 -0
  286. package/dist/graph/callLLM.js +274 -0
  287. package/dist/graph/callLLM.js.map +1 -0
  288. package/dist/graph/types.d.ts +76 -0
  289. package/dist/graph/types.d.ts.map +1 -0
  290. package/dist/graph/types.js +5 -0
  291. package/dist/graph/types.js.map +1 -0
  292. package/dist/graph/walkExports.d.ts +2 -0
  293. package/dist/graph/walkExports.d.ts.map +1 -0
  294. package/dist/graph/walkExports.js +172 -0
  295. package/dist/graph/walkExports.js.map +1 -0
  296. package/dist/heuristics/file-patterns.json +325 -0
  297. package/dist/heuristics/known-packages.json +1022 -0
  298. package/dist/heuristics/loader.d.ts +121 -0
  299. package/dist/heuristics/loader.d.ts.map +1 -0
  300. package/dist/heuristics/loader.js +196 -0
  301. package/dist/heuristics/loader.js.map +1 -0
  302. package/dist/heuristics/repo-mode-signals.json +248 -0
  303. package/dist/index.d.ts +3 -0
  304. package/dist/index.d.ts.map +1 -0
  305. package/dist/index.js +93 -0
  306. package/dist/index.js.map +1 -0
  307. package/dist/mcp.d.ts +3 -0
  308. package/dist/mcp.d.ts.map +1 -0
  309. package/dist/mcp.js +356 -0
  310. package/dist/mcp.js.map +1 -0
  311. package/dist/scanner/buildImportGraph.d.ts +23 -0
  312. package/dist/scanner/buildImportGraph.d.ts.map +1 -0
  313. package/dist/scanner/buildImportGraph.js +186 -0
  314. package/dist/scanner/buildImportGraph.js.map +1 -0
  315. package/dist/scanner/detectDBOps.d.ts +21 -0
  316. package/dist/scanner/detectDBOps.d.ts.map +1 -0
  317. package/dist/scanner/detectDBOps.js +346 -0
  318. package/dist/scanner/detectDBOps.js.map +1 -0
  319. package/dist/scanner/detectOutbound.d.ts +6 -0
  320. package/dist/scanner/detectOutbound.d.ts.map +1 -0
  321. package/dist/scanner/detectOutbound.js +101 -0
  322. package/dist/scanner/detectOutbound.js.map +1 -0
  323. package/dist/scanner/detectRepoPurpose.d.ts +19 -0
  324. package/dist/scanner/detectRepoPurpose.d.ts.map +1 -0
  325. package/dist/scanner/detectRepoPurpose.js +335 -0
  326. package/dist/scanner/detectRepoPurpose.js.map +1 -0
  327. package/dist/scanner/detectRoutes.d.ts +22 -0
  328. package/dist/scanner/detectRoutes.d.ts.map +1 -0
  329. package/dist/scanner/detectRoutes.js +406 -0
  330. package/dist/scanner/detectRoutes.js.map +1 -0
  331. package/dist/scanner/filterNoise.d.ts +4 -0
  332. package/dist/scanner/filterNoise.d.ts.map +1 -0
  333. package/dist/scanner/filterNoise.js +95 -0
  334. package/dist/scanner/filterNoise.js.map +1 -0
  335. package/dist/scanner/loadTsAliases.d.ts +20 -0
  336. package/dist/scanner/loadTsAliases.d.ts.map +1 -0
  337. package/dist/scanner/loadTsAliases.js +135 -0
  338. package/dist/scanner/loadTsAliases.js.map +1 -0
  339. package/dist/scanner/routeHandlers.d.ts +15 -0
  340. package/dist/scanner/routeHandlers.d.ts.map +1 -0
  341. package/dist/scanner/routeHandlers.js +154 -0
  342. package/dist/scanner/routeHandlers.js.map +1 -0
  343. package/dist/scanner/scanRepo.d.ts +10 -0
  344. package/dist/scanner/scanRepo.d.ts.map +1 -0
  345. package/dist/scanner/scanRepo.js +165 -0
  346. package/dist/scanner/scanRepo.js.map +1 -0
  347. package/dist/scanner/walkImports.d.ts +14 -0
  348. package/dist/scanner/walkImports.d.ts.map +1 -0
  349. package/dist/scanner/walkImports.js +162 -0
  350. package/dist/scanner/walkImports.js.map +1 -0
  351. package/dist/server.d.ts +2 -0
  352. package/dist/server.d.ts.map +1 -0
  353. package/dist/server.js +956 -0
  354. package/dist/server.js.map +1 -0
  355. package/dist/session/diff.d.ts +4 -0
  356. package/dist/session/diff.d.ts.map +1 -0
  357. package/dist/session/diff.js +150 -0
  358. package/dist/session/diff.js.map +1 -0
  359. package/dist/session/snapshot.d.ts +5 -0
  360. package/dist/session/snapshot.d.ts.map +1 -0
  361. package/dist/session/snapshot.js +114 -0
  362. package/dist/session/snapshot.js.map +1 -0
  363. package/dist/session/store.d.ts +8 -0
  364. package/dist/session/store.d.ts.map +1 -0
  365. package/dist/session/store.js +101 -0
  366. package/dist/session/store.js.map +1 -0
  367. package/dist/session/types.d.ts +46 -0
  368. package/dist/session/types.d.ts.map +1 -0
  369. package/dist/session/types.js +4 -0
  370. package/dist/session/types.js.map +1 -0
  371. package/dist/types.d.ts +350 -0
  372. package/dist/types.d.ts.map +1 -0
  373. package/dist/types.js +4 -0
  374. package/dist/types.js.map +1 -0
  375. package/dist/utils/file.d.ts +5 -0
  376. package/dist/utils/file.d.ts.map +1 -0
  377. package/dist/utils/file.js +76 -0
  378. package/dist/utils/file.js.map +1 -0
  379. package/dist/utils/path.d.ts +7 -0
  380. package/dist/utils/path.d.ts.map +1 -0
  381. package/dist/utils/path.js +62 -0
  382. package/dist/utils/path.js.map +1 -0
  383. package/dist/utils/text.d.ts +5 -0
  384. package/dist/utils/text.d.ts.map +1 -0
  385. package/dist/utils/text.js +29 -0
  386. package/dist/utils/text.js.map +1 -0
  387. package/dist/viewBuilders/buildSystemFolders.d.ts +39 -0
  388. package/dist/viewBuilders/buildSystemFolders.d.ts.map +1 -0
  389. package/dist/viewBuilders/buildSystemFolders.js +198 -0
  390. package/dist/viewBuilders/buildSystemFolders.js.map +1 -0
  391. package/dist/watcher/repoWatcher.d.ts +17 -0
  392. package/dist/watcher/repoWatcher.d.ts.map +1 -0
  393. package/dist/watcher/repoWatcher.js +87 -0
  394. package/dist/watcher/repoWatcher.js.map +1 -0
  395. package/package.json +102 -0
  396. package/public/memor_logo.svg +18 -0
  397. package/public/memor_transparent_logo.svg +25 -0
  398. package/public/tIcons/bun.svg +1 -0
  399. package/public/tIcons/css.svg +1 -0
  400. package/public/tIcons/docker.svg +3 -0
  401. package/public/tIcons/expressjs.svg +1 -0
  402. package/public/tIcons/html5.svg +6 -0
  403. package/public/tIcons/javascript.svg +1 -0
  404. package/public/tIcons/jest.svg +4 -0
  405. package/public/tIcons/json.svg +1 -0
  406. package/public/tIcons/markdown-light.svg +1 -0
  407. package/public/tIcons/nestjs.svg +1 -0
  408. package/public/tIcons/nextjs_icon_dark.svg +1 -0
  409. package/public/tIcons/npm.svg +1 -0
  410. package/public/tIcons/pnpm.svg +1 -0
  411. package/public/tIcons/prisma.svg +1 -0
  412. package/public/tIcons/react_dark.svg +11 -0
  413. package/public/tIcons/supabase.svg +15 -0
  414. package/public/tIcons/tailwindcss.svg +1 -0
  415. package/public/tIcons/turborepo-icon-light.svg +1 -0
  416. package/public/tIcons/typescript.svg +1 -0
  417. package/public/tIcons/vite.svg +1 -0
  418. package/public/tIcons/yarn.svg +1 -0
@@ -0,0 +1,715 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTransportScaffold = isTransportScaffold;
4
+ exports.isDocPage = isDocPage;
5
+ exports.classifyArchetype = classifyArchetype;
6
+ exports.buildLLMPayloadWithMeta = buildLLMPayloadWithMeta;
7
+ exports.buildLLMPayload = buildLLMPayload;
8
+ exports.estimateTokens = estimateTokens;
9
+ exports.promoteFamilies = promoteFamilies;
10
+ exports.buildAmbiguousPayload = buildAmbiguousPayload;
11
+ const MAX_CLUSTERS = 50;
12
+ const MAX_EDGES = 20;
13
+ const MAX_EXPORTS_PER_CLUSTER = 8;
14
+ const MAX_PACKAGE_GUARANTEE = 10; // Layer 3: cap on L1 package coverage additions
15
+ const TOKEN_BUDGET = 2500; // Layer 2: cluster-array budget (~4500 total with meta/edges overhead)
16
+ // ── Filtering ─────────────────────────────────────────────────────────────
17
+ const NOISE_TOP_DIRS = new Set([
18
+ "examples", "example", "demo", "demos", "playground", "playgrounds",
19
+ "bench", "benchmark", "benchmarks", "fixtures", "scripts", "tools",
20
+ "hack", "spike", "sandbox", "test", "tests", "spec", "specs",
21
+ "__tests__", "__mocks__", "e2e", "cypress", "playwright",
22
+ "archived", "archive", "old", "deprecated", "legacy", "unused",
23
+ ]);
24
+ // ── Transport scaffold detection ──────────────────────────────────────────
25
+ // Parameterised route handlers ([id].ts, [teamId].ts) are filesystem artifacts —
26
+ // they are not systems. They get filtered and their routes summarised as families.
27
+ const DOC_DIRS = new Set(["docs", "documentation", "doc", "website", "www", "storybook-static"]);
28
+ function isTransportScaffold(n) {
29
+ if (n.kind !== "cluster" && n.kind !== "package")
30
+ return false;
31
+ // [param] in path = parameterised route directory — a filesystem artifact, never a system.
32
+ // Universal across Next.js / SvelteKit / Remix / Astro / Nuxt.
33
+ // We drop the inDegree requirement: barrel imports (inDegree=1) don't make it a real system.
34
+ if (n.id.includes("[") && n.id.includes("]") && n.routes.length > 0 && n.models.length === 0)
35
+ return true;
36
+ return false;
37
+ }
38
+ function isDocPage(n) {
39
+ if (n.kind !== "cluster" && n.kind !== "package")
40
+ return false;
41
+ const parts = n.id.split("/");
42
+ // docs/pages/... or website/pages/... — framework routing inside a doc site
43
+ for (let i = 0; i < parts.length - 1; i++) {
44
+ if (DOC_DIRS.has(parts[i]) && (parts[i + 1] === "pages" || parts[i + 1] === "src"))
45
+ return true;
46
+ }
47
+ return false;
48
+ }
49
+ function isNoiseNode(n) {
50
+ // L1-declared infra/app/queue/etc. nodes are never noise — explicitly declared
51
+ if (n.kind !== "cluster" && n.kind !== "package")
52
+ return false;
53
+ // Transport scaffolding must be checked before the route guard below
54
+ if (isTransportScaffold(n))
55
+ return true;
56
+ // Documentation site pages masquerading as routes
57
+ if (isDocPage(n))
58
+ return true;
59
+ // Clusters that own routes or models are NEVER noise — orientation anchors
60
+ if (n.routes.length > 0 || n.models.length > 0)
61
+ return false;
62
+ // Test-only clusters with no incoming edges
63
+ if (n.hasTests && n.inDegree === 0)
64
+ return true;
65
+ // Empty clusters
66
+ if (n.fileCount === 0)
67
+ return true;
68
+ // Zero-connection clusters — barrel stubs or dead code
69
+ if (n.inDegree === 0 && n.outDegree === 0)
70
+ return true;
71
+ // Example/demo/archived directories (case-insensitive)
72
+ const topDir = n.id.split("/")[0].toLowerCase();
73
+ if (NOISE_TOP_DIRS.has(topDir))
74
+ return true;
75
+ // Micro-clusters: single file, low connectivity, not shared
76
+ if (n.fileCount === 1 && n.inDegree <= 1 && n.outDegree <= 2 && !n.isShared)
77
+ return true;
78
+ return false;
79
+ }
80
+ // ── Layer 1: Sibling Collapse ──────────────────────────────────────────────
81
+ // Merge structurally identical sibling clusters pre-selection to prevent slot flooding.
82
+ // Only collapses when structure matches AND no semantic boundary signals differ.
83
+ // Example: /packages/email + /packages/pdf + /packages/sms collapse into /packages
84
+ // when they look identical. But /billing + /bookings do NOT collapse (different routes).
85
+ function getParentPath(id) {
86
+ const parts = id.split("/");
87
+ return parts.length > 1 ? parts.slice(0, -1).join("/") : "__root__";
88
+ }
89
+ function routeRoot(routes) {
90
+ if (routes.length === 0)
91
+ return null;
92
+ return routes[0].replace(/^\//, "").split("/")[0] || null;
93
+ }
94
+ function setsEqual(a, b) {
95
+ if (a.size !== b.size)
96
+ return false;
97
+ for (const v of a)
98
+ if (!b.has(v))
99
+ return false;
100
+ return true;
101
+ }
102
+ // Returns true if siblings are structurally similar enough to consider collapsing.
103
+ function structuralGate(siblings) {
104
+ if (siblings.length < 3)
105
+ return false;
106
+ const fileCounts = siblings.map((n) => n.fileCount);
107
+ const maxFC = Math.max(...fileCounts);
108
+ const minFC = Math.min(...fileCounts);
109
+ if (maxFC > minFC * 2 + 1)
110
+ return false; // file counts vary too much
111
+ const routeCounts = siblings.map((n) => n.routes.length);
112
+ if (Math.max(...routeCounts) - Math.min(...routeCounts) > 1)
113
+ return false;
114
+ const shape = (n) => `${n.hasTests}-${n.hasTypes}-${n.hasConfig}`;
115
+ if (new Set(siblings.map(shape)).size > 1)
116
+ return false; // different signal shapes
117
+ return true;
118
+ }
119
+ // Returns true if collapse should be VETOED — siblings cross semantic boundaries.
120
+ function semanticVeto(siblings) {
121
+ // 1. Different env var usage — different runtime configs = different systems
122
+ const firstEnv = new Set(siblings[0].envConsumes);
123
+ for (let i = 1; i < siblings.length; i++) {
124
+ if (!setsEqual(firstEnv, new Set(siblings[i].envConsumes)))
125
+ return true;
126
+ }
127
+ // 2. Different ORM usage — different DB access patterns
128
+ const firstOrm = new Set(siblings[0].ormUses);
129
+ for (let i = 1; i < siblings.length; i++) {
130
+ if (!setsEqual(firstOrm, new Set(siblings[i].ormUses)))
131
+ return true;
132
+ }
133
+ // 3. Non-empty model sets that differ — different domain boundaries
134
+ if (siblings.some((n) => n.models.length > 0)) {
135
+ const firstModels = new Set(siblings[0].models);
136
+ for (let i = 1; i < siblings.length; i++) {
137
+ if (!setsEqual(firstModels, new Set(siblings[i].models)))
138
+ return true;
139
+ }
140
+ }
141
+ // 4. Mixed entry-point status — entry points are structurally distinct
142
+ if (new Set(siblings.map((n) => n.isEntryPoint)).size > 1)
143
+ return true;
144
+ // 5. Different route roots (when any sibling is route-bearing — orientation anchor)
145
+ const withRoutes = siblings.filter((n) => n.routes.length > 0);
146
+ if (withRoutes.length > 0) {
147
+ const roots = new Set(withRoutes.map((n) => routeRoot(n.routes)));
148
+ if (roots.size > 1)
149
+ return true;
150
+ }
151
+ return false;
152
+ }
153
+ function collapseGroup(siblings, parentId) {
154
+ return {
155
+ id: parentId,
156
+ name: parentId.split("/").pop() ?? parentId,
157
+ kind: "cluster",
158
+ packageId: siblings[0]?.packageId,
159
+ fileCount: siblings.reduce((s, n) => s + n.fileCount, 0),
160
+ topExports: [...new Set(siblings.flatMap((n) => n.topExports))].slice(0, 20),
161
+ centrality: Math.max(...siblings.map((n) => n.centrality)),
162
+ inDegree: Math.max(...siblings.map((n) => n.inDegree)),
163
+ outDegree: Math.max(...siblings.map((n) => n.outDegree)),
164
+ isEntryPoint: siblings[0]?.isEntryPoint ?? false,
165
+ isShared: siblings.some((n) => n.isShared),
166
+ routes: [...new Set(siblings.flatMap((n) => n.routes))],
167
+ models: [...new Set(siblings.flatMap((n) => n.models))],
168
+ hasTests: siblings.some((n) => n.hasTests),
169
+ hasTypes: siblings.some((n) => n.hasTypes),
170
+ hasConfig: siblings.some((n) => n.hasConfig),
171
+ envConsumes: [...new Set(siblings.flatMap((n) => n.envConsumes))],
172
+ ormUses: [...new Set(siblings.flatMap((n) => n.ormUses))],
173
+ };
174
+ }
175
+ function applySiblingCollapse(nodes) {
176
+ const nodeIds = new Set(nodes.map((n) => n.id));
177
+ const byParent = new Map();
178
+ for (const n of nodes) {
179
+ const parent = getParentPath(n.id);
180
+ if (parent === "__root__")
181
+ continue;
182
+ if (nodeIds.has(parent))
183
+ continue; // parent is a first-class node, never collapse into it
184
+ if (!byParent.has(parent))
185
+ byParent.set(parent, []);
186
+ byParent.get(parent).push(n);
187
+ }
188
+ const collapseMap = new Map(); // child id → merged parent id
189
+ const collapsedChildIds = new Set();
190
+ const syntheticNodes = [];
191
+ for (const [parentId, siblings] of byParent) {
192
+ if (!structuralGate(siblings))
193
+ continue;
194
+ if (semanticVeto(siblings))
195
+ continue;
196
+ syntheticNodes.push(collapseGroup(siblings, parentId));
197
+ for (const s of siblings) {
198
+ collapseMap.set(s.id, parentId);
199
+ collapsedChildIds.add(s.id);
200
+ }
201
+ }
202
+ const surviving = nodes.filter((n) => !collapsedChildIds.has(n.id));
203
+ surviving.push(...syntheticNodes);
204
+ return { nodes: surviving, collapseMap };
205
+ }
206
+ function classifyArchetype(n) {
207
+ const name = n.name.toLowerCase();
208
+ const id = n.id.toLowerCase();
209
+ // ── Data layer ─────────────────────────────────────────────────────────────
210
+ // Prisma cluster (by name or ORM signal + models)
211
+ if (id.includes("prisma") && (n.ormUses.length > 0 || n.models.length > 0))
212
+ return "data-layer";
213
+ // Any ORM with significant models
214
+ if (n.ormUses.length > 0 && n.models.length > 2)
215
+ return "data-layer";
216
+ // TypeORM / Mongoose / Sequelize / Drizzle / Knex — DB-access layer regardless of models
217
+ if (n.ormUses.some((o) => /typeorm|mongoose|sequelize|drizzle|knex/i.test(o)))
218
+ return "data-layer";
219
+ // Non-ORM DB clients: Supabase, Firebase, Neon, PlanetScale, Turso, libSQL.
220
+ // Guard: the cluster name or id must also suggest it IS the data layer, not just
221
+ // a consumer of it. A generic "lib" that initialises supabase is not a data layer.
222
+ const DB_LAYER_NAME = /database|^db$|^data$|supabase|firebase|neon|planetscale|mongo|postgres|repository|repositories|repo|store|storage/i;
223
+ if (n.ormUses.some((o) => /supabase|firebase|firestore|neon|planetscale|turso|libsql/i.test(o)) &&
224
+ (DB_LAYER_NAME.test(n.name) || DB_LAYER_NAME.test(n.id)))
225
+ return "data-layer";
226
+ // Env-pattern fallback: DATABASE_URL etc. signal a data layer only when the cluster
227
+ // has a database-related name AND at least one model — prevents API routes that merely
228
+ // read SUPABASE_URL from being mis-classified.
229
+ const DB_ENV = /^(DATABASE_URL|MONGO_URI|MONGODB_URI|SUPABASE_URL|FIREBASE_URL|NEON_URL|TURSO_URL|PLANETSCALE_URL)$/i;
230
+ if (n.envConsumes.some((e) => DB_ENV.test(e)) &&
231
+ (DB_LAYER_NAME.test(n.name) || n.models.length >= 1) &&
232
+ n.inDegree >= 1)
233
+ return "data-layer";
234
+ // ── DB migrations / seeds ──────────────────────────────────────────────────
235
+ if ((/migrations?$|seeders?$|seeds?$/.test(name) || id.includes("/migration")) &&
236
+ n.routes.length === 0)
237
+ return "db-migration";
238
+ // ── Cache client ───────────────────────────────────────────────────────────
239
+ if (n.envConsumes.some((e) => /redis/i.test(e)) || n.ormUses.some((o) => /redis/i.test(o)))
240
+ return "cache-client";
241
+ // ── Auth / session ─────────────────────────────────────────────────────────
242
+ if (/auth|jwt|passport|session/.test(name) &&
243
+ n.envConsumes.some((e) => /jwt|secret|auth|token|password/i.test(e)))
244
+ return "auth-service";
245
+ // ── Queue / worker ─────────────────────────────────────────────────────────
246
+ if (/queue|worker|bull|job|cron/.test(name) && n.envConsumes.length > 0)
247
+ return "queue-worker";
248
+ // ── Email / notification service ───────────────────────────────────────────
249
+ if (/mailer?|mailing|smtp|sendgrid|notification|notif$|messaging$/.test(name) &&
250
+ n.routes.length === 0 && n.models.length < 2 &&
251
+ n.envConsumes.length > 0)
252
+ return "email-service";
253
+ // ── Middleware / cross-cutting concerns ────────────────────────────────────
254
+ if (/^middleware$|interceptors?$|guards?$|pipes?$|exception.?filters?$|decorators?$/.test(name) &&
255
+ n.routes.length === 0 && n.models.length === 0 &&
256
+ n.fileCount < 30)
257
+ return "middleware";
258
+ // ── Pure type definitions ──────────────────────────────────────────────────
259
+ // If hasTypes is set and there are zero runtime signals, this cluster is
260
+ // unambiguously a type-definitions package regardless of name.
261
+ if (n.hasTypes && n.routes.length === 0 && n.models.length === 0 &&
262
+ n.ormUses.length === 0 && n.envConsumes.length === 0 && !n.hasTests &&
263
+ n.fileCount < 25)
264
+ return "type-defs";
265
+ // Name-driven fallback for larger type packages (DTOs, interfaces, schemas)
266
+ if (n.routes.length === 0 && n.models.length === 0 &&
267
+ n.ormUses.length === 0 && n.envConsumes.length === 0 &&
268
+ /^types?$|^interfaces?$|^dtos?$|^schemas?$|^typings?$|^declarations?$|^contracts?$|^enums?$/.test(name))
269
+ return "type-defs";
270
+ // Path-driven: cluster is a sub-directory of a dto/types/interfaces/schemas folder.
271
+ // Covers "jira" in server/api/v1/dto/jira — name alone won't match but parent path does.
272
+ const DTO_PATH_SEGMENTS = new Set(["dto", "dtos", "types", "type", "interfaces", "schemas", "typings", "contracts"]);
273
+ const pathSegs = n.id.split("/");
274
+ if (pathSegs.some((seg) => DTO_PATH_SEGMENTS.has(seg.toLowerCase())) &&
275
+ n.routes.length === 0 && n.models.length === 0 &&
276
+ n.ormUses.length === 0 && n.envConsumes.length === 0)
277
+ return "type-defs";
278
+ // ── Config-only package ────────────────────────────────────────────────────
279
+ // Small clusters with config signal and no runtime signals are unambiguous.
280
+ if (n.hasConfig && n.routes.length === 0 && n.models.length === 0 &&
281
+ n.ormUses.length === 0 && n.envConsumes.length === 0 && n.fileCount < 8)
282
+ return "config";
283
+ // Name-driven config (larger config packages like eslint, prettier, tsconfig)
284
+ if (n.routes.length === 0 && n.models.length === 0 && n.fileCount < 15 &&
285
+ /config|tsconfig|eslint|prettier|constants?$|settings?$|^env$|environment/.test(name))
286
+ return "config";
287
+ // ── Shared utility library ─────────────────────────────────────────────────
288
+ // Universal utility name catch-all — these folder names are unambiguous
289
+ const UTIL_NAMES = new Set([
290
+ "utils", "util", "helpers", "helper", "common", "lib", "tools", "toolkit",
291
+ "shared", "core-utils", "utilities",
292
+ ]);
293
+ if (UTIL_NAMES.has(name) &&
294
+ n.routes.length === 0 && n.models.length === 0 &&
295
+ n.ormUses.length === 0 && n.envConsumes.length === 0)
296
+ return "shared-lib";
297
+ // React hooks folder — unambiguously support layer
298
+ if ((name === "hooks" || n.name.startsWith("use") || name.endsWith("-hooks")) &&
299
+ n.routes.length === 0 && n.models.length === 0 && n.isShared)
300
+ return "shared-lib";
301
+ // Heavily imported with no business signals
302
+ if (n.isShared && n.inDegree >= 3 && n.routes.length === 0 && n.models.length === 0)
303
+ return "shared-lib";
304
+ // ── App entry ──────────────────────────────────────────────────────────────
305
+ if (n.isEntryPoint && n.fileCount <= 5 && n.outDegree >= 4 && n.routes.length === 0)
306
+ return "app-entry";
307
+ // ── Public web page ────────────────────────────────────────────────────────
308
+ // Next.js app-router page clusters: public-facing routes (not /api/, not /admin/).
309
+ // These are orientation anchors the LLM routinely overlooks because they have
310
+ // minimal signal (1 file, 1 route, no models/ORM) — classify deterministically.
311
+ if (n.routes.length > 0 &&
312
+ n.routes.every((r) => !r.startsWith("/api/") && !r.startsWith("/admin")) &&
313
+ n.models.length === 0 && n.ormUses.length === 0 &&
314
+ !n.id.includes("[") // not a transport scaffold
315
+ )
316
+ return "web-page";
317
+ return null;
318
+ }
319
+ // ── Layer 2: Token Budget ─────────────────────────────────────────────────
320
+ // Drop lowest-signal clusters when payload exceeds budget.
321
+ // Runtime-edge clusters are always preserved (they carry dynamic architecture facts).
322
+ function enforceTokenBudget(clusters, runtimeEdgeClusterIds) {
323
+ const budget = TOKEN_BUDGET * 4; // chars (~4 chars per token)
324
+ if (JSON.stringify(clusters).length <= budget)
325
+ return clusters;
326
+ const scored = clusters.map((c) => ({
327
+ c,
328
+ score: c.routes.length * 5 +
329
+ c.models.length * 3 +
330
+ (c.uses_orm?.length ?? 0) * 4 +
331
+ (c.env_consumes?.length ?? 0) * 2 +
332
+ c.files * 0.5 +
333
+ c.centrality * 10 +
334
+ (c.is_entry ? 3 : 0) +
335
+ (runtimeEdgeClusterIds.has(c.id) ? 1000 : 0), // never drop runtime-edge clusters
336
+ }));
337
+ scored.sort((a, b) => b.score - a.score);
338
+ const kept = [];
339
+ let chars = 0;
340
+ for (const { c } of scored) {
341
+ const len = JSON.stringify(c).length;
342
+ // Always keep the first item; skip others that would bust the budget
343
+ if (chars + len > budget && kept.length > 0)
344
+ continue;
345
+ kept.push(c);
346
+ chars += len;
347
+ }
348
+ return kept;
349
+ }
350
+ function buildLLMPayloadWithMeta(graph) {
351
+ // Split nodes: structural clusters vs declared infra nodes
352
+ const clusterNodes = graph.nodes.filter((n) => n.kind === "cluster" || n.kind === "package");
353
+ const infraNodes = graph.nodes.filter((n) => n.kind !== "cluster" && n.kind !== "package");
354
+ // ── Transport scaffold extraction ────────────────────────────────────────
355
+ // Collect route families from transport clusters before they're discarded,
356
+ // so the LLM still gets route orientation context in a compact form.
357
+ const transportNodes = clusterNodes.filter((n) => isTransportScaffold(n) || isDocPage(n));
358
+ const routeFamilyMap = new Map();
359
+ for (const n of transportNodes) {
360
+ for (const route of n.routes) {
361
+ const seg = route.replace(/^\//, "").split("/")[0];
362
+ const family = seg ? `/${seg}` : "/";
363
+ routeFamilyMap.set(family, (routeFamilyMap.get(family) ?? 0) + 1);
364
+ }
365
+ }
366
+ const routeFamilies = [...routeFamilyMap.entries()]
367
+ .filter(([, count]) => count >= 2)
368
+ .sort((a, b) => b[1] - a[1])
369
+ .slice(0, 10)
370
+ .map(([family, count]) => ({ family: family + "/*", count }));
371
+ // Filter noisy cluster nodes
372
+ const filtered = clusterNodes.filter((n) => !isNoiseNode(n));
373
+ // ── Layer 1: Sibling Collapse ────────────────────────────────────────────
374
+ const { nodes: collapsed, collapseMap } = applySiblingCollapse(filtered);
375
+ const resolve = (id) => collapseMap.get(id) ?? id;
376
+ // ── Orientation-driven selection ─────────────────────────────────────────
377
+ const ROUTE_SLOTS = Math.floor(MAX_CLUSTERS * 0.45);
378
+ const MODEL_SLOTS = Math.floor(MAX_CLUSTERS * 0.10);
379
+ const INFRA_SLOTS = MAX_CLUSTERS - ROUTE_SLOTS - MODEL_SLOTS;
380
+ const withRoutes = collapsed
381
+ .filter((n) => n.routes.length > 0)
382
+ .sort((a, b) => (b.routes.length + b.fileCount) - (a.routes.length + a.fileCount))
383
+ .slice(0, ROUTE_SLOTS);
384
+ const orientationIds = new Set(withRoutes.map((n) => n.id));
385
+ const withModels = collapsed
386
+ .filter((n) => n.models.length > 0 && !orientationIds.has(n.id))
387
+ .sort((a, b) => b.models.length - a.models.length)
388
+ .slice(0, MODEL_SLOTS);
389
+ withModels.forEach((n) => orientationIds.add(n.id));
390
+ const orientationNodes = [...withRoutes, ...withModels];
391
+ // Sort rest by centrality so collapsed synthetic nodes rank fairly
392
+ const rest = collapsed
393
+ .filter((n) => !orientationIds.has(n.id))
394
+ .sort((a, b) => b.centrality - a.centrality);
395
+ const CENTRALITY_SLOTS = Math.floor(INFRA_SLOTS * 0.5);
396
+ const FILECOUNT_SLOTS = Math.floor(INFRA_SLOTS * 0.35);
397
+ const ENTRY_SLOTS = INFRA_SLOTS - CENTRALITY_SLOTS - FILECOUNT_SLOTS;
398
+ const byCentrality = rest.slice(0, CENTRALITY_SLOTS);
399
+ const centralityIds = new Set(byCentrality.map((n) => n.id));
400
+ const afterCentrality = rest.filter((n) => !centralityIds.has(n.id));
401
+ const byFileCount = afterCentrality
402
+ .sort((a, b) => b.fileCount - a.fileCount)
403
+ .slice(0, FILECOUNT_SLOTS);
404
+ const fileCountIds = new Set(byFileCount.map((n) => n.id));
405
+ const byEntry = afterCentrality
406
+ .filter((n) => !fileCountIds.has(n.id) && n.isEntryPoint && n.outDegree >= 2)
407
+ .sort((a, b) => b.outDegree - a.outDegree)
408
+ .slice(0, ENTRY_SLOTS);
409
+ const selected = [...orientationNodes, ...byCentrality, ...byFileCount, ...byEntry];
410
+ // ── Layer 3: L1 package coverage guarantee (capped) ──────────────────────
411
+ const coveredPackageIds = new Set(selected.map((n) => n.packageId).filter((id) => !!id));
412
+ const allPackageIds = new Set(collapsed.map((n) => n.packageId).filter((id) => !!id));
413
+ const selectedIds = new Set(selected.map((n) => n.id));
414
+ let packageGuaranteeCount = 0;
415
+ for (const pkgId of allPackageIds) {
416
+ if (packageGuaranteeCount >= MAX_PACKAGE_GUARANTEE)
417
+ break;
418
+ if (coveredPackageIds.has(pkgId))
419
+ continue;
420
+ const best = collapsed
421
+ .filter((n) => n.packageId === pkgId && !selectedIds.has(n.id))
422
+ .sort((a, b) => (b.routes.length * 5 + b.models.length * 3 + b.fileCount + b.centrality * 10) -
423
+ (a.routes.length * 5 + a.models.length * 3 + a.fileCount + a.centrality * 10))[0];
424
+ if (best) {
425
+ selected.push(best);
426
+ selectedIds.add(best.id);
427
+ coveredPackageIds.add(pkgId);
428
+ packageGuaranteeCount++;
429
+ }
430
+ }
431
+ // Always include declared infra nodes (they are architecture facts, not noise)
432
+ // Cap at 10 to avoid flooding the payload on large compose files
433
+ const selectedInfra = infraNodes
434
+ .filter((n) => graph.edges.some((e) => (e.to === n.id || e.from === n.id) &&
435
+ (selectedIds.has(resolve(e.from)) || selectedIds.has(resolve(e.to)))))
436
+ .slice(0, 10);
437
+ selectedInfra.forEach((n) => selectedIds.add(n.id));
438
+ const allSelected = [...selected, ...selectedInfra];
439
+ const includedIds = new Set(allSelected.map((n) => n.id));
440
+ // ── Import edges (with collapse remapping) ────────────────────────────────
441
+ const importEdges = graph.edges
442
+ .filter((e) => e.kind === "import")
443
+ .map((e) => ({ ...e, from: resolve(e.from), to: resolve(e.to) }))
444
+ .filter((e) => e.from !== e.to && includedIds.has(e.from) && includedIds.has(e.to))
445
+ .sort((a, b) => b.weight - a.weight)
446
+ .slice(0, MAX_EDGES);
447
+ // Pre-build adjacency for compact cluster representation
448
+ const outgoing = new Map();
449
+ const incoming = new Map();
450
+ for (const id of includedIds) {
451
+ outgoing.set(id, []);
452
+ incoming.set(id, []);
453
+ }
454
+ for (const e of importEdges) {
455
+ outgoing.get(e.from)?.push(e.to);
456
+ incoming.get(e.to)?.push(e.from);
457
+ }
458
+ // ── Runtime edges ─────────────────────────────────────────────────────────
459
+ const runtimeEdges = graph.edges
460
+ .filter((e) => e.kind === "runtime" && (includedIds.has(e.from) || includedIds.has(e.to)));
461
+ const runtimeEdgeClusterIds = new Set(runtimeEdges.flatMap((e) => [e.from, e.to]));
462
+ // ── Build compact clusters ────────────────────────────────────────────────
463
+ const compactClusters = allSelected.map((n) => {
464
+ const signals = {};
465
+ if (n.hasTests)
466
+ signals.tests = true;
467
+ if (n.hasTypes)
468
+ signals.types = true;
469
+ if (n.hasConfig)
470
+ signals.config = true;
471
+ // Runtime calls from this node to other nodes (HTTP, tRPC, proxy)
472
+ const runtimeCalls = [...new Set(runtimeEdges
473
+ .filter((e) => e.from === n.id &&
474
+ (e.type === "HTTP_CALL" || e.type === "TRPC_CALL" || e.type === "PROXY_ROUTE"))
475
+ .map((e) => e.to))];
476
+ const compact = {
477
+ id: n.id,
478
+ name: n.name,
479
+ files: n.fileCount,
480
+ exports: n.topExports.slice(0, MAX_EXPORTS_PER_CLUSTER),
481
+ imports_from: outgoing.get(n.id) ?? [],
482
+ imported_by: incoming.get(n.id) ?? [],
483
+ is_entry: n.isEntryPoint,
484
+ is_shared: n.isShared,
485
+ centrality: n.centrality,
486
+ routes: n.routes.slice(0, 6),
487
+ models: n.models.slice(0, 10),
488
+ signals,
489
+ };
490
+ if (n.kind !== "cluster" && n.kind !== "package")
491
+ compact.kind = n.kind;
492
+ const archetype = classifyArchetype(n);
493
+ if (archetype)
494
+ compact.archetype = archetype;
495
+ if (n.envConsumes.length > 0)
496
+ compact.env_consumes = n.envConsumes;
497
+ if (n.ormUses.length > 0)
498
+ compact.uses_orm = n.ormUses;
499
+ if (runtimeCalls.length > 0)
500
+ compact.runtime_calls = runtimeCalls;
501
+ return compact;
502
+ });
503
+ // ── Layer 2: Token Budget ─────────────────────────────────────────────────
504
+ const budgetedClusters = enforceTokenBudget(compactClusters, runtimeEdgeClusterIds);
505
+ const budgetedIds = new Set(budgetedClusters.map((c) => c.id));
506
+ const topEdges = importEdges
507
+ .filter((e) => budgetedIds.has(e.from) && budgetedIds.has(e.to))
508
+ .map((e) => ({
509
+ from: e.from,
510
+ to: e.to,
511
+ weight: e.weight,
512
+ symbols: e.symbols.slice(0, 3),
513
+ }));
514
+ const meta = {
515
+ repo_name: graph.meta.repoName,
516
+ total_files: graph.meta.totalFiles,
517
+ total_clusters: graph.meta.totalClusters,
518
+ frameworks: graph.meta.frameworks,
519
+ packages: graph.meta.packages,
520
+ };
521
+ if (graph.meta.readmeSummary)
522
+ meta.repo_purpose = graph.meta.readmeSummary;
523
+ if (graph.meta.repoStructure)
524
+ meta.repo_structure = graph.meta.repoStructure;
525
+ if (graph.meta.repoType)
526
+ meta.repo_type = graph.meta.repoType;
527
+ if (graph.meta.techStack?.length)
528
+ meta.tech_stack = graph.meta.techStack;
529
+ if (graph.meta.dataModels.length > 0)
530
+ meta.data_models = graph.meta.dataModels;
531
+ if (routeFamilies.length > 0)
532
+ meta.route_families = routeFamilies;
533
+ const payload = { meta, clusters: budgetedClusters, top_edges: topEdges };
534
+ // Include runtime edges that involve budgeted clusters
535
+ const compactRuntime = runtimeEdges
536
+ .filter((e) => budgetedIds.has(e.from) || budgetedIds.has(e.to))
537
+ .map((e) => ({
538
+ from: e.from,
539
+ to: e.to,
540
+ type: e.type ?? "runtime",
541
+ evidence: e.evidence ?? "",
542
+ }));
543
+ if (compactRuntime.length > 0)
544
+ payload.runtime_edges = compactRuntime;
545
+ const payloadStr = JSON.stringify(payload);
546
+ const tokens = estimateTokens(payloadStr);
547
+ // ── Compute metrics ───────────────────────────────────────────────────────
548
+ const routesTotal = clusterNodes.reduce((s, n) => s + n.routes.length, 0);
549
+ const routesRetained = budgetedClusters.reduce((s, c) => s + c.routes.length, 0);
550
+ const modelsTotal = clusterNodes.reduce((s, n) => s + n.models.length, 0);
551
+ const modelsRetained = budgetedClusters.reduce((s, c) => s + c.models.length, 0);
552
+ const ormClustersTotal = clusterNodes.filter((n) => n.ormUses.length > 0).length;
553
+ const ormClustersRetained = budgetedClusters.filter((c) => (c.uses_orm?.length ?? 0) > 0).length;
554
+ const hasSignal = (c) => c.routes.length > 0 || c.models.length > 0 ||
555
+ (c.uses_orm?.length ?? 0) > 0 || (c.env_consumes?.length ?? 0) > 0;
556
+ const semanticDensity = budgetedClusters.length === 0 ? 0
557
+ : budgetedClusters.filter(hasSignal).length / budgetedClusters.length;
558
+ const archetypeHits = budgetedClusters.filter((c) => c.archetype !== undefined).length;
559
+ const buildMeta = {
560
+ rawClusters: clusterNodes.length,
561
+ afterNoiseFilter: filtered.length,
562
+ afterSiblingCollapse: collapsed.length,
563
+ siblingsCollapsed: collapseMap.size,
564
+ transportFolded: transportNodes.length,
565
+ prebudgetClusters: compactClusters.length,
566
+ payloadClusters: budgetedClusters.length,
567
+ budgetDropped: compactClusters.length - budgetedClusters.length,
568
+ packageGuaranteeAdded: packageGuaranteeCount,
569
+ tokens,
570
+ routesTotal,
571
+ routesRetained,
572
+ modelsTotal,
573
+ modelsRetained,
574
+ ormClustersTotal,
575
+ ormClustersRetained,
576
+ semanticDensity,
577
+ signalRetentionRoutes: routesTotal === 0 ? 1 : routesRetained / routesTotal,
578
+ signalRetentionModels: modelsTotal === 0 ? 1 : modelsRetained / modelsTotal,
579
+ archetypeHits,
580
+ archetypeRate: budgetedClusters.length === 0 ? 0 : archetypeHits / budgetedClusters.length,
581
+ };
582
+ return { payload: payloadStr, meta: buildMeta };
583
+ }
584
+ function buildLLMPayload(graph) {
585
+ return buildLLMPayloadWithMeta(graph).payload;
586
+ }
587
+ function estimateTokens(payload) {
588
+ return Math.ceil(payload.length / 4);
589
+ }
590
+ // ── Family Promotion ─────────────────────────────────────────────────────────
591
+ // When ≥ FAMILY_THRESHOLD siblings share a parent directory, replace them with
592
+ // one merged cluster at the parent level. The LLM names the parent once instead
593
+ // of naming each child separately. Repo-agnostic: works for any framework.
594
+ const FAMILY_THRESHOLD = 3;
595
+ function parentDir(id) {
596
+ const i = id.lastIndexOf("/");
597
+ return i > 0 ? id.slice(0, i) : "";
598
+ }
599
+ function promoteFamilies(clusters) {
600
+ const existingIds = new Set(clusters.map((c) => c.id));
601
+ const byParent = new Map();
602
+ for (const c of clusters) {
603
+ const p = parentDir(c.id);
604
+ if (!p)
605
+ continue;
606
+ if (!byParent.has(p))
607
+ byParent.set(p, []);
608
+ byParent.get(p).push(c);
609
+ }
610
+ const toRemove = new Set();
611
+ const toAdd = [];
612
+ const parentToChildren = new Map();
613
+ for (const [parent, children] of byParent) {
614
+ if (children.length < FAMILY_THRESHOLD)
615
+ continue;
616
+ const parentCluster = clusters.find((c) => c.id === parent);
617
+ if (parentCluster) {
618
+ // Parent already a cluster — absorb children's signals into it, remove children.
619
+ // Routes, models, exports, envs, orms are unioned in; parent keeps its own signals.
620
+ const allRoutes = [...new Set([...parentCluster.routes, ...children.flatMap((c) => c.routes)])];
621
+ const allModels = [...new Set([...parentCluster.models, ...children.flatMap((c) => c.models)])];
622
+ const allExports = [...new Set([...parentCluster.exports, ...children.flatMap((c) => c.exports)])].slice(0, 10);
623
+ const allEnvs = [...new Set([...(parentCluster.env_consumes ?? []), ...children.flatMap((c) => c.env_consumes ?? [])])];
624
+ const allOrms = [...new Set([...(parentCluster.uses_orm ?? []), ...children.flatMap((c) => c.uses_orm ?? [])])];
625
+ const allCalls = [...new Set([...(parentCluster.runtime_calls ?? []), ...children.flatMap((c) => c.runtime_calls ?? [])])];
626
+ parentCluster.routes = allRoutes;
627
+ parentCluster.models = allModels;
628
+ parentCluster.exports = allExports;
629
+ parentCluster.files += children.reduce((s, c) => s + c.files, 0);
630
+ parentCluster.centrality = Math.max(parentCluster.centrality, ...children.map((c) => c.centrality));
631
+ if (allEnvs.length)
632
+ parentCluster.env_consumes = allEnvs;
633
+ if (allOrms.length)
634
+ parentCluster.uses_orm = allOrms;
635
+ if (allCalls.length)
636
+ parentCluster.runtime_calls = allCalls;
637
+ for (const c of children)
638
+ toRemove.add(c.id);
639
+ parentToChildren.set(parent, children.map((c) => c.id));
640
+ continue;
641
+ }
642
+ const merged = {
643
+ id: parent,
644
+ name: parent.split("/").pop() ?? parent,
645
+ files: children.reduce((s, c) => s + c.files, 0),
646
+ exports: [...new Set(children.flatMap((c) => c.exports))].slice(0, 10),
647
+ imports_from: [...new Set(children.flatMap((c) => c.imports_from))],
648
+ imported_by: [...new Set(children.flatMap((c) => c.imported_by))],
649
+ is_entry: children.some((c) => c.is_entry),
650
+ is_shared: children.some((c) => c.is_shared),
651
+ centrality: Math.max(...children.map((c) => c.centrality)),
652
+ routes: [...new Set(children.flatMap((c) => c.routes))],
653
+ models: [...new Set(children.flatMap((c) => c.models))],
654
+ signals: {
655
+ tests: children.some((c) => c.signals.tests) ? true : undefined,
656
+ types: children.some((c) => c.signals.types) ? true : undefined,
657
+ config: children.some((c) => c.signals.config) ? true : undefined,
658
+ },
659
+ };
660
+ const envs = [...new Set(children.flatMap((c) => c.env_consumes ?? []))];
661
+ const orms = [...new Set(children.flatMap((c) => c.uses_orm ?? []))];
662
+ const calls = [...new Set(children.flatMap((c) => c.runtime_calls ?? []))];
663
+ if (envs.length)
664
+ merged.env_consumes = envs;
665
+ if (orms.length)
666
+ merged.uses_orm = orms;
667
+ if (calls.length)
668
+ merged.runtime_calls = calls;
669
+ for (const c of children)
670
+ toRemove.add(c.id);
671
+ toAdd.push(merged);
672
+ parentToChildren.set(parent, children.map((c) => c.id));
673
+ }
674
+ return {
675
+ clusters: [...clusters.filter((c) => !toRemove.has(c.id)), ...toAdd],
676
+ parentToChildren,
677
+ };
678
+ }
679
+ /**
680
+ * Split the full payload into deterministic (classified) and ambiguous clusters.
681
+ * Returns the ambiguous-only payload string for LLM + the deterministic clusters
682
+ * for pre-naming without an API call. Core of Phase 3.
683
+ * Also runs family promotion so sibling-heavy directories appear as one cluster.
684
+ */
685
+ function buildAmbiguousPayload(graph) {
686
+ const { payload } = buildLLMPayloadWithMeta(graph);
687
+ const parsed = JSON.parse(payload);
688
+ const routeFamilies = parsed.meta.route_families ?? [];
689
+ const deterministicClusters = parsed.clusters.filter((c) => c.archetype !== undefined);
690
+ // Infra/synthetic nodes (kind set = not a real cluster) are architecture facts captured
691
+ // in uses_infra — they must NOT become named systems on the AM.
692
+ let ambiguousClusters = parsed.clusters.filter((c) => c.archetype === undefined && !c.kind);
693
+ // Family promotion: merge siblings → parent before sending to LLM
694
+ const { clusters: promoted, parentToChildren } = promoteFamilies(ambiguousClusters);
695
+ ambiguousClusters = promoted;
696
+ if (ambiguousClusters.length === 0) {
697
+ return { ambiguousPayloadStr: "", deterministicClusters, routeFamilies, parentToChildren };
698
+ }
699
+ const ambiguousIds = new Set(ambiguousClusters.map((c) => c.id));
700
+ const ambiguousPayload = {
701
+ meta: parsed.meta,
702
+ clusters: ambiguousClusters,
703
+ top_edges: (parsed.top_edges ?? []).filter((e) => ambiguousIds.has(e.from) && ambiguousIds.has(e.to)),
704
+ ...(parsed.runtime_edges
705
+ ? { runtime_edges: parsed.runtime_edges.filter((e) => ambiguousIds.has(e.from) || ambiguousIds.has(e.to)) }
706
+ : {}),
707
+ };
708
+ return {
709
+ ambiguousPayloadStr: JSON.stringify(ambiguousPayload),
710
+ deterministicClusters,
711
+ routeFamilies,
712
+ parentToChildren,
713
+ };
714
+ }
715
+ //# sourceMappingURL=buildLLMPayload.js.map