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
package/dist/server.js ADDED
@@ -0,0 +1,956 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.startAppServer = startAppServer;
37
+ const http = __importStar(require("http"));
38
+ const path = __importStar(require("path"));
39
+ const url = __importStar(require("url"));
40
+ const fs = __importStar(require("fs"));
41
+ const child_process_1 = require("child_process");
42
+ const buildFileXRay_1 = require("./analysis/buildFileXRay");
43
+ const llmXRay_1 = require("./analysis/llmXRay");
44
+ const buildDetailedFileXRay_1 = require("./analysis/buildDetailedFileXRay");
45
+ const repoWatcher_1 = require("./watcher/repoWatcher");
46
+ const generateAMForRepo_1 = require("./amGeneration/generateAMForRepo");
47
+ const enrichAMEdges_1 = require("./amGeneration/enrichAMEdges");
48
+ const selectStrategicFiles_1 = require("./amGeneration/selectStrategicFiles");
49
+ const generateFileInsight_1 = require("./analysis/generateFileInsight");
50
+ const extractRouteMap_1 = require("./analysis/extractRouteMap");
51
+ const generateFlows_1 = require("./amGeneration/generateFlows");
52
+ const buildFlowGraph_1 = require("./amGeneration/buildFlowGraph");
53
+ const buildBranchStory_1 = require("./analysis/buildBranchStory");
54
+ // If path is a directory, resolve to its index file so X-Ray doesn't fail on folders.
55
+ function resolveFilePath(absPath) {
56
+ try {
57
+ if (fs.statSync(absPath).isDirectory()) {
58
+ for (const candidate of ["index.ts", "index.tsx", "index.js", "index.mjs"]) {
59
+ const resolved = path.join(absPath, candidate);
60
+ if (fs.existsSync(resolved))
61
+ return resolved;
62
+ }
63
+ }
64
+ }
65
+ catch { /* path doesn't exist — let downstream handle it */ }
66
+ return absPath;
67
+ }
68
+ // Runtime API key — loaded from ~/.memor/config.json on start, updated via /api/set-key
69
+ let runtimeApiKey;
70
+ // No bundled key — AI calls go through api.memor.dev when the user has no personal key.
71
+ const CONFIG_PATH = path.join(process.env.HOME ?? process.env.USERPROFILE ?? ".", ".memor", "config.json");
72
+ function loadSavedKey() {
73
+ try {
74
+ const cfg = JSON.parse(fs.readFileSync(CONFIG_PATH, "utf8"));
75
+ if (typeof cfg.apiKey === "string" && cfg.apiKey.length > 10) {
76
+ runtimeApiKey = cfg.apiKey;
77
+ }
78
+ }
79
+ catch { /* no config yet — fine */ }
80
+ }
81
+ function saveKey(key) {
82
+ try {
83
+ const dir = path.dirname(CONFIG_PATH);
84
+ if (!fs.existsSync(dir))
85
+ fs.mkdirSync(dir, { recursive: true });
86
+ const existing = (() => {
87
+ try {
88
+ return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf8"));
89
+ }
90
+ catch {
91
+ return {};
92
+ }
93
+ })();
94
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify({ ...existing, apiKey: key }, null, 2), "utf8");
95
+ }
96
+ catch { /* ignore write errors */ }
97
+ }
98
+ loadSavedKey();
99
+ function getApiKey() {
100
+ return runtimeApiKey || process.env.ANTHROPIC_API_KEY || "memor-proxy";
101
+ }
102
+ function readBody(req) {
103
+ return new Promise((resolve, reject) => {
104
+ const chunks = [];
105
+ req.on("data", (c) => chunks.push(c));
106
+ req.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
107
+ req.on("error", reject);
108
+ });
109
+ }
110
+ function startAppServer(html, port, onReady, repoRoot) {
111
+ const server = http.createServer((req, res) => {
112
+ if (req.url === "/favicon.ico") {
113
+ res.writeHead(204);
114
+ res.end();
115
+ return;
116
+ }
117
+ // ── /app-bundle.js — serve frontend bundle fresh from disk ───────────
118
+ if (req.url === "/app-bundle.js") {
119
+ res.setHeader("Cache-Control", "no-store");
120
+ res.setHeader("Content-Type", "application/javascript; charset=utf-8");
121
+ const candidates = [
122
+ path.join(__dirname, "app-bundle.js"),
123
+ path.join(__dirname, "..", "dist", "app-bundle.js"),
124
+ ];
125
+ for (const p of candidates) {
126
+ try {
127
+ res.writeHead(200);
128
+ res.end(fs.readFileSync(p, "utf-8"));
129
+ return;
130
+ }
131
+ catch { }
132
+ }
133
+ res.writeHead(404);
134
+ res.end("// bundle not found");
135
+ return;
136
+ }
137
+ // ── /api/am — serve current architecture-map.json ────────────
138
+ if (req.url === "/api/am") {
139
+ res.setHeader("Access-Control-Allow-Origin", "*");
140
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
141
+ if (!repoRoot) {
142
+ res.writeHead(503);
143
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
144
+ return;
145
+ }
146
+ (async () => {
147
+ const amPath = path.join(repoRoot, ".memor", "architecture-map.json");
148
+ try {
149
+ const am = JSON.parse(fs.readFileSync(amPath, "utf8"));
150
+ // Attach evidence files to flows deterministically
151
+ if (am.flows?.length > 0) {
152
+ try {
153
+ const routeMap = (0, extractRouteMap_1.extractRouteMap)(repoRoot);
154
+ am.flows = (0, generateFlows_1.attachEvidenceFiles)(am.flows, routeMap, repoRoot);
155
+ }
156
+ catch { /* non-fatal */ }
157
+ }
158
+ // Strip key_files that don't exist on disk (LLM often hallucinates file paths)
159
+ if (am.systems?.length > 0) {
160
+ for (const sys of am.systems) {
161
+ if (Array.isArray(sys.key_files)) {
162
+ sys.key_files = sys.key_files.filter((f) => fs.existsSync(path.join(repoRoot, f)));
163
+ }
164
+ }
165
+ }
166
+ // Enrich missing edges deterministically from key_file imports
167
+ try {
168
+ const manifests = await (0, selectStrategicFiles_1.readWorkspaceManifests)(repoRoot);
169
+ const enriched = (0, enrichAMEdges_1.enrichAMEdges)(am, repoRoot, manifests);
170
+ res.writeHead(200);
171
+ res.end(JSON.stringify(enriched));
172
+ }
173
+ catch {
174
+ res.writeHead(200);
175
+ res.end(JSON.stringify(am));
176
+ }
177
+ }
178
+ catch {
179
+ res.writeHead(404);
180
+ res.end(JSON.stringify({ error: "No architecture map generated yet" }));
181
+ }
182
+ })();
183
+ return;
184
+ }
185
+ // ── /api/branch-story — git diff → spatial change graph ─────────────────
186
+ if (req.url?.startsWith("/api/branch-story")) {
187
+ res.setHeader("Access-Control-Allow-Origin", "*");
188
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
189
+ res.setHeader("Cache-Control", "no-store");
190
+ if (!repoRoot) {
191
+ res.writeHead(503);
192
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
193
+ return;
194
+ }
195
+ const parsed = url.parse(req.url, true);
196
+ const base = parsed.query.base || "main"; // Target: what to diff against
197
+ const source = parsed.query.source || "working"; // Source: working tree or a branch
198
+ // Two-phase: ?enrich=1 runs the LLM comprehension layer (role/change/threads).
199
+ // Without it, the story is purely deterministic and returns at git-status speed.
200
+ const enrich = parsed.query.enrich === "1";
201
+ const apiKey = enrich ? getApiKey() : undefined;
202
+ let am = null;
203
+ try {
204
+ am = JSON.parse(fs.readFileSync(path.join(repoRoot, ".memor", "architecture-map.json"), "utf8"));
205
+ }
206
+ catch { }
207
+ (0, buildBranchStory_1.buildBranchStoryForSource)(repoRoot, base, apiKey, am, source)
208
+ .then(story => { res.writeHead(200); res.end(JSON.stringify(story)); })
209
+ .catch(e => { res.writeHead(500); res.end(JSON.stringify({ error: String(e) })); });
210
+ return;
211
+ }
212
+ // ── /api/fetch — pull the latest remote refs so peer PR branches are current ──
213
+ if (req.url === "/api/fetch" && req.method === "POST") {
214
+ res.setHeader("Access-Control-Allow-Origin", "*");
215
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
216
+ if (!repoRoot) {
217
+ res.writeHead(503);
218
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
219
+ return;
220
+ }
221
+ try {
222
+ // Read-only network op (updates remote-tracking refs; never touches the working tree).
223
+ (0, child_process_1.execSync)(`git -C "${repoRoot}" fetch origin --prune`, { stdio: ["pipe", "pipe", "pipe"], timeout: 30000 });
224
+ res.writeHead(200);
225
+ res.end(JSON.stringify({ ok: true }));
226
+ }
227
+ catch (e) {
228
+ res.writeHead(200);
229
+ res.end(JSON.stringify({ ok: false, error: String(e).slice(0, 200) }));
230
+ }
231
+ return;
232
+ }
233
+ // ── /api/branches — list local + remote branches for the Source/Target selectors ──
234
+ if (req.url?.startsWith("/api/branches")) {
235
+ const wantCounts = url.parse(req.url, true).query.counts === "1";
236
+ res.setHeader("Access-Control-Allow-Origin", "*");
237
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
238
+ res.setHeader("Cache-Control", "no-store");
239
+ if (!repoRoot) {
240
+ res.writeHead(503);
241
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
242
+ return;
243
+ }
244
+ try {
245
+ const current = (() => {
246
+ try {
247
+ return (0, child_process_1.execSync)(`git -C "${repoRoot}" rev-parse --abbrev-ref HEAD`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
248
+ }
249
+ catch {
250
+ return "";
251
+ }
252
+ })();
253
+ // The default branch we judge "merged" against (main, else master).
254
+ const defaultBranch = (() => {
255
+ for (const c of ["main", "master"]) {
256
+ try {
257
+ (0, child_process_1.execSync)(`git -C "${repoRoot}" rev-parse --verify ${c}`, { stdio: "pipe" });
258
+ return c;
259
+ }
260
+ catch { }
261
+ }
262
+ return current || "main";
263
+ })();
264
+ // Branches with commits NOT in the default branch (ahead > 0) — the live/open ones.
265
+ // `--no-merged` is a single reachability check (fast, no per-branch loop).
266
+ const notMerged = new Set();
267
+ for (const flag of ["", "-r"]) {
268
+ try {
269
+ const out = (0, child_process_1.execSync)(`git -C "${repoRoot}" branch ${flag} --no-merged ${defaultBranch} --format="%(refname:short)"`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], maxBuffer: 2_000_000 }).trim();
270
+ for (const n of out.split("\n").filter(Boolean))
271
+ notMerged.add(n.replace(/^origin\//, "").trim());
272
+ }
273
+ catch { }
274
+ }
275
+ // name + committer date (epoch) for local and remote branches, newest first
276
+ const raw = (0, child_process_1.execSync)(`git -C "${repoRoot}" for-each-ref --sort=-committerdate --format="%(refname:short)|%(committerdate:unix)" refs/heads refs/remotes`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], maxBuffer: 2_000_000 }).trim();
277
+ const seen = new Set();
278
+ const branches = raw.split("\n").filter(Boolean).map(l => {
279
+ const [name, ts] = l.split("|");
280
+ const shortName = name.replace(/^origin\//, "");
281
+ // The default branch is the comparison base — never a valid Source. Force merged=true
282
+ // so it's hidden from Source (a stale local main can otherwise read as "not merged").
283
+ const merged = shortName === defaultBranch ? true : !notMerged.has(shortName);
284
+ return { name: shortName, raw: name, lastCommit: Number(ts) || 0, isCurrent: name === current, merged };
285
+ }).filter(b => {
286
+ if (b.raw.endsWith("/HEAD"))
287
+ return false; // skip origin/HEAD symref
288
+ if (b.name === "origin" || b.name === "HEAD")
289
+ return false; // phantom remote noise
290
+ if (seen.has(b.name))
291
+ return false; // dedupe local/remote of same name
292
+ seen.add(b.name);
293
+ return true;
294
+ });
295
+ // Optional: ahead-count vs the default branch, for the open (non-merged) branches only
296
+ // — used by the "Review a Pull Request" modal. Computed on demand (?counts=1) to keep
297
+ // the regular mount fast.
298
+ let out = branches;
299
+ if (wantCounts) {
300
+ // Count ahead vs the REMOTE default (origin/main) to match the actual review baseline,
301
+ // not a possibly-stale local main.
302
+ const tgt = (() => {
303
+ try {
304
+ (0, child_process_1.execSync)(`git -C "${repoRoot}" rev-parse --verify origin/${defaultBranch}`, { stdio: "pipe" });
305
+ return `origin/${defaultBranch}`;
306
+ }
307
+ catch {
308
+ return defaultBranch;
309
+ }
310
+ })();
311
+ out = branches.map(b => {
312
+ if (b.merged)
313
+ return b;
314
+ try {
315
+ const n = (0, child_process_1.execSync)(`git -C "${repoRoot}" rev-list --count ${tgt}..${b.raw}`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
316
+ return { ...b, ahead: parseInt(n, 10) || 0 };
317
+ }
318
+ catch {
319
+ return b;
320
+ }
321
+ });
322
+ }
323
+ // When the remote refs were last fetched (FETCH_HEAD mtime) — drives "fetched Xm ago".
324
+ const fetchedAt = (() => {
325
+ try {
326
+ return Math.floor(fs.statSync(path.join(repoRoot, ".git", "FETCH_HEAD")).mtimeMs);
327
+ }
328
+ catch {
329
+ return null;
330
+ }
331
+ })();
332
+ res.writeHead(200);
333
+ res.end(JSON.stringify({ current, defaultBranch, fetchedAt, branches: out }));
334
+ }
335
+ catch (e) {
336
+ res.writeHead(200);
337
+ res.end(JSON.stringify({ current: "", branches: [] }));
338
+ }
339
+ return;
340
+ }
341
+ // ── /api/commit-log — commits between base..HEAD with per-commit file lists ─
342
+ if (req.url?.startsWith("/api/commit-log")) {
343
+ res.setHeader("Access-Control-Allow-Origin", "*");
344
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
345
+ res.setHeader("Cache-Control", "no-store");
346
+ if (!repoRoot) {
347
+ res.writeHead(503);
348
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
349
+ return;
350
+ }
351
+ const parsed = url.parse(req.url, true);
352
+ const base = parsed.query.base || "main";
353
+ try {
354
+ // Single pass: pretty header lines interleaved with name-status file lines
355
+ const raw = (0, child_process_1.execSync)(`git -C "${repoRoot}" log ${base}..HEAD --pretty=format:">>C<<%H<<%s<<%an<<%ai" --name-status`, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
356
+ const commits = [];
357
+ if (raw) {
358
+ let current = null;
359
+ for (const line of raw.split("\n")) {
360
+ if (line.startsWith(">>C<<")) {
361
+ if (current)
362
+ commits.push(current);
363
+ const [, sha, message, author, date] = line.split("<<");
364
+ current = { sha, shortSha: sha.slice(0, 7), message: message ?? "", author: author ?? "", date: date ?? "", files: [] };
365
+ }
366
+ else if (current && line.trim()) {
367
+ const parts = line.split("\t");
368
+ const s = parts[0]?.[0];
369
+ const filePath = parts[parts.length - 1];
370
+ if (filePath && s) {
371
+ const status = s === "A" ? "added" : s === "D" ? "deleted" : "modified";
372
+ current.files.push({ path: filePath, status });
373
+ }
374
+ }
375
+ }
376
+ if (current)
377
+ commits.push(current);
378
+ }
379
+ res.writeHead(200);
380
+ res.end(JSON.stringify({ commits }));
381
+ }
382
+ catch {
383
+ res.writeHead(200);
384
+ res.end(JSON.stringify({ commits: [] }));
385
+ }
386
+ return;
387
+ }
388
+ // ── /api/branch-diff — raw git diff for a single file ────────────────────
389
+ if (req.url?.startsWith("/api/branch-diff")) {
390
+ res.setHeader("Access-Control-Allow-Origin", "*");
391
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
392
+ res.setHeader("Cache-Control", "no-store");
393
+ if (!repoRoot) {
394
+ res.writeHead(503);
395
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
396
+ return;
397
+ }
398
+ const parsed = url.parse(req.url, true);
399
+ const file = parsed.query.file || "";
400
+ const rawBase = parsed.query.base || "main";
401
+ const source = parsed.query.source || "working";
402
+ const isWorking = !source || source === "working";
403
+ // Prefer origin/<base> over a stale local target (match the branch-story baseline).
404
+ const base = (() => {
405
+ if (/^(HEAD|origin\/)/.test(rawBase) || /[~^]/.test(rawBase) || /^[0-9a-f]{7,40}$/.test(rawBase))
406
+ return rawBase;
407
+ for (const c of [`origin/${rawBase}`, rawBase]) {
408
+ try {
409
+ (0, child_process_1.execSync)(`git -C "${repoRoot}" rev-parse --verify ${c}`, { stdio: "pipe" });
410
+ return c;
411
+ }
412
+ catch { }
413
+ }
414
+ return rawBase;
415
+ })();
416
+ // Resolve source to a concrete ref. Prefer origin/<branch> over the local branch —
417
+ // the local copy may be stale (force-pushed, rebased) and produce a different diff
418
+ // than what the brief was computed from. Matching the brief's baseline is critical
419
+ // so that chunk indices align and inference points show the right diff slice.
420
+ const srcRef = isWorking ? "" : (() => {
421
+ for (const c of [`origin/${source}`, source]) {
422
+ try {
423
+ (0, child_process_1.execSync)(`git -C "${repoRoot}" rev-parse --verify ${c}`, { stdio: "pipe" });
424
+ return c;
425
+ }
426
+ catch { }
427
+ }
428
+ return source;
429
+ })();
430
+ // Match the changeset baseline: diff against the merge-base of Target and Source.
431
+ let diffBase = base;
432
+ try {
433
+ const otherRef = isWorking ? "HEAD" : srcRef;
434
+ diffBase = (0, child_process_1.execSync)(`git -C "${repoRoot}" merge-base ${base} ${otherRef}`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim() || base;
435
+ }
436
+ catch {
437
+ diffBase = (0, buildBranchStory_1.resolveMergeBase)(repoRoot, base) ?? base;
438
+ }
439
+ const diff = (0, buildBranchStory_1.getFileDiffRaw)(repoRoot, file, diffBase, srcRef);
440
+ res.writeHead(200);
441
+ res.end(JSON.stringify({ diff }));
442
+ return;
443
+ }
444
+ // ── /api/default-branch — detect the repo's default branch ─────────────
445
+ if (req.url === "/api/default-branch") {
446
+ res.setHeader("Access-Control-Allow-Origin", "*");
447
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
448
+ res.setHeader("Cache-Control", "no-store");
449
+ let defaultBranch = "main";
450
+ if (repoRoot) {
451
+ try {
452
+ // Try the remote HEAD ref first (most reliable)
453
+ const ref = (0, child_process_1.execSync)(`git -C "${repoRoot}" symbolic-ref refs/remotes/origin/HEAD`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
454
+ defaultBranch = ref.replace(/^refs\/remotes\/origin\//, "");
455
+ }
456
+ catch {
457
+ // Fall back: check which of main/master/develop actually exists
458
+ for (const candidate of ["main", "master", "develop", "trunk"]) {
459
+ try {
460
+ (0, child_process_1.execSync)(`git -C "${repoRoot}" rev-parse --verify ${candidate}`, { stdio: "pipe" });
461
+ defaultBranch = candidate;
462
+ break;
463
+ }
464
+ catch { /* try next */ }
465
+ }
466
+ }
467
+ }
468
+ res.writeHead(200);
469
+ res.end(JSON.stringify({ defaultBranch }));
470
+ return;
471
+ }
472
+ // ── /api/am-freshness — how many commits since last AM generation ────────
473
+ if (req.url === "/api/am-freshness") {
474
+ res.setHeader("Access-Control-Allow-Origin", "*");
475
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
476
+ res.setHeader("Cache-Control", "no-store");
477
+ if (!repoRoot) {
478
+ res.writeHead(200);
479
+ res.end(JSON.stringify({ commitsBehind: 0 }));
480
+ return;
481
+ }
482
+ try {
483
+ const amPath = path.join(repoRoot, ".memor", "architecture-map.json");
484
+ const am = JSON.parse(fs.readFileSync(amPath, "utf8"));
485
+ const commit = am._meta?.generatedAtCommit;
486
+ if (!commit) {
487
+ // Old map with no stored commit — use file mtime as rough proxy
488
+ const stat = fs.statSync(amPath);
489
+ const since = stat.mtime.toISOString();
490
+ res.writeHead(200);
491
+ res.end(JSON.stringify({ commitsBehind: null, generatedAt: since, noCommitStored: true }));
492
+ return;
493
+ }
494
+ let commitsBehind = 0;
495
+ try {
496
+ const out = (0, child_process_1.execSync)(`git -C "${repoRoot}" rev-list --count ${commit}..HEAD`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
497
+ commitsBehind = parseInt(out) || 0;
498
+ }
499
+ catch { /* git not available or commit not found */ }
500
+ res.writeHead(200);
501
+ res.end(JSON.stringify({ commitsBehind, generatedAt: am._meta?.generatedAt }));
502
+ }
503
+ catch {
504
+ // No architecture map at all — not stale, just missing
505
+ res.writeHead(200);
506
+ res.end(JSON.stringify({ commitsBehind: 0 }));
507
+ }
508
+ return;
509
+ }
510
+ // ── /api/xray-detail?file=relative/path — typed AST signatures ───
511
+ if (req.url?.startsWith("/api/xray-detail")) {
512
+ res.setHeader("Access-Control-Allow-Origin", "*");
513
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
514
+ if (!repoRoot) {
515
+ res.writeHead(503);
516
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
517
+ return;
518
+ }
519
+ const parsed = url.parse(req.url, true);
520
+ const fileRel = parsed.query.file;
521
+ if (!fileRel) {
522
+ res.writeHead(400);
523
+ res.end(JSON.stringify({ error: "Missing ?file= parameter" }));
524
+ return;
525
+ }
526
+ const absPath = path.resolve(repoRoot, fileRel);
527
+ if (!absPath.startsWith(path.resolve(repoRoot))) {
528
+ res.writeHead(403);
529
+ res.end(JSON.stringify({ error: "Path traversal not allowed" }));
530
+ return;
531
+ }
532
+ try {
533
+ const detail = (0, buildDetailedFileXRay_1.buildDetailedFileXRay)(absPath, repoRoot);
534
+ res.writeHead(200);
535
+ res.end(JSON.stringify(detail));
536
+ }
537
+ catch (e) {
538
+ res.writeHead(500);
539
+ res.end(JSON.stringify({ error: String(e) }));
540
+ }
541
+ return;
542
+ }
543
+ // ── /api/xray?file=relative/path/to/file.ts ──────────────────
544
+ if (req.url?.startsWith("/api/xray") && !req.url.startsWith("/api/xray-llm")) {
545
+ res.setHeader("Access-Control-Allow-Origin", "*");
546
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
547
+ if (!repoRoot) {
548
+ res.writeHead(503);
549
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
550
+ return;
551
+ }
552
+ const parsed = url.parse(req.url, true);
553
+ const fileRel = parsed.query.file;
554
+ if (!fileRel) {
555
+ res.writeHead(400);
556
+ res.end(JSON.stringify({ error: "Missing ?file= parameter" }));
557
+ return;
558
+ }
559
+ // Safety: resolve and ensure file is under repoRoot
560
+ const absPath = path.resolve(repoRoot, fileRel);
561
+ if (!absPath.startsWith(path.resolve(repoRoot))) {
562
+ res.writeHead(403);
563
+ res.end(JSON.stringify({ error: "Path traversal not allowed" }));
564
+ return;
565
+ }
566
+ try {
567
+ const xray = (0, buildFileXRay_1.buildFileXRay)(absPath, repoRoot);
568
+ res.writeHead(200);
569
+ res.end(JSON.stringify(xray));
570
+ }
571
+ catch (e) {
572
+ res.writeHead(500);
573
+ res.end(JSON.stringify({ error: String(e) }));
574
+ }
575
+ return;
576
+ }
577
+ // ── /api/events — SSE stream for live code-change notifications ──
578
+ if (req.url === "/api/events") {
579
+ res.setHeader("Access-Control-Allow-Origin", "*");
580
+ res.setHeader("Content-Type", "text/event-stream");
581
+ res.setHeader("Cache-Control", "no-cache");
582
+ res.setHeader("Connection", "keep-alive");
583
+ res.writeHead(200);
584
+ res.write("data: {\"type\":\"connected\"}\n\n");
585
+ (0, repoWatcher_1.addSSEClient)(res);
586
+ return;
587
+ }
588
+ // ── /api/repo-root — return the repo root path ───────────────
589
+ if (req.url === "/api/repo-root" && req.method === "GET") {
590
+ res.setHeader("Access-Control-Allow-Origin", "*");
591
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
592
+ res.writeHead(200);
593
+ res.end(JSON.stringify({ repoRoot: repoRoot ?? "" }));
594
+ return;
595
+ }
596
+ // ── /api/key-status — check if API key is available ──────────
597
+ if (req.url === "/api/key-status" && req.method === "GET") {
598
+ res.setHeader("Access-Control-Allow-Origin", "*");
599
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
600
+ res.writeHead(200);
601
+ const source = runtimeApiKey ? "runtime" : process.env.ANTHROPIC_API_KEY ? "env" : "none";
602
+ res.end(JSON.stringify({ hasKey: source !== "none", source }));
603
+ return;
604
+ }
605
+ // ── /api/set-key — store API key in memory for this session ───
606
+ if (req.url === "/api/set-key" && req.method === "POST") {
607
+ res.setHeader("Access-Control-Allow-Origin", "*");
608
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
609
+ readBody(req).then((raw) => {
610
+ try {
611
+ const { key } = JSON.parse(raw);
612
+ if (typeof key === "string" && key.trim().length > 10) {
613
+ runtimeApiKey = key.trim();
614
+ saveKey(runtimeApiKey);
615
+ res.writeHead(200);
616
+ res.end(JSON.stringify({ ok: true }));
617
+ }
618
+ else {
619
+ res.writeHead(400);
620
+ res.end(JSON.stringify({ error: "invalid key" }));
621
+ }
622
+ }
623
+ catch {
624
+ res.writeHead(400);
625
+ res.end(JSON.stringify({ error: "bad request" }));
626
+ }
627
+ }).catch(() => { res.writeHead(500); res.end("{}"); });
628
+ return;
629
+ }
630
+ // ── /api/generate-am — trigger AM (re)generation ──────────────
631
+ if (req.url === "/api/generate-am" && req.method === "POST") {
632
+ res.setHeader("Access-Control-Allow-Origin", "*");
633
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
634
+ if (!repoRoot) {
635
+ res.writeHead(503);
636
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
637
+ return;
638
+ }
639
+ const apiKey = getApiKey();
640
+ if (!apiKey) {
641
+ res.writeHead(503);
642
+ res.end(JSON.stringify({ error: "ANTHROPIC_API_KEY not set" }));
643
+ return;
644
+ }
645
+ // Respond immediately — generation runs in background
646
+ res.writeHead(202);
647
+ res.end(JSON.stringify({ status: "generating" }));
648
+ (0, generateAMForRepo_1.generateAMForRepo)(repoRoot, apiKey, (step) => {
649
+ if (step.startsWith("am-intel:")) {
650
+ try {
651
+ (0, repoWatcher_1.broadcast)({ type: "am-intel", data: JSON.parse(step.slice(9)) });
652
+ }
653
+ catch { }
654
+ }
655
+ else {
656
+ (0, repoWatcher_1.broadcast)({ type: "am-progress", step });
657
+ }
658
+ })
659
+ .then(() => (0, repoWatcher_1.broadcast)({ type: "am-ready" }))
660
+ .catch((e) => {
661
+ console.error("[memor] AM generation failed:", e.message);
662
+ (0, repoWatcher_1.broadcast)({ type: "am-error", error: e.message });
663
+ });
664
+ return;
665
+ }
666
+ // ── /api/xray-llm?file=relative/path — LLM narrative X-Ray ──
667
+ if (req.url?.startsWith("/api/xray-llm")) {
668
+ res.setHeader("Access-Control-Allow-Origin", "*");
669
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
670
+ if (!repoRoot) {
671
+ res.writeHead(503);
672
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
673
+ return;
674
+ }
675
+ const parsed = url.parse(req.url, true);
676
+ const fileRel = parsed.query.file;
677
+ if (!fileRel) {
678
+ res.writeHead(400);
679
+ res.end(JSON.stringify({ error: "Missing ?file= parameter" }));
680
+ return;
681
+ }
682
+ const absPath = resolveFilePath(path.resolve(repoRoot, fileRel));
683
+ if (!absPath.startsWith(path.resolve(repoRoot))) {
684
+ res.writeHead(403);
685
+ res.end(JSON.stringify({ error: "Path traversal not allowed" }));
686
+ return;
687
+ }
688
+ (0, llmXRay_1.generateLLMXRay)(absPath, repoRoot)
689
+ .then((xray) => {
690
+ res.writeHead(200);
691
+ res.end(JSON.stringify(xray));
692
+ })
693
+ .catch((e) => {
694
+ const status = e.message.includes("ANTHROPIC_API_KEY") ? 503
695
+ : e.message.includes("too large") || e.message.includes("only supports") ? 400
696
+ : 500;
697
+ res.writeHead(status);
698
+ res.end(JSON.stringify({ error: e.message }));
699
+ });
700
+ return;
701
+ }
702
+ // ── /api/generate-flows — deterministic route map → Haiku → patch AM ────
703
+ if (req.url === "/api/generate-flows" && req.method === "POST") {
704
+ res.setHeader("Access-Control-Allow-Origin", "*");
705
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
706
+ if (!repoRoot) {
707
+ res.writeHead(503);
708
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
709
+ return;
710
+ }
711
+ const apiKey = getApiKey();
712
+ if (!apiKey) {
713
+ res.writeHead(503);
714
+ res.end(JSON.stringify({ error: "ANTHROPIC_API_KEY not set" }));
715
+ return;
716
+ }
717
+ const amPath = path.join(repoRoot, ".memor", "architecture-map.json");
718
+ let am;
719
+ try {
720
+ am = JSON.parse(fs.readFileSync(amPath, "utf8"));
721
+ }
722
+ catch {
723
+ res.writeHead(404);
724
+ res.end(JSON.stringify({ error: "No architecture map found — generate AM first" }));
725
+ return;
726
+ }
727
+ // Respond immediately, run in background
728
+ res.writeHead(202);
729
+ res.end(JSON.stringify({ status: "generating" }));
730
+ Promise.resolve().then(async () => {
731
+ try {
732
+ const systemIds = (am.systems ?? []).map((s) => s.id);
733
+ const externalIds = (am.external ?? []).map((e) => e.id);
734
+ // L1–L4 deterministic pipeline
735
+ const candidates = await (0, buildFlowGraph_1.buildFlowGraph)(repoRoot, am, (step) => {
736
+ (0, repoWatcher_1.broadcast)({ type: "flows-progress", step });
737
+ });
738
+ if (candidates.length === 0) {
739
+ // Fallback to legacy route-map path
740
+ (0, repoWatcher_1.broadcast)({ type: "flows-progress", step: "No entry points found — falling back to route map…" });
741
+ const routeMap = (0, extractRouteMap_1.extractRouteMap)(repoRoot);
742
+ (0, repoWatcher_1.broadcast)({ type: "flows-progress", step: `Found ${routeMap.apiRoutes.length} routes — narrating with LLM…` });
743
+ const flows = await (0, generateFlows_1.generateFlows)(routeMap, systemIds, externalIds, apiKey, repoRoot);
744
+ am.flows = flows;
745
+ fs.writeFileSync(amPath, JSON.stringify(am, null, 2), "utf8");
746
+ (0, repoWatcher_1.broadcast)({ type: "flows-ready", count: flows.length });
747
+ return;
748
+ }
749
+ (0, repoWatcher_1.broadcast)({ type: "flows-progress", step: `Narrating ${candidates.length} flows with LLM…` });
750
+ const flows = await (0, generateFlows_1.generateFlows)(candidates, systemIds, externalIds, apiKey, repoRoot);
751
+ am.flows = flows;
752
+ fs.writeFileSync(amPath, JSON.stringify(am, null, 2), "utf8");
753
+ (0, repoWatcher_1.broadcast)({ type: "flows-ready", count: flows.length });
754
+ }
755
+ catch (e) {
756
+ console.error("[memor] Flow generation failed:", e.message);
757
+ (0, repoWatcher_1.broadcast)({ type: "flows-error", error: e.message });
758
+ }
759
+ });
760
+ return;
761
+ }
762
+ // ── /api/ai-file-insight?file=relative/path — description + suggestions ──
763
+ if (req.url?.startsWith("/api/ai-file-insight")) {
764
+ res.setHeader("Access-Control-Allow-Origin", "*");
765
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
766
+ if (!repoRoot) {
767
+ res.writeHead(503);
768
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
769
+ return;
770
+ }
771
+ const apiKey = getApiKey();
772
+ if (!apiKey) {
773
+ res.writeHead(503);
774
+ res.end(JSON.stringify({ error: "ANTHROPIC_API_KEY not set" }));
775
+ return;
776
+ }
777
+ const parsed = url.parse(req.url, true);
778
+ const fileRel = parsed.query.file;
779
+ if (!fileRel) {
780
+ res.writeHead(400);
781
+ res.end(JSON.stringify({ error: "Missing ?file= parameter" }));
782
+ return;
783
+ }
784
+ const absPath = resolveFilePath(path.resolve(repoRoot, fileRel));
785
+ if (!absPath.startsWith(path.resolve(repoRoot))) {
786
+ res.writeHead(403);
787
+ res.end(JSON.stringify({ error: "Path traversal not allowed" }));
788
+ return;
789
+ }
790
+ // Build the deterministic X-Ray first, then feed its structured summary to LLM
791
+ // (covers the whole file with far fewer tokens than raw lines)
792
+ let xrayData;
793
+ try {
794
+ xrayData = (0, buildDetailedFileXRay_1.buildDetailedFileXRay)(absPath, repoRoot);
795
+ }
796
+ catch (e) {
797
+ res.writeHead(500);
798
+ res.end(JSON.stringify({ error: `X-Ray failed: ${String(e)}` }));
799
+ return;
800
+ }
801
+ (0, generateFileInsight_1.generateFileInsight)(absPath, repoRoot, apiKey, xrayData)
802
+ .then(insight => { res.writeHead(200); res.end(JSON.stringify(insight)); })
803
+ .catch((e) => { res.writeHead(500); res.end(JSON.stringify({ error: e.message })); });
804
+ return;
805
+ }
806
+ // ── /api/git-changes — staged + working-tree changes ─────────
807
+ if (req.url?.startsWith("/api/git-changes")) {
808
+ res.setHeader("Access-Control-Allow-Origin", "*");
809
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
810
+ if (!repoRoot) {
811
+ res.writeHead(503);
812
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
813
+ return;
814
+ }
815
+ try {
816
+ const parseFiles = (out) => out.split("\n").map((l) => l.trim()).filter(Boolean);
817
+ let files = [];
818
+ try {
819
+ const staged = parseFiles((0, child_process_1.execSync)("git diff --name-only --cached", { cwd: repoRoot, encoding: "utf-8" }));
820
+ files.push(...staged);
821
+ }
822
+ catch { }
823
+ try {
824
+ const unstaged = parseFiles((0, child_process_1.execSync)("git diff --name-only", { cwd: repoRoot, encoding: "utf-8" }));
825
+ files.push(...unstaged);
826
+ }
827
+ catch { }
828
+ // Deduplicate and filter to JS/TS source files
829
+ const sourceRe = /\.(ts|tsx|js|jsx|mjs|cjs)$/;
830
+ const unique = [...new Set(files)].filter((f) => sourceRe.test(f));
831
+ res.writeHead(200);
832
+ res.end(JSON.stringify({ files: unique }));
833
+ }
834
+ catch (e) {
835
+ res.writeHead(500);
836
+ res.end(JSON.stringify({ error: String(e) }));
837
+ }
838
+ return;
839
+ }
840
+ // ── /api/file-slice?file=rel/path&from=N&to=N — raw source lines ─
841
+ if (req.url?.startsWith("/api/file-slice")) {
842
+ res.setHeader("Access-Control-Allow-Origin", "*");
843
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
844
+ if (!repoRoot) {
845
+ res.writeHead(503);
846
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
847
+ return;
848
+ }
849
+ const parsed = url.parse(req.url, true);
850
+ const fileRel = parsed.query.file;
851
+ const from = Math.max(1, parseInt(parsed.query.from ?? "1", 10));
852
+ const to = parseInt(parsed.query.to ?? "0", 10);
853
+ if (!fileRel || !to) {
854
+ res.writeHead(400);
855
+ res.end(JSON.stringify({ error: "Missing ?file=, ?from=, ?to= params" }));
856
+ return;
857
+ }
858
+ const absPath = path.resolve(repoRoot, fileRel);
859
+ if (!absPath.startsWith(path.resolve(repoRoot))) {
860
+ res.writeHead(403);
861
+ res.end(JSON.stringify({ error: "Path traversal not allowed" }));
862
+ return;
863
+ }
864
+ try {
865
+ const lines = fs.readFileSync(absPath, "utf8").split("\n");
866
+ const sliced = lines.slice(from - 1, Math.min(to, from + 299)).join("\n"); // max 300 lines
867
+ res.writeHead(200);
868
+ res.end(JSON.stringify({ code: sliced, from, to: Math.min(to, from + 299) }));
869
+ }
870
+ catch {
871
+ res.writeHead(404);
872
+ res.end(JSON.stringify({ error: "File not found" }));
873
+ }
874
+ return;
875
+ }
876
+ // ── /api/git-head — files changed in HEAD commit ──────────────
877
+ if (req.url?.startsWith("/api/git-head")) {
878
+ res.setHeader("Access-Control-Allow-Origin", "*");
879
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
880
+ if (!repoRoot) {
881
+ res.writeHead(503);
882
+ res.end(JSON.stringify({ error: "repoRoot not set" }));
883
+ return;
884
+ }
885
+ try {
886
+ const out = (0, child_process_1.execSync)("git diff-tree --no-commit-id -r --name-only HEAD", {
887
+ cwd: repoRoot, encoding: "utf-8",
888
+ });
889
+ const sourceRe = /\.(ts|tsx|js|jsx|mjs|cjs)$/;
890
+ const files = out.split("\n").map((l) => l.trim()).filter(Boolean).filter((f) => sourceRe.test(f));
891
+ res.writeHead(200);
892
+ res.end(JSON.stringify({ files }));
893
+ }
894
+ catch (e) {
895
+ res.writeHead(500);
896
+ res.end(JSON.stringify({ error: String(e) }));
897
+ }
898
+ return;
899
+ }
900
+ // ── /tIcons/* — serve tech stack SVG icons ────────────────────
901
+ if (req.url?.startsWith("/tIcons/")) {
902
+ const iconName = req.url.slice("/tIcons/".length).replace(/[^a-zA-Z0-9_.\-]/g, "");
903
+ const iconPath = path.join(__dirname, "..", "public", "tIcons", iconName);
904
+ try {
905
+ const svg = fs.readFileSync(iconPath, "utf8");
906
+ res.writeHead(200, { "Content-Type": "image/svg+xml", "Cache-Control": "public, max-age=86400" });
907
+ res.end(svg);
908
+ }
909
+ catch {
910
+ res.writeHead(404);
911
+ res.end("");
912
+ }
913
+ return;
914
+ }
915
+ // ── Main app HTML ─────────────────────────────────────────────
916
+ res.writeHead(200, {
917
+ "Content-Type": "text/html; charset=utf-8",
918
+ "Cache-Control": "no-store",
919
+ });
920
+ res.end(html);
921
+ });
922
+ const BASE_PORT = port;
923
+ let currentPort = port;
924
+ function tryListen() {
925
+ server.listen(currentPort, () => {
926
+ if (currentPort !== BASE_PORT) {
927
+ console.log(` Port ${BASE_PORT} was in use — started on ${currentPort} instead.`);
928
+ }
929
+ onReady(`http://localhost:${currentPort}`);
930
+ if (repoRoot)
931
+ (0, repoWatcher_1.startRepoWatcher)(repoRoot);
932
+ });
933
+ }
934
+ server.on("error", (err) => {
935
+ if (err.code === "EADDRINUSE") {
936
+ if (currentPort < BASE_PORT + 4) {
937
+ currentPort++;
938
+ server.close(() => tryListen());
939
+ }
940
+ else {
941
+ console.error(`\n ✗ Ports ${BASE_PORT}–${BASE_PORT + 4} are all in use.`);
942
+ console.error(` Kill the other memor instance, or run with --port <number>.\n`);
943
+ process.exit(1);
944
+ }
945
+ return;
946
+ }
947
+ throw err;
948
+ });
949
+ tryListen();
950
+ process.on("SIGINT", () => {
951
+ server.close();
952
+ console.log("\n Memor stopped.");
953
+ process.exit(0);
954
+ });
955
+ }
956
+ //# sourceMappingURL=server.js.map