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,963 @@
1
+ /**
2
+ * OpenSpec Format Generator
3
+ *
4
+ * Takes structured LLM outputs and formats them into clean OpenSpec-compatible
5
+ * specification files.
6
+ */
7
+ const DEFAULT_OPTIONS = {
8
+ version: '1.0.0',
9
+ style: 'detailed',
10
+ includeConfidence: true,
11
+ includeTechnicalNotes: true,
12
+ maxLineWidth: 100,
13
+ };
14
+ // ============================================================================
15
+ // OPENSPEC FORMAT GENERATOR
16
+ // ============================================================================
17
+ /**
18
+ * OpenSpec Format Generator
19
+ */
20
+ export class OpenSpecFormatGenerator {
21
+ options;
22
+ constructor(options = {}) {
23
+ const { depGraph, ...rest } = options;
24
+ this.options = { ...DEFAULT_OPTIONS, ...rest, depGraph };
25
+ }
26
+ /**
27
+ * Generate all spec files from pipeline result.
28
+ * Pass mappingArtifact to annotate each Requirement with `> Implementation: file:line`.
29
+ */
30
+ generateSpecs(result, mappingArtifact) {
31
+ const specs = [];
32
+ const domains = this.groupByDomain(result);
33
+ // 1. Overview spec
34
+ specs.push(this.generateOverviewSpec(result.survey, domains, result.architecture));
35
+ // 2. Domain specs
36
+ for (const domain of domains) {
37
+ specs.push(this.generateDomainSpec(domain, result.survey, mappingArtifact));
38
+ }
39
+ // 3. Architecture spec
40
+ specs.push(this.generateArchitectureSpec(result.architecture, result.survey, domains));
41
+ // 4. API spec (if endpoints exist)
42
+ if (result.endpoints.length > 0) {
43
+ specs.push(this.generateApiSpec(result.endpoints, result.survey));
44
+ }
45
+ return specs;
46
+ }
47
+ /**
48
+ * Group entities, services, and endpoints by domain
49
+ */
50
+ groupByDomain(result) {
51
+ const domainMap = new Map();
52
+ // Initialize domains from survey suggestions
53
+ for (const domainName of result.survey.suggestedDomains) {
54
+ domainMap.set(domainName.toLowerCase(), {
55
+ name: domainName,
56
+ description: '',
57
+ entities: [],
58
+ services: [],
59
+ endpoints: [],
60
+ files: [],
61
+ });
62
+ }
63
+ // Add entities to domains
64
+ for (const entity of result.entities) {
65
+ const domainName = this.inferDomain(entity.name, entity.location, result.survey.suggestedDomains);
66
+ let domain = domainMap.get(domainName.toLowerCase());
67
+ if (!domain) {
68
+ domain = {
69
+ name: domainName,
70
+ description: '',
71
+ entities: [],
72
+ services: [],
73
+ endpoints: [],
74
+ files: [],
75
+ };
76
+ domainMap.set(domainName.toLowerCase(), domain);
77
+ }
78
+ domain.entities.push(entity);
79
+ if (entity.location && !domain.files.includes(entity.location)) {
80
+ domain.files.push(entity.location);
81
+ }
82
+ }
83
+ // Add services to domains
84
+ for (const service of result.services) {
85
+ const domainName = service.domain || this.inferDomain(service.name, '', result.survey.suggestedDomains);
86
+ let domain = domainMap.get(domainName.toLowerCase());
87
+ if (!domain) {
88
+ domain = {
89
+ name: domainName,
90
+ description: '',
91
+ entities: [],
92
+ services: [],
93
+ endpoints: [],
94
+ files: [],
95
+ };
96
+ domainMap.set(domainName.toLowerCase(), domain);
97
+ }
98
+ domain.services.push(service);
99
+ }
100
+ // Add endpoints to domains
101
+ for (const endpoint of result.endpoints) {
102
+ const domainName = endpoint.relatedEntity
103
+ ? this.inferDomain(endpoint.relatedEntity, endpoint.path, result.survey.suggestedDomains)
104
+ : 'api';
105
+ let domain = domainMap.get(domainName.toLowerCase());
106
+ if (!domain) {
107
+ domain = {
108
+ name: domainName,
109
+ description: '',
110
+ entities: [],
111
+ services: [],
112
+ endpoints: [],
113
+ files: [],
114
+ };
115
+ domainMap.set(domainName.toLowerCase(), domain);
116
+ }
117
+ domain.endpoints.push(endpoint);
118
+ }
119
+ // Set descriptions based on content — prefer service purpose (descriptive) over entity list
120
+ for (const domain of domainMap.values()) {
121
+ if (domain.services.length > 0) {
122
+ const representative = domain.services.find(s => s.name.toLowerCase().includes(domain.name.toLowerCase())) ?? domain.services[0];
123
+ domain.description = representative.purpose;
124
+ }
125
+ else if (domain.entities.length > 0) {
126
+ const preview = domain.entities.slice(0, 3).map(e => e.name).join(', ');
127
+ const extra = domain.entities.length > 3 ? ` and ${domain.entities.length - 3} more` : '';
128
+ domain.description = `Defines core data models: ${preview}${extra}.`;
129
+ }
130
+ else if (domain.endpoints.length > 0) {
131
+ const firstPurpose = domain.endpoints[0]?.purpose;
132
+ domain.description = firstPurpose
133
+ ? firstPurpose
134
+ : `Provides ${domain.endpoints.length} API endpoint${domain.endpoints.length > 1 ? 's' : ''}`;
135
+ }
136
+ }
137
+ // Filter out empty domains
138
+ return Array.from(domainMap.values()).filter(d => d.entities.length > 0 || d.services.length > 0 || d.endpoints.length > 0);
139
+ }
140
+ /**
141
+ * Infer domain from name and location
142
+ */
143
+ inferDomain(name, location, suggestedDomains) {
144
+ const nameLower = (name ?? '').toLowerCase();
145
+ const locationLower = (location ?? '').toLowerCase();
146
+ // Check suggested domains first
147
+ for (const domain of suggestedDomains) {
148
+ if (nameLower.includes(domain.toLowerCase()) || locationLower.includes(domain.toLowerCase())) {
149
+ return domain;
150
+ }
151
+ }
152
+ // Fall back to first suggested domain rather than inventing one from the name prefix
153
+ return suggestedDomains[0] ?? 'core';
154
+ }
155
+ /**
156
+ * Generate the overview spec
157
+ */
158
+ generateOverviewSpec(survey, domains, architecture) {
159
+ const lines = [];
160
+ const now = new Date();
161
+ const date = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
162
+ // Header
163
+ lines.push('# System Overview');
164
+ lines.push('');
165
+ lines.push(`> Generated by openlore v${this.options.version} on ${date}`);
166
+ if (this.options.includeConfidence) {
167
+ lines.push(`> Confidence: ${Math.round(survey.confidence * 100)}%`);
168
+ }
169
+ lines.push('');
170
+ // Purpose
171
+ lines.push('## Purpose');
172
+ lines.push('');
173
+ lines.push(this.wrapText(architecture.systemPurpose));
174
+ lines.push('');
175
+ // Domains
176
+ lines.push('## Domains');
177
+ lines.push('');
178
+ lines.push('This system is organized into the following domains:');
179
+ lines.push('');
180
+ lines.push('| Domain | Description | Spec |');
181
+ lines.push('|--------|-------------|------|');
182
+ for (const domain of domains) {
183
+ const specPath = `../${domain.name.toLowerCase()}/spec.md`;
184
+ lines.push(`| ${this.capitalize(domain.name)} | ${domain.description || 'No description'} | [spec.md](${specPath}) |`);
185
+ }
186
+ lines.push('');
187
+ // Technical Stack
188
+ lines.push('## Technical Stack');
189
+ lines.push('');
190
+ lines.push(`- **Type**: ${this.formatCategory(survey.projectCategory)}`);
191
+ lines.push(`- **Primary Language**: ${survey.primaryLanguage}`);
192
+ lines.push(`- **Key Frameworks**: ${survey.frameworks.join(', ') || 'None detected'}`);
193
+ lines.push(`- **Architecture**: ${this.formatArchitecture(survey.architecturePattern)}`);
194
+ lines.push('');
195
+ // Requirements
196
+ lines.push('## Requirements');
197
+ lines.push('');
198
+ // Generate capabilities from architecture
199
+ if (architecture.keyDecisions.length > 0) {
200
+ lines.push('### Requirement: SystemCapabilities');
201
+ lines.push('');
202
+ lines.push('The system SHALL provide the following capabilities:');
203
+ for (const decision of architecture.keyDecisions) {
204
+ lines.push(`- ${decision}`);
205
+ }
206
+ lines.push('');
207
+ lines.push('#### Scenario: CapabilitiesProvided');
208
+ lines.push('- **GIVEN** the system is operational');
209
+ lines.push('- **WHEN** a user interacts with the system');
210
+ lines.push('- **THEN** the system provides the documented capabilities');
211
+ lines.push('');
212
+ }
213
+ // Data flow as a scenario
214
+ if (architecture.dataFlow && architecture.dataFlow !== 'Unknown') {
215
+ lines.push('### Requirement: DataFlow');
216
+ lines.push('');
217
+ lines.push('The system SHALL process data through defined layers:');
218
+ lines.push('');
219
+ lines.push('#### Scenario: StandardDataFlow');
220
+ lines.push('- **GIVEN** an incoming request');
221
+ lines.push(`- **WHEN** the request is processed`);
222
+ lines.push(`- **THEN** data flows through: ${architecture.dataFlow}`);
223
+ lines.push('');
224
+ }
225
+ // Technical notes
226
+ if (this.options.includeTechnicalNotes) {
227
+ lines.push('## Technical Notes');
228
+ lines.push('');
229
+ const archStyleNote = typeof architecture.architectureStyle === 'string'
230
+ ? architecture.architectureStyle
231
+ : architecture.architectureStyle?.pattern ?? architecture.architectureStyle?.name ?? JSON.stringify(architecture.architectureStyle);
232
+ lines.push(`- **Architecture Style**: ${archStyleNote}`);
233
+ if (architecture.securityModel && architecture.securityModel !== 'Unknown') {
234
+ lines.push(`- **Security Model**: ${architecture.securityModel}`);
235
+ }
236
+ if (architecture.integrations.length > 0) {
237
+ const integrationNames = architecture.integrations.map(i => typeof i === 'string' ? i : i.name ?? JSON.stringify(i));
238
+ lines.push(`- **External Integrations**: ${integrationNames.join(', ')}`);
239
+ }
240
+ lines.push('');
241
+ }
242
+ return {
243
+ path: 'openspec/specs/overview/spec.md',
244
+ content: lines.join('\n'),
245
+ domain: 'overview',
246
+ type: 'overview',
247
+ };
248
+ }
249
+ /**
250
+ * Generate a domain spec
251
+ */
252
+ generateDomainSpec(domain, _survey, mappingArtifact) {
253
+ const lines = [];
254
+ const now = new Date();
255
+ const date = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
256
+ // Header
257
+ lines.push(`# ${this.capitalize(domain.name)} Specification`);
258
+ lines.push('');
259
+ lines.push(`> Generated by openlore v${this.options.version} on ${date}`);
260
+ if (domain.files.length > 0) {
261
+ lines.push(`> Source files: ${domain.files.join(', ')}`);
262
+ }
263
+ lines.push('');
264
+ // Purpose
265
+ lines.push('## Purpose');
266
+ lines.push('');
267
+ lines.push(this.wrapText(domain.description || `The ${domain.name} domain manages core business logic.`));
268
+ lines.push('');
269
+ // Entities section
270
+ if (domain.entities.length > 0) {
271
+ lines.push('## Entities');
272
+ lines.push('');
273
+ for (const entity of domain.entities) {
274
+ lines.push(`### ${entity.name}`);
275
+ lines.push('');
276
+ if (entity.location) {
277
+ lines.push(`> \`${entity.location}\``);
278
+ lines.push('');
279
+ }
280
+ lines.push(this.wrapText(entity.description));
281
+ lines.push('');
282
+ // Properties table
283
+ if ((entity.properties ?? []).length > 0) {
284
+ lines.push('**Properties:**');
285
+ lines.push('');
286
+ lines.push('| Name | Type | Description |');
287
+ lines.push('|------|------|-------------|');
288
+ for (const prop of (entity.properties ?? [])) {
289
+ const desc = prop.description || (prop.required ? 'Required' : 'Optional');
290
+ lines.push(`| ${prop.name} | ${prop.type} | ${desc} |`);
291
+ }
292
+ lines.push('');
293
+ }
294
+ // Relationships
295
+ if ((entity.relationships ?? []).length > 0) {
296
+ lines.push('**Relationships:**');
297
+ lines.push('');
298
+ for (const rel of (entity.relationships ?? [])) {
299
+ lines.push(`- ${this.formatRelationship(rel)}`);
300
+ }
301
+ lines.push('');
302
+ }
303
+ }
304
+ }
305
+ // Requirements section
306
+ lines.push('## Requirements');
307
+ lines.push('');
308
+ // Entity validation requirements
309
+ for (const entity of domain.entities) {
310
+ if ((entity.validations ?? []).length > 0) {
311
+ lines.push(`### Requirement: ${entity.name}Validation`);
312
+ lines.push('');
313
+ lines.push(`The system SHALL validate ${entity.name} according to these rules:`);
314
+ for (const rule of (entity.validations ?? [])) {
315
+ lines.push(`- ${rule}`);
316
+ }
317
+ lines.push('');
318
+ // Scenarios from entity
319
+ const entityScenarios = entity.scenarios ?? [];
320
+ if (entityScenarios.length > 0) {
321
+ for (const scenario of entityScenarios) {
322
+ this.addScenario(lines, scenario);
323
+ }
324
+ }
325
+ else {
326
+ // Validator requires at least one scenario per requirement
327
+ lines.push(`#### Scenario: Valid${entity.name}Accepted`);
328
+ lines.push(`- **GIVEN** A valid ${entity.name} object with all required fields`);
329
+ lines.push(`- **WHEN** The object is validated`);
330
+ lines.push(`- **THEN** Validation passes with no errors`);
331
+ lines.push('');
332
+ }
333
+ }
334
+ }
335
+ // Service operation requirements
336
+ for (const service of domain.services) {
337
+ if (service.locationFile) {
338
+ lines.push(`> \`${service.locationFile}\``);
339
+ lines.push('');
340
+ }
341
+ for (const operation of (service.operations ?? [])) {
342
+ const reqName = this.formatRequirementName(operation.name);
343
+ lines.push(`### Requirement: ${reqName}`);
344
+ lines.push('');
345
+ this.emitImplementationHint(lines, reqName, domain.name, mappingArtifact);
346
+ const opDesc = (operation.description ?? '').replace(/^\s*(shall|must|should|may)\s+/i, '');
347
+ lines.push(`The system SHALL ${opDesc.toLowerCase()}`);
348
+ lines.push('');
349
+ // Operation scenarios
350
+ for (const scenario of (operation.scenarios ?? [])) {
351
+ this.addScenario(lines, scenario);
352
+ }
353
+ }
354
+ // Sub-components for orchestrator services (god functions)
355
+ if (service.subSpecs && service.subSpecs.length > 0) {
356
+ lines.push('');
357
+ lines.push('## Sub-components');
358
+ lines.push('');
359
+ lines.push(`> \`${service.name}\` is an orchestrator. Each sub-component below implements one logical block.`);
360
+ lines.push('');
361
+ for (const sub of service.subSpecs) {
362
+ lines.push(`### Sub-component: ${this.formatRequirementName(sub.name)}`);
363
+ lines.push('');
364
+ lines.push(`> Implements: \`${sub.callee}\``);
365
+ lines.push('');
366
+ lines.push(sub.purpose);
367
+ lines.push('');
368
+ for (const op of (sub.operations ?? [])) {
369
+ lines.push(`#### Requirement: ${this.formatRequirementName(op.name)}`);
370
+ lines.push('');
371
+ const opDesc = (op.description ?? '').replace(/^\s*(shall|must|should|may)\s+/i, '');
372
+ lines.push(`The system SHALL ${opDesc.toLowerCase()}`);
373
+ lines.push('');
374
+ for (const scenario of (op.scenarios ?? [])) {
375
+ this.addScenario(lines, scenario);
376
+ }
377
+ }
378
+ }
379
+ }
380
+ }
381
+ // Fallback: if no requirements were generated, add a placeholder
382
+ const hasRequirements = domain.entities.some(e => (e.validations ?? []).length > 0) ||
383
+ domain.services.some(s => (s.operations ?? []).length > 0);
384
+ if (!hasRequirements) {
385
+ if (domain.endpoints.length > 0) {
386
+ for (const endpoint of domain.endpoints) {
387
+ const reqName = this.formatRequirementName(endpoint.purpose || `${endpoint.method}${endpoint.path}`);
388
+ lines.push(`### Requirement: ${reqName}`);
389
+ lines.push('');
390
+ this.emitImplementationHint(lines, reqName, domain.name, mappingArtifact);
391
+ const epPurpose = (endpoint.purpose ?? 'handle this endpoint').replace(/^\s*(shall|must|should|may)\s+/i, '');
392
+ lines.push(`The system SHALL ${epPurpose.toLowerCase()}`);
393
+ lines.push('');
394
+ lines.push(`#### Scenario: ${reqName}Success`);
395
+ lines.push(`- **GIVEN** the system is operational`);
396
+ lines.push(`- **WHEN** ${endpoint.method} ${endpoint.path} is called`);
397
+ lines.push(`- **THEN** the request is processed successfully`);
398
+ lines.push('');
399
+ }
400
+ }
401
+ else {
402
+ const reqName = this.formatRequirementName(`${domain.name}Overview`);
403
+ lines.push(`### Requirement: ${reqName}`);
404
+ lines.push('');
405
+ this.emitImplementationHint(lines, reqName, domain.name, mappingArtifact);
406
+ lines.push(`The ${domain.name} domain SHALL provide its documented functionality.`);
407
+ lines.push('');
408
+ lines.push(`#### Scenario: ${reqName}Works`);
409
+ lines.push('- **GIVEN** the system is operational');
410
+ lines.push('- **WHEN** the domain functionality is invoked');
411
+ lines.push('- **THEN** the expected outcome is produced');
412
+ lines.push('');
413
+ }
414
+ }
415
+ // Technical notes
416
+ if (this.options.includeTechnicalNotes && domain.services.length > 0) {
417
+ lines.push('## Technical Notes');
418
+ lines.push('');
419
+ const allFiles = new Set(domain.files);
420
+ const allDeps = new Set();
421
+ for (const service of domain.services) {
422
+ for (const dep of (service.dependencies ?? [])) {
423
+ allDeps.add(dep);
424
+ }
425
+ }
426
+ if (allFiles.size > 0) {
427
+ lines.push(`- **Implementation**: \`${Array.from(allFiles).join(', ')}\``);
428
+ }
429
+ if (allDeps.size > 0) {
430
+ lines.push(`- **Dependencies**: ${Array.from(allDeps).join(', ')}`);
431
+ }
432
+ lines.push('');
433
+ }
434
+ // Cross-domain dependency section (requires depGraph)
435
+ const depSection = this.buildDependencySection(domain.name, domain.files);
436
+ if (depSection.length > 0) {
437
+ lines.push(...depSection);
438
+ }
439
+ return {
440
+ path: `openspec/specs/${domain.name.toLowerCase()}/spec.md`,
441
+ content: lines.join('\n'),
442
+ domain: domain.name.toLowerCase(),
443
+ type: 'domain',
444
+ };
445
+ }
446
+ /**
447
+ * Generate the architecture spec
448
+ */
449
+ generateArchitectureSpec(architecture, _survey, _domains) {
450
+ const lines = [];
451
+ const now = new Date();
452
+ const date = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
453
+ // Header
454
+ lines.push('# Architecture Specification');
455
+ lines.push('');
456
+ lines.push(`> Generated by openlore v${this.options.version} on ${date}`);
457
+ lines.push('');
458
+ // Purpose
459
+ lines.push('## Purpose');
460
+ lines.push('');
461
+ lines.push('This document describes the architectural patterns and structure of the system.');
462
+ lines.push('');
463
+ // Architecture Style
464
+ lines.push('## Architecture Style');
465
+ lines.push('');
466
+ const archStyle = architecture.architectureStyle;
467
+ const archStyleStr = typeof archStyle === 'string'
468
+ ? archStyle
469
+ : archStyle?.pattern ?? archStyle?.name ?? JSON.stringify(archStyle);
470
+ const archJustification = typeof archStyle === 'object' && archStyle !== null
471
+ ? archStyle?.justification
472
+ : undefined;
473
+ lines.push(this.wrapText(archStyleStr));
474
+ if (archJustification) {
475
+ lines.push('');
476
+ lines.push(`*${archJustification}*`);
477
+ }
478
+ lines.push('');
479
+ // Requirements
480
+ lines.push('## Requirements');
481
+ lines.push('');
482
+ // Layered architecture requirement
483
+ if (architecture.layerMap.length > 0) {
484
+ lines.push('### Requirement: LayeredArchitecture');
485
+ lines.push('');
486
+ lines.push('The system SHALL maintain separation between:');
487
+ for (const layer of architecture.layerMap) {
488
+ lines.push(`- ${layer.name} (${layer.purpose})`);
489
+ }
490
+ lines.push('');
491
+ lines.push('#### Scenario: LayerSeparation');
492
+ lines.push('- **GIVEN** a request from the presentation layer');
493
+ lines.push('- **WHEN** business logic is needed');
494
+ lines.push('- **THEN** the presentation layer delegates to the business layer');
495
+ lines.push('- **AND** direct database access from presentation is prohibited');
496
+ lines.push('');
497
+ }
498
+ // Security requirement
499
+ if (architecture.securityModel && architecture.securityModel !== 'Unknown') {
500
+ lines.push('### Requirement: SecurityModel');
501
+ lines.push('');
502
+ lines.push(`The system SHALL implement security via: ${architecture.securityModel}`);
503
+ lines.push('');
504
+ lines.push('#### Scenario: AuthenticatedAccess');
505
+ lines.push('- **GIVEN** an unauthenticated request');
506
+ lines.push('- **WHEN** accessing protected resources');
507
+ lines.push('- **THEN** access is denied');
508
+ lines.push('');
509
+ }
510
+ // System Diagram (Mermaid)
511
+ lines.push('## System Diagram');
512
+ lines.push('');
513
+ lines.push('```mermaid');
514
+ lines.push('graph TB');
515
+ // Generate layer diagram
516
+ for (let i = 0; i < architecture.layerMap.length; i++) {
517
+ const layer = architecture.layerMap[i];
518
+ const layerId = layer.name.replace(/\s+/g, '');
519
+ lines.push(` ${layerId}[${layer.name}]`);
520
+ if (i < architecture.layerMap.length - 1) {
521
+ const nextLayerId = architecture.layerMap[i + 1].name.replace(/\s+/g, '');
522
+ lines.push(` ${layerId} --> ${nextLayerId}`);
523
+ }
524
+ }
525
+ lines.push('```');
526
+ lines.push('');
527
+ // Layer Structure
528
+ lines.push('## Layer Structure');
529
+ lines.push('');
530
+ for (const layer of architecture.layerMap) {
531
+ lines.push(`### ${layer.name}`);
532
+ lines.push('');
533
+ lines.push(`**Purpose**: ${layer.purpose}`);
534
+ if (layer.components.length > 0) {
535
+ lines.push(`**Location**: \`${layer.components.join(', ')}\``);
536
+ }
537
+ lines.push('');
538
+ }
539
+ // Data Flow
540
+ lines.push('## Data Flow');
541
+ lines.push('');
542
+ if (architecture.dataFlow && architecture.dataFlow !== 'Unknown') {
543
+ lines.push(this.wrapText(architecture.dataFlow));
544
+ }
545
+ else {
546
+ lines.push('Data flows through the defined layers in sequence.');
547
+ }
548
+ lines.push('');
549
+ // External Integrations
550
+ if (architecture.integrations.length > 0) {
551
+ lines.push('## External Integrations');
552
+ lines.push('');
553
+ lines.push('| System | Purpose |');
554
+ lines.push('|--------|---------|');
555
+ for (const integration of architecture.integrations) {
556
+ const name = typeof integration === 'string' ? integration : integration.name ?? String(integration);
557
+ const purpose = typeof integration === 'object' && integration !== null
558
+ ? (integration.purpose ?? 'External integration')
559
+ : 'External integration';
560
+ lines.push(`| ${name} | ${purpose} |`);
561
+ }
562
+ lines.push('');
563
+ }
564
+ return {
565
+ path: 'openspec/specs/architecture/spec.md',
566
+ content: lines.join('\n'),
567
+ domain: 'architecture',
568
+ type: 'architecture',
569
+ };
570
+ }
571
+ /**
572
+ * Generate the API spec
573
+ */
574
+ generateApiSpec(endpoints, _survey) {
575
+ const lines = [];
576
+ const now = new Date();
577
+ const date = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
578
+ // Header
579
+ lines.push('# API Specification');
580
+ lines.push('');
581
+ lines.push(`> Generated by openlore v${this.options.version} on ${date}`);
582
+ lines.push('');
583
+ // Purpose
584
+ lines.push('## Purpose');
585
+ lines.push('');
586
+ lines.push('This document specifies the HTTP API exposed by the system.');
587
+ lines.push('');
588
+ // Requirements section (always present)
589
+ lines.push('## Requirements');
590
+ lines.push('');
591
+ // Authentication requirement
592
+ const authMethods = new Set(endpoints.map(e => e.authentication).filter(Boolean));
593
+ if (authMethods.size > 0) {
594
+ lines.push('### Requirement: APIAuthentication');
595
+ lines.push('');
596
+ lines.push(`The API SHALL require authentication via: ${Array.from(authMethods).join(', ')}`);
597
+ lines.push('');
598
+ lines.push('#### Scenario: AuthenticatedRequest');
599
+ lines.push('- **GIVEN** a request with valid authentication credentials');
600
+ lines.push('- **WHEN** the request is processed');
601
+ lines.push('- **THEN** the request is authenticated successfully');
602
+ lines.push('');
603
+ lines.push('#### Scenario: UnauthenticatedRequest');
604
+ lines.push('- **GIVEN** a request without authentication');
605
+ lines.push('- **WHEN** accessing a protected endpoint');
606
+ lines.push('- **THEN** the response status is 401 Unauthorized');
607
+ lines.push('');
608
+ }
609
+ // Group endpoints by related entity
610
+ const endpointsByResource = new Map();
611
+ for (const endpoint of endpoints) {
612
+ const resource = endpoint.relatedEntity || 'General';
613
+ const existing = endpointsByResource.get(resource) || [];
614
+ existing.push(endpoint);
615
+ endpointsByResource.set(resource, existing);
616
+ }
617
+ // Endpoint requirements (under ## Requirements, no separate ## Endpoints section)
618
+ for (const [resource, resourceEndpoints] of endpointsByResource) {
619
+ for (const endpoint of resourceEndpoints) {
620
+ const reqName = this.formatRequirementName(`${endpoint.method}${resource}`);
621
+ lines.push(`### Requirement: ${reqName}`);
622
+ lines.push('');
623
+ lines.push(`The API SHALL support \`${endpoint.method} ${endpoint.path}\` to ${(endpoint.purpose ?? '').toLowerCase()}`);
624
+ lines.push('');
625
+ // Request schema
626
+ if (endpoint.requestSchema && Object.keys(endpoint.requestSchema).length > 0) {
627
+ lines.push('**Request:**');
628
+ lines.push('');
629
+ lines.push('```json');
630
+ lines.push(JSON.stringify(endpoint.requestSchema, null, 2));
631
+ lines.push('```');
632
+ lines.push('');
633
+ }
634
+ // Response schema
635
+ if (endpoint.responseSchema && Object.keys(endpoint.responseSchema).length > 0) {
636
+ lines.push('**Response:**');
637
+ lines.push('');
638
+ lines.push('```json');
639
+ lines.push(JSON.stringify(endpoint.responseSchema, null, 2));
640
+ lines.push('```');
641
+ lines.push('');
642
+ }
643
+ // Scenarios
644
+ for (const scenario of (endpoint.scenarios ?? [])) {
645
+ this.addScenario(lines, scenario);
646
+ }
647
+ // Default success scenario if none provided
648
+ if ((endpoint.scenarios ?? []).length === 0) {
649
+ lines.push(`#### Scenario: ${reqName}Success`);
650
+ lines.push('- **GIVEN** an authenticated user');
651
+ lines.push(`- **WHEN** \`${endpoint.method} ${endpoint.path}\` is called with valid data`);
652
+ lines.push('- **THEN** the response status is 200 OK');
653
+ lines.push('');
654
+ }
655
+ }
656
+ }
657
+ return {
658
+ path: 'openspec/specs/api/spec.md',
659
+ content: lines.join('\n'),
660
+ domain: 'api',
661
+ type: 'api',
662
+ };
663
+ }
664
+ /**
665
+ * Emit `> Implementation: \`file:line\`` after a Requirement header when a
666
+ * high-confidence mapping entry exists. Mutates `lines` in-place.
667
+ */
668
+ emitImplementationHint(lines, reqName, domainName, mappingArtifact) {
669
+ if (!mappingArtifact)
670
+ return;
671
+ const normReq = reqName.toLowerCase().replace(/[^a-z0-9]/g, '');
672
+ const match = mappingArtifact.mappings.find(m => {
673
+ const normM = m.requirement.toLowerCase().replace(/[^a-z0-9]/g, '');
674
+ return normM === normReq && m.domain.toLowerCase() === domainName.toLowerCase();
675
+ });
676
+ if (!match || match.functions.length === 0)
677
+ return;
678
+ const best = [...match.functions].sort((a, b) => {
679
+ const order = { llm: 0, semantic: 1, heuristic: 2 };
680
+ return (order[a.confidence] ?? 3) - (order[b.confidence] ?? 3);
681
+ })[0];
682
+ lines.push(`> Implementation: \`${best.name}\` in \`${best.file}\` · confidence: ${best.confidence}`);
683
+ lines.push('');
684
+ }
685
+ /**
686
+ * Build `## Dependencies` section for a domain spec using depGraph edges.
687
+ * Returns an empty array if no depGraph or no cross-domain edges found.
688
+ */
689
+ buildDependencySection(domainName, _domainFiles) {
690
+ const depGraph = this.options.depGraph;
691
+ if (!depGraph)
692
+ return [];
693
+ // Resolve the cluster for this domain from depGraph
694
+ const cluster = depGraph.clusters.find(c => c.suggestedDomain.toLowerCase() === domainName.toLowerCase());
695
+ if (!cluster || cluster.files.length === 0)
696
+ return [];
697
+ const domainFileSet = new Set(cluster.files);
698
+ // Build file → cluster mapping
699
+ const clusterByFile = new Map();
700
+ for (const c of depGraph.clusters) {
701
+ for (const f of c.files) {
702
+ if (!clusterByFile.has(f)) {
703
+ clusterByFile.set(f, { id: c.id, suggestedDomain: c.suggestedDomain });
704
+ }
705
+ }
706
+ }
707
+ // Scan edges for cross-domain calls
708
+ const callsInto = new Map(); // target domain → imported names
709
+ const calledBy = new Map(); // source domain → imported names
710
+ for (const edge of depGraph.edges) {
711
+ const srcInDomain = domainFileSet.has(edge.source);
712
+ const tgtInDomain = domainFileSet.has(edge.target);
713
+ if (srcInDomain === tgtInDomain)
714
+ continue; // intra-domain or unrelated
715
+ if (srcInDomain) {
716
+ const tgtCluster = clusterByFile.get(edge.target);
717
+ const tgtDomain = tgtCluster?.suggestedDomain.toLowerCase();
718
+ if (tgtDomain && tgtDomain !== domainName.toLowerCase()) {
719
+ if (!callsInto.has(tgtDomain))
720
+ callsInto.set(tgtDomain, new Set());
721
+ for (const name of (edge.importedNames ?? []))
722
+ callsInto.get(tgtDomain).add(name);
723
+ }
724
+ }
725
+ else {
726
+ const srcCluster = clusterByFile.get(edge.source);
727
+ const srcDomain = srcCluster?.suggestedDomain.toLowerCase();
728
+ if (srcDomain && srcDomain !== domainName.toLowerCase()) {
729
+ if (!calledBy.has(srcDomain))
730
+ calledBy.set(srcDomain, new Set());
731
+ for (const name of (edge.importedNames ?? []))
732
+ calledBy.get(srcDomain).add(name);
733
+ }
734
+ }
735
+ }
736
+ if (callsInto.size === 0 && calledBy.size === 0)
737
+ return [];
738
+ const lines = ['## Dependencies', ''];
739
+ if (calledBy.size > 0) {
740
+ lines.push('### Called by this domain');
741
+ for (const [srcDomain, names] of [...calledBy.entries()].sort()) {
742
+ const nameList = [...names].slice(0, 3).map(n => `\`${n}\``).join(', ');
743
+ lines.push(`- \`${srcDomain}\`${nameList ? ` → ${nameList}` : ''}`);
744
+ }
745
+ lines.push('');
746
+ }
747
+ if (callsInto.size > 0) {
748
+ lines.push('### Calls into');
749
+ for (const [tgtDomain, names] of [...callsInto.entries()].sort()) {
750
+ const nameList = [...names].slice(0, 3).map(n => `\`${n}\``).join(', ');
751
+ lines.push(`- \`${tgtDomain}\`${nameList ? ` → ${nameList}` : ''}`);
752
+ }
753
+ lines.push('');
754
+ }
755
+ return lines;
756
+ }
757
+ /**
758
+ * Infer a openlore-test annotation from scenario name and THEN clause.
759
+ * Returns null when no annotation is worth emitting (all defaults).
760
+ */
761
+ inferTestAnnotation(scenarioName, then) {
762
+ const text = `${scenarioName} ${then}`.toLowerCase();
763
+ const tags = [];
764
+ let priority = null;
765
+ // Tag: smoke — happy-path / successful scenarios
766
+ // Use \b to avoid matching "valid" inside "invalid"
767
+ if (/success|\bvalid(?:ation)?\b|happy|creat|register|accept/.test(text)) {
768
+ tags.push('smoke');
769
+ }
770
+ // Tag: regression — error / failure / rejection scenarios
771
+ if (/invalid|error|fail|missing|reject|unauthori|forbidden|duplicate|conflict|expired|wrong/.test(text)) {
772
+ tags.push('regression');
773
+ }
774
+ // Priority: high — security, auth, payment, permissions
775
+ if (/auth|login|logout|jwt|token|password|payment|billing|permission|role|security|access/.test(text)) {
776
+ priority = 'high';
777
+ }
778
+ // Priority: low — legacy, deprecated, backwards-compat
779
+ if (/legacy|deprecated|backcompat|backward/.test(text)) {
780
+ priority = 'low';
781
+ }
782
+ const parts = [];
783
+ if (priority)
784
+ parts.push(`priority=${priority}`);
785
+ if (tags.length > 0)
786
+ parts.push(`tags=${tags.join(',')}`);
787
+ if (parts.length === 0)
788
+ return null;
789
+ return `<!-- openlore-test: ${parts.join(' ')} (auto) -->`;
790
+ }
791
+ /**
792
+ * Add a scenario to the lines array
793
+ */
794
+ addScenario(lines, scenario) {
795
+ lines.push(`#### Scenario: ${this.formatRequirementName(scenario.name)}`);
796
+ const annotation = this.inferTestAnnotation(scenario.name ?? '', scenario.then ?? '');
797
+ if (annotation)
798
+ lines.push(annotation);
799
+ lines.push(`- **GIVEN** ${this.wrapText(scenario.given ?? 'the system is in a valid state')}`);
800
+ lines.push(`- **WHEN** ${this.wrapText(scenario.when ?? 'the operation is invoked')}`);
801
+ lines.push(`- **THEN** ${this.wrapText(scenario.then ?? 'the expected outcome occurs')}`);
802
+ if (scenario.and && scenario.and.length > 0) {
803
+ const andClauses = Array.isArray(scenario.and) ? scenario.and : [scenario.and];
804
+ for (const andClause of andClauses) {
805
+ lines.push(`- **AND** ${this.wrapText(andClause)}`);
806
+ }
807
+ }
808
+ lines.push('');
809
+ }
810
+ /**
811
+ * Format a requirement name (PascalCase, no spaces)
812
+ */
813
+ formatRequirementName(name) {
814
+ if (!name)
815
+ return 'Unnamed';
816
+ return name
817
+ .split(/[\s_-]+/)
818
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
819
+ .join('');
820
+ }
821
+ /**
822
+ * Format a relationship for display
823
+ */
824
+ formatRelationship(rel) {
825
+ const typeLabel = {
826
+ 'one-to-one': 'has one',
827
+ 'one-to-many': 'has many',
828
+ 'many-to-many': 'has many',
829
+ 'belongs-to': 'belongs to',
830
+ }[rel.type] || rel.type;
831
+ return `${typeLabel} ${rel.targetEntity}${rel.description ? ` (${rel.description})` : ''}`;
832
+ }
833
+ /**
834
+ * Format project category for display
835
+ */
836
+ formatCategory(category) {
837
+ const labels = {
838
+ 'web-frontend': 'Web Frontend Application',
839
+ 'web-backend': 'Web Backend Service',
840
+ 'api-service': 'API Service',
841
+ 'cli-tool': 'Command Line Tool',
842
+ library: 'Library/Package',
843
+ 'mobile-app': 'Mobile Application',
844
+ 'desktop-app': 'Desktop Application',
845
+ 'data-pipeline': 'Data Pipeline',
846
+ 'ml-service': 'Machine Learning Service',
847
+ monorepo: 'Monorepo',
848
+ other: 'Other',
849
+ };
850
+ return labels[category] || category;
851
+ }
852
+ /**
853
+ * Format architecture pattern for display
854
+ */
855
+ formatArchitecture(pattern) {
856
+ const labels = {
857
+ layered: 'Layered Architecture',
858
+ hexagonal: 'Hexagonal Architecture (Ports & Adapters)',
859
+ microservices: 'Microservices',
860
+ monolith: 'Monolithic',
861
+ serverless: 'Serverless',
862
+ 'event-driven': 'Event-Driven Architecture',
863
+ mvc: 'Model-View-Controller (MVC)',
864
+ other: 'Custom Architecture',
865
+ };
866
+ return labels[pattern] || pattern;
867
+ }
868
+ /**
869
+ * Capitalize first letter
870
+ */
871
+ capitalize(str) {
872
+ return str.charAt(0).toUpperCase() + str.slice(1);
873
+ }
874
+ /**
875
+ * Wrap text at max line width
876
+ */
877
+ wrapText(text) {
878
+ if (!text)
879
+ return '';
880
+ const str = typeof text === 'string' ? text : JSON.stringify(text);
881
+ const words = str.split(/\s+/);
882
+ const lines = [];
883
+ let currentLine = '';
884
+ for (const word of words) {
885
+ if (currentLine.length + word.length + 1 > this.options.maxLineWidth) {
886
+ lines.push(currentLine);
887
+ currentLine = word;
888
+ }
889
+ else {
890
+ currentLine = currentLine ? `${currentLine} ${word}` : word;
891
+ }
892
+ }
893
+ if (currentLine) {
894
+ lines.push(currentLine);
895
+ }
896
+ return lines.join('\n');
897
+ }
898
+ }
899
+ /**
900
+ * Validate a generated spec against OpenSpec conventions
901
+ */
902
+ export function validateSpec(content) {
903
+ const errors = [];
904
+ const warnings = [];
905
+ // Check for title
906
+ if (!content.match(/^#\s+.+/m)) {
907
+ errors.push('Missing title (# heading)');
908
+ }
909
+ // Check for Purpose section
910
+ if (!content.includes('## Purpose')) {
911
+ warnings.push('Missing Purpose section');
912
+ }
913
+ // Check for Requirements section (except overview)
914
+ if (!content.includes('## Requirements') && !content.includes('## Domains')) {
915
+ warnings.push('Missing Requirements section');
916
+ }
917
+ // Check requirement format (RFC 2119 keywords)
918
+ const requirements = content.match(/###\s+Requirement:\s+.+/g) || [];
919
+ for (const req of requirements) {
920
+ const reqSection = content.substring(content.indexOf(req));
921
+ const nextSection = reqSection.indexOf('\n### ');
922
+ const reqContent = nextSection > 0 ? reqSection.substring(0, nextSection) : reqSection;
923
+ if (!reqContent.match(/\b(SHALL|MUST|SHOULD|MAY)\b/)) {
924
+ warnings.push(`Requirement missing RFC 2119 keyword: ${req}`);
925
+ }
926
+ }
927
+ // Check scenario format
928
+ const scenarios = content.match(/####\s+Scenario:\s+.+/g) || [];
929
+ for (const scenario of scenarios) {
930
+ const scenarioSection = content.substring(content.indexOf(scenario));
931
+ const nextScenario = scenarioSection.indexOf('\n#### ');
932
+ const scenarioContent = nextScenario > 0 ? scenarioSection.substring(0, nextScenario) : scenarioSection;
933
+ if (!scenarioContent.includes('**GIVEN**')) {
934
+ errors.push(`Scenario missing GIVEN: ${scenario}`);
935
+ }
936
+ if (!scenarioContent.includes('**WHEN**')) {
937
+ errors.push(`Scenario missing WHEN: ${scenario}`);
938
+ }
939
+ if (!scenarioContent.includes('**THEN**')) {
940
+ errors.push(`Scenario missing THEN: ${scenario}`);
941
+ }
942
+ }
943
+ // Check for delta markers (should not be in generated specs)
944
+ if (content.match(/\[ADDED\]|\[MODIFIED\]|\[REMOVED\]/)) {
945
+ errors.push('Generated specs should not contain delta markers');
946
+ }
947
+ return {
948
+ valid: errors.length === 0,
949
+ errors,
950
+ warnings,
951
+ };
952
+ }
953
+ // ============================================================================
954
+ // CONVENIENCE FUNCTIONS
955
+ // ============================================================================
956
+ /**
957
+ * Generate OpenSpec files from pipeline result
958
+ */
959
+ export function generateOpenSpecs(result, options) {
960
+ const generator = new OpenSpecFormatGenerator(options);
961
+ return generator.generateSpecs(result);
962
+ }
963
+ //# sourceMappingURL=openspec-format-generator.js.map