@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.
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
@@ -23,6 +23,9 @@ import { detectRepoCollectionRoot, isInitializedWebpressoProject, } from "./repo
23
23
  import { isAgentKitSourceRepo } from "./source-repo-hook-policy.js";
24
24
  import { summarizeResults } from "./merge.js";
25
25
  import { WritePlan, collectRepoWriteEntries, renderWritePlan } from "./write-plan.js";
26
+ import { writeConvergenceState } from "./convergence-state.js";
27
+ import { authorConvergenceCommit, collectAppliedConvergeUnits, formatWpSetupError, } from "./convergence-apply.js";
28
+ import { prepareRepositoryForConvergence } from "./git-convergence.js";
26
29
  import { collectUserScopeSteps, userScopeStepsToEntries, } from "./user-scope-plan.js";
27
30
  import { clearUserScopeConsentMarker, resolveUserScopeConsent, writeUserScopeConsentMarker, } from "./user-scope-consent.js";
28
31
  import { resolveTier3Selection } from "./prompts.js";
@@ -55,6 +58,7 @@ import { ensureClaudePlaywrightMcp, ensureCodexProjectMcpServers, ensureCodexWeb
55
58
  import { scaffoldExampleSkill } from "./scaffolders/example-skill/index.js";
56
59
  import { scaffoldLoreCommits } from "./scaffolders/lore-commits/index.js";
57
60
  import { ensureOpenCodeWebpressoPlugin } from "./scaffolders/opencode-plugin/index.js";
61
+ import { ensureGrokWebpressoMcp } from "./scaffolders/grok-mcp/index.js";
58
62
  import { ensureRtk } from "./scaffolders/rtk/index.js";
59
63
  import { checkRuntimes } from "./scaffolders/runtime-check/index.js";
60
64
  import { scaffoldSubagents } from "./scaffolders/subagents/index.js";
@@ -101,6 +105,22 @@ function normalizeAllToken(rawWith, allFlag) {
101
105
  all: wantsAll,
102
106
  };
103
107
  }
108
+ export function setupDeprecationWarnings(flags) {
109
+ const warnings = [];
110
+ if (flags.profile !== undefined) {
111
+ warnings.push("wp setup: `--profile` is deprecated and will be removed after this compatibility wave; use bare `wp setup` for repository convergence.");
112
+ }
113
+ if (flags.prune === true) {
114
+ warnings.push("wp setup: `--prune` is deprecated; use `wp update` for machine plugin/cache refresh.");
115
+ }
116
+ if (flags.yesGlobal === true ||
117
+ flags["yes-global"] === true ||
118
+ flags.skipGlobal === true ||
119
+ flags["skip-global"] === true) {
120
+ warnings.push("wp setup: global-consent flags are deprecated; use `wp setup` for repository convergence and `wp update` for machine state.");
121
+ }
122
+ return warnings;
123
+ }
104
124
  export function resolveSetupProfile(raw) {
105
125
  if (raw === undefined)
106
126
  return DEFAULT_SETUP_PROFILE;
@@ -307,28 +327,32 @@ async function runUserOnlySetup(input) {
307
327
  console.log(" workspace config: ✓ created ~/.agent/workspace.yaml");
308
328
  }
309
329
  }
310
- if (isCiEnvironment) {
311
- console.log(" codex cli: - skipped (CI environment)");
312
- }
313
- else {
314
- const codexCliResult = ensureCodexCli({ options: userScopeOptions });
315
- switch (codexCliResult.kind) {
316
- case "codex-cli-ok":
317
- console.log(codexCliResult.installed ? " codex cli: ✓ installed" : " codex cli: ✓");
318
- if (!userScopeOptions.dryRun) {
319
- writeToolingOwnershipState(claimUserOwnedTool(readToolingOwnershipState(), "codex"));
320
- }
321
- break;
322
- case "codex-cli-skipped-dry-run":
323
- console.log(" codex cli: skipped (--dry-run)");
324
- break;
325
- case "codex-cli-skipped-package-lifecycle":
326
- console.log(" codex cli: - skipped (package lifecycle environment)");
327
- break;
328
- case "codex-cli-unavailable":
329
- console.warn(` codex cli: ⚠ ${codexCliResult.hint}`);
330
- break;
330
+ if (selectedHosts.includes("codex")) {
331
+ if (isCiEnvironment) {
332
+ console.log(" codex cli: - skipped (CI environment)");
333
+ }
334
+ else {
335
+ const codexCliResult = ensureCodexCli({ options: userScopeOptions });
336
+ switch (codexCliResult.kind) {
337
+ case "codex-cli-ok":
338
+ console.log(codexCliResult.installed ? " codex cli: ✓ installed" : " codex cli: ✓");
339
+ if (!userScopeOptions.dryRun) {
340
+ writeToolingOwnershipState(claimUserOwnedTool(readToolingOwnershipState(), "codex"));
341
+ }
342
+ break;
343
+ case "codex-cli-skipped-dry-run":
344
+ console.log(" codex cli: skipped (--dry-run)");
345
+ break;
346
+ case "codex-cli-skipped-package-lifecycle":
347
+ console.log(" codex cli: - skipped (package lifecycle environment)");
348
+ break;
349
+ case "codex-cli-unavailable":
350
+ console.warn(` codex cli: ⚠ ${codexCliResult.hint}`);
351
+ break;
352
+ }
331
353
  }
354
+ }
355
+ if (selectedHosts.includes("claude") && !isCiEnvironment) {
332
356
  if (process.env.WP_SKIP_CLAUDE_PLUGIN === "1") {
333
357
  console.log(" claude cli: skipped (WP_SKIP_CLAUDE_PLUGIN=1)");
334
358
  }
@@ -356,22 +380,27 @@ async function runUserOnlySetup(input) {
356
380
  if (presets.includes("playwright-mcp")) {
357
381
  console.log(" playwright mcp: - skipped (the preset requires a project-owned .mcp.json; run setup inside the project repo)");
358
382
  }
359
- const webpressoMcpResult = ensureCodexWebpressoMcp({ options: userScopeOptions });
360
- switch (webpressoMcpResult.kind) {
361
- case "codex-webpresso-mcp-written":
362
- console.log(` codex webpresso mcp: ✓ ${webpressoMcpResult.path} → ${webpressoMcpResult.entryPath}`);
363
- break;
364
- case "codex-webpresso-mcp-unchanged":
365
- console.log(` codex webpresso mcp: already configured at ${webpressoMcpResult.path}`);
366
- break;
367
- case "codex-webpresso-mcp-skipped-dry-run":
368
- console.log(" codex webpresso mcp: skipped (--dry-run)");
369
- break;
370
- case "codex-webpresso-mcp-not-installed":
371
- console.log(` codex webpresso mcp: ⚠ no install root found (checked ${webpressoMcpResult.checked.length} paths). Install @webpresso/agent-kit globally (\`bun add -g @webpresso/agent-kit\`) or via the Claude plugin to wire up codex MCP.`);
372
- break;
383
+ if (selectedHosts.includes("codex")) {
384
+ const webpressoMcpResult = ensureCodexWebpressoMcp({ options: userScopeOptions });
385
+ switch (webpressoMcpResult.kind) {
386
+ case "codex-webpresso-mcp-written":
387
+ console.log(` codex webpresso mcp: ✓ ${webpressoMcpResult.path} → ${webpressoMcpResult.entryPath}`);
388
+ break;
389
+ case "codex-webpresso-mcp-unchanged":
390
+ console.log(` codex webpresso mcp: already configured at ${webpressoMcpResult.path}`);
391
+ break;
392
+ case "codex-webpresso-mcp-ambiguous":
393
+ console.warn(` codex webpresso mcp: ⚠ ambiguous MCP config at ${webpressoMcpResult.path}; left unchanged`);
394
+ break;
395
+ case "codex-webpresso-mcp-skipped-dry-run":
396
+ console.log(" codex webpresso mcp: skipped (--dry-run)");
397
+ break;
398
+ case "codex-webpresso-mcp-not-installed":
399
+ console.log(` codex webpresso mcp: ⚠ no install root found (checked ${webpressoMcpResult.checked.length} paths). Install @webpresso/agent-kit globally (\`bun add -g @webpresso/agent-kit\`) or via the Claude plugin to wire up codex MCP.`);
400
+ break;
401
+ }
402
+ console.log(" codex project mcp: - skipped (no project .mcp.json outside a repo)");
373
403
  }
374
- console.log(" codex project mcp: - skipped (no project .mcp.json outside a repo)");
375
404
  if (isCiEnvironment) {
376
405
  console.log(" agent-kit global: - skipped (CI environment)");
377
406
  }
@@ -406,33 +435,35 @@ async function runUserOnlySetup(input) {
406
435
  break;
407
436
  }
408
437
  }
409
- const claudePluginResult = ensureClaudeCodeUserPlugin({
410
- options: userScopeOptions,
411
- packageRoot,
412
- });
413
- switch (claudePluginResult.kind) {
414
- case "claude-plugin-installed":
415
- console.log(` claude plugin: ✓ user-scope marketplace + plugin ensured (${claudePluginResult.pluginId})`);
416
- break;
417
- case "claude-plugin-skipped-dry-run":
418
- console.log(" claude plugin: skipped (--dry-run)");
419
- break;
420
- case "claude-plugin-skipped-opt-out":
421
- console.log(" claude plugin: skipped (WP_SKIP_CLAUDE_PLUGIN=1)");
422
- break;
423
- case "claude-plugin-skipped-package-lifecycle":
424
- console.log(" claude plugin: - skipped (package lifecycle environment)");
425
- break;
426
- case "claude-plugin-skipped-no-cli":
427
- console.log(" claude plugin: - skipped (claude not on PATH)");
428
- break;
429
- case "claude-plugin-unavailable":
430
- console.log(" claude plugin: - skipped (plugin manifest unavailable in this install)");
431
- break;
432
- case "claude-plugin-failed":
433
- console.warn(` claude plugin: ⚠ ${claudePluginResult.step} exited with ${claudePluginResult.exitCode}; ` +
434
- `fallback: claude plugin marketplace add --scope user webpresso/agent-kit@v$(wp --version) && claude plugin install --scope user ${claudePluginResult.pluginId}`);
435
- break;
438
+ if (selectedHosts.includes("claude")) {
439
+ const claudePluginResult = ensureClaudeCodeUserPlugin({
440
+ options: userScopeOptions,
441
+ packageRoot,
442
+ });
443
+ switch (claudePluginResult.kind) {
444
+ case "claude-plugin-installed":
445
+ console.log(` claude plugin: ✓ user-scope marketplace + plugin ensured (${claudePluginResult.pluginId})`);
446
+ break;
447
+ case "claude-plugin-skipped-dry-run":
448
+ console.log(" claude plugin: skipped (--dry-run)");
449
+ break;
450
+ case "claude-plugin-skipped-opt-out":
451
+ console.log(" claude plugin: skipped (WP_SKIP_CLAUDE_PLUGIN=1)");
452
+ break;
453
+ case "claude-plugin-skipped-package-lifecycle":
454
+ console.log(" claude plugin: - skipped (package lifecycle environment)");
455
+ break;
456
+ case "claude-plugin-skipped-no-cli":
457
+ console.log(" claude plugin: - skipped (claude not on PATH)");
458
+ break;
459
+ case "claude-plugin-unavailable":
460
+ console.log(" claude plugin: - skipped (plugin manifest unavailable in this install)");
461
+ break;
462
+ case "claude-plugin-failed":
463
+ console.warn(` claude plugin: ${claudePluginResult.step} exited with ${claudePluginResult.exitCode}; ` +
464
+ `fallback: claude plugin marketplace add --scope user webpresso/agent-kit@v$(wp --version) && claude plugin install --scope user ${claudePluginResult.pluginId}`);
465
+ break;
466
+ }
436
467
  }
437
468
  if (selectedHosts.includes("codex") && !isCiEnvironment) {
438
469
  const codexPluginResult = ensureCodexUserPlugin({ options: userScopeOptions, packageRoot });
@@ -552,7 +583,7 @@ function enabledManagedHookVendors(manifest) {
552
583
  function disabledManagedHookVendors(manifest) {
553
584
  return ["claude", "codex"].filter((vendor) => manifest.vendorState[vendor] === "disabled");
554
585
  }
555
- async function runSourceRepoHookOnlyRecovery(repoRoot, options, stdout, mode = "repair-stale-only",
586
+ async function runSourceRepoHookOnlyRecovery(repoRoot, options, stdout, selectedHosts, mode = "repair-stale-only",
556
587
  /**
557
588
  * User/home-scope gate for the Codex hook-trust sync leg. The repo-scope
558
589
  * `.claude`/`.codex` hook restore always runs with `options`, but the trust
@@ -571,10 +602,15 @@ trustSync) {
571
602
  }
572
603
  const nextManifest = buildManagedHooksManifest(repoRoot, previousManifest?.vendorState);
573
604
  const input = { repoRoot, options, trustCodexHooks: false };
574
- const restored = restoreManagedHooksFromManifest(input, nextManifest, enabledManagedHookVendors(nextManifest));
605
+ const selectedManagedVendors = ["claude", "codex"].filter((vendor) => selectedHosts.includes(vendor));
606
+ if (selectedManagedVendors.length === 0) {
607
+ return null;
608
+ }
609
+ const restored = restoreManagedHooksFromManifest(input, nextManifest, enabledManagedHookVendors(nextManifest).filter((vendor) => selectedManagedVendors.includes(vendor)));
575
610
  const disabledVendors = disabledManagedHookVendors(nextManifest);
576
- const disabled = disabledVendors.length > 0
577
- ? disableManagedHooksFromManifest(input, nextManifest, disabledVendors)
611
+ const selectedDisabledVendors = disabledVendors.filter((vendor) => selectedManagedVendors.includes(vendor));
612
+ const disabled = selectedDisabledVendors.length > 0
613
+ ? disableManagedHooksFromManifest(input, nextManifest, selectedDisabledVendors)
578
614
  : {};
579
615
  if (!options.dryRun) {
580
616
  writeHooksManifest(repoRoot, nextManifest.claude, nextManifest.codex, nextManifest.vendorState);
@@ -769,7 +805,7 @@ async function runSourceRepoSafeSetup(input) {
769
805
  skipGlobal,
770
806
  explicitConsent: input.explicitConsent,
771
807
  });
772
- const hookExit = await runSourceRepoHookOnlyRecovery(repoRoot, options, stdout, forceHookRepair ? "force-repair" : "repair-stale-only", {
808
+ const hookExit = await runSourceRepoHookOnlyRecovery(repoRoot, options, stdout, selectedHosts, forceHookRepair ? "force-repair" : "repair-stale-only", {
773
809
  options: userScopeOptions,
774
810
  consent: trustConsent,
775
811
  createCodexAppServer: input.createCodexAppServer,
@@ -881,6 +917,8 @@ function detectPlainDirectoryConsumer(startDir) {
881
917
  }
882
918
  export async function runInit(flags, deps = {}) {
883
919
  flags = normalizeInitFlagsForExecution(flags);
920
+ for (const warning of setupDeprecationWarnings(flags))
921
+ console.warn(warning);
884
922
  const stdout = deps.stdout ?? process.stdout;
885
923
  const startMs = Date.now();
886
924
  const cwd = flags.cwd ?? process.cwd();
@@ -923,6 +961,7 @@ export async function runInit(flags, deps = {}) {
923
961
  const options = {
924
962
  overwrite: flags.overwrite ?? false,
925
963
  dryRun: flags.dryRun ?? flags["dry-run"] ?? false,
964
+ repoRoot: consumer.repoRoot,
926
965
  };
927
966
  // Source-repo safe setup is the agent-kit maintainer's own contributor
928
967
  // workflow (running `wp setup` inside a checkout of @webpresso/agent-kit). Its
@@ -974,7 +1013,7 @@ export async function runInit(flags, deps = {}) {
974
1013
  skipGlobal,
975
1014
  explicitConsent: forceUserOnly,
976
1015
  });
977
- const hookOnlyRecoveryExit = await runSourceRepoHookOnlyRecovery(consumer.repoRoot, options, stdout, "repair-stale-only", {
1016
+ const hookOnlyRecoveryExit = await runSourceRepoHookOnlyRecovery(consumer.repoRoot, options, stdout, recoveryHosts, "repair-stale-only", {
978
1017
  options: userScopeOptions,
979
1018
  consent: trustConsent,
980
1019
  createCodexAppServer: deps.createCodexAppServer,
@@ -1001,6 +1040,22 @@ export async function runInit(flags, deps = {}) {
1001
1040
  ? "non-webpresso-project"
1002
1041
  : null;
1003
1042
  const userOnlySetup = userOnlyReason !== null;
1043
+ const isCiEnvironment = process.env.CI === "true" || process.env.CI === "1";
1044
+ if (!userOnlySetup && !options.dryRun) {
1045
+ const gitConvergence = prepareRepositoryForConvergence({
1046
+ repoRoot: consumer.repoRoot,
1047
+ isCi: isCiEnvironment,
1048
+ });
1049
+ for (const warning of gitConvergence.warnings)
1050
+ console.warn(` git convergence: ⚠ ${warning}`);
1051
+ if (!gitConvergence.ok) {
1052
+ console.error(`wp setup: ${gitConvergence.error ?? "Git convergence preflight failed."}`);
1053
+ return EXIT_SETUP_FAIL;
1054
+ }
1055
+ if (gitConvergence.shouldReplan) {
1056
+ console.log(" git convergence: ✓ fast-forwarded upstream; recomputing setup plan");
1057
+ }
1058
+ }
1004
1059
  if (!userOnlySetup) {
1005
1060
  warnIfNonLocalCli(consumer.repoRoot);
1006
1061
  }
@@ -1159,7 +1214,7 @@ export async function runInit(flags, deps = {}) {
1159
1214
  // set side-effect-free, then decide once whether to apply it. On skip,
1160
1215
  // user-scope steps run in dry-run mode (their existing skip-branches) so only
1161
1216
  // repo-scope writes land; the decision is recorded for `wp hooks doctor`.
1162
- const isCiEnvironmentForConsent = process.env.CI === "true" || process.env.CI === "1";
1217
+ const isCiEnvironmentForConsent = isCiEnvironment;
1163
1218
  const skipClaudePlugin = process.env.WP_SKIP_CLAUDE_PLUGIN === "1";
1164
1219
  const userScopeSteps = collectUserScopeSteps({
1165
1220
  isCiEnvironment: isCiEnvironmentForConsent,
@@ -1310,6 +1365,7 @@ export async function runInit(flags, deps = {}) {
1310
1365
  agentHooksResult = await scaffoldAgentHooks({
1311
1366
  repoRoot: consumer.repoRoot,
1312
1367
  options,
1368
+ selectedHosts,
1313
1369
  claudeUserOptions: userScopeOptions,
1314
1370
  // Env-gate the home `~/.claude/settings.json` leg to match the preflight
1315
1371
  // inventory: under WP_SKIP_CLAUDE_PLUGIN=1 the `claude-user-settings` step
@@ -1353,35 +1409,67 @@ export async function runInit(flags, deps = {}) {
1353
1409
  else {
1354
1410
  console.log(` hooks: - skipped (profile: ${profile} omits agent + audit hooks)`);
1355
1411
  }
1356
- const opencodePluginResult = ensureOpenCodeWebpressoPlugin({
1357
- repoRoot: consumer.repoRoot,
1358
- options,
1359
- });
1360
- switch (opencodePluginResult.kind) {
1361
- case "opencode-webpresso-plugin-written":
1362
- console.log(` opencode plugin: ✓ ${opencodePluginResult.path} ensures ${opencodePluginResult.pluginPackage}`);
1363
- if (opencodePluginResult.removed.length > 0) {
1364
- console.log(` opencode cleanup: removed ${opencodePluginResult.removed.join(", ")}`);
1365
- }
1366
- if (opencodePluginResult.preserved.length > 0) {
1367
- console.warn(` opencode cleanup: left ${opencodePluginResult.preserved.join(", ")} unchanged (no Webpresso ownership marker)`);
1368
- }
1369
- break;
1370
- case "opencode-webpresso-plugin-unchanged":
1371
- console.log(` opencode plugin: already configured at ${opencodePluginResult.path}`);
1372
- if (opencodePluginResult.preserved.length > 0) {
1373
- console.warn(` opencode cleanup: left ${opencodePluginResult.preserved.join(", ")} unchanged (no Webpresso ownership marker)`);
1374
- }
1375
- break;
1376
- case "opencode-webpresso-plugin-skipped-dry-run":
1377
- console.log(" opencode plugin: skipped (--dry-run)");
1378
- break;
1379
- case "opencode-webpresso-plugin-invalid-json":
1380
- console.warn(` opencode plugin: ${opencodePluginResult.path} is not valid JSON; left unchanged`);
1381
- break;
1382
- case "opencode-webpresso-plugin-invalid-config":
1383
- console.warn(` opencode plugin: ⚠ ${opencodePluginResult.path} has a non-string plugin config; left unchanged`);
1384
- break;
1412
+ if (selectedHosts.includes("opencode")) {
1413
+ const opencodePluginResult = ensureOpenCodeWebpressoPlugin({
1414
+ repoRoot: consumer.repoRoot,
1415
+ options,
1416
+ });
1417
+ switch (opencodePluginResult.kind) {
1418
+ case "opencode-webpresso-plugin-written":
1419
+ console.log(` opencode plugin: ✓ ${opencodePluginResult.path} ensures ${opencodePluginResult.pluginPackage}`);
1420
+ if (opencodePluginResult.mcpEntryPath) {
1421
+ console.log(` opencode mcp: ✓ mcp.webpresso launches webpresso via ${opencodePluginResult.mcpEntryPath}`);
1422
+ }
1423
+ else {
1424
+ console.warn(" opencode mcp: ⚠ webpresso launcher not found; mcp.webpresso left unset");
1425
+ }
1426
+ if (opencodePluginResult.removed.length > 0) {
1427
+ console.log(` opencode cleanup: removed ${opencodePluginResult.removed.join(", ")}`);
1428
+ }
1429
+ if (opencodePluginResult.preserved.length > 0) {
1430
+ console.warn(` opencode cleanup: left ${opencodePluginResult.preserved.join(", ")} unchanged (no Webpresso ownership marker)`);
1431
+ }
1432
+ break;
1433
+ case "opencode-webpresso-plugin-unchanged":
1434
+ console.log(` opencode plugin: already configured at ${opencodePluginResult.path}`);
1435
+ if (opencodePluginResult.preserved.length > 0) {
1436
+ console.warn(` opencode cleanup: left ${opencodePluginResult.preserved.join(", ")} unchanged (no Webpresso ownership marker)`);
1437
+ }
1438
+ break;
1439
+ case "opencode-webpresso-plugin-skipped-dry-run":
1440
+ console.log(" opencode plugin: skipped (--dry-run)");
1441
+ break;
1442
+ case "opencode-webpresso-plugin-invalid-json":
1443
+ console.warn(` opencode plugin: ⚠ ${opencodePluginResult.path} is not valid JSON; left unchanged`);
1444
+ break;
1445
+ case "opencode-webpresso-plugin-invalid-config":
1446
+ console.warn(` opencode plugin: ⚠ ${opencodePluginResult.path} has a non-string plugin config; left unchanged`);
1447
+ break;
1448
+ }
1449
+ }
1450
+ if (selectedHosts.includes("grok")) {
1451
+ const grokMcpResult = ensureGrokWebpressoMcp({
1452
+ repoRoot: consumer.repoRoot,
1453
+ options,
1454
+ });
1455
+ switch (grokMcpResult.kind) {
1456
+ case "grok-webpresso-mcp-written":
1457
+ console.log(` grok mcp: ✓ ${grokMcpResult.path} launches webpresso via ${grokMcpResult.entryPath}`);
1458
+ console.log(" grok hooks: run /hooks-trust once in Grok to arm the managed hooks");
1459
+ break;
1460
+ case "grok-webpresso-mcp-unchanged":
1461
+ console.log(` grok mcp: already configured at ${grokMcpResult.path}`);
1462
+ break;
1463
+ case "grok-webpresso-mcp-ambiguous":
1464
+ console.warn(` grok mcp: ⚠ ambiguous MCP config at ${grokMcpResult.path}; left unchanged`);
1465
+ break;
1466
+ case "grok-webpresso-mcp-skipped-dry-run":
1467
+ console.log(" grok mcp: skipped (--dry-run)");
1468
+ break;
1469
+ case "grok-webpresso-mcp-not-installed":
1470
+ console.warn(` grok mcp: ⚠ webpresso launcher not found (checked ${grokMcpResult.checked.length} location(s)); left ${grokMcpResult.path} unchanged`);
1471
+ break;
1472
+ }
1385
1473
  }
1386
1474
  let claudeRulesResults = [];
1387
1475
  try {
@@ -1397,18 +1485,23 @@ export async function runInit(flags, deps = {}) {
1397
1485
  const subagentResults = scaffoldSubagents({ repoRoot: consumer.repoRoot, options });
1398
1486
  // Generated host instructions (AGENTS.md) are a tier-1 (guarded/full)
1399
1487
  // surface; the tier-0 quality profile omits them.
1488
+ // Base-kit may have created or updated package metadata earlier in this
1489
+ // same convergence pass. Render from that post-apply repository view so a
1490
+ // fresh setup reaches the same fixed point as an immediate repeat.
1491
+ const convergedConsumer = detectConsumer(consumer.repoRoot) ?? consumer;
1400
1492
  const agentsMdResult = surfaces.hostInstructions
1401
1493
  ? scaffoldAgentsMd({
1402
1494
  catalogDir,
1403
1495
  repoRoot: consumer.repoRoot,
1404
- consumer,
1496
+ consumer: convergedConsumer,
1405
1497
  config,
1406
1498
  options,
1407
1499
  })
1408
1500
  : null;
1501
+ let configuredGeneratedPathsRemoved = [];
1409
1502
  if (!options.dryRun) {
1410
1503
  writeConfig(consumer.repoRoot, config);
1411
- removeConfiguredGeneratedPaths(consumer.repoRoot, config);
1504
+ configuredGeneratedPathsRemoved = removeConfiguredGeneratedPaths(consumer.repoRoot, config);
1412
1505
  }
1413
1506
  // Apply scaffolder presets
1414
1507
  const presetResults = [];
@@ -1450,30 +1543,34 @@ export async function runInit(flags, deps = {}) {
1450
1543
  // Failures from these installations must not fail the postinstall in that
1451
1544
  // context.
1452
1545
  const isCiEnvironment = process.env.CI === "true" || process.env.CI === "1";
1453
- if (isCiEnvironment) {
1454
- console.log(" codex cli: - skipped (CI environment)");
1455
- }
1456
- else {
1457
- const codexCliResult = ensureCodexCli({ options: userScopeOptions });
1458
- switch (codexCliResult.kind) {
1459
- case "codex-cli-ok":
1460
- console.log(codexCliResult.installed ? " codex cli: ✓ installed" : " codex cli: ✓");
1461
- recordUserScope("codex-cli");
1462
- if (!userScopeOptions.dryRun) {
1463
- toolingOwnership = claimUserOwnedTool(toolingOwnership, "codex");
1464
- toolingOwnershipChanged = true;
1465
- }
1466
- break;
1467
- case "codex-cli-skipped-dry-run":
1468
- console.log(" codex cli: skipped (--dry-run)");
1469
- break;
1470
- case "codex-cli-skipped-package-lifecycle":
1471
- console.log(" codex cli: - skipped (package lifecycle environment)");
1472
- break;
1473
- case "codex-cli-unavailable":
1474
- console.warn(` codex cli: ⚠ ${codexCliResult.hint}`);
1475
- break;
1546
+ if (selectedHosts.includes("codex")) {
1547
+ if (isCiEnvironment) {
1548
+ console.log(" codex cli: - skipped (CI environment)");
1476
1549
  }
1550
+ else {
1551
+ const codexCliResult = ensureCodexCli({ options: userScopeOptions });
1552
+ switch (codexCliResult.kind) {
1553
+ case "codex-cli-ok":
1554
+ console.log(codexCliResult.installed ? " codex cli: ✓ installed" : " codex cli: ✓");
1555
+ recordUserScope("codex-cli");
1556
+ if (!userScopeOptions.dryRun) {
1557
+ toolingOwnership = claimUserOwnedTool(toolingOwnership, "codex");
1558
+ toolingOwnershipChanged = true;
1559
+ }
1560
+ break;
1561
+ case "codex-cli-skipped-dry-run":
1562
+ console.log(" codex cli: skipped (--dry-run)");
1563
+ break;
1564
+ case "codex-cli-skipped-package-lifecycle":
1565
+ console.log(" codex cli: - skipped (package lifecycle environment)");
1566
+ break;
1567
+ case "codex-cli-unavailable":
1568
+ console.warn(` codex cli: ⚠ ${codexCliResult.hint}`);
1569
+ break;
1570
+ }
1571
+ }
1572
+ }
1573
+ if (selectedHosts.includes("claude") && !isCiEnvironment) {
1477
1574
  if (process.env.WP_SKIP_CLAUDE_PLUGIN === "1") {
1478
1575
  console.log(" claude cli: skipped (WP_SKIP_CLAUDE_PLUGIN=1)");
1479
1576
  }
@@ -1520,10 +1617,10 @@ export async function runInit(flags, deps = {}) {
1520
1617
  break;
1521
1618
  }
1522
1619
  }
1523
- // Trusting codex hooks only matters when hooks were scaffolded (tier 1+),
1524
- // and even then only with resolved user-scope consent (the trust write
1525
- // touches $CODEX_HOME, which is user/home scope).
1526
- if (surfaces.hooks) {
1620
+ // Trusting Codex hooks only matters when Codex hooks were scaffolded
1621
+ // (tier 1+) for this host selection, and even then only with resolved
1622
+ // user-scope consent (the trust write touches $CODEX_HOME).
1623
+ if (surfaces.hooks && selectedHosts.includes("codex")) {
1527
1624
  await trustCodexWebpressoHooksForRepo({ repoRoot: consumer.repoRoot, options: userScopeOptions }, userScopeConsent
1528
1625
  ? { kind: "apply" }
1529
1626
  : { kind: "skip", reason: skipGlobal ? "--skip-global" : "user-scope writes declined" });
@@ -1532,23 +1629,28 @@ export async function runInit(flags, deps = {}) {
1532
1629
  // an install root is discoverable. Codex's config.toml is user-global, so
1533
1630
  // we resolve to whatever absolute install path exists today (Claude
1534
1631
  // plugin / bun global / pnpm global / npm global) and write that.
1535
- const webpressoMcpResult = ensureCodexWebpressoMcp({ options: userScopeOptions });
1536
- switch (webpressoMcpResult.kind) {
1537
- case "codex-webpresso-mcp-written":
1538
- console.log(` codex webpresso mcp: ✓ ${webpressoMcpResult.path} → ${webpressoMcpResult.entryPath}`);
1539
- recordUserScope("codex-config");
1540
- break;
1541
- case "codex-webpresso-mcp-unchanged":
1542
- console.log(` codex webpresso mcp: already configured at ${webpressoMcpResult.path}`);
1543
- break;
1544
- case "codex-webpresso-mcp-skipped-dry-run":
1545
- console.log(" codex webpresso mcp: skipped (--dry-run)");
1546
- break;
1547
- case "codex-webpresso-mcp-not-installed":
1548
- console.log(` codex webpresso mcp: ⚠ no install root found (checked ${webpressoMcpResult.checked.length} paths). Install @webpresso/agent-kit globally (\`bun add -g @webpresso/agent-kit\`) or via the Claude plugin to wire up codex MCP.`);
1549
- break;
1632
+ if (selectedHosts.includes("codex")) {
1633
+ const webpressoMcpResult = ensureCodexWebpressoMcp({ options: userScopeOptions });
1634
+ switch (webpressoMcpResult.kind) {
1635
+ case "codex-webpresso-mcp-written":
1636
+ console.log(` codex webpresso mcp: ✓ ${webpressoMcpResult.path} → ${webpressoMcpResult.entryPath}`);
1637
+ recordUserScope("codex-config");
1638
+ break;
1639
+ case "codex-webpresso-mcp-unchanged":
1640
+ console.log(` codex webpresso mcp: already configured at ${webpressoMcpResult.path}`);
1641
+ break;
1642
+ case "codex-webpresso-mcp-ambiguous":
1643
+ console.warn(` codex webpresso mcp: ⚠ ambiguous MCP config at ${webpressoMcpResult.path}; left unchanged`);
1644
+ break;
1645
+ case "codex-webpresso-mcp-skipped-dry-run":
1646
+ console.log(" codex webpresso mcp: skipped (--dry-run)");
1647
+ break;
1648
+ case "codex-webpresso-mcp-not-installed":
1649
+ console.log(` codex webpresso mcp: ⚠ no install root found (checked ${webpressoMcpResult.checked.length} paths). Install @webpresso/agent-kit globally (\`bun add -g @webpresso/agent-kit\`) or via the Claude plugin to wire up codex MCP.`);
1650
+ break;
1651
+ }
1652
+ reconcileCodexProjectMcpServers(consumer.repoRoot, userScopeOptions);
1550
1653
  }
1551
- reconcileCodexProjectMcpServers(consumer.repoRoot, userScopeOptions);
1552
1654
  // Self-update the globally-distributed agent-kit install that backs PATH
1553
1655
  // `wp`, mirroring codex/claude. Non-fatal: a failed refresh never
1554
1656
  // fails consumer setup, and it skips cleanly in explicit source mode, on
@@ -1592,34 +1694,36 @@ export async function runInit(flags, deps = {}) {
1592
1694
  }
1593
1695
  }
1594
1696
  const successfullyInstalledPluginHosts = new Set();
1595
- const claudePluginResult = ensureClaudeCodeUserPlugin({
1596
- options: userScopeOptions,
1597
- packageRoot,
1598
- });
1599
- switch (claudePluginResult.kind) {
1600
- case "claude-plugin-installed":
1601
- successfullyInstalledPluginHosts.add("claude");
1602
- console.log(` claude plugin: ✓ user-scope marketplace + plugin ensured (${claudePluginResult.pluginId})`);
1603
- break;
1604
- case "claude-plugin-skipped-dry-run":
1605
- console.log(" claude plugin: skipped (--dry-run)");
1606
- break;
1607
- case "claude-plugin-skipped-opt-out":
1608
- console.log(" claude plugin: skipped (WP_SKIP_CLAUDE_PLUGIN=1)");
1609
- break;
1610
- case "claude-plugin-skipped-package-lifecycle":
1611
- console.log(" claude plugin: - skipped (package lifecycle environment)");
1612
- break;
1613
- case "claude-plugin-skipped-no-cli":
1614
- console.log(" claude plugin: - skipped (claude not on PATH)");
1615
- break;
1616
- case "claude-plugin-unavailable":
1617
- console.log(" claude plugin: - skipped (plugin manifest unavailable in this install)");
1618
- break;
1619
- case "claude-plugin-failed":
1620
- console.warn(` claude plugin: ⚠ ${claudePluginResult.step} exited with ${claudePluginResult.exitCode}; ` +
1621
- `fallback: claude plugin marketplace add --scope user webpresso/agent-kit@v$(wp --version) && claude plugin install --scope user ${claudePluginResult.pluginId}`);
1622
- break;
1697
+ if (selectedHosts.includes("claude")) {
1698
+ const claudePluginResult = ensureClaudeCodeUserPlugin({
1699
+ options: userScopeOptions,
1700
+ packageRoot,
1701
+ });
1702
+ switch (claudePluginResult.kind) {
1703
+ case "claude-plugin-installed":
1704
+ successfullyInstalledPluginHosts.add("claude");
1705
+ console.log(` claude plugin: ✓ user-scope marketplace + plugin ensured (${claudePluginResult.pluginId})`);
1706
+ break;
1707
+ case "claude-plugin-skipped-dry-run":
1708
+ console.log(" claude plugin: skipped (--dry-run)");
1709
+ break;
1710
+ case "claude-plugin-skipped-opt-out":
1711
+ console.log(" claude plugin: skipped (WP_SKIP_CLAUDE_PLUGIN=1)");
1712
+ break;
1713
+ case "claude-plugin-skipped-package-lifecycle":
1714
+ console.log(" claude plugin: - skipped (package lifecycle environment)");
1715
+ break;
1716
+ case "claude-plugin-skipped-no-cli":
1717
+ console.log(" claude plugin: - skipped (claude not on PATH)");
1718
+ break;
1719
+ case "claude-plugin-unavailable":
1720
+ console.log(" claude plugin: - skipped (plugin manifest unavailable in this install)");
1721
+ break;
1722
+ case "claude-plugin-failed":
1723
+ console.warn(` claude plugin: ${claudePluginResult.step} exited with ${claudePluginResult.exitCode}; ` +
1724
+ `fallback: claude plugin marketplace add --scope user webpresso/agent-kit@v$(wp --version) && claude plugin install --scope user ${claudePluginResult.pluginId}`);
1725
+ break;
1726
+ }
1623
1727
  }
1624
1728
  if (selectedHosts.includes("codex") && !isCiEnvironment) {
1625
1729
  const codexPluginResult = ensureCodexUserPlugin({ options: userScopeOptions, packageRoot });
@@ -1838,6 +1942,52 @@ export async function runInit(flags, deps = {}) {
1838
1942
  visibility: serializeHostVisibility(visibilityAudit),
1839
1943
  };
1840
1944
  writeConfig(consumer.repoRoot, config);
1945
+ writeConvergenceState(consumer.repoRoot, {
1946
+ schemaVersion: 1,
1947
+ agentKitVersion: packageVersion,
1948
+ host: selectedHosts.join(",") || "none",
1949
+ sentinels: {
1950
+ profile,
1951
+ selectedHosts: selectedHosts.toSorted().join(","),
1952
+ },
1953
+ writtenAt: new Date().toISOString(),
1954
+ });
1955
+ const candidates = [
1956
+ ...all.map((result) => ({
1957
+ targetPath: result.targetPath,
1958
+ reason: result.note ?? "setup-managed surface",
1959
+ })),
1960
+ {
1961
+ targetPath: join(consumer.repoRoot, ".webpressorc.json"),
1962
+ reason: "setup convergence config",
1963
+ },
1964
+ ...configuredGeneratedPathsRemoved.map((path) => ({
1965
+ targetPath: join(consumer.repoRoot, path),
1966
+ reason: "configured generated cleanup",
1967
+ })),
1968
+ ...(generatedIndexCleanupResult.kind === "ok"
1969
+ ? generatedIndexCleanupResult.removedPaths.map((path) => ({
1970
+ targetPath: join(consumer.repoRoot, path),
1971
+ reason: "generated index cleanup",
1972
+ }))
1973
+ : []),
1974
+ ];
1975
+ const commitResult = authorConvergenceCommit({
1976
+ repoRoot: consumer.repoRoot,
1977
+ appliedUnits: collectAppliedConvergeUnits(consumer.repoRoot, candidates),
1978
+ message: "chore: converge webpresso setup",
1979
+ isCi: isCiEnvironment,
1980
+ });
1981
+ if (!commitResult.ok) {
1982
+ console.error(formatWpSetupError(commitResult.error ?? "Unable to author convergence commit."));
1983
+ return EXIT_WRITE_FAIL;
1984
+ }
1985
+ if (commitResult.status === "committed") {
1986
+ console.log(` git convergence: ✓ authored ${commitResult.commit?.slice(0, 12)}`);
1987
+ }
1988
+ else if (commitResult.status === "skipped-ci") {
1989
+ console.log(" git convergence: - commit skipped (CI)");
1990
+ }
1841
1991
  console.log("\nHost skill visibility:");
1842
1992
  if (visibilityAudit.selectedHosts.length === 0) {
1843
1993
  console.log(" hosts: - skipped (--host none)");
@@ -1948,7 +2098,7 @@ function registerPrimaryInitOptions(command) {
1948
2098
  .option("--with <skills>", withHelp)
1949
2099
  .option("--without <skills>", withoutHelp)
1950
2100
  .option("--profile <profile>", `Adoption tier to scaffold: ${SETUP_PROFILES.join(", ")} (default: ${DEFAULT_SETUP_PROFILE} — bare \`wp setup\` is unchanged). quality = wp scripts + MCP + session memory; guarded = + hooks/audits/host instructions; full = + blueprint lifecycle`)
1951
- .option("--host <hosts>", "Comma-separated host targets: codex, claude, opencode, all, none")
2101
+ .option("--host <hosts>", "Comma-separated host targets: codex, claude, opencode, grok, all, none")
1952
2102
  .option("--prune", "Widen stale agent-kit plugin-cache pruning from the default host set (claude, codex, opencode) to every supported host while retaining recent versions")
1953
2103
  .option("--dry-run", "Show what would change without writing anything")
1954
2104
  .option("--yes-global", "Apply user/home-scope writes (host config, plugin/CLI installs, agent caches) without an interactive consent prompt")
@@ -1970,6 +2120,9 @@ export function registerInitCommand(cli, commandName = "init") {
1970
2120
  ? "Scaffold webpresso catalog into the current repo; default runs also clean obsolete notifier state and prune stale plugin caches while retaining recent versions for claude, codex, and opencode"
1971
2121
  : "Compatibility alias for wp setup";
1972
2122
  registerPrimaryInitOptions(cli.command(commandName, description).action(async (flags) => {
2123
+ if (commandName === "init") {
2124
+ console.warn("wp init is deprecated; use `wp setup` for repository convergence.");
2125
+ }
1973
2126
  const validationError = validatePrimarySetupFlags(commandName, flags);
1974
2127
  if (validationError) {
1975
2128
  console.error(validationError);