@sdd-method/sdd-cli 0.9.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 (373) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +17 -0
  3. package/README.md +151 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +8 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/index.d.ts +2 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +66 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/lib/bundle.d.ts +20 -0
  13. package/dist/lib/bundle.d.ts.map +1 -0
  14. package/dist/lib/bundle.js +75 -0
  15. package/dist/lib/bundle.js.map +1 -0
  16. package/dist/lib/generate-claude-md/index.d.ts +16 -0
  17. package/dist/lib/generate-claude-md/index.d.ts.map +1 -0
  18. package/dist/lib/generate-claude-md/index.js +89 -0
  19. package/dist/lib/generate-claude-md/index.js.map +1 -0
  20. package/dist/lib/hooks-seed/entries.d.ts +16 -0
  21. package/dist/lib/hooks-seed/entries.d.ts.map +1 -0
  22. package/dist/lib/hooks-seed/entries.js +47 -0
  23. package/dist/lib/hooks-seed/entries.js.map +1 -0
  24. package/dist/lib/hooks-seed/index.d.ts +17 -0
  25. package/dist/lib/hooks-seed/index.d.ts.map +1 -0
  26. package/dist/lib/hooks-seed/index.js +15 -0
  27. package/dist/lib/hooks-seed/index.js.map +1 -0
  28. package/dist/lib/hooks-seed/merge.d.ts +24 -0
  29. package/dist/lib/hooks-seed/merge.d.ts.map +1 -0
  30. package/dist/lib/hooks-seed/merge.js +73 -0
  31. package/dist/lib/hooks-seed/merge.js.map +1 -0
  32. package/dist/lib/hooks-seed/types.d.ts +27 -0
  33. package/dist/lib/hooks-seed/types.d.ts.map +1 -0
  34. package/dist/lib/hooks-seed/types.js +20 -0
  35. package/dist/lib/hooks-seed/types.js.map +1 -0
  36. package/dist/lib/init/app.d.ts +21 -0
  37. package/dist/lib/init/app.d.ts.map +1 -0
  38. package/dist/lib/init/app.js +132 -0
  39. package/dist/lib/init/app.js.map +1 -0
  40. package/dist/lib/init/ci-workflow.d.ts +29 -0
  41. package/dist/lib/init/ci-workflow.d.ts.map +1 -0
  42. package/dist/lib/init/ci-workflow.js +78 -0
  43. package/dist/lib/init/ci-workflow.js.map +1 -0
  44. package/dist/lib/init/claude-md.d.ts +19 -0
  45. package/dist/lib/init/claude-md.d.ts.map +1 -0
  46. package/dist/lib/init/claude-md.js +140 -0
  47. package/dist/lib/init/claude-md.js.map +1 -0
  48. package/dist/lib/init/index.d.ts +33 -0
  49. package/dist/lib/init/index.d.ts.map +1 -0
  50. package/dist/lib/init/index.js +232 -0
  51. package/dist/lib/init/index.js.map +1 -0
  52. package/dist/lib/init/integration.d.ts +53 -0
  53. package/dist/lib/init/integration.d.ts.map +1 -0
  54. package/dist/lib/init/integration.js +237 -0
  55. package/dist/lib/init/integration.js.map +1 -0
  56. package/dist/lib/init/platform.d.ts +26 -0
  57. package/dist/lib/init/platform.d.ts.map +1 -0
  58. package/dist/lib/init/platform.js +188 -0
  59. package/dist/lib/init/platform.js.map +1 -0
  60. package/dist/lib/list/discover.d.ts +8 -0
  61. package/dist/lib/list/discover.d.ts.map +1 -0
  62. package/dist/lib/list/discover.js +77 -0
  63. package/dist/lib/list/discover.js.map +1 -0
  64. package/dist/lib/list/format.d.ts +9 -0
  65. package/dist/lib/list/format.d.ts.map +1 -0
  66. package/dist/lib/list/format.js +44 -0
  67. package/dist/lib/list/format.js.map +1 -0
  68. package/dist/lib/list/index.d.ts +12 -0
  69. package/dist/lib/list/index.d.ts.map +1 -0
  70. package/dist/lib/list/index.js +15 -0
  71. package/dist/lib/list/index.js.map +1 -0
  72. package/dist/lib/lock-file.d.ts +14 -0
  73. package/dist/lib/lock-file.d.ts.map +1 -0
  74. package/dist/lib/lock-file.js +80 -0
  75. package/dist/lib/lock-file.js.map +1 -0
  76. package/dist/lib/mcp/build-info.d.ts +9 -0
  77. package/dist/lib/mcp/build-info.d.ts.map +1 -0
  78. package/dist/lib/mcp/build-info.js +10 -0
  79. package/dist/lib/mcp/build-info.js.map +1 -0
  80. package/dist/lib/mcp/errors.d.ts +23 -0
  81. package/dist/lib/mcp/errors.d.ts.map +1 -0
  82. package/dist/lib/mcp/errors.js +25 -0
  83. package/dist/lib/mcp/errors.js.map +1 -0
  84. package/dist/lib/mcp/parse/frontmatter.d.ts +22 -0
  85. package/dist/lib/mcp/parse/frontmatter.d.ts.map +1 -0
  86. package/dist/lib/mcp/parse/frontmatter.js +49 -0
  87. package/dist/lib/mcp/parse/frontmatter.js.map +1 -0
  88. package/dist/lib/mcp/parse/gate-registry.d.ts +19 -0
  89. package/dist/lib/mcp/parse/gate-registry.d.ts.map +1 -0
  90. package/dist/lib/mcp/parse/gate-registry.js +68 -0
  91. package/dist/lib/mcp/parse/gate-registry.js.map +1 -0
  92. package/dist/lib/mcp/parse/paths.d.ts +21 -0
  93. package/dist/lib/mcp/parse/paths.d.ts.map +1 -0
  94. package/dist/lib/mcp/parse/paths.js +83 -0
  95. package/dist/lib/mcp/parse/paths.js.map +1 -0
  96. package/dist/lib/mcp/pin/errors.d.ts +11 -0
  97. package/dist/lib/mcp/pin/errors.d.ts.map +1 -0
  98. package/dist/lib/mcp/pin/errors.js +32 -0
  99. package/dist/lib/mcp/pin/errors.js.map +1 -0
  100. package/dist/lib/mcp/pin/index.d.ts +18 -0
  101. package/dist/lib/mcp/pin/index.d.ts.map +1 -0
  102. package/dist/lib/mcp/pin/index.js +29 -0
  103. package/dist/lib/mcp/pin/index.js.map +1 -0
  104. package/dist/lib/mcp/pin/read.d.ts +24 -0
  105. package/dist/lib/mcp/pin/read.d.ts.map +1 -0
  106. package/dist/lib/mcp/pin/read.js +64 -0
  107. package/dist/lib/mcp/pin/read.js.map +1 -0
  108. package/dist/lib/mcp/pin/resolve.d.ts +12 -0
  109. package/dist/lib/mcp/pin/resolve.d.ts.map +1 -0
  110. package/dist/lib/mcp/pin/resolve.js +33 -0
  111. package/dist/lib/mcp/pin/resolve.js.map +1 -0
  112. package/dist/lib/mcp/prompts/evaluate-cascade.d.ts +14 -0
  113. package/dist/lib/mcp/prompts/evaluate-cascade.d.ts.map +1 -0
  114. package/dist/lib/mcp/prompts/evaluate-cascade.js +147 -0
  115. package/dist/lib/mcp/prompts/evaluate-cascade.js.map +1 -0
  116. package/dist/lib/mcp/prompts/index.d.ts +9 -0
  117. package/dist/lib/mcp/prompts/index.d.ts.map +1 -0
  118. package/dist/lib/mcp/prompts/index.js +23 -0
  119. package/dist/lib/mcp/prompts/index.js.map +1 -0
  120. package/dist/lib/mcp/prompts/propose-adr.d.ts +12 -0
  121. package/dist/lib/mcp/prompts/propose-adr.d.ts.map +1 -0
  122. package/dist/lib/mcp/prompts/propose-adr.js +94 -0
  123. package/dist/lib/mcp/prompts/propose-adr.js.map +1 -0
  124. package/dist/lib/mcp/prompts/review-data-model-change.d.ts +10 -0
  125. package/dist/lib/mcp/prompts/review-data-model-change.d.ts.map +1 -0
  126. package/dist/lib/mcp/prompts/review-data-model-change.js +134 -0
  127. package/dist/lib/mcp/prompts/review-data-model-change.js.map +1 -0
  128. package/dist/lib/mcp/prompts/template-loader.d.ts +29 -0
  129. package/dist/lib/mcp/prompts/template-loader.d.ts.map +1 -0
  130. package/dist/lib/mcp/prompts/template-loader.js +44 -0
  131. package/dist/lib/mcp/prompts/template-loader.js.map +1 -0
  132. package/dist/lib/mcp/prompts/types.d.ts +17 -0
  133. package/dist/lib/mcp/prompts/types.d.ts.map +1 -0
  134. package/dist/lib/mcp/prompts/types.js +10 -0
  135. package/dist/lib/mcp/prompts/types.js.map +1 -0
  136. package/dist/lib/mcp/prompts/write-capability-spec.d.ts +8 -0
  137. package/dist/lib/mcp/prompts/write-capability-spec.d.ts.map +1 -0
  138. package/dist/lib/mcp/prompts/write-capability-spec.js +85 -0
  139. package/dist/lib/mcp/prompts/write-capability-spec.js.map +1 -0
  140. package/dist/lib/mcp/prompts/write-feature-spec.d.ts +10 -0
  141. package/dist/lib/mcp/prompts/write-feature-spec.d.ts.map +1 -0
  142. package/dist/lib/mcp/prompts/write-feature-spec.js +94 -0
  143. package/dist/lib/mcp/prompts/write-feature-spec.js.map +1 -0
  144. package/dist/lib/mcp/prompts/write-work-order.d.ts +7 -0
  145. package/dist/lib/mcp/prompts/write-work-order.d.ts.map +1 -0
  146. package/dist/lib/mcp/prompts/write-work-order.js +69 -0
  147. package/dist/lib/mcp/prompts/write-work-order.js.map +1 -0
  148. package/dist/lib/mcp/reader.d.ts +37 -0
  149. package/dist/lib/mcp/reader.d.ts.map +1 -0
  150. package/dist/lib/mcp/reader.js +93 -0
  151. package/dist/lib/mcp/reader.js.map +1 -0
  152. package/dist/lib/mcp/resources/adrs.d.ts +3 -0
  153. package/dist/lib/mcp/resources/adrs.d.ts.map +1 -0
  154. package/dist/lib/mcp/resources/adrs.js +97 -0
  155. package/dist/lib/mcp/resources/adrs.js.map +1 -0
  156. package/dist/lib/mcp/resources/data-models.d.ts +14 -0
  157. package/dist/lib/mcp/resources/data-models.d.ts.map +1 -0
  158. package/dist/lib/mcp/resources/data-models.js +81 -0
  159. package/dist/lib/mcp/resources/data-models.js.map +1 -0
  160. package/dist/lib/mcp/resources/gates.d.ts +9 -0
  161. package/dist/lib/mcp/resources/gates.d.ts.map +1 -0
  162. package/dist/lib/mcp/resources/gates.js +90 -0
  163. package/dist/lib/mcp/resources/gates.js.map +1 -0
  164. package/dist/lib/mcp/resources/glossary.d.ts +16 -0
  165. package/dist/lib/mcp/resources/glossary.d.ts.map +1 -0
  166. package/dist/lib/mcp/resources/glossary.js +87 -0
  167. package/dist/lib/mcp/resources/glossary.js.map +1 -0
  168. package/dist/lib/mcp/resources/specs.d.ts +23 -0
  169. package/dist/lib/mcp/resources/specs.d.ts.map +1 -0
  170. package/dist/lib/mcp/resources/specs.js +151 -0
  171. package/dist/lib/mcp/resources/specs.js.map +1 -0
  172. package/dist/lib/mcp/resources/version.d.ts +3 -0
  173. package/dist/lib/mcp/resources/version.d.ts.map +1 -0
  174. package/dist/lib/mcp/resources/version.js +45 -0
  175. package/dist/lib/mcp/resources/version.js.map +1 -0
  176. package/dist/lib/mcp/server.d.ts +29 -0
  177. package/dist/lib/mcp/server.d.ts.map +1 -0
  178. package/dist/lib/mcp/server.js +104 -0
  179. package/dist/lib/mcp/server.js.map +1 -0
  180. package/dist/lib/mcp/tools/cascade-impact.d.ts +22 -0
  181. package/dist/lib/mcp/tools/cascade-impact.d.ts.map +1 -0
  182. package/dist/lib/mcp/tools/cascade-impact.js +53 -0
  183. package/dist/lib/mcp/tools/cascade-impact.js.map +1 -0
  184. package/dist/lib/mcp/tools/find-consumers-of-contract.d.ts +7 -0
  185. package/dist/lib/mcp/tools/find-consumers-of-contract.d.ts.map +1 -0
  186. package/dist/lib/mcp/tools/find-consumers-of-contract.js +70 -0
  187. package/dist/lib/mcp/tools/find-consumers-of-contract.js.map +1 -0
  188. package/dist/lib/mcp/tools/find-consumers.d.ts +7 -0
  189. package/dist/lib/mcp/tools/find-consumers.d.ts.map +1 -0
  190. package/dist/lib/mcp/tools/find-consumers.js +52 -0
  191. package/dist/lib/mcp/tools/find-consumers.js.map +1 -0
  192. package/dist/lib/mcp/tools/find-dependencies.d.ts +8 -0
  193. package/dist/lib/mcp/tools/find-dependencies.d.ts.map +1 -0
  194. package/dist/lib/mcp/tools/find-dependencies.js +89 -0
  195. package/dist/lib/mcp/tools/find-dependencies.js.map +1 -0
  196. package/dist/lib/mcp/tools/find-dependents.d.ts +8 -0
  197. package/dist/lib/mcp/tools/find-dependents.d.ts.map +1 -0
  198. package/dist/lib/mcp/tools/find-dependents.js +89 -0
  199. package/dist/lib/mcp/tools/find-dependents.js.map +1 -0
  200. package/dist/lib/mcp/tools/find-producers.d.ts +8 -0
  201. package/dist/lib/mcp/tools/find-producers.d.ts.map +1 -0
  202. package/dist/lib/mcp/tools/find-producers.js +57 -0
  203. package/dist/lib/mcp/tools/find-producers.js.map +1 -0
  204. package/dist/lib/mcp/tools/find-related-specs.d.ts +9 -0
  205. package/dist/lib/mcp/tools/find-related-specs.d.ts.map +1 -0
  206. package/dist/lib/mcp/tools/find-related-specs.js +92 -0
  207. package/dist/lib/mcp/tools/find-related-specs.js.map +1 -0
  208. package/dist/lib/mcp/tools/list-adrs.d.ts +3 -0
  209. package/dist/lib/mcp/tools/list-adrs.d.ts.map +1 -0
  210. package/dist/lib/mcp/tools/list-adrs.js +73 -0
  211. package/dist/lib/mcp/tools/list-adrs.js.map +1 -0
  212. package/dist/lib/mcp/tools/query-gate-status.d.ts +3 -0
  213. package/dist/lib/mcp/tools/query-gate-status.d.ts.map +1 -0
  214. package/dist/lib/mcp/tools/query-gate-status.js +82 -0
  215. package/dist/lib/mcp/tools/query-gate-status.js.map +1 -0
  216. package/dist/lib/mcp/tools/search-specs.d.ts +12 -0
  217. package/dist/lib/mcp/tools/search-specs.d.ts.map +1 -0
  218. package/dist/lib/mcp/tools/search-specs.js +151 -0
  219. package/dist/lib/mcp/tools/search-specs.js.map +1 -0
  220. package/dist/lib/mcp/workspace.d.ts +25 -0
  221. package/dist/lib/mcp/workspace.d.ts.map +1 -0
  222. package/dist/lib/mcp/workspace.js +129 -0
  223. package/dist/lib/mcp/workspace.js.map +1 -0
  224. package/dist/lib/mcp-seed/entries.d.ts +19 -0
  225. package/dist/lib/mcp-seed/entries.d.ts.map +1 -0
  226. package/dist/lib/mcp-seed/entries.js +14 -0
  227. package/dist/lib/mcp-seed/entries.js.map +1 -0
  228. package/dist/lib/mcp-seed/index.d.ts +36 -0
  229. package/dist/lib/mcp-seed/index.d.ts.map +1 -0
  230. package/dist/lib/mcp-seed/index.js +28 -0
  231. package/dist/lib/mcp-seed/index.js.map +1 -0
  232. package/dist/lib/mcp-seed/merge.d.ts +34 -0
  233. package/dist/lib/mcp-seed/merge.d.ts.map +1 -0
  234. package/dist/lib/mcp-seed/merge.js +99 -0
  235. package/dist/lib/mcp-seed/merge.js.map +1 -0
  236. package/dist/lib/mcp-seed/types.d.ts +24 -0
  237. package/dist/lib/mcp-seed/types.d.ts.map +1 -0
  238. package/dist/lib/mcp-seed/types.js +13 -0
  239. package/dist/lib/mcp-seed/types.js.map +1 -0
  240. package/dist/lib/plan/index.d.ts +19 -0
  241. package/dist/lib/plan/index.d.ts.map +1 -0
  242. package/dist/lib/plan/index.js +69 -0
  243. package/dist/lib/plan/index.js.map +1 -0
  244. package/dist/lib/plan/read-sdd.d.ts +46 -0
  245. package/dist/lib/plan/read-sdd.d.ts.map +1 -0
  246. package/dist/lib/plan/read-sdd.js +102 -0
  247. package/dist/lib/plan/read-sdd.js.map +1 -0
  248. package/dist/lib/plan/render-template.d.ts +8 -0
  249. package/dist/lib/plan/render-template.d.ts.map +1 -0
  250. package/dist/lib/plan/render-template.js +60 -0
  251. package/dist/lib/plan/render-template.js.map +1 -0
  252. package/dist/lib/repo-kind.d.ts +20 -0
  253. package/dist/lib/repo-kind.d.ts.map +1 -0
  254. package/dist/lib/repo-kind.js +73 -0
  255. package/dist/lib/repo-kind.js.map +1 -0
  256. package/dist/lib/scripts.d.ts +2 -0
  257. package/dist/lib/scripts.d.ts.map +1 -0
  258. package/dist/lib/scripts.js +7 -0
  259. package/dist/lib/scripts.js.map +1 -0
  260. package/dist/lib/sdd-index/cascade.d.ts +46 -0
  261. package/dist/lib/sdd-index/cascade.d.ts.map +1 -0
  262. package/dist/lib/sdd-index/cascade.js +91 -0
  263. package/dist/lib/sdd-index/cascade.js.map +1 -0
  264. package/dist/lib/sdd-index/contracts.d.ts +29 -0
  265. package/dist/lib/sdd-index/contracts.d.ts.map +1 -0
  266. package/dist/lib/sdd-index/contracts.js +216 -0
  267. package/dist/lib/sdd-index/contracts.js.map +1 -0
  268. package/dist/lib/sdd-index/data-model.d.ts +13 -0
  269. package/dist/lib/sdd-index/data-model.d.ts.map +1 -0
  270. package/dist/lib/sdd-index/data-model.js +23 -0
  271. package/dist/lib/sdd-index/data-model.js.map +1 -0
  272. package/dist/lib/sdd-index/execution-map.d.ts +34 -0
  273. package/dist/lib/sdd-index/execution-map.d.ts.map +1 -0
  274. package/dist/lib/sdd-index/execution-map.js +105 -0
  275. package/dist/lib/sdd-index/execution-map.js.map +1 -0
  276. package/dist/lib/sdd-index/graph.d.ts +28 -0
  277. package/dist/lib/sdd-index/graph.d.ts.map +1 -0
  278. package/dist/lib/sdd-index/graph.js +122 -0
  279. package/dist/lib/sdd-index/graph.js.map +1 -0
  280. package/dist/lib/sdd-index/index.d.ts +29 -0
  281. package/dist/lib/sdd-index/index.d.ts.map +1 -0
  282. package/dist/lib/sdd-index/index.js +79 -0
  283. package/dist/lib/sdd-index/index.js.map +1 -0
  284. package/dist/lib/sdd-index/repo-config.d.ts +23 -0
  285. package/dist/lib/sdd-index/repo-config.d.ts.map +1 -0
  286. package/dist/lib/sdd-index/repo-config.js +150 -0
  287. package/dist/lib/sdd-index/repo-config.js.map +1 -0
  288. package/dist/lib/sdd-index/types.d.ts +106 -0
  289. package/dist/lib/sdd-index/types.d.ts.map +1 -0
  290. package/dist/lib/sdd-index/types.js +13 -0
  291. package/dist/lib/sdd-index/types.js.map +1 -0
  292. package/dist/lib/sdd-index/watch.d.ts +24 -0
  293. package/dist/lib/sdd-index/watch.d.ts.map +1 -0
  294. package/dist/lib/sdd-index/watch.js +112 -0
  295. package/dist/lib/sdd-index/watch.js.map +1 -0
  296. package/dist/lib/spawn.d.ts +8 -0
  297. package/dist/lib/spawn.d.ts.map +1 -0
  298. package/dist/lib/spawn.js +16 -0
  299. package/dist/lib/spawn.js.map +1 -0
  300. package/dist/lib/sync/apply.d.ts +3 -0
  301. package/dist/lib/sync/apply.d.ts.map +1 -0
  302. package/dist/lib/sync/apply.js +16 -0
  303. package/dist/lib/sync/apply.js.map +1 -0
  304. package/dist/lib/sync/diff.d.ts +8 -0
  305. package/dist/lib/sync/diff.d.ts.map +1 -0
  306. package/dist/lib/sync/diff.js +48 -0
  307. package/dist/lib/sync/diff.js.map +1 -0
  308. package/dist/lib/sync/index.d.ts +17 -0
  309. package/dist/lib/sync/index.d.ts.map +1 -0
  310. package/dist/lib/sync/index.js +184 -0
  311. package/dist/lib/sync/index.js.map +1 -0
  312. package/dist/lib/sync/settings-merge.d.ts +45 -0
  313. package/dist/lib/sync/settings-merge.d.ts.map +1 -0
  314. package/dist/lib/sync/settings-merge.js +109 -0
  315. package/dist/lib/sync/settings-merge.js.map +1 -0
  316. package/dist/lib/sync/source-tag.d.ts +5 -0
  317. package/dist/lib/sync/source-tag.d.ts.map +1 -0
  318. package/dist/lib/sync/source-tag.js +34 -0
  319. package/dist/lib/sync/source-tag.js.map +1 -0
  320. package/dist/lib/sync/yaml-block-merge.d.ts +50 -0
  321. package/dist/lib/sync/yaml-block-merge.d.ts.map +1 -0
  322. package/dist/lib/sync/yaml-block-merge.js +113 -0
  323. package/dist/lib/sync/yaml-block-merge.js.map +1 -0
  324. package/dist/lib/validate/aggregate.d.ts +13 -0
  325. package/dist/lib/validate/aggregate.d.ts.map +1 -0
  326. package/dist/lib/validate/aggregate.js +35 -0
  327. package/dist/lib/validate/aggregate.js.map +1 -0
  328. package/dist/lib/validate/dispatch.d.ts +34 -0
  329. package/dist/lib/validate/dispatch.d.ts.map +1 -0
  330. package/dist/lib/validate/dispatch.js +167 -0
  331. package/dist/lib/validate/dispatch.js.map +1 -0
  332. package/dist/lib/validate/index.d.ts +13 -0
  333. package/dist/lib/validate/index.d.ts.map +1 -0
  334. package/dist/lib/validate/index.js +69 -0
  335. package/dist/lib/validate/index.js.map +1 -0
  336. package/dist/lib/validate/runner.d.ts +16 -0
  337. package/dist/lib/validate/runner.d.ts.map +1 -0
  338. package/dist/lib/validate/runner.js +66 -0
  339. package/dist/lib/validate/runner.js.map +1 -0
  340. package/dist/verbs/generate-claude-md.d.ts +3 -0
  341. package/dist/verbs/generate-claude-md.d.ts.map +1 -0
  342. package/dist/verbs/generate-claude-md.js +36 -0
  343. package/dist/verbs/generate-claude-md.js.map +1 -0
  344. package/dist/verbs/init.d.ts +3 -0
  345. package/dist/verbs/init.d.ts.map +1 -0
  346. package/dist/verbs/init.js +90 -0
  347. package/dist/verbs/init.js.map +1 -0
  348. package/dist/verbs/list.d.ts +3 -0
  349. package/dist/verbs/list.d.ts.map +1 -0
  350. package/dist/verbs/list.js +43 -0
  351. package/dist/verbs/list.js.map +1 -0
  352. package/dist/verbs/mcp.d.ts +3 -0
  353. package/dist/verbs/mcp.d.ts.map +1 -0
  354. package/dist/verbs/mcp.js +22 -0
  355. package/dist/verbs/mcp.js.map +1 -0
  356. package/dist/verbs/plan.d.ts +3 -0
  357. package/dist/verbs/plan.d.ts.map +1 -0
  358. package/dist/verbs/plan.js +41 -0
  359. package/dist/verbs/plan.js.map +1 -0
  360. package/dist/verbs/sync.d.ts +3 -0
  361. package/dist/verbs/sync.d.ts.map +1 -0
  362. package/dist/verbs/sync.js +27 -0
  363. package/dist/verbs/sync.js.map +1 -0
  364. package/dist/verbs/validate.d.ts +3 -0
  365. package/dist/verbs/validate.d.ts.map +1 -0
  366. package/dist/verbs/validate.js +21 -0
  367. package/dist/verbs/validate.js.map +1 -0
  368. package/package.json +61 -0
  369. package/scripts/README.md +48 -0
  370. package/scripts/sync-method-baseline.sh +258 -0
  371. package/scripts/validate-app-dependencies.sh +289 -0
  372. package/scripts/validate-app-docs.sh +185 -0
  373. package/scripts/validate-integration-docs.sh +222 -0
@@ -0,0 +1,89 @@
1
+ /**
2
+ * find_dependents — given a service name, return services downstream
3
+ * of it: those that name it as an internal dependency, consume a
4
+ * contract it produces, or have an execution-map edge pointing at it.
5
+ */
6
+ import { z } from "zod";
7
+ import { McpEnvelopeError } from "../errors.js";
8
+ import { readerFor } from "../pin/index.js";
9
+ import { getSddIndex } from "../../sdd-index/index.js";
10
+ export function register(server, sddRoot) {
11
+ server.registerTool("find_dependents", {
12
+ title: "Find dependents",
13
+ description: "List services downstream of a given service — those that depend on it directly (via repo-config), consume a contract it produces, or point at it in the execution-dependency-map.",
14
+ inputSchema: {
15
+ service: z
16
+ .string()
17
+ .min(1)
18
+ .describe("Service id (matches the repo-config `repo` field)."),
19
+ pin_to_commit: z
20
+ .string()
21
+ .optional()
22
+ .describe("Optional commit SHA (or ref) to pin the SDD to."),
23
+ },
24
+ }, async ({ service, pin_to_commit }) => {
25
+ const reader = readerFor(sddRoot, pin_to_commit);
26
+ const index = getSddIndex(reader);
27
+ if (!index.services.has(service)) {
28
+ throw new McpEnvelopeError({
29
+ code: "SERVICE_NOT_FOUND",
30
+ message: `No service named '${service}' in the SDD index.`,
31
+ remediation: `Check spelling. Known services: ${Array.from(index.services.keys()).sort().join(", ") || "(none)"}.`,
32
+ context: {
33
+ service,
34
+ known: Array.from(index.services.keys()).sort(),
35
+ },
36
+ });
37
+ }
38
+ const directDependents = [];
39
+ for (const [id, other] of index.services) {
40
+ if (other.internalDependencies.includes(service)) {
41
+ directDependents.push({
42
+ service: id,
43
+ domain: other.domain,
44
+ via: "internal_dependency",
45
+ });
46
+ }
47
+ }
48
+ const contractsProduced = Array.from(index.contracts.values()).filter((c) => c.producers.includes(service));
49
+ const contractDependents = [];
50
+ for (const node of contractsProduced) {
51
+ for (const consumer of node.consumers) {
52
+ const consumerSvc = index.services.get(consumer);
53
+ const ref = consumerSvc?.contracts.find((c) => c.path === node.path);
54
+ contractDependents.push({
55
+ service: consumer,
56
+ contract_path: node.path,
57
+ version_pin: ref?.version ?? null,
58
+ stability: ref?.stability ?? null,
59
+ });
60
+ }
61
+ }
62
+ const executionEdges = index.executionEdges
63
+ .filter((e) => e.to === service)
64
+ .map((e) => ({
65
+ from: e.from,
66
+ kind: e.kind,
67
+ note: e.note ?? null,
68
+ }));
69
+ const payload = {
70
+ query: { service },
71
+ dependents: {
72
+ direct: directDependents,
73
+ contract_consumers: contractDependents,
74
+ execution_edges: executionEdges,
75
+ },
76
+ pin_to_commit: reader.pin,
77
+ sources: [
78
+ `sdd://repo-config/${index.services.get(service)?.domain}/${service}`,
79
+ ...(contractsProduced.length > 0
80
+ ? contractsProduced.map((c) => `sdd://contracts/${c.path}`)
81
+ : []),
82
+ ],
83
+ };
84
+ return {
85
+ content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
86
+ };
87
+ });
88
+ }
89
+ //# sourceMappingURL=find-dependents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-dependents.js","sourceRoot":"","sources":["../../../../src/lib/mcp/tools/find-dependents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * find_producers — given an aggregate name or event name, return the
3
+ * services that own / publish it. Backed by the SDD index's
4
+ * `producers` map.
5
+ */
6
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7
+ export declare function register(server: McpServer, sddRoot: string): void;
8
+ //# sourceMappingURL=find-producers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-producers.d.ts","sourceRoot":"","sources":["../../../../src/lib/mcp/tools/find-producers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAgEjE"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * find_producers — given an aggregate name or event name, return the
3
+ * services that own / publish it. Backed by the SDD index's
4
+ * `producers` map.
5
+ */
6
+ import { z } from "zod";
7
+ import { readerFor } from "../pin/index.js";
8
+ import { getSddIndex } from "../../sdd-index/index.js";
9
+ export function register(server, sddRoot) {
10
+ server.registerTool("find_producers", {
11
+ title: "Find producers",
12
+ description: "Given an aggregate name or event name, return the services that publish it. A service is classed as producer when it owns an aggregate the contract describes.",
13
+ inputSchema: {
14
+ target: z
15
+ .string()
16
+ .min(1)
17
+ .describe("Aggregate name or event name. Case-sensitive."),
18
+ pin_to_commit: z
19
+ .string()
20
+ .optional()
21
+ .describe("Optional commit SHA (or ref) to pin the SDD to."),
22
+ },
23
+ }, async ({ target, pin_to_commit }) => {
24
+ const reader = readerFor(sddRoot, pin_to_commit);
25
+ const index = getSddIndex(reader);
26
+ const producers = index.producers.get(target) ?? [];
27
+ const matches = producers.map((serviceId) => {
28
+ const svc = index.services.get(serviceId);
29
+ const contracts = svc?.contracts ?? [];
30
+ const refMatching = contracts.find((c) => {
31
+ const node = index.contracts.get(c.path);
32
+ return (node?.producedAggregates.includes(target) ||
33
+ node?.producedEvents.includes(target));
34
+ });
35
+ return {
36
+ service: serviceId,
37
+ domain: svc?.domain ?? null,
38
+ owns_aggregate: svc?.aggregates.includes(target) ?? false,
39
+ contract_path: refMatching?.path ?? null,
40
+ version_pin: refMatching?.version ?? null,
41
+ stability: refMatching?.stability ?? null,
42
+ };
43
+ });
44
+ const payload = {
45
+ query: { target },
46
+ matches,
47
+ total: matches.length,
48
+ pin_to_commit: reader.pin,
49
+ sources: Array.from(new Set(matches.map((m) => m.contract_path).filter(Boolean))).map((p) => `sdd://contracts/${p}`),
50
+ metadata_incomplete: matches.length > 0 && matches.every((m) => !m.contract_path),
51
+ };
52
+ return {
53
+ content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
54
+ };
55
+ });
56
+ }
57
+ //# sourceMappingURL=find-producers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-producers.js","sourceRoot":"","sources":["../../../../src/lib/mcp/tools/find-producers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * find_related_specs — given an entity name (e.g. an aggregate, an
3
+ * event, a ubiquitous term), return every spec / ADR / glossary that
4
+ * references it by literal substring match. Case-insensitive; counts
5
+ * occurrences per document; no tokenisation.
6
+ */
7
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
+ export declare function register(server: McpServer, sddRoot: string): void;
9
+ //# sourceMappingURL=find-related-specs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-related-specs.d.ts","sourceRoot":"","sources":["../../../../src/lib/mcp/tools/find-related-specs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAgGjE"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * find_related_specs — given an entity name (e.g. an aggregate, an
3
+ * event, a ubiquitous term), return every spec / ADR / glossary that
4
+ * references it by literal substring match. Case-insensitive; counts
5
+ * occurrences per document; no tokenisation.
6
+ */
7
+ import { readFileSync } from "node:fs";
8
+ import { z } from "zod";
9
+ import { discoverAdrs } from "../parse/paths.js";
10
+ import { readerFor } from "../pin/index.js";
11
+ import { discoverCapabilitySpecs, discoverFeatureSpecs } from "../resources/specs.js";
12
+ import { discoverGlossaries } from "../resources/glossary.js";
13
+ export function register(server, sddRoot) {
14
+ server.registerTool("find_related_specs", {
15
+ title: "Find related specs",
16
+ description: "Locate every ADR, spec, or glossary entry that references a given entity by literal substring match.",
17
+ inputSchema: {
18
+ entity_name: z
19
+ .string()
20
+ .min(1)
21
+ .describe("Entity name to search for (case-insensitive substring)."),
22
+ pin_to_commit: z
23
+ .string()
24
+ .optional()
25
+ .describe("Optional commit SHA (or any ref) to pin the SDD to. When set, the server reads from a git worktree at that commit rather than the working tree."),
26
+ },
27
+ }, async ({ entity_name, pin_to_commit }) => {
28
+ const reader = readerFor(sddRoot, pin_to_commit);
29
+ const needle = entity_name.toLowerCase();
30
+ const docs = [];
31
+ for (const adr of discoverAdrs(reader.sddRoot)) {
32
+ docs.push({
33
+ uri: `sdd://adrs/${adr.scope}/${adr.number}`,
34
+ path: adr.path,
35
+ kind: "adr",
36
+ });
37
+ }
38
+ for (const c of discoverCapabilitySpecs(reader.sddRoot)) {
39
+ docs.push({
40
+ uri: `sdd://specs/capability/${c.domain}/${c.capability}`,
41
+ path: c.path,
42
+ kind: "capability",
43
+ });
44
+ }
45
+ for (const f of discoverFeatureSpecs(reader.sddRoot)) {
46
+ docs.push({
47
+ uri: `sdd://specs/feature/${f.domain}/${f.capability}/${f.feature}`,
48
+ path: f.path,
49
+ kind: "feature",
50
+ });
51
+ }
52
+ for (const g of discoverGlossaries(reader.sddRoot)) {
53
+ docs.push({
54
+ uri: `sdd://glossary/${g.scope}`,
55
+ path: g.path,
56
+ kind: "glossary",
57
+ });
58
+ }
59
+ const matches = [];
60
+ for (const doc of docs) {
61
+ let body;
62
+ try {
63
+ body = readFileSync(doc.path, "utf8");
64
+ }
65
+ catch {
66
+ continue;
67
+ }
68
+ const lower = body.toLowerCase();
69
+ let count = 0;
70
+ let idx = 0;
71
+ while ((idx = lower.indexOf(needle, idx)) !== -1) {
72
+ count++;
73
+ idx += needle.length;
74
+ }
75
+ if (count > 0) {
76
+ matches.push({ uri: doc.uri, kind: doc.kind, occurrences: count });
77
+ }
78
+ }
79
+ matches.sort((a, b) => b.occurrences - a.occurrences);
80
+ const payload = {
81
+ entity_name,
82
+ total: matches.length,
83
+ matches,
84
+ sources: matches.map((m) => m.uri),
85
+ pin_to_commit: reader.pin,
86
+ };
87
+ return {
88
+ content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
89
+ };
90
+ });
91
+ }
92
+ //# sourceMappingURL=find-related-specs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-related-specs.js","sourceRoot":"","sources":["../../../../src/lib/mcp/tools/find-related-specs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer, sddRoot: string): void;
3
+ //# sourceMappingURL=list-adrs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-adrs.d.ts","sourceRoot":"","sources":["../../../../src/lib/mcp/tools/list-adrs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CA2EjE"}
@@ -0,0 +1,73 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { z } from "zod";
3
+ import { parseAdrMetadata } from "../parse/frontmatter.js";
4
+ import { discoverAdrs } from "../parse/paths.js";
5
+ import { readerFor } from "../pin/index.js";
6
+ export function register(server, sddRoot) {
7
+ server.registerTool("list_adrs", {
8
+ title: "List ADRs",
9
+ description: "Enumerate ADRs discovered under docs/method/adr, docs/platform/adr, and docs/domains/{domain}/adr. Optionally filter by scope prefix or status.",
10
+ inputSchema: {
11
+ scope: z
12
+ .string()
13
+ .optional()
14
+ .describe("Filter by ADR scope: 'method', 'platform', or 'domain' (matches any domain:*)"),
15
+ status: z
16
+ .string()
17
+ .optional()
18
+ .describe("Filter by ADR status (Accepted / Proposed / Superseded / Deprecated / Deferred). Case-insensitive."),
19
+ pin_to_commit: z
20
+ .string()
21
+ .optional()
22
+ .describe("Optional commit SHA (or any ref) to pin the SDD to. When set, the server reads from a git worktree at that commit rather than the working tree."),
23
+ },
24
+ }, async ({ scope, status, pin_to_commit }) => {
25
+ const reader = readerFor(sddRoot, pin_to_commit);
26
+ const wantScope = scope?.toLowerCase();
27
+ const wantStatus = status?.toLowerCase();
28
+ const adrs = discoverAdrs(reader.sddRoot);
29
+ const entries = adrs
30
+ .map((a) => {
31
+ const metadata = parseAdrMetadata(readFileSync(a.path, "utf8"));
32
+ return {
33
+ number: a.number,
34
+ scope: a.scope,
35
+ title: metadata.title || a.title,
36
+ status: metadata.status ?? null,
37
+ date: metadata.date ?? null,
38
+ decision_type: metadata.decisionType ?? null,
39
+ uri: `sdd://adrs/${a.scope}/${a.number}`,
40
+ };
41
+ })
42
+ .filter((e) => {
43
+ if (wantScope) {
44
+ if (wantScope === "domain") {
45
+ if (!e.scope.startsWith("domain:"))
46
+ return false;
47
+ }
48
+ else if (e.scope !== wantScope) {
49
+ return false;
50
+ }
51
+ }
52
+ if (wantStatus && (e.status ?? "").toLowerCase() !== wantStatus) {
53
+ return false;
54
+ }
55
+ return true;
56
+ });
57
+ const payload = {
58
+ sdd_root: sddRoot,
59
+ filters: {
60
+ scope: scope ?? null,
61
+ status: status ?? null,
62
+ },
63
+ count: entries.length,
64
+ adrs: entries,
65
+ sources: ["sdd://adrs/catalogue"],
66
+ pin_to_commit: reader.pin,
67
+ };
68
+ return {
69
+ content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
70
+ };
71
+ });
72
+ }
73
+ //# sourceMappingURL=list-adrs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-adrs.js","sourceRoot":"","sources":["../../../../src/lib/mcp/tools/list-adrs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer, sddRoot: string): void;
3
+ //# sourceMappingURL=query-gate-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-gate-status.d.ts","sourceRoot":"","sources":["../../../../src/lib/mcp/tools/query-gate-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAoEjE"}
@@ -0,0 +1,82 @@
1
+ import { z } from "zod";
2
+ import { McpEnvelopeError } from "../errors.js";
3
+ import { listGates, readGateRegistry } from "../parse/gate-registry.js";
4
+ import { readerFor } from "../pin/index.js";
5
+ export function register(server, sddRoot) {
6
+ server.registerTool("query_gate_status", {
7
+ title: "Query gate status",
8
+ description: "Read the status of a specific gate from orchestration/gate-registry/{gate}-scores.yaml. Returns summary counts plus scoped entries.",
9
+ inputSchema: {
10
+ gate: z
11
+ .string()
12
+ .describe("Gate name, e.g. adr-quality, contract-quality, intent-quality, feature-grounding, domain-architecture, c4-diagram, strategic-doc, traceability-manifest, user-story, work-order"),
13
+ scope: z
14
+ .string()
15
+ .optional()
16
+ .describe("Optional filter applied to entry keys (substring match, case-insensitive). Useful for narrowing e.g. to a specific domain or ADR number."),
17
+ pin_to_commit: z
18
+ .string()
19
+ .optional()
20
+ .describe("Optional commit SHA (or any ref) to pin the SDD to. When set, the server reads from a git worktree at that commit rather than the working tree."),
21
+ },
22
+ }, async ({ gate, scope, pin_to_commit }) => {
23
+ const reader = readerFor(sddRoot, pin_to_commit);
24
+ const registry = readGateRegistry(reader.sddRoot, gate);
25
+ if (!registry) {
26
+ throw new McpEnvelopeError({
27
+ code: "GATE_NOT_FOUND",
28
+ message: `No gate registry for ${gate} under SDD root ${reader.sddRoot}.`,
29
+ remediation: `Check the gate name — available gates in this SDD: ${listGates(reader.sddRoot).join(", ") || "(none)"}.`,
30
+ context: {
31
+ gate,
32
+ available: listGates(reader.sddRoot),
33
+ sdd_root: reader.sddRoot,
34
+ },
35
+ });
36
+ }
37
+ const wantScope = scope?.toLowerCase();
38
+ const entries = wantScope
39
+ ? Object.fromEntries(Object.entries(registry.entries).filter(([k]) => k.toLowerCase().includes(wantScope)))
40
+ : registry.entries;
41
+ const summary = summarise(entries);
42
+ const payload = {
43
+ gate,
44
+ scope_filter: scope ?? null,
45
+ schema_version: registry.schemaVersion,
46
+ pass_threshold: registry.passThreshold,
47
+ summary,
48
+ entries,
49
+ sources: [`sdd://gates/${gate}`],
50
+ pin_to_commit: reader.pin,
51
+ };
52
+ return {
53
+ content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
54
+ };
55
+ });
56
+ }
57
+ function summarise(entries) {
58
+ let total = 0;
59
+ let pass = 0;
60
+ let conditional = 0;
61
+ let fail = 0;
62
+ let unscored = 0;
63
+ for (const value of Object.values(entries)) {
64
+ total++;
65
+ if (value && typeof value === "object") {
66
+ const gateVal = value["gate"];
67
+ if (gateVal === "pass")
68
+ pass++;
69
+ else if (gateVal === "conditional")
70
+ conditional++;
71
+ else if (gateVal === "fail")
72
+ fail++;
73
+ else
74
+ unscored++;
75
+ }
76
+ else {
77
+ unscored++;
78
+ }
79
+ }
80
+ return { total, pass, conditional, fail, unscored };
81
+ }
82
+ //# sourceMappingURL=query-gate-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-gate-status.js","sourceRoot":"","sources":["../../../../src/lib/mcp/tools/query-gate-status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * search_specs — plain-text search across ADRs, capability specs,
3
+ * feature specs, and glossaries. Scores by count of query-token
4
+ * occurrences in each document body; returns top N with a snippet.
5
+ *
6
+ * Deliberately simple for Phase 1: no fuzzy matching, no stemming, no
7
+ * BM25. Upgrade path is to drop in fuse.js or a proper index in a
8
+ * later phase if precision becomes an issue.
9
+ */
10
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
11
+ export declare function register(server: McpServer, sddRoot: string): void;
12
+ //# sourceMappingURL=search-specs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-specs.d.ts","sourceRoot":"","sources":["../../../../src/lib/mcp/tools/search-specs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAazE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAyGjE"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * search_specs — plain-text search across ADRs, capability specs,
3
+ * feature specs, and glossaries. Scores by count of query-token
4
+ * occurrences in each document body; returns top N with a snippet.
5
+ *
6
+ * Deliberately simple for Phase 1: no fuzzy matching, no stemming, no
7
+ * BM25. Upgrade path is to drop in fuse.js or a proper index in a
8
+ * later phase if precision becomes an issue.
9
+ */
10
+ import { readFileSync } from "node:fs";
11
+ import { z } from "zod";
12
+ import { discoverAdrs } from "../parse/paths.js";
13
+ import { readerFor } from "../pin/index.js";
14
+ import { discoverCapabilitySpecs, discoverFeatureSpecs } from "../resources/specs.js";
15
+ import { discoverGlossaries } from "../resources/glossary.js";
16
+ export function register(server, sddRoot) {
17
+ server.registerTool("search_specs", {
18
+ title: "Search specs",
19
+ description: "Plain-text search across ADRs, capability specs, feature specs, and glossaries. Returns ranked matches with URIs and short snippets.",
20
+ inputSchema: {
21
+ query: z.string().min(1).describe("Free-text query. Tokenised by whitespace; case-insensitive."),
22
+ limit: z
23
+ .number()
24
+ .int()
25
+ .min(1)
26
+ .max(50)
27
+ .optional()
28
+ .describe("Maximum number of hits to return. Default 10."),
29
+ kinds: z
30
+ .array(z.enum(["adr", "capability", "feature", "glossary"]))
31
+ .optional()
32
+ .describe("Restrict the search to specific document kinds."),
33
+ pin_to_commit: z
34
+ .string()
35
+ .optional()
36
+ .describe("Optional commit SHA (or any ref) to pin the SDD to. When set, the server reads from a git worktree at that commit rather than the working tree."),
37
+ },
38
+ }, async ({ query, limit, kinds, pin_to_commit }) => {
39
+ const reader = readerFor(sddRoot, pin_to_commit);
40
+ const tokens = query
41
+ .toLowerCase()
42
+ .split(/\s+/)
43
+ .filter((t) => t.length > 0);
44
+ if (tokens.length === 0) {
45
+ return {
46
+ content: [
47
+ {
48
+ type: "text",
49
+ text: JSON.stringify({ query, matches: [], sources: [], pin_to_commit: reader.pin }, null, 2),
50
+ },
51
+ ],
52
+ };
53
+ }
54
+ const activeKinds = new Set(kinds ?? ["adr", "capability", "feature", "glossary"]);
55
+ const docs = collectDocuments(reader.sddRoot, activeKinds);
56
+ const cap = limit ?? 10;
57
+ const hits = [];
58
+ for (const doc of docs) {
59
+ let body;
60
+ try {
61
+ body = readFileSync(doc.path, "utf8");
62
+ }
63
+ catch {
64
+ continue;
65
+ }
66
+ const lower = body.toLowerCase();
67
+ let score = 0;
68
+ for (const token of tokens) {
69
+ let idx = 0;
70
+ while ((idx = lower.indexOf(token, idx)) !== -1) {
71
+ score++;
72
+ idx += token.length;
73
+ }
74
+ }
75
+ if (score === 0)
76
+ continue;
77
+ hits.push({
78
+ uri: doc.uri,
79
+ kind: doc.kind,
80
+ score,
81
+ snippet: buildSnippet(body, lower, tokens[0]),
82
+ });
83
+ }
84
+ hits.sort((a, b) => b.score - a.score);
85
+ const top = hits.slice(0, cap);
86
+ const payload = {
87
+ query,
88
+ kinds: Array.from(activeKinds),
89
+ limit: cap,
90
+ total_hits: hits.length,
91
+ returned: top.length,
92
+ matches: top,
93
+ sources: top.map((h) => h.uri),
94
+ pin_to_commit: reader.pin,
95
+ };
96
+ return {
97
+ content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
98
+ };
99
+ });
100
+ }
101
+ function collectDocuments(sddRoot, kinds) {
102
+ const out = [];
103
+ if (kinds.has("adr")) {
104
+ for (const adr of discoverAdrs(sddRoot)) {
105
+ out.push({
106
+ uri: `sdd://adrs/${adr.scope}/${adr.number}`,
107
+ path: adr.path,
108
+ kind: "adr",
109
+ });
110
+ }
111
+ }
112
+ if (kinds.has("capability")) {
113
+ for (const c of discoverCapabilitySpecs(sddRoot)) {
114
+ out.push({
115
+ uri: `sdd://specs/capability/${c.domain}/${c.capability}`,
116
+ path: c.path,
117
+ kind: "capability",
118
+ });
119
+ }
120
+ }
121
+ if (kinds.has("feature")) {
122
+ for (const f of discoverFeatureSpecs(sddRoot)) {
123
+ out.push({
124
+ uri: `sdd://specs/feature/${f.domain}/${f.capability}/${f.feature}`,
125
+ path: f.path,
126
+ kind: "feature",
127
+ });
128
+ }
129
+ }
130
+ if (kinds.has("glossary")) {
131
+ for (const g of discoverGlossaries(sddRoot)) {
132
+ out.push({
133
+ uri: `sdd://glossary/${g.scope}`,
134
+ path: g.path,
135
+ kind: "glossary",
136
+ });
137
+ }
138
+ }
139
+ return out;
140
+ }
141
+ function buildSnippet(body, bodyLower, firstToken) {
142
+ const idx = bodyLower.indexOf(firstToken);
143
+ if (idx === -1)
144
+ return body.slice(0, 160);
145
+ const start = Math.max(0, idx - 60);
146
+ const end = Math.min(body.length, idx + firstToken.length + 60);
147
+ const prefix = start === 0 ? "" : "…";
148
+ const suffix = end === body.length ? "" : "…";
149
+ return prefix + body.slice(start, end).replace(/\s+/g, " ").trim() + suffix;
150
+ }
151
+ //# sourceMappingURL=search-specs.js.map