@webpresso/agent-kit 3.1.30 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @webpresso/agent-kit might be problematic. Click here for more details.

Files changed (300) hide show
  1. package/README.md +53 -15
  2. package/bin/_run.js +183 -20
  3. package/catalog/AGENTS.md.tpl +3 -3
  4. package/catalog/agent/agents/implementer.md +45 -0
  5. package/catalog/agent/rules/parallel-orchestration-quota.md +100 -0
  6. package/catalog/agent/rules/pre-implementation.md +28 -1
  7. package/catalog/agent/rules/supported-agent-clis.md +9 -0
  8. package/catalog/agent/rules/typescript-version.md +50 -0
  9. package/catalog/agent/skills/codex/SKILL.md +25 -1
  10. package/catalog/agent/skills/verify/SKILL.md +4 -2
  11. package/catalog/docs/templates/blueprint.md +1 -1
  12. package/dist/esm/audit/agents.js +1 -0
  13. package/dist/esm/audit/blueprint-lifecycle-sql.d.ts +12 -0
  14. package/dist/esm/audit/blueprint-lifecycle-sql.js +23 -2
  15. package/dist/esm/audit/blueprint-pr-coverage.js +4 -0
  16. package/dist/esm/audit/blueprint-trust.js +14 -10
  17. package/dist/esm/audit/changeset-evidence.d.ts +23 -0
  18. package/dist/esm/audit/changeset-evidence.js +30 -0
  19. package/dist/esm/audit/changeset-required.d.ts +10 -0
  20. package/dist/esm/audit/changeset-required.js +73 -0
  21. package/dist/esm/audit/ci-guardrails-detection.d.ts +27 -0
  22. package/dist/esm/audit/ci-guardrails-detection.js +68 -0
  23. package/dist/esm/audit/ci-guardrails-wiring.d.ts +22 -0
  24. package/dist/esm/audit/ci-guardrails-wiring.js +80 -0
  25. package/dist/esm/audit/ci-test-perf.js +30 -0
  26. package/dist/esm/audit/command-surface.js +4 -2
  27. package/dist/esm/audit/host-substitution-risk.d.ts +2 -0
  28. package/dist/esm/audit/host-substitution-risk.js +256 -0
  29. package/dist/esm/audit/registry.d.ts +4 -4
  30. package/dist/esm/audit/registry.js +13 -1
  31. package/dist/esm/audit/toolchain-isolation.js +1 -2
  32. package/dist/esm/audit/typescript-version.d.ts +2 -0
  33. package/dist/esm/audit/typescript-version.js +123 -0
  34. package/dist/esm/blueprint/core/parser.js +101 -2
  35. package/dist/esm/blueprint/core/schema.d.ts +1 -0
  36. package/dist/esm/blueprint/core/schema.js +26 -0
  37. package/dist/esm/blueprint/core/validation/criteria.d.ts +14 -0
  38. package/dist/esm/blueprint/core/validation/criteria.js +41 -2
  39. package/dist/esm/blueprint/core/validation/state.js +25 -14
  40. package/dist/esm/blueprint/db/migrations/run.js +4 -2
  41. package/dist/esm/blueprint/lifecycle/audit.d.ts +20 -0
  42. package/dist/esm/blueprint/lifecycle/audit.js +87 -20
  43. package/dist/esm/blueprint/lifecycle/canonicalize.d.ts +6 -0
  44. package/dist/esm/blueprint/lifecycle/canonicalize.js +135 -0
  45. package/dist/esm/blueprint/lifecycle/local.d.ts +2 -1
  46. package/dist/esm/blueprint/lifecycle/local.js +19 -3
  47. package/dist/esm/blueprint/lifecycle/review-provenance.d.ts +6 -0
  48. package/dist/esm/blueprint/lifecycle/review-provenance.js +68 -12
  49. package/dist/esm/blueprint/lifecycle/rollout-anchor.d.ts +97 -0
  50. package/dist/esm/blueprint/lifecycle/rollout-anchor.js +161 -0
  51. package/dist/esm/blueprint/service/BlueprintCreationService.d.ts +1 -0
  52. package/dist/esm/blueprint/service/BlueprintCreationService.js +53 -4
  53. package/dist/esm/blueprint/service/blueprint-tech-debt-links.js +16 -2
  54. package/dist/esm/blueprint/sync/client.d.ts +2 -1
  55. package/dist/esm/blueprint/sync/client.js +1 -1
  56. package/dist/esm/blueprint/trust/command-runner.d.ts +26 -0
  57. package/dist/esm/blueprint/trust/command-runner.js +148 -0
  58. package/dist/esm/blueprint/trust/dossier.d.ts +1 -0
  59. package/dist/esm/blueprint/trust/dossier.js +40 -6
  60. package/dist/esm/blueprint/trust/gates.d.ts +7 -0
  61. package/dist/esm/blueprint/trust/gates.js +20 -0
  62. package/dist/esm/blueprint/trust/promotion.d.ts +8 -0
  63. package/dist/esm/blueprint/trust/promotion.js +74 -112
  64. package/dist/esm/blueprint/trust/scaffold.d.ts +19 -0
  65. package/dist/esm/blueprint/trust/scaffold.js +64 -0
  66. package/dist/esm/blueprint/trust/validator.d.ts +1 -0
  67. package/dist/esm/blueprint/trust/validator.js +7 -1
  68. package/dist/esm/blueprint/utils/archive.js +27 -5
  69. package/dist/esm/blueprint/utils/document-paths.d.ts +18 -0
  70. package/dist/esm/blueprint/utils/document-paths.js +45 -12
  71. package/dist/esm/build/cli-mcp-parity.js +15 -0
  72. package/dist/esm/cli/bundle/commands/blueprint.d.ts +1 -0
  73. package/dist/esm/cli/bundle/commands/blueprint.js +1 -0
  74. package/dist/esm/cli/cli.d.ts +1 -1
  75. package/dist/esm/cli/cli.js +43 -0
  76. package/dist/esm/cli/commands/agent-launch.d.ts +8 -1
  77. package/dist/esm/cli/commands/agent-launch.js +93 -4
  78. package/dist/esm/cli/commands/audit-core.d.ts +1 -1
  79. package/dist/esm/cli/commands/audit-core.js +8 -1
  80. package/dist/esm/cli/commands/audit.js +21 -5
  81. package/dist/esm/cli/commands/blueprint/execution.js +18 -6
  82. package/dist/esm/cli/commands/blueprint/mutations.js +59 -40
  83. package/dist/esm/cli/commands/blueprint/router-dispatch.d.ts +2 -1
  84. package/dist/esm/cli/commands/blueprint/router-dispatch.js +20 -1
  85. package/dist/esm/cli/commands/blueprint/router-output.d.ts +21 -0
  86. package/dist/esm/cli/commands/blueprint/router-output.js +48 -17
  87. package/dist/esm/cli/commands/blueprint/router.d.ts +7 -0
  88. package/dist/esm/cli/commands/blueprint/router.js +13 -1
  89. package/dist/esm/cli/commands/ci-preflight.d.ts +13 -2
  90. package/dist/esm/cli/commands/ci-preflight.js +30 -6
  91. package/dist/esm/cli/commands/compile.js +5 -31
  92. package/dist/esm/cli/commands/dash/delivery-status.d.ts +1 -0
  93. package/dist/esm/cli/commands/dash/delivery-status.js +11 -4
  94. package/dist/esm/cli/commands/doctor.js +5 -0
  95. package/dist/esm/cli/commands/hook.d.ts +5 -0
  96. package/dist/esm/cli/commands/hook.js +15 -9
  97. package/dist/esm/cli/commands/init/config.js +2 -2
  98. package/dist/esm/cli/commands/init/convergence-apply.d.ts +88 -0
  99. package/dist/esm/cli/commands/init/convergence-apply.js +325 -0
  100. package/dist/esm/cli/commands/init/convergence-state.d.ts +13 -0
  101. package/dist/esm/cli/commands/init/convergence-state.js +54 -0
  102. package/dist/esm/cli/commands/init/convergence.d.ts +23 -0
  103. package/dist/esm/cli/commands/init/convergence.js +57 -0
  104. package/dist/esm/cli/commands/init/git-convergence.d.ts +19 -0
  105. package/dist/esm/cli/commands/init/git-convergence.js +168 -0
  106. package/dist/esm/cli/commands/init/gitignore-patcher.js +2 -0
  107. package/dist/esm/cli/commands/init/grok-privacy-smoke.d.ts +52 -0
  108. package/dist/esm/cli/commands/init/grok-privacy-smoke.js +91 -0
  109. package/dist/esm/cli/commands/init/host-native-proof.d.ts +18 -0
  110. package/dist/esm/cli/commands/init/host-native-proof.js +88 -0
  111. package/dist/esm/cli/commands/init/host-visibility.d.ts +2 -2
  112. package/dist/esm/cli/commands/init/host-visibility.js +94 -5
  113. package/dist/esm/cli/commands/init/index.d.ts +3 -0
  114. package/dist/esm/cli/commands/init/index.js +326 -173
  115. package/dist/esm/cli/commands/init/mcp-spec.d.ts +57 -0
  116. package/dist/esm/cli/commands/init/mcp-spec.js +273 -0
  117. package/dist/esm/cli/commands/init/merge.d.ts +1 -0
  118. package/dist/esm/cli/commands/init/merge.js +30 -1
  119. package/dist/esm/cli/commands/init/package-root.d.ts +7 -0
  120. package/dist/esm/cli/commands/init/package-root.js +10 -2
  121. package/dist/esm/cli/commands/init/plugin-cache-prune.d.ts +0 -3
  122. package/dist/esm/cli/commands/init/plugin-cache-prune.js +0 -1
  123. package/dist/esm/cli/commands/init/scaffold-agents-md.d.ts +1 -1
  124. package/dist/esm/cli/commands/init/scaffold-agents-md.js +9 -3
  125. package/dist/esm/cli/commands/init/scaffold-base-kit.d.ts +20 -0
  126. package/dist/esm/cli/commands/init/scaffold-base-kit.js +61 -5
  127. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.d.ts +14 -8
  128. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.js +41 -24
  129. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.d.ts +2 -0
  130. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +54 -24
  131. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.d.ts +12 -31
  132. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.js +288 -202
  133. package/dist/esm/cli/commands/init/scaffolders/file-transaction.d.ts +22 -0
  134. package/dist/esm/cli/commands/init/scaffolders/file-transaction.js +230 -0
  135. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.d.ts +38 -0
  136. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.js +73 -0
  137. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.d.ts +21 -0
  138. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.js +559 -63
  139. package/dist/esm/cli/commands/init/untracked-collision.d.ts +14 -0
  140. package/dist/esm/cli/commands/init/untracked-collision.js +42 -0
  141. package/dist/esm/cli/commands/opencode-probe.d.ts +107 -0
  142. package/dist/esm/cli/commands/opencode-probe.js +323 -0
  143. package/dist/esm/cli/commands/opencode-rotate.d.ts +72 -0
  144. package/dist/esm/cli/commands/opencode-rotate.js +147 -0
  145. package/dist/esm/cli/commands/public-readiness.d.ts +11 -0
  146. package/dist/esm/cli/commands/public-readiness.js +42 -0
  147. package/dist/esm/cli/commands/quality-runner.js +3 -3
  148. package/dist/esm/cli/commands/review.d.ts +35 -3
  149. package/dist/esm/cli/commands/review.js +751 -209
  150. package/dist/esm/cli/commands/run-wait.d.ts +2 -0
  151. package/dist/esm/cli/commands/run-wait.js +122 -0
  152. package/dist/esm/cli/commands/rust-check.d.ts +24 -0
  153. package/dist/esm/cli/commands/rust-check.js +110 -0
  154. package/dist/esm/cli/commands/setup-help.js +1 -1
  155. package/dist/esm/cli/commands/setup-repair-help.js +1 -1
  156. package/dist/esm/cli/commands/typecheck.d.ts +1 -0
  157. package/dist/esm/cli/commands/typecheck.js +30 -1
  158. package/dist/esm/cli/commands/worktree/router-dispatch.d.ts +6 -0
  159. package/dist/esm/cli/commands/worktree/router-dispatch.js +126 -9
  160. package/dist/esm/cli/commands/worktree/router.js +10 -0
  161. package/dist/esm/cli/direct-provider-launch.js +9 -5
  162. package/dist/esm/cli/optional-tool-freshness.d.ts +27 -0
  163. package/dist/esm/cli/optional-tool-freshness.js +219 -9
  164. package/dist/esm/daemon/domains/git-actions.d.ts +29 -0
  165. package/dist/esm/daemon/domains/git-actions.js +136 -0
  166. package/dist/esm/daemon/domains/run-registry-interop.d.ts +16 -0
  167. package/dist/esm/daemon/domains/run-registry-interop.js +45 -0
  168. package/dist/esm/daemon/domains/sessions-search.d.ts +11 -0
  169. package/dist/esm/daemon/domains/sessions-search.js +29 -0
  170. package/dist/esm/daemon/handlers/blueprints-handlers.d.ts +5 -0
  171. package/dist/esm/daemon/handlers/blueprints-handlers.js +36 -0
  172. package/dist/esm/daemon/handlers/deploy-handlers.d.ts +6 -0
  173. package/dist/esm/daemon/handlers/deploy-handlers.js +5 -0
  174. package/dist/esm/daemon/handlers/fleet-handlers.d.ts +15 -0
  175. package/dist/esm/daemon/handlers/fleet-handlers.js +91 -0
  176. package/dist/esm/daemon/handlers/git-handlers.d.ts +6 -0
  177. package/dist/esm/daemon/handlers/git-handlers.js +27 -0
  178. package/dist/esm/daemon/handlers/product.d.ts +7 -0
  179. package/dist/esm/daemon/handlers/product.js +10 -119
  180. package/dist/esm/daemon/handlers/sessions-handlers.d.ts +12 -0
  181. package/dist/esm/daemon/handlers/sessions-handlers.js +31 -0
  182. package/dist/esm/daemon/handlers/shared.d.ts +5 -0
  183. package/dist/esm/daemon/handlers/shared.js +16 -0
  184. package/dist/esm/daemon/methods.d.ts +8 -1
  185. package/dist/esm/daemon/methods.js +7 -0
  186. package/dist/esm/daemon/protocol/contract.d.ts +43 -0
  187. package/dist/esm/daemon/protocol/contract.js +26 -0
  188. package/dist/esm/daemon/protocol/index.d.ts +1 -1
  189. package/dist/esm/daemon/protocol/index.js +1 -1
  190. package/dist/esm/hooks/__conformance__/matrix.d.ts +6 -0
  191. package/dist/esm/hooks/__conformance__/matrix.js +137 -0
  192. package/dist/esm/hooks/conformance/batch.js +5 -0
  193. package/dist/esm/hooks/doctor.d.ts +5 -3
  194. package/dist/esm/hooks/doctor.js +67 -16
  195. package/dist/esm/hooks/permission-request/index.js +9 -3
  196. package/dist/esm/hooks/permission-request/policy.d.ts +9 -0
  197. package/dist/esm/hooks/permission-request/policy.js +13 -0
  198. package/dist/esm/hooks/pretool-guard/dev-routing.d.ts +9 -0
  199. package/dist/esm/hooks/pretool-guard/dev-routing.js +41 -5
  200. package/dist/esm/hooks/pretool-guard/logger.d.ts +7 -0
  201. package/dist/esm/hooks/pretool-guard/logger.js +16 -0
  202. package/dist/esm/hooks/pretool-guard/runner.d.ts +6 -0
  203. package/dist/esm/hooks/pretool-guard/runner.js +68 -16
  204. package/dist/esm/hooks/pretool-guard/validators/blueprint.js +30 -10
  205. package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +54 -0
  206. package/dist/esm/hooks/pretool-guard/validators/index.d.ts +7 -0
  207. package/dist/esm/hooks/pretool-guard/validators/index.js +21 -0
  208. package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +19 -0
  209. package/dist/esm/hooks/pretool-guard/validators/path-contract.js +25 -8
  210. package/dist/esm/hooks/pretool-guard/validators/worktree-discipline.js +6 -1
  211. package/dist/esm/hooks/shared/guard-outcome.d.ts +149 -0
  212. package/dist/esm/hooks/shared/guard-outcome.js +215 -0
  213. package/dist/esm/hooks/shared/hook-bootstrap.d.ts +26 -0
  214. package/dist/esm/hooks/shared/hook-bootstrap.js +64 -1
  215. package/dist/esm/hooks/shared/types.d.ts +8 -5
  216. package/dist/esm/hooks/shared/types.js +50 -9
  217. package/dist/esm/hooks/stop/qa-changed-files.d.ts +11 -0
  218. package/dist/esm/hooks/stop/qa-changed-files.js +92 -0
  219. package/dist/esm/mcp/blueprint/_shared/lifecycle.js +14 -1
  220. package/dist/esm/mcp/blueprint/handlers/document-mutations.d.ts +5 -0
  221. package/dist/esm/mcp/blueprint/handlers/document-mutations.js +109 -11
  222. package/dist/esm/mcp/blueprint/handlers/review-log.js +8 -1
  223. package/dist/esm/mcp/blueprint/handlers/task-advance.js +113 -54
  224. package/dist/esm/mcp/blueprint/handlers/task-verify.js +39 -19
  225. package/dist/esm/mcp/blueprint/registration.js +3 -2
  226. package/dist/esm/mcp/server.d.ts +1 -0
  227. package/dist/esm/mcp/server.js +27 -0
  228. package/dist/esm/mcp/tools/_names.d.ts +1 -1
  229. package/dist/esm/mcp/tools/_names.js +5 -0
  230. package/dist/esm/mcp/tools/_registry.js +10 -0
  231. package/dist/esm/mcp/tools/_shared/audit-kinds.d.ts +1 -1
  232. package/dist/esm/mcp/tools/_shared/result.js +44 -1
  233. package/dist/esm/mcp/tools/audit.d.ts +5 -1
  234. package/dist/esm/mcp/tools/audit.js +42 -0
  235. package/dist/esm/mcp/tools/audits.d.ts +4 -0
  236. package/dist/esm/mcp/tools/ci-preflight.d.ts +50 -0
  237. package/dist/esm/mcp/tools/ci-preflight.js +183 -0
  238. package/dist/esm/mcp/tools/pr-upsert.js +39 -1
  239. package/dist/esm/mcp/tools/review-run.d.ts +28 -0
  240. package/dist/esm/mcp/tools/review-run.js +216 -0
  241. package/dist/esm/mcp/tools/run-wait.d.ts +86 -0
  242. package/dist/esm/mcp/tools/run-wait.js +593 -0
  243. package/dist/esm/mcp/tools/session-fetch-and-index.d.ts +1 -1
  244. package/dist/esm/mcp/tools/session-id.d.ts +3 -0
  245. package/dist/esm/mcp/tools/session-id.js +45 -0
  246. package/dist/esm/mcp/tools/session-info.d.ts +3 -0
  247. package/dist/esm/mcp/tools/session-info.js +49 -0
  248. package/dist/esm/output-transforms/audit.d.ts +23 -0
  249. package/dist/esm/output-transforms/audit.js +47 -0
  250. package/dist/esm/output-transforms/index.js +2 -0
  251. package/dist/esm/package.json +2 -0
  252. package/dist/esm/platform/client.d.ts +7 -1
  253. package/dist/esm/platform/github-contract-source.d.ts +2 -1
  254. package/dist/esm/pr-description/contract.js +24 -4
  255. package/dist/esm/review/authority.js +27 -14
  256. package/dist/esm/review/availability.d.ts +33 -0
  257. package/dist/esm/review/availability.js +122 -20
  258. package/dist/esm/review/delivery-verifier.d.ts +27 -0
  259. package/dist/esm/review/delivery-verifier.js +115 -0
  260. package/dist/esm/review/events.d.ts +3 -2
  261. package/dist/esm/review/events.js +23 -3
  262. package/dist/esm/review/execution/adapters.d.ts +11 -1
  263. package/dist/esm/review/execution/adapters.js +36 -10
  264. package/dist/esm/review/execution/artifacts.d.ts +1 -1
  265. package/dist/esm/review/execution/output-policy.d.ts +2 -0
  266. package/dist/esm/review/execution/output-policy.js +12 -0
  267. package/dist/esm/review/execution/review-checkout.js +121 -21
  268. package/dist/esm/review/execution/supervisor.js +36 -4
  269. package/dist/esm/review/execution/types.d.ts +9 -0
  270. package/dist/esm/review/opencode-account.d.ts +24 -0
  271. package/dist/esm/review/opencode-account.js +68 -0
  272. package/dist/esm/review/opencode-auth.d.ts +33 -0
  273. package/dist/esm/review/opencode-auth.js +79 -0
  274. package/dist/esm/review/subject.d.ts +25 -0
  275. package/dist/esm/review/subject.js +116 -26
  276. package/dist/esm/runtime/opencode-account-materializer.d.ts +34 -0
  277. package/dist/esm/runtime/opencode-account-materializer.js +33 -0
  278. package/dist/esm/rust/affected-manifests.d.ts +38 -0
  279. package/dist/esm/rust/affected-manifests.js +69 -0
  280. package/dist/esm/session-memory/fetch-index.d.ts +1 -1
  281. package/dist/esm/status/snapshot.js +32 -25
  282. package/dist/esm/test/duration-sequencer.d.ts +20 -0
  283. package/dist/esm/test/duration-sequencer.js +54 -0
  284. package/dist/esm/test/shard-durations.json +922 -0
  285. package/dist/esm/test/worker-budget.d.ts +6 -0
  286. package/dist/esm/test/worker-budget.js +59 -1
  287. package/dist/esm/test-helpers/global-setup.d.ts +1 -2
  288. package/dist/esm/test-helpers/global-setup.js +79 -32
  289. package/dist/esm/typecheck/planner.d.ts +9 -1
  290. package/dist/esm/typecheck/planner.js +31 -0
  291. package/dist/esm/ultragoal/service.d.ts +7 -0
  292. package/dist/esm/ultragoal/service.js +42 -2
  293. package/dist/esm/utils/write-json-file.js +3 -1
  294. package/dist/esm/worktrees/codex-project-trust.d.ts +15 -0
  295. package/dist/esm/worktrees/codex-project-trust.js +56 -0
  296. package/dist/esm/worktrees/orphan-scan.d.ts +50 -0
  297. package/dist/esm/worktrees/orphan-scan.js +211 -0
  298. package/dist/esm/worktrees/registry.d.ts +8 -0
  299. package/dist/esm/worktrees/registry.js +18 -3
  300. package/package.json +18 -13
@@ -10,8 +10,9 @@ import { hashMutationPayload, readMutationReplay, recordMutationReplay, validate
10
10
  import { bytes } from "#mcp/blueprint/_shared/payload";
11
11
  import { findBlueprintDir, resolveToolProject } from "#mcp/blueprint/_shared/project";
12
12
  import { handleTaskNext } from "#mcp/blueprint/handlers/task-next";
13
- import { writeFileAtomic } from "#shared-utils/write-json-file.js";
14
- import { applyVerification, readTaskVerification } from "#verification.js";
13
+ import { readTaskVerification } from "#verification.js";
14
+ import { applyBlueprintLifecycle } from "#lifecycle/engine.js";
15
+ import { applyBlueprintLifecycleToFile } from "#lifecycle/local.js";
15
16
  const ALL_STATES = ["draft", "planned", "in-progress", "parked", "archived", "completed"];
16
17
  // Task 3.2 — wp_blueprint_task_verify
17
18
  const taskVerifySchema = z.object({
@@ -52,13 +53,31 @@ export async function handleTaskVerify(projectResolver, cwd, raw) {
52
53
  return err("wp_blueprint_task_verify failed", `Blueprint overview not found at ${filePath}`);
53
54
  }
54
55
  const markdownBefore = readFileSync(filePath, "utf8");
55
- // Idempotency check: if the task already has the same canonical evidence block, skip write.
56
- // We check this BEFORE calling applyVerification to avoid whitespace normalization drift
57
- // making `result.markdown !== markdownBefore` always true even for identical evidence.
58
56
  const incomingCanonical = canonicalizeEvidenceList(evidence);
59
57
  const existingEvidence = readTaskVerification(markdownBefore, task_id);
58
+ let result;
59
+ try {
60
+ result = applyBlueprintLifecycle(markdownBefore, slug, {
61
+ type: "task_verify",
62
+ taskId: task_id,
63
+ evidence,
64
+ });
65
+ }
66
+ catch (error) {
67
+ return jsonContent({
68
+ summary: "Verification failed",
69
+ failures: [error instanceof Error ? error.message : String(error)],
70
+ next_action: makeNextAction("verify_task", error instanceof Error ? error.message : String(error)),
71
+ bytes: 0,
72
+ tokensSaved: 0,
73
+ }, true);
74
+ }
75
+ // Idempotency includes all lifecycle-owned fields. Reapplying identical
76
+ // evidence repairs stale progress/last_updated metadata once, then becomes a
77
+ // byte-for-byte no-op.
60
78
  if (existingEvidence !== null &&
61
- canonicalizeEvidenceList(existingEvidence) === incomingCanonical) {
79
+ canonicalizeEvidenceList(existingEvidence) === incomingCanonical &&
80
+ result.markdown === markdownBefore) {
62
81
  const nextPayload = parseStructuredJson(await handleTaskNext(projectResolver, projectCwd, {
63
82
  blueprint: slug,
64
83
  project_id: resolvedProject.project_id ?? projectCwd,
@@ -82,19 +101,20 @@ export async function handleTaskVerify(projectResolver, cwd, raw) {
82
101
  }
83
102
  return finishPayload(payload);
84
103
  }
85
- // Apply verification (pure function no FS side effects)
86
- const result = applyVerification(markdownBefore, task_id, evidence);
87
- if (!result.ok) {
88
- return jsonContent({
89
- summary: "Verification failed",
90
- failures: result.failures,
91
- next_action: makeNextAction("verify_task", result.failures[0] ?? "Verification failed"),
92
- bytes: 0,
93
- tokensSaved: 0,
94
- }, true);
95
- }
96
- // Write updated markdown back to disk
97
- writeFileAtomic(filePath, result.markdown, "utf8");
104
+ // Write the mutated markdown back to disk via the file-aware lifecycle
105
+ // wrapper, not a raw write to the pre-mutation path: the pure engine call
106
+ // above can change the blueprint's frontmatter `status` (e.g. draft ->
107
+ // in-progress on the first task mutation), and that status change must be
108
+ // paired with the matching physical folder move -- the same contract the
109
+ // CLI router and BlueprintService already honor via
110
+ // applyBlueprintLifecycleToFile. Writing to the original `filePath`
111
+ // unconditionally would leave folder and status disagreeing whenever the
112
+ // blueprint started outside in-progress/.
113
+ await applyBlueprintLifecycleToFile(projectCwd, slug, {
114
+ type: "task_verify",
115
+ taskId: task_id,
116
+ evidence,
117
+ });
98
118
  // Re-ingest so the DB projection reflects the completed status
99
119
  try {
100
120
  await reIngest(projectCwd);
@@ -107,16 +107,17 @@ export async function registerBlueprintTools(registrar, cwd, projectResolver = c
107
107
  type: "object",
108
108
  properties: { blueprint: { type: "string" }, project_id: { type: "string" } },
109
109
  }, undefined, (r) => handleTaskNext(projectResolver, cwd, r), { title: "Blueprint Task Next", readOnlyHint: true, openWorldHint: false });
110
- registrar.registerTool("wp_blueprint_task_advance", "Advance task status. Edits the canonical blueprint markdown and re-syncs DB. Accepts optional request_id for idempotent retries and optional head_at_ingest from wp_blueprint_get/wp_blueprint_list to reject stale writes. Returns { summary, old_status, new_status, idempotent }.", {
110
+ registrar.registerTool("wp_blueprint_task_advance", "Advance task status within a specific blueprint. Requires slug to scope the mutation — task ids (e.g. 2.1) are not unique across blueprints in a project, so slug prevents advancing the wrong blueprint. Edits the canonical blueprint markdown and re-syncs DB. Accepts optional request_id for idempotent retries and optional head_at_ingest from wp_blueprint_get/wp_blueprint_list to reject stale writes. Returns { summary, old_status, new_status, idempotent }.", {
111
111
  type: "object",
112
112
  properties: {
113
113
  project_id: { type: "string" },
114
+ slug: { type: "string" },
114
115
  task_id: { type: "string" },
115
116
  to: { type: "string", enum: ["todo", "in-progress", "blocked", "done", "dropped"] },
116
117
  request_id: { type: "string" },
117
118
  head_at_ingest: { type: ["string", "null"] },
118
119
  },
119
- required: ["project_id", "task_id", "to"],
120
+ required: ["project_id", "slug", "task_id", "to"],
120
121
  }, {
121
122
  ...summaryEnvelopeOutputSchema,
122
123
  properties: {
@@ -7,6 +7,7 @@
7
7
  * — no edits required here.
8
8
  */
9
9
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
10
+ export declare function resolveMcpToolAllowlist(raw?: string | undefined): ReadonlySet<string> | null;
10
11
  export declare function isBunSingleFileModuleUrl(moduleUrl: string): boolean;
11
12
  export type ToolLoadMode = "filesystem" | "registry";
12
13
  export declare function resolveDefaultToolLoadMode(moduleUrl?: string): ToolLoadMode;
@@ -16,6 +16,24 @@ import { COMPILED_TOOL_REGISTRY } from "./tools/_registry.js";
16
16
  import { readOwnedPackageVersion } from "#runtime/package-version.js";
17
17
  const SERVER_NAME = "webpresso";
18
18
  const SERVER_VERSION = readOwnedPackageVersion(import.meta.url);
19
+ const MCP_TOOL_ALLOWLIST_ENV = "WP_MCP_TOOL_ALLOWLIST";
20
+ export function resolveMcpToolAllowlist(raw = process.env[MCP_TOOL_ALLOWLIST_ENV]) {
21
+ if (raw === undefined)
22
+ return null;
23
+ const names = raw
24
+ .split(",")
25
+ .map((name) => name.trim())
26
+ .filter(Boolean);
27
+ if (names.length === 0 || new Set(names).size !== names.length) {
28
+ throw new Error(`${MCP_TOOL_ALLOWLIST_ENV} must contain a non-empty, duplicate-free comma-separated tool list`);
29
+ }
30
+ for (const name of names) {
31
+ if (!/^wp_[a-z0-9_]+$/u.test(name)) {
32
+ throw new Error(`${MCP_TOOL_ALLOWLIST_ENV} contains invalid tool name: ${name}`);
33
+ }
34
+ }
35
+ return new Set(names);
36
+ }
19
37
  function modulePathFromUrl(moduleUrl) {
20
38
  try {
21
39
  return fileURLToPath(moduleUrl);
@@ -53,8 +71,11 @@ export async function createServer(options = {}) {
53
71
  },
54
72
  });
55
73
  const tools = new Map();
74
+ const allowlist = resolveMcpToolAllowlist();
56
75
  const registrar = {
57
76
  registerTool(name, description, inputSchema, outputSchema, handler, annotations) {
77
+ if (allowlist !== null && !allowlist.has(name))
78
+ return;
58
79
  tools.set(name, { name, description, inputSchema, outputSchema, handler, annotations });
59
80
  },
60
81
  };
@@ -90,6 +111,12 @@ export async function createServer(options = {}) {
90
111
  }
91
112
  },
92
113
  });
114
+ if (allowlist !== null) {
115
+ const missing = [...allowlist].filter((name) => !tools.has(name));
116
+ if (missing.length > 0) {
117
+ throw new Error(`${MCP_TOOL_ALLOWLIST_ENV} names unavailable tools: ${missing.sort().join(", ")}`);
118
+ }
119
+ }
93
120
  // Empty prompts/resources/resource-templates handlers, registered exactly
94
121
  // the same way other MCP servers do. Several MCP clients —
95
122
  // including Claude Code 2.1.x and OpenCode — call listPrompts() or
@@ -8,4 +8,4 @@
8
8
  * is enforced by `_names.test.ts` against `COMPILED_TOOL_REGISTRY`, so this list
9
9
  * cannot silently drift.
10
10
  */
11
- export declare const WP_TOOL_NAMES: readonly ["wp_audit", "wp_audits", "wp_bench", "wp_ci_act", "wp_e2e", "wp_fleet_status", "wp_format", "wp_gain", "wp_lint", "wp_pr_status", "wp_pr_upsert", "wp_pr_wait", "wp_qa", "wp_release_readiness", "wp_session_batch_execute", "wp_session_capture", "wp_session_context", "wp_session_doctor", "wp_session_execute", "wp_session_execute_file", "wp_session_fetch_and_index", "wp_session_index", "wp_session_purge", "wp_session_retrieve", "wp_session_restore", "wp_session_search", "wp_session_snapshot", "wp_session_stats", "wp_test", "wp_typecheck", "wp_ultragoal_cancel", "wp_ultragoal_handoff", "wp_ultragoal_new", "wp_ultragoal_run", "wp_ultragoal_status", "wp_worker_tail", "wp_worktree"];
11
+ export declare const WP_TOOL_NAMES: readonly ["wp_audit", "wp_audits", "wp_bench", "wp_ci_act", "wp_ci_preflight", "wp_e2e", "wp_fleet_status", "wp_format", "wp_gain", "wp_lint", "wp_pr_status", "wp_pr_upsert", "wp_pr_wait", "wp_qa", "wp_release_readiness", "wp_review_run", "wp_run_wait", "wp_session_batch_execute", "wp_session_capture", "wp_session_context", "wp_session_doctor", "wp_session_execute", "wp_session_execute_file", "wp_session_fetch_and_index", "wp_session_id", "wp_session_index", "wp_session_info", "wp_session_purge", "wp_session_retrieve", "wp_session_restore", "wp_session_search", "wp_session_snapshot", "wp_session_stats", "wp_test", "wp_typecheck", "wp_ultragoal_cancel", "wp_ultragoal_handoff", "wp_ultragoal_new", "wp_ultragoal_run", "wp_ultragoal_status", "wp_worker_tail", "wp_worktree"];
@@ -13,6 +13,7 @@ export const WP_TOOL_NAMES = [
13
13
  "wp_audits",
14
14
  "wp_bench",
15
15
  "wp_ci_act",
16
+ "wp_ci_preflight",
16
17
  "wp_e2e",
17
18
  "wp_fleet_status",
18
19
  "wp_format",
@@ -23,6 +24,8 @@ export const WP_TOOL_NAMES = [
23
24
  "wp_pr_wait",
24
25
  "wp_qa",
25
26
  "wp_release_readiness",
27
+ "wp_review_run",
28
+ "wp_run_wait",
26
29
  "wp_session_batch_execute",
27
30
  "wp_session_capture",
28
31
  "wp_session_context",
@@ -30,7 +33,9 @@ export const WP_TOOL_NAMES = [
30
33
  "wp_session_execute",
31
34
  "wp_session_execute_file",
32
35
  "wp_session_fetch_and_index",
36
+ "wp_session_id",
33
37
  "wp_session_index",
38
+ "wp_session_info",
34
39
  "wp_session_purge",
35
40
  "wp_session_retrieve",
36
41
  "wp_session_restore",
@@ -2,6 +2,7 @@ import audit from "./audit.js";
2
2
  import audits from "./audits.js";
3
3
  import bench from "./bench.js";
4
4
  import ciAct from "./ci-act.js";
5
+ import ciPreflight from "./ci-preflight.js";
5
6
  import e2e from "./e2e.js";
6
7
  import format from "./format.js";
7
8
  import fleet from "./fleet.js";
@@ -12,6 +13,8 @@ import prUpsert from "./pr-upsert.js";
12
13
  import prWait from "./pr-wait.js";
13
14
  import qa from "./qa.js";
14
15
  import releaseReadiness from "./release-readiness.js";
16
+ import reviewRun from "./review-run.js";
17
+ import runWait from "./run-wait.js";
15
18
  import sessionBatchExecute from "./session-batch-execute.js";
16
19
  import sessionCapture from "./session-capture.js";
17
20
  import sessionContext from "./session-context.js";
@@ -19,7 +22,9 @@ import sessionDoctor from "./session-doctor.js";
19
22
  import sessionExecute from "./session-execute.js";
20
23
  import sessionExecuteFile from "./session-execute-file.js";
21
24
  import sessionFetchAndIndex from "./session-fetch-and-index.js";
25
+ import sessionId from "./session-id.js";
22
26
  import sessionIndex from "./session-index.js";
27
+ import sessionInfo from "./session-info.js";
23
28
  import sessionPurge from "./session-purge.js";
24
29
  import sessionRetrieve from "./session-retrieve.js";
25
30
  import sessionRestore from "./session-restore.js";
@@ -40,6 +45,7 @@ export const COMPILED_TOOL_REGISTRY = [
40
45
  audits,
41
46
  bench,
42
47
  ciAct,
48
+ ciPreflight,
43
49
  e2e,
44
50
  fleet,
45
51
  format,
@@ -50,6 +56,8 @@ export const COMPILED_TOOL_REGISTRY = [
50
56
  prWait,
51
57
  qa,
52
58
  releaseReadiness,
59
+ reviewRun,
60
+ runWait,
53
61
  sessionBatchExecute,
54
62
  sessionCapture,
55
63
  sessionContext,
@@ -57,7 +65,9 @@ export const COMPILED_TOOL_REGISTRY = [
57
65
  sessionExecute,
58
66
  sessionExecuteFile,
59
67
  sessionFetchAndIndex,
68
+ sessionId,
60
69
  sessionIndex,
70
+ sessionInfo,
61
71
  sessionPurge,
62
72
  sessionRetrieve,
63
73
  sessionRestore,
@@ -1,3 +1,3 @@
1
- export declare const MCP_AUDIT_KINDS: readonly ["test-smells", "tph-e2e", "agents", "catalog-drift", "package-surface", "reference-parity-matrix", "docs-frontmatter", "blueprint-readme-drift", "blueprint-pr-coverage", "blueprint-lifecycle", "blueprint-trust", "architecture-drift", "cloudflare-deploy-contract", "absolute-path-policy", "no-first-party-mjs", "no-math-random", "roadmap-links", "bundle-budget", "commit-message", "tech-debt", "supported-agent-clis", "hook-surface", "harness-surfaces", "weakness-mining", "harness-overlay-evidence", "ai-contracts", "atomic-state-writes", "no-relative-package-scripts", "toolchain-isolation", "open-source-licenses", "secrets-policy", "no-dev-vars", "github-actions-secrets", "secret-provider-quarantine", "security-quality-regressions", "secrets-config", "consumer-agent-kit-dependency", "ci-test-perf", "test-scan-perf", "session-memory-hardcut", "worktree-main-ownership", "sast"];
1
+ export declare const MCP_AUDIT_KINDS: readonly ["test-smells", "tph-e2e", "agents", "catalog-drift", "package-surface", "reference-parity-matrix", "docs-frontmatter", "blueprint-readme-drift", "blueprint-pr-coverage", "blueprint-lifecycle", "blueprint-trust", "architecture-drift", "cloudflare-deploy-contract", "absolute-path-policy", "no-first-party-mjs", "no-math-random", "roadmap-links", "bundle-budget", "commit-message", "tech-debt", "supported-agent-clis", "hook-surface", "harness-surfaces", "weakness-mining", "harness-overlay-evidence", "host-substitution-risk", "ai-contracts", "atomic-state-writes", "no-relative-package-scripts", "toolchain-isolation", "open-source-licenses", "secrets-policy", "no-dev-vars", "github-actions-secrets", "secret-provider-quarantine", "security-quality-regressions", "secrets-config", "consumer-agent-kit-dependency", "ci-test-perf", "test-scan-perf", "session-memory-hardcut", "worktree-main-ownership", "typescript-version", "ci-guardrails-wiring", "sast", "changeset-required"];
2
2
  export type MCPAuditKind = (typeof MCP_AUDIT_KINDS)[number];
3
3
  export declare function isMCPAuditKind(value: string): value is MCPAuditKind;
@@ -82,8 +82,51 @@ export function clipRawOutput(rawOutput, maxChars = DEFAULT_RAW_OUTPUT_LIMIT, op
82
82
  ...(recorded?.warning ? { warnings: [recorded.warning] } : {}),
83
83
  };
84
84
  }
85
+ /**
86
+ * Maximum bytes of serialized `details` appended to an ERROR result's text
87
+ * content. Generous enough to carry a full validation-error array or a failed
88
+ * command record, small enough that a pathological payload cannot flood the
89
+ * caller's context.
90
+ */
91
+ const ERROR_DETAIL_TEXT_LIMIT = 2_000;
92
+ /**
93
+ * Render the actionable part of a failing payload for the text `content`.
94
+ *
95
+ * MCP hosts surface `content` (not `structuredContent`) when `isError` is set,
96
+ * so an error whose text is only the one-line `summary` forces the caller to
97
+ * go read the tool's source to learn WHAT failed — e.g. `wp_pr_upsert`
98
+ * returning bare "PR description validation failed; no GitHub mutation was
99
+ * attempted" while `details.validation.errors` held the exact missing fields.
100
+ * That round trip is pure wasted context. Fold the details into the text so
101
+ * one call is enough.
102
+ */
103
+ function renderErrorDetail(payload) {
104
+ const details = payload.details;
105
+ if (details === undefined || details === null)
106
+ return undefined;
107
+ let serialized;
108
+ try {
109
+ // Compact (no pretty-print indentation): keeps the payload cheap in the
110
+ // caller's context, and avoids emitting whitespace runs that never came
111
+ // from the data — `session-index.test.ts` asserts a whitespace-only INPUT
112
+ // is not echoed back, which indented output would trip incidentally.
113
+ serialized = JSON.stringify(details);
114
+ }
115
+ catch {
116
+ return undefined; // circular/unserializable — summary alone still ships
117
+ }
118
+ if (!serialized || serialized === "{}" || serialized === "[]")
119
+ return undefined;
120
+ return serialized.length <= ERROR_DETAIL_TEXT_LIMIT
121
+ ? serialized
122
+ : `${serialized.slice(0, ERROR_DETAIL_TEXT_LIMIT - 1)}…`;
123
+ }
85
124
  export function createSummaryResult(payload, options = {}) {
86
- const text = clipSummaryText(options.text ?? payload.summary);
125
+ const summaryText = clipSummaryText(options.text ?? payload.summary);
126
+ // Only errors get the detail block: success results are already summary-first
127
+ // by design, and their details are available via `structuredContent`.
128
+ const detail = options.isError ? renderErrorDetail(payload) : undefined;
129
+ const text = detail ? `${summaryText}\n\n${detail}` : summaryText;
87
130
  return {
88
131
  content: [{ type: "text", text }],
89
132
  structuredContent: payload,
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { z } from "zod";
17
17
  import type { ToolDescriptor } from "#mcp/auto-discover";
18
- export declare const KINDS: readonly ["test-smells", "tph-e2e", "agents", "catalog-drift", "package-surface", "reference-parity-matrix", "docs-frontmatter", "blueprint-readme-drift", "blueprint-pr-coverage", "blueprint-lifecycle", "blueprint-trust", "architecture-drift", "cloudflare-deploy-contract", "absolute-path-policy", "no-first-party-mjs", "no-math-random", "roadmap-links", "bundle-budget", "commit-message", "tech-debt", "supported-agent-clis", "hook-surface", "harness-surfaces", "weakness-mining", "harness-overlay-evidence", "ai-contracts", "atomic-state-writes", "no-relative-package-scripts", "toolchain-isolation", "open-source-licenses", "secrets-policy", "no-dev-vars", "github-actions-secrets", "secret-provider-quarantine", "security-quality-regressions", "secrets-config", "consumer-agent-kit-dependency", "ci-test-perf", "test-scan-perf", "session-memory-hardcut", "worktree-main-ownership", "sast"];
18
+ export declare const KINDS: readonly ["test-smells", "tph-e2e", "agents", "catalog-drift", "package-surface", "reference-parity-matrix", "docs-frontmatter", "blueprint-readme-drift", "blueprint-pr-coverage", "blueprint-lifecycle", "blueprint-trust", "architecture-drift", "cloudflare-deploy-contract", "absolute-path-policy", "no-first-party-mjs", "no-math-random", "roadmap-links", "bundle-budget", "commit-message", "tech-debt", "supported-agent-clis", "hook-surface", "harness-surfaces", "weakness-mining", "harness-overlay-evidence", "host-substitution-risk", "ai-contracts", "atomic-state-writes", "no-relative-package-scripts", "toolchain-isolation", "open-source-licenses", "secrets-policy", "no-dev-vars", "github-actions-secrets", "secret-provider-quarantine", "security-quality-regressions", "secrets-config", "consumer-agent-kit-dependency", "ci-test-perf", "test-scan-perf", "session-memory-hardcut", "worktree-main-ownership", "typescript-version", "ci-guardrails-wiring", "sast", "changeset-required"];
19
19
  export declare const inputSchema: z.ZodObject<{
20
20
  kind: z.ZodEnum<{
21
21
  "absolute-path-policy": "absolute-path-policy";
@@ -29,6 +29,8 @@ export declare const inputSchema: z.ZodObject<{
29
29
  "blueprint-trust": "blueprint-trust";
30
30
  "bundle-budget": "bundle-budget";
31
31
  "catalog-drift": "catalog-drift";
32
+ "changeset-required": "changeset-required";
33
+ "ci-guardrails-wiring": "ci-guardrails-wiring";
32
34
  "ci-test-perf": "ci-test-perf";
33
35
  "cloudflare-deploy-contract": "cloudflare-deploy-contract";
34
36
  "commit-message": "commit-message";
@@ -38,6 +40,7 @@ export declare const inputSchema: z.ZodObject<{
38
40
  "harness-overlay-evidence": "harness-overlay-evidence";
39
41
  "harness-surfaces": "harness-surfaces";
40
42
  "hook-surface": "hook-surface";
43
+ "host-substitution-risk": "host-substitution-risk";
41
44
  "no-dev-vars": "no-dev-vars";
42
45
  "no-first-party-mjs": "no-first-party-mjs";
43
46
  "no-math-random": "no-math-random";
@@ -58,6 +61,7 @@ export declare const inputSchema: z.ZodObject<{
58
61
  "test-smells": "test-smells";
59
62
  "toolchain-isolation": "toolchain-isolation";
60
63
  "tph-e2e": "tph-e2e";
64
+ "typescript-version": "typescript-version";
61
65
  "weakness-mining": "weakness-mining";
62
66
  "worktree-main-ownership": "worktree-main-ownership";
63
67
  }>;
@@ -128,6 +128,16 @@ export async function dispatchAudit(input) {
128
128
  details: auditResult,
129
129
  };
130
130
  }
131
+ case "host-substitution-risk": {
132
+ const { auditHostSubstitutionRisk } = await import("#audit/host-substitution-risk");
133
+ const auditResult = auditHostSubstitutionRisk(input.cwd ?? input.directory ?? process.cwd());
134
+ return {
135
+ passed: auditResult.ok,
136
+ summary: summarizeRepoAudit(kind, auditResult),
137
+ kind,
138
+ details: auditResult,
139
+ };
140
+ }
131
141
  case "agents": {
132
142
  const { auditAgents } = await import("#audit/agents");
133
143
  const auditResult = auditAgents(input.cwd ?? input.directory ?? process.cwd());
@@ -464,6 +474,16 @@ export async function dispatchAudit(input) {
464
474
  details: auditResult,
465
475
  };
466
476
  }
477
+ case "ci-guardrails-wiring": {
478
+ const { auditCiGuardrailsWiring } = await import("#audit/ci-guardrails-wiring");
479
+ const auditResult = auditCiGuardrailsWiring(input.cwd ?? input.directory ?? process.cwd());
480
+ return {
481
+ passed: auditResult.ok,
482
+ summary: summarizeRepoAudit(kind, auditResult),
483
+ kind,
484
+ details: auditResult,
485
+ };
486
+ }
467
487
  case "test-scan-perf": {
468
488
  const { auditTestScanPerf } = await import("#audit/test-scan-perf");
469
489
  const auditResult = auditTestScanPerf(input.cwd ?? input.directory ?? process.cwd());
@@ -539,6 +559,28 @@ export async function dispatchAudit(input) {
539
559
  },
540
560
  };
541
561
  }
562
+ case "typescript-version": {
563
+ const { auditTypescriptVersion } = await import("#audit/typescript-version");
564
+ const auditResult = auditTypescriptVersion(input.cwd ?? input.directory ?? process.cwd());
565
+ return {
566
+ passed: auditResult.ok,
567
+ summary: summarizeRepoAudit(kind, auditResult),
568
+ kind,
569
+ details: auditResult,
570
+ };
571
+ }
572
+ case "changeset-required": {
573
+ const { auditChangesetRequired } = await import("#audit/changeset-required");
574
+ const auditResult = auditChangesetRequired(input.cwd ?? input.directory ?? process.cwd(), {
575
+ baseRef: input.baseRef,
576
+ });
577
+ return {
578
+ passed: auditResult.ok,
579
+ summary: summarizeRepoAudit(kind, auditResult),
580
+ kind,
581
+ details: auditResult,
582
+ };
583
+ }
542
584
  default: {
543
585
  // Exhaustiveness check — z.enum should make this unreachable.
544
586
  const _exhaustive = kind;
@@ -25,6 +25,8 @@ declare const inputSchema: z.ZodObject<{
25
25
  "blueprint-trust": "blueprint-trust";
26
26
  "bundle-budget": "bundle-budget";
27
27
  "catalog-drift": "catalog-drift";
28
+ "changeset-required": "changeset-required";
29
+ "ci-guardrails-wiring": "ci-guardrails-wiring";
28
30
  "ci-test-perf": "ci-test-perf";
29
31
  "cloudflare-deploy-contract": "cloudflare-deploy-contract";
30
32
  "commit-message": "commit-message";
@@ -34,6 +36,7 @@ declare const inputSchema: z.ZodObject<{
34
36
  "harness-overlay-evidence": "harness-overlay-evidence";
35
37
  "harness-surfaces": "harness-surfaces";
36
38
  "hook-surface": "hook-surface";
39
+ "host-substitution-risk": "host-substitution-risk";
37
40
  "no-dev-vars": "no-dev-vars";
38
41
  "no-first-party-mjs": "no-first-party-mjs";
39
42
  "no-math-random": "no-math-random";
@@ -54,6 +57,7 @@ declare const inputSchema: z.ZodObject<{
54
57
  "test-smells": "test-smells";
55
58
  "toolchain-isolation": "toolchain-isolation";
56
59
  "tph-e2e": "tph-e2e";
60
+ "typescript-version": "typescript-version";
57
61
  "weakness-mining": "weakness-mining";
58
62
  "worktree-main-ownership": "worktree-main-ownership";
59
63
  }>>>;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * `wp_ci_preflight` MCP tool.
3
+ *
4
+ * Wraps `runCiPreflight` (the single owner of the pre-push gate — see
5
+ * `src/cli/commands/ci-preflight.ts`) so agents can run the exact fail-fast,
6
+ * branch-scoped sequence CI mirrors — `format → guardrails → typecheck →
7
+ * lint → test` — without shelling out to `wp ci-preflight` via Bash.
8
+ *
9
+ * `runCiPreflight`'s default `runCheck` re-invokes `wp <subcommand>` via
10
+ * `spawnSync(..., {stdio: "inherit"})`. That is correct for a real terminal
11
+ * but unsafe here: `wp mcp` speaks stdio-transport JSON-RPC over the process's
12
+ * real stdout, and an inherited child write would corrupt that stream. This
13
+ * tool substitutes a `runCheck` that spawns each stage asynchronously via the
14
+ * shared `runCommand` helper (captured stdout/stderr, a bounded per-stage
15
+ * timeout, and `extra.signal` cancellation) using the same `wp` launcher
16
+ * resolution (`resolveWpLauncher`) the CLI uses, so behavior stays identical
17
+ * — only the transport of the output changes. `runCiPreflight`'s own
18
+ * `stdout`/`stderr` deps are swallowed for the same reason (they default to
19
+ * `process.stdout`/`process.stderr`); the equivalent progress detail is
20
+ * reconstructed from the per-stage results this tool collects itself.
21
+ *
22
+ * `runCiPreflight` returns only an exit code — there is no structured
23
+ * per-stage payload to "pass through." The `{passed, summary, details:
24
+ * {stages, stoppedAt}}` shape below mirrors `wp_qa`'s aggregate-gate
25
+ * convention (structured pass/fail + per-stage breakdown) since ci-preflight
26
+ * is the same shape of thing: a staged composite gate, just sequential and
27
+ * fail-fast instead of `wp_qa`'s parallel `Promise.all`.
28
+ */
29
+ import { z } from "zod";
30
+ import type { ToolDescriptor } from "#mcp/auto-discover";
31
+ declare const inputSchema: z.ZodObject<{
32
+ cwd: z.ZodOptional<z.ZodString>;
33
+ full: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
34
+ }, z.core.$strip>;
35
+ export type AkCiPreflightInput = z.infer<typeof inputSchema>;
36
+ declare const stageResultSchema: z.ZodObject<{
37
+ label: z.ZodString;
38
+ args: z.ZodArray<z.ZodString>;
39
+ passed: z.ZodBoolean;
40
+ exitCode: z.ZodOptional<z.ZodNumber>;
41
+ timedOut: z.ZodOptional<z.ZodBoolean>;
42
+ aborted: z.ZodOptional<z.ZodBoolean>;
43
+ spawnError: z.ZodOptional<z.ZodString>;
44
+ rawOutput: z.ZodOptional<z.ZodString>;
45
+ truncated: z.ZodOptional<z.ZodBoolean>;
46
+ logPath: z.ZodOptional<z.ZodString>;
47
+ }, z.core.$strip>;
48
+ export type CiPreflightStageResult = z.infer<typeof stageResultSchema>;
49
+ declare const tool: ToolDescriptor;
50
+ export default tool;