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,683 @@
1
+ /**
2
+ * openlore analyze command
3
+ *
4
+ * Runs static analysis on the codebase without LLM involvement.
5
+ * Outputs repository map, dependency graph, and file significance scores.
6
+ */
7
+ import { Command } from 'commander';
8
+ import { writeFile, mkdir, readFile } from 'node:fs/promises';
9
+ import { join } from 'node:path';
10
+ import { logger } from '../../utils/logger.js';
11
+ import { fileExists, formatDuration, formatAge, getAnalysisAge } from '../../utils/command-helpers.js';
12
+ import { ANALYSIS_STALE_THRESHOLD_MS, ARTIFACT_DEPENDENCY_GRAPH, ARTIFACT_FINGERPRINT, ARTIFACT_REFACTOR_PRIORITIES, ARTIFACT_REPO_STRUCTURE, DEFAULT_MAX_FILES, DEEP_ANALYSIS_FILE_RATIO, MAX_DEEP_ANALYSIS_FILES, MAX_VALIDATION_FILES, OPENSPEC_DIR, OPENSPEC_SPECS_SUBDIR, OPENSPEC_DECISIONS_SUBDIR, OPENLORE_ANALYSIS_REL_PATH, OPENLORE_CONFIG_REL_PATH, } from '../../constants.js';
13
+ import { computeProjectFingerprint } from '../../core/services/mcp-handlers/utils.js';
14
+ import { readOpenLoreConfig } from '../../core/services/config-manager.js';
15
+ import { RepositoryMapper } from '../../core/analyzer/repository-mapper.js';
16
+ import { DependencyGraphBuilder, } from '../../core/analyzer/dependency-graph.js';
17
+ import { AnalysisArtifactGenerator, } from '../../core/analyzer/artifact-generator.js';
18
+ import { buildArchitectureOverview, writeArchitectureMd, } from '../../core/analyzer/architecture-writer.js';
19
+ import { EmbeddingService } from '../../core/analyzer/embedding-service.js';
20
+ import { generateCodebaseDigest } from '../../core/analyzer/codebase-digest.js';
21
+ import { extractUIComponents } from '../../core/analyzer/ui-component-extractor.js';
22
+ import { extractSchemas } from '../../core/analyzer/schema-extractor.js';
23
+ import { buildRouteInventory } from '../../core/analyzer/http-route-parser.js';
24
+ import { extractMiddleware } from '../../core/analyzer/middleware-extractor.js';
25
+ import { extractEnvVars } from '../../core/analyzer/env-extractor.js';
26
+ import { generateAiConfigs, AI_TOOL_TARGETS } from '../../core/analyzer/ai-config-generator.js';
27
+ // ============================================================================
28
+ // HELPER FUNCTIONS
29
+ // ============================================================================
30
+ /**
31
+ * Collect multiple values for repeatable options
32
+ */
33
+ function collect(value, previous) {
34
+ return previous.concat([value]);
35
+ }
36
+ /**
37
+ * Check if analysis exists and return its age
38
+ */
39
+ // ============================================================================
40
+ // CORE ANALYSIS FUNCTION
41
+ // ============================================================================
42
+ /**
43
+ * Run the complete analysis pipeline
44
+ */
45
+ export async function runAnalysis(rootPath, outputPath, options) {
46
+ const startTime = Date.now();
47
+ // Merge config patterns with caller-supplied patterns so all entry points
48
+ // (CLI, MCP, …) automatically respect the project configuration.
49
+ const openloreConfig = await readOpenLoreConfig(rootPath);
50
+ const configExclude = openloreConfig?.analysis.excludePatterns ?? [];
51
+ const configInclude = openloreConfig?.analysis.includePatterns ?? [];
52
+ const mergedExclude = [...new Set([...configExclude, ...options.exclude])];
53
+ const mergedInclude = [...new Set([...configInclude, ...options.include])];
54
+ // Phase 1: Repository Mapping
55
+ logger.analysis('Scanning directory structure...');
56
+ const mapper = new RepositoryMapper(rootPath, {
57
+ maxFiles: options.maxFiles,
58
+ includePatterns: mergedInclude.length > 0 ? mergedInclude : undefined,
59
+ excludePatterns: mergedExclude.length > 0 ? mergedExclude : undefined,
60
+ });
61
+ const repoMap = await mapper.map();
62
+ logger.info('Files found', repoMap.summary.totalFiles);
63
+ logger.info('Files analyzed', repoMap.summary.analyzedFiles);
64
+ logger.info('Files skipped', repoMap.summary.skippedFiles);
65
+ logger.blank();
66
+ // Phase 2: Dependency Graph
67
+ logger.analysis('Building dependency graph...');
68
+ const graphBuilder = new DependencyGraphBuilder({
69
+ rootDir: rootPath,
70
+ });
71
+ const depGraph = await graphBuilder.build(repoMap.allFiles);
72
+ logger.info('Nodes', depGraph.statistics.nodeCount);
73
+ logger.info('Edges', depGraph.statistics.edgeCount);
74
+ logger.info('Clusters', depGraph.statistics.clusterCount);
75
+ if (depGraph.statistics.cycleCount > 0) {
76
+ logger.warning(`Circular dependencies: ${depGraph.statistics.cycleCount}`);
77
+ }
78
+ logger.blank();
79
+ // Phase 3: Run new enrichment extractors in parallel
80
+ logger.analysis('Extracting UI components, schemas, routes, and env vars...');
81
+ const allFilePaths = repoMap.allFiles.map(f => f.path);
82
+ const [uiComponents, schemas, routeInventory, middleware, envVars] = await Promise.all([
83
+ extractUIComponents(allFilePaths, rootPath),
84
+ extractSchemas(allFilePaths, rootPath),
85
+ buildRouteInventory(allFilePaths, rootPath),
86
+ extractMiddleware(allFilePaths, rootPath),
87
+ extractEnvVars(allFilePaths, rootPath),
88
+ ]);
89
+ // Phase 4: Generate Artifacts
90
+ logger.analysis('Generating analysis artifacts...');
91
+ const artifactGenerator = new AnalysisArtifactGenerator({
92
+ rootDir: rootPath,
93
+ outputDir: outputPath,
94
+ maxDeepAnalysisFiles: Math.min(MAX_DEEP_ANALYSIS_FILES, Math.ceil(repoMap.highValueFiles.length * DEEP_ANALYSIS_FILE_RATIO)),
95
+ maxValidationFiles: MAX_VALIDATION_FILES,
96
+ });
97
+ const artifacts = await artifactGenerator.generateAndSave(repoMap, depGraph, {
98
+ uiComponents,
99
+ schemas,
100
+ routeInventory,
101
+ middleware,
102
+ envVars,
103
+ });
104
+ // Also save the raw dependency graph
105
+ await writeFile(join(outputPath, ARTIFACT_DEPENDENCY_GRAPH), JSON.stringify(depGraph, null, 2));
106
+ // Write content-hash fingerprint so future runs can skip re-analysis when
107
+ // source files are unchanged (replaces the 1-hour TTL on a warm cache).
108
+ const fingerprintHash = await computeProjectFingerprint(rootPath);
109
+ await writeFile(join(outputPath, ARTIFACT_FINGERPRINT), JSON.stringify({ hash: fingerprintHash, computedAt: new Date().toISOString(), fileCount: repoMap.allFiles.length }));
110
+ const duration = Date.now() - startTime;
111
+ return { repoMap, depGraph, artifacts, duration };
112
+ }
113
+ // ============================================================================
114
+ // COMMAND
115
+ // ============================================================================
116
+ export const analyzeCommand = new Command('analyze')
117
+ .description('Run static analysis on the codebase (no LLM required)')
118
+ .option('--output <path>', 'Directory to write analysis results', `${OPENLORE_ANALYSIS_REL_PATH}/`)
119
+ .option('--max-files <n>', 'Maximum number of files to analyze (default: 100000)', '100000')
120
+ .option('--include <glob>', 'Additional glob patterns to include (repeatable)', collect, [])
121
+ .option('--exclude <glob>', 'Additional glob patterns to exclude (repeatable)', collect, [])
122
+ .option('--force', 'Force re-analysis even if recent analysis exists', false)
123
+ .option('--embed', 'Build a semantic vector index after analysis (requires EMBED_BASE_URL + EMBED_MODEL)', true)
124
+ .option('--no-embed', 'Skip vector index build (overrides default --embed)')
125
+ .option('--reindex-specs', 'Re-index OpenSpec specs into the vector index without re-running full analysis (requires EMBED_BASE_URL + EMBED_MODEL)', false)
126
+ .option('--ai-configs', 'Generate AI tool config files (.cursorrules, .clinerules/openlore.md, CLAUDE.md) if they do not already exist', false)
127
+ .addHelpText('after', `
128
+ Examples:
129
+ $ openlore analyze Analyze with defaults
130
+ $ openlore analyze --max-files 1000
131
+ Analyze more files
132
+ $ openlore analyze --include "*.graphql" --include "*.prisma"
133
+ Include additional file types
134
+ $ openlore analyze --exclude "legacy/**"
135
+ Exclude specific directories
136
+ $ openlore analyze --output ./my-analysis
137
+ Custom output location
138
+ $ openlore analyze --force Force re-analysis
139
+ $ openlore analyze --no-embed Skip vector index build
140
+ $ openlore analyze --reindex-specs Re-index specs only (no full re-analysis)
141
+
142
+ Output files:
143
+ .openlore/analysis/
144
+ ├── repo-structure.json Repository structure and metadata
145
+ ├── dependency-graph.json Import/export relationships
146
+ ├── llm-context.json Optimized context for LLM
147
+ ├── dependencies.mermaid Visual dependency diagram
148
+ └── SUMMARY.md Human-readable analysis summary
149
+
150
+ After analysis, run 'openlore generate' to create OpenSpec files.
151
+ `)
152
+ .action(async (options) => {
153
+ const startTime = Date.now();
154
+ const rootPath = process.cwd();
155
+ const opts = {
156
+ output: options.output ?? `${OPENLORE_ANALYSIS_REL_PATH}/`,
157
+ maxFiles: typeof options.maxFiles === 'string'
158
+ ? parseInt(options.maxFiles, 10)
159
+ : options.maxFiles ?? DEFAULT_MAX_FILES,
160
+ include: options.include ?? [],
161
+ exclude: options.exclude ?? [],
162
+ force: options.force ?? false,
163
+ embed: options.embed ?? false,
164
+ reindexSpecs: options.reindexSpecs ?? false,
165
+ aiConfigs: options.aiConfigs ?? false,
166
+ quiet: false,
167
+ verbose: false,
168
+ noColor: false,
169
+ config: OPENLORE_CONFIG_REL_PATH,
170
+ };
171
+ if (isNaN(opts.maxFiles) || opts.maxFiles < 1) {
172
+ logger.error('--max-files must be a positive integer');
173
+ process.exitCode = 1;
174
+ return;
175
+ }
176
+ try {
177
+ // ========================================================================
178
+ // PHASE 1: VALIDATION
179
+ // ========================================================================
180
+ logger.section('Analyzing Codebase');
181
+ // Check for openlore config
182
+ const openloreConfig = await readOpenLoreConfig(rootPath);
183
+ if (!openloreConfig) {
184
+ logger.error('No openlore configuration found. Run "openlore init" first.');
185
+ process.exitCode = 1;
186
+ return;
187
+ }
188
+ // Auto-enable --embed when embedding is configured but flag wasn't passed explicitly.
189
+ if (!options.embed) {
190
+ const embedConfigured = !!process.env.EMBED_BASE_URL ||
191
+ !!EmbeddingService.fromConfig(openloreConfig);
192
+ if (embedConfigured)
193
+ opts.embed = true;
194
+ }
195
+ logger.info('Project', openloreConfig.projectType);
196
+ logger.info('Output', opts.output);
197
+ logger.info('Max files', opts.maxFiles);
198
+ if (opts.include.length > 0) {
199
+ logger.info('Include patterns', opts.include.join(', '));
200
+ }
201
+ if (opts.exclude.length > 0) {
202
+ logger.info('Exclude patterns', opts.exclude.join(', '));
203
+ }
204
+ logger.blank();
205
+ // ========================================================================
206
+ // PHASE 1b: --reindex-specs fast path (no full analysis)
207
+ // ========================================================================
208
+ if (opts.reindexSpecs) {
209
+ const outputPath = join(rootPath, opts.output);
210
+ await mkdir(outputPath, { recursive: true });
211
+ await runSpecIndexing(rootPath, outputPath, openloreConfig);
212
+ return;
213
+ }
214
+ // ========================================================================
215
+ // PHASE 2: CHECK EXISTING ANALYSIS
216
+ // ========================================================================
217
+ const outputPath = join(rootPath, opts.output);
218
+ const analysisAge = await getAnalysisAge(outputPath);
219
+ if (analysisAge !== null && !opts.force) {
220
+ // Analysis exists - check if recent
221
+ if (analysisAge < ANALYSIS_STALE_THRESHOLD_MS) {
222
+ logger.discovery(`Recent analysis exists (${formatAge(analysisAge)})`);
223
+ logger.info('Tip', 'Use --force to re-analyze');
224
+ logger.blank();
225
+ // Show existing analysis stats
226
+ try {
227
+ const repoStructurePath = join(outputPath, ARTIFACT_REPO_STRUCTURE);
228
+ const content = await import('node:fs/promises').then(fs => fs.readFile(repoStructurePath, 'utf-8'));
229
+ const repoStructure = JSON.parse(content);
230
+ logger.success('Analysis Summary');
231
+ logger.info('Files analyzed', repoStructure.statistics.analyzedFiles);
232
+ logger.info('Domains detected', repoStructure.domains.map((d) => d.name).join(', ') || 'None');
233
+ logger.info('Architecture', repoStructure.architecture.pattern);
234
+ logger.blank();
235
+ // If embed is requested, run the embed step (incremental: only re-embeds changed functions)
236
+ if (opts.embed) {
237
+ await runEmbedStep(rootPath, outputPath, openloreConfig, opts.force ?? false, null);
238
+ }
239
+ // If --ai-configs is requested, generate them even from cached analysis
240
+ if (opts.aiConfigs) {
241
+ let selectedTools;
242
+ if (process.stdin.isTTY) {
243
+ const { checkbox } = await import('@inquirer/prompts');
244
+ const chosen = await checkbox({
245
+ message: 'Generate config files for which AI assistants?',
246
+ choices: AI_TOOL_TARGETS.map(t => ({
247
+ name: t.label,
248
+ value: t.tool,
249
+ checked: true,
250
+ })),
251
+ });
252
+ selectedTools = chosen.length > 0 ? chosen : undefined;
253
+ }
254
+ if (selectedTools === undefined || selectedTools.length > 0) {
255
+ const aiResults = await generateAiConfigs({
256
+ rootDir: rootPath,
257
+ analysisDir: opts.output.replace(/\/$/, ''),
258
+ projectName: repoStructure.projectName ?? 'project',
259
+ tools: selectedTools,
260
+ });
261
+ logger.blank();
262
+ console.log(' Agent config files:');
263
+ for (const { rel, created } of aiResults) {
264
+ const tag = created ? '(created)' : '(already exists)';
265
+ console.log(` ├─ ${rel} ${tag}`);
266
+ }
267
+ logger.blank();
268
+ }
269
+ }
270
+ logger.info('Next step', "Run 'openlore generate' to create OpenSpec files");
271
+ return;
272
+ }
273
+ catch (readErr) {
274
+ logger.debug(`Could not read existing analysis summary: ${readErr.message}`);
275
+ }
276
+ }
277
+ else {
278
+ logger.discovery(`Existing analysis is ${formatAge(analysisAge)} old, re-analyzing...`);
279
+ logger.blank();
280
+ }
281
+ }
282
+ // ========================================================================
283
+ // PHASE 3: RUN ANALYSIS
284
+ // ========================================================================
285
+ // Ensure output directory exists
286
+ await mkdir(outputPath, { recursive: true });
287
+ const result = await runAnalysis(rootPath, outputPath, {
288
+ maxFiles: opts.maxFiles,
289
+ include: opts.include,
290
+ exclude: opts.exclude,
291
+ });
292
+ // ========================================================================
293
+ // PHASE 4: DISPLAY RESULTS
294
+ // ========================================================================
295
+ logger.blank();
296
+ logger.section('Analysis Complete');
297
+ const { repoMap, depGraph, artifacts } = result;
298
+ // Summary
299
+ console.log('');
300
+ console.log(' Repository Structure:');
301
+ console.log(` ├─ Files analyzed: ${repoMap.summary.analyzedFiles}`);
302
+ console.log(` ├─ High-value files: ${repoMap.highValueFiles.length}`);
303
+ console.log(` ├─ Languages: ${repoMap.summary.languages.slice(0, 3).map(l => l.language).join(', ')}`);
304
+ console.log(` └─ Architecture: ${artifacts.repoStructure.architecture.pattern}`);
305
+ console.log('');
306
+ console.log(' Dependency Graph:');
307
+ console.log(` ├─ Nodes: ${depGraph.statistics.nodeCount}`);
308
+ console.log(` ├─ Edges: ${depGraph.statistics.edgeCount}`);
309
+ console.log(` ├─ Clusters: ${depGraph.statistics.clusterCount}`);
310
+ if (depGraph.statistics.cycleCount > 0) {
311
+ console.log(` ├─ ⚠ Circular dependencies: ${depGraph.statistics.cycleCount}`);
312
+ }
313
+ console.log(` └─ Average degree: ${depGraph.statistics.avgDegree.toFixed(1)}`);
314
+ console.log('');
315
+ // Call Graph
316
+ const cg = artifacts.llmContext.callGraph;
317
+ if (cg && cg.stats?.totalNodes > 0) {
318
+ console.log(' Call Graph (static analysis):');
319
+ console.log(` ├─ Functions: ${cg.stats.totalNodes}`);
320
+ console.log(` ├─ Internal calls: ${cg.stats.totalEdges}`);
321
+ if (cg.hubFunctions?.length > 0) {
322
+ const hubs = cg.hubFunctions.slice(0, 3).map(f => `${f.name}(fanIn=${f.fanIn})`).join(', ');
323
+ console.log(` ├─ Hub functions: ${hubs}`);
324
+ }
325
+ if (cg.layerViolations?.length > 0) {
326
+ console.log(` ├─ ⚠ Layer violations: ${cg.layerViolations.length}`);
327
+ }
328
+ console.log(` └─ Entry points: ${cg.entryPoints?.length ?? 0}`);
329
+ console.log('');
330
+ }
331
+ // Refactor priorities (read from disk if available)
332
+ try {
333
+ const { readFile: rf } = await import('node:fs/promises');
334
+ const rp = JSON.parse(await rf(join(opts.output, ARTIFACT_REFACTOR_PRIORITIES), 'utf-8'));
335
+ if (rp?.stats?.withIssues > 0) {
336
+ const s = rp.stats;
337
+ const badges = [
338
+ s.unreachable > 0 ? `${s.unreachable} unreachable` : null,
339
+ s.highFanIn > 0 ? `${s.highFanIn} hub overload` : null,
340
+ s.highFanOut > 0 ? `${s.highFanOut} god function` : null,
341
+ s.srpViolations > 0 ? `${s.srpViolations} SRP` : null,
342
+ s.cyclesDetected > 0 ? `${s.cyclesDetected} cycle` : null,
343
+ s.inCloneGroup > 0 ? `${s.inCloneGroup} duplicate` : null,
344
+ ].filter(Boolean).join(' · ');
345
+ const issueLabel = {
346
+ unreachable: 'dead code',
347
+ high_fan_in: `hub fanIn`,
348
+ high_fan_out: `god fanOut`,
349
+ multi_requirement: 'SRP',
350
+ in_cycle: 'cycle',
351
+ in_clone_group: 'clone',
352
+ };
353
+ console.log(` Refactoring Candidates (${s.withIssues}/${s.totalFunctions} functions):`);
354
+ console.log(` ${badges}`);
355
+ console.log('');
356
+ const top = rp.priorities.slice(0, 7);
357
+ if (top.length === 0) {
358
+ console.log(' (no refactoring candidates)');
359
+ }
360
+ else {
361
+ const maxNameLen = Math.max(...top.map(p => (p.function ?? '').length), 8);
362
+ const maxFileLen = Math.max(...top.map(p => (p.file?.split('/').pop() ?? '').length), 8);
363
+ for (const p of top) {
364
+ const name = (p.function ?? '').padEnd(maxNameLen);
365
+ const file = (p.file?.split('/').pop() ?? '').padEnd(maxFileLen);
366
+ const main = p.issues?.[0];
367
+ const val = main === 'high_fan_in' ? `fanIn=${p.fanIn}`
368
+ : main === 'high_fan_out' ? `fanOut=${p.fanOut}`
369
+ : main === 'in_cycle' ? `cycle`
370
+ : main === 'unreachable' ? `unreachable`
371
+ : `${p.requirements?.length ?? 0} req`;
372
+ const extra = (p.issues ?? []).slice(1).map(i => issueLabel[i] ?? i).join(', ');
373
+ const reqs = (p.requirements?.length ?? 0) > 0 ? ` [${p.requirements.slice(0, 2).join(', ')}${p.requirements.length > 2 ? '…' : ''}]` : '';
374
+ console.log(` ${name} ${file} ${val.padEnd(12)}${extra ? ' +' + extra : ''}${reqs}`);
375
+ }
376
+ }
377
+ if (rp.cycles?.length > 0) {
378
+ console.log('');
379
+ for (const c of rp.cycles) {
380
+ const names = c.participants.map(p => p.function).join(' ↔ ');
381
+ console.log(` ⚠ Cycle: ${names}`);
382
+ }
383
+ }
384
+ console.log('');
385
+ console.log(` → ${opts.output}refactor-priorities.json`);
386
+ console.log('');
387
+ }
388
+ }
389
+ catch (rpErr) {
390
+ logger.debug(`Refactor priorities not available: ${rpErr.message}`);
391
+ }
392
+ // Duplicate code detection
393
+ try {
394
+ const { readFile: rf } = await import('node:fs/promises');
395
+ const dup = JSON.parse(await rf(join(opts.output, 'duplicates.json'), 'utf-8'));
396
+ if (dup?.stats?.cloneGroupCount > 0) {
397
+ const s = dup.stats;
398
+ const severity = s.duplicationRatio >= 0.2 ? '⚠'
399
+ : s.duplicationRatio >= 0.1 ? 'ℹ'
400
+ : ' ';
401
+ console.log(` ${severity} Code Duplication (${s.duplicatedFunctions}/${s.totalFunctions} functions):`);
402
+ console.log(` ├─ Ratio: ${(s.duplicationRatio * 100).toFixed(1)}%`);
403
+ console.log(` ├─ Clone groups: ${s.cloneGroupCount}`);
404
+ // Show top clone types
405
+ const typeCounts = { exact: 0, structural: 0, near: 0 };
406
+ for (const group of dup.cloneGroups) {
407
+ typeCounts[group.type]++;
408
+ }
409
+ const typeLabels = Object.entries(typeCounts)
410
+ .filter(([_, count]) => count > 0)
411
+ .map(([type, count]) => `${count} ${type}`)
412
+ .join(' · ');
413
+ console.log(` └─ Types: ${typeLabels}`);
414
+ // Show top 5 clone groups
415
+ if (dup.cloneGroups.length > 0) {
416
+ console.log('');
417
+ console.log(' Top 5 Clone Groups:');
418
+ const topGroups = dup.cloneGroups
419
+ .sort((a, b) => b.instances.length - a.instances.length)
420
+ .slice(0, 5);
421
+ for (const group of topGroups) {
422
+ const files = group.instances.map((i) => {
423
+ const fileParts = i.file.split('/');
424
+ return `${fileParts[fileParts.length - 2]}/${fileParts[fileParts.length - 1]}:${i.functionName}`;
425
+ }).join(' ');
426
+ console.log(` ${group.type.padEnd(10)} (${group.instances.length}x, ${group.lineCount} lines): ${files}`);
427
+ }
428
+ }
429
+ console.log('');
430
+ console.log(` → ${opts.output}duplicates.json`);
431
+ console.log('');
432
+ }
433
+ }
434
+ catch (dupErr) {
435
+ logger.debug(`Duplicates report not available: ${dupErr.message}`);
436
+ }
437
+ // Detected domains
438
+ if (artifacts.repoStructure.domains.length > 0) {
439
+ console.log(' Detected Domains:');
440
+ for (let i = 0; i < Math.min(artifacts.repoStructure.domains.length, 6); i++) {
441
+ const domain = artifacts.repoStructure.domains[i];
442
+ const isLast = i === Math.min(artifacts.repoStructure.domains.length, 6) - 1;
443
+ const prefix = isLast ? '└─' : '├─';
444
+ console.log(` ${prefix} ${domain.name} (${domain.files.length} files)`);
445
+ }
446
+ if (artifacts.repoStructure.domains.length > 6) {
447
+ console.log(` ... and ${artifacts.repoStructure.domains.length - 6} more`);
448
+ }
449
+ console.log('');
450
+ }
451
+ // Generate ARCHITECTURE.md from cached analysis (no LLM)
452
+ let architectureMdWritten = false;
453
+ try {
454
+ const ctx = artifacts.llmContext ?? null;
455
+ const overview = buildArchitectureOverview(depGraph, ctx, rootPath);
456
+ await writeArchitectureMd(rootPath, overview);
457
+ architectureMdWritten = true;
458
+ }
459
+ catch (archErr) {
460
+ logger.debug(`ARCHITECTURE.md generation skipped: ${archErr.message}`);
461
+ }
462
+ // Generate .openlore/analysis/CODEBASE.md — agent-readable architecture digest
463
+ const digestWritten = await generateCodebaseDigest(artifacts.llmContext, depGraph, { rootPath, outputDir: outputPath });
464
+ // Generate AI tool config files — prompt user to select which assistants
465
+ let aiConfigsCreated = [];
466
+ if (opts.aiConfigs) {
467
+ let selectedTools;
468
+ if (process.stdin.isTTY) {
469
+ const { checkbox } = await import('@inquirer/prompts');
470
+ const chosen = await checkbox({
471
+ message: 'Generate config files for which AI assistants?',
472
+ choices: AI_TOOL_TARGETS.map(t => ({
473
+ name: t.label,
474
+ value: t.tool,
475
+ checked: true,
476
+ })),
477
+ });
478
+ selectedTools = chosen.length > 0 ? chosen : undefined;
479
+ }
480
+ // Non-TTY: generate for all tools (CI / pipe usage)
481
+ if (selectedTools === undefined || selectedTools.length > 0) {
482
+ aiConfigsCreated = await generateAiConfigs({
483
+ rootDir: rootPath,
484
+ analysisDir: opts.output.replace(/\/$/, ''),
485
+ projectName: result.repoMap.metadata.projectName,
486
+ tools: selectedTools,
487
+ });
488
+ }
489
+ }
490
+ // Files generated
491
+ console.log(' Output Files:');
492
+ console.log(` ├─ ${opts.output}repo-structure.json`);
493
+ console.log(` ├─ ${opts.output}dependency-graph.json`);
494
+ console.log(` ├─ ${opts.output}llm-context.json`);
495
+ console.log(` ├─ ${opts.output}dependencies.mermaid`);
496
+ if (artifacts.repoStructure.schemas.length > 0) {
497
+ console.log(` ├─ ${opts.output}schema-inventory.json (${artifacts.repoStructure.schemas.length} table(s))`);
498
+ }
499
+ if (artifacts.repoStructure.routeInventory.total > 0) {
500
+ console.log(` ├─ ${opts.output}route-inventory.json (${artifacts.repoStructure.routeInventory.total} route(s))`);
501
+ }
502
+ if (artifacts.repoStructure.middleware.length > 0) {
503
+ console.log(` ├─ ${opts.output}middleware-inventory.json (${artifacts.repoStructure.middleware.length} middleware entry(ies))`);
504
+ }
505
+ if (artifacts.repoStructure.uiComponents.length > 0) {
506
+ console.log(` ├─ ${opts.output}ui-inventory.json (${artifacts.repoStructure.uiComponents.length} UI component(s))`);
507
+ }
508
+ if (artifacts.repoStructure.envVars.length > 0) {
509
+ console.log(` ├─ ${opts.output}env-inventory.json (${artifacts.repoStructure.envVars.length} env var(s))`);
510
+ }
511
+ if (architectureMdWritten) {
512
+ console.log(` ├─ ${opts.output}SUMMARY.md`);
513
+ console.log(' ├─ ARCHITECTURE.md');
514
+ }
515
+ else {
516
+ console.log(` ├─ ${opts.output}SUMMARY.md`);
517
+ }
518
+ if (digestWritten) {
519
+ console.log(` └─ ${opts.output}CODEBASE.md`);
520
+ console.log('');
521
+ console.log(' Agent setup (one-time):');
522
+ console.log(` Add to your CLAUDE.md or .clinerules:`);
523
+ console.log('');
524
+ console.log(` @.openlore/analysis/CODEBASE.md`);
525
+ console.log('');
526
+ console.log(' ## openlore MCP tools — when to use them');
527
+ console.log(' | Situation | Tool |');
528
+ console.log(' |-------------------------------------------------|-----------------------------------|');
529
+ console.log(" | Don't know which file/function handles a concept | search_code |");
530
+ console.log(' | Need call topology across many files | get_subgraph / analyze_impact |');
531
+ console.log(' | Starting a new task on an unfamiliar codebase | orient |');
532
+ console.log(' | Planning where to add a feature | suggest_insertion_points |');
533
+ console.log(' | Checking if code still matches spec | check_spec_drift |');
534
+ console.log(' | Finding spec requirements by meaning | search_specs |');
535
+ }
536
+ console.log('');
537
+ if (aiConfigsCreated.length > 0) {
538
+ console.log(' Agent config files:');
539
+ for (const { rel, created } of aiConfigsCreated) {
540
+ const tag = created ? '(created)' : '(already exists)';
541
+ console.log(` ├─ ${rel} ${tag}`);
542
+ }
543
+ }
544
+ else {
545
+ console.log(' Agent config files: not generated');
546
+ console.log(' Tip: Re-run with --ai-configs to generate CLAUDE.md, .cursorrules, AGENTS.md, etc.');
547
+ }
548
+ console.log('');
549
+ // ========================================================================
550
+ // PHASE 5 (optional): BUILD VECTOR INDEX
551
+ // ========================================================================
552
+ if (opts.embed) {
553
+ await runEmbedStep(rootPath, outputPath, openloreConfig, opts.force ?? false, result.artifacts.llmContext);
554
+ }
555
+ // Duration
556
+ const totalDuration = Date.now() - startTime;
557
+ console.log(` Total time: ${formatDuration(totalDuration)}`);
558
+ console.log('');
559
+ logger.success('Ready for generation!');
560
+ logger.blank();
561
+ logger.info('Next step', "Run 'openlore generate' to create OpenSpec files");
562
+ }
563
+ catch (error) {
564
+ logger.error(`Analysis failed: ${error.message}`);
565
+ if (process.env.DEBUG) {
566
+ console.error(error);
567
+ }
568
+ process.exitCode = 1;
569
+ }
570
+ });
571
+ // ============================================================================
572
+ // EMBED STEP HELPER
573
+ // ============================================================================
574
+ /**
575
+ * Build (or incrementally update) the vector index from a LLMContext.
576
+ * When llmContext is null, reads llm-context.json from outputDir (cache path).
577
+ * Non-fatal: prints a warning on failure without throwing.
578
+ */
579
+ async function runEmbedStep(rootPath, outputPath, openloreConfig, force, llmContext) {
580
+ console.log(' Building semantic vector index...');
581
+ try {
582
+ const { EmbeddingService } = await import('../../core/analyzer/embedding-service.js');
583
+ const { VectorIndex } = await import('../../core/analyzer/vector-index.js');
584
+ // Resolve embedding service
585
+ let embedSvc;
586
+ try {
587
+ embedSvc = EmbeddingService.fromEnv();
588
+ }
589
+ catch {
590
+ const cfg = openloreConfig ?? await readOpenLoreConfig(rootPath);
591
+ if (!cfg)
592
+ throw new Error('No embedding config found. Set EMBED_BASE_URL and EMBED_MODEL, or add "embedding" to .openlore/config.json');
593
+ const svcFromConfig = EmbeddingService.fromConfig(cfg);
594
+ if (!svcFromConfig)
595
+ throw new Error('No embedding config found. Set EMBED_BASE_URL and EMBED_MODEL, or add "embedding" to .openlore/config.json');
596
+ embedSvc = svcFromConfig;
597
+ }
598
+ // Load context from disk if not provided (cache hit path)
599
+ if (!llmContext) {
600
+ try {
601
+ const raw = await readFile(join(outputPath, 'llm-context.json'), 'utf-8');
602
+ llmContext = JSON.parse(raw);
603
+ }
604
+ catch {
605
+ console.log(' ⚠ Could not read llm-context.json — run openlore analyze --force');
606
+ return;
607
+ }
608
+ }
609
+ const cg = llmContext.callGraph;
610
+ const sigs = llmContext.signatures ?? [];
611
+ if (!cg || cg.nodes.length === 0) {
612
+ console.log(' ⚠ No call graph data — function index skipped');
613
+ }
614
+ else {
615
+ const hubIds = new Set(cg.hubFunctions.map(f => f.id));
616
+ const entryIds = new Set(cg.entryPoints.map(f => f.id));
617
+ const fileContents = new Map();
618
+ const uniquePaths = new Set(cg.nodes.map(n => n.filePath));
619
+ await Promise.all([...uniquePaths].map(async (fp) => {
620
+ try {
621
+ fileContents.set(fp, await readFile(join(rootPath, fp), 'utf-8'));
622
+ }
623
+ catch { /* skip unreadable files */ }
624
+ }));
625
+ const { embedded, reused } = await VectorIndex.build(outputPath, cg.nodes, sigs, hubIds, entryIds, embedSvc, fileContents,
626
+ /* incremental */ !force);
627
+ const total = embedded + reused;
628
+ const cacheNote = reused > 0 ? ` (${embedded} embedded, ${reused} cached)` : '';
629
+ console.log(` ✓ Function index built (${total} functions${cacheNote}, ${fileContents.size} files with skeleton bodies)`);
630
+ console.log(` → ${outputPath.replace(rootPath + '/', '')}vector-index/`);
631
+ }
632
+ // Also index specs if they exist
633
+ await runSpecIndexing(rootPath, outputPath, openloreConfig);
634
+ }
635
+ catch (embedErr) {
636
+ console.log(` ✗ Vector index failed: ${embedErr.message}`);
637
+ }
638
+ console.log('');
639
+ }
640
+ // ============================================================================
641
+ // SPEC INDEXING HELPER
642
+ // ============================================================================
643
+ /**
644
+ * Index OpenSpec specs into the vector index.
645
+ * Looks for specs in <rootPath>/openspec/specs/ (configured or default).
646
+ * Non-fatal: prints a warning if no specs found or embedding fails.
647
+ */
648
+ async function runSpecIndexing(rootPath, outputPath, openloreConfig) {
649
+ const { join: pathJoin } = await import('node:path');
650
+ const { SpecVectorIndex } = await import('../../core/analyzer/spec-vector-index.js');
651
+ const { readOpenLoreConfig } = await import('../../core/services/config-manager.js');
652
+ // Resolve embedding service
653
+ let embedSvc;
654
+ try {
655
+ embedSvc = EmbeddingService.fromEnv();
656
+ }
657
+ catch {
658
+ const cfg = openloreConfig ?? await readOpenLoreConfig(rootPath);
659
+ if (!cfg)
660
+ return; // no embedding config — silently skip
661
+ const svc = EmbeddingService.fromConfig(cfg);
662
+ if (!svc)
663
+ return;
664
+ embedSvc = svc;
665
+ }
666
+ // Locate specs directory
667
+ const specsDir = pathJoin(rootPath, OPENSPEC_DIR, OPENSPEC_SPECS_SUBDIR);
668
+ if (!(await fileExists(specsDir))) {
669
+ console.log(` ℹ No ${OPENSPEC_DIR}/${OPENSPEC_SPECS_SUBDIR}/ directory found — spec index skipped`);
670
+ return;
671
+ }
672
+ const mappingJsonPath = pathJoin(outputPath, 'mapping.json');
673
+ try {
674
+ const decisionsDir = pathJoin(rootPath, OPENSPEC_DIR, OPENSPEC_DECISIONS_SUBDIR);
675
+ const { recordCount } = await SpecVectorIndex.build(outputPath, specsDir, embedSvc, mappingJsonPath, decisionsDir);
676
+ console.log(` ✓ Spec index built (${recordCount} sections)`);
677
+ console.log(` → ${outputPath.replace(rootPath + '/', '')}vector-index/`);
678
+ }
679
+ catch (err) {
680
+ console.log(` ⚠ Spec index skipped: ${err.message}`);
681
+ }
682
+ }
683
+ //# sourceMappingURL=analyze.js.map