@pixel-point/toolcraft 0.0.17 → 0.0.19

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 (503) hide show
  1. package/package.json +1 -1
  2. package/src/generate-demand-only-lifecycle.test.mjs +9 -1
  3. package/src/generate-performance-iteration-execution.test.mjs +3 -3
  4. package/src/generate-test-delivery-architecture-assertions.mjs +11 -73
  5. package/src/generate-test-demand-only-lifecycle.mjs +34 -36
  6. package/src/generate-test-dependency-sandbox.mjs +4 -1
  7. package/src/generate-test-doc-assertions.mjs +81 -89
  8. package/src/generate-test-doc-assertions.test.mjs +44 -1
  9. package/src/generate-test-doc-policy-assertions.mjs +92 -0
  10. package/src/generate-test-export-doc-assertions.mjs +53 -0
  11. package/src/generate-test-file-assertions.mjs +77 -83
  12. package/src/generate-test-integrity-assertions.mjs +5 -2
  13. package/src/generate-test-integrity-manifest-assertions.mjs +16 -5
  14. package/src/generate-test-integrity-ownership-assertions.mjs +36 -4
  15. package/src/generate-test-package-assertions.mjs +4 -0
  16. package/src/generate-test-product-fixture.mjs +1 -1
  17. package/src/generate-test-product-fixture.test.mjs +35 -38
  18. package/src/generate-test-product-iteration.mjs +0 -1
  19. package/src/generate-test-product-iteration.test.mjs +17 -1
  20. package/src/generate-test-runtime-boundary-assertions.mjs +178 -0
  21. package/src/generate-test-standalone-assertions.mjs +7 -13
  22. package/src/generate-test-standalone-delivery-stages.mjs +2 -86
  23. package/src/generate.test.mjs +4 -0
  24. package/src/generated-integrity-manifest.test.mjs +5 -2
  25. package/src/generated-source-policy.test.mjs +0 -4
  26. package/src/package-json.mjs +5 -0
  27. package/src/package-json.test.mjs +21 -0
  28. package/src/package-manager.mjs +2 -0
  29. package/src/package-manager.test.mjs +8 -0
  30. package/src/packaged-template-fallback-helpers.mjs +254 -0
  31. package/src/packaged-template-fallback.test.mjs +121 -46
  32. package/src/packaged-template-runtime-assertions.mjs +150 -0
  33. package/templates/runtime/contracts/component-contracts.choices.test.ts +64 -5
  34. package/templates/runtime/contracts/component-contracts.choices.ts +55 -5
  35. package/templates/runtime/contracts/component-contracts.inputs.test.ts +6 -6
  36. package/templates/runtime/contracts/component-contracts.inputs.ts +8 -7
  37. package/templates/runtime/contracts/component-contracts.media-custom.test.ts +8 -2
  38. package/templates/runtime/contracts/component-contracts.media-custom.ts +8 -2
  39. package/templates/runtime/contracts/component-contracts.runtime-acceptance.test.ts +22 -8
  40. package/templates/runtime/contracts/component-contracts.runtime-labels.test.ts +7 -1
  41. package/templates/runtime/contracts/component-contracts.runtime-panels.test.ts +3 -0
  42. package/templates/runtime/contracts/component-contracts.runtime-shell.test.ts +4 -1
  43. package/templates/runtime/contracts/component-contracts.runtime.ts +19 -12
  44. package/templates/runtime/contracts/component-contracts.test.ts +2 -0
  45. package/templates/runtime/contracts/component-contracts.visual.test.ts +20 -0
  46. package/templates/runtime/contracts/component-contracts.visual.ts +4 -0
  47. package/templates/runtime/contracts/decision-contracts.test.ts +35 -11
  48. package/templates/runtime/contracts/decision-contracts.ts +12 -12
  49. package/templates/runtime/contracts/performance-verification-policy.test.ts +12 -12
  50. package/templates/runtime/contracts/performance-verification-policy.ts +8 -8
  51. package/templates/runtime/export/artifact-download.ts +1 -0
  52. package/templates/runtime/export/artifact-frame-renderer.ts +2 -15
  53. package/templates/runtime/export/artifact-frame-state.ts +16 -0
  54. package/templates/runtime/export/artifact-scene-frame.test.ts +3 -3
  55. package/templates/runtime/export/artifact-scene-frame.ts +3 -3
  56. package/templates/runtime/export/export-background.ts +0 -19
  57. package/templates/runtime/export/export-error.ts +5 -0
  58. package/templates/runtime/export/export-renderer-coverage.ts +54 -0
  59. package/templates/runtime/export/export.test.ts +45 -42
  60. package/templates/runtime/export/image-artifact-export.ts +2 -2
  61. package/templates/runtime/export/index.ts +57 -16
  62. package/templates/runtime/export/product-export-renderer.test.ts +38 -4
  63. package/templates/runtime/export/product-export-renderer.ts +0 -41
  64. package/templates/runtime/export/product-svg-export-renderer.ts +21 -0
  65. package/templates/runtime/export/svg-artifact-export.test.ts +98 -0
  66. package/templates/runtime/export/svg-artifact-export.ts +120 -0
  67. package/templates/runtime/export/svg-document.test.ts +221 -0
  68. package/templates/runtime/export/svg-document.ts +400 -0
  69. package/templates/runtime/export/svg-policy.ts +47 -0
  70. package/templates/runtime/index.ts +3 -0
  71. package/templates/runtime/model-import/model-import-limits.ts +15 -4
  72. package/templates/runtime/react/app-shell/runtime-public-api.test.tsx +21 -1
  73. package/templates/runtime/react/app-shell/settings-transfer.test.ts +21 -0
  74. package/templates/runtime/react/app-shell/toolcraft-app.scene-export.test.tsx +75 -1
  75. package/templates/runtime/react/app-shell/toolcraft-app.tsx +24 -9
  76. package/templates/runtime/react/canvas/canvas-shell-interactions.test.tsx +30 -0
  77. package/templates/runtime/react/canvas/canvas-shell-pinch-interactions.test.tsx +155 -0
  78. package/templates/runtime/react/canvas/canvas-shell-rendering.test.tsx +77 -1
  79. package/templates/runtime/react/canvas/canvas-shell-test-utils.tsx +13 -1
  80. package/templates/runtime/react/canvas/canvas-shell.tsx +32 -6
  81. package/templates/runtime/react/canvas/canvas-viewport-geometry.ts +133 -0
  82. package/templates/runtime/react/canvas/product-scene-surface.test.tsx +195 -0
  83. package/templates/runtime/react/canvas/product-scene-surface.tsx +155 -0
  84. package/templates/runtime/react/canvas/runtime-scene-export.ts +1 -1
  85. package/templates/runtime/react/canvas/use-canvas-viewport-interactions.ts +285 -36
  86. package/templates/runtime/react/controls-panel/__tests__/control-conditions.test.ts +61 -0
  87. package/templates/runtime/react/controls-panel/__tests__/controls-panel.collection-actions.test.tsx +89 -0
  88. package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-applicability-layout.test.tsx +134 -0
  89. package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-layout.test.tsx +16 -1
  90. package/templates/runtime/react/controls-panel/__tests__/controls-panel.control-visibility.test.tsx +40 -19
  91. package/templates/runtime/react/controls-panel/__tests__/controls-panel.render-isolation.test.tsx +2 -0
  92. package/templates/runtime/react/controls-panel/__tests__/controls-panel.scene-export-actions.test.tsx +40 -1
  93. package/templates/runtime/react/controls-panel/__tests__/controls-panel.setup-controls.test.tsx +3 -3
  94. package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-collection.test.tsx +59 -0
  95. package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-color-bank.test.tsx +67 -0
  96. package/templates/runtime/react/controls-panel/__tests__/controls-panel.vector-interaction.test.tsx +6 -6
  97. package/templates/runtime/react/controls-panel/actions/controls-panel-actions.ts +4 -6
  98. package/templates/runtime/react/controls-panel/actions/export-action-runner.ts +41 -6
  99. package/templates/runtime/react/controls-panel/conditions/control-conditions.ts +32 -119
  100. package/templates/runtime/react/controls-panel/layout/controls-panel-control-group.tsx +5 -2
  101. package/templates/runtime/react/controls-panel/layout/controls-panel-layout.tsx +41 -10
  102. package/templates/runtime/react/controls-panel/layout/controls-panel-section.tsx +7 -4
  103. package/templates/runtime/react/controls-panel/renderers/controls-panel-action-renderer.tsx +2 -1
  104. package/templates/runtime/react/controls-panel/renderers/controls-panel-basic-renderers.tsx +2 -52
  105. package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-item-fields.test.tsx +63 -0
  106. package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-item-fields.tsx +138 -0
  107. package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-items.tsx +104 -0
  108. package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-renderer.tsx +115 -236
  109. package/templates/runtime/react/controls-panel/renderers/controls-panel-file-drop-item-controls.test.tsx +95 -0
  110. package/templates/runtime/react/controls-panel/renderers/controls-panel-file-drop-item-controls.tsx +82 -0
  111. package/templates/runtime/react/controls-panel/renderers/controls-panel-media-renderer.test.tsx +73 -1
  112. package/templates/runtime/react/controls-panel/renderers/controls-panel-media-renderer.tsx +50 -1
  113. package/templates/runtime/react/controls-panel/renderers/controls-panel-renderer-registry.test.ts +1 -1
  114. package/templates/runtime/react/controls-panel/renderers/controls-panel-renderer-registry.ts +2 -1
  115. package/templates/runtime/react/controls-panel/values/controls-panel-collection-values.ts +38 -6
  116. package/templates/runtime/react/controls-panel/values/controls-panel-color-values.ts +1 -9
  117. package/templates/runtime/react/controls-panel/values/controls-panel-spatial-values.ts +7 -2
  118. package/templates/runtime/react/controls-panel/values/controls-panel-value-labels.ts +1 -0
  119. package/templates/runtime/react/index.ts +4 -0
  120. package/templates/runtime/react/model-rendering/model-export.ts +1 -1
  121. package/templates/runtime/react/orientation-gizmo/orientation-gizmo-math.ts +9 -69
  122. package/templates/runtime/react/orientation-gizmo/orientation-gizmo-selection.ts +5 -5
  123. package/templates/runtime/react/orientation-gizmo/use-toolcraft-orientation-control-selection.ts +2 -2
  124. package/templates/runtime/scene/scene-bounds.test.ts +23 -0
  125. package/templates/runtime/scene/scene-bounds.ts +31 -17
  126. package/templates/runtime/schema/app-capabilities.test.ts +4 -0
  127. package/templates/runtime/schema/artifact-export-actions.test.ts +47 -0
  128. package/templates/runtime/schema/artifact-export-actions.ts +49 -0
  129. package/templates/runtime/schema/collection-item-controls.ts +29 -0
  130. package/templates/runtime/schema/control-applicability.test.ts +127 -0
  131. package/templates/runtime/schema/control-applicability.ts +433 -0
  132. package/templates/runtime/schema/control-schema-normalization.ts +177 -11
  133. package/templates/runtime/schema/controls-panel-actions.ts +2 -2
  134. package/templates/runtime/schema/controls-panel-section-layout.ts +14 -9
  135. package/templates/runtime/schema/controls-panel-section-roundtrip.test.ts +59 -0
  136. package/templates/runtime/schema/define-toolcraft.collection-actions-item-controls.test.ts +127 -0
  137. package/templates/runtime/schema/define-toolcraft.control-sections.test.ts +10 -4
  138. package/templates/runtime/schema/define-toolcraft.file-drop-item-controls.test.ts +98 -0
  139. package/templates/runtime/schema/define-toolcraft.file-drop-normalization.test.ts +27 -0
  140. package/templates/runtime/schema/define-toolcraft.segmented-control-fit.test.ts +20 -2
  141. package/templates/runtime/schema/define-toolcraft.setup-canvas.test.ts +16 -3
  142. package/templates/runtime/schema/define-toolcraft.source-collection.test.ts +79 -0
  143. package/templates/runtime/schema/runtime-setup-section.ts +24 -5
  144. package/templates/runtime/schema/types.ts +69 -13
  145. package/templates/runtime/state/canvas-background-state.ts +1 -16
  146. package/templates/runtime/state/canvas-state.ts +32 -20
  147. package/templates/runtime/state/control-value-codecs.test.ts +98 -0
  148. package/templates/runtime/state/control-value-codecs.ts +700 -0
  149. package/templates/runtime/state/control-value-normalization.test.ts +1 -1
  150. package/templates/runtime/state/control-value-normalization.ts +127 -135
  151. package/templates/runtime/state/controls-reducer.ts +26 -3
  152. package/templates/runtime/state/create-template-state.test.ts +30 -0
  153. package/templates/runtime/state/create-template-state.ts +52 -31
  154. package/templates/runtime/state/orientation-pose.ts +80 -0
  155. package/templates/runtime/state/persistence-control-values.test.ts +59 -0
  156. package/templates/runtime/state/reducer-controls.test.ts +45 -0
  157. package/templates/runtime/state/reducer-media-reset.test.ts +1 -1
  158. package/templates/runtime/state/reducer-timeline.test.ts +70 -0
  159. package/templates/runtime/state/timeline-reducer.ts +40 -2
  160. package/templates/runtime/testing/performance-schema-queries.ts +2 -2
  161. package/templates/starter/AGENTS.md +29 -28
  162. package/templates/starter/docs/toolcraft/README.md +6 -6
  163. package/templates/starter/docs/toolcraft/acceptance-testing.md +34 -48
  164. package/templates/starter/docs/toolcraft/agent-worklog.md +103 -1
  165. package/templates/starter/docs/toolcraft/assembly-workflow.md +16 -8
  166. package/templates/starter/docs/toolcraft/component-rules.md +9 -7
  167. package/templates/starter/docs/toolcraft/core/control-selection.md +9 -3
  168. package/templates/starter/docs/toolcraft/core/layout.md +13 -8
  169. package/templates/starter/docs/toolcraft/core/media-upload.md +3 -1
  170. package/templates/starter/docs/toolcraft/core/performance.md +8 -10
  171. package/templates/starter/docs/toolcraft/core/reference-study.md +80 -19
  172. package/templates/starter/docs/toolcraft/core/runtime-boundary.md +15 -3
  173. package/templates/starter/docs/toolcraft/core/setup-export.md +67 -11
  174. package/templates/starter/docs/toolcraft/custom-controls.md +6 -4
  175. package/templates/starter/docs/toolcraft/decision-contract.md +4 -2
  176. package/templates/starter/docs/toolcraft/performance.md +8 -10
  177. package/templates/starter/docs/toolcraft/renderer-technique.md +6 -2
  178. package/templates/starter/docs/toolcraft/schema-reference.md +24 -22
  179. package/templates/starter/docs/toolcraft/workflow.md +14 -14
  180. package/templates/starter/e2e/app-browser-control-applicability-requirements.spec.ts +163 -0
  181. package/templates/starter/e2e/app-browser-infinity-canvas-evidence.spec.ts +45 -2
  182. package/templates/starter/e2e/app-browser-motion-reference-requirements.spec.ts +411 -0
  183. package/templates/starter/e2e/app-browser-orientation-evidence.spec.ts +174 -21
  184. package/templates/starter/e2e/app-browser-proof-session.spec.ts +85 -0
  185. package/templates/starter/e2e/app-browser-runtime-requirements.spec.ts +63 -33
  186. package/templates/starter/e2e/app-browser-selection-scope-evidence.spec.ts +137 -0
  187. package/templates/starter/e2e/app-browser-semantic-evidence.spec.ts +61 -15
  188. package/templates/starter/e2e/{browser-conditional-output-evidence-helpers.ts → browser-background-output-evidence.ts} +0 -68
  189. package/templates/starter/e2e/browser-control-applicability-evidence.ts +114 -0
  190. package/templates/starter/e2e/browser-infinity-canvas-evidence.ts +20 -11
  191. package/templates/starter/e2e/browser-infinity-canvas-svg-evidence.ts +42 -0
  192. package/templates/starter/e2e/browser-layer-evidence-helpers.ts +15 -36
  193. package/templates/starter/e2e/browser-orientation-gizmo-evidence-helpers.ts +4 -0
  194. package/templates/starter/e2e/browser-orientation-gizmo-live-preconditions.ts +86 -0
  195. package/templates/starter/e2e/browser-product-raster-snapshot.ts +213 -0
  196. package/templates/starter/e2e/browser-proof-session.ts +43 -15
  197. package/templates/starter/e2e/browser-proof-surface-action.ts +79 -0
  198. package/templates/starter/e2e/browser-proof-types.ts +15 -0
  199. package/templates/starter/e2e/browser-runtime-applicability-requirements.ts +84 -0
  200. package/templates/starter/e2e/browser-runtime-evidence-reporter.ts +9 -2
  201. package/templates/starter/e2e/browser-runtime-evidence-requirements.ts +51 -32
  202. package/templates/starter/e2e/browser-selection-scope-evidence.ts +269 -0
  203. package/templates/starter/e2e/browser-semantic-evidence-test-helpers.ts +122 -0
  204. package/templates/starter/e2e/browser-svg-export-evidence.spec.ts +79 -0
  205. package/templates/starter/e2e/browser-svg-export-evidence.ts +152 -0
  206. package/templates/starter/e2e/export-artifact-helpers.ts +70 -0
  207. package/templates/starter/e2e/product-observable-helpers.ts +8 -129
  208. package/templates/starter/e2e/svg-artifact-inspection.spec.ts +136 -0
  209. package/templates/starter/e2e/svg-artifact-inspection.ts +331 -0
  210. package/templates/starter/e2e/svg-download-test-fixtures.ts +34 -0
  211. package/templates/starter/e2e/toolcraft-delivery-catalog-reporter.ts +198 -15
  212. package/templates/starter/e2e/toolcraft-feature-verification-reporter.spec.ts +149 -0
  213. package/templates/starter/e2e/toolcraft-feature-verification-reporter.ts +223 -0
  214. package/templates/starter/package.json +2 -0
  215. package/templates/starter/scripts/check-toolcraft-docs.mjs +1 -0
  216. package/templates/starter/scripts/create-toolcraft-motion-reference-study.mjs +233 -0
  217. package/templates/starter/scripts/create-toolcraft-motion-reference-study.test.mjs +459 -0
  218. package/templates/starter/scripts/playwright-test-title-selection.d.mts +45 -0
  219. package/templates/starter/scripts/run-browser-performance-test-helpers.mjs +0 -27
  220. package/templates/starter/scripts/run-browser-performance.mjs +0 -6
  221. package/templates/starter/scripts/run-browser-performance.test.mjs +5 -13
  222. package/templates/starter/scripts/run-delivery-verification-test-helpers.mjs +0 -34
  223. package/templates/starter/scripts/run-delivery-verification.test.mjs +135 -31
  224. package/templates/starter/scripts/run-feature-verification.mjs +212 -0
  225. package/templates/starter/scripts/run-feature-verification.test.mjs +226 -0
  226. package/templates/starter/scripts/toolcraft-checkpoint-delivery-state.mjs +21 -8
  227. package/templates/starter/scripts/toolcraft-checkpoint-delivery-state.test.mjs +32 -92
  228. package/templates/starter/scripts/toolcraft-checkpoint-transaction.mjs +28 -6
  229. package/templates/starter/scripts/toolcraft-checkpoint-transaction.test.mjs +8 -63
  230. package/templates/starter/scripts/toolcraft-contract-manifest.json +1 -0
  231. package/templates/starter/scripts/toolcraft-delivery-anchor.mjs +28 -8
  232. package/templates/starter/scripts/toolcraft-delivery-anchor.test.mjs +50 -61
  233. package/templates/starter/scripts/toolcraft-delivery-architecture-inventory.mjs +0 -4
  234. package/templates/starter/scripts/toolcraft-delivery-architecture-policy.mjs +0 -1
  235. package/templates/starter/scripts/toolcraft-delivery-evidence.test.mjs +2 -3
  236. package/templates/starter/scripts/toolcraft-delivery-executor.mjs +5 -1
  237. package/templates/starter/scripts/toolcraft-delivery-executor.test.mjs +5 -12
  238. package/templates/starter/scripts/toolcraft-delivery-functional-context.d.mts +1 -48
  239. package/templates/starter/scripts/toolcraft-delivery-functional-context.mjs +2 -30
  240. package/templates/starter/scripts/toolcraft-delivery-functional-context.test.mjs +4 -166
  241. package/templates/starter/scripts/toolcraft-delivery-functional-initial.test.mjs +4 -20
  242. package/templates/starter/scripts/toolcraft-delivery-lifecycle.mjs +43 -192
  243. package/templates/starter/scripts/toolcraft-delivery-performance-iteration-lifecycle.test.mjs +79 -440
  244. package/templates/starter/scripts/toolcraft-delivery-plan-authority.test.mjs +102 -297
  245. package/templates/starter/scripts/toolcraft-delivery-plan-construction.mjs +46 -97
  246. package/templates/starter/scripts/toolcraft-delivery-plan-test-helpers.mjs +125 -0
  247. package/templates/starter/scripts/toolcraft-delivery-plan-validation.test.mjs +58 -0
  248. package/templates/starter/scripts/toolcraft-delivery-plan.d.mts +19 -31
  249. package/templates/starter/scripts/toolcraft-delivery-plan.mjs +254 -252
  250. package/templates/starter/scripts/toolcraft-delivery-plan.test.mjs +29 -457
  251. package/templates/starter/scripts/toolcraft-delivery-receipt-performance.test.mjs +1 -1
  252. package/templates/starter/scripts/toolcraft-delivery-receipt-strictness.test.mjs +3 -72
  253. package/templates/starter/scripts/toolcraft-delivery-receipt-test-helpers.mjs +7 -36
  254. package/templates/starter/scripts/toolcraft-delivery-receipt.d.mts +3 -5
  255. package/templates/starter/scripts/toolcraft-delivery-receipt.mjs +15 -31
  256. package/templates/starter/scripts/toolcraft-delivery-receipt.test.mjs +28 -20
  257. package/templates/starter/scripts/toolcraft-delivery-receipt.types.test.mts +22 -30
  258. package/templates/starter/scripts/toolcraft-feature-verification-plan.d.mts +20 -0
  259. package/templates/starter/scripts/toolcraft-feature-verification-plan.mjs +146 -0
  260. package/templates/starter/scripts/toolcraft-feature-verification-plan.test.mjs +96 -0
  261. package/templates/starter/scripts/toolcraft-functional-proof-model.d.mts +3 -18
  262. package/templates/starter/scripts/toolcraft-functional-proof-model.mjs +39 -127
  263. package/templates/starter/scripts/toolcraft-functional-proof-model.test.mjs +25 -362
  264. package/templates/starter/scripts/toolcraft-functional-proof-model.types.test.mts +6 -83
  265. package/templates/starter/scripts/toolcraft-functional-proof-primitives.d.mts +11 -0
  266. package/templates/starter/scripts/toolcraft-functional-proof-primitives.mjs +61 -0
  267. package/templates/starter/scripts/toolcraft-functional-proof-primitives.test.mjs +43 -0
  268. package/templates/starter/scripts/toolcraft-integrity-policy.mjs +13 -0
  269. package/templates/starter/scripts/toolcraft-integrity-test-utils.mjs +1 -1
  270. package/templates/starter/scripts/toolcraft-layer-evidence-facade.test.mjs +58 -22
  271. package/templates/starter/scripts/toolcraft-motion-reference-analysis-protocol.mjs +111 -0
  272. package/templates/starter/scripts/toolcraft-motion-reference-analysis-protocol.test.mjs +116 -0
  273. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.d.mts +37 -0
  274. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.mjs +308 -0
  275. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.test.mjs +420 -0
  276. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.types.test.mts +50 -0
  277. package/templates/starter/scripts/toolcraft-motion-reference-command-options.mjs +195 -0
  278. package/templates/starter/scripts/toolcraft-motion-reference-command-options.test.mjs +224 -0
  279. package/templates/starter/scripts/toolcraft-motion-reference-contact-sheet.mjs +122 -0
  280. package/templates/starter/scripts/toolcraft-motion-reference-contact-sheet.test.mjs +153 -0
  281. package/templates/starter/scripts/toolcraft-motion-reference-evidence-assembly.mjs +270 -0
  282. package/templates/starter/scripts/toolcraft-motion-reference-evidence.test.mjs +432 -0
  283. package/templates/starter/scripts/toolcraft-motion-reference-ffmpeg-output.mjs +275 -0
  284. package/templates/starter/scripts/toolcraft-motion-reference-ffmpeg-output.test.mjs +294 -0
  285. package/templates/starter/scripts/toolcraft-motion-reference-group-inventory.mjs +148 -0
  286. package/templates/starter/scripts/toolcraft-motion-reference-image-filter-graph.mjs +101 -0
  287. package/templates/starter/scripts/toolcraft-motion-reference-image-filter-graph.test.mjs +124 -0
  288. package/templates/starter/scripts/toolcraft-motion-reference-image-source.mjs +259 -0
  289. package/templates/starter/scripts/toolcraft-motion-reference-image-source.test.mjs +338 -0
  290. package/templates/starter/scripts/toolcraft-motion-reference-image-timing.mjs +96 -0
  291. package/templates/starter/scripts/toolcraft-motion-reference-image-timing.test.mjs +81 -0
  292. package/templates/starter/scripts/toolcraft-motion-reference-lock-recovery.test.mjs +144 -0
  293. package/templates/starter/scripts/toolcraft-motion-reference-media-source.mjs +165 -0
  294. package/templates/starter/scripts/toolcraft-motion-reference-media-source.test.mjs +299 -0
  295. package/templates/starter/scripts/toolcraft-motion-reference-publication-discovery.test.mjs +142 -0
  296. package/templates/starter/scripts/toolcraft-motion-reference-publication-isolation.test.mjs +234 -0
  297. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-schema.mjs +122 -0
  298. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-store.mjs +89 -0
  299. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-store.test.mjs +74 -0
  300. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal.mjs +264 -0
  301. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal.test.mjs +377 -0
  302. package/templates/starter/scripts/toolcraft-motion-reference-publication-lease.mjs +254 -0
  303. package/templates/starter/scripts/toolcraft-motion-reference-publication-lease.test.mjs +130 -0
  304. package/templates/starter/scripts/toolcraft-motion-reference-publication-staging.mjs +128 -0
  305. package/templates/starter/scripts/toolcraft-motion-reference-publication-staging.test.mjs +209 -0
  306. package/templates/starter/scripts/toolcraft-motion-reference-publication.fixtures.mjs +88 -0
  307. package/templates/starter/scripts/toolcraft-motion-reference-publication.mjs +249 -0
  308. package/templates/starter/scripts/toolcraft-motion-reference-publication.test.mjs +433 -0
  309. package/templates/starter/scripts/toolcraft-motion-reference-review-output.mjs +38 -0
  310. package/templates/starter/scripts/toolcraft-motion-reference-review-output.test.mjs +29 -0
  311. package/templates/starter/scripts/toolcraft-motion-reference-root-safety.test.mjs +84 -0
  312. package/templates/starter/scripts/toolcraft-motion-reference-roots.mjs +83 -0
  313. package/templates/starter/scripts/toolcraft-motion-reference-sampling.mjs +283 -0
  314. package/templates/starter/scripts/toolcraft-motion-reference-sampling.test.mjs +480 -0
  315. package/templates/starter/scripts/toolcraft-motion-reference-stage-registry.mjs +39 -0
  316. package/templates/starter/scripts/toolcraft-motion-reference-stage-registry.test.mjs +59 -0
  317. package/templates/starter/scripts/toolcraft-motion-reference-stage.mjs +71 -0
  318. package/templates/starter/scripts/toolcraft-motion-reference-stage.test.mjs +61 -0
  319. package/templates/starter/scripts/toolcraft-motion-review-numeric.mjs +74 -0
  320. package/templates/starter/scripts/toolcraft-motion-review-numeric.test.mjs +65 -0
  321. package/templates/starter/scripts/toolcraft-motion-review-partitioning.mjs +268 -0
  322. package/templates/starter/scripts/toolcraft-motion-review-partitioning.test.mjs +329 -0
  323. package/templates/starter/scripts/toolcraft-motion-review-protected-units.mjs +120 -0
  324. package/templates/starter/scripts/toolcraft-motion-review-protected-units.test.mjs +111 -0
  325. package/templates/starter/scripts/toolcraft-performance-escalation-policy.test.mjs +77 -345
  326. package/templates/starter/scripts/toolcraft-performance-receipt-validation.test.mjs +19 -21
  327. package/templates/starter/scripts/toolcraft-product-boundary-ast.mjs +85 -115
  328. package/templates/starter/scripts/toolcraft-product-boundary-module-policy.mjs +101 -0
  329. package/templates/starter/scripts/toolcraft-product-boundary.test.mjs +0 -72
  330. package/templates/starter/scripts/toolcraft-product-control-bindings.mjs +182 -0
  331. package/templates/starter/scripts/toolcraft-product-control-boundary.mjs +146 -0
  332. package/templates/starter/scripts/toolcraft-product-control-boundary.test.mjs +186 -0
  333. package/templates/starter/scripts/toolcraft-product-export-boundary.mjs +16 -18
  334. package/templates/starter/scripts/toolcraft-product-export-boundary.test.mjs +200 -0
  335. package/templates/starter/scripts/toolcraft-product-observable-facade.test.mjs +46 -1
  336. package/templates/starter/scripts/toolcraft-receipt-boundary.test.mjs +0 -1
  337. package/templates/starter/scripts/toolcraft-source-inventory.d.mts +5 -0
  338. package/templates/starter/scripts/toolcraft-source-inventory.mjs +25 -14
  339. package/templates/starter/scripts/toolcraft-source-inventory.test.mjs +48 -0
  340. package/templates/starter/scripts/toolcraft-source-ownership.mjs +0 -1
  341. package/templates/starter/scripts/toolcraft-source-ownership.test.mjs +30 -5
  342. package/templates/starter/scripts/toolcraft-typescript-source-evidence-structure.test.mjs +20 -0
  343. package/templates/starter/scripts/toolcraft-typescript-source-evidence.mjs +1 -0
  344. package/templates/starter/scripts/toolcraft-unavailable-resource-evidence-facade.test.mjs +2 -0
  345. package/templates/starter/scripts/toolcraft-verification-receipt-test-helpers.mjs +5 -26
  346. package/templates/starter/scripts/toolcraft-verification-receipt.d.mts +0 -7
  347. package/templates/starter/scripts/toolcraft-verification-receipt.mjs +3 -47
  348. package/templates/starter/scripts/toolcraft-verification-receipt.test.mjs +6 -87
  349. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.d.mts +19 -0
  350. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.mjs +107 -0
  351. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.test.mjs +114 -0
  352. package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.mjs +13 -2
  353. package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.test.mjs +110 -0
  354. package/templates/starter/src/app/acceptance/artifact-export-intent.ts +161 -0
  355. package/templates/starter/src/app/acceptance/canvas-coverage.ts +1 -0
  356. package/templates/starter/src/app/acceptance/color-bank-labels.ts +11 -15
  357. package/templates/starter/src/app/acceptance/color-row-grouping.ts +33 -0
  358. package/templates/starter/src/app/acceptance/conditions.ts +1 -1
  359. package/templates/starter/src/app/acceptance/control-acceptance-context.ts +2 -2
  360. package/templates/starter/src/app/acceptance/control-acceptance-coverage.ts +6 -31
  361. package/templates/starter/src/app/acceptance/control-acceptance-kind-rules.ts +24 -5
  362. package/templates/starter/src/app/acceptance/control-acceptance-policy.ts +4 -16
  363. package/templates/starter/src/app/acceptance/control-applicability-cases.test.ts +321 -0
  364. package/templates/starter/src/app/acceptance/control-applicability-cases.ts +290 -0
  365. package/templates/starter/src/app/acceptance/control-applicability.ts +332 -0
  366. package/templates/starter/src/app/acceptance/control-component-rules.ts +0 -10
  367. package/templates/starter/src/app/acceptance/control-labels.ts +30 -1
  368. package/templates/starter/src/app/acceptance/control-layout-dependency-rules.ts +20 -9
  369. package/templates/starter/src/app/acceptance/control-layout-entity-rules.ts +4 -6
  370. package/templates/starter/src/app/acceptance/control-layout-model.ts +4 -4
  371. package/templates/starter/src/app/acceptance/control-layout-section-rules.ts +21 -10
  372. package/templates/starter/src/app/acceptance/control-parts.ts +8 -0
  373. package/templates/starter/src/app/acceptance/control-section-entity-cohesion.test.ts +215 -0
  374. package/templates/starter/src/app/acceptance/control-section-entity-cohesion.ts +132 -0
  375. package/templates/starter/src/app/acceptance/control-section-inventory.test.ts +87 -0
  376. package/templates/starter/src/app/acceptance/control-section-inventory.ts +74 -44
  377. package/templates/starter/src/app/acceptance/custom-controls.ts +11 -3
  378. package/templates/starter/src/app/acceptance/export-artifact-coverage.ts +25 -17
  379. package/templates/starter/src/app/acceptance/feature-verification-selection.test.ts +295 -0
  380. package/templates/starter/src/app/acceptance/feature-verification-selection.ts +161 -0
  381. package/templates/starter/src/app/acceptance/infinity-canvas.ts +10 -0
  382. package/templates/starter/src/app/acceptance/inline-layout.ts +64 -9
  383. package/templates/starter/src/app/acceptance/interaction-ownership-intent.ts +19 -1
  384. package/templates/starter/src/app/acceptance/interaction-ownership.ts +18 -2
  385. package/templates/starter/src/app/acceptance/media-upload.ts +5 -1
  386. package/templates/starter/src/app/acceptance/motion-reference-evidence-validation.mjs +65 -0
  387. package/templates/starter/src/app/acceptance/motion-reference-evidence-windows.mjs +301 -0
  388. package/templates/starter/src/app/acceptance/motion-reference-evidence.d.mts +11 -0
  389. package/templates/starter/src/app/acceptance/motion-reference-evidence.mjs +145 -0
  390. package/templates/starter/src/app/acceptance/motion-reference-study-behaviors.ts +162 -0
  391. package/templates/starter/src/app/acceptance/motion-reference-study-coverage.ts +206 -0
  392. package/templates/starter/src/app/acceptance/motion-reference-study-identity.ts +129 -0
  393. package/templates/starter/src/app/acceptance/motion-reference-study-partitions.ts +186 -0
  394. package/templates/starter/src/app/acceptance/motion-reference-study.ts +90 -0
  395. package/templates/starter/src/app/acceptance/orientation-gizmo.ts +18 -11
  396. package/templates/starter/src/app/acceptance/output-background-rules.ts +2 -2
  397. package/templates/starter/src/app/acceptance/output-export-actions.test.ts +9 -1
  398. package/templates/starter/src/app/acceptance/output-export-actions.ts +14 -22
  399. package/templates/starter/src/app/acceptance/output-export-layout-rules.ts +22 -10
  400. package/templates/starter/src/app/acceptance/output-export-model.ts +58 -11
  401. package/templates/starter/src/app/acceptance/output-export.ts +25 -10
  402. package/templates/starter/src/app/acceptance/output-video-export-rules.ts +99 -0
  403. package/templates/starter/src/app/acceptance/reference-study-types.ts +167 -17
  404. package/templates/starter/src/app/acceptance/runtime-coverage.ts +6 -1
  405. package/templates/starter/src/app/acceptance/selection-scope.test.ts +200 -0
  406. package/templates/starter/src/app/acceptance/selection-scope.ts +151 -0
  407. package/templates/starter/src/app/acceptance/transfer-mode-types.ts +114 -0
  408. package/templates/starter/src/app/acceptance/types.ts +65 -125
  409. package/templates/starter/src/app/acceptance/validate-coverage.ts +33 -5
  410. package/templates/starter/src/app/starter-acceptance-data.ts +1 -0
  411. package/templates/starter/src/app/starter-acceptance.animation-intent.test.ts +3 -0
  412. package/templates/starter/src/app/starter-acceptance.artifact-export-intent.test.ts +312 -0
  413. package/templates/starter/src/app/starter-acceptance.background-export.test.ts +35 -0
  414. package/templates/starter/src/app/starter-acceptance.canvas-sizing.test.ts +18 -1
  415. package/templates/starter/src/app/starter-acceptance.color-row-grouping.test.ts +118 -0
  416. package/templates/starter/src/app/starter-acceptance.compound-part-coverage.test.ts +66 -1
  417. package/templates/starter/src/app/starter-acceptance.contract-fixtures.test.ts +41 -0
  418. package/templates/starter/src/app/starter-acceptance.contract-fixtures.ts +113 -16
  419. package/templates/starter/src/app/starter-acceptance.control-applicability.test.ts +225 -0
  420. package/templates/starter/src/app/starter-acceptance.control-label-context.test.ts +1 -0
  421. package/templates/starter/src/app/starter-acceptance.control-labels.test.ts +78 -3
  422. package/templates/starter/src/app/starter-acceptance.control-naming-rules.test.ts +77 -1
  423. package/templates/starter/src/app/starter-acceptance.control-order.test.ts +58 -3
  424. package/templates/starter/src/app/starter-acceptance.control-state.test.ts +0 -111
  425. package/templates/starter/src/app/starter-acceptance.custom-control-collections.test.ts +3 -1
  426. package/templates/starter/src/app/starter-acceptance.custom-control-fit-check.test.ts +1 -1
  427. package/templates/starter/src/app/starter-acceptance.custom-control-valid.test.ts +1 -1
  428. package/templates/starter/src/app/starter-acceptance.export-artifact.test.ts +74 -3
  429. package/templates/starter/src/app/starter-acceptance.export-test-utils.ts +26 -0
  430. package/templates/starter/src/app/{starter-acceptance.image-video-export-settings.test.ts → starter-acceptance.image-export-settings.test.ts} +39 -9
  431. package/templates/starter/src/app/starter-acceptance.interaction-ownership.test.ts +31 -3
  432. package/templates/starter/src/app/starter-acceptance.layers.test.ts +2 -1
  433. package/templates/starter/src/app/starter-acceptance.media-upload.fixtures.ts +11 -1
  434. package/templates/starter/src/app/starter-acceptance.media-upload.test.ts +56 -0
  435. package/templates/starter/src/app/starter-acceptance.motion-reference-evidence.test.ts +17 -0
  436. package/templates/starter/src/app/starter-acceptance.motion-reference-identity.test.ts +163 -0
  437. package/templates/starter/src/app/starter-acceptance.motion-reference-mapping.test.ts +133 -0
  438. package/templates/starter/src/app/starter-acceptance.motion-reference-ownership.test.ts +121 -0
  439. package/templates/starter/src/app/starter-acceptance.motion-reference-partitions.test.ts +210 -0
  440. package/templates/starter/src/app/starter-acceptance.motion-reference-test-utils.ts +313 -0
  441. package/templates/starter/src/app/starter-acceptance.output-export-intent.test.ts +458 -0
  442. package/templates/starter/src/app/starter-acceptance.output-export-rules.test.ts +4 -0
  443. package/templates/starter/src/app/starter-acceptance.product-output-export.test.ts +116 -104
  444. package/templates/starter/src/app/starter-acceptance.product-readiness.test.ts +29 -0
  445. package/templates/starter/src/app/starter-acceptance.product-worklog.test.ts +123 -2
  446. package/templates/starter/src/app/starter-acceptance.reference-custom-timeline.test.ts +2 -0
  447. package/templates/starter/src/app/starter-acceptance.reference-foundation.test.ts +8 -0
  448. package/templates/starter/src/app/starter-acceptance.reference-timeline.test.ts +7 -0
  449. package/templates/starter/src/app/starter-acceptance.section-cohesion.test.ts +3 -1
  450. package/templates/starter/src/app/starter-acceptance.section-dependencies.test.ts +35 -24
  451. package/templates/starter/src/app/starter-acceptance.section-size.test.ts +72 -0
  452. package/templates/starter/src/app/starter-acceptance.timeline-playback.test.ts +5 -0
  453. package/templates/starter/src/app/starter-acceptance.ts +45 -10
  454. package/templates/starter/src/app/starter-acceptance.video-export-settings.test.ts +338 -0
  455. package/templates/starter/src/app/starter-acceptance.video-reference-study.test.ts +34 -236
  456. package/templates/starter/src/app/starter-acceptance.view-interaction.test.ts +12 -0
  457. package/templates/starter/src/app/starter-acceptance.worklog-test-utils.ts +122 -6
  458. package/templates/starter/src/app/starter-acceptance.worklog.test.ts +152 -16
  459. package/templates/starter/src/app/starter-performance.gates.test.ts +20 -18
  460. package/templates/starter/src/app/starter-performance.lifecycle.test.ts +22 -6
  461. package/templates/starter/src/app/test-evidence/browser-runtime-contract.ts +5 -2
  462. package/templates/starter/src/routes/index.tsx +1 -0
  463. package/templates/starter/tsconfig.json +1 -0
  464. package/templates/ui/components/composites/tabs.tsx +2 -2
  465. package/templates/ui/components/controls/collection-actions/collection-item-groups.test.tsx +38 -0
  466. package/templates/ui/components/controls/collection-actions/collection-item-groups.tsx +36 -0
  467. package/templates/ui/components/controls/collection-actions/index.ts +2 -0
  468. package/templates/ui/components/controls/file-drop/file-drop-collection-control.tsx +137 -0
  469. package/templates/ui/components/controls/file-drop/file-drop-control.test.tsx +189 -0
  470. package/templates/ui/components/controls/file-drop/file-drop-control.tsx +81 -88
  471. package/templates/ui/components/controls/file-drop/file-drop-presentation.tsx +131 -9
  472. package/templates/ui/components/controls/file-drop/file-drop-types.ts +36 -22
  473. package/templates/ui/components/controls/file-drop/index.ts +1 -0
  474. package/templates/ui/components/controls/index.ts +3 -0
  475. package/templates/ui/components/controls/range-slider/range-slider-control.tsx +1 -1
  476. package/templates/ui/components/controls/range-slider/range-slider-value.test.ts +14 -0
  477. package/templates/ui/components/controls/range-slider/range-slider-value.ts +3 -2
  478. package/templates/starter/scripts/toolcraft-browser-impact-selection.mjs +0 -26
  479. package/templates/starter/scripts/toolcraft-delivery-framework-refresh.test.mjs +0 -141
  480. package/templates/starter/scripts/toolcraft-delivery-functional-changed.test.mjs +0 -468
  481. package/templates/starter/scripts/toolcraft-delivery-functional-model-lifecycle.test.mjs +0 -254
  482. package/templates/starter/scripts/toolcraft-delivery-functional-semantic-regression.test.mjs +0 -135
  483. package/templates/starter/scripts/toolcraft-delivery-performance-iteration-durability.test.mjs +0 -329
  484. package/templates/starter/scripts/toolcraft-delivery-plan-errors.test.mjs +0 -430
  485. package/templates/starter/scripts/toolcraft-delivery-plan-functional-model.test.mjs +0 -358
  486. package/templates/starter/scripts/toolcraft-functional-proof-regression-fixtures.mjs +0 -298
  487. package/templates/starter/scripts/toolcraft-verification-impact-inventory.d.mts +0 -62
  488. package/templates/starter/scripts/toolcraft-verification-impact-inventory.mjs +0 -344
  489. package/templates/starter/scripts/toolcraft-verification-impact-inventory.test.mjs +0 -204
  490. package/templates/starter/scripts/toolcraft-verification-impact-performance-candidates.test.mjs +0 -210
  491. package/templates/starter/scripts/toolcraft-verification-impact-resolution.mjs +0 -344
  492. package/templates/starter/scripts/toolcraft-verification-impact-resolution.test.mjs +0 -270
  493. package/templates/starter/scripts/toolcraft-verification-impact-semantic-resolution.test.mjs +0 -449
  494. package/templates/starter/scripts/toolcraft-verification-impact-support-resolution.test.mjs +0 -195
  495. package/templates/starter/scripts/toolcraft-verification-impact.d.mts +0 -132
  496. package/templates/starter/scripts/toolcraft-verification-impact.mjs +0 -169
  497. package/templates/starter/scripts/toolcraft-verification-impact.test.mjs +0 -300
  498. package/templates/starter/scripts/toolcraft-verification-input-roles.mjs +0 -197
  499. package/templates/starter/scripts/toolcraft-verification-input-roles.test.mjs +0 -225
  500. package/templates/starter/src/app/acceptance/condition-exclusivity.test.ts +0 -60
  501. package/templates/starter/src/app/acceptance/condition-exclusivity.ts +0 -221
  502. package/templates/starter/src/app/acceptance/video-reference-study.ts +0 -217
  503. package/templates/starter/src/app/starter-verification-impact.json +0 -15
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
 
3
+ import type { ToolcraftCollectionItemControlType } from "./collection-item-controls";
3
4
  import { defineToolcraft } from "./define-toolcraft";
4
5
  import type { ToolcraftControlSchema } from "./types";
5
6
 
@@ -39,8 +40,9 @@ function createModeControl(
39
40
  }
40
41
 
41
42
  function createCollectionModeControl(
42
- type: string,
43
+ type: ToolcraftCollectionItemControlType,
43
44
  labels: readonly string[],
45
+ parentType = "collectionActions",
44
46
  ): ToolcraftControlSchema {
45
47
  return {
46
48
  defaultValue: ["default"],
@@ -57,7 +59,7 @@ function createCollectionModeControl(
57
59
  label: "Modes",
58
60
  minItems: 1,
59
61
  target: "appearance.modes",
60
- type: "collectionActions",
62
+ type: parentType,
61
63
  };
62
64
  }
63
65
 
@@ -138,6 +140,22 @@ describe("defineToolcraft segmented control fit", () => {
138
140
  expect(control).toEqual(inputSnapshot);
139
141
  });
140
142
 
143
+ it("applies segmented item fit validation to sourceCollection", () => {
144
+ expect(() =>
145
+ defineToolcraft(
146
+ createAppSchema(
147
+ createCollectionModeControl(
148
+ "segmented",
149
+ SCREENSHOT_LABELS,
150
+ "sourceCollection",
151
+ ),
152
+ ),
153
+ ),
154
+ ).toThrow(
155
+ /Toolcraft control validation \[segmented-control-fit\] for target "appearance\.modes" itemControl: .*select dropdown/u,
156
+ );
157
+ });
158
+
141
159
  it.each(["type", "target"] as const)(
142
160
  "preserves required %s validation ownership",
143
161
  (fieldName) => {
@@ -32,6 +32,7 @@ describe("defineToolcraft runtime setup canvas controls", () => {
32
32
 
33
33
  expect(canvasSection?.title).toBe("Setup");
34
34
  expect(canvasSection?.controls.infinityCanvas).toMatchObject({
35
+ applicability: { mode: "always", origin: "explicit" },
35
36
  defaultValue: false,
36
37
  label: "Infinity canvas",
37
38
  target: "canvas.infinity",
@@ -52,7 +53,11 @@ describe("defineToolcraft runtime setup canvas controls", () => {
52
53
  performanceRole: "workload",
53
54
  target: "canvas.aspectRatio",
54
55
  type: "aspectRatio",
55
- visibleWhen: { equals: false, target: "canvas.infinity" },
56
+ applicability: {
57
+ all: [{ equals: false, target: "canvas.infinity" }],
58
+ mode: "conditional",
59
+ origin: "explicit",
60
+ },
56
61
  });
57
62
  expect(canvasSection?.controls.canvasWidth).toMatchObject({
58
63
  defaultValue: 1440,
@@ -60,7 +65,11 @@ describe("defineToolcraft runtime setup canvas controls", () => {
60
65
  performanceRole: "workload",
61
66
  target: "canvas.size.width",
62
67
  type: "text",
63
- visibleWhen: { equals: false, target: "canvas.infinity" },
68
+ applicability: {
69
+ all: [{ equals: false, target: "canvas.infinity" }],
70
+ mode: "conditional",
71
+ origin: "explicit",
72
+ },
64
73
  });
65
74
  expect(canvasSection?.controls.canvasHeight).toMatchObject({
66
75
  defaultValue: 900,
@@ -68,7 +77,11 @@ describe("defineToolcraft runtime setup canvas controls", () => {
68
77
  performanceRole: "workload",
69
78
  target: "canvas.size.height",
70
79
  type: "text",
71
- visibleWhen: { equals: false, target: "canvas.infinity" },
80
+ applicability: {
81
+ all: [{ equals: false, target: "canvas.infinity" }],
82
+ mode: "conditional",
83
+ origin: "explicit",
84
+ },
72
85
  });
73
86
  expect(canvasSection?.layoutGroups).toEqual([
74
87
  {
@@ -0,0 +1,79 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { defineToolcraft } from "./define-toolcraft";
4
+ import type { ToolcraftControlSchema } from "./types";
5
+
6
+ function createAppSchema(control: ToolcraftControlSchema) {
7
+ return {
8
+ canvas: { enabled: false },
9
+ panels: {
10
+ controls: {
11
+ sections: [
12
+ {
13
+ controls: { sections: control },
14
+ title: "Fill Sections",
15
+ },
16
+ ],
17
+ title: "Controls",
18
+ },
19
+ },
20
+ };
21
+ }
22
+
23
+ function createSourceCollection(
24
+ overrides: Record<string, unknown> = {},
25
+ ): ToolcraftControlSchema {
26
+ return {
27
+ defaultValue: [{ hex: "#DFFF1A" }],
28
+ itemControl: { label: false, type: "color" },
29
+ itemLabel: "Section",
30
+ label: "Sections",
31
+ target: "fills.sections",
32
+ type: "sourceCollection",
33
+ ...overrides,
34
+ } as ToolcraftControlSchema;
35
+ }
36
+
37
+ describe("defineToolcraft source collection", () => {
38
+ it("accepts a source-owned collection of built-in item controls", () => {
39
+ const app = defineToolcraft(createAppSchema(createSourceCollection()));
40
+ const control = app.panels.controls?.sections.find(
41
+ (section) => section.title === "Fill Sections",
42
+ )?.controls.sections;
43
+
44
+ expect(control?.type).toBe("sourceCollection");
45
+ expect(control?.itemControl?.type).toBe("color");
46
+ });
47
+
48
+ it("requires source collections to declare their built-in item control", () => {
49
+ expect(() =>
50
+ defineToolcraft(
51
+ createAppSchema(createSourceCollection({ itemControl: undefined })),
52
+ ),
53
+ ).toThrow(
54
+ /Toolcraft control validation \[source-collection-item-control\] for target "fills\.sections": itemControl is required/u,
55
+ );
56
+ });
57
+
58
+ it("rejects unsupported collection item controls", () => {
59
+ const control = createSourceCollection({
60
+ itemControl: { type: "imaginary" },
61
+ });
62
+
63
+ expect(() => defineToolcraft(createAppSchema(control))).toThrow(
64
+ /Toolcraft control validation \[collection-item-control\] for target "fills\.sections": unsupported collection item control "imaginary"/u,
65
+ );
66
+ });
67
+
68
+ it("rejects unsupported collectionActions item controls instead of falling back to text", () => {
69
+ const control = {
70
+ ...createSourceCollection(),
71
+ itemControl: { type: "imaginary" },
72
+ type: "collectionActions",
73
+ } as unknown as ToolcraftControlSchema;
74
+
75
+ expect(() => defineToolcraft(createAppSchema(control))).toThrow(
76
+ /Toolcraft control validation \[collection-item-control\] for target "fills\.sections": unsupported collection item control "imaginary"/u,
77
+ );
78
+ });
79
+ });
@@ -38,6 +38,11 @@ const finiteCanvasCondition = Object.freeze({
38
38
  equals: false,
39
39
  target: toolcraftCanvasInfinityTarget,
40
40
  });
41
+ const alwaysApplicable = Object.freeze({ mode: "always" as const });
42
+ const finiteCanvasApplicability = Object.freeze({
43
+ all: [finiteCanvasCondition],
44
+ mode: "conditional" as const,
45
+ });
41
46
 
42
47
  type RuntimeSetupControlGroup = {
43
48
  controls: ToolcraftControlSectionSchema["controls"];
@@ -146,6 +151,7 @@ function createRenderScaleControl(
146
151
  }
147
152
 
148
153
  return {
154
+ applicability: alwaysApplicable,
149
155
  defaultValue: canvas.renderScale.defaultValue,
150
156
  description:
151
157
  "Increases raster canvas backing resolution without changing the visible output size.",
@@ -175,6 +181,7 @@ function createInfinityCanvasControl(
175
181
  }
176
182
 
177
183
  return {
184
+ applicability: alwaysApplicable,
178
185
  defaultValue: getToolcraftDefaultCanvasMode(canvas) === "infinite",
179
186
  ...(background
180
187
  ? {
@@ -199,6 +206,7 @@ function createTimelineExtendedControl(
199
206
  }
200
207
 
201
208
  return {
209
+ applicability: alwaysApplicable,
202
210
  defaultValue: false,
203
211
  label: "Timeline",
204
212
  target: toolcraftTimelinePanelExtendedTarget,
@@ -230,13 +238,23 @@ function createRuntimeSetupBackgroundControls({
230
238
  return {
231
239
  controls: {
232
240
  ...(includeBackgroundControl
233
- ? { includeBackground: includeBackgroundControl }
241
+ ? {
242
+ includeBackground: {
243
+ ...includeBackgroundControl,
244
+ applicability: alwaysApplicable,
245
+ },
246
+ }
234
247
  : {}),
235
248
  ...(infinityCanvasControl
236
249
  ? { infinityCanvas: infinityCanvasControl }
237
250
  : {}),
238
251
  ...(backgroundColorControl
239
- ? { background: backgroundColorControl }
252
+ ? {
253
+ background: {
254
+ ...backgroundColorControl,
255
+ applicability: alwaysApplicable,
256
+ },
257
+ }
240
258
  : {}),
241
259
  },
242
260
  layoutGroups:
@@ -262,6 +280,7 @@ function createFiniteCanvasControls(
262
280
  return {
263
281
  controls: {
264
282
  canvasAspectRatio: {
283
+ applicability: finiteCanvasApplicability,
265
284
  defaultValue: getCanvasAspectRatioDefaultValue(canvas.size),
266
285
  label: "Aspect ratio",
267
286
  orderRole: "input",
@@ -269,9 +288,9 @@ function createFiniteCanvasControls(
269
288
  performanceRole: "workload",
270
289
  target: canvasAspectRatioTarget,
271
290
  type: "aspectRatio",
272
- visibleWhen: finiteCanvasCondition,
273
291
  },
274
292
  canvasWidth: {
293
+ applicability: finiteCanvasApplicability,
275
294
  defaultValue: canvas.size.width,
276
295
  label: "Canvas width",
277
296
  orderRole: "input",
@@ -279,9 +298,9 @@ function createFiniteCanvasControls(
279
298
  performanceRole: "workload",
280
299
  target: canvasSizeControlTargets.width,
281
300
  type: "text",
282
- visibleWhen: finiteCanvasCondition,
283
301
  },
284
302
  canvasHeight: {
303
+ applicability: finiteCanvasApplicability,
285
304
  defaultValue: canvas.size.height,
286
305
  label: "Canvas height",
287
306
  orderRole: "input",
@@ -289,7 +308,6 @@ function createFiniteCanvasControls(
289
308
  performanceRole: "workload",
290
309
  target: canvasSizeControlTargets.height,
291
310
  type: "text",
292
- visibleWhen: finiteCanvasCondition,
293
311
  },
294
312
  },
295
313
  layoutGroups: [
@@ -325,6 +343,7 @@ export function createToolcraftRuntimeSetupSection({
325
343
  const section: ToolcraftControlSectionSchema & { id: string } = {
326
344
  controls: {
327
345
  settingsTransfer: {
346
+ applicability: alwaysApplicable,
328
347
  label: false,
329
348
  target: settingsTransferTarget,
330
349
  type: "settingsTransfer",
@@ -3,6 +3,7 @@ import type {
3
3
  ToolcraftControlLayoutGroupLayout,
4
4
  ToolcraftSectionLayout,
5
5
  } from "../contracts/types";
6
+ import type { ToolcraftCollectionItemControlType } from "./collection-item-controls";
6
7
 
7
8
  export type ToolcraftCanvasSize = {
8
9
  height: number;
@@ -276,6 +277,7 @@ export type ToolcraftActionRole =
276
277
  | "copy-output"
277
278
  | "download-output"
278
279
  | "export-image"
280
+ | "export-svg"
279
281
  | "export-video";
280
282
 
281
283
  export type ToolcraftActionSchema = {
@@ -412,7 +414,7 @@ export type ResolvedToolcraftMediaSchema = {
412
414
  defaultAssets: readonly ToolcraftDefaultMediaAssetSchema[];
413
415
  };
414
416
 
415
- export type ToolcraftControlConditionSchema = {
417
+ export type ToolcraftControlPredicateSchema = Readonly<{
416
418
  equals?: unknown;
417
419
  greaterThan?: number;
418
420
  greaterThanOrEqual?: number;
@@ -422,7 +424,28 @@ export type ToolcraftControlConditionSchema = {
422
424
  notEquals?: unknown;
423
425
  oneOf?: readonly unknown[];
424
426
  target: string;
425
- };
427
+ }>;
428
+
429
+ export type ToolcraftControlConditionSchema =
430
+ ToolcraftControlPredicateSchema;
431
+
432
+ export type ToolcraftControlApplicabilitySchema =
433
+ | Readonly<{ mode: "always" }>
434
+ | Readonly<{
435
+ all: readonly ToolcraftControlPredicateSchema[];
436
+ mode: "conditional";
437
+ }>;
438
+
439
+ export type ToolcraftResolvedControlApplicabilitySchema =
440
+ | Readonly<{
441
+ mode: "always";
442
+ origin: "explicit" | "implicit";
443
+ }>
444
+ | Readonly<{
445
+ all: readonly ToolcraftControlPredicateSchema[];
446
+ mode: "conditional";
447
+ origin: "explicit" | "legacy";
448
+ }>;
426
449
 
427
450
  export type ToolcraftControlDisabledConditionSchema =
428
451
  ToolcraftControlConditionSchema;
@@ -434,18 +457,29 @@ export type ToolcraftColorOpacityValueSchema = {
434
457
 
435
458
  export type ToolcraftCollectionItemControlSchema = {
436
459
  commitMode?: "content" | "setting";
460
+ coordinateMode?: ToolcraftVectorCoordinateMode;
437
461
  defaultValue?: unknown;
462
+ description?: string;
438
463
  label?: boolean | string;
439
464
  markerCount?: number;
440
465
  max?: number;
441
466
  min?: number;
442
467
  options?: readonly { label: string; value: string }[];
468
+ performanceReason?: string;
469
+ performanceRole?: ToolcraftControlPerformanceRole;
470
+ sliderValueKind?: ToolcraftSliderValueKind;
443
471
  step?: number;
444
- type: string;
472
+ type: ToolcraftCollectionItemControlType;
445
473
  unit?: string;
446
474
  variant?: string;
475
+ xLabel?: string;
476
+ yLabel?: string;
447
477
  };
448
478
 
479
+ export type ToolcraftCollectionItemControlsSchema = Readonly<
480
+ Record<string, ToolcraftCollectionItemControlSchema>
481
+ >;
482
+
449
483
  export type ToolcraftFontPickerValueSchema = {
450
484
  color?: string;
451
485
  fontId: string;
@@ -461,7 +495,7 @@ export type ToolcraftCurveInterpolation = "monotone" | "smooth";
461
495
 
462
496
  export type ToolcraftVectorCoordinateMode = "cartesian" | "screen";
463
497
 
464
- export type ToolcraftControlSchemaBase = {
498
+ type ToolcraftControlSchemaFields = {
465
499
  accept?: string;
466
500
  actions?: readonly (ToolcraftActionSchema | string)[];
467
501
  addLabel?: string;
@@ -476,6 +510,7 @@ export type ToolcraftControlSchemaBase = {
476
510
  interpolation?: ToolcraftCurveInterpolation;
477
511
  items?: readonly ToolcraftImagePickerItemSchema[];
478
512
  itemControl?: ToolcraftCollectionItemControlSchema;
513
+ itemControls?: ToolcraftCollectionItemControlsSchema;
479
514
  itemDefaultValue?: unknown;
480
515
  itemLabel?: string;
481
516
  keyframeable?: boolean;
@@ -498,11 +533,16 @@ export type ToolcraftControlSchemaBase = {
498
533
  unit?: string;
499
534
  valueLabel?: string;
500
535
  variant?: string;
501
- visibleWhen?: ToolcraftControlConditionSchema;
502
536
  xLabel?: string;
503
537
  yLabel?: string;
504
538
  };
505
539
 
540
+ export type ToolcraftControlSchemaBase = ToolcraftControlSchemaFields & {
541
+ applicability?: ToolcraftControlApplicabilitySchema;
542
+ /** @deprecated Product controls use conditional applicability. */
543
+ visibleWhen?: ToolcraftControlPredicateSchema;
544
+ };
545
+
506
546
  export type ToolcraftNonModelControlSchema = ToolcraftControlSchemaBase & {
507
547
  assetKind?: ToolcraftMediaAssetKind;
508
548
  modelFormats?: never;
@@ -525,18 +565,34 @@ export type ToolcraftControlSchema =
525
565
  | ToolcraftNonModelControlSchema
526
566
  | ToolcraftModelFileDropSchema;
527
567
 
568
+ type ToolcraftResolvedControlApplicabilityFields = Readonly<{
569
+ applicability: ToolcraftResolvedControlApplicabilitySchema;
570
+ }>;
571
+
572
+ export type ResolvedToolcraftNonModelControlSchema = Omit<
573
+ ToolcraftNonModelControlSchema,
574
+ "applicability" | "visibleWhen"
575
+ > &
576
+ ToolcraftResolvedControlApplicabilityFields;
577
+
528
578
  export type ResolvedToolcraftModelFileDropSchema = Omit<
529
579
  ToolcraftModelFileDropSchema,
530
- "modelFormats" | "modelLimits" | "multiple" | "topologyProfile"
531
- > & {
532
- modelFormats: readonly ToolcraftModelFormat[];
533
- modelLimits: ToolcraftModelImportLimits;
534
- multiple: false;
535
- topologyProfile: ToolcraftModelTopologyProfile;
536
- };
580
+ | "applicability"
581
+ | "modelFormats"
582
+ | "modelLimits"
583
+ | "multiple"
584
+ | "topologyProfile"
585
+ | "visibleWhen"
586
+ > &
587
+ ToolcraftResolvedControlApplicabilityFields & {
588
+ modelFormats: readonly ToolcraftModelFormat[];
589
+ modelLimits: ToolcraftModelImportLimits;
590
+ multiple: false;
591
+ topologyProfile: ToolcraftModelTopologyProfile;
592
+ };
537
593
 
538
594
  export type ResolvedToolcraftControlSchema =
539
- | ToolcraftNonModelControlSchema
595
+ | ResolvedToolcraftNonModelControlSchema
540
596
  | ResolvedToolcraftModelFileDropSchema;
541
597
 
542
598
  export type ToolcraftControlLayoutGroupSchema = {
@@ -5,21 +5,6 @@ import {
5
5
  import type { ResolvedToolcraftAppSchema } from "../schema/types";
6
6
  import type { ToolcraftState } from "./types";
7
7
 
8
- function getToolcraftColorHex(value: unknown): string | undefined {
9
- const candidate =
10
- typeof value === "string"
11
- ? value
12
- : value !== null &&
13
- typeof value === "object" &&
14
- "hex" in value &&
15
- typeof value.hex === "string"
16
- ? value.hex
17
- : undefined;
18
- const normalized = candidate?.trim();
19
-
20
- return normalized ? normalized : undefined;
21
- }
22
-
23
8
  export function hasToolcraftRuntimeSetupBackground(
24
9
  schema: ResolvedToolcraftAppSchema,
25
10
  ): boolean {
@@ -75,5 +60,5 @@ export function getToolcraftRuntimeBackgroundColor(
75
60
  ? state.values[background.color.target] ?? background.color.defaultValue
76
61
  : undefined;
77
62
 
78
- return getToolcraftColorHex(value);
63
+ return typeof value === "string" ? value : undefined;
79
64
  }
@@ -86,32 +86,44 @@ function parseCanvasAspectRatioString(
86
86
  };
87
87
  }
88
88
 
89
- export function normalizeToolcraftCanvasAspectRatioValue(
89
+ export function decodeToolcraftCanvasAspectRatioValue(
90
90
  value: unknown,
91
- fallbackSize: ToolcraftState["canvas"]["size"],
92
- ): ToolcraftCanvasAspectRatioValue {
91
+ ): ToolcraftCanvasAspectRatioValue | null {
93
92
  if (typeof value === "string") {
94
- return parseCanvasAspectRatioString(value) ?? getToolcraftCanvasAspectRatioFromSize(fallbackSize);
93
+ return parseCanvasAspectRatioString(value);
94
+ }
95
+
96
+ if (!isRecord(value)) {
97
+ return null;
95
98
  }
96
99
 
97
- if (isRecord(value)) {
98
- const width = asToolcraftCanvasSizeDimension(value.width);
99
- const height = asToolcraftCanvasSizeDimension(value.height);
100
-
101
- if (width !== null && height !== null) {
102
- const rawValue = typeof value.value === "string" ? value.value : `${width}:${height}`;
103
- const mode = value.mode === "preset" ? "preset" : "custom";
104
-
105
- return {
106
- height,
107
- mode,
108
- value: mode === "preset" ? rawValue : `${width}:${height}`,
109
- width,
110
- };
111
- }
100
+ const width = asToolcraftCanvasSizeDimension(value.width);
101
+ const height = asToolcraftCanvasSizeDimension(value.height);
102
+
103
+ if (width === null || height === null) {
104
+ return null;
112
105
  }
113
106
 
114
- return getToolcraftCanvasAspectRatioFromSize(fallbackSize);
107
+ const rawValue =
108
+ typeof value.value === "string" ? value.value : `${width}:${height}`;
109
+ const mode = value.mode === "preset" ? "preset" : "custom";
110
+
111
+ return {
112
+ height,
113
+ mode,
114
+ value: mode === "preset" ? rawValue : `${width}:${height}`,
115
+ width,
116
+ };
117
+ }
118
+
119
+ export function normalizeToolcraftCanvasAspectRatioValue(
120
+ value: unknown,
121
+ fallbackSize: ToolcraftState["canvas"]["size"],
122
+ ): ToolcraftCanvasAspectRatioValue {
123
+ return (
124
+ decodeToolcraftCanvasAspectRatioValue(value) ??
125
+ getToolcraftCanvasAspectRatioFromSize(fallbackSize)
126
+ );
115
127
  }
116
128
 
117
129
  export function toolcraftCanvasAspectRatioValuesEqual(
@@ -0,0 +1,98 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { TOOLCRAFT_BUILT_IN_CONTROL_TYPES } from "../contracts/component-contracts";
4
+ import {
5
+ areToolcraftControlValuesEqual,
6
+ decodeToolcraftBuiltInControlValue,
7
+ TOOLCRAFT_CONTROL_VALUE_CODEC_REGISTRY,
8
+ } from "./control-value-codecs";
9
+
10
+ describe("Toolcraft built-in control value codecs", () => {
11
+ it("canonicalizes Color strings and UI payloads to one string shape", () => {
12
+ const control = {
13
+ defaultValue: "#112233",
14
+ target: "shape.fill",
15
+ type: "color",
16
+ } as const;
17
+
18
+ expect(decodeToolcraftBuiltInControlValue(control, "#445566")).toEqual({
19
+ accepted: true,
20
+ value: "#445566",
21
+ });
22
+ expect(
23
+ decodeToolcraftBuiltInControlValue(control, { hex: "#778899" }),
24
+ ).toEqual({ accepted: true, value: "#778899" });
25
+ expect(decodeToolcraftBuiltInControlValue(control, "#abc")).toEqual({
26
+ accepted: true,
27
+ value: "#AABBCC",
28
+ });
29
+ });
30
+
31
+ it("recursively canonicalizes source-owned Color items", () => {
32
+ const control = {
33
+ defaultValue: ["#111111"],
34
+ itemControl: { label: false, type: "color" },
35
+ target: "fills.items",
36
+ type: "sourceCollection",
37
+ } as const;
38
+
39
+ expect(
40
+ decodeToolcraftBuiltInControlValue(control, [
41
+ { hex: "#222222" },
42
+ "#333333",
43
+ ]),
44
+ ).toEqual({ accepted: true, value: ["#222222", "#333333"] });
45
+ });
46
+
47
+ it("keeps Vector numeric regardless of authored or UI ingress shape", () => {
48
+ const control = {
49
+ defaultValue: { x: "0.00", y: "0.00" },
50
+ type: "vector",
51
+ } as const;
52
+
53
+ expect(
54
+ decodeToolcraftBuiltInControlValue(control, { x: "1.25", y: -2 }),
55
+ ).toEqual({ accepted: true, value: { x: 1.25, y: -2 } });
56
+ });
57
+
58
+ it("keeps only declared FileDrop item settings beside mediaId", () => {
59
+ const control = {
60
+ defaultValue: [],
61
+ itemControls: {
62
+ depth: { defaultValue: 0.2, max: 1, min: 0, type: "slider" },
63
+ tint: { defaultValue: "#112233", type: "color" },
64
+ },
65
+ target: "media.bumpMaps",
66
+ type: "fileDrop",
67
+ } as const;
68
+
69
+ expect(
70
+ decodeToolcraftBuiltInControlValue(control, [
71
+ {
72
+ depth: 0.6,
73
+ ignoredBinaryMetadata: "must-not-enter-values",
74
+ mediaId: "bump-a",
75
+ tint: { hex: "#445566" },
76
+ },
77
+ ]),
78
+ ).toEqual({
79
+ accepted: true,
80
+ value: [{ depth: 0.6, mediaId: "bump-a", tint: "#445566" }],
81
+ });
82
+ });
83
+
84
+ it("classifies every built-in exactly once", () => {
85
+ expect(Object.keys(TOOLCRAFT_CONTROL_VALUE_CODEC_REGISTRY).sort()).toEqual(
86
+ [...TOOLCRAFT_BUILT_IN_CONTROL_TYPES].sort(),
87
+ );
88
+ });
89
+
90
+ it("compares cloned canonical values structurally", () => {
91
+ const first = { stops: [{ color: "#FFFFFF", position: "0%" }] };
92
+ const equal = { stops: [{ color: "#FFFFFF", position: "0%" }] };
93
+ const changed = { stops: [{ color: "#000000", position: "0%" }] };
94
+
95
+ expect(areToolcraftControlValuesEqual(first, equal)).toBe(true);
96
+ expect(areToolcraftControlValuesEqual(first, changed)).toBe(false);
97
+ });
98
+ });