spectra-cli 4.1.1 → 4.3.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 (682) hide show
  1. package/README.md +12 -5
  2. package/dist/.spectra-build-meta.json +9 -0
  3. package/dist/adapters/go-adapter.d.ts.map +1 -1
  4. package/dist/adapters/go-adapter.js +2 -0
  5. package/dist/adapters/go-adapter.js.map +1 -1
  6. package/dist/adapters/index.d.ts +1 -1
  7. package/dist/adapters/index.d.ts.map +1 -1
  8. package/dist/adapters/java-adapter.d.ts.map +1 -1
  9. package/dist/adapters/java-adapter.js +2 -0
  10. package/dist/adapters/java-adapter.js.map +1 -1
  11. package/dist/adapters/language-adapter.d.ts +42 -9
  12. package/dist/adapters/language-adapter.d.ts.map +1 -1
  13. package/dist/adapters/python-adapter.d.ts +34 -6
  14. package/dist/adapters/python-adapter.d.ts.map +1 -1
  15. package/dist/adapters/python-adapter.js +168 -61
  16. package/dist/adapters/python-adapter.js.map +1 -1
  17. package/dist/adapters/ts-js-adapter.d.ts +13 -5
  18. package/dist/adapters/ts-js-adapter.d.ts.map +1 -1
  19. package/dist/adapters/ts-js-adapter.js +55 -14
  20. package/dist/adapters/ts-js-adapter.js.map +1 -1
  21. package/dist/batch/batch-orchestrator.d.ts +74 -5
  22. package/dist/batch/batch-orchestrator.d.ts.map +1 -1
  23. package/dist/batch/batch-orchestrator.js +583 -70
  24. package/dist/batch/batch-orchestrator.js.map +1 -1
  25. package/dist/batch/delta-regenerator.d.ts +2 -2
  26. package/dist/batch/delta-regenerator.d.ts.map +1 -1
  27. package/dist/batch/delta-regenerator.js +21 -28
  28. package/dist/batch/delta-regenerator.js.map +1 -1
  29. package/dist/batch/module-grouper.d.ts +9 -2
  30. package/dist/batch/module-grouper.d.ts.map +1 -1
  31. package/dist/batch/module-grouper.js +3 -1
  32. package/dist/batch/module-grouper.js.map +1 -1
  33. package/dist/batch/regen-plan.d.ts +78 -0
  34. package/dist/batch/regen-plan.d.ts.map +1 -0
  35. package/dist/batch/regen-plan.js +93 -0
  36. package/dist/batch/regen-plan.js.map +1 -0
  37. package/dist/cli/commands/batch.d.ts.map +1 -1
  38. package/dist/cli/commands/batch.js +36 -8
  39. package/dist/cli/commands/batch.js.map +1 -1
  40. package/dist/cli/commands/graph.js +1 -1
  41. package/dist/cli/commands/graph.js.map +1 -1
  42. package/dist/cli/commands/index.d.ts +8 -0
  43. package/dist/cli/commands/index.d.ts.map +1 -0
  44. package/dist/cli/commands/index.js +274 -0
  45. package/dist/cli/commands/index.js.map +1 -0
  46. package/dist/cli/commands/query.d.ts.map +1 -1
  47. package/dist/cli/commands/query.js +3 -1
  48. package/dist/cli/commands/query.js.map +1 -1
  49. package/dist/cli/commands/scaffold-kb.d.ts +9 -0
  50. package/dist/cli/commands/scaffold-kb.d.ts.map +1 -0
  51. package/dist/cli/commands/scaffold-kb.js +179 -0
  52. package/dist/cli/commands/scaffold-kb.js.map +1 -0
  53. package/dist/cli/index.js +33 -14
  54. package/dist/cli/index.js.map +1 -1
  55. package/dist/cli/utils/error-handler.d.ts +0 -6
  56. package/dist/cli/utils/error-handler.d.ts.map +1 -1
  57. package/dist/cli/utils/error-handler.js +0 -13
  58. package/dist/cli/utils/error-handler.js.map +1 -1
  59. package/dist/cli/utils/parse-args.d.ts +55 -3
  60. package/dist/cli/utils/parse-args.d.ts.map +1 -1
  61. package/dist/cli/utils/parse-args.js +176 -13
  62. package/dist/cli/utils/parse-args.js.map +1 -1
  63. package/dist/cli/version-meta.d.ts +16 -0
  64. package/dist/cli/version-meta.d.ts.map +1 -0
  65. package/dist/cli/version-meta.js +28 -0
  66. package/dist/cli/version-meta.js.map +1 -0
  67. package/dist/core/ast-analyzer.d.ts.map +1 -1
  68. package/dist/core/ast-analyzer.js +75 -5
  69. package/dist/core/ast-analyzer.js.map +1 -1
  70. package/dist/core/import-resolver.d.ts +93 -0
  71. package/dist/core/import-resolver.d.ts.map +1 -0
  72. package/dist/core/import-resolver.js +414 -0
  73. package/dist/core/import-resolver.js.map +1 -0
  74. package/dist/core/query-mappers/base-mapper.d.ts +13 -0
  75. package/dist/core/query-mappers/base-mapper.d.ts.map +1 -1
  76. package/dist/core/query-mappers/go-mapper.d.ts +68 -0
  77. package/dist/core/query-mappers/go-mapper.d.ts.map +1 -1
  78. package/dist/core/query-mappers/go-mapper.js +421 -0
  79. package/dist/core/query-mappers/go-mapper.js.map +1 -1
  80. package/dist/core/query-mappers/java-mapper.d.ts +196 -0
  81. package/dist/core/query-mappers/java-mapper.d.ts.map +1 -1
  82. package/dist/core/query-mappers/java-mapper.js +600 -0
  83. package/dist/core/query-mappers/java-mapper.js.map +1 -1
  84. package/dist/core/query-mappers/python-mapper.d.ts +55 -0
  85. package/dist/core/query-mappers/python-mapper.d.ts.map +1 -1
  86. package/dist/core/query-mappers/python-mapper.js +273 -0
  87. package/dist/core/query-mappers/python-mapper.js.map +1 -1
  88. package/dist/core/query-mappers/typescript-mapper.d.ts +102 -0
  89. package/dist/core/query-mappers/typescript-mapper.d.ts.map +1 -1
  90. package/dist/core/query-mappers/typescript-mapper.js +470 -0
  91. package/dist/core/query-mappers/typescript-mapper.js.map +1 -1
  92. package/dist/core/single-spec-orchestrator.d.ts +21 -0
  93. package/dist/core/single-spec-orchestrator.d.ts.map +1 -1
  94. package/dist/core/single-spec-orchestrator.js +187 -23
  95. package/dist/core/single-spec-orchestrator.js.map +1 -1
  96. package/dist/core/skeleton-hash.d.ts +33 -0
  97. package/dist/core/skeleton-hash.d.ts.map +1 -0
  98. package/dist/core/skeleton-hash.js +76 -0
  99. package/dist/core/skeleton-hash.js.map +1 -0
  100. package/dist/core/tree-sitter-analyzer.d.ts +7 -0
  101. package/dist/core/tree-sitter-analyzer.d.ts.map +1 -1
  102. package/dist/core/tree-sitter-analyzer.js +32 -1
  103. package/dist/core/tree-sitter-analyzer.js.map +1 -1
  104. package/dist/core/tree-sitter-fallback.d.ts +12 -4
  105. package/dist/core/tree-sitter-fallback.d.ts.map +1 -1
  106. package/dist/core/tree-sitter-fallback.js +160 -12
  107. package/dist/core/tree-sitter-fallback.js.map +1 -1
  108. package/dist/extraction/extraction-types.d.ts +25 -25
  109. package/dist/extraction/image-extractor.d.ts.map +1 -1
  110. package/dist/extraction/image-extractor.js +3 -1
  111. package/dist/extraction/image-extractor.js.map +1 -1
  112. package/dist/extraction/markdown-extractor.d.ts.map +1 -1
  113. package/dist/extraction/markdown-extractor.js +3 -1
  114. package/dist/extraction/markdown-extractor.js.map +1 -1
  115. package/dist/generator/frontmatter.d.ts +5 -0
  116. package/dist/generator/frontmatter.d.ts.map +1 -1
  117. package/dist/generator/frontmatter.js +4 -0
  118. package/dist/generator/frontmatter.js.map +1 -1
  119. package/dist/generator/index-generator.d.ts +3 -3
  120. package/dist/generator/index-generator.d.ts.map +1 -1
  121. package/dist/generator/index-generator.js +1 -1
  122. package/dist/generator/index-generator.js.map +1 -1
  123. package/dist/graph/directory-graph.d.ts +14 -4
  124. package/dist/graph/directory-graph.d.ts.map +1 -1
  125. package/dist/graph/directory-graph.js +71 -128
  126. package/dist/graph/directory-graph.js.map +1 -1
  127. package/dist/graph/mermaid-renderer.d.ts +8 -5
  128. package/dist/graph/mermaid-renderer.d.ts.map +1 -1
  129. package/dist/graph/mermaid-renderer.js +3 -3
  130. package/dist/graph/mermaid-renderer.js.map +1 -1
  131. package/dist/graph/topological-sort.d.ts +13 -6
  132. package/dist/graph/topological-sort.d.ts.map +1 -1
  133. package/dist/graph/topological-sort.js +2 -2
  134. package/dist/graph/topological-sort.js.map +1 -1
  135. package/dist/kb-mcp/index.d.ts +14 -0
  136. package/dist/kb-mcp/index.d.ts.map +1 -0
  137. package/dist/kb-mcp/index.js +24 -0
  138. package/dist/kb-mcp/index.js.map +1 -0
  139. package/dist/kb-mcp/lib/kb-error.d.ts +21 -0
  140. package/dist/kb-mcp/lib/kb-error.d.ts.map +1 -0
  141. package/dist/kb-mcp/lib/kb-error.js +28 -0
  142. package/dist/kb-mcp/lib/kb-error.js.map +1 -0
  143. package/dist/kb-mcp/lib/kb-locator.d.ts +58 -0
  144. package/dist/kb-mcp/lib/kb-locator.d.ts.map +1 -0
  145. package/dist/kb-mcp/lib/kb-locator.js +85 -0
  146. package/dist/kb-mcp/lib/kb-locator.js.map +1 -0
  147. package/dist/kb-mcp/lib/result-merger.d.ts +35 -0
  148. package/dist/kb-mcp/lib/result-merger.d.ts.map +1 -0
  149. package/dist/kb-mcp/lib/result-merger.js +64 -0
  150. package/dist/kb-mcp/lib/result-merger.js.map +1 -0
  151. package/dist/kb-mcp/server.d.ts +12 -0
  152. package/dist/kb-mcp/server.d.ts.map +1 -0
  153. package/dist/kb-mcp/server.js +29 -0
  154. package/dist/kb-mcp/server.js.map +1 -0
  155. package/dist/kb-mcp/tools/kb-api-lookup.d.ts +28 -0
  156. package/dist/kb-mcp/tools/kb-api-lookup.d.ts.map +1 -0
  157. package/dist/kb-mcp/tools/kb-api-lookup.js +237 -0
  158. package/dist/kb-mcp/tools/kb-api-lookup.js.map +1 -0
  159. package/dist/kb-mcp/tools/kb-doc-lookup.d.ts +20 -0
  160. package/dist/kb-mcp/tools/kb-doc-lookup.d.ts.map +1 -0
  161. package/dist/kb-mcp/tools/kb-doc-lookup.js +92 -0
  162. package/dist/kb-mcp/tools/kb-doc-lookup.js.map +1 -0
  163. package/dist/kb-mcp/tools/kb-search.d.ts +23 -0
  164. package/dist/kb-mcp/tools/kb-search.d.ts.map +1 -0
  165. package/dist/kb-mcp/tools/kb-search.js +126 -0
  166. package/dist/kb-mcp/tools/kb-search.js.map +1 -0
  167. package/dist/knowledge-graph/call-resolver.d.ts +64 -0
  168. package/dist/knowledge-graph/call-resolver.d.ts.map +1 -0
  169. package/dist/knowledge-graph/call-resolver.js +323 -0
  170. package/dist/knowledge-graph/call-resolver.js.map +1 -0
  171. package/dist/knowledge-graph/import-resolver.d.ts +39 -0
  172. package/dist/knowledge-graph/import-resolver.d.ts.map +1 -0
  173. package/dist/knowledge-graph/import-resolver.js +214 -0
  174. package/dist/knowledge-graph/import-resolver.js.map +1 -0
  175. package/dist/knowledge-graph/incremental.d.ts +131 -0
  176. package/dist/knowledge-graph/incremental.d.ts.map +1 -0
  177. package/dist/knowledge-graph/incremental.js +432 -0
  178. package/dist/knowledge-graph/incremental.js.map +1 -0
  179. package/dist/knowledge-graph/index.d.ts +85 -0
  180. package/dist/knowledge-graph/index.d.ts.map +1 -0
  181. package/dist/knowledge-graph/index.js +198 -0
  182. package/dist/knowledge-graph/index.js.map +1 -0
  183. package/dist/knowledge-graph/module-derivation.d.ts +252 -0
  184. package/dist/knowledge-graph/module-derivation.d.ts.map +1 -0
  185. package/dist/knowledge-graph/module-derivation.js +418 -0
  186. package/dist/knowledge-graph/module-derivation.js.map +1 -0
  187. package/dist/knowledge-graph/persistence.d.ts +310 -0
  188. package/dist/knowledge-graph/persistence.d.ts.map +1 -0
  189. package/dist/knowledge-graph/persistence.js +280 -0
  190. package/dist/knowledge-graph/persistence.js.map +1 -0
  191. package/dist/knowledge-graph/query-helpers.d.ts +191 -0
  192. package/dist/knowledge-graph/query-helpers.d.ts.map +1 -0
  193. package/dist/knowledge-graph/query-helpers.js +559 -0
  194. package/dist/knowledge-graph/query-helpers.js.map +1 -0
  195. package/dist/knowledge-graph/relativize.d.ts +51 -0
  196. package/dist/knowledge-graph/relativize.d.ts.map +1 -0
  197. package/dist/knowledge-graph/relativize.js +104 -0
  198. package/dist/knowledge-graph/relativize.js.map +1 -0
  199. package/dist/knowledge-graph/unified-graph.d.ts +310 -0
  200. package/dist/knowledge-graph/unified-graph.d.ts.map +1 -0
  201. package/dist/knowledge-graph/unified-graph.js +182 -0
  202. package/dist/knowledge-graph/unified-graph.js.map +1 -0
  203. package/dist/mcp/agent-context-tools.d.ts +53 -0
  204. package/dist/mcp/agent-context-tools.d.ts.map +1 -0
  205. package/dist/mcp/agent-context-tools.js +806 -0
  206. package/dist/mcp/agent-context-tools.js.map +1 -0
  207. package/dist/mcp/file-nav-tools.d.ts +42 -0
  208. package/dist/mcp/file-nav-tools.d.ts.map +1 -0
  209. package/dist/mcp/file-nav-tools.js +318 -0
  210. package/dist/mcp/file-nav-tools.js.map +1 -0
  211. package/dist/mcp/graph-tools.d.ts +22 -0
  212. package/dist/mcp/graph-tools.d.ts.map +1 -1
  213. package/dist/mcp/graph-tools.js +204 -133
  214. package/dist/mcp/graph-tools.js.map +1 -1
  215. package/dist/mcp/lib/file-nav-helpers.d.ts +128 -0
  216. package/dist/mcp/lib/file-nav-helpers.d.ts.map +1 -0
  217. package/dist/mcp/lib/file-nav-helpers.js +305 -0
  218. package/dist/mcp/lib/file-nav-helpers.js.map +1 -0
  219. package/dist/mcp/lib/response-helpers.d.ts +67 -0
  220. package/dist/mcp/lib/response-helpers.d.ts.map +1 -0
  221. package/dist/mcp/lib/response-helpers.js +103 -0
  222. package/dist/mcp/lib/response-helpers.js.map +1 -0
  223. package/dist/mcp/lib/telemetry.d.ts +69 -0
  224. package/dist/mcp/lib/telemetry.d.ts.map +1 -0
  225. package/dist/mcp/lib/telemetry.js +113 -0
  226. package/dist/mcp/lib/telemetry.js.map +1 -0
  227. package/dist/mcp/lib/tool-response.d.ts +46 -0
  228. package/dist/mcp/lib/tool-response.d.ts.map +1 -0
  229. package/dist/mcp/lib/tool-response.js +83 -0
  230. package/dist/mcp/lib/tool-response.js.map +1 -0
  231. package/dist/mcp/server.d.ts +14 -1
  232. package/dist/mcp/server.d.ts.map +1 -1
  233. package/dist/mcp/server.js +216 -158
  234. package/dist/mcp/server.js.map +1 -1
  235. package/dist/models/call-site.d.ts +68 -0
  236. package/dist/models/call-site.d.ts.map +1 -0
  237. package/dist/models/call-site.js +60 -0
  238. package/dist/models/call-site.js.map +1 -0
  239. package/dist/models/code-skeleton.d.ts +80 -6
  240. package/dist/models/code-skeleton.d.ts.map +1 -1
  241. package/dist/models/code-skeleton.js +30 -0
  242. package/dist/models/code-skeleton.js.map +1 -1
  243. package/dist/models/drift-item.d.ts +4 -4
  244. package/dist/models/module-spec.d.ts +173 -94
  245. package/dist/models/module-spec.d.ts.map +1 -1
  246. package/dist/models/module-spec.js +6 -0
  247. package/dist/models/module-spec.js.map +1 -1
  248. package/dist/panoramic/adr-decision-pipeline.d.ts +53 -0
  249. package/dist/panoramic/adr-decision-pipeline.d.ts.map +1 -0
  250. package/dist/panoramic/adr-decision-pipeline.js +685 -0
  251. package/dist/panoramic/adr-decision-pipeline.js.map +1 -0
  252. package/dist/panoramic/api-surface-generator.d.ts +56 -0
  253. package/dist/panoramic/api-surface-generator.d.ts.map +1 -0
  254. package/dist/panoramic/api-surface-generator.js +1671 -0
  255. package/dist/panoramic/api-surface-generator.js.map +1 -0
  256. package/dist/panoramic/architecture-ir-builder.d.ts +19 -0
  257. package/dist/panoramic/architecture-ir-builder.d.ts.map +1 -0
  258. package/dist/panoramic/architecture-ir-builder.js +561 -0
  259. package/dist/panoramic/architecture-ir-builder.js.map +1 -0
  260. package/dist/panoramic/architecture-ir-exporters.d.ts +7 -0
  261. package/dist/panoramic/architecture-ir-exporters.d.ts.map +1 -0
  262. package/dist/panoramic/architecture-ir-exporters.js +183 -0
  263. package/dist/panoramic/architecture-ir-exporters.js.map +1 -0
  264. package/dist/panoramic/architecture-ir-generator.d.ts +36 -0
  265. package/dist/panoramic/architecture-ir-generator.d.ts.map +1 -0
  266. package/dist/panoramic/architecture-ir-generator.js +51 -0
  267. package/dist/panoramic/architecture-ir-generator.js.map +1 -0
  268. package/dist/panoramic/architecture-ir-mermaid-adapter.d.ts +6 -0
  269. package/dist/panoramic/architecture-ir-mermaid-adapter.d.ts.map +1 -0
  270. package/dist/panoramic/architecture-ir-mermaid-adapter.js +98 -0
  271. package/dist/panoramic/architecture-ir-mermaid-adapter.js.map +1 -0
  272. package/dist/panoramic/architecture-ir-model.d.ts +87 -0
  273. package/dist/panoramic/architecture-ir-model.d.ts.map +1 -0
  274. package/dist/panoramic/architecture-ir-model.js +20 -0
  275. package/dist/panoramic/architecture-ir-model.js.map +1 -0
  276. package/dist/panoramic/architecture-narrative.d.ts +68 -0
  277. package/dist/panoramic/architecture-narrative.d.ts.map +1 -0
  278. package/dist/panoramic/architecture-narrative.js +401 -0
  279. package/dist/panoramic/architecture-narrative.js.map +1 -0
  280. package/dist/panoramic/architecture-overview-generator.d.ts +31 -0
  281. package/dist/panoramic/architecture-overview-generator.d.ts.map +1 -0
  282. package/dist/panoramic/architecture-overview-generator.js +454 -0
  283. package/dist/panoramic/architecture-overview-generator.js.map +1 -0
  284. package/dist/panoramic/architecture-overview-model.d.ts +77 -0
  285. package/dist/panoramic/architecture-overview-model.d.ts.map +1 -0
  286. package/dist/panoramic/architecture-overview-model.js +31 -0
  287. package/dist/panoramic/architecture-overview-model.js.map +1 -0
  288. package/dist/panoramic/batch-project-docs.d.ts.map +1 -1
  289. package/dist/panoramic/batch-project-docs.js +4 -2
  290. package/dist/panoramic/batch-project-docs.js.map +1 -1
  291. package/dist/panoramic/builders/component-view-builder.d.ts +25 -1
  292. package/dist/panoramic/builders/component-view-builder.d.ts.map +1 -1
  293. package/dist/panoramic/builders/component-view-builder.js +83 -3
  294. package/dist/panoramic/builders/component-view-builder.js.map +1 -1
  295. package/dist/panoramic/builders/doc-graph-builder.d.ts +15 -2
  296. package/dist/panoramic/builders/doc-graph-builder.d.ts.map +1 -1
  297. package/dist/panoramic/builders/doc-graph-builder.js +20 -0
  298. package/dist/panoramic/builders/doc-graph-builder.js.map +1 -1
  299. package/dist/panoramic/component-view-builder.d.ts +17 -0
  300. package/dist/panoramic/component-view-builder.d.ts.map +1 -0
  301. package/dist/panoramic/component-view-builder.js +652 -0
  302. package/dist/panoramic/component-view-builder.js.map +1 -0
  303. package/dist/panoramic/component-view-model.d.ts +127 -0
  304. package/dist/panoramic/component-view-model.d.ts.map +1 -0
  305. package/dist/panoramic/component-view-model.js +65 -0
  306. package/dist/panoramic/component-view-model.js.map +1 -0
  307. package/dist/panoramic/config-reference-generator.d.ts +78 -0
  308. package/dist/panoramic/config-reference-generator.d.ts.map +1 -0
  309. package/dist/panoramic/config-reference-generator.js +199 -0
  310. package/dist/panoramic/config-reference-generator.js.map +1 -0
  311. package/dist/panoramic/coverage-auditor.d.ts +95 -0
  312. package/dist/panoramic/coverage-auditor.d.ts.map +1 -0
  313. package/dist/panoramic/coverage-auditor.js +290 -0
  314. package/dist/panoramic/coverage-auditor.js.map +1 -0
  315. package/dist/panoramic/cross-package-analyzer.d.ts +112 -0
  316. package/dist/panoramic/cross-package-analyzer.d.ts.map +1 -0
  317. package/dist/panoramic/cross-package-analyzer.js +258 -0
  318. package/dist/panoramic/cross-package-analyzer.js.map +1 -0
  319. package/dist/panoramic/data-model-generator.d.ts +528 -0
  320. package/dist/panoramic/data-model-generator.d.ts.map +1 -0
  321. package/dist/panoramic/data-model-generator.js +647 -0
  322. package/dist/panoramic/data-model-generator.js.map +1 -0
  323. package/dist/panoramic/doc-graph-builder.d.ts +80 -0
  324. package/dist/panoramic/doc-graph-builder.d.ts.map +1 -0
  325. package/dist/panoramic/doc-graph-builder.js +352 -0
  326. package/dist/panoramic/doc-graph-builder.js.map +1 -0
  327. package/dist/panoramic/docs-bundle-manifest-reader.d.ts +26 -0
  328. package/dist/panoramic/docs-bundle-manifest-reader.d.ts.map +1 -0
  329. package/dist/panoramic/docs-bundle-manifest-reader.js +106 -0
  330. package/dist/panoramic/docs-bundle-manifest-reader.js.map +1 -0
  331. package/dist/panoramic/docs-bundle-orchestrator.d.ts +14 -0
  332. package/dist/panoramic/docs-bundle-orchestrator.d.ts.map +1 -0
  333. package/dist/panoramic/docs-bundle-orchestrator.js +538 -0
  334. package/dist/panoramic/docs-bundle-orchestrator.js.map +1 -0
  335. package/dist/panoramic/docs-bundle-profiles.d.ts +4 -0
  336. package/dist/panoramic/docs-bundle-profiles.d.ts.map +1 -0
  337. package/dist/panoramic/docs-bundle-profiles.js +82 -0
  338. package/dist/panoramic/docs-bundle-profiles.js.map +1 -0
  339. package/dist/panoramic/docs-bundle-types.d.ts +94 -0
  340. package/dist/panoramic/docs-bundle-types.d.ts.map +1 -0
  341. package/dist/panoramic/docs-bundle-types.js +10 -0
  342. package/dist/panoramic/docs-bundle-types.js.map +1 -0
  343. package/dist/panoramic/docs-quality-evaluator.d.ts +31 -0
  344. package/dist/panoramic/docs-quality-evaluator.d.ts.map +1 -0
  345. package/dist/panoramic/docs-quality-evaluator.js +941 -0
  346. package/dist/panoramic/docs-quality-evaluator.js.map +1 -0
  347. package/dist/panoramic/docs-quality-model.d.ts +125 -0
  348. package/dist/panoramic/docs-quality-model.d.ts.map +1 -0
  349. package/dist/panoramic/docs-quality-model.js +166 -0
  350. package/dist/panoramic/docs-quality-model.js.map +1 -0
  351. package/dist/panoramic/dynamic-scenarios-builder.d.ts +18 -0
  352. package/dist/panoramic/dynamic-scenarios-builder.d.ts.map +1 -0
  353. package/dist/panoramic/dynamic-scenarios-builder.js +316 -0
  354. package/dist/panoramic/dynamic-scenarios-builder.js.map +1 -0
  355. package/dist/panoramic/event-surface-generator.d.ts +52 -0
  356. package/dist/panoramic/event-surface-generator.d.ts.map +1 -0
  357. package/dist/panoramic/event-surface-generator.js +507 -0
  358. package/dist/panoramic/event-surface-generator.js.map +1 -0
  359. package/dist/panoramic/generator-registry.d.ts +1 -1
  360. package/dist/panoramic/generator-registry.d.ts.map +1 -1
  361. package/dist/panoramic/generator-registry.js +5 -2
  362. package/dist/panoramic/generator-registry.js.map +1 -1
  363. package/dist/panoramic/generators/cross-package-analyzer.d.ts +5 -5
  364. package/dist/panoramic/generators/cross-package-analyzer.d.ts.map +1 -1
  365. package/dist/panoramic/generators/cross-package-analyzer.js +1 -1
  366. package/dist/panoramic/generators/cross-package-analyzer.js.map +1 -1
  367. package/dist/panoramic/generators/data-model-generator.d.ts +27 -27
  368. package/dist/panoramic/graph/confidence-mapper.d.ts +18 -0
  369. package/dist/panoramic/graph/confidence-mapper.d.ts.map +1 -1
  370. package/dist/panoramic/graph/confidence-mapper.js +26 -0
  371. package/dist/panoramic/graph/confidence-mapper.js.map +1 -1
  372. package/dist/panoramic/graph/graph-builder.d.ts +72 -2
  373. package/dist/panoramic/graph/graph-builder.d.ts.map +1 -1
  374. package/dist/panoramic/graph/graph-builder.js +330 -46
  375. package/dist/panoramic/graph/graph-builder.js.map +1 -1
  376. package/dist/panoramic/graph/graph-paths.d.ts +8 -0
  377. package/dist/panoramic/graph/graph-paths.d.ts.map +1 -1
  378. package/dist/panoramic/graph/graph-paths.js +10 -0
  379. package/dist/panoramic/graph/graph-paths.js.map +1 -1
  380. package/dist/panoramic/graph/graph-query.d.ts +49 -2
  381. package/dist/panoramic/graph/graph-query.d.ts.map +1 -1
  382. package/dist/panoramic/graph/graph-query.js +117 -19
  383. package/dist/panoramic/graph/graph-query.js.map +1 -1
  384. package/dist/panoramic/graph/graph-types.d.ts +32 -3
  385. package/dist/panoramic/graph/graph-types.d.ts.map +1 -1
  386. package/dist/panoramic/graph/index.d.ts +2 -1
  387. package/dist/panoramic/graph/index.d.ts.map +1 -1
  388. package/dist/panoramic/graph/index.js +1 -1
  389. package/dist/panoramic/graph/index.js.map +1 -1
  390. package/dist/panoramic/hyperedges/schema.d.ts +6 -6
  391. package/dist/panoramic/interface-surface-generator.d.ts +50 -0
  392. package/dist/panoramic/interface-surface-generator.d.ts.map +1 -0
  393. package/dist/panoramic/interface-surface-generator.js +388 -0
  394. package/dist/panoramic/interface-surface-generator.js.map +1 -0
  395. package/dist/panoramic/interfaces.d.ts +2 -2
  396. package/dist/panoramic/mock-readme-generator.d.ts +90 -0
  397. package/dist/panoramic/mock-readme-generator.d.ts.map +1 -0
  398. package/dist/panoramic/mock-readme-generator.js +111 -0
  399. package/dist/panoramic/mock-readme-generator.js.map +1 -0
  400. package/dist/panoramic/models/component-view-model.d.ts +1 -1
  401. package/dist/panoramic/models/component-view-model.d.ts.map +1 -1
  402. package/dist/panoramic/models/component-view-model.js.map +1 -1
  403. package/dist/panoramic/narrative-provenance-adapter.d.ts +8 -0
  404. package/dist/panoramic/narrative-provenance-adapter.d.ts.map +1 -0
  405. package/dist/panoramic/narrative-provenance-adapter.js +99 -0
  406. package/dist/panoramic/narrative-provenance-adapter.js.map +1 -0
  407. package/dist/panoramic/parser-registry.d.ts +1 -1
  408. package/dist/panoramic/parser-registry.js +1 -1
  409. package/dist/panoramic/parsers/types.d.ts +6 -6
  410. package/dist/panoramic/pattern-hints-generator.d.ts +28 -0
  411. package/dist/panoramic/pattern-hints-generator.d.ts.map +1 -0
  412. package/dist/panoramic/pattern-hints-generator.js +218 -0
  413. package/dist/panoramic/pattern-hints-generator.js.map +1 -0
  414. package/dist/panoramic/pattern-hints-model.d.ts +89 -0
  415. package/dist/panoramic/pattern-hints-model.d.ts.map +1 -0
  416. package/dist/panoramic/pattern-hints-model.js +61 -0
  417. package/dist/panoramic/pattern-hints-model.js.map +1 -0
  418. package/dist/panoramic/pattern-knowledge-base.d.ts +31 -0
  419. package/dist/panoramic/pattern-knowledge-base.d.ts.map +1 -0
  420. package/dist/panoramic/pattern-knowledge-base.js +407 -0
  421. package/dist/panoramic/pattern-knowledge-base.js.map +1 -0
  422. package/dist/panoramic/pipelines/adr-evidence-verifier.d.ts.map +1 -1
  423. package/dist/panoramic/pipelines/adr-evidence-verifier.js +1 -29
  424. package/dist/panoramic/pipelines/adr-evidence-verifier.js.map +1 -1
  425. package/dist/panoramic/pipelines/coverage-auditor.d.ts.map +1 -1
  426. package/dist/panoramic/pipelines/coverage-auditor.js +4 -2
  427. package/dist/panoramic/pipelines/coverage-auditor.js.map +1 -1
  428. package/dist/panoramic/pipelines/docs-bundle-orchestrator.js +13 -6
  429. package/dist/panoramic/pipelines/docs-bundle-orchestrator.js.map +1 -1
  430. package/dist/panoramic/pipelines/product-ux-docs.d.ts +5 -0
  431. package/dist/panoramic/pipelines/product-ux-docs.d.ts.map +1 -1
  432. package/dist/panoramic/pipelines/product-ux-docs.js +34 -6
  433. package/dist/panoramic/pipelines/product-ux-docs.js.map +1 -1
  434. package/dist/panoramic/product-ux-docs.d.ts +104 -0
  435. package/dist/panoramic/product-ux-docs.d.ts.map +1 -0
  436. package/dist/panoramic/product-ux-docs.js +817 -0
  437. package/dist/panoramic/product-ux-docs.js.map +1 -0
  438. package/dist/panoramic/qa/__tests__/citation.test.d.ts +2 -0
  439. package/dist/panoramic/qa/__tests__/citation.test.d.ts.map +1 -0
  440. package/dist/panoramic/qa/__tests__/citation.test.js +193 -0
  441. package/dist/panoramic/qa/__tests__/citation.test.js.map +1 -0
  442. package/dist/panoramic/qa/__tests__/debt-context.test.d.ts +2 -0
  443. package/dist/panoramic/qa/__tests__/debt-context.test.d.ts.map +1 -0
  444. package/dist/panoramic/qa/__tests__/debt-context.test.js +154 -0
  445. package/dist/panoramic/qa/__tests__/debt-context.test.js.map +1 -0
  446. package/dist/panoramic/qa/__tests__/graph-retriever.test.d.ts +2 -0
  447. package/dist/panoramic/qa/__tests__/graph-retriever.test.d.ts.map +1 -0
  448. package/dist/panoramic/qa/__tests__/graph-retriever.test.js +148 -0
  449. package/dist/panoramic/qa/__tests__/graph-retriever.test.js.map +1 -0
  450. package/dist/panoramic/qa/__tests__/index.test.d.ts +2 -0
  451. package/dist/panoramic/qa/__tests__/index.test.d.ts.map +1 -0
  452. package/dist/panoramic/qa/__tests__/index.test.js +246 -0
  453. package/dist/panoramic/qa/__tests__/index.test.js.map +1 -0
  454. package/dist/panoramic/qa/__tests__/llm-caller.test.d.ts +2 -0
  455. package/dist/panoramic/qa/__tests__/llm-caller.test.d.ts.map +1 -0
  456. package/dist/panoramic/qa/__tests__/llm-caller.test.js +168 -0
  457. package/dist/panoramic/qa/__tests__/llm-caller.test.js.map +1 -0
  458. package/dist/panoramic/qa/__tests__/prompt-builder.test.d.ts +2 -0
  459. package/dist/panoramic/qa/__tests__/prompt-builder.test.d.ts.map +1 -0
  460. package/dist/panoramic/qa/__tests__/prompt-builder.test.js +150 -0
  461. package/dist/panoramic/qa/__tests__/prompt-builder.test.js.map +1 -0
  462. package/dist/panoramic/qa/__tests__/qa-integration.test.d.ts +2 -0
  463. package/dist/panoramic/qa/__tests__/qa-integration.test.d.ts.map +1 -0
  464. package/dist/panoramic/qa/__tests__/qa-integration.test.js +296 -0
  465. package/dist/panoramic/qa/__tests__/qa-integration.test.js.map +1 -0
  466. package/dist/panoramic/qa/__tests__/rag-reranker.test.d.ts +2 -0
  467. package/dist/panoramic/qa/__tests__/rag-reranker.test.d.ts.map +1 -0
  468. package/dist/panoramic/qa/__tests__/rag-reranker.test.js +136 -0
  469. package/dist/panoramic/qa/__tests__/rag-reranker.test.js.map +1 -0
  470. package/dist/panoramic/qa/index.d.ts.map +1 -1
  471. package/dist/panoramic/qa/index.js +10 -3
  472. package/dist/panoramic/qa/index.js.map +1 -1
  473. package/dist/panoramic/query.d.ts +1 -0
  474. package/dist/panoramic/query.d.ts.map +1 -1
  475. package/dist/panoramic/query.js +5 -0
  476. package/dist/panoramic/query.js.map +1 -1
  477. package/dist/panoramic/runtime-topology-generator.d.ts +77 -0
  478. package/dist/panoramic/runtime-topology-generator.d.ts.map +1 -0
  479. package/dist/panoramic/runtime-topology-generator.js +676 -0
  480. package/dist/panoramic/runtime-topology-generator.js.map +1 -0
  481. package/dist/panoramic/runtime-topology-model.d.ts +145 -0
  482. package/dist/panoramic/runtime-topology-model.d.ts.map +1 -0
  483. package/dist/panoramic/runtime-topology-model.js +300 -0
  484. package/dist/panoramic/runtime-topology-model.js.map +1 -0
  485. package/dist/panoramic/troubleshooting-generator.d.ts +51 -0
  486. package/dist/panoramic/troubleshooting-generator.d.ts.map +1 -0
  487. package/dist/panoramic/troubleshooting-generator.js +451 -0
  488. package/dist/panoramic/troubleshooting-generator.js.map +1 -0
  489. package/dist/panoramic/utils/text-segmenter.d.ts +15 -0
  490. package/dist/panoramic/utils/text-segmenter.d.ts.map +1 -1
  491. package/dist/panoramic/utils/text-segmenter.js +38 -0
  492. package/dist/panoramic/utils/text-segmenter.js.map +1 -1
  493. package/dist/panoramic/workspace-index-generator.d.ts +148 -0
  494. package/dist/panoramic/workspace-index-generator.d.ts.map +1 -0
  495. package/dist/panoramic/workspace-index-generator.js +497 -0
  496. package/dist/panoramic/workspace-index-generator.js.map +1 -0
  497. package/dist/runtime-bootstrap.d.ts +9 -0
  498. package/dist/runtime-bootstrap.d.ts.map +1 -0
  499. package/dist/runtime-bootstrap.js +33 -0
  500. package/dist/runtime-bootstrap.js.map +1 -0
  501. package/dist/scaffold-kb/api-entities-serializer.d.ts +12 -0
  502. package/dist/scaffold-kb/api-entities-serializer.d.ts.map +1 -0
  503. package/dist/scaffold-kb/api-entities-serializer.js +144 -0
  504. package/dist/scaffold-kb/api-entities-serializer.js.map +1 -0
  505. package/dist/scaffold-kb/arbitration.d.ts +44 -0
  506. package/dist/scaffold-kb/arbitration.d.ts.map +1 -0
  507. package/dist/scaffold-kb/arbitration.js +144 -0
  508. package/dist/scaffold-kb/arbitration.js.map +1 -0
  509. package/dist/scaffold-kb/chunk-splitter.d.ts +20 -0
  510. package/dist/scaffold-kb/chunk-splitter.d.ts.map +1 -0
  511. package/dist/scaffold-kb/chunk-splitter.js +309 -0
  512. package/dist/scaffold-kb/chunk-splitter.js.map +1 -0
  513. package/dist/scaffold-kb/doc-graph-builder.d.ts +26 -0
  514. package/dist/scaffold-kb/doc-graph-builder.d.ts.map +1 -0
  515. package/dist/scaffold-kb/doc-graph-builder.js +72 -0
  516. package/dist/scaffold-kb/doc-graph-builder.js.map +1 -0
  517. package/dist/scaffold-kb/entity-extractor.d.ts +40 -0
  518. package/dist/scaffold-kb/entity-extractor.d.ts.map +1 -0
  519. package/dist/scaffold-kb/entity-extractor.js +0 -0
  520. package/dist/scaffold-kb/entity-extractor.js.map +1 -0
  521. package/dist/scaffold-kb/entity-heuristic.d.ts +14 -0
  522. package/dist/scaffold-kb/entity-heuristic.d.ts.map +1 -0
  523. package/dist/scaffold-kb/entity-heuristic.js +107 -0
  524. package/dist/scaffold-kb/entity-heuristic.js.map +1 -0
  525. package/dist/scaffold-kb/entity-matcher.d.ts +20 -0
  526. package/dist/scaffold-kb/entity-matcher.d.ts.map +1 -0
  527. package/dist/scaffold-kb/entity-matcher.js +53 -0
  528. package/dist/scaffold-kb/entity-matcher.js.map +1 -0
  529. package/dist/scaffold-kb/entity-util.d.ts +11 -0
  530. package/dist/scaffold-kb/entity-util.d.ts.map +1 -0
  531. package/dist/scaffold-kb/entity-util.js +23 -0
  532. package/dist/scaffold-kb/entity-util.js.map +1 -0
  533. package/dist/scaffold-kb/evidence-envelope.d.ts +17 -0
  534. package/dist/scaffold-kb/evidence-envelope.d.ts.map +1 -0
  535. package/dist/scaffold-kb/evidence-envelope.js +32 -0
  536. package/dist/scaffold-kb/evidence-envelope.js.map +1 -0
  537. package/dist/scaffold-kb/index.d.ts +20 -0
  538. package/dist/scaffold-kb/index.d.ts.map +1 -0
  539. package/dist/scaffold-kb/index.js +102 -0
  540. package/dist/scaffold-kb/index.js.map +1 -0
  541. package/dist/scaffold-kb/ingest/ingest-core.d.ts +47 -0
  542. package/dist/scaffold-kb/ingest/ingest-core.d.ts.map +1 -0
  543. package/dist/scaffold-kb/ingest/ingest-core.js +231 -0
  544. package/dist/scaffold-kb/ingest/ingest-core.js.map +1 -0
  545. package/dist/scaffold-kb/ingest/office-parser.d.ts +33 -0
  546. package/dist/scaffold-kb/ingest/office-parser.d.ts.map +1 -0
  547. package/dist/scaffold-kb/ingest/office-parser.js +187 -0
  548. package/dist/scaffold-kb/ingest/office-parser.js.map +1 -0
  549. package/dist/scaffold-kb/ingest/url-fetcher.d.ts +43 -0
  550. package/dist/scaffold-kb/ingest/url-fetcher.d.ts.map +1 -0
  551. package/dist/scaffold-kb/ingest/url-fetcher.js +245 -0
  552. package/dist/scaffold-kb/ingest/url-fetcher.js.map +1 -0
  553. package/dist/scaffold-kb/ingester.d.ts +38 -0
  554. package/dist/scaffold-kb/ingester.d.ts.map +1 -0
  555. package/dist/scaffold-kb/ingester.js +261 -0
  556. package/dist/scaffold-kb/ingester.js.map +1 -0
  557. package/dist/scaffold-kb/injection-format.d.ts +25 -0
  558. package/dist/scaffold-kb/injection-format.d.ts.map +1 -0
  559. package/dist/scaffold-kb/injection-format.js +55 -0
  560. package/dist/scaffold-kb/injection-format.js.map +1 -0
  561. package/dist/scaffold-kb/kb-writer.d.ts +13 -0
  562. package/dist/scaffold-kb/kb-writer.d.ts.map +1 -0
  563. package/dist/scaffold-kb/kb-writer.js +69 -0
  564. package/dist/scaffold-kb/kb-writer.js.map +1 -0
  565. package/dist/scaffold-kb/keyword-extract.d.ts +16 -0
  566. package/dist/scaffold-kb/keyword-extract.d.ts.map +1 -0
  567. package/dist/scaffold-kb/keyword-extract.js +49 -0
  568. package/dist/scaffold-kb/keyword-extract.js.map +1 -0
  569. package/dist/scaffold-kb/query-sanitizer.d.ts +28 -0
  570. package/dist/scaffold-kb/query-sanitizer.d.ts.map +1 -0
  571. package/dist/scaffold-kb/query-sanitizer.js +38 -0
  572. package/dist/scaffold-kb/query-sanitizer.js.map +1 -0
  573. package/dist/scaffold-kb/recall-eval.d.ts +48 -0
  574. package/dist/scaffold-kb/recall-eval.d.ts.map +1 -0
  575. package/dist/scaffold-kb/recall-eval.js +55 -0
  576. package/dist/scaffold-kb/recall-eval.js.map +1 -0
  577. package/dist/scaffold-kb/schema-compat.d.ts +22 -0
  578. package/dist/scaffold-kb/schema-compat.d.ts.map +1 -0
  579. package/dist/scaffold-kb/schema-compat.js +32 -0
  580. package/dist/scaffold-kb/schema-compat.js.map +1 -0
  581. package/dist/scaffold-kb/search-core.d.ts +42 -0
  582. package/dist/scaffold-kb/search-core.d.ts.map +1 -0
  583. package/dist/scaffold-kb/search-core.js +89 -0
  584. package/dist/scaffold-kb/search-core.js.map +1 -0
  585. package/dist/scaffold-kb/sqlite-engine.d.ts +58 -0
  586. package/dist/scaffold-kb/sqlite-engine.d.ts.map +1 -0
  587. package/dist/scaffold-kb/sqlite-engine.js +61 -0
  588. package/dist/scaffold-kb/sqlite-engine.js.map +1 -0
  589. package/dist/scaffold-kb/sqlite-writer.d.ts +18 -0
  590. package/dist/scaffold-kb/sqlite-writer.d.ts.map +1 -0
  591. package/dist/scaffold-kb/sqlite-writer.js +76 -0
  592. package/dist/scaffold-kb/sqlite-writer.js.map +1 -0
  593. package/dist/scaffold-kb/tokenizer.d.ts +26 -0
  594. package/dist/scaffold-kb/tokenizer.d.ts.map +1 -0
  595. package/dist/scaffold-kb/tokenizer.js +97 -0
  596. package/dist/scaffold-kb/tokenizer.js.map +1 -0
  597. package/dist/scaffold-kb/types.d.ts +157 -0
  598. package/dist/scaffold-kb/types.d.ts.map +1 -0
  599. package/dist/scaffold-kb/types.js +5 -0
  600. package/dist/scaffold-kb/types.js.map +1 -0
  601. package/dist/utils/file-scanner.d.ts +15 -0
  602. package/dist/utils/file-scanner.d.ts.map +1 -1
  603. package/dist/utils/file-scanner.js +18 -1
  604. package/dist/utils/file-scanner.js.map +1 -1
  605. package/dist/utils/string-distance.d.ts +20 -0
  606. package/dist/utils/string-distance.d.ts.map +1 -0
  607. package/dist/utils/string-distance.js +38 -0
  608. package/dist/utils/string-distance.js.map +1 -0
  609. package/package.json +22 -3
  610. package/plugins/demo-kb-en/.claude-plugin/plugin.json +11 -0
  611. package/plugins/demo-kb-en/.mcp.json +8 -0
  612. package/plugins/demo-kb-en/FIXTURE.json +23 -0
  613. package/plugins/demo-kb-en/FIXTURE.md +53 -0
  614. package/plugins/demo-kb-en/ingest-samples/meeting-notes.md +13 -0
  615. package/plugins/demo-kb-en/kb/api-entities.json +3445 -0
  616. package/plugins/demo-kb-en/kb/chunks.sqlite +0 -0
  617. package/plugins/demo-kb-en/kb/doc-graph.json +113 -0
  618. package/plugins/demo-kb-zh/.claude-plugin/plugin.json +11 -0
  619. package/plugins/demo-kb-zh/.mcp.json +8 -0
  620. package/plugins/demo-kb-zh/FIXTURE.json +23 -0
  621. package/plugins/demo-kb-zh/FIXTURE.md +63 -0
  622. package/plugins/demo-kb-zh/ingest-samples/meeting-notes.md +13 -0
  623. package/plugins/demo-kb-zh/kb/api-entities.json +990 -0
  624. package/plugins/demo-kb-zh/kb/chunks.sqlite +0 -0
  625. package/plugins/demo-kb-zh/kb/doc-graph.json +113 -0
  626. package/plugins/spec-driver/.claude-plugin/plugin.json +1 -1
  627. package/plugins/spec-driver/README.md +50 -1
  628. package/plugins/spec-driver/agents/implement.md +20 -1
  629. package/plugins/spec-driver/agents/plan.md +20 -1
  630. package/plugins/spec-driver/agents/quality-review.md +20 -1
  631. package/plugins/spec-driver/agents/spec-review.md +20 -1
  632. package/plugins/spec-driver/agents/verify.md +108 -1
  633. package/plugins/spec-driver/config/orchestration.yaml +39 -31
  634. package/plugins/spec-driver/contracts/orchestration-overrides-contract.yaml +27 -0
  635. package/plugins/spec-driver/contracts/orchestration-schema.mjs +272 -227
  636. package/plugins/spec-driver/contracts/wrapper-source-of-truth.yaml +3 -0
  637. package/plugins/spec-driver/docs/customization.md +134 -0
  638. package/plugins/spec-driver/docs/spectra-mcp-integration.md +165 -0
  639. package/plugins/spec-driver/hooks/hooks.json +9 -0
  640. package/plugins/spec-driver/hooks/stop-fix-compliance-check.sh +36 -0
  641. package/plugins/spec-driver/lib/delegation-contract.mjs +84 -0
  642. package/plugins/spec-driver/lib/orchestration-resolver.mjs +49 -0
  643. package/plugins/spec-driver/lib/orchestrator.mjs +29 -1
  644. package/plugins/spec-driver/lib/preference-rules.mjs +96 -0
  645. package/plugins/spec-driver/scripts/codex-skills.sh +28 -28
  646. package/plugins/spec-driver/scripts/dev/spike-fix-compliance-e2e.mjs +130 -0
  647. package/plugins/spec-driver/scripts/fix-compliance-judge.mjs +415 -0
  648. package/plugins/spec-driver/scripts/generate-adoption-insights.mjs +48 -1
  649. package/plugins/spec-driver/scripts/goal-loop-cli.mjs +307 -0
  650. package/plugins/spec-driver/scripts/init-project.sh +56 -0
  651. package/plugins/spec-driver/scripts/kb-prequery.mjs +125 -0
  652. package/plugins/spec-driver/scripts/lib/config-schema.mjs +200 -94
  653. package/plugins/spec-driver/scripts/lib/ensure-gitignore.sh +277 -0
  654. package/plugins/spec-driver/scripts/lib/extract-wrapper-body.mjs +136 -0
  655. package/plugins/spec-driver/scripts/lib/fix-compliance-core.mjs +434 -0
  656. package/plugins/spec-driver/scripts/lib/fix-compliance-io.mjs +335 -0
  657. package/plugins/spec-driver/scripts/lib/goal-loop-core.mjs +783 -0
  658. package/plugins/spec-driver/scripts/lib/init-project-output.sh +28 -0
  659. package/plugins/spec-driver/scripts/lib/load-zod.mjs +62 -0
  660. package/plugins/spec-driver/scripts/lib/project-profile-resolver.mjs +141 -49
  661. package/plugins/spec-driver/scripts/lib/project-profile-schema.mjs +88 -54
  662. package/plugins/spec-driver/scripts/postinstall.sh +13 -1
  663. package/plugins/spec-driver/scripts/record-workflow-run.mjs +75 -0
  664. package/plugins/spec-driver/scripts/sync-delegation-contract.mjs +187 -0
  665. package/plugins/spec-driver/scripts/sync-preference-rules.mjs +148 -0
  666. package/plugins/spec-driver/scripts/validate-orchestrator-models.mjs +156 -0
  667. package/plugins/spec-driver/scripts/validate-wrapper-sources.mjs +46 -1
  668. package/plugins/spec-driver/skills/spec-driver-feature/SKILL.md +302 -0
  669. package/plugins/spec-driver/skills/spec-driver-fix/SKILL.md +97 -8
  670. package/plugins/spec-driver/skills/spec-driver-implement/SKILL.md +18 -0
  671. package/plugins/spec-driver/skills/spec-driver-refactor/SKILL.md +10 -0
  672. package/plugins/spec-driver/skills/spec-driver-resume/SKILL.md +12 -1
  673. package/plugins/spec-driver/skills/spec-driver-story/SKILL.md +30 -0
  674. package/plugins/spec-driver/templates/delegation-contract.md +27 -0
  675. package/plugins/spec-driver/templates/goal-loop-override-template.yaml +284 -0
  676. package/plugins/spec-driver/templates/preference-rules.md +39 -0
  677. package/plugins/spec-driver/templates/specify-base/project-context-template.yaml +10 -0
  678. package/plugins/spectra/.claude-plugin/plugin.json +1 -1
  679. package/plugins/spectra/README.md +48 -1
  680. package/plugins/spectra/hooks/post-commit.sh +40 -0
  681. package/templates/module-spec.hbs +1 -0
  682. package/templates/product-overview.hbs +1 -1
@@ -18,6 +18,14 @@ import { readJsonArtifact, writeJsonArtifact, writeMarkdownArtifact } from './li
18
18
  const SCHEMA_VERSION = 1;
19
19
  const PRODUCT_ID = 'spec-driver';
20
20
 
21
+ /**
22
+ * 已知的非 summary 事件类型白名单(Feature 208,data-model.md §9)。
23
+ * 这些事件与 workflow-run-summary 共存于同一 .specify/runs/*.jsonl,但不参与 adoption 统计。
24
+ * why 需要白名单:normalizeRunEvent 对非 summary 行返回 null → 原逻辑会计入 invalidLineCount 并
25
+ * 产生"忽略无效 run event"warning,污染 adoption 报告 invalid 统计。白名单命中者静默 skip。
26
+ */
27
+ const KNOWN_NON_SUMMARY_EVENT_TYPES = new Set(['fix-compliance-verdict']);
28
+
21
29
  function parseArgs(argv) {
22
30
  const args = {
23
31
  projectRoot: process.cwd(),
@@ -126,6 +134,10 @@ function readRunLogs(projectRoot) {
126
134
  const line = lines[index];
127
135
  try {
128
136
  const parsed = JSON.parse(line);
137
+ // 已知非 summary 事件类型(如 fix-compliance-verdict)静默 skip:不计 invalid、不产生 warning
138
+ if (isObject(parsed) && KNOWN_NON_SUMMARY_EVENT_TYPES.has(parsed.eventType)) {
139
+ continue;
140
+ }
129
141
  const normalized = normalizeRunEvent(parsed);
130
142
  if (normalized) {
131
143
  events.push(normalized);
@@ -181,12 +193,47 @@ function normalizeRunEvent(entry) {
181
193
  };
182
194
  }
183
195
 
196
+ // 同一 (workflowId, runId) 可能出现多条终态事件:Feature 211 的 compliant-reset 语义下,
197
+ // 同一 session 后续再次耗尽额度降级会重写 workflow-run-summary 终态事件(每个"阻断周期"一条)。
198
+ // JSONL 是 append-only 审计日志,原始事件全部保留;此处仅在统计聚合前按 (workflowId, runId)
199
+ // 去重,取时间最晚的一条作为该 run 的最终结果,避免同一 run 被重复计入 totalRuns 等指标。
200
+ // runId 缺失的事件在 normalizeRunEvent 阶段已被判为无效(不进入本函数),故无需在此特殊处理。
201
+ function dedupeRunEvents(events) {
202
+ const latestByRun = new Map();
203
+ const order = [];
204
+ for (const event of events) {
205
+ const key = `${event.workflowId}\u0000${event.runId}`;
206
+ const existing = latestByRun.get(key);
207
+ if (!existing) {
208
+ latestByRun.set(key, event);
209
+ order.push(key);
210
+ continue;
211
+ }
212
+ // 时间可比时取更晚者;时间相等或缺失时取文件内后出现者(append-only 天然有序)
213
+ const newMs = eventRecencyMs(event);
214
+ const existingMs = eventRecencyMs(existing);
215
+ if (newMs === null || existingMs === null || newMs >= existingMs) {
216
+ latestByRun.set(key, event);
217
+ }
218
+ }
219
+ return order.map((key) => latestByRun.get(key));
220
+ }
221
+
222
+ // 终态事件的"新近度":取 recordedAt / finishedAt 中可解析的最晚时间戳(ms),均缺失则返回 null
223
+ function eventRecencyMs(event) {
224
+ const candidates = [event.recordedAt, event.finishedAt]
225
+ .map((value) => (value ? Date.parse(value) : Number.NaN))
226
+ .filter((value) => !Number.isNaN(value));
227
+ return candidates.length > 0 ? Math.max(...candidates) : null;
228
+ }
229
+
184
230
  function calculateMetrics(events, workflowDefs) {
185
231
  const workflowMap = new Map(
186
232
  (Array.isArray(workflowDefs) ? workflowDefs : [])
187
233
  .filter((workflow) => isObject(workflow) && typeof workflow.id === 'string')
188
234
  .map((workflow) => [workflow.id, workflow]),
189
235
  );
236
+ const dedupedEvents = dedupeRunEvents(events);
190
237
  const grouped = new Map();
191
238
  const rerunPhaseCounts = new Map();
192
239
  const gatePauseCounts = new Map();
@@ -194,7 +241,7 @@ function calculateMetrics(events, workflowDefs) {
194
241
  const phaseDurationCounts = new Map();
195
242
  let runsWithPhaseDurations = 0;
196
243
 
197
- for (const event of events) {
244
+ for (const event of dedupedEvents) {
198
245
  if (!grouped.has(event.workflowId)) {
199
246
  grouped.set(event.workflowId, []);
200
247
  }
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * goal-loop-cli.mjs
5
+ * Feature 201 — goal_loop core 的薄 CLI 包装(仿 orchestrator-cli.mjs)
6
+ *
7
+ * 设计契约(plan §1.1 / tasks T018,修正 Codex C-02):
8
+ * 所有"需要复杂结构输入"的子命令一律接受**单个 JSON payload**(文件路径),
9
+ * 输出 JSON 到 stdout;简单标量子命令用位置参数。SKILL.md 散文必须按本契约调用。
10
+ *
11
+ * 用法:
12
+ * node goal-loop-cli.mjs parse-report <reportJsonFile>
13
+ * node goal-loop-cli.mjs classify-command <cmdJsonFile>
14
+ * node goal-loop-cli.mjs decide-stop <payloadJsonFile> # payload={report,round,config,prevReports,rollbackResult}
15
+ * node goal-loop-cli.mjs plan-snapshot <isClean:true|false>
16
+ * node goal-loop-cli.mjs plan-rollback <snapshotJsonFile> # snapshot={clean,ref}
17
+ * node goal-loop-cli.mjs select-verify-mode <round> <max> <aboutToExit:true|false>
18
+ * node goal-loop-cli.mjs decide-dispatch <phaseId> <agentMode>
19
+ * node goal-loop-cli.mjs interpret-impact <mcpResultJsonFile>
20
+ * node goal-loop-cli.mjs format-iteration-log-entry <entryJsonFile> # 输出 markdown 块到 stdout
21
+ * node goal-loop-cli.mjs assess-preserved-config-safety <porcelainFile|-(stdin)>
22
+ * # 输入 = `git status --porcelain --untracked-files=all -- <PRESERVED_CONFIG_PATHSPECS>` 原始 stdout
23
+ * # (MUST 带 --untracked-files=all:避免 untracked 目录折叠成 `?? .specify/` 漏检 preserved 文件)
24
+ * # CLI 内部 parsePreservedConfigStates(porcelain, PRESERVED_CONFIG_PATHSPECS) → assessPreservedConfigSafety
25
+ * node goal-loop-cli.mjs is-clean-excluding-preserved <porcelainFile|-(stdin)>
26
+ * # 输入 = **全仓** `git status --porcelain --untracked-files=all` 原始 stdout(不带 -- pathspec)
27
+ * # (MUST 带 --untracked-files=all:默认会把 untracked 目录折叠成 `?? .specify/`,折叠形式喂入
28
+ * # 会使 isClean 误判 false → 空 stash 抓无关旧 stash,CRITICAL-7 漏网根因)
29
+ * # 输出 {isClean:boolean}:排除 PRESERVED_CONFIG_PATHSPECS 后是否干净(F203 CRITICAL-7)
30
+ * node goal-loop-cli.mjs acquire-lock <lockPath>
31
+ * node goal-loop-cli.mjs release-lock <lockPath>
32
+ */
33
+
34
+ import fs from 'node:fs';
35
+ import { fileURLToPath } from 'node:url';
36
+ import {
37
+ classifyCommand,
38
+ decideStop,
39
+ decideDispatch,
40
+ selectVerifyMode,
41
+ planSnapshotCommands,
42
+ planRollbackCommands,
43
+ parseReport,
44
+ interpretImpactResult,
45
+ formatIterationLogEntry,
46
+ assessPreservedConfigSafety,
47
+ parsePreservedConfigStates,
48
+ isCleanExcludingPreserved,
49
+ PRESERVED_CONFIG_PATHSPECS,
50
+ } from './lib/goal-loop-core.mjs';
51
+
52
+ // ──────────────────────────────────────────────────────────────────────────
53
+ // I/O 边界:单实例文件锁(FR-018)—— 非纯函数,故放 CLI 不放纯 core
54
+ // ──────────────────────────────────────────────────────────────────────────
55
+
56
+ /**
57
+ * 写锁 payload 到已打开的 fd 并关闭
58
+ * @param {number} fd
59
+ */
60
+ function writeLockPayload(fd) {
61
+ const payload = JSON.stringify({ pid: process.pid, start_time: new Date().toISOString() });
62
+ try {
63
+ fs.writeSync(fd, payload);
64
+ } finally {
65
+ fs.closeSync(fd);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * 判定现有锁是否为 stale(仅当持锁进程已不存在 或 锁内容损坏)(Codex W3 / Phase B 复审修正)
71
+ *
72
+ * 关键不变量(FR-018 单实例保证):**持锁 PID 存活时永不视为 stale**,无论锁多老。
73
+ * 早期版本曾用 TTL(30min)兜底接管"超龄但存活"的锁,但真实 goal_loop 跑满
74
+ * max_iterations × max_verify_seconds 很容易超 30min,会导致新实例强抢活锁、破坏单实例保证。
75
+ * 因此移除 TTL 接管路径:接管只发生在"持有者证明已死"或"锁文件损坏无法证明存活"两种情况。
76
+ *
77
+ * 已知罕见残留:PID 复用——死 goal_loop 的 PID 被无关进程复用后,process.kill(pid,0) 误判存活,
78
+ * 锁将无法自动接管,需人工清理 .lock 文件。我们接受这个罕见 case,不引入 TTL 接管活锁的
79
+ * 更大风险(误杀正在跑的长任务)来换取它。
80
+ * @param {string} lockPath
81
+ * @returns {{ stale: boolean, holderPid: number|null, reason: string }}
82
+ */
83
+ function inspectLock(lockPath) {
84
+ let payload;
85
+ try {
86
+ payload = JSON.parse(fs.readFileSync(lockPath, 'utf-8'));
87
+ } catch {
88
+ // 锁内容损坏/不可解析 → 无法证明持有者存活,视为 stale 可接管
89
+ return { stale: true, holderPid: null, reason: 'lock_payload_unreadable' };
90
+ }
91
+ const holderPid = typeof payload.pid === 'number' ? payload.pid : null;
92
+
93
+ // 进程存活探测:process.kill(pid, 0) 不发信号,仅校验进程存在;ESRCH = 进程不存在
94
+ if (holderPid !== null) {
95
+ try {
96
+ process.kill(holderPid, 0);
97
+ } catch (err) {
98
+ if (err.code === 'ESRCH') {
99
+ return { stale: true, holderPid, reason: 'holder_process_gone' };
100
+ }
101
+ // EPERM = 进程存在但无权限发信号 → 持有者存活(保守),非 stale
102
+ }
103
+ } else {
104
+ // payload 缺合法 pid 字段 → 无法证明存活,视为 stale 可接管
105
+ return { stale: true, holderPid: null, reason: 'lock_payload_unreadable' };
106
+ }
107
+
108
+ // 走到这里:holderPid 存活(kill 未抛 ESRCH)→ 永不接管,无论锁龄
109
+ return { stale: false, holderPid, reason: 'holder_alive' };
110
+ }
111
+
112
+ /**
113
+ * 单实例文件锁:以 O_EXCL 原子创建 .lock(FR-018)
114
+ *
115
+ * stale 恢复(Codex W3 / Phase B 复审修正):遇 EEXIST 时校验现有锁——仅当持锁进程不存在(ESRCH)
116
+ * 或锁文件损坏无法证明持有者存活时,原子清理 stale 锁后重试一次获取;否则(持有者存活)返回
117
+ * lock_exists(含 holder pid)。不再用 TTL 接管"超龄但存活"的活锁(见 inspectLock 注释)。
118
+ * @param {string} lockPath
119
+ * @returns {{ acquired: true }|{ acquired: false, reason: string, holderPid?: number|null }}
120
+ */
121
+ export function acquireLock(lockPath) {
122
+ let fd;
123
+ try {
124
+ // 'wx' = O_CREAT | O_EXCL | O_WRONLY:文件已存在则抛 EEXIST(原子,防竞态)
125
+ fd = fs.openSync(lockPath, 'wx');
126
+ } catch (err) {
127
+ if (err.code === 'EEXIST') {
128
+ const info = inspectLock(lockPath);
129
+ if (!info.stale) {
130
+ return { acquired: false, reason: 'lock_exists', holderPid: info.holderPid };
131
+ }
132
+ // stale 锁:原子清理后重试一次获取。
133
+ // 用第二个 'wx' 而非先 unlink 再 open,避免清理与重建之间的竞态(仅重试一次防活锁)。
134
+ try {
135
+ fs.unlinkSync(lockPath);
136
+ } catch (unlinkErr) {
137
+ if (unlinkErr.code !== 'ENOENT') throw unlinkErr;
138
+ // ENOENT:他人已抢先清理,继续尝试创建
139
+ }
140
+ try {
141
+ fd = fs.openSync(lockPath, 'wx');
142
+ } catch (retryErr) {
143
+ if (retryErr.code === 'EEXIST') {
144
+ // 清理后被其他进程抢占 → 让对方持有,返回 lock_exists
145
+ const after = inspectLock(lockPath);
146
+ return { acquired: false, reason: 'lock_exists', holderPid: after.holderPid };
147
+ }
148
+ throw retryErr;
149
+ }
150
+ writeLockPayload(fd);
151
+ return { acquired: true };
152
+ }
153
+ throw err;
154
+ }
155
+ writeLockPayload(fd);
156
+ return { acquired: true };
157
+ }
158
+
159
+ /**
160
+ * 释放单实例文件锁(FR-018)
161
+ * @param {string} lockPath
162
+ * @returns {{ released: boolean }}
163
+ */
164
+ export function releaseLock(lockPath) {
165
+ try {
166
+ fs.unlinkSync(lockPath);
167
+ } catch (err) {
168
+ if (err.code === 'ENOENT') {
169
+ // 锁不存在视为已释放(幂等)
170
+ return { released: true };
171
+ }
172
+ throw err;
173
+ }
174
+ return { released: true };
175
+ }
176
+
177
+ // ──────────────────────────────────────────────────────────────────────────
178
+ // CLI dispatch
179
+ // ──────────────────────────────────────────────────────────────────────────
180
+
181
+ function output(data) {
182
+ console.log(JSON.stringify(data, null, 2));
183
+ }
184
+
185
+ function fail(message) {
186
+ console.error(JSON.stringify({ success: false, error: message }, null, 2));
187
+ process.exit(1);
188
+ }
189
+
190
+ function readJsonFile(filePath) {
191
+ if (!filePath) {
192
+ fail('缺少 JSON payload 文件路径参数');
193
+ }
194
+ return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
195
+ }
196
+
197
+ /** 同步读取 stdin(fd 0)全部内容为 UTF-8 文本 */
198
+ function readStdin() {
199
+ return fs.readFileSync(0, 'utf-8');
200
+ }
201
+
202
+ function parseBool(value, name) {
203
+ if (value === 'true') return true;
204
+ if (value === 'false') return false;
205
+ fail(`参数 ${name} 必须为 true|false,实际为 "${value}"`);
206
+ }
207
+
208
+ function main(argv) {
209
+ const [subcommand, ...args] = argv;
210
+
211
+ switch (subcommand) {
212
+ case 'parse-report': {
213
+ // parseReport 接受原始文本(含可能非法 JSON),故直接读文本不预解析
214
+ const filePath = args[0];
215
+ if (!filePath) fail('parse-report 需要 <reportJsonFile>');
216
+ const text = fs.readFileSync(filePath, 'utf-8');
217
+ output(parseReport(text));
218
+ break;
219
+ }
220
+ case 'classify-command': {
221
+ output({ status: classifyCommand(readJsonFile(args[0])) });
222
+ break;
223
+ }
224
+ case 'decide-stop': {
225
+ const payload = readJsonFile(args[0]);
226
+ output(
227
+ decideStop({
228
+ report: payload.report,
229
+ round: payload.round,
230
+ config: payload.config,
231
+ prevReports: payload.prevReports ?? [],
232
+ rollbackResult: payload.rollbackResult ?? null,
233
+ }),
234
+ );
235
+ break;
236
+ }
237
+ case 'plan-snapshot': {
238
+ output({ commands: planSnapshotCommands(parseBool(args[0], 'isClean')) });
239
+ break;
240
+ }
241
+ case 'plan-rollback': {
242
+ output({ commands: planRollbackCommands(readJsonFile(args[0])) });
243
+ break;
244
+ }
245
+ case 'select-verify-mode': {
246
+ const round = Number(args[0]);
247
+ const max = Number(args[1]);
248
+ const aboutToExit = parseBool(args[2], 'aboutToExit');
249
+ if (Number.isNaN(round) || Number.isNaN(max)) {
250
+ fail('select-verify-mode 需要数字 <round> <max>');
251
+ }
252
+ output({ mode: selectVerifyMode(round, max, aboutToExit) });
253
+ break;
254
+ }
255
+ case 'decide-dispatch': {
256
+ if (args.length < 2) fail('decide-dispatch 需要 <phaseId> <agentMode>');
257
+ output(decideDispatch(args[0], args[1]));
258
+ break;
259
+ }
260
+ case 'interpret-impact': {
261
+ output(interpretImpactResult(readJsonFile(args[0])));
262
+ break;
263
+ }
264
+ case 'format-iteration-log-entry': {
265
+ // 输出 markdown 块(含内嵌 ```json 围栏)到 stdout,供编排器直接追加写入 iteration-log.md。
266
+ // 与其它子命令不同:本子命令输出原始 markdown 文本,而非 JSON.stringify 包裹(散文直接拼日志)。
267
+ if (!args[0]) fail('format-iteration-log-entry 需要 <entryJsonFile>');
268
+ process.stdout.write(formatIterationLogEntry(readJsonFile(args[0])));
269
+ break;
270
+ }
271
+ case 'assess-preserved-config-safety': {
272
+ // 吃原始 `git status --porcelain` 文本(解析在 core,编排器零解析):
273
+ // porcelain → state 由 parsePreservedConfigStates;state → 安全 由 assessPreservedConfigSafety。
274
+ if (!args[0]) fail('assess-preserved-config-safety 需要 <porcelainFile|-(stdin)>');
275
+ const porcelain = args[0] === '-' ? readStdin() : fs.readFileSync(args[0], 'utf-8');
276
+ const entries = parsePreservedConfigStates(porcelain, PRESERVED_CONFIG_PATHSPECS);
277
+ output(assessPreservedConfigSafety(entries));
278
+ break;
279
+ }
280
+ case 'is-clean-excluding-preserved': {
281
+ // 吃**全仓** `git status --porcelain` 文本(不带 pathspec),排除 PRESERVED_CONFIG_PATHSPECS
282
+ // 后判 isClean——杜绝"唯一 dirty 是 preserved override 却按全仓判 false → 空 stash 抓无关旧
283
+ // stash"的 CRITICAL-7 危险路径。解析全在已单测 core。
284
+ if (!args[0]) fail('is-clean-excluding-preserved 需要 <porcelainFile|-(stdin)>');
285
+ const porcelainAll = args[0] === '-' ? readStdin() : fs.readFileSync(args[0], 'utf-8');
286
+ output({ isClean: isCleanExcludingPreserved(porcelainAll, PRESERVED_CONFIG_PATHSPECS) });
287
+ break;
288
+ }
289
+ case 'acquire-lock': {
290
+ if (!args[0]) fail('acquire-lock 需要 <lockPath>');
291
+ output(acquireLock(args[0]));
292
+ break;
293
+ }
294
+ case 'release-lock': {
295
+ if (!args[0]) fail('release-lock 需要 <lockPath>');
296
+ output(releaseLock(args[0]));
297
+ break;
298
+ }
299
+ default:
300
+ fail(`未知子命令: ${subcommand ?? '(空)'}`);
301
+ }
302
+ }
303
+
304
+ // 仅当作为入口脚本直接运行时执行 dispatch(被 import 时不触发,便于单测)
305
+ if (process.argv[1] && fileURLToPath(import.meta.url) === fs.realpathSync(process.argv[1])) {
306
+ main(process.argv.slice(2));
307
+ }
@@ -46,6 +46,7 @@ ALT_CONFIG_FILE="${SPECIFY_DIR}/spec-driver.config.yaml"
46
46
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
47
47
  PLUGIN_DIR="$(dirname "$SCRIPT_DIR")"
48
48
  source "${SCRIPT_DIR}/lib/init-project-output.sh"
49
+ source "${SCRIPT_DIR}/lib/ensure-gitignore.sh"
49
50
  SPECIFY_BASE_TEMPLATES_DIR="${PLUGIN_DIR}/templates/specify-base"
50
51
  FALLBACK_SPECIFY_TEMPLATES_DIR="${PLUGIN_DIR}/../../.specify/templates"
51
52
  DEFAULT_SCORECARD_DIR="${PLUGIN_DIR}/scorecards"
@@ -291,8 +292,63 @@ detect_spec_driver_skills() {
291
292
  fi
292
293
  }
293
294
 
295
+ # 步骤 1a: 确保 Spec Driver 落盘产物的 ignore 规则就位(Feature 207,分层防线)
296
+ # 分两条防线:
297
+ # (1) .git/info/exclude — 非 tracked 的主防线(零 diff 污染),仅 .git 为目录时执行
298
+ # (2) .gitignore — 团队共享配置(.git/info/exclude 无法共享的兜底,覆盖 worktree/非 git 场景)
299
+ # 防御:吞掉共享库的非零返回(极端只读文件系统等),只记录信号,绝不 exit 中断初始化
300
+ ensure_gitignore_step() {
301
+ # 主防线:.git/info/exclude(非 git / worktree 场景返回 skipped)
302
+ local exclude_result
303
+ exclude_result="$(ensure_spec_driver_git_exclude "$PROJECT_ROOT")" || {
304
+ INIT_RESULTS+=("git_exclude:skip_error")
305
+ exclude_result="__handled__"
306
+ }
307
+ if [[ "$exclude_result" != "__handled__" ]]; then
308
+ case "$exclude_result" in
309
+ created:*) INIT_RESULTS+=("git_exclude:created:${exclude_result#created:}") ;;
310
+ appended:*) INIT_RESULTS+=("git_exclude:injected:${exclude_result#appended:}") ;;
311
+ ready:*) INIT_RESULTS+=("git_exclude:ready") ;;
312
+ failed:*) INIT_RESULTS+=("git_exclude:skip_error") ;;
313
+ skipped:*) INIT_RESULTS+=("git_exclude:skipped") ;;
314
+ *) INIT_RESULTS+=("git_exclude:unknown") ;;
315
+ esac
316
+ fi
317
+
318
+ # 兜底防线:.gitignore(团队共享配置)
319
+ local result
320
+ result="$(ensure_spec_driver_gitignore "$PROJECT_ROOT")" || {
321
+ INIT_RESULTS+=("gitignore:skip_error")
322
+ return 0
323
+ }
324
+
325
+ case "$result" in
326
+ created:*)
327
+ INIT_RESULTS+=("gitignore:created:${result#created:}")
328
+ ;;
329
+ appended:*)
330
+ INIT_RESULTS+=("gitignore:injected:${result#appended:}")
331
+ ;;
332
+ ready:*)
333
+ INIT_RESULTS+=("gitignore:ready")
334
+ ;;
335
+ failed:*)
336
+ # 写入失败(只读 FS 等)→ 复用既有 skip_error 文本分支
337
+ INIT_RESULTS+=("gitignore:skip_error")
338
+ ;;
339
+ skipped:*)
340
+ # 并发会话持锁 → 本次跳过检查,下次会话自然补齐(不等同 ready,勿撒谎为已就位)
341
+ INIT_RESULTS+=("gitignore:lock_skipped")
342
+ ;;
343
+ *)
344
+ INIT_RESULTS+=("gitignore:unknown")
345
+ ;;
346
+ esac
347
+ }
348
+
294
349
  run_init_checks() {
295
350
  init_specify_dir
351
+ ensure_gitignore_step
296
352
  sync_specify_templates
297
353
  sync_scorecard_defaults
298
354
  ensure_project_context
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * F191 kb-prequery — spec-driver 编排器在 specify 阶段前的 KB 预查(确定性脚本)。
4
+ *
5
+ * 读 resolved knowledge_sources → bin 发现 + 能力探测 → shell out `spectra scaffold-kb query`
6
+ * → 注入块透传 stdout。退出**始终 0**(不阻断 spec-driver 流程);降级原因写 stderr。
7
+ * keyword 提取 / 检索 / 格式化 / 字符 cap 全在 spectra query 侧(本脚本只薄编排)。
8
+ */
9
+
10
+ import { spawnSync } from 'node:child_process';
11
+ import { existsSync } from 'node:fs';
12
+ import { dirname, join } from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const PROBE_SENTINEL = 'scaffold-kb-query:1';
17
+ const SPAWN_TIMEOUT_MS = 10_000;
18
+ const MAX_BUFFER = 4 * 1024 * 1024;
19
+
20
+ function parseArgs(argv) {
21
+ const out = {};
22
+ for (let i = 0; i < argv.length; i++) {
23
+ if (argv[i] === '--requirement') out.requirement = argv[++i];
24
+ else if (argv[i] === '--project-root') out.projectRoot = argv[++i];
25
+ }
26
+ return out;
27
+ }
28
+
29
+ function diag(reason) {
30
+ process.stderr.write(`[kb-prequery] ${reason}\n`);
31
+ }
32
+
33
+ /** 经 resolve-project-context.mjs --json 读取 resolvedProfile.knowledgeSources */
34
+ function resolveKnowledgeSources(projectRoot) {
35
+ const resolver = join(__dirname, 'resolve-project-context.mjs');
36
+ const r = spawnSync('node', [resolver, '--project-root', projectRoot, '--json'], {
37
+ encoding: 'utf-8',
38
+ timeout: SPAWN_TIMEOUT_MS,
39
+ maxBuffer: MAX_BUFFER,
40
+ });
41
+ if (r.status !== 0 || typeof r.stdout !== 'string') return null;
42
+ try {
43
+ return JSON.parse(r.stdout).resolvedProfile?.knowledgeSources ?? null;
44
+ } catch {
45
+ return null;
46
+ }
47
+ }
48
+
49
+ /** bin 发现(覆盖优先):$SPECTRA_BIN → 项目 node_modules/.bin → PATH */
50
+ function discoverSpectraBin(projectRoot) {
51
+ const envBin = process.env['SPECTRA_BIN'];
52
+ if (envBin && existsSync(envBin)) return envBin;
53
+ const local = join(projectRoot, 'node_modules', '.bin', 'spectra');
54
+ if (existsSync(local)) return local;
55
+ return 'spectra'; // 交给 PATH;不存在则 spawnSync ENOENT
56
+ }
57
+
58
+ /**
59
+ * 能力探测:区分 ok / missing(bin 不存在 ENOENT)/ too-old(能跑但无 sentinel = 旧版无 query)。
60
+ * 修 Codex W2:原实现全归 spectra-unavailable,无法区分缺 bin 与旧版。
61
+ */
62
+ function probeBin(bin) {
63
+ const r = spawnSync(bin, ['scaffold-kb', 'query', '--probe'], {
64
+ encoding: 'utf-8',
65
+ timeout: SPAWN_TIMEOUT_MS,
66
+ maxBuffer: MAX_BUFFER,
67
+ });
68
+ if (r.error && r.error.code === 'ENOENT') return 'missing';
69
+ if (r.status === 0 && typeof r.stdout === 'string' && r.stdout.includes(PROBE_SENTINEL)) return 'ok';
70
+ return 'too-old';
71
+ }
72
+
73
+ function main() {
74
+ const { requirement, projectRoot = process.cwd() } = parseArgs(process.argv.slice(2));
75
+ if (!requirement) {
76
+ diag('no-requirement');
77
+ return;
78
+ }
79
+
80
+ const ks = resolveKnowledgeSources(projectRoot);
81
+ if (!ks || ks.enabled !== true || !ks.vendorKb) {
82
+ diag('disabled-or-unconfigured');
83
+ return;
84
+ }
85
+
86
+ const bin = discoverSpectraBin(projectRoot);
87
+ const probeResult = probeBin(bin);
88
+ if (probeResult === 'missing') {
89
+ diag(`spectra-unavailable (bin=${bin}; 未安装 spectra)`);
90
+ return;
91
+ }
92
+ if (probeResult === 'too-old') {
93
+ diag(`spectra-too-old (bin=${bin}; 版本过旧,无 scaffold-kb query 子命令)`);
94
+ return;
95
+ }
96
+
97
+ const args = [
98
+ 'scaffold-kb', 'query',
99
+ '--requirement', requirement,
100
+ '--vendor-kb', ks.vendorKb,
101
+ '--top-k', String(ks.topK ?? 3),
102
+ '--max-inject-chars', String(ks.maxInjectChars ?? 6000),
103
+ '--format', 'markdown',
104
+ ];
105
+ if (ks.projectKb) args.push('--project-kb', ks.projectKb);
106
+
107
+ const q = spawnSync(bin, args, {
108
+ encoding: 'utf-8',
109
+ timeout: SPAWN_TIMEOUT_MS,
110
+ maxBuffer: MAX_BUFFER,
111
+ });
112
+ if (q.status !== 0) {
113
+ diag(`query-failed (status=${q.status}): ${(q.stderr ?? '').trim()}`);
114
+ return;
115
+ }
116
+ const block = (q.stdout ?? '').trim();
117
+ if (block.length === 0) {
118
+ // 透传 query 自身的结构化降级原因(kb-missing / no-hit / no-query),不再一律标 no-hit(修 Codex W2)
119
+ diag(`no-injection: ${(q.stderr ?? 'no-hit').trim()}`);
120
+ return;
121
+ }
122
+ process.stdout.write(`${block}\n`);
123
+ }
124
+
125
+ main();