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,6 +1,3 @@
1
- import {
2
- isProcessAlive
3
- } from "./design-loopback-server.mjs";
4
1
  import {
5
2
  Parser,
6
3
  defaultTreeAdapter
@@ -11,147 +8,14 @@ import {
11
8
  hasUnescapedText
12
9
  } from "./design-parse5-tokenizer.mjs";
13
10
  import {
14
- MAX_ARTIFACT_HTML_BYTES
15
- } from "./design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs";
16
- import {
17
- DESIGN_DOCUMENT_SCHEMA,
18
- DESIGN_DOCUMENT_V120_SCHEMA,
19
- DESIGN_REVIEW_BUNDLE_SCHEMA,
20
- validateDesignProps,
11
+ MAX_ARTIFACT_HTML_BYTES,
21
12
  validateJson
22
- } from "./design-shared-protocol-contracts-b5f28f94.mjs";
23
- import {
24
- canonicalizeJson,
25
- sha256Hex
26
- } from "./design-shared-protocol-contracts-75a938cc.mjs";
27
-
28
- // packages/design/lib/design/document-state.mjs
29
- import { createHash, randomUUID } from "node:crypto";
30
- import {
31
- chmodSync,
32
- closeSync,
33
- lstatSync,
34
- mkdirSync,
35
- openSync,
36
- readFileSync,
37
- realpathSync,
38
- renameSync,
39
- rmSync,
40
- writeFileSync
41
- } from "node:fs";
42
- import { dirname, join, resolve } from "node:path";
43
- var hash = (value) => createHash("sha256").update(value).digest("hex");
44
- var json = (value) => `${JSON.stringify(value, null, 2)}
45
- `;
46
- function readJson(path, fallback = void 0) {
47
- try {
48
- return JSON.parse(readFileSync(path, "utf8"));
49
- } catch (error) {
50
- if (error.code === "ENOENT" && fallback !== void 0) return fallback;
51
- throw error;
52
- }
53
- }
54
- function atomicJson(path, value, { mode } = {}) {
55
- atomicBytes(path, json(value), mode);
56
- }
57
- function atomicBytes(path, bytes, mode) {
58
- mkdirSync(dirname(path), { recursive: true });
59
- const temporary = `${path}.${randomUUID()}.tmp`;
60
- try {
61
- writeFileSync(temporary, bytes, { mode: 384, flag: "wx" });
62
- if (mode !== void 0) chmodSync(temporary, mode);
63
- renameSync(temporary, path);
64
- } finally {
65
- rmSync(temporary, { force: true });
66
- }
67
- }
68
- function recoverDesignPublication(root, { ownsRenderLock = false } = {}) {
69
- const journalPath = join(root, ".design/publication.json");
70
- let journal = readJson(journalPath, null);
71
- if (!journal) return;
72
- const lockPath = join(root, ".design/render.lock");
73
- let recoveryOwner;
74
- if (!ownsRenderLock) {
75
- const lock = readJson(lockPath, null);
76
- if (lock && isProcessAlive(lock.pid)) return;
77
- if (lock) rmSync(lockPath, { force: true });
78
- recoveryOwner = randomUUID();
79
- let descriptor;
80
- try {
81
- descriptor = openSync(lockPath, "wx", 384);
82
- writeFileSync(
83
- descriptor,
84
- json({ pid: process.pid, owner: recoveryOwner, createdAt: Date.now() })
85
- );
86
- } catch (error) {
87
- if (error.code === "EEXIST") return;
88
- throw error;
89
- } finally {
90
- if (descriptor !== void 0) closeSync(descriptor);
91
- }
92
- }
93
- try {
94
- journal = readJson(journalPath, null);
95
- if (!journal) return;
96
- const pointer = readJson(join(root, ".design/current.json"), null);
97
- const manifestPath = join(root, "finalized.json");
98
- if (pointer?.revision === journal.revision) atomicJson(manifestPath, journal.manifest);
99
- else if ((pointer?.revision ?? null) === journal.previousRevision) {
100
- if (journal.previousManifest === null) rmSync(manifestPath, { force: true });
101
- else atomicBytes(manifestPath, Buffer.from(journal.previousManifest, "base64"));
102
- } else if (pointer?.revision && /^[a-f0-9]{64}$/u.test(pointer.revision)) {
103
- atomicJson(
104
- manifestPath,
105
- readJson(join(root, ".design/revisions", pointer.revision, "render.json")).manifest
106
- );
107
- } else
108
- throw new Error("Design publication recovery could not identify the committed revision.");
109
- rmSync(journalPath, { force: true });
110
- } finally {
111
- if (recoveryOwner && readJson(lockPath, null)?.owner === recoveryOwner)
112
- rmSync(lockPath, { force: true });
113
- }
114
- }
115
- function designSpecPath(root) {
116
- return /(?:^|\/)output\/feats\/feat-[^/]+\/design$/u.test(root.replaceAll("\\", "/")) ? join(dirname(root), "design-spec.md") : join(root, "design-spec.md");
117
- }
118
- function currentDesign(file, { recoverPublication = true } = {}) {
119
- const root = realpathSync(dirname(resolve(file)));
120
- if (recoverPublication) recoverDesignPublication(root);
121
- else {
122
- try {
123
- lstatSync(join(root, ".design/publication.json"));
124
- throw Object.assign(
125
- new Error(
126
- "Design publication state is pending or needs recovery. Finish or recover it with the Design utility; repair or restore an invalid .design/publication.json before retrying Plan handoff inspection."
127
- ),
128
- { code: "E_DESIGN_PUBLICATION_PENDING", statusCode: 409 }
129
- );
130
- } catch (error) {
131
- if (error.code !== "ENOENT") throw error;
132
- }
133
- }
134
- const pointer = readJson(join(root, ".design/current.json"), null);
135
- if (!pointer || !/^[a-f0-9]{64}$/u.test(pointer.revision))
136
- throw new Error("Design has no completed render. Run the render utility first.");
137
- const directory = join(root, ".design/revisions", pointer.revision);
138
- const prepared = readJson(join(directory, "render.json"));
139
- return {
140
- ...prepared,
141
- root,
142
- directory,
143
- file: resolve(file),
144
- verification: readJson(join(root, ".design/verification", `${pointer.revision}.json`), {
145
- status: "unverified",
146
- revision: pointer.revision
147
- })
148
- };
149
- }
13
+ } from "./design-shared-artifact-support-protocol-contracts-9f6918b0.mjs";
150
14
 
151
15
  // packages/artifact/lib/artifact/local-document.mjs
152
- import { createHash as createHash2 } from "node:crypto";
153
- import { readFileSync as readFileSync2, realpathSync as realpathSync2, statSync } from "node:fs";
154
- import { dirname as dirname2, extname, isAbsolute, relative, resolve as resolve2 } from "node:path";
16
+ import { createHash } from "node:crypto";
17
+ import { readFileSync, realpathSync, statSync } from "node:fs";
18
+ import { dirname, extname, isAbsolute, relative, resolve } from "node:path";
155
19
  import { Script } from "node:vm";
156
20
 
157
21
  // node_modules/entities/dist/escape.js
@@ -355,13 +219,13 @@ function inspectLocalDocumentBody(html) {
355
219
  function resolveLocalDocumentFile(root, path, from = root) {
356
220
  if (typeof path !== "string" || !path || /^(?:[a-z][a-z\d+.-]*:|\/|\\)/iu.test(path))
357
221
  throw new Error(`Expected a local relative asset: ${path}`);
358
- const candidate = resolve2(from, path);
222
+ const candidate = resolve(from, path);
359
223
  const inside = (file) => {
360
224
  const r = relative(root, file);
361
225
  return r !== ".." && !r.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) && !isAbsolute(r);
362
226
  };
363
227
  if (!inside(candidate)) throw new Error(`Asset escapes design root: ${path}`);
364
- const actual = realpathSync2(candidate);
228
+ const actual = realpathSync(candidate);
365
229
  if (!inside(actual) || !statSync(actual).isFile())
366
230
  throw new Error(`Asset is not a contained regular file: ${path}`);
367
231
  return actual;
@@ -376,7 +240,7 @@ function bundleLocalDocument({
376
240
  passive = false,
377
241
  screenProps
378
242
  }) {
379
- const root = realpathSync2(inputRoot);
243
+ const root = realpathSync(inputRoot);
380
244
  const files = /* @__PURE__ */ new Map();
381
245
  const mediaStack = /* @__PURE__ */ new Set();
382
246
  let svgDepth = 0;
@@ -387,7 +251,7 @@ function bundleLocalDocument({
387
251
  const checked = readSource?.(path, from);
388
252
  const file = checked?.file ?? resolveLocalDocumentFile(root, path, from);
389
253
  if (!files.has(file)) {
390
- const value = checked?.value ?? readFileSync2(file);
254
+ const value = checked?.value ?? readFileSync(file);
391
255
  bytes += value.length;
392
256
  if (bytes > maxBytes || files.size >= 1e3)
393
257
  throw new Error("Design source exceeds the local asset budget.");
@@ -416,7 +280,7 @@ function bundleLocalDocument({
416
280
  throw new Error("Circular or excessively nested SVG media cannot be published.");
417
281
  mediaStack.add(file);
418
282
  try {
419
- payload = Buffer.from(passiveSvg(value.toString("utf8"), dirname2(file)));
283
+ payload = Buffer.from(passiveSvg(value.toString("utf8"), dirname(file)));
420
284
  } finally {
421
285
  mediaStack.delete(file);
422
286
  }
@@ -479,7 +343,7 @@ function bundleLocalDocument({
479
343
  if (stack.has(next.file)) throw new Error(`Circular stylesheet import: ${ref}`);
480
344
  const expanded = css(
481
345
  next.value.toString("utf8"),
482
- dirname2(next.file),
346
+ dirname(next.file),
483
347
  /* @__PURE__ */ new Set([...stack, next.file])
484
348
  );
485
349
  return media.trim() ? `@media ${media.trim()}{${expanded}}` : expanded;
@@ -527,21 +391,21 @@ function bundleLocalDocument({
527
391
  );
528
392
  if (node.tagName === "meta" && attr(node, "http-equiv")?.value.toLowerCase() === "refresh")
529
393
  throw new Error("Design screens cannot redirect.");
530
- if (node.tagName === "style") setText(node, css(text(node), dirname2(input.file)));
394
+ if (node.tagName === "style") setText(node, css(text(node), dirname(input.file)));
531
395
  if (node.tagName === "link" && attr(node, "rel")?.value.toLowerCase().split(/\s+/u).includes("stylesheet")) {
532
- const linked = read(attr(node, "href")?.value, dirname2(input.file));
396
+ const linked = read(attr(node, "href")?.value, dirname(input.file));
533
397
  node.tagName = "style";
534
398
  node.nodeName = "style";
535
399
  node.attrs = [];
536
400
  setText(
537
401
  node,
538
- css(linked.value.toString("utf8"), dirname2(linked.file), /* @__PURE__ */ new Set([linked.file]))
402
+ css(linked.value.toString("utf8"), dirname(linked.file), /* @__PURE__ */ new Set([linked.file]))
539
403
  );
540
404
  }
541
405
  if (node.tagName === "script") {
542
406
  const src = attr(node, "src");
543
407
  if (passive) {
544
- if (src) read(src.value, dirname2(input.file));
408
+ if (src) read(src.value, dirname(input.file));
545
409
  node.parentNode.childNodes = node.parentNode.childNodes.filter((child) => child !== node);
546
410
  continue;
547
411
  }
@@ -549,7 +413,7 @@ function bundleLocalDocument({
549
413
  if (type === "module")
550
414
  throw new Error("Compile module scripts before using them in a portable design.");
551
415
  if (!type || /(?:javascript|ecmascript)/u.test(type)) {
552
- const linked = src ? read(src.value, dirname2(input.file)) : null;
416
+ const linked = src ? read(src.value, dirname(input.file)) : null;
553
417
  setText(
554
418
  node,
555
419
  js(linked ? linked.value.toString("utf8") : text(node), linked?.file ?? input.file)
@@ -565,16 +429,16 @@ function bundleLocalDocument({
565
429
  }
566
430
  if (passive) node.attrs = (node.attrs ?? []).filter((item2) => !/^on/iu.test(item2.name));
567
431
  for (const item2 of node.attrs ?? []) {
568
- if (item2.name === "style") item2.value = css(item2.value, dirname2(input.file));
432
+ if (item2.name === "style") item2.value = css(item2.value, dirname(input.file));
569
433
  if (["src", "poster"].includes(item2.name))
570
- item2.value = asset(item2.value, dirname2(input.file));
434
+ item2.value = asset(item2.value, dirname(input.file));
571
435
  if (item2.name === "srcset")
572
436
  throw new Error("Use a local src and responsive CSS for portable design images.");
573
437
  if (["action", "formaction", "target", "formtarget"].includes(item2.name) && item2.value.trim())
574
438
  throw new Error("Design forms must use local submit handlers without navigation targets.");
575
439
  if (item2.name === "href" && !item2.value.startsWith("#")) {
576
440
  if (node.tagName === "link" || node.namespaceURI === "http://www.w3.org/2000/svg")
577
- item2.value = asset(item2.value, dirname2(input.file));
441
+ item2.value = asset(item2.value, dirname(input.file));
578
442
  else if (node.tagName === "a")
579
443
  throw new Error('Use data-design-navigate="screen-id" for prototype navigation.');
580
444
  }
@@ -587,7 +451,7 @@ function bundleLocalDocument({
587
451
  prepend.push(
588
452
  element(
589
453
  "style",
590
- css(linked.value.toString("utf8"), dirname2(linked.file), /* @__PURE__ */ new Set([linked.file]))
454
+ css(linked.value.toString("utf8"), dirname(linked.file), /* @__PURE__ */ new Set([linked.file]))
591
455
  )
592
456
  );
593
457
  }
@@ -630,7 +494,7 @@ function bundleLocalDocument({
630
494
  sourceDigests: Object.fromEntries(
631
495
  [...files].map(([path, value]) => [
632
496
  relative(root, path),
633
- createHash2("sha256").update(value).digest("hex")
497
+ createHash("sha256").update(value).digest("hex")
634
498
  ])
635
499
  ),
636
500
  inputBytes: bytes,
@@ -638,6 +502,725 @@ function bundleLocalDocument({
638
502
  };
639
503
  }
640
504
 
505
+ // packages/protocol/src/design-contracts.mjs
506
+ var DESIGN_DOCUMENT_VERSION = "1.0.0";
507
+ function initialFrameHeight(document) {
508
+ const fixed = document.frames.flatMap(
509
+ ({ height }) => typeof height === "number" && Number.isInteger(height) ? [height] : []
510
+ );
511
+ return fixed.length ? Math.max(...fixed) : 900;
512
+ }
513
+ var freeze = (value) => {
514
+ if (value && typeof value === "object") {
515
+ for (const nested of Object.values(value)) freeze(nested);
516
+ Object.freeze(value);
517
+ }
518
+ return value;
519
+ };
520
+ var FRAME_SCHEMA = {
521
+ type: "array",
522
+ minItems: 1,
523
+ items: {
524
+ type: "object",
525
+ additionalProperties: false,
526
+ required: ["id", "label", "width", "height"],
527
+ properties: {
528
+ id: { $ref: "#/$defs/id" },
529
+ label: { $ref: "#/$defs/text" },
530
+ width: { type: "integer", minimum: 1, maximum: 16384 },
531
+ height: { type: "integer", minimum: 1, maximum: 16384 }
532
+ }
533
+ }
534
+ };
535
+ var DESIGN_DOCUMENT_V1_SCHEMA = freeze({
536
+ $schema: "https://json-schema.org/draft/2020-12/schema",
537
+ $id: "https://openplanr.dev/schemas/v1.9.0/design-document.schema.json",
538
+ "x-openplanr-contract": { id: "design-document", version: "1.9.0" },
539
+ title: "OpenPlanr authored design document",
540
+ type: "object",
541
+ additionalProperties: false,
542
+ required: [
543
+ "kind",
544
+ "schemaVersion",
545
+ "id",
546
+ "title",
547
+ "brief",
548
+ "frames",
549
+ "screens",
550
+ "screenOrder",
551
+ "variants",
552
+ "selectedVariant",
553
+ "defaultView"
554
+ ],
555
+ properties: {
556
+ kind: { const: "openplanr-design-document" },
557
+ schemaVersion: { const: DESIGN_DOCUMENT_VERSION },
558
+ id: { $ref: "#/$defs/id" },
559
+ title: { $ref: "#/$defs/text" },
560
+ brief: {
561
+ type: "object",
562
+ additionalProperties: false,
563
+ required: ["text", "source", "provenance"],
564
+ properties: {
565
+ text: { $ref: "#/$defs/text" },
566
+ source: { enum: ["spec", "png", "describe"] },
567
+ provenance: { enum: ["spec", "inferred"] },
568
+ references: { type: "array", items: { $ref: "#/$defs/text" }, uniqueItems: true }
569
+ }
570
+ },
571
+ designSystem: {
572
+ type: "object",
573
+ additionalProperties: false,
574
+ properties: {
575
+ path: { $ref: "#/$defs/localPath" },
576
+ tokens: { $ref: "#/$defs/localPath" },
577
+ spacing: {
578
+ type: "array",
579
+ minItems: 1,
580
+ uniqueItems: true,
581
+ items: { type: "number", minimum: 0, maximum: 16384 }
582
+ }
583
+ }
584
+ },
585
+ assets: { $ref: "#/$defs/paths" },
586
+ frames: FRAME_SCHEMA,
587
+ screens: {
588
+ type: "array",
589
+ minItems: 1,
590
+ items: {
591
+ type: "object",
592
+ additionalProperties: false,
593
+ required: ["id", "title", "source"],
594
+ properties: {
595
+ id: { $ref: "#/$defs/id" },
596
+ title: { $ref: "#/$defs/text" },
597
+ description: { $ref: "#/$defs/text" },
598
+ source: { $ref: "#/$defs/source" },
599
+ anchors: { $ref: "#/$defs/ids" }
600
+ }
601
+ }
602
+ },
603
+ screenOrder: { type: "array", minItems: 1, items: { $ref: "#/$defs/id" }, uniqueItems: true },
604
+ flows: {
605
+ type: "array",
606
+ items: {
607
+ type: "object",
608
+ additionalProperties: false,
609
+ required: ["id", "title", "screens"],
610
+ properties: {
611
+ id: { $ref: "#/$defs/id" },
612
+ title: { $ref: "#/$defs/text" },
613
+ screens: { type: "array", minItems: 1, items: { $ref: "#/$defs/id" } }
614
+ }
615
+ }
616
+ },
617
+ variants: {
618
+ type: "array",
619
+ minItems: 1,
620
+ items: {
621
+ type: "object",
622
+ additionalProperties: false,
623
+ required: ["id", "label", "status"],
624
+ properties: {
625
+ id: { $ref: "#/$defs/id" },
626
+ label: { $ref: "#/$defs/text" },
627
+ description: { $ref: "#/$defs/text" },
628
+ status: { enum: ["ready", "failed"] },
629
+ issue: { $ref: "#/$defs/text" },
630
+ sources: { type: "object", additionalProperties: { $ref: "#/$defs/source" } }
631
+ },
632
+ if: { properties: { status: { const: "failed" } } },
633
+ then: { required: ["issue"] }
634
+ }
635
+ },
636
+ selectedVariant: { $ref: "#/$defs/id" },
637
+ defaultView: { enum: ["canvas", "prototype", "walkthrough"] }
638
+ },
639
+ $defs: {
640
+ id: { type: "string", minLength: 1, maxLength: 128, pattern: "^[A-Za-z][A-Za-z0-9_-]*$" },
641
+ text: { type: "string", minLength: 1, pattern: "\\S" },
642
+ ids: { type: "array", items: { $ref: "#/$defs/id" }, uniqueItems: true },
643
+ localPath: {
644
+ type: "string",
645
+ minLength: 1,
646
+ description: "Path relative to the authored document directory. No URL, traversal, encoded path, query or fragment.",
647
+ pattern: "^(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*//)(?!.*[/ ]$)[^\\\\:\\u0000-\\u001F%?#]+$"
648
+ },
649
+ paths: { type: "array", items: { $ref: "#/$defs/localPath" }, uniqueItems: true },
650
+ source: {
651
+ type: "object",
652
+ additionalProperties: false,
653
+ required: ["html"],
654
+ properties: {
655
+ html: { $ref: "#/$defs/localPath" },
656
+ styles: { $ref: "#/$defs/paths" },
657
+ scripts: { $ref: "#/$defs/paths" }
658
+ }
659
+ }
660
+ }
661
+ });
662
+ var DESIGN_DOCUMENT_V120_SCHEMA = freeze({
663
+ ...DESIGN_DOCUMENT_V1_SCHEMA,
664
+ $id: "https://openplanr.dev/schemas/v1.20.0/design-document.schema.json",
665
+ "x-openplanr-contract": { id: "design-document", version: "1.20.0" },
666
+ properties: {
667
+ .../** @type {Record<string, unknown>} */
668
+ DESIGN_DOCUMENT_V1_SCHEMA.properties,
669
+ frames: {
670
+ ...FRAME_SCHEMA,
671
+ items: {
672
+ ...FRAME_SCHEMA.items,
673
+ properties: {
674
+ ...FRAME_SCHEMA.items.properties,
675
+ height: { anyOf: [{ type: "integer", minimum: 1, maximum: 16384 }, { const: "auto" }] }
676
+ }
677
+ }
678
+ },
679
+ layout: {
680
+ type: "object",
681
+ additionalProperties: false,
682
+ properties: {
683
+ boards: {
684
+ type: "object",
685
+ description: "Keys are screenId, screenId/frameId or screenId/frameId/variantId; each ID must exist in the document.",
686
+ additionalProperties: {
687
+ type: "object",
688
+ additionalProperties: false,
689
+ required: ["x", "y"],
690
+ properties: {
691
+ x: { $ref: "#/$defs/coordinate" },
692
+ y: { $ref: "#/$defs/coordinate" },
693
+ title: { $ref: "#/$defs/text" }
694
+ }
695
+ }
696
+ },
697
+ sections: {
698
+ type: "array",
699
+ items: {
700
+ type: "object",
701
+ additionalProperties: false,
702
+ required: ["id", "x", "y", "text"],
703
+ properties: {
704
+ id: { $ref: "#/$defs/id" },
705
+ x: { $ref: "#/$defs/coordinate" },
706
+ y: { $ref: "#/$defs/coordinate" },
707
+ text: { $ref: "#/$defs/text" },
708
+ maxW: { type: "integer", minimum: 1, maximum: 16384 }
709
+ }
710
+ }
711
+ }
712
+ }
713
+ }
714
+ },
715
+ $defs: {
716
+ .../** @type {Record<string, unknown>} */
717
+ DESIGN_DOCUMENT_V1_SCHEMA.$defs,
718
+ coordinate: { type: "number", minimum: -1e7, maximum: 1e7 }
719
+ }
720
+ });
721
+ var PROP_TOKEN_SCHEMA = {
722
+ type: "string",
723
+ minLength: 1,
724
+ maxLength: 128,
725
+ pattern: "^[a-z][a-z0-9-]*(?![\\s\\S])"
726
+ };
727
+ var propTokenPattern = new RegExp(PROP_TOKEN_SCHEMA.pattern, "u");
728
+ var isPropToken2 = (value) => typeof value === "string" && value.length <= PROP_TOKEN_SCHEMA.maxLength && propTokenPattern.test(value);
729
+ var currentDocument = (
730
+ /** @type {{ properties: Record<string, unknown>; [key: string]: unknown }} */
731
+ structuredClone(DESIGN_DOCUMENT_V120_SCHEMA)
732
+ );
733
+ currentDocument.$id = "https://openplanr.dev/schemas/v1.22.0/design-document.schema.json";
734
+ currentDocument["x-openplanr-contract"] = { id: "design-document", version: "1.22.0" };
735
+ currentDocument.properties.schemaVersion = { enum: ["1.0.0", "1.1.0"] };
736
+ var screenSchema = (
737
+ /** @type {{ items: { properties: Record<string, unknown> } }} */
738
+ currentDocument.properties.screens
739
+ );
740
+ screenSchema.items.properties.props = {
741
+ type: "object",
742
+ propertyNames: PROP_TOKEN_SCHEMA,
743
+ additionalProperties: {
744
+ oneOf: [
745
+ {
746
+ type: "object",
747
+ additionalProperties: false,
748
+ required: ["type", "options", "default"],
749
+ properties: {
750
+ type: { const: "enum" },
751
+ options: {
752
+ type: "array",
753
+ minItems: 1,
754
+ uniqueItems: true,
755
+ items: PROP_TOKEN_SCHEMA
756
+ },
757
+ default: PROP_TOKEN_SCHEMA
758
+ }
759
+ },
760
+ {
761
+ type: "object",
762
+ additionalProperties: false,
763
+ required: ["type", "default"],
764
+ properties: { type: { const: "boolean" }, default: { type: "boolean" } }
765
+ }
766
+ ]
767
+ }
768
+ };
769
+ var variantSchema = (
770
+ /** @type {{ items: { properties: Record<string, unknown> } }} */
771
+ currentDocument.properties.variants
772
+ );
773
+ variantSchema.items.properties.props = {
774
+ type: "object",
775
+ propertyNames: { $ref: "#/$defs/id" },
776
+ additionalProperties: {
777
+ type: "object",
778
+ propertyNames: PROP_TOKEN_SCHEMA,
779
+ additionalProperties: { anyOf: [PROP_TOKEN_SCHEMA, { type: "boolean" }] }
780
+ }
781
+ };
782
+ currentDocument.allOf = [
783
+ {
784
+ if: { properties: { schemaVersion: { const: "1.1.0" } }, required: ["schemaVersion"] },
785
+ else: {
786
+ properties: {
787
+ screens: { items: { not: { required: ["props"] } } },
788
+ variants: { items: { not: { required: ["props"] } } }
789
+ }
790
+ }
791
+ }
792
+ ];
793
+ var DESIGN_DOCUMENT_SCHEMA = freeze(currentDocument);
794
+ function validateDesignProps(document) {
795
+ const errors = [];
796
+ const checkToken = (value, path) => {
797
+ if (!isPropToken2(value))
798
+ errors.push(
799
+ `${path}: ${JSON.stringify(value)} must be a lowercase token matching ${PROP_TOKEN_SCHEMA.pattern} with at most ${PROP_TOKEN_SCHEMA.maxLength} characters`
800
+ );
801
+ };
802
+ const screens = new Map(document.screens.map((screen) => [screen.id, screen]));
803
+ for (const [index, screen] of document.screens.entries()) {
804
+ for (const [name, prop] of Object.entries(screen.props ?? {})) {
805
+ const path = `$.screens[${index}].props.${name}`;
806
+ checkToken(name, path);
807
+ if (prop.type === "enum") {
808
+ for (const [optionIndex, option] of prop.options.entries())
809
+ checkToken(option, `${path}.options[${optionIndex}]`);
810
+ checkToken(prop.default, `${path}.default`);
811
+ if (!prop.options.includes(prop.default))
812
+ errors.push(`${path}.default: '${prop.default}' is not an enum option`);
813
+ }
814
+ }
815
+ }
816
+ for (const [index, variant] of document.variants.entries()) {
817
+ for (const [screenId, values] of Object.entries(variant.props ?? {})) {
818
+ const screen = screens.get(screenId);
819
+ const path = `$.variants[${index}].props.${screenId}`;
820
+ if (!screen) {
821
+ errors.push(`${path}: unknown screen '${screenId}'`);
822
+ continue;
823
+ }
824
+ for (const [name, value] of Object.entries(values)) {
825
+ checkToken(name, `${path}.${name}`);
826
+ if (typeof value === "string") checkToken(value, `${path}.${name}`);
827
+ const props = screen.props ?? {};
828
+ const prop = Object.hasOwn(props, name) ? props[name] : void 0;
829
+ if (!prop) errors.push(`${path}.${name}: unknown prop '${name}' on screen '${screenId}'`);
830
+ else if (prop.type === "boolean" && typeof value !== "boolean")
831
+ errors.push(`${path}.${name}: expected a boolean, received ${JSON.stringify(value)}`);
832
+ else if (prop.type === "enum" && (typeof value !== "string" || !prop.options.includes(value)))
833
+ errors.push(`${path}.${name}: ${JSON.stringify(value)} is not an enum option`);
834
+ }
835
+ }
836
+ }
837
+ return errors;
838
+ }
839
+ function validateDesignDocument(value) {
840
+ const errors = validateJson(value, DESIGN_DOCUMENT_SCHEMA).map(
841
+ ({ path, detail }) => `${path}: ${detail}`
842
+ );
843
+ if (value?.schemaVersion === "1.0.0" && ["screens", "variants"].some(
844
+ (field) => Array.isArray(value[field]) && value[field].some((item2) => item2 && Object.hasOwn(item2, "props"))
845
+ ))
846
+ errors.push('$.schemaVersion: props require schemaVersion "1.1.0"');
847
+ if (errors.length > 0) return { ok: false, errors };
848
+ errors.push(...validateDesignProps(value));
849
+ for (const field of ["frames", "screens", "flows", "variants"]) {
850
+ const seen = /* @__PURE__ */ new Set();
851
+ for (const [index, item2] of (value[field] ?? []).entries()) {
852
+ if (seen.has(item2.id))
853
+ errors.push(`$.${field}[${index}].id: duplicate identity '${item2.id}'`);
854
+ seen.add(item2.id);
855
+ }
856
+ }
857
+ const screenIds = new Set(value.screens.map(({ id: id2 }) => id2));
858
+ const orderedIds = new Set(value.screenOrder);
859
+ for (const id2 of value.screenOrder) {
860
+ if (!screenIds.has(id2)) errors.push(`$.screenOrder: unknown screen '${id2}'`);
861
+ }
862
+ for (const id2 of screenIds) {
863
+ if (!orderedIds.has(id2)) errors.push(`$.screenOrder: missing screen '${id2}'`);
864
+ }
865
+ for (const [index, flow] of (value.flows ?? []).entries()) {
866
+ for (const id2 of flow.screens) {
867
+ if (!screenIds.has(id2)) errors.push(`$.flows[${index}].screens: unknown screen '${id2}'`);
868
+ }
869
+ }
870
+ for (const [index, variant] of value.variants.entries()) {
871
+ for (const id2 of Object.keys(variant.sources ?? {})) {
872
+ if (!screenIds.has(id2)) errors.push(`$.variants[${index}].sources: unknown screen '${id2}'`);
873
+ }
874
+ }
875
+ const frameIds = new Set(value.frames.map(({ id: id2 }) => id2));
876
+ const variantIds = new Set(value.variants.map(({ id: id2 }) => id2));
877
+ for (const [key, position] of Object.entries(value.layout?.boards ?? {})) {
878
+ const parts = key.split("/");
879
+ const path = `$.layout.boards['${key}']`;
880
+ if (parts.length > 3 || parts.some((id2) => !/^[A-Za-z][A-Za-z0-9_-]{0,127}$/.test(id2))) {
881
+ errors.push(`${path}: expected screenId, screenId/frameId or screenId/frameId/variantId`);
882
+ } else {
883
+ const [screenId, frameId, variantId] = parts;
884
+ if (!screenIds.has(screenId)) errors.push(`${path}: unknown screen '${screenId}'`);
885
+ if (frameId !== void 0 && !frameIds.has(frameId))
886
+ errors.push(`${path}: unknown frame '${frameId}'`);
887
+ if (variantId !== void 0 && !variantIds.has(variantId))
888
+ errors.push(`${path}: unknown variant '${variantId}'`);
889
+ }
890
+ for (const axis of ["x", "y"]) {
891
+ if (!Number.isFinite(position[axis]))
892
+ errors.push(`${path}.${axis}: expected a finite coordinate`);
893
+ }
894
+ }
895
+ const sectionIds = /* @__PURE__ */ new Set();
896
+ for (const [index, section] of (value.layout?.sections ?? []).entries()) {
897
+ if (sectionIds.has(section.id))
898
+ errors.push(`$.layout.sections[${index}].id: duplicate identity '${section.id}'`);
899
+ sectionIds.add(section.id);
900
+ for (const axis of ["x", "y"]) {
901
+ if (!Number.isFinite(section[axis]))
902
+ errors.push(`$.layout.sections[${index}].${axis}: expected a finite coordinate`);
903
+ }
904
+ }
905
+ const selected = value.variants.find(({ id: id2 }) => id2 === value.selectedVariant);
906
+ if (!selected) errors.push(`$.selectedVariant: unknown variant '${value.selectedVariant}'`);
907
+ else if (selected.status !== "ready")
908
+ errors.push("$.selectedVariant: selected variant must be ready");
909
+ for (const [index, spacing] of (value.designSystem?.spacing ?? []).entries()) {
910
+ if (!Number.isFinite(spacing))
911
+ errors.push(`$.designSystem.spacing[${index}]: expected a finite spacing value`);
912
+ }
913
+ return { ok: errors.length === 0, errors };
914
+ }
915
+ function assertDesignDocument(value) {
916
+ const result = validateDesignDocument(value);
917
+ if (!result.ok) throw new TypeError(`Invalid design document:
918
+ ${result.errors.join("\n")}`);
919
+ return value;
920
+ }
921
+
922
+ // packages/protocol/src/canonical-json.mjs
923
+ var hasOwn = (value, key) => Object.hasOwn(value, key);
924
+ function assertUnicodeScalarString(value, path) {
925
+ for (let index = 0; index < value.length; index += 1) {
926
+ const code = value.charCodeAt(index);
927
+ if (code >= 55296 && code <= 56319) {
928
+ const next = value.charCodeAt(index + 1);
929
+ if (!(next >= 56320 && next <= 57343)) {
930
+ throw new TypeError(`JCS cannot canonicalize a lone high surrogate at ${path}.`);
931
+ }
932
+ index += 1;
933
+ } else if (code >= 56320 && code <= 57343) {
934
+ throw new TypeError(`JCS cannot canonicalize a lone low surrogate at ${path}.`);
935
+ }
936
+ }
937
+ }
938
+ function serialize2(value, path, seen) {
939
+ if (value === null) return "null";
940
+ if (typeof value === "boolean") return value ? "true" : "false";
941
+ if (typeof value === "string") {
942
+ assertUnicodeScalarString(value, path);
943
+ return JSON.stringify(value);
944
+ }
945
+ if (typeof value === "number") {
946
+ if (!Number.isFinite(value)) throw new TypeError(`JCS requires a finite number at ${path}.`);
947
+ return JSON.stringify(value);
948
+ }
949
+ if (typeof value !== "object")
950
+ throw new TypeError(`JCS cannot canonicalize ${typeof value} at ${path}.`);
951
+ if (seen.has(value)) throw new TypeError(`JCS cannot canonicalize a cycle at ${path}.`);
952
+ seen.add(value);
953
+ try {
954
+ if (Array.isArray(value)) {
955
+ const entries2 = [];
956
+ for (let index = 0; index < value.length; index += 1) {
957
+ if (!hasOwn(value, index))
958
+ throw new TypeError(`JCS cannot canonicalize a sparse array at ${path}[${index}].`);
959
+ entries2.push(serialize2(value[index], `${path}[${index}]`, seen));
960
+ }
961
+ return `[${entries2.join(",")}]`;
962
+ }
963
+ const prototype = Object.getPrototypeOf(value);
964
+ if (prototype !== Object.prototype && prototype !== null) {
965
+ throw new TypeError(`JCS requires a plain JSON object at ${path}.`);
966
+ }
967
+ const entries = Object.keys(value).sort().map((key) => {
968
+ assertUnicodeScalarString(key, `${path} key`);
969
+ return `${JSON.stringify(key)}:${serialize2(value[key], `${path}.${key}`, seen)}`;
970
+ });
971
+ return `{${entries.join(",")}}`;
972
+ } finally {
973
+ seen.delete(value);
974
+ }
975
+ }
976
+ function canonicalizeJson(value) {
977
+ return serialize2(value, "$", /* @__PURE__ */ new Set());
978
+ }
979
+ var SHA256_K = /* @__PURE__ */ new Int32Array([
980
+ 1116352408,
981
+ 1899447441,
982
+ 3049323471,
983
+ 3921009573,
984
+ 961987163,
985
+ 1508970993,
986
+ 2453635748,
987
+ 2870763221,
988
+ 3624381080,
989
+ 310598401,
990
+ 607225278,
991
+ 1426881987,
992
+ 1925078388,
993
+ 2162078206,
994
+ 2614888103,
995
+ 3248222580,
996
+ 3835390401,
997
+ 4022224774,
998
+ 264347078,
999
+ 604807628,
1000
+ 770255983,
1001
+ 1249150122,
1002
+ 1555081692,
1003
+ 1996064986,
1004
+ 2554220882,
1005
+ 2821834349,
1006
+ 2952996808,
1007
+ 3210313671,
1008
+ 3336571891,
1009
+ 3584528711,
1010
+ 113926993,
1011
+ 338241895,
1012
+ 666307205,
1013
+ 773529912,
1014
+ 1294757372,
1015
+ 1396182291,
1016
+ 1695183700,
1017
+ 1986661051,
1018
+ 2177026350,
1019
+ 2456956037,
1020
+ 2730485921,
1021
+ 2820302411,
1022
+ 3259730800,
1023
+ 3345764771,
1024
+ 3516065817,
1025
+ 3600352804,
1026
+ 4094571909,
1027
+ 275423344,
1028
+ 430227734,
1029
+ 506948616,
1030
+ 659060556,
1031
+ 883997877,
1032
+ 958139571,
1033
+ 1322822218,
1034
+ 1537002063,
1035
+ 1747873779,
1036
+ 1955562222,
1037
+ 2024104815,
1038
+ 2227730452,
1039
+ 2361852424,
1040
+ 2428436474,
1041
+ 2756734187,
1042
+ 3204031479,
1043
+ 3329325298
1044
+ ]);
1045
+ var rotr = (value, bits) => value >>> bits | value << 32 - bits;
1046
+ function sha256Hex(value) {
1047
+ const candidate = typeof value === "string" ? new TextEncoder().encode(value) : value;
1048
+ if (!ArrayBuffer.isView(candidate) || Object.prototype.toString.call(candidate) !== "[object Uint8Array]") {
1049
+ throw new TypeError("sha256Hex expects a string or Uint8Array.");
1050
+ }
1051
+ const input = new Uint8Array(candidate.buffer, candidate.byteOffset, candidate.byteLength);
1052
+ const paddedLength = Math.ceil((input.length + 9) / 64) * 64;
1053
+ const bytes = new Uint8Array(paddedLength);
1054
+ bytes.set(input);
1055
+ bytes[input.length] = 128;
1056
+ const view = new DataView(bytes.buffer);
1057
+ const bitLength = BigInt(input.length) * 8n;
1058
+ view.setUint32(paddedLength - 8, Number(bitLength >> 32n & 0xffffffffn));
1059
+ view.setUint32(paddedLength - 4, Number(bitLength & 0xffffffffn));
1060
+ let h0 = 1779033703;
1061
+ let h1 = 3144134277;
1062
+ let h2 = 1013904242;
1063
+ let h3 = 2773480762;
1064
+ let h4 = 1359893119;
1065
+ let h5 = 2600822924;
1066
+ let h6 = 528734635;
1067
+ let h7 = 1541459225;
1068
+ const words = new Int32Array(64);
1069
+ for (let offset = 0; offset < bytes.length; offset += 64) {
1070
+ for (let index = 0; index < 16; index += 1) words[index] = view.getUint32(offset + index * 4);
1071
+ for (let index = 16; index < 64; index += 1) {
1072
+ const s0 = rotr(words[index - 15], 7) ^ rotr(words[index - 15], 18) ^ words[index - 15] >>> 3;
1073
+ const s1 = rotr(words[index - 2], 17) ^ rotr(words[index - 2], 19) ^ words[index - 2] >>> 10;
1074
+ words[index] = words[index - 16] + s0 + words[index - 7] + s1 | 0;
1075
+ }
1076
+ let a = h0;
1077
+ let b = h1;
1078
+ let c = h2;
1079
+ let d = h3;
1080
+ let e = h4;
1081
+ let f = h5;
1082
+ let g = h6;
1083
+ let h = h7;
1084
+ for (let index = 0; index < 64; index += 1) {
1085
+ const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
1086
+ const choice = e & f ^ ~e & g;
1087
+ const temp1 = h + s1 + choice + SHA256_K[index] + words[index] | 0;
1088
+ const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
1089
+ const majority = a & b ^ a & c ^ b & c;
1090
+ const temp2 = s0 + majority | 0;
1091
+ h = g;
1092
+ g = f;
1093
+ f = e;
1094
+ e = d + temp1 | 0;
1095
+ d = c;
1096
+ c = b;
1097
+ b = a;
1098
+ a = temp1 + temp2 | 0;
1099
+ }
1100
+ h0 = h0 + a | 0;
1101
+ h1 = h1 + b | 0;
1102
+ h2 = h2 + c | 0;
1103
+ h3 = h3 + d | 0;
1104
+ h4 = h4 + e | 0;
1105
+ h5 = h5 + f | 0;
1106
+ h6 = h6 + g | 0;
1107
+ h7 = h7 + h | 0;
1108
+ }
1109
+ return [h0, h1, h2, h3, h4, h5, h6, h7].map((part) => (part >>> 0).toString(16).padStart(8, "0")).join("");
1110
+ }
1111
+ function deepFreeze(value) {
1112
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
1113
+ for (const nested of Object.values(value)) deepFreeze(nested);
1114
+ Object.freeze(value);
1115
+ }
1116
+ return value;
1117
+ }
1118
+ function assertPlainDataAt(value, label, depth, seen) {
1119
+ if (depth > 64) throw new TypeError(`${label} exceeds the maximum nesting depth.`);
1120
+ if (value === null || ["string", "boolean"].includes(typeof value)) return;
1121
+ if (typeof value === "number" && Number.isFinite(value)) return;
1122
+ if (typeof value !== "object" || seen.has(value))
1123
+ throw new TypeError(`${label} must be finite, acyclic JSON.`);
1124
+ if (!Array.isArray(value) && ![Object.prototype, null].includes(Object.getPrototypeOf(value)))
1125
+ throw new TypeError(`${label} must contain only plain JSON objects.`);
1126
+ seen.add(value);
1127
+ for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value))) {
1128
+ if (["__proto__", "prototype", "constructor"].includes(key) || !Object.hasOwn(descriptor, "value"))
1129
+ throw new TypeError(`${label} contains a forbidden property.`);
1130
+ assertPlainDataAt(descriptor.value, label, depth + 1, seen);
1131
+ }
1132
+ seen.delete(value);
1133
+ }
1134
+ function assertPlainData(value, label) {
1135
+ assertPlainDataAt(value, label, 0, /* @__PURE__ */ new Set());
1136
+ }
1137
+
1138
+ // packages/protocol/src/design-review-bundle-contracts.mjs
1139
+ var DESIGN_WORKSPACE_VERSION = "1.0.0";
1140
+ var designProperties = (
1141
+ /** @type {Record<string, { items: { properties: Record<string, unknown>; required: string[] } }>} */
1142
+ structuredClone(DESIGN_DOCUMENT_V1_SCHEMA.properties)
1143
+ );
1144
+ for (const key of ["kind", "schemaVersion", "brief", "assets", "designSystem"])
1145
+ delete designProperties[key];
1146
+ delete designProperties.screens.items.properties.source;
1147
+ designProperties.screens.items.required = ["id", "title"];
1148
+ delete designProperties.variants.items.properties.sources;
1149
+ var DESIGN_REVIEW_BUNDLE_SCHEMA = {
1150
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1151
+ $id: "https://openplanr.dev/schemas/v1.9.0/design-review-bundle.schema.json",
1152
+ "x-openplanr-contract": { id: "design-review-bundle", version: "1.9.0" },
1153
+ type: "object",
1154
+ additionalProperties: false,
1155
+ properties: {
1156
+ kind: { const: "openplanr-design-review-bundle" },
1157
+ schemaVersion: { const: DESIGN_WORKSPACE_VERSION },
1158
+ design: {
1159
+ type: "object",
1160
+ additionalProperties: false,
1161
+ properties: designProperties,
1162
+ required: [
1163
+ "id",
1164
+ "title",
1165
+ "frames",
1166
+ "screens",
1167
+ "screenOrder",
1168
+ "variants",
1169
+ "selectedVariant",
1170
+ "defaultView"
1171
+ ]
1172
+ },
1173
+ envelope: {
1174
+ type: "object",
1175
+ required: ["schemaVersion", "artifacts", "viewer"]
1176
+ },
1177
+ entries: {
1178
+ type: "array",
1179
+ minItems: 1,
1180
+ maxItems: 256,
1181
+ items: {
1182
+ type: "object",
1183
+ additionalProperties: false,
1184
+ required: ["artifactId", "screenId", "variantId", "frameId"],
1185
+ properties: Object.fromEntries(
1186
+ ["artifactId", "screenId", "variantId", "frameId"].map((key) => [
1187
+ key,
1188
+ { type: "string", minLength: 1, maxLength: 128 }
1189
+ ])
1190
+ )
1191
+ }
1192
+ },
1193
+ state: {
1194
+ type: ["object", "null"],
1195
+ additionalProperties: false,
1196
+ properties: {
1197
+ positions: {
1198
+ type: "object",
1199
+ additionalProperties: {
1200
+ type: "object",
1201
+ additionalProperties: false,
1202
+ required: ["x", "y"],
1203
+ properties: {
1204
+ x: { type: "number", minimum: -1e7, maximum: 1e7 },
1205
+ y: { type: "number", minimum: -1e7, maximum: 1e7 }
1206
+ }
1207
+ }
1208
+ }
1209
+ }
1210
+ },
1211
+ revision: { type: "string", minLength: 1, maxLength: 128 },
1212
+ verification: {
1213
+ type: ["object", "null"],
1214
+ additionalProperties: false,
1215
+ properties: {
1216
+ status: { enum: ["verified", "unverified", "failed", "pending"] }
1217
+ }
1218
+ }
1219
+ },
1220
+ required: ["kind", "schemaVersion", "design", "envelope", "entries", "revision"],
1221
+ $defs: structuredClone(DESIGN_DOCUMENT_V1_SCHEMA.$defs)
1222
+ };
1223
+
641
1224
  // packages/protocol/src/review-experience-contracts.mjs
642
1225
  var text2 = { type: "string", maxLength: 16384 };
643
1226
  var id = { type: "string", minLength: 1, maxLength: 128 };
@@ -731,7 +1314,6 @@ Object.assign(bundleV12.properties, {
731
1314
  },
732
1315
  fingerprints: list(DESIGN_FINGERPRINT_SCHEMA, 4096)
733
1316
  });
734
- var DESIGN_REVIEW_BUNDLE_V12_SCHEMA = bundleV12;
735
1317
  var bundleCurrent = (
736
1318
  /** @type {MutableSchema} */
737
1319
  structuredClone(bundleV12)
@@ -746,12 +1328,12 @@ bundleCurrent.allOf = [
746
1328
  then: { properties: { envelope: bundleV12.properties.envelope } }
747
1329
  }
748
1330
  ];
749
- var currentDesign2 = (
1331
+ var currentDesign = (
750
1332
  /** @type {MutableSchema} */
751
1333
  bundleCurrent.properties.design
752
1334
  );
753
1335
  for (const key of ["frames", "layout"])
754
- currentDesign2.properties[key] = /** @type {Record<string, unknown>} */
1336
+ currentDesign.properties[key] = /** @type {Record<string, unknown>} */
755
1337
  DESIGN_DOCUMENT_V120_SCHEMA.properties[key];
756
1338
  bundleCurrent.$defs = structuredClone(DESIGN_DOCUMENT_V120_SCHEMA.$defs);
757
1339
  var currentEntries = (
@@ -786,7 +1368,6 @@ for (const key of ["screens", "variants"]) {
786
1368
  projected.items.properties.props = authored.items.properties.props;
787
1369
  }
788
1370
  propsDesign.allOf = structuredClone(DESIGN_DOCUMENT_SCHEMA.allOf);
789
- var DESIGN_REVIEW_BUNDLE_CURRENT_SCHEMA = bundleProps;
790
1371
  var item = closed(
791
1372
  {
792
1373
  pinId: id,
@@ -887,7 +1468,6 @@ Object.assign(payloadV11.properties, {
887
1468
  schemaVersion: { const: "1.1.0" },
888
1469
  category: { enum: ["question", "suggestion", "change-request", "blocker"] }
889
1470
  });
890
- var DESIGN_REVIEW_METADATA_PAYLOAD_V11_SCHEMA = payloadV11;
891
1471
  function assertReviewExperience(value, contract) {
892
1472
  const errors = validateJson(value, contract);
893
1473
  if (errors.length)
@@ -896,44 +1476,6 @@ function assertReviewExperience(value, contract) {
896
1476
  );
897
1477
  return value;
898
1478
  }
899
- function assertDesignReviewMetadata(value) {
900
- return assertReviewExperience(
901
- value,
902
- value?.schemaVersion === "1.1.0" ? DESIGN_REVIEW_METADATA_PAYLOAD_V11_SCHEMA : DESIGN_REVIEW_METADATA_PAYLOAD_SCHEMA
903
- );
904
- }
905
- function assertDesignReviewBundle(value) {
906
- if (value?.design?.schemaVersion !== "1.1.0" && ["screens", "variants"].some(
907
- (field) => Array.isArray(value?.design?.[field]) && value.design[field].some((item2) => item2 && Object.hasOwn(item2, "props"))
908
- ))
909
- throw new TypeError('Invalid design props: props require design.schemaVersion "1.1.0"');
910
- assertReviewExperience(
911
- value,
912
- value?.design?.schemaVersion !== void 0 || ["screens", "variants"].some(
913
- (field) => Array.isArray(value?.design?.[field]) && value.design[field].some((item2) => item2 && Object.hasOwn(item2, "props"))
914
- ) || value?.design?.layout !== void 0 || Array.isArray(value?.design?.frames) && value.design.frames.some(({ height }) => height === "auto") ? DESIGN_REVIEW_BUNDLE_CURRENT_SCHEMA : value?.schemaVersion === "1.2.0" ? DESIGN_REVIEW_BUNDLE_V12_SCHEMA : value?.schemaVersion === "1.1.0" ? DESIGN_REVIEW_BUNDLE_V11_SCHEMA : DESIGN_REVIEW_BUNDLE_SCHEMA
915
- );
916
- const propErrors = validateDesignProps(value.design);
917
- if (propErrors.length) throw new TypeError(`Invalid design props:
918
- ${propErrors.join("\n")}`);
919
- if (["1.1.0", "1.2.0"].includes(value.schemaVersion)) {
920
- if (value.reviewContext.designId !== value.design.id || value.contextDigest !== sha256Hex(canonicalizeJson(value.reviewContext)))
921
- throw new TypeError("Review context identity or digest does not match its published design.");
922
- const entries = new Set(
923
- value.entries.map((entry) => `${entry.screenId}:${entry.variantId}:${entry.frameId}`)
924
- );
925
- const seen = /* @__PURE__ */ new Set();
926
- for (const item2 of value.fingerprints) {
927
- const key = `${item2.screenId}:${item2.variantId}:${item2.frameId}`;
928
- if (!entries.has(key) || seen.has(key))
929
- throw new TypeError("Review fingerprints must identify distinct published artboards.");
930
- seen.add(key);
931
- }
932
- if (seen.size && seen.size !== entries.size)
933
- throw new TypeError("Review fingerprints must cover every published artboard.");
934
- }
935
- return value;
936
- }
937
1479
  var REVIEW_EXPERIENCE_SCHEMAS = Object.freeze({
938
1480
  "design-review-context": DESIGN_REVIEW_CONTEXT_SCHEMA,
939
1481
  "design-review-bundle": DESIGN_REVIEW_BUNDLE_V11_SCHEMA,
@@ -942,10 +1484,10 @@ var REVIEW_EXPERIENCE_SCHEMAS = Object.freeze({
942
1484
  });
943
1485
 
944
1486
  // packages/design/lib/design/context.mjs
945
- import { createHash as createHash3 } from "node:crypto";
946
- import { existsSync, readdirSync, readFileSync as readFileSync3, realpathSync as realpathSync3 } from "node:fs";
947
- import { dirname as dirname3, join as join2, resolve as resolve3 } from "node:path";
948
- var reviewDigest = (value) => createHash3("sha256").update(canonicalizeJson(value)).digest("hex");
1487
+ import { createHash as createHash2 } from "node:crypto";
1488
+ import { existsSync, readdirSync, readFileSync as readFileSync2, realpathSync as realpathSync2 } from "node:fs";
1489
+ import { dirname as dirname2, join, resolve as resolve2 } from "node:path";
1490
+ var reviewDigest = (value) => createHash2("sha256").update(canonicalizeJson(value)).digest("hex");
949
1491
  function emptyReviewContext(document) {
950
1492
  return {
951
1493
  kind: "openplanr-design-review-context",
@@ -956,10 +1498,10 @@ function emptyReviewContext(document) {
956
1498
  };
957
1499
  }
958
1500
  function loadReviewContext(root, document, { readSource } = {}) {
959
- const file = join2(root, "review-context.json");
1501
+ const file = join(root, "review-context.json");
960
1502
  if (!existsSync(file)) return emptyReviewContext(document);
961
1503
  const context = JSON.parse(
962
- readSource ? readSource("review-context.json", root).value.toString("utf8") : readFileSync3(resolveLocalDocumentFile(root, "review-context.json"), "utf8")
1504
+ readSource ? readSource("review-context.json", root).value.toString("utf8") : readFileSync2(resolveLocalDocumentFile(root, "review-context.json"), "utf8")
963
1505
  );
964
1506
  assertReviewExperience(context, DESIGN_REVIEW_CONTEXT_SCHEMA);
965
1507
  if (context.designId !== document.id)
@@ -1054,13 +1596,13 @@ function bundleDesignRevision(current, state = {}) {
1054
1596
  fingerprints: current.fingerprints ?? []
1055
1597
  };
1056
1598
  }
1057
- var localRoot = (file) => realpathSync3(dirname3(resolve3(file)));
1599
+ var localRoot = (file) => realpathSync2(dirname2(resolve2(file)));
1058
1600
  function listDesignRevisions(file) {
1059
1601
  const root = localRoot(file);
1060
- const pointer = JSON.parse(readFileSync3(join2(root, ".design/current.json"), "utf8"));
1061
- const revisions = readdirSync(join2(root, ".design/revisions")).filter((name) => /^[a-f0-9]{64}$/u.test(name)).map((revision) => {
1602
+ const pointer = JSON.parse(readFileSync2(join(root, ".design/current.json"), "utf8"));
1603
+ const revisions = readdirSync(join(root, ".design/revisions")).filter((name) => /^[a-f0-9]{64}$/u.test(name)).map((revision) => {
1062
1604
  const value = JSON.parse(
1063
- readFileSync3(join2(root, ".design/revisions", revision, "render.json"), "utf8")
1605
+ readFileSync2(join(root, ".design/revisions", revision, "render.json"), "utf8")
1064
1606
  );
1065
1607
  return {
1066
1608
  revision,
@@ -1075,7 +1617,7 @@ function readDesignRevision(file, revision) {
1075
1617
  if (!/^[a-f0-9]{64}$/u.test(revision)) throw new Error("Invalid design revision identity.");
1076
1618
  const root = localRoot(file);
1077
1619
  const value = JSON.parse(
1078
- readFileSync3(
1620
+ readFileSync2(
1079
1621
  resolveLocalDocumentFile(root, `.design/revisions/${revision}/render.json`),
1080
1622
  "utf8"
1081
1623
  )
@@ -1090,24 +1632,21 @@ export {
1090
1632
  inspectLocalDocumentBody,
1091
1633
  resolveLocalDocumentFile,
1092
1634
  bundleLocalDocument,
1635
+ initialFrameHeight,
1636
+ DESIGN_DOCUMENT_SCHEMA,
1637
+ validateDesignProps,
1638
+ assertDesignDocument,
1639
+ canonicalizeJson,
1640
+ sha256Hex,
1641
+ deepFreeze,
1642
+ assertPlainData,
1093
1643
  DESIGN_HANDOFF_CONTENT_SCHEMA,
1094
1644
  DESIGN_HANDOFF_SCHEMA,
1095
1645
  assertReviewExperience,
1096
- assertDesignReviewMetadata,
1097
- assertDesignReviewBundle,
1098
1646
  reviewDigest,
1099
1647
  emptyReviewContext,
1100
1648
  loadReviewContext,
1101
1649
  reviewFingerprints,
1102
- bundleDesignRevision,
1103
1650
  listDesignRevisions,
1104
- readDesignRevision,
1105
- hash,
1106
- json,
1107
- readJson,
1108
- atomicJson,
1109
- atomicBytes,
1110
- recoverDesignPublication,
1111
- designSpecPath,
1112
- currentDesign
1651
+ readDesignRevision
1113
1652
  };