openplanr 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cli/commands/spec.d.ts +2 -1
  3. package/dist/cli/commands/spec.d.ts.map +1 -1
  4. package/dist/cli/commands/spec.js +45 -5
  5. package/dist/cli/commands/spec.js.map +1 -1
  6. package/dist/dashboard/.vite/manifest.json +1 -1
  7. package/dist/dashboard/assets/index-B_96uzCl.js +572 -0
  8. package/dist/dashboard/assets/index-B_96uzCl.js.map +1 -0
  9. package/dist/dashboard/dashboard-manifest.json +10 -10
  10. package/dist/dashboard/index.html +1 -1
  11. package/dist/services/claude-plugin-service.d.ts +5 -0
  12. package/dist/services/claude-plugin-service.d.ts.map +1 -1
  13. package/dist/services/claude-plugin-service.js +18 -2
  14. package/dist/services/claude-plugin-service.js.map +1 -1
  15. package/dist/services/codex-plugin-service.d.ts.map +1 -1
  16. package/dist/services/codex-plugin-service.js +11 -3
  17. package/dist/services/codex-plugin-service.js.map +1 -1
  18. package/dist/services/runtime-manager/codex-discovery.d.ts +1 -3
  19. package/dist/services/runtime-manager/codex-discovery.d.ts.map +1 -1
  20. package/dist/services/runtime-manager/codex-discovery.js +3 -16
  21. package/dist/services/runtime-manager/codex-discovery.js.map +1 -1
  22. package/dist/services/runtime-manager/doctor.d.ts +25 -0
  23. package/dist/services/runtime-manager/doctor.d.ts.map +1 -1
  24. package/dist/services/runtime-manager/doctor.js +480 -0
  25. package/dist/services/runtime-manager/doctor.js.map +1 -1
  26. package/dist/services/runtime-manager/errors.d.ts +12 -0
  27. package/dist/services/runtime-manager/errors.d.ts.map +1 -0
  28. package/dist/services/runtime-manager/errors.js +14 -0
  29. package/dist/services/runtime-manager/errors.js.map +1 -0
  30. package/dist/services/runtime-manager/global-state.d.ts +7 -0
  31. package/dist/services/runtime-manager/global-state.d.ts.map +1 -1
  32. package/dist/services/runtime-manager/global-state.js +116 -0
  33. package/dist/services/runtime-manager/global-state.js.map +1 -1
  34. package/dist/services/runtime-manager/host-version-probe.d.ts +8 -0
  35. package/dist/services/runtime-manager/host-version-probe.d.ts.map +1 -0
  36. package/dist/services/runtime-manager/host-version-probe.js +14 -0
  37. package/dist/services/runtime-manager/host-version-probe.js.map +1 -0
  38. package/dist/services/runtime-manager/install-plan.d.ts +25 -0
  39. package/dist/services/runtime-manager/install-plan.d.ts.map +1 -1
  40. package/dist/services/runtime-manager/install-plan.js +305 -0
  41. package/dist/services/runtime-manager/install-plan.js.map +1 -1
  42. package/dist/services/runtime-manager/inventory.d.ts +6 -0
  43. package/dist/services/runtime-manager/inventory.d.ts.map +1 -1
  44. package/dist/services/runtime-manager/inventory.js +16 -1
  45. package/dist/services/runtime-manager/inventory.js.map +1 -1
  46. package/dist/services/runtime-manager/legacy-adapters.d.ts +9 -0
  47. package/dist/services/runtime-manager/legacy-adapters.d.ts.map +1 -0
  48. package/dist/services/runtime-manager/legacy-adapters.js +187 -0
  49. package/dist/services/runtime-manager/legacy-adapters.js.map +1 -0
  50. package/dist/services/runtime-manager/paths.d.ts +18 -0
  51. package/dist/services/runtime-manager/paths.d.ts.map +1 -0
  52. package/dist/services/runtime-manager/paths.js +83 -0
  53. package/dist/services/runtime-manager/paths.js.map +1 -0
  54. package/dist/services/runtime-manager/runtime-package.d.ts +21 -0
  55. package/dist/services/runtime-manager/runtime-package.d.ts.map +1 -1
  56. package/dist/services/runtime-manager/runtime-package.js +77 -0
  57. package/dist/services/runtime-manager/runtime-package.js.map +1 -1
  58. package/dist/services/runtime-manager/storage.d.ts +47 -0
  59. package/dist/services/runtime-manager/storage.d.ts.map +1 -0
  60. package/dist/services/runtime-manager/storage.js +604 -0
  61. package/dist/services/runtime-manager/storage.js.map +1 -0
  62. package/dist/services/runtime-manager-service.d.ts +7 -17
  63. package/dist/services/runtime-manager-service.d.ts.map +1 -1
  64. package/dist/services/runtime-manager-service.js +32 -1695
  65. package/dist/services/runtime-manager-service.js.map +1 -1
  66. package/dist/services/ship-checks/contract.d.ts +13 -1
  67. package/dist/services/ship-checks/contract.d.ts.map +1 -1
  68. package/dist/services/ship-checks/contract.js +1 -1
  69. package/dist/services/ship-checks/contract.js.map +1 -1
  70. package/dist/services/ship-checks/coverage.d.ts +4 -0
  71. package/dist/services/ship-checks/coverage.d.ts.map +1 -0
  72. package/dist/services/ship-checks/coverage.js +113 -0
  73. package/dist/services/ship-checks/coverage.js.map +1 -0
  74. package/dist/services/ship-checks/discover.d.ts.map +1 -1
  75. package/dist/services/ship-checks/discover.js +3 -0
  76. package/dist/services/ship-checks/discover.js.map +1 -1
  77. package/dist/services/spec-service.d.ts +18 -0
  78. package/dist/services/spec-service.d.ts.map +1 -1
  79. package/dist/services/spec-service.js +174 -9
  80. package/dist/services/spec-service.js.map +1 -1
  81. package/dist/templates/spec/spec-shaped.md.hbs +1 -1
  82. package/dist/templates/spec/spec.md.hbs +2 -2
  83. package/docs/CLI.md +49 -2
  84. package/lib/host-packages/adapter-registry.json +5 -5
  85. package/lib/host-packages/capability-map.json +3 -3
  86. package/lib/host-packages/claude/.claude-plugin/marketplace.json +2 -2
  87. package/lib/host-packages/claude/openplanr/.claude-plugin/plugin.json +1 -1
  88. package/lib/host-packages/claude/openplanr/.openplanr-content.json +50 -46
  89. package/lib/host-packages/claude/openplanr/README.md +1 -1
  90. package/lib/host-packages/claude/openplanr/agents/planr-qa.md +5 -3
  91. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-document.mjs +87 -2
  92. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-handoff.mjs +1 -1
  93. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-share.mjs +1 -1
  94. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs +102 -9
  95. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-protocol-contracts-b5f28f94.mjs +130 -1
  96. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design.mjs +271 -28
  97. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +32 -32
  98. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +77 -1
  99. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +4 -4
  100. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  101. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +2 -2
  102. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +5 -5
  103. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-protocol-contracts.js +72 -2
  104. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-design-review-experience.js +14 -7
  105. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-canvas-engine.js +71 -34
  106. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/21-design-studio.js +28 -14
  107. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +12 -12
  108. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +2 -2
  109. package/lib/host-packages/{cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.20.0 → claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0}/design-document.schema.json +131 -4
  110. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0/design-review-bundle.schema.json +822 -0
  111. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +78 -1
  112. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/design.mjs +30 -2
  113. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +2 -2
  114. package/lib/host-packages/claude/openplanr/skills/design/references/design-system.md +17 -2
  115. package/lib/host-packages/claude/openplanr/skills/design/references/generation.md +60 -2
  116. package/lib/host-packages/claude/openplanr/skills/design/references/utilities.md +11 -1
  117. package/lib/host-packages/claude/openplanr/skills/design/schemas/design-document.schema.json +131 -4
  118. package/lib/host-packages/claude/openplanr/skills/design-loop/references/design-system.md +17 -2
  119. package/lib/host-packages/claude/openplanr/skills/design-loop/references/generation.md +60 -2
  120. package/lib/host-packages/claude/openplanr/skills/design-loop/references/utilities.md +11 -1
  121. package/lib/host-packages/claude/openplanr/skills/design-loop/schemas/design-document.schema.json +131 -4
  122. package/lib/host-packages/claude/openplanr/skills/design-review/references/design-system.md +17 -2
  123. package/lib/host-packages/claude/openplanr/skills/design-review/references/generation.md +60 -2
  124. package/lib/host-packages/claude/openplanr/skills/design-review/references/utilities.md +11 -1
  125. package/lib/host-packages/claude/openplanr/skills/design-review/schemas/design-document.schema.json +131 -4
  126. package/lib/host-packages/claude/openplanr/skills/investigate/SKILL.md +1 -1
  127. package/lib/host-packages/claude/openplanr/skills/plan/SKILL.md +21 -11
  128. package/lib/host-packages/claude/openplanr/skills/plan/schemas/design-document.schema.json +131 -4
  129. package/lib/host-packages/claude/openplanr/skills/ship/SKILL.md +31 -10
  130. package/lib/host-packages/claude/openplanr/skills/spec/SKILL.md +6 -0
  131. package/lib/host-packages/claude/openplanr/skills/spec/references/specification-contract.md +3 -1
  132. package/lib/host-packages/cursor/openplanr/.openplanr-content.json +48 -44
  133. package/lib/host-packages/cursor/openplanr/manifest.json +1 -1
  134. package/lib/host-packages/cursor/openplanr/rules/planr-design/references/design-system.md +17 -2
  135. package/lib/host-packages/cursor/openplanr/rules/planr-design/references/generation.md +60 -2
  136. package/lib/host-packages/cursor/openplanr/rules/planr-design/references/utilities.md +11 -1
  137. package/lib/host-packages/cursor/openplanr/rules/planr-design/schemas/design-document.schema.json +131 -4
  138. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/design-system.md +17 -2
  139. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/generation.md +60 -2
  140. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/utilities.md +11 -1
  141. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/schemas/design-document.schema.json +131 -4
  142. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/design-system.md +17 -2
  143. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/generation.md +60 -2
  144. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/utilities.md +11 -1
  145. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/schemas/design-document.schema.json +131 -4
  146. package/lib/host-packages/cursor/openplanr/rules/planr-investigate.mdc +1 -1
  147. package/lib/host-packages/cursor/openplanr/rules/planr-plan/schemas/design-document.schema.json +131 -4
  148. package/lib/host-packages/cursor/openplanr/rules/planr-plan.mdc +21 -11
  149. package/lib/host-packages/cursor/openplanr/rules/planr-ship.mdc +31 -10
  150. package/lib/host-packages/cursor/openplanr/rules/planr-spec/references/specification-contract.md +3 -1
  151. package/lib/host-packages/cursor/openplanr/rules/planr-spec.mdc +6 -0
  152. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-document.mjs +87 -2
  153. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-handoff.mjs +1 -1
  154. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-share.mjs +1 -1
  155. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs +102 -9
  156. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-protocol-contracts-b5f28f94.mjs +130 -1
  157. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design.mjs +271 -28
  158. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +32 -32
  159. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +77 -1
  160. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +4 -4
  161. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  162. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +2 -2
  163. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +5 -5
  164. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-protocol-contracts.js +72 -2
  165. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-design-review-experience.js +14 -7
  166. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-canvas-engine.js +71 -34
  167. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/21-design-studio.js +28 -14
  168. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +12 -12
  169. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +2 -2
  170. package/lib/host-packages/{openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.20.0 → cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0}/design-document.schema.json +131 -4
  171. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0/design-review-bundle.schema.json +822 -0
  172. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +78 -1
  173. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/design.mjs +30 -2
  174. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +2 -2
  175. package/lib/host-packages/openai/.claude-plugin/marketplace.json +2 -2
  176. package/lib/host-packages/openai/openplanr/.codex-plugin/plugin.json +1 -1
  177. package/lib/host-packages/openai/openplanr/.openplanr-content.json +54 -50
  178. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-document.mjs +87 -2
  179. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-handoff.mjs +1 -1
  180. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-share.mjs +1 -1
  181. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs +102 -9
  182. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-protocol-contracts-b5f28f94.mjs +130 -1
  183. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design.mjs +271 -28
  184. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +32 -32
  185. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +77 -1
  186. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +4 -4
  187. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  188. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +2 -2
  189. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +5 -5
  190. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-protocol-contracts.js +72 -2
  191. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-design-review-experience.js +14 -7
  192. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-canvas-engine.js +71 -34
  193. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/21-design-studio.js +28 -14
  194. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +12 -12
  195. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +2 -2
  196. package/lib/host-packages/{claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.20.0 → openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0}/design-document.schema.json +131 -4
  197. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0/design-review-bundle.schema.json +822 -0
  198. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +78 -1
  199. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/design.mjs +30 -2
  200. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +2 -2
  201. package/lib/host-packages/openai/openplanr/skills/design/references/design-system.md +17 -2
  202. package/lib/host-packages/openai/openplanr/skills/design/references/generation.md +60 -2
  203. package/lib/host-packages/openai/openplanr/skills/design/references/utilities.md +11 -1
  204. package/lib/host-packages/openai/openplanr/skills/design/schemas/design-document.schema.json +131 -4
  205. package/lib/host-packages/openai/openplanr/skills/design-loop/references/design-system.md +17 -2
  206. package/lib/host-packages/openai/openplanr/skills/design-loop/references/generation.md +60 -2
  207. package/lib/host-packages/openai/openplanr/skills/design-loop/references/utilities.md +11 -1
  208. package/lib/host-packages/openai/openplanr/skills/design-loop/schemas/design-document.schema.json +131 -4
  209. package/lib/host-packages/openai/openplanr/skills/design-review/references/design-system.md +17 -2
  210. package/lib/host-packages/openai/openplanr/skills/design-review/references/generation.md +60 -2
  211. package/lib/host-packages/openai/openplanr/skills/design-review/references/utilities.md +11 -1
  212. package/lib/host-packages/openai/openplanr/skills/design-review/schemas/design-document.schema.json +131 -4
  213. package/lib/host-packages/openai/openplanr/skills/investigate/SKILL.md +1 -1
  214. package/lib/host-packages/openai/openplanr/skills/investigate/agents/openai.yaml +1 -1
  215. package/lib/host-packages/openai/openplanr/skills/investigate/openplanr.skill.json +1 -1
  216. package/lib/host-packages/openai/openplanr/skills/plan/SKILL.md +21 -11
  217. package/lib/host-packages/openai/openplanr/skills/plan/openplanr.skill.json +1 -1
  218. package/lib/host-packages/openai/openplanr/skills/plan/schemas/design-document.schema.json +131 -4
  219. package/lib/host-packages/openai/openplanr/skills/ship/SKILL.md +31 -10
  220. package/lib/host-packages/openai/openplanr/skills/ship/agents/openai.yaml +1 -1
  221. package/lib/host-packages/openai/openplanr/skills/ship/openplanr.skill.json +1 -1
  222. package/lib/host-packages/openai/openplanr/skills/spec/SKILL.md +6 -0
  223. package/lib/host-packages/openai/openplanr/skills/spec/openplanr.skill.json +1 -1
  224. package/lib/host-packages/openai/openplanr/skills/spec/references/specification-contract.md +3 -1
  225. package/lib/json-schema.mjs +4 -0
  226. package/package.json +12 -12
  227. package/dist/dashboard/assets/index-L8qtwqv6.js +0 -572
  228. package/dist/dashboard/assets/index-L8qtwqv6.js.map +0 -1
  229. /package/lib/host-packages/claude/openplanr/runtime/design/scripts/{design-runtime-support-6774fd3d5d02.mjs → design-runtime-support-25485dbf1cb2.mjs} +0 -0
  230. /package/lib/host-packages/cursor/openplanr/runtime/design/scripts/{design-runtime-support-6774fd3d5d02.mjs → design-runtime-support-25485dbf1cb2.mjs} +0 -0
  231. /package/lib/host-packages/openai/openplanr/runtime/design/scripts/{design-runtime-support-6774fd3d5d02.mjs → design-runtime-support-25485dbf1cb2.mjs} +0 -0
@@ -18,6 +18,7 @@ import {
18
18
  currentDesign,
19
19
  designSpecPath,
20
20
  hash,
21
+ inspectLocalDocumentBody,
21
22
  json,
22
23
  loadReviewContext,
23
24
  parse,
@@ -44,7 +45,8 @@ import {
44
45
  import {
45
46
  DESIGN_DOCUMENT_SCHEMA,
46
47
  assertDesignDocument,
47
- initialFrameHeight
48
+ initialFrameHeight,
49
+ validateDesignProps
48
50
  } from "./design-shared-protocol-contracts-b5f28f94.mjs";
49
51
 
50
52
  // packages/design/lib/design/frame-size.mjs
@@ -1620,6 +1622,15 @@ function lintDesign(html, opts = {}) {
1620
1622
  const { designSystem = null } = opts;
1621
1623
  const errors = [];
1622
1624
  const warnings = [];
1625
+ if (opts.screen) {
1626
+ const values = Object.hasOwn(opts.variant?.props ?? {}, opts.screen.id) ? opts.variant.props[opts.screen.id] : {};
1627
+ errors.push(
1628
+ ...validateDesignProps({
1629
+ screens: [opts.screen],
1630
+ variants: [{ props: { [opts.screen.id]: values } }]
1631
+ }).map((message) => ({ rule: "invalid-instance-prop", level: "error", message }))
1632
+ );
1633
+ }
1623
1634
  const decls = [...styleBlockDecls(html), ...inlineStyleDecls(html)];
1624
1635
  for (const d of decls) {
1625
1636
  if (SPACING_PROP.test(d.prop)) {
@@ -1693,6 +1704,57 @@ function lintDesign(html, opts = {}) {
1693
1704
  summary: `${errors.length} error(s), ${warnings.length} warning(s)`
1694
1705
  };
1695
1706
  }
1707
+ function withoutRootTheme(html) {
1708
+ if (!/theme-(?:light|dark)|data-theme/iu.test(html)) return null;
1709
+ const body = inspectLocalDocumentBody(html);
1710
+ if (!body) return null;
1711
+ const edits = [];
1712
+ for (const { name, value } of body.attrs) {
1713
+ const location = body.location.attrs?.[name];
1714
+ if (!location) continue;
1715
+ let replacement;
1716
+ if (name === "data-theme" && ["light", "dark"].includes(value)) replacement = "";
1717
+ if (name === "class") {
1718
+ const raw = html.slice(location.startOffset, location.endOffset);
1719
+ const quoted = /^(class\s*=\s*)(["'])([\s\S]*)\2$/iu.exec(raw);
1720
+ if (quoted) {
1721
+ const kept = quoted[3].replace(/(^|\s)theme-(?:light|dark)(?=\s|$)/gu, "$1");
1722
+ if (kept !== quoted[3]) replacement = `${quoted[1]}${quoted[2]}${kept}${quoted[2]}`;
1723
+ } else if (/^class\s*=\s*theme-(?:light|dark)$/iu.test(raw)) replacement = "";
1724
+ }
1725
+ if (replacement !== void 0) edits.push({ ...location, replacement });
1726
+ }
1727
+ if (!edits.length) return null;
1728
+ let normalized = html;
1729
+ for (const { startOffset, endOffset, replacement } of edits.sort(
1730
+ (a, b) => b.startOffset - a.startOffset
1731
+ ))
1732
+ normalized = normalized.slice(0, startOffset) + replacement + normalized.slice(endOffset);
1733
+ return normalized;
1734
+ }
1735
+ function lintThemeOnlySources(sources) {
1736
+ const warnings = [];
1737
+ const seen = /* @__PURE__ */ new Map();
1738
+ for (const { screenId, source, html } of sources) {
1739
+ const normalized = withoutRootTheme(html);
1740
+ if (normalized === null) continue;
1741
+ const key = JSON.stringify({
1742
+ html: normalized,
1743
+ styles: source.styles ?? [],
1744
+ scripts: source.scripts ?? []
1745
+ });
1746
+ const previous = seen.get(key);
1747
+ if (previous && previous.screenId !== screenId && previous.source !== source.html && previous.html !== html)
1748
+ warnings.push({
1749
+ rule: "theme-only-source",
1750
+ level: "warn",
1751
+ screenId,
1752
+ message: `Screens ${previous.screenId} (${previous.source}) and ${screenId} (${source.html}) differ only by a root theme marker; declare a theme prop and share one source.`
1753
+ });
1754
+ else seen.set(key, { screenId, source: source.html, html });
1755
+ }
1756
+ return warnings;
1757
+ }
1696
1758
  function lintCanvasData(data, { frames } = {}) {
1697
1759
  const errors = [];
1698
1760
  for (const section of data?.sections || []) {
@@ -2434,8 +2496,19 @@ function prepareDesignDocument(file, { readSource, passive = false, maxBytes } =
2434
2496
  ])
2435
2497
  );
2436
2498
  for (const variant of document2.variants.filter((item) => item.status === "ready")) {
2499
+ const themeWarnings = lintThemeOnlySources(
2500
+ document2.screens.map((screen) => {
2501
+ const source = variant.sources?.[screen.id] ?? screen.source;
2502
+ return {
2503
+ screenId: screen.id,
2504
+ source,
2505
+ html: sourceContents.get(source.html).toString("utf8")
2506
+ };
2507
+ })
2508
+ );
2437
2509
  for (const screenId of document2.screenOrder) {
2438
2510
  const screen = document2.screens.find((item) => item.id === screenId);
2511
+ const values = Object.hasOwn(variant.props ?? {}, screenId) ? variant.props[screenId] : {};
2439
2512
  const bundled = bundleLocalDocument({
2440
2513
  root,
2441
2514
  source: variant.sources?.[screenId] ?? screen.source,
@@ -2443,6 +2516,14 @@ function prepareDesignDocument(file, { readSource, passive = false, maxBytes } =
2443
2516
  screenId,
2444
2517
  readSource,
2445
2518
  passive,
2519
+ ...screen.props ? {
2520
+ screenProps: Object.fromEntries(
2521
+ Object.entries(screen.props).map(([name, declaration]) => [
2522
+ name,
2523
+ Object.hasOwn(values, name) ? values[name] : declaration.default
2524
+ ])
2525
+ )
2526
+ } : {},
2446
2527
  ...maxBytes === void 0 ? {} : { maxBytes }
2447
2528
  });
2448
2529
  if (document2.frames.some(({ height }) => height === "auto"))
@@ -2465,8 +2546,12 @@ function prepareDesignDocument(file, { readSource, passive = false, maxBytes } =
2465
2546
  );
2466
2547
  }
2467
2548
  const report = lintDesign(bundled.html, {
2468
- designSystem: document2.designSystem
2549
+ designSystem: document2.designSystem,
2550
+ screen,
2551
+ variant
2469
2552
  });
2553
+ report.warnings.push(...themeWarnings.filter((item) => item.screenId === screenId));
2554
+ report.summary = `${report.errors.length} error(s), ${report.warnings.length} warning(s)`;
2470
2555
  lint.push({ variantId: variant.id, screenId, ...report });
2471
2556
  for (const anchor of screen.anchors ?? []) {
2472
2557
  if (!bundled.html.includes(`data-planr-id="${anchor}"`) && !bundled.html.includes(`id="${anchor}"`))
@@ -654,7 +654,7 @@ function compileDesignHandoffReadiness(input) {
654
654
  if (input === null || input === void 0) return designHandoffReadinessAbsence();
655
655
  const source = plainClone(input);
656
656
  const document = source.document;
657
- if (!document || document.kind !== "openplanr-design-document" || document.schemaVersion !== "1.0.0" || typeof document.id !== "string" || !document.id)
657
+ if (!document || document.kind !== "openplanr-design-document" || !["1.0.0", "1.1.0"].includes(document.schemaVersion) || typeof document.id !== "string" || !document.id)
658
658
  throw new TypeError("Readiness requires one supported design document.");
659
659
  const revision = source.sourceRevision === null || source.sourceRevision === void 0 ? null : normalizeDigest(source.sourceRevision, "design revision");
660
660
  const direction = selectedDirection(document, source.studioState);
@@ -1807,7 +1807,7 @@ async function importDesignShareRecovery(file, { input, ...options } = {}) {
1807
1807
  const pending = custody.pendingCreate ?? custody.pendingMutation.body;
1808
1808
  const destination = join3(root, "uploads", custody.id, pending.operationId);
1809
1809
  if (existsSync4(destination)) {
1810
- const { spoolChunkReader: spoolChunkReader2 } = await import("./design-runtime-support-6774fd3d5d02.mjs");
1810
+ const { spoolChunkReader: spoolChunkReader2 } = await import("./design-runtime-support-25485dbf1cb2.mjs");
1811
1811
  const reader = spoolChunkReader2(destination, pending);
1812
1812
  for (const part of pending.manifest.chunks) await reader(part.index);
1813
1813
  } else await copyUploadSpool(custody, destination);
@@ -15,7 +15,9 @@ import {
15
15
  } from "./design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs";
16
16
  import {
17
17
  DESIGN_DOCUMENT_SCHEMA,
18
+ DESIGN_DOCUMENT_V120_SCHEMA,
18
19
  DESIGN_REVIEW_BUNDLE_SCHEMA,
20
+ validateDesignProps,
19
21
  validateJson
20
22
  } from "./design-shared-protocol-contracts-b5f28f94.mjs";
21
23
  import {
@@ -323,6 +325,7 @@ var MIME = {
323
325
  };
324
326
  var children = (node) => [...node.childNodes ?? [], ...node.content?.childNodes ?? []];
325
327
  var attr = (node, name) => node.attrs?.find((item2) => item2.name === name);
328
+ var isPropToken = (value) => typeof value === "string" && value.length <= 128 && /^[a-z][a-z0-9-]*(?![\s\S])/u.test(value);
326
329
  var text = (node) => children(node).map((item2) => item2.value ?? "").join("");
327
330
  function setText(node, value) {
328
331
  node.childNodes = [{ nodeName: "#text", value, parentNode: node }];
@@ -332,6 +335,23 @@ function element(name, value) {
332
335
  setText(node, value);
333
336
  return node;
334
337
  }
338
+ function parseBodySource(html) {
339
+ const roots = [];
340
+ const parser = new Parser({ sourceCodeLocationInfo: true });
341
+ const onStartTag = parser.onStartTag.bind(parser);
342
+ parser.onStartTag = (token) => {
343
+ if (token.tagName === "body") roots.push(token);
344
+ onStartTag(token);
345
+ };
346
+ parser.tokenizer.write(html, true);
347
+ const body = parser.document.childNodes.find((node) => node.tagName === "html")?.childNodes.find((node) => node.tagName === "body");
348
+ const root = roots.length === 1 && body?.sourceCodeLocation?.startTag?.startOffset === roots[0].location?.startOffset ? roots[0] : null;
349
+ return { document: parser.document, roots, root };
350
+ }
351
+ function inspectLocalDocumentBody(html) {
352
+ const { root } = parseBodySource(html);
353
+ return root ? { attrs: root.attrs, location: root.location } : null;
354
+ }
335
355
  function resolveLocalDocumentFile(root, path, from = root) {
336
356
  if (typeof path !== "string" || !path || /^(?:[a-z][a-z\d+.-]*:|\/|\\)/iu.test(path))
337
357
  throw new Error(`Expected a local relative asset: ${path}`);
@@ -353,7 +373,8 @@ function bundleLocalDocument({
353
373
  screenId,
354
374
  maxBytes = MAX_ARTIFACT_HTML_BYTES,
355
375
  readSource,
356
- passive = false
376
+ passive = false,
377
+ screenProps
357
378
  }) {
358
379
  const root = realpathSync2(inputRoot);
359
380
  const files = /* @__PURE__ */ new Map();
@@ -483,7 +504,16 @@ function bundleLocalDocument({
483
504
  return value.replace(/<\/script/giu, "<\\/script");
484
505
  }
485
506
  const input = read(source.html);
486
- const document = parse(input.value.toString("utf8"));
507
+ const propEntries = Object.entries(screenProps ?? {});
508
+ let document;
509
+ if (propEntries.length) {
510
+ const parsed = parseBodySource(input.value.toString("utf8"));
511
+ if (!parsed.root)
512
+ throw new Error(
513
+ `Screen ${screenId} source ${source.html} requires a single authored <body> root for props; found ${parsed.roots.length}.`
514
+ );
515
+ document = parsed.document;
516
+ } else document = parse(input.value.toString("utf8"));
487
517
  let head, body;
488
518
  const deferredScripts = [];
489
519
  const queue = [...children(document)];
@@ -575,6 +605,22 @@ function bundleLocalDocument({
575
605
  body.childNodes.push(node);
576
606
  }
577
607
  body.attrs.push({ name: "data-planr-screen", value: screenId });
608
+ if (propEntries.length) {
609
+ const classes = (attr(body, "class")?.value ?? "").split(/\s+/u).filter(Boolean).filter((item2) => !propEntries.some(([name]) => item2.startsWith(`prop-${name}-`)));
610
+ for (const [name, value] of propEntries) {
611
+ if (!isPropToken(name) || !(typeof value === "boolean" || isPropToken(value)))
612
+ throw new TypeError(
613
+ `Screen ${screenId} source ${source.html} has invalid prop ${name}: ${JSON.stringify(value)}.`
614
+ );
615
+ const attribute = `data-prop-${name}`;
616
+ body.attrs = body.attrs.filter((item2) => item2.name !== attribute);
617
+ body.attrs.push({ name: attribute, value: String(value) });
618
+ const prefix = `prop-${name}-`;
619
+ classes.push(`${prefix}${value}`);
620
+ }
621
+ body.attrs = body.attrs.filter((item2) => item2.name !== "class");
622
+ body.attrs.push({ name: "class", value: classes.join(" ") });
623
+ }
578
624
  const html = serialize(document);
579
625
  if (Buffer.byteLength(html) > maxBytes)
580
626
  throw new Error("Bundled design exceeds the output budget.");
@@ -706,14 +752,41 @@ var currentDesign2 = (
706
752
  );
707
753
  for (const key of ["frames", "layout"])
708
754
  currentDesign2.properties[key] = /** @type {Record<string, unknown>} */
709
- DESIGN_DOCUMENT_SCHEMA.properties[key];
710
- bundleCurrent.$defs = structuredClone(DESIGN_DOCUMENT_SCHEMA.$defs);
755
+ DESIGN_DOCUMENT_V120_SCHEMA.properties[key];
756
+ bundleCurrent.$defs = structuredClone(DESIGN_DOCUMENT_V120_SCHEMA.$defs);
711
757
  var currentEntries = (
712
758
  /** @type {{ items: { properties: Record<string, unknown> } }} */
713
759
  bundleCurrent.properties.entries
714
760
  );
715
761
  currentEntries.items.properties.height = { const: "auto" };
716
- var DESIGN_REVIEW_BUNDLE_CURRENT_SCHEMA = bundleCurrent;
762
+ var bundleProps = (
763
+ /** @type {MutableSchema} */
764
+ structuredClone(bundleCurrent)
765
+ );
766
+ bundleProps.$id = "https://openplanr.dev/schemas/v1.22.0/design-review-bundle.schema.json";
767
+ bundleProps["x-openplanr-contract"] = { id: "design-review-bundle", version: "1.22.0" };
768
+ var propsDesign = (
769
+ /** @type {MutableSchema} */
770
+ bundleProps.properties.design
771
+ );
772
+ var authoredProperties = (
773
+ /** @type {Record<string, unknown>} */
774
+ DESIGN_DOCUMENT_SCHEMA.properties
775
+ );
776
+ propsDesign.properties.schemaVersion = authoredProperties.schemaVersion;
777
+ for (const key of ["screens", "variants"]) {
778
+ const projected = (
779
+ /** @type {{ items: { properties: Record<string, unknown> } }} */
780
+ propsDesign.properties[key]
781
+ );
782
+ const authored = (
783
+ /** @type {{ items: { properties: Record<string, unknown> } }} */
784
+ authoredProperties[key]
785
+ );
786
+ projected.items.properties.props = authored.items.properties.props;
787
+ }
788
+ propsDesign.allOf = structuredClone(DESIGN_DOCUMENT_SCHEMA.allOf);
789
+ var DESIGN_REVIEW_BUNDLE_CURRENT_SCHEMA = bundleProps;
717
790
  var item = closed(
718
791
  {
719
792
  pinId: id,
@@ -830,10 +903,19 @@ function assertDesignReviewMetadata(value) {
830
903
  );
831
904
  }
832
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"');
833
910
  assertReviewExperience(
834
911
  value,
835
- 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
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
836
915
  );
916
+ const propErrors = validateDesignProps(value.design);
917
+ if (propErrors.length) throw new TypeError(`Invalid design props:
918
+ ${propErrors.join("\n")}`);
837
919
  if (["1.1.0", "1.2.0"].includes(value.schemaVersion)) {
838
920
  if (value.reviewContext.designId !== value.design.id || value.contextDigest !== sha256Hex(canonicalizeJson(value.reviewContext)))
839
921
  throw new TypeError("Review context identity or digest does not match its published design.");
@@ -902,6 +984,7 @@ function reviewFingerprints({ document, context, screen, variant, frame, sourceD
902
984
  const components = context.implementation.components.filter(
903
985
  (component) => !component.screenIds?.length || component.screenIds.includes(screen.id)
904
986
  );
987
+ const values = Object.hasOwn(variant.props ?? {}, screen.id) ? variant.props[screen.id] : {};
905
988
  return {
906
989
  screenId: screen.id,
907
990
  variantId: variant.id,
@@ -909,7 +992,15 @@ function reviewFingerprints({ document, context, screen, variant, frame, sourceD
909
992
  contentDigest: reviewDigest({
910
993
  files: Object.entries(sourceDigests).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0),
911
994
  width: frame.width,
912
- height: frame.height
995
+ height: frame.height,
996
+ ...screen.props === void 0 ? {} : {
997
+ props: Object.fromEntries(
998
+ Object.entries(screen.props).map(([name, declaration]) => [
999
+ name,
1000
+ Object.hasOwn(values, name) ? values[name] : declaration.default
1001
+ ])
1002
+ )
1003
+ }
913
1004
  }),
914
1005
  guidanceDigest: reviewDigest({
915
1006
  title: screen.title,
@@ -934,6 +1025,7 @@ function bundleDesignRevision(current, state = {}) {
934
1025
  kind: "openplanr-design-review-bundle",
935
1026
  schemaVersion: current.envelope.schemaVersion === "1.1.0" ? "1.2.0" : "1.1.0",
936
1027
  design: {
1028
+ ...document.screens.some((screen) => screen.props !== void 0) || document.variants.some((variant) => variant.props !== void 0) ? { schemaVersion: document.schemaVersion } : {},
937
1029
  ...pick(document, [
938
1030
  "id",
939
1031
  "title",
@@ -945,12 +1037,12 @@ function bundleDesignRevision(current, state = {}) {
945
1037
  "layout"
946
1038
  ]),
947
1039
  screens: document.screens.map(
948
- (screen) => pick(screen, ["id", "title", "description", "anchors"])
1040
+ (screen) => pick(screen, ["id", "title", "description", "anchors", "props"])
949
1041
  ),
950
1042
  selectedVariant: document.variants.some(
951
1043
  (variant) => variant.id === state.selectedVariant && variant.status === "ready"
952
1044
  ) ? state.selectedVariant : document.selectedVariant,
953
- variants: document.variants.filter((variant) => variant.status === "ready").map((variant) => pick(variant, ["id", "label", "status"]))
1045
+ variants: document.variants.filter((variant) => variant.status === "ready").map((variant) => pick(variant, ["id", "label", "status", "props"]))
954
1046
  },
955
1047
  envelope: structuredClone(current.envelope),
956
1048
  entries: structuredClone(current.entries),
@@ -995,6 +1087,7 @@ export {
995
1087
  serialize,
996
1088
  parse,
997
1089
  parseFragment,
1090
+ inspectLocalDocumentBody,
998
1091
  resolveLocalDocumentFile,
999
1092
  bundleLocalDocument,
1000
1093
  DESIGN_HANDOFF_CONTENT_SCHEMA,
@@ -104,6 +104,7 @@ var VALIDATION_KEYWORDS = [
104
104
  "maxContains",
105
105
  "required",
106
106
  "properties",
107
+ "propertyNames",
107
108
  "additionalProperties",
108
109
  "maxProperties",
109
110
  "dependentRequired",
@@ -172,6 +173,7 @@ var KEYWORD_SHAPES = {
172
173
  maxContains: ["a non-negative integer", isCount],
173
174
  required: ["an array of unique strings", isUniqueStrings],
174
175
  properties: ["an object of schemas", isSchemaMap],
176
+ propertyNames: ["a schema", isSchema],
175
177
  additionalProperties: ["a schema", isSchema],
176
178
  maxProperties: ["a non-negative integer", isCount],
177
179
  dependentRequired: [
@@ -440,6 +442,8 @@ var validateNode = (value, schema6, path, errs, context) => {
440
442
  }
441
443
  const props = schema6.properties || {};
442
444
  for (const [k, v] of Object.entries(value)) {
445
+ if (schema6.propertyNames !== void 0)
446
+ validateNode(k, schema6.propertyNames, `${path}.${k}`, errs, context);
443
447
  if (Object.hasOwn(props, k)) evaluated.add(k);
444
448
  else if (schema6.additionalProperties !== void 0) evaluated.add(k);
445
449
  if (!Object.hasOwn(props, k)) {
@@ -4733,7 +4737,7 @@ var DESIGN_DOCUMENT_V1_SCHEMA = freeze({
4733
4737
  }
4734
4738
  }
4735
4739
  });
4736
- var DESIGN_DOCUMENT_SCHEMA = freeze({
4740
+ var DESIGN_DOCUMENT_V120_SCHEMA = freeze({
4737
4741
  ...DESIGN_DOCUMENT_V1_SCHEMA,
4738
4742
  $id: "https://openplanr.dev/schemas/v1.20.0/design-document.schema.json",
4739
4743
  "x-openplanr-contract": { id: "design-document", version: "1.20.0" },
@@ -4792,11 +4796,134 @@ var DESIGN_DOCUMENT_SCHEMA = freeze({
4792
4796
  coordinate: { type: "number", minimum: -1e7, maximum: 1e7 }
4793
4797
  }
4794
4798
  });
4799
+ var PROP_TOKEN_SCHEMA = {
4800
+ type: "string",
4801
+ minLength: 1,
4802
+ maxLength: 128,
4803
+ pattern: "^[a-z][a-z0-9-]*(?![\\s\\S])"
4804
+ };
4805
+ var propTokenPattern = new RegExp(PROP_TOKEN_SCHEMA.pattern, "u");
4806
+ var isPropToken = (value) => typeof value === "string" && value.length <= PROP_TOKEN_SCHEMA.maxLength && propTokenPattern.test(value);
4807
+ var currentDocument = (
4808
+ /** @type {{ properties: Record<string, unknown>; [key: string]: unknown }} */
4809
+ structuredClone(DESIGN_DOCUMENT_V120_SCHEMA)
4810
+ );
4811
+ currentDocument.$id = "https://openplanr.dev/schemas/v1.22.0/design-document.schema.json";
4812
+ currentDocument["x-openplanr-contract"] = { id: "design-document", version: "1.22.0" };
4813
+ currentDocument.properties.schemaVersion = { enum: ["1.0.0", "1.1.0"] };
4814
+ var screenSchema = (
4815
+ /** @type {{ items: { properties: Record<string, unknown> } }} */
4816
+ currentDocument.properties.screens
4817
+ );
4818
+ screenSchema.items.properties.props = {
4819
+ type: "object",
4820
+ propertyNames: PROP_TOKEN_SCHEMA,
4821
+ additionalProperties: {
4822
+ oneOf: [
4823
+ {
4824
+ type: "object",
4825
+ additionalProperties: false,
4826
+ required: ["type", "options", "default"],
4827
+ properties: {
4828
+ type: { const: "enum" },
4829
+ options: {
4830
+ type: "array",
4831
+ minItems: 1,
4832
+ uniqueItems: true,
4833
+ items: PROP_TOKEN_SCHEMA
4834
+ },
4835
+ default: PROP_TOKEN_SCHEMA
4836
+ }
4837
+ },
4838
+ {
4839
+ type: "object",
4840
+ additionalProperties: false,
4841
+ required: ["type", "default"],
4842
+ properties: { type: { const: "boolean" }, default: { type: "boolean" } }
4843
+ }
4844
+ ]
4845
+ }
4846
+ };
4847
+ var variantSchema = (
4848
+ /** @type {{ items: { properties: Record<string, unknown> } }} */
4849
+ currentDocument.properties.variants
4850
+ );
4851
+ variantSchema.items.properties.props = {
4852
+ type: "object",
4853
+ propertyNames: { $ref: "#/$defs/id" },
4854
+ additionalProperties: {
4855
+ type: "object",
4856
+ propertyNames: PROP_TOKEN_SCHEMA,
4857
+ additionalProperties: { anyOf: [PROP_TOKEN_SCHEMA, { type: "boolean" }] }
4858
+ }
4859
+ };
4860
+ currentDocument.allOf = [
4861
+ {
4862
+ if: { properties: { schemaVersion: { const: "1.1.0" } }, required: ["schemaVersion"] },
4863
+ else: {
4864
+ properties: {
4865
+ screens: { items: { not: { required: ["props"] } } },
4866
+ variants: { items: { not: { required: ["props"] } } }
4867
+ }
4868
+ }
4869
+ }
4870
+ ];
4871
+ var DESIGN_DOCUMENT_SCHEMA = freeze(currentDocument);
4872
+ function validateDesignProps(document) {
4873
+ const errors = [];
4874
+ const checkToken = (value, path) => {
4875
+ if (!isPropToken(value))
4876
+ errors.push(
4877
+ `${path}: ${JSON.stringify(value)} must be a lowercase token matching ${PROP_TOKEN_SCHEMA.pattern} with at most ${PROP_TOKEN_SCHEMA.maxLength} characters`
4878
+ );
4879
+ };
4880
+ const screens = new Map(document.screens.map((screen) => [screen.id, screen]));
4881
+ for (const [index2, screen] of document.screens.entries()) {
4882
+ for (const [name, prop] of Object.entries(screen.props ?? {})) {
4883
+ const path = `$.screens[${index2}].props.${name}`;
4884
+ checkToken(name, path);
4885
+ if (prop.type === "enum") {
4886
+ for (const [optionIndex, option] of prop.options.entries())
4887
+ checkToken(option, `${path}.options[${optionIndex}]`);
4888
+ checkToken(prop.default, `${path}.default`);
4889
+ if (!prop.options.includes(prop.default))
4890
+ errors.push(`${path}.default: '${prop.default}' is not an enum option`);
4891
+ }
4892
+ }
4893
+ }
4894
+ for (const [index2, variant] of document.variants.entries()) {
4895
+ for (const [screenId, values] of Object.entries(variant.props ?? {})) {
4896
+ const screen = screens.get(screenId);
4897
+ const path = `$.variants[${index2}].props.${screenId}`;
4898
+ if (!screen) {
4899
+ errors.push(`${path}: unknown screen '${screenId}'`);
4900
+ continue;
4901
+ }
4902
+ for (const [name, value] of Object.entries(values)) {
4903
+ checkToken(name, `${path}.${name}`);
4904
+ if (typeof value === "string") checkToken(value, `${path}.${name}`);
4905
+ const props = screen.props ?? {};
4906
+ const prop = Object.hasOwn(props, name) ? props[name] : void 0;
4907
+ if (!prop) errors.push(`${path}.${name}: unknown prop '${name}' on screen '${screenId}'`);
4908
+ else if (prop.type === "boolean" && typeof value !== "boolean")
4909
+ errors.push(`${path}.${name}: expected a boolean, received ${JSON.stringify(value)}`);
4910
+ else if (prop.type === "enum" && (typeof value !== "string" || !prop.options.includes(value)))
4911
+ errors.push(`${path}.${name}: ${JSON.stringify(value)} is not an enum option`);
4912
+ }
4913
+ }
4914
+ }
4915
+ return errors;
4916
+ }
4795
4917
  function validateDesignDocument(value) {
4796
4918
  const errors = validateJson(value, DESIGN_DOCUMENT_SCHEMA).map(
4797
4919
  ({ path, detail }) => `${path}: ${detail}`
4798
4920
  );
4921
+ if (value?.schemaVersion === "1.0.0" && ["screens", "variants"].some(
4922
+ (field) => Array.isArray(value[field]) && value[field].some((item2) => item2 && Object.hasOwn(item2, "props"))
4923
+ ))
4924
+ errors.push('$.schemaVersion: props require schemaVersion "1.1.0"');
4799
4925
  if (errors.length > 0) return { ok: false, errors };
4926
+ errors.push(...validateDesignProps(value));
4800
4927
  for (const field of ["frames", "screens", "flows", "variants"]) {
4801
4928
  const seen = /* @__PURE__ */ new Set();
4802
4929
  for (const [index2, item2] of (value[field] ?? []).entries()) {
@@ -5759,7 +5886,9 @@ function assertLargeObjectContract(value, kind) {
5759
5886
  export {
5760
5887
  validateJson,
5761
5888
  initialFrameHeight,
5889
+ DESIGN_DOCUMENT_V120_SCHEMA,
5762
5890
  DESIGN_DOCUMENT_SCHEMA,
5891
+ validateDesignProps,
5763
5892
  assertDesignDocument,
5764
5893
  DESIGN_WORKSPACE_VERSION,
5765
5894
  DESIGN_WORKSPACE_API,