forgecraft-mcp 1.4.0 → 1.7.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 (418) hide show
  1. package/LICENSE +67 -0
  2. package/README.md +527 -525
  3. package/dist/analyzers/anchors/anchor-loader.d.ts +47 -0
  4. package/dist/analyzers/anchors/anchor-loader.d.ts.map +1 -0
  5. package/dist/analyzers/anchors/anchor-loader.js +113 -0
  6. package/dist/analyzers/anchors/anchor-loader.js.map +1 -0
  7. package/dist/analyzers/anti-pattern.d.ts.map +1 -1
  8. package/dist/analyzers/anti-pattern.js +38 -26
  9. package/dist/analyzers/anti-pattern.js.map +1 -1
  10. package/dist/analyzers/completeness-helpers.d.ts +5 -0
  11. package/dist/analyzers/completeness-helpers.d.ts.map +1 -1
  12. package/dist/analyzers/completeness-helpers.js +17 -0
  13. package/dist/analyzers/completeness-helpers.js.map +1 -1
  14. package/dist/analyzers/completeness.d.ts.map +1 -1
  15. package/dist/analyzers/completeness.js +4 -4
  16. package/dist/analyzers/completeness.js.map +1 -1
  17. package/dist/analyzers/gs-scorer.d.ts +3 -1
  18. package/dist/analyzers/gs-scorer.d.ts.map +1 -1
  19. package/dist/analyzers/gs-scorer.js +5 -2
  20. package/dist/analyzers/gs-scorer.js.map +1 -1
  21. package/dist/analyzers/package-json.d.ts.map +1 -1
  22. package/dist/analyzers/package-json.js +194 -34
  23. package/dist/analyzers/package-json.js.map +1 -1
  24. package/dist/analyzers/scorers/composable-scorer.d.ts +4 -2
  25. package/dist/analyzers/scorers/composable-scorer.d.ts.map +1 -1
  26. package/dist/analyzers/scorers/composable-scorer.js +50 -2
  27. package/dist/analyzers/scorers/composable-scorer.js.map +1 -1
  28. package/dist/analyzers/scorers/executable-scorer.d.ts +3 -2
  29. package/dist/analyzers/scorers/executable-scorer.d.ts.map +1 -1
  30. package/dist/analyzers/scorers/executable-scorer.js +64 -4
  31. package/dist/analyzers/scorers/executable-scorer.js.map +1 -1
  32. package/dist/analyzers/scorers/scorer-utils.d.ts +5 -3
  33. package/dist/analyzers/scorers/scorer-utils.d.ts.map +1 -1
  34. package/dist/analyzers/scorers/scorer-utils.js +34 -9
  35. package/dist/analyzers/scorers/scorer-utils.js.map +1 -1
  36. package/dist/analyzers/scorers/self-describing-scorer.d.ts +7 -4
  37. package/dist/analyzers/scorers/self-describing-scorer.d.ts.map +1 -1
  38. package/dist/analyzers/scorers/self-describing-scorer.js +17 -18
  39. package/dist/analyzers/scorers/self-describing-scorer.js.map +1 -1
  40. package/dist/cli/help.js +51 -51
  41. package/dist/disciplines/catalog.d.ts +16 -0
  42. package/dist/disciplines/catalog.d.ts.map +1 -0
  43. package/dist/disciplines/catalog.js +196 -0
  44. package/dist/disciplines/catalog.js.map +1 -0
  45. package/dist/disciplines/runner.d.ts +13 -0
  46. package/dist/disciplines/runner.d.ts.map +1 -0
  47. package/dist/disciplines/runner.js +35 -0
  48. package/dist/disciplines/runner.js.map +1 -0
  49. package/dist/registry/composer.d.ts.map +1 -1
  50. package/dist/registry/composer.js +9 -4
  51. package/dist/registry/composer.js.map +1 -1
  52. package/dist/registry/loader-tag.d.ts.map +1 -1
  53. package/dist/registry/loader-tag.js +1 -0
  54. package/dist/registry/loader-tag.js.map +1 -1
  55. package/dist/registry/remote-gates.js +1 -1
  56. package/dist/registry/remote-gates.js.map +1 -1
  57. package/dist/registry/renderer-skeletons.js +92 -92
  58. package/dist/registry/sentinel-renderer.js +299 -20
  59. package/dist/registry/sentinel-renderer.js.map +1 -1
  60. package/dist/sentinel/detect.d.ts +41 -0
  61. package/dist/sentinel/detect.d.ts.map +1 -0
  62. package/dist/sentinel/detect.js +122 -0
  63. package/dist/sentinel/detect.js.map +1 -0
  64. package/dist/sentinel/write.d.ts +54 -0
  65. package/dist/sentinel/write.d.ts.map +1 -0
  66. package/dist/sentinel/write.js +75 -0
  67. package/dist/sentinel/write.js.map +1 -0
  68. package/dist/shared/cnt-health.d.ts +16 -0
  69. package/dist/shared/cnt-health.d.ts.map +1 -1
  70. package/dist/shared/cnt-health.js +55 -8
  71. package/dist/shared/cnt-health.js.map +1 -1
  72. package/dist/shared/config.d.ts +14 -0
  73. package/dist/shared/config.d.ts.map +1 -1
  74. package/dist/shared/config.js +45 -0
  75. package/dist/shared/config.js.map +1 -1
  76. package/dist/shared/gs-score-logger.js +6 -6
  77. package/dist/shared/hook-installer.d.ts +58 -0
  78. package/dist/shared/hook-installer.d.ts.map +1 -0
  79. package/dist/shared/hook-installer.js +316 -0
  80. package/dist/shared/hook-installer.js.map +1 -0
  81. package/dist/shared/project-gates-helpers.d.ts +9 -0
  82. package/dist/shared/project-gates-helpers.d.ts.map +1 -1
  83. package/dist/shared/project-gates-helpers.js +35 -0
  84. package/dist/shared/project-gates-helpers.js.map +1 -1
  85. package/dist/shared/types/config.d.ts +7 -1
  86. package/dist/shared/types/config.d.ts.map +1 -1
  87. package/dist/shared/types/gates.d.ts +34 -0
  88. package/dist/shared/types/gates.d.ts.map +1 -1
  89. package/dist/shared/types/project.d.ts +68 -2
  90. package/dist/shared/types/project.d.ts.map +1 -1
  91. package/dist/shared/types/project.js +1 -0
  92. package/dist/shared/types/project.js.map +1 -1
  93. package/dist/shared/types/templates.d.ts +8 -1
  94. package/dist/shared/types/templates.d.ts.map +1 -1
  95. package/dist/shared/types/verify.d.ts +51 -1
  96. package/dist/shared/types/verify.d.ts.map +1 -1
  97. package/dist/shared/types/verify.js +37 -1
  98. package/dist/shared/types/verify.js.map +1 -1
  99. package/dist/tools/add-hook.d.ts.map +1 -1
  100. package/dist/tools/add-hook.js +8 -1
  101. package/dist/tools/add-hook.js.map +1 -1
  102. package/dist/tools/add-module.js +123 -123
  103. package/dist/tools/advice-registry.d.ts.map +1 -1
  104. package/dist/tools/advice-registry.js +108 -18
  105. package/dist/tools/advice-registry.js.map +1 -1
  106. package/dist/tools/advise-session-advisor.d.ts +16 -0
  107. package/dist/tools/advise-session-advisor.d.ts.map +1 -0
  108. package/dist/tools/advise-session-advisor.js +89 -0
  109. package/dist/tools/advise-session-advisor.js.map +1 -0
  110. package/dist/tools/advise-session-signals.d.ts +21 -0
  111. package/dist/tools/advise-session-signals.d.ts.map +1 -0
  112. package/dist/tools/advise-session-signals.js +113 -0
  113. package/dist/tools/advise-session-signals.js.map +1 -0
  114. package/dist/tools/advise-session.d.ts +22 -0
  115. package/dist/tools/advise-session.d.ts.map +1 -0
  116. package/dist/tools/advise-session.js +31 -0
  117. package/dist/tools/advise-session.js.map +1 -0
  118. package/dist/tools/analyze-harness.d.ts +18 -0
  119. package/dist/tools/analyze-harness.d.ts.map +1 -0
  120. package/dist/tools/analyze-harness.js +298 -0
  121. package/dist/tools/analyze-harness.js.map +1 -0
  122. package/dist/tools/audit.d.ts.map +1 -1
  123. package/dist/tools/audit.js +19 -0
  124. package/dist/tools/audit.js.map +1 -1
  125. package/dist/tools/change-request.d.ts +53 -0
  126. package/dist/tools/change-request.d.ts.map +1 -0
  127. package/dist/tools/change-request.js +395 -0
  128. package/dist/tools/change-request.js.map +1 -0
  129. package/dist/tools/check-cascade-contracts.d.ts +13 -0
  130. package/dist/tools/check-cascade-contracts.d.ts.map +1 -1
  131. package/dist/tools/check-cascade-contracts.js +73 -2
  132. package/dist/tools/check-cascade-contracts.js.map +1 -1
  133. package/dist/tools/check-cascade-report.js +64 -64
  134. package/dist/tools/check-cascade-steps.d.ts +3 -0
  135. package/dist/tools/check-cascade-steps.d.ts.map +1 -1
  136. package/dist/tools/check-cascade-steps.js +104 -15
  137. package/dist/tools/check-cascade-steps.js.map +1 -1
  138. package/dist/tools/check-cascade.d.ts +4 -3
  139. package/dist/tools/check-cascade.d.ts.map +1 -1
  140. package/dist/tools/check-cascade.js +30 -12
  141. package/dist/tools/check-cascade.js.map +1 -1
  142. package/dist/tools/check-derivation-chain.d.ts +37 -0
  143. package/dist/tools/check-derivation-chain.d.ts.map +1 -0
  144. package/dist/tools/check-derivation-chain.js +418 -0
  145. package/dist/tools/check-derivation-chain.js.map +1 -0
  146. package/dist/tools/check-spec-consistency.d.ts +25 -0
  147. package/dist/tools/check-spec-consistency.d.ts.map +1 -0
  148. package/dist/tools/check-spec-consistency.js +339 -0
  149. package/dist/tools/check-spec-consistency.js.map +1 -0
  150. package/dist/tools/check-t4.d.ts +54 -0
  151. package/dist/tools/check-t4.d.ts.map +1 -0
  152. package/dist/tools/check-t4.js +305 -0
  153. package/dist/tools/check-t4.js.map +1 -0
  154. package/dist/tools/close-cycle.d.ts +11 -0
  155. package/dist/tools/close-cycle.d.ts.map +1 -1
  156. package/dist/tools/close-cycle.js +364 -4
  157. package/dist/tools/close-cycle.js.map +1 -1
  158. package/dist/tools/cnt-add-routing.d.ts +31 -0
  159. package/dist/tools/cnt-add-routing.d.ts.map +1 -0
  160. package/dist/tools/cnt-add-routing.js +99 -0
  161. package/dist/tools/cnt-add-routing.js.map +1 -0
  162. package/dist/tools/configure-mcp.d.ts.map +1 -1
  163. package/dist/tools/configure-mcp.js +52 -2
  164. package/dist/tools/configure-mcp.js.map +1 -1
  165. package/dist/tools/consolidate-status.d.ts +31 -0
  166. package/dist/tools/consolidate-status.d.ts.map +1 -1
  167. package/dist/tools/consolidate-status.js +105 -0
  168. package/dist/tools/consolidate-status.js.map +1 -1
  169. package/dist/tools/executable-gates.d.ts +52 -0
  170. package/dist/tools/executable-gates.d.ts.map +1 -0
  171. package/dist/tools/executable-gates.js +333 -0
  172. package/dist/tools/executable-gates.js.map +1 -0
  173. package/dist/tools/extract-adrs-from-spec.d.ts +33 -0
  174. package/dist/tools/extract-adrs-from-spec.d.ts.map +1 -0
  175. package/dist/tools/extract-adrs-from-spec.js +410 -0
  176. package/dist/tools/extract-adrs-from-spec.js.map +1 -0
  177. package/dist/tools/extract-adrs-history.d.ts +47 -0
  178. package/dist/tools/extract-adrs-history.d.ts.map +1 -0
  179. package/dist/tools/extract-adrs-history.js +265 -0
  180. package/dist/tools/extract-adrs-history.js.map +1 -0
  181. package/dist/tools/forgecraft-dispatch-extended.d.ts.map +1 -1
  182. package/dist/tools/forgecraft-dispatch-extended.js +137 -0
  183. package/dist/tools/forgecraft-dispatch-extended.js.map +1 -1
  184. package/dist/tools/forgecraft-dispatch.d.ts.map +1 -1
  185. package/dist/tools/forgecraft-dispatch.js +16 -0
  186. package/dist/tools/forgecraft-dispatch.js.map +1 -1
  187. package/dist/tools/forgecraft-schema-params.d.ts +174 -2
  188. package/dist/tools/forgecraft-schema-params.d.ts.map +1 -1
  189. package/dist/tools/forgecraft-schema-params.js +197 -0
  190. package/dist/tools/forgecraft-schema-params.js.map +1 -1
  191. package/dist/tools/forgecraft-schema.d.ts +179 -7
  192. package/dist/tools/forgecraft-schema.d.ts.map +1 -1
  193. package/dist/tools/forgecraft-schema.js +37 -0
  194. package/dist/tools/forgecraft-schema.js.map +1 -1
  195. package/dist/tools/generate-adr.js +6 -6
  196. package/dist/tools/generate-adr.js.map +1 -1
  197. package/dist/tools/generate-decision.d.ts +77 -0
  198. package/dist/tools/generate-decision.d.ts.map +1 -0
  199. package/dist/tools/generate-decision.js +162 -0
  200. package/dist/tools/generate-decision.js.map +1 -0
  201. package/dist/tools/generate-env-probe.d.ts +49 -0
  202. package/dist/tools/generate-env-probe.d.ts.map +1 -0
  203. package/dist/tools/generate-env-probe.js +365 -0
  204. package/dist/tools/generate-env-probe.js.map +1 -0
  205. package/dist/tools/generate-harness.d.ts +53 -0
  206. package/dist/tools/generate-harness.d.ts.map +1 -0
  207. package/dist/tools/generate-harness.js +395 -0
  208. package/dist/tools/generate-harness.js.map +1 -0
  209. package/dist/tools/generate-roadmap.d.ts +1 -1
  210. package/dist/tools/generate-roadmap.d.ts.map +1 -1
  211. package/dist/tools/generate-roadmap.js +38 -4
  212. package/dist/tools/generate-roadmap.js.map +1 -1
  213. package/dist/tools/generate-session-prompt.d.ts +3 -3
  214. package/dist/tools/generate-session-prompt.d.ts.map +1 -1
  215. package/dist/tools/generate-session-prompt.js +9 -1
  216. package/dist/tools/generate-session-prompt.js.map +1 -1
  217. package/dist/tools/generate-slo-probe.d.ts +53 -0
  218. package/dist/tools/generate-slo-probe.d.ts.map +1 -0
  219. package/dist/tools/generate-slo-probe.js +366 -0
  220. package/dist/tools/generate-slo-probe.js.map +1 -0
  221. package/dist/tools/layer-status-gates.d.ts +24 -0
  222. package/dist/tools/layer-status-gates.d.ts.map +1 -0
  223. package/dist/tools/layer-status-gates.js +151 -0
  224. package/dist/tools/layer-status-gates.js.map +1 -0
  225. package/dist/tools/layer-status.d.ts +126 -0
  226. package/dist/tools/layer-status.d.ts.map +1 -0
  227. package/dist/tools/layer-status.js +647 -0
  228. package/dist/tools/layer-status.js.map +1 -0
  229. package/dist/tools/list.d.ts.map +1 -1
  230. package/dist/tools/list.js +9 -5
  231. package/dist/tools/list.js.map +1 -1
  232. package/dist/tools/postcondition-coverage.d.ts +57 -0
  233. package/dist/tools/postcondition-coverage.d.ts.map +1 -0
  234. package/dist/tools/postcondition-coverage.js +256 -0
  235. package/dist/tools/postcondition-coverage.js.map +1 -0
  236. package/dist/tools/probe-runners.d.ts +21 -0
  237. package/dist/tools/probe-runners.d.ts.map +1 -0
  238. package/dist/tools/probe-runners.js +246 -0
  239. package/dist/tools/probe-runners.js.map +1 -0
  240. package/dist/tools/probe-templates.d.ts +27 -0
  241. package/dist/tools/probe-templates.d.ts.map +1 -0
  242. package/dist/tools/probe-templates.js +279 -0
  243. package/dist/tools/probe-templates.js.map +1 -0
  244. package/dist/tools/propose-session.d.ts +28 -0
  245. package/dist/tools/propose-session.d.ts.map +1 -0
  246. package/dist/tools/propose-session.js +333 -0
  247. package/dist/tools/propose-session.js.map +1 -0
  248. package/dist/tools/refresh-output.js +14 -14
  249. package/dist/tools/review-stubs.d.ts +29 -0
  250. package/dist/tools/review-stubs.d.ts.map +1 -0
  251. package/dist/tools/review-stubs.js +173 -0
  252. package/dist/tools/review-stubs.js.map +1 -0
  253. package/dist/tools/roadmap-builder.d.ts +49 -1
  254. package/dist/tools/roadmap-builder.d.ts.map +1 -1
  255. package/dist/tools/roadmap-builder.js +210 -5
  256. package/dist/tools/roadmap-builder.js.map +1 -1
  257. package/dist/tools/run-env-probe.d.ts +57 -0
  258. package/dist/tools/run-env-probe.d.ts.map +1 -0
  259. package/dist/tools/run-env-probe.js +270 -0
  260. package/dist/tools/run-env-probe.js.map +1 -0
  261. package/dist/tools/run-harness.d.ts +52 -0
  262. package/dist/tools/run-harness.d.ts.map +1 -0
  263. package/dist/tools/run-harness.js +279 -0
  264. package/dist/tools/run-harness.js.map +1 -0
  265. package/dist/tools/run-slo-probe.d.ts +50 -0
  266. package/dist/tools/run-slo-probe.d.ts.map +1 -0
  267. package/dist/tools/run-slo-probe.js +281 -0
  268. package/dist/tools/run-slo-probe.js.map +1 -0
  269. package/dist/tools/scaffold-spec-stubs.js +115 -115
  270. package/dist/tools/scaffold-templates.js +62 -62
  271. package/dist/tools/scaffold-writer.d.ts.map +1 -1
  272. package/dist/tools/scaffold-writer.js +9 -0
  273. package/dist/tools/scaffold-writer.js.map +1 -1
  274. package/dist/tools/score-rubric.d.ts +19 -0
  275. package/dist/tools/score-rubric.d.ts.map +1 -0
  276. package/dist/tools/score-rubric.js +411 -0
  277. package/dist/tools/score-rubric.js.map +1 -0
  278. package/dist/tools/session-prompt-builders.d.ts +20 -0
  279. package/dist/tools/session-prompt-builders.d.ts.map +1 -1
  280. package/dist/tools/session-prompt-builders.js +78 -5
  281. package/dist/tools/session-prompt-builders.js.map +1 -1
  282. package/dist/tools/session-prompt-sections.d.ts +4 -2
  283. package/dist/tools/session-prompt-sections.d.ts.map +1 -1
  284. package/dist/tools/session-prompt-sections.js +22 -10
  285. package/dist/tools/session-prompt-sections.js.map +1 -1
  286. package/dist/tools/setup-artifact-writers.d.ts +69 -4
  287. package/dist/tools/setup-artifact-writers.d.ts.map +1 -1
  288. package/dist/tools/setup-artifact-writers.js +681 -5
  289. package/dist/tools/setup-artifact-writers.js.map +1 -1
  290. package/dist/tools/setup-cnt-builders.d.ts.map +1 -1
  291. package/dist/tools/setup-cnt-builders.js +162 -34
  292. package/dist/tools/setup-cnt-builders.js.map +1 -1
  293. package/dist/tools/setup-monitoring.d.ts +41 -0
  294. package/dist/tools/setup-monitoring.d.ts.map +1 -0
  295. package/dist/tools/setup-monitoring.js +364 -0
  296. package/dist/tools/setup-monitoring.js.map +1 -0
  297. package/dist/tools/setup-phase1.d.ts.map +1 -1
  298. package/dist/tools/setup-phase1.js +14 -1
  299. package/dist/tools/setup-phase1.js.map +1 -1
  300. package/dist/tools/setup-phase2.d.ts +14 -0
  301. package/dist/tools/setup-phase2.d.ts.map +1 -1
  302. package/dist/tools/setup-phase2.js +130 -3
  303. package/dist/tools/setup-phase2.js.map +1 -1
  304. package/dist/tools/setup-project.d.ts +8 -0
  305. package/dist/tools/setup-project.d.ts.map +1 -1
  306. package/dist/tools/setup-project.js +52 -2
  307. package/dist/tools/setup-project.js.map +1 -1
  308. package/dist/tools/spec-parser-tags.d.ts.map +1 -1
  309. package/dist/tools/spec-parser-tags.js +1 -0
  310. package/dist/tools/spec-parser-tags.js.map +1 -1
  311. package/dist/tools/verify-formatter.d.ts.map +1 -1
  312. package/dist/tools/verify-formatter.js +15 -1
  313. package/dist/tools/verify-formatter.js.map +1 -1
  314. package/dist/tools/verify.d.ts.map +1 -1
  315. package/dist/tools/verify.js +3 -0
  316. package/dist/tools/verify.js.map +1 -1
  317. package/package.json +98 -89
  318. package/templates/analytics/instructions.yaml +37 -37
  319. package/templates/analytics/mcp-servers.yaml +11 -11
  320. package/templates/analytics/structure.yaml +25 -25
  321. package/templates/api/harness/uc-template.hurl +20 -0
  322. package/templates/api/instructions.yaml +231 -231
  323. package/templates/api/mcp-servers.yaml +22 -22
  324. package/templates/api/nfr.yaml +23 -23
  325. package/templates/api/review.yaml +103 -103
  326. package/templates/api/structure.yaml +34 -34
  327. package/templates/api/verification.yaml +132 -132
  328. package/templates/cli/instructions.yaml +31 -31
  329. package/templates/cli/mcp-servers.yaml +11 -11
  330. package/templates/cli/review.yaml +53 -53
  331. package/templates/cli/structure.yaml +16 -16
  332. package/templates/data-lineage/instructions.yaml +28 -28
  333. package/templates/data-lineage/mcp-servers.yaml +22 -22
  334. package/templates/data-pipeline/instructions.yaml +84 -84
  335. package/templates/data-pipeline/mcp-servers.yaml +13 -13
  336. package/templates/data-pipeline/nfr.yaml +39 -39
  337. package/templates/data-pipeline/structure.yaml +23 -23
  338. package/templates/docs-manifest.yaml +227 -0
  339. package/templates/fintech/hooks.yaml +55 -55
  340. package/templates/fintech/instructions.yaml +112 -112
  341. package/templates/fintech/mcp-servers.yaml +13 -13
  342. package/templates/fintech/nfr.yaml +46 -46
  343. package/templates/fintech/playbook.yaml +210 -210
  344. package/templates/fintech/verification.yaml +239 -239
  345. package/templates/game/harness/uc-template.sim.ts +29 -0
  346. package/templates/game/instructions.yaml +289 -289
  347. package/templates/game/mcp-servers.yaml +38 -38
  348. package/templates/game/nfr.yaml +64 -64
  349. package/templates/game/playbook.yaml +214 -214
  350. package/templates/game/review.yaml +97 -97
  351. package/templates/game/structure.yaml +67 -67
  352. package/templates/game/verification.yaml +174 -174
  353. package/templates/healthcare/instructions.yaml +42 -42
  354. package/templates/healthcare/mcp-servers.yaml +13 -13
  355. package/templates/healthcare/nfr.yaml +47 -47
  356. package/templates/hipaa/instructions.yaml +41 -41
  357. package/templates/hipaa/mcp-servers.yaml +13 -13
  358. package/templates/infra/instructions.yaml +104 -104
  359. package/templates/infra/mcp-servers.yaml +20 -20
  360. package/templates/infra/nfr.yaml +46 -46
  361. package/templates/infra/review.yaml +65 -65
  362. package/templates/infra/structure.yaml +25 -25
  363. package/templates/library/instructions.yaml +36 -36
  364. package/templates/library/mcp-servers.yaml +20 -20
  365. package/templates/library/review.yaml +56 -56
  366. package/templates/library/structure.yaml +19 -19
  367. package/templates/medallion-architecture/instructions.yaml +41 -41
  368. package/templates/medallion-architecture/mcp-servers.yaml +22 -22
  369. package/templates/ml/instructions.yaml +85 -85
  370. package/templates/ml/mcp-servers.yaml +11 -11
  371. package/templates/ml/nfr.yaml +39 -39
  372. package/templates/ml/structure.yaml +25 -25
  373. package/templates/ml/verification.yaml +156 -156
  374. package/templates/mobile/instructions.yaml +44 -44
  375. package/templates/mobile/mcp-servers.yaml +11 -11
  376. package/templates/mobile/nfr.yaml +49 -49
  377. package/templates/mobile/structure.yaml +27 -27
  378. package/templates/mobile/verification.yaml +121 -121
  379. package/templates/observability-xray/instructions.yaml +40 -40
  380. package/templates/observability-xray/mcp-servers.yaml +15 -15
  381. package/templates/realtime/instructions.yaml +42 -42
  382. package/templates/realtime/mcp-servers.yaml +13 -13
  383. package/templates/soc2/instructions.yaml +41 -41
  384. package/templates/soc2/mcp-servers.yaml +24 -24
  385. package/templates/social/instructions.yaml +43 -43
  386. package/templates/social/mcp-servers.yaml +24 -24
  387. package/templates/state-machine/instructions.yaml +42 -42
  388. package/templates/state-machine/mcp-servers.yaml +11 -11
  389. package/templates/tools-registry.yaml +164 -164
  390. package/templates/universal/claude-md-blocks/layer-navigation.md +20 -0
  391. package/templates/universal/claude-md-blocks/nfr-contracts.md +22 -0
  392. package/templates/universal/hooks.yaml +879 -723
  393. package/templates/universal/instructions.yaml +1692 -1692
  394. package/templates/universal/mcp-servers.yaml +50 -50
  395. package/templates/universal/nfr.yaml +197 -197
  396. package/templates/universal/reference.yaml +326 -326
  397. package/templates/universal/review.yaml +204 -204
  398. package/templates/universal/skills.yaml +262 -262
  399. package/templates/universal/structure.yaml +67 -67
  400. package/templates/universal/verification.yaml +416 -416
  401. package/templates/web-next/hooks.yaml +114 -0
  402. package/templates/web-next/instructions.yaml +106 -0
  403. package/templates/web-react/harness/uc-template.spec.ts +35 -0
  404. package/templates/web-react/hooks.yaml +156 -44
  405. package/templates/web-react/instructions.yaml +296 -207
  406. package/templates/web-react/mcp-servers.yaml +20 -20
  407. package/templates/web-react/nfr.yaml +27 -27
  408. package/templates/web-react/review.yaml +94 -94
  409. package/templates/web-react/structure.yaml +46 -46
  410. package/templates/web-react/verification.yaml +126 -126
  411. package/templates/web-static/hooks.yaml +85 -0
  412. package/templates/web-static/instructions.yaml +204 -115
  413. package/templates/web-static/mcp-servers.yaml +20 -20
  414. package/templates/web3/instructions.yaml +44 -44
  415. package/templates/web3/mcp-servers.yaml +11 -11
  416. package/templates/web3/verification.yaml +159 -159
  417. package/templates/zero-trust/instructions.yaml +41 -41
  418. package/templates/zero-trust/mcp-servers.yaml +15 -15
@@ -0,0 +1,162 @@
1
+ /**
2
+ * generate_decision tool handler.
3
+ *
4
+ * Emits a structured Decision/Post-mortem record into docs/decisions/ —
5
+ * the GS taxonomy slot for non-architectural one-pagers: bug-fix interpretations,
6
+ * operational tweaks, "we chose X over Y because Z" notes that don't warrant a
7
+ * full ADR.
8
+ *
9
+ * Encouraged on `fix:` commits (per cascade) and required when a bug-postmortem
10
+ * change_request reaches `verified` status.
11
+ *
12
+ * Output file: docs/decisions/YYYY-MM-DD-slug.md
13
+ * Format: Trigger / Root cause / Fix / Regression test / Chronicle link.
14
+ */
15
+ import { z } from "zod";
16
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
17
+ import { join } from "node:path";
18
+ import { createLogger } from "../shared/logger/index.js";
19
+ const logger = createLogger("tools/generate-decision");
20
+ const DECISION_DIR = join("docs", "decisions");
21
+ // ── Schema ───────────────────────────────────────────────────────────
22
+ export const generateDecisionSchema = z.object({
23
+ project_dir: z
24
+ .string()
25
+ .describe("Absolute path to the project root. Decision is written to {project_dir}/docs/decisions/."),
26
+ title: z
27
+ .string()
28
+ .describe("Short imperative title of the decision/post-mortem (e.g. 'Drop duplicate task_id rows on import'). " +
29
+ "Becomes the slug in the filename and the H1 heading."),
30
+ trigger: z
31
+ .string()
32
+ .optional()
33
+ .describe("What surfaced this decision — bug symptom, incident, support ticket, observed behavior. " +
34
+ "If omitted, a placeholder is written."),
35
+ root_cause: z
36
+ .string()
37
+ .optional()
38
+ .describe("Why it happened — the underlying defect, missing guard, or design oversight. " +
39
+ "If omitted, a placeholder is written."),
40
+ fix: z
41
+ .string()
42
+ .optional()
43
+ .describe("What was changed (code, config, or behavior) and why this fix was chosen over alternatives. " +
44
+ "If omitted, a placeholder is written."),
45
+ regression_test: z
46
+ .string()
47
+ .optional()
48
+ .describe("Test or gate that locks this fix in (test name, gate id, monitor). " +
49
+ "If omitted, a placeholder is written — required for fix: commits per cascade."),
50
+ chronicle_session_id: z
51
+ .string()
52
+ .optional()
53
+ .describe("Optional chronicle session id where the investigation was recorded. " +
54
+ "Links the post-mortem back to its individual-memory provenance."),
55
+ related_adr: z
56
+ .string()
57
+ .optional()
58
+ .describe("Optional ADR id this decision touches or refines (e.g. 'ADR-0007'). " +
59
+ "Use when the bug exposed an architectural assumption — promotes traceability."),
60
+ });
61
+ // ── Handler ──────────────────────────────────────────────────────────
62
+ /**
63
+ * Generate and write a structured decision/post-mortem file.
64
+ *
65
+ * @param args - Validated tool input
66
+ * @returns MCP tool response with the written file path and content
67
+ */
68
+ export async function generateDecisionHandler(args) {
69
+ const { project_dir, title } = args;
70
+ const decisionDir = join(project_dir, DECISION_DIR);
71
+ if (!existsSync(decisionDir)) {
72
+ mkdirSync(decisionDir, { recursive: true });
73
+ logger.info("Created docs/decisions/ directory", { decisionDir });
74
+ }
75
+ const date = new Date().toISOString().slice(0, 10);
76
+ const slug = titleToSlug(title);
77
+ const filename = `${date}-${slug}.md`;
78
+ const filePath = join(decisionDir, filename);
79
+ const relativePath = join(DECISION_DIR, filename).replace(/\\/g, "/");
80
+ if (existsSync(filePath)) {
81
+ return {
82
+ content: [
83
+ {
84
+ type: "text",
85
+ text: `Decision file already exists: ${relativePath}\nChoose a different title or edit the existing file directly.`,
86
+ },
87
+ ],
88
+ };
89
+ }
90
+ const content = renderDecision({
91
+ date,
92
+ title,
93
+ trigger: args.trigger,
94
+ root_cause: args.root_cause,
95
+ fix: args.fix,
96
+ regression_test: args.regression_test,
97
+ chronicle_session_id: args.chronicle_session_id,
98
+ related_adr: args.related_adr,
99
+ });
100
+ writeFileSync(filePath, content, "utf-8");
101
+ logger.info("Decision written", { filePath, date, slug });
102
+ const lines = [
103
+ `# Decision Written`,
104
+ ``,
105
+ `**File:** \`${relativePath}\``,
106
+ `**Date:** ${date}`,
107
+ `**Title:** ${title}`,
108
+ ``,
109
+ `## Content`,
110
+ ``,
111
+ "```markdown",
112
+ content,
113
+ "```",
114
+ ``,
115
+ `> **Next step:** Resolve any \`[NEEDS CLARIFICATION]\` markers — especially the regression test, which is required by the \`fix:\` cascade.`,
116
+ args.chronicle_session_id
117
+ ? `> Chronicle session \`${args.chronicle_session_id}\` is linked — keep that record alive while this decision is current.`
118
+ : `> If this decision came out of a chronicle session, re-run with \`chronicle_session_id\` to link the investigation.`,
119
+ ];
120
+ return { content: [{ type: "text", text: lines.join("\n") }] };
121
+ }
122
+ // ── Helpers ──────────────────────────────────────────────────────────
123
+ /**
124
+ * Convert a title string to a URL-safe kebab-case slug.
125
+ * Strips punctuation, lowercases, replaces spaces/underscores with hyphens.
126
+ */
127
+ export function titleToSlug(title) {
128
+ return title
129
+ .toLowerCase()
130
+ .replace(/[^a-z0-9\s_-]/g, "")
131
+ .trim()
132
+ .replace(/[\s_]+/g, "-")
133
+ .replace(/-{2,}/g, "-")
134
+ .slice(0, 60);
135
+ }
136
+ /**
137
+ * Render a complete decision/post-mortem document from the provided fields.
138
+ */
139
+ export function renderDecision(fields) {
140
+ const { date, title, trigger, root_cause, fix, regression_test, chronicle_session_id, related_adr, } = fields;
141
+ const lines = [
142
+ `# ${title}`,
143
+ ``,
144
+ `**Date:** ${date}`,
145
+ `**Type:** Decision / Post-mortem`,
146
+ ];
147
+ if (related_adr) {
148
+ lines.push(`**Related ADR:** ${related_adr}`);
149
+ }
150
+ if (chronicle_session_id) {
151
+ lines.push(`**Chronicle session:** \`${chronicle_session_id}\``);
152
+ }
153
+ lines.push(``, `## Trigger`, ``, trigger ??
154
+ "[NEEDS CLARIFICATION: what surfaced this — bug symptom, incident, support ticket, observed behavior]", ``, `## Root Cause`, ``, root_cause ??
155
+ "[NEEDS CLARIFICATION: why it happened — the underlying defect, missing guard, or design oversight]", ``, `## Fix`, ``, fix ??
156
+ "[NEEDS CLARIFICATION: what was changed (code, config, behavior) and why this fix was chosen]", ``, `## Regression Test`, ``, regression_test ??
157
+ "[NEEDS CLARIFICATION: test name, gate id, or monitor that locks this fix in — REQUIRED by fix: cascade]", ``, `## Chronicle Link`, ``, chronicle_session_id
158
+ ? `Investigation recorded in chronicle session \`${chronicle_session_id}\`. Pull notes/prompts from there before editing this file.`
159
+ : "[OPTIONAL: chronicle session id if the investigation was recorded — leave empty if this was a one-shot fix]", ``, `---`, ``, `_This decision record was generated by ForgeCraft. Resolve any [NEEDS CLARIFICATION] sections before merging — the cascade gate will block a \`fix:\` PR whose regression test is unresolved._`);
160
+ return lines.join("\n");
161
+ }
162
+ //# sourceMappingURL=generate-decision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-decision.js","sourceRoot":"","sources":["../../src/tools/generate-decision.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * generate_env_probe tool handler.
3
+ *
4
+ * Reads environment probe specs from .forgecraft/env/*.yaml and scaffolds
5
+ * executable probe files in tests/env/. Idempotent — skips existing unless force=true.
6
+ */
7
+ import { z } from "zod";
8
+ import type { ToolResult } from "../shared/types.js";
9
+ export declare const generateEnvProbeSchema: z.ZodObject<{
10
+ project_dir: z.ZodString;
11
+ force: z.ZodOptional<z.ZodBoolean>;
12
+ }, "strip", z.ZodTypeAny, {
13
+ project_dir: string;
14
+ force?: boolean | undefined;
15
+ }, {
16
+ project_dir: string;
17
+ force?: boolean | undefined;
18
+ }>;
19
+ export type GenerateEnvProbeInput = z.infer<typeof generateEnvProbeSchema>;
20
+ export interface EnvProbeSpec {
21
+ service: string;
22
+ title?: string;
23
+ probes?: Array<{
24
+ id: string;
25
+ type: string;
26
+ description?: string;
27
+ url?: string;
28
+ vars?: string[];
29
+ host?: string;
30
+ port?: number;
31
+ }>;
32
+ }
33
+ export interface EnvGenerateResult {
34
+ service: string;
35
+ probeId: string;
36
+ probeType: string;
37
+ probeFile: string;
38
+ status: "generated" | "skipped" | "error";
39
+ reason?: string;
40
+ }
41
+ export declare function envExtensionForType(probeType: string): string;
42
+ export declare function generateEnvProbeContent(service: string, probeId: string, probeType: string, description: string, extra?: {
43
+ url?: string;
44
+ vars?: string[];
45
+ host?: string;
46
+ port?: number;
47
+ }): string;
48
+ export declare function generateEnvProbeHandler(args: GenerateEnvProbeInput): Promise<ToolResult>;
49
+ //# sourceMappingURL=generate-env-probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-env-probe.d.ts","sourceRoot":"","sources":["../../src/tools/generate-env-probe.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,eAAO,MAAM,sBAAsB;;;;;;;;;EAMjC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAI3E,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAiB7D;AA2ND,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACtE,MAAM,CAsCR;AAID,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,UAAU,CAAC,CA+GrB"}
@@ -0,0 +1,365 @@
1
+ /**
2
+ * generate_env_probe tool handler.
3
+ *
4
+ * Reads environment probe specs from .forgecraft/env/*.yaml and scaffolds
5
+ * executable probe files in tests/env/. Idempotent — skips existing unless force=true.
6
+ */
7
+ import { z } from "zod";
8
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, } from "node:fs";
9
+ import { join, resolve } from "node:path";
10
+ import yaml from "js-yaml";
11
+ // ── Schema ───────────────────────────────────────────────────────────
12
+ export const generateEnvProbeSchema = z.object({
13
+ project_dir: z.string().describe("Absolute path to the project root."),
14
+ force: z
15
+ .boolean()
16
+ .optional()
17
+ .describe("Overwrite existing probe files. Default: false."),
18
+ });
19
+ // ── Probe type → file extension ───────────────────────────────────────
20
+ export function envExtensionForType(probeType) {
21
+ switch (probeType) {
22
+ case "health_check":
23
+ return ".health.sh";
24
+ case "env_var":
25
+ return ".env.sh";
26
+ case "port_check":
27
+ return ".port.sh";
28
+ case "schema_validate":
29
+ return ".schema.sh";
30
+ case "docker_check":
31
+ return ".docker.sh";
32
+ case "migration_check":
33
+ return ".migration.sh";
34
+ default:
35
+ return ".sh";
36
+ }
37
+ }
38
+ // ── Probe content generators ──────────────────────────────────────────
39
+ function generateHealthCheckContent(service, probeId, description, url) {
40
+ const targetUrl = url ?? "http://{{host}}:{{port}}/health";
41
+ return `#!/usr/bin/env bash
42
+ # Service: ${service}
43
+ # Probe: ${probeId}
44
+ # Type: health_check
45
+ # Description: ${description}
46
+ set -euo pipefail
47
+
48
+ # TODO: set actual health endpoint URL
49
+ URL="${targetUrl}"
50
+
51
+ if ! command -v curl &>/dev/null; then
52
+ echo "FAIL: curl not found — cannot run health check"
53
+ exit 1
54
+ fi
55
+
56
+ HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$URL" || echo "000")
57
+
58
+ if [ "$HTTP_STATUS" = "200" ]; then
59
+ echo "PASS: ${probeId} — health endpoint returned 200"
60
+ else
61
+ echo "FAIL: ${probeId} — health endpoint returned $HTTP_STATUS (expected 200)"
62
+ exit 1
63
+ fi
64
+ `;
65
+ }
66
+ function generateEnvVarContent(service, probeId, description, vars) {
67
+ const varList = vars && vars.length > 0 ? vars : ["# TODO: add required env var names"];
68
+ const checkLines = vars && vars.length > 0
69
+ ? vars
70
+ .map((v) => `if [ -z "\${${v}:-}" ]; then\n echo "FAIL: ${probeId} — required env var ${v} is not set or empty"\n exit 1\nfi`)
71
+ .join("\n")
72
+ : `# TODO: check required env vars\necho "TODO: implement env var checks for ${probeId}"\nexit 1`;
73
+ return `#!/usr/bin/env bash
74
+ # Service: ${service}
75
+ # Probe: ${probeId}
76
+ # Type: env_var
77
+ # Description: ${description}
78
+ # Required vars: ${varList.join(", ")}
79
+ set -euo pipefail
80
+
81
+ ${checkLines}
82
+
83
+ echo "PASS: ${probeId} — all required env vars are set"
84
+ `;
85
+ }
86
+ function generatePortCheckContent(service, probeId, description, host, port) {
87
+ const targetHost = host ?? "{{db_host}}";
88
+ const targetPort = port ?? 5432;
89
+ return `#!/usr/bin/env bash
90
+ # Service: ${service}
91
+ # Probe: ${probeId}
92
+ # Type: port_check
93
+ # Description: ${description}
94
+ set -euo pipefail
95
+
96
+ # TODO: set actual host and port
97
+ HOST="${targetHost}"
98
+ PORT="${targetPort}"
99
+
100
+ if command -v nc &>/dev/null; then
101
+ if nc -z -w 5 "$HOST" "$PORT" 2>/dev/null; then
102
+ echo "PASS: ${probeId} — port $HOST:$PORT is reachable"
103
+ else
104
+ echo "FAIL: ${probeId} — port $HOST:$PORT is not reachable"
105
+ exit 1
106
+ fi
107
+ elif command -v curl &>/dev/null; then
108
+ if curl -s --max-time 5 "telnet://$HOST:$PORT" &>/dev/null || curl -s --connect-timeout 5 "$HOST:$PORT" &>/dev/null; then
109
+ echo "PASS: ${probeId} — port $HOST:$PORT is reachable"
110
+ else
111
+ echo "FAIL: ${probeId} — port $HOST:$PORT is not reachable"
112
+ exit 1
113
+ fi
114
+ else
115
+ echo "FAIL: ${probeId} — neither nc nor curl found"
116
+ exit 1
117
+ fi
118
+ `;
119
+ }
120
+ function generateSchemaValidateContent(service, probeId, description) {
121
+ return `#!/usr/bin/env bash
122
+ # Service: ${service}
123
+ # Probe: ${probeId}
124
+ # Type: schema_validate
125
+ # Description: ${description}
126
+ set -euo pipefail
127
+
128
+ # TODO: set path to .env.example and actual env file
129
+ ENV_EXAMPLE=".env.example"
130
+ ENV_FILE=".env"
131
+
132
+ if [ ! -f "$ENV_EXAMPLE" ]; then
133
+ echo "FAIL: ${probeId} — .env.example not found at $ENV_EXAMPLE"
134
+ exit 1
135
+ fi
136
+
137
+ MISSING=()
138
+ while IFS= read -r line; do
139
+ # Extract var name (skip comments and empty lines)
140
+ [[ "$line" =~ ^#.*$ || -z "$line" ]] && continue
141
+ VAR_NAME=$(echo "$line" | cut -d= -f1)
142
+ if [ -z "\${!VAR_NAME:-}" ]; then
143
+ MISSING+=("$VAR_NAME")
144
+ fi
145
+ done < "$ENV_EXAMPLE"
146
+
147
+ if [ \${#MISSING[@]} -gt 0 ]; then
148
+ echo "FAIL: ${probeId} — missing env vars: \${MISSING[*]}"
149
+ exit 1
150
+ fi
151
+
152
+ echo "PASS: ${probeId} — env schema validated against .env.example"
153
+ `;
154
+ }
155
+ function generateDockerCheckContent(service, probeId, description) {
156
+ return `#!/usr/bin/env bash
157
+ # Service: ${service}
158
+ # Probe: ${probeId}
159
+ # Type: docker_check
160
+ # Description: ${description}
161
+ set -euo pipefail
162
+
163
+ # TODO: set actual container name
164
+ CONTAINER_NAME="${service}"
165
+
166
+ if ! command -v docker &>/dev/null; then
167
+ echo "FAIL: ${probeId} — docker not found"
168
+ exit 1
169
+ fi
170
+
171
+ if docker compose ps --format json 2>/dev/null | grep -q "$CONTAINER_NAME"; then
172
+ STATUS=$(docker compose ps --format json 2>/dev/null | grep "$CONTAINER_NAME" | grep -o '"State":"[^"]*"' | head -1)
173
+ if echo "$STATUS" | grep -q '"running"'; then
174
+ echo "PASS: ${probeId} — container $CONTAINER_NAME is running"
175
+ else
176
+ echo "FAIL: ${probeId} — container $CONTAINER_NAME is not running: $STATUS"
177
+ exit 1
178
+ fi
179
+ elif docker ps --filter "name=$CONTAINER_NAME" --format "{{.Status}}" 2>/dev/null | grep -q "Up"; then
180
+ echo "PASS: ${probeId} — container $CONTAINER_NAME is running"
181
+ else
182
+ echo "FAIL: ${probeId} — container $CONTAINER_NAME is not running"
183
+ exit 1
184
+ fi
185
+ `;
186
+ }
187
+ function generateMigrationCheckContent(service, probeId, description) {
188
+ return `#!/usr/bin/env bash
189
+ # Service: ${service}
190
+ # Probe: ${probeId}
191
+ # Type: migration_check
192
+ # Description: ${description}
193
+ set -euo pipefail
194
+
195
+ DB_URL="\${DATABASE_URL:-}"
196
+ if [ -z "$DB_URL" ]; then
197
+ echo "FAIL: ${probeId} — DATABASE_URL not set"
198
+ exit 1
199
+ fi
200
+
201
+ # TODO: adapt to your migration tool (prisma, flyway, liquibase, etc.)
202
+ if command -v prisma &>/dev/null; then
203
+ PENDING=$(npx prisma migrate status 2>&1 | grep -c "pending" || true)
204
+ if [ "$PENDING" -gt 0 ]; then
205
+ echo "FAIL: ${probeId} — $PENDING pending migration(s)"
206
+ exit 1
207
+ fi
208
+ echo "PASS: ${probeId} — no pending migrations"
209
+ else
210
+ echo "TODO: implement migration check for ${probeId} — set up migration tool"
211
+ exit 1
212
+ fi
213
+ `;
214
+ }
215
+ export function generateEnvProbeContent(service, probeId, probeType, description, extra) {
216
+ switch (probeType) {
217
+ case "health_check":
218
+ return generateHealthCheckContent(service, probeId, description, extra?.url);
219
+ case "env_var":
220
+ return generateEnvVarContent(service, probeId, description, extra?.vars);
221
+ case "port_check":
222
+ return generatePortCheckContent(service, probeId, description, extra?.host, extra?.port);
223
+ case "schema_validate":
224
+ return generateSchemaValidateContent(service, probeId, description);
225
+ case "docker_check":
226
+ return generateDockerCheckContent(service, probeId, description);
227
+ case "migration_check":
228
+ return generateMigrationCheckContent(service, probeId, description);
229
+ default:
230
+ return `#!/usr/bin/env bash
231
+ # Service: ${service}
232
+ # Probe: ${probeId}
233
+ # Type: ${probeType}
234
+ # Description: ${description}
235
+ set -euo pipefail
236
+
237
+ # TODO: implement probe check for ${probeId}
238
+ echo "TODO: implement ${probeId}"
239
+ exit 1
240
+ `;
241
+ }
242
+ }
243
+ // ── Handler ───────────────────────────────────────────────────────────
244
+ export async function generateEnvProbeHandler(args) {
245
+ const projectDir = resolve(args.project_dir);
246
+ const force = args.force ?? false;
247
+ const envSpecDir = join(projectDir, ".forgecraft", "env");
248
+ if (!existsSync(envSpecDir)) {
249
+ return {
250
+ content: [
251
+ {
252
+ type: "text",
253
+ text: "No env probe specs found. Create .forgecraft/env/service.yaml to define environment contracts.",
254
+ },
255
+ ],
256
+ };
257
+ }
258
+ // Read all spec files
259
+ let specFiles = [];
260
+ try {
261
+ specFiles = readdirSync(envSpecDir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
262
+ }
263
+ catch {
264
+ specFiles = [];
265
+ }
266
+ if (specFiles.length === 0) {
267
+ return {
268
+ content: [
269
+ {
270
+ type: "text",
271
+ text: "No env probe specs found. Create .forgecraft/env/service.yaml to define environment contracts.",
272
+ },
273
+ ],
274
+ };
275
+ }
276
+ const envDir = join(projectDir, "tests", "env");
277
+ try {
278
+ mkdirSync(envDir, { recursive: true });
279
+ }
280
+ catch {
281
+ /* ignore */
282
+ }
283
+ const results = [];
284
+ for (const specFile of specFiles) {
285
+ let spec;
286
+ try {
287
+ const raw = readFileSync(join(envSpecDir, specFile), "utf-8");
288
+ spec = yaml.load(raw);
289
+ }
290
+ catch {
291
+ continue;
292
+ }
293
+ if (!spec?.service || !spec.probes)
294
+ continue;
295
+ for (const probe of spec.probes) {
296
+ const ext = envExtensionForType(probe.type);
297
+ const fileName = `${spec.service}-${probe.id}${ext}`;
298
+ const filePath = join(envDir, fileName);
299
+ const relPath = `tests/env/${fileName}`;
300
+ if (existsSync(filePath) && !force) {
301
+ results.push({
302
+ service: spec.service,
303
+ probeId: probe.id,
304
+ probeType: probe.type,
305
+ probeFile: relPath,
306
+ status: "skipped",
307
+ reason: "already exists",
308
+ });
309
+ continue;
310
+ }
311
+ const content = generateEnvProbeContent(spec.service, probe.id, probe.type, probe.description ?? probe.id, {
312
+ url: probe.url,
313
+ vars: probe.vars,
314
+ host: probe.host,
315
+ port: probe.port,
316
+ });
317
+ try {
318
+ writeFileSync(filePath, content, "utf-8");
319
+ results.push({
320
+ service: spec.service,
321
+ probeId: probe.id,
322
+ probeType: probe.type,
323
+ probeFile: relPath,
324
+ status: "generated",
325
+ });
326
+ }
327
+ catch (err) {
328
+ results.push({
329
+ service: spec.service,
330
+ probeId: probe.id,
331
+ probeType: probe.type,
332
+ probeFile: relPath,
333
+ status: "error",
334
+ reason: `write failed: ${String(err)}`,
335
+ });
336
+ }
337
+ }
338
+ }
339
+ return { content: [{ type: "text", text: formatEnvReport(results) }] };
340
+ }
341
+ // ── Report formatter ──────────────────────────────────────────────────
342
+ function formatEnvReport(results) {
343
+ const generated = results.filter((r) => r.status === "generated");
344
+ const skipped = results.filter((r) => r.status === "skipped");
345
+ const noSpec = results.filter((r) => r.status === "error");
346
+ const lines = [
347
+ "## Env Probe Generation Report",
348
+ "",
349
+ `Generated: ${generated.length} Skipped: ${skipped.length} No spec: ${noSpec.length}`,
350
+ "",
351
+ "| Service | Probe | Type | File | Status |",
352
+ "|---|---|---|---|---|",
353
+ ];
354
+ for (const r of results) {
355
+ const statusLabel = r.status === "generated"
356
+ ? "✅ generated"
357
+ : r.status === "skipped"
358
+ ? "⏭ skipped"
359
+ : `❌ error: ${r.reason ?? ""}`;
360
+ lines.push(`| ${r.service} | ${r.probeId} | ${r.probeType} | ${r.probeFile} | ${statusLabel} |`);
361
+ }
362
+ lines.push("", "To run: call run_env_probe");
363
+ return lines.join("\n");
364
+ }
365
+ //# sourceMappingURL=generate-env-probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-env-probe.js","sourceRoot":"","sources":["../../src/tools/generate-env-probe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * generate_harness tool handler.
3
+ *
4
+ * Reads UC specs from docs/use-cases.md and probe blueprints from
5
+ * .forgecraft/harness/uc-NNN.yaml, then scaffolds executable probe files
6
+ * in tests/harness/. Idempotent: skips existing files unless force=true.
7
+ */
8
+ import { z } from "zod";
9
+ import type { ToolResult } from "../shared/types.js";
10
+ export declare const generateHarnessSchema: z.ZodObject<{
11
+ project_dir: z.ZodString;
12
+ uc_ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
13
+ force: z.ZodOptional<z.ZodBoolean>;
14
+ }, "strip", z.ZodTypeAny, {
15
+ project_dir: string;
16
+ force?: boolean | undefined;
17
+ uc_ids?: string[] | undefined;
18
+ }, {
19
+ project_dir: string;
20
+ force?: boolean | undefined;
21
+ uc_ids?: string[] | undefined;
22
+ }>;
23
+ export type GenerateHarnessInput = z.infer<typeof generateHarnessSchema>;
24
+ export interface ProbeSpec {
25
+ uc: string;
26
+ title: string;
27
+ action?: string;
28
+ probes?: Array<{
29
+ id: string;
30
+ type: string;
31
+ scenario?: string;
32
+ description?: string;
33
+ }>;
34
+ }
35
+ export type ProbeType = "playwright" | "api_call" | "hurl" | "graphql" | "file_system" | "mcp_call" | "headless_sim" | "db_query" | "message_queue" | "performance" | "websocket" | "log_assertion" | "a11y" | "contract_consumer" | "contract_provider" | "grpc" | "security_scan";
36
+ export interface GenerateResult {
37
+ ucId: string;
38
+ title: string;
39
+ status: "generated" | "skipped" | "no_spec";
40
+ probeFile?: string;
41
+ probeType?: string;
42
+ reason?: string;
43
+ autoSpec?: boolean;
44
+ }
45
+ export interface ErrorCase {
46
+ name: string;
47
+ slug: string;
48
+ description: string;
49
+ }
50
+ export declare function extensionForType(probeType: ProbeType): string;
51
+ export declare function parseErrorCases(ucSection: string): ErrorCase[];
52
+ export declare function generateHarnessHandler(args: GenerateHarnessInput): Promise<ToolResult>;
53
+ //# sourceMappingURL=generate-harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-harness.d.ts","sourceRoot":"","sources":["../../src/tools/generate-harness.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;EAehC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAIzE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;CACJ;AAED,MAAM,MAAM,SAAS,GACjB,YAAY,GACZ,UAAU,GACV,MAAM,GACN,SAAS,GACT,aAAa,GACb,UAAU,GACV,cAAc,GACd,UAAU,GACV,eAAe,GACf,aAAa,GACb,WAAW,GACX,eAAe,GACf,MAAM,GACN,mBAAmB,GACnB,mBAAmB,GACnB,MAAM,GACN,eAAe,CAAC;AAEpB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AA8BD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAoC7D;AAID,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,CAyB9D;AA0ND,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,UAAU,CAAC,CAqIrB"}