openplanr 3.3.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 (267) hide show
  1. package/CHANGELOG.md +52 -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/dashboard/.vite/manifest.json +2 -2
  13. package/dist/dashboard/assets/index-Cv4Vwhuw.css +2 -0
  14. package/dist/dashboard/assets/index-CvQAlBy3.js +75 -0
  15. package/dist/dashboard/assets/index-CvQAlBy3.js.map +1 -0
  16. package/dist/dashboard/dashboard-manifest.json +14 -14
  17. package/dist/dashboard/index.html +2 -2
  18. package/dist/services/design-artifact-service.d.ts +20 -1
  19. package/dist/services/design-artifact-service.d.ts.map +1 -1
  20. package/dist/services/design-artifact-service.js +137 -18
  21. package/dist/services/design-artifact-service.js.map +1 -1
  22. package/dist/services/ship-checks/contract.d.ts +3 -1
  23. package/dist/services/ship-checks/contract.d.ts.map +1 -1
  24. package/dist/services/ship-checks/contract.js +1 -1
  25. package/dist/services/ship-checks/contract.js.map +1 -1
  26. package/dist/services/ship-checks/discover.d.ts.map +1 -1
  27. package/dist/services/ship-checks/discover.js +2 -1
  28. package/dist/services/ship-checks/discover.js.map +1 -1
  29. package/dist/services/ship-checks/package-contents.d.ts +4 -0
  30. package/dist/services/ship-checks/package-contents.d.ts.map +1 -0
  31. package/dist/services/ship-checks/package-contents.js +91 -0
  32. package/dist/services/ship-checks/package-contents.js.map +1 -0
  33. package/dist/services/ship-checks/packages.d.ts +2 -0
  34. package/dist/services/ship-checks/packages.d.ts.map +1 -1
  35. package/dist/services/ship-checks/packages.js +4 -0
  36. package/dist/services/ship-checks/packages.js.map +1 -1
  37. package/dist/services/ship-checks/scope.js +2 -1
  38. package/dist/services/ship-checks/scope.js.map +1 -1
  39. package/dist/utils/splice-managed-block.js +1 -1
  40. package/dist/utils/splice-managed-block.js.map +1 -1
  41. package/docs/CLI.md +38 -1
  42. package/lib/host-packages/adapter-registry.json +5 -5
  43. package/lib/host-packages/capability-map.json +1 -1
  44. package/lib/host-packages/claude/.claude-plugin/marketplace.json +3 -3
  45. package/lib/host-packages/claude/openplanr/.claude-plugin/plugin.json +6 -6
  46. package/lib/host-packages/claude/openplanr/.openplanr-content.json +67 -123
  47. package/lib/host-packages/claude/openplanr/README.md +12 -12
  48. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/shared/task-context-resolution.md +4 -4
  49. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-artifact-shell.mjs +2 -4
  50. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-document.mjs +26 -26
  51. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-handoff.mjs +850 -56
  52. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-review-state-store.mjs +45 -0
  53. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-review.mjs +65 -74
  54. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-runtime-home.mjs +0 -1
  55. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-share-cli-bridge.mjs +321 -0
  56. package/lib/host-packages/{openai/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs → claude/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-d707e49b.mjs} +762 -223
  57. 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
  58. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-design-support-0bac378d.mjs +137 -0
  59. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design.mjs +107 -37
  60. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +0 -27
  61. 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
  62. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +1 -5684
  63. 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
  64. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +10 -74
  65. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/package.json +3 -3
  66. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/share.js +8 -2
  67. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +5 -1
  68. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +545 -4781
  69. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/design.mjs +219 -452
  70. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +5 -1
  71. package/lib/host-packages/claude/openplanr/skills/delegate/SKILL.md +2 -1
  72. package/lib/host-packages/claude/openplanr/skills/delegate/references/integration-review.md +26 -20
  73. package/lib/host-packages/claude/openplanr/skills/delegate/references/operator-guide.md +25 -1
  74. package/lib/host-packages/claude/openplanr/skills/delegate/references/run-handoff.md +2 -2
  75. package/lib/host-packages/claude/openplanr/skills/delegate/references/worktree-custody.md +17 -9
  76. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/adapters/claude.mjs +15 -3
  77. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/adapters/codex.mjs +38 -2
  78. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/adapters/native.mjs +5 -0
  79. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/custody.mjs +217 -10
  80. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/handoff.mjs +1080 -0
  81. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/integrate.mjs +96 -201
  82. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/integration-files.mjs +3 -382
  83. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/presentation.mjs +29 -12
  84. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-contract.mjs +11 -0
  85. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-execution.mjs +1 -1
  86. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-lifecycle.mjs +14 -10
  87. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-preparation.mjs +4 -0
  88. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-record.mjs +2 -2
  89. package/lib/host-packages/claude/openplanr/skills/design/references/utilities.md +14 -8
  90. package/lib/host-packages/claude/openplanr/skills/design-loop/references/utilities.md +14 -8
  91. package/lib/host-packages/claude/openplanr/skills/design-review/references/utilities.md +14 -8
  92. package/lib/host-packages/claude/openplanr/skills/investigate/SKILL.md +1 -0
  93. package/lib/host-packages/claude/openplanr/skills/investigate/references/fail-first.md +40 -0
  94. package/lib/host-packages/claude/openplanr/skills/ship/SKILL.md +22 -10
  95. package/lib/host-packages/claude/openplanr/skills/ship/references/fail-first.md +40 -0
  96. package/lib/host-packages/claude/openplanr/skills/ship/references/result-contract.md +7 -3
  97. package/lib/host-packages/cursor/openplanr/.openplanr-content.json +65 -121
  98. package/lib/host-packages/cursor/openplanr/manifest.json +1 -1
  99. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/references/integration-review.md +26 -20
  100. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/references/operator-guide.md +25 -1
  101. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/references/run-handoff.md +2 -2
  102. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/references/worktree-custody.md +17 -9
  103. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/adapters/claude.mjs +15 -3
  104. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/adapters/codex.mjs +38 -2
  105. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/adapters/native.mjs +5 -0
  106. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/custody.mjs +217 -10
  107. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/handoff.mjs +1080 -0
  108. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/integrate.mjs +96 -201
  109. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/integration-files.mjs +3 -382
  110. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/presentation.mjs +29 -12
  111. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-contract.mjs +11 -0
  112. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-execution.mjs +1 -1
  113. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-lifecycle.mjs +14 -10
  114. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-preparation.mjs +4 -0
  115. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-record.mjs +2 -2
  116. package/lib/host-packages/cursor/openplanr/rules/planr-delegate.mdc +2 -1
  117. package/lib/host-packages/cursor/openplanr/rules/planr-design/references/utilities.md +14 -8
  118. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/utilities.md +14 -8
  119. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/utilities.md +14 -8
  120. package/lib/host-packages/cursor/openplanr/rules/planr-investigate/references/fail-first.md +40 -0
  121. package/lib/host-packages/cursor/openplanr/rules/planr-investigate.mdc +1 -0
  122. package/lib/host-packages/cursor/openplanr/rules/planr-ship/references/fail-first.md +40 -0
  123. package/lib/host-packages/cursor/openplanr/rules/planr-ship/references/result-contract.md +7 -3
  124. package/lib/host-packages/cursor/openplanr/rules/planr-ship.mdc +22 -10
  125. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-artifact-shell.mjs +2 -4
  126. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-document.mjs +26 -26
  127. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-handoff.mjs +850 -56
  128. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-review-state-store.mjs +45 -0
  129. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-review.mjs +65 -74
  130. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-runtime-home.mjs +0 -1
  131. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-share-cli-bridge.mjs +321 -0
  132. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/{design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs → design-shared-artifact-support-dependencies-design-support-protocol-contracts-d707e49b.mjs} +762 -223
  133. 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
  134. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-design-support-0bac378d.mjs +137 -0
  135. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design.mjs +107 -37
  136. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +0 -27
  137. 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
  138. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +1 -5684
  139. 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
  140. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +10 -74
  141. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/package.json +3 -3
  142. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/share.js +8 -2
  143. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +5 -1
  144. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +545 -4781
  145. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/design.mjs +219 -452
  146. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +5 -1
  147. package/lib/host-packages/openai/.claude-plugin/marketplace.json +3 -3
  148. package/lib/host-packages/openai/openplanr/.codex-plugin/plugin.json +2 -2
  149. package/lib/host-packages/openai/openplanr/.openplanr-content.json +68 -124
  150. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-artifact-shell.mjs +2 -4
  151. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-document.mjs +26 -26
  152. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-handoff.mjs +850 -56
  153. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-review-state-store.mjs +45 -0
  154. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-review.mjs +65 -74
  155. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-runtime-home.mjs +0 -1
  156. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-share-cli-bridge.mjs +321 -0
  157. package/lib/host-packages/{claude/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs → openai/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-d707e49b.mjs} +762 -223
  158. 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
  159. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-design-support-0bac378d.mjs +137 -0
  160. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design.mjs +107 -37
  161. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +0 -27
  162. 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
  163. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +1 -5684
  164. 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
  165. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +10 -74
  166. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/package.json +3 -3
  167. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/share.js +8 -2
  168. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +5 -1
  169. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +545 -4781
  170. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/design.mjs +219 -452
  171. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +5 -1
  172. package/lib/host-packages/openai/openplanr/skills/delegate/SKILL.md +2 -1
  173. package/lib/host-packages/openai/openplanr/skills/delegate/openplanr.skill.json +1 -1
  174. package/lib/host-packages/openai/openplanr/skills/delegate/references/integration-review.md +26 -20
  175. package/lib/host-packages/openai/openplanr/skills/delegate/references/operator-guide.md +25 -1
  176. package/lib/host-packages/openai/openplanr/skills/delegate/references/run-handoff.md +2 -2
  177. package/lib/host-packages/openai/openplanr/skills/delegate/references/worktree-custody.md +17 -9
  178. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/adapters/claude.mjs +15 -3
  179. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/adapters/codex.mjs +38 -2
  180. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/adapters/native.mjs +5 -0
  181. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/custody.mjs +217 -10
  182. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/handoff.mjs +1080 -0
  183. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/integrate.mjs +96 -201
  184. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/integration-files.mjs +3 -382
  185. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/presentation.mjs +29 -12
  186. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-contract.mjs +11 -0
  187. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-execution.mjs +1 -1
  188. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-lifecycle.mjs +14 -10
  189. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-preparation.mjs +4 -0
  190. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-record.mjs +2 -2
  191. package/lib/host-packages/openai/openplanr/skills/design/references/utilities.md +14 -8
  192. package/lib/host-packages/openai/openplanr/skills/design-loop/references/utilities.md +14 -8
  193. package/lib/host-packages/openai/openplanr/skills/design-review/references/utilities.md +14 -8
  194. package/lib/host-packages/openai/openplanr/skills/investigate/SKILL.md +1 -0
  195. package/lib/host-packages/openai/openplanr/skills/investigate/openplanr.skill.json +12 -1
  196. package/lib/host-packages/openai/openplanr/skills/investigate/references/fail-first.md +40 -0
  197. package/lib/host-packages/openai/openplanr/skills/ship/SKILL.md +22 -10
  198. package/lib/host-packages/openai/openplanr/skills/ship/openplanr.skill.json +12 -1
  199. package/lib/host-packages/openai/openplanr/skills/ship/references/fail-first.md +40 -0
  200. package/lib/host-packages/openai/openplanr/skills/ship/references/result-contract.md +7 -3
  201. package/package.json +8 -8
  202. package/dist/dashboard/assets/index-BU5fzjyz.css +0 -1
  203. package/dist/dashboard/assets/index-B_96uzCl.js +0 -572
  204. package/dist/dashboard/assets/index-B_96uzCl.js.map +0 -1
  205. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +0 -555
  206. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-compression.mjs +0 -4180
  207. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-encrypted-workspace-client.mjs +0 -647
  208. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-owner-custody.mjs +0 -129
  209. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-resource-pack.mjs +0 -698
  210. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-runtime-support-25485dbf1cb2.mjs +0 -24
  211. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-share.mjs +0 -1993
  212. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-protocol-contracts-75a938cc.mjs +0 -222
  213. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-protocol-contracts-b5f28f94.mjs +0 -5907
  214. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-upload-spool.mjs +0 -198
  215. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-compression.js +0 -4175
  216. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/05-artifact-sharing.js +0 -65
  217. 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
  218. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/07-artifact-sharing.js +0 -62
  219. 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
  220. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +0 -49
  221. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +0 -108
  222. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +0 -170
  223. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +0 -97
  224. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +0 -56
  225. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/integration-transaction.mjs +0 -958
  226. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/integration-transaction.mjs +0 -958
  227. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +0 -555
  228. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-compression.mjs +0 -4180
  229. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-encrypted-workspace-client.mjs +0 -647
  230. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-owner-custody.mjs +0 -129
  231. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-resource-pack.mjs +0 -698
  232. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-runtime-support-25485dbf1cb2.mjs +0 -24
  233. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-share.mjs +0 -1993
  234. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-protocol-contracts-75a938cc.mjs +0 -222
  235. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-protocol-contracts-b5f28f94.mjs +0 -5907
  236. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-upload-spool.mjs +0 -198
  237. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-compression.js +0 -4175
  238. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/05-artifact-sharing.js +0 -65
  239. 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
  240. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/07-artifact-sharing.js +0 -62
  241. 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
  242. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +0 -49
  243. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +0 -108
  244. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +0 -170
  245. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +0 -97
  246. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +0 -56
  247. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +0 -555
  248. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-compression.mjs +0 -4180
  249. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-encrypted-workspace-client.mjs +0 -647
  250. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-owner-custody.mjs +0 -129
  251. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-resource-pack.mjs +0 -698
  252. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-runtime-support-25485dbf1cb2.mjs +0 -24
  253. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-share.mjs +0 -1993
  254. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-protocol-contracts-75a938cc.mjs +0 -222
  255. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-protocol-contracts-b5f28f94.mjs +0 -5907
  256. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-upload-spool.mjs +0 -198
  257. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-compression.js +0 -4175
  258. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/05-artifact-sharing.js +0 -65
  259. 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
  260. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/07-artifact-sharing.js +0 -62
  261. 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
  262. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-paste.schema.json +0 -49
  263. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-review-workspace.schema.json +0 -108
  264. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-create.schema.json +0 -170
  265. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-event.schema.json +0 -97
  266. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0/design-workspace-revision.schema.json +0 -56
  267. 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
- }