openplanr 2.2640.8 → 2.2640.9

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 (186) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/dashboard/.vite/manifest.json +1 -1
  3. package/dist/dashboard/assets/{index-COZ36pFn.js → index-D7R6tnlX.js} +2 -2
  4. package/dist/dashboard/assets/{index-COZ36pFn.js.map → index-D7R6tnlX.js.map} +1 -1
  5. package/dist/dashboard/dashboard-manifest.json +8 -8
  6. package/dist/dashboard/index.html +1 -1
  7. package/lib/host-packages/adapter-registry.json +5 -5
  8. package/lib/host-packages/capability-map.json +1 -1
  9. package/lib/host-packages/claude/.claude-plugin/marketplace.json +2 -2
  10. package/lib/host-packages/claude/openplanr/.claude-plugin/plugin.json +1 -1
  11. package/lib/host-packages/claude/openplanr/.openplanr-content.json +165 -33
  12. package/lib/host-packages/claude/openplanr/README.md +22 -1
  13. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-artifact-shell.mjs +3 -11
  14. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +555 -0
  15. package/lib/host-packages/claude/openplanr/runtime/design/scripts/{design-pako-esm.mjs → design-compression.mjs} +2 -1521
  16. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-document.mjs +133 -12
  17. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-encrypted-workspace-client.mjs +647 -0
  18. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-entities.mjs +17 -67
  19. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-handoff.mjs +14 -16
  20. package/lib/host-packages/claude/openplanr/runtime/design/scripts/{design-planr-home.mjs → design-loopback-server.mjs} +15 -36
  21. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-owner-custody.mjs +121 -0
  22. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-resource-pack.mjs +698 -0
  23. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-review.mjs +798 -796
  24. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-runtime-home.mjs +39 -0
  25. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-runtime-support-5cb7531bede8.mjs +24 -0
  26. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-share.mjs +138 -765
  27. package/lib/host-packages/claude/openplanr/runtime/design/scripts/{design-escape.mjs → design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs} +158 -156
  28. package/lib/host-packages/{openai/openplanr/runtime/design/scripts/design-artifact-sources.mjs → claude/openplanr/runtime/design/scripts/design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs} +1 -1
  29. package/lib/host-packages/{openai/openplanr/runtime/design/scripts/design-bounded-json-data.mjs → claude/openplanr/runtime/design/scripts/design-shared-protocol-contracts-31a760fc.mjs} +241 -454
  30. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-protocol-contracts-75a938cc.mjs +222 -0
  31. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-upload-spool.mjs +198 -0
  32. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design.mjs +12 -5
  33. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/01-module-runtime.js +18 -0
  34. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/02-artifact-review-ui.js +809 -0
  35. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +5193 -0
  36. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-compression.js +4175 -0
  37. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/05-artifact-sharing.js +65 -0
  38. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/06-artifact-review-ui.js +1755 -0
  39. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/07-artifact-sharing.js +62 -0
  40. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/08-artifact-review-ui.js +2600 -0
  41. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +123 -0
  42. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/package.json +3 -3
  43. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/01-module-runtime.js +34 -0
  44. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +992 -0
  45. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/03-react-dom-client-fiber-foundations.js +2513 -0
  46. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/04-react-dom-client-reconciliation-hooks.js +1919 -0
  47. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/05-react-dom-client-render-phases.js +1759 -0
  48. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/06-react-dom-client-commit-effects.js +1551 -0
  49. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/07-react-dom-client-work-loop-scheduling.js +1121 -0
  50. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/08-react-dom-client-dom-events-properties-hydration.js +2183 -0
  51. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +705 -0
  52. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/10-react.js +27 -0
  53. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/11-artifact-review-ui.js +13 -0
  54. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +3561 -0
  55. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-studio-shell.js +184 -0
  56. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/14-interface-primitives.js +5045 -0
  57. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-interface-primitives.js +1698 -0
  58. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-studio-shell.js +455 -0
  59. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/17-design-studio.js +1844 -0
  60. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +257 -0
  61. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +1 -1
  62. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +4966 -0
  63. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/design.mjs +240 -5192
  64. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +1 -1
  65. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/backend-diagnostics.mjs +6 -2
  66. package/lib/host-packages/cursor/openplanr/.openplanr-content.json +164 -32
  67. package/lib/host-packages/cursor/openplanr/manifest.json +1 -1
  68. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/backend-diagnostics.mjs +6 -2
  69. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-artifact-shell.mjs +3 -11
  70. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +555 -0
  71. package/lib/host-packages/{openai/openplanr/runtime/design/scripts/design-pako-esm.mjs → cursor/openplanr/runtime/design/scripts/design-compression.mjs} +2 -1521
  72. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-document.mjs +133 -12
  73. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-encrypted-workspace-client.mjs +647 -0
  74. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-entities.mjs +17 -67
  75. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-handoff.mjs +14 -16
  76. package/lib/host-packages/{openai/openplanr/runtime/design/scripts/design-planr-home.mjs → cursor/openplanr/runtime/design/scripts/design-loopback-server.mjs} +15 -36
  77. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-owner-custody.mjs +121 -0
  78. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-resource-pack.mjs +698 -0
  79. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-review.mjs +798 -796
  80. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-runtime-home.mjs +39 -0
  81. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-runtime-support-5cb7531bede8.mjs +24 -0
  82. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-share.mjs +138 -765
  83. package/lib/host-packages/{openai/openplanr/runtime/design/scripts/design-escape.mjs → cursor/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs} +158 -156
  84. package/lib/host-packages/{claude/openplanr/runtime/design/scripts/design-artifact-sources.mjs → cursor/openplanr/runtime/design/scripts/design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs} +1 -1
  85. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/{design-bounded-json-data.mjs → design-shared-protocol-contracts-31a760fc.mjs} +241 -454
  86. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-protocol-contracts-75a938cc.mjs +222 -0
  87. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-upload-spool.mjs +198 -0
  88. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design.mjs +12 -5
  89. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/01-module-runtime.js +18 -0
  90. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/02-artifact-review-ui.js +809 -0
  91. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +5193 -0
  92. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-compression.js +4175 -0
  93. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/05-artifact-sharing.js +65 -0
  94. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/06-artifact-review-ui.js +1755 -0
  95. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/07-artifact-sharing.js +62 -0
  96. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/08-artifact-review-ui.js +2600 -0
  97. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +123 -0
  98. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/package.json +3 -3
  99. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/01-module-runtime.js +34 -0
  100. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +992 -0
  101. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/03-react-dom-client-fiber-foundations.js +2513 -0
  102. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/04-react-dom-client-reconciliation-hooks.js +1919 -0
  103. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/05-react-dom-client-render-phases.js +1759 -0
  104. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/06-react-dom-client-commit-effects.js +1551 -0
  105. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/07-react-dom-client-work-loop-scheduling.js +1121 -0
  106. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/08-react-dom-client-dom-events-properties-hydration.js +2183 -0
  107. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +705 -0
  108. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/10-react.js +27 -0
  109. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/11-artifact-review-ui.js +13 -0
  110. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +3561 -0
  111. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-studio-shell.js +184 -0
  112. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/14-interface-primitives.js +5045 -0
  113. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-interface-primitives.js +1698 -0
  114. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-studio-shell.js +455 -0
  115. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/17-design-studio.js +1844 -0
  116. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +257 -0
  117. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +1 -1
  118. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +4966 -0
  119. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/design.mjs +240 -5192
  120. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +1 -1
  121. package/lib/host-packages/openai/.claude-plugin/marketplace.json +2 -2
  122. package/lib/host-packages/openai/openplanr/.codex-plugin/plugin.json +1 -1
  123. package/lib/host-packages/openai/openplanr/.openplanr-content.json +164 -32
  124. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-artifact-shell.mjs +3 -11
  125. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +555 -0
  126. package/lib/host-packages/{cursor/openplanr/runtime/design/scripts/design-pako-esm.mjs → openai/openplanr/runtime/design/scripts/design-compression.mjs} +2 -1521
  127. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-document.mjs +133 -12
  128. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-encrypted-workspace-client.mjs +647 -0
  129. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-entities.mjs +17 -67
  130. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-handoff.mjs +14 -16
  131. package/lib/host-packages/{cursor/openplanr/runtime/design/scripts/design-planr-home.mjs → openai/openplanr/runtime/design/scripts/design-loopback-server.mjs} +15 -36
  132. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-owner-custody.mjs +121 -0
  133. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-resource-pack.mjs +698 -0
  134. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-review.mjs +798 -796
  135. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-runtime-home.mjs +39 -0
  136. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-runtime-support-5cb7531bede8.mjs +24 -0
  137. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-share.mjs +138 -765
  138. package/lib/host-packages/{cursor/openplanr/runtime/design/scripts/design-escape.mjs → openai/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs} +158 -156
  139. package/lib/host-packages/{cursor/openplanr/runtime/design/scripts/design-artifact-sources.mjs → openai/openplanr/runtime/design/scripts/design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs} +1 -1
  140. package/lib/host-packages/{claude/openplanr/runtime/design/scripts/design-bounded-json-data.mjs → openai/openplanr/runtime/design/scripts/design-shared-protocol-contracts-31a760fc.mjs} +241 -454
  141. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-protocol-contracts-75a938cc.mjs +222 -0
  142. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-upload-spool.mjs +198 -0
  143. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design.mjs +12 -5
  144. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/01-module-runtime.js +18 -0
  145. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/02-artifact-review-ui.js +809 -0
  146. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +5193 -0
  147. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/04-compression.js +4175 -0
  148. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/05-artifact-sharing.js +65 -0
  149. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/06-artifact-review-ui.js +1755 -0
  150. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/07-artifact-sharing.js +62 -0
  151. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/08-artifact-review-ui.js +2600 -0
  152. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +123 -0
  153. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/package.json +3 -3
  154. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/01-module-runtime.js +34 -0
  155. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +992 -0
  156. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/03-react-dom-client-fiber-foundations.js +2513 -0
  157. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/04-react-dom-client-reconciliation-hooks.js +1919 -0
  158. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/05-react-dom-client-render-phases.js +1759 -0
  159. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/06-react-dom-client-commit-effects.js +1551 -0
  160. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/07-react-dom-client-work-loop-scheduling.js +1121 -0
  161. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/08-react-dom-client-dom-events-properties-hydration.js +2183 -0
  162. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +705 -0
  163. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/10-react.js +27 -0
  164. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/11-artifact-review-ui.js +13 -0
  165. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +3561 -0
  166. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-studio-shell.js +184 -0
  167. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/14-interface-primitives.js +5045 -0
  168. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-interface-primitives.js +1698 -0
  169. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-studio-shell.js +455 -0
  170. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/17-design-studio.js +1844 -0
  171. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +257 -0
  172. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +1 -1
  173. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +4966 -0
  174. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/design.mjs +240 -5192
  175. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +1 -1
  176. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/backend-diagnostics.mjs +6 -2
  177. package/package.json +2 -2
  178. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-generated-b0798298053515fd.mjs +0 -18
  179. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +0 -5
  180. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js +0 -25597
  181. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-generated-b0798298053515fd.mjs +0 -18
  182. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +0 -5
  183. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js +0 -25597
  184. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-generated-b0798298053515fd.mjs +0 -18
  185. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js +0 -5
  186. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js +0 -25597
@@ -6,21 +6,31 @@ import {
6
6
  currentDesign,
7
7
  hash,
8
8
  readJson
9
- } from "./design-escape.mjs";
9
+ } from "./design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs";
10
+ import {
11
+ createEncryptedWorkspaceClient,
12
+ createWorkspaceAddress
13
+ } from "./design-encrypted-workspace-client.mjs";
10
14
  import {
11
15
  copyUploadSpool,
12
- createChunkedWorkspaceClient,
13
- ensurePrivateDirectory,
14
16
  persistUploadSpool,
17
+ spoolChunkReader
18
+ } from "./design-upload-spool.mjs";
19
+ import {
20
+ createChunkedWorkspaceClient
21
+ } from "./design-chunked-workspace-client.mjs";
22
+ import {
23
+ ensurePrivateDirectory,
15
24
  readCustody,
16
- spoolChunkReader,
17
25
  writeCustody
18
- } from "./design-pako-esm.mjs";
26
+ } from "./design-owner-custody.mjs";
19
27
  import {
20
- acquireStartLock,
21
28
  configuredPlanrHome,
22
29
  planrHome
23
- } from "./design-planr-home.mjs";
30
+ } from "./design-runtime-home.mjs";
31
+ import {
32
+ acquireStartLock
33
+ } from "./design-loopback-server.mjs";
24
34
  import {
25
35
  ARTIFACT_ERROR_CODES,
26
36
  PipelineError,
@@ -28,7 +38,7 @@ import {
28
38
  digestArtifactEnvelope,
29
39
  validateArtifactEnvelope,
30
40
  validateArtifactReview
31
- } from "./design-artifact-sources.mjs";
41
+ } from "./design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs";
32
42
  import {
33
43
  DESIGN_WORKSPACE_API,
34
44
  DESIGN_WORKSPACE_CREATE_SCHEMA,
@@ -38,11 +48,93 @@ import {
38
48
  DESIGN_WORKSPACE_REVISION_SCHEMA,
39
49
  DESIGN_WORKSPACE_SCHEMA,
40
50
  DESIGN_WORKSPACE_VERSION,
41
- assertWorkspaceContract,
51
+ assertWorkspaceContract
52
+ } from "./design-shared-protocol-contracts-31a760fc.mjs";
53
+ import {
42
54
  canonicalizeJson,
43
55
  deepFreeze,
44
56
  sha256Hex
45
- } from "./design-bounded-json-data.mjs";
57
+ } from "./design-shared-protocol-contracts-75a938cc.mjs";
58
+
59
+ // packages/design/lib/design/share-status.mjs
60
+ import { existsSync, realpathSync } from "node:fs";
61
+ import { homedir } from "node:os";
62
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
63
+
64
+ // packages/design/lib/design/workspace-address.mjs
65
+ var DESIGN_SHARE_BASE_URL = "https://share.openplanr.dev";
66
+ var DESIGN_SHARE_REVIEW_PATH = "/d";
67
+ var address = createWorkspaceAddress({
68
+ label: "Design",
69
+ reviewPath: DESIGN_SHARE_REVIEW_PATH,
70
+ defaultBaseUrl: DESIGN_SHARE_BASE_URL
71
+ });
72
+ var normalizeWorkspaceBase = address.normalizeWorkspaceBase;
73
+ var workspaceReviewUrl = (access) => `${address.workspaceReviewUrl(access)}${access.schemaVersion === "2.0.0" ? "?v=2" : ""}`;
74
+
75
+ // packages/design/lib/design/share-status.mjs
76
+ var FORMAT = "openplanr-design-owner-custody";
77
+ function custodyLocation(file, options = {}, { allowMissing = false } = {}) {
78
+ const current = currentDesign(file, options);
79
+ const env = options.env ?? process.env;
80
+ const root = resolve(options.custodyRoot ?? join(planrHome(env), "design-shares"));
81
+ let project = current.root;
82
+ for (let candidate = current.root; dirname(candidate) !== candidate; candidate = dirname(candidate)) {
83
+ if (existsSync(join(candidate, ".git")) || existsSync(join(candidate, ".planr"))) {
84
+ project = candidate;
85
+ break;
86
+ }
87
+ }
88
+ const key = hash(`${current.root}
89
+ ${current.document.id}`);
90
+ const path = join(root, `${key}.json`);
91
+ const within = relative(project, root);
92
+ if ((!allowMissing || existsSync(path)) && (within === "" || !within.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) && within !== ".." && !isAbsolute(within)))
93
+ throw new Error(
94
+ "Design owner credentials must be stored outside the project. Set PLANR_HOME to a private user-level directory."
95
+ );
96
+ const legacyPath = !options.custodyRoot && !configuredPlanrHome(env) ? join(realpathSync(env.HOME || homedir()), ".openplanr", "design-shares", `${key}.json`) : null;
97
+ return { root, path, current, legacyPath };
98
+ }
99
+ function presentationFingerprint(current) {
100
+ const state = readJson(join(current.root, ".design/studio-state.json"), { state: {} }).state;
101
+ return hash(
102
+ JSON.stringify({
103
+ revision: current.revision,
104
+ selectedVariant: state.selectedVariant ?? current.document.selectedVariant,
105
+ positions: state.positions ?? {},
106
+ verification: current.verification.status
107
+ })
108
+ );
109
+ }
110
+ var safeStatus = (record, current) => ({
111
+ ok: true,
112
+ shared: Boolean(record),
113
+ title: current.document.title,
114
+ localRevision: current.revision,
115
+ retention: "until-revoked",
116
+ ...record ? {
117
+ id: record.custody.id,
118
+ url: workspaceReviewUrl(record.custody),
119
+ revision: record.custody.currentRevision ?? record.publishedRevision ?? null,
120
+ publishedRevision: record.publishedRevision ?? null,
121
+ hasUpdate: record.publishedRevision !== current.revision || record.publishedPresentation !== presentationFingerprint(current),
122
+ epoch: record.custody.epoch,
123
+ commentsPaused: Boolean(record.custody.commentsPaused ?? record.commentsPaused),
124
+ revoked: Boolean(record.revoked),
125
+ deleted: Boolean(record.deleted),
126
+ pending: Boolean(
127
+ record.custody.pendingCreate || record.custody.pendingMutation || record.pendingReviewMetadata?.length
128
+ ),
129
+ pendingAction: record.custody.pendingCreate ? "create" : record.custody.pendingMutation?.action ?? (record.pendingReviewMetadata?.length ? "review-metadata" : null),
130
+ pendingReviewMetadata: Boolean(record.pendingReviewMetadata?.length)
131
+ } : {}
132
+ });
133
+ function getDesignShareStatus(file, options = {}) {
134
+ const { path, current, legacyPath } = custodyLocation(file, options);
135
+ const record = readCustody(path, { label: "Design", format: FORMAT }) ?? (legacyPath ? readCustody(legacyPath, { label: "Design", format: FORMAT }) : null);
136
+ return safeStatus(record, current);
137
+ }
46
138
 
47
139
  // packages/design/lib/design/share.mjs
48
140
  import {
@@ -59,18 +151,18 @@ import { basename, dirname as dirname4, join as join3, resolve as resolve3 } fro
59
151
 
60
152
  // packages/artifact/lib/artifact/import.mjs
61
153
  import {
62
- existsSync as existsSync2,
154
+ existsSync as existsSync3,
63
155
  lstatSync as lstatSync2,
64
156
  mkdirSync as mkdirSync2,
65
157
  readFileSync as readFileSync2,
66
- realpathSync,
158
+ realpathSync as realpathSync2,
67
159
  renameSync as renameSync2,
68
160
  rmSync as rmSync2,
69
161
  statSync as statSync2,
70
162
  writeFileSync as writeFileSync2
71
163
  } from "node:fs";
72
- import { homedir } from "node:os";
73
- import { dirname as dirname2, isAbsolute, join, relative, resolve } from "node:path";
164
+ import { homedir as homedir2 } from "node:os";
165
+ import { dirname as dirname3, isAbsolute as isAbsolute2, join as join2, relative as relative2, resolve as resolve2 } from "node:path";
74
166
 
75
167
  // packages/artifact/lib/artifact/internal/feedback.mjs
76
168
  var FEEDBACK_FILE = "feedback.json";
@@ -308,7 +400,7 @@ function effectiveReviewDecision(value) {
308
400
  // packages/artifact/lib/artifact/review.mjs
309
401
  import { randomBytes, randomUUID } from "node:crypto";
310
402
  import {
311
- existsSync,
403
+ existsSync as existsSync2,
312
404
  lstatSync,
313
405
  mkdirSync,
314
406
  readFileSync,
@@ -317,7 +409,7 @@ import {
317
409
  statSync,
318
410
  writeFileSync
319
411
  } from "node:fs";
320
- import { dirname } from "node:path";
412
+ import { dirname as dirname2 } from "node:path";
321
413
  var ARTIFACT_REVIEW_MAX_STATE_BYTES = 5 * 1024 * 1024;
322
414
  var reviewPathQueues = /* @__PURE__ */ new Map();
323
415
  function finalEntry(path, fs = { lstatSync }) {
@@ -412,7 +504,7 @@ function readArtifactReviewState(path, { allowMissing = false } = {}) {
412
504
  }
413
505
  function writeArtifactReviewState(path, ledger, { fileSystem = {}, suffix = `${process.pid}.${randomBytes(8).toString("hex")}` } = {}) {
414
506
  validateReviewLedger(ledger);
415
- const fs = { existsSync, lstatSync, mkdirSync, writeFileSync, renameSync, rmSync, ...fileSystem };
507
+ const fs = { existsSync: existsSync2, lstatSync, mkdirSync, writeFileSync, renameSync, rmSync, ...fileSystem };
416
508
  const temporary = `${path}.${suffix}.tmp`;
417
509
  const serialized = serializeReviewState(ledger);
418
510
  if (Buffer.byteLength(serialized, "utf8") > ARTIFACT_REVIEW_MAX_STATE_BYTES) {
@@ -427,7 +519,7 @@ function writeArtifactReviewState(path, ledger, { fileSystem = {}, suffix = `${p
427
519
  const target = initial;
428
520
  if (target.isSymbolicLink() || !target.isFile()) throw new Error("unsafe final target");
429
521
  }
430
- fs.mkdirSync(dirname(path), { recursive: true, mode: 448 });
522
+ fs.mkdirSync(dirname2(path), { recursive: true, mode: 448 });
431
523
  fs.writeFileSync(temporary, serialized, { mode: 384, flag: "wx" });
432
524
  const final = finalEntry(path, fs);
433
525
  if (final) {
@@ -588,12 +680,12 @@ function pathEntry(path, fs = { lstatSync: lstatSync2 }) {
588
680
  }
589
681
  }
590
682
  function inside(base, candidate) {
591
- const rel = relative(base, candidate);
592
- return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
683
+ const rel = relative2(base, candidate);
684
+ return rel === "" || !rel.startsWith("..") && !isAbsolute2(rel);
593
685
  }
594
686
  function parseablePlanrConfig(root) {
595
- const path = join(root, ".planr", "config.json");
596
- if (!existsSync2(path)) return false;
687
+ const path = join2(root, ".planr", "config.json");
688
+ if (!existsSync3(path)) return false;
597
689
  try {
598
690
  if (lstatSync2(path).isSymbolicLink()) return false;
599
691
  const value = JSON.parse(readFileSync2(path, "utf8"));
@@ -603,20 +695,20 @@ function parseablePlanrConfig(root) {
603
695
  }
604
696
  }
605
697
  function hasGitMarker(root) {
606
- const marker = join(root, ".git");
607
- if (!existsSync2(marker)) return false;
698
+ const marker = join2(root, ".git");
699
+ if (!existsSync3(marker)) return false;
608
700
  try {
609
701
  const stat = lstatSync2(marker);
610
702
  if (stat.isSymbolicLink()) return false;
611
703
  if (stat.isDirectory()) {
612
- const head = join(marker, "HEAD");
613
- return existsSync2(head) && lstatSync2(head).isFile();
704
+ const head = join2(marker, "HEAD");
705
+ return existsSync3(head) && lstatSync2(head).isFile();
614
706
  }
615
707
  if (!stat.isFile() || stat.size > 4096) return false;
616
708
  const match = /^gitdir:\s*(.+?)\s*$/u.exec(readFileSync2(marker, "utf8"));
617
709
  if (!match) return false;
618
- const gitDir = resolve(root, match[1]);
619
- return existsSync2(gitDir) && statSync2(gitDir).isDirectory() && existsSync2(join(gitDir, "HEAD")) && lstatSync2(join(gitDir, "HEAD")).isFile();
710
+ const gitDir = resolve2(root, match[1]);
711
+ return existsSync3(gitDir) && statSync2(gitDir).isDirectory() && existsSync3(join2(gitDir, "HEAD")) && lstatSync2(join2(gitDir, "HEAD")).isFile();
620
712
  } catch {
621
713
  return false;
622
714
  }
@@ -624,37 +716,37 @@ function hasGitMarker(root) {
624
716
  function findArtifactProjectRoot(start = process.cwd(), { env = process.env } = {}) {
625
717
  let current;
626
718
  try {
627
- current = realpathSync(resolve(start));
719
+ current = realpathSync2(resolve2(start));
628
720
  } catch {
629
721
  pathError(
630
722
  ARTIFACT_ERROR_CODES.REVIEW_IMPORT,
631
723
  "Artifact review working directory does not exist."
632
724
  );
633
725
  }
634
- const homeCandidate = resolve(env.HOME ?? homedir());
726
+ const homeCandidate = resolve2(env.HOME ?? homedir2());
635
727
  let home = homeCandidate;
636
728
  try {
637
- home = realpathSync(homeCandidate);
729
+ home = realpathSync2(homeCandidate);
638
730
  } catch {
639
731
  }
640
732
  while (true) {
641
733
  if (current !== home && (parseablePlanrConfig(current) || hasGitMarker(current)))
642
734
  return current;
643
- const parent = dirname2(current);
735
+ const parent = dirname3(current);
644
736
  if (parent === current) return null;
645
737
  current = parent;
646
738
  }
647
739
  }
648
740
  function assertSafeDestination(base, relativeParts) {
649
- const absoluteBase = resolve(base);
650
- if (existsSync2(absoluteBase) && lstatSync2(absoluteBase).isSymbolicLink()) {
741
+ const absoluteBase = resolve2(base);
742
+ if (existsSync3(absoluteBase) && lstatSync2(absoluteBase).isSymbolicLink()) {
651
743
  pathError(
652
744
  ARTIFACT_ERROR_CODES.SYMLINK_ESCAPE,
653
745
  "Artifact review destination base is a symlink."
654
746
  );
655
747
  }
656
748
  let realBase = absoluteBase;
657
- if (existsSync2(absoluteBase)) realBase = realpathSync(absoluteBase);
749
+ if (existsSync3(absoluteBase)) realBase = realpathSync2(absoluteBase);
658
750
  let current = absoluteBase;
659
751
  for (const part of relativeParts) {
660
752
  if (!part || part === "." || part === ".." || part.includes("/") || part.includes("\\") || part.includes("\0")) {
@@ -663,7 +755,7 @@ function assertSafeDestination(base, relativeParts) {
663
755
  "Artifact review destination contains an unsafe segment."
664
756
  );
665
757
  }
666
- current = join(current, part);
758
+ current = join2(current, part);
667
759
  const entry = pathEntry(current);
668
760
  if (!entry) continue;
669
761
  if (entry.isSymbolicLink()) {
@@ -672,7 +764,7 @@ function assertSafeDestination(base, relativeParts) {
672
764
  "Artifact review destination contains a symlink."
673
765
  );
674
766
  }
675
- if (!inside(realBase, realpathSync(current))) {
767
+ if (!inside(realBase, realpathSync2(current))) {
676
768
  pathError(
677
769
  ARTIFACT_ERROR_CODES.PATH_TRAVERSAL,
678
770
  "Artifact review destination escapes its storage root."
@@ -700,8 +792,8 @@ function resolveArtifactReviewDestination({
700
792
  );
701
793
  }
702
794
  if (designDir !== void 0) {
703
- const lexical = resolve(designDir);
704
- if (!existsSync2(lexical) || !statSync2(lexical).isDirectory()) {
795
+ const lexical = resolve2(designDir);
796
+ if (!existsSync3(lexical) || !statSync2(lexical).isDirectory()) {
705
797
  pathError(ARTIFACT_ERROR_CODES.REVIEW_IMPORT, "Design review destination does not exist.");
706
798
  }
707
799
  if (lstatSync2(lexical).isSymbolicLink()) {
@@ -710,13 +802,13 @@ function resolveArtifactReviewDestination({
710
802
  "Design review destination must be a real directory."
711
803
  );
712
804
  }
713
- const requested = realpathSync(lexical);
805
+ const requested = realpathSync2(lexical);
714
806
  return Object.freeze({
715
807
  kind: "design",
716
808
  artifactId,
717
809
  directory: requested,
718
- path: join(requested, FEEDBACK_FILE),
719
- reviewStatePath: join(requested, "artifact-review-state.json")
810
+ path: join2(requested, FEEDBACK_FILE),
811
+ reviewStatePath: join2(requested, "artifact-review-state.json")
720
812
  });
721
813
  }
722
814
  const projectRoot = findArtifactProjectRoot(cwd, { env });
@@ -727,17 +819,17 @@ function resolveArtifactReviewDestination({
727
819
  artifactId,
728
820
  root: projectRoot,
729
821
  directory: directory2,
730
- path: join(directory2, "review-state.json")
822
+ path: join2(directory2, "review-state.json")
731
823
  });
732
824
  }
733
- const root = resolve(planrHome(env));
825
+ const root = resolve2(planrHome(env));
734
826
  const directory = assertSafeDestination(root, ["artifacts", artifactId]);
735
827
  return Object.freeze({
736
828
  kind: "user",
737
829
  artifactId,
738
830
  root,
739
831
  directory,
740
- path: join(directory, "review-state.json")
832
+ path: join2(directory, "review-state.json")
741
833
  });
742
834
  }
743
835
  function reviewsFromDecoded(value) {
@@ -820,724 +912,6 @@ async function decodeArtifactReviewSources(sources, { decodeSource, withMetadata
820
912
  return withMetadata ? entries : entries.map((entry) => entry.review);
821
913
  }
822
914
 
823
- // packages/design/lib/design/share-status.mjs
824
- import { existsSync as existsSync3, realpathSync as realpathSync2 } from "node:fs";
825
- import { homedir as homedir2 } from "node:os";
826
- import { dirname as dirname3, isAbsolute as isAbsolute2, join as join2, relative as relative2, resolve as resolve2 } from "node:path";
827
-
828
- // packages/artifact/lib/artifact/internal/workspace-address.mjs
829
- function createWorkspaceAddress({
830
- label,
831
- reviewPath,
832
- defaultBaseUrl = "https://share.openplanr.dev"
833
- }) {
834
- function normalizeWorkspaceBase2(baseUrl = defaultBaseUrl) {
835
- const url = new URL(baseUrl);
836
- if (url.username || url.password || url.search || url.hash || url.pathname !== "/" || url.protocol !== "https:" && !(url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname)))
837
- throw new TypeError(
838
- `${label} sharing requires an HTTPS origin or a local development server.`
839
- );
840
- return url.origin;
841
- }
842
- function workspaceReviewUrl2(access) {
843
- if (!/^[A-Za-z0-9_-]{22,64}$/.test(access.id))
844
- throw new TypeError(`Invalid ${label.toLowerCase()} workspace identity.`);
845
- return `${normalizeWorkspaceBase2(access.baseUrl)}${reviewPath}/${access.id}`;
846
- }
847
- return { normalizeWorkspaceBase: normalizeWorkspaceBase2, workspaceReviewUrl: workspaceReviewUrl2 };
848
- }
849
-
850
- // packages/design/lib/design/workspace-address.mjs
851
- var DESIGN_SHARE_BASE_URL = "https://share.openplanr.dev";
852
- var DESIGN_SHARE_REVIEW_PATH = "/d";
853
- var address = createWorkspaceAddress({
854
- label: "Design",
855
- reviewPath: DESIGN_SHARE_REVIEW_PATH,
856
- defaultBaseUrl: DESIGN_SHARE_BASE_URL
857
- });
858
- var normalizeWorkspaceBase = address.normalizeWorkspaceBase;
859
- var workspaceReviewUrl = (access) => `${address.workspaceReviewUrl(access)}${access.schemaVersion === "2.0.0" ? "?v=2" : ""}`;
860
-
861
- // packages/design/lib/design/share-status.mjs
862
- var FORMAT = "openplanr-design-owner-custody";
863
- function custodyLocation(file, options = {}, { allowMissing = false } = {}) {
864
- const current = currentDesign(file, options);
865
- const env = options.env ?? process.env;
866
- const root = resolve2(options.custodyRoot ?? join2(planrHome(env), "design-shares"));
867
- let project = current.root;
868
- for (let candidate = current.root; dirname3(candidate) !== candidate; candidate = dirname3(candidate)) {
869
- if (existsSync3(join2(candidate, ".git")) || existsSync3(join2(candidate, ".planr"))) {
870
- project = candidate;
871
- break;
872
- }
873
- }
874
- const key = hash(`${current.root}
875
- ${current.document.id}`);
876
- const path = join2(root, `${key}.json`);
877
- const within = relative2(project, root);
878
- if ((!allowMissing || existsSync3(path)) && (within === "" || !within.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) && within !== ".." && !isAbsolute2(within)))
879
- throw new Error(
880
- "Design owner credentials must be stored outside the project. Set PLANR_HOME to a private user-level directory."
881
- );
882
- const legacyPath = !options.custodyRoot && !configuredPlanrHome(env) ? join2(realpathSync2(env.HOME || homedir2()), ".openplanr", "design-shares", `${key}.json`) : null;
883
- return { root, path, current, legacyPath };
884
- }
885
- function presentationFingerprint(current) {
886
- const state = readJson(join2(current.root, ".design/studio-state.json"), { state: {} }).state;
887
- return hash(
888
- JSON.stringify({
889
- revision: current.revision,
890
- selectedVariant: state.selectedVariant ?? current.document.selectedVariant,
891
- positions: state.positions ?? {},
892
- verification: current.verification.status
893
- })
894
- );
895
- }
896
- var safeStatus = (record, current) => ({
897
- ok: true,
898
- shared: Boolean(record),
899
- title: current.document.title,
900
- localRevision: current.revision,
901
- retention: "until-revoked",
902
- ...record ? {
903
- id: record.custody.id,
904
- url: workspaceReviewUrl(record.custody),
905
- revision: record.custody.currentRevision ?? record.publishedRevision ?? null,
906
- publishedRevision: record.publishedRevision ?? null,
907
- hasUpdate: record.publishedRevision !== current.revision || record.publishedPresentation !== presentationFingerprint(current),
908
- epoch: record.custody.epoch,
909
- commentsPaused: Boolean(record.custody.commentsPaused ?? record.commentsPaused),
910
- revoked: Boolean(record.revoked),
911
- deleted: Boolean(record.deleted),
912
- pending: Boolean(
913
- record.custody.pendingCreate || record.custody.pendingMutation || record.pendingReviewMetadata?.length
914
- ),
915
- pendingAction: record.custody.pendingCreate ? "create" : record.custody.pendingMutation?.action ?? (record.pendingReviewMetadata?.length ? "review-metadata" : null),
916
- pendingReviewMetadata: Boolean(record.pendingReviewMetadata?.length)
917
- } : {}
918
- });
919
- function getDesignShareStatus(file, options = {}) {
920
- const { path, current, legacyPath } = custodyLocation(file, options);
921
- const record = readCustody(path, { label: "Design", format: FORMAT }) ?? (legacyPath ? readCustody(legacyPath, { label: "Design", format: FORMAT }) : null);
922
- return safeStatus(record, current);
923
- }
924
-
925
- // packages/artifact/lib/artifact/encrypted-workspace-client.mjs
926
- function createEncryptedWorkspaceClient({
927
- domain,
928
- apiPath,
929
- reviewPath,
930
- label,
931
- compatibilityMessage,
932
- compatibilityCode = "E_WORKSPACE_UNSUPPORTED",
933
- defaultBaseUrl = "https://share.openplanr.dev",
934
- version = "1.0.0",
935
- maxBytes = 5 * 1024 * 1024,
936
- maxEventBytes = 256 * 1024,
937
- schemas,
938
- assertContract,
939
- assertBundle,
940
- assertFeedback,
941
- bundleDigest,
942
- digestInput = (bundle) => bundle,
943
- packBundle = async (bundle) => bundle,
944
- unpackBundle = async (bundle) => bundle
945
- }) {
946
- if (!domain || !apiPath?.startsWith("/") || !reviewPath?.startsWith("/") || !label)
947
- throw new TypeError("An encrypted workspace requires an explicit domain and routes.");
948
- const encoder2 = new TextEncoder();
949
- const decoder2 = new TextDecoder("utf-8", { fatal: true });
950
- const tokenPattern = /^[A-Za-z0-9_-]{43}$/;
951
- const idPattern = /^[A-Za-z0-9_-]{22,64}$/;
952
- const ec = { name: "ECDSA", namedCurve: "P-256" };
953
- const signatureAlgorithm = { name: "ECDSA", hash: "SHA-256" };
954
- const omitSignature = ({ signature: _signature, ...value }) => value;
955
- const operationError = (message, code, status) => Object.assign(new Error(message), { code, ...status ? { status } : {} });
956
- function encodeWorkspaceBytes2(bytes) {
957
- let binary = "";
958
- for (let offset = 0; offset < bytes.length; offset += 8192)
959
- binary += String.fromCharCode(...bytes.subarray(offset, offset + 8192));
960
- return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
961
- }
962
- function decodeWorkspaceBytes2(value) {
963
- if (typeof value !== "string" || !/^[A-Za-z0-9_-]+$/u.test(value))
964
- throw new TypeError("Invalid encoded workspace value.");
965
- const decoded = Uint8Array.from(
966
- atob(value.replaceAll("-", "+").replaceAll("_", "/")),
967
- (char) => char.charCodeAt(0)
968
- );
969
- if (encodeWorkspaceBytes2(decoded) !== value)
970
- throw new TypeError("Noncanonical encoded workspace value.");
971
- return decoded;
972
- }
973
- function newWorkspaceToken2() {
974
- return encodeWorkspaceBytes2(crypto.getRandomValues(new Uint8Array(32)));
975
- }
976
- function newWorkspaceId2() {
977
- return encodeWorkspaceBytes2(crypto.getRandomValues(new Uint8Array(18)));
978
- }
979
- const { normalizeWorkspaceBase: normalizeWorkspaceBase2, workspaceReviewUrl: workspaceReviewUrl2 } = createWorkspaceAddress({
980
- label,
981
- reviewPath,
982
- defaultBaseUrl
983
- });
984
- async function tokenMaterial(token, id, purpose) {
985
- if (!tokenPattern.test(token) || decodeWorkspaceBytes2(token).length !== 32 || !idPattern.test(id))
986
- throw new TypeError("Enter the complete generated access token.");
987
- const key = await crypto.subtle.importKey("raw", decodeWorkspaceBytes2(token), "HKDF", false, [
988
- "deriveBits"
989
- ]);
990
- return new Uint8Array(
991
- await crypto.subtle.deriveBits(
992
- {
993
- name: "HKDF",
994
- hash: "SHA-256",
995
- salt: encoder2.encode(id),
996
- info: encoder2.encode(`${domain}/${purpose}`)
997
- },
998
- key,
999
- 256
1000
- )
1001
- );
1002
- }
1003
- async function deriveWorkspaceAuthentication2(token, id) {
1004
- return encodeWorkspaceBytes2(await tokenMaterial(token, id, "reviewer-auth"));
1005
- }
1006
- function canonicalWorkspacePublicKey2(value) {
1007
- if (value?.kty !== "EC" || value.crv !== "P-256" || !tokenPattern.test(value.x ?? "") || !tokenPattern.test(value.y ?? "") || "d" in value) {
1008
- throw new TypeError(`Invalid ${label.toLowerCase()} workspace public key.`);
1009
- }
1010
- return { kty: "EC", crv: "P-256", x: value.x, y: value.y };
1011
- }
1012
- async function createWorkspaceSigner2() {
1013
- const pair = await crypto.subtle.generateKey(ec, true, ["sign", "verify"]);
1014
- return {
1015
- privateKey: encodeWorkspaceBytes2(
1016
- new Uint8Array(await crypto.subtle.exportKey("pkcs8", pair.privateKey))
1017
- ),
1018
- publicKey: canonicalWorkspacePublicKey2(await crypto.subtle.exportKey("jwk", pair.publicKey))
1019
- };
1020
- }
1021
- async function signWorkspaceValue2(value, privateKey) {
1022
- const key = await crypto.subtle.importKey(
1023
- "pkcs8",
1024
- decodeWorkspaceBytes2(privateKey),
1025
- ec,
1026
- false,
1027
- ["sign"]
1028
- );
1029
- const signature = await crypto.subtle.sign(
1030
- signatureAlgorithm,
1031
- key,
1032
- encoder2.encode(canonicalizeJson(omitSignature(value)))
1033
- );
1034
- return { ...omitSignature(value), signature: encodeWorkspaceBytes2(new Uint8Array(signature)) };
1035
- }
1036
- async function verifyWorkspaceSignature2(value, publicKey) {
1037
- try {
1038
- const key = await crypto.subtle.importKey("jwk", publicKey, ec, false, ["verify"]);
1039
- return await crypto.subtle.verify(
1040
- signatureAlgorithm,
1041
- key,
1042
- decodeWorkspaceBytes2(value.signature),
1043
- encoder2.encode(canonicalizeJson(omitSignature(value)))
1044
- );
1045
- } catch {
1046
- return false;
1047
- }
1048
- }
1049
- async function seal(value, rawKey, context, limit = maxBytes) {
1050
- const bytes = encoder2.encode(canonicalizeJson(value));
1051
- if (bytes.length + 16 > limit)
1052
- throw Object.assign(
1053
- new RangeError(
1054
- `Encrypted ${label.toLowerCase()} data exceeds the ${Math.floor(limit / 1024)} KB upload limit.`
1055
- ),
1056
- { code: "E_WORKSPACE_PAYLOAD_TOO_LARGE", status: 413 }
1057
- );
1058
- const key = await crypto.subtle.importKey("raw", rawKey, "AES-GCM", false, ["encrypt"]);
1059
- const iv = crypto.getRandomValues(new Uint8Array(12));
1060
- const ciphertext = await crypto.subtle.encrypt(
1061
- { name: "AES-GCM", iv, additionalData: encoder2.encode(canonicalizeJson(context)) },
1062
- key,
1063
- bytes
1064
- );
1065
- return {
1066
- iv: encodeWorkspaceBytes2(iv),
1067
- ciphertext: encodeWorkspaceBytes2(new Uint8Array(ciphertext))
1068
- };
1069
- }
1070
- async function unseal(value, rawKey, context, limit = maxBytes) {
1071
- const bytes = decodeWorkspaceBytes2(value.ciphertext);
1072
- if (bytes.length > limit)
1073
- throw new RangeError(`Shared ${label.toLowerCase()} data exceeds its size limit.`);
1074
- const key = await crypto.subtle.importKey("raw", rawKey, "AES-GCM", false, ["decrypt"]);
1075
- const plaintext = await crypto.subtle.decrypt(
1076
- {
1077
- name: "AES-GCM",
1078
- iv: decodeWorkspaceBytes2(value.iv),
1079
- additionalData: encoder2.encode(canonicalizeJson(context))
1080
- },
1081
- key,
1082
- bytes
1083
- );
1084
- return JSON.parse(decoder2.decode(plaintext));
1085
- }
1086
- const keyringContext = (id, epoch) => ({ type: "keyring", workspaceId: id, epoch });
1087
- const revisionContext = (id, revision) => ({
1088
- type: "revision",
1089
- workspaceId: id,
1090
- id: revision.id,
1091
- epoch: revision.epoch,
1092
- reviewOf: revision.reviewOf
1093
- });
1094
- const eventContext = (id, event) => ({
1095
- type: "event",
1096
- workspaceId: id,
1097
- id: event.id,
1098
- epoch: event.epoch,
1099
- revisionId: event.revisionId,
1100
- reviewOf: event.reviewOf
1101
- });
1102
- function workspaceEnvelopeDigest2(value) {
1103
- return bundleDigest(value);
1104
- }
1105
- async function wrapKeyring(custody, token = custody.token, epoch = custody.epoch, keys = custody.keys) {
1106
- return seal(
1107
- { keys, ownerPublicKey: custody.ownerPublicKey },
1108
- await tokenMaterial(token, custody.id, "key-wrap"),
1109
- keyringContext(custody.id, epoch)
1110
- );
1111
- }
1112
- async function prepareRevision(custody, bundle) {
1113
- assertBundle(bundle);
1114
- const header = {
1115
- id: newWorkspaceId2(),
1116
- epoch: custody.epoch,
1117
- reviewOf: workspaceEnvelopeDigest2(digestInput(bundle)),
1118
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
1119
- };
1120
- return signWorkspaceValue2(
1121
- {
1122
- ...header,
1123
- ...await seal(
1124
- await packBundle(bundle),
1125
- decodeWorkspaceBytes2(custody.keys[custody.epoch]),
1126
- revisionContext(custody.id, header)
1127
- )
1128
- },
1129
- custody.ownerPrivateKey
1130
- );
1131
- }
1132
- async function prepareWorkspace2(bundle, { baseUrl = defaultBaseUrl } = {}) {
1133
- const signer = await createWorkspaceSigner2();
1134
- const custody = {
1135
- schemaVersion: version,
1136
- id: newWorkspaceId2(),
1137
- baseUrl: normalizeWorkspaceBase2(baseUrl),
1138
- token: newWorkspaceToken2(),
1139
- ownerAuth: newWorkspaceToken2(),
1140
- ownerPrivateKey: signer.privateKey,
1141
- ownerPublicKey: signer.publicKey,
1142
- epoch: 1,
1143
- keys: { 1: newWorkspaceToken2() },
1144
- version: 0
1145
- };
1146
- custody.keyring = await wrapKeyring(custody);
1147
- custody.pendingCreate = await signWorkspaceValue2(
1148
- {
1149
- schemaVersion: version,
1150
- id: custody.id,
1151
- ownerPublicKey: custody.ownerPublicKey,
1152
- ownerAuthHash: sha256Hex(custody.ownerAuth),
1153
- reviewerAuthHash: sha256Hex(await deriveWorkspaceAuthentication2(custody.token, custody.id)),
1154
- epoch: 1,
1155
- keyring: custody.keyring,
1156
- revision: await prepareRevision(custody, bundle),
1157
- operationId: newWorkspaceId2()
1158
- },
1159
- custody.ownerPrivateKey
1160
- );
1161
- assertContract(custody.pendingCreate, schemas.create);
1162
- return custody;
1163
- }
1164
- async function request(access, suffix = "", {
1165
- method = "GET",
1166
- body,
1167
- fetchImpl = globalThis.fetch,
1168
- owner = Boolean(access.ownerAuth),
1169
- timeoutMs = 2e4
1170
- } = {}) {
1171
- if (!idPattern.test(access.id))
1172
- throw new TypeError(`Invalid ${label.toLowerCase()} workspace identity.`);
1173
- const authorization = owner ? access.ownerAuth : await deriveWorkspaceAuthentication2(access.token, access.id);
1174
- const headers = { Authorization: `Bearer ${authorization}`, Accept: "application/json" };
1175
- if (body) headers["Content-Type"] = "application/json";
1176
- let response;
1177
- try {
1178
- response = await fetchImpl(
1179
- `${normalizeWorkspaceBase2(access.baseUrl)}${apiPath}/${access.id}${suffix}`,
1180
- {
1181
- method,
1182
- headers,
1183
- body: body ? JSON.stringify(body) : void 0,
1184
- redirect: "error",
1185
- cache: "no-store",
1186
- credentials: "omit",
1187
- signal: AbortSignal.timeout(timeoutMs)
1188
- }
1189
- );
1190
- } catch {
1191
- throw operationError(
1192
- `${label} sharing is unreachable. Check the connection and retry; the previous review is unchanged.`,
1193
- "E_WORKSPACE_NETWORK"
1194
- );
1195
- }
1196
- if (!response.ok) await throwResponseError(response, method);
1197
- return readResponse(response);
1198
- }
1199
- async function throwResponseError(response, method) {
1200
- if (response.status === 404 && method === "PUT" && compatibilityMessage) {
1201
- const error2 = new Error(compatibilityMessage);
1202
- error2.code = compatibilityCode;
1203
- error2.status = 404;
1204
- throw error2;
1205
- }
1206
- const messages = {
1207
- 401: "Access token is incorrect or has been rotated.",
1208
- 403: "This review is unavailable or this action requires its owner.",
1209
- 404: "This shared review could not be found.",
1210
- 409: "The shared review changed. Refresh its status before retrying.",
1211
- 410: "This shared review has been revoked or deleted.",
1212
- 413: `This ${label.toLowerCase()} exceeds the sharing upload limit.`,
1213
- 429: "Too many requests. Wait a moment and retry.",
1214
- 503: `${label} sharing is temporarily unavailable. Retry shortly.`
1215
- };
1216
- const error = new Error(
1217
- messages[response.status] ?? `${label} sharing failed (${response.status}). Retry shortly.`
1218
- );
1219
- error.status = response.status;
1220
- error.code = `E_WORKSPACE_HTTP_${response.status}`;
1221
- try {
1222
- const reader = response.body?.getReader();
1223
- const body = reader && JSON.parse(decoder2.decode(await responseBytes(reader, 4096)));
1224
- if (typeof body?.error === "string" && /^[A-Za-z][A-Za-z0-9_-]{0,127}$/u.test(body.error))
1225
- error.code = body.error;
1226
- } catch {
1227
- }
1228
- if (response.status === 429) {
1229
- const header = response.headers.get("retry-after");
1230
- const seconds = header && /^\d+(?:\.\d+)?$/u.test(header.trim()) ? Number(header) : header ? (Date.parse(header) - Date.now()) / 1e3 : NaN;
1231
- if (Number.isFinite(seconds) && seconds >= 0)
1232
- error.retryAfterSeconds = Math.min(3600, Math.max(1, Math.ceil(seconds)));
1233
- }
1234
- throw error;
1235
- }
1236
- async function responseBytes(reader, limit) {
1237
- const chunks = [];
1238
- let length = 0;
1239
- try {
1240
- for (; ; ) {
1241
- const { value, done } = await reader.read();
1242
- if (done) break;
1243
- length += value.length;
1244
- if (length > limit) {
1245
- await reader.cancel();
1246
- throw new RangeError(`${label} service returned an oversized response.`);
1247
- }
1248
- chunks.push(value);
1249
- }
1250
- } catch (error) {
1251
- if (error instanceof RangeError) throw error;
1252
- throw new Error("The sharing response was interrupted. Retry the pending operation.");
1253
- }
1254
- const bytes = new Uint8Array(length);
1255
- let offset = 0;
1256
- for (const chunk of chunks) {
1257
- bytes.set(chunk, offset);
1258
- offset += chunk.length;
1259
- }
1260
- return bytes;
1261
- }
1262
- async function readResponse(response) {
1263
- if (response.status === 204) return {};
1264
- const reader = response.body?.getReader();
1265
- if (!reader) throw new Error(`${label} service returned an empty response.`);
1266
- try {
1267
- return JSON.parse(decoder2.decode(await responseBytes(reader, maxBytes * 1.5 + 65536)));
1268
- } catch (cause) {
1269
- throw Object.assign(
1270
- operationError(
1271
- "The sharing response could not be verified. Retry the pending operation.",
1272
- "E_WORKSPACE_RESPONSE_INVALID"
1273
- ),
1274
- { cause }
1275
- );
1276
- }
1277
- }
1278
- async function commitWorkspace2(custody, options = {}) {
1279
- if (!custody.pendingCreate) return getWorkspace2(custody, options);
1280
- const result = await request(custody, "", {
1281
- ...options,
1282
- method: "PUT",
1283
- body: custody.pendingCreate
1284
- });
1285
- assertContract(result, schemas.workspace);
1286
- if (result.id !== custody.id || result.version !== 1 || result.epoch !== 1 || result.currentRevision !== custody.pendingCreate.revision.id || canonicalizeJson(result.ownerPublicKey) !== canonicalizeJson(custody.ownerPublicKey) || canonicalizeJson(result.keyring) !== canonicalizeJson(custody.keyring))
1287
- throw new Error("The sharing creation receipt is invalid. Retry the saved operation.");
1288
- custody.version = result.version;
1289
- custody.currentRevision = result.currentRevision;
1290
- delete custody.pendingCreate;
1291
- return result;
1292
- }
1293
- async function getWorkspace2(access, options = {}) {
1294
- const result = assertContract(await request(access, "", options), schemas.workspace);
1295
- if (result.id !== access.id) throw new Error("Shared review identity mismatch.");
1296
- const ring = await unseal(
1297
- result.keyring,
1298
- await tokenMaterial(access.token, access.id, "key-wrap"),
1299
- keyringContext(access.id, result.epoch)
1300
- );
1301
- if (canonicalizeJson(ring.ownerPublicKey) !== canonicalizeJson(result.ownerPublicKey) || access.ownerPublicKey && canonicalizeJson(access.ownerPublicKey) !== canonicalizeJson(result.ownerPublicKey))
1302
- throw new Error("Shared review owner identity changed.");
1303
- if (!ring.keys?.[result.epoch] || Object.entries(ring.keys).some(
1304
- ([keyEpoch, key]) => !/^[1-9][0-9]*$/u.test(keyEpoch) || !tokenPattern.test(key)
1305
- ))
1306
- throw new Error("Invalid shared review key history.");
1307
- Object.assign(access, {
1308
- keys: ring.keys,
1309
- ownerPublicKey: result.ownerPublicKey,
1310
- epoch: result.epoch,
1311
- keyring: result.keyring,
1312
- version: result.version,
1313
- currentRevision: result.currentRevision,
1314
- commentsPaused: result.commentsPaused
1315
- });
1316
- return result;
1317
- }
1318
- async function listWorkspaceRevisions(access, { after = "", ...options } = {}) {
1319
- if (after && !idPattern.test(after)) throw new TypeError("Invalid revision cursor.");
1320
- return request(
1321
- access,
1322
- `/revisions${after ? `?after=${encodeURIComponent(after)}` : ""}`,
1323
- options
1324
- );
1325
- }
1326
- async function decryptWorkspaceRevision2(access, revisionId = access.currentRevision, options = {}) {
1327
- if (!access.keys) await getWorkspace2(access, options);
1328
- if (!idPattern.test(revisionId))
1329
- throw new TypeError(`Invalid ${label.toLowerCase()} revision.`);
1330
- const revision = assertContract(
1331
- await request(access, `/revisions/${revisionId}`, options),
1332
- schemas.revision
1333
- );
1334
- if (revision.id !== revisionId || !await verifyWorkspaceSignature2(revision, access.ownerPublicKey))
1335
- throw new Error(`The published ${label.toLowerCase()} signature is invalid.`);
1336
- if (!access.keys[revision.epoch])
1337
- throw new Error("The access token cannot open this revision.");
1338
- const bundle = assertBundle(
1339
- await unpackBundle(
1340
- await unseal(
1341
- revision,
1342
- decodeWorkspaceBytes2(access.keys[revision.epoch]),
1343
- revisionContext(access.id, revision)
1344
- )
1345
- )
1346
- );
1347
- if (workspaceEnvelopeDigest2(digestInput(bundle)) !== revision.reviewOf)
1348
- throw new Error(`Published ${label.toLowerCase()} content does not match its revision.`);
1349
- return { ...bundle, workspaceRevision: revision.id, reviewOf: revision.reviewOf };
1350
- }
1351
- async function prepareWorkspaceMutation2(custody, action, payload = void 0) {
1352
- if (custody.pendingCreate)
1353
- throw new Error("Finish creating this shared review before changing it.");
1354
- if (custody.pendingMutation)
1355
- throw new Error("A sharing operation is pending. Retry it before making another change.");
1356
- const body = {
1357
- operationId: newWorkspaceId2(),
1358
- expectedVersion: custody.version,
1359
- epoch: custody.epoch
1360
- };
1361
- let next = {};
1362
- if (action === "publish") body.revision = await prepareRevision(custody, payload);
1363
- else if (action === "rotate") {
1364
- const token = newWorkspaceToken2();
1365
- const epoch = custody.epoch + 1;
1366
- const keys = { ...custody.keys, [epoch]: newWorkspaceToken2() };
1367
- const keyring = await wrapKeyring(custody, token, epoch, keys);
1368
- Object.assign(body, {
1369
- epoch,
1370
- reviewerAuthHash: sha256Hex(await deriveWorkspaceAuthentication2(token, custody.id)),
1371
- keyring
1372
- });
1373
- next = { token, epoch, keys, keyring };
1374
- } else if (["pause", "resume", "revoke", "delete"].includes(action)) body.action = action;
1375
- else throw new TypeError(`Unknown ${label.toLowerCase()} sharing operation.`);
1376
- custody.pendingMutation = {
1377
- action,
1378
- body: await signWorkspaceValue2(body, custody.ownerPrivateKey),
1379
- next
1380
- };
1381
- return custody.pendingMutation;
1382
- }
1383
- function assertDeletionReceipt(custody, result) {
1384
- if (result.schemaVersion !== version || result.id !== custody.id || result.deleted !== true || Object.keys(result).some((key) => !["schemaVersion", "id", "deleted"].includes(key)))
1385
- throw new Error("The deletion receipt is invalid. Retry the saved operation.");
1386
- }
1387
- function assertMutationReceipt(custody, pending, result) {
1388
- if (pending.action === "delete") return assertDeletionReceipt(custody, result);
1389
- assertContract(result, schemas.workspace);
1390
- const expectedRevision = pending.action === "publish" ? pending.body.revision.id : custody.currentRevision;
1391
- if (result.id !== custody.id || result.version !== pending.body.expectedVersion + 1 || result.epoch !== pending.body.epoch || result.currentRevision !== expectedRevision || canonicalizeJson(result.ownerPublicKey) !== canonicalizeJson(custody.ownerPublicKey) || canonicalizeJson(result.keyring) !== canonicalizeJson(pending.next.keyring ?? custody.keyring) || ["pause", "resume"].includes(pending.action) && result.commentsPaused !== (pending.action === "pause"))
1392
- throw new Error("The sharing operation receipt is invalid. Retry the saved operation.");
1393
- }
1394
- async function commitWorkspaceMutation2(custody, options = {}) {
1395
- const pending = custody.pendingMutation;
1396
- if (!pending) throw new Error("No sharing operation is pending.");
1397
- const suffix = ["publish", "rotate"].includes(pending.action) ? pending.action : "manage";
1398
- const result = await request(custody, `/${suffix}`, {
1399
- ...options,
1400
- method: "POST",
1401
- body: pending.body
1402
- });
1403
- assertMutationReceipt(custody, pending, result);
1404
- Object.assign(custody, pending.next, { version: pending.body.expectedVersion + 1 });
1405
- if (pending.action === "publish") custody.currentRevision = pending.body.revision.id;
1406
- if (pending.action === "pause" || pending.action === "resume")
1407
- custody.commentsPaused = pending.action === "pause";
1408
- if (pending.action === "revoke" || pending.action === "delete")
1409
- custody.status = pending.action === "revoke" ? "revoked" : "deleted";
1410
- delete custody.pendingMutation;
1411
- return result;
1412
- }
1413
- async function publishWorkspace(custody, bundle, options = {}) {
1414
- await prepareWorkspaceMutation2(custody, "publish", bundle);
1415
- return commitWorkspaceMutation2(custody, options);
1416
- }
1417
- async function rotateWorkspace(custody, options = {}) {
1418
- await prepareWorkspaceMutation2(custody, "rotate");
1419
- return commitWorkspaceMutation2(custody, options);
1420
- }
1421
- async function manageWorkspace(custody, action, options = {}) {
1422
- await prepareWorkspaceMutation2(custody, action);
1423
- return commitWorkspaceMutation2(custody, options);
1424
- }
1425
- async function prepareWorkspaceEvent2(access, payload, { revisionId = access.currentRevision, reviewOf = payload.reviewOf, signer } = {}) {
1426
- if (!access.keys) throw new Error("Unlock the shared review before commenting.");
1427
- assertFeedback(payload);
1428
- const identity = signer ?? await createWorkspaceSigner2();
1429
- const publicKey = canonicalWorkspacePublicKey2(identity.publicKey);
1430
- const header = { id: newWorkspaceId2(), revisionId, reviewOf, epoch: access.epoch };
1431
- const event = await signWorkspaceValue2(
1432
- {
1433
- ...header,
1434
- ...await seal(
1435
- payload,
1436
- decodeWorkspaceBytes2(access.keys[access.epoch]),
1437
- eventContext(access.id, header),
1438
- maxEventBytes
1439
- ),
1440
- publicKey
1441
- },
1442
- identity.privateKey
1443
- );
1444
- return assertContract(event, schemas.event);
1445
- }
1446
- async function appendWorkspaceEvent2(access, payload, { preparedEvent, signer, revisionId, reviewOf, ...options } = {}) {
1447
- const event = preparedEvent ?? await prepareWorkspaceEvent2(access, payload, {
1448
- signer,
1449
- revisionId,
1450
- reviewOf: reviewOf ?? payload.reviewOf
1451
- });
1452
- const result = await request(access, "/events", { ...options, method: "POST", body: event });
1453
- if (!result || typeof result !== "object" || Array.isArray(result) || !Number.isSafeInteger(result.sequence) || result.sequence < 1 || !result.event || typeof result.event !== "object" || Array.isArray(result.event))
1454
- throw new Error("The feedback receipt is invalid. Retry the saved operation.");
1455
- const { sequence: eventSequence, ...received } = result.event;
1456
- if (eventSequence !== void 0 && eventSequence !== result.sequence || canonicalizeJson(received) !== canonicalizeJson(event))
1457
- throw new Error(
1458
- "The feedback receipt does not match the saved event. Retry the saved operation."
1459
- );
1460
- return { event: { ...received, sequence: result.sequence }, sequence: result.sequence };
1461
- }
1462
- function assertEventPage(page, after) {
1463
- if (!Array.isArray(page.events) || page.events.length > 100 || !Number.isSafeInteger(page.cursor) || page.cursor < after || typeof page.hasMore !== "boolean")
1464
- throw new Error("Invalid shared feedback page.");
1465
- }
1466
- async function decryptEvent(access, record, sequence) {
1467
- assertContract(record, schemas.event);
1468
- if (!await verifyWorkspaceSignature2(record, record.publicKey))
1469
- throw new Error("Signature verification failed.");
1470
- if (!access.keys[record.epoch]) throw new Error("The encryption epoch is unavailable.");
1471
- const payload = await unseal(
1472
- record,
1473
- decodeWorkspaceBytes2(access.keys[record.epoch]),
1474
- eventContext(access.id, record),
1475
- maxEventBytes
1476
- );
1477
- assertFeedback(payload);
1478
- if (payload.reviewOf !== record.reviewOf) throw new Error("Feedback revision is invalid.");
1479
- return { ...record, sequence, payload };
1480
- }
1481
- function eventFromPage(item, pageIds, previousSequence, cursor) {
1482
- const { sequence, ...record } = item?.event ? { ...item.event, sequence: item.sequence } : item ?? {};
1483
- if (!Number.isSafeInteger(sequence) || sequence <= previousSequence || sequence > cursor)
1484
- throw new Error("Invalid shared feedback sequence.");
1485
- if (typeof record.id !== "string" || pageIds.has(record.id))
1486
- throw new Error("Invalid shared feedback event identity.");
1487
- pageIds.add(record.id);
1488
- return { sequence, record };
1489
- }
1490
- async function readWorkspaceEvents2(access, { after = 0, ...options } = {}) {
1491
- if (!Number.isSafeInteger(after) || after < 0) throw new TypeError("Invalid feedback cursor.");
1492
- if (!access.keys) await getWorkspace2(access, options);
1493
- const page = await request(access, `/events?after=${after}`, options);
1494
- assertEventPage(page, after);
1495
- const events = [], issues = [], pageIds = /* @__PURE__ */ new Set();
1496
- let previousSequence = after;
1497
- for (const item of page.events) {
1498
- const { sequence, record } = eventFromPage(item, pageIds, previousSequence, page.cursor);
1499
- previousSequence = sequence;
1500
- try {
1501
- events.push(await decryptEvent(access, record, sequence));
1502
- } catch {
1503
- issues.push({
1504
- sequence,
1505
- id: typeof record.id === "string" && idPattern.test(record.id) ? record.id : null,
1506
- reason: "Invalid encrypted feedback; not imported."
1507
- });
1508
- }
1509
- }
1510
- return { ...page, events, issues };
1511
- }
1512
- return {
1513
- encodeWorkspaceBytes: encodeWorkspaceBytes2,
1514
- decodeWorkspaceBytes: decodeWorkspaceBytes2,
1515
- newWorkspaceToken: newWorkspaceToken2,
1516
- newWorkspaceId: newWorkspaceId2,
1517
- normalizeWorkspaceBase: normalizeWorkspaceBase2,
1518
- workspaceReviewUrl: workspaceReviewUrl2,
1519
- deriveWorkspaceAuthentication: deriveWorkspaceAuthentication2,
1520
- canonicalWorkspacePublicKey: canonicalWorkspacePublicKey2,
1521
- createWorkspaceSigner: createWorkspaceSigner2,
1522
- signWorkspaceValue: signWorkspaceValue2,
1523
- verifyWorkspaceSignature: verifyWorkspaceSignature2,
1524
- workspaceEnvelopeDigest: workspaceEnvelopeDigest2,
1525
- prepareWorkspace: prepareWorkspace2,
1526
- commitWorkspace: commitWorkspace2,
1527
- getWorkspace: getWorkspace2,
1528
- listWorkspaceRevisions,
1529
- decryptWorkspaceRevision: decryptWorkspaceRevision2,
1530
- prepareWorkspaceMutation: prepareWorkspaceMutation2,
1531
- commitWorkspaceMutation: commitWorkspaceMutation2,
1532
- publishWorkspace,
1533
- rotateWorkspace,
1534
- manageWorkspace,
1535
- prepareWorkspaceEvent: prepareWorkspaceEvent2,
1536
- appendWorkspaceEvent: appendWorkspaceEvent2,
1537
- readWorkspaceEvents: readWorkspaceEvents2
1538
- };
1539
- }
1540
-
1541
915
  // packages/design/lib/design/workspace-client.mjs
1542
916
  var encoder = new TextEncoder();
1543
917
  var decoder = new TextDecoder("utf-8", { fatal: true });
@@ -2425,7 +1799,7 @@ async function importDesignShareRecovery(file, { input, ...options } = {}) {
2425
1799
  const pending = custody.pendingCreate ?? custody.pendingMutation.body;
2426
1800
  const destination = join3(root, "uploads", custody.id, pending.operationId);
2427
1801
  if (existsSync4(destination)) {
2428
- const { spoolChunkReader: spoolChunkReader2 } = await import("./design-generated-b0798298053515fd.mjs");
1802
+ const { spoolChunkReader: spoolChunkReader2 } = await import("./design-runtime-support-5cb7531bede8.mjs");
2429
1803
  const reader = spoolChunkReader2(destination, pending);
2430
1804
  for (const part of pending.manifest.chunks) await reader(part.index);
2431
1805
  } else await copyUploadSpool(custody, destination);
@@ -2601,7 +1975,6 @@ export {
2601
1975
  resolveArtifactReviewDestination,
2602
1976
  decodeArtifactReviewSources,
2603
1977
  getDesignShareStatus,
2604
- prepareDesignShareBundle,
2605
1978
  shareDesign,
2606
1979
  publishDesignShare,
2607
1980
  manageDesignShare,