openplanr 3.2.0 → 3.4.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 (411) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/dist/cli/commands/artifact-design-share.d.ts +9 -0
  3. package/dist/cli/commands/artifact-design-share.d.ts.map +1 -0
  4. package/dist/cli/commands/artifact-design-share.js +200 -0
  5. package/dist/cli/commands/artifact-design-share.js.map +1 -0
  6. package/dist/cli/commands/artifact.d.ts.map +1 -1
  7. package/dist/cli/commands/artifact.js +5 -18
  8. package/dist/cli/commands/artifact.js.map +1 -1
  9. package/dist/cli/commands/ship.d.ts.map +1 -1
  10. package/dist/cli/commands/ship.js +2 -0
  11. package/dist/cli/commands/ship.js.map +1 -1
  12. package/dist/cli/commands/spec.d.ts +2 -1
  13. package/dist/cli/commands/spec.d.ts.map +1 -1
  14. package/dist/cli/commands/spec.js +45 -5
  15. package/dist/cli/commands/spec.js.map +1 -1
  16. package/dist/dashboard/.vite/manifest.json +2 -2
  17. package/dist/dashboard/assets/index-Cv4Vwhuw.css +2 -0
  18. package/dist/dashboard/assets/index-CvQAlBy3.js +75 -0
  19. package/dist/dashboard/assets/index-CvQAlBy3.js.map +1 -0
  20. package/dist/dashboard/dashboard-manifest.json +14 -14
  21. package/dist/dashboard/index.html +2 -2
  22. package/dist/services/claude-plugin-service.d.ts +5 -0
  23. package/dist/services/claude-plugin-service.d.ts.map +1 -1
  24. package/dist/services/claude-plugin-service.js +18 -2
  25. package/dist/services/claude-plugin-service.js.map +1 -1
  26. package/dist/services/codex-plugin-service.d.ts.map +1 -1
  27. package/dist/services/codex-plugin-service.js +11 -3
  28. package/dist/services/codex-plugin-service.js.map +1 -1
  29. package/dist/services/design-artifact-service.d.ts +20 -1
  30. package/dist/services/design-artifact-service.d.ts.map +1 -1
  31. package/dist/services/design-artifact-service.js +137 -18
  32. package/dist/services/design-artifact-service.js.map +1 -1
  33. package/dist/services/runtime-manager/codex-discovery.d.ts +1 -3
  34. package/dist/services/runtime-manager/codex-discovery.d.ts.map +1 -1
  35. package/dist/services/runtime-manager/codex-discovery.js +3 -16
  36. package/dist/services/runtime-manager/codex-discovery.js.map +1 -1
  37. package/dist/services/runtime-manager/doctor.d.ts +25 -0
  38. package/dist/services/runtime-manager/doctor.d.ts.map +1 -1
  39. package/dist/services/runtime-manager/doctor.js +480 -0
  40. package/dist/services/runtime-manager/doctor.js.map +1 -1
  41. package/dist/services/runtime-manager/errors.d.ts +12 -0
  42. package/dist/services/runtime-manager/errors.d.ts.map +1 -0
  43. package/dist/services/runtime-manager/errors.js +14 -0
  44. package/dist/services/runtime-manager/errors.js.map +1 -0
  45. package/dist/services/runtime-manager/global-state.d.ts +7 -0
  46. package/dist/services/runtime-manager/global-state.d.ts.map +1 -1
  47. package/dist/services/runtime-manager/global-state.js +116 -0
  48. package/dist/services/runtime-manager/global-state.js.map +1 -1
  49. package/dist/services/runtime-manager/host-version-probe.d.ts +8 -0
  50. package/dist/services/runtime-manager/host-version-probe.d.ts.map +1 -0
  51. package/dist/services/runtime-manager/host-version-probe.js +14 -0
  52. package/dist/services/runtime-manager/host-version-probe.js.map +1 -0
  53. package/dist/services/runtime-manager/install-plan.d.ts +25 -0
  54. package/dist/services/runtime-manager/install-plan.d.ts.map +1 -1
  55. package/dist/services/runtime-manager/install-plan.js +305 -0
  56. package/dist/services/runtime-manager/install-plan.js.map +1 -1
  57. package/dist/services/runtime-manager/inventory.d.ts +6 -0
  58. package/dist/services/runtime-manager/inventory.d.ts.map +1 -1
  59. package/dist/services/runtime-manager/inventory.js +16 -1
  60. package/dist/services/runtime-manager/inventory.js.map +1 -1
  61. package/dist/services/runtime-manager/legacy-adapters.d.ts +9 -0
  62. package/dist/services/runtime-manager/legacy-adapters.d.ts.map +1 -0
  63. package/dist/services/runtime-manager/legacy-adapters.js +187 -0
  64. package/dist/services/runtime-manager/legacy-adapters.js.map +1 -0
  65. package/dist/services/runtime-manager/paths.d.ts +18 -0
  66. package/dist/services/runtime-manager/paths.d.ts.map +1 -0
  67. package/dist/services/runtime-manager/paths.js +83 -0
  68. package/dist/services/runtime-manager/paths.js.map +1 -0
  69. package/dist/services/runtime-manager/runtime-package.d.ts +21 -0
  70. package/dist/services/runtime-manager/runtime-package.d.ts.map +1 -1
  71. package/dist/services/runtime-manager/runtime-package.js +77 -0
  72. package/dist/services/runtime-manager/runtime-package.js.map +1 -1
  73. package/dist/services/runtime-manager/storage.d.ts +47 -0
  74. package/dist/services/runtime-manager/storage.d.ts.map +1 -0
  75. package/dist/services/runtime-manager/storage.js +604 -0
  76. package/dist/services/runtime-manager/storage.js.map +1 -0
  77. package/dist/services/runtime-manager-service.d.ts +7 -17
  78. package/dist/services/runtime-manager-service.d.ts.map +1 -1
  79. package/dist/services/runtime-manager-service.js +32 -1695
  80. package/dist/services/runtime-manager-service.js.map +1 -1
  81. package/dist/services/ship-checks/contract.d.ts +15 -1
  82. package/dist/services/ship-checks/contract.d.ts.map +1 -1
  83. package/dist/services/ship-checks/contract.js +1 -1
  84. package/dist/services/ship-checks/contract.js.map +1 -1
  85. package/dist/services/ship-checks/coverage.d.ts +4 -0
  86. package/dist/services/ship-checks/coverage.d.ts.map +1 -0
  87. package/dist/services/ship-checks/coverage.js +113 -0
  88. package/dist/services/ship-checks/coverage.js.map +1 -0
  89. package/dist/services/ship-checks/discover.d.ts.map +1 -1
  90. package/dist/services/ship-checks/discover.js +5 -1
  91. package/dist/services/ship-checks/discover.js.map +1 -1
  92. package/dist/services/ship-checks/package-contents.d.ts +4 -0
  93. package/dist/services/ship-checks/package-contents.d.ts.map +1 -0
  94. package/dist/services/ship-checks/package-contents.js +91 -0
  95. package/dist/services/ship-checks/package-contents.js.map +1 -0
  96. package/dist/services/ship-checks/packages.d.ts +2 -0
  97. package/dist/services/ship-checks/packages.d.ts.map +1 -1
  98. package/dist/services/ship-checks/packages.js +4 -0
  99. package/dist/services/ship-checks/packages.js.map +1 -1
  100. package/dist/services/ship-checks/scope.js +2 -1
  101. package/dist/services/ship-checks/scope.js.map +1 -1
  102. package/dist/services/spec-service.d.ts +18 -0
  103. package/dist/services/spec-service.d.ts.map +1 -1
  104. package/dist/services/spec-service.js +174 -9
  105. package/dist/services/spec-service.js.map +1 -1
  106. package/dist/templates/spec/spec-shaped.md.hbs +1 -1
  107. package/dist/templates/spec/spec.md.hbs +2 -2
  108. package/dist/utils/splice-managed-block.js +1 -1
  109. package/dist/utils/splice-managed-block.js.map +1 -1
  110. package/docs/CLI.md +86 -2
  111. package/lib/host-packages/adapter-registry.json +5 -5
  112. package/lib/host-packages/capability-map.json +3 -3
  113. package/lib/host-packages/claude/.claude-plugin/marketplace.json +3 -3
  114. package/lib/host-packages/claude/openplanr/.claude-plugin/plugin.json +6 -6
  115. package/lib/host-packages/claude/openplanr/.openplanr-content.json +94 -146
  116. package/lib/host-packages/claude/openplanr/README.md +12 -12
  117. package/lib/host-packages/claude/openplanr/agents/planr-qa.md +5 -3
  118. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/shared/task-context-resolution.md +4 -4
  119. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-artifact-shell.mjs +2 -4
  120. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-document.mjs +110 -25
  121. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-handoff.mjs +851 -57
  122. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-review-state-store.mjs +45 -0
  123. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-review.mjs +65 -74
  124. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-runtime-home.mjs +0 -1
  125. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-share-cli-bridge.mjs +321 -0
  126. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-d707e49b.mjs +1652 -0
  127. package/lib/host-packages/{openai/openplanr/runtime/design/scripts/design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs → claude/openplanr/runtime/design/scripts/design-shared-artifact-support-protocol-contracts-9f6918b0.mjs} +537 -5
  128. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-design-support-0bac378d.mjs +137 -0
  129. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design.mjs +374 -61
  130. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +32 -59
  131. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/02-artifact-review-ui.js +138 -133
  132. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +1 -5608
  133. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-artifact-review-ui.js +2568 -0
  134. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +10 -74
  135. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  136. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/share.js +8 -2
  137. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +2 -2
  138. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +5 -5
  139. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-protocol-contracts.js +72 -2
  140. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-design-review-experience.js +14 -7
  141. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-canvas-engine.js +71 -34
  142. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/21-design-studio.js +28 -14
  143. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +12 -12
  144. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +6 -2
  145. package/lib/host-packages/{openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.20.0 → claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0}/design-document.schema.json +131 -4
  146. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0/design-review-bundle.schema.json +822 -0
  147. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +616 -4775
  148. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/design.mjs +219 -424
  149. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +6 -2
  150. package/lib/host-packages/claude/openplanr/skills/delegate/SKILL.md +2 -1
  151. package/lib/host-packages/claude/openplanr/skills/delegate/references/integration-review.md +26 -20
  152. package/lib/host-packages/claude/openplanr/skills/delegate/references/operator-guide.md +25 -1
  153. package/lib/host-packages/claude/openplanr/skills/delegate/references/run-handoff.md +2 -2
  154. package/lib/host-packages/claude/openplanr/skills/delegate/references/worktree-custody.md +17 -9
  155. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/adapters/claude.mjs +15 -3
  156. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/adapters/codex.mjs +38 -2
  157. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/adapters/native.mjs +5 -0
  158. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/custody.mjs +217 -10
  159. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/handoff.mjs +1080 -0
  160. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/integrate.mjs +96 -201
  161. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/integration-files.mjs +3 -382
  162. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/presentation.mjs +29 -12
  163. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-contract.mjs +11 -0
  164. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-execution.mjs +1 -1
  165. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-lifecycle.mjs +14 -10
  166. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-preparation.mjs +4 -0
  167. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-record.mjs +2 -2
  168. package/lib/host-packages/claude/openplanr/skills/design/references/design-system.md +17 -2
  169. package/lib/host-packages/claude/openplanr/skills/design/references/generation.md +60 -2
  170. package/lib/host-packages/claude/openplanr/skills/design/references/utilities.md +23 -7
  171. package/lib/host-packages/claude/openplanr/skills/design/schemas/design-document.schema.json +131 -4
  172. package/lib/host-packages/claude/openplanr/skills/design-loop/references/design-system.md +17 -2
  173. package/lib/host-packages/claude/openplanr/skills/design-loop/references/generation.md +60 -2
  174. package/lib/host-packages/claude/openplanr/skills/design-loop/references/utilities.md +23 -7
  175. package/lib/host-packages/claude/openplanr/skills/design-loop/schemas/design-document.schema.json +131 -4
  176. package/lib/host-packages/claude/openplanr/skills/design-review/references/design-system.md +17 -2
  177. package/lib/host-packages/claude/openplanr/skills/design-review/references/generation.md +60 -2
  178. package/lib/host-packages/claude/openplanr/skills/design-review/references/utilities.md +23 -7
  179. package/lib/host-packages/claude/openplanr/skills/design-review/schemas/design-document.schema.json +131 -4
  180. package/lib/host-packages/claude/openplanr/skills/investigate/SKILL.md +2 -1
  181. package/lib/host-packages/claude/openplanr/skills/investigate/references/fail-first.md +40 -0
  182. package/lib/host-packages/claude/openplanr/skills/plan/SKILL.md +21 -11
  183. package/lib/host-packages/claude/openplanr/skills/plan/schemas/design-document.schema.json +131 -4
  184. package/lib/host-packages/claude/openplanr/skills/ship/SKILL.md +51 -18
  185. package/lib/host-packages/claude/openplanr/skills/ship/references/fail-first.md +40 -0
  186. package/lib/host-packages/claude/openplanr/skills/ship/references/result-contract.md +7 -3
  187. package/lib/host-packages/claude/openplanr/skills/spec/SKILL.md +6 -0
  188. package/lib/host-packages/claude/openplanr/skills/spec/references/specification-contract.md +3 -1
  189. package/lib/host-packages/cursor/openplanr/.openplanr-content.json +91 -143
  190. package/lib/host-packages/cursor/openplanr/manifest.json +1 -1
  191. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/references/integration-review.md +26 -20
  192. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/references/operator-guide.md +25 -1
  193. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/references/run-handoff.md +2 -2
  194. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/references/worktree-custody.md +17 -9
  195. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/adapters/claude.mjs +15 -3
  196. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/adapters/codex.mjs +38 -2
  197. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/adapters/native.mjs +5 -0
  198. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/custody.mjs +217 -10
  199. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/handoff.mjs +1080 -0
  200. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/integrate.mjs +96 -201
  201. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/integration-files.mjs +3 -382
  202. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/presentation.mjs +29 -12
  203. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-contract.mjs +11 -0
  204. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-execution.mjs +1 -1
  205. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-lifecycle.mjs +14 -10
  206. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-preparation.mjs +4 -0
  207. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-record.mjs +2 -2
  208. package/lib/host-packages/cursor/openplanr/rules/planr-delegate.mdc +2 -1
  209. package/lib/host-packages/cursor/openplanr/rules/planr-design/references/design-system.md +17 -2
  210. package/lib/host-packages/cursor/openplanr/rules/planr-design/references/generation.md +60 -2
  211. package/lib/host-packages/cursor/openplanr/rules/planr-design/references/utilities.md +23 -7
  212. package/lib/host-packages/cursor/openplanr/rules/planr-design/schemas/design-document.schema.json +131 -4
  213. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/design-system.md +17 -2
  214. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/generation.md +60 -2
  215. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/utilities.md +23 -7
  216. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/schemas/design-document.schema.json +131 -4
  217. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/design-system.md +17 -2
  218. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/generation.md +60 -2
  219. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/utilities.md +23 -7
  220. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/schemas/design-document.schema.json +131 -4
  221. package/lib/host-packages/cursor/openplanr/rules/planr-investigate/references/fail-first.md +40 -0
  222. package/lib/host-packages/cursor/openplanr/rules/planr-investigate.mdc +2 -1
  223. package/lib/host-packages/cursor/openplanr/rules/planr-plan/schemas/design-document.schema.json +131 -4
  224. package/lib/host-packages/cursor/openplanr/rules/planr-plan.mdc +21 -11
  225. package/lib/host-packages/cursor/openplanr/rules/planr-ship/references/fail-first.md +40 -0
  226. package/lib/host-packages/cursor/openplanr/rules/planr-ship/references/result-contract.md +7 -3
  227. package/lib/host-packages/cursor/openplanr/rules/planr-ship.mdc +51 -18
  228. package/lib/host-packages/cursor/openplanr/rules/planr-spec/references/specification-contract.md +3 -1
  229. package/lib/host-packages/cursor/openplanr/rules/planr-spec.mdc +6 -0
  230. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-artifact-shell.mjs +2 -4
  231. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-document.mjs +110 -25
  232. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-handoff.mjs +851 -57
  233. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-review-state-store.mjs +45 -0
  234. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-review.mjs +65 -74
  235. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-runtime-home.mjs +0 -1
  236. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-share-cli-bridge.mjs +321 -0
  237. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-d707e49b.mjs +1652 -0
  238. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/{design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs → design-shared-artifact-support-protocol-contracts-9f6918b0.mjs} +537 -5
  239. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-design-support-0bac378d.mjs +137 -0
  240. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design.mjs +374 -61
  241. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +32 -59
  242. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/02-artifact-review-ui.js +138 -133
  243. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +1 -5608
  244. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-artifact-review-ui.js +2568 -0
  245. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +10 -74
  246. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  247. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/share.js +8 -2
  248. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +2 -2
  249. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +5 -5
  250. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-protocol-contracts.js +72 -2
  251. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-design-review-experience.js +14 -7
  252. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-canvas-engine.js +71 -34
  253. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/21-design-studio.js +28 -14
  254. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +12 -12
  255. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +6 -2
  256. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/{v1.20.0 → v1.22.0}/design-document.schema.json +131 -4
  257. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0/design-review-bundle.schema.json +822 -0
  258. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +616 -4775
  259. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/design.mjs +219 -424
  260. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +6 -2
  261. package/lib/host-packages/openai/.claude-plugin/marketplace.json +3 -3
  262. package/lib/host-packages/openai/openplanr/.codex-plugin/plugin.json +2 -2
  263. package/lib/host-packages/openai/openplanr/.openplanr-content.json +98 -150
  264. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-artifact-shell.mjs +2 -4
  265. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-document.mjs +110 -25
  266. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-handoff.mjs +851 -57
  267. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-review-state-store.mjs +45 -0
  268. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-review.mjs +65 -74
  269. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-runtime-home.mjs +0 -1
  270. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-share-cli-bridge.mjs +321 -0
  271. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-d707e49b.mjs +1652 -0
  272. package/lib/host-packages/{claude/openplanr/runtime/design/scripts/design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs → openai/openplanr/runtime/design/scripts/design-shared-artifact-support-protocol-contracts-9f6918b0.mjs} +537 -5
  273. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-design-support-0bac378d.mjs +137 -0
  274. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design.mjs +374 -61
  275. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +32 -59
  276. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/02-artifact-review-ui.js +138 -133
  277. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +1 -5608
  278. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-artifact-review-ui.js +2568 -0
  279. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +10 -74
  280. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  281. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/share.js +8 -2
  282. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +2 -2
  283. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +5 -5
  284. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-protocol-contracts.js +72 -2
  285. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-design-review-experience.js +14 -7
  286. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-canvas-engine.js +71 -34
  287. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/21-design-studio.js +28 -14
  288. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +12 -12
  289. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +6 -2
  290. package/lib/host-packages/{claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.20.0 → openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0}/design-document.schema.json +131 -4
  291. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0/design-review-bundle.schema.json +822 -0
  292. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +616 -4775
  293. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/design.mjs +219 -424
  294. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +6 -2
  295. package/lib/host-packages/openai/openplanr/skills/delegate/SKILL.md +2 -1
  296. package/lib/host-packages/openai/openplanr/skills/delegate/openplanr.skill.json +1 -1
  297. package/lib/host-packages/openai/openplanr/skills/delegate/references/integration-review.md +26 -20
  298. package/lib/host-packages/openai/openplanr/skills/delegate/references/operator-guide.md +25 -1
  299. package/lib/host-packages/openai/openplanr/skills/delegate/references/run-handoff.md +2 -2
  300. package/lib/host-packages/openai/openplanr/skills/delegate/references/worktree-custody.md +17 -9
  301. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/adapters/claude.mjs +15 -3
  302. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/adapters/codex.mjs +38 -2
  303. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/adapters/native.mjs +5 -0
  304. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/custody.mjs +217 -10
  305. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/handoff.mjs +1080 -0
  306. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/integrate.mjs +96 -201
  307. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/integration-files.mjs +3 -382
  308. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/presentation.mjs +29 -12
  309. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-contract.mjs +11 -0
  310. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-execution.mjs +1 -1
  311. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-lifecycle.mjs +14 -10
  312. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-preparation.mjs +4 -0
  313. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-record.mjs +2 -2
  314. package/lib/host-packages/openai/openplanr/skills/design/references/design-system.md +17 -2
  315. package/lib/host-packages/openai/openplanr/skills/design/references/generation.md +60 -2
  316. package/lib/host-packages/openai/openplanr/skills/design/references/utilities.md +23 -7
  317. package/lib/host-packages/openai/openplanr/skills/design/schemas/design-document.schema.json +131 -4
  318. package/lib/host-packages/openai/openplanr/skills/design-loop/references/design-system.md +17 -2
  319. package/lib/host-packages/openai/openplanr/skills/design-loop/references/generation.md +60 -2
  320. package/lib/host-packages/openai/openplanr/skills/design-loop/references/utilities.md +23 -7
  321. package/lib/host-packages/openai/openplanr/skills/design-loop/schemas/design-document.schema.json +131 -4
  322. package/lib/host-packages/openai/openplanr/skills/design-review/references/design-system.md +17 -2
  323. package/lib/host-packages/openai/openplanr/skills/design-review/references/generation.md +60 -2
  324. package/lib/host-packages/openai/openplanr/skills/design-review/references/utilities.md +23 -7
  325. package/lib/host-packages/openai/openplanr/skills/design-review/schemas/design-document.schema.json +131 -4
  326. package/lib/host-packages/openai/openplanr/skills/investigate/SKILL.md +2 -1
  327. package/lib/host-packages/openai/openplanr/skills/investigate/agents/openai.yaml +1 -1
  328. package/lib/host-packages/openai/openplanr/skills/investigate/openplanr.skill.json +12 -1
  329. package/lib/host-packages/openai/openplanr/skills/investigate/references/fail-first.md +40 -0
  330. package/lib/host-packages/openai/openplanr/skills/plan/SKILL.md +21 -11
  331. package/lib/host-packages/openai/openplanr/skills/plan/openplanr.skill.json +1 -1
  332. package/lib/host-packages/openai/openplanr/skills/plan/schemas/design-document.schema.json +131 -4
  333. package/lib/host-packages/openai/openplanr/skills/ship/SKILL.md +51 -18
  334. package/lib/host-packages/openai/openplanr/skills/ship/agents/openai.yaml +1 -1
  335. package/lib/host-packages/openai/openplanr/skills/ship/openplanr.skill.json +12 -1
  336. package/lib/host-packages/openai/openplanr/skills/ship/references/fail-first.md +40 -0
  337. package/lib/host-packages/openai/openplanr/skills/ship/references/result-contract.md +7 -3
  338. package/lib/host-packages/openai/openplanr/skills/spec/SKILL.md +6 -0
  339. package/lib/host-packages/openai/openplanr/skills/spec/openplanr.skill.json +1 -1
  340. package/lib/host-packages/openai/openplanr/skills/spec/references/specification-contract.md +3 -1
  341. package/lib/json-schema.mjs +4 -0
  342. package/package.json +16 -16
  343. package/dist/dashboard/assets/index-BU5fzjyz.css +0 -1
  344. package/dist/dashboard/assets/index-L8qtwqv6.js +0 -572
  345. package/dist/dashboard/assets/index-L8qtwqv6.js.map +0 -1
  346. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +0 -555
  347. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-compression.mjs +0 -4180
  348. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-encrypted-workspace-client.mjs +0 -647
  349. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-owner-custody.mjs +0 -129
  350. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-resource-pack.mjs +0 -698
  351. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-runtime-support-6774fd3d5d02.mjs +0 -24
  352. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-share.mjs +0 -1993
  353. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs +0 -1020
  354. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-protocol-contracts-75a938cc.mjs +0 -222
  355. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-protocol-contracts-b5f28f94.mjs +0 -5778
  356. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-upload-spool.mjs +0 -198
  357. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-compression.js +0 -4175
  358. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/05-artifact-sharing.js +0 -65
  359. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/06-artifact-review-ui.js +0 -1755
  360. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/07-artifact-sharing.js +0 -62
  361. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/08-artifact-review-ui.js +0 -2633
  362. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +0 -49
  363. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +0 -108
  364. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +0 -170
  365. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +0 -97
  366. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +0 -56
  367. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/integration-transaction.mjs +0 -958
  368. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/integration-transaction.mjs +0 -958
  369. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +0 -555
  370. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-compression.mjs +0 -4180
  371. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-encrypted-workspace-client.mjs +0 -647
  372. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-owner-custody.mjs +0 -129
  373. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-resource-pack.mjs +0 -698
  374. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-runtime-support-6774fd3d5d02.mjs +0 -24
  375. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-share.mjs +0 -1993
  376. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs +0 -1020
  377. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-protocol-contracts-75a938cc.mjs +0 -222
  378. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-protocol-contracts-b5f28f94.mjs +0 -5778
  379. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-upload-spool.mjs +0 -198
  380. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-compression.js +0 -4175
  381. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/05-artifact-sharing.js +0 -65
  382. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/06-artifact-review-ui.js +0 -1755
  383. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/07-artifact-sharing.js +0 -62
  384. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/08-artifact-review-ui.js +0 -2633
  385. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +0 -49
  386. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +0 -108
  387. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +0 -170
  388. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +0 -97
  389. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +0 -56
  390. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +0 -555
  391. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-compression.mjs +0 -4180
  392. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-encrypted-workspace-client.mjs +0 -647
  393. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-owner-custody.mjs +0 -129
  394. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-resource-pack.mjs +0 -698
  395. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-runtime-support-6774fd3d5d02.mjs +0 -24
  396. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-share.mjs +0 -1993
  397. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs +0 -1020
  398. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-protocol-contracts-75a938cc.mjs +0 -222
  399. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-protocol-contracts-b5f28f94.mjs +0 -5778
  400. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-upload-spool.mjs +0 -198
  401. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-compression.js +0 -4175
  402. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/05-artifact-sharing.js +0 -65
  403. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/06-artifact-review-ui.js +0 -1755
  404. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/07-artifact-sharing.js +0 -62
  405. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/08-artifact-review-ui.js +0 -2633
  406. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +0 -49
  407. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +0 -108
  408. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +0 -170
  409. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +0 -97
  410. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +0 -56
  411. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/integration-transaction.mjs +0 -958
@@ -1,958 +0,0 @@
1
- import { execFile as execFileCallback } from 'node:child_process';
2
- import { createHash, randomUUID } from 'node:crypto';
3
- import {
4
- chmod,
5
- cp,
6
- mkdir,
7
- mkdtemp,
8
- readdir,
9
- readFile,
10
- readlink,
11
- rm,
12
- rmdir,
13
- writeFile,
14
- } from 'node:fs/promises';
15
- import { tmpdir } from 'node:os';
16
- import { dirname, join, resolve, sep } from 'node:path';
17
- import { promisify } from 'node:util';
18
- import {
19
- captureFileState,
20
- gitFileState,
21
- headFileState,
22
- sameGitState,
23
- validateWorktreeCustody,
24
- } from './custody.mjs';
25
- import {
26
- executionEnvironment,
27
- resolveSelectedChecks,
28
- resolveSelectedGenerators,
29
- runDelegateChecks,
30
- runGenerator,
31
- } from './integration-checks.mjs';
32
- import {
33
- assertSafeChanges,
34
- changedSinceSnapshot,
35
- covers,
36
- git,
37
- IntegrationError,
38
- putState,
39
- putStateGuarded,
40
- rollbackWritten,
41
- safePath,
42
- sameState,
43
- treeIdentity,
44
- workingSnapshot,
45
- } from './integration-files.mjs';
46
- import {
47
- acquireRunTransitionLock,
48
- compactIntegrationState,
49
- processIdentity,
50
- processIdentityState,
51
- } from './run-record.mjs';
52
-
53
- const execFile = promisify(execFileCallback);
54
-
55
- async function candidatePaths(custody) {
56
- const diff = await git(custody.worktreePath, 'diff', '--name-only', '-z', custody.initialHead);
57
- const untracked = await git(
58
- custody.worktreePath,
59
- 'ls-files',
60
- '--others',
61
- '--exclude-standard',
62
- '-z',
63
- );
64
- return [
65
- ...new Set(
66
- [
67
- ...diff.toString('utf8').split('\0'),
68
- ...untracked.toString('utf8').split('\0'),
69
- ...Object.keys(custody.startingFiles ?? {}),
70
- ]
71
- .filter(Boolean)
72
- .map(safePath),
73
- ),
74
- ].sort();
75
- }
76
-
77
- function completed(run) {
78
- return run?.status === 'completed' || run?.state === 'completed';
79
- }
80
-
81
- export async function reviewDelegateDelta({
82
- custody,
83
- run,
84
- scopePaths = [],
85
- preservePaths = [],
86
- } = {}) {
87
- if (!custody?.repositoryRoot || !custody?.worktreePath)
88
- throw new IntegrationError('E_INTEGRATION_RECORD', 'A custody record is required.');
89
- if (!completed(run))
90
- throw new IntegrationError(
91
- 'E_INTEGRATION_RUN',
92
- 'Only a completed delegate run can be reviewed.',
93
- );
94
- if (!Array.isArray(scopePaths) || scopePaths.length === 0)
95
- throw new IntegrationError(
96
- 'E_INTEGRATION_SCOPE',
97
- 'Explicit writable scope paths are required.',
98
- );
99
- const allowed = scopePaths.map(safePath);
100
- const protectedPaths = [...(custody.preservePaths ?? []), ...preservePaths].map((entry) =>
101
- safePath(typeof entry === 'string' ? entry : entry.path),
102
- );
103
- const custodyCheck = await validateWorktreeCustody(custody, {
104
- native: Boolean(run.nativeSelection),
105
- });
106
- const violations = [
107
- ...(custodyCheck.violations ?? []).map((violation) =>
108
- typeof violation === 'string'
109
- ? { code: 'E_INTEGRATION_CUSTODY', message: violation }
110
- : violation,
111
- ),
112
- ];
113
- const changes = [];
114
- for (const path of await candidatePaths(custody)) {
115
- const before =
116
- (!run.nativeSelection ? custody.setupFiles?.[path] : null) ??
117
- custody.startingFiles?.[path] ??
118
- (await headFileState(custody.worktreePath, path, custody.initialHead));
119
- let after;
120
- try {
121
- after = await captureFileState(custody.worktreePath, path);
122
- } catch (error) {
123
- violations.push({
124
- code: 'E_INTEGRATION_UNSAFE_WORKTREE_PATH',
125
- path,
126
- reason: error.code ?? 'unreadable',
127
- });
128
- continue;
129
- }
130
- if (
131
- sameGitState(
132
- await gitFileState(custody.worktreePath, path, before),
133
- await gitFileState(custody.worktreePath, path, after),
134
- )
135
- )
136
- continue;
137
- if (!allowed.some((rule) => covers(rule, path)))
138
- violations.push({ code: 'E_INTEGRATION_SCOPE', path });
139
- if (protectedPaths.some((rule) => covers(rule, path)))
140
- violations.push({ code: 'E_INTEGRATION_PRESERVE', path });
141
- const sourceBefore =
142
- custody.sourceFiles?.[path] ??
143
- (await headFileState(custody.repositoryRoot, path, custody.initialHead));
144
- let sourceNow;
145
- try {
146
- sourceNow = await captureFileState(custody.repositoryRoot, path);
147
- } catch (error) {
148
- violations.push({
149
- code: 'E_INTEGRATION_UNSAFE_SOURCE_PATH',
150
- path,
151
- reason: error.code ?? 'unreadable',
152
- });
153
- continue;
154
- }
155
- if (
156
- !sameGitState(
157
- await gitFileState(custody.repositoryRoot, path, sourceBefore),
158
- await gitFileState(custody.repositoryRoot, path, sourceNow),
159
- )
160
- )
161
- violations.push({ code: 'E_INTEGRATION_SOURCE_DRIFT', path });
162
- changes.push({
163
- path,
164
- before,
165
- after,
166
- sourceBefore: sourceNow,
167
- origin: run.verificationMutations?.includes(path)
168
- ? 'parent-verification'
169
- : run.preparationProvenance?.paths?.includes(path)
170
- ? 'preparation-and-delegate'
171
- : 'delegate',
172
- });
173
- }
174
- return {
175
- ready: violations.length === 0,
176
- changedPaths: changes.map(({ path }) => path),
177
- changes,
178
- violations,
179
- patch: changes.map(({ path, before, after }) => ({ path, before, after })),
180
- };
181
- }
182
-
183
- export function patchDigest(review) {
184
- return createHash('sha256').update(JSON.stringify(review.patch)).digest('hex');
185
- }
186
-
187
- async function createScratch(source) {
188
- const base = await mkdtemp(join(tmpdir(), 'planr-integration-'));
189
- await chmod(base, 0o700);
190
- const root = join(base, 'checkout');
191
- const home = join(base, 'home');
192
- await mkdir(root, { mode: 0o700 });
193
- await mkdir(home, { mode: 0o700 });
194
- try {
195
- const paths = (
196
- await git(source, 'ls-files', '-z', '--cached', '--others', '--exclude-standard')
197
- )
198
- .toString('utf8')
199
- .split('\0')
200
- .filter(Boolean);
201
- for (const path of new Set(paths)) {
202
- const state = await captureFileState(source, safePath(path));
203
- await putState(root, path, state, randomUUID());
204
- }
205
- const env = executionEnvironment(home);
206
- await execFile('git', ['init', '-q'], { cwd: root, env });
207
- await execFile('git', ['-c', 'core.hooksPath=/dev/null', 'add', '--all'], { cwd: root, env });
208
- await execFile(
209
- 'git',
210
- [
211
- '-c',
212
- 'user.name=OpenPlanr',
213
- '-c',
214
- 'user.email=delegate@localhost',
215
- '-c',
216
- 'core.hooksPath=/dev/null',
217
- 'commit',
218
- '-qm',
219
- 'Integration baseline',
220
- '--allow-empty',
221
- ],
222
- { cwd: root, env },
223
- );
224
- // npm workspaces may keep tools in package-local node_modules as well as the root.
225
- const dependencyRoots = new Set([
226
- '.',
227
- ...paths.filter((path) => path.endsWith('/package.json')).map(dirname),
228
- ]);
229
- for (const directory of dependencyRoots) {
230
- // Dependencies are copied, never symlinked back to the owner's checkout.
231
- try {
232
- await cp(join(source, directory, 'node_modules'), join(root, directory, 'node_modules'), {
233
- recursive: true,
234
- verbatimSymlinks: true,
235
- });
236
- } catch (error) {
237
- if (error.code !== 'ENOENT') throw error;
238
- }
239
- }
240
- // A copied dependency must not point back into the owner checkout or elsewhere.
241
- async function checkLinks(directory) {
242
- let entries;
243
- try {
244
- entries = await readdir(directory, { withFileTypes: true });
245
- } catch (error) {
246
- if (error.code === 'ENOENT') return;
247
- throw error;
248
- }
249
- for (const entry of entries) {
250
- const path = join(directory, entry.name);
251
- if (entry.isSymbolicLink()) {
252
- const target = resolve(directory, await readlink(path));
253
- if (!target.startsWith(`${root}${sep}`))
254
- throw new IntegrationError(
255
- 'E_INTEGRATION_DEPENDENCY_LINK',
256
- 'Copied dependencies contain a link outside scratch.',
257
- );
258
- } else if (entry.isDirectory()) await checkLinks(path);
259
- }
260
- }
261
- for (const directory of dependencyRoots)
262
- await checkLinks(join(root, directory, 'node_modules'));
263
- return { base, root, home };
264
- } catch (error) {
265
- await rm(base, { recursive: true, force: true });
266
- throw error;
267
- }
268
- }
269
-
270
- async function integrationCandidate(custody, review) {
271
- const sourceIdentity = await treeIdentity(custody.repositoryRoot);
272
- const projectedSource = await treeIdentity(
273
- custody.repositoryRoot,
274
- new Map(review.changes.map((change) => [change.path, change.after])),
275
- );
276
- if (projectedSource === (await treeIdentity(custody.worktreePath)))
277
- return {
278
- root: custody.worktreePath,
279
- base: null,
280
- sourceIdentity,
281
- identity: projectedSource,
282
- kind: 'prepared-worktree',
283
- };
284
- // Owner edits elsewhere make the prepared worktree stale. Copy only in this case.
285
- const candidate = await createScratch(custody.worktreePath);
286
- // Preserve the prepared build/cache outputs as well as installed dependencies.
287
- await cp(custody.worktreePath, candidate.root, {
288
- recursive: true,
289
- verbatimSymlinks: true,
290
- filter: (path) => path !== join(custody.worktreePath, '.git'),
291
- });
292
- const sourcePaths = (
293
- await git(
294
- custody.repositoryRoot,
295
- 'ls-files',
296
- '-z',
297
- '--cached',
298
- '--others',
299
- '--exclude-standard',
300
- )
301
- )
302
- .toString('utf8')
303
- .split('\0')
304
- .filter(Boolean);
305
- const candidatePaths = (
306
- await git(candidate.root, 'ls-files', '-z', '--cached', '--others', '--exclude-standard')
307
- )
308
- .toString('utf8')
309
- .split('\0')
310
- .filter(Boolean);
311
- for (const path of new Set([...sourcePaths, ...candidatePaths]))
312
- await putState(
313
- candidate.root,
314
- safePath(path),
315
- await captureFileState(custody.repositoryRoot, path),
316
- randomUUID(),
317
- );
318
- for (const change of review.changes)
319
- await putState(candidate.root, change.path, change.after, randomUUID());
320
- return {
321
- ...candidate,
322
- sourceIdentity,
323
- identity: await treeIdentity(candidate.root),
324
- kind: 'fresh-candidate',
325
- };
326
- }
327
-
328
- export async function checkoutLock(root) {
329
- const path = join(
330
- tmpdir(),
331
- `planr-integration-lock-${createHash('sha256').update(root).digest('hex')}`,
332
- );
333
- // Serialize stale recovery with the same crash-safe acquisition used by runs.
334
- // Keep the checkout owner file so retained helpers still observe an active apply.
335
- const transitions = `${path}-transitions`;
336
- await mkdir(join(transitions, 'checkout'), { recursive: true, mode: 0o700 });
337
- let releaseTransition;
338
- try {
339
- releaseTransition = await acquireRunTransitionLock('checkout', { directory: transitions });
340
- } catch (error) {
341
- if (error.code === 'E_RUN_LOCKED')
342
- throw new IntegrationError(
343
- 'E_INTEGRATION_LOCKED',
344
- 'Another integration holds this checkout.',
345
- );
346
- throw error;
347
- }
348
- const token = randomUUID();
349
- try {
350
- try {
351
- await mkdir(path, { mode: 0o700 });
352
- } catch (error) {
353
- if (error.code !== 'EEXIST') throw error;
354
- const owner = JSON.parse(await readFile(join(path, 'owner.json'), 'utf8'));
355
- if (!['exited', 'reused'].includes(await processIdentityState(owner)))
356
- throw new IntegrationError(
357
- 'E_INTEGRATION_LOCKED',
358
- 'Another integration holds this checkout.',
359
- );
360
- await rm(path, { recursive: true });
361
- await mkdir(path, { mode: 0o700 });
362
- }
363
- await writeFile(
364
- join(path, 'owner.json'),
365
- JSON.stringify({ ...(await processIdentity()), token }),
366
- {
367
- flag: 'wx',
368
- mode: 0o600,
369
- },
370
- );
371
- } catch (error) {
372
- await releaseTransition();
373
- throw error;
374
- }
375
- return async () => {
376
- try {
377
- const owner = JSON.parse(await readFile(join(path, 'owner.json'), 'utf8'));
378
- if (owner.token !== token)
379
- throw new IntegrationError('E_INTEGRATION_LOCKED', 'Checkout lock ownership changed.');
380
- await rm(path, { recursive: true });
381
- } finally {
382
- await releaseTransition();
383
- }
384
- };
385
- }
386
-
387
- async function generateCandidate({
388
- scratch,
389
- generators,
390
- custody,
391
- review,
392
- timeoutMs,
393
- signal,
394
- phase,
395
- generatorRuns,
396
- generatedPaths,
397
- retainMutation,
398
- onProcess,
399
- }) {
400
- for (const generator of generators) {
401
- const result = await phase('generation', () =>
402
- runGenerator(
403
- scratch.root,
404
- { ...generator, home: scratch.home, signal, onProcess },
405
- timeoutMs,
406
- ),
407
- );
408
- generatorRuns.push({
409
- packagePath: generator.packagePath,
410
- script: generator.script,
411
- ...result.result,
412
- });
413
- if (result.result.processTerminationConfirmed === false)
414
- throw new IntegrationError(
415
- 'E_INTEGRATION_PROCESS',
416
- 'An owned generator process could not be stopped. Recover it before inspecting or accepting the candidate.',
417
- );
418
- await retainMutation?.(scratch, result.changes);
419
- if (!result.passed)
420
- throw new IntegrationError('E_INTEGRATION_GENERATION', 'A declared generator failed.', {
421
- results: [result.result],
422
- });
423
- const unexpected = result.changes.filter(({ path }) => !generator.outputPaths.includes(path));
424
- if (unexpected.length) {
425
- review.violations.push(
426
- ...unexpected.map(({ path }) => ({ code: 'E_INTEGRATION_GENERATOR_SCOPE', path })),
427
- );
428
- throw new IntegrationError(
429
- 'E_INTEGRATION_GENERATOR_SCOPE',
430
- 'Generator changed undeclared files.',
431
- );
432
- }
433
- for (const change of result.changes) {
434
- const sourceBefore = await captureFileState(custody.repositoryRoot, change.path);
435
- generatedPaths.push(change.path);
436
- review.changedPaths.push(change.path);
437
- review.changes.push({ ...change, sourceBefore, origin: 'generator' });
438
- review.patch.push(change);
439
- }
440
- }
441
- }
442
-
443
- async function compareWithBaseline(
444
- results,
445
- selectedChecks,
446
- target,
447
- { phase, timeoutMs, signal, onProcess },
448
- ) {
449
- const beforeBaseline = await workingSnapshot(target.root);
450
- const failing = selectedChecks.filter((_check, index) => results[index]?.status === 'failed');
451
- const baseline = await phase('baseline-checks', () =>
452
- runDelegateChecks({
453
- repositoryRoot: target.root,
454
- checks: failing,
455
- onProcess,
456
- timeoutMs,
457
- home: target.home,
458
- signal: signal,
459
- }),
460
- );
461
- const effects = await changedSinceSnapshot(target.root, beforeBaseline);
462
- let index = 0;
463
- const compared = results.map((result) => {
464
- if (result.status !== 'failed') return result;
465
- const evidence = baseline[index++];
466
- const baselineStatus = effects.length ? 'unverified' : evidence.status;
467
- return {
468
- ...result,
469
- baselineStatus,
470
- baseline: evidence,
471
- classification:
472
- baselineStatus === 'failed'
473
- ? 'baseline-failure'
474
- : baselineStatus === 'passed'
475
- ? 'regression'
476
- : 'unverified',
477
- };
478
- });
479
- return { results: compared, effects };
480
- }
481
-
482
- async function validateSourceChanges(root, changes) {
483
- for (const change of changes) {
484
- if (!sameState(await captureFileState(root, change.path), change.sourceBefore))
485
- throw new IntegrationError(
486
- 'E_INTEGRATION_SOURCE_DRIFT',
487
- 'A destination changed while checks ran.',
488
- { path: change.path },
489
- );
490
- // Keep physical non-executable permissions; only the Git executable bit belongs to the delta.
491
- if (change.after.kind === 'file' && change.sourceBefore.kind === 'file') {
492
- change.after = {
493
- ...change.after,
494
- mode: (change.sourceBefore.mode & ~0o111) | (change.after.mode & 0o111),
495
- };
496
- }
497
- }
498
- }
499
-
500
- async function writeChanges({ root, changes, signal, onProgress, applied, createdDirectories }) {
501
- for (const change of changes) {
502
- if (signal.aborted)
503
- throw new IntegrationError('E_INTEGRATION_INTERRUPTED', 'Integration was interrupted.');
504
- // The journal records all intended states before this first write, including crash recovery.
505
- await onProgress?.(change.path, 'before');
506
- await putStateGuarded(
507
- root,
508
- change.path,
509
- change.after,
510
- change.sourceBefore,
511
- change.writeId,
512
- createdDirectories,
513
- );
514
- applied.push(change);
515
- await onProgress?.(change.path, 'after');
516
- }
517
- }
518
-
519
- export async function integrateDelegateDelta({
520
- custody,
521
- run,
522
- scopePaths,
523
- preservePaths,
524
- capsule,
525
- checks,
526
- preparation,
527
- generators,
528
- timeoutMs,
529
- reviewedDigest,
530
- baselineComparison = false,
531
- reviewOnlyReason,
532
- onVerification,
533
- beforeApply,
534
- onProgress,
535
- onAccepted,
536
- onRolledBack,
537
- } = {}) {
538
- const native = Boolean(run.nativeSelection);
539
- const review = await reviewDelegateDelta({ custody, run, scopePaths, preservePaths });
540
- if (!review.ready)
541
- return {
542
- status: 'blocked',
543
- ...review,
544
- nextAction: 'Inspect the retained worktree and resolve the reported conflicts.',
545
- };
546
- if (reviewedDigest && reviewedDigest !== patchDigest(review))
547
- throw new IntegrationError(
548
- 'E_INTEGRATION_REVIEW_DRIFT',
549
- 'The delegate patch changed since review; review it again.',
550
- );
551
- const release = await checkoutLock(custody.repositoryRoot);
552
- const controller = new AbortController();
553
- const interrupt = () => controller.abort();
554
- process.once('SIGINT', interrupt);
555
- process.once('SIGTERM', interrupt);
556
- let scratch, baselineScratch, worktreeBefore, worktreeIdentity;
557
- const verification = {
558
- status: 'running',
559
- phase: 'candidate-selection',
560
- candidateIdentity: patchDigest(review),
561
- startedAt: new Date().toISOString(),
562
- phases: [],
563
- preparation: [],
564
- checks: [],
565
- };
566
- const progress = () => onVerification?.(verification);
567
- const onProcess = async (identity) => {
568
- verification.commandProcess = identity;
569
- await progress();
570
- };
571
- async function phase(name, operation) {
572
- verification.phase = name;
573
- const step = { phase: name, startedAt: new Date().toISOString() };
574
- verification.phases.push(step);
575
- await progress();
576
- try {
577
- return await operation();
578
- } finally {
579
- step.finishedAt = new Date().toISOString();
580
- step.durationMs = Date.parse(step.finishedAt) - Date.parse(step.startedAt);
581
- await progress();
582
- }
583
- }
584
- async function assertCandidateIdentity() {
585
- if (native && (await treeIdentity(scratch.root)) !== scratch.identity)
586
- throw new IntegrationError(
587
- 'E_INTEGRATION_CANDIDATE_STALE',
588
- 'The selected candidate changed. Review the actual files before verification or acceptance.',
589
- );
590
- }
591
- async function retainVerificationMutation(target, effects) {
592
- if (!native || !effects.length) return;
593
- verification.mutatedPaths = [
594
- ...new Set([...(verification.mutatedPaths ?? []), ...effects.map((effect) => effect.path)]),
595
- ];
596
- if (target.kind !== 'fresh-candidate') return;
597
- verification.retainedCandidate = true;
598
- for (const { path } of effects) {
599
- const before =
600
- worktreeBefore.get(path) ??
601
- (await headFileState(custody.worktreePath, path, custody.initialHead));
602
- if (!sameState(await captureFileState(custody.worktreePath, path), before))
603
- throw new IntegrationError(
604
- 'E_INTEGRATION_CANDIDATE_STALE',
605
- 'Owned worktree changed during verification; preserve the fresh candidate for inspection.',
606
- { path },
607
- );
608
- }
609
- for (const { path } of effects) {
610
- const before =
611
- worktreeBefore.get(path) ??
612
- (await headFileState(custody.worktreePath, path, custody.initialHead));
613
- await putStateGuarded(
614
- custody.worktreePath,
615
- path,
616
- await captureFileState(target.root, path),
617
- before,
618
- randomUUID(),
619
- );
620
- }
621
- verification.mutationsReturnedToWorktree = true;
622
- verification.retainedCandidate = false;
623
- }
624
- async function prepareScratch(target, steps, targetName) {
625
- const before = await workingSnapshot(target.root);
626
- const results = await runDelegateChecks({
627
- repositoryRoot: target.root,
628
- checks: steps,
629
- timeoutMs,
630
- home: target.home,
631
- signal: controller.signal,
632
- onProcess,
633
- stopOnFailure: true,
634
- onResult: async (result) => {
635
- verification.preparation.push({ ...result, target: targetName });
636
- await progress();
637
- },
638
- });
639
- if (results.some((result) => result.processTerminationConfirmed === false))
640
- throw new IntegrationError(
641
- 'E_INTEGRATION_PROCESS',
642
- 'An owned preparation process could not be stopped.',
643
- );
644
- const effects = await changedSinceSnapshot(target.root, before);
645
- if (effects.length) {
646
- await retainVerificationMutation(target, effects);
647
- review.violations.push(
648
- ...effects.map(({ path }) => ({
649
- code: native ? 'E_INTEGRATION_REVIEW_DRIFT' : 'E_INTEGRATION_PREPARATION_SIDE_EFFECT',
650
- path,
651
- })),
652
- );
653
- throw new IntegrationError(
654
- native ? 'E_INTEGRATION_REVIEW_DRIFT' : 'E_INTEGRATION_PREPARATION_SIDE_EFFECT',
655
- 'Preparation changed reviewable files. Inspect the updated candidate and review again.',
656
- );
657
- }
658
- if (results.some(({ status }) => status !== 'passed'))
659
- throw new IntegrationError(
660
- 'E_INTEGRATION_PREPARATION',
661
- 'Scratch preparation failed before checks.',
662
- );
663
- }
664
- const applied = [],
665
- createdDirectories = [],
666
- generatorRuns = [],
667
- generatedPaths = [];
668
- const delegatePaths = [...review.changedPaths];
669
- let results = [],
670
- failureCode,
671
- rollbackErrors = [];
672
- try {
673
- const protectedPaths = [...(custody.preservePaths ?? []), ...(preservePaths ?? [])].map(
674
- (entry) => safePath(typeof entry === 'string' ? entry : entry.path),
675
- );
676
- const selectedGenerators = await resolveSelectedGenerators(
677
- custody.repositoryRoot,
678
- generators,
679
- delegatePaths,
680
- scopePaths.map(safePath),
681
- protectedPaths,
682
- );
683
- await assertSafeChanges(custody.repositoryRoot, review.changes);
684
- if (native) {
685
- worktreeBefore = await workingSnapshot(custody.worktreePath);
686
- worktreeIdentity = await treeIdentity(custody.worktreePath);
687
- }
688
- scratch = await phase(native ? 'candidate-selection' : 'scratch-preparation', () =>
689
- native ? integrationCandidate(custody, review) : createScratch(custody.repositoryRoot),
690
- );
691
- if (!native)
692
- for (const change of review.changes)
693
- await putState(scratch.root, change.path, change.after, randomUUID());
694
- const selectedChecks = await resolveSelectedChecks(scratch.root, checks, { legacy: !native });
695
- const selectedPreparation = (
696
- await resolveSelectedChecks(scratch.root, preparation ?? [], { legacy: !native })
697
- ).map((step) => ({ ...step, kind: 'preparation' }));
698
- if (
699
- native &&
700
- !selectedChecks.length &&
701
- (typeof reviewOnlyReason !== 'string' || !reviewOnlyReason.trim())
702
- )
703
- throw new IntegrationError(
704
- 'E_INTEGRATION_CHECKS_REQUIRED',
705
- 'Select applicable independent commands or provide a reviewOnlyReason. Zero checks remains unverified.',
706
- );
707
- verification.candidateIdentity = scratch.identity;
708
- verification.candidatePath = scratch.root;
709
- verification.candidateKind = scratch.kind;
710
- verification.reviewOnlyReason = selectedChecks.length ? null : reviewOnlyReason;
711
- await assertCandidateIdentity();
712
- if (selectedPreparation.length)
713
- await phase('build-preparation', () =>
714
- prepareScratch(scratch, selectedPreparation, 'candidate'),
715
- );
716
- await generateCandidate({
717
- scratch,
718
- generators: selectedGenerators,
719
- custody,
720
- review,
721
- timeoutMs,
722
- signal: controller.signal,
723
- phase,
724
- generatorRuns,
725
- generatedPaths,
726
- retainMutation: native ? retainVerificationMutation : null,
727
- onProcess,
728
- });
729
- if (native && generatedPaths.length)
730
- throw new IntegrationError(
731
- 'E_INTEGRATION_REVIEW_DRIFT',
732
- 'Generated files changed the candidate. Review the resulting files before accepting.',
733
- );
734
- const beforeChecks = await workingSnapshot(scratch.root);
735
- await assertCandidateIdentity();
736
- results = await phase('checks', () =>
737
- runDelegateChecks({
738
- repositoryRoot: scratch.root,
739
- checks: selectedChecks,
740
- timeoutMs,
741
- home: scratch.home,
742
- signal: controller.signal,
743
- onProcess,
744
- onResult: async (_result, current) => {
745
- verification.checks = [...current];
746
- await progress();
747
- },
748
- }),
749
- );
750
- if (results.some((result) => result.processTerminationConfirmed === false))
751
- throw new IntegrationError(
752
- 'E_INTEGRATION_PROCESS',
753
- 'An owned check process could not be stopped. Recover it before verification or acceptance.',
754
- );
755
- const checkEffects = await changedSinceSnapshot(scratch.root, beforeChecks);
756
- if (checkEffects.length) {
757
- await retainVerificationMutation(scratch, checkEffects);
758
- review.violations.push(
759
- ...checkEffects.map(({ path }) => ({ code: 'E_INTEGRATION_CHECK_SIDE_EFFECT', path })),
760
- );
761
- throw new IntegrationError(
762
- native ? 'E_INTEGRATION_REVIEW_DRIFT' : 'E_INTEGRATION_CHECK_SIDE_EFFECT',
763
- 'Verification changed reviewable files. Inspect this candidate and review again.',
764
- );
765
- }
766
- if (results.some((result) => result.status === 'timed-out'))
767
- throw new IntegrationError('E_INTEGRATION_CHECK_TIMEOUT', 'An independent check timed out.');
768
- if (results.some((result) => result.status === 'failed') && (!native || baselineComparison)) {
769
- // Rebuild a fresh source baseline; candidate build outputs must not influence classification.
770
- baselineScratch = await phase('baseline-preparation', async () => {
771
- const target = await createScratch(custody.repositoryRoot);
772
- baselineScratch = target;
773
- await prepareScratch(target, selectedPreparation, 'baseline');
774
- for (const generator of selectedGenerators) {
775
- const generated = await runGenerator(
776
- target.root,
777
- { ...generator, home: target.home, signal: controller.signal, onProcess },
778
- timeoutMs,
779
- );
780
- if (
781
- !generated.passed ||
782
- generated.changes.some(({ path }) => !generator.outputPaths.includes(path))
783
- )
784
- throw new IntegrationError(
785
- 'E_INTEGRATION_BASELINE_GENERATION',
786
- 'Baseline generation could not be verified.',
787
- );
788
- }
789
- return target;
790
- });
791
- const comparison = await compareWithBaseline(results, selectedChecks, baselineScratch, {
792
- phase,
793
- timeoutMs,
794
- signal: controller.signal,
795
- onProcess,
796
- });
797
- results = comparison.results;
798
- const effects = comparison.effects;
799
- if (effects.length)
800
- review.violations.push(
801
- ...effects.map(({ path }) => ({ code: 'E_INTEGRATION_BASELINE_SIDE_EFFECT', path })),
802
- );
803
- verification.checks = results;
804
- await progress();
805
- throw new IntegrationError(
806
- effects.length ? 'E_INTEGRATION_BASELINE_SIDE_EFFECT' : 'E_INTEGRATION_CHECKS',
807
- 'Independent checks failed.',
808
- );
809
- }
810
- if (results.some((result) => result.status !== 'passed'))
811
- throw new IntegrationError(
812
- 'E_INTEGRATION_CHECKS',
813
- 'Independent checks failed. Baseline comparison is an explicit diagnostic action.',
814
- );
815
- await assertCandidateIdentity();
816
- if (native && (await treeIdentity(custody.worktreePath)) !== worktreeIdentity)
817
- throw new IntegrationError(
818
- 'E_INTEGRATION_CANDIDATE_STALE',
819
- 'Owned worktree changed during verification; retain it for review.',
820
- );
821
- if (native && (await treeIdentity(custody.repositoryRoot)) !== scratch.sourceIdentity)
822
- throw new IntegrationError(
823
- 'E_INTEGRATION_CANDIDATE_STALE',
824
- 'The source checkout changed while verification ran. Review the actual candidate again.',
825
- );
826
- if (controller.signal.aborted)
827
- throw new IntegrationError('E_INTEGRATION_INTERRUPTED', 'Integration was interrupted.');
828
- await assertSafeChanges(custody.repositoryRoot, review.changes);
829
- await validateSourceChanges(custody.repositoryRoot, review.changes);
830
- const states = Object.fromEntries(
831
- review.changes.map(({ path, after }) => [path, compactIntegrationState(after)]),
832
- );
833
- const accepted = {
834
- delegatePaths,
835
- generatedPaths,
836
- changedPaths: review.changedPaths,
837
- states,
838
- checks: results,
839
- generators: generatorRuns,
840
- preparation: verification.preparation,
841
- candidateIdentity: verification.candidateIdentity,
842
- ...(native ? { worktreeIdentity } : {}),
843
- verified: results.length > 0 && results.every((result) => result.status === 'passed'),
844
- reviewOnlyReason: verification.reviewOnlyReason,
845
- };
846
- verification.phase = 'source-write';
847
- verification.phases.push({
848
- phase: 'source-write',
849
- startedAt: new Date().toISOString(),
850
- });
851
- await progress();
852
- for (const change of review.changes) change.writeId = randomUUID();
853
- await beforeApply?.({ ...accepted, changes: review.changes });
854
- await assertCandidateIdentity();
855
- await writeChanges({
856
- root: custody.repositoryRoot,
857
- changes: review.changes,
858
- signal: controller.signal,
859
- onProgress,
860
- applied,
861
- createdDirectories,
862
- });
863
- await assertCandidateIdentity();
864
- if (native && (await treeIdentity(custody.worktreePath)) !== worktreeIdentity)
865
- throw new IntegrationError(
866
- 'E_INTEGRATION_CANDIDATE_STALE',
867
- 'Owned worktree changed before acceptance; retain it for review.',
868
- );
869
- if (native && (await treeIdentity(custody.repositoryRoot)) !== scratch.identity)
870
- throw new IntegrationError(
871
- 'E_INTEGRATION_SOURCE_DRIFT',
872
- 'The resulting checkout differs from the verified candidate. Retain concurrent edits and review again.',
873
- );
874
- await onAccepted?.(accepted);
875
- return {
876
- status: 'completed',
877
- ...review,
878
- checks: results,
879
- generatedPaths,
880
- generators: generatorRuns,
881
- nextAction:
882
- 'Review the uncommitted local diff. The owned worktree is removed unless retention was requested.',
883
- };
884
- } catch (error) {
885
- failureCode = error.code ?? 'E_INTEGRATION_APPLY';
886
- if (verification.commandProcess && scratch?.base) verification.retainedCandidate = true;
887
- if (
888
- [
889
- 'E_INTEGRATION_CHECK_SELECTION',
890
- 'E_INTEGRATION_GENERATOR_SELECTION',
891
- 'E_INTEGRATION_GENERATOR_DRIFT',
892
- ].includes(error.code)
893
- )
894
- throw error;
895
- failureCode = error.code ?? 'E_INTEGRATION_APPLY';
896
- if (error.details?.path) review.violations.push({ code: failureCode, ...error.details });
897
- rollbackErrors = await rollbackWritten(custody.repositoryRoot, applied, randomUUID());
898
- if (error.details?.published)
899
- rollbackErrors.push({
900
- path: error.details.path,
901
- retainedPath: error.details.retainedPath,
902
- code: 'E_INTEGRATION_ROLLBACK_CONFLICT',
903
- });
904
- for (const directory of createdDirectories.reverse()) {
905
- try {
906
- await rmdir(directory);
907
- } catch (cleanupError) {
908
- if (!['ENOTEMPTY', 'ENOENT'].includes(cleanupError.code))
909
- rollbackErrors.push({ path: directory, code: cleanupError.code });
910
- }
911
- }
912
- await onRolledBack?.({ rollbackErrors, code: failureCode });
913
- return {
914
- status: 'blocked',
915
- ...review,
916
- code: failureCode,
917
- checks: results,
918
- generatedPaths,
919
- generators: generatorRuns,
920
- rollbackErrors,
921
- nextAction:
922
- failureCode === 'E_INTEGRATION_PROCESS'
923
- ? 'Recover the recorded owned parent command before checks, continuation or cleanup.'
924
- : rollbackErrors.length
925
- ? 'Resolve the integration journal conflicts before continuing.'
926
- : failureCode === 'E_INTEGRATION_CHECK_TIMEOUT'
927
- ? 'Retry apply with a measured timeoutMs.'
928
- : 'Send the findings to the same delegate session for correction; the worktree remains available.',
929
- };
930
- } finally {
931
- process.removeListener('SIGINT', interrupt);
932
- process.removeListener('SIGTERM', interrupt);
933
- for (const step of verification.phases) {
934
- if (!step.finishedAt) {
935
- step.finishedAt = new Date().toISOString();
936
- step.durationMs = Date.parse(step.finishedAt) - Date.parse(step.startedAt);
937
- }
938
- }
939
- if (verification.commandProcess)
940
- verification.retainedCandidatePaths = [scratch?.root, baselineScratch?.root].filter(Boolean);
941
- verification.status = failureCode ? 'blocked' : 'completed';
942
- verification.phase = failureCode ? 'blocked' : 'integrated';
943
- verification.finishedAt = new Date().toISOString();
944
- verification.durationMs =
945
- Date.parse(verification.finishedAt) - Date.parse(verification.startedAt);
946
- verification.code = failureCode ?? null;
947
- verification.checks = results.length ? results : verification.checks;
948
- try {
949
- await progress();
950
- } finally {
951
- if (scratch?.base && !verification.retainedCandidate)
952
- await rm(scratch.base, { recursive: true, force: true });
953
- if (baselineScratch && !verification.commandProcess)
954
- await rm(baselineScratch.base, { recursive: true, force: true });
955
- await release();
956
- }
957
- }
958
- }