@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
@@ -0,0 +1,221 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { join } from "node:path";
3
+ import { convergeUnitFromTarget, deriveCommitAllowlist } from "./convergence.js";
4
+ export { resolveUntrackedCollision } from "./untracked-collision.js";
5
+ const GIT_TIMEOUT_MS = 15_000;
6
+ function git(repoRoot, args) {
7
+ const result = spawnSync("git", [...args], {
8
+ cwd: repoRoot,
9
+ encoding: "utf8",
10
+ timeout: GIT_TIMEOUT_MS,
11
+ maxBuffer: 1024 * 1024,
12
+ stdio: ["ignore", "pipe", "pipe"],
13
+ });
14
+ return {
15
+ ok: result.status === 0 && !result.error,
16
+ stdout: result.stdout.trim(),
17
+ stderr: result.stderr.trim(),
18
+ };
19
+ }
20
+ function lines(value) {
21
+ return value.length === 0 ? [] : value.split("\n").filter(Boolean).sort();
22
+ }
23
+ function readPorcelainStatus(repoRoot, gitPath) {
24
+ const result = spawnSync("git", [
25
+ "status",
26
+ "--porcelain=v1",
27
+ "-z",
28
+ "--untracked-files=all",
29
+ "--ignored=matching",
30
+ "--",
31
+ gitPath,
32
+ ], {
33
+ cwd: repoRoot,
34
+ encoding: "utf8",
35
+ timeout: GIT_TIMEOUT_MS,
36
+ maxBuffer: 1024 * 1024,
37
+ stdio: ["ignore", "pipe", "pipe"],
38
+ });
39
+ if (result.status !== 0 || result.error)
40
+ return null;
41
+ const fields = result.stdout.split("\0");
42
+ const entries = [];
43
+ for (let index = 0; index < fields.length; index += 1) {
44
+ const record = fields[index];
45
+ if (!record || record.length < 4)
46
+ continue;
47
+ const code = record.slice(0, 2);
48
+ entries.push({ code, gitPath: record.slice(3) });
49
+ if (code.includes("R") || code.includes("C"))
50
+ index += 1;
51
+ }
52
+ return entries;
53
+ }
54
+ function isIgnored(repoRoot, gitPath) {
55
+ return git(repoRoot, ["check-ignore", "--no-index", "-q", "--", gitPath]).ok;
56
+ }
57
+ export function collectAppliedConvergeUnits(repoRoot, candidates) {
58
+ const units = [];
59
+ const seen = new Set();
60
+ for (const candidate of candidates) {
61
+ let candidateUnit;
62
+ try {
63
+ candidateUnit = convergeUnitFromTarget(repoRoot, candidate.targetPath, {
64
+ action: "modify",
65
+ scope: "repo-committed",
66
+ reason: candidate.reason,
67
+ });
68
+ }
69
+ catch {
70
+ continue;
71
+ }
72
+ const statuses = readPorcelainStatus(repoRoot, candidateUnit.gitPath);
73
+ if (!statuses)
74
+ continue;
75
+ for (const { code, gitPath } of statuses) {
76
+ if (seen.has(gitPath))
77
+ continue;
78
+ let unit;
79
+ try {
80
+ unit = convergeUnitFromTarget(repoRoot, join(repoRoot, gitPath), {
81
+ action: code === "??" || code === "!!" || code.includes("A")
82
+ ? "create"
83
+ : code.includes("D")
84
+ ? "delete"
85
+ : "modify",
86
+ scope: "repo-committed",
87
+ reason: candidate.reason,
88
+ });
89
+ }
90
+ catch {
91
+ continue;
92
+ }
93
+ units.push({
94
+ ...unit,
95
+ scope: code === "!!" || (code === "??" && isIgnored(repoRoot, gitPath))
96
+ ? "repo-ignored"
97
+ : "repo-committed",
98
+ });
99
+ seen.add(gitPath);
100
+ }
101
+ }
102
+ return units;
103
+ }
104
+ export function authorConvergenceCommit(options) {
105
+ const allowlist = deriveCommitAllowlist(options.appliedUnits);
106
+ if (options.isCi)
107
+ return { status: "skipped-ci", ok: true, allowlist };
108
+ if (allowlist.length === 0)
109
+ return { status: "no-change", ok: true, allowlist };
110
+ const before = git(options.repoRoot, ["rev-parse", "--verify", "HEAD"]);
111
+ if (!before.ok) {
112
+ return { status: "failed", ok: false, allowlist, error: before.stderr || "Missing HEAD." };
113
+ }
114
+ const add = git(options.repoRoot, ["add", "--", ...allowlist]);
115
+ if (!add.ok) {
116
+ return { status: "failed", ok: false, allowlist, error: add.stderr || "git add failed." };
117
+ }
118
+ const staged = git(options.repoRoot, ["diff", "--cached", "--name-only"]);
119
+ if (!staged.ok) {
120
+ return { status: "failed", ok: false, allowlist, error: staged.stderr || "git diff failed." };
121
+ }
122
+ if (lines(staged.stdout).length === 0) {
123
+ return { status: "no-change", ok: true, allowlist };
124
+ }
125
+ const commit = git(options.repoRoot, ["commit", "-m", options.message]);
126
+ if (!commit.ok) {
127
+ return {
128
+ status: "failed",
129
+ ok: false,
130
+ allowlist,
131
+ error: commit.stderr || commit.stdout || "git commit failed; hook changes were preserved.",
132
+ };
133
+ }
134
+ const committedHead = git(options.repoRoot, ["rev-parse", "--verify", "HEAD"]);
135
+ if (!committedHead.ok) {
136
+ return {
137
+ status: "failed",
138
+ ok: false,
139
+ allowlist,
140
+ error: committedHead.stderr || "Unable to validate the authored commit.",
141
+ };
142
+ }
143
+ const committedParent = git(options.repoRoot, [
144
+ "rev-parse",
145
+ "--verify",
146
+ `${committedHead.stdout}^`,
147
+ ]);
148
+ if (!committedParent.ok || committedParent.stdout !== before.stdout) {
149
+ return {
150
+ status: "failed",
151
+ ok: false,
152
+ allowlist,
153
+ commit: committedHead.stdout,
154
+ error: "The observed commit does not directly follow the recorded HEAD; no rollback was attempted. Inspect Git history and recover manually.",
155
+ };
156
+ }
157
+ const committedPathsResult = git(options.repoRoot, [
158
+ "diff-tree",
159
+ "--root",
160
+ "--no-commit-id",
161
+ "--name-only",
162
+ "-r",
163
+ committedHead.stdout,
164
+ ]);
165
+ if (!committedPathsResult.ok) {
166
+ return {
167
+ status: "failed",
168
+ ok: false,
169
+ allowlist,
170
+ commit: committedHead.stdout,
171
+ error: committedPathsResult.stderr || "Unable to inspect the authored commit.",
172
+ };
173
+ }
174
+ const committedPaths = lines(committedPathsResult.stdout);
175
+ const allowed = new Set(allowlist);
176
+ const committed = new Set(committedPaths);
177
+ const unexpectedPaths = committedPaths.filter((path) => !allowed.has(path));
178
+ const missingPaths = allowlist.filter((path) => !committed.has(path));
179
+ if (unexpectedPaths.length === 0 && missingPaths.length === 0) {
180
+ return {
181
+ status: "committed",
182
+ ok: true,
183
+ allowlist,
184
+ commit: committedHead.stdout,
185
+ };
186
+ }
187
+ const currentHead = git(options.repoRoot, ["rev-parse", "--verify", "HEAD"]);
188
+ if (!currentHead.ok || currentHead.stdout !== committedHead.stdout) {
189
+ return {
190
+ status: "failed",
191
+ ok: false,
192
+ allowlist,
193
+ commit: committedHead.stdout,
194
+ unexpectedPaths,
195
+ missingPaths,
196
+ error: "The setup-authored commit changed before validation; no rollback was attempted. Inspect Git history and recover manually.",
197
+ };
198
+ }
199
+ const rollback = git(options.repoRoot, ["reset", "--mixed", before.stdout]);
200
+ if (!rollback.ok) {
201
+ return {
202
+ status: "failed",
203
+ ok: false,
204
+ allowlist,
205
+ commit: committedHead.stdout,
206
+ unexpectedPaths,
207
+ missingPaths,
208
+ error: rollback.stderr || "Failed to undo the path-invalid setup commit.",
209
+ };
210
+ }
211
+ return {
212
+ status: "rolled-back",
213
+ ok: false,
214
+ allowlist,
215
+ commit: committedHead.stdout,
216
+ unexpectedPaths,
217
+ missingPaths,
218
+ error: `A commit hook changed setup commit scope (unexpected: ${unexpectedPaths.join(", ") || "none"}; missing: ${missingPaths.join(", ") || "none"}). ` +
219
+ "The setup commit was undone and all worktree changes were retained. Update the hook so it does not stage unrelated paths, then stage or discard those paths and rerun wp setup.",
220
+ };
221
+ }
@@ -0,0 +1,13 @@
1
+ export declare const CONVERGENCE_STATE_SCHEMA_VERSION: 1;
2
+ export declare const CONVERGENCE_STATE_PATH = ".webpresso/converged.json";
3
+ export interface ConvergenceState {
4
+ readonly schemaVersion: typeof CONVERGENCE_STATE_SCHEMA_VERSION;
5
+ readonly agentKitVersion: string;
6
+ readonly host: string;
7
+ readonly sentinels: Readonly<Record<string, string>>;
8
+ readonly writtenAt: string;
9
+ }
10
+ export declare function parseConvergenceState(value: unknown): ConvergenceState | null;
11
+ export declare function readConvergenceState(repoRoot: string): ConvergenceState | null;
12
+ export declare function isConvergenceStateCurrent(state: ConvergenceState | null, expected: Pick<ConvergenceState, "agentKitVersion" | "host" | "sentinels">): boolean;
13
+ export declare function writeConvergenceState(repoRoot: string, state: ConvergenceState): void;
@@ -0,0 +1,54 @@
1
+ import { mkdirSync, readFileSync } from "node:fs";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import { writeJsonFile } from "#shared-utils/write-json-file.js";
4
+ export const CONVERGENCE_STATE_SCHEMA_VERSION = 1;
5
+ export const CONVERGENCE_STATE_PATH = ".webpresso/converged.json";
6
+ function isStringRecord(value) {
7
+ return (value !== null &&
8
+ typeof value === "object" &&
9
+ !Array.isArray(value) &&
10
+ Object.values(value).every((entry) => typeof entry === "string"));
11
+ }
12
+ export function parseConvergenceState(value) {
13
+ if (value === null || typeof value !== "object" || Array.isArray(value))
14
+ return null;
15
+ const record = value;
16
+ if (record.schemaVersion !== CONVERGENCE_STATE_SCHEMA_VERSION ||
17
+ typeof record.agentKitVersion !== "string" ||
18
+ typeof record.host !== "string" ||
19
+ typeof record.writtenAt !== "string" ||
20
+ !isStringRecord(record.sentinels)) {
21
+ return null;
22
+ }
23
+ return {
24
+ schemaVersion: CONVERGENCE_STATE_SCHEMA_VERSION,
25
+ agentKitVersion: record.agentKitVersion,
26
+ host: record.host,
27
+ sentinels: record.sentinels,
28
+ writtenAt: record.writtenAt,
29
+ };
30
+ }
31
+ export function readConvergenceState(repoRoot) {
32
+ try {
33
+ return parseConvergenceState(JSON.parse(readFileSync(join(resolve(repoRoot), CONVERGENCE_STATE_PATH), "utf8")));
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ export function isConvergenceStateCurrent(state, expected) {
40
+ if (!state ||
41
+ state.agentKitVersion !== expected.agentKitVersion ||
42
+ state.host !== expected.host) {
43
+ return false;
44
+ }
45
+ return Object.entries(expected.sentinels).every(([name, value]) => state.sentinels[name] === value);
46
+ }
47
+ export function writeConvergenceState(repoRoot, state) {
48
+ const statePath = join(resolve(repoRoot), CONVERGENCE_STATE_PATH);
49
+ mkdirSync(dirname(statePath), { recursive: true });
50
+ writeJsonFile(statePath, state, {
51
+ atomic: true,
52
+ indent: 2,
53
+ });
54
+ }
@@ -0,0 +1,23 @@
1
+ import type { WriteAction } from "./write-plan.js";
2
+ export declare const CONVERGE_SCOPES: readonly ["repo-committed", "repo-ignored"];
3
+ export type ConvergeScope = (typeof CONVERGE_SCOPES)[number];
4
+ export interface ConvergeUnit {
5
+ readonly repoRoot: string;
6
+ readonly targetPath: string;
7
+ readonly gitPath: string;
8
+ readonly action: WriteAction;
9
+ readonly scope: ConvergeScope;
10
+ readonly reason: string;
11
+ }
12
+ export interface CreateConvergeUnitInput {
13
+ readonly repoRoot: string;
14
+ readonly targetPath: string;
15
+ readonly gitPath: string;
16
+ readonly action: WriteAction;
17
+ readonly scope: ConvergeScope;
18
+ readonly reason: string;
19
+ }
20
+ export declare function createConvergeUnit(input: CreateConvergeUnitInput): ConvergeUnit;
21
+ export declare function convergeUnitFromTarget(repoRoot: string, targetPath: string, input: Pick<CreateConvergeUnitInput, "action" | "scope" | "reason">): ConvergeUnit;
22
+ /** Applied units are the sole authority for authored commit scope. */
23
+ export declare function deriveCommitAllowlist(appliedUnits: readonly ConvergeUnit[]): string[];
@@ -0,0 +1,57 @@
1
+ import { isAbsolute, relative, resolve, sep } from "node:path";
2
+ export const CONVERGE_SCOPES = ["repo-committed", "repo-ignored"];
3
+ function normalizeGitPath(value) {
4
+ return value.replaceAll("\\", "/").replace(/^\.\//u, "");
5
+ }
6
+ function assertInsideRepo(repoRoot, targetPath) {
7
+ const relativePath = relative(repoRoot, targetPath);
8
+ if (relativePath.length === 0 ||
9
+ relativePath === ".." ||
10
+ relativePath.startsWith(`..${sep}`) ||
11
+ isAbsolute(relativePath)) {
12
+ throw new Error(`Convergence target must be a file inside the repository: ${targetPath}`);
13
+ }
14
+ return normalizeGitPath(relativePath);
15
+ }
16
+ export function createConvergeUnit(input) {
17
+ if (!isAbsolute(input.repoRoot)) {
18
+ throw new Error(`Convergence repo root must be absolute: ${input.repoRoot}`);
19
+ }
20
+ if (!isAbsolute(input.targetPath)) {
21
+ throw new Error(`Convergence target must be absolute: ${input.targetPath}`);
22
+ }
23
+ if (!CONVERGE_SCOPES.includes(input.scope)) {
24
+ throw new Error(`Unsupported convergence scope: ${input.scope}`);
25
+ }
26
+ const repoRoot = resolve(input.repoRoot);
27
+ const targetPath = resolve(input.targetPath);
28
+ const derivedGitPath = assertInsideRepo(repoRoot, targetPath);
29
+ const gitPath = normalizeGitPath(input.gitPath);
30
+ if (gitPath.length === 0 || isAbsolute(gitPath) || gitPath !== derivedGitPath) {
31
+ throw new Error(`Convergence git path must match its repo-anchored target: expected ${derivedGitPath}, received ${input.gitPath}`);
32
+ }
33
+ return {
34
+ repoRoot,
35
+ targetPath,
36
+ gitPath,
37
+ action: input.action,
38
+ scope: input.scope,
39
+ reason: input.reason,
40
+ };
41
+ }
42
+ export function convergeUnitFromTarget(repoRoot, targetPath, input) {
43
+ const anchoredRoot = resolve(repoRoot);
44
+ const anchoredTarget = resolve(targetPath);
45
+ return createConvergeUnit({
46
+ ...input,
47
+ repoRoot: anchoredRoot,
48
+ targetPath: anchoredTarget,
49
+ gitPath: assertInsideRepo(anchoredRoot, anchoredTarget),
50
+ });
51
+ }
52
+ /** Applied units are the sole authority for authored commit scope. */
53
+ export function deriveCommitAllowlist(appliedUnits) {
54
+ return [
55
+ ...new Set(appliedUnits.filter((unit) => unit.scope === "repo-committed").map((unit) => unit.gitPath)),
56
+ ].sort();
57
+ }
@@ -0,0 +1,19 @@
1
+ export type GitConvergenceStatus = "ready" | "fast-forwarded" | "not-git" | "unborn" | "detached" | "dirty" | "diverged" | "failed";
2
+ export interface GitConvergenceResult {
3
+ readonly status: GitConvergenceStatus;
4
+ readonly ok: boolean;
5
+ readonly repoRoot: string;
6
+ readonly head?: string;
7
+ readonly upstream?: string;
8
+ readonly shouldReplan: boolean;
9
+ readonly canCommit: boolean;
10
+ readonly warnings: readonly string[];
11
+ readonly error?: string;
12
+ }
13
+ export interface PrepareGitConvergenceOptions {
14
+ readonly repoRoot: string;
15
+ readonly isCi?: boolean;
16
+ readonly fetchTimeoutMs?: number;
17
+ readonly gitCommand?: string;
18
+ }
19
+ export declare function prepareRepositoryForConvergence(options: PrepareGitConvergenceOptions): GitConvergenceResult;
@@ -0,0 +1,168 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { resolve } from "node:path";
3
+ const DEFAULT_GIT_TIMEOUT_MS = 5_000;
4
+ const GIT_MAX_BUFFER = 1024 * 1024;
5
+ function git(repoRoot, args, timeoutMs, command = "git") {
6
+ const result = spawnSync(command, [...args], {
7
+ cwd: repoRoot,
8
+ encoding: "utf8",
9
+ timeout: timeoutMs,
10
+ maxBuffer: GIT_MAX_BUFFER,
11
+ stdio: ["ignore", "pipe", "pipe"],
12
+ });
13
+ return {
14
+ ok: result.status === 0 && !result.error,
15
+ stdout: result.stdout.trim(),
16
+ stderr: result.stderr.trim(),
17
+ timedOut: result.error !== undefined && "code" in result.error && result.error.code === "ETIMEDOUT",
18
+ };
19
+ }
20
+ function failed(repoRoot, status, error) {
21
+ return {
22
+ status,
23
+ ok: false,
24
+ repoRoot,
25
+ shouldReplan: false,
26
+ canCommit: false,
27
+ warnings: [],
28
+ error,
29
+ };
30
+ }
31
+ function parseAheadBehindCounts(stdout) {
32
+ const parts = stdout.trim().split(/\s+/u);
33
+ if (parts.length !== 2)
34
+ return null;
35
+ if (!parts.every((part) => /^\d+$/u.test(part)))
36
+ return null;
37
+ const [ahead, behind] = parts.map((part) => Number.parseInt(part, 10));
38
+ if (ahead === undefined ||
39
+ behind === undefined ||
40
+ !Number.isSafeInteger(ahead) ||
41
+ !Number.isSafeInteger(behind) ||
42
+ ahead < 0 ||
43
+ behind < 0) {
44
+ return null;
45
+ }
46
+ return { ahead, behind };
47
+ }
48
+ export function prepareRepositoryForConvergence(options) {
49
+ const repoRoot = resolve(options.repoRoot);
50
+ const timeoutMs = options.fetchTimeoutMs ?? DEFAULT_GIT_TIMEOUT_MS;
51
+ const gitCommand = options.gitCommand ?? "git";
52
+ const runGit = (args) => git(repoRoot, args, timeoutMs, gitCommand);
53
+ const inside = runGit(["rev-parse", "--is-inside-work-tree"]);
54
+ if (!inside.ok || inside.stdout !== "true") {
55
+ return failed(repoRoot, "not-git", "Repository convergence requires a Git worktree.");
56
+ }
57
+ const headResult = runGit(["rev-parse", "--verify", "HEAD"]);
58
+ if (!headResult.ok) {
59
+ return failed(repoRoot, "unborn", "Repository convergence requires an existing HEAD commit.");
60
+ }
61
+ const head = headResult.stdout;
62
+ const branch = runGit(["symbolic-ref", "--quiet", "--short", "HEAD"]);
63
+ const detached = !branch.ok;
64
+ if (detached && !options.isCi) {
65
+ return failed(repoRoot, "detached", "Repository convergence refuses a detached HEAD.");
66
+ }
67
+ const trackedStatus = runGit(["status", "--porcelain=v1", "--untracked-files=no"]);
68
+ if (!trackedStatus.ok) {
69
+ return failed(repoRoot, "failed", trackedStatus.stderr || "Unable to inspect Git status.");
70
+ }
71
+ if (trackedStatus.stdout.length > 0) {
72
+ return failed(repoRoot, "dirty", "Repository convergence requires a clean tracked index and worktree.");
73
+ }
74
+ const warnings = [];
75
+ if (detached) {
76
+ warnings.push("Detached HEAD accepted in CI; skipped upstream update and authored commit.");
77
+ return {
78
+ status: "ready",
79
+ ok: true,
80
+ repoRoot,
81
+ head,
82
+ shouldReplan: false,
83
+ canCommit: false,
84
+ warnings,
85
+ };
86
+ }
87
+ const upstreamResult = runGit(["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"]);
88
+ if (!upstreamResult.ok) {
89
+ warnings.push("No upstream is configured; skipped fetch and fast-forward.");
90
+ return {
91
+ status: "ready",
92
+ ok: true,
93
+ repoRoot,
94
+ head,
95
+ shouldReplan: false,
96
+ canCommit: !options.isCi,
97
+ warnings,
98
+ };
99
+ }
100
+ const upstream = upstreamResult.stdout;
101
+ const remoteSeparator = upstream.indexOf("/");
102
+ const remote = remoteSeparator === -1 ? upstream : upstream.slice(0, remoteSeparator);
103
+ const fetch = runGit(["fetch", "--quiet", "--no-tags", remote]);
104
+ if (!fetch.ok) {
105
+ warnings.push(fetch.timedOut
106
+ ? `Upstream fetch timed out after ${timeoutMs}ms; continuing from local refs.`
107
+ : `Upstream fetch unavailable; continuing from local refs${fetch.stderr ? `: ${fetch.stderr}` : "."}`);
108
+ }
109
+ const counts = runGit(["rev-list", "--left-right", "--count", `HEAD...${upstream}`]);
110
+ if (!counts.ok) {
111
+ return {
112
+ ...failed(repoRoot, "failed", counts.stderr || "Unable to compare HEAD with upstream."),
113
+ head,
114
+ upstream,
115
+ warnings,
116
+ };
117
+ }
118
+ const parsedCounts = parseAheadBehindCounts(counts.stdout);
119
+ if (!parsedCounts) {
120
+ return {
121
+ ...failed(repoRoot, "failed", `Unable to parse HEAD/upstream divergence counts from git rev-list output: ${JSON.stringify(counts.stdout)}.`),
122
+ head,
123
+ upstream,
124
+ warnings,
125
+ };
126
+ }
127
+ const { ahead, behind } = parsedCounts;
128
+ if (ahead > 0 && behind > 0) {
129
+ return {
130
+ ...failed(repoRoot, "diverged", `HEAD has diverged from ${upstream}; reconcile it manually.`),
131
+ head,
132
+ upstream,
133
+ warnings,
134
+ };
135
+ }
136
+ if (behind > 0) {
137
+ const merge = runGit(["merge", "--ff-only", upstream]);
138
+ if (!merge.ok) {
139
+ return {
140
+ ...failed(repoRoot, "failed", merge.stderr || `Unable to fast-forward from ${upstream}.`),
141
+ head,
142
+ upstream,
143
+ warnings,
144
+ };
145
+ }
146
+ const nextHead = runGit(["rev-parse", "--verify", "HEAD"]);
147
+ return {
148
+ status: "fast-forwarded",
149
+ ok: true,
150
+ repoRoot,
151
+ head: nextHead.ok ? nextHead.stdout : undefined,
152
+ upstream,
153
+ shouldReplan: true,
154
+ canCommit: !options.isCi,
155
+ warnings,
156
+ };
157
+ }
158
+ return {
159
+ status: "ready",
160
+ ok: true,
161
+ repoRoot,
162
+ head,
163
+ upstream,
164
+ shouldReplan: false,
165
+ canCommit: !options.isCi,
166
+ warnings,
167
+ };
168
+ }
@@ -55,8 +55,10 @@ export const GENERATED_PATHS_BLOCK = {
55
55
  ".runtime/",
56
56
  ".opencode/",
57
57
  ".codex/",
58
+ ".grok/",
58
59
  "_worktrees/",
59
60
  ".webpresso/hooks-manifest.json",
61
+ ".webpresso/converged.json",
60
62
  ".claude/settings.json",
61
63
  ".claude/settings.local.json",
62
64
  ".claude/agents/",
@@ -0,0 +1,52 @@
1
+ export interface GrokPrivacyFlow {
2
+ readonly hostname: string;
3
+ readonly method: string;
4
+ readonly requestCount: number;
5
+ readonly requestBytes: number;
6
+ readonly responseBytes: number;
7
+ }
8
+ export interface GrokPrivacyBaseline {
9
+ readonly schemaVersion: 1;
10
+ readonly cliVersion: string;
11
+ readonly authMode: "local-session";
12
+ readonly transportVarianceBytes: number;
13
+ readonly maxAggregateRequestBytes: number;
14
+ readonly flows: readonly {
15
+ readonly hostname: string;
16
+ readonly method: string;
17
+ readonly maxRequestCount: number;
18
+ readonly maxRequestBytes: number;
19
+ }[];
20
+ }
21
+ export interface GrokPrivacyEvidence {
22
+ readonly schemaVersion: 1;
23
+ readonly host: "grok";
24
+ readonly cliVersion: string;
25
+ readonly authMode: "local-session";
26
+ readonly reviewedSha: string;
27
+ readonly traceSha256: string;
28
+ readonly sentinelObserved: false;
29
+ readonly native: {
30
+ readonly hooksTrusted: true;
31
+ readonly hookDenial: true;
32
+ readonly inspect: true;
33
+ readonly mcpList: true;
34
+ readonly mcpDoctor: true;
35
+ readonly localInference: true;
36
+ };
37
+ readonly flows: readonly GrokPrivacyFlow[];
38
+ }
39
+ export declare function buildGrokPrivacyEvidence(input: {
40
+ baseline: GrokPrivacyBaseline;
41
+ cliVersion: string;
42
+ reviewedSha: string;
43
+ sentinelObserved: boolean;
44
+ hooksTrusted: boolean;
45
+ hookDenialPassed: boolean;
46
+ inspectPassed: boolean;
47
+ mcpListPassed: boolean;
48
+ mcpDoctorPassed: boolean;
49
+ localInferencePassed: boolean;
50
+ flows: readonly GrokPrivacyFlow[];
51
+ }): GrokPrivacyEvidence;
52
+ export declare function serializeGrokPrivacyEvidence(evidence: GrokPrivacyEvidence): string;