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.
- package/LICENSE +21 -0
- package/README.md +109 -0
- package/dist/IntentionalStructure/index.d.ts +13 -0
- package/dist/IntentionalStructure/index.d.ts.map +1 -0
- package/dist/IntentionalStructure/index.js +46 -0
- package/dist/IntentionalStructure/index.js.map +1 -0
- package/dist/IntentionalStructure/parseCompose.d.ts +13 -0
- package/dist/IntentionalStructure/parseCompose.d.ts.map +1 -0
- package/dist/IntentionalStructure/parseCompose.js +234 -0
- package/dist/IntentionalStructure/parseCompose.js.map +1 -0
- package/dist/IntentionalStructure/parseDeployConfigs.d.ts +7 -0
- package/dist/IntentionalStructure/parseDeployConfigs.d.ts.map +1 -0
- package/dist/IntentionalStructure/parseDeployConfigs.js +168 -0
- package/dist/IntentionalStructure/parseDeployConfigs.js.map +1 -0
- package/dist/IntentionalStructure/parseEnvWiring.d.ts +7 -0
- package/dist/IntentionalStructure/parseEnvWiring.d.ts.map +1 -0
- package/dist/IntentionalStructure/parseEnvWiring.js +159 -0
- package/dist/IntentionalStructure/parseEnvWiring.js.map +1 -0
- package/dist/IntentionalStructure/parseWorkspaces.d.ts +8 -0
- package/dist/IntentionalStructure/parseWorkspaces.d.ts.map +1 -0
- package/dist/IntentionalStructure/parseWorkspaces.js +179 -0
- package/dist/IntentionalStructure/parseWorkspaces.js.map +1 -0
- package/dist/IntentionalStructure/types.d.ts +34 -0
- package/dist/IntentionalStructure/types.d.ts.map +1 -0
- package/dist/IntentionalStructure/types.js +8 -0
- package/dist/IntentionalStructure/types.js.map +1 -0
- package/dist/RepoTypeDetection/applyRepoModeConsistency.d.ts +11 -0
- package/dist/RepoTypeDetection/applyRepoModeConsistency.d.ts.map +1 -0
- package/dist/RepoTypeDetection/applyRepoModeConsistency.js +53 -0
- package/dist/RepoTypeDetection/applyRepoModeConsistency.js.map +1 -0
- package/dist/RepoTypeDetection/detectAppArchetype.d.ts +12 -0
- package/dist/RepoTypeDetection/detectAppArchetype.d.ts.map +1 -0
- package/dist/RepoTypeDetection/detectAppArchetype.js +162 -0
- package/dist/RepoTypeDetection/detectAppArchetype.js.map +1 -0
- package/dist/RepoTypeDetection/detectPackageArchetype.d.ts +10 -0
- package/dist/RepoTypeDetection/detectPackageArchetype.d.ts.map +1 -0
- package/dist/RepoTypeDetection/detectPackageArchetype.js +149 -0
- package/dist/RepoTypeDetection/detectPackageArchetype.js.map +1 -0
- package/dist/RepoTypeDetection/detectRepoCenterSystems.d.ts +11 -0
- package/dist/RepoTypeDetection/detectRepoCenterSystems.d.ts.map +1 -0
- package/dist/RepoTypeDetection/detectRepoCenterSystems.js +123 -0
- package/dist/RepoTypeDetection/detectRepoCenterSystems.js.map +1 -0
- package/dist/RepoTypeDetection/detectRepoMode.d.ts +16 -0
- package/dist/RepoTypeDetection/detectRepoMode.d.ts.map +1 -0
- package/dist/RepoTypeDetection/detectRepoMode.js +338 -0
- package/dist/RepoTypeDetection/detectRepoMode.js.map +1 -0
- package/dist/RepoTypeDetection/detectRepoSignals.d.ts +13 -0
- package/dist/RepoTypeDetection/detectRepoSignals.d.ts.map +1 -0
- package/dist/RepoTypeDetection/detectRepoSignals.js +451 -0
- package/dist/RepoTypeDetection/detectRepoSignals.js.map +1 -0
- package/dist/RepoTypeDetection/inferSupportRole.d.ts +8 -0
- package/dist/RepoTypeDetection/inferSupportRole.d.ts.map +1 -0
- package/dist/RepoTypeDetection/inferSupportRole.js +177 -0
- package/dist/RepoTypeDetection/inferSupportRole.js.map +1 -0
- package/dist/RuntimeInference/detectEnvConsumers.d.ts +7 -0
- package/dist/RuntimeInference/detectEnvConsumers.d.ts.map +1 -0
- package/dist/RuntimeInference/detectEnvConsumers.js +108 -0
- package/dist/RuntimeInference/detectEnvConsumers.js.map +1 -0
- package/dist/RuntimeInference/detectHttpEdges.d.ts +4 -0
- package/dist/RuntimeInference/detectHttpEdges.d.ts.map +1 -0
- package/dist/RuntimeInference/detectHttpEdges.js +146 -0
- package/dist/RuntimeInference/detectHttpEdges.js.map +1 -0
- package/dist/RuntimeInference/detectOrmConsumers.d.ts +5 -0
- package/dist/RuntimeInference/detectOrmConsumers.d.ts.map +1 -0
- package/dist/RuntimeInference/detectOrmConsumers.js +117 -0
- package/dist/RuntimeInference/detectOrmConsumers.js.map +1 -0
- package/dist/RuntimeInference/detectProxyRewrites.d.ts +5 -0
- package/dist/RuntimeInference/detectProxyRewrites.d.ts.map +1 -0
- package/dist/RuntimeInference/detectProxyRewrites.js +137 -0
- package/dist/RuntimeInference/detectProxyRewrites.js.map +1 -0
- package/dist/RuntimeInference/detectTrpcEdges.d.ts +4 -0
- package/dist/RuntimeInference/detectTrpcEdges.d.ts.map +1 -0
- package/dist/RuntimeInference/detectTrpcEdges.js +137 -0
- package/dist/RuntimeInference/detectTrpcEdges.js.map +1 -0
- package/dist/RuntimeInference/index.d.ts +17 -0
- package/dist/RuntimeInference/index.d.ts.map +1 -0
- package/dist/RuntimeInference/index.js +32 -0
- package/dist/RuntimeInference/index.js.map +1 -0
- package/dist/RuntimeInference/types.d.ts +8 -0
- package/dist/RuntimeInference/types.d.ts.map +1 -0
- package/dist/RuntimeInference/types.js +3 -0
- package/dist/RuntimeInference/types.js.map +1 -0
- package/dist/SystemSynthesis/index.d.ts +27 -0
- package/dist/SystemSynthesis/index.d.ts.map +1 -0
- package/dist/SystemSynthesis/index.js +31 -0
- package/dist/SystemSynthesis/index.js.map +1 -0
- package/dist/SystemSynthesis/mergeLayerOutputs.d.ts +13 -0
- package/dist/SystemSynthesis/mergeLayerOutputs.d.ts.map +1 -0
- package/dist/SystemSynthesis/mergeLayerOutputs.js +220 -0
- package/dist/SystemSynthesis/mergeLayerOutputs.js.map +1 -0
- package/dist/SystemSynthesis/stampDeterministic.d.ts +11 -0
- package/dist/SystemSynthesis/stampDeterministic.d.ts.map +1 -0
- package/dist/SystemSynthesis/stampDeterministic.js +177 -0
- package/dist/SystemSynthesis/stampDeterministic.js.map +1 -0
- package/dist/SystemSynthesis/synthesize.d.ts +15 -0
- package/dist/SystemSynthesis/synthesize.d.ts.map +1 -0
- package/dist/SystemSynthesis/synthesize.js +258 -0
- package/dist/SystemSynthesis/synthesize.js.map +1 -0
- package/dist/SystemSynthesis/types.d.ts +110 -0
- package/dist/SystemSynthesis/types.d.ts.map +1 -0
- package/dist/SystemSynthesis/types.js +12 -0
- package/dist/SystemSynthesis/types.js.map +1 -0
- package/dist/amGeneration/buildFlowGraph.d.ts +39 -0
- package/dist/amGeneration/buildFlowGraph.d.ts.map +1 -0
- package/dist/amGeneration/buildFlowGraph.js +643 -0
- package/dist/amGeneration/buildFlowGraph.js.map +1 -0
- package/dist/amGeneration/enrichAMEdges.d.ts +16 -0
- package/dist/amGeneration/enrichAMEdges.d.ts.map +1 -0
- package/dist/amGeneration/enrichAMEdges.js +291 -0
- package/dist/amGeneration/enrichAMEdges.js.map +1 -0
- package/dist/amGeneration/generateAM.d.ts +23 -0
- package/dist/amGeneration/generateAM.d.ts.map +1 -0
- package/dist/amGeneration/generateAM.js +131 -0
- package/dist/amGeneration/generateAM.js.map +1 -0
- package/dist/amGeneration/generateAMForRepo.d.ts +6 -0
- package/dist/amGeneration/generateAMForRepo.d.ts.map +1 -0
- package/dist/amGeneration/generateAMForRepo.js +130 -0
- package/dist/amGeneration/generateAMForRepo.js.map +1 -0
- package/dist/amGeneration/generateFlows.d.ts +27 -0
- package/dist/amGeneration/generateFlows.d.ts.map +1 -0
- package/dist/amGeneration/generateFlows.js +320 -0
- package/dist/amGeneration/generateFlows.js.map +1 -0
- package/dist/amGeneration/promptBuilder.d.ts +24 -0
- package/dist/amGeneration/promptBuilder.d.ts.map +1 -0
- package/dist/amGeneration/promptBuilder.js +299 -0
- package/dist/amGeneration/promptBuilder.js.map +1 -0
- package/dist/amGeneration/selectStrategicFiles.d.ts +42 -0
- package/dist/amGeneration/selectStrategicFiles.d.ts.map +1 -0
- package/dist/amGeneration/selectStrategicFiles.js +672 -0
- package/dist/amGeneration/selectStrategicFiles.js.map +1 -0
- package/dist/amGeneration/types.d.ts +83 -0
- package/dist/amGeneration/types.d.ts.map +1 -0
- package/dist/amGeneration/types.js +9 -0
- package/dist/amGeneration/types.js.map +1 -0
- package/dist/amSections.d.ts +29 -0
- package/dist/amSections.d.ts.map +1 -0
- package/dist/amSections.js +424 -0
- package/dist/amSections.js.map +1 -0
- package/dist/analysis/analysisCache.d.ts +4 -0
- package/dist/analysis/analysisCache.d.ts.map +1 -0
- package/dist/analysis/analysisCache.js +92 -0
- package/dist/analysis/analysisCache.js.map +1 -0
- package/dist/analysis/buildBranchStory.d.ts +95 -0
- package/dist/analysis/buildBranchStory.d.ts.map +1 -0
- package/dist/analysis/buildBranchStory.js +1264 -0
- package/dist/analysis/buildBranchStory.js.map +1 -0
- package/dist/analysis/buildDetailedFileXRay.d.ts +49 -0
- package/dist/analysis/buildDetailedFileXRay.d.ts.map +1 -0
- package/dist/analysis/buildDetailedFileXRay.js +607 -0
- package/dist/analysis/buildDetailedFileXRay.js.map +1 -0
- package/dist/analysis/buildFileXRay.d.ts +35 -0
- package/dist/analysis/buildFileXRay.d.ts.map +1 -0
- package/dist/analysis/buildFileXRay.js +305 -0
- package/dist/analysis/buildFileXRay.js.map +1 -0
- package/dist/analysis/classifySilentKiller.d.ts +14 -0
- package/dist/analysis/classifySilentKiller.d.ts.map +1 -0
- package/dist/analysis/classifySilentKiller.js +235 -0
- package/dist/analysis/classifySilentKiller.js.map +1 -0
- package/dist/analysis/diffChunks.d.ts +21 -0
- package/dist/analysis/diffChunks.d.ts.map +1 -0
- package/dist/analysis/diffChunks.js +302 -0
- package/dist/analysis/diffChunks.js.map +1 -0
- package/dist/analysis/extractRouteMap.d.ts +49 -0
- package/dist/analysis/extractRouteMap.d.ts.map +1 -0
- package/dist/analysis/extractRouteMap.js +354 -0
- package/dist/analysis/extractRouteMap.js.map +1 -0
- package/dist/analysis/generateFileInsight.d.ts +19 -0
- package/dist/analysis/generateFileInsight.d.ts.map +1 -0
- package/dist/analysis/generateFileInsight.js +103 -0
- package/dist/analysis/generateFileInsight.js.map +1 -0
- package/dist/analysis/llmXRay.d.ts +39 -0
- package/dist/analysis/llmXRay.d.ts.map +1 -0
- package/dist/analysis/llmXRay.js +208 -0
- package/dist/analysis/llmXRay.js.map +1 -0
- package/dist/analysis/simulateFailure.d.ts +44 -0
- package/dist/analysis/simulateFailure.d.ts.map +1 -0
- package/dist/analysis/simulateFailure.js +407 -0
- package/dist/analysis/simulateFailure.js.map +1 -0
- package/dist/anthropic.d.ts +3 -0
- package/dist/anthropic.d.ts.map +1 -0
- package/dist/anthropic.js +16 -0
- package/dist/anthropic.js.map +1 -0
- package/dist/app/buildAppPage.d.ts +34 -0
- package/dist/app/buildAppPage.d.ts.map +1 -0
- package/dist/app/buildAppPage.js +3085 -0
- package/dist/app/buildAppPage.js.map +1 -0
- package/dist/app-bundle.js +122 -0
- package/dist/buildAppData.d.ts +3 -0
- package/dist/buildAppData.d.ts.map +1 -0
- package/dist/buildAppData.js +207 -0
- package/dist/buildAppData.js.map +1 -0
- package/dist/builders/analyzeRepo.d.ts +25 -0
- package/dist/builders/analyzeRepo.d.ts.map +1 -0
- package/dist/builders/analyzeRepo.js +873 -0
- package/dist/builders/analyzeRepo.js.map +1 -0
- package/dist/builders/buildSystemConnections.d.ts +3 -0
- package/dist/builders/buildSystemConnections.d.ts.map +1 -0
- package/dist/builders/buildSystemConnections.js +388 -0
- package/dist/builders/buildSystemConnections.js.map +1 -0
- package/dist/builders/buildTextSummary.d.ts +61 -0
- package/dist/builders/buildTextSummary.d.ts.map +1 -0
- package/dist/builders/buildTextSummary.js +178 -0
- package/dist/builders/buildTextSummary.js.map +1 -0
- package/dist/builders/deriveRecommendedStartPath.d.ts +11 -0
- package/dist/builders/deriveRecommendedStartPath.d.ts.map +1 -0
- package/dist/builders/deriveRecommendedStartPath.js +140 -0
- package/dist/builders/deriveRecommendedStartPath.js.map +1 -0
- package/dist/builders/deriveRuntimeRole.d.ts +4 -0
- package/dist/builders/deriveRuntimeRole.d.ts.map +1 -0
- package/dist/builders/deriveRuntimeRole.js +30 -0
- package/dist/builders/deriveRuntimeRole.js.map +1 -0
- package/dist/builders/detectRunCommands.d.ts +16 -0
- package/dist/builders/detectRunCommands.d.ts.map +1 -0
- package/dist/builders/detectRunCommands.js +285 -0
- package/dist/builders/detectRunCommands.js.map +1 -0
- package/dist/builders/generateSystemNarrative.d.ts +12 -0
- package/dist/builders/generateSystemNarrative.d.ts.map +1 -0
- package/dist/builders/generateSystemNarrative.js +474 -0
- package/dist/builders/generateSystemNarrative.js.map +1 -0
- package/dist/builders/gitLogParser.d.ts +15 -0
- package/dist/builders/gitLogParser.d.ts.map +1 -0
- package/dist/builders/gitLogParser.js +116 -0
- package/dist/builders/gitLogParser.js.map +1 -0
- package/dist/builders/readRepoContext.d.ts +30 -0
- package/dist/builders/readRepoContext.d.ts.map +1 -0
- package/dist/builders/readRepoContext.js +323 -0
- package/dist/builders/readRepoContext.js.map +1 -0
- package/dist/builders/readSystemReadme.d.ts +39 -0
- package/dist/builders/readSystemReadme.d.ts.map +1 -0
- package/dist/builders/readSystemReadme.js +133 -0
- package/dist/builders/readSystemReadme.js.map +1 -0
- package/dist/builders/systemRanking.d.ts +24 -0
- package/dist/builders/systemRanking.d.ts.map +1 -0
- package/dist/builders/systemRanking.js +153 -0
- package/dist/builders/systemRanking.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +170 -0
- package/dist/cli.js.map +1 -0
- package/dist/detectors/applyRunnableConfidenceGate.d.ts +8 -0
- package/dist/detectors/applyRunnableConfidenceGate.d.ts.map +1 -0
- package/dist/detectors/applyRunnableConfidenceGate.js +166 -0
- package/dist/detectors/applyRunnableConfidenceGate.js.map +1 -0
- package/dist/detectors/classifySystemType.d.ts +17 -0
- package/dist/detectors/classifySystemType.d.ts.map +1 -0
- package/dist/detectors/classifySystemType.js +460 -0
- package/dist/detectors/classifySystemType.js.map +1 -0
- package/dist/detectors/detectAppInternalUnits.d.ts +20 -0
- package/dist/detectors/detectAppInternalUnits.d.ts.map +1 -0
- package/dist/detectors/detectAppInternalUnits.js +454 -0
- package/dist/detectors/detectAppInternalUnits.js.map +1 -0
- package/dist/detectors/detectBlocks.d.ts +6 -0
- package/dist/detectors/detectBlocks.d.ts.map +1 -0
- package/dist/detectors/detectBlocks.js +354 -0
- package/dist/detectors/detectBlocks.js.map +1 -0
- package/dist/detectors/detectComposeServices.d.ts +23 -0
- package/dist/detectors/detectComposeServices.d.ts.map +1 -0
- package/dist/detectors/detectComposeServices.js +255 -0
- package/dist/detectors/detectComposeServices.js.map +1 -0
- package/dist/detectors/detectEntryPoints.d.ts +6 -0
- package/dist/detectors/detectEntryPoints.d.ts.map +1 -0
- package/dist/detectors/detectEntryPoints.js +376 -0
- package/dist/detectors/detectEntryPoints.js.map +1 -0
- package/dist/detectors/detectSubsystems.d.ts +6 -0
- package/dist/detectors/detectSubsystems.d.ts.map +1 -0
- package/dist/detectors/detectSubsystems.js +376 -0
- package/dist/detectors/detectSubsystems.js.map +1 -0
- package/dist/detectors/detectSystemCandidates.d.ts +3 -0
- package/dist/detectors/detectSystemCandidates.d.ts.map +1 -0
- package/dist/detectors/detectSystemCandidates.js +577 -0
- package/dist/detectors/detectSystemCandidates.js.map +1 -0
- package/dist/devWatcher.d.ts +14 -0
- package/dist/devWatcher.d.ts.map +1 -0
- package/dist/devWatcher.js +96 -0
- package/dist/devWatcher.js.map +1 -0
- package/dist/graph/buildCodebaseGraph.d.ts +3 -0
- package/dist/graph/buildCodebaseGraph.d.ts.map +1 -0
- package/dist/graph/buildCodebaseGraph.js +602 -0
- package/dist/graph/buildCodebaseGraph.js.map +1 -0
- package/dist/graph/buildLLMPayload.d.ts +89 -0
- package/dist/graph/buildLLMPayload.d.ts.map +1 -0
- package/dist/graph/buildLLMPayload.js +715 -0
- package/dist/graph/buildLLMPayload.js.map +1 -0
- package/dist/graph/callLLM.d.ts +16 -0
- package/dist/graph/callLLM.d.ts.map +1 -0
- package/dist/graph/callLLM.js +274 -0
- package/dist/graph/callLLM.js.map +1 -0
- package/dist/graph/types.d.ts +76 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +5 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/graph/walkExports.d.ts +2 -0
- package/dist/graph/walkExports.d.ts.map +1 -0
- package/dist/graph/walkExports.js +172 -0
- package/dist/graph/walkExports.js.map +1 -0
- package/dist/heuristics/file-patterns.json +325 -0
- package/dist/heuristics/known-packages.json +1022 -0
- package/dist/heuristics/loader.d.ts +121 -0
- package/dist/heuristics/loader.d.ts.map +1 -0
- package/dist/heuristics/loader.js +196 -0
- package/dist/heuristics/loader.js.map +1 -0
- package/dist/heuristics/repo-mode-signals.json +248 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +3 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +356 -0
- package/dist/mcp.js.map +1 -0
- package/dist/scanner/buildImportGraph.d.ts +23 -0
- package/dist/scanner/buildImportGraph.d.ts.map +1 -0
- package/dist/scanner/buildImportGraph.js +186 -0
- package/dist/scanner/buildImportGraph.js.map +1 -0
- package/dist/scanner/detectDBOps.d.ts +21 -0
- package/dist/scanner/detectDBOps.d.ts.map +1 -0
- package/dist/scanner/detectDBOps.js +346 -0
- package/dist/scanner/detectDBOps.js.map +1 -0
- package/dist/scanner/detectOutbound.d.ts +6 -0
- package/dist/scanner/detectOutbound.d.ts.map +1 -0
- package/dist/scanner/detectOutbound.js +101 -0
- package/dist/scanner/detectOutbound.js.map +1 -0
- package/dist/scanner/detectRepoPurpose.d.ts +19 -0
- package/dist/scanner/detectRepoPurpose.d.ts.map +1 -0
- package/dist/scanner/detectRepoPurpose.js +335 -0
- package/dist/scanner/detectRepoPurpose.js.map +1 -0
- package/dist/scanner/detectRoutes.d.ts +22 -0
- package/dist/scanner/detectRoutes.d.ts.map +1 -0
- package/dist/scanner/detectRoutes.js +406 -0
- package/dist/scanner/detectRoutes.js.map +1 -0
- package/dist/scanner/filterNoise.d.ts +4 -0
- package/dist/scanner/filterNoise.d.ts.map +1 -0
- package/dist/scanner/filterNoise.js +95 -0
- package/dist/scanner/filterNoise.js.map +1 -0
- package/dist/scanner/loadTsAliases.d.ts +20 -0
- package/dist/scanner/loadTsAliases.d.ts.map +1 -0
- package/dist/scanner/loadTsAliases.js +135 -0
- package/dist/scanner/loadTsAliases.js.map +1 -0
- package/dist/scanner/routeHandlers.d.ts +15 -0
- package/dist/scanner/routeHandlers.d.ts.map +1 -0
- package/dist/scanner/routeHandlers.js +154 -0
- package/dist/scanner/routeHandlers.js.map +1 -0
- package/dist/scanner/scanRepo.d.ts +10 -0
- package/dist/scanner/scanRepo.d.ts.map +1 -0
- package/dist/scanner/scanRepo.js +165 -0
- package/dist/scanner/scanRepo.js.map +1 -0
- package/dist/scanner/walkImports.d.ts +14 -0
- package/dist/scanner/walkImports.d.ts.map +1 -0
- package/dist/scanner/walkImports.js +162 -0
- package/dist/scanner/walkImports.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +956 -0
- package/dist/server.js.map +1 -0
- package/dist/session/diff.d.ts +4 -0
- package/dist/session/diff.d.ts.map +1 -0
- package/dist/session/diff.js +150 -0
- package/dist/session/diff.js.map +1 -0
- package/dist/session/snapshot.d.ts +5 -0
- package/dist/session/snapshot.d.ts.map +1 -0
- package/dist/session/snapshot.js +114 -0
- package/dist/session/snapshot.js.map +1 -0
- package/dist/session/store.d.ts +8 -0
- package/dist/session/store.d.ts.map +1 -0
- package/dist/session/store.js +101 -0
- package/dist/session/store.js.map +1 -0
- package/dist/session/types.d.ts +46 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +4 -0
- package/dist/session/types.js.map +1 -0
- package/dist/types.d.ts +350 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/file.d.ts +5 -0
- package/dist/utils/file.d.ts.map +1 -0
- package/dist/utils/file.js +76 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/path.d.ts +7 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +62 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/text.d.ts +5 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +29 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/viewBuilders/buildSystemFolders.d.ts +39 -0
- package/dist/viewBuilders/buildSystemFolders.d.ts.map +1 -0
- package/dist/viewBuilders/buildSystemFolders.js +198 -0
- package/dist/viewBuilders/buildSystemFolders.js.map +1 -0
- package/dist/watcher/repoWatcher.d.ts +17 -0
- package/dist/watcher/repoWatcher.d.ts.map +1 -0
- package/dist/watcher/repoWatcher.js +87 -0
- package/dist/watcher/repoWatcher.js.map +1 -0
- package/package.json +102 -0
- package/public/memor_logo.svg +18 -0
- package/public/memor_transparent_logo.svg +25 -0
- package/public/tIcons/bun.svg +1 -0
- package/public/tIcons/css.svg +1 -0
- package/public/tIcons/docker.svg +3 -0
- package/public/tIcons/expressjs.svg +1 -0
- package/public/tIcons/html5.svg +6 -0
- package/public/tIcons/javascript.svg +1 -0
- package/public/tIcons/jest.svg +4 -0
- package/public/tIcons/json.svg +1 -0
- package/public/tIcons/markdown-light.svg +1 -0
- package/public/tIcons/nestjs.svg +1 -0
- package/public/tIcons/nextjs_icon_dark.svg +1 -0
- package/public/tIcons/npm.svg +1 -0
- package/public/tIcons/pnpm.svg +1 -0
- package/public/tIcons/prisma.svg +1 -0
- package/public/tIcons/react_dark.svg +11 -0
- package/public/tIcons/supabase.svg +15 -0
- package/public/tIcons/tailwindcss.svg +1 -0
- package/public/tIcons/turborepo-icon-light.svg +1 -0
- package/public/tIcons/typescript.svg +1 -0
- package/public/tIcons/vite.svg +1 -0
- package/public/tIcons/yarn.svg +1 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buildFlowGraph — 4-layer deterministic flow discovery pipeline.
|
|
3
|
+
*
|
|
4
|
+
* L1: Multi-framework entry point discovery (Next.js, NestJS, Express)
|
|
5
|
+
* L2: Cross-file call chain tracing — follows imports 4 hops deep
|
|
6
|
+
* L3: Step enrichment — maps files to AM systems, detects DB/external calls
|
|
7
|
+
* L4: Flow clustering — group by domain, deduplicate, rank by richness
|
|
8
|
+
*
|
|
9
|
+
* Zero LLM calls. Output feeds generateFlows for narration only.
|
|
10
|
+
*/
|
|
11
|
+
export type FlowStep = {
|
|
12
|
+
fn: string;
|
|
13
|
+
file: string;
|
|
14
|
+
systemId: string | null;
|
|
15
|
+
externalCalls: string[];
|
|
16
|
+
dbAccess: string[];
|
|
17
|
+
returnType: string;
|
|
18
|
+
isExternal: boolean;
|
|
19
|
+
};
|
|
20
|
+
export type FlowCandidate = {
|
|
21
|
+
id: string;
|
|
22
|
+
nameSeed: string;
|
|
23
|
+
method: string;
|
|
24
|
+
routePath: string;
|
|
25
|
+
entryFile: string;
|
|
26
|
+
steps: FlowStep[];
|
|
27
|
+
framework: "nextjs" | "nestjs" | "express" | "generic";
|
|
28
|
+
};
|
|
29
|
+
type EntryPoint = {
|
|
30
|
+
method: string;
|
|
31
|
+
routePath: string;
|
|
32
|
+
handlerFn: string;
|
|
33
|
+
absFile: string;
|
|
34
|
+
framework: FlowCandidate["framework"];
|
|
35
|
+
};
|
|
36
|
+
export declare function discoverEntryPoints(repoRoot: string): EntryPoint[];
|
|
37
|
+
export declare function buildFlowGraph(repoRoot: string, am: any, onProgress?: (step: string) => void): Promise<FlowCandidate[]>;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=buildFlowGraph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildFlowGraph.d.ts","sourceRoot":"","sources":["../../src/amGeneration/buildFlowGraph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;CACxD,CAAC;AAIF,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;CACvC,CAAC;AAsTF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE,CAclE;AA2ND,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,GAAG,EACP,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAClC,OAAO,CAAC,aAAa,EAAE,CAAC,CA2C1B"}
|
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* buildFlowGraph — 4-layer deterministic flow discovery pipeline.
|
|
4
|
+
*
|
|
5
|
+
* L1: Multi-framework entry point discovery (Next.js, NestJS, Express)
|
|
6
|
+
* L2: Cross-file call chain tracing — follows imports 4 hops deep
|
|
7
|
+
* L3: Step enrichment — maps files to AM systems, detects DB/external calls
|
|
8
|
+
* L4: Flow clustering — group by domain, deduplicate, rank by richness
|
|
9
|
+
*
|
|
10
|
+
* Zero LLM calls. Output feeds generateFlows for narration only.
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
46
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
|
+
};
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.discoverEntryPoints = discoverEntryPoints;
|
|
50
|
+
exports.buildFlowGraph = buildFlowGraph;
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const babelParser = __importStar(require("@babel/parser"));
|
|
54
|
+
const traverse_1 = __importDefault(require("@babel/traverse"));
|
|
55
|
+
const buildDetailedFileXRay_1 = require("../analysis/buildDetailedFileXRay");
|
|
56
|
+
// ── Shared helpers ────────────────────────────────────────────────────────────
|
|
57
|
+
const HTTP_METHODS = new Set(["GET", "POST", "PUT", "PATCH", "DELETE"]);
|
|
58
|
+
function walkDir(dir, pattern) {
|
|
59
|
+
const out = [];
|
|
60
|
+
if (!fs.existsSync(dir))
|
|
61
|
+
return out;
|
|
62
|
+
function walk(cur) {
|
|
63
|
+
let entries;
|
|
64
|
+
try {
|
|
65
|
+
entries = fs.readdirSync(cur, { withFileTypes: true });
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
for (const e of entries) {
|
|
71
|
+
if (e.name.startsWith(".") || e.name === "node_modules" || e.name === "dist")
|
|
72
|
+
continue;
|
|
73
|
+
const full = path.join(cur, e.name);
|
|
74
|
+
if (e.isDirectory())
|
|
75
|
+
walk(full);
|
|
76
|
+
else if (pattern.test(e.name))
|
|
77
|
+
out.push(full);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
walk(dir);
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
function resolveImport(source, fromAbs) {
|
|
84
|
+
// Skip npm packages
|
|
85
|
+
if (!source.startsWith(".") && !source.startsWith("/"))
|
|
86
|
+
return null;
|
|
87
|
+
const fromDir = path.dirname(fromAbs);
|
|
88
|
+
for (const suffix of ["", ".ts", ".tsx", "/index.ts", "/index.tsx", ".js", "/index.js"]) {
|
|
89
|
+
const abs = path.resolve(fromDir, source + suffix);
|
|
90
|
+
if (fs.existsSync(abs))
|
|
91
|
+
return abs;
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
function parseBabel(src) {
|
|
96
|
+
try {
|
|
97
|
+
return babelParser.parse(src, {
|
|
98
|
+
sourceType: "module",
|
|
99
|
+
plugins: ["typescript", "jsx", "decorators-legacy", "classProperties", "optionalChaining"],
|
|
100
|
+
errorRecovery: true,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function getDecoratorName(d) {
|
|
108
|
+
const e = d?.expression;
|
|
109
|
+
if (e?.type === "Identifier")
|
|
110
|
+
return e.name;
|
|
111
|
+
if (e?.type === "CallExpression") {
|
|
112
|
+
const c = e.callee;
|
|
113
|
+
if (c?.type === "Identifier")
|
|
114
|
+
return c.name;
|
|
115
|
+
if (c?.type === "MemberExpression")
|
|
116
|
+
return c.property?.name ?? "";
|
|
117
|
+
}
|
|
118
|
+
return "";
|
|
119
|
+
}
|
|
120
|
+
function getDecoratorArg(d) {
|
|
121
|
+
const args = d?.expression?.arguments;
|
|
122
|
+
if (!args?.length)
|
|
123
|
+
return "";
|
|
124
|
+
const a = args[0];
|
|
125
|
+
if (a?.type === "StringLiteral")
|
|
126
|
+
return a.value;
|
|
127
|
+
return "";
|
|
128
|
+
}
|
|
129
|
+
// ── L1: Entry point discovery ─────────────────────────────────────────────────
|
|
130
|
+
function discoverNextJS(repoRoot) {
|
|
131
|
+
const entries = [];
|
|
132
|
+
const files = [
|
|
133
|
+
...walkDir(repoRoot, /^route\.(ts|tsx|js|jsx)$/),
|
|
134
|
+
...walkDir(path.join(repoRoot, "pages", "api"), /\.(ts|tsx|js|jsx)$/),
|
|
135
|
+
].filter(f => !f.includes("node_modules"));
|
|
136
|
+
for (const absFile of files) {
|
|
137
|
+
let xray;
|
|
138
|
+
try {
|
|
139
|
+
xray = (0, buildDetailedFileXRay_1.buildDetailedFileXRay)(absFile, repoRoot);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const handlers = xray.functions.filter(f => HTTP_METHODS.has(f.name));
|
|
145
|
+
if (!handlers.length)
|
|
146
|
+
continue;
|
|
147
|
+
const rel = path.relative(repoRoot, absFile).replace(/\\/g, "/");
|
|
148
|
+
const routePath = ("/" + rel
|
|
149
|
+
.replace(/\.(ts|tsx|js|jsx)$/, "")
|
|
150
|
+
.replace(/\/route$/, "")
|
|
151
|
+
.replace(/^(app|pages)\//, "")
|
|
152
|
+
.replace(/\/\([^)]+\)/g, "")
|
|
153
|
+
.replace(/\/+/g, "/")).replace(/\/$/, "") || "/";
|
|
154
|
+
for (const h of handlers) {
|
|
155
|
+
entries.push({ method: h.name, routePath, handlerFn: h.name, absFile, framework: "nextjs" });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return entries;
|
|
159
|
+
}
|
|
160
|
+
function discoverNestJS(repoRoot) {
|
|
161
|
+
const entries = [];
|
|
162
|
+
const tsFiles = walkDir(repoRoot, /\.(ts|tsx)$/).filter(f => !f.includes("node_modules") && !f.includes(".spec.") && !f.includes(".test."));
|
|
163
|
+
for (const absFile of tsFiles) {
|
|
164
|
+
let src;
|
|
165
|
+
try {
|
|
166
|
+
src = fs.readFileSync(absFile, "utf-8");
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (!src.includes("@Controller"))
|
|
172
|
+
continue;
|
|
173
|
+
const ast = parseBabel(src);
|
|
174
|
+
if (!ast)
|
|
175
|
+
continue;
|
|
176
|
+
try {
|
|
177
|
+
(0, traverse_1.default)(ast, {
|
|
178
|
+
ClassDeclaration(np) {
|
|
179
|
+
const cls = np.node;
|
|
180
|
+
const ctrlDec = (cls.decorators ?? []).find((d) => getDecoratorName(d) === "Controller");
|
|
181
|
+
if (!ctrlDec)
|
|
182
|
+
return;
|
|
183
|
+
const base = ("/" + getDecoratorArg(ctrlDec).replace(/^\//, "")).replace(/\/$/, "") || "/";
|
|
184
|
+
for (const member of cls.body?.body ?? []) {
|
|
185
|
+
const methodName = member.key?.name;
|
|
186
|
+
if (!methodName)
|
|
187
|
+
continue;
|
|
188
|
+
for (const dec of member.decorators ?? []) {
|
|
189
|
+
const verb = getDecoratorName(dec).toUpperCase();
|
|
190
|
+
if (!HTTP_METHODS.has(verb))
|
|
191
|
+
continue;
|
|
192
|
+
const sub = getDecoratorArg(dec).replace(/^\//, "");
|
|
193
|
+
const routePath = (base + (sub ? "/" + sub : "")).replace(/\/+/g, "/") || "/";
|
|
194
|
+
entries.push({ method: verb, routePath, handlerFn: methodName, absFile, framework: "nestjs" });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
catch { /* best-effort */ }
|
|
201
|
+
}
|
|
202
|
+
return entries;
|
|
203
|
+
}
|
|
204
|
+
// Build cross-file mount map: absFilePath → mount prefix
|
|
205
|
+
// Scans all files for app.use('/prefix', require('./routes/X')) and import-based patterns
|
|
206
|
+
function buildMountMap(repoRoot, files) {
|
|
207
|
+
const mountMap = new Map();
|
|
208
|
+
for (const absFile of files) {
|
|
209
|
+
let src;
|
|
210
|
+
try {
|
|
211
|
+
src = fs.readFileSync(absFile, "utf-8");
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if (!src.includes(".use("))
|
|
217
|
+
continue;
|
|
218
|
+
const ast = parseBabel(src);
|
|
219
|
+
if (!ast)
|
|
220
|
+
continue;
|
|
221
|
+
// Collect varName → resolved abs path from imports and requires
|
|
222
|
+
const importedVars = new Map();
|
|
223
|
+
try {
|
|
224
|
+
(0, traverse_1.default)(ast, {
|
|
225
|
+
ImportDeclaration(np) {
|
|
226
|
+
const resolved = resolveImport(np.node.source?.value ?? "", absFile);
|
|
227
|
+
if (!resolved)
|
|
228
|
+
return;
|
|
229
|
+
for (const spec of np.node.specifiers ?? []) {
|
|
230
|
+
if (spec.local?.name)
|
|
231
|
+
importedVars.set(spec.local.name, resolved);
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
VariableDeclarator(np) {
|
|
235
|
+
const init = np.node.init;
|
|
236
|
+
const name = np.node.id?.name;
|
|
237
|
+
if (!name)
|
|
238
|
+
return;
|
|
239
|
+
// const X = require('./path') or require('./path').default or .router
|
|
240
|
+
let srcStr = null;
|
|
241
|
+
if (init?.type === "CallExpression" && init.callee?.name === "require") {
|
|
242
|
+
srcStr = init.arguments?.[0]?.value;
|
|
243
|
+
}
|
|
244
|
+
else if (init?.type === "MemberExpression" && init.object?.type === "CallExpression"
|
|
245
|
+
&& init.object.callee?.name === "require") {
|
|
246
|
+
srcStr = init.object.arguments?.[0]?.value;
|
|
247
|
+
}
|
|
248
|
+
if (srcStr) {
|
|
249
|
+
const resolved = resolveImport(srcStr, absFile);
|
|
250
|
+
if (resolved)
|
|
251
|
+
importedVars.set(name, resolved);
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
catch { }
|
|
257
|
+
// Find app.use('/prefix', importedVar) calls
|
|
258
|
+
try {
|
|
259
|
+
(0, traverse_1.default)(ast, {
|
|
260
|
+
CallExpression(np) {
|
|
261
|
+
const callee = np.node.callee;
|
|
262
|
+
if (callee?.type !== "MemberExpression")
|
|
263
|
+
return;
|
|
264
|
+
if (callee.property?.name !== "use")
|
|
265
|
+
return;
|
|
266
|
+
const args = np.node.arguments ?? [];
|
|
267
|
+
if (args.length < 2 || args[0]?.type !== "StringLiteral")
|
|
268
|
+
return;
|
|
269
|
+
const prefix = args[0].value;
|
|
270
|
+
const routerArg = args[1];
|
|
271
|
+
// Identifier: app.use('/prefix', routerVar)
|
|
272
|
+
if (routerArg?.type === "Identifier") {
|
|
273
|
+
const resolved = importedVars.get(routerArg.name);
|
|
274
|
+
if (resolved && !mountMap.has(resolved))
|
|
275
|
+
mountMap.set(resolved, prefix);
|
|
276
|
+
}
|
|
277
|
+
// Inline require: app.use('/prefix', require('./X'))
|
|
278
|
+
if (routerArg?.type === "CallExpression" && routerArg.callee?.name === "require") {
|
|
279
|
+
const srcStr = routerArg.arguments?.[0]?.value;
|
|
280
|
+
if (srcStr) {
|
|
281
|
+
const resolved = resolveImport(srcStr, absFile);
|
|
282
|
+
if (resolved && !mountMap.has(resolved))
|
|
283
|
+
mountMap.set(resolved, prefix);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
catch { }
|
|
290
|
+
}
|
|
291
|
+
return mountMap;
|
|
292
|
+
}
|
|
293
|
+
function discoverExpress(repoRoot) {
|
|
294
|
+
const entries = [];
|
|
295
|
+
const files = walkDir(repoRoot, /\.(ts|tsx|js|jsx)$/).filter(f => !f.includes("node_modules"));
|
|
296
|
+
// Build cross-file mount map first (one pass over all files)
|
|
297
|
+
const mountMap = buildMountMap(repoRoot, files);
|
|
298
|
+
for (const absFile of files) {
|
|
299
|
+
let src;
|
|
300
|
+
try {
|
|
301
|
+
src = fs.readFileSync(absFile, "utf-8");
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
if (!/\.(get|post|put|patch|delete)\s*\(/.test(src))
|
|
307
|
+
continue;
|
|
308
|
+
const ast = parseBabel(src);
|
|
309
|
+
if (!ast)
|
|
310
|
+
continue;
|
|
311
|
+
// Pass 1: discover all router variable names in this file (dynamic — not hardcoded)
|
|
312
|
+
const routerVars = new Set(["router", "app", "Router", "api"]);
|
|
313
|
+
try {
|
|
314
|
+
(0, traverse_1.default)(ast, {
|
|
315
|
+
VariableDeclarator(np) {
|
|
316
|
+
const init = np.node.init;
|
|
317
|
+
const name = np.node.id?.name;
|
|
318
|
+
if (!name || !init)
|
|
319
|
+
return;
|
|
320
|
+
const isRouter = (init.type === "CallExpression" && (init.callee?.name === "Router" ||
|
|
321
|
+
(init.callee?.type === "MemberExpression" &&
|
|
322
|
+
(init.callee.property?.name === "Router" ||
|
|
323
|
+
(init.callee.object?.name === "express" && init.callee.property?.name === "Router") ||
|
|
324
|
+
init.callee.object?.name === "express"))));
|
|
325
|
+
if (isRouter)
|
|
326
|
+
routerVars.add(name);
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
catch { }
|
|
331
|
+
// Pass 2: within-file mount map — app.use('/prefix', subRouter) in same file
|
|
332
|
+
// Maps subRouter variable name → prefix applied to it
|
|
333
|
+
const withinFileMount = new Map();
|
|
334
|
+
try {
|
|
335
|
+
(0, traverse_1.default)(ast, {
|
|
336
|
+
CallExpression(np) {
|
|
337
|
+
const callee = np.node.callee;
|
|
338
|
+
if (callee?.type !== "MemberExpression")
|
|
339
|
+
return;
|
|
340
|
+
if (callee.property?.name !== "use")
|
|
341
|
+
return;
|
|
342
|
+
if (!routerVars.has(callee.object?.name ?? ""))
|
|
343
|
+
return;
|
|
344
|
+
const args = np.node.arguments ?? [];
|
|
345
|
+
if (args.length < 2 || args[0]?.type !== "StringLiteral")
|
|
346
|
+
return;
|
|
347
|
+
const prefix = args[0].value;
|
|
348
|
+
const subArg = args[1];
|
|
349
|
+
if (subArg?.type === "Identifier")
|
|
350
|
+
withinFileMount.set(subArg.name, prefix);
|
|
351
|
+
},
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
catch { }
|
|
355
|
+
// Cross-file mount prefix for this file
|
|
356
|
+
const crossFilePrefix = mountMap.get(absFile) ?? "";
|
|
357
|
+
// Pass 3: collect route definitions
|
|
358
|
+
try {
|
|
359
|
+
(0, traverse_1.default)(ast, {
|
|
360
|
+
CallExpression(np) {
|
|
361
|
+
const callee = np.node.callee;
|
|
362
|
+
if (callee?.type !== "MemberExpression")
|
|
363
|
+
return;
|
|
364
|
+
const verb = callee.property?.name?.toUpperCase();
|
|
365
|
+
if (!verb || !HTTP_METHODS.has(verb))
|
|
366
|
+
return;
|
|
367
|
+
const obj = callee.object?.name ?? "";
|
|
368
|
+
if (!routerVars.has(obj))
|
|
369
|
+
return;
|
|
370
|
+
const args = np.node.arguments ?? [];
|
|
371
|
+
if (args.length < 2 || args[0]?.type !== "StringLiteral")
|
|
372
|
+
return;
|
|
373
|
+
const localPath = args[0].value;
|
|
374
|
+
// Compose full path: crossFile mount + within-file mount for this var + local path
|
|
375
|
+
const withinPrefix = withinFileMount.get(obj) ?? "";
|
|
376
|
+
const rawFull = (crossFilePrefix + withinPrefix + "/" + localPath).replace(/\/+/g, "/");
|
|
377
|
+
const routePath = rawFull || "/";
|
|
378
|
+
const handlerArg = args[1];
|
|
379
|
+
const handlerFn = handlerArg?.type === "Identifier"
|
|
380
|
+
? handlerArg.name
|
|
381
|
+
: `${verb.toLowerCase()}${localPath.replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "")}`;
|
|
382
|
+
entries.push({ method: verb, routePath, handlerFn, absFile, framework: "express" });
|
|
383
|
+
},
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
catch { /* best-effort */ }
|
|
387
|
+
}
|
|
388
|
+
return entries;
|
|
389
|
+
}
|
|
390
|
+
function discoverEntryPoints(repoRoot) {
|
|
391
|
+
const all = [
|
|
392
|
+
...discoverNextJS(repoRoot),
|
|
393
|
+
...discoverNestJS(repoRoot),
|
|
394
|
+
...discoverExpress(repoRoot),
|
|
395
|
+
];
|
|
396
|
+
// Deduplicate by method + routePath
|
|
397
|
+
const seen = new Set();
|
|
398
|
+
return all.filter(e => {
|
|
399
|
+
const k = `${e.method}:${e.routePath}`;
|
|
400
|
+
if (seen.has(k))
|
|
401
|
+
return false;
|
|
402
|
+
seen.add(k);
|
|
403
|
+
return true;
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
// ── L2: Cross-file call chain tracing ────────────────────────────────────────
|
|
407
|
+
const MAX_DEPTH = 4;
|
|
408
|
+
const MAX_FAN_OUT = 5;
|
|
409
|
+
const MAX_STEPS = 16;
|
|
410
|
+
function traceChain(fn, absFile, repoRoot, depth, visited, xrayCache) {
|
|
411
|
+
const key = `${absFile}::${fn}`;
|
|
412
|
+
if (visited.has(key) || depth < 0 || visited.size > 30)
|
|
413
|
+
return [];
|
|
414
|
+
visited.add(key);
|
|
415
|
+
let xray = xrayCache.get(absFile);
|
|
416
|
+
if (!xray) {
|
|
417
|
+
try {
|
|
418
|
+
xray = (0, buildDetailedFileXRay_1.buildDetailedFileXRay)(absFile, repoRoot);
|
|
419
|
+
}
|
|
420
|
+
catch {
|
|
421
|
+
return [];
|
|
422
|
+
}
|
|
423
|
+
xrayCache.set(absFile, xray);
|
|
424
|
+
}
|
|
425
|
+
const fnDef = xray.functions.find(f => f.name === fn);
|
|
426
|
+
if (!fnDef)
|
|
427
|
+
return [];
|
|
428
|
+
const step = {
|
|
429
|
+
fn: fnDef.name,
|
|
430
|
+
absFile,
|
|
431
|
+
calls: fnDef.calls,
|
|
432
|
+
externalCalls: fnDef.externalCalls ?? [],
|
|
433
|
+
returnType: fnDef.returnType,
|
|
434
|
+
};
|
|
435
|
+
const steps = [step];
|
|
436
|
+
if (depth === 0)
|
|
437
|
+
return steps;
|
|
438
|
+
for (const callee of fnDef.calls.slice(0, MAX_FAN_OUT)) {
|
|
439
|
+
if (steps.length >= MAX_STEPS)
|
|
440
|
+
break;
|
|
441
|
+
// Callee defined in this file?
|
|
442
|
+
if (xray.functions.some(f => f.name === callee)) {
|
|
443
|
+
steps.push(...traceChain(callee, absFile, repoRoot, depth - 1, visited, xrayCache));
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
// Follow import to another file
|
|
447
|
+
for (const imp of xray.imports) {
|
|
448
|
+
if (!imp.names.includes(callee))
|
|
449
|
+
continue;
|
|
450
|
+
const target = resolveImport(imp.source, absFile);
|
|
451
|
+
if (target) {
|
|
452
|
+
steps.push(...traceChain(callee, target, repoRoot, depth - 1, visited, xrayCache));
|
|
453
|
+
}
|
|
454
|
+
break;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return steps;
|
|
458
|
+
}
|
|
459
|
+
// ── L3: Step enrichment ───────────────────────────────────────────────────────
|
|
460
|
+
const DB_PATTERN = /^(prisma|sequelize|typeorm|mongoose|knex|db|pool|client|repository|repo|dataSource)\./i;
|
|
461
|
+
const ORM_METHODS = new Set([
|
|
462
|
+
"find", "findOne", "findAll", "findMany", "findFirst", "findUnique", "findById",
|
|
463
|
+
"create", "save", "insert", "insertOne", "insertMany",
|
|
464
|
+
"update", "updateOne", "updateMany", "updateById",
|
|
465
|
+
"delete", "deleteOne", "deleteMany", "remove", "destroy",
|
|
466
|
+
"upsert", "count", "aggregate", "query", "execute", "raw",
|
|
467
|
+
]);
|
|
468
|
+
function classifyExternalCall(call) {
|
|
469
|
+
if (DB_PATTERN.test(call))
|
|
470
|
+
return "db";
|
|
471
|
+
const method = call.split(".").pop() ?? "";
|
|
472
|
+
if (ORM_METHODS.has(method))
|
|
473
|
+
return "db";
|
|
474
|
+
return "external";
|
|
475
|
+
}
|
|
476
|
+
// External service name patterns — presence in externalCalls signals a step IS external
|
|
477
|
+
const EXTERNAL_SERVICE_PATTERNS = [
|
|
478
|
+
/supabase/i, /prisma/i, /mongo/i, /redis/i, /stripe/i, /sendgrid/i, /twilio/i,
|
|
479
|
+
/s3\b/i, /cloudinary/i, /firebase/i, /dynamodb/i, /elasticsearch/i, /algolia/i,
|
|
480
|
+
/youtube/i, /openai/i, /anthropic/i, /github\.com/i, /axios\.(get|post|put)/i,
|
|
481
|
+
];
|
|
482
|
+
function stepIsExternal(dbAccess, externalCalls) {
|
|
483
|
+
if (dbAccess.length > 0)
|
|
484
|
+
return true;
|
|
485
|
+
return externalCalls.some(c => EXTERNAL_SERVICE_PATTERNS.some(p => p.test(c)));
|
|
486
|
+
}
|
|
487
|
+
function mapFileToSystem(relFile, routePath, am) {
|
|
488
|
+
if (!am?.systems)
|
|
489
|
+
return null;
|
|
490
|
+
// Strategy 1a: exact key_file match (highest precision)
|
|
491
|
+
for (const sys of am.systems) {
|
|
492
|
+
for (const kf of (sys.key_files ?? [])) {
|
|
493
|
+
if (relFile === kf)
|
|
494
|
+
return sys.id;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
// Strategy 1b: same directory as a key_file — only for deep paths (depth ≥ 2)
|
|
498
|
+
// Prevents shallow dirs like "app/" matching everything
|
|
499
|
+
for (const sys of am.systems) {
|
|
500
|
+
for (const kf of (sys.key_files ?? [])) {
|
|
501
|
+
const kfDir = kf.replace(/\/[^/]+$/, "");
|
|
502
|
+
const depth = kfDir.split("/").filter(Boolean).length;
|
|
503
|
+
if (depth >= 2 && relFile.startsWith(kfDir + "/"))
|
|
504
|
+
return sys.id;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
// Strategy 2: owns_routes match — most precise for API route handlers
|
|
508
|
+
if (routePath) {
|
|
509
|
+
const normalise = (r) => r.replace(/^[A-Z]+\s+/, "").replace(/\[[^\]]+\]/g, ":p").replace(/:[^/]+/g, ":p");
|
|
510
|
+
const needle = normalise(routePath);
|
|
511
|
+
for (const sys of am.systems) {
|
|
512
|
+
for (const r of (sys.owns_routes ?? [])) {
|
|
513
|
+
if (normalise(r) === needle)
|
|
514
|
+
return sys.id;
|
|
515
|
+
const base = normalise(r).replace(/\/:p$/, "");
|
|
516
|
+
if (base.length > 4 && needle.startsWith(base))
|
|
517
|
+
return sys.id;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
// Strategy 3: path-segment overlap with system id tokens (fuzzy fallback)
|
|
522
|
+
const skip = new Set(["app", "api", "src", "pages", "route", "index", "lib", "utils", "helpers"]);
|
|
523
|
+
const fileSegs = relFile
|
|
524
|
+
.replace(/\.(ts|tsx|js|jsx)$/, "")
|
|
525
|
+
.split("/")
|
|
526
|
+
.filter(s => s && !skip.has(s) && !s.startsWith("[") && !s.startsWith("("));
|
|
527
|
+
let bestSys = null;
|
|
528
|
+
let bestScore = 0;
|
|
529
|
+
for (const sys of am.systems) {
|
|
530
|
+
const sysTokens = sys.id.split("-").filter((t) => t.length > 2);
|
|
531
|
+
let score = 0;
|
|
532
|
+
for (const t of sysTokens) {
|
|
533
|
+
if (fileSegs.some(s => s.toLowerCase().includes(t) || t.includes(s.toLowerCase())))
|
|
534
|
+
score++;
|
|
535
|
+
}
|
|
536
|
+
if (score > 0 && score >= sysTokens.length - 1 && score > bestScore) {
|
|
537
|
+
bestScore = score;
|
|
538
|
+
bestSys = sys.id;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
return bestSys;
|
|
542
|
+
}
|
|
543
|
+
function enrichStep(raw, repoRoot, am, routePath) {
|
|
544
|
+
const relFile = path.relative(repoRoot, raw.absFile).replace(/\\/g, "/");
|
|
545
|
+
const dbAccess = [];
|
|
546
|
+
const externalCalls = [];
|
|
547
|
+
for (const call of raw.externalCalls) {
|
|
548
|
+
if (classifyExternalCall(call) === "db")
|
|
549
|
+
dbAccess.push(call);
|
|
550
|
+
else
|
|
551
|
+
externalCalls.push(call);
|
|
552
|
+
}
|
|
553
|
+
return {
|
|
554
|
+
fn: raw.fn,
|
|
555
|
+
file: relFile,
|
|
556
|
+
systemId: mapFileToSystem(relFile, routePath, am),
|
|
557
|
+
dbAccess,
|
|
558
|
+
externalCalls,
|
|
559
|
+
returnType: raw.returnType,
|
|
560
|
+
isExternal: stepIsExternal(dbAccess, externalCalls),
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
// ── L4: Flow clustering ───────────────────────────────────────────────────────
|
|
564
|
+
function routeToId(method, route) {
|
|
565
|
+
return (method.toLowerCase() + "-" + route.replace(/[/:*?]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, ""))
|
|
566
|
+
.slice(0, 60);
|
|
567
|
+
}
|
|
568
|
+
function flowRichness(f) {
|
|
569
|
+
const dbHits = f.steps.reduce((n, s) => n + s.dbAccess.length, 0);
|
|
570
|
+
const extHits = f.steps.reduce((n, s) => n + s.externalCalls.length, 0);
|
|
571
|
+
const withSystem = f.steps.filter(s => s.systemId).length;
|
|
572
|
+
return f.steps.length * 2 + dbHits * 3 + extHits * 2 + withSystem;
|
|
573
|
+
}
|
|
574
|
+
// Extract domain prefix from route (/api/auth/login → "auth")
|
|
575
|
+
function routeDomain(routePath) {
|
|
576
|
+
const parts = routePath.split("/").filter(Boolean);
|
|
577
|
+
if (parts[0] === "api" && parts[1])
|
|
578
|
+
return parts[1];
|
|
579
|
+
return parts[0] ?? "root";
|
|
580
|
+
}
|
|
581
|
+
function clusterFlows(candidates) {
|
|
582
|
+
if (candidates.length === 0)
|
|
583
|
+
return [];
|
|
584
|
+
// Sort richest first
|
|
585
|
+
const ranked = [...candidates].sort((a, b) => flowRichness(b) - flowRichness(a));
|
|
586
|
+
// Keep at most 2 flows per (domain × method) to avoid repetition
|
|
587
|
+
const domainMethodCount = new Map();
|
|
588
|
+
const MAX_PER_BUCKET = 2;
|
|
589
|
+
const MAX_TOTAL = 16;
|
|
590
|
+
const kept = [];
|
|
591
|
+
for (const f of ranked) {
|
|
592
|
+
if (kept.length >= MAX_TOTAL)
|
|
593
|
+
break;
|
|
594
|
+
const key = `${routeDomain(f.routePath)}:${f.method}`;
|
|
595
|
+
const count = domainMethodCount.get(key) ?? 0;
|
|
596
|
+
if (count >= MAX_PER_BUCKET)
|
|
597
|
+
continue;
|
|
598
|
+
domainMethodCount.set(key, count + 1);
|
|
599
|
+
kept.push(f);
|
|
600
|
+
}
|
|
601
|
+
// Sort final output by route path for determinism
|
|
602
|
+
return kept.sort((a, b) => a.routePath.localeCompare(b.routePath));
|
|
603
|
+
}
|
|
604
|
+
// ── Public API ────────────────────────────────────────────────────────────────
|
|
605
|
+
async function buildFlowGraph(repoRoot, am, onProgress) {
|
|
606
|
+
const log = (s) => onProgress?.(s);
|
|
607
|
+
const xrayCache = new Map();
|
|
608
|
+
// L1
|
|
609
|
+
log("L1 Discovering entry points…");
|
|
610
|
+
const entries = discoverEntryPoints(repoRoot);
|
|
611
|
+
log(`L1 Found ${entries.length} entry points (Next.js / NestJS / Express)`);
|
|
612
|
+
if (entries.length === 0)
|
|
613
|
+
return [];
|
|
614
|
+
// L2
|
|
615
|
+
log("L2 Tracing call chains…");
|
|
616
|
+
const rawFlows = [];
|
|
617
|
+
for (const entry of entries) {
|
|
618
|
+
const visited = new Set();
|
|
619
|
+
const steps = traceChain(entry.handlerFn, entry.absFile, repoRoot, MAX_DEPTH, visited, xrayCache);
|
|
620
|
+
rawFlows.push({ entry, steps });
|
|
621
|
+
}
|
|
622
|
+
log(`L2 Traced ${rawFlows.length} call chains (${xrayCache.size} files parsed)`);
|
|
623
|
+
// L3
|
|
624
|
+
log("L3 Enriching steps with system IDs and DB access…");
|
|
625
|
+
const enrichedFlows = rawFlows.map(({ entry, steps }) => ({
|
|
626
|
+
id: routeToId(entry.method, entry.routePath),
|
|
627
|
+
nameSeed: `${entry.method} ${entry.routePath}`,
|
|
628
|
+
method: entry.method,
|
|
629
|
+
routePath: entry.routePath,
|
|
630
|
+
entryFile: path.relative(repoRoot, entry.absFile).replace(/\\/g, "/"),
|
|
631
|
+
steps: steps.map(s => enrichStep(s, repoRoot, am, entry.routePath)),
|
|
632
|
+
framework: entry.framework,
|
|
633
|
+
}));
|
|
634
|
+
const withDb = enrichedFlows.filter(f => f.steps.some(s => s.dbAccess.length > 0)).length;
|
|
635
|
+
const withSystem = enrichedFlows.filter(f => f.steps.some(s => s.systemId)).length;
|
|
636
|
+
log(`L3 ${withDb} flows reach DB · ${withSystem} flows map to AM systems`);
|
|
637
|
+
// L4
|
|
638
|
+
log("L4 Clustering and ranking flows…");
|
|
639
|
+
const final = clusterFlows(enrichedFlows);
|
|
640
|
+
log(`L4 Selected ${final.length} flows from ${enrichedFlows.length} candidates`);
|
|
641
|
+
return final;
|
|
642
|
+
}
|
|
643
|
+
//# sourceMappingURL=buildFlowGraph.js.map
|