openlore 2.0.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 (634) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +268 -0
  3. package/dist/api/analyze.d.ts +17 -0
  4. package/dist/api/analyze.d.ts.map +1 -0
  5. package/dist/api/analyze.js +143 -0
  6. package/dist/api/analyze.js.map +1 -0
  7. package/dist/api/audit.d.ts +10 -0
  8. package/dist/api/audit.d.ts.map +1 -0
  9. package/dist/api/audit.js +117 -0
  10. package/dist/api/audit.js.map +1 -0
  11. package/dist/api/decisions.d.ts +55 -0
  12. package/dist/api/decisions.d.ts.map +1 -0
  13. package/dist/api/decisions.js +157 -0
  14. package/dist/api/decisions.js.map +1 -0
  15. package/dist/api/drift.d.ts +21 -0
  16. package/dist/api/drift.d.ts.map +1 -0
  17. package/dist/api/drift.js +152 -0
  18. package/dist/api/drift.js.map +1 -0
  19. package/dist/api/generate.d.ts +18 -0
  20. package/dist/api/generate.d.ts.map +1 -0
  21. package/dist/api/generate.js +259 -0
  22. package/dist/api/generate.js.map +1 -0
  23. package/dist/api/index.d.ts +41 -0
  24. package/dist/api/index.d.ts.map +1 -0
  25. package/dist/api/index.js +34 -0
  26. package/dist/api/index.js.map +1 -0
  27. package/dist/api/init.d.ts +18 -0
  28. package/dist/api/init.d.ts.map +1 -0
  29. package/dist/api/init.js +83 -0
  30. package/dist/api/init.js.map +1 -0
  31. package/dist/api/run.d.ts +19 -0
  32. package/dist/api/run.d.ts.map +1 -0
  33. package/dist/api/run.js +312 -0
  34. package/dist/api/run.js.map +1 -0
  35. package/dist/api/specs.d.ts +49 -0
  36. package/dist/api/specs.d.ts.map +1 -0
  37. package/dist/api/specs.js +137 -0
  38. package/dist/api/specs.js.map +1 -0
  39. package/dist/api/types.d.ts +201 -0
  40. package/dist/api/types.d.ts.map +1 -0
  41. package/dist/api/types.js +9 -0
  42. package/dist/api/types.js.map +1 -0
  43. package/dist/api/verify.d.ts +20 -0
  44. package/dist/api/verify.d.ts.map +1 -0
  45. package/dist/api/verify.js +117 -0
  46. package/dist/api/verify.js.map +1 -0
  47. package/dist/cli/commands/analyze.d.ts +30 -0
  48. package/dist/cli/commands/analyze.d.ts.map +1 -0
  49. package/dist/cli/commands/analyze.js +683 -0
  50. package/dist/cli/commands/analyze.js.map +1 -0
  51. package/dist/cli/commands/audit.d.ts +9 -0
  52. package/dist/cli/commands/audit.d.ts.map +1 -0
  53. package/dist/cli/commands/audit.js +98 -0
  54. package/dist/cli/commands/audit.js.map +1 -0
  55. package/dist/cli/commands/decisions.d.ts +16 -0
  56. package/dist/cli/commands/decisions.d.ts.map +1 -0
  57. package/dist/cli/commands/decisions.js +864 -0
  58. package/dist/cli/commands/decisions.js.map +1 -0
  59. package/dist/cli/commands/digest.d.ts +9 -0
  60. package/dist/cli/commands/digest.d.ts.map +1 -0
  61. package/dist/cli/commands/digest.js +61 -0
  62. package/dist/cli/commands/digest.js.map +1 -0
  63. package/dist/cli/commands/doctor.d.ts +9 -0
  64. package/dist/cli/commands/doctor.d.ts.map +1 -0
  65. package/dist/cli/commands/doctor.js +398 -0
  66. package/dist/cli/commands/doctor.js.map +1 -0
  67. package/dist/cli/commands/drift.d.ts +9 -0
  68. package/dist/cli/commands/drift.d.ts.map +1 -0
  69. package/dist/cli/commands/drift.js +550 -0
  70. package/dist/cli/commands/drift.js.map +1 -0
  71. package/dist/cli/commands/generate.d.ts +9 -0
  72. package/dist/cli/commands/generate.d.ts.map +1 -0
  73. package/dist/cli/commands/generate.js +565 -0
  74. package/dist/cli/commands/generate.js.map +1 -0
  75. package/dist/cli/commands/init.d.ts +9 -0
  76. package/dist/cli/commands/init.d.ts.map +1 -0
  77. package/dist/cli/commands/init.js +173 -0
  78. package/dist/cli/commands/init.js.map +1 -0
  79. package/dist/cli/commands/mcp.d.ts +2235 -0
  80. package/dist/cli/commands/mcp.d.ts.map +1 -0
  81. package/dist/cli/commands/mcp.js +1384 -0
  82. package/dist/cli/commands/mcp.js.map +1 -0
  83. package/dist/cli/commands/refresh-stories.d.ts +10 -0
  84. package/dist/cli/commands/refresh-stories.d.ts.map +1 -0
  85. package/dist/cli/commands/refresh-stories.js +314 -0
  86. package/dist/cli/commands/refresh-stories.js.map +1 -0
  87. package/dist/cli/commands/run.d.ts +9 -0
  88. package/dist/cli/commands/run.d.ts.map +1 -0
  89. package/dist/cli/commands/run.js +459 -0
  90. package/dist/cli/commands/run.js.map +1 -0
  91. package/dist/cli/commands/setup.d.ts +19 -0
  92. package/dist/cli/commands/setup.d.ts.map +1 -0
  93. package/dist/cli/commands/setup.js +355 -0
  94. package/dist/cli/commands/setup.js.map +1 -0
  95. package/dist/cli/commands/test.d.ts +22 -0
  96. package/dist/cli/commands/test.d.ts.map +1 -0
  97. package/dist/cli/commands/test.js +180 -0
  98. package/dist/cli/commands/test.js.map +1 -0
  99. package/dist/cli/commands/verify.d.ts +9 -0
  100. package/dist/cli/commands/verify.d.ts.map +1 -0
  101. package/dist/cli/commands/verify.js +383 -0
  102. package/dist/cli/commands/verify.js.map +1 -0
  103. package/dist/cli/commands/view.d.ts +13 -0
  104. package/dist/cli/commands/view.d.ts.map +1 -0
  105. package/dist/cli/commands/view.js +547 -0
  106. package/dist/cli/commands/view.js.map +1 -0
  107. package/dist/cli/index.d.ts +9 -0
  108. package/dist/cli/index.d.ts.map +1 -0
  109. package/dist/cli/index.js +118 -0
  110. package/dist/cli/index.js.map +1 -0
  111. package/dist/cli/tui-approval.d.ts +11 -0
  112. package/dist/cli/tui-approval.d.ts.map +1 -0
  113. package/dist/cli/tui-approval.js +129 -0
  114. package/dist/cli/tui-approval.js.map +1 -0
  115. package/dist/constants.d.ts +314 -0
  116. package/dist/constants.d.ts.map +1 -0
  117. package/dist/constants.js +382 -0
  118. package/dist/constants.js.map +1 -0
  119. package/dist/core/analyzer/ai-config-generator.d.ts +54 -0
  120. package/dist/core/analyzer/ai-config-generator.d.ts.map +1 -0
  121. package/dist/core/analyzer/ai-config-generator.js +98 -0
  122. package/dist/core/analyzer/ai-config-generator.js.map +1 -0
  123. package/dist/core/analyzer/architecture-writer.d.ts +67 -0
  124. package/dist/core/analyzer/architecture-writer.d.ts.map +1 -0
  125. package/dist/core/analyzer/architecture-writer.js +209 -0
  126. package/dist/core/analyzer/architecture-writer.js.map +1 -0
  127. package/dist/core/analyzer/artifact-generator.d.ts +261 -0
  128. package/dist/core/analyzer/artifact-generator.d.ts.map +1 -0
  129. package/dist/core/analyzer/artifact-generator.js +909 -0
  130. package/dist/core/analyzer/artifact-generator.js.map +1 -0
  131. package/dist/core/analyzer/ast-chunker.d.ts +24 -0
  132. package/dist/core/analyzer/ast-chunker.d.ts.map +1 -0
  133. package/dist/core/analyzer/ast-chunker.js +198 -0
  134. package/dist/core/analyzer/ast-chunker.js.map +1 -0
  135. package/dist/core/analyzer/call-graph.d.ts +162 -0
  136. package/dist/core/analyzer/call-graph.d.ts.map +1 -0
  137. package/dist/core/analyzer/call-graph.js +2040 -0
  138. package/dist/core/analyzer/call-graph.js.map +1 -0
  139. package/dist/core/analyzer/code-shaper.d.ts +33 -0
  140. package/dist/core/analyzer/code-shaper.d.ts.map +1 -0
  141. package/dist/core/analyzer/code-shaper.js +154 -0
  142. package/dist/core/analyzer/code-shaper.js.map +1 -0
  143. package/dist/core/analyzer/codebase-digest.d.ts +40 -0
  144. package/dist/core/analyzer/codebase-digest.d.ts.map +1 -0
  145. package/dist/core/analyzer/codebase-digest.js +195 -0
  146. package/dist/core/analyzer/codebase-digest.js.map +1 -0
  147. package/dist/core/analyzer/cpp-header-resolver.d.ts +30 -0
  148. package/dist/core/analyzer/cpp-header-resolver.d.ts.map +1 -0
  149. package/dist/core/analyzer/cpp-header-resolver.js +71 -0
  150. package/dist/core/analyzer/cpp-header-resolver.js.map +1 -0
  151. package/dist/core/analyzer/dependency-graph.d.ts +230 -0
  152. package/dist/core/analyzer/dependency-graph.d.ts.map +1 -0
  153. package/dist/core/analyzer/dependency-graph.js +752 -0
  154. package/dist/core/analyzer/dependency-graph.js.map +1 -0
  155. package/dist/core/analyzer/duplicate-detector.d.ts +52 -0
  156. package/dist/core/analyzer/duplicate-detector.d.ts.map +1 -0
  157. package/dist/core/analyzer/duplicate-detector.js +289 -0
  158. package/dist/core/analyzer/duplicate-detector.js.map +1 -0
  159. package/dist/core/analyzer/embedding-service.d.ts +56 -0
  160. package/dist/core/analyzer/embedding-service.d.ts.map +1 -0
  161. package/dist/core/analyzer/embedding-service.js +118 -0
  162. package/dist/core/analyzer/embedding-service.js.map +1 -0
  163. package/dist/core/analyzer/env-extractor.d.ts +33 -0
  164. package/dist/core/analyzer/env-extractor.d.ts.map +1 -0
  165. package/dist/core/analyzer/env-extractor.js +196 -0
  166. package/dist/core/analyzer/env-extractor.js.map +1 -0
  167. package/dist/core/analyzer/external-packages.d.ts +20 -0
  168. package/dist/core/analyzer/external-packages.d.ts.map +1 -0
  169. package/dist/core/analyzer/external-packages.js +175 -0
  170. package/dist/core/analyzer/external-packages.js.map +1 -0
  171. package/dist/core/analyzer/file-walker.d.ts +78 -0
  172. package/dist/core/analyzer/file-walker.d.ts.map +1 -0
  173. package/dist/core/analyzer/file-walker.js +532 -0
  174. package/dist/core/analyzer/file-walker.js.map +1 -0
  175. package/dist/core/analyzer/function-registry-trie.d.ts +21 -0
  176. package/dist/core/analyzer/function-registry-trie.d.ts.map +1 -0
  177. package/dist/core/analyzer/function-registry-trie.js +39 -0
  178. package/dist/core/analyzer/function-registry-trie.js.map +1 -0
  179. package/dist/core/analyzer/http-route-parser.d.ts +152 -0
  180. package/dist/core/analyzer/http-route-parser.d.ts.map +1 -0
  181. package/dist/core/analyzer/http-route-parser.js +971 -0
  182. package/dist/core/analyzer/http-route-parser.js.map +1 -0
  183. package/dist/core/analyzer/import-parser.d.ts +100 -0
  184. package/dist/core/analyzer/import-parser.d.ts.map +1 -0
  185. package/dist/core/analyzer/import-parser.js +952 -0
  186. package/dist/core/analyzer/import-parser.js.map +1 -0
  187. package/dist/core/analyzer/import-resolver-bridge.d.ts +25 -0
  188. package/dist/core/analyzer/import-resolver-bridge.d.ts.map +1 -0
  189. package/dist/core/analyzer/import-resolver-bridge.js +99 -0
  190. package/dist/core/analyzer/import-resolver-bridge.js.map +1 -0
  191. package/dist/core/analyzer/index.d.ts +10 -0
  192. package/dist/core/analyzer/index.d.ts.map +1 -0
  193. package/dist/core/analyzer/index.js +10 -0
  194. package/dist/core/analyzer/index.js.map +1 -0
  195. package/dist/core/analyzer/middleware-extractor.d.ts +29 -0
  196. package/dist/core/analyzer/middleware-extractor.d.ts.map +1 -0
  197. package/dist/core/analyzer/middleware-extractor.js +195 -0
  198. package/dist/core/analyzer/middleware-extractor.js.map +1 -0
  199. package/dist/core/analyzer/refactor-analyzer.d.ts +83 -0
  200. package/dist/core/analyzer/refactor-analyzer.d.ts.map +1 -0
  201. package/dist/core/analyzer/refactor-analyzer.js +351 -0
  202. package/dist/core/analyzer/refactor-analyzer.js.map +1 -0
  203. package/dist/core/analyzer/repository-mapper.d.ts +150 -0
  204. package/dist/core/analyzer/repository-mapper.d.ts.map +1 -0
  205. package/dist/core/analyzer/repository-mapper.js +740 -0
  206. package/dist/core/analyzer/repository-mapper.js.map +1 -0
  207. package/dist/core/analyzer/schema-extractor.d.ts +41 -0
  208. package/dist/core/analyzer/schema-extractor.d.ts.map +1 -0
  209. package/dist/core/analyzer/schema-extractor.js +229 -0
  210. package/dist/core/analyzer/schema-extractor.js.map +1 -0
  211. package/dist/core/analyzer/signature-extractor.d.ts +31 -0
  212. package/dist/core/analyzer/signature-extractor.d.ts.map +1 -0
  213. package/dist/core/analyzer/signature-extractor.js +675 -0
  214. package/dist/core/analyzer/signature-extractor.js.map +1 -0
  215. package/dist/core/analyzer/significance-scorer.d.ts +79 -0
  216. package/dist/core/analyzer/significance-scorer.d.ts.map +1 -0
  217. package/dist/core/analyzer/significance-scorer.js +407 -0
  218. package/dist/core/analyzer/significance-scorer.js.map +1 -0
  219. package/dist/core/analyzer/spec-snapshot-generator.d.ts +17 -0
  220. package/dist/core/analyzer/spec-snapshot-generator.d.ts.map +1 -0
  221. package/dist/core/analyzer/spec-snapshot-generator.js +201 -0
  222. package/dist/core/analyzer/spec-snapshot-generator.js.map +1 -0
  223. package/dist/core/analyzer/spec-vector-index.d.ts +68 -0
  224. package/dist/core/analyzer/spec-vector-index.d.ts.map +1 -0
  225. package/dist/core/analyzer/spec-vector-index.js +340 -0
  226. package/dist/core/analyzer/spec-vector-index.js.map +1 -0
  227. package/dist/core/analyzer/subgraph-extractor.d.ts +51 -0
  228. package/dist/core/analyzer/subgraph-extractor.d.ts.map +1 -0
  229. package/dist/core/analyzer/subgraph-extractor.js +147 -0
  230. package/dist/core/analyzer/subgraph-extractor.js.map +1 -0
  231. package/dist/core/analyzer/type-inference-engine.d.ts +23 -0
  232. package/dist/core/analyzer/type-inference-engine.d.ts.map +1 -0
  233. package/dist/core/analyzer/type-inference-engine.js +130 -0
  234. package/dist/core/analyzer/type-inference-engine.js.map +1 -0
  235. package/dist/core/analyzer/ui-component-extractor.d.ts +43 -0
  236. package/dist/core/analyzer/ui-component-extractor.d.ts.map +1 -0
  237. package/dist/core/analyzer/ui-component-extractor.js +245 -0
  238. package/dist/core/analyzer/ui-component-extractor.js.map +1 -0
  239. package/dist/core/analyzer/unified-search.d.ts +116 -0
  240. package/dist/core/analyzer/unified-search.d.ts.map +1 -0
  241. package/dist/core/analyzer/unified-search.js +231 -0
  242. package/dist/core/analyzer/unified-search.js.map +1 -0
  243. package/dist/core/analyzer/vector-index.d.ts +92 -0
  244. package/dist/core/analyzer/vector-index.d.ts.map +1 -0
  245. package/dist/core/analyzer/vector-index.js +451 -0
  246. package/dist/core/analyzer/vector-index.js.map +1 -0
  247. package/dist/core/decisions/consolidator.d.ts +14 -0
  248. package/dist/core/decisions/consolidator.d.ts.map +1 -0
  249. package/dist/core/decisions/consolidator.js +169 -0
  250. package/dist/core/decisions/consolidator.js.map +1 -0
  251. package/dist/core/decisions/extractor.d.ts +26 -0
  252. package/dist/core/decisions/extractor.d.ts.map +1 -0
  253. package/dist/core/decisions/extractor.js +156 -0
  254. package/dist/core/decisions/extractor.js.map +1 -0
  255. package/dist/core/decisions/index.d.ts +19 -0
  256. package/dist/core/decisions/index.d.ts.map +1 -0
  257. package/dist/core/decisions/index.js +16 -0
  258. package/dist/core/decisions/index.js.map +1 -0
  259. package/dist/core/decisions/store.d.ts +36 -0
  260. package/dist/core/decisions/store.d.ts.map +1 -0
  261. package/dist/core/decisions/store.js +109 -0
  262. package/dist/core/decisions/store.js.map +1 -0
  263. package/dist/core/decisions/syncer.d.ts +27 -0
  264. package/dist/core/decisions/syncer.d.ts.map +1 -0
  265. package/dist/core/decisions/syncer.js +214 -0
  266. package/dist/core/decisions/syncer.js.map +1 -0
  267. package/dist/core/decisions/verifier.d.ts +20 -0
  268. package/dist/core/decisions/verifier.d.ts.map +1 -0
  269. package/dist/core/decisions/verifier.js +115 -0
  270. package/dist/core/decisions/verifier.js.map +1 -0
  271. package/dist/core/digest/digest-generator.d.ts +29 -0
  272. package/dist/core/digest/digest-generator.d.ts.map +1 -0
  273. package/dist/core/digest/digest-generator.js +181 -0
  274. package/dist/core/digest/digest-generator.js.map +1 -0
  275. package/dist/core/drift/drift-detector.d.ts +102 -0
  276. package/dist/core/drift/drift-detector.d.ts.map +1 -0
  277. package/dist/core/drift/drift-detector.js +598 -0
  278. package/dist/core/drift/drift-detector.js.map +1 -0
  279. package/dist/core/drift/git-diff.d.ts +60 -0
  280. package/dist/core/drift/git-diff.d.ts.map +1 -0
  281. package/dist/core/drift/git-diff.js +383 -0
  282. package/dist/core/drift/git-diff.js.map +1 -0
  283. package/dist/core/drift/index.d.ts +12 -0
  284. package/dist/core/drift/index.d.ts.map +1 -0
  285. package/dist/core/drift/index.js +9 -0
  286. package/dist/core/drift/index.js.map +1 -0
  287. package/dist/core/drift/spec-mapper.d.ts +73 -0
  288. package/dist/core/drift/spec-mapper.d.ts.map +1 -0
  289. package/dist/core/drift/spec-mapper.js +353 -0
  290. package/dist/core/drift/spec-mapper.js.map +1 -0
  291. package/dist/core/drift/test-suggester.d.ts +18 -0
  292. package/dist/core/drift/test-suggester.d.ts.map +1 -0
  293. package/dist/core/drift/test-suggester.js +107 -0
  294. package/dist/core/drift/test-suggester.js.map +1 -0
  295. package/dist/core/generator/adr-generator.d.ts +32 -0
  296. package/dist/core/generator/adr-generator.d.ts.map +1 -0
  297. package/dist/core/generator/adr-generator.js +192 -0
  298. package/dist/core/generator/adr-generator.js.map +1 -0
  299. package/dist/core/generator/index.d.ts +9 -0
  300. package/dist/core/generator/index.d.ts.map +1 -0
  301. package/dist/core/generator/index.js +12 -0
  302. package/dist/core/generator/index.js.map +1 -0
  303. package/dist/core/generator/mapping-generator.d.ts +54 -0
  304. package/dist/core/generator/mapping-generator.d.ts.map +1 -0
  305. package/dist/core/generator/mapping-generator.js +240 -0
  306. package/dist/core/generator/mapping-generator.js.map +1 -0
  307. package/dist/core/generator/openspec-compat.d.ts +160 -0
  308. package/dist/core/generator/openspec-compat.d.ts.map +1 -0
  309. package/dist/core/generator/openspec-compat.js +524 -0
  310. package/dist/core/generator/openspec-compat.js.map +1 -0
  311. package/dist/core/generator/openspec-format-generator.d.ts +131 -0
  312. package/dist/core/generator/openspec-format-generator.d.ts.map +1 -0
  313. package/dist/core/generator/openspec-format-generator.js +963 -0
  314. package/dist/core/generator/openspec-format-generator.js.map +1 -0
  315. package/dist/core/generator/openspec-writer.d.ts +130 -0
  316. package/dist/core/generator/openspec-writer.d.ts.map +1 -0
  317. package/dist/core/generator/openspec-writer.js +404 -0
  318. package/dist/core/generator/openspec-writer.js.map +1 -0
  319. package/dist/core/generator/prompts.d.ts +35 -0
  320. package/dist/core/generator/prompts.d.ts.map +1 -0
  321. package/dist/core/generator/prompts.js +212 -0
  322. package/dist/core/generator/prompts.js.map +1 -0
  323. package/dist/core/generator/rag-manifest-generator.d.ts +37 -0
  324. package/dist/core/generator/rag-manifest-generator.d.ts.map +1 -0
  325. package/dist/core/generator/rag-manifest-generator.js +134 -0
  326. package/dist/core/generator/rag-manifest-generator.js.map +1 -0
  327. package/dist/core/generator/schemas.d.ts +365 -0
  328. package/dist/core/generator/schemas.d.ts.map +1 -0
  329. package/dist/core/generator/schemas.js +190 -0
  330. package/dist/core/generator/schemas.js.map +1 -0
  331. package/dist/core/generator/spec-pipeline.d.ts +123 -0
  332. package/dist/core/generator/spec-pipeline.d.ts.map +1 -0
  333. package/dist/core/generator/spec-pipeline.js +699 -0
  334. package/dist/core/generator/spec-pipeline.js.map +1 -0
  335. package/dist/core/generator/stages/stage1-survey.d.ts +19 -0
  336. package/dist/core/generator/stages/stage1-survey.d.ts.map +1 -0
  337. package/dist/core/generator/stages/stage1-survey.js +171 -0
  338. package/dist/core/generator/stages/stage1-survey.js.map +1 -0
  339. package/dist/core/generator/stages/stage2-entities.d.ts +11 -0
  340. package/dist/core/generator/stages/stage2-entities.d.ts.map +1 -0
  341. package/dist/core/generator/stages/stage2-entities.js +74 -0
  342. package/dist/core/generator/stages/stage2-entities.js.map +1 -0
  343. package/dist/core/generator/stages/stage3-services.d.ts +11 -0
  344. package/dist/core/generator/stages/stage3-services.d.ts.map +1 -0
  345. package/dist/core/generator/stages/stage3-services.js +85 -0
  346. package/dist/core/generator/stages/stage3-services.js.map +1 -0
  347. package/dist/core/generator/stages/stage4-api.d.ts +11 -0
  348. package/dist/core/generator/stages/stage4-api.d.ts.map +1 -0
  349. package/dist/core/generator/stages/stage4-api.js +72 -0
  350. package/dist/core/generator/stages/stage4-api.js.map +1 -0
  351. package/dist/core/generator/stages/stage5-architecture.d.ts +11 -0
  352. package/dist/core/generator/stages/stage5-architecture.d.ts.map +1 -0
  353. package/dist/core/generator/stages/stage5-architecture.js +75 -0
  354. package/dist/core/generator/stages/stage5-architecture.js.map +1 -0
  355. package/dist/core/generator/stages/stage6-adr.d.ts +8 -0
  356. package/dist/core/generator/stages/stage6-adr.d.ts.map +1 -0
  357. package/dist/core/generator/stages/stage6-adr.js +47 -0
  358. package/dist/core/generator/stages/stage6-adr.js.map +1 -0
  359. package/dist/core/services/chat-agent.d.ts +50 -0
  360. package/dist/core/services/chat-agent.d.ts.map +1 -0
  361. package/dist/core/services/chat-agent.js +369 -0
  362. package/dist/core/services/chat-agent.js.map +1 -0
  363. package/dist/core/services/chat-tools.d.ts +32 -0
  364. package/dist/core/services/chat-tools.d.ts.map +1 -0
  365. package/dist/core/services/chat-tools.js +494 -0
  366. package/dist/core/services/chat-tools.js.map +1 -0
  367. package/dist/core/services/config-manager.d.ts +61 -0
  368. package/dist/core/services/config-manager.d.ts.map +1 -0
  369. package/dist/core/services/config-manager.js +149 -0
  370. package/dist/core/services/config-manager.js.map +1 -0
  371. package/dist/core/services/edge-store.d.ts +57 -0
  372. package/dist/core/services/edge-store.d.ts.map +1 -0
  373. package/dist/core/services/edge-store.js +419 -0
  374. package/dist/core/services/edge-store.js.map +1 -0
  375. package/dist/core/services/gitignore-manager.d.ts +29 -0
  376. package/dist/core/services/gitignore-manager.d.ts.map +1 -0
  377. package/dist/core/services/gitignore-manager.js +95 -0
  378. package/dist/core/services/gitignore-manager.js.map +1 -0
  379. package/dist/core/services/index.d.ts +8 -0
  380. package/dist/core/services/index.d.ts.map +1 -0
  381. package/dist/core/services/index.js +8 -0
  382. package/dist/core/services/index.js.map +1 -0
  383. package/dist/core/services/llm-service.d.ts +379 -0
  384. package/dist/core/services/llm-service.d.ts.map +1 -0
  385. package/dist/core/services/llm-service.js +1553 -0
  386. package/dist/core/services/llm-service.js.map +1 -0
  387. package/dist/core/services/mcp-handlers/analysis.d.ts +127 -0
  388. package/dist/core/services/mcp-handlers/analysis.d.ts.map +1 -0
  389. package/dist/core/services/mcp-handlers/analysis.js +1185 -0
  390. package/dist/core/services/mcp-handlers/analysis.js.map +1 -0
  391. package/dist/core/services/mcp-handlers/change.d.ts +14 -0
  392. package/dist/core/services/mcp-handlers/change.d.ts.map +1 -0
  393. package/dist/core/services/mcp-handlers/change.js +416 -0
  394. package/dist/core/services/mcp-handlers/change.js.map +1 -0
  395. package/dist/core/services/mcp-handlers/decisions.d.ts +16 -0
  396. package/dist/core/services/mcp-handlers/decisions.d.ts.map +1 -0
  397. package/dist/core/services/mcp-handlers/decisions.js +239 -0
  398. package/dist/core/services/mcp-handlers/decisions.js.map +1 -0
  399. package/dist/core/services/mcp-handlers/graph.d.ts +94 -0
  400. package/dist/core/services/mcp-handlers/graph.d.ts.map +1 -0
  401. package/dist/core/services/mcp-handlers/graph.js +693 -0
  402. package/dist/core/services/mcp-handlers/graph.js.map +1 -0
  403. package/dist/core/services/mcp-handlers/orient.d.ts +17 -0
  404. package/dist/core/services/mcp-handlers/orient.d.ts.map +1 -0
  405. package/dist/core/services/mcp-handlers/orient.js +357 -0
  406. package/dist/core/services/mcp-handlers/orient.js.map +1 -0
  407. package/dist/core/services/mcp-handlers/semantic.d.ts +66 -0
  408. package/dist/core/services/mcp-handlers/semantic.d.ts.map +1 -0
  409. package/dist/core/services/mcp-handlers/semantic.js +432 -0
  410. package/dist/core/services/mcp-handlers/semantic.js.map +1 -0
  411. package/dist/core/services/mcp-handlers/utils.d.ts +85 -0
  412. package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -0
  413. package/dist/core/services/mcp-handlers/utils.js +262 -0
  414. package/dist/core/services/mcp-handlers/utils.js.map +1 -0
  415. package/dist/core/services/mcp-watcher.d.ts +41 -0
  416. package/dist/core/services/mcp-watcher.d.ts.map +1 -0
  417. package/dist/core/services/mcp-watcher.js +254 -0
  418. package/dist/core/services/mcp-watcher.js.map +1 -0
  419. package/dist/core/services/project-detector.d.ts +32 -0
  420. package/dist/core/services/project-detector.d.ts.map +1 -0
  421. package/dist/core/services/project-detector.js +100 -0
  422. package/dist/core/services/project-detector.js.map +1 -0
  423. package/dist/core/test-generator/coverage-analyzer.d.ts +27 -0
  424. package/dist/core/test-generator/coverage-analyzer.d.ts.map +1 -0
  425. package/dist/core/test-generator/coverage-analyzer.js +285 -0
  426. package/dist/core/test-generator/coverage-analyzer.js.map +1 -0
  427. package/dist/core/test-generator/framework-detector.d.ts +17 -0
  428. package/dist/core/test-generator/framework-detector.d.ts.map +1 -0
  429. package/dist/core/test-generator/framework-detector.js +65 -0
  430. package/dist/core/test-generator/framework-detector.js.map +1 -0
  431. package/dist/core/test-generator/index.d.ts +14 -0
  432. package/dist/core/test-generator/index.d.ts.map +1 -0
  433. package/dist/core/test-generator/index.js +11 -0
  434. package/dist/core/test-generator/index.js.map +1 -0
  435. package/dist/core/test-generator/renderers/catch2.d.ts +8 -0
  436. package/dist/core/test-generator/renderers/catch2.d.ts.map +1 -0
  437. package/dist/core/test-generator/renderers/catch2.js +47 -0
  438. package/dist/core/test-generator/renderers/catch2.js.map +1 -0
  439. package/dist/core/test-generator/renderers/gtest.d.ts +8 -0
  440. package/dist/core/test-generator/renderers/gtest.d.ts.map +1 -0
  441. package/dist/core/test-generator/renderers/gtest.js +45 -0
  442. package/dist/core/test-generator/renderers/gtest.js.map +1 -0
  443. package/dist/core/test-generator/renderers/index.d.ts +20 -0
  444. package/dist/core/test-generator/renderers/index.d.ts.map +1 -0
  445. package/dist/core/test-generator/renderers/index.js +35 -0
  446. package/dist/core/test-generator/renderers/index.js.map +1 -0
  447. package/dist/core/test-generator/renderers/playwright.d.ts +8 -0
  448. package/dist/core/test-generator/renderers/playwright.d.ts.map +1 -0
  449. package/dist/core/test-generator/renderers/playwright.js +44 -0
  450. package/dist/core/test-generator/renderers/playwright.js.map +1 -0
  451. package/dist/core/test-generator/renderers/pytest.d.ts +8 -0
  452. package/dist/core/test-generator/renderers/pytest.d.ts.map +1 -0
  453. package/dist/core/test-generator/renderers/pytest.js +44 -0
  454. package/dist/core/test-generator/renderers/pytest.js.map +1 -0
  455. package/dist/core/test-generator/renderers/shared.d.ts +21 -0
  456. package/dist/core/test-generator/renderers/shared.d.ts.map +1 -0
  457. package/dist/core/test-generator/renderers/shared.js +56 -0
  458. package/dist/core/test-generator/renderers/shared.js.map +1 -0
  459. package/dist/core/test-generator/renderers/vitest.d.ts +8 -0
  460. package/dist/core/test-generator/renderers/vitest.d.ts.map +1 -0
  461. package/dist/core/test-generator/renderers/vitest.js +52 -0
  462. package/dist/core/test-generator/renderers/vitest.js.map +1 -0
  463. package/dist/core/test-generator/scenario-parser.d.ts +33 -0
  464. package/dist/core/test-generator/scenario-parser.d.ts.map +1 -0
  465. package/dist/core/test-generator/scenario-parser.js +244 -0
  466. package/dist/core/test-generator/scenario-parser.js.map +1 -0
  467. package/dist/core/test-generator/test-generator.d.ts +30 -0
  468. package/dist/core/test-generator/test-generator.d.ts.map +1 -0
  469. package/dist/core/test-generator/test-generator.js +174 -0
  470. package/dist/core/test-generator/test-generator.js.map +1 -0
  471. package/dist/core/test-generator/test-writer.d.ts +25 -0
  472. package/dist/core/test-generator/test-writer.d.ts.map +1 -0
  473. package/dist/core/test-generator/test-writer.js +128 -0
  474. package/dist/core/test-generator/test-writer.js.map +1 -0
  475. package/dist/core/test-generator/then-matchers.d.ts +35 -0
  476. package/dist/core/test-generator/then-matchers.d.ts.map +1 -0
  477. package/dist/core/test-generator/then-matchers.js +211 -0
  478. package/dist/core/test-generator/then-matchers.js.map +1 -0
  479. package/dist/core/verifier/index.d.ts +5 -0
  480. package/dist/core/verifier/index.d.ts.map +1 -0
  481. package/dist/core/verifier/index.js +5 -0
  482. package/dist/core/verifier/index.js.map +1 -0
  483. package/dist/core/verifier/verification-engine.d.ts +293 -0
  484. package/dist/core/verifier/verification-engine.d.ts.map +1 -0
  485. package/dist/core/verifier/verification-engine.js +919 -0
  486. package/dist/core/verifier/verification-engine.js.map +1 -0
  487. package/dist/types/index.d.ts +368 -0
  488. package/dist/types/index.d.ts.map +1 -0
  489. package/dist/types/index.js +5 -0
  490. package/dist/types/index.js.map +1 -0
  491. package/dist/types/pipeline.d.ts +167 -0
  492. package/dist/types/pipeline.d.ts.map +1 -0
  493. package/dist/types/pipeline.js +5 -0
  494. package/dist/types/pipeline.js.map +1 -0
  495. package/dist/types/test-generator.d.ts +103 -0
  496. package/dist/types/test-generator.d.ts.map +1 -0
  497. package/dist/types/test-generator.js +17 -0
  498. package/dist/types/test-generator.js.map +1 -0
  499. package/dist/utils/command-helpers.d.ts +68 -0
  500. package/dist/utils/command-helpers.d.ts.map +1 -0
  501. package/dist/utils/command-helpers.js +150 -0
  502. package/dist/utils/command-helpers.js.map +1 -0
  503. package/dist/utils/errors.d.ts +51 -0
  504. package/dist/utils/errors.d.ts.map +1 -0
  505. package/dist/utils/errors.js +129 -0
  506. package/dist/utils/errors.js.map +1 -0
  507. package/dist/utils/logger.d.ts +149 -0
  508. package/dist/utils/logger.d.ts.map +1 -0
  509. package/dist/utils/logger.js +342 -0
  510. package/dist/utils/logger.js.map +1 -0
  511. package/dist/utils/misc.d.ts +10 -0
  512. package/dist/utils/misc.d.ts.map +1 -0
  513. package/dist/utils/misc.js +21 -0
  514. package/dist/utils/misc.js.map +1 -0
  515. package/dist/utils/progress.d.ts +142 -0
  516. package/dist/utils/progress.d.ts.map +1 -0
  517. package/dist/utils/progress.js +283 -0
  518. package/dist/utils/progress.js.map +1 -0
  519. package/dist/utils/prompts.d.ts +53 -0
  520. package/dist/utils/prompts.d.ts.map +1 -0
  521. package/dist/utils/prompts.js +199 -0
  522. package/dist/utils/prompts.js.map +1 -0
  523. package/dist/utils/shutdown.d.ts +89 -0
  524. package/dist/utils/shutdown.d.ts.map +1 -0
  525. package/dist/utils/shutdown.js +238 -0
  526. package/dist/utils/shutdown.js.map +1 -0
  527. package/examples/bmad/README.md +113 -0
  528. package/examples/bmad/agents/architect.md +226 -0
  529. package/examples/bmad/agents/dev-brownfield.md +69 -0
  530. package/examples/bmad/setup/architect.customize.yaml +14 -0
  531. package/examples/bmad/tasks/implement-story.md +254 -0
  532. package/examples/bmad/tasks/onboarding.md +169 -0
  533. package/examples/bmad/tasks/refactor.md +178 -0
  534. package/examples/bmad/tasks/sprint-planning.md +168 -0
  535. package/examples/bmad/templates/story.md +108 -0
  536. package/examples/cline-workflows/openlore-analyze-codebase.md +101 -0
  537. package/examples/cline-workflows/openlore-check-spec-drift.md +102 -0
  538. package/examples/cline-workflows/openlore-execute-refactor.md +212 -0
  539. package/examples/cline-workflows/openlore-implement-feature.md +266 -0
  540. package/examples/cline-workflows/openlore-plan-refactor.md +279 -0
  541. package/examples/cline-workflows/openlore-refactor-codebase.md +16 -0
  542. package/examples/cline-workflows/openlore-write-tests.md +177 -0
  543. package/examples/drift-demo/openspec/config.yaml +14 -0
  544. package/examples/drift-demo/openspec/specs/architecture/spec.md +30 -0
  545. package/examples/drift-demo/openspec/specs/auth/spec.md +71 -0
  546. package/examples/drift-demo/openspec/specs/database/spec.md +33 -0
  547. package/examples/drift-demo/openspec/specs/overview/spec.md +20 -0
  548. package/examples/drift-demo/openspec/specs/projects/spec.md +55 -0
  549. package/examples/drift-demo/openspec/specs/tasks/spec.md +78 -0
  550. package/examples/drift-demo/package.json +21 -0
  551. package/examples/drift-demo/src/auth/auth-middleware.ts +30 -0
  552. package/examples/drift-demo/src/auth/auth-routes.ts +29 -0
  553. package/examples/drift-demo/src/auth/auth-service.ts +45 -0
  554. package/examples/drift-demo/src/database/connection.ts +27 -0
  555. package/examples/drift-demo/src/index.ts +16 -0
  556. package/examples/drift-demo/src/projects/project-model.ts +15 -0
  557. package/examples/drift-demo/src/projects/project-service.ts +34 -0
  558. package/examples/drift-demo/src/tasks/task-model.ts +37 -0
  559. package/examples/drift-demo/src/tasks/task-routes.ts +53 -0
  560. package/examples/drift-demo/src/tasks/task-service.ts +60 -0
  561. package/examples/drift-demo/src/utils/validation.ts +11 -0
  562. package/examples/drift-demo/tests/auth.test.ts +4 -0
  563. package/examples/drift-demo/tests/tasks.test.ts +4 -0
  564. package/examples/drift-demo/tsconfig.json +10 -0
  565. package/examples/drift-test/run-drift-test.sh +1087 -0
  566. package/examples/gsd/README.md +119 -0
  567. package/examples/gsd/commands/gsd/openlore-drift.md +111 -0
  568. package/examples/gsd/commands/gsd/openlore-orient.md +191 -0
  569. package/examples/mistral-vibe/README.md +101 -0
  570. package/examples/mistral-vibe/antipatterns-template.md +18 -0
  571. package/examples/mistral-vibe/skills/openlore-analyze-codebase/SKILL.md +124 -0
  572. package/examples/mistral-vibe/skills/openlore-brainstorm/SKILL.md +379 -0
  573. package/examples/mistral-vibe/skills/openlore-debug/SKILL.md +330 -0
  574. package/examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md +291 -0
  575. package/examples/mistral-vibe/skills/openlore-generate/SKILL.md +245 -0
  576. package/examples/mistral-vibe/skills/openlore-implement-story/SKILL.md +326 -0
  577. package/examples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md +365 -0
  578. package/examples/mistral-vibe/skills/openlore-review-changes/SKILL.md +128 -0
  579. package/examples/mistral-vibe/skills/openlore-write-tests/SKILL.md +261 -0
  580. package/examples/opencode/agent-guard.ts +170 -0
  581. package/examples/opencode/plugins/anti-laziness.ts +202 -0
  582. package/examples/opencode/plugins/lib/openlore-context-injector-helpers.ts +116 -0
  583. package/examples/opencode/plugins/lib/openlore-decision-extractor-helpers.ts +65 -0
  584. package/examples/opencode/plugins/openlore-context-injector.test.ts +211 -0
  585. package/examples/opencode/plugins/openlore-context-injector.ts +165 -0
  586. package/examples/opencode/plugins/openlore-decision-extractor.test.ts +131 -0
  587. package/examples/opencode/plugins/openlore-decision-extractor.ts +322 -0
  588. package/examples/opencode/plugins/openlore-enforcer.ts +227 -0
  589. package/examples/opencode/prompts/sisyphus-sdd.md +150 -0
  590. package/examples/opencode-skills/openlore-analyze-codebase/SKILL.md +101 -0
  591. package/examples/opencode-skills/openlore-brainstorm/SKILL.md +354 -0
  592. package/examples/opencode-skills/openlore-debug/SKILL.md +291 -0
  593. package/examples/opencode-skills/openlore-execute-refactor/SKILL.md +241 -0
  594. package/examples/opencode-skills/openlore-generate/SKILL.md +236 -0
  595. package/examples/opencode-skills/openlore-implement-story/SKILL.md +251 -0
  596. package/examples/opencode-skills/openlore-plan-refactor/SKILL.md +298 -0
  597. package/examples/opencode-skills/openlore-review-changes/SKILL.md +134 -0
  598. package/examples/opencode-skills/openlore-write-tests/SKILL.md +230 -0
  599. package/examples/openspec-analysis/README.md +59 -0
  600. package/examples/openspec-analysis/SUMMARY.md +72 -0
  601. package/examples/openspec-analysis/config.json +16 -0
  602. package/examples/openspec-analysis/dependencies.mermaid +35 -0
  603. package/examples/openspec-analysis/dependency-graph.json +12116 -0
  604. package/examples/openspec-analysis/llm-context.json +119 -0
  605. package/examples/openspec-analysis/repo-structure.json +871 -0
  606. package/examples/openspec-cli/README.md +67 -0
  607. package/examples/openspec-cli/openspec/config.yaml +26 -0
  608. package/examples/openspec-cli/openspec/specs/architecture/spec.md +178 -0
  609. package/examples/openspec-cli/openspec/specs/artifact-graph/spec.md +143 -0
  610. package/examples/openspec-cli/openspec/specs/cli/spec.md +138 -0
  611. package/examples/openspec-cli/openspec/specs/overview/spec.md +60 -0
  612. package/examples/openspec-cli/openspec/specs/parsing/spec.md +123 -0
  613. package/examples/openspec-cli/openspec/specs/validation/spec.md +108 -0
  614. package/examples/spec-kit/README.md +104 -0
  615. package/examples/spec-kit/commands/drift.md +87 -0
  616. package/examples/spec-kit/commands/orient.md +138 -0
  617. package/examples/spec-kit/extension.yml +54 -0
  618. package/package.json +125 -0
  619. package/src/viewer/InteractiveGraphViewer.jsx +1600 -0
  620. package/src/viewer/app/index.html +17 -0
  621. package/src/viewer/app/main.jsx +13 -0
  622. package/src/viewer/components/ArchitectureView.jsx +177 -0
  623. package/src/viewer/components/ChatPanel.jsx +450 -0
  624. package/src/viewer/components/ClassGraph.jsx +782 -0
  625. package/src/viewer/components/ClusterGraph.jsx +469 -0
  626. package/src/viewer/components/FilterBar.jsx +179 -0
  627. package/src/viewer/components/FlatGraph.jsx +282 -0
  628. package/src/viewer/components/MicroComponents.jsx +85 -0
  629. package/src/viewer/hooks/usePanZoom.js +79 -0
  630. package/src/viewer/utils/constants.js +64 -0
  631. package/src/viewer/utils/graph-helpers.js +303 -0
  632. package/src/viewer/utils/graph-helpers.test.ts +39 -0
  633. package/src/viewer/utils/themes.js +206 -0
  634. package/stubs/tree-sitter-cli-stub/package.json +6 -0
@@ -0,0 +1,909 @@
1
+ /**
2
+ * Analysis Artifact Generator
3
+ *
4
+ * Takes all analysis results and generates structured output files
5
+ * that will be consumed by the LLM generation phase and optionally by humans.
6
+ */
7
+ import { writeFile, mkdir, readFile } from 'node:fs/promises';
8
+ import { join, basename } from 'node:path';
9
+ import { TOKENS_PER_CHAR_DEFAULT, PHASE2_FILE_CONTENT_MAX_CHARS, PHASE3_FILE_CONTENT_MAX_CHARS, DEPENDENCY_DIAGRAM_MAX_FILES, ARTIFACT_REPO_STRUCTURE, ARTIFACT_LLM_CONTEXT, ARTIFACT_MAPPING, ARTIFACT_REFACTOR_PRIORITIES, ARTIFACT_SCHEMA_INVENTORY, ARTIFACT_ROUTE_INVENTORY, ARTIFACT_UI_INVENTORY, ARTIFACT_CALL_GRAPH_DB, } from '../../constants.js';
10
+ import { toMermaidFormat, injectCallGraphEdges, IMPLICIT_IMPORT_LANGS } from './dependency-graph.js';
11
+ /**
12
+ * Heuristic to detect test/spec files across languages.
13
+ * Excludes them from call graph analysis — test helpers inflate fanIn,
14
+ * and test functions are never "unreachable" by definition.
15
+ *
16
+ * Patterns covered:
17
+ * TypeScript/JS: *.test.ts, *.spec.ts, *.test.tsx, __tests__/*, test_*.ts
18
+ * Python: test_*.py, *_test.py, tests/*.py
19
+ * Go: *_test.go
20
+ * Rust: files with #[cfg(test)] (not detectable here — excluded by directory pattern)
21
+ * Java/Kotlin: *Test.java, *Spec.kt
22
+ */
23
+ export function isTestFile(filePath) {
24
+ const name = filePath.replace(/\\/g, '/');
25
+ return (/\.(test|spec)\.(ts|tsx|js|jsx|mjs|cjs)$/.test(name) || // JS/TS: foo.test.ts
26
+ /(^|\/)__tests__\//.test(name) || // JS/TS: __tests__/
27
+ /(^|\/)test_[^/]+\.(ts|js|py)$/.test(name) || // Python/TS: test_foo.py
28
+ /[^/]+_test\.(py|go)$/.test(name) || // Python/Go: foo_test.py, foo_test.go
29
+ /(^|\/)tests?\/[^/]+\.(py|ts|js|rb|php)$/.test(name) || // tests/ directory
30
+ /[A-Z][a-zA-Z0-9]*Test\.(java|kt|scala)$/.test(name) || // Java: FooTest.java
31
+ /[A-Z][a-zA-Z0-9]*Spec\.(kt|scala|rb)$/.test(name) // Kotlin/Ruby: FooSpec.kt
32
+ );
33
+ }
34
+ /**
35
+ * Convert a serialised RepoStructure (from repo-structure.json on disk) back
36
+ * to a minimal RepositoryMap-compatible object. Only the fields that
37
+ * consumers of the cached-analysis path actually use are populated; the
38
+ * file-level arrays (`allFiles`, `highValueFiles`, etc.) are left empty
39
+ * because the original per-file data is not persisted to disk.
40
+ */
41
+ export function repoStructureToRepoMap(rs) {
42
+ return {
43
+ metadata: {
44
+ projectName: rs.projectName,
45
+ projectType: (rs.projectType === 'node-typescript' ? 'nodejs' : rs.projectType),
46
+ rootPath: '',
47
+ analyzedAt: '',
48
+ version: '',
49
+ },
50
+ summary: {
51
+ totalFiles: rs.statistics.totalFiles,
52
+ analyzedFiles: rs.statistics.analyzedFiles,
53
+ skippedFiles: rs.statistics.skippedFiles,
54
+ languages: [],
55
+ frameworks: rs.frameworks.map(name => ({
56
+ name,
57
+ category: 'other',
58
+ confidence: 'medium',
59
+ evidence: [],
60
+ })),
61
+ directories: [],
62
+ },
63
+ highValueFiles: [],
64
+ entryPoints: [],
65
+ schemaFiles: [],
66
+ configFiles: [],
67
+ clusters: {
68
+ byDirectory: {},
69
+ byDomain: {},
70
+ byLayer: { presentation: [], business: [], data: [], infrastructure: [] },
71
+ },
72
+ allFiles: [],
73
+ };
74
+ }
75
+ // ============================================================================
76
+ // ARTIFACT GENERATOR
77
+ // ============================================================================
78
+ /**
79
+ * Generates analysis artifacts from repository map and dependency graph
80
+ */
81
+ export class AnalysisArtifactGenerator {
82
+ options;
83
+ constructor(options) {
84
+ this.options = {
85
+ rootDir: options.rootDir,
86
+ outputDir: options.outputDir,
87
+ maxDeepAnalysisFiles: options.maxDeepAnalysisFiles ?? 20,
88
+ maxValidationFiles: options.maxValidationFiles ?? 5,
89
+ tokensPerChar: options.tokensPerChar ?? TOKENS_PER_CHAR_DEFAULT,
90
+ };
91
+ }
92
+ /**
93
+ * Generate all artifacts
94
+ */
95
+ async generate(repoMap, depGraph, enrichment) {
96
+ // Generate each artifact
97
+ const repoStructure = this.generateRepoStructure(repoMap, depGraph, enrichment);
98
+ const summaryMarkdown = this.generateSummaryMarkdown(repoMap, depGraph, repoStructure);
99
+ const dependencyDiagram = this.generateDependencyDiagram(depGraph);
100
+ const llmContext = await this.generateLLMContext(repoMap, depGraph);
101
+ return {
102
+ repoStructure,
103
+ summaryMarkdown,
104
+ dependencyDiagram,
105
+ llmContext,
106
+ };
107
+ }
108
+ /**
109
+ * Generate and save all artifacts to disk
110
+ */
111
+ async generateAndSave(repoMap, depGraph, enrichment) {
112
+ const artifacts = await this.generate(repoMap, depGraph, enrichment);
113
+ // Ensure output directory exists
114
+ await mkdir(this.options.outputDir, { recursive: true });
115
+ // Save each artifact
116
+ const saves = [
117
+ writeFile(join(this.options.outputDir, ARTIFACT_REPO_STRUCTURE), JSON.stringify(artifacts.repoStructure, null, 2)),
118
+ writeFile(join(this.options.outputDir, 'SUMMARY.md'), artifacts.summaryMarkdown),
119
+ writeFile(join(this.options.outputDir, 'dependencies.mermaid'), artifacts.dependencyDiagram),
120
+ writeFile(join(this.options.outputDir, ARTIFACT_LLM_CONTEXT), JSON.stringify(artifacts.llmContext, null, 2)),
121
+ ];
122
+ if (enrichment?.schemas) {
123
+ saves.push(writeFile(join(this.options.outputDir, ARTIFACT_SCHEMA_INVENTORY), JSON.stringify(enrichment.schemas, null, 2)));
124
+ }
125
+ if (enrichment?.uiComponents) {
126
+ saves.push(writeFile(join(this.options.outputDir, ARTIFACT_UI_INVENTORY), JSON.stringify(enrichment.uiComponents, null, 2)));
127
+ }
128
+ if (enrichment?.routeInventory) {
129
+ saves.push(writeFile(join(this.options.outputDir, ARTIFACT_ROUTE_INVENTORY), JSON.stringify(enrichment.routeInventory, null, 2)));
130
+ }
131
+ if (enrichment?.middleware) {
132
+ const { ARTIFACT_MIDDLEWARE_INVENTORY } = await import('../../constants.js');
133
+ saves.push(writeFile(join(this.options.outputDir, ARTIFACT_MIDDLEWARE_INVENTORY), JSON.stringify(enrichment.middleware, null, 2)));
134
+ }
135
+ if (enrichment?.envVars) {
136
+ const { ARTIFACT_ENV_INVENTORY } = await import('../../constants.js');
137
+ saves.push(writeFile(join(this.options.outputDir, ARTIFACT_ENV_INVENTORY), JSON.stringify(enrichment.envVars, null, 2)));
138
+ }
139
+ await Promise.all(saves);
140
+ // Write SQLite edge store alongside JSON artifacts (additive, non-fatal)
141
+ if (artifacts.llmContext.callGraph) {
142
+ try {
143
+ const dbPath = join(this.options.outputDir, ARTIFACT_CALL_GRAPH_DB);
144
+ await writeEdgesToSQLite(artifacts.llmContext.callGraph, dbPath, this.options.rootDir);
145
+ }
146
+ catch {
147
+ // Non-fatal — JSON artifacts are the source of truth
148
+ }
149
+ }
150
+ return artifacts;
151
+ }
152
+ /**
153
+ * Generate repo-structure.json
154
+ */
155
+ generateRepoStructure(repoMap, depGraph, enrichment) {
156
+ // Detect architecture pattern
157
+ const architecturePattern = this.detectArchitecturePattern(repoMap, depGraph);
158
+ // Generate layers
159
+ const layers = this.generateArchitectureLayers(repoMap);
160
+ // Generate domains from clusters
161
+ const domains = this.generateDomains(repoMap, depGraph);
162
+ // Generate entry points
163
+ const entryPoints = this.generateEntryPoints(repoMap);
164
+ // Generate data flow
165
+ const dataFlow = this.generateDataFlow(repoMap);
166
+ // Generate key files
167
+ const keyFiles = this.generateKeyFiles(repoMap);
168
+ // Calculate statistics
169
+ const avgScore = repoMap.allFiles.length > 0
170
+ ? repoMap.allFiles.reduce((sum, f) => sum + f.score, 0) / repoMap.allFiles.length
171
+ : 0;
172
+ return {
173
+ projectName: repoMap.metadata.projectName,
174
+ projectType: this.formatProjectType(repoMap.metadata.projectType),
175
+ frameworks: repoMap.summary.frameworks.map(f => f.name),
176
+ architecture: {
177
+ pattern: architecturePattern,
178
+ layers,
179
+ },
180
+ domains,
181
+ entryPoints,
182
+ dataFlow,
183
+ keyFiles,
184
+ uiComponents: enrichment?.uiComponents ?? [],
185
+ schemas: enrichment?.schemas ?? [],
186
+ routeInventory: enrichment?.routeInventory ?? { total: 0, byMethod: {}, byFramework: {}, routes: [] },
187
+ middleware: enrichment?.middleware ?? [],
188
+ envVars: enrichment?.envVars ?? [],
189
+ statistics: {
190
+ totalFiles: repoMap.summary.totalFiles,
191
+ analyzedFiles: repoMap.summary.analyzedFiles,
192
+ skippedFiles: repoMap.summary.skippedFiles,
193
+ avgFileScore: Math.round(avgScore * 10) / 10,
194
+ nodeCount: depGraph.statistics.nodeCount,
195
+ edgeCount: depGraph.statistics.edgeCount,
196
+ cycleCount: depGraph.statistics.cycleCount,
197
+ clusterCount: depGraph.statistics.clusterCount,
198
+ },
199
+ };
200
+ }
201
+ /**
202
+ * Format project type for display
203
+ */
204
+ formatProjectType(type) {
205
+ const mapping = {
206
+ nodejs: 'node-typescript',
207
+ python: 'python',
208
+ rust: 'rust',
209
+ go: 'go',
210
+ java: 'java',
211
+ ruby: 'ruby',
212
+ php: 'php',
213
+ unknown: 'unknown',
214
+ };
215
+ return mapping[type] ?? type;
216
+ }
217
+ /**
218
+ * Detect architecture pattern from code structure
219
+ */
220
+ detectArchitecturePattern(repoMap, _depGraph) {
221
+ const dirs = repoMap.summary.directories;
222
+ const dirNames = dirs.map(d => basename(d.path).toLowerCase());
223
+ // Check for layered architecture indicators
224
+ const layeredIndicators = ['controllers', 'services', 'repositories', 'routes', 'models', 'views'];
225
+ const hasLayeredStructure = layeredIndicators.filter(i => dirNames.some(d => d.includes(i))).length >= 3;
226
+ // Check for modular/domain-driven indicators
227
+ const moduleIndicators = ['modules', 'features', 'domains'];
228
+ const hasModularStructure = moduleIndicators.some(i => dirNames.includes(i));
229
+ // Check for microservices indicators
230
+ const hasMultiplePackageJson = repoMap.configFiles.filter(f => f.name === 'package.json').length > 1;
231
+ const hasDockerCompose = repoMap.configFiles.some(f => f.name.includes('docker-compose'));
232
+ // Determine pattern
233
+ if (hasMultiplePackageJson && hasDockerCompose) {
234
+ return 'microservices';
235
+ }
236
+ if (hasModularStructure) {
237
+ return 'modular';
238
+ }
239
+ if (hasLayeredStructure) {
240
+ return 'layered';
241
+ }
242
+ if (repoMap.summary.totalFiles < 50) {
243
+ return 'monolith';
244
+ }
245
+ return 'unknown';
246
+ }
247
+ /**
248
+ * Generate architecture layers
249
+ */
250
+ generateArchitectureLayers(repoMap) {
251
+ const layers = [];
252
+ // API/Routes layer
253
+ const apiFiles = repoMap.allFiles.filter(f => f.directory.includes('routes') ||
254
+ f.directory.includes('controllers') ||
255
+ f.directory.includes('api') ||
256
+ f.name.includes('route') ||
257
+ f.name.includes('controller'));
258
+ if (apiFiles.length > 0) {
259
+ layers.push({
260
+ name: 'API Layer',
261
+ purpose: 'HTTP request handling and routing',
262
+ files: apiFiles.map(f => f.path),
263
+ representativeFile: apiFiles[0]?.path ?? null,
264
+ });
265
+ }
266
+ // Service/Business layer
267
+ const serviceFiles = repoMap.allFiles.filter(f => f.directory.includes('services') ||
268
+ f.directory.includes('business') ||
269
+ f.directory.includes('domain') ||
270
+ f.name.includes('service') ||
271
+ f.name.includes('manager'));
272
+ if (serviceFiles.length > 0) {
273
+ layers.push({
274
+ name: 'Service Layer',
275
+ purpose: 'Business logic and domain operations',
276
+ files: serviceFiles.map(f => f.path),
277
+ representativeFile: serviceFiles[0]?.path ?? null,
278
+ });
279
+ }
280
+ // Data/Repository layer
281
+ const dataFiles = repoMap.allFiles.filter(f => f.directory.includes('repositories') ||
282
+ f.directory.includes('data') ||
283
+ f.directory.includes('database') ||
284
+ f.directory.includes('models') ||
285
+ f.name.includes('repository') ||
286
+ f.name.includes('model'));
287
+ if (dataFiles.length > 0) {
288
+ layers.push({
289
+ name: 'Data Layer',
290
+ purpose: 'Data access and persistence',
291
+ files: dataFiles.map(f => f.path),
292
+ representativeFile: dataFiles[0]?.path ?? null,
293
+ });
294
+ }
295
+ // Infrastructure layer
296
+ const infraFiles = repoMap.allFiles.filter(f => f.directory.includes('infrastructure') ||
297
+ f.directory.includes('config') ||
298
+ f.directory.includes('middleware') ||
299
+ f.directory.includes('utils') ||
300
+ f.isConfig);
301
+ if (infraFiles.length > 0) {
302
+ layers.push({
303
+ name: 'Infrastructure Layer',
304
+ purpose: 'Configuration, middleware, and utilities',
305
+ files: infraFiles.map(f => f.path),
306
+ representativeFile: infraFiles[0]?.path ?? null,
307
+ });
308
+ }
309
+ return layers;
310
+ }
311
+ /**
312
+ * Generate domains from clusters
313
+ */
314
+ generateDomains(repoMap, depGraph) {
315
+ const domains = [];
316
+ // Use directory-based clusters from repo map
317
+ for (const [dirName, files] of Object.entries(repoMap.clusters.byDomain)) {
318
+ if (files.length === 0)
319
+ continue;
320
+ // Skip infrastructure directories
321
+ const skipDirs = ['utils', 'helpers', 'common', 'shared', 'config', 'middleware'];
322
+ if (skipDirs.includes(dirName.toLowerCase()))
323
+ continue;
324
+ // Extract potential entities from file names
325
+ const entities = this.extractEntities(files);
326
+ // Find the key file (highest score in domain)
327
+ const keyFile = files.sort((a, b) => b.score - a.score)[0];
328
+ // Generate suggested spec path
329
+ const domainName = this.normalizeDomainName(dirName);
330
+ domains.push({
331
+ name: domainName,
332
+ suggestedSpecPath: `openspec/specs/${domainName}/spec.md`,
333
+ files: files.map(f => f.path),
334
+ entities,
335
+ keyFile: keyFile?.path ?? null,
336
+ });
337
+ }
338
+ // Also consider clusters from dependency graph
339
+ for (const cluster of depGraph.clusters) {
340
+ const clusterName = this.normalizeDomainName(cluster.suggestedDomain);
341
+ // Skip if already covered
342
+ if (domains.some(d => d.name === clusterName))
343
+ continue;
344
+ // Skip small clusters
345
+ if (cluster.files.length < 2)
346
+ continue;
347
+ // Get file details
348
+ const files = cluster.files
349
+ .map(id => depGraph.nodes.find(n => n.id === id)?.file)
350
+ .filter((f) => f !== undefined);
351
+ if (files.length === 0)
352
+ continue;
353
+ const entities = this.extractEntities(files);
354
+ const keyFile = files.sort((a, b) => b.score - a.score)[0];
355
+ domains.push({
356
+ name: clusterName,
357
+ suggestedSpecPath: `openspec/specs/${clusterName}/spec.md`,
358
+ files: files.map(f => f.path),
359
+ entities,
360
+ keyFile: keyFile?.path ?? null,
361
+ });
362
+ }
363
+ return domains;
364
+ }
365
+ /**
366
+ * Normalize domain name for OpenSpec path
367
+ */
368
+ normalizeDomainName(name) {
369
+ return name
370
+ .toLowerCase()
371
+ .replace(/[^a-z0-9]/g, '-')
372
+ .replace(/-+/g, '-')
373
+ .replace(/^-|-$/g, '') || 'misc';
374
+ }
375
+ /**
376
+ * Extract potential entity names from files
377
+ */
378
+ extractEntities(files) {
379
+ const entities = new Set();
380
+ for (const file of files) {
381
+ // Extract from file name
382
+ const name = file.name.replace(/\.(ts|js|tsx|jsx|py)$/, '');
383
+ // Convert to PascalCase as potential entity name
384
+ const entityName = name
385
+ .split(/[-_.]/)
386
+ .map(part => part.charAt(0).toUpperCase() + part.slice(1))
387
+ .join('');
388
+ // Skip generic names
389
+ const skipNames = ['Index', 'Types', 'Utils', 'Helpers', 'Constants', 'Test', 'Spec'];
390
+ if (!skipNames.includes(entityName) && entityName.length > 2) {
391
+ entities.add(entityName);
392
+ }
393
+ }
394
+ return Array.from(entities).slice(0, 5); // Limit to top 5
395
+ }
396
+ /**
397
+ * Generate entry points information
398
+ */
399
+ generateEntryPoints(repoMap) {
400
+ return repoMap.entryPoints.map(file => {
401
+ // Determine entry point type
402
+ let type = 'application-entry';
403
+ if (file.name.includes('test') || file.name.includes('spec')) {
404
+ type = 'test-entry';
405
+ }
406
+ else if (file.name.includes('route') || file.name.includes('api')) {
407
+ type = 'api-entry';
408
+ }
409
+ else if (file.name.includes('build') || file.name.includes('webpack')) {
410
+ type = 'build-entry';
411
+ }
412
+ // Infer what gets initialized (simplified)
413
+ const initializes = [];
414
+ if (file.name.includes('app') || file.name === 'index.ts') {
415
+ initializes.push('application');
416
+ }
417
+ if (file.directory.includes('database')) {
418
+ initializes.push('database');
419
+ }
420
+ return {
421
+ file: file.path,
422
+ type,
423
+ initializes,
424
+ };
425
+ });
426
+ }
427
+ /**
428
+ * Generate data flow information
429
+ */
430
+ generateDataFlow(repoMap) {
431
+ const sources = [];
432
+ const sinks = [];
433
+ const transformers = [];
434
+ for (const file of repoMap.allFiles) {
435
+ const dir = file.directory.toLowerCase();
436
+ const name = file.name.toLowerCase();
437
+ // Sources: routes, controllers, APIs
438
+ if (dir.includes('routes') || dir.includes('controllers') || dir.includes('api')) {
439
+ sources.push(file.path);
440
+ }
441
+ // Sinks: repositories, database, storage
442
+ else if (dir.includes('repositories') || dir.includes('database') || dir.includes('storage')) {
443
+ sinks.push(file.path);
444
+ }
445
+ // Transformers: services, middleware
446
+ else if (dir.includes('services') || dir.includes('middleware') || name.includes('service')) {
447
+ transformers.push(file.path);
448
+ }
449
+ }
450
+ return { sources, sinks, transformers };
451
+ }
452
+ /**
453
+ * Generate key files by category
454
+ */
455
+ generateKeyFiles(repoMap) {
456
+ const keyFiles = {
457
+ schemas: [],
458
+ config: [],
459
+ auth: [],
460
+ database: [],
461
+ routes: [],
462
+ services: [],
463
+ };
464
+ for (const file of repoMap.allFiles) {
465
+ const dir = file.directory.toLowerCase();
466
+ const name = file.name.toLowerCase();
467
+ if (dir.includes('models') || dir.includes('schemas') || name.includes('schema')) {
468
+ keyFiles.schemas.push(file.path);
469
+ }
470
+ if (file.isConfig || dir.includes('config')) {
471
+ keyFiles.config.push(file.path);
472
+ }
473
+ if (dir.includes('auth') || name.includes('auth')) {
474
+ keyFiles.auth.push(file.path);
475
+ }
476
+ if (dir.includes('database') || dir.includes('db') || name.includes('database')) {
477
+ keyFiles.database.push(file.path);
478
+ }
479
+ if (dir.includes('routes') || name.includes('route')) {
480
+ keyFiles.routes.push(file.path);
481
+ }
482
+ if (dir.includes('services') || name.includes('service')) {
483
+ keyFiles.services.push(file.path);
484
+ }
485
+ }
486
+ return keyFiles;
487
+ }
488
+ /**
489
+ * Generate SUMMARY.md
490
+ */
491
+ generateSummaryMarkdown(repoMap, depGraph, repoStructure) {
492
+ const lines = [];
493
+ // Header
494
+ lines.push(`# Repository Analysis: ${repoMap.metadata.projectName}`);
495
+ lines.push('');
496
+ // Overview
497
+ lines.push('## Overview');
498
+ lines.push(`- **Type**: ${this.formatProjectTypeReadable(repoMap.metadata.projectType)}`);
499
+ if (repoMap.summary.frameworks.length > 0) {
500
+ lines.push(`- **Frameworks**: ${repoMap.summary.frameworks.map(f => f.name).join(', ')}`);
501
+ }
502
+ lines.push(`- **Files Analyzed**: ${repoMap.summary.analyzedFiles} of ${repoMap.summary.totalFiles} (${repoMap.summary.skippedFiles} skipped)`);
503
+ lines.push(`- **Analysis Date**: ${repoMap.metadata.analyzedAt}`);
504
+ lines.push('');
505
+ // Architecture
506
+ lines.push('## Architecture Pattern');
507
+ lines.push(`This appears to be a **${repoStructure.architecture.pattern}** architecture.`);
508
+ if (repoStructure.architecture.layers.length > 0) {
509
+ lines.push('');
510
+ lines.push('**Detected Layers:**');
511
+ for (const layer of repoStructure.architecture.layers) {
512
+ lines.push(`- ${layer.name}: ${layer.purpose} (${layer.files.length} files)`);
513
+ }
514
+ }
515
+ lines.push('');
516
+ // Languages
517
+ if (repoMap.summary.languages.length > 0) {
518
+ lines.push('## Language Breakdown');
519
+ lines.push('| Language | Files | Percentage |');
520
+ lines.push('|----------|-------|------------|');
521
+ for (const lang of repoMap.summary.languages.slice(0, 5)) {
522
+ lines.push(`| ${lang.language} | ${lang.fileCount} | ${lang.percentage.toFixed(1)}% |`);
523
+ }
524
+ lines.push('');
525
+ }
526
+ // Domains
527
+ if (repoStructure.domains.length > 0) {
528
+ lines.push('## Detected Domains');
529
+ lines.push('These domains will become OpenSpec specifications:');
530
+ lines.push('');
531
+ lines.push('| Domain | Files | Key Entities | Spec Path |');
532
+ lines.push('|--------|-------|--------------|-----------|');
533
+ for (const domain of repoStructure.domains.slice(0, 10)) {
534
+ const entities = domain.entities.slice(0, 3).join(', ') || '-';
535
+ lines.push(`| ${domain.name} | ${domain.files.length} | ${entities} | \`${domain.suggestedSpecPath}\` |`);
536
+ }
537
+ lines.push('');
538
+ }
539
+ // Dependency insights
540
+ lines.push('## Dependency Insights');
541
+ // Most connected
542
+ const topConnected = depGraph.rankings.byConnectivity.slice(0, 3);
543
+ if (topConnected.length > 0) {
544
+ lines.push('');
545
+ lines.push('**Most Connected Files:**');
546
+ for (const nodeId of topConnected) {
547
+ const node = depGraph.nodes.find(n => n.id === nodeId);
548
+ if (node) {
549
+ const totalDegree = node.metrics.inDegree + node.metrics.outDegree;
550
+ lines.push(`- \`${node.file.path}\` (${totalDegree} connections)`);
551
+ }
552
+ }
553
+ }
554
+ // Cycles
555
+ if (depGraph.cycles.length > 0) {
556
+ lines.push('');
557
+ lines.push(`**Circular Dependencies**: ${depGraph.cycles.length} cycle(s) detected`);
558
+ for (const cycle of depGraph.cycles.slice(0, 3)) {
559
+ const cycleFiles = cycle.map(id => {
560
+ const node = depGraph.nodes.find(n => n.id === id);
561
+ return node ? basename(node.file.path) : basename(id);
562
+ });
563
+ lines.push(`- ${cycleFiles.join(' → ')}`);
564
+ }
565
+ }
566
+ // HTTP cross-language edges
567
+ if (depGraph.statistics.httpEdgeCount > 0) {
568
+ lines.push('');
569
+ lines.push(`**HTTP Cross-Language Edges**: ${depGraph.statistics.httpEdgeCount} edge(s) detected between JS/TS callers and Python route handlers`);
570
+ lines.push(` (${depGraph.statistics.importEdgeCount} static import edges + ${depGraph.statistics.httpEdgeCount} HTTP edges = ${depGraph.statistics.edgeCount} total)`);
571
+ }
572
+ // Orphans
573
+ if (depGraph.rankings.orphanNodes.length > 0) {
574
+ lines.push('');
575
+ lines.push(`**Orphan Files**: ${depGraph.rankings.orphanNodes.length} file(s) with no imports or exports`);
576
+ }
577
+ lines.push('');
578
+ // Top files
579
+ lines.push('## Files Selected for Deep Analysis');
580
+ lines.push('The following files were selected as most significant:');
581
+ lines.push('');
582
+ const topFiles = repoMap.highValueFiles.slice(0, 15);
583
+ for (let i = 0; i < topFiles.length; i++) {
584
+ const file = topFiles[i];
585
+ const tags = file.tags.length > 0 ? ` - ${file.tags.join(', ')}` : '';
586
+ lines.push(`${i + 1}. \`${file.path}\` (score: ${file.score})${tags}`);
587
+ }
588
+ lines.push('');
589
+ // Recommendations
590
+ lines.push('## Recommendations');
591
+ const recommendations = [];
592
+ if (depGraph.cycles.length > 0) {
593
+ recommendations.push(`- Consider breaking the ${depGraph.cycles.length} circular dependency cycle(s)`);
594
+ }
595
+ if (depGraph.rankings.orphanNodes.length > 0) {
596
+ recommendations.push(`- Review ${depGraph.rankings.orphanNodes.length} orphan file(s) that may be unused`);
597
+ }
598
+ if (depGraph.rankings.bridgeNodes.length > 0) {
599
+ recommendations.push(`- The following files are critical bridges: ${depGraph.rankings.bridgeNodes.slice(0, 3).map(id => {
600
+ const node = depGraph.nodes.find(n => n.id === id);
601
+ return node ? `\`${basename(node.file.path)}\`` : '';
602
+ }).filter(Boolean).join(', ')}`);
603
+ }
604
+ if (recommendations.length === 0) {
605
+ recommendations.push('- No immediate architectural concerns detected');
606
+ }
607
+ for (const rec of recommendations) {
608
+ lines.push(rec);
609
+ }
610
+ lines.push('');
611
+ // ── UI Components ─────────────────────────────────────────────────────────
612
+ if (repoStructure.uiComponents.length > 0) {
613
+ const byFramework = {};
614
+ for (const c of repoStructure.uiComponents) {
615
+ byFramework[c.framework] = (byFramework[c.framework] ?? 0) + 1;
616
+ }
617
+ lines.push('## UI Components');
618
+ lines.push(`**Total**: ${repoStructure.uiComponents.length} component(s)`);
619
+ for (const [fw, count] of Object.entries(byFramework)) {
620
+ lines.push(`- ${fw}: ${count}`);
621
+ }
622
+ lines.push('');
623
+ }
624
+ // ── Database Schemas ──────────────────────────────────────────────────────
625
+ if (repoStructure.schemas.length > 0) {
626
+ const byOrm = {};
627
+ for (const t of repoStructure.schemas) {
628
+ byOrm[t.orm] = (byOrm[t.orm] ?? 0) + 1;
629
+ }
630
+ lines.push('## Database Schemas');
631
+ lines.push(`**Total tables/models**: ${repoStructure.schemas.length}`);
632
+ for (const [orm, count] of Object.entries(byOrm)) {
633
+ lines.push(`- ${orm}: ${count} model(s)`);
634
+ }
635
+ lines.push('');
636
+ }
637
+ // ── Route Inventory ───────────────────────────────────────────────────────
638
+ if (repoStructure.routeInventory.total > 0) {
639
+ const inv = repoStructure.routeInventory;
640
+ lines.push('## API Routes');
641
+ lines.push(`**Total routes**: ${inv.total}`);
642
+ const methodSummary = Object.entries(inv.byMethod)
643
+ .sort((a, b) => b[1] - a[1])
644
+ .map(([m, n]) => `${m}: ${n}`)
645
+ .join(', ');
646
+ if (methodSummary)
647
+ lines.push(`- By method: ${methodSummary}`);
648
+ const frameworkSummary = Object.entries(inv.byFramework)
649
+ .sort((a, b) => b[1] - a[1])
650
+ .map(([f, n]) => `${f}: ${n}`)
651
+ .join(', ');
652
+ if (frameworkSummary)
653
+ lines.push(`- By framework: ${frameworkSummary}`);
654
+ lines.push('');
655
+ }
656
+ // ── Environment Variables ─────────────────────────────────────────────────
657
+ if (repoStructure.envVars.length > 0) {
658
+ lines.push('## Environment Variables');
659
+ lines.push(`**Total**: ${repoStructure.envVars.length} variable(s)`);
660
+ const required = repoStructure.envVars.filter(v => v.required);
661
+ if (required.length > 0) {
662
+ lines.push(`- Required (no default): ${required.map(v => v.name).join(', ')}`);
663
+ }
664
+ lines.push('');
665
+ }
666
+ // Footer
667
+ lines.push('---');
668
+ lines.push(`*Generated by openlore v${repoMap.metadata.version}*`);
669
+ return lines.join('\n');
670
+ }
671
+ /**
672
+ * Format project type for human reading
673
+ */
674
+ formatProjectTypeReadable(type) {
675
+ const mapping = {
676
+ nodejs: 'Node.js/TypeScript',
677
+ python: 'Python',
678
+ rust: 'Rust',
679
+ go: 'Go',
680
+ java: 'Java',
681
+ ruby: 'Ruby',
682
+ php: 'PHP',
683
+ unknown: 'Unknown',
684
+ };
685
+ return mapping[type] ?? type;
686
+ }
687
+ /**
688
+ * Generate dependency diagram in Mermaid format
689
+ */
690
+ generateDependencyDiagram(depGraph) {
691
+ // Use the built-in Mermaid converter with clustering
692
+ const lines = ['```mermaid'];
693
+ // Generate diagram with top files
694
+ const mermaid = toMermaidFormat(depGraph, DEPENDENCY_DIAGRAM_MAX_FILES);
695
+ lines.push(mermaid);
696
+ lines.push('```');
697
+ return lines.join('\n');
698
+ }
699
+ /**
700
+ * Generate LLM context preparation
701
+ */
702
+ async generateLLMContext(repoMap, depGraph) {
703
+ // Phase 1: Survey (repo structure summary)
704
+ const phase1 = {
705
+ purpose: 'Initial project categorization',
706
+ files: [
707
+ {
708
+ path: ARTIFACT_REPO_STRUCTURE,
709
+ tokens: 2000, // Estimate
710
+ },
711
+ ],
712
+ // FIX 1: estimatedTokens → totalTokens pour cohérence avec phase2/phase3
713
+ totalTokens: 2000,
714
+ };
715
+ // Phase 2: Deep analysis (top files by importance, excluding test files)
716
+ const phase2Files = [];
717
+ const topFiles = repoMap.highValueFiles
718
+ .filter(f => !isTestFile(f.path))
719
+ .slice(0, this.options.maxDeepAnalysisFiles);
720
+ for (const file of topFiles) {
721
+ try {
722
+ const content = await readFile(file.absolutePath, 'utf-8');
723
+ const tokens = Math.ceil(content.length * this.options.tokensPerChar);
724
+ phase2Files.push({
725
+ path: file.path,
726
+ content: content.slice(0, PHASE2_FILE_CONTENT_MAX_CHARS),
727
+ tokens,
728
+ });
729
+ }
730
+ catch {
731
+ // File couldn't be read, skip
732
+ }
733
+ }
734
+ const phase2 = {
735
+ purpose: 'Core entity and logic extraction',
736
+ files: phase2Files,
737
+ // FIX 2: tokens peut être undefined → utiliser ?? 0
738
+ totalTokens: phase2Files.reduce((sum, f) => sum + (f.tokens ?? 0), 0),
739
+ };
740
+ // Phase 3: Validation (random leaf nodes not in phase 2, excluding test files)
741
+ const phase2Paths = new Set(phase2Files.map(f => f.path));
742
+ const leafFiles = depGraph.rankings.leafNodes
743
+ .map(id => depGraph.nodes.find(n => n.id === id)?.file)
744
+ .filter((f) => f !== undefined)
745
+ .filter(f => !phase2Paths.has(f.path))
746
+ .filter(f => !isTestFile(f.path));
747
+ // FIX 3: Fisher-Yates shuffle (sort(() => Math.random()) est biaisé + mute le tableau original)
748
+ const shuffled = [...leafFiles];
749
+ for (let i = shuffled.length - 1; i > 0; i--) {
750
+ const j = Math.floor(Math.random() * (i + 1));
751
+ [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
752
+ }
753
+ const validationFiles = shuffled.slice(0, this.options.maxValidationFiles);
754
+ const phase3Files = [];
755
+ for (const file of validationFiles) {
756
+ try {
757
+ const content = await readFile(file.absolutePath, 'utf-8');
758
+ const tokens = Math.ceil(content.length * this.options.tokensPerChar);
759
+ phase3Files.push({
760
+ path: file.path,
761
+ content: content.slice(0, PHASE3_FILE_CONTENT_MAX_CHARS),
762
+ tokens,
763
+ });
764
+ }
765
+ catch {
766
+ // File couldn't be read, skip
767
+ }
768
+ }
769
+ const phase3 = {
770
+ purpose: 'Verification samples',
771
+ files: phase3Files,
772
+ totalTokens: phase3Files.reduce((sum, f) => sum + (f.tokens ?? 0), 0),
773
+ };
774
+ // Signature extraction + call graph for ALL analyzed files
775
+ // Read each file once and reuse the content for both operations.
776
+ // All dynamic imports grouped here; CALL_GRAPH_LANGS hoisted out of the loop.
777
+ const { extractSignatures, detectLanguage } = await import('./signature-extractor.js');
778
+ const { CallGraphBuilder, serializeCallGraph } = await import('./call-graph.js');
779
+ const { detectDuplicates } = await import('./duplicate-detector.js');
780
+ const { analyzeForRefactoring } = await import('./refactor-analyzer.js');
781
+ const CALL_GRAPH_LANGS = new Set(['Python', 'TypeScript', 'JavaScript', 'Go', 'Rust', 'Ruby', 'Java', 'C++', 'Swift']);
782
+ const signatures = [];
783
+ const callGraphFiles = [];
784
+ for (const file of repoMap.allFiles) {
785
+ try {
786
+ const content = await readFile(file.absolutePath, 'utf-8');
787
+ const isTest = isTestFile(file.path);
788
+ // Signatures: exclude test files
789
+ if (!isTest) {
790
+ const map = extractSignatures(file.path, content);
791
+ if (map.entries.length > 0) {
792
+ signatures.push(map);
793
+ }
794
+ }
795
+ // Call graph — all supported languages, include test files so tested_by edges are derived
796
+ const lang = detectLanguage(file.path);
797
+ if (!isTest && CALL_GRAPH_LANGS.has(lang)) {
798
+ callGraphFiles.push({ path: file.path, content, language: lang });
799
+ }
800
+ }
801
+ catch {
802
+ // skip unreadable files
803
+ }
804
+ }
805
+ // Build call graph
806
+ const builder = new CallGraphBuilder();
807
+ const callGraphResult = await builder.build(callGraphFiles);
808
+ const callGraph = serializeCallGraph(callGraphResult);
809
+ // For languages without intra-module imports (Swift, C++, …), the dependency
810
+ // graph has no import edges. Synthesize file-level dependency edges from the
811
+ // call graph so the viewer shows a meaningful graph.
812
+ const hasImplicitImportFiles = callGraphFiles.some(f => IMPLICIT_IMPORT_LANGS.has(f.language));
813
+ if (hasImplicitImportFiles && depGraph.statistics.importEdgeCount === 0) {
814
+ const nodeMap = new Map(Array.from(callGraphResult.nodes.values()).map(n => [n.id, n.filePath]));
815
+ injectCallGraphEdges(depGraph, callGraphResult.edges, id => nodeMap.get(id));
816
+ }
817
+ // Duplicate detection — static analysis, no LLM (Types 1-2-3)
818
+ const duplicates = detectDuplicates(callGraphFiles, callGraphResult);
819
+ // Save duplicates
820
+ try {
821
+ await writeFile(join(this.options.outputDir, 'duplicates.json'), JSON.stringify(duplicates, null, 2));
822
+ }
823
+ catch {
824
+ // non-fatal if output dir doesn't exist yet
825
+ }
826
+ // Refactoring priorities (structural — enriched after generate)
827
+ let mappings;
828
+ try {
829
+ const mappingRaw = await readFile(join(this.options.outputDir, ARTIFACT_MAPPING), 'utf-8');
830
+ const mappingJson = JSON.parse(mappingRaw);
831
+ mappings = mappingJson.mappings;
832
+ }
833
+ catch {
834
+ // mapping.json not yet available — that's fine
835
+ }
836
+ const refactorReport = analyzeForRefactoring(callGraph, mappings, duplicates);
837
+ // Save refactor priorities
838
+ try {
839
+ await writeFile(join(this.options.outputDir, ARTIFACT_REFACTOR_PRIORITIES), JSON.stringify(refactorReport, null, 2));
840
+ }
841
+ catch {
842
+ // non-fatal
843
+ }
844
+ return {
845
+ phase1_survey: phase1,
846
+ phase2_deep: phase2,
847
+ phase3_validation: phase3,
848
+ signatures,
849
+ callGraph,
850
+ };
851
+ }
852
+ }
853
+ // ============================================================================
854
+ // SQLITE GRAPH STORE
855
+ // ============================================================================
856
+ /**
857
+ * Writes the full call graph (nodes, edges, classes, inheritance) to SQLite.
858
+ * Full rebuild on every analyze — incremental updates handled by the watcher.
859
+ * Additive alongside llm-context.json; backward compat preserved.
860
+ */
861
+ export async function writeEdgesToSQLite(callGraph, dbPath, rootPath) {
862
+ const { EdgeStore } = await import('../services/edge-store.js');
863
+ const store = EdgeStore.open(dbPath);
864
+ try {
865
+ store.clearAll();
866
+ // Normalize absolute paths to relative — vector index uses relative IDs; DB must match.
867
+ const prefix = rootPath ? (rootPath.endsWith('/') ? rootPath : rootPath + '/') : '';
868
+ const norm = (s) => (prefix && s.startsWith(prefix)) ? s.slice(prefix.length) : s;
869
+ const nodes = prefix
870
+ ? callGraph.nodes.map(n => ({ ...n, id: norm(n.id), filePath: norm(n.filePath) }))
871
+ : callGraph.nodes;
872
+ const edges = prefix
873
+ ? callGraph.edges.map(e => ({ ...e, callerId: norm(e.callerId), calleeId: norm(e.calleeId) }))
874
+ : callGraph.edges;
875
+ const classes = prefix
876
+ ? callGraph.classes.map(c => ({ ...c, id: norm(c.id), filePath: norm(c.filePath), methodIds: c.methodIds.map(norm) }))
877
+ : callGraph.classes;
878
+ const inheritanceEdges = prefix
879
+ ? callGraph.inheritanceEdges.map(e => ({ ...e, parentId: norm(e.parentId), childId: norm(e.childId) }))
880
+ : callGraph.inheritanceEdges;
881
+ const hubIds = new Set(callGraph.hubFunctions.map(n => norm(n.id)));
882
+ const entryIds = new Set(callGraph.entryPoints.map(n => norm(n.id)));
883
+ store.insertNodes(nodes, hubIds, entryIds);
884
+ store.insertEdges(edges);
885
+ store.insertInheritanceEdges(inheritanceEdges);
886
+ store.insertClasses(classes);
887
+ }
888
+ finally {
889
+ store.close();
890
+ }
891
+ }
892
+ // ============================================================================
893
+ // CONVENIENCE FUNCTIONS
894
+ // ============================================================================
895
+ /**
896
+ * Generate all artifacts
897
+ */
898
+ export async function generateArtifacts(repoMap, depGraph, options) {
899
+ const generator = new AnalysisArtifactGenerator(options);
900
+ return generator.generate(repoMap, depGraph);
901
+ }
902
+ /**
903
+ * Generate and save all artifacts
904
+ */
905
+ export async function generateAndSaveArtifacts(repoMap, depGraph, options) {
906
+ const generator = new AnalysisArtifactGenerator(options);
907
+ return generator.generateAndSave(repoMap, depGraph);
908
+ }
909
+ //# sourceMappingURL=artifact-generator.js.map