@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,374 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { defineToolcraft, validateToolcraftPerformanceCoverage } from "@repo/toolcraft-runtime";
3
+
4
+ import { starterSchema } from "./starter-schema";
5
+
6
+ describe("Toolcraft starter performance budgets and control coverage", () => {
7
+ it("requires every visible non-action control to have performance coverage", () => {
8
+ const rendererSchema = defineToolcraft({
9
+ canvas: {
10
+ enabled: true,
11
+ size: { height: 1080, unit: "px", width: 1440 },
12
+ sizing: { mode: "editable-output" },
13
+ },
14
+ panels: {
15
+ controls: {
16
+ sections: [
17
+ {
18
+ controls: {
19
+ depth: {
20
+ defaultValue: 50,
21
+ label: "Depth",
22
+ max: 100,
23
+ min: 0,
24
+ target: "shader.depth",
25
+ type: "slider",
26
+ },
27
+ gradient: {
28
+ defaultValue: "aurora",
29
+ label: "Gradient",
30
+ options: [
31
+ { label: "Aurora", value: "aurora" },
32
+ { label: "Prism", value: "prism" },
33
+ ],
34
+ target: "shader.gradient",
35
+ type: "select",
36
+ },
37
+ mode: {
38
+ defaultValue: "soft",
39
+ label: "Mode",
40
+ options: [
41
+ { label: "Soft", value: "soft" },
42
+ { label: "Sharp", value: "sharp" },
43
+ ],
44
+ target: "shader.mode",
45
+ type: "segmented",
46
+ },
47
+ },
48
+ title: "Shader",
49
+ },
50
+ ],
51
+ title: "Shader Controls",
52
+ },
53
+ },
54
+ });
55
+
56
+ expect(
57
+ validateToolcraftPerformanceCoverage(rendererSchema, {
58
+ rendererStrategy: "canvas-2d",
59
+ rendererWorkload: "simple-composition",
60
+ scenarios: [
61
+ {
62
+ automated: true,
63
+ automatedTestName: "perf: preview render stays under budget",
64
+ browser: true,
65
+ browserTestName: "browser perf: preview render stays under budget",
66
+ budget: { maxPreviewMs: 1000 },
67
+ expectedObservable: "Preview renders without freezing.",
68
+ fixture: "1440x1080 shader fixture",
69
+ id: "preview-render",
70
+ interaction: "preview-render",
71
+ workload: false,
72
+ },
73
+ {
74
+ automated: true,
75
+ automatedTestName: "perf: depth drag stays responsive",
76
+ browser: true,
77
+ browserTestName: "browser perf: depth drag stays responsive",
78
+ budget: { maxFrameGapMs: 50, maxInteractionMs: 250 },
79
+ controlLabel: "Depth",
80
+ expectedObservable: "Dragging Depth remains responsive.",
81
+ fixture: "1440x1080 shader fixture",
82
+ id: "depth-drag",
83
+ interaction: "control-drag",
84
+ target: "shader.depth",
85
+ values: { default: 50, max: 100, min: 0 },
86
+ workload: true,
87
+ },
88
+ {
89
+ automated: true,
90
+ automatedTestName: "perf: viewport stays stable",
91
+ browser: true,
92
+ browserTestName: "browser perf: viewport stays stable",
93
+ budget: { maxFrameGapMs: 50 },
94
+ expectedObservable: "Canvas zoom and offset do not jump.",
95
+ fixture: "1440x1080 shader fixture",
96
+ id: "viewport-stability",
97
+ interaction: "viewport-stability",
98
+ workload: false,
99
+ },
100
+ ],
101
+ usesCustomRenderer: true,
102
+ workloadTargets: ["shader.depth"],
103
+ }),
104
+ ).toEqual(
105
+ expect.arrayContaining([
106
+ "shader.gradient must have a performance scenario because every visible control can affect app responsiveness.",
107
+ "shader.mode must have a performance scenario because every visible control can affect app responsiveness.",
108
+ ]),
109
+ );
110
+ });
111
+
112
+ it("requires visible control performance coverage even without a custom renderer", () => {
113
+ const controlsSchema = defineToolcraft({
114
+ canvas: {
115
+ enabled: true,
116
+ sizing: { mode: "intrinsic-media" },
117
+ },
118
+ panels: {
119
+ controls: {
120
+ sections: [
121
+ {
122
+ controls: {
123
+ mode: {
124
+ defaultValue: "soft",
125
+ label: "Mode",
126
+ options: [
127
+ { label: "Soft", value: "soft" },
128
+ { label: "Sharp", value: "sharp" },
129
+ ],
130
+ target: "app.mode",
131
+ type: "select",
132
+ },
133
+ },
134
+ title: "Display",
135
+ },
136
+ ],
137
+ title: "Controls",
138
+ },
139
+ },
140
+ });
141
+
142
+ expect(
143
+ validateToolcraftPerformanceCoverage(controlsSchema, {
144
+ rendererStrategy: "none",
145
+ rendererWorkload: "none",
146
+ scenarios: [],
147
+ usesCustomRenderer: false,
148
+ workloadTargets: [],
149
+ }),
150
+ ).toEqual(
151
+ expect.arrayContaining([
152
+ "app.mode must have a performance scenario because every visible control can affect app responsiveness.",
153
+ ]),
154
+ );
155
+ });
156
+
157
+ it("requires budgets that match each performance interaction type", () => {
158
+ expect(
159
+ validateToolcraftPerformanceCoverage(starterSchema, {
160
+ rendererStrategy: "none",
161
+ rendererWorkload: "none",
162
+ scenarios: [
163
+ {
164
+ automated: true,
165
+ automatedTestName: "perf: char size drag stays responsive",
166
+ browser: true,
167
+ browserTestName: "browser perf: char size drag stays responsive",
168
+ budget: { maxExportMs: 100 },
169
+ expectedObservable: "Dragging Char Size remains responsive.",
170
+ fixture: "1600x1000 transparent glyph fixture",
171
+ id: "char-size-drag",
172
+ interaction: "control-drag",
173
+ target: "generation.prompt",
174
+ values: { default: 12, max: 32, min: 4 },
175
+ workload: true,
176
+ },
177
+ {
178
+ actionValue: "export.png",
179
+ automated: true,
180
+ automatedTestName: "perf: export png stays under budget",
181
+ browser: true,
182
+ browserTestName: "browser perf: export png stays under budget",
183
+ budget: { maxFrameGapMs: 50 },
184
+ completionEvidence: "download",
185
+ controlLabel: "Export PNG",
186
+ expectedObservable: "Export completes without blocking the UI.",
187
+ fixture: "1920x1080 output fixture",
188
+ id: "export-png",
189
+ interaction: "export-copy",
190
+ workload: false,
191
+ },
192
+ {
193
+ automated: true,
194
+ automatedTestName: "perf: preview render stays under budget",
195
+ browser: true,
196
+ browserTestName: "browser perf: preview render stays under budget",
197
+ budget: { maxFrameGapMs: 50 },
198
+ expectedObservable: "Preview renders without freezing.",
199
+ fixture: "1920x1080 output fixture",
200
+ id: "preview-render",
201
+ interaction: "preview-render",
202
+ workload: false,
203
+ },
204
+ {
205
+ automated: true,
206
+ automatedTestName: "perf: animation frame loop stays smooth",
207
+ browser: true,
208
+ browserTestName: "browser perf: animation frame loop stays smooth",
209
+ budget: { maxFrameGapMs: 50 },
210
+ expectedObservable: "Animation advances without frame stalls.",
211
+ fixture: "animated output fixture",
212
+ id: "animation-frame-loop",
213
+ interaction: "animation-frame",
214
+ workload: false,
215
+ },
216
+ ],
217
+ usesCustomRenderer: false,
218
+ workloadTargets: ["generation.prompt"],
219
+ }),
220
+ ).toEqual(
221
+ expect.arrayContaining([
222
+ "char-size-drag control-drag scenario must declare maxInteractionMs and maxFrameGapMs.",
223
+ "export-png export-copy scenario must declare maxExportMs.",
224
+ "preview-render preview-render scenario must declare maxPreviewMs or maxRenderMs.",
225
+ "animation-frame-loop animation-frame scenario must declare maxLongTaskMs.",
226
+ ]),
227
+ );
228
+ });
229
+
230
+ it("rejects performance budgets that are too loose to catch lag", () => {
231
+ expect(
232
+ validateToolcraftPerformanceCoverage(starterSchema, {
233
+ rendererStrategy: "none",
234
+ rendererWorkload: "none",
235
+ scenarios: [
236
+ {
237
+ automated: true,
238
+ automatedTestName: "perf: char size drag stays responsive",
239
+ browser: true,
240
+ browserTestName: "browser perf: char size drag stays responsive",
241
+ budget: { maxFrameGapMs: 1000, maxInteractionMs: 10000 },
242
+ controlLabel: "Char Size",
243
+ expectedObservable: "Dragging Char Size remains responsive.",
244
+ fixture: "1600x1000 transparent glyph fixture",
245
+ id: "char-size-drag",
246
+ interaction: "control-drag",
247
+ target: "generation.prompt",
248
+ values: { default: 12, max: 32, min: 4 },
249
+ workload: true,
250
+ },
251
+ ],
252
+ usesCustomRenderer: false,
253
+ workloadTargets: ["generation.prompt"],
254
+ }),
255
+ ).toEqual(
256
+ expect.arrayContaining([
257
+ "char-size-drag maxFrameGapMs budget must be <= 120ms, received 1000ms.",
258
+ "char-size-drag maxInteractionMs budget must be <= 2000ms, received 10000ms.",
259
+ ]),
260
+ );
261
+ });
262
+
263
+ it("does not let load-profile smooth targets bypass required interaction budgets", () => {
264
+ const schema = defineToolcraft({
265
+ canvas: { enabled: true },
266
+ panels: {
267
+ controls: {
268
+ sections: [
269
+ {
270
+ controls: {
271
+ density: {
272
+ defaultValue: 4,
273
+ label: "Density",
274
+ max: 12,
275
+ min: 1,
276
+ performanceReason: "Density changes rendered output size.",
277
+ performanceRole: "workload",
278
+ target: "render.density",
279
+ type: "slider",
280
+ },
281
+ },
282
+ title: "Render",
283
+ },
284
+ ],
285
+ title: "Controls",
286
+ },
287
+ },
288
+ });
289
+
290
+ expect(
291
+ validateToolcraftPerformanceCoverage(schema, {
292
+ rendererStrategy: "none",
293
+ rendererWorkload: "none",
294
+ scenarios: [
295
+ {
296
+ automated: true,
297
+ automatedTestName: "perf: density drag stays responsive",
298
+ browser: true,
299
+ browserTestName: "browser perf: density drag stays responsive",
300
+ budget: { maxFrameGapMs: 80 },
301
+ controlLabel: "Density",
302
+ expectedObservable: "Dragging Density updates product output without blocking the UI.",
303
+ fixture: "density smooth target fixture",
304
+ id: "density-drag",
305
+ interaction: "control-drag",
306
+ stressFixture: {
307
+ kind: "max-value",
308
+ loadProfile: {
309
+ degradationStepPercent: 10,
310
+ evidence: [
311
+ {
312
+ attemptedRatio: 1,
313
+ attemptedTarget: 12,
314
+ decision: "Keep 12 as experimental and guarantee smoothness through 11.",
315
+ measuredResult: "At density 12, maxFrameGapMs 148 exceeded the 80ms budget.",
316
+ optimizationAttempted:
317
+ "Cached expensive render inputs and coalesced preview work to requestAnimationFrame.",
318
+ result: "failed",
319
+ scenarioId: "density-drag",
320
+ target: "render.density",
321
+ },
322
+ ],
323
+ hardLimit: 12,
324
+ metric: "numeric-max",
325
+ smoothTarget: 11,
326
+ smoothTargetRatio: 0.9,
327
+ target: "render.density",
328
+ userFacingRange: "experimental-above-smooth",
329
+ },
330
+ reason: "Density 11 is the measured smooth target after hard-limit testing.",
331
+ value: 11,
332
+ },
333
+ target: "render.density",
334
+ values: { default: 4, max: 12, min: 1 },
335
+ workload: true,
336
+ },
337
+ ],
338
+ usesCustomRenderer: false,
339
+ workloadTargets: ["render.density"],
340
+ }),
341
+ ).toContain("density-drag control-drag scenario must declare maxInteractionMs.");
342
+ });
343
+
344
+ it("requires real browser interaction metadata for control performance scenarios", () => {
345
+ expect(
346
+ validateToolcraftPerformanceCoverage(starterSchema, {
347
+ rendererStrategy: "none",
348
+ rendererWorkload: "none",
349
+ scenarios: [
350
+ {
351
+ automated: true,
352
+ automatedTestName: "perf: char size drag stays responsive",
353
+ browser: true,
354
+ browserTestName: "browser perf: char size drag stays responsive",
355
+ budget: { maxFrameGapMs: 50, maxInteractionMs: 250 },
356
+ expectedObservable: "Dragging Char Size remains responsive.",
357
+ fixture: "1600x1000 transparent glyph fixture",
358
+ id: "char-size-drag",
359
+ interaction: "control-drag",
360
+ target: "generation.prompt",
361
+ values: { default: 12, max: 32, min: 4 },
362
+ workload: true,
363
+ },
364
+ ],
365
+ usesCustomRenderer: false,
366
+ workloadTargets: ["generation.prompt"],
367
+ }),
368
+ ).toEqual(
369
+ expect.arrayContaining([
370
+ "char-size-drag control-drag scenario must declare controlLabel or uiSelector for its real browser interaction.",
371
+ ]),
372
+ );
373
+ });
374
+ });
@@ -0,0 +1,128 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ import { describe, expect, it } from "vitest";
5
+ import {
6
+ collectToolcraftUnclassifiedPerformanceControls,
7
+ validateToolcraftPerformanceCoverage,
8
+ } from "@repo/toolcraft-runtime";
9
+
10
+ import { starterPerformance } from "./starter-performance";
11
+ import { starterSchema } from "./starter-schema";
12
+ import {
13
+ e2eDir,
14
+ playwrightConfigForbidsFocusedTests,
15
+ projectDir,
16
+ } from "./starter-performance-test-utils";
17
+
18
+ describe("Toolcraft starter performance gates", () => {
19
+ it("publishes separate browser acceptance and performance fallback gates", () => {
20
+ const packageJson = JSON.parse(readFileSync(join(projectDir, "package.json"), "utf8")) as {
21
+ scripts?: Record<string, string>;
22
+ };
23
+ const generatedAppTestScript =
24
+ packageJson.scripts?.["test:generated"] ?? packageJson.scripts?.test;
25
+ const runScriptPattern = (scriptName: string) =>
26
+ `(?:pnpm ${scriptName}|npm run ${scriptName})`;
27
+
28
+ expect(
29
+ generatedAppTestScript,
30
+ "Generated app tests must invoke the Toolcraft integrity checker.",
31
+ ).toContain("node scripts/check-toolcraft-integrity.mjs");
32
+
33
+ expect(
34
+ packageJson.scripts?.["test:browser"],
35
+ "Generated apps must keep full performance scenarios out of the default browser acceptance gate.",
36
+ ).toBe('playwright install chromium && playwright test --grep-invert "browser perf:"');
37
+ expect(
38
+ packageJson.scripts?.["test:browser:perf"],
39
+ "Generated apps must expose a protected sequential Playwright checkpoint for final performance proof.",
40
+ ).toBe("node scripts/run-browser-performance.mjs");
41
+ const performanceRunner = readFileSync(
42
+ join(projectDir, "scripts/run-browser-performance.mjs"),
43
+ "utf8",
44
+ );
45
+ const receiptModule = readFileSync(
46
+ join(projectDir, "scripts/toolcraft-verification-receipt.mjs"),
47
+ "utf8",
48
+ );
49
+ expect(performanceRunner).toContain('runBinary(viteBin, ["build"])');
50
+ expect(performanceRunner).toContain('TOOLCRAFT_BROWSER_SERVER_MODE: "preview"');
51
+ expect(performanceRunner).toContain('"--workers=1"');
52
+ expect(performanceRunner).not.toContain('"--pass-with-no-tests"');
53
+ expect(performanceRunner).not.toContain("process.argv.slice(2)");
54
+ expect(performanceRunner).toContain(
55
+ "assertToolcraftVerificationInputsUnchanged",
56
+ );
57
+ expect(performanceRunner).toContain("clearToolcraftPerformanceReceipt");
58
+ expect(performanceRunner).toContain("writeToolcraftPerformanceCheckpointReceipt");
59
+ expect(receiptModule).not.toContain(
60
+ "export async function writeToolcraftPerformanceReceipt",
61
+ );
62
+ expect(packageJson.scripts?.["verify:quick"]).toMatch(
63
+ new RegExp(`^${runScriptPattern("ai:check")} && ${runScriptPattern("test")}$`),
64
+ );
65
+ expect(packageJson.scripts?.["verify:ui"]).toMatch(
66
+ new RegExp(`^${runScriptPattern("test:browser")}$`),
67
+ );
68
+ expect(packageJson.scripts?.["verify:perf"]).toMatch(
69
+ new RegExp(`^${runScriptPattern("test:browser:perf")}$`),
70
+ );
71
+ expect(packageJson.scripts?.["verify:perf:playwright"]).toMatch(
72
+ new RegExp(`^${runScriptPattern("test:browser:perf")}$`),
73
+ );
74
+ expect(
75
+ packageJson.scripts?.["verify:perf:record-agent-browser"],
76
+ "A terminal-only command must not mint an agent-browser performance receipt without browser evidence.",
77
+ ).toBeUndefined();
78
+ expect(packageJson.scripts?.["verify:perf:record-exemption"]).toContain(
79
+ "record-exemption",
80
+ );
81
+ expect(packageJson.scripts?.["verify:receipt"]).toContain("validate");
82
+ expect(packageJson.scripts?.["verify:final"]).toMatch(
83
+ new RegExp(
84
+ `^${runScriptPattern("ai:check")} && ${runScriptPattern("test")} && ${runScriptPattern("build")} && ${runScriptPattern("test:browser")} && ${runScriptPattern("verify:receipt")}$`,
85
+ ),
86
+ );
87
+ });
88
+
89
+ it("keeps the Playwright performance audit inside the browser perf tag", () => {
90
+ const source = readFileSync(join(e2eDir, "app-performance.spec.ts"), "utf8");
91
+ const testNames = [...source.matchAll(/test\(\s*(["'`])([^"'`]+)\1/g)].map(
92
+ (match) => match[2],
93
+ );
94
+
95
+ expect(source).not.toContain("TOOLCRAFT_PERF_CHECK");
96
+ expect(testNames.length).toBeGreaterThan(0);
97
+ expect(
98
+ testNames.every((name) => name.includes("browser perf:")),
99
+ `app-performance.spec.ts tests must all be tagged for the dedicated perf checkpoint: ${testNames.join(", ")}`,
100
+ ).toBe(true);
101
+ });
102
+
103
+ it("rejects focused Playwright tests that would bypass protected browser gates", () => {
104
+ expect(playwrightConfigForbidsFocusedTests()).toBe(true);
105
+ });
106
+
107
+ it("declares agent browser as the preferred performance runner", () => {
108
+ expect(starterPerformance.browserCheckPolicy).toEqual({
109
+ fallbackRunner: "playwright",
110
+ fallbackWhen: ["agent-browser-unavailable", "ci"],
111
+ preferredRunner: "agent-browser",
112
+ });
113
+ });
114
+
115
+ it("requires valid performance coverage for declared workload scenarios", () => {
116
+ expect(validateToolcraftPerformanceCoverage(starterSchema, starterPerformance)).toEqual([]);
117
+ });
118
+
119
+ it("requires every visible control to classify its performance role", () => {
120
+ const unclassifiedControls =
121
+ collectToolcraftUnclassifiedPerformanceControls(starterSchema);
122
+
123
+ expect(
124
+ unclassifiedControls,
125
+ "Every visible non-action control must declare performanceRole as workload or responsiveness so AI cannot skip the performance decision.",
126
+ ).toEqual([]);
127
+ });
128
+ });
@@ -0,0 +1,136 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { starterPerformance } from "./starter-performance";
4
+ import { starterSchema } from "./starter-schema";
5
+ import {
6
+ appPerformanceHasInteractionInvalidation,
7
+ appPerformanceHasRenderPipelinePass,
8
+ sourceCreatesWebGlContextInComponentRender,
9
+ sourceMayUploadTextureFromTimelineDrivenEffect,
10
+ sourceResyncsTimelineDurationFromRuntimeDuration,
11
+ sourceUsesAnimationFrameWithoutCleanup,
12
+ sourceUsesCpuPixelLoop,
13
+ sourceUsesDirectStorageApi,
14
+ sourceUsesGpuRenderer,
15
+ sourceUsesLowResolutionPreviewUpscale,
16
+ sourceUsesWebGlLifecycleGuard,
17
+ } from "./starter-performance-test-utils";
18
+
19
+ describe("Toolcraft starter renderer source performance contract", () => {
20
+ it("detects low-resolution preview upscale code paths", () => {
21
+ expect(
22
+ sourceUsesLowResolutionPreviewUpscale(`
23
+ const maxPreviewPixels = 1_250_000;
24
+ const previewScale = Math.sqrt(maxPreviewPixels / (outputWidth * outputHeight));
25
+ previewContext.drawImage(offscreenCanvas, 0, 0, outputWidth, outputHeight);
26
+ `),
27
+ ).toBe(true);
28
+
29
+ expect(
30
+ sourceUsesLowResolutionPreviewUpscale(`
31
+ canvas.width = outputWidth;
32
+ canvas.height = outputHeight;
33
+ drawAsciiTextToCanvas({ canvas, text });
34
+ `),
35
+ ).toBe(false);
36
+ });
37
+
38
+ it("rejects low-resolution preview upscale for text and vector output renderers", () => {
39
+ if (
40
+ starterPerformance.rendererWorkload !== "text-output" &&
41
+ starterPerformance.rendererWorkload !== "vector-output"
42
+ ) {
43
+ return;
44
+ }
45
+
46
+ expect(
47
+ sourceUsesLowResolutionPreviewUpscale(),
48
+ "Text/vector product previews must preserve native output fidelity. Do not render a low-resolution preview canvas/texture and upscale it to state.canvas.size; optimize layout/drawing instead.",
49
+ ).toBe(false);
50
+ });
51
+
52
+ it("requires procedural pixel-loop renderers to use a GPU strategy", () => {
53
+ if (!sourceUsesCpuPixelLoop()) {
54
+ return;
55
+ }
56
+
57
+ expect(
58
+ starterPerformance.rendererWorkload,
59
+ "Procedural ImageData/getImageData/putImageData renderers must be classified as pixel-output.",
60
+ ).toBe("pixel-output");
61
+ expect(
62
+ starterPerformance.rendererStrategy,
63
+ "Procedural ImageData/getImageData/putImageData renderers must be converted to WebGL/WebGPU or removed from the critical render path.",
64
+ ).toMatch(/^(webgl|webgpu)$/);
65
+ expect(
66
+ sourceUsesGpuRenderer(),
67
+ "Procedural pixel renderers must contain an actual WebGL/WebGPU code path, not only declare a GPU strategy.",
68
+ ).toBe(true);
69
+ expect(
70
+ appPerformanceHasRenderPipelinePass("pixel-transform"),
71
+ "Procedural pixel renderers must declare a rendererPipeline pixel-transform pass so caching and invalidation are machine-checkable.",
72
+ ).toBe(true);
73
+ });
74
+
75
+ it("requires custom renderers to declare high-frequency viewport invalidation", () => {
76
+ if (!starterPerformance.usesCustomRenderer) {
77
+ return;
78
+ }
79
+
80
+ expect(
81
+ appPerformanceHasInteractionInvalidation("viewport-zoom"),
82
+ "Custom renderer apps must declare rendererPipeline interactionInvalidation for viewport-zoom so zoom can stay responsive without recomputing expensive passes.",
83
+ ).toBe(true);
84
+ });
85
+
86
+ it("requires WebGL/WebGPU renderers to keep their pipeline lifecycle outside React render", () => {
87
+ if (!sourceUsesGpuRenderer()) {
88
+ return;
89
+ }
90
+
91
+ expect(
92
+ sourceUsesWebGlLifecycleGuard(),
93
+ "WebGL/WebGPU renderer setup must be guarded by refs, memoized setup, an effect, or a renderer class so control changes update uniforms/buffers instead of rebuilding the pipeline.",
94
+ ).toBe(true);
95
+ expect(
96
+ sourceCreatesWebGlContextInComponentRender(),
97
+ "Do not create a WebGL context directly in the component render path; initialize it once and update uniforms/buffers on runtime value changes.",
98
+ ).toBe(false);
99
+ });
100
+
101
+ it("requires animation loops to clean up scheduled frames", () => {
102
+ expect(
103
+ sourceUsesAnimationFrameWithoutCleanup(),
104
+ "Renderers that schedule requestAnimationFrame must cancelAnimationFrame on cleanup to avoid runaway loops during control changes or route unmount.",
105
+ ).toBe(false);
106
+ });
107
+
108
+ it("rejects direct app storage writes outside the runtime persistence policy", () => {
109
+ expect(
110
+ sourceUsesDirectStorageApi(),
111
+ "Generated apps must not read or write app state through localStorage/sessionStorage directly. Use runtime persistence policy when product persistence is required.",
112
+ ).toBe(false);
113
+ });
114
+
115
+ it("rejects renderer effects that overwrite user-edited timeline duration", () => {
116
+ expect(
117
+ sourceResyncsTimelineDurationFromRuntimeDuration(),
118
+ "Renderers must not watch state.timeline.durationSeconds and dispatch timeline.setDuration back to a computed local duration. Compute a default only during initialization/reset, then map renderer progress to state.timeline.durationSeconds.",
119
+ ).toBe(false);
120
+ });
121
+
122
+ it("rejects timeline-driven texture uploads in GPU keyframe renderers", () => {
123
+ if (
124
+ !sourceUsesGpuRenderer() ||
125
+ starterSchema.panels.timeline?.enabled !== true ||
126
+ starterSchema.panels.timeline.mode !== "keyframes"
127
+ ) {
128
+ return;
129
+ }
130
+
131
+ expect(
132
+ sourceMayUploadTextureFromTimelineDrivenEffect(),
133
+ "GPU keyframe renderers must upload source textures only when media/resource keys change. Timeline-driven effects may update uniforms and draw, but must not call texImage2D or renderer.setImage from an effect that depends on settings/currentTime/keyframeGroups.",
134
+ ).toBe(false);
135
+ });
136
+ });