spectra-cli 4.1.1 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (422) hide show
  1. package/README.md +1 -1
  2. package/dist/adapters/go-adapter.d.ts.map +1 -1
  3. package/dist/adapters/go-adapter.js +2 -0
  4. package/dist/adapters/go-adapter.js.map +1 -1
  5. package/dist/adapters/index.d.ts +1 -1
  6. package/dist/adapters/index.d.ts.map +1 -1
  7. package/dist/adapters/java-adapter.d.ts.map +1 -1
  8. package/dist/adapters/java-adapter.js +2 -0
  9. package/dist/adapters/java-adapter.js.map +1 -1
  10. package/dist/adapters/language-adapter.d.ts +47 -9
  11. package/dist/adapters/language-adapter.d.ts.map +1 -1
  12. package/dist/adapters/python-adapter.d.ts +34 -6
  13. package/dist/adapters/python-adapter.d.ts.map +1 -1
  14. package/dist/adapters/python-adapter.js +157 -59
  15. package/dist/adapters/python-adapter.js.map +1 -1
  16. package/dist/adapters/ts-js-adapter.d.ts +13 -5
  17. package/dist/adapters/ts-js-adapter.d.ts.map +1 -1
  18. package/dist/adapters/ts-js-adapter.js +55 -14
  19. package/dist/adapters/ts-js-adapter.js.map +1 -1
  20. package/dist/batch/batch-orchestrator.d.ts +30 -4
  21. package/dist/batch/batch-orchestrator.d.ts.map +1 -1
  22. package/dist/batch/batch-orchestrator.js +284 -7
  23. package/dist/batch/batch-orchestrator.js.map +1 -1
  24. package/dist/batch/delta-regenerator.d.ts +2 -2
  25. package/dist/batch/delta-regenerator.d.ts.map +1 -1
  26. package/dist/batch/delta-regenerator.js.map +1 -1
  27. package/dist/batch/module-grouper.d.ts +2 -2
  28. package/dist/batch/module-grouper.d.ts.map +1 -1
  29. package/dist/batch/module-grouper.js +1 -1
  30. package/dist/batch/module-grouper.js.map +1 -1
  31. package/dist/cli/commands/graph.js +1 -1
  32. package/dist/cli/commands/graph.js.map +1 -1
  33. package/dist/cli/commands/index.d.ts +8 -0
  34. package/dist/cli/commands/index.d.ts.map +1 -0
  35. package/dist/cli/commands/index.js +274 -0
  36. package/dist/cli/commands/index.js.map +1 -0
  37. package/dist/cli/commands/query.d.ts.map +1 -1
  38. package/dist/cli/commands/query.js +3 -1
  39. package/dist/cli/commands/query.js.map +1 -1
  40. package/dist/cli/index.js +9 -9
  41. package/dist/cli/index.js.map +1 -1
  42. package/dist/cli/utils/parse-args.d.ts +13 -1
  43. package/dist/cli/utils/parse-args.d.ts.map +1 -1
  44. package/dist/cli/utils/parse-args.js +79 -2
  45. package/dist/cli/utils/parse-args.js.map +1 -1
  46. package/dist/core/ast-analyzer.d.ts.map +1 -1
  47. package/dist/core/ast-analyzer.js +79 -5
  48. package/dist/core/ast-analyzer.js.map +1 -1
  49. package/dist/core/import-resolver.d.ts +90 -0
  50. package/dist/core/import-resolver.d.ts.map +1 -0
  51. package/dist/core/import-resolver.js +273 -0
  52. package/dist/core/import-resolver.js.map +1 -0
  53. package/dist/core/query-mappers/base-mapper.d.ts +13 -0
  54. package/dist/core/query-mappers/base-mapper.d.ts.map +1 -1
  55. package/dist/core/query-mappers/go-mapper.d.ts +68 -0
  56. package/dist/core/query-mappers/go-mapper.d.ts.map +1 -1
  57. package/dist/core/query-mappers/go-mapper.js +421 -0
  58. package/dist/core/query-mappers/go-mapper.js.map +1 -1
  59. package/dist/core/query-mappers/java-mapper.d.ts +196 -0
  60. package/dist/core/query-mappers/java-mapper.d.ts.map +1 -1
  61. package/dist/core/query-mappers/java-mapper.js +600 -0
  62. package/dist/core/query-mappers/java-mapper.js.map +1 -1
  63. package/dist/core/query-mappers/python-mapper.d.ts +55 -0
  64. package/dist/core/query-mappers/python-mapper.d.ts.map +1 -1
  65. package/dist/core/query-mappers/python-mapper.js +273 -0
  66. package/dist/core/query-mappers/python-mapper.js.map +1 -1
  67. package/dist/core/query-mappers/typescript-mapper.d.ts +102 -0
  68. package/dist/core/query-mappers/typescript-mapper.d.ts.map +1 -1
  69. package/dist/core/query-mappers/typescript-mapper.js +470 -0
  70. package/dist/core/query-mappers/typescript-mapper.js.map +1 -1
  71. package/dist/core/single-spec-orchestrator.d.ts.map +1 -1
  72. package/dist/core/single-spec-orchestrator.js +146 -9
  73. package/dist/core/single-spec-orchestrator.js.map +1 -1
  74. package/dist/core/tree-sitter-analyzer.d.ts +6 -0
  75. package/dist/core/tree-sitter-analyzer.d.ts.map +1 -1
  76. package/dist/core/tree-sitter-analyzer.js +33 -1
  77. package/dist/core/tree-sitter-analyzer.js.map +1 -1
  78. package/dist/core/tree-sitter-fallback.d.ts +7 -4
  79. package/dist/core/tree-sitter-fallback.d.ts.map +1 -1
  80. package/dist/core/tree-sitter-fallback.js +157 -12
  81. package/dist/core/tree-sitter-fallback.js.map +1 -1
  82. package/dist/extraction/extraction-types.d.ts +25 -25
  83. package/dist/generator/index-generator.d.ts +3 -3
  84. package/dist/generator/index-generator.d.ts.map +1 -1
  85. package/dist/generator/index-generator.js +1 -1
  86. package/dist/generator/index-generator.js.map +1 -1
  87. package/dist/graph/directory-graph.d.ts +14 -4
  88. package/dist/graph/directory-graph.d.ts.map +1 -1
  89. package/dist/graph/directory-graph.js +71 -128
  90. package/dist/graph/directory-graph.js.map +1 -1
  91. package/dist/graph/mermaid-renderer.d.ts +8 -5
  92. package/dist/graph/mermaid-renderer.d.ts.map +1 -1
  93. package/dist/graph/mermaid-renderer.js +3 -3
  94. package/dist/graph/mermaid-renderer.js.map +1 -1
  95. package/dist/graph/topological-sort.d.ts +13 -6
  96. package/dist/graph/topological-sort.d.ts.map +1 -1
  97. package/dist/graph/topological-sort.js +2 -2
  98. package/dist/graph/topological-sort.js.map +1 -1
  99. package/dist/knowledge-graph/call-resolver.d.ts +64 -0
  100. package/dist/knowledge-graph/call-resolver.d.ts.map +1 -0
  101. package/dist/knowledge-graph/call-resolver.js +323 -0
  102. package/dist/knowledge-graph/call-resolver.js.map +1 -0
  103. package/dist/knowledge-graph/import-resolver.d.ts +114 -0
  104. package/dist/knowledge-graph/import-resolver.d.ts.map +1 -0
  105. package/dist/knowledge-graph/import-resolver.js +537 -0
  106. package/dist/knowledge-graph/import-resolver.js.map +1 -0
  107. package/dist/knowledge-graph/incremental.d.ts +110 -0
  108. package/dist/knowledge-graph/incremental.d.ts.map +1 -0
  109. package/dist/knowledge-graph/incremental.js +410 -0
  110. package/dist/knowledge-graph/incremental.js.map +1 -0
  111. package/dist/knowledge-graph/index.d.ts +74 -0
  112. package/dist/knowledge-graph/index.d.ts.map +1 -0
  113. package/dist/knowledge-graph/index.js +156 -0
  114. package/dist/knowledge-graph/index.js.map +1 -0
  115. package/dist/knowledge-graph/module-derivation.d.ts +238 -0
  116. package/dist/knowledge-graph/module-derivation.d.ts.map +1 -0
  117. package/dist/knowledge-graph/module-derivation.js +418 -0
  118. package/dist/knowledge-graph/module-derivation.js.map +1 -0
  119. package/dist/knowledge-graph/persistence.d.ts +270 -0
  120. package/dist/knowledge-graph/persistence.d.ts.map +1 -0
  121. package/dist/knowledge-graph/persistence.js +226 -0
  122. package/dist/knowledge-graph/persistence.js.map +1 -0
  123. package/dist/knowledge-graph/query-helpers.d.ts +164 -0
  124. package/dist/knowledge-graph/query-helpers.d.ts.map +1 -0
  125. package/dist/knowledge-graph/query-helpers.js +394 -0
  126. package/dist/knowledge-graph/query-helpers.js.map +1 -0
  127. package/dist/knowledge-graph/unified-graph.d.ts +310 -0
  128. package/dist/knowledge-graph/unified-graph.d.ts.map +1 -0
  129. package/dist/knowledge-graph/unified-graph.js +182 -0
  130. package/dist/knowledge-graph/unified-graph.js.map +1 -0
  131. package/dist/mcp/agent-context-tools.d.ts +104 -0
  132. package/dist/mcp/agent-context-tools.d.ts.map +1 -0
  133. package/dist/mcp/agent-context-tools.js +854 -0
  134. package/dist/mcp/agent-context-tools.js.map +1 -0
  135. package/dist/mcp/graph-tools.d.ts +20 -0
  136. package/dist/mcp/graph-tools.d.ts.map +1 -1
  137. package/dist/mcp/graph-tools.js +71 -11
  138. package/dist/mcp/graph-tools.js.map +1 -1
  139. package/dist/mcp/lib/response-helpers.d.ts +67 -0
  140. package/dist/mcp/lib/response-helpers.d.ts.map +1 -0
  141. package/dist/mcp/lib/response-helpers.js +103 -0
  142. package/dist/mcp/lib/response-helpers.js.map +1 -0
  143. package/dist/mcp/server.d.ts +3 -1
  144. package/dist/mcp/server.d.ts.map +1 -1
  145. package/dist/mcp/server.js +9 -10
  146. package/dist/mcp/server.js.map +1 -1
  147. package/dist/models/call-site.d.ts +68 -0
  148. package/dist/models/call-site.d.ts.map +1 -0
  149. package/dist/models/call-site.js +60 -0
  150. package/dist/models/call-site.js.map +1 -0
  151. package/dist/models/code-skeleton.d.ts +78 -6
  152. package/dist/models/code-skeleton.d.ts.map +1 -1
  153. package/dist/models/code-skeleton.js +29 -0
  154. package/dist/models/code-skeleton.js.map +1 -1
  155. package/dist/models/drift-item.d.ts +4 -4
  156. package/dist/models/module-spec.d.ts +155 -94
  157. package/dist/models/module-spec.d.ts.map +1 -1
  158. package/dist/panoramic/adr-decision-pipeline.d.ts +53 -0
  159. package/dist/panoramic/adr-decision-pipeline.d.ts.map +1 -0
  160. package/dist/panoramic/adr-decision-pipeline.js +685 -0
  161. package/dist/panoramic/adr-decision-pipeline.js.map +1 -0
  162. package/dist/panoramic/api-surface-generator.d.ts +56 -0
  163. package/dist/panoramic/api-surface-generator.d.ts.map +1 -0
  164. package/dist/panoramic/api-surface-generator.js +1671 -0
  165. package/dist/panoramic/api-surface-generator.js.map +1 -0
  166. package/dist/panoramic/architecture-ir-builder.d.ts +19 -0
  167. package/dist/panoramic/architecture-ir-builder.d.ts.map +1 -0
  168. package/dist/panoramic/architecture-ir-builder.js +561 -0
  169. package/dist/panoramic/architecture-ir-builder.js.map +1 -0
  170. package/dist/panoramic/architecture-ir-exporters.d.ts +7 -0
  171. package/dist/panoramic/architecture-ir-exporters.d.ts.map +1 -0
  172. package/dist/panoramic/architecture-ir-exporters.js +183 -0
  173. package/dist/panoramic/architecture-ir-exporters.js.map +1 -0
  174. package/dist/panoramic/architecture-ir-generator.d.ts +36 -0
  175. package/dist/panoramic/architecture-ir-generator.d.ts.map +1 -0
  176. package/dist/panoramic/architecture-ir-generator.js +51 -0
  177. package/dist/panoramic/architecture-ir-generator.js.map +1 -0
  178. package/dist/panoramic/architecture-ir-mermaid-adapter.d.ts +6 -0
  179. package/dist/panoramic/architecture-ir-mermaid-adapter.d.ts.map +1 -0
  180. package/dist/panoramic/architecture-ir-mermaid-adapter.js +98 -0
  181. package/dist/panoramic/architecture-ir-mermaid-adapter.js.map +1 -0
  182. package/dist/panoramic/architecture-ir-model.d.ts +87 -0
  183. package/dist/panoramic/architecture-ir-model.d.ts.map +1 -0
  184. package/dist/panoramic/architecture-ir-model.js +20 -0
  185. package/dist/panoramic/architecture-ir-model.js.map +1 -0
  186. package/dist/panoramic/architecture-narrative.d.ts +68 -0
  187. package/dist/panoramic/architecture-narrative.d.ts.map +1 -0
  188. package/dist/panoramic/architecture-narrative.js +401 -0
  189. package/dist/panoramic/architecture-narrative.js.map +1 -0
  190. package/dist/panoramic/architecture-overview-generator.d.ts +31 -0
  191. package/dist/panoramic/architecture-overview-generator.d.ts.map +1 -0
  192. package/dist/panoramic/architecture-overview-generator.js +454 -0
  193. package/dist/panoramic/architecture-overview-generator.js.map +1 -0
  194. package/dist/panoramic/architecture-overview-model.d.ts +77 -0
  195. package/dist/panoramic/architecture-overview-model.d.ts.map +1 -0
  196. package/dist/panoramic/architecture-overview-model.js +31 -0
  197. package/dist/panoramic/architecture-overview-model.js.map +1 -0
  198. package/dist/panoramic/batch-project-docs.d.ts.map +1 -1
  199. package/dist/panoramic/batch-project-docs.js +4 -2
  200. package/dist/panoramic/batch-project-docs.js.map +1 -1
  201. package/dist/panoramic/builders/component-view-builder.d.ts +25 -1
  202. package/dist/panoramic/builders/component-view-builder.d.ts.map +1 -1
  203. package/dist/panoramic/builders/component-view-builder.js +83 -3
  204. package/dist/panoramic/builders/component-view-builder.js.map +1 -1
  205. package/dist/panoramic/builders/doc-graph-builder.d.ts +2 -2
  206. package/dist/panoramic/builders/doc-graph-builder.d.ts.map +1 -1
  207. package/dist/panoramic/builders/doc-graph-builder.js.map +1 -1
  208. package/dist/panoramic/component-view-builder.d.ts +17 -0
  209. package/dist/panoramic/component-view-builder.d.ts.map +1 -0
  210. package/dist/panoramic/component-view-builder.js +652 -0
  211. package/dist/panoramic/component-view-builder.js.map +1 -0
  212. package/dist/panoramic/component-view-model.d.ts +127 -0
  213. package/dist/panoramic/component-view-model.d.ts.map +1 -0
  214. package/dist/panoramic/component-view-model.js +65 -0
  215. package/dist/panoramic/component-view-model.js.map +1 -0
  216. package/dist/panoramic/config-reference-generator.d.ts +78 -0
  217. package/dist/panoramic/config-reference-generator.d.ts.map +1 -0
  218. package/dist/panoramic/config-reference-generator.js +199 -0
  219. package/dist/panoramic/config-reference-generator.js.map +1 -0
  220. package/dist/panoramic/coverage-auditor.d.ts +95 -0
  221. package/dist/panoramic/coverage-auditor.d.ts.map +1 -0
  222. package/dist/panoramic/coverage-auditor.js +290 -0
  223. package/dist/panoramic/coverage-auditor.js.map +1 -0
  224. package/dist/panoramic/cross-package-analyzer.d.ts +112 -0
  225. package/dist/panoramic/cross-package-analyzer.d.ts.map +1 -0
  226. package/dist/panoramic/cross-package-analyzer.js +258 -0
  227. package/dist/panoramic/cross-package-analyzer.js.map +1 -0
  228. package/dist/panoramic/data-model-generator.d.ts +528 -0
  229. package/dist/panoramic/data-model-generator.d.ts.map +1 -0
  230. package/dist/panoramic/data-model-generator.js +647 -0
  231. package/dist/panoramic/data-model-generator.js.map +1 -0
  232. package/dist/panoramic/doc-graph-builder.d.ts +80 -0
  233. package/dist/panoramic/doc-graph-builder.d.ts.map +1 -0
  234. package/dist/panoramic/doc-graph-builder.js +352 -0
  235. package/dist/panoramic/doc-graph-builder.js.map +1 -0
  236. package/dist/panoramic/docs-bundle-manifest-reader.d.ts +26 -0
  237. package/dist/panoramic/docs-bundle-manifest-reader.d.ts.map +1 -0
  238. package/dist/panoramic/docs-bundle-manifest-reader.js +106 -0
  239. package/dist/panoramic/docs-bundle-manifest-reader.js.map +1 -0
  240. package/dist/panoramic/docs-bundle-orchestrator.d.ts +14 -0
  241. package/dist/panoramic/docs-bundle-orchestrator.d.ts.map +1 -0
  242. package/dist/panoramic/docs-bundle-orchestrator.js +538 -0
  243. package/dist/panoramic/docs-bundle-orchestrator.js.map +1 -0
  244. package/dist/panoramic/docs-bundle-profiles.d.ts +4 -0
  245. package/dist/panoramic/docs-bundle-profiles.d.ts.map +1 -0
  246. package/dist/panoramic/docs-bundle-profiles.js +82 -0
  247. package/dist/panoramic/docs-bundle-profiles.js.map +1 -0
  248. package/dist/panoramic/docs-bundle-types.d.ts +94 -0
  249. package/dist/panoramic/docs-bundle-types.d.ts.map +1 -0
  250. package/dist/panoramic/docs-bundle-types.js +10 -0
  251. package/dist/panoramic/docs-bundle-types.js.map +1 -0
  252. package/dist/panoramic/docs-quality-evaluator.d.ts +31 -0
  253. package/dist/panoramic/docs-quality-evaluator.d.ts.map +1 -0
  254. package/dist/panoramic/docs-quality-evaluator.js +941 -0
  255. package/dist/panoramic/docs-quality-evaluator.js.map +1 -0
  256. package/dist/panoramic/docs-quality-model.d.ts +125 -0
  257. package/dist/panoramic/docs-quality-model.d.ts.map +1 -0
  258. package/dist/panoramic/docs-quality-model.js +166 -0
  259. package/dist/panoramic/docs-quality-model.js.map +1 -0
  260. package/dist/panoramic/dynamic-scenarios-builder.d.ts +18 -0
  261. package/dist/panoramic/dynamic-scenarios-builder.d.ts.map +1 -0
  262. package/dist/panoramic/dynamic-scenarios-builder.js +316 -0
  263. package/dist/panoramic/dynamic-scenarios-builder.js.map +1 -0
  264. package/dist/panoramic/event-surface-generator.d.ts +52 -0
  265. package/dist/panoramic/event-surface-generator.d.ts.map +1 -0
  266. package/dist/panoramic/event-surface-generator.js +507 -0
  267. package/dist/panoramic/event-surface-generator.js.map +1 -0
  268. package/dist/panoramic/generator-registry.d.ts +1 -1
  269. package/dist/panoramic/generator-registry.d.ts.map +1 -1
  270. package/dist/panoramic/generator-registry.js +5 -2
  271. package/dist/panoramic/generator-registry.js.map +1 -1
  272. package/dist/panoramic/generators/cross-package-analyzer.d.ts +5 -5
  273. package/dist/panoramic/generators/cross-package-analyzer.d.ts.map +1 -1
  274. package/dist/panoramic/generators/cross-package-analyzer.js +1 -1
  275. package/dist/panoramic/generators/cross-package-analyzer.js.map +1 -1
  276. package/dist/panoramic/generators/data-model-generator.d.ts +27 -27
  277. package/dist/panoramic/graph/confidence-mapper.d.ts +18 -0
  278. package/dist/panoramic/graph/confidence-mapper.d.ts.map +1 -1
  279. package/dist/panoramic/graph/confidence-mapper.js +26 -0
  280. package/dist/panoramic/graph/confidence-mapper.js.map +1 -1
  281. package/dist/panoramic/graph/graph-builder.d.ts.map +1 -1
  282. package/dist/panoramic/graph/graph-builder.js +78 -0
  283. package/dist/panoramic/graph/graph-builder.js.map +1 -1
  284. package/dist/panoramic/graph/graph-paths.d.ts +8 -0
  285. package/dist/panoramic/graph/graph-paths.d.ts.map +1 -1
  286. package/dist/panoramic/graph/graph-paths.js +10 -0
  287. package/dist/panoramic/graph/graph-paths.js.map +1 -1
  288. package/dist/panoramic/graph/graph-query.d.ts +33 -2
  289. package/dist/panoramic/graph/graph-query.d.ts.map +1 -1
  290. package/dist/panoramic/graph/graph-query.js +69 -19
  291. package/dist/panoramic/graph/graph-query.js.map +1 -1
  292. package/dist/panoramic/graph/graph-types.d.ts +32 -3
  293. package/dist/panoramic/graph/graph-types.d.ts.map +1 -1
  294. package/dist/panoramic/hyperedges/schema.d.ts +6 -6
  295. package/dist/panoramic/interface-surface-generator.d.ts +50 -0
  296. package/dist/panoramic/interface-surface-generator.d.ts.map +1 -0
  297. package/dist/panoramic/interface-surface-generator.js +388 -0
  298. package/dist/panoramic/interface-surface-generator.js.map +1 -0
  299. package/dist/panoramic/interfaces.d.ts +2 -2
  300. package/dist/panoramic/mock-readme-generator.d.ts +90 -0
  301. package/dist/panoramic/mock-readme-generator.d.ts.map +1 -0
  302. package/dist/panoramic/mock-readme-generator.js +111 -0
  303. package/dist/panoramic/mock-readme-generator.js.map +1 -0
  304. package/dist/panoramic/models/component-view-model.d.ts +1 -1
  305. package/dist/panoramic/models/component-view-model.d.ts.map +1 -1
  306. package/dist/panoramic/models/component-view-model.js.map +1 -1
  307. package/dist/panoramic/narrative-provenance-adapter.d.ts +8 -0
  308. package/dist/panoramic/narrative-provenance-adapter.d.ts.map +1 -0
  309. package/dist/panoramic/narrative-provenance-adapter.js +99 -0
  310. package/dist/panoramic/narrative-provenance-adapter.js.map +1 -0
  311. package/dist/panoramic/parser-registry.d.ts +1 -1
  312. package/dist/panoramic/parser-registry.js +1 -1
  313. package/dist/panoramic/parsers/types.d.ts +6 -6
  314. package/dist/panoramic/pattern-hints-generator.d.ts +28 -0
  315. package/dist/panoramic/pattern-hints-generator.d.ts.map +1 -0
  316. package/dist/panoramic/pattern-hints-generator.js +218 -0
  317. package/dist/panoramic/pattern-hints-generator.js.map +1 -0
  318. package/dist/panoramic/pattern-hints-model.d.ts +89 -0
  319. package/dist/panoramic/pattern-hints-model.d.ts.map +1 -0
  320. package/dist/panoramic/pattern-hints-model.js +61 -0
  321. package/dist/panoramic/pattern-hints-model.js.map +1 -0
  322. package/dist/panoramic/pattern-knowledge-base.d.ts +31 -0
  323. package/dist/panoramic/pattern-knowledge-base.d.ts.map +1 -0
  324. package/dist/panoramic/pattern-knowledge-base.js +407 -0
  325. package/dist/panoramic/pattern-knowledge-base.js.map +1 -0
  326. package/dist/panoramic/pipelines/coverage-auditor.d.ts.map +1 -1
  327. package/dist/panoramic/pipelines/coverage-auditor.js +4 -2
  328. package/dist/panoramic/pipelines/coverage-auditor.js.map +1 -1
  329. package/dist/panoramic/pipelines/docs-bundle-orchestrator.js +13 -6
  330. package/dist/panoramic/pipelines/docs-bundle-orchestrator.js.map +1 -1
  331. package/dist/panoramic/pipelines/product-ux-docs.d.ts +5 -0
  332. package/dist/panoramic/pipelines/product-ux-docs.d.ts.map +1 -1
  333. package/dist/panoramic/pipelines/product-ux-docs.js +34 -6
  334. package/dist/panoramic/pipelines/product-ux-docs.js.map +1 -1
  335. package/dist/panoramic/product-ux-docs.d.ts +104 -0
  336. package/dist/panoramic/product-ux-docs.d.ts.map +1 -0
  337. package/dist/panoramic/product-ux-docs.js +817 -0
  338. package/dist/panoramic/product-ux-docs.js.map +1 -0
  339. package/dist/panoramic/qa/__tests__/citation.test.d.ts +2 -0
  340. package/dist/panoramic/qa/__tests__/citation.test.d.ts.map +1 -0
  341. package/dist/panoramic/qa/__tests__/citation.test.js +193 -0
  342. package/dist/panoramic/qa/__tests__/citation.test.js.map +1 -0
  343. package/dist/panoramic/qa/__tests__/debt-context.test.d.ts +2 -0
  344. package/dist/panoramic/qa/__tests__/debt-context.test.d.ts.map +1 -0
  345. package/dist/panoramic/qa/__tests__/debt-context.test.js +154 -0
  346. package/dist/panoramic/qa/__tests__/debt-context.test.js.map +1 -0
  347. package/dist/panoramic/qa/__tests__/graph-retriever.test.d.ts +2 -0
  348. package/dist/panoramic/qa/__tests__/graph-retriever.test.d.ts.map +1 -0
  349. package/dist/panoramic/qa/__tests__/graph-retriever.test.js +148 -0
  350. package/dist/panoramic/qa/__tests__/graph-retriever.test.js.map +1 -0
  351. package/dist/panoramic/qa/__tests__/index.test.d.ts +2 -0
  352. package/dist/panoramic/qa/__tests__/index.test.d.ts.map +1 -0
  353. package/dist/panoramic/qa/__tests__/index.test.js +246 -0
  354. package/dist/panoramic/qa/__tests__/index.test.js.map +1 -0
  355. package/dist/panoramic/qa/__tests__/llm-caller.test.d.ts +2 -0
  356. package/dist/panoramic/qa/__tests__/llm-caller.test.d.ts.map +1 -0
  357. package/dist/panoramic/qa/__tests__/llm-caller.test.js +168 -0
  358. package/dist/panoramic/qa/__tests__/llm-caller.test.js.map +1 -0
  359. package/dist/panoramic/qa/__tests__/prompt-builder.test.d.ts +2 -0
  360. package/dist/panoramic/qa/__tests__/prompt-builder.test.d.ts.map +1 -0
  361. package/dist/panoramic/qa/__tests__/prompt-builder.test.js +150 -0
  362. package/dist/panoramic/qa/__tests__/prompt-builder.test.js.map +1 -0
  363. package/dist/panoramic/qa/__tests__/qa-integration.test.d.ts +2 -0
  364. package/dist/panoramic/qa/__tests__/qa-integration.test.d.ts.map +1 -0
  365. package/dist/panoramic/qa/__tests__/qa-integration.test.js +296 -0
  366. package/dist/panoramic/qa/__tests__/qa-integration.test.js.map +1 -0
  367. package/dist/panoramic/qa/__tests__/rag-reranker.test.d.ts +2 -0
  368. package/dist/panoramic/qa/__tests__/rag-reranker.test.d.ts.map +1 -0
  369. package/dist/panoramic/qa/__tests__/rag-reranker.test.js +136 -0
  370. package/dist/panoramic/qa/__tests__/rag-reranker.test.js.map +1 -0
  371. package/dist/panoramic/qa/index.d.ts.map +1 -1
  372. package/dist/panoramic/qa/index.js +10 -3
  373. package/dist/panoramic/qa/index.js.map +1 -1
  374. package/dist/panoramic/runtime-topology-generator.d.ts +77 -0
  375. package/dist/panoramic/runtime-topology-generator.d.ts.map +1 -0
  376. package/dist/panoramic/runtime-topology-generator.js +676 -0
  377. package/dist/panoramic/runtime-topology-generator.js.map +1 -0
  378. package/dist/panoramic/runtime-topology-model.d.ts +145 -0
  379. package/dist/panoramic/runtime-topology-model.d.ts.map +1 -0
  380. package/dist/panoramic/runtime-topology-model.js +300 -0
  381. package/dist/panoramic/runtime-topology-model.js.map +1 -0
  382. package/dist/panoramic/troubleshooting-generator.d.ts +51 -0
  383. package/dist/panoramic/troubleshooting-generator.d.ts.map +1 -0
  384. package/dist/panoramic/troubleshooting-generator.js +451 -0
  385. package/dist/panoramic/troubleshooting-generator.js.map +1 -0
  386. package/dist/panoramic/utils/text-segmenter.d.ts +15 -0
  387. package/dist/panoramic/utils/text-segmenter.d.ts.map +1 -1
  388. package/dist/panoramic/utils/text-segmenter.js +38 -0
  389. package/dist/panoramic/utils/text-segmenter.js.map +1 -1
  390. package/dist/panoramic/workspace-index-generator.d.ts +148 -0
  391. package/dist/panoramic/workspace-index-generator.d.ts.map +1 -0
  392. package/dist/panoramic/workspace-index-generator.js +497 -0
  393. package/dist/panoramic/workspace-index-generator.js.map +1 -0
  394. package/dist/runtime-bootstrap.d.ts +9 -0
  395. package/dist/runtime-bootstrap.d.ts.map +1 -0
  396. package/dist/runtime-bootstrap.js +33 -0
  397. package/dist/runtime-bootstrap.js.map +1 -0
  398. package/dist/utils/file-scanner.js +1 -1
  399. package/dist/utils/file-scanner.js.map +1 -1
  400. package/package.json +12 -2
  401. package/plugins/spec-driver/.claude-plugin/plugin.json +1 -1
  402. package/plugins/spec-driver/README.md +18 -1
  403. package/plugins/spec-driver/agents/implement.md +20 -1
  404. package/plugins/spec-driver/agents/plan.md +20 -1
  405. package/plugins/spec-driver/agents/quality-review.md +20 -1
  406. package/plugins/spec-driver/agents/spec-review.md +20 -1
  407. package/plugins/spec-driver/agents/verify.md +20 -1
  408. package/plugins/spec-driver/docs/customization.md +134 -0
  409. package/plugins/spec-driver/docs/spectra-mcp-integration.md +165 -0
  410. package/plugins/spec-driver/lib/preference-rules.mjs +96 -0
  411. package/plugins/spec-driver/scripts/postinstall.sh +1 -1
  412. package/plugins/spec-driver/scripts/sync-preference-rules.mjs +148 -0
  413. package/plugins/spec-driver/skills/spec-driver-feature/SKILL.md +10 -0
  414. package/plugins/spec-driver/skills/spec-driver-fix/SKILL.md +10 -0
  415. package/plugins/spec-driver/skills/spec-driver-implement/SKILL.md +10 -0
  416. package/plugins/spec-driver/skills/spec-driver-refactor/SKILL.md +10 -0
  417. package/plugins/spec-driver/skills/spec-driver-story/SKILL.md +10 -0
  418. package/plugins/spec-driver/templates/preference-rules.md +39 -0
  419. package/plugins/spectra/.claude-plugin/plugin.json +1 -1
  420. package/plugins/spectra/README.md +48 -1
  421. package/plugins/spectra/hooks/post-commit.sh +40 -0
  422. package/templates/product-overview.hbs +1 -1
@@ -0,0 +1,941 @@
1
+ /**
2
+ * Docs quality evaluator
3
+ *
4
+ * 在现有 panoramic / ADR 结构化输出之上,生成 provenance、conflict、required-doc
5
+ * 与总体质量结论。059 不新增事实抽取器,也不把 Markdown 当作 canonical facts。
6
+ */
7
+ import * as fs from 'node:fs';
8
+ import * as path from 'node:path';
9
+ import { loadTemplate } from './utils/template-loader.js';
10
+ import { adaptArchitectureNarrativeProvenance } from './narrative-provenance-adapter.js';
11
+ import { determineDocsQualityStatus, normalizeConfidence, summarizeDocsQualityStats, summarizeProvenanceRecord, summarizeProvenanceSection, } from './docs-quality-model.js';
12
+ const DOC_METADATA = {
13
+ 'product-overview': {
14
+ title: 'Product Overview',
15
+ relativePath: 'product-overview.md',
16
+ },
17
+ 'user-journeys': {
18
+ title: 'User Journeys',
19
+ relativePath: 'user-journeys.md',
20
+ },
21
+ 'feature-briefs/index': {
22
+ title: 'Feature Briefs',
23
+ relativePath: 'feature-briefs/index.md',
24
+ },
25
+ 'architecture-narrative': {
26
+ title: 'Architecture Narrative',
27
+ relativePath: 'architecture-narrative.md',
28
+ },
29
+ 'architecture-overview': {
30
+ title: 'Architecture Overview',
31
+ relativePath: 'architecture-overview.md',
32
+ },
33
+ 'runtime-topology': {
34
+ title: 'Runtime Topology',
35
+ relativePath: 'runtime-topology.md',
36
+ },
37
+ 'component-view': {
38
+ title: 'Component View',
39
+ relativePath: 'component-view.md',
40
+ },
41
+ 'dynamic-scenarios': {
42
+ title: 'Dynamic Scenarios',
43
+ relativePath: 'dynamic-scenarios.md',
44
+ },
45
+ 'pattern-hints': {
46
+ title: 'Pattern Hints',
47
+ relativePath: 'pattern-hints.md',
48
+ },
49
+ 'api-surface': {
50
+ title: 'API Surface',
51
+ relativePath: 'api-surface.md',
52
+ },
53
+ 'interface-surface': {
54
+ title: 'Interface Surface',
55
+ relativePath: 'interface-surface.md',
56
+ },
57
+ 'data-model': {
58
+ title: 'Data Model',
59
+ relativePath: 'data-model.md',
60
+ },
61
+ 'workspace-index': {
62
+ title: 'Workspace Index',
63
+ relativePath: 'workspace-index.md',
64
+ },
65
+ 'cross-package-analysis': {
66
+ title: 'Cross-Package Analysis',
67
+ relativePath: 'cross-package-analysis.md',
68
+ },
69
+ 'docs/adr/index': {
70
+ title: 'ADR Index',
71
+ relativePath: 'docs/adr/index.md',
72
+ },
73
+ 'quality-report': {
74
+ title: 'Docs Quality Report',
75
+ relativePath: 'quality-report.md',
76
+ },
77
+ };
78
+ const REQUIRED_DOC_RULES = [
79
+ {
80
+ docId: 'product-overview',
81
+ title: DOC_METADATA['product-overview'].title,
82
+ requiredBy: ['product-managed'],
83
+ reason: '产品事实已被纳入编排时,必须有产品概览作为统一入口。',
84
+ },
85
+ {
86
+ docId: 'user-journeys',
87
+ title: DOC_METADATA['user-journeys'].title,
88
+ requiredBy: ['product-managed'],
89
+ reason: '产品 / UX 文档至少需要一份用户旅程,说明用户目标与关键任务流。',
90
+ },
91
+ {
92
+ docId: 'feature-briefs/index',
93
+ title: DOC_METADATA['feature-briefs/index'].title,
94
+ requiredBy: ['product-managed'],
95
+ reason: '产品事实接入后应沉淀 feature brief 索引,连接 issue/PR 与产品叙事。',
96
+ },
97
+ {
98
+ docId: 'architecture-narrative',
99
+ title: DOC_METADATA['architecture-narrative'].title,
100
+ requiredBy: ['general'],
101
+ reason: '叙事文档是 explanation 层的默认入口。',
102
+ },
103
+ {
104
+ docId: 'architecture-overview',
105
+ title: DOC_METADATA['architecture-overview'].title,
106
+ requiredBy: ['runtime-project', 'architecture-heavy'],
107
+ reason: '架构概览提供 system context / deployment / layered 的统一总览。',
108
+ },
109
+ {
110
+ docId: 'pattern-hints',
111
+ title: DOC_METADATA['pattern-hints'].title,
112
+ requiredBy: ['architecture-heavy'],
113
+ reason: '模式提示用于解释系统采用当前架构形态的证据与替代方案。',
114
+ },
115
+ {
116
+ docId: 'docs/adr/index',
117
+ title: DOC_METADATA['docs/adr/index'].title,
118
+ requiredBy: ['architecture-heavy'],
119
+ reason: 'ADR 索引是架构决策审计入口。',
120
+ },
121
+ {
122
+ docId: 'runtime-topology',
123
+ title: DOC_METADATA['runtime-topology'].title,
124
+ requiredBy: ['runtime-project'],
125
+ reason: '运行时项目必须显式记录服务、容器和部署边界。',
126
+ },
127
+ {
128
+ docId: 'component-view',
129
+ title: DOC_METADATA['component-view'].title,
130
+ requiredBy: ['runtime-project'],
131
+ reason: '组件视图是运行时链路与部署角色之间的关键中间层。',
132
+ },
133
+ {
134
+ docId: 'dynamic-scenarios',
135
+ title: DOC_METADATA['dynamic-scenarios'].title,
136
+ requiredBy: ['runtime-project'],
137
+ reason: '动态链路文档用于说明主链路、参与者和 hand-off。',
138
+ },
139
+ {
140
+ docId: 'interface-surface',
141
+ title: DOC_METADATA['interface-surface'].title,
142
+ requiredBy: ['library-sdk'],
143
+ reason: 'SDK / library 项目需要一份聚焦公开入口、关键类型与关键方法的接口摘要。',
144
+ },
145
+ {
146
+ docId: 'api-surface',
147
+ title: DOC_METADATA['api-surface'].title,
148
+ requiredBy: ['http-api'],
149
+ reason: 'HTTP API 项目需要稳定的 REST / RPC / endpoint 接口入口摘要。',
150
+ },
151
+ {
152
+ docId: 'data-model',
153
+ title: DOC_METADATA['data-model'].title,
154
+ requiredBy: ['library-sdk'],
155
+ reason: 'SDK / library 项目需要对外和内部关键结构的数据模型摘要。',
156
+ },
157
+ {
158
+ docId: 'workspace-index',
159
+ title: DOC_METADATA['workspace-index'].title,
160
+ requiredBy: ['monorepo'],
161
+ reason: 'Monorepo 需要 workspace / package 结构索引。',
162
+ },
163
+ {
164
+ docId: 'cross-package-analysis',
165
+ title: DOC_METADATA['cross-package-analysis'].title,
166
+ requiredBy: ['monorepo'],
167
+ reason: 'Monorepo 需要跨包依赖分析和关系摘要。',
168
+ },
169
+ ];
170
+ const TOPIC_PATTERNS = {
171
+ 'product-positioning': [
172
+ { value: 'sdk', patterns: [/\bsdk\b/i, /\blibrary\b/i] },
173
+ { value: 'cli', patterns: [/\bcli\b/i, /\bcommand[- ]line\b/i] },
174
+ { value: 'plugin', patterns: [/\bplugin\b/i, /\bextension\b/i] },
175
+ { value: 'service', patterns: [/\bservice\b/i] },
176
+ { value: 'platform', patterns: [/\bplatform\b/i, /\bframework\b/i] },
177
+ ],
178
+ 'runtime-hosting': [
179
+ { value: 'containerized', patterns: [/\bdocker\b/i, /\bcompose\b/i, /\bcontainer/i] },
180
+ { value: 'serverless', patterns: [/\bserverless\b/i, /\blambda\b/i] },
181
+ { value: 'browser', patterns: [/\bbrowser\b/i] },
182
+ { value: 'desktop', patterns: [/\bdesktop\b/i] },
183
+ { value: 'local-process', patterns: [/\blocal process\b/i, /\bhost process\b/i, /\blocal runtime\b/i] },
184
+ ],
185
+ 'protocol-boundary': [
186
+ { value: 'http-rest', patterns: [/\bhttp\b/i, /\brest\b/i] },
187
+ { value: 'grpc', patterns: [/\bgrpc\b/i] },
188
+ { value: 'json-rpc', patterns: [/\bjson-rpc\b/i] },
189
+ { value: 'websocket', patterns: [/\bwebsocket\b/i] },
190
+ { value: 'stdio', patterns: [/\bstdio\b/i, /\bstdin\b/i, /\bstdout\b/i] },
191
+ { value: 'event-bus', patterns: [/\bevent/i, /\bpub(?:lish)?\b/i, /\bsub(?:scribe)?\b/i] },
192
+ ],
193
+ 'extensibility-boundary': [
194
+ { value: 'registry', patterns: [/\bregistry\b/i] },
195
+ { value: 'plugin', patterns: [/\bplugin\b/i, /\bextension\b/i] },
196
+ { value: 'hook', patterns: [/\bhook\b/i] },
197
+ { value: 'adapter', patterns: [/\badapter\b/i] },
198
+ { value: 'middleware', patterns: [/\bmiddleware\b/i] },
199
+ ],
200
+ 'degradation-strategy': [
201
+ { value: 'partial', patterns: [/\bpartial\b/i] },
202
+ { value: 'warning', patterns: [/\bwarn(?:ing)?\b/i] },
203
+ { value: 'fallback', patterns: [/\bfallback\b/i, /\bbest effort\b/i] },
204
+ { value: 'graceful', patterns: [/\bgraceful\b/i, /\bdegrad/i] },
205
+ { value: 'strict', patterns: [/\bfail fast\b/i, /\bstrict\b/i, /\bblocking\b/i] },
206
+ ],
207
+ };
208
+ export function evaluateDocsQuality(options) {
209
+ const dependencyWarnings = [...(options.dependencyWarnings ?? [])];
210
+ const presentDocs = collectPresentDocs(options.generatedDocs, options.projectRoot, options.outputDir);
211
+ const warnings = collectGeneratedDocWarnings(options.generatedDocs);
212
+ if (!hasReadme(options.projectRoot)) {
213
+ warnings.push('未找到 README.md,部分产品定位和协议边界冲突无法完整校验。');
214
+ }
215
+ if (!hasCurrentSpec(options.projectRoot)) {
216
+ warnings.push('未找到 current-spec.md,产品级事实冲突校验将按可见 sources 保守降级。');
217
+ }
218
+ const provenance = buildProvenanceRecords(options, presentDocs);
219
+ const evidenceDocs = collectEvidenceDocuments(options);
220
+ const conflicts = detectConflicts(evidenceDocs);
221
+ const requiredDocs = evaluateRequiredDocs(options, presentDocs, dependencyWarnings);
222
+ const bundleCoverage = determineBundleCoverage(requiredDocs, options.docsBundleManifest);
223
+ const status = determineDocsQualityStatus({
224
+ bundleCoverage,
225
+ conflicts,
226
+ requiredDocs,
227
+ warnings,
228
+ dependencyWarnings,
229
+ });
230
+ const stats = summarizeDocsQualityStats({
231
+ provenance,
232
+ conflicts,
233
+ requiredDocs,
234
+ dependencyWarnings,
235
+ warnings,
236
+ });
237
+ return {
238
+ title: `文档质量报告: ${options.architectureNarrative.projectName}`,
239
+ generatedAt: new Date().toISOString().split('T')[0],
240
+ projectName: options.architectureNarrative.projectName,
241
+ status,
242
+ bundleCoverage,
243
+ summary: buildSummaryLines({
244
+ provenance,
245
+ conflicts,
246
+ requiredDocs,
247
+ bundleCoverage,
248
+ dependencyWarnings,
249
+ warnings,
250
+ }),
251
+ provenance,
252
+ conflicts,
253
+ requiredDocs,
254
+ dependencyWarnings: uniqueSorted(dependencyWarnings),
255
+ warnings: uniqueSorted(warnings),
256
+ stats,
257
+ };
258
+ }
259
+ export function renderDocsQualityReport(report) {
260
+ const template = loadTemplate('quality-report.hbs', import.meta.url);
261
+ return template(report);
262
+ }
263
+ function buildProvenanceRecords(options, presentDocs) {
264
+ return [
265
+ adaptArchitectureNarrativeProvenance(options.architectureNarrative, {
266
+ outputDir: options.outputDir,
267
+ projectRoot: options.projectRoot,
268
+ }),
269
+ options.componentView
270
+ ? buildComponentViewProvenance(options.componentView, presentDocs.get('component-view')?.path)
271
+ : createMissingRecord('component-view', 'Component View', '当前批次未生成 component-view。'),
272
+ options.dynamicScenarios
273
+ ? buildDynamicScenariosProvenance(options.dynamicScenarios, presentDocs.get('dynamic-scenarios')?.path)
274
+ : createMissingRecord('dynamic-scenarios', 'Dynamic Scenarios', '当前批次未生成 dynamic-scenarios。'),
275
+ options.adrIndex
276
+ ? buildAdrProvenance(options.adrIndex, presentDocs.get('docs/adr/index')?.path)
277
+ : createMissingRecord('docs/adr/index', 'ADR Index', '当前批次未生成 ADR 索引。'),
278
+ options.productOverview
279
+ ? buildProductOverviewProvenance(options.productOverview, presentDocs.get('product-overview')?.path)
280
+ : (hasCurrentSpec(options.projectRoot)
281
+ ? createMissingRecord('product-overview', 'Product Overview', '检测到 current-spec,但当前批次未生成 product-overview。')
282
+ : null),
283
+ options.userJourneys
284
+ ? buildUserJourneysProvenance(options.userJourneys, presentDocs.get('user-journeys')?.path)
285
+ : (hasCurrentSpec(options.projectRoot)
286
+ ? createMissingRecord('user-journeys', 'User Journeys', '检测到 current-spec,但当前批次未生成 user-journeys。')
287
+ : null),
288
+ options.featureBriefIndex
289
+ ? buildFeatureBriefIndexProvenance(options.featureBriefIndex, presentDocs.get('feature-briefs/index')?.path)
290
+ : (hasCurrentSpec(options.projectRoot)
291
+ ? createMissingRecord('feature-briefs/index', 'Feature Briefs', '检测到 current-spec,但当前批次未生成 feature briefs 索引。')
292
+ : null),
293
+ ].filter((record) => record !== null);
294
+ }
295
+ function buildComponentViewProvenance(output, sourcePath) {
296
+ const componentEntries = output.model.components.flatMap((component) => component.evidence.map((evidence) => ({
297
+ sourceType: mapComponentSourceType(evidence.sourceType),
298
+ originType: evidence.sourceType,
299
+ ref: `${component.name}:${evidence.ref}`,
300
+ path: component.relatedFiles[0],
301
+ note: evidence.note ?? component.summary,
302
+ confidence: normalizeConfidence(component.confidence),
303
+ inferred: Boolean(component.inferred || evidence.inferred),
304
+ })));
305
+ const relationshipEntries = output.model.relationships.flatMap((relationship) => relationship.evidence.map((evidence) => ({
306
+ sourceType: mapComponentSourceType(evidence.sourceType),
307
+ originType: evidence.sourceType,
308
+ ref: `${relationship.fromId}->${relationship.toId}:${relationship.kind}`,
309
+ note: evidence.note ?? relationship.label,
310
+ confidence: normalizeConfidence(relationship.confidence),
311
+ inferred: Boolean(evidence.inferred),
312
+ })));
313
+ return summarizeProvenanceRecord({
314
+ documentId: 'component-view',
315
+ title: output.title,
316
+ sourcePath,
317
+ available: true,
318
+ warnings: output.warnings,
319
+ sections: [
320
+ summarizeProvenanceSection({
321
+ id: 'components',
322
+ title: 'Components',
323
+ summary: `关键组件数: ${output.model.components.length}`,
324
+ entries: componentEntries,
325
+ }),
326
+ summarizeProvenanceSection({
327
+ id: 'relationships',
328
+ title: 'Relationships',
329
+ summary: `关系数: ${output.model.relationships.length}`,
330
+ entries: relationshipEntries,
331
+ }),
332
+ ],
333
+ });
334
+ }
335
+ function buildDynamicScenariosProvenance(output, sourcePath) {
336
+ const scenarioEntries = output.model.scenarios.flatMap((scenario) => scenario.evidence.map((evidence) => ({
337
+ sourceType: mapComponentSourceType(evidence.sourceType),
338
+ originType: evidence.sourceType,
339
+ ref: `${scenario.id}:${evidence.ref}`,
340
+ note: evidence.note ?? scenario.summary,
341
+ confidence: normalizeConfidence(scenario.confidence),
342
+ inferred: Boolean(scenario.inferred || evidence.inferred),
343
+ })));
344
+ const stepEntries = output.model.scenarios.flatMap((scenario) => scenario.steps.flatMap((step) => step.evidence.map((evidence) => ({
345
+ sourceType: mapComponentSourceType(evidence.sourceType),
346
+ originType: evidence.sourceType,
347
+ ref: `${scenario.id}:step-${step.index}:${evidence.ref}`,
348
+ note: `${step.actor} -> ${step.target ?? 'n/a'}: ${step.action}`,
349
+ confidence: normalizeConfidence(step.confidence),
350
+ inferred: Boolean(step.inferred || evidence.inferred),
351
+ }))));
352
+ return summarizeProvenanceRecord({
353
+ documentId: 'dynamic-scenarios',
354
+ title: output.title,
355
+ sourcePath,
356
+ available: true,
357
+ warnings: output.warnings,
358
+ sections: [
359
+ summarizeProvenanceSection({
360
+ id: 'scenarios',
361
+ title: 'Scenarios',
362
+ summary: `场景数: ${output.model.scenarios.length}`,
363
+ entries: scenarioEntries,
364
+ }),
365
+ summarizeProvenanceSection({
366
+ id: 'steps',
367
+ title: 'Steps',
368
+ summary: `步骤数: ${output.model.stats.totalSteps}`,
369
+ entries: stepEntries,
370
+ }),
371
+ ],
372
+ });
373
+ }
374
+ function buildAdrProvenance(output, sourcePath) {
375
+ const draftSections = output.drafts.map((draft) => summarizeProvenanceSection({
376
+ id: draft.decisionId.toLowerCase(),
377
+ title: draft.title,
378
+ summary: draft.summary,
379
+ entries: draft.evidence.map((evidence) => toAdrProvenanceEntry(draft, evidence)),
380
+ }));
381
+ return summarizeProvenanceRecord({
382
+ documentId: 'docs/adr/index',
383
+ title: output.title,
384
+ sourcePath,
385
+ available: true,
386
+ warnings: output.warnings,
387
+ sections: draftSections,
388
+ });
389
+ }
390
+ function buildProductOverviewProvenance(output, sourcePath) {
391
+ return summarizeProvenanceRecord({
392
+ documentId: 'product-overview',
393
+ title: output.title,
394
+ sourcePath,
395
+ available: true,
396
+ warnings: output.warnings,
397
+ sections: [
398
+ summarizeProvenanceSection({
399
+ id: 'summary',
400
+ title: 'Summary',
401
+ summary: `摘要段落: ${output.summary.length}`,
402
+ entries: output.evidence.map((evidence) => toProductProvenanceEntry('overview', evidence, output.confidence)),
403
+ }),
404
+ summarizeProvenanceSection({
405
+ id: 'target-users',
406
+ title: 'Target Users',
407
+ summary: `用户段数: ${output.targetUsers.length}`,
408
+ entries: output.targetUsers.flatMap((user) => user.evidence.map((evidence) => toProductProvenanceEntry(`user:${user.name}`, evidence, user.confidence))),
409
+ }),
410
+ summarizeProvenanceSection({
411
+ id: 'core-scenarios',
412
+ title: 'Core Scenarios',
413
+ summary: `核心场景数: ${output.coreScenarios.length}`,
414
+ entries: output.coreScenarios.flatMap((scenario) => scenario.evidence.map((evidence) => toProductProvenanceEntry(`scenario:${scenario.title}`, evidence, scenario.confidence))),
415
+ }),
416
+ ],
417
+ });
418
+ }
419
+ function buildUserJourneysProvenance(output, sourcePath) {
420
+ return summarizeProvenanceRecord({
421
+ documentId: 'user-journeys',
422
+ title: output.title,
423
+ sourcePath,
424
+ available: true,
425
+ warnings: output.warnings,
426
+ sections: output.journeys.map((journey) => summarizeProvenanceSection({
427
+ id: journey.id,
428
+ title: journey.title,
429
+ summary: `${journey.actor} -> ${journey.goal}`,
430
+ entries: journey.evidence.map((evidence) => toProductProvenanceEntry(journey.id, evidence, journey.confidence)),
431
+ })),
432
+ });
433
+ }
434
+ function buildFeatureBriefIndexProvenance(output, sourcePath) {
435
+ return summarizeProvenanceRecord({
436
+ documentId: 'feature-briefs/index',
437
+ title: output.title,
438
+ sourcePath,
439
+ available: true,
440
+ warnings: output.warnings,
441
+ sections: output.briefs.map((brief) => summarizeProvenanceSection({
442
+ id: brief.id.toLowerCase(),
443
+ title: brief.title,
444
+ summary: brief.summary,
445
+ entries: brief.evidence.map((evidence) => toProductProvenanceEntry(brief.id, evidence, brief.confidence)),
446
+ })),
447
+ });
448
+ }
449
+ function toProductProvenanceEntry(ref, evidence, confidence) {
450
+ return {
451
+ sourceType: mapProductSourceType(evidence.sourceType),
452
+ originType: evidence.sourceType,
453
+ ref: `${ref}:${evidence.label}`,
454
+ path: evidence.path,
455
+ excerpt: evidence.excerpt,
456
+ confidence: normalizeConfidence(confidence),
457
+ inferred: evidence.inferred,
458
+ };
459
+ }
460
+ function toAdrProvenanceEntry(draft, evidence) {
461
+ return {
462
+ sourceType: mapAdrSourceType(evidence.sourceType),
463
+ originType: evidence.sourceType,
464
+ ref: `${draft.decisionId}:${evidence.label}`,
465
+ path: evidence.path,
466
+ excerpt: evidence.excerpt,
467
+ note: draft.summary,
468
+ confidence: normalizeConfidence(draft.confidence),
469
+ inferred: draft.inferred,
470
+ };
471
+ }
472
+ function createMissingRecord(documentId, title, reason) {
473
+ return summarizeProvenanceRecord({
474
+ documentId,
475
+ title,
476
+ available: false,
477
+ warnings: [],
478
+ missingReason: reason,
479
+ sections: [],
480
+ });
481
+ }
482
+ function evaluateRequiredDocs(options, presentDocs, dependencyWarnings) {
483
+ const projectKinds = inferProjectKinds(options, presentDocs);
484
+ const manifest = options.docsBundleManifest;
485
+ if (!manifest) {
486
+ dependencyWarnings.push('缺少 docs-bundle manifest,发布覆盖度只能按 partial 模式估算。');
487
+ }
488
+ return REQUIRED_DOC_RULES
489
+ .filter((rule) => rule.requiredBy.some((kind) => projectKinds.has(kind)))
490
+ .map((rule) => {
491
+ const presentDoc = presentDocs.get(rule.docId);
492
+ const includedInBundles = manifest
493
+ ? manifest.profiles
494
+ .filter((profile) => profile.documentIds.includes(rule.docId))
495
+ .map((profile) => profile.id)
496
+ : [];
497
+ const missingFromBundles = manifest && presentDoc && includedInBundles.length === 0
498
+ ? manifest.profiles.map((profile) => profile.id)
499
+ : [];
500
+ return {
501
+ docId: rule.docId,
502
+ title: rule.title,
503
+ required: true,
504
+ present: Boolean(presentDoc),
505
+ presentPath: presentDoc?.path,
506
+ coverage: presentDoc
507
+ ? (manifest && includedInBundles.length === 0 ? 'partial' : 'covered')
508
+ : 'missing',
509
+ requiredBy: [...rule.requiredBy],
510
+ includedInBundles,
511
+ missingFromBundles,
512
+ notes: [
513
+ rule.reason,
514
+ ...(manifest
515
+ ? (includedInBundles.length === 0 && presentDoc
516
+ ? ['文档已生成,但当前 bundle profiles 未包含该文档。']
517
+ : [])
518
+ : ['docs-bundle manifest 不可用,发布覆盖度未完全校验。']),
519
+ ],
520
+ };
521
+ })
522
+ .sort((left, right) => left.docId.localeCompare(right.docId));
523
+ }
524
+ function inferProjectKinds(options, presentDocs) {
525
+ const projectKinds = new Set(['general']);
526
+ const hasRuntime = Boolean(options.runtimeTopology?.topology.services.length
527
+ || options.architectureOverview?.deploymentView?.available);
528
+ const isMonorepo = Boolean(options.projectContext?.workspaceType === 'monorepo'
529
+ || presentDocs.has('workspace-index')
530
+ || presentDocs.has('cross-package-analysis'));
531
+ const isHttpApi = presentDocs.has('api-surface');
532
+ const isLibrarySdk = Boolean(looksLikeLibrarySdkProject(options.projectRoot)
533
+ || presentDocs.has('interface-surface')
534
+ || (presentDocs.has('data-model') && !hasRuntime && !presentDocs.has('api-surface')));
535
+ const isArchitectureHeavy = Boolean(options.architectureOverview
536
+ || options.patternHints
537
+ || options.adrIndex);
538
+ const isProductManaged = Boolean(hasCurrentSpec(options.projectRoot)
539
+ || presentDocs.has('product-overview')
540
+ || presentDocs.has('user-journeys')
541
+ || presentDocs.has('feature-briefs/index'));
542
+ if (hasRuntime) {
543
+ projectKinds.add('runtime-project');
544
+ }
545
+ if (isMonorepo) {
546
+ projectKinds.add('monorepo');
547
+ }
548
+ if (isLibrarySdk) {
549
+ projectKinds.add('library-sdk');
550
+ }
551
+ if (isHttpApi) {
552
+ projectKinds.add('http-api');
553
+ }
554
+ if (isArchitectureHeavy) {
555
+ projectKinds.add('architecture-heavy');
556
+ }
557
+ if (isProductManaged) {
558
+ projectKinds.add('product-managed');
559
+ }
560
+ return projectKinds;
561
+ }
562
+ function looksLikeLibrarySdkProject(projectRoot) {
563
+ return looksLikeNodeLibrary(projectRoot) || looksLikePythonLibrary(projectRoot);
564
+ }
565
+ function looksLikeNodeLibrary(projectRoot) {
566
+ const packageJsonPath = path.join(projectRoot, 'package.json');
567
+ if (!fs.existsSync(packageJsonPath)) {
568
+ return false;
569
+ }
570
+ try {
571
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
572
+ if (pkg.exports || pkg.main || pkg.module || pkg.types || pkg.typings) {
573
+ return true;
574
+ }
575
+ const keywords = Array.isArray(pkg.keywords)
576
+ ? pkg.keywords.filter((item) => typeof item === 'string')
577
+ : [];
578
+ return keywords.some((keyword) => /(sdk|library|client|plugin|toolkit|api-client)/i.test(keyword));
579
+ }
580
+ catch {
581
+ return false;
582
+ }
583
+ }
584
+ function looksLikePythonLibrary(projectRoot) {
585
+ const pyprojectPath = path.join(projectRoot, 'pyproject.toml');
586
+ if (!fs.existsSync(pyprojectPath)) {
587
+ return false;
588
+ }
589
+ try {
590
+ const content = fs.readFileSync(pyprojectPath, 'utf-8');
591
+ return /^\[project\]/m.test(content) || /^\[tool\.poetry\]/m.test(content);
592
+ }
593
+ catch {
594
+ return false;
595
+ }
596
+ }
597
+ function determineBundleCoverage(requiredDocs, manifest) {
598
+ if (!manifest) {
599
+ return 'partial';
600
+ }
601
+ return requiredDocs.some((doc) => doc.present && doc.includedInBundles.length === 0)
602
+ ? 'partial'
603
+ : 'full';
604
+ }
605
+ function detectConflicts(documents) {
606
+ const claims = documents.flatMap((document) => extractTopicClaims(document));
607
+ const records = [];
608
+ for (const topic of Object.keys(TOPIC_PATTERNS)) {
609
+ const topicClaims = claims.filter((claim) => claim.topic === topic);
610
+ const distinctValues = uniqueSorted(topicClaims.map((claim) => claim.canonicalValue));
611
+ if (topicClaims.length < 2 || distinctValues.length < 2) {
612
+ continue;
613
+ }
614
+ const sourceRefs = dedupeConflictSources(topicClaims).slice(0, 4);
615
+ records.push({
616
+ topic,
617
+ severity: severityForTopic(topic),
618
+ summary: `${humanizeTopic(topic)} 在多个来源之间存在不一致:${distinctValues.join(' vs ')}`,
619
+ sources: sourceRefs,
620
+ });
621
+ }
622
+ return records.sort((left, right) => severityWeight(right.severity) - severityWeight(left.severity)
623
+ || left.topic.localeCompare(right.topic));
624
+ }
625
+ function collectEvidenceDocuments(options) {
626
+ const documents = [];
627
+ if (options.runtimeTopology?.topology.services.length) {
628
+ documents.push({
629
+ sourceType: 'generated-doc',
630
+ label: 'runtime-topology',
631
+ path: normalizeProjectPath(path.join(options.outputDir, 'runtime-topology.md'), options.projectRoot),
632
+ text: options.runtimeTopology.topology.services.map((service) => [
633
+ service.name,
634
+ service.image,
635
+ service.command ?? '',
636
+ service.dependsOn.map((dependency) => dependency.service).join(' '),
637
+ ].join('\n')).join('\n\n'),
638
+ });
639
+ }
640
+ documents.push({
641
+ sourceType: 'generated-doc',
642
+ label: 'architecture-narrative',
643
+ path: normalizeProjectPath(path.join(options.outputDir, 'architecture-narrative.md'), options.projectRoot),
644
+ text: [
645
+ ...options.architectureNarrative.executiveSummary,
646
+ ...options.architectureNarrative.observations,
647
+ ...options.architectureNarrative.keyModules.map((module) => [
648
+ module.sourceTarget,
649
+ module.intentSummary,
650
+ module.businessSummary,
651
+ module.dependencySummary,
652
+ ].join('\n')),
653
+ ].join('\n'),
654
+ });
655
+ if (options.patternHints) {
656
+ documents.push({
657
+ sourceType: 'generated-doc',
658
+ label: 'pattern-hints',
659
+ path: normalizeProjectPath(path.join(options.outputDir, 'pattern-hints.md'), options.projectRoot),
660
+ text: options.patternHints.model.matchedPatterns.map((hint) => [
661
+ hint.patternName,
662
+ hint.summary,
663
+ hint.explanation,
664
+ ].join('\n')).join('\n\n'),
665
+ });
666
+ }
667
+ for (const readmePath of findFilesByBasename(options.projectRoot, ['README.md', 'readme.md'])) {
668
+ documents.push({
669
+ sourceType: 'readme',
670
+ label: path.basename(readmePath),
671
+ path: normalizeProjectPath(readmePath, options.projectRoot),
672
+ text: fs.readFileSync(readmePath, 'utf-8'),
673
+ });
674
+ }
675
+ for (const specPath of findSpecEvidenceFiles(options.projectRoot)) {
676
+ const basename = path.basename(specPath);
677
+ const sourceType = basename === 'current-spec.md'
678
+ ? 'current-spec'
679
+ : 'spec';
680
+ documents.push({
681
+ sourceType,
682
+ label: basename,
683
+ path: normalizeProjectPath(specPath, options.projectRoot),
684
+ text: fs.readFileSync(specPath, 'utf-8'),
685
+ });
686
+ }
687
+ return documents;
688
+ }
689
+ function extractTopicClaims(document) {
690
+ const claims = [];
691
+ for (const topic of Object.keys(TOPIC_PATTERNS)) {
692
+ const matches = TOPIC_PATTERNS[topic]
693
+ .filter((matcher) => matcher.patterns.some((pattern) => pattern.test(document.text)))
694
+ .map((matcher) => matcher.value);
695
+ const canonicalValue = uniqueSorted(matches).join('+');
696
+ if (!canonicalValue) {
697
+ continue;
698
+ }
699
+ claims.push({
700
+ topic,
701
+ sourceType: document.sourceType,
702
+ label: document.label,
703
+ path: document.path,
704
+ canonicalValue,
705
+ excerpt: extractExcerpt(document.text, TOPIC_PATTERNS[topic]),
706
+ });
707
+ }
708
+ return claims;
709
+ }
710
+ function collectPresentDocs(generatedDocs, projectRoot, outputDir) {
711
+ const docs = new Map();
712
+ for (const generatedDoc of generatedDocs) {
713
+ for (const filePath of generatedDoc.writtenFiles.filter((candidate) => candidate.endsWith('.md'))) {
714
+ const docId = toDocumentId(generatedDoc.generatorId, filePath, outputDir);
715
+ if (!docId || !DOC_METADATA[docId]) {
716
+ continue;
717
+ }
718
+ docs.set(docId, {
719
+ id: docId,
720
+ title: DOC_METADATA[docId].title,
721
+ path: normalizeProjectPath(filePath, projectRoot),
722
+ });
723
+ }
724
+ }
725
+ return docs;
726
+ }
727
+ function collectGeneratedDocWarnings(generatedDocs) {
728
+ return uniqueSorted(generatedDocs.flatMap((doc) => doc.warnings.map((warning) => `${doc.generatorId}: ${warning}`)));
729
+ }
730
+ function toDocumentId(generatorId, filePath, outputDir) {
731
+ if (generatorId === 'adr-pipeline') {
732
+ return filePath.endsWith(path.join('docs', 'adr', 'index.md')) ? 'docs/adr/index' : undefined;
733
+ }
734
+ if (generatorId === 'cross-package-deps') {
735
+ return 'cross-package-analysis';
736
+ }
737
+ if (generatorId === 'quality-report') {
738
+ return 'quality-report';
739
+ }
740
+ if (DOC_METADATA[generatorId]) {
741
+ return generatorId;
742
+ }
743
+ const relative = path.relative(outputDir, filePath).split(path.sep).join('/');
744
+ const matched = Object.entries(DOC_METADATA)
745
+ .find(([, metadata]) => metadata.relativePath === relative);
746
+ return matched?.[0];
747
+ }
748
+ function buildSummaryLines(input) {
749
+ const availableDocs = input.provenance.filter((record) => record.available).length;
750
+ const highCoverageDocs = input.provenance.filter((record) => record.coverage === 'high').length;
751
+ const coveredRequiredDocs = input.requiredDocs.filter((doc) => doc.coverage === 'covered').length;
752
+ const missingRequiredDocs = input.requiredDocs.filter((doc) => doc.coverage === 'missing').length;
753
+ return [
754
+ `Explanation provenance 可用文档 ${availableDocs}/${input.provenance.length},其中高覆盖 ${highCoverageDocs} 份。`,
755
+ input.conflicts.length > 0
756
+ ? `检测到 ${input.conflicts.length} 条显式冲突,最高严重级别为 ${input.conflicts[0].severity}。`
757
+ : '未检测到显式冲突记录。',
758
+ `Required docs 覆盖 ${coveredRequiredDocs}/${input.requiredDocs.length},缺失 ${missingRequiredDocs} 份。`,
759
+ input.bundleCoverage === 'full'
760
+ ? 'docs bundle manifest 可用,已完成发布覆盖校验。'
761
+ : 'docs bundle manifest 缺失或覆盖不完整,发布覆盖校验按 partial 模式降级。',
762
+ ...(input.dependencyWarnings.length > 0
763
+ ? [`Dependency warnings: ${input.dependencyWarnings.length} 条。`]
764
+ : []),
765
+ ...(input.warnings.length > 0
766
+ ? [`General warnings: ${input.warnings.length} 条。`]
767
+ : []),
768
+ ];
769
+ }
770
+ function severityForTopic(topic) {
771
+ switch (topic) {
772
+ case 'product-positioning':
773
+ case 'runtime-hosting':
774
+ return 'high';
775
+ case 'protocol-boundary':
776
+ case 'extensibility-boundary':
777
+ return 'medium';
778
+ case 'degradation-strategy':
779
+ default:
780
+ return 'low';
781
+ }
782
+ }
783
+ function severityWeight(severity) {
784
+ switch (severity) {
785
+ case 'high':
786
+ return 3;
787
+ case 'medium':
788
+ return 2;
789
+ case 'low':
790
+ default:
791
+ return 1;
792
+ }
793
+ }
794
+ function humanizeTopic(topic) {
795
+ switch (topic) {
796
+ case 'product-positioning':
797
+ return '产品定位';
798
+ case 'runtime-hosting':
799
+ return '运行时宿主';
800
+ case 'protocol-boundary':
801
+ return '协议边界';
802
+ case 'extensibility-boundary':
803
+ return '扩展边界';
804
+ case 'degradation-strategy':
805
+ default:
806
+ return '降级策略';
807
+ }
808
+ }
809
+ function dedupeConflictSources(claims) {
810
+ const seen = new Set();
811
+ const result = [];
812
+ for (const claim of claims) {
813
+ const key = `${claim.topic}:${claim.sourceType}:${claim.label}:${claim.canonicalValue}`;
814
+ if (seen.has(key)) {
815
+ continue;
816
+ }
817
+ seen.add(key);
818
+ result.push({
819
+ sourceType: claim.sourceType,
820
+ label: claim.label,
821
+ canonicalValue: claim.canonicalValue,
822
+ path: claim.path,
823
+ excerpt: claim.excerpt,
824
+ });
825
+ }
826
+ return result;
827
+ }
828
+ function mapComponentSourceType(sourceType) {
829
+ switch (sourceType) {
830
+ case 'architecture-ir':
831
+ case 'baseline-skeleton':
832
+ return 'code';
833
+ case 'runtime-topology':
834
+ return 'config';
835
+ case 'test-file':
836
+ return 'test';
837
+ case 'module-spec':
838
+ return 'spec';
839
+ case 'architecture-narrative':
840
+ case 'event-surface':
841
+ default:
842
+ return 'generated-doc';
843
+ }
844
+ }
845
+ function mapAdrSourceType(sourceType) {
846
+ switch (sourceType) {
847
+ case 'current-spec':
848
+ return 'current-spec';
849
+ case 'commit':
850
+ return 'commit';
851
+ case 'spec':
852
+ case 'blueprint':
853
+ return 'spec';
854
+ case 'source-path':
855
+ return 'code';
856
+ case 'architecture-overview':
857
+ case 'architecture-narrative':
858
+ case 'pattern-hints':
859
+ default:
860
+ return 'generated-doc';
861
+ }
862
+ }
863
+ function mapProductSourceType(sourceType) {
864
+ switch (sourceType) {
865
+ case 'current-spec':
866
+ return 'current-spec';
867
+ case 'readme':
868
+ return 'readme';
869
+ case 'design-doc':
870
+ return 'design-doc';
871
+ case 'issue':
872
+ return 'issue';
873
+ case 'pull-request':
874
+ return 'pull-request';
875
+ case 'commit':
876
+ return 'commit';
877
+ case 'inference':
878
+ return 'inference';
879
+ default:
880
+ return 'generated-doc';
881
+ }
882
+ }
883
+ function hasReadme(projectRoot) {
884
+ return findFilesByBasename(projectRoot, ['README.md', 'readme.md']).length > 0;
885
+ }
886
+ function hasCurrentSpec(projectRoot) {
887
+ return findSpecEvidenceFiles(projectRoot).some((filePath) => path.basename(filePath) === 'current-spec.md');
888
+ }
889
+ function findSpecEvidenceFiles(projectRoot) {
890
+ const specsDir = path.join(projectRoot, 'specs');
891
+ if (!fs.existsSync(specsDir)) {
892
+ return [];
893
+ }
894
+ const results = [];
895
+ walkDirectory(specsDir, (filePath) => {
896
+ const basename = path.basename(filePath);
897
+ if (basename === 'current-spec.md' || basename === 'spec.md' || basename === 'blueprint.md') {
898
+ results.push(filePath);
899
+ }
900
+ });
901
+ return results.sort((left, right) => left.localeCompare(right));
902
+ }
903
+ function findFilesByBasename(projectRoot, fileNames) {
904
+ return fileNames
905
+ .map((fileName) => path.join(projectRoot, fileName))
906
+ .filter((candidatePath) => fs.existsSync(candidatePath));
907
+ }
908
+ function walkDirectory(dir, visitor) {
909
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
910
+ if (entry.name === 'node_modules' || entry.name === '.git') {
911
+ continue;
912
+ }
913
+ const fullPath = path.join(dir, entry.name);
914
+ if (entry.isDirectory()) {
915
+ walkDirectory(fullPath, visitor);
916
+ continue;
917
+ }
918
+ if (entry.isFile()) {
919
+ visitor(fullPath);
920
+ }
921
+ }
922
+ }
923
+ function extractExcerpt(text, topicPatterns) {
924
+ const lines = text.split('\n').map((line) => line.trim()).filter(Boolean);
925
+ for (const line of lines) {
926
+ if (topicPatterns.some((matcher) => matcher.patterns.some((pattern) => pattern.test(line)))) {
927
+ return line.slice(0, 180);
928
+ }
929
+ }
930
+ return text.trim().slice(0, 180);
931
+ }
932
+ function normalizeProjectPath(candidatePath, projectRoot) {
933
+ const relative = path.relative(projectRoot, candidatePath);
934
+ return relative.startsWith('..')
935
+ ? candidatePath.split(path.sep).join('/')
936
+ : relative.split(path.sep).join('/');
937
+ }
938
+ function uniqueSorted(values) {
939
+ return [...new Set(values)].sort((left, right) => left.localeCompare(right));
940
+ }
941
+ //# sourceMappingURL=docs-quality-evaluator.js.map