@pixel-point/toolcraft 0.0.13 → 0.0.15

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 (582) hide show
  1. package/README.md +13 -2
  2. package/package.json +1 -1
  3. package/scripts/prepare-pack.mjs +2 -28
  4. package/src/cli-io.mjs +174 -0
  5. package/src/cli-package-manager-flow.test.mjs +206 -0
  6. package/src/cli.mjs +7 -495
  7. package/src/cli.test.mjs +34 -177
  8. package/src/create-command.mjs +152 -0
  9. package/src/create-options.mjs +194 -0
  10. package/src/generate-test-assertions.mjs +27 -0
  11. package/src/generate-test-doc-assertions.mjs +162 -0
  12. package/src/generate-test-file-assertions.mjs +251 -0
  13. package/src/generate-test-fs-utils.mjs +59 -0
  14. package/src/generate-test-integrity-assertions.mjs +30 -0
  15. package/src/generate-test-integrity-framework-assertions.mjs +222 -0
  16. package/src/generate-test-integrity-manifest-assertions.mjs +150 -0
  17. package/src/generate-test-integrity-ownership-assertions.mjs +127 -0
  18. package/src/generate-test-integrity-test-utils.mjs +102 -0
  19. package/src/generate-test-package-assertions.mjs +75 -0
  20. package/src/generate-test-product-fixture.mjs +84 -0
  21. package/src/generate-test-product-fixture.test.mjs +73 -0
  22. package/src/generate-test-standalone-assertions.mjs +209 -0
  23. package/src/generate-transactional.test.mjs +151 -0
  24. package/src/generate.mjs +182 -102
  25. package/src/generate.test.mjs +241 -294
  26. package/src/generated-integrity-manifest.mjs +127 -0
  27. package/src/generated-integrity-manifest.test.mjs +151 -0
  28. package/src/generated-source-policy.mjs +22 -0
  29. package/src/generated-source-policy.test.mjs +35 -0
  30. package/src/generated-target-policy.mjs +55 -0
  31. package/src/generation-transaction.mjs +135 -0
  32. package/src/generation-transaction.test.mjs +74 -0
  33. package/src/package-json.mjs +18 -1
  34. package/src/package-json.test.mjs +38 -5
  35. package/src/package-manager.mjs +2 -0
  36. package/src/package-manager.test.mjs +5 -1
  37. package/src/packaged-template-fallback.test.mjs +126 -0
  38. package/src/prepare-pack-templates.mjs +34 -0
  39. package/templates/runtime/contracts/component-contract-builders.ts +95 -0
  40. package/templates/runtime/contracts/component-contracts.choices.test.ts +293 -0
  41. package/templates/runtime/contracts/component-contracts.choices.ts +322 -0
  42. package/templates/runtime/contracts/component-contracts.inputs.test.ts +210 -0
  43. package/templates/runtime/contracts/component-contracts.inputs.ts +252 -0
  44. package/templates/runtime/contracts/component-contracts.media-custom.test.ts +116 -0
  45. package/templates/runtime/contracts/component-contracts.media-custom.ts +144 -0
  46. package/templates/runtime/contracts/component-contracts.runtime-acceptance.test.ts +229 -0
  47. package/templates/runtime/contracts/component-contracts.runtime-labels.test.ts +76 -0
  48. package/templates/runtime/contracts/component-contracts.runtime-panels.test.ts +135 -0
  49. package/templates/runtime/contracts/component-contracts.runtime-shell.test.ts +148 -0
  50. package/templates/runtime/contracts/component-contracts.runtime.ts +361 -0
  51. package/templates/runtime/contracts/component-contracts.test.ts +39 -1458
  52. package/templates/runtime/contracts/component-contracts.ts +44 -1505
  53. package/templates/runtime/contracts/component-contracts.visual.test.ts +316 -0
  54. package/templates/runtime/contracts/component-contracts.visual.ts +385 -0
  55. package/templates/runtime/contracts/contract-manifest.test.ts +64 -0
  56. package/templates/runtime/contracts/decision-contracts.test.ts +29 -4
  57. package/templates/runtime/contracts/decision-contracts.ts +38 -1
  58. package/templates/runtime/index.ts +1 -0
  59. package/templates/runtime/react/{runtime-public-api.test.tsx → app-shell/runtime-public-api.test.tsx} +29 -7
  60. package/templates/runtime/react/{settings-transfer.test.ts → app-shell/settings-transfer.test.ts} +4 -4
  61. package/templates/runtime/react/{settings-transfer.ts → app-shell/settings-transfer.ts} +3 -3
  62. package/templates/runtime/react/{toolbar-panel.test.tsx → app-shell/toolbar-panel.test.tsx} +2 -2
  63. package/templates/runtime/react/{toolbar-panel.tsx → app-shell/toolbar-panel.tsx} +3 -3
  64. package/templates/runtime/react/{toolcraft-app.integration.test.tsx → app-shell/toolcraft-app.integration.test.tsx} +6 -6
  65. package/templates/runtime/react/{toolcraft-app.test.tsx → app-shell/toolcraft-app.test.tsx} +3 -3
  66. package/templates/runtime/react/{toolcraft-app.tsx → app-shell/toolcraft-app.tsx} +11 -8
  67. package/templates/runtime/react/{toolcraft-root.test.tsx → app-shell/toolcraft-root.test.tsx} +1 -1
  68. package/templates/runtime/react/{toolcraft-root.tsx → app-shell/toolcraft-root.tsx} +5 -5
  69. package/templates/runtime/react/{use-toolcraft.ts → app-shell/use-toolcraft.ts} +1 -1
  70. package/templates/runtime/react/canvas/canvas-default-media-layer.tsx +81 -0
  71. package/templates/runtime/react/canvas/canvas-media-transform.ts +33 -0
  72. package/templates/runtime/react/canvas/canvas-shell-interactions.test.tsx +156 -0
  73. package/templates/runtime/react/canvas/canvas-shell-media-rendering.test.tsx +87 -0
  74. package/templates/runtime/react/canvas/canvas-shell-rendering.test.tsx +102 -0
  75. package/templates/runtime/react/canvas/canvas-shell-test-utils.tsx +108 -0
  76. package/templates/runtime/react/canvas/canvas-shell-upload.test.tsx +106 -0
  77. package/templates/runtime/react/canvas/canvas-shell.tsx +146 -0
  78. package/templates/runtime/react/canvas/canvas-upload-routing.ts +84 -0
  79. package/templates/runtime/react/{media-file.ts → canvas/media-file.ts} +1 -1
  80. package/templates/runtime/react/canvas/use-canvas-drop-import.ts +145 -0
  81. package/templates/runtime/react/canvas/use-canvas-viewport-interactions.ts +227 -0
  82. package/templates/runtime/react/controls-panel/__tests__/control-conditions.test.ts +89 -0
  83. package/templates/runtime/react/{controls-panel-filedrop-reorder.test.tsx → controls-panel/__tests__/controls-panel-filedrop-reorder.test.tsx} +4 -4
  84. package/templates/runtime/react/controls-panel/__tests__/controls-panel.actions-layout.test.tsx +91 -0
  85. package/templates/runtime/react/controls-panel/__tests__/controls-panel.collection-actions.test.tsx +213 -0
  86. package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-layout.test.tsx +366 -0
  87. package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-picker-models.test.tsx +169 -0
  88. package/templates/runtime/react/controls-panel/__tests__/controls-panel.compound-layout.test.tsx +160 -0
  89. package/templates/runtime/react/controls-panel/__tests__/controls-panel.control-visibility.test.tsx +352 -0
  90. package/templates/runtime/react/controls-panel/__tests__/controls-panel.curves.test.tsx +226 -0
  91. package/templates/runtime/react/controls-panel/__tests__/controls-panel.floating-shell.test.tsx +13 -0
  92. package/templates/runtime/react/controls-panel/__tests__/controls-panel.font-picker.test.tsx +302 -0
  93. package/templates/runtime/react/controls-panel/__tests__/controls-panel.footer-actions.test.tsx +401 -0
  94. package/templates/runtime/react/controls-panel/__tests__/controls-panel.gradient-control.test.tsx +139 -0
  95. package/templates/runtime/react/controls-panel/__tests__/controls-panel.help-policy.test.tsx +103 -0
  96. package/templates/runtime/react/controls-panel/__tests__/controls-panel.image-picker.test.tsx +16 -0
  97. package/templates/runtime/react/controls-panel/__tests__/controls-panel.inline-layout.test.tsx +290 -0
  98. package/templates/runtime/react/controls-panel/__tests__/controls-panel.keyframes.test.tsx +175 -0
  99. package/templates/runtime/react/controls-panel/__tests__/controls-panel.media-upload-files.test.tsx +121 -0
  100. package/templates/runtime/react/controls-panel/__tests__/controls-panel.media-upload-image.test.tsx +363 -0
  101. package/templates/runtime/react/controls-panel/__tests__/controls-panel.media-upload-multi-image.test.tsx +105 -0
  102. package/templates/runtime/react/controls-panel/__tests__/controls-panel.range-slider-editing.test.tsx +149 -0
  103. package/templates/runtime/react/controls-panel/__tests__/controls-panel.section-shell.test.tsx +138 -0
  104. package/templates/runtime/react/controls-panel/__tests__/controls-panel.select-layout.test.tsx +148 -0
  105. package/templates/runtime/react/controls-panel/__tests__/controls-panel.setup-controls.test.tsx +189 -0
  106. package/templates/runtime/react/controls-panel/__tests__/controls-panel.slider-rendering.test.tsx +317 -0
  107. package/templates/runtime/react/controls-panel/__tests__/controls-panel.state-reset.test.tsx +137 -0
  108. package/templates/runtime/react/controls-panel/__tests__/controls-panel.structure.test.tsx +66 -0
  109. package/templates/runtime/react/controls-panel/__tests__/controls-panel.text-input.test.tsx +205 -0
  110. package/templates/runtime/react/controls-panel/__tests__/controls-panel.vector-interaction.test.tsx +388 -0
  111. package/templates/runtime/react/controls-panel/__tests__/controls-panel.vector-layout.test.tsx +155 -0
  112. package/templates/runtime/react/controls-panel/actions/controls-panel-actions.ts +172 -0
  113. package/templates/runtime/react/{control-conditions.ts → controls-panel/conditions/control-conditions.ts} +26 -3
  114. package/templates/runtime/react/{control-renderers.ts → controls-panel/control-renderers.ts} +2 -2
  115. package/templates/runtime/react/controls-panel/controls-panel.tsx +250 -0
  116. package/templates/runtime/react/controls-panel/keyframes/controls-panel-keyframes.tsx +265 -0
  117. package/templates/runtime/react/controls-panel/layout/controls-panel-collapse-storage.ts +131 -0
  118. package/templates/runtime/react/controls-panel/layout/controls-panel-help.tsx +132 -0
  119. package/templates/runtime/react/controls-panel/layout/controls-panel-inline-layout.tsx +311 -0
  120. package/templates/runtime/react/controls-panel/layout/controls-panel-layout.tsx +216 -0
  121. package/templates/runtime/react/controls-panel/layout/controls-panel-section.tsx +401 -0
  122. package/templates/runtime/react/controls-panel/renderers/controls-panel-action-renderer.tsx +137 -0
  123. package/templates/runtime/react/controls-panel/renderers/controls-panel-basic-renderers.tsx +421 -0
  124. package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-renderer.tsx +286 -0
  125. package/templates/runtime/react/controls-panel/renderers/controls-panel-compound-renderers.tsx +366 -0
  126. package/templates/runtime/react/controls-panel/renderers/controls-panel-media-renderer.tsx +173 -0
  127. package/templates/runtime/react/controls-panel/renderers/controls-panel-renderer-registry.test.ts +23 -0
  128. package/templates/runtime/react/controls-panel/renderers/controls-panel-renderer-registry.ts +55 -0
  129. package/templates/runtime/react/controls-panel/renderers/controls-panel-settings-transfer-renderer.tsx +45 -0
  130. package/templates/runtime/react/controls-panel/testing/controls-panel-test-utils.tsx +300 -0
  131. package/templates/runtime/react/controls-panel/values/controls-panel-aspect-ratio-values.ts +94 -0
  132. package/templates/runtime/react/controls-panel/values/controls-panel-collection-values.ts +87 -0
  133. package/templates/runtime/react/controls-panel/values/controls-panel-color-values.ts +82 -0
  134. package/templates/runtime/react/controls-panel/values/controls-panel-font-values.ts +69 -0
  135. package/templates/runtime/react/controls-panel/values/controls-panel-spatial-values.ts +64 -0
  136. package/templates/runtime/react/controls-panel/values/controls-panel-value-labels.ts +93 -0
  137. package/templates/runtime/react/controls-panel/values/controls-panel-value-primitives.ts +30 -0
  138. package/templates/runtime/react/controls-panel/values/controls-panel-values.ts +7 -0
  139. package/templates/runtime/react/index.ts +13 -13
  140. package/templates/runtime/react/{layer-tree.ts → layers/layer-tree.ts} +1 -1
  141. package/templates/runtime/react/layers/layers-panel-drag-drop.test.tsx +190 -0
  142. package/templates/runtime/react/layers/layers-panel-editing.test.tsx +41 -0
  143. package/templates/runtime/react/layers/layers-panel-insert-targets.test.ts +87 -0
  144. package/templates/runtime/react/layers/layers-panel-insert-targets.ts +254 -0
  145. package/templates/runtime/react/layers/layers-panel-model.ts +15 -0
  146. package/templates/runtime/react/layers/layers-panel-rendering.test.tsx +43 -0
  147. package/templates/runtime/react/layers/layers-panel-reorder.ts +148 -0
  148. package/templates/runtime/react/layers/layers-panel-row.tsx +475 -0
  149. package/templates/runtime/react/layers/layers-panel-test-utils.tsx +135 -0
  150. package/templates/runtime/react/layers/layers-panel-visibility.test.tsx +126 -0
  151. package/templates/runtime/react/layers/layers-panel.tsx +349 -0
  152. package/templates/runtime/react/layers/use-layers-panel-drag-controller.ts +327 -0
  153. package/templates/runtime/react/{panel-host-types.ts → panel-host/panel-host-types.ts} +2 -2
  154. package/templates/runtime/react/{panel-host.test.tsx → panel-host/panel-host.test.tsx} +3 -3
  155. package/templates/runtime/react/{panel-host.tsx → panel-host/panel-host.tsx} +1 -1
  156. package/templates/runtime/react/timeline/timeline-easing-editor.tsx +409 -0
  157. package/templates/runtime/react/timeline/timeline-easing-geometry.ts +42 -0
  158. package/templates/runtime/react/timeline/timeline-easing-icons.tsx +135 -0
  159. package/templates/runtime/react/timeline/timeline-easing-model.test.ts +87 -0
  160. package/templates/runtime/react/timeline/timeline-easing-model.ts +271 -0
  161. package/templates/runtime/react/timeline/timeline-easing-popover-content.tsx +227 -0
  162. package/templates/runtime/react/timeline/timeline-easing-popover-layout.ts +69 -0
  163. package/templates/runtime/react/timeline/timeline-easing-popover.tsx +60 -0
  164. package/templates/runtime/react/timeline/timeline-event-targets.ts +19 -0
  165. package/templates/runtime/react/timeline/timeline-expanded-content.tsx +299 -0
  166. package/templates/runtime/react/timeline/timeline-icon-button.tsx +51 -0
  167. package/templates/runtime/react/timeline/timeline-keyframe-row.tsx +360 -0
  168. package/templates/runtime/react/timeline/timeline-keyframes.ts +23 -0
  169. package/templates/runtime/react/timeline/timeline-panel-floating-layout.test.tsx +328 -0
  170. package/templates/runtime/react/timeline/timeline-panel-header.tsx +404 -0
  171. package/templates/runtime/react/timeline/timeline-panel-keyframes.test.tsx +90 -0
  172. package/templates/runtime/react/timeline/timeline-panel-layout.ts +30 -0
  173. package/templates/runtime/react/timeline/timeline-panel-responsive-layout.ts +182 -0
  174. package/templates/runtime/react/timeline/timeline-panel-test-utils.tsx +88 -0
  175. package/templates/runtime/react/timeline/timeline-panel-transport.test.tsx +202 -0
  176. package/templates/runtime/react/timeline/timeline-panel-upload.test.tsx +53 -0
  177. package/templates/runtime/react/timeline/timeline-panel.tsx +449 -0
  178. package/templates/runtime/react/timeline/timeline-playback-hooks.ts +254 -0
  179. package/templates/runtime/schema/assembly-contract.ts +271 -0
  180. package/templates/runtime/schema/control-schema-normalization.ts +55 -0
  181. package/templates/runtime/schema/controls-panel-actions.ts +141 -0
  182. package/templates/runtime/schema/controls-panel-layout-groups.ts +144 -0
  183. package/templates/runtime/schema/controls-panel-normalization.ts +19 -0
  184. package/templates/runtime/schema/controls-panel-section-layout.ts +140 -0
  185. package/templates/runtime/schema/controls-panel-section-titles.ts +161 -0
  186. package/templates/runtime/schema/define-toolcraft-test-utils.ts +18 -0
  187. package/templates/runtime/schema/define-toolcraft.actions.test.ts +182 -0
  188. package/templates/runtime/schema/define-toolcraft.assembly.test.ts +246 -0
  189. package/templates/runtime/schema/define-toolcraft.canvas.test.ts +150 -0
  190. package/templates/runtime/schema/define-toolcraft.control-layout.test.ts +345 -0
  191. package/templates/runtime/schema/define-toolcraft.control-sections.test.ts +304 -0
  192. package/templates/runtime/schema/define-toolcraft.setup-canvas.test.ts +69 -0
  193. package/templates/runtime/schema/define-toolcraft.setup-persistence.test.ts +66 -0
  194. package/templates/runtime/schema/define-toolcraft.setup-render-scale-timeline.test.ts +116 -0
  195. package/templates/runtime/schema/define-toolcraft.setup-settings-transfer.test.ts +291 -0
  196. package/templates/runtime/schema/define-toolcraft.ts +24 -1449
  197. package/templates/runtime/schema/panels-schema-normalization.ts +49 -0
  198. package/templates/runtime/schema/runtime-section-titles.ts +1 -0
  199. package/templates/runtime/schema/runtime-setup-section.ts +282 -0
  200. package/templates/runtime/schema/schema-resolvers.ts +168 -0
  201. package/templates/runtime/schema/types.ts +17 -0
  202. package/templates/runtime/state/canvas-reducer.ts +106 -0
  203. package/templates/runtime/state/canvas-state.ts +209 -0
  204. package/templates/runtime/state/controls-reducer.ts +277 -0
  205. package/templates/runtime/state/history-patches.ts +174 -0
  206. package/templates/runtime/state/layer-state.ts +12 -0
  207. package/templates/runtime/state/layers-reducer.ts +318 -0
  208. package/templates/runtime/state/media-reducer.ts +283 -0
  209. package/templates/runtime/state/media-state.ts +105 -0
  210. package/templates/runtime/state/panels-reducer.ts +58 -0
  211. package/templates/runtime/state/persistence-merge.ts +53 -0
  212. package/templates/runtime/state/persistence-reader-canvas.ts +27 -0
  213. package/templates/runtime/state/persistence-reader-layers.ts +73 -0
  214. package/templates/runtime/state/persistence-reader-media.ts +82 -0
  215. package/templates/runtime/state/persistence-reader-panels.ts +56 -0
  216. package/templates/runtime/state/persistence-reader-primitives.ts +27 -0
  217. package/templates/runtime/state/persistence-reader-timeline.ts +145 -0
  218. package/templates/runtime/state/persistence-reader-values.ts +40 -0
  219. package/templates/runtime/state/persistence-readers.ts +72 -0
  220. package/templates/runtime/state/persistence-shared.ts +23 -0
  221. package/templates/runtime/state/persistence-snapshot.ts +57 -0
  222. package/templates/runtime/state/persistence.ts +16 -581
  223. package/templates/runtime/state/reducer-canvas-panels.test.ts +324 -0
  224. package/templates/runtime/state/reducer-controls.test.ts +158 -0
  225. package/templates/runtime/state/reducer-layers.test.ts +306 -0
  226. package/templates/runtime/state/reducer-media-import-sizing.test.ts +197 -0
  227. package/templates/runtime/state/reducer-media-reorder-history.test.ts +116 -0
  228. package/templates/runtime/state/reducer-media-reset.test.ts +249 -0
  229. package/templates/runtime/state/reducer-media-test-utils.ts +40 -0
  230. package/templates/runtime/state/reducer-media-transform.test.ts +52 -0
  231. package/templates/runtime/state/reducer-test-utils.ts +30 -0
  232. package/templates/runtime/state/reducer-timeline.test.ts +242 -0
  233. package/templates/runtime/state/reducer.ts +57 -1785
  234. package/templates/runtime/state/timeline-reducer.ts +412 -0
  235. package/templates/runtime/state/timeline-values.test.ts +45 -0
  236. package/templates/runtime/state/timeline-values.ts +45 -0
  237. package/templates/runtime/testing/performance-browser-policy.test.ts +81 -0
  238. package/templates/runtime/testing/performance-browser-policy.ts +102 -0
  239. package/templates/runtime/testing/performance-budget-validation.ts +84 -0
  240. package/templates/runtime/testing/performance-control-classification.test.ts +106 -0
  241. package/templates/runtime/testing/performance-control-classification.ts +101 -0
  242. package/templates/runtime/testing/performance-coverage-context.ts +44 -0
  243. package/templates/runtime/testing/performance-coverage-renderer-policy.ts +221 -0
  244. package/templates/runtime/testing/performance-coverage-scenario-policy.ts +147 -0
  245. package/templates/runtime/testing/performance-coverage-target-policy.ts +121 -0
  246. package/templates/runtime/testing/performance-coverage-validator.ts +34 -0
  247. package/templates/runtime/testing/performance-export-coverage.test.ts +234 -0
  248. package/templates/runtime/testing/performance-fixture-load-profile.test.ts +360 -0
  249. package/templates/runtime/testing/performance-fixture-media.test.ts +80 -0
  250. package/templates/runtime/testing/performance-fixture-stress.test.ts +314 -0
  251. package/templates/runtime/testing/performance-fixture-validation.ts +255 -0
  252. package/templates/runtime/testing/performance-fixture-values.ts +275 -0
  253. package/templates/runtime/testing/performance-fixture-workload.test.ts +140 -0
  254. package/templates/runtime/testing/performance-load-profile-validation.ts +467 -0
  255. package/templates/runtime/testing/performance-renderer-coverage.test.ts +325 -0
  256. package/templates/runtime/testing/performance-renderer-pipeline-coverage.test.ts +115 -0
  257. package/templates/runtime/testing/performance-renderer-pipeline-interactions.test.ts +201 -0
  258. package/templates/runtime/testing/performance-renderer-pipeline-passes.test.ts +247 -0
  259. package/templates/runtime/testing/performance-renderer-pipeline-validation.ts +360 -0
  260. package/templates/runtime/testing/performance-renderer-technique-validation.ts +329 -0
  261. package/templates/runtime/testing/performance-renderer-technique.test.ts +275 -0
  262. package/templates/runtime/testing/performance-renderer-validation.ts +2 -0
  263. package/templates/runtime/testing/performance-scenario-coverage.test.ts +303 -0
  264. package/templates/runtime/testing/performance-scenario-validation.ts +49 -0
  265. package/templates/runtime/testing/performance-schema-derived-workloads.test.ts +231 -0
  266. package/templates/runtime/testing/performance-schema-queries.ts +181 -0
  267. package/templates/runtime/testing/performance-test-fixtures/index.ts +4 -0
  268. package/templates/runtime/testing/performance-test-fixtures/renderer-pipelines.ts +322 -0
  269. package/templates/runtime/testing/performance-test-fixtures/scenarios.ts +172 -0
  270. package/templates/runtime/testing/performance-test-fixtures/schemas.ts +151 -0
  271. package/templates/runtime/testing/performance-test-fixtures/stress-fixtures.ts +133 -0
  272. package/templates/runtime/testing/performance-test-fixtures.ts +1 -0
  273. package/templates/runtime/testing/performance-types.ts +338 -0
  274. package/templates/runtime/testing/performance.ts +15 -2485
  275. package/templates/starter/AGENTS.md +45 -29
  276. package/templates/starter/LICENSE.md +18 -95
  277. package/templates/starter/NOTICE.md +3 -3
  278. package/templates/starter/docs/toolcraft/README.md +19 -4
  279. package/templates/starter/docs/toolcraft/acceptance-testing.md +38 -8
  280. package/templates/starter/docs/toolcraft/assembly-workflow.md +46 -185
  281. package/templates/starter/docs/toolcraft/component-rules.md +18 -190
  282. package/templates/starter/docs/toolcraft/core/control-selection.md +93 -0
  283. package/templates/starter/docs/toolcraft/core/layout.md +105 -0
  284. package/templates/starter/docs/toolcraft/core/media-upload.md +85 -0
  285. package/templates/starter/docs/toolcraft/core/performance.md +86 -0
  286. package/templates/starter/docs/toolcraft/core/reference-study.md +115 -0
  287. package/templates/starter/docs/toolcraft/core/runtime-boundary.md +60 -0
  288. package/templates/starter/docs/toolcraft/core/setup-export.md +86 -0
  289. package/templates/starter/docs/toolcraft/core/timeline-animation.md +68 -0
  290. package/templates/starter/docs/toolcraft/custom-controls.md +10 -1
  291. package/templates/starter/docs/toolcraft/decision-contract.md +26 -22
  292. package/templates/starter/docs/toolcraft/performance.md +44 -16
  293. package/templates/starter/docs/toolcraft/renderer-technique.md +2 -0
  294. package/templates/starter/docs/toolcraft/schema-reference.md +127 -366
  295. package/templates/starter/docs/toolcraft/workflow.md +26 -16
  296. package/templates/starter/e2e/app-browser-acceptance-evidence.spec.ts +111 -0
  297. package/templates/starter/e2e/app-browser-control-coverage.spec.ts +118 -0
  298. package/templates/starter/e2e/app-browser-performance-evidence.spec.ts +217 -0
  299. package/templates/starter/e2e/app-browser-performance-probe.spec.ts +322 -0
  300. package/templates/starter/e2e/app-browser-proof-session.spec.ts +196 -0
  301. package/templates/starter/e2e/app-browser-runtime-evidence.spec.ts +9 -0
  302. package/templates/starter/e2e/app-browser-runtime-provenance.spec.ts +240 -0
  303. package/templates/starter/e2e/app-browser-runtime-reporter.spec.ts +180 -0
  304. package/templates/starter/e2e/app-browser-runtime-requirements.spec.ts +310 -0
  305. package/templates/starter/e2e/app-browser-semantic-evidence.spec.ts +432 -0
  306. package/templates/starter/e2e/app-browser-shell.spec.ts +171 -0
  307. package/templates/starter/e2e/app-browser-timeline-layers-reference.spec.ts +70 -0
  308. package/templates/starter/e2e/app-performance.spec.ts +0 -491
  309. package/templates/starter/e2e/browser-acceptance-outcome-helpers.ts +97 -0
  310. package/templates/starter/e2e/browser-acceptance-transition-helpers.ts +74 -0
  311. package/templates/starter/e2e/browser-conditional-output-evidence-helpers.ts +230 -0
  312. package/templates/starter/e2e/browser-control-target-helpers.ts +109 -0
  313. package/templates/starter/e2e/browser-layer-evidence-helpers.ts +229 -0
  314. package/templates/starter/e2e/browser-proof-session.ts +392 -0
  315. package/templates/starter/e2e/browser-runtime-evidence-reporter.ts +136 -0
  316. package/templates/starter/e2e/browser-runtime-evidence-requirements.ts +290 -0
  317. package/templates/starter/e2e/browser-runtime-evidence.ts +27 -0
  318. package/templates/starter/e2e/browser-state-evidence-helpers.ts +205 -0
  319. package/templates/starter/e2e/browser-timeline-evidence-helpers.ts +319 -0
  320. package/templates/starter/e2e/canvas-handle-helpers.ts +86 -4
  321. package/templates/starter/e2e/export-artifact-helpers.ts +132 -0
  322. package/templates/starter/e2e/performance-budget-helpers.ts +159 -0
  323. package/templates/starter/e2e/performance-canvas-helpers.ts +123 -0
  324. package/templates/starter/e2e/performance-control-helpers.ts +3 -0
  325. package/templates/starter/e2e/performance-control-layout-helpers.ts +161 -0
  326. package/templates/starter/e2e/performance-fixture-helpers.ts +217 -0
  327. package/templates/starter/e2e/performance-frame-probe.ts +247 -0
  328. package/templates/starter/e2e/performance-helpers.ts +6 -854
  329. package/templates/starter/e2e/performance-interaction-measurement.ts +251 -0
  330. package/templates/starter/e2e/performance-measurement-evidence.ts +72 -0
  331. package/templates/starter/e2e/performance-output-action-helpers.spec.ts +43 -0
  332. package/templates/starter/e2e/performance-output-action-helpers.ts +109 -0
  333. package/templates/starter/e2e/performance-probe-helpers.ts +12 -0
  334. package/templates/starter/e2e/performance-render-scale-helpers.ts +55 -0
  335. package/templates/starter/e2e/performance-slider-helpers.ts +271 -0
  336. package/templates/starter/e2e/product-observable-helpers.ts +72 -17
  337. package/templates/starter/e2e/stable-outcome-helpers.ts +208 -0
  338. package/templates/starter/package.json +10 -5
  339. package/templates/starter/playwright.config.ts +5 -2
  340. package/templates/starter/scripts/check-ai-skills.mjs +14 -8
  341. package/templates/starter/scripts/check-ai-skills.test.mjs +64 -0
  342. package/templates/starter/scripts/check-toolcraft-code-health.mjs +108 -0
  343. package/templates/starter/scripts/check-toolcraft-code-health.test.mjs +213 -0
  344. package/templates/starter/scripts/check-toolcraft-docs.mjs +70 -35
  345. package/templates/starter/scripts/check-toolcraft-integrity.mjs +141 -144
  346. package/templates/starter/scripts/run-browser-performance.mjs +118 -0
  347. package/templates/starter/scripts/run-browser-performance.test.mjs +53 -0
  348. package/templates/starter/scripts/toolcraft-code-health-core.mjs +297 -0
  349. package/templates/starter/scripts/toolcraft-contract-doc-integrity.mjs +77 -0
  350. package/templates/starter/scripts/toolcraft-contract-doc-integrity.test.mjs +81 -0
  351. package/templates/starter/scripts/toolcraft-contract-manifest.json +113 -0
  352. package/templates/starter/scripts/toolcraft-contract-manifest.mjs +128 -0
  353. package/templates/starter/scripts/toolcraft-contract-manifest.test.mjs +72 -0
  354. package/templates/starter/scripts/toolcraft-integrity-manifest.mjs +172 -0
  355. package/templates/starter/scripts/toolcraft-integrity-policy.mjs +60 -0
  356. package/templates/starter/scripts/toolcraft-product-boundary-ast-utils.mjs +23 -0
  357. package/templates/starter/scripts/toolcraft-product-boundary-ast.mjs +264 -0
  358. package/templates/starter/scripts/toolcraft-product-boundary-test-fixtures.mjs +16 -0
  359. package/templates/starter/scripts/toolcraft-product-boundary.mjs +243 -0
  360. package/templates/starter/scripts/toolcraft-product-boundary.test.mjs +289 -0
  361. package/templates/starter/scripts/toolcraft-product-dependency-graph.mjs +176 -0
  362. package/templates/starter/scripts/toolcraft-product-dependency-graph.test.mjs +196 -0
  363. package/templates/starter/scripts/toolcraft-product-dependency-resolution.mjs +279 -0
  364. package/templates/starter/scripts/toolcraft-product-evidence-boundary-ast.mjs +91 -0
  365. package/templates/starter/scripts/toolcraft-product-evidence-boundary.test.mjs +138 -0
  366. package/templates/starter/scripts/toolcraft-product-style-boundary.mjs +219 -0
  367. package/templates/starter/scripts/toolcraft-source-inventory.d.mts +46 -0
  368. package/templates/starter/scripts/toolcraft-source-inventory.mjs +187 -0
  369. package/templates/starter/scripts/toolcraft-source-inventory.test.mjs +132 -0
  370. package/templates/starter/scripts/toolcraft-source-ownership.mjs +167 -0
  371. package/templates/starter/scripts/toolcraft-source-ownership.test.mjs +113 -0
  372. package/templates/starter/scripts/toolcraft-static-string.mjs +104 -0
  373. package/templates/starter/scripts/toolcraft-verification-inventory.mjs +123 -0
  374. package/templates/starter/scripts/toolcraft-verification-receipt.d.mts +19 -0
  375. package/templates/starter/scripts/toolcraft-verification-receipt.mjs +284 -0
  376. package/templates/starter/scripts/toolcraft-verification-receipt.test.mjs +282 -0
  377. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.d.mts +32 -0
  378. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.mjs +88 -0
  379. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.test.mjs +87 -0
  380. package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.mjs +109 -0
  381. package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.test.mjs +111 -0
  382. package/templates/starter/scripts/toolcraft-workflow-routes.mjs +314 -0
  383. package/templates/starter/scripts/toolcraft-workflow-routes.test.mjs +204 -0
  384. package/templates/starter/src/app/acceptance/actions.ts +30 -0
  385. package/templates/starter/src/app/acceptance/animation-intent.ts +184 -0
  386. package/templates/starter/src/app/acceptance/canvas-handle-acceptance.ts +70 -0
  387. package/templates/starter/src/app/acceptance/color-bank-labels.ts +164 -0
  388. package/templates/starter/src/app/acceptance/conditions.ts +80 -0
  389. package/templates/starter/src/app/acceptance/control-acceptance-context.ts +70 -0
  390. package/templates/starter/src/app/acceptance/control-acceptance-coverage.ts +271 -0
  391. package/templates/starter/src/app/acceptance/control-acceptance-kind-rules.ts +149 -0
  392. package/templates/starter/src/app/acceptance/control-acceptance-policy.ts +189 -0
  393. package/templates/starter/src/app/acceptance/control-acceptance.ts +70 -0
  394. package/templates/starter/src/app/acceptance/control-component-rules.ts +277 -0
  395. package/templates/starter/src/app/acceptance/control-labels.ts +223 -0
  396. package/templates/starter/src/app/acceptance/control-layout-dependency-rules.ts +107 -0
  397. package/templates/starter/src/app/acceptance/control-layout-entity-rules.ts +104 -0
  398. package/templates/starter/src/app/acceptance/control-layout-model.ts +159 -0
  399. package/templates/starter/src/app/acceptance/control-layout-section-rules.ts +164 -0
  400. package/templates/starter/src/app/acceptance/control-layout.ts +45 -0
  401. package/templates/starter/src/app/acceptance/control-order.ts +123 -0
  402. package/templates/starter/src/app/acceptance/control-parts.ts +47 -0
  403. package/templates/starter/src/app/acceptance/control-section-inventory.ts +183 -0
  404. package/templates/starter/src/app/acceptance/controls.ts +27 -0
  405. package/templates/starter/src/app/acceptance/coverage.ts +81 -0
  406. package/templates/starter/src/app/acceptance/custom-controls.ts +140 -0
  407. package/templates/starter/src/app/acceptance/inline-layout.ts +192 -0
  408. package/templates/starter/src/app/acceptance/media-upload.ts +55 -0
  409. package/templates/starter/src/app/acceptance/output-background-rules.ts +135 -0
  410. package/templates/starter/src/app/acceptance/output-export-actions.test.ts +76 -0
  411. package/templates/starter/src/app/acceptance/output-export-actions.ts +34 -0
  412. package/templates/starter/src/app/acceptance/output-export-layout-rules.ts +46 -0
  413. package/templates/starter/src/app/acceptance/output-export-model.ts +146 -0
  414. package/templates/starter/src/app/acceptance/output-export.ts +45 -0
  415. package/templates/starter/src/app/acceptance/output-image-export-rules.ts +87 -0
  416. package/templates/starter/src/app/acceptance/reference-runtime-coverage.ts +96 -0
  417. package/templates/starter/src/app/acceptance/reference-runtime-feature-inventory.ts +171 -0
  418. package/templates/starter/src/app/acceptance/reference-runtime-study.ts +73 -0
  419. package/templates/starter/src/app/acceptance/reference-runtime-timeline.ts +291 -0
  420. package/templates/starter/src/app/acceptance/reference-runtime.ts +99 -0
  421. package/templates/starter/src/app/acceptance/runtime-coverage.ts +290 -0
  422. package/templates/starter/src/app/acceptance/runtime-setup.ts +117 -0
  423. package/templates/starter/src/app/acceptance/section-title-rules.ts +8 -0
  424. package/templates/starter/src/app/acceptance/sections.ts +6 -0
  425. package/templates/starter/src/app/acceptance/semantic.ts +63 -0
  426. package/templates/starter/src/app/acceptance/timeline-loop.ts +21 -0
  427. package/templates/starter/src/app/acceptance/types.ts +363 -0
  428. package/templates/starter/src/app/acceptance/validate-coverage.ts +217 -0
  429. package/templates/starter/src/app/acceptance/validation-pipeline.test.ts +56 -0
  430. package/templates/starter/src/app/acceptance/validation-pipeline.ts +60 -0
  431. package/templates/starter/src/app/acceptance/video-reference-study.ts +217 -0
  432. package/templates/starter/src/app/starter-acceptance-data.ts +21 -0
  433. package/templates/starter/src/app/starter-acceptance.animation-intent.test.ts +383 -0
  434. package/templates/starter/src/app/starter-acceptance.background-export.test.ts +349 -0
  435. package/templates/starter/src/app/starter-acceptance.base-coverage.test.ts +47 -0
  436. package/templates/starter/src/app/starter-acceptance.canvas-handles.test.ts +71 -0
  437. package/templates/starter/src/app/starter-acceptance.canvas-sizing.test.ts +199 -0
  438. package/templates/starter/src/app/starter-acceptance.compound-part-coverage.test.ts +244 -0
  439. package/templates/starter/src/app/starter-acceptance.contract-fixtures.ts +63 -0
  440. package/templates/starter/src/app/starter-acceptance.control-label-context.test.ts +172 -0
  441. package/templates/starter/src/app/starter-acceptance.control-labels.test.ts +387 -0
  442. package/templates/starter/src/app/starter-acceptance.control-naming-rules.test.ts +215 -0
  443. package/templates/starter/src/app/starter-acceptance.control-order.test.ts +274 -0
  444. package/templates/starter/src/app/starter-acceptance.control-state.test.ts +275 -0
  445. package/templates/starter/src/app/starter-acceptance.curves-rules.test.ts +184 -0
  446. package/templates/starter/src/app/starter-acceptance.custom-control-collections.test.ts +200 -0
  447. package/templates/starter/src/app/starter-acceptance.custom-control-coverage.test.ts +111 -0
  448. package/templates/starter/src/app/starter-acceptance.custom-control-fit-check.test.ts +135 -0
  449. package/templates/starter/src/app/starter-acceptance.custom-control-valid.test.ts +74 -0
  450. package/templates/starter/src/app/starter-acceptance.export-test-utils.ts +107 -0
  451. package/templates/starter/src/app/starter-acceptance.framework-boundary.test.ts +327 -0
  452. package/templates/starter/src/app/starter-acceptance.image-video-export-settings.test.ts +328 -0
  453. package/templates/starter/src/app/starter-acceptance.keyframes.test.ts +242 -0
  454. package/templates/starter/src/app/starter-acceptance.layers.test.ts +203 -0
  455. package/templates/starter/src/app/starter-acceptance.media-upload.fixtures.ts +110 -0
  456. package/templates/starter/src/app/starter-acceptance.media-upload.test.ts +153 -0
  457. package/templates/starter/src/app/starter-acceptance.output-export-rules.test.ts +97 -0
  458. package/templates/starter/src/app/starter-acceptance.persistence-coverage.test.ts +134 -0
  459. package/templates/starter/src/app/starter-acceptance.product-output-export.test.ts +202 -0
  460. package/templates/starter/src/app/starter-acceptance.product-readiness-rules.test.ts +14 -0
  461. package/templates/starter/src/app/starter-acceptance.product-readiness-test-utils.ts +25 -0
  462. package/templates/starter/src/app/starter-acceptance.product-readiness.test.ts +50 -0
  463. package/templates/starter/src/app/starter-acceptance.product-worklog.test.ts +27 -0
  464. package/templates/starter/src/app/starter-acceptance.range-slider-rules.test.ts +147 -0
  465. package/templates/starter/src/app/starter-acceptance.reference-custom-timeline.test.ts +197 -0
  466. package/templates/starter/src/app/starter-acceptance.reference-foundation.test.ts +304 -0
  467. package/templates/starter/src/app/starter-acceptance.reference-test-utils.ts +102 -0
  468. package/templates/starter/src/app/starter-acceptance.reference-timeline.test.ts +267 -0
  469. package/templates/starter/src/app/starter-acceptance.schema-test-utils.ts +116 -0
  470. package/templates/starter/src/app/starter-acceptance.section-cohesion.test.ts +373 -0
  471. package/templates/starter/src/app/starter-acceptance.section-dependencies.test.ts +260 -0
  472. package/templates/starter/src/app/starter-acceptance.section-titles.test.ts +180 -0
  473. package/templates/starter/src/app/starter-acceptance.setup-readiness.test.ts +205 -0
  474. package/templates/starter/src/app/starter-acceptance.slider-rules.test.ts +470 -0
  475. package/templates/starter/src/app/starter-acceptance.slider-unit-rules.test.ts +61 -0
  476. package/templates/starter/src/app/starter-acceptance.source-test-utils.ts +43 -0
  477. package/templates/starter/src/app/starter-acceptance.test-utils.ts +21 -0
  478. package/templates/starter/src/app/starter-acceptance.text-control-kind.test.ts +89 -0
  479. package/templates/starter/src/app/starter-acceptance.timeline-playback.test.ts +264 -0
  480. package/templates/starter/src/app/starter-acceptance.timeline-test-utils.ts +56 -0
  481. package/templates/starter/src/app/starter-acceptance.toggle-pair-layout.test.ts +200 -0
  482. package/templates/starter/src/app/starter-acceptance.toggle-parameter-layout.test.ts +277 -0
  483. package/templates/starter/src/app/starter-acceptance.ts +151 -4576
  484. package/templates/starter/src/app/starter-acceptance.video-export-test-utils.ts +37 -0
  485. package/templates/starter/src/app/starter-acceptance.video-reference-study.test.ts +262 -0
  486. package/templates/starter/src/app/starter-acceptance.worklog-test-utils.ts +428 -0
  487. package/templates/starter/src/app/starter-acceptance.worklog.test.ts +283 -0
  488. package/templates/starter/src/app/starter-automated-runtime-evidence.test.ts +34 -0
  489. package/templates/starter/src/app/starter-composition.tsx +7 -0
  490. package/templates/starter/src/app/starter-performance-test-utils.ts +275 -0
  491. package/templates/starter/src/app/starter-performance.budgets.test.ts +374 -0
  492. package/templates/starter/src/app/starter-performance.gates.test.ts +128 -0
  493. package/templates/starter/src/app/starter-performance.renderer-source.test.ts +136 -0
  494. package/templates/starter/src/app/starter-performance.renderer-technique.test.ts +291 -0
  495. package/templates/starter/src/app/starter-performance.scenarios.test.ts +355 -0
  496. package/templates/starter/src/app/test-evidence/browser-runtime-contract.test.ts +253 -0
  497. package/templates/starter/src/app/test-evidence/browser-runtime-contract.ts +243 -0
  498. package/templates/starter/src/routes/index.tsx +11 -2
  499. package/templates/starter/vite.config.ts +8 -0
  500. package/templates/ui/components/controls/color/color-control-types.ts +38 -0
  501. package/templates/ui/components/controls/color/color-control.tsx +19 -437
  502. package/templates/ui/components/controls/color/color-footer.tsx +272 -0
  503. package/templates/ui/components/controls/color/color-model-slider.tsx +271 -0
  504. package/templates/ui/components/controls/color/color-opacity-input.tsx +94 -0
  505. package/templates/ui/components/controls/color/color-surface.tsx +194 -0
  506. package/templates/ui/components/controls/color/color-value-control.tsx +159 -0
  507. package/templates/ui/components/controls/color/color-value-utils.ts +170 -0
  508. package/templates/ui/components/controls/color/index.ts +10 -3
  509. package/templates/ui/components/controls/color/palette-control-controller.ts +407 -0
  510. package/templates/ui/components/controls/color/palette-control-layout.ts +14 -0
  511. package/templates/ui/components/controls/color/palette-control-types.ts +50 -0
  512. package/templates/ui/components/controls/color/palette-control-view.tsx +174 -0
  513. package/templates/ui/components/controls/color/palette-control.tsx +6 -544
  514. package/templates/ui/components/controls/color/style-guide-color-picker-color-utils.ts +39 -0
  515. package/templates/ui/components/controls/color/style-guide-color-picker-controller.ts +370 -0
  516. package/templates/ui/components/controls/color/style-guide-color-picker-hue-handlers.ts +66 -0
  517. package/templates/ui/components/controls/color/style-guide-color-picker-interaction-state.ts +49 -0
  518. package/templates/ui/components/controls/color/style-guide-color-picker-interactions.ts +2 -2
  519. package/templates/ui/components/controls/color/style-guide-color-picker-model.ts +125 -0
  520. package/templates/ui/components/controls/color/style-guide-color-picker-parts.tsx +10 -707
  521. package/templates/ui/components/controls/color/style-guide-color-picker-surface-drag.ts +93 -0
  522. package/templates/ui/components/controls/color/style-guide-color-picker-surface-geometry.ts +114 -0
  523. package/templates/ui/components/controls/color/style-guide-color-picker-surface-preview.ts +45 -0
  524. package/templates/ui/components/controls/color/style-guide-color-picker-types.ts +84 -0
  525. package/templates/ui/components/controls/color/style-guide-color-picker-view.tsx +69 -0
  526. package/templates/ui/components/controls/color/style-guide-color-picker.tsx +6 -495
  527. package/templates/ui/components/controls/curves/curves-control.tsx +4 -3
  528. package/templates/ui/components/controls/file-drop/file-drop-control.tsx +39 -515
  529. package/templates/ui/components/controls/file-drop/file-drop-empty-state.tsx +35 -0
  530. package/templates/ui/components/controls/file-drop/file-drop-file-list.tsx +160 -0
  531. package/templates/ui/components/controls/file-drop/file-drop-image-grid.tsx +175 -0
  532. package/templates/ui/components/controls/file-drop/file-drop-model.tsx +170 -0
  533. package/templates/ui/components/controls/file-drop/file-drop-single-preview.tsx +63 -0
  534. package/templates/ui/components/controls/file-drop/file-drop-types.ts +48 -0
  535. package/templates/ui/components/controls/file-drop/index.ts +2 -2
  536. package/templates/ui/components/controls/font-picker/font-picker-control.tsx +133 -906
  537. package/templates/ui/components/controls/font-picker/font-picker-footer.tsx +116 -0
  538. package/templates/ui/components/controls/font-picker/font-picker-list.tsx +194 -0
  539. package/templates/ui/components/controls/font-picker/font-picker-popover-content.tsx +191 -0
  540. package/templates/ui/components/controls/font-picker/font-picker-value.ts +222 -0
  541. package/templates/ui/components/controls/font-picker/index.ts +4 -1
  542. package/templates/ui/components/controls/font-picker/use-font-picker-preview-pipeline.ts +163 -0
  543. package/templates/ui/components/controls/font-picker/use-font-picker-virtual-list.ts +293 -0
  544. package/templates/ui/components/controls/gradient/gradient-control-utils.ts +2 -25
  545. package/templates/ui/components/controls/gradient/gradient-control.tsx +4 -464
  546. package/templates/ui/components/controls/gradient/gradient-stops-controller.ts +332 -0
  547. package/templates/ui/components/controls/gradient/gradient-stops-track.tsx +159 -0
  548. package/templates/ui/components/controls/vector/vector-control-types.ts +26 -0
  549. package/templates/ui/components/controls/vector/vector-control.tsx +10 -486
  550. package/templates/ui/components/controls/vector/vector-pad-field.tsx +211 -0
  551. package/templates/ui/components/controls/vector/vector-pad-geometry.ts +61 -0
  552. package/templates/ui/components/controls/vector/vector-pad-parts.tsx +72 -0
  553. package/templates/ui/components/controls/vector/vector-pad-variants.ts +20 -0
  554. package/templates/ui/components/controls/vector/vector-size-field.tsx +104 -0
  555. package/templates/ui/components/controls/vector/vector-value.ts +46 -0
  556. package/templates/ui/components/primitives/slider/slider-discrete-state.ts +181 -0
  557. package/templates/ui/components/primitives/slider/slider-marker-policy.ts +52 -0
  558. package/templates/ui/components/primitives/slider/slider-pointer-dragging.ts +87 -0
  559. package/templates/ui/components/primitives/slider/slider-runtime.ts +109 -0
  560. package/templates/ui/components/primitives/slider/slider-types.ts +21 -0
  561. package/templates/ui/components/primitives/slider/slider.tsx +2 -403
  562. package/templates/runtime/react/canvas-shell.test.tsx +0 -554
  563. package/templates/runtime/react/canvas-shell.tsx +0 -585
  564. package/templates/runtime/react/controls-panel.test.tsx +0 -5446
  565. package/templates/runtime/react/controls-panel.tsx +0 -3220
  566. package/templates/runtime/react/layers-panel.test.tsx +0 -487
  567. package/templates/runtime/react/layers-panel.tsx +0 -1348
  568. package/templates/runtime/react/timeline-panel.test.tsx +0 -751
  569. package/templates/runtime/react/timeline-panel.tsx +0 -3078
  570. package/templates/runtime/schema/define-toolcraft.test.ts +0 -1742
  571. package/templates/runtime/state/reducer.test.ts +0 -1703
  572. package/templates/runtime/testing/performance.test.ts +0 -3081
  573. package/templates/starter/e2e/app-browser-acceptance.spec.ts +0 -785
  574. package/templates/starter/src/app/starter-acceptance.test.ts +0 -10067
  575. package/templates/starter/src/app/starter-performance.test.ts +0 -1583
  576. package/templates/ui/components/controls/color/style-guide-color-picker-logic.ts +0 -490
  577. /package/templates/runtime/react/{storage-key-migration.ts → app-shell/storage-key-migration.ts} +0 -0
  578. /package/templates/runtime/react/{theme-runtime.tsx → app-shell/theme-runtime.tsx} +0 -0
  579. /package/templates/runtime/react/{curve-geometry.test.ts → controls-panel/__tests__/curve-geometry.test.ts} +0 -0
  580. /package/templates/runtime/react/{panel-host-config.ts → panel-host/panel-host-config.ts} +0 -0
  581. /package/templates/runtime/react/{panel-host-geometry.test.ts → panel-host/panel-host-geometry.test.ts} +0 -0
  582. /package/templates/runtime/react/{panel-host-geometry.ts → panel-host/panel-host-geometry.ts} +0 -0
@@ -0,0 +1,291 @@
1
+ import type { ResolvedToolcraftAppSchema } from "@repo/toolcraft-runtime";
2
+
3
+ import {
4
+ isValidTimelineLoopDurationSource,
5
+ } from "./timeline-loop";
6
+ import type {
7
+ ToolcraftComponentAcceptance,
8
+ ToolcraftReferenceCoverage,
9
+ ToolcraftReferenceTimelineCoverage,
10
+ ToolcraftTransferMode,
11
+ } from "./types";
12
+
13
+ const referenceTransportCoverage = new Set<ToolcraftReferenceCoverage>([
14
+ "export-at-time",
15
+ "pause-resume",
16
+ "restart",
17
+ "time-progress",
18
+ ]);
19
+
20
+ const toolcraftReferenceTimelineCoverage = new Set<ToolcraftReferenceTimelineCoverage>([
21
+ "duration",
22
+ "export-at-time",
23
+ "keyframes",
24
+ "loop",
25
+ "playback",
26
+ "restart",
27
+ "scrub",
28
+ "time-progress",
29
+ ]);
30
+
31
+ const customReferenceTimelineCoverage = new Set<ToolcraftReferenceTimelineCoverage>([
32
+ "all-range",
33
+ "export-range",
34
+ "jump-to-trim-start",
35
+ "range-playback",
36
+ "state-jump",
37
+ "trim-range",
38
+ ]);
39
+
40
+ function getReferenceTimelineLoopDurationErrors({
41
+ referenceTimelineMode,
42
+ schema,
43
+ transferMode,
44
+ }: {
45
+ referenceTimelineMode: "toolcraft-keyframes" | "toolcraft-playback";
46
+ schema: ResolvedToolcraftAppSchema;
47
+ transferMode: Extract<ToolcraftTransferMode, { mode: "reference-runtime-clone" }>;
48
+ }): string[] {
49
+ const errors: string[] = [];
50
+ const referenceTimeline = transferMode.referenceTimeline;
51
+ const timelineDefaultDurationSeconds = schema.panels.timeline?.defaultDurationSeconds;
52
+ const loopDuration = referenceTimeline.loopDuration;
53
+
54
+ if (!loopDuration) {
55
+ errors.push(
56
+ `referenceTimeline mode "${referenceTimelineMode}" must declare loopDuration with source, seconds, and evidence. Do not let runtime/template fallback duration such as 8s stand in for reference loop intent.`,
57
+ );
58
+ return errors;
59
+ }
60
+
61
+ if (!Number.isFinite(loopDuration.seconds) || loopDuration.seconds <= 0) {
62
+ errors.push(
63
+ `referenceTimeline.loopDuration.seconds must be a positive finite duration; received ${String(loopDuration.seconds)}.`,
64
+ );
65
+ }
66
+
67
+ if (!isValidTimelineLoopDurationSource(loopDuration.source)) {
68
+ errors.push(
69
+ `referenceTimeline.loopDuration.source must be "reference", "user-request", or "product-derived"; received "${String(loopDuration.source)}". Runtime/template fallback is not a valid loop-duration source.`,
70
+ );
71
+ }
72
+
73
+ if (!loopDuration.evidence.trim()) {
74
+ errors.push(
75
+ "referenceTimeline.loopDuration.evidence must explain where the reference loop duration came from, such as measured reference timing, an explicit user request, or a product-derived timing rule.",
76
+ );
77
+ }
78
+
79
+ if (typeof timelineDefaultDurationSeconds !== "number") {
80
+ errors.push(
81
+ "Toolcraft reference playback/keyframe timelines must set panels.timeline.defaultDurationSeconds to referenceTimeline.loopDuration.seconds so the initial UI duration is not the runtime fallback.",
82
+ );
83
+ } else if (
84
+ Number.isFinite(loopDuration.seconds) &&
85
+ Math.abs(timelineDefaultDurationSeconds - loopDuration.seconds) > 0.001
86
+ ) {
87
+ errors.push(
88
+ `panels.timeline.defaultDurationSeconds (${timelineDefaultDurationSeconds}) must match referenceTimeline.loopDuration.seconds (${loopDuration.seconds}).`,
89
+ );
90
+ }
91
+
92
+ return errors;
93
+ }
94
+
95
+ function getReferenceTimelineAcceptanceCoverageErrors({
96
+ acceptance,
97
+ declaredReferenceTimelineCoverage,
98
+ referenceTimelineMode,
99
+ }: {
100
+ acceptance: readonly ToolcraftComponentAcceptance[];
101
+ declaredReferenceTimelineCoverage: ReadonlySet<ToolcraftReferenceTimelineCoverage>;
102
+ referenceTimelineMode: string;
103
+ }): string[] {
104
+ const errors: string[] = [];
105
+
106
+ for (const coverage of declaredReferenceTimelineCoverage) {
107
+ if (
108
+ customReferenceTimelineCoverage.has(coverage) &&
109
+ referenceTimelineMode !== "custom-reference-timeline"
110
+ ) {
111
+ errors.push(
112
+ `referenceTimeline mode "${referenceTimelineMode}" cannot preserve custom reference timeline behavior "${coverage}". Use mode "custom-reference-timeline" and browser-backed referenceTimelineCoverage instead.`,
113
+ );
114
+ }
115
+
116
+ const entry = acceptance.find(
117
+ (acceptanceEntry) => acceptanceEntry.referenceTimelineCoverage === coverage,
118
+ );
119
+
120
+ if (!entry) {
121
+ errors.push(
122
+ `referenceTimeline behaviorCoverage "${coverage}" is missing an acceptance entry with referenceTimelineCoverage "${coverage}".`,
123
+ );
124
+ continue;
125
+ }
126
+
127
+ if (entry.kind !== "runtime") {
128
+ errors.push(
129
+ `${entry.id} must be a runtime acceptance entry proving reference timeline behavior "${coverage}".`,
130
+ );
131
+ }
132
+
133
+ if (!entry.automated || !entry.automatedTestName.trim()) {
134
+ errors.push(
135
+ `${entry.id} must have automated coverage proving reference timeline behavior "${coverage}".`,
136
+ );
137
+ }
138
+
139
+ if (!entry.browser || !entry.browserTestName.trim()) {
140
+ errors.push(
141
+ `${entry.id} must have browser coverage proving reference timeline behavior "${coverage}".`,
142
+ );
143
+ }
144
+
145
+ if (!entry.expectedObservable.trim()) {
146
+ errors.push(
147
+ `${entry.id} must describe the observable reference timeline behavior for "${coverage}".`,
148
+ );
149
+ }
150
+ }
151
+
152
+ return errors;
153
+ }
154
+
155
+ export function getReferenceTimelineErrors({
156
+ acceptance,
157
+ referenceTimelineCoverageFromInventory,
158
+ schema,
159
+ timelineMode,
160
+ transferMode,
161
+ }: {
162
+ acceptance: readonly ToolcraftComponentAcceptance[];
163
+ referenceTimelineCoverageFromInventory: ReadonlySet<ToolcraftReferenceTimelineCoverage>;
164
+ schema: ResolvedToolcraftAppSchema;
165
+ timelineMode: "keyframes" | "playback" | null;
166
+ transferMode: Extract<ToolcraftTransferMode, { mode: "reference-runtime-clone" }>;
167
+ }): string[] {
168
+ const errors: string[] = [];
169
+ const referenceTimeline = transferMode.referenceTimeline;
170
+
171
+ if (!referenceTimeline) {
172
+ errors.push(
173
+ 'reference-runtime-clone transferMode must declare referenceTimeline with mode "none", "toolcraft-playback", "toolcraft-keyframes", or "custom-reference-timeline".',
174
+ );
175
+ return errors;
176
+ }
177
+
178
+ const declaredReferenceCoverage = new Set(transferMode.behaviorCoverage);
179
+ const declaredReferenceTimelineCoverage = new Set(referenceTimeline.behaviorCoverage);
180
+ const declaredReferenceTransportCoverage = [...declaredReferenceCoverage].filter(
181
+ (coverage) => referenceTransportCoverage.has(coverage),
182
+ );
183
+ const declaredToolcraftTimelineCoverage = [...declaredReferenceTimelineCoverage].filter(
184
+ (coverage) => toolcraftReferenceTimelineCoverage.has(coverage),
185
+ );
186
+
187
+ for (const coverage of declaredReferenceTimelineCoverage) {
188
+ if (!referenceTimelineCoverageFromInventory.has(coverage)) {
189
+ errors.push(
190
+ `referenceTimeline behaviorCoverage "${coverage}" must be represented in referenceFeatureInventory by an item whose acceptanceId points to that referenceTimelineCoverage.`,
191
+ );
192
+ }
193
+ }
194
+
195
+ if (referenceTimeline.mode === "none" && declaredReferenceTimelineCoverage.size > 0) {
196
+ errors.push(
197
+ 'referenceTimeline mode "none" must not declare reference timeline behaviorCoverage.',
198
+ );
199
+ }
200
+
201
+ if (
202
+ referenceTimeline.mode === "none" &&
203
+ declaredReferenceTransportCoverage.length > 0
204
+ ) {
205
+ errors.push(
206
+ `reference-runtime-clone transport behaviorCoverage ${declaredReferenceTransportCoverage.map((coverage) => `"${coverage}"`).join(", ")} requires referenceTimeline mode "toolcraft-playback", "toolcraft-keyframes", or "custom-reference-timeline"; mode "none" is only for references with no user-facing transport behavior.`,
207
+ );
208
+ }
209
+
210
+ if (
211
+ (referenceTimeline.mode === "toolcraft-playback" ||
212
+ referenceTimeline.mode === "toolcraft-keyframes") &&
213
+ declaredReferenceTimelineCoverage.size === 0
214
+ ) {
215
+ errors.push(
216
+ `referenceTimeline mode "${referenceTimeline.mode}" must list the concrete timeline transport behaviors in behaviorCoverage.`,
217
+ );
218
+ }
219
+
220
+ if (referenceTimeline.mode === "toolcraft-playback" && timelineMode !== "playback") {
221
+ errors.push(
222
+ 'referenceTimeline mode "toolcraft-playback" requires panels.timeline mode "playback".',
223
+ );
224
+ }
225
+
226
+ if (referenceTimeline.mode === "toolcraft-keyframes" && timelineMode !== "keyframes") {
227
+ errors.push(
228
+ 'referenceTimeline mode "toolcraft-keyframes" requires panels.timeline mode "keyframes".',
229
+ );
230
+ }
231
+
232
+ if (
233
+ referenceTimeline.mode === "toolcraft-playback" ||
234
+ referenceTimeline.mode === "toolcraft-keyframes"
235
+ ) {
236
+ errors.push(
237
+ ...getReferenceTimelineLoopDurationErrors({
238
+ referenceTimelineMode: referenceTimeline.mode,
239
+ schema,
240
+ transferMode,
241
+ }),
242
+ );
243
+ }
244
+
245
+ if (
246
+ referenceTimeline.mode === "toolcraft-playback" &&
247
+ declaredReferenceTimelineCoverage.has("keyframes")
248
+ ) {
249
+ errors.push(
250
+ 'referenceTimeline behaviorCoverage "keyframes" requires referenceTimeline mode "toolcraft-keyframes".',
251
+ );
252
+ }
253
+
254
+ if (
255
+ referenceTimeline.mode === "toolcraft-keyframes" &&
256
+ !declaredReferenceTimelineCoverage.has("keyframes")
257
+ ) {
258
+ errors.push(
259
+ 'referenceTimeline mode "toolcraft-keyframes" must include behaviorCoverage "keyframes".',
260
+ );
261
+ }
262
+
263
+ if (
264
+ (referenceTimeline.mode === "toolcraft-playback" ||
265
+ referenceTimeline.mode === "toolcraft-keyframes") &&
266
+ declaredToolcraftTimelineCoverage.length === 0
267
+ ) {
268
+ errors.push(
269
+ `referenceTimeline mode "${referenceTimeline.mode}" must include at least one Toolcraft timeline behavior such as "playback", "restart", "scrub", "duration", "loop", "time-progress", "export-at-time", or "keyframes".`,
270
+ );
271
+ }
272
+
273
+ if (
274
+ referenceTimeline.mode === "custom-reference-timeline" &&
275
+ declaredReferenceTimelineCoverage.size === 0
276
+ ) {
277
+ errors.push(
278
+ 'referenceTimeline mode "custom-reference-timeline" must list every reference timeline behavior in behaviorCoverage.',
279
+ );
280
+ }
281
+
282
+ errors.push(
283
+ ...getReferenceTimelineAcceptanceCoverageErrors({
284
+ acceptance,
285
+ declaredReferenceTimelineCoverage,
286
+ referenceTimelineMode: referenceTimeline.mode,
287
+ }),
288
+ );
289
+
290
+ return errors;
291
+ }
@@ -0,0 +1,99 @@
1
+ import type { ResolvedToolcraftAppSchema } from "@repo/toolcraft-runtime";
2
+
3
+ import {
4
+ getReferenceBehaviorCoverageErrors,
5
+ getUnmappedReferenceAcceptanceErrors,
6
+ } from "./reference-runtime-coverage";
7
+ import { getReferenceFeatureInventoryValidationResult } from "./reference-runtime-feature-inventory";
8
+ import { getReferenceStudyErrors } from "./reference-runtime-study";
9
+ import { getReferenceTimelineErrors } from "./reference-runtime-timeline";
10
+ import type {
11
+ ToolcraftComponentAcceptance,
12
+ ToolcraftTransferMode,
13
+ } from "./types";
14
+
15
+ export function getToolcraftReferenceRuntimeCloneErrors({
16
+ acceptance,
17
+ schema,
18
+ timelineMode,
19
+ transferMode,
20
+ }: {
21
+ acceptance: readonly ToolcraftComponentAcceptance[];
22
+ schema: ResolvedToolcraftAppSchema;
23
+ timelineMode: "keyframes" | "playback" | null;
24
+ transferMode: ToolcraftTransferMode;
25
+ }): string[] {
26
+ const errors: string[] = [];
27
+
28
+ if (transferMode.mode !== "reference-runtime-clone") {
29
+ for (const entry of acceptance) {
30
+ if (entry.referenceCoverage) {
31
+ errors.push(
32
+ `${entry.id} declares referenceCoverage "${entry.referenceCoverage}" but transferMode is not "reference-runtime-clone".`,
33
+ );
34
+ }
35
+
36
+ if (entry.referenceTimelineCoverage) {
37
+ errors.push(
38
+ `${entry.id} declares referenceTimelineCoverage "${entry.referenceTimelineCoverage}" but transferMode is not "reference-runtime-clone".`,
39
+ );
40
+ }
41
+ }
42
+
43
+ return errors;
44
+ }
45
+
46
+ if (!schema.assembly.surfaces.canvas.enabled) {
47
+ errors.push(
48
+ "reference-runtime-clone must keep the Toolcraft canvas shell enabled; preserve the reference renderer inside ToolcraftApp canvasContent instead of replacing the app with the original UI.",
49
+ );
50
+ }
51
+
52
+ if (!transferMode.referenceName.trim()) {
53
+ errors.push(
54
+ "reference-runtime-clone transferMode must name the reference app or artifact.",
55
+ );
56
+ }
57
+
58
+ if (transferMode.sourceOfTruth !== "reference-runtime") {
59
+ errors.push(
60
+ 'reference-runtime-clone transferMode must set sourceOfTruth to "reference-runtime".',
61
+ );
62
+ }
63
+
64
+ errors.push(...getReferenceStudyErrors(transferMode));
65
+
66
+ const featureInventoryResult = getReferenceFeatureInventoryValidationResult({
67
+ acceptance,
68
+ transferMode,
69
+ });
70
+
71
+ errors.push(...featureInventoryResult.errors);
72
+ errors.push(
73
+ ...getReferenceBehaviorCoverageErrors({
74
+ acceptance,
75
+ referenceCoverageFromInventory:
76
+ featureInventoryResult.referenceCoverageFromInventory,
77
+ transferMode,
78
+ }),
79
+ );
80
+ errors.push(
81
+ ...getReferenceTimelineErrors({
82
+ acceptance,
83
+ referenceTimelineCoverageFromInventory:
84
+ featureInventoryResult.referenceTimelineCoverageFromInventory,
85
+ schema,
86
+ timelineMode,
87
+ transferMode,
88
+ }),
89
+ );
90
+ errors.push(
91
+ ...getUnmappedReferenceAcceptanceErrors({
92
+ acceptance,
93
+ referenceFeatureAcceptanceIds:
94
+ featureInventoryResult.referenceFeatureAcceptanceIds,
95
+ }),
96
+ );
97
+
98
+ return errors;
99
+ }
@@ -0,0 +1,290 @@
1
+ import type {
2
+ ResolvedToolcraftAppSchema,
3
+ ToolcraftTimelineMode,
4
+ } from "@repo/toolcraft-runtime";
5
+
6
+ import {
7
+ hasTimelinePlaybackCoverage,
8
+ hasTimelinePlaybackCoveragePart,
9
+ } from "./coverage";
10
+ import {
11
+ schemaHasPngExportPanelAction,
12
+ schemaHasVideoExportPanelAction,
13
+ } from "./output-export";
14
+ import type {
15
+ ToolcraftComponentAcceptance,
16
+ ToolcraftLayerCoverage,
17
+ ToolcraftTimelineLoopProof,
18
+ ToolcraftTimelinePlaybackCoverage,
19
+ } from "./types";
20
+
21
+ const requiredLayerCoverage = [
22
+ "selection",
23
+ "visibility",
24
+ "reorder",
25
+ "grouping",
26
+ ] satisfies readonly ToolcraftLayerCoverage[];
27
+
28
+ const requiredTimelinePlaybackCoverage = [
29
+ "pause-resume",
30
+ "scrub",
31
+ "duration",
32
+ "loop",
33
+ "rendered-frame",
34
+ ] satisfies readonly ToolcraftTimelinePlaybackCoverage[];
35
+
36
+ const requiredTimelineLoopProof = {
37
+ direction: "forward-only",
38
+ durationChange: "reproved-after-edit",
39
+ reversePlayback: "forbidden",
40
+ seam: "first-last-match",
41
+ } satisfies ToolcraftTimelineLoopProof;
42
+
43
+ export function getToolcraftLayerCoverageErrors({
44
+ acceptance,
45
+ layersEnabled,
46
+ }: {
47
+ acceptance: readonly ToolcraftComponentAcceptance[];
48
+ layersEnabled: boolean;
49
+ }): string[] {
50
+ const errors: string[] = [];
51
+
52
+ if (layersEnabled) {
53
+ for (const coverage of requiredLayerCoverage) {
54
+ const entry = acceptance.find(
55
+ (acceptanceEntry) =>
56
+ acceptanceEntry.kind === "runtime" && acceptanceEntry.layerCoverage === coverage,
57
+ );
58
+
59
+ if (!entry) {
60
+ errors.push(
61
+ `panels.layers requires a runtime acceptance entry with layerCoverage "${coverage}" proving layer ${coverage} behavior.`,
62
+ );
63
+ continue;
64
+ }
65
+
66
+ if (!entry.automated || !entry.automatedTestName.trim()) {
67
+ errors.push(`${entry.id} must have automated coverage proving layer ${coverage}.`);
68
+ }
69
+
70
+ if (!entry.browser || !entry.browserTestName.trim()) {
71
+ errors.push(`${entry.id} must have browser coverage proving layer ${coverage}.`);
72
+ }
73
+
74
+ if (!entry.expectedObservable.trim()) {
75
+ errors.push(
76
+ `${entry.id} must describe the observable layer behavior for "${coverage}".`,
77
+ );
78
+ }
79
+ }
80
+ } else {
81
+ for (const entry of acceptance) {
82
+ if (entry.layerCoverage) {
83
+ errors.push(
84
+ `${entry.id} declares layerCoverage "${entry.layerCoverage}" but panels.layers is not enabled.`,
85
+ );
86
+ }
87
+ }
88
+ }
89
+
90
+ return errors;
91
+ }
92
+
93
+ export function getToolcraftTimelinePlaybackCoverageErrors({
94
+ acceptance,
95
+ timelineMode,
96
+ }: {
97
+ acceptance: readonly ToolcraftComponentAcceptance[];
98
+ timelineMode: ToolcraftTimelineMode | null;
99
+ }): string[] {
100
+ const errors: string[] = [];
101
+
102
+ if (!timelineMode) {
103
+ return errors;
104
+ }
105
+
106
+ const playbackEntry = acceptance.find(
107
+ (entry) => entry.kind === "runtime" && entry.timelineCoverage === "playback",
108
+ );
109
+
110
+ if (!playbackEntry) {
111
+ errors.push(
112
+ `panels.timeline mode "${timelineMode}" requires a runtime acceptance entry with timelineCoverage "playback" proving pause, scrub, duration/loop, and rendered-frame behavior.`,
113
+ );
114
+ return errors;
115
+ }
116
+
117
+ if (
118
+ !hasTimelinePlaybackCoverage(
119
+ playbackEntry.timelinePlaybackCoverage,
120
+ requiredTimelinePlaybackCoverage,
121
+ )
122
+ ) {
123
+ errors.push(
124
+ `${playbackEntry.id} timelineCoverage "playback" must declare timelinePlaybackCoverage for pause-resume, scrub, duration, loop, and rendered-frame. Duration coverage must prove renderer progress maps 0..state.timeline.durationSeconds, not a local fixed animation duration.`,
125
+ );
126
+ return errors;
127
+ }
128
+
129
+ if (
130
+ hasTimelinePlaybackCoveragePart(playbackEntry.timelinePlaybackCoverage, "loop") &&
131
+ (playbackEntry.timelineLoopProof?.direction !==
132
+ requiredTimelineLoopProof.direction ||
133
+ playbackEntry.timelineLoopProof.durationChange !==
134
+ requiredTimelineLoopProof.durationChange ||
135
+ playbackEntry.timelineLoopProof.reversePlayback !==
136
+ requiredTimelineLoopProof.reversePlayback ||
137
+ playbackEntry.timelineLoopProof.seam !== requiredTimelineLoopProof.seam)
138
+ ) {
139
+ errors.push(
140
+ `${playbackEntry.id} timelinePlaybackCoverage "loop" must declare timelineLoopProof with forward-only direction, forbidden reverse playback, first-last-match seam, and reproved-after-edit duration behavior. Browser evidence still proves the real samples and seam.`,
141
+ );
142
+ }
143
+
144
+ return errors;
145
+ }
146
+
147
+ export function getToolcraftTimelineKeyframeCoverageErrors({
148
+ acceptance,
149
+ timelineMode,
150
+ }: {
151
+ acceptance: readonly ToolcraftComponentAcceptance[];
152
+ timelineMode: ToolcraftTimelineMode | null;
153
+ }): string[] {
154
+ if (timelineMode !== "keyframes") {
155
+ return [];
156
+ }
157
+
158
+ const hasKeyframesCoverage = acceptance.some(
159
+ (entry) => entry.kind === "runtime" && entry.timelineCoverage === "keyframes",
160
+ );
161
+
162
+ if (hasKeyframesCoverage) {
163
+ return [];
164
+ }
165
+
166
+ return [
167
+ 'panels.timeline mode "keyframes" requires a runtime acceptance entry with timelineCoverage "keyframes" proving expanded rows, diamonds, keyframe mutation, and renderer evaluation.',
168
+ ];
169
+ }
170
+
171
+ export function getToolcraftCanvasSizingCoverageErrors({
172
+ acceptance,
173
+ schema,
174
+ }: {
175
+ acceptance: readonly ToolcraftComponentAcceptance[];
176
+ schema: ResolvedToolcraftAppSchema;
177
+ }): string[] {
178
+ const errors: string[] = [];
179
+
180
+ if (schema.canvas.sizing.mode === "fixed-output") {
181
+ if (schemaHasPngExportPanelAction(schema) || schemaHasVideoExportPanelAction(schema)) {
182
+ errors.push(
183
+ 'Product/output apps with export actions must use canvas.sizing mode "editable-output" so Aspect ratio, Canvas width, and Canvas height are always available. Put reference, fixed-format, or user-requested dimensions in canvas.size as the initial value instead of hiding size controls with "fixed-output".',
184
+ );
185
+ }
186
+
187
+ const fixedCanvasSizingEntry = acceptance.find(
188
+ (entry) =>
189
+ entry.kind === "runtime" &&
190
+ entry.canvasSizingCoverage === "fixed-output-size",
191
+ );
192
+
193
+ if (!fixedCanvasSizingEntry) {
194
+ errors.push(
195
+ 'canvas.sizing mode "fixed-output" requires a runtime acceptance entry with canvasSizingCoverage "fixed-output-size" explaining why width and height are intentionally non-editable. Product/output apps must use "editable-output"; user-provided, reference, fixed-format, or base/default sizes belong in canvas.size as editable initial values.',
196
+ );
197
+ } else {
198
+ if (!fixedCanvasSizingEntry.automated || !fixedCanvasSizingEntry.automatedTestName.trim()) {
199
+ errors.push(
200
+ `${fixedCanvasSizingEntry.id} must have automated coverage proving fixed output dimensions.`,
201
+ );
202
+ }
203
+
204
+ if (!fixedCanvasSizingEntry.browser || !fixedCanvasSizingEntry.browserTestName.trim()) {
205
+ errors.push(
206
+ `${fixedCanvasSizingEntry.id} must have browser coverage proving fixed output dimensions.`,
207
+ );
208
+ }
209
+ }
210
+ }
211
+
212
+ if (
213
+ schema.canvas.enabled &&
214
+ schema.canvas.upload &&
215
+ schema.canvas.sizing.mode === "intrinsic-media"
216
+ ) {
217
+ const intrinsicCanvasSizingEntry = acceptance.find(
218
+ (entry) =>
219
+ entry.kind === "runtime" &&
220
+ entry.canvasSizingCoverage === "intrinsic-media-size",
221
+ );
222
+
223
+ if (!intrinsicCanvasSizingEntry) {
224
+ errors.push(
225
+ 'canvas.sizing mode "intrinsic-media" with upload requires a runtime acceptance entry with canvasSizingCoverage "intrinsic-media-size" proving the app is a true media-viewer/source-native product where imported media natural dimensions intentionally own canvas.size. Uploaded background/source images inside product canvases must use "editable-output" and keep the current canvas size.',
226
+ );
227
+ } else {
228
+ if (!intrinsicCanvasSizingEntry.automated || !intrinsicCanvasSizingEntry.automatedTestName.trim()) {
229
+ errors.push(
230
+ `${intrinsicCanvasSizingEntry.id} must have automated coverage proving intrinsic media sizing.`,
231
+ );
232
+ }
233
+
234
+ if (!intrinsicCanvasSizingEntry.browser || !intrinsicCanvasSizingEntry.browserTestName.trim()) {
235
+ errors.push(
236
+ `${intrinsicCanvasSizingEntry.id} must have browser coverage proving intrinsic media sizing.`,
237
+ );
238
+ }
239
+ }
240
+ }
241
+
242
+ return errors;
243
+ }
244
+
245
+ export function getToolcraftPersistenceCoverageErrors({
246
+ acceptance,
247
+ schema,
248
+ }: {
249
+ acceptance: readonly ToolcraftComponentAcceptance[];
250
+ schema: ResolvedToolcraftAppSchema;
251
+ }): string[] {
252
+ const errors: string[] = [];
253
+
254
+ if (schema.persistence.storage !== "localStorage") {
255
+ return errors;
256
+ }
257
+
258
+ const persistenceEntry = acceptance.find(
259
+ (entry) =>
260
+ entry.kind === "runtime" &&
261
+ entry.persistenceCoverage === "reload",
262
+ );
263
+
264
+ if (!persistenceEntry) {
265
+ errors.push(
266
+ 'persistence.storage "localStorage" requires a runtime acceptance entry with persistenceCoverage "reload" proving user-edited persisted state restores after a real browser reload. Settings import/export is not a substitute for persistence.',
267
+ );
268
+ return errors;
269
+ }
270
+
271
+ if (!persistenceEntry.automated || !persistenceEntry.automatedTestName.trim()) {
272
+ errors.push(
273
+ `${persistenceEntry.id} must have automated coverage proving persistence reload behavior.`,
274
+ );
275
+ }
276
+
277
+ if (!persistenceEntry.browser || !persistenceEntry.browserTestName.trim()) {
278
+ errors.push(
279
+ `${persistenceEntry.id} must have browser coverage proving persistence reload behavior.`,
280
+ );
281
+ }
282
+
283
+ if (!persistenceEntry.expectedObservable.trim()) {
284
+ errors.push(
285
+ `${persistenceEntry.id} must describe the persisted state observable after reload.`,
286
+ );
287
+ }
288
+
289
+ return errors;
290
+ }