@webpresso/agent-kit 3.1.28 → 3.2.0

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

Potentially problematic release.


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

Files changed (329) hide show
  1. package/README.md +53 -15
  2. package/bin/_run.js +179 -19
  3. package/catalog/AGENTS.md.tpl +6 -6
  4. package/catalog/agent/agents/implementer.md +45 -0
  5. package/catalog/agent/rules/ci-cost-local-first.md +139 -0
  6. package/catalog/agent/rules/ci-test-perf.md +5 -1
  7. package/catalog/agent/rules/cmd-execution.md +9 -0
  8. package/catalog/agent/rules/parallel-orchestration-quota.md +100 -0
  9. package/catalog/agent/rules/pre-implementation.md +30 -2
  10. package/catalog/agent/rules/supported-agent-clis.md +9 -0
  11. package/catalog/agent/rules/test-scan-perf.md +80 -0
  12. package/catalog/agent/rules/typescript-version.md +50 -0
  13. package/catalog/agent/rules/workflow-skills-routing.md +4 -2
  14. package/catalog/agent/skills/codex/SKILL.md +25 -1
  15. package/catalog/agent/skills/fix/SKILL.md +3 -0
  16. package/catalog/agent/skills/verify/SKILL.md +22 -2
  17. package/catalog/docs/templates/blueprint.md +1 -1
  18. package/dist/esm/audit/agents.js +1 -0
  19. package/dist/esm/audit/blueprint-lifecycle-sql.d.ts +12 -0
  20. package/dist/esm/audit/blueprint-lifecycle-sql.js +23 -2
  21. package/dist/esm/audit/blueprint-pr-coverage.js +72 -7
  22. package/dist/esm/audit/ci-guardrails-wiring.d.ts +22 -0
  23. package/dist/esm/audit/ci-guardrails-wiring.js +90 -0
  24. package/dist/esm/audit/ci-test-perf.js +30 -0
  25. package/dist/esm/audit/command-surface.js +4 -2
  26. package/dist/esm/audit/host-substitution-risk.d.ts +2 -0
  27. package/dist/esm/audit/host-substitution-risk.js +256 -0
  28. package/dist/esm/audit/registry.d.ts +4 -4
  29. package/dist/esm/audit/registry.js +11 -1
  30. package/dist/esm/audit/roadmap-links.js +6 -0
  31. package/dist/esm/audit/test-scan-perf.d.ts +18 -0
  32. package/dist/esm/audit/test-scan-perf.js +275 -0
  33. package/dist/esm/audit/toolchain-isolation.js +1 -2
  34. package/dist/esm/audit/typescript-version.d.ts +2 -0
  35. package/dist/esm/audit/typescript-version.js +123 -0
  36. package/dist/esm/blueprint/core/parser.js +43 -1
  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 +65 -10
  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/engine.d.ts +9 -0
  46. package/dist/esm/blueprint/lifecycle/engine.js +53 -6
  47. package/dist/esm/blueprint/lifecycle/local.d.ts +2 -1
  48. package/dist/esm/blueprint/lifecycle/local.js +19 -3
  49. package/dist/esm/blueprint/lifecycle/review-provenance.d.ts +6 -0
  50. package/dist/esm/blueprint/lifecycle/review-provenance.js +118 -12
  51. package/dist/esm/blueprint/markdown/helpers.js +6 -2
  52. package/dist/esm/blueprint/service/BlueprintCreationService.d.ts +1 -0
  53. package/dist/esm/blueprint/service/BlueprintCreationService.js +53 -4
  54. package/dist/esm/blueprint/service/blueprint-tech-debt-links.js +16 -2
  55. package/dist/esm/blueprint/trust/command-runner.d.ts +26 -0
  56. package/dist/esm/blueprint/trust/command-runner.js +148 -0
  57. package/dist/esm/blueprint/trust/gates.d.ts +7 -0
  58. package/dist/esm/blueprint/trust/gates.js +20 -0
  59. package/dist/esm/blueprint/trust/promotion.d.ts +8 -0
  60. package/dist/esm/blueprint/trust/promotion.js +62 -112
  61. package/dist/esm/blueprint/trust/scaffold.d.ts +19 -0
  62. package/dist/esm/blueprint/trust/scaffold.js +64 -0
  63. package/dist/esm/blueprint/trust/validator.d.ts +1 -0
  64. package/dist/esm/blueprint/trust/validator.js +7 -1
  65. package/dist/esm/blueprint/utils/archive.js +27 -5
  66. package/dist/esm/blueprint/utils/document-paths.d.ts +18 -0
  67. package/dist/esm/blueprint/utils/document-paths.js +45 -12
  68. package/dist/esm/build/cli-mcp-parity.js +10 -0
  69. package/dist/esm/ci/act-replay.js +110 -7
  70. package/dist/esm/ci/act-runner.d.ts +4 -0
  71. package/dist/esm/ci/act-runner.js +85 -26
  72. package/dist/esm/ci/act-worktree-git.d.ts +11 -0
  73. package/dist/esm/ci/act-worktree-git.js +219 -0
  74. package/dist/esm/cli/bundle/commands/blueprint.d.ts +1 -0
  75. package/dist/esm/cli/bundle/commands/blueprint.js +1 -0
  76. package/dist/esm/cli/cli.d.ts +1 -1
  77. package/dist/esm/cli/cli.js +34 -0
  78. package/dist/esm/cli/commands/agent-launch.d.ts +6 -1
  79. package/dist/esm/cli/commands/agent-launch.js +82 -4
  80. package/dist/esm/cli/commands/audit-core.d.ts +1 -1
  81. package/dist/esm/cli/commands/audit-core.js +8 -1
  82. package/dist/esm/cli/commands/audit.js +20 -5
  83. package/dist/esm/cli/commands/blueprint/execution.js +18 -6
  84. package/dist/esm/cli/commands/blueprint/mutations.js +83 -47
  85. package/dist/esm/cli/commands/blueprint/router-dispatch.d.ts +2 -1
  86. package/dist/esm/cli/commands/blueprint/router-dispatch.js +20 -1
  87. package/dist/esm/cli/commands/blueprint/router-output.d.ts +21 -0
  88. package/dist/esm/cli/commands/blueprint/router-output.js +48 -17
  89. package/dist/esm/cli/commands/blueprint/router.d.ts +7 -0
  90. package/dist/esm/cli/commands/blueprint/router.js +40 -3
  91. package/dist/esm/cli/commands/ci-preflight.d.ts +13 -2
  92. package/dist/esm/cli/commands/ci-preflight.js +6 -3
  93. package/dist/esm/cli/commands/ci.d.ts +8 -1
  94. package/dist/esm/cli/commands/ci.js +80 -21
  95. package/dist/esm/cli/commands/compile.js +5 -31
  96. package/dist/esm/cli/commands/dash/delivery-status.d.ts +1 -0
  97. package/dist/esm/cli/commands/dash/delivery-status.js +11 -4
  98. package/dist/esm/cli/commands/dash/keymap.js +1 -0
  99. package/dist/esm/cli/commands/dash/launch-preferences.d.ts +15 -0
  100. package/dist/esm/cli/commands/dash/launch-preferences.js +46 -17
  101. package/dist/esm/cli/commands/dash/plan-once-label.d.ts +7 -0
  102. package/dist/esm/cli/commands/dash/plan-once-label.js +5 -0
  103. package/dist/esm/cli/commands/dash/plan-once-membership.d.ts +67 -0
  104. package/dist/esm/cli/commands/dash/plan-once-membership.js +151 -0
  105. package/dist/esm/cli/commands/dash/plan-once-merge.d.ts +143 -0
  106. package/dist/esm/cli/commands/dash/plan-once-merge.js +238 -0
  107. package/dist/esm/cli/commands/dash/plan-once.d.ts +22 -2
  108. package/dist/esm/cli/commands/dash/plan-once.js +41 -4
  109. package/dist/esm/cli/commands/dash/tui/attention-hud.d.ts +9 -0
  110. package/dist/esm/cli/commands/dash/tui/attention-hud.js +9 -0
  111. package/dist/esm/cli/commands/dash/tui/chat-bridge.d.ts +41 -0
  112. package/dist/esm/cli/commands/dash/tui/chat-bridge.js +73 -0
  113. package/dist/esm/cli/commands/dash/tui/chat-mode.d.ts +47 -0
  114. package/dist/esm/cli/commands/dash/tui/chat-mode.js +98 -0
  115. package/dist/esm/cli/commands/dash/tui/frame.d.ts +3 -0
  116. package/dist/esm/cli/commands/dash/tui/frame.js +3 -1
  117. package/dist/esm/cli/commands/dash/tui/palette.d.ts +1 -1
  118. package/dist/esm/cli/commands/dash/tui/palette.js +14 -0
  119. package/dist/esm/cli/commands/dash/tui/runtime.js +239 -4
  120. package/dist/esm/cli/commands/dash/tui/state.d.ts +41 -0
  121. package/dist/esm/cli/commands/dash/tui/state.js +257 -4
  122. package/dist/esm/cli/commands/doctor.js +5 -0
  123. package/dist/esm/cli/commands/format.js +0 -2
  124. package/dist/esm/cli/commands/hook.d.ts +5 -0
  125. package/dist/esm/cli/commands/hook.js +15 -9
  126. package/dist/esm/cli/commands/init/config.d.ts +0 -1
  127. package/dist/esm/cli/commands/init/config.js +3 -6
  128. package/dist/esm/cli/commands/init/convergence-apply.d.ts +24 -0
  129. package/dist/esm/cli/commands/init/convergence-apply.js +221 -0
  130. package/dist/esm/cli/commands/init/convergence-state.d.ts +13 -0
  131. package/dist/esm/cli/commands/init/convergence-state.js +54 -0
  132. package/dist/esm/cli/commands/init/convergence.d.ts +23 -0
  133. package/dist/esm/cli/commands/init/convergence.js +57 -0
  134. package/dist/esm/cli/commands/init/git-convergence.d.ts +19 -0
  135. package/dist/esm/cli/commands/init/git-convergence.js +168 -0
  136. package/dist/esm/cli/commands/init/gitignore-patcher.js +2 -0
  137. package/dist/esm/cli/commands/init/grok-privacy-smoke.d.ts +52 -0
  138. package/dist/esm/cli/commands/init/grok-privacy-smoke.js +91 -0
  139. package/dist/esm/cli/commands/init/host-native-proof.d.ts +18 -0
  140. package/dist/esm/cli/commands/init/host-native-proof.js +88 -0
  141. package/dist/esm/cli/commands/init/host-visibility.d.ts +2 -2
  142. package/dist/esm/cli/commands/init/host-visibility.js +94 -5
  143. package/dist/esm/cli/commands/init/index.d.ts +1 -0
  144. package/dist/esm/cli/commands/init/index.js +326 -173
  145. package/dist/esm/cli/commands/init/mcp-spec.d.ts +57 -0
  146. package/dist/esm/cli/commands/init/mcp-spec.js +273 -0
  147. package/dist/esm/cli/commands/init/merge.d.ts +1 -0
  148. package/dist/esm/cli/commands/init/merge.js +30 -1
  149. package/dist/esm/cli/commands/init/plugin-cache-prune.d.ts +0 -3
  150. package/dist/esm/cli/commands/init/plugin-cache-prune.js +0 -1
  151. package/dist/esm/cli/commands/init/scaffold-agents-md.d.ts +1 -1
  152. package/dist/esm/cli/commands/init/scaffold-agents-md.js +9 -3
  153. package/dist/esm/cli/commands/init/scaffold-base-kit.d.ts +11 -0
  154. package/dist/esm/cli/commands/init/scaffold-base-kit.js +56 -1
  155. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/claude.d.ts +5 -6
  156. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/claude.js +6 -13
  157. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.d.ts +14 -8
  158. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.js +41 -24
  159. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.d.ts +2 -0
  160. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +51 -23
  161. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/ir.d.ts +0 -2
  162. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/ir.js +0 -2
  163. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/merge.d.ts +6 -3
  164. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/merge.js +39 -26
  165. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.d.ts +12 -31
  166. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.js +297 -173
  167. package/dist/esm/cli/commands/init/scaffolders/file-transaction.d.ts +7 -0
  168. package/dist/esm/cli/commands/init/scaffolders/file-transaction.js +58 -0
  169. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.d.ts +38 -0
  170. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.js +73 -0
  171. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.d.ts +21 -0
  172. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.js +559 -63
  173. package/dist/esm/cli/commands/init/untracked-collision.d.ts +14 -0
  174. package/dist/esm/cli/commands/init/untracked-collision.js +42 -0
  175. package/dist/esm/cli/commands/logs.d.ts +15 -0
  176. package/dist/esm/cli/commands/logs.js +192 -3
  177. package/dist/esm/cli/commands/opencode-rotate.d.ts +49 -0
  178. package/dist/esm/cli/commands/opencode-rotate.js +135 -0
  179. package/dist/esm/cli/commands/public-readiness.d.ts +11 -0
  180. package/dist/esm/cli/commands/public-readiness.js +42 -0
  181. package/dist/esm/cli/commands/quality-log-store.d.ts +1 -0
  182. package/dist/esm/cli/commands/quality-log-store.js +187 -51
  183. package/dist/esm/cli/commands/review.d.ts +35 -3
  184. package/dist/esm/cli/commands/review.js +734 -217
  185. package/dist/esm/cli/commands/run-wait.d.ts +2 -0
  186. package/dist/esm/cli/commands/run-wait.js +122 -0
  187. package/dist/esm/cli/commands/secrets.d.ts +1 -0
  188. package/dist/esm/cli/commands/secrets.js +4 -1
  189. package/dist/esm/cli/commands/setup-help.js +1 -1
  190. package/dist/esm/cli/commands/setup-repair-help.js +1 -1
  191. package/dist/esm/cli/commands/worktree/router-dispatch.js +13 -8
  192. package/dist/esm/cli/direct-provider-launch.js +31 -3
  193. package/dist/esm/cli/optional-tool-freshness.d.ts +27 -0
  194. package/dist/esm/cli/optional-tool-freshness.js +219 -9
  195. package/dist/esm/daemon/domains/git-actions.d.ts +29 -0
  196. package/dist/esm/daemon/domains/git-actions.js +136 -0
  197. package/dist/esm/daemon/domains/run-registry-interop.d.ts +16 -0
  198. package/dist/esm/daemon/domains/run-registry-interop.js +45 -0
  199. package/dist/esm/daemon/domains/sessions-search.d.ts +11 -0
  200. package/dist/esm/daemon/domains/sessions-search.js +29 -0
  201. package/dist/esm/daemon/handlers/blueprints-handlers.d.ts +5 -0
  202. package/dist/esm/daemon/handlers/blueprints-handlers.js +36 -0
  203. package/dist/esm/daemon/handlers/deploy-handlers.d.ts +6 -0
  204. package/dist/esm/daemon/handlers/deploy-handlers.js +5 -0
  205. package/dist/esm/daemon/handlers/fleet-handlers.d.ts +15 -0
  206. package/dist/esm/daemon/handlers/fleet-handlers.js +91 -0
  207. package/dist/esm/daemon/handlers/git-handlers.d.ts +6 -0
  208. package/dist/esm/daemon/handlers/git-handlers.js +27 -0
  209. package/dist/esm/daemon/handlers/product.d.ts +7 -0
  210. package/dist/esm/daemon/handlers/product.js +10 -119
  211. package/dist/esm/daemon/handlers/sessions-handlers.d.ts +12 -0
  212. package/dist/esm/daemon/handlers/sessions-handlers.js +31 -0
  213. package/dist/esm/daemon/handlers/shared.d.ts +5 -0
  214. package/dist/esm/daemon/handlers/shared.js +16 -0
  215. package/dist/esm/daemon/methods.d.ts +8 -1
  216. package/dist/esm/daemon/methods.js +7 -0
  217. package/dist/esm/daemon/protocol/contract.d.ts +43 -0
  218. package/dist/esm/daemon/protocol/contract.js +26 -0
  219. package/dist/esm/daemon/protocol/index.d.ts +1 -1
  220. package/dist/esm/daemon/protocol/index.js +1 -1
  221. package/dist/esm/hooks/__conformance__/matrix.d.ts +6 -0
  222. package/dist/esm/hooks/__conformance__/matrix.js +137 -0
  223. package/dist/esm/hooks/conformance/batch.js +5 -0
  224. package/dist/esm/hooks/doctor.d.ts +15 -0
  225. package/dist/esm/hooks/doctor.js +79 -8
  226. package/dist/esm/hooks/permission-request/index.js +9 -3
  227. package/dist/esm/hooks/permission-request/policy.d.ts +9 -0
  228. package/dist/esm/hooks/permission-request/policy.js +13 -0
  229. package/dist/esm/hooks/pretool-guard/dev-routing.d.ts +9 -0
  230. package/dist/esm/hooks/pretool-guard/dev-routing.js +41 -5
  231. package/dist/esm/hooks/pretool-guard/logger.d.ts +7 -0
  232. package/dist/esm/hooks/pretool-guard/logger.js +16 -0
  233. package/dist/esm/hooks/pretool-guard/runner.d.ts +6 -0
  234. package/dist/esm/hooks/pretool-guard/runner.js +68 -16
  235. package/dist/esm/hooks/pretool-guard/validators/blueprint.js +30 -10
  236. package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +58 -4
  237. package/dist/esm/hooks/pretool-guard/validators/index.d.ts +7 -0
  238. package/dist/esm/hooks/pretool-guard/validators/index.js +21 -0
  239. package/dist/esm/hooks/pretool-guard/validators/mcp-redirect.d.ts +0 -1
  240. package/dist/esm/hooks/pretool-guard/validators/mcp-redirect.js +8 -5
  241. package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +19 -0
  242. package/dist/esm/hooks/pretool-guard/validators/path-contract.js +25 -8
  243. package/dist/esm/hooks/pretool-guard/validators/worktree-discipline.d.ts +9 -7
  244. package/dist/esm/hooks/pretool-guard/validators/worktree-discipline.js +126 -14
  245. package/dist/esm/hooks/shared/guard-outcome.d.ts +149 -0
  246. package/dist/esm/hooks/shared/guard-outcome.js +215 -0
  247. package/dist/esm/hooks/shared/hook-bootstrap.d.ts +26 -0
  248. package/dist/esm/hooks/shared/hook-bootstrap.js +64 -1
  249. package/dist/esm/hooks/shared/types.d.ts +8 -5
  250. package/dist/esm/hooks/shared/types.js +23 -8
  251. package/dist/esm/hooks/stop/qa-changed-files.d.ts +11 -0
  252. package/dist/esm/hooks/stop/qa-changed-files.js +74 -0
  253. package/dist/esm/mcp/blueprint/_shared/lifecycle.js +14 -1
  254. package/dist/esm/mcp/blueprint/handlers/document-mutations.js +78 -4
  255. package/dist/esm/mcp/blueprint/handlers/review-log.js +8 -1
  256. package/dist/esm/mcp/blueprint/handlers/task-advance.js +113 -54
  257. package/dist/esm/mcp/blueprint/handlers/task-verify.js +39 -19
  258. package/dist/esm/mcp/blueprint/registration.js +3 -2
  259. package/dist/esm/mcp/server.d.ts +1 -0
  260. package/dist/esm/mcp/server.js +27 -0
  261. package/dist/esm/mcp/tools/_names.d.ts +1 -1
  262. package/dist/esm/mcp/tools/_names.js +5 -0
  263. package/dist/esm/mcp/tools/_registry.js +10 -0
  264. package/dist/esm/mcp/tools/_shared/audit-kinds.d.ts +1 -1
  265. package/dist/esm/mcp/tools/_shared/result.js +44 -1
  266. package/dist/esm/mcp/tools/audit.d.ts +5 -1
  267. package/dist/esm/mcp/tools/audit.js +40 -0
  268. package/dist/esm/mcp/tools/audits.d.ts +4 -0
  269. package/dist/esm/mcp/tools/ci-act.js +9 -11
  270. package/dist/esm/mcp/tools/ci-preflight.d.ts +50 -0
  271. package/dist/esm/mcp/tools/ci-preflight.js +183 -0
  272. package/dist/esm/mcp/tools/pr-upsert.js +39 -1
  273. package/dist/esm/mcp/tools/review-run.d.ts +28 -0
  274. package/dist/esm/mcp/tools/review-run.js +216 -0
  275. package/dist/esm/mcp/tools/run-wait.d.ts +86 -0
  276. package/dist/esm/mcp/tools/run-wait.js +593 -0
  277. package/dist/esm/mcp/tools/session-id.d.ts +3 -0
  278. package/dist/esm/mcp/tools/session-id.js +45 -0
  279. package/dist/esm/mcp/tools/session-info.d.ts +3 -0
  280. package/dist/esm/mcp/tools/session-info.js +49 -0
  281. package/dist/esm/output-transforms/audit.d.ts +23 -0
  282. package/dist/esm/output-transforms/audit.js +47 -0
  283. package/dist/esm/output-transforms/index.js +2 -0
  284. package/dist/esm/paths/state-root.js +3 -0
  285. package/dist/esm/review/authority.js +30 -7
  286. package/dist/esm/review/availability.d.ts +22 -0
  287. package/dist/esm/review/availability.js +123 -23
  288. package/dist/esm/review/delivery-verifier.d.ts +27 -0
  289. package/dist/esm/review/delivery-verifier.js +115 -0
  290. package/dist/esm/review/events.d.ts +3 -2
  291. package/dist/esm/review/events.js +23 -3
  292. package/dist/esm/review/execution/adapters.js +26 -9
  293. package/dist/esm/review/execution/output-policy.d.ts +2 -0
  294. package/dist/esm/review/execution/output-policy.js +12 -0
  295. package/dist/esm/review/execution/review-checkout.js +87 -6
  296. package/dist/esm/review/execution/supervisor.js +5 -0
  297. package/dist/esm/review/execution/types.d.ts +8 -0
  298. package/dist/esm/review/opencode-account.d.ts +24 -0
  299. package/dist/esm/review/opencode-account.js +68 -0
  300. package/dist/esm/review/opencode-auth.d.ts +33 -0
  301. package/dist/esm/review/opencode-auth.js +79 -0
  302. package/dist/esm/review/subject.d.ts +27 -0
  303. package/dist/esm/review/subject.js +179 -32
  304. package/dist/esm/runtime/executor.d.ts +1 -0
  305. package/dist/esm/runtime/executor.js +2 -1
  306. package/dist/esm/runtime/opencode-account-materializer.d.ts +34 -0
  307. package/dist/esm/runtime/opencode-account-materializer.js +33 -0
  308. package/dist/esm/secret-gate/runner.d.ts +1 -0
  309. package/dist/esm/secret-gate/runner.js +4 -1
  310. package/dist/esm/status/snapshot.js +30 -19
  311. package/dist/esm/test/duration-sequencer.d.ts +20 -0
  312. package/dist/esm/test/duration-sequencer.js +54 -0
  313. package/dist/esm/test/shard-durations.json +922 -0
  314. package/dist/esm/test/worker-budget.d.ts +6 -0
  315. package/dist/esm/test/worker-budget.js +59 -1
  316. package/dist/esm/test-helpers/global-setup.d.ts +1 -1
  317. package/dist/esm/test-helpers/global-setup.js +68 -24
  318. package/dist/esm/ultragoal/service.d.ts +7 -0
  319. package/dist/esm/ultragoal/service.js +42 -2
  320. package/dist/esm/utils/write-json-file.js +3 -1
  321. package/dist/esm/worktrees/codex-project-trust.d.ts +15 -0
  322. package/dist/esm/worktrees/codex-project-trust.js +56 -0
  323. package/dist/esm/worktrees/current.d.ts +1 -0
  324. package/dist/esm/worktrees/current.js +1 -0
  325. package/dist/esm/worktrees/project-agent-surfaces.d.ts +1 -0
  326. package/dist/esm/worktrees/project-agent-surfaces.js +2 -1
  327. package/dist/esm/worktrees/registry.d.ts +8 -0
  328. package/dist/esm/worktrees/registry.js +18 -3
  329. package/package.json +18 -15
package/README.md CHANGED
@@ -12,6 +12,11 @@ projects a repeatable `wp` command surface, generated host instructions, MCP
12
12
  quality tools, local continuity, and policy checks so agent work can be run,
13
13
  reviewed, and repaired with evidence.
14
14
 
15
+ Its durable value is repo-owned policy and evidence, not matching every native
16
+ host feature. Host launchers and plugin packages bridge the repo contract onto
17
+ Claude, Codex, OpenCode, Grok, and future hosts; parity utilities are kept only
18
+ where they protect that contract.
19
+
15
20
  The root `@webpresso/agent-kit` package is the CLI/core distribution: it
16
21
  ships `wp`, MCP tools, audits, blueprints, session memory, docs, and the
17
22
  catalog sources that generate repo-owned agent surfaces. Host-native plugin
@@ -96,13 +101,25 @@ Native host delivery is package-scoped: Claude, Codex, and OpenCode consume
96
101
  `@webpresso/claude-plugin`, `@webpresso/codex-plugin`, and
97
102
  `@webpresso/opencode-plugin` respectively. The root
98
103
  `@webpresso/agent-kit` package no longer ships repo-root host plugin payloads,
99
- and OpenCode uses native `opencode.json` `plugin[]` registration via
100
- `@webpresso/opencode-plugin`, not an MCP bridge. Claude Code installs the
104
+ and OpenCode combines native `opencode.json` `plugin[]` registration via
105
+ `@webpresso/opencode-plugin` (hook bridge) with a setup-managed
106
+ `mcp.webpresso` entry that launches the shared `wp mcp` server directly.
107
+ Claude Code installs the
101
108
  plugin as `agent-kit@webpresso` from a **version-pinned** GitHub marketplace
102
109
  (`webpresso/agent-kit@vX.Y.Z`); `wp update` / `wp setup` rebind that pin so
103
110
  hosts do not freeze on a stale catalog. See
104
111
  [`docs/packages/claude-plugin.md`](./docs/packages/claude-plugin.md).
105
112
 
113
+ All four supported hosts receive the same `wp mcp` server from one canonical
114
+ spec (`webpresso`, args `["mcp"]`, env `WP_SKIP_UPDATE_CHECK=1`):
115
+
116
+ | Host | Skills | Hooks | MCP (`wp mcp`) |
117
+ | -------- | ------------------------------------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------- |
118
+ | Claude | plugin `agent-kit@webpresso` | setup-managed `.claude/settings.json` | plugin manifest `mcpServers.webpresso` |
119
+ | Codex | plugin `@webpresso/codex-plugin` | setup-managed `.codex/hooks.json` | setup-managed `~/.codex/config.toml` `[mcp_servers.webpresso]` |
120
+ | OpenCode | shared skill roots (`.claude/`, `.agents/`) | npm plugin `@webpresso/opencode-plugin` via `plugin[]` | setup-managed `opencode.json` `mcp.webpresso` |
121
+ | Grok | reads `AGENTS.md`/`CLAUDE.md` natively | project `.grok/hooks/webpresso.json` (trust-gated: run `/hooks-trust` once) | project `.grok/config.toml` `[mcp_servers.webpresso]` |
122
+
106
123
  Then ask Claude, Codex, or another MCP-capable host for one bounded read-only
107
124
  check:
108
125
 
@@ -122,20 +139,40 @@ When a repo uses provider-backed MCP credentials, launch the host through
122
139
  `wp claude`, `wp codex`, `wp grok`, `wp opencode`, or `wp dash` so `wp` can inject the
123
140
  configured provider environment before the host starts.
124
141
 
142
+ Maintainers prove Claude's package-native path in an isolated fixture with
143
+ `claude --plugin-dir packages/claude-plugin`, empty setting sources, built-in
144
+ tools disabled, and an MCP allowlist containing only `wp_session_stats`. Grok
145
+ operators run `/hooks-trust` in the project once, then verify discovery with
146
+ `grok inspect --json`, `grok mcp list --json`, and
147
+ `grok mcp doctor webpresso --json`. Scoping doctor keeps unrelated personal MCP
148
+ authentication failures out of the Webpresso result.
149
+ Provider-authenticated inference is deliberately local-only:
150
+
151
+ ```bash
152
+ wp run proof:host-native
153
+ ```
154
+
155
+ The command uses the Claude and Grok CLIs' saved local subscription sessions,
156
+ removes API-key and CI OAuth variables from its child processes, fails closed
157
+ when either login is unavailable, and writes only redacted evidence under
158
+ `.webpresso/evidence/`. CI/CD validates the deterministic host contracts but
159
+ never receives provider credentials or performs billed model inference. Use
160
+ `proof:host-native:claude` or `proof:host-native:grok` to run one host.
161
+
125
162
  ## What `wp` guards
126
163
 
127
- | Outcome | What Agent Kit provides | Proof |
128
- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
129
- | Start from a known repo contract | `wp setup repair --project-init` creates or repairs agent instructions, host config, docs templates, blueprint folders, quality scripts, and safe ignores. | [setup command source](https://github.com/webpresso/agent-kit/tree/main/src/cli/commands/init) |
130
- | Give agents one command facade | `wp test`, `wp lint`, `wp typecheck`, `wp format`, `wp e2e`, `wp qa`, `wp audit`, `wp worktree`, `wp fleet`, and `wp secrets` wrap repo-specific tooling behind one facade (see [stability policy](./docs/stability-policy.md) for which surfaces carry semver guarantees). | [CLI entrypoint](https://github.com/webpresso/agent-kit/blob/main/src/cli/cli.ts) |
131
- | Expose bounded MCP tools | `wp_*` MCP tools return JSON summaries with failure evidence, output limits, and token-saved metadata instead of raw terminal dumps. | [MCP registry](https://github.com/webpresso/agent-kit/blob/main/src/mcp/tools/_registry.ts) |
132
- | Keep host surfaces consistent | One catalog projects rules, hooks, generated instruction files, and the adapter-package contents used for native Claude, Codex, and OpenCode registration. | [Claude adapter](./packages/claude-plugin/), [Codex adapter](./packages/codex-plugin/), [OpenCode adapter](./packages/opencode-plugin/) |
133
- | Preserve local continuity | Session memory is local storage with explicit search, restore, capture, retrieve, reset, and doctor tools. | [`docs/guides/session-memory.md`](./docs/guides/session-memory.md), [`docs/bench/session-memory-methodology.md`](./docs/bench/session-memory-methodology.md) |
134
- | Isolate risky work | Managed worktrees and blueprint owner binding keep implementation lanes separate from the main checkout. | [worktrees guide](https://github.com/webpresso/agent-kit/blob/main/docs/worktrees.md) |
135
- | Run browser QA with evidence | Browser doctor/ensure helpers and bundled browse, QA, design-review, and devex-review skills support local or explicit preview URLs. | [browser source](https://github.com/webpresso/agent-kit/tree/main/src/browser), [QA output guide](https://github.com/webpresso/agent-kit/blob/main/docs/qa-output.md) |
136
- | Handle secrets without committing them | Provider/profile/sink contracts route secrets through configured runtime channels for local commands, host launch wrappers, CI rehearsal, and supported preview/deploy workflows with repo-specific setup. | [`docs/secrets/providers.md`](./docs/secrets/providers.md), [`docs/ci-act.md`](./docs/ci-act.md) |
137
- | Block drift before release | Guardrails cover docs, blueprints, catalog drift, reference parity, paths, licenses, secrets, tech debt, and package surface. | [audit source](https://github.com/webpresso/agent-kit/tree/main/src/audit), [`docs/bench/reference-parity-matrix.md`](./docs/bench/reference-parity-matrix.md), [host smoke test](https://github.com/webpresso/agent-kit/blob/main/src/__integration__/reference-parity-host-smoke.integration.test.ts), [tool surface test](https://github.com/webpresso/agent-kit/blob/main/src/__integration__/reference-parity-tool-surface.integration.test.ts) |
138
- | Tie claims to evidence | Public benchmark and release claims require docs gates plus a checked-in first-party result card under `docs/bench/result-cards/` before publication. | [`docs/bench/result-card-contract.md`](./docs/bench/result-card-contract.md), [`docs/bench/result-cards/README.md`](./docs/bench/result-cards/README.md), [public readiness script](https://github.com/webpresso/agent-kit/blob/main/scripts/public-readiness.ts) |
164
+ | Outcome | What Agent Kit provides | Proof |
165
+ | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
166
+ | Start from a known repo contract | `wp setup repair --project-init` creates or repairs agent instructions, host config, docs templates, blueprint folders, quality scripts, and safe ignores. | [setup command source](https://github.com/webpresso/agent-kit/tree/main/src/cli/commands/init) |
167
+ | Give agents one command bridge | `wp test`, `wp lint`, `wp typecheck`, `wp format`, `wp e2e`, `wp qa`, `wp audit`, `wp worktree`, `wp fleet`, and `wp secrets` expose repo-owned checks consistently while host-native mechanics stay replaceable (see [stability policy](./docs/stability-policy.md) for which surfaces carry semver guarantees). | [CLI entrypoint](https://github.com/webpresso/agent-kit/blob/main/src/cli/cli.ts) |
168
+ | Expose bounded MCP tools | `wp_*` MCP tools return JSON summaries with failure evidence, output limits, and token-saved metadata instead of raw terminal dumps. | [MCP registry](https://github.com/webpresso/agent-kit/blob/main/src/mcp/tools/_registry.ts) |
169
+ | Keep host surfaces consistent | One catalog projects rules, hooks, generated instruction files, and adapter-package contents; host-specific plugins are bridges, not the source of policy truth. | [Claude adapter](./packages/claude-plugin/), [Codex adapter](./packages/codex-plugin/), [OpenCode adapter](./packages/opencode-plugin/), [host substitution scorecard](./docs/host-substitution-scorecard.md) |
170
+ | Preserve local continuity | Session memory is local storage with explicit search, restore, capture, retrieve, reset, and doctor tools. | [`docs/guides/session-memory.md`](./docs/guides/session-memory.md), [`docs/bench/session-memory-methodology.md`](./docs/bench/session-memory-methodology.md) |
171
+ | Isolate risky work | Managed worktrees and blueprint owner binding keep implementation lanes separate from the main checkout. | [worktrees guide](https://github.com/webpresso/agent-kit/blob/main/docs/worktrees.md) |
172
+ | Run browser QA with evidence | Browser doctor/ensure helpers and bundled browse, QA, design-review, and devex-review skills support local or explicit preview URLs. | [browser source](https://github.com/webpresso/agent-kit/tree/main/src/browser), [QA output guide](https://github.com/webpresso/agent-kit/blob/main/docs/qa-output.md) |
173
+ | Handle secrets without committing them | Provider/profile/sink contracts route secrets through configured runtime channels for local commands, host launch wrappers, CI rehearsal, and supported preview/deploy workflows with repo-specific setup. | [`docs/secrets/providers.md`](./docs/secrets/providers.md), [`docs/ci-act.md`](./docs/ci-act.md) |
174
+ | Block drift before release | Guardrails cover docs, blueprints, catalog drift, reference parity, paths, licenses, secrets, tech debt, and package surface. | [audit source](https://github.com/webpresso/agent-kit/tree/main/src/audit), [`docs/bench/reference-parity-matrix.md`](./docs/bench/reference-parity-matrix.md), [host smoke test](https://github.com/webpresso/agent-kit/blob/main/src/__integration__/reference-parity-host-smoke.integration.test.ts), [tool surface test](https://github.com/webpresso/agent-kit/blob/main/src/__integration__/reference-parity-tool-surface.integration.test.ts) |
175
+ | Tie claims to evidence | Public benchmark and release claims require docs gates plus a checked-in first-party result card under `docs/bench/result-cards/` before publication. | [`docs/bench/result-card-contract.md`](./docs/bench/result-card-contract.md), [`docs/bench/result-cards/README.md`](./docs/bench/result-cards/README.md), [public readiness script](https://github.com/webpresso/agent-kit/blob/main/scripts/public-readiness.ts) |
139
176
 
140
177
  ## Develop/deploy workflow shape
141
178
 
@@ -258,7 +295,8 @@ surfaces, quality gates, MCP tools, session memory, worktrees, blueprints,
258
295
  preview/deploy guardrails, and audit policy in one repeatable package.
259
296
 
260
297
  Skip it when you only want a prompt library, cannot run Node-based developer
261
- tooling, or do not want repo-local agent files. See
298
+ tooling, or do not want repo-local agent files. Agent Kit is a repository
299
+ delivery harness around coding-agent hosts, not a runtime agent SDK — see
262
300
  [`docs/is-agent-kit-for-me.md`](https://github.com/webpresso/agent-kit/blob/main/docs/is-agent-kit-for-me.md).
263
301
 
264
302
  ## Maintainer verification
package/bin/_run.js CHANGED
@@ -1,8 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { spawn, spawnSync } from "node:child_process";
4
- import { existsSync, readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
5
- import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
4
+ import {
5
+ accessSync,
6
+ constants,
7
+ existsSync,
8
+ readFileSync,
9
+ readdirSync,
10
+ realpathSync,
11
+ statSync,
12
+ } from "node:fs";
13
+ import { basename, delimiter, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
6
14
  import { fileURLToPath } from "node:url";
7
15
 
8
16
  import {
@@ -28,6 +36,9 @@ const LAUNCHER_LINEAGE_ENV = "WP_INTERNAL_LAUNCHER_LINEAGE";
28
36
  const MAX_LAUNCHER_LINEAGE_DEPTH = 16;
29
37
  const MAX_LAUNCHER_LINEAGE_BYTES = 16 * 1024;
30
38
  const WP_PROBE_TIMEOUT_MS = 5_000;
39
+ // Set on the child env when bootstrapping deps via `vp install`; a re-entrant `wp install`
40
+ // (e.g. a vp wrapper that shells back to wp) sees it and refuses, bounding recursion.
41
+ const BOOTSTRAP_VP_INSTALL_SENTINEL = "WP_BOOTSTRAP_VP_INSTALL";
31
42
  const WP_PROBE_TERM_GRACE_MS = 250;
32
43
  const WP_PROBE_KILL_OBSERVE_MS = 1_000;
33
44
  const WP_PROBE_OUTPUT_LIMIT_BYTES = 64 * 1024;
@@ -839,6 +850,139 @@ function formatMissingPathDelegateDiagnostic(repoRoot) {
839
850
  ].join(" ");
840
851
  }
841
852
 
853
+ // Shared PATH-scan core for the bootstrap layer: yields { candidate, realpath } for each
854
+ // `join(dir, name)` (name ∈ binNames) across PATH, realpath-deduped, skipping excludedOwners.
855
+ // Extracted so the wp delegate resolver and the vp bootstrap resolver share one loop instead of
856
+ // copying it. binNames is a list so callers can supply Windows PATHEXT variants (e.g. vp.cmd).
857
+ function* iterateAgentPathCandidates({ binNames, pathEnv, excludedOwners = new Set() }) {
858
+ const seen = new Set();
859
+ for (const dir of pathEnv.split(delimiter)) {
860
+ if (!dir) continue;
861
+ for (const binName of binNames) {
862
+ const candidate = join(dir, binName);
863
+ if (!existsSync(candidate)) continue;
864
+ let realpath;
865
+ try {
866
+ realpath = canonicalPath(candidate);
867
+ } catch {
868
+ continue;
869
+ }
870
+ if (excludedOwners.has(realpath) || seen.has(realpath)) continue;
871
+ seen.add(realpath);
872
+ yield { candidate, realpath };
873
+ }
874
+ }
875
+ }
876
+
877
+ // Plain-JS mirror of src/cli/global-vp.ts's rejection contract. bin/_run.js is the
878
+ // dependency-free bootstrap layer and cannot import global-vp.ts (TS, resolved from
879
+ // node_modules that do not exist yet), so the contract is duplicated here by necessity.
880
+ function splitPathSegments(value) {
881
+ const normalized = value.replace(/\\/g, sep);
882
+ const stripped = normalized.startsWith(sep) ? normalized.slice(sep.length) : normalized;
883
+ return stripped.split(sep).filter((segment) => segment.length > 0 && segment !== delimiter);
884
+ }
885
+ function hasSegmentPair(segments, left, right) {
886
+ return segments.some((segment, index) => segment === left && segments[index + 1] === right);
887
+ }
888
+ function isProjectNodeModulesCandidate(value) {
889
+ const segments = splitPathSegments(value);
890
+ return segments.includes("node_modules") && !segments.includes(".vite-plus");
891
+ }
892
+ function isRuntimeLocalVitePlusCandidate(value) {
893
+ return hasSegmentPair(splitPathSegments(value), ".vite-plus", "js_runtime");
894
+ }
895
+ function isRejectedBootstrapVpCandidate(candidatePath, realpath) {
896
+ return (
897
+ isProjectNodeModulesCandidate(candidatePath) ||
898
+ isProjectNodeModulesCandidate(realpath) ||
899
+ isRuntimeLocalVitePlusCandidate(candidatePath) ||
900
+ isRuntimeLocalVitePlusCandidate(realpath)
901
+ );
902
+ }
903
+ function isExecutableFile(path, platform = process.platform) {
904
+ try {
905
+ if (!statSync(path).isFile()) return false;
906
+ if (platform !== "win32") accessSync(path, constants.X_OK);
907
+ return true;
908
+ } catch {
909
+ return false;
910
+ }
911
+ }
912
+
913
+ // The `vp` filenames to look for on PATH. On Windows, expand PATHEXT (e.g. vp.cmd, vp.exe) so a
914
+ // shim-installed `vp` is found; elsewhere just `vp`. Mirrors src/cli/global-vp.ts's discovery.
915
+ function bootstrapVpCandidateNames(platform, env) {
916
+ if (platform !== "win32") return ["vp"];
917
+ const exts = (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD")
918
+ .split(";")
919
+ .map((ext) => ext.trim())
920
+ .filter((ext) => ext.length > 0);
921
+ return [...exts.map((ext) => `vp${ext}`), "vp"];
922
+ }
923
+
924
+ // Build the spawn descriptor for a resolved vp. On Windows a `.cmd`/`.bat` shim must run through
925
+ // the command interpreter; elsewhere the realpath is executed directly. Mirrors global-vp.ts.
926
+ function bootstrapVpCommand(realpath, platform, env) {
927
+ if (platform === "win32" && /\.(?:cmd|bat)$/iu.test(realpath)) {
928
+ return {
929
+ command: env.ComSpec ?? env.COMSPEC ?? "cmd.exe",
930
+ args: ["/d", "/s", "/c", realpath],
931
+ };
932
+ }
933
+ return { command: realpath, args: [] };
934
+ }
935
+
936
+ // Resolve a global Vite+ (`vp`) binary on PATH to bootstrap dependency installation on a bare
937
+ // agent-kit source checkout, where `wp install` cannot load its own CLI. Mirrors the
938
+ // `resolveGlobalCapableVp` contract: rejects project-local and Vite+ runtime-local `vp`, checks
939
+ // executability, expands Windows PATHEXT, and wraps `.cmd`/`.bat` shims. Returns a spawn
940
+ // descriptor `{ command, args }` (args is the prefix before the forwarded install args) or null.
941
+ export function resolveBareCheckoutVp({
942
+ pathEnv = process.env.PATH ?? "",
943
+ platform = process.platform,
944
+ env = process.env,
945
+ } = {}) {
946
+ const binNames = bootstrapVpCandidateNames(platform, env);
947
+ for (const { candidate, realpath } of iterateAgentPathCandidates({ binNames, pathEnv })) {
948
+ if (isRejectedBootstrapVpCandidate(candidate, realpath)) continue;
949
+ if (!isExecutableFile(realpath, platform)) continue;
950
+ return bootstrapVpCommand(realpath, platform, env);
951
+ }
952
+ return null;
953
+ }
954
+
955
+ // True only for a BARE `wp install` on a bare checkout. Positional subcommands
956
+ // (`wp install codex|claude-code|opencode|oh-my`, or `wp install <pkg>`) route to
957
+ // adapter/global-install/add paths in the real CLI and must NOT be blindly delegated to
958
+ // `vp install`; only flag-only forms (e.g. `--frozen-lockfile`) pass. Deliberately not
959
+ // generalized to `update`/`add`: default `wp update` is a tooling refresh, not a PM install.
960
+ //
961
+ // Eligibility keys off whether the CLI can actually load, not merely `node_modules` absence: the
962
+ // CLI's own dependency `cac` must be present, or a built dist CLI must exist. This covers both a
963
+ // fully bare checkout AND a partial/interrupted install (node_modules present but `cac` missing),
964
+ // which would otherwise fall through to the same missing-dependency source crash.
965
+ export function isInstallBootstrapNeeded(binName, argv, { repoRoot, env = process.env } = {}) {
966
+ if (binName !== "wp") return false;
967
+ if (argv[0] !== "install") return false;
968
+ if (!argv.slice(1).every((arg) => arg.startsWith("-"))) return false;
969
+ if (env.WP_FORCE_SOURCE === "1") return false;
970
+ if (!isAgentKitSourceRepo(repoRoot)) return false;
971
+ const cacInstalled = existsSync(join(repoRoot, "node_modules", "cac"));
972
+ const builtCli = existsSync(join(repoRoot, "dist", "esm", "cli", "cli.js"));
973
+ return !cacInstalled && !builtCli;
974
+ }
975
+
976
+ function formatMissingBareInstallDiagnostic(repoRoot) {
977
+ return [
978
+ "Unable to bootstrap dependencies for this @webpresso/agent-kit checkout:",
979
+ "its runtime dependencies are not installed, so `wp install` cannot load its own CLI (which",
980
+ "depends on packages that are not present yet).",
981
+ `No Vite+ (\`vp\`) binary was found on PATH to perform the install for ${repoRoot}.`,
982
+ "Install Vite+ (see the vite-plus documentation) or run a supported global `wp`, then re-run `wp install`.",
983
+ ].join(" ");
984
+ }
985
+
842
986
  export async function resolvePathDelegateWp({
843
987
  repoRoot = resolvePackageRoot(),
844
988
  pathEnv = process.env.PATH ?? "",
@@ -861,24 +1005,15 @@ export async function resolvePathDelegateWp({
861
1005
 
862
1006
  const excludedOwners = new Set(launcherLineage);
863
1007
  if (selfRealpath !== null) excludedOwners.add(selfRealpath);
864
- const seenCandidates = new Set();
865
- for (const dir of pathEnv.split(delimiter)) {
866
- if (!dir) continue;
867
- const candidate = join(dir, "wp");
868
- if (!existsSync(candidate)) continue;
869
- let candidateRealpath;
870
- try {
871
- candidateRealpath = canonicalPath(candidate);
872
- } catch {
873
- continue;
874
- }
875
- if (excludedOwners.has(candidateRealpath) || seenCandidates.has(candidateRealpath)) continue;
876
- seenCandidates.add(candidateRealpath);
877
- const probeEnv = withLauncherDelegate(env, launcherLineage, candidateRealpath);
878
- if (!(await isAgentKitWpBinary(candidateRealpath, probeEnv, probeVersion, probeCommand))) {
879
- continue;
1008
+ for (const { realpath } of iterateAgentPathCandidates({
1009
+ binNames: ["wp"],
1010
+ pathEnv,
1011
+ excludedOwners,
1012
+ })) {
1013
+ const probeEnv = withLauncherDelegate(env, launcherLineage, realpath);
1014
+ if (await isAgentKitWpBinary(realpath, probeEnv, probeVersion, probeCommand)) {
1015
+ return realpath;
880
1016
  }
881
- return candidateRealpath;
882
1017
  }
883
1018
  return null;
884
1019
  }
@@ -954,6 +1089,31 @@ export async function runNamedBin(binName, argv = process.argv.slice(2)) {
954
1089
  if (shouldBareMcpDelegate) throw new Error(formatMissingPathDelegateDiagnostic(repoRoot));
955
1090
  }
956
1091
 
1092
+ // Dependency bootstrap for `wp install` when the CLI's own deps are not installed. Runs after
1093
+ // the global-`wp` delegate attempt above (a healthy global wp is preferred for bare checkouts),
1094
+ // and independently of `bareExternalPluginCheckout` so a partial/interrupted install (node_modules
1095
+ // present but unusable) is also recovered instead of crashing on the missing `cac` import.
1096
+ if (isInstallBootstrapNeeded(binName, argv, { repoRoot })) {
1097
+ if (process.env[BOOTSTRAP_VP_INSTALL_SENTINEL] === "1") {
1098
+ throw new Error(
1099
+ "Refusing recursive vp bootstrap: a vp on PATH re-invoked `wp install` during dependency bootstrap.",
1100
+ );
1101
+ }
1102
+ const vp = resolveBareCheckoutVp();
1103
+ if (!vp) throw new Error(formatMissingBareInstallDiagnostic(repoRoot));
1104
+ // Preserve the caller's cwd (matches package-manager.ts's `vp install`); do not force repoRoot.
1105
+ const installed = spawnSync(vp.command, [...vp.args, "install", ...argv.slice(1)], {
1106
+ stdio: "inherit",
1107
+ env: { ...process.env, [BOOTSTRAP_VP_INSTALL_SENTINEL]: "1" },
1108
+ });
1109
+ if (installed.error) throw installed.error;
1110
+ if (installed.signal) {
1111
+ process.kill(process.pid, installed.signal);
1112
+ return;
1113
+ }
1114
+ process.exit(installed.status ?? 1);
1115
+ }
1116
+
957
1117
  const plan = buildLaunchPlan({ binName, forwardedArgs: argv, repoRoot });
958
1118
  const isHookDispatch = binName === "wp" && argv[0] === "hook";
959
1119
  const isHooksRuntimeCommand =
@@ -47,8 +47,8 @@ Catalog-owned surfaces:
47
47
 
48
48
  - Command routing is a hard invariant: prefer `wp`, then `vp`, then `pnpm`.
49
49
  Use `vp` only when `wp` has no equivalent, and raw `pnpm` only when
50
- neither facade can perform the operation. All documentation, instructions,
51
- scripts, and workflow examples must follow this order.
50
+ neither facade can perform the operation. All docs, instructions, scripts,
51
+ and workflows must follow this order.
52
52
  - Prefer repo scripts/wrappers over ad-hoc commands.
53
53
  - Repo hook/tool denial: switch to the named facade/lifecycle; do not retry raw.
54
54
  - Reuse nearby utilities and patterns before adding new abstractions.
@@ -63,10 +63,10 @@ asynchronously.
63
63
 
64
64
  ## Verify
65
65
 
66
- Before claiming completion, run the narrowest checks that prove the change:
67
- MCP/`wp` quality tools, typecheck, lint/format, affected tests, policy checks,
68
- docs/blueprint validation when those changed, and `wp sync --check` after
69
- template/catalog changes. On failure, fix root cause or record the blocker.
66
+ Before claiming completion, run the narrowest MCP/`wp` checks that prove the
67
+ change: typecheck, lint/format, affected tests, policy, docs/blueprint, and
68
+ `wp sync --check` after template/catalog changes. Fix root cause or record the
69
+ blocker. Before pushing, run `wp_ci_preflight` (see `ci-cost-local-first`).
70
70
 
71
71
  ## Communicate
72
72
 
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: implementer
3
+ description: Implement a scoped fix or feature end-to-end (reproduce, edit, verify) when the task needs real Edit/Write/Bash access, not just review or docs. Prefer this over general-purpose for a single well-scoped code change.
4
+ tools:
5
+ - Read
6
+ - Grep
7
+ - Glob
8
+ - Edit
9
+ - Write
10
+ - Bash
11
+ model: sonnet
12
+ ---
13
+
14
+ # Implementer
15
+
16
+ You own landing one scoped code change: reproduce the problem or confirm the
17
+ requirement, make the minimal correct edit, and prove it works.
18
+
19
+ ## Primary responsibilities
20
+
21
+ - Reproduce the failure or confirm the requirement before editing.
22
+ - Fix at the owning boundary — the root cause, not the nearest symptom.
23
+ - Write or strengthen a regression proof (test, or the nearest reliable
24
+ equivalent) that fails against the old behavior before your fix and passes
25
+ after.
26
+ - Update every consumer of a changed contract in the same change. No
27
+ half-migrations.
28
+ - Run the narrowest verification that proves the repaired behavior (lint,
29
+ typecheck, targeted tests, relevant audits) before reporting done.
30
+
31
+ ## Scope discipline
32
+
33
+ - One coherent repair per dispatch. If the task turns out to be several
34
+ unrelated failures, say so and name them instead of bundling fixes.
35
+ - No speculative abstractions, config knobs, or unrelated cleanup alongside
36
+ the fix.
37
+ - No silent fallbacks, suppressions, or lint disables to make a check pass.
38
+
39
+ ## Expected output
40
+
41
+ - The invariant that was broken, in one sentence.
42
+ - What changed and why, at the owning boundary.
43
+ - The verification that ran (commands, exit codes, test names) — not a claim
44
+ without evidence.
45
+ - Anything noticed but intentionally left unfixed, named explicitly.
@@ -0,0 +1,139 @@
1
+ ---
2
+ type: rule
3
+ slug: ci-cost-local-first
4
+ title: CI cost and local-first gates
5
+ status: active
6
+ scope: repo
7
+ applies_to: [agents]
8
+ related:
9
+ - cmd-execution
10
+ - ci-test-perf
11
+ - pre-implementation
12
+ - hook-hot-path
13
+ - no-timeout-as-fix
14
+ created: "2026-07-21"
15
+ last_reviewed: "2026-07-21"
16
+ paths:
17
+ - ".github/workflows/**"
18
+ - "catalog/agent/**"
19
+ - "AGENTS.md"
20
+ - ".husky/**"
21
+ ---
22
+
23
+ # CI cost and local-first gates
24
+
25
+ Agents waste money when they treat remote CI as the primary debugger.
26
+ **Catch failures locally first.** Remote CI is confirmation, not exploration.
27
+
28
+ Monthly spend on private repos (Ubicloud + GitHub-hosted minutes + artifact
29
+ storage) is a product constraint. Prefer cheap local loops over burning full
30
+ PR matrices to discover format/lint/type/test/governance failures.
31
+
32
+ ## Iron law
33
+
34
+ 1. **Never open or update a PR you already know will fail** a locally-runnable
35
+ gate (format, guardrails, typecheck, lint, affected tests, PR body contract,
36
+ changeset/blueprint trailers when applicable).
37
+ 2. **Never use `git push --no-verify` / `HUSKY=0` / skip hooks** to “save
38
+ time.” That only moves the failure to paid CI and trains a red-loop habit.
39
+ 3. **Never re-run a failed CI job “to see if it flaked”** until you have a
40
+ local reproduction or a concrete flake hypothesis with evidence.
41
+ 4. **Never add GitHub-hosted runners** (`ubuntu-latest`, `macos-*`,
42
+ `windows-*`) on private-repo workflows except the **Release / npm OIDC
43
+ publish** path (and release-native targets that truly need that OS). Default
44
+ is **Ubicloud** (`ubicloud-standard-2` / `-4` only when justified).
45
+
46
+ ## Local gate stack (must pass before push)
47
+
48
+ | When | Command / check |
49
+ | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
50
+ | Every commit | Managed pre-commit (format + staged guardrails) |
51
+ | Every push | `wp ci-preflight` before pushing; in agent-kit itself this is also enforced by `.husky/pre-push` |
52
+ | Before PR open / body edit | PR template fields filled; trailers exact (`Blueprint-exempt`, `Changeset-exempt`, `Review-skip` as **start-of-line** when used) |
53
+ | Before claim merge-ready | `/verify <target>` then `/verify <target> --merge-ready` when landing |
54
+
55
+ `wp ci-preflight` is fail-fast and **branch-scoped**:
56
+
57
+ 1. `wp format --affected --branch --check`
58
+ 2. `wp audit guardrails --affected --branch`
59
+ 3. `wp typecheck --affected --branch`
60
+ 4. `wp lint --affected --branch`
61
+ 5. `wp test --affected --branch`
62
+
63
+ If preflight fails: **fix locally**, do not push. Reproduce with the printed
64
+ `wp …` line.
65
+
66
+ ### Bootstrap before preflight
67
+
68
+ Missing `node_modules` in a worktree → run `wp install` (or the repo’s setup),
69
+ then preflight. Use `vp install` only when `wp` has no equivalent. Do not push a
70
+ bare worktree “to let CI install.”
71
+
72
+ ## Cost model (private repos)
73
+
74
+ | Resource | Cost driver | Agent duty |
75
+ | ------------------------------ | ------------------------------------------------- | ---------------------------------------------- |
76
+ | Ubicloud minutes | Every PR job matrix (lint, tests, smokes, shards) | Local preflight; avoid drive-by full re-runs |
77
+ | GitHub-hosted `ubuntu-latest` | Billable Actions minutes | Only release/OIDC publish unless proven needed |
78
+ | GitHub `macos-*` / `windows-*` | ~10× Linux minutes | Release natives only; never default PR CI |
79
+ | Actions artifacts / caches | Storage quota; can block Release uploads | Prefer short retention; do not spam artifacts |
80
+ | Failed CI loops | Full matrix × attempts | Fix from logs locally before `gh run rerun` |
81
+
82
+ Related: `ci-test-perf.md` (keep coverage; speed via workers/cache/shards — not
83
+ by skipping tests). Prefer **fewer/cheaper runners + sharding** over raising
84
+ timeouts (`no-timeout-as-fix.md`).
85
+
86
+ ## Workflow authoring (when you touch CI)
87
+
88
+ - Private non-release jobs: `runs-on: ubicloud-standard-2` by default.
89
+ - Use `ubicloud-standard-4` only when wall-time evidence shows standard-2 is
90
+ insufficient **with** full coverage and workers (document why).
91
+ - Release publish job may use `ubuntu-latest` for npm trusted publishing /
92
+ provenance. Session-memory / platform native matrices that require Darwin or
93
+ Windows may use GH-hosted OS runners **only on the Release (publish=true)
94
+ path**, never on ordinary PR CI.
95
+ - Path filters, `concurrency` cancel-in-progress, and change-scope skips are
96
+ preferred over always-on heavy jobs.
97
+ - Do not add nightly/macOS “perf” jobs that run on every PR; keep them opt-in
98
+ (`workflow_dispatch`, label, or schedule) and prefer Ubicloud for any check
99
+ that is not Apple-signing/display-bound.
100
+
101
+ ## PR governance without burning CI
102
+
103
+ These fail **before** expensive tests if you get them wrong — fix **before**
104
+ push/open:
105
+
106
+ - PR description AI/model disclosure + `Session id` (or `Session-skip`)
107
+ - `Review-skip: SKIP <reason>` must match `^Review-skip:` at **line start**
108
+ (not nested under a bullet)
109
+ - `Blueprint-exempt:` / `Changeset-exempt:` in **commit message** and/or body
110
+ when required (blueprint-pr-coverage reads **git trailers**, not only the PR body)
111
+ - Version Packages / bot CI: do not invent admin-merge; use the runbook
112
+ (`docs/runbooks/version-packages-bot-ci.md` when present)
113
+
114
+ ## Forbidden agent habits
115
+
116
+ - Push → watch red CI → tweak → push again (the “CI as unit test” loop)
117
+ - Broaden CI timeouts / disable flakes instead of root-cause fix
118
+ - Schedule or matrix-expand macOS/Windows for convenience
119
+ - Upload large artifacts every PR “for debugging”
120
+ - Claim “CI is green” from a partial check while WP check / required jobs pending
121
+ - Force-push past hooks to land red work for “later fix”
122
+
123
+ ## Good loop
124
+
125
+ ```text
126
+ edit → scoped lint/type/test → commit (hooks) → wp ci-preflight → push
127
+ → open PR with complete body → watch CI once → fix root cause locally if red
128
+ ```
129
+
130
+ When CI fails: download/read the failed job log, reproduce with the matching
131
+ local `wp` command, fix, preflight, push **one** corrective commit.
132
+
133
+ ## Related
134
+
135
+ - `cmd-execution.md` — bookend QA; scoped commands in the middle
136
+ - `ci-test-perf.md` — parallelism and install cache
137
+ - `pre-implementation.md` — blueprint gates that only fail in CI if left open
138
+ - `hook-hot-path.md` — pre-push stays local and non-network
139
+ - CLI: `wp ci-preflight` (pre-push owner)
@@ -56,9 +56,13 @@ Mutation/Stryker jobs are auto-exempt when the step/job name or nearby lines men
56
56
  When a single job still exceeds budget **with full coverage**:
57
57
 
58
58
  1. Prefer **Vitest sharding** (`vitest run --shard=i/n` + blob reporter merge) over raising isolation-off globally.
59
- 2. Prefer a **larger runner** (`ubicloud-standard-4`, etc.) + more `VITEST_MAX_WORKERS` over dropping suites.
59
+ 2. Prefer a **larger runner** (`ubicloud-standard-4`, etc.) + more `VITEST_MAX_WORKERS` over dropping suites — only after `ubicloud-standard-2` is proven insufficient. Do not jump to GitHub-hosted macOS/Windows for ordinary test jobs.
60
60
  3. Cache **native/build artifacts** when warm steps rebuild every PR (producer-specific).
61
61
 
62
+ Private-repo default is **Ubicloud** for non-release jobs. GitHub-hosted
63
+ runners are reserved for Release/OIDC publish (and release-native OS builds).
64
+ See `ci-cost-local-first.md`.
65
+
62
66
  ## Related
63
67
 
64
68
  - Vitest performance: https://vitest.dev/guide/improving-performance
@@ -14,6 +14,15 @@ paths:
14
14
 
15
15
  # Command Execution Rules
16
16
 
17
+ ## Local-first before remote CI
18
+
19
+ Paid CI (Ubicloud + GitHub-hosted) is for confirmation. Use scoped commands
20
+ while iterating, then **`wp ci-preflight` before every push**. In agent-kit
21
+ itself, `.husky/pre-push` enforces that gate; consumer templates may leave
22
+ pre-push checks user-owned. Never `git push --no-verify` to skip a configured
23
+ local gate. See `ci-cost-local-first.md` for runner policy and anti-red-loop
24
+ habits.
25
+
17
26
  ## BOOKEND Rule: Full QA Runs Exactly Twice
18
27
 
19
28
  The full QA pipeline (e.g. `wp qa`, `bun run qa`) is a