@webpresso/agent-kit 3.1.30 → 3.3.0

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

Potentially problematic release.


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

Files changed (300) hide show
  1. package/README.md +53 -15
  2. package/bin/_run.js +183 -20
  3. package/catalog/AGENTS.md.tpl +3 -3
  4. package/catalog/agent/agents/implementer.md +45 -0
  5. package/catalog/agent/rules/parallel-orchestration-quota.md +100 -0
  6. package/catalog/agent/rules/pre-implementation.md +28 -1
  7. package/catalog/agent/rules/supported-agent-clis.md +9 -0
  8. package/catalog/agent/rules/typescript-version.md +50 -0
  9. package/catalog/agent/skills/codex/SKILL.md +25 -1
  10. package/catalog/agent/skills/verify/SKILL.md +4 -2
  11. package/catalog/docs/templates/blueprint.md +1 -1
  12. package/dist/esm/audit/agents.js +1 -0
  13. package/dist/esm/audit/blueprint-lifecycle-sql.d.ts +12 -0
  14. package/dist/esm/audit/blueprint-lifecycle-sql.js +23 -2
  15. package/dist/esm/audit/blueprint-pr-coverage.js +4 -0
  16. package/dist/esm/audit/blueprint-trust.js +14 -10
  17. package/dist/esm/audit/changeset-evidence.d.ts +23 -0
  18. package/dist/esm/audit/changeset-evidence.js +30 -0
  19. package/dist/esm/audit/changeset-required.d.ts +10 -0
  20. package/dist/esm/audit/changeset-required.js +73 -0
  21. package/dist/esm/audit/ci-guardrails-detection.d.ts +27 -0
  22. package/dist/esm/audit/ci-guardrails-detection.js +68 -0
  23. package/dist/esm/audit/ci-guardrails-wiring.d.ts +22 -0
  24. package/dist/esm/audit/ci-guardrails-wiring.js +80 -0
  25. package/dist/esm/audit/ci-test-perf.js +30 -0
  26. package/dist/esm/audit/command-surface.js +4 -2
  27. package/dist/esm/audit/host-substitution-risk.d.ts +2 -0
  28. package/dist/esm/audit/host-substitution-risk.js +256 -0
  29. package/dist/esm/audit/registry.d.ts +4 -4
  30. package/dist/esm/audit/registry.js +13 -1
  31. package/dist/esm/audit/toolchain-isolation.js +1 -2
  32. package/dist/esm/audit/typescript-version.d.ts +2 -0
  33. package/dist/esm/audit/typescript-version.js +123 -0
  34. package/dist/esm/blueprint/core/parser.js +101 -2
  35. package/dist/esm/blueprint/core/schema.d.ts +1 -0
  36. package/dist/esm/blueprint/core/schema.js +26 -0
  37. package/dist/esm/blueprint/core/validation/criteria.d.ts +14 -0
  38. package/dist/esm/blueprint/core/validation/criteria.js +41 -2
  39. package/dist/esm/blueprint/core/validation/state.js +25 -14
  40. package/dist/esm/blueprint/db/migrations/run.js +4 -2
  41. package/dist/esm/blueprint/lifecycle/audit.d.ts +20 -0
  42. package/dist/esm/blueprint/lifecycle/audit.js +87 -20
  43. package/dist/esm/blueprint/lifecycle/canonicalize.d.ts +6 -0
  44. package/dist/esm/blueprint/lifecycle/canonicalize.js +135 -0
  45. package/dist/esm/blueprint/lifecycle/local.d.ts +2 -1
  46. package/dist/esm/blueprint/lifecycle/local.js +19 -3
  47. package/dist/esm/blueprint/lifecycle/review-provenance.d.ts +6 -0
  48. package/dist/esm/blueprint/lifecycle/review-provenance.js +68 -12
  49. package/dist/esm/blueprint/lifecycle/rollout-anchor.d.ts +97 -0
  50. package/dist/esm/blueprint/lifecycle/rollout-anchor.js +161 -0
  51. package/dist/esm/blueprint/service/BlueprintCreationService.d.ts +1 -0
  52. package/dist/esm/blueprint/service/BlueprintCreationService.js +53 -4
  53. package/dist/esm/blueprint/service/blueprint-tech-debt-links.js +16 -2
  54. package/dist/esm/blueprint/sync/client.d.ts +2 -1
  55. package/dist/esm/blueprint/sync/client.js +1 -1
  56. package/dist/esm/blueprint/trust/command-runner.d.ts +26 -0
  57. package/dist/esm/blueprint/trust/command-runner.js +148 -0
  58. package/dist/esm/blueprint/trust/dossier.d.ts +1 -0
  59. package/dist/esm/blueprint/trust/dossier.js +40 -6
  60. package/dist/esm/blueprint/trust/gates.d.ts +7 -0
  61. package/dist/esm/blueprint/trust/gates.js +20 -0
  62. package/dist/esm/blueprint/trust/promotion.d.ts +8 -0
  63. package/dist/esm/blueprint/trust/promotion.js +74 -112
  64. package/dist/esm/blueprint/trust/scaffold.d.ts +19 -0
  65. package/dist/esm/blueprint/trust/scaffold.js +64 -0
  66. package/dist/esm/blueprint/trust/validator.d.ts +1 -0
  67. package/dist/esm/blueprint/trust/validator.js +7 -1
  68. package/dist/esm/blueprint/utils/archive.js +27 -5
  69. package/dist/esm/blueprint/utils/document-paths.d.ts +18 -0
  70. package/dist/esm/blueprint/utils/document-paths.js +45 -12
  71. package/dist/esm/build/cli-mcp-parity.js +15 -0
  72. package/dist/esm/cli/bundle/commands/blueprint.d.ts +1 -0
  73. package/dist/esm/cli/bundle/commands/blueprint.js +1 -0
  74. package/dist/esm/cli/cli.d.ts +1 -1
  75. package/dist/esm/cli/cli.js +43 -0
  76. package/dist/esm/cli/commands/agent-launch.d.ts +8 -1
  77. package/dist/esm/cli/commands/agent-launch.js +93 -4
  78. package/dist/esm/cli/commands/audit-core.d.ts +1 -1
  79. package/dist/esm/cli/commands/audit-core.js +8 -1
  80. package/dist/esm/cli/commands/audit.js +21 -5
  81. package/dist/esm/cli/commands/blueprint/execution.js +18 -6
  82. package/dist/esm/cli/commands/blueprint/mutations.js +59 -40
  83. package/dist/esm/cli/commands/blueprint/router-dispatch.d.ts +2 -1
  84. package/dist/esm/cli/commands/blueprint/router-dispatch.js +20 -1
  85. package/dist/esm/cli/commands/blueprint/router-output.d.ts +21 -0
  86. package/dist/esm/cli/commands/blueprint/router-output.js +48 -17
  87. package/dist/esm/cli/commands/blueprint/router.d.ts +7 -0
  88. package/dist/esm/cli/commands/blueprint/router.js +13 -1
  89. package/dist/esm/cli/commands/ci-preflight.d.ts +13 -2
  90. package/dist/esm/cli/commands/ci-preflight.js +30 -6
  91. package/dist/esm/cli/commands/compile.js +5 -31
  92. package/dist/esm/cli/commands/dash/delivery-status.d.ts +1 -0
  93. package/dist/esm/cli/commands/dash/delivery-status.js +11 -4
  94. package/dist/esm/cli/commands/doctor.js +5 -0
  95. package/dist/esm/cli/commands/hook.d.ts +5 -0
  96. package/dist/esm/cli/commands/hook.js +15 -9
  97. package/dist/esm/cli/commands/init/config.js +2 -2
  98. package/dist/esm/cli/commands/init/convergence-apply.d.ts +88 -0
  99. package/dist/esm/cli/commands/init/convergence-apply.js +325 -0
  100. package/dist/esm/cli/commands/init/convergence-state.d.ts +13 -0
  101. package/dist/esm/cli/commands/init/convergence-state.js +54 -0
  102. package/dist/esm/cli/commands/init/convergence.d.ts +23 -0
  103. package/dist/esm/cli/commands/init/convergence.js +57 -0
  104. package/dist/esm/cli/commands/init/git-convergence.d.ts +19 -0
  105. package/dist/esm/cli/commands/init/git-convergence.js +168 -0
  106. package/dist/esm/cli/commands/init/gitignore-patcher.js +2 -0
  107. package/dist/esm/cli/commands/init/grok-privacy-smoke.d.ts +52 -0
  108. package/dist/esm/cli/commands/init/grok-privacy-smoke.js +91 -0
  109. package/dist/esm/cli/commands/init/host-native-proof.d.ts +18 -0
  110. package/dist/esm/cli/commands/init/host-native-proof.js +88 -0
  111. package/dist/esm/cli/commands/init/host-visibility.d.ts +2 -2
  112. package/dist/esm/cli/commands/init/host-visibility.js +94 -5
  113. package/dist/esm/cli/commands/init/index.d.ts +3 -0
  114. package/dist/esm/cli/commands/init/index.js +326 -173
  115. package/dist/esm/cli/commands/init/mcp-spec.d.ts +57 -0
  116. package/dist/esm/cli/commands/init/mcp-spec.js +273 -0
  117. package/dist/esm/cli/commands/init/merge.d.ts +1 -0
  118. package/dist/esm/cli/commands/init/merge.js +30 -1
  119. package/dist/esm/cli/commands/init/package-root.d.ts +7 -0
  120. package/dist/esm/cli/commands/init/package-root.js +10 -2
  121. package/dist/esm/cli/commands/init/plugin-cache-prune.d.ts +0 -3
  122. package/dist/esm/cli/commands/init/plugin-cache-prune.js +0 -1
  123. package/dist/esm/cli/commands/init/scaffold-agents-md.d.ts +1 -1
  124. package/dist/esm/cli/commands/init/scaffold-agents-md.js +9 -3
  125. package/dist/esm/cli/commands/init/scaffold-base-kit.d.ts +20 -0
  126. package/dist/esm/cli/commands/init/scaffold-base-kit.js +61 -5
  127. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.d.ts +14 -8
  128. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.js +41 -24
  129. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.d.ts +2 -0
  130. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +54 -24
  131. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.d.ts +12 -31
  132. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.js +288 -202
  133. package/dist/esm/cli/commands/init/scaffolders/file-transaction.d.ts +22 -0
  134. package/dist/esm/cli/commands/init/scaffolders/file-transaction.js +230 -0
  135. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.d.ts +38 -0
  136. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.js +73 -0
  137. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.d.ts +21 -0
  138. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.js +559 -63
  139. package/dist/esm/cli/commands/init/untracked-collision.d.ts +14 -0
  140. package/dist/esm/cli/commands/init/untracked-collision.js +42 -0
  141. package/dist/esm/cli/commands/opencode-probe.d.ts +107 -0
  142. package/dist/esm/cli/commands/opencode-probe.js +323 -0
  143. package/dist/esm/cli/commands/opencode-rotate.d.ts +72 -0
  144. package/dist/esm/cli/commands/opencode-rotate.js +147 -0
  145. package/dist/esm/cli/commands/public-readiness.d.ts +11 -0
  146. package/dist/esm/cli/commands/public-readiness.js +42 -0
  147. package/dist/esm/cli/commands/quality-runner.js +3 -3
  148. package/dist/esm/cli/commands/review.d.ts +35 -3
  149. package/dist/esm/cli/commands/review.js +751 -209
  150. package/dist/esm/cli/commands/run-wait.d.ts +2 -0
  151. package/dist/esm/cli/commands/run-wait.js +122 -0
  152. package/dist/esm/cli/commands/rust-check.d.ts +24 -0
  153. package/dist/esm/cli/commands/rust-check.js +110 -0
  154. package/dist/esm/cli/commands/setup-help.js +1 -1
  155. package/dist/esm/cli/commands/setup-repair-help.js +1 -1
  156. package/dist/esm/cli/commands/typecheck.d.ts +1 -0
  157. package/dist/esm/cli/commands/typecheck.js +30 -1
  158. package/dist/esm/cli/commands/worktree/router-dispatch.d.ts +6 -0
  159. package/dist/esm/cli/commands/worktree/router-dispatch.js +126 -9
  160. package/dist/esm/cli/commands/worktree/router.js +10 -0
  161. package/dist/esm/cli/direct-provider-launch.js +9 -5
  162. package/dist/esm/cli/optional-tool-freshness.d.ts +27 -0
  163. package/dist/esm/cli/optional-tool-freshness.js +219 -9
  164. package/dist/esm/daemon/domains/git-actions.d.ts +29 -0
  165. package/dist/esm/daemon/domains/git-actions.js +136 -0
  166. package/dist/esm/daemon/domains/run-registry-interop.d.ts +16 -0
  167. package/dist/esm/daemon/domains/run-registry-interop.js +45 -0
  168. package/dist/esm/daemon/domains/sessions-search.d.ts +11 -0
  169. package/dist/esm/daemon/domains/sessions-search.js +29 -0
  170. package/dist/esm/daemon/handlers/blueprints-handlers.d.ts +5 -0
  171. package/dist/esm/daemon/handlers/blueprints-handlers.js +36 -0
  172. package/dist/esm/daemon/handlers/deploy-handlers.d.ts +6 -0
  173. package/dist/esm/daemon/handlers/deploy-handlers.js +5 -0
  174. package/dist/esm/daemon/handlers/fleet-handlers.d.ts +15 -0
  175. package/dist/esm/daemon/handlers/fleet-handlers.js +91 -0
  176. package/dist/esm/daemon/handlers/git-handlers.d.ts +6 -0
  177. package/dist/esm/daemon/handlers/git-handlers.js +27 -0
  178. package/dist/esm/daemon/handlers/product.d.ts +7 -0
  179. package/dist/esm/daemon/handlers/product.js +10 -119
  180. package/dist/esm/daemon/handlers/sessions-handlers.d.ts +12 -0
  181. package/dist/esm/daemon/handlers/sessions-handlers.js +31 -0
  182. package/dist/esm/daemon/handlers/shared.d.ts +5 -0
  183. package/dist/esm/daemon/handlers/shared.js +16 -0
  184. package/dist/esm/daemon/methods.d.ts +8 -1
  185. package/dist/esm/daemon/methods.js +7 -0
  186. package/dist/esm/daemon/protocol/contract.d.ts +43 -0
  187. package/dist/esm/daemon/protocol/contract.js +26 -0
  188. package/dist/esm/daemon/protocol/index.d.ts +1 -1
  189. package/dist/esm/daemon/protocol/index.js +1 -1
  190. package/dist/esm/hooks/__conformance__/matrix.d.ts +6 -0
  191. package/dist/esm/hooks/__conformance__/matrix.js +137 -0
  192. package/dist/esm/hooks/conformance/batch.js +5 -0
  193. package/dist/esm/hooks/doctor.d.ts +5 -3
  194. package/dist/esm/hooks/doctor.js +67 -16
  195. package/dist/esm/hooks/permission-request/index.js +9 -3
  196. package/dist/esm/hooks/permission-request/policy.d.ts +9 -0
  197. package/dist/esm/hooks/permission-request/policy.js +13 -0
  198. package/dist/esm/hooks/pretool-guard/dev-routing.d.ts +9 -0
  199. package/dist/esm/hooks/pretool-guard/dev-routing.js +41 -5
  200. package/dist/esm/hooks/pretool-guard/logger.d.ts +7 -0
  201. package/dist/esm/hooks/pretool-guard/logger.js +16 -0
  202. package/dist/esm/hooks/pretool-guard/runner.d.ts +6 -0
  203. package/dist/esm/hooks/pretool-guard/runner.js +68 -16
  204. package/dist/esm/hooks/pretool-guard/validators/blueprint.js +30 -10
  205. package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +54 -0
  206. package/dist/esm/hooks/pretool-guard/validators/index.d.ts +7 -0
  207. package/dist/esm/hooks/pretool-guard/validators/index.js +21 -0
  208. package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +19 -0
  209. package/dist/esm/hooks/pretool-guard/validators/path-contract.js +25 -8
  210. package/dist/esm/hooks/pretool-guard/validators/worktree-discipline.js +6 -1
  211. package/dist/esm/hooks/shared/guard-outcome.d.ts +149 -0
  212. package/dist/esm/hooks/shared/guard-outcome.js +215 -0
  213. package/dist/esm/hooks/shared/hook-bootstrap.d.ts +26 -0
  214. package/dist/esm/hooks/shared/hook-bootstrap.js +64 -1
  215. package/dist/esm/hooks/shared/types.d.ts +8 -5
  216. package/dist/esm/hooks/shared/types.js +50 -9
  217. package/dist/esm/hooks/stop/qa-changed-files.d.ts +11 -0
  218. package/dist/esm/hooks/stop/qa-changed-files.js +92 -0
  219. package/dist/esm/mcp/blueprint/_shared/lifecycle.js +14 -1
  220. package/dist/esm/mcp/blueprint/handlers/document-mutations.d.ts +5 -0
  221. package/dist/esm/mcp/blueprint/handlers/document-mutations.js +109 -11
  222. package/dist/esm/mcp/blueprint/handlers/review-log.js +8 -1
  223. package/dist/esm/mcp/blueprint/handlers/task-advance.js +113 -54
  224. package/dist/esm/mcp/blueprint/handlers/task-verify.js +39 -19
  225. package/dist/esm/mcp/blueprint/registration.js +3 -2
  226. package/dist/esm/mcp/server.d.ts +1 -0
  227. package/dist/esm/mcp/server.js +27 -0
  228. package/dist/esm/mcp/tools/_names.d.ts +1 -1
  229. package/dist/esm/mcp/tools/_names.js +5 -0
  230. package/dist/esm/mcp/tools/_registry.js +10 -0
  231. package/dist/esm/mcp/tools/_shared/audit-kinds.d.ts +1 -1
  232. package/dist/esm/mcp/tools/_shared/result.js +44 -1
  233. package/dist/esm/mcp/tools/audit.d.ts +5 -1
  234. package/dist/esm/mcp/tools/audit.js +42 -0
  235. package/dist/esm/mcp/tools/audits.d.ts +4 -0
  236. package/dist/esm/mcp/tools/ci-preflight.d.ts +50 -0
  237. package/dist/esm/mcp/tools/ci-preflight.js +183 -0
  238. package/dist/esm/mcp/tools/pr-upsert.js +39 -1
  239. package/dist/esm/mcp/tools/review-run.d.ts +28 -0
  240. package/dist/esm/mcp/tools/review-run.js +216 -0
  241. package/dist/esm/mcp/tools/run-wait.d.ts +86 -0
  242. package/dist/esm/mcp/tools/run-wait.js +593 -0
  243. package/dist/esm/mcp/tools/session-fetch-and-index.d.ts +1 -1
  244. package/dist/esm/mcp/tools/session-id.d.ts +3 -0
  245. package/dist/esm/mcp/tools/session-id.js +45 -0
  246. package/dist/esm/mcp/tools/session-info.d.ts +3 -0
  247. package/dist/esm/mcp/tools/session-info.js +49 -0
  248. package/dist/esm/output-transforms/audit.d.ts +23 -0
  249. package/dist/esm/output-transforms/audit.js +47 -0
  250. package/dist/esm/output-transforms/index.js +2 -0
  251. package/dist/esm/package.json +2 -0
  252. package/dist/esm/platform/client.d.ts +7 -1
  253. package/dist/esm/platform/github-contract-source.d.ts +2 -1
  254. package/dist/esm/pr-description/contract.js +24 -4
  255. package/dist/esm/review/authority.js +27 -14
  256. package/dist/esm/review/availability.d.ts +33 -0
  257. package/dist/esm/review/availability.js +122 -20
  258. package/dist/esm/review/delivery-verifier.d.ts +27 -0
  259. package/dist/esm/review/delivery-verifier.js +115 -0
  260. package/dist/esm/review/events.d.ts +3 -2
  261. package/dist/esm/review/events.js +23 -3
  262. package/dist/esm/review/execution/adapters.d.ts +11 -1
  263. package/dist/esm/review/execution/adapters.js +36 -10
  264. package/dist/esm/review/execution/artifacts.d.ts +1 -1
  265. package/dist/esm/review/execution/output-policy.d.ts +2 -0
  266. package/dist/esm/review/execution/output-policy.js +12 -0
  267. package/dist/esm/review/execution/review-checkout.js +121 -21
  268. package/dist/esm/review/execution/supervisor.js +36 -4
  269. package/dist/esm/review/execution/types.d.ts +9 -0
  270. package/dist/esm/review/opencode-account.d.ts +24 -0
  271. package/dist/esm/review/opencode-account.js +68 -0
  272. package/dist/esm/review/opencode-auth.d.ts +33 -0
  273. package/dist/esm/review/opencode-auth.js +79 -0
  274. package/dist/esm/review/subject.d.ts +25 -0
  275. package/dist/esm/review/subject.js +116 -26
  276. package/dist/esm/runtime/opencode-account-materializer.d.ts +34 -0
  277. package/dist/esm/runtime/opencode-account-materializer.js +33 -0
  278. package/dist/esm/rust/affected-manifests.d.ts +38 -0
  279. package/dist/esm/rust/affected-manifests.js +69 -0
  280. package/dist/esm/session-memory/fetch-index.d.ts +1 -1
  281. package/dist/esm/status/snapshot.js +32 -25
  282. package/dist/esm/test/duration-sequencer.d.ts +20 -0
  283. package/dist/esm/test/duration-sequencer.js +54 -0
  284. package/dist/esm/test/shard-durations.json +922 -0
  285. package/dist/esm/test/worker-budget.d.ts +6 -0
  286. package/dist/esm/test/worker-budget.js +59 -1
  287. package/dist/esm/test-helpers/global-setup.d.ts +1 -2
  288. package/dist/esm/test-helpers/global-setup.js +79 -32
  289. package/dist/esm/typecheck/planner.d.ts +9 -1
  290. package/dist/esm/typecheck/planner.js +31 -0
  291. package/dist/esm/ultragoal/service.d.ts +7 -0
  292. package/dist/esm/ultragoal/service.js +42 -2
  293. package/dist/esm/utils/write-json-file.js +3 -1
  294. package/dist/esm/worktrees/codex-project-trust.d.ts +15 -0
  295. package/dist/esm/worktrees/codex-project-trust.js +56 -0
  296. package/dist/esm/worktrees/orphan-scan.d.ts +50 -0
  297. package/dist/esm/worktrees/orphan-scan.js +211 -0
  298. package/dist/esm/worktrees/registry.d.ts +8 -0
  299. package/dist/esm/worktrees/registry.js +18 -3
  300. package/package.json +18 -13
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Filesystem-level orphan scan for `wp worktree prune --orphans`.
3
+ *
4
+ * Complements the existing registry-only `wp worktree prune --all`: that
5
+ * command only drops stale bookkeeping rows from `registry.json`. This module
6
+ * instead walks the physical managed-worktree roots
7
+ * (`~/.webpresso/worktrees`, legacy `~/.agent/worktrees`) directly, because a
8
+ * large share of stale directories on disk were never registered at all
9
+ * (crashed sessions, `gh pr merge --delete-branch` deregistering the git
10
+ * worktree out from under the directory, manual `rm` of only part of a
11
+ * worktree). Git metadata and the registry can both be perfectly clean while
12
+ * the `~/.webpresso` tree still accumulates dozens of dead directories.
13
+ *
14
+ * Classification (see `catalog blueprint worktree-prune-stale-dirs`):
15
+ *
16
+ * - `alive` — path is listed by `git worktree list` for its resolved
17
+ * primary repo. Never removable.
18
+ * - `orphan` — a resolvable, existing primary repo's `git worktree
19
+ * list` output does NOT include this path. Removable only
20
+ * when a `git status --porcelain` probe inside the
21
+ * directory succeeds AND reports no changes.
22
+ * - `broken` — a primary repo pointer was resolved, but the target
23
+ * repo itself is missing on disk, or its `git worktree
24
+ * list` probe failed outright (bounded, non-retrying).
25
+ * Never removable — the directory's true state cannot be
26
+ * proven.
27
+ * - `unrecognized` — no primary repo pointer could be resolved at all
28
+ * (neither `registry.json` nor the directory's own
29
+ * `.git` file yields one), or the directory's `.git`
30
+ * pointer resolves but `git status --porcelain` cannot
31
+ * even run inside it (not a functioning checkout).
32
+ * Reported for manual review; never removable.
33
+ */
34
+ import { readdirSync, statSync } from "node:fs";
35
+ import { join, relative, sep } from "node:path";
36
+ import { canonicalizeWorktreePath } from "./identity.js";
37
+ function measureSizeSafely(path, deps) {
38
+ try {
39
+ return deps.measureSize(path);
40
+ }
41
+ catch {
42
+ return "unknown";
43
+ }
44
+ }
45
+ function finalizeRow(candidate, classification, reason, deps) {
46
+ if (classification !== "orphan") {
47
+ return {
48
+ ...candidate,
49
+ classification,
50
+ dirty: "unknown",
51
+ sizeBytes: "unknown",
52
+ removable: false,
53
+ reason,
54
+ };
55
+ }
56
+ const dirty = deps.probeDirty(candidate.path);
57
+ if (dirty === "unknown") {
58
+ return {
59
+ ...candidate,
60
+ classification: "unrecognized",
61
+ dirty,
62
+ sizeBytes: "unknown",
63
+ removable: false,
64
+ reason: "git status probe failed — not a functioning git checkout",
65
+ };
66
+ }
67
+ // Size is decision-relevant only once a row is a confirmed orphan, so it is
68
+ // measured here — never for alive/broken/unrecognized rows above.
69
+ const sizeBytes = measureSizeSafely(candidate.path, deps);
70
+ return {
71
+ ...candidate,
72
+ classification,
73
+ dirty,
74
+ sizeBytes,
75
+ removable: dirty === false,
76
+ reason: dirty ? "uncommitted/untracked changes present" : reason,
77
+ };
78
+ }
79
+ /** Classify a single on-disk candidate. Pure aside from the injected deps. */
80
+ export function classifyOrphanCandidate(candidate, deps) {
81
+ const repoRoot = deps.resolveRepoRoot(candidate);
82
+ if (!repoRoot) {
83
+ return finalizeRow(candidate, "unrecognized", "no resolvable primary repo pointer", deps);
84
+ }
85
+ if (!deps.repoRootExists(repoRoot)) {
86
+ return finalizeRow(candidate, "broken", `target repo missing: ${repoRoot}`, deps);
87
+ }
88
+ const inventory = deps.buildInventory(repoRoot);
89
+ if (!inventory.complete) {
90
+ return finalizeRow(candidate, "broken", "git worktree list unavailable for target repo", deps);
91
+ }
92
+ const canonical = canonicalizeWorktreePath(candidate.path);
93
+ if (inventory.canonicalPaths.has(canonical)) {
94
+ return finalizeRow(candidate, "alive", "present in git worktree list", deps);
95
+ }
96
+ return finalizeRow(candidate, "orphan", "absent from git worktree list", deps);
97
+ }
98
+ /** Namespace-keyed lookup of a known-live `repoRoot`, first-registered-wins. */
99
+ export function buildRegistryRepoRootMap(entries) {
100
+ const map = new Map();
101
+ for (const entry of entries) {
102
+ if (!map.has(entry.repoNamespace))
103
+ map.set(entry.repoNamespace, entry.repoRoot);
104
+ }
105
+ return map;
106
+ }
107
+ const WORKTREES_GITDIR_MARKER = "/.git/worktrees/";
108
+ /**
109
+ * Fallback primary-repo resolver for candidates the registry never recorded:
110
+ * a linked worktree's `.git` is a file containing `gitdir: <repoRoot>/.git/
111
+ * worktrees/<name>`. Returns `undefined` when unreadable or unparseable
112
+ * (e.g. `.git` is a directory, or the pointer target was already reaped).
113
+ */
114
+ export function resolveRepoRootFromGitPointer(path, readGitPointer) {
115
+ const content = readGitPointer(join(path, ".git"));
116
+ if (!content)
117
+ return undefined;
118
+ const match = /^gitdir:\s*(.+)$/mu.exec(content.trim());
119
+ const gitdir = match?.[1]?.trim();
120
+ if (!gitdir)
121
+ return undefined;
122
+ const markerIndex = gitdir.lastIndexOf(WORKTREES_GITDIR_MARKER);
123
+ if (markerIndex === -1)
124
+ return undefined;
125
+ return gitdir.slice(0, markerIndex);
126
+ }
127
+ const MAX_SCAN_DEPTH = 8;
128
+ const SKIP_DIR_NAMES = new Set([".git", "node_modules"]);
129
+ function repoNamespaceFromPath(root, path) {
130
+ const segments = relative(root, path).split(sep).filter(Boolean);
131
+ const reposIndex = segments.indexOf("repos");
132
+ if (reposIndex === -1)
133
+ return undefined;
134
+ return segments[reposIndex + 1];
135
+ }
136
+ function walkForCandidates(root, dir, depth, out) {
137
+ if (depth > MAX_SCAN_DEPTH)
138
+ return;
139
+ let entries;
140
+ try {
141
+ entries = readdirSync(dir, { withFileTypes: true, encoding: "utf8" });
142
+ }
143
+ catch {
144
+ return;
145
+ }
146
+ if (entries.some((entry) => entry.name === ".git")) {
147
+ const repoNamespace = repoNamespaceFromPath(root, dir);
148
+ if (repoNamespace)
149
+ out.push({ path: dir, repoNamespace });
150
+ return; // never descend into a worktree checkout's own contents
151
+ }
152
+ for (const entry of entries) {
153
+ if (!entry.isDirectory() || SKIP_DIR_NAMES.has(entry.name))
154
+ continue;
155
+ walkForCandidates(root, join(dir, entry.name), depth + 1, out);
156
+ }
157
+ }
158
+ /** Walk every known managed-worktree root and collect worktree-shaped leaf dirs. */
159
+ export function discoverOrphanScanCandidates(roots, options = {}) {
160
+ const dirExists = options.dirExists ??
161
+ ((path) => {
162
+ try {
163
+ return statSync(path).isDirectory();
164
+ }
165
+ catch {
166
+ return false;
167
+ }
168
+ });
169
+ const out = [];
170
+ for (const root of roots) {
171
+ if (!dirExists(root))
172
+ continue;
173
+ walkForCandidates(root, root, 0, out);
174
+ }
175
+ return options.repoNamespaceFilter
176
+ ? out.filter((candidate) => candidate.repoNamespace === options.repoNamespaceFilter)
177
+ : out;
178
+ }
179
+ /** Bounded recursive directory size, symlinks excluded, unreadable entries skipped. */
180
+ export function measureDirectorySizeBytes(path) {
181
+ let total = 0;
182
+ const stack = [path];
183
+ while (stack.length > 0) {
184
+ const current = stack.pop();
185
+ if (current === undefined)
186
+ break;
187
+ let entries;
188
+ try {
189
+ entries = readdirSync(current, { withFileTypes: true, encoding: "utf8" });
190
+ }
191
+ catch {
192
+ continue;
193
+ }
194
+ for (const entry of entries) {
195
+ if (entry.isSymbolicLink())
196
+ continue;
197
+ const full = join(current, entry.name);
198
+ if (entry.isDirectory()) {
199
+ stack.push(full);
200
+ continue;
201
+ }
202
+ try {
203
+ total += statSync(full).size;
204
+ }
205
+ catch {
206
+ // unreadable file: skip rather than fail the whole scan
207
+ }
208
+ }
209
+ }
210
+ return total;
211
+ }
@@ -50,6 +50,13 @@ export interface PruneStaleWorktreeRegistryOptions extends RegistryOptions {
50
50
  readonly inventory: WorktreeInventory;
51
51
  readonly scope: MembershipScope;
52
52
  }
53
+ export interface StaleWorktreeRegistryPrunePlan {
54
+ readonly kept: ManagedWorktreeEntry[];
55
+ readonly removed: ManagedWorktreeEntry[];
56
+ readonly warnings: string[];
57
+ /** Persist the already-classified registry mutation after dependent cleanup succeeds. */
58
+ commit(): void;
59
+ }
53
60
  /** Read one physical registry file at `root`. */
54
61
  export declare function readPhysicalRegistry(root: string): WorktreeRegistry;
55
62
  /** Write one physical registry file at `root`. */
@@ -100,6 +107,7 @@ export declare function removeWorktreeRegistryEntries(predicate: (entry: Managed
100
107
  * when it is PROVEN-SAME-REPO and STALE against a COMPLETE inventory; unknown,
101
108
  * other-repo, and present entries are RETAINED.
102
109
  */
110
+ export declare function planStaleWorktreeRegistryPrune(options: PruneStaleWorktreeRegistryOptions): StaleWorktreeRegistryPrunePlan;
103
111
  export declare function pruneStaleWorktreeRegistryEntries(options: PruneStaleWorktreeRegistryOptions): {
104
112
  kept: ManagedWorktreeEntry[];
105
113
  removed: ManagedWorktreeEntry[];
@@ -193,7 +193,7 @@ export function removeWorktreeRegistryEntries(predicate, options = {}) {
193
193
  * when it is PROVEN-SAME-REPO and STALE against a COMPLETE inventory; unknown,
194
194
  * other-repo, and present entries are RETAINED.
195
195
  */
196
- export function pruneStaleWorktreeRegistryEntries(options) {
196
+ export function planStaleWorktreeRegistryPrune(options) {
197
197
  const resolveKey = options.scope.resolveMembershipRepoKey ?? ((dir) => resolveRepoIdentity(dir));
198
198
  const shouldPrune = (entry) => {
199
199
  const membership = classifyMembership(entry.repoRoot, options.scope.authoritativeRepoKey, resolveKey);
@@ -205,16 +205,31 @@ export function pruneStaleWorktreeRegistryEntries(options) {
205
205
  };
206
206
  const kept = [];
207
207
  const removed = [];
208
+ const pendingWrites = [];
208
209
  for (const root of physicalRoots(options)) {
209
210
  const registry = readPhysicalRegistry(root);
210
211
  const rootRemoved = registry.entries.filter(shouldPrune);
211
212
  const rootKept = registry.entries.filter((entry) => !shouldPrune(entry));
212
213
  if (rootRemoved.length > 0)
213
- writePhysicalRegistry({ version: 1, entries: rootKept }, root);
214
+ pendingWrites.push({ root, entries: rootKept });
214
215
  kept.push(...rootKept);
215
216
  removed.push(...rootRemoved);
216
217
  }
217
- return { kept, removed, warnings: [...options.inventory.warnings] };
218
+ return {
219
+ kept,
220
+ removed,
221
+ warnings: [...options.inventory.warnings],
222
+ commit() {
223
+ for (const pendingWrite of pendingWrites) {
224
+ writePhysicalRegistry({ version: 1, entries: pendingWrite.entries }, pendingWrite.root);
225
+ }
226
+ },
227
+ };
228
+ }
229
+ export function pruneStaleWorktreeRegistryEntries(options) {
230
+ const plan = planStaleWorktreeRegistryPrune(options);
231
+ plan.commit();
232
+ return plan;
218
233
  }
219
234
  /**
220
235
  * LISTING-ONLY logical lookup by id. Identity-sensitive owner resolution must
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpresso/agent-kit",
3
- "version": "3.1.30",
3
+ "version": "3.3.0",
4
4
  "private": false,
5
5
  "description": "TypeScript-first agent harness for guarded develop/deploy workflows: wp CLI gates, MCP tools, hooks, memory, worktrees, secrets, audits, and evidence checks.",
6
6
  "keywords": [
@@ -142,6 +142,8 @@
142
142
  "#compiler/*": "./src/compiler/*.ts",
143
143
  "#review/*.js": "./src/review/*.ts",
144
144
  "#review/*": "./src/review/*.ts",
145
+ "#rust/*.js": "./src/rust/*.ts",
146
+ "#rust/*": "./src/rust/*.ts",
145
147
  "#telemetry/*.js": "./src/telemetry/*.ts",
146
148
  "#telemetry/*": "./src/telemetry/*.ts",
147
149
  "#codex/app-server/client": "./src/codex/app-server/client.ts",
@@ -365,7 +367,7 @@
365
367
  "version": "changeset version && vp run sync-marketplace-version && vp run generate-skills && ./bin/wp format",
366
368
  "release:publish": "bun scripts/release-publish.ts",
367
369
  "typecheck": "./bin/wp typecheck",
368
- "test": "vitest run",
370
+ "test": "bun scripts/run-vitest-projects.ts",
369
371
  "test:mutation": "bun stryker run stryker.config.ts",
370
372
  "eval": "bun src/runners/evals/index.ts",
371
373
  "bench:dash": "bun scripts/bench/wp-dash-menu.tsx",
@@ -392,6 +394,9 @@
392
394
  "audits:check": "./bin/wp audit guardrails && vp run workflow-actions:check && vp run hooks:doctor:ci && vp run check:blueprint-done-ledger",
393
395
  "hooks:doctor": "./bin/wp hooks doctor",
394
396
  "hooks:doctor:ci": "./bin/wp hooks doctor --skip-mcp && PATH=\"$PWD/bin:$PATH\" ./bin/wp hooks conformance --hosts codex,claude,opencode --lanes generated,repo,runtime,global,plugin --strict",
397
+ "proof:host-native": "bun scripts/host-native-proof.ts",
398
+ "proof:host-native:claude": "bun scripts/host-native-proof.ts --host claude",
399
+ "proof:host-native:grok": "bun scripts/host-native-proof.ts --host grok",
395
400
  "qa": "vp run build && bun scripts/run-parallel-checks.ts",
396
401
  "changeset": "changeset",
397
402
  "changeset:status": "GIT_WORK_TREE=$PWD changeset status",
@@ -502,16 +507,16 @@
502
507
  "setupWpActionRef": "c2c71a7a4be446fc6858e6b57bf55a11ccfa2d88"
503
508
  },
504
509
  "optionalDependencies": {
505
- "@webpresso/agent-kit-runtime-darwin-arm64": "3.1.30",
506
- "@webpresso/agent-kit-runtime-darwin-x64": "3.1.30",
507
- "@webpresso/agent-kit-runtime-linux-x64": "3.1.30",
508
- "@webpresso/agent-kit-runtime-linux-arm64": "3.1.30",
509
- "@webpresso/agent-kit-runtime-windows-x64": "3.1.30",
510
- "@webpresso/agent-kit-session-memory-darwin-x64": "3.1.30",
511
- "@webpresso/agent-kit-session-memory-darwin-arm64": "3.1.30",
512
- "@webpresso/agent-kit-session-memory-linux-x64": "3.1.30",
513
- "@webpresso/agent-kit-session-memory-linux-arm64": "3.1.30",
514
- "@webpresso/agent-kit-session-memory-win32-x64": "3.1.30",
515
- "@webpresso/agent-kit-session-memory-win32-arm64": "3.1.30"
510
+ "@webpresso/agent-kit-runtime-darwin-arm64": "3.3.0",
511
+ "@webpresso/agent-kit-runtime-darwin-x64": "3.3.0",
512
+ "@webpresso/agent-kit-runtime-linux-x64": "3.3.0",
513
+ "@webpresso/agent-kit-runtime-linux-arm64": "3.3.0",
514
+ "@webpresso/agent-kit-runtime-windows-x64": "3.3.0",
515
+ "@webpresso/agent-kit-session-memory-darwin-x64": "3.3.0",
516
+ "@webpresso/agent-kit-session-memory-darwin-arm64": "3.3.0",
517
+ "@webpresso/agent-kit-session-memory-linux-x64": "3.3.0",
518
+ "@webpresso/agent-kit-session-memory-linux-arm64": "3.3.0",
519
+ "@webpresso/agent-kit-session-memory-win32-x64": "3.3.0",
520
+ "@webpresso/agent-kit-session-memory-win32-arm64": "3.3.0"
516
521
  }
517
522
  }