@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
@@ -1,497 +1,6 @@
1
- import { readdirSync, readFileSync } from "node:fs";
2
- import { basename, dirname, join } from "node:path";
3
- import { fileURLToPath } from "node:url";
4
-
5
1
  import { expect, test } from "@playwright/test";
6
2
 
7
3
  import { starterPerformance } from "../src/app/starter-performance";
8
- import { starterSchema } from "../src/app/starter-schema";
9
-
10
- const currentFileName = basename(fileURLToPath(import.meta.url));
11
- const e2eDir = dirname(fileURLToPath(import.meta.url));
12
-
13
- type BrowserTestSource = {
14
- fileName: string;
15
- source: string;
16
- };
17
-
18
- function escapeRegExp(value: string): string {
19
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
20
- }
21
-
22
- function stripJsComments(source: string): string {
23
- return source
24
- .replace(/\/\*[\s\S]*?\*\//g, "")
25
- .replace(/(^|[^:])\/\/.*$/gm, "$1");
26
- }
27
-
28
- function hasRealLayerRowInteraction(source: string): boolean {
29
- return /data-layer-id|data-template-layer-name|selectLayerByName\s*\(|layerRowByName\s*\(|getByRole\s*\(\s*(["'`])option\1/i.test(
30
- source,
31
- );
32
- }
33
-
34
- function hasRealLayerVisibilityInteraction(source: string): boolean {
35
- return /toggleLayerVisibilityByName\s*\(|getByRole\s*\([\s\S]*?(Hide|Show|Disable|Enable).*layer|aria-label[\s\S]*?(Hide|Show|Disable|Enable)/i.test(
36
- source,
37
- );
38
- }
39
-
40
- function hasRealLayerDragInteraction(source: string): boolean {
41
- return /\.dragTo\s*\(|page\.mouse\.(?:down|move|up)\s*\(|dragLayer(?:Before|After|ToGroup|ByName)?\s*\(/i.test(
42
- source,
43
- );
44
- }
45
-
46
- function readSiblingBrowserTestSources(): BrowserTestSource[] {
47
- return readdirSync(e2eDir)
48
- .filter((fileName) => /\.(test|spec)\.[cm]?[jt]sx?$/.test(fileName))
49
- .filter((fileName) => fileName !== currentFileName)
50
- .map((fileName) => ({
51
- fileName,
52
- source: readFileSync(join(e2eDir, fileName), "utf8"),
53
- }));
54
- }
55
-
56
- function findNamedBrowserTestSource(
57
- sources: readonly BrowserTestSource[],
58
- testName: string,
59
- ): string | undefined {
60
- const testStartPattern = new RegExp(
61
- `(?:test|it)(?:\\.[\\w]+)?\\(\\s*(["'\`])${escapeRegExp(testName)}\\1`,
62
- );
63
- const nextTestPattern = /\n\s*(?:test|it)(?:\.[\w]+)?\(\s*["'`]/;
64
-
65
- for (const { source } of sources) {
66
- const cleanSource = stripJsComments(source);
67
- const match = testStartPattern.exec(cleanSource);
68
- if (!match) {
69
- continue;
70
- }
71
-
72
- const startIndex = match.index;
73
- const afterStart = cleanSource.slice(startIndex + 1);
74
- const nextMatchIndex = afterStart.search(nextTestPattern);
75
-
76
- return cleanSource.slice(
77
- startIndex,
78
- nextMatchIndex === -1 ? undefined : startIndex + 1 + nextMatchIndex,
79
- );
80
- }
81
-
82
- return undefined;
83
- }
84
-
85
- function getDiscreteControlLabels(): Set<string> {
86
- const labels = new Set<string>();
87
-
88
- for (const section of starterSchema.panels.controls?.sections ?? []) {
89
- for (const control of Object.values(section.controls)) {
90
- if (
91
- (control.type === "slider" || control.type === "rangeSlider") &&
92
- control.variant === "discrete" &&
93
- typeof control.label === "string"
94
- ) {
95
- labels.add(control.label);
96
- }
97
- }
98
- }
99
-
100
- return labels;
101
- }
102
-
103
- function getScenarioBudgetAssertionPattern(scenarioId: string): RegExp {
104
- return new RegExp(
105
- `expectToolcraftScenarioPerformanceBudget\\s*\\([\\s\\S]*?,\\s*(?:starterPerformance|appPerformance)\\s*,\\s*(["'\`])${escapeRegExp(
106
- scenarioId,
107
- )}\\1`,
108
- );
109
- }
110
-
111
- function getScenarioStressFixturePattern(scenarioId: string): RegExp {
112
- return new RegExp(
113
- `(?:getToolcraftPerformanceStressValue(?:\\s*<[^>]+>)?\\s*\\(\\s*(?:starterPerformance|appPerformance)|dragToolcraftSliderToPerformanceStressValue\\s*\\([\\s\\S]*?(?:starterPerformance|appPerformance)|applyToolcraftPerformanceStressFixture\\s*\\(\\s*page\\s*,\\s*(?:starterPerformance|appPerformance))\\s*,\\s*(["'\`])${escapeRegExp(
114
- scenarioId,
115
- )}\\1`,
116
- );
117
- }
118
-
119
- function getScenarioWorkloadFixturePattern(scenarioId: string): RegExp {
120
- return new RegExp(
121
- `(?:getToolcraftPerformanceWorkloadValue(?:\\s*<[^>]+>)?\\s*\\(\\s*(?:starterPerformance|appPerformance)|applyToolcraftPerformanceWorkloadFixture\\s*\\(\\s*page\\s*,\\s*(?:starterPerformance|appPerformance))\\s*,\\s*(["'\`])${escapeRegExp(
122
- scenarioId,
123
- )}\\1`,
124
- );
125
- }
126
-
127
- function getScenarioCustomStressFixturePattern(scenarioId: string): RegExp {
128
- return new RegExp(
129
- `applyToolcraftPerformanceStressFixture\\s*\\(\\s*page\\s*,\\s*(?:starterPerformance|appPerformance)\\s*,\\s*(["'\`])${escapeRegExp(
130
- scenarioId,
131
- )}\\1`,
132
- );
133
- }
134
-
135
- function getScenarioCustomWorkloadFixturePattern(scenarioId: string): RegExp {
136
- return new RegExp(
137
- `applyToolcraftPerformanceWorkloadFixture\\s*\\(\\s*page\\s*,\\s*(?:starterPerformance|appPerformance)\\s*,\\s*(["'\`])${escapeRegExp(
138
- scenarioId,
139
- )}\\1`,
140
- );
141
- }
142
-
143
- function getScenarioSliderStressValuePattern(scenarioId: string): RegExp {
144
- return new RegExp(
145
- `dragToolcraftSliderToPerformanceStressValue\\s*\\([\\s\\S]*?(?:starterPerformance|appPerformance)\\s*,\\s*(["'\`])${escapeRegExp(
146
- scenarioId,
147
- )}\\1`,
148
- );
149
- }
150
-
151
- function fixtureValueUsesRenderScale(value: unknown, pathPrefix = ""): boolean {
152
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
153
- return false;
154
- }
155
-
156
- return Object.entries(value).some(([key, itemValue]) => {
157
- const itemPath = pathPrefix ? `${pathPrefix}.${key}` : key;
158
-
159
- return (
160
- /^(?:canvas\.)?renderScale$|(?:^|[._-])resolutionScale$/i.test(itemPath) ||
161
- fixtureValueUsesRenderScale(itemValue, itemPath)
162
- );
163
- });
164
- }
165
-
166
- function scenarioUsesRenderScaleFixture(
167
- scenario: (typeof starterPerformance.scenarios)[number],
168
- ): boolean {
169
- return (
170
- scenario.target === "canvas.renderScale" ||
171
- fixtureValueUsesRenderScale(scenario.stressFixture?.value) ||
172
- fixtureValueUsesRenderScale(scenario.workloadFixture?.value)
173
- );
174
- }
175
-
176
- function scenarioUsesLoadProfile(
177
- scenario: (typeof starterPerformance.scenarios)[number],
178
- ): boolean {
179
- return Boolean(scenario.stressFixture?.loadProfile || scenario.workloadFixture?.loadProfile);
180
- }
181
-
182
- function getFirstMatchIndex(source: string, pattern: RegExp): number {
183
- const match = pattern.exec(source);
184
- return match?.index ?? -1;
185
- }
186
-
187
- test("browser perf: performance matrix points at real fallback browser tests", () => {
188
- const browserTestSources = readSiblingBrowserTestSources();
189
-
190
- for (const scenario of starterPerformance.scenarios) {
191
- if (!scenario.browser) {
192
- continue;
193
- }
194
-
195
- expect(
196
- Boolean(findNamedBrowserTestSource(browserTestSources, scenario.browserTestName)),
197
- `${scenario.id} must be backed by a fallback browser performance test named "${scenario.browserTestName}".`,
198
- ).toBe(true);
199
- }
200
- });
201
-
202
- test("browser perf: performance tests use real Toolcraft interactions", () => {
203
- if (starterPerformance.scenarios.length === 0) {
204
- return;
205
- }
206
-
207
- const browserTestSources = readSiblingBrowserTestSources();
208
- const discreteControlLabels = getDiscreteControlLabels();
209
-
210
- for (const scenario of starterPerformance.scenarios) {
211
- const browserTestSource = findNamedBrowserTestSource(
212
- browserTestSources,
213
- scenario.browserTestName,
214
- );
215
-
216
- expect(
217
- browserTestSource,
218
- `${scenario.id} must be backed by a browser performance test named "${scenario.browserTestName}".`,
219
- ).toBeDefined();
220
-
221
- if (!browserTestSource) {
222
- continue;
223
- }
224
-
225
- if (scenario.workload || scenario.stress === true || scenario.stressFixture) {
226
- expect(
227
- scenario.stressFixture,
228
- `${scenario.id} stress scenario must declare stressFixture so browser tests cannot use toy inputs.`,
229
- ).toBeDefined();
230
- expect(
231
- browserTestSource,
232
- `${scenario.id} must read the declared stress fixture with getToolcraftPerformanceStressValue(appPerformance, "${scenario.id}") before measuring performance.`,
233
- ).toMatch(getScenarioStressFixturePattern(scenario.id));
234
-
235
- if (
236
- scenario.stressFixture?.kind === "custom" &&
237
- typeof scenario.stressFixture.value === "object" &&
238
- scenario.stressFixture.value !== null &&
239
- !Array.isArray(scenario.stressFixture.value)
240
- ) {
241
- expect(
242
- browserTestSource,
243
- `${scenario.id} custom stress fixture must be applied with applyToolcraftPerformanceStressFixture so every heavy-state key is mapped through the real UI before measurement.`,
244
- ).toMatch(getScenarioCustomStressFixturePattern(scenario.id));
245
- }
246
- }
247
-
248
- if (scenario.workloadFixture) {
249
- const workloadFixtureIndex = getFirstMatchIndex(
250
- browserTestSource,
251
- getScenarioWorkloadFixturePattern(scenario.id),
252
- );
253
- const stressFixtureIndex = getFirstMatchIndex(
254
- browserTestSource,
255
- getScenarioStressFixturePattern(scenario.id),
256
- );
257
- const budgetAssertionIndex = getFirstMatchIndex(
258
- browserTestSource,
259
- getScenarioBudgetAssertionPattern(scenario.id),
260
- );
261
-
262
- expect(
263
- browserTestSource,
264
- `${scenario.id} must apply the declared workloadFixture with getToolcraftPerformanceWorkloadValue(appPerformance, "${scenario.id}") or applyToolcraftPerformanceWorkloadFixture before measuring performance.`,
265
- ).toMatch(getScenarioWorkloadFixturePattern(scenario.id));
266
- expect(
267
- workloadFixtureIndex,
268
- `${scenario.id} must apply workloadFixture before stressFixture so the measured control runs inside the heavy app baseline.`,
269
- ).toBeGreaterThanOrEqual(0);
270
- expect(
271
- stressFixtureIndex,
272
- `${scenario.id} must read/apply stressFixture after workloadFixture.`,
273
- ).toBeGreaterThan(workloadFixtureIndex);
274
- expect(
275
- budgetAssertionIndex,
276
- `${scenario.id} must assert budget only after workloadFixture is applied.`,
277
- ).toBeGreaterThan(workloadFixtureIndex);
278
-
279
- if (
280
- scenario.workloadFixture.kind === "custom" &&
281
- typeof scenario.workloadFixture.value === "object" &&
282
- scenario.workloadFixture.value !== null &&
283
- !Array.isArray(scenario.workloadFixture.value)
284
- ) {
285
- expect(
286
- browserTestSource,
287
- `${scenario.id} custom workload fixture must be applied with applyToolcraftPerformanceWorkloadFixture so every baseline-state key is mapped through the real UI before measurement.`,
288
- ).toMatch(getScenarioCustomWorkloadFixturePattern(scenario.id));
289
- }
290
- }
291
-
292
- if (scenario.interaction === "control-drag") {
293
- expect(
294
- browserTestSource,
295
- `${scenario.id} must measure a real Toolcraft pointer drag instead of filling a hidden/numeric editor.`,
296
- ).toMatch(/dragToolcraftSliderByLabel\s*\(/);
297
-
298
- if (scenario.controlLabel) {
299
- expect(
300
- browserTestSource,
301
- `${scenario.id} must drag the declared control label "${scenario.controlLabel}".`,
302
- ).toMatch(
303
- new RegExp(
304
- `dragToolcraftSliderByLabel\\s*\\([\\s\\S]*?(["'\`])${escapeRegExp(
305
- scenario.controlLabel,
306
- )}\\1`,
307
- ),
308
- );
309
- }
310
-
311
- if (scenario.controlLabel && discreteControlLabels.has(scenario.controlLabel)) {
312
- expect(
313
- browserTestSource,
314
- `${scenario.id} drags discrete slider "${scenario.controlLabel}" and must verify Toolcraft marker-budget behavior plus smooth drag.`,
315
- ).toMatch(/expectToolcraftDiscreteSliderDragSmoothness\s*\(/);
316
- }
317
-
318
- if (scenario.workload && scenario.controlLabel) {
319
- expect(
320
- browserTestSource,
321
- `${scenario.id} workload slider drags must apply the exact stressFixture.value with dragToolcraftSliderToPerformanceStressValue instead of hand-dividing by max or typing a ratio.`,
322
- ).toMatch(getScenarioSliderStressValuePattern(scenario.id));
323
- }
324
- }
325
-
326
- if (scenarioUsesRenderScaleFixture(scenario)) {
327
- expect(
328
- browserTestSource,
329
- `${scenario.id} uses canvas.renderScale and must prove the selected Resolution scale changes backing canvas pixels instead of only changing declarative state.`,
330
- ).toMatch(/expectToolcraftCanvasBackingPixelsForRenderScale\s*\(/);
331
- }
332
-
333
- if (scenarioUsesLoadProfile(scenario)) {
334
- expect(
335
- browserTestSource,
336
- `${scenario.id} declares a loadProfile and must apply the documented smoothTarget through appPerformance fixtures instead of recalculating a smaller browser-only target.`,
337
- ).toMatch(
338
- scenario.workloadFixture
339
- ? getScenarioWorkloadFixturePattern(scenario.id)
340
- : getScenarioStressFixturePattern(scenario.id),
341
- );
342
- expect(
343
- browserTestSource,
344
- `${scenario.id} declares a loadProfile and must keep budget assertions tied to app-performance.ts.`,
345
- ).toMatch(getScenarioBudgetAssertionPattern(scenario.id));
346
- }
347
-
348
- if (scenario.interaction === "control-change") {
349
- expect(
350
- browserTestSource,
351
- `${scenario.id} must change the declared control through the browser UI.`,
352
- ).toMatch(/\.fill\s*\(|\.pressSequentially\s*\(|\.selectOption\s*\(|getByRole\s*\([\s\S]*?\.click\s*\(/);
353
- }
354
-
355
- if (scenario.uiSelector) {
356
- expect(
357
- browserTestSource,
358
- `${scenario.id} must interact with the declared UI selector "${scenario.uiSelector}".`,
359
- ).toContain(scenario.uiSelector);
360
- }
361
-
362
- expect(
363
- browserTestSource,
364
- `${scenario.id} must measure browser responsiveness with measureToolcraftInteraction.`,
365
- ).toMatch(
366
- /measureToolcraftInteraction\s*\(|measureToolcraftAnimationFrames\s*\(|expectToolcraftCanvasViewportStable\s*\(/,
367
- );
368
-
369
- if (scenario.interaction === "viewport-stability") {
370
- expect(
371
- browserTestSource,
372
- `${scenario.id} must use expectToolcraftCanvasViewportStable to catch canvas zoom/offset jumps.`,
373
- ).toMatch(/expectToolcraftCanvasViewportStable\s*\(/);
374
-
375
- if (scenario.target === "timeline.keyframes") {
376
- expect(
377
- browserTestSource,
378
- `${scenario.id} must exercise toolbar zoom or radar before checking keyframe viewport stability.`,
379
- ).toMatch(/Zoom in|Zoom out|Center canvas|canvas\.zoom|canvas\.center/);
380
- expect(
381
- browserTestSource,
382
- `${scenario.id} must open the expanded keyframe editor while checking viewport stability.`,
383
- ).toMatch(/Expand timeline panel|timeline\.setExpanded|timeline-expanded/);
384
- expect(
385
- browserTestSource,
386
- `${scenario.id} must create or update at least one keyframe while checking viewport stability.`,
387
- ).toMatch(/Add .* keyframe|Disable .* keyframes|timeline-keyframe-row/);
388
- expect(
389
- browserTestSource,
390
- `${scenario.id} must scrub or play the timeline while checking viewport stability.`,
391
- ).toMatch(/Playback position|Play playback|Pause playback|timeline\.setCurrentTime/);
392
- }
393
-
394
- if (scenario.target === "layers.interactions") {
395
- expect(
396
- browserTestSource,
397
- `${scenario.id} must exercise toolbar zoom or radar before checking layer viewport stability.`,
398
- ).toMatch(/Zoom in|Zoom out|Center canvas|canvas\.zoom|canvas\.center/);
399
- expect(
400
- hasRealLayerRowInteraction(browserTestSource),
401
- `${scenario.id} must select real LayersPanel rows while checking viewport stability.`,
402
- ).toBe(true);
403
- expect(
404
- hasRealLayerVisibilityInteraction(browserTestSource),
405
- `${scenario.id} must toggle real layer visibility while checking viewport stability.`,
406
- ).toBe(true);
407
- expect(
408
- hasRealLayerDragInteraction(browserTestSource),
409
- `${scenario.id} must drag real layer rows for reorder or grouping while checking viewport stability.`,
410
- ).toBe(true);
411
- expect(
412
- browserTestSource,
413
- `${scenario.id} must assert selected-layer or product output after layer interactions.`,
414
- ).toMatch(/selected layer|selectedLayer|product-output|rendered-pixels|canvas|export|output/i);
415
- }
416
- }
417
-
418
- if (scenario.interaction === "animation-frame") {
419
- expect(
420
- browserTestSource,
421
- `${scenario.id} must use measureToolcraftAnimationFrames so animated renderers are sampled for at least 120 frames.`,
422
- ).toMatch(/measureToolcraftAnimationFrames\s*\(/);
423
- expect(
424
- browserTestSource,
425
- `${scenario.id} must not satisfy animation coverage with a short waitForToolcraftAnimationFrames probe.`,
426
- ).not.toMatch(/waitForToolcraftAnimationFrames\s*\(\s*page\s*,\s*(?:[1-9]|[1-9]\d|1[01]\d)\s*\)/);
427
- }
428
-
429
- if (scenario.interaction === "animation-viewport-drag") {
430
- expect(
431
- browserTestSource,
432
- `${scenario.id} must measure a real canvas viewport drag while the renderer is animated.`,
433
- ).toMatch(/measureToolcraftInteraction\s*\([\s\S]*dragToolcraftCanvasViewport\s*\(/);
434
- expect(
435
- browserTestSource,
436
- `${scenario.id} must not fake animated viewport coverage with toolbar zoom or direct canvas commands.`,
437
- ).not.toMatch(/canvas\.setOffset|canvas\.panBy|canvas\.zoom|Zoom in|Zoom out|Center canvas/);
438
- }
439
-
440
- if (scenario.interaction === "timeline-playback") {
441
- expect(
442
- browserTestSource,
443
- `${scenario.id} must use the real timeline playback UI while measuring frames.`,
444
- ).toMatch(/measureToolcraftInteraction\s*\([\s\S]*(Play playback|Pause playback|timeline-playback|data-slot=["']timeline-playback)/);
445
- expect(
446
- browserTestSource,
447
- `${scenario.id} must not satisfy timeline playback performance by dispatching timeline state directly.`,
448
- ).not.toMatch(/timeline\.setCurrentTime|timeline\.setPlaying|timeline\.play|timeline\.pause/);
449
- }
450
-
451
- if (scenario.interaction === "timeline-scrub") {
452
- expect(
453
- browserTestSource,
454
- `${scenario.id} must scrub the real timeline UI while measuring interaction responsiveness.`,
455
- ).toMatch(/measureToolcraftInteraction\s*\([\s\S]*(Playback position|timeline-playback-handle|data-slot=["']timeline-playback-handle|page\.mouse\.(?:down|move|up))/);
456
- expect(
457
- browserTestSource,
458
- `${scenario.id} must not satisfy timeline scrub performance by setting timeline time directly.`,
459
- ).not.toMatch(/timeline\.setCurrentTime|canvas\.setCurrentTime/);
460
- }
461
-
462
- if (scenario.interaction === "mask-drag") {
463
- expect(
464
- browserTestSource,
465
- `${scenario.id} must measure a real canvas handle/mask drag.`,
466
- ).toMatch(/measureToolcraftInteraction\s*\([\s\S]*dragCanvasHandle\s*\(/);
467
- expect(
468
- browserTestSource,
469
- `${scenario.id} must not fake mask drag coverage with direct runtime state mutation.`,
470
- ).not.toMatch(/mask\.(?:set|update|move)|canvas\.setOffset|canvas\.panBy/);
471
- }
472
-
473
- if (scenario.interaction === "viewport-zoom-stress") {
474
- expect(
475
- browserTestSource,
476
- `${scenario.id} must measure real toolbar zoom while sampling frame gaps.`,
477
- ).toMatch(/measureToolcraftInteraction\s*\([\s\S]*zoomToolcraftCanvasViewport\s*\(/);
478
- expect(
479
- browserTestSource,
480
- `${scenario.id} must not fake zoom stress with direct runtime canvas commands.`,
481
- ).not.toMatch(/canvas\.setZoom|canvas\.zoom|canvas\.setScale|canvas\.setOffset|canvas\.panBy/);
482
- }
483
-
484
- expect(
485
- browserTestSource,
486
- `${scenario.id} must assert product or UI output after the measured interaction so a no-op control cannot pass.`,
487
- ).toMatch(/await\s+expect\s*\(|expect\s*\(/);
488
-
489
- expect(
490
- browserTestSource,
491
- `${scenario.id} must assert its typed budget through expectToolcraftScenarioPerformanceBudget(..., appPerformance, "${scenario.id}") so browser thresholds cannot drift from app-performance.ts.`,
492
- ).toMatch(getScenarioBudgetAssertionPattern(scenario.id));
493
- }
494
- });
495
4
 
496
5
  test("browser perf: declared renderer layer selectors are present", async ({ page }) => {
497
6
  if (!starterPerformance.usesCustomRenderer) {
@@ -0,0 +1,97 @@
1
+ import { expect } from "@playwright/test";
2
+
3
+ import type { ToolcraftBrowserAcceptanceOutcomeEvidenceType } from "../src/app/test-evidence/browser-runtime-contract";
4
+ import { attachToolcraftBrowserRuntimeEvidence } from "./browser-runtime-evidence";
5
+ import {
6
+ getToolcraftBrowserActionTarget,
7
+ isToolcraftBrowserAction,
8
+ runToolcraftBrowserValueAction,
9
+ type ToolcraftBrowserAction,
10
+ } from "./browser-proof-session";
11
+ import {
12
+ assertToolcraftProducedArtifact,
13
+ type ToolcraftExportArtifactInspectionResult,
14
+ validateToolcraftExportArtifactInspection,
15
+ } from "./export-artifact-helpers";
16
+ import { expectToolcraftPersistentOutcomeAfterAction } from "./stable-outcome-helpers";
17
+
18
+ export async function expectToolcraftAcceptanceOutcome<T>(
19
+ observeOutcome: () => Promise<T>,
20
+ action: () => Promise<void>,
21
+ {
22
+ evidenceType,
23
+ requirementId,
24
+ stabilityIntervalMs,
25
+ stabilitySamples,
26
+ timeoutMs = 5_000,
27
+ }: {
28
+ evidenceType: ToolcraftBrowserAcceptanceOutcomeEvidenceType;
29
+ requirementId: string;
30
+ stabilityIntervalMs?: number;
31
+ stabilitySamples?: number;
32
+ timeoutMs?: number;
33
+ },
34
+ ): Promise<T> {
35
+ if (evidenceType !== "command-side-effect") {
36
+ throw new Error(
37
+ `Generic acceptance outcomes cannot emit specialized evidence "${String(evidenceType)}". Use the protected semantic recipe for that behavior.`,
38
+ );
39
+ }
40
+ const result = await expectToolcraftPersistentOutcomeAfterAction(
41
+ observeOutcome,
42
+ action,
43
+ {
44
+ message: `Acceptance outcome "${requirementId}" should change after the tested action.`,
45
+ stabilityIntervalMs,
46
+ stabilitySamples,
47
+ timeoutMs,
48
+ },
49
+ );
50
+ await attachToolcraftBrowserRuntimeEvidence({ evidenceType, requirementId });
51
+ return result;
52
+ }
53
+
54
+ export async function expectToolcraftReferenceParity<T>(
55
+ observeActual: () => Promise<T>,
56
+ expected: T,
57
+ { requirementId }: { requirementId: string },
58
+ ): Promise<T> {
59
+ const actual = await observeActual();
60
+ expect(actual, `Reference outcome "${requirementId}" should match the inspected baseline.`).toEqual(
61
+ expected,
62
+ );
63
+ await attachToolcraftBrowserRuntimeEvidence({
64
+ evidenceType: "reference-parity",
65
+ requirementId,
66
+ });
67
+ return actual;
68
+ }
69
+
70
+ export async function expectToolcraftExportedArtifact<
71
+ TArtifact,
72
+ TObservation extends ToolcraftExportArtifactInspectionResult,
73
+ >(
74
+ produceArtifact:
75
+ | (() => Promise<TArtifact>)
76
+ | ToolcraftBrowserAction<"interaction", TArtifact>,
77
+ verifyArtifact: (
78
+ artifact: TArtifact,
79
+ ) => Promise<TObservation> | TObservation,
80
+ { requirementId }: { requirementId: string },
81
+ ): Promise<TArtifact> {
82
+ const target = isToolcraftBrowserAction(produceArtifact)
83
+ ? getToolcraftBrowserActionTarget(produceArtifact)
84
+ : undefined;
85
+ const artifact = isToolcraftBrowserAction(produceArtifact)
86
+ ? await runToolcraftBrowserValueAction(produceArtifact)
87
+ : await produceArtifact();
88
+ assertToolcraftProducedArtifact(artifact, requirementId);
89
+ const observation = await verifyArtifact(artifact);
90
+ validateToolcraftExportArtifactInspection(observation, requirementId);
91
+ await attachToolcraftBrowserRuntimeEvidence({
92
+ evidenceType: "exported-artifact",
93
+ requirementId,
94
+ target,
95
+ });
96
+ return artifact;
97
+ }
@@ -0,0 +1,74 @@
1
+ import { expect } from "@playwright/test";
2
+
3
+ import {
4
+ expectToolcraftPersistentExpectedOutcome,
5
+ expectToolcraftStableOutcomeBaseline,
6
+ snapshotToolcraftOutcome,
7
+ type ToolcraftStableOutcomeOptions,
8
+ } from "./stable-outcome-helpers";
9
+ import {
10
+ assertToolcraftBrowserProofSession,
11
+ readToolcraftBrowserObservation,
12
+ runToolcraftBrowserAction,
13
+ type ToolcraftBrowserAction,
14
+ type ToolcraftBrowserObservation,
15
+ } from "./browser-proof-session";
16
+
17
+ export type ToolcraftExpectedTransitionResult<T> = {
18
+ after: T;
19
+ before: T;
20
+ };
21
+
22
+ export type ToolcraftSemanticEvidenceOptions = {
23
+ requirementId: string;
24
+ stabilityIntervalMs?: number;
25
+ stabilitySamples?: number;
26
+ timeoutMs?: number;
27
+ };
28
+
29
+ export function createToolcraftSemanticTransitionOptions(
30
+ message: string,
31
+ options: ToolcraftSemanticEvidenceOptions,
32
+ ): ToolcraftStableOutcomeOptions {
33
+ return {
34
+ message,
35
+ ...(options.stabilityIntervalMs === undefined
36
+ ? {}
37
+ : { stabilityIntervalMs: options.stabilityIntervalMs }),
38
+ ...(options.stabilitySamples === undefined
39
+ ? {}
40
+ : { stabilitySamples: options.stabilitySamples }),
41
+ ...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),
42
+ };
43
+ }
44
+
45
+ export async function expectToolcraftExpectedOutcomeAfterAction<T>(
46
+ observeOutcome: ToolcraftBrowserObservation<T>,
47
+ action: ToolcraftBrowserAction,
48
+ expected: T,
49
+ options: ToolcraftStableOutcomeOptions,
50
+ ): Promise<ToolcraftExpectedTransitionResult<T>> {
51
+ assertToolcraftBrowserProofSession(observeOutcome, action);
52
+ const observe = () => readToolcraftBrowserObservation(observeOutcome);
53
+ const before = snapshotToolcraftOutcome(
54
+ await observe(),
55
+ options.message,
56
+ );
57
+ const expectedSnapshot = snapshotToolcraftOutcome(expected, options.message);
58
+
59
+ expect(
60
+ before,
61
+ `${options.message} The expected state must differ from the pre-action state so the tested action proves a transition.`,
62
+ ).not.toEqual(expectedSnapshot);
63
+
64
+ await expectToolcraftStableOutcomeBaseline(observe, before, options);
65
+
66
+ await runToolcraftBrowserAction(action);
67
+ const after = await expectToolcraftPersistentExpectedOutcome(
68
+ observe,
69
+ expectedSnapshot,
70
+ options,
71
+ );
72
+
73
+ return { after, before };
74
+ }