@pixel-point/toolcraft 0.0.18 → 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 (384) 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 +55 -53
  8. package/src/generate-test-doc-assertions.test.mjs +1 -1
  9. package/src/generate-test-doc-policy-assertions.mjs +1 -1
  10. package/src/generate-test-export-doc-assertions.mjs +53 -0
  11. package/src/generate-test-file-assertions.mjs +51 -8
  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 +0 -1
  20. package/src/generate-test-runtime-boundary-assertions.mjs +20 -0
  21. package/src/generate-test-standalone-assertions.mjs +0 -16
  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 +18 -3
  34. package/templates/runtime/contracts/component-contracts.choices.ts +8 -3
  35. package/templates/runtime/contracts/component-contracts.inputs.ts +2 -1
  36. package/templates/runtime/contracts/component-contracts.runtime-acceptance.test.ts +18 -4
  37. package/templates/runtime/contracts/component-contracts.runtime-shell.test.ts +1 -1
  38. package/templates/runtime/contracts/component-contracts.runtime.ts +7 -4
  39. package/templates/runtime/contracts/component-contracts.visual.test.ts +20 -0
  40. package/templates/runtime/contracts/component-contracts.visual.ts +4 -0
  41. package/templates/runtime/contracts/decision-contracts.test.ts +18 -12
  42. package/templates/runtime/contracts/decision-contracts.ts +4 -4
  43. package/templates/runtime/contracts/performance-verification-policy.test.ts +12 -12
  44. package/templates/runtime/contracts/performance-verification-policy.ts +8 -8
  45. package/templates/runtime/export/artifact-download.ts +1 -0
  46. package/templates/runtime/export/artifact-frame-renderer.ts +2 -15
  47. package/templates/runtime/export/artifact-frame-state.ts +16 -0
  48. package/templates/runtime/export/artifact-scene-frame.test.ts +3 -3
  49. package/templates/runtime/export/artifact-scene-frame.ts +3 -3
  50. package/templates/runtime/export/export-error.ts +5 -0
  51. package/templates/runtime/export/export-renderer-coverage.ts +54 -0
  52. package/templates/runtime/export/image-artifact-export.ts +2 -2
  53. package/templates/runtime/export/index.ts +13 -0
  54. package/templates/runtime/export/product-export-renderer.test.ts +38 -4
  55. package/templates/runtime/export/product-export-renderer.ts +0 -41
  56. package/templates/runtime/export/product-svg-export-renderer.ts +21 -0
  57. package/templates/runtime/export/svg-artifact-export.test.ts +98 -0
  58. package/templates/runtime/export/svg-artifact-export.ts +120 -0
  59. package/templates/runtime/export/svg-document.test.ts +221 -0
  60. package/templates/runtime/export/svg-document.ts +400 -0
  61. package/templates/runtime/export/svg-policy.ts +47 -0
  62. package/templates/runtime/index.ts +1 -0
  63. package/templates/runtime/react/app-shell/runtime-public-api.test.tsx +10 -0
  64. package/templates/runtime/react/app-shell/settings-transfer.test.ts +21 -0
  65. package/templates/runtime/react/app-shell/toolcraft-app.scene-export.test.tsx +46 -1
  66. package/templates/runtime/react/app-shell/toolcraft-app.tsx +7 -2
  67. package/templates/runtime/react/canvas/canvas-shell-interactions.test.tsx +30 -0
  68. package/templates/runtime/react/canvas/canvas-shell-pinch-interactions.test.tsx +155 -0
  69. package/templates/runtime/react/canvas/canvas-shell-rendering.test.tsx +1 -1
  70. package/templates/runtime/react/canvas/canvas-shell.tsx +16 -5
  71. package/templates/runtime/react/canvas/canvas-viewport-geometry.ts +133 -0
  72. package/templates/runtime/react/canvas/use-canvas-viewport-interactions.ts +285 -36
  73. package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-applicability-layout.test.tsx +134 -0
  74. package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-layout.test.tsx +16 -1
  75. package/templates/runtime/react/controls-panel/__tests__/controls-panel.render-isolation.test.tsx +2 -0
  76. package/templates/runtime/react/controls-panel/__tests__/controls-panel.scene-export-actions.test.tsx +39 -0
  77. package/templates/runtime/react/controls-panel/__tests__/controls-panel.setup-controls.test.tsx +3 -3
  78. package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-collection.test.tsx +1 -4
  79. package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-color-bank.test.tsx +2 -2
  80. package/templates/runtime/react/controls-panel/__tests__/controls-panel.vector-interaction.test.tsx +6 -6
  81. package/templates/runtime/react/controls-panel/actions/controls-panel-actions.ts +2 -2
  82. package/templates/runtime/react/controls-panel/actions/export-action-runner.ts +40 -11
  83. package/templates/runtime/react/controls-panel/layout/controls-panel-layout.tsx +31 -2
  84. package/templates/runtime/react/controls-panel/layout/controls-panel-section.tsx +4 -1
  85. package/templates/runtime/react/controls-panel/renderers/controls-panel-action-renderer.tsx +2 -1
  86. package/templates/runtime/react/controls-panel/renderers/controls-panel-basic-renderers.tsx +2 -52
  87. package/templates/runtime/react/controls-panel/values/controls-panel-color-values.ts +1 -9
  88. package/templates/runtime/react/controls-panel/values/controls-panel-spatial-values.ts +7 -2
  89. package/templates/runtime/react/orientation-gizmo/orientation-gizmo-math.ts +9 -69
  90. package/templates/runtime/schema/artifact-export-actions.test.ts +47 -0
  91. package/templates/runtime/schema/artifact-export-actions.ts +49 -0
  92. package/templates/runtime/schema/types.ts +1 -0
  93. package/templates/runtime/state/canvas-background-state.ts +1 -16
  94. package/templates/runtime/state/canvas-state.ts +32 -20
  95. package/templates/runtime/state/control-value-codecs.test.ts +98 -0
  96. package/templates/runtime/state/control-value-codecs.ts +700 -0
  97. package/templates/runtime/state/control-value-normalization.test.ts +1 -1
  98. package/templates/runtime/state/control-value-normalization.ts +127 -135
  99. package/templates/runtime/state/controls-reducer.ts +26 -3
  100. package/templates/runtime/state/create-template-state.test.ts +30 -0
  101. package/templates/runtime/state/create-template-state.ts +52 -31
  102. package/templates/runtime/state/orientation-pose.ts +80 -0
  103. package/templates/runtime/state/persistence-control-values.test.ts +59 -0
  104. package/templates/runtime/state/reducer-controls.test.ts +45 -0
  105. package/templates/runtime/state/reducer-media-reset.test.ts +1 -1
  106. package/templates/runtime/state/reducer-timeline.test.ts +70 -0
  107. package/templates/runtime/state/timeline-reducer.ts +40 -2
  108. package/templates/runtime/testing/performance-schema-queries.ts +2 -2
  109. package/templates/starter/AGENTS.md +21 -22
  110. package/templates/starter/docs/toolcraft/README.md +6 -6
  111. package/templates/starter/docs/toolcraft/acceptance-testing.md +20 -20
  112. package/templates/starter/docs/toolcraft/agent-worklog.md +88 -1
  113. package/templates/starter/docs/toolcraft/assembly-workflow.md +7 -6
  114. package/templates/starter/docs/toolcraft/component-rules.md +2 -2
  115. package/templates/starter/docs/toolcraft/core/layout.md +6 -1
  116. package/templates/starter/docs/toolcraft/core/media-upload.md +1 -1
  117. package/templates/starter/docs/toolcraft/core/performance.md +8 -10
  118. package/templates/starter/docs/toolcraft/core/reference-study.md +80 -19
  119. package/templates/starter/docs/toolcraft/core/runtime-boundary.md +2 -1
  120. package/templates/starter/docs/toolcraft/core/setup-export.md +43 -13
  121. package/templates/starter/docs/toolcraft/decision-contract.md +2 -2
  122. package/templates/starter/docs/toolcraft/performance.md +8 -10
  123. package/templates/starter/docs/toolcraft/renderer-technique.md +2 -2
  124. package/templates/starter/docs/toolcraft/schema-reference.md +8 -8
  125. package/templates/starter/docs/toolcraft/workflow.md +14 -14
  126. package/templates/starter/e2e/app-browser-infinity-canvas-evidence.spec.ts +38 -0
  127. package/templates/starter/e2e/app-browser-motion-reference-requirements.spec.ts +411 -0
  128. package/templates/starter/e2e/app-browser-proof-session.spec.ts +85 -0
  129. package/templates/starter/e2e/app-browser-runtime-requirements.spec.ts +62 -0
  130. package/templates/starter/e2e/app-browser-selection-scope-evidence.spec.ts +137 -0
  131. package/templates/starter/e2e/browser-infinity-canvas-svg-evidence.ts +42 -0
  132. package/templates/starter/e2e/browser-layer-evidence-helpers.ts +15 -36
  133. package/templates/starter/e2e/browser-product-raster-snapshot.ts +213 -0
  134. package/templates/starter/e2e/browser-proof-session.ts +43 -15
  135. package/templates/starter/e2e/browser-proof-surface-action.ts +79 -0
  136. package/templates/starter/e2e/browser-proof-types.ts +15 -0
  137. package/templates/starter/e2e/browser-runtime-evidence-requirements.ts +22 -6
  138. package/templates/starter/e2e/browser-selection-scope-evidence.ts +269 -0
  139. package/templates/starter/e2e/browser-semantic-evidence-test-helpers.ts +97 -0
  140. package/templates/starter/e2e/browser-svg-export-evidence.spec.ts +79 -0
  141. package/templates/starter/e2e/browser-svg-export-evidence.ts +152 -0
  142. package/templates/starter/e2e/export-artifact-helpers.ts +70 -0
  143. package/templates/starter/e2e/product-observable-helpers.ts +8 -129
  144. package/templates/starter/e2e/svg-artifact-inspection.spec.ts +136 -0
  145. package/templates/starter/e2e/svg-artifact-inspection.ts +331 -0
  146. package/templates/starter/e2e/svg-download-test-fixtures.ts +34 -0
  147. package/templates/starter/e2e/toolcraft-delivery-catalog-reporter.ts +198 -15
  148. package/templates/starter/e2e/toolcraft-feature-verification-reporter.spec.ts +149 -0
  149. package/templates/starter/e2e/toolcraft-feature-verification-reporter.ts +223 -0
  150. package/templates/starter/package.json +2 -0
  151. package/templates/starter/scripts/check-toolcraft-docs.mjs +1 -0
  152. package/templates/starter/scripts/create-toolcraft-motion-reference-study.mjs +233 -0
  153. package/templates/starter/scripts/create-toolcraft-motion-reference-study.test.mjs +459 -0
  154. package/templates/starter/scripts/playwright-test-title-selection.d.mts +45 -0
  155. package/templates/starter/scripts/run-browser-performance-test-helpers.mjs +0 -27
  156. package/templates/starter/scripts/run-browser-performance.mjs +0 -6
  157. package/templates/starter/scripts/run-browser-performance.test.mjs +5 -13
  158. package/templates/starter/scripts/run-delivery-verification-test-helpers.mjs +0 -34
  159. package/templates/starter/scripts/run-delivery-verification.test.mjs +135 -31
  160. package/templates/starter/scripts/run-feature-verification.mjs +212 -0
  161. package/templates/starter/scripts/run-feature-verification.test.mjs +226 -0
  162. package/templates/starter/scripts/toolcraft-checkpoint-delivery-state.mjs +21 -8
  163. package/templates/starter/scripts/toolcraft-checkpoint-delivery-state.test.mjs +32 -92
  164. package/templates/starter/scripts/toolcraft-checkpoint-transaction.mjs +28 -6
  165. package/templates/starter/scripts/toolcraft-checkpoint-transaction.test.mjs +8 -63
  166. package/templates/starter/scripts/toolcraft-delivery-anchor.mjs +28 -8
  167. package/templates/starter/scripts/toolcraft-delivery-anchor.test.mjs +50 -61
  168. package/templates/starter/scripts/toolcraft-delivery-architecture-inventory.mjs +0 -4
  169. package/templates/starter/scripts/toolcraft-delivery-architecture-policy.mjs +0 -1
  170. package/templates/starter/scripts/toolcraft-delivery-evidence.test.mjs +2 -3
  171. package/templates/starter/scripts/toolcraft-delivery-executor.mjs +5 -1
  172. package/templates/starter/scripts/toolcraft-delivery-executor.test.mjs +5 -12
  173. package/templates/starter/scripts/toolcraft-delivery-functional-context.d.mts +1 -48
  174. package/templates/starter/scripts/toolcraft-delivery-functional-context.mjs +2 -30
  175. package/templates/starter/scripts/toolcraft-delivery-functional-context.test.mjs +4 -166
  176. package/templates/starter/scripts/toolcraft-delivery-functional-initial.test.mjs +4 -20
  177. package/templates/starter/scripts/toolcraft-delivery-lifecycle.mjs +43 -192
  178. package/templates/starter/scripts/toolcraft-delivery-performance-iteration-lifecycle.test.mjs +79 -440
  179. package/templates/starter/scripts/toolcraft-delivery-plan-authority.test.mjs +102 -297
  180. package/templates/starter/scripts/toolcraft-delivery-plan-construction.mjs +46 -97
  181. package/templates/starter/scripts/toolcraft-delivery-plan-test-helpers.mjs +125 -0
  182. package/templates/starter/scripts/toolcraft-delivery-plan-validation.test.mjs +58 -0
  183. package/templates/starter/scripts/toolcraft-delivery-plan.d.mts +19 -31
  184. package/templates/starter/scripts/toolcraft-delivery-plan.mjs +254 -252
  185. package/templates/starter/scripts/toolcraft-delivery-plan.test.mjs +29 -457
  186. package/templates/starter/scripts/toolcraft-delivery-receipt-performance.test.mjs +1 -1
  187. package/templates/starter/scripts/toolcraft-delivery-receipt-strictness.test.mjs +3 -72
  188. package/templates/starter/scripts/toolcraft-delivery-receipt-test-helpers.mjs +7 -36
  189. package/templates/starter/scripts/toolcraft-delivery-receipt.d.mts +3 -5
  190. package/templates/starter/scripts/toolcraft-delivery-receipt.mjs +15 -31
  191. package/templates/starter/scripts/toolcraft-delivery-receipt.test.mjs +28 -20
  192. package/templates/starter/scripts/toolcraft-delivery-receipt.types.test.mts +22 -30
  193. package/templates/starter/scripts/toolcraft-feature-verification-plan.d.mts +20 -0
  194. package/templates/starter/scripts/toolcraft-feature-verification-plan.mjs +146 -0
  195. package/templates/starter/scripts/toolcraft-feature-verification-plan.test.mjs +96 -0
  196. package/templates/starter/scripts/toolcraft-functional-proof-model.d.mts +3 -18
  197. package/templates/starter/scripts/toolcraft-functional-proof-model.mjs +39 -127
  198. package/templates/starter/scripts/toolcraft-functional-proof-model.test.mjs +25 -362
  199. package/templates/starter/scripts/toolcraft-functional-proof-model.types.test.mts +6 -83
  200. package/templates/starter/scripts/toolcraft-functional-proof-primitives.d.mts +11 -0
  201. package/templates/starter/scripts/toolcraft-functional-proof-primitives.mjs +61 -0
  202. package/templates/starter/scripts/toolcraft-functional-proof-primitives.test.mjs +43 -0
  203. package/templates/starter/scripts/toolcraft-integrity-policy.mjs +13 -0
  204. package/templates/starter/scripts/toolcraft-integrity-test-utils.mjs +1 -1
  205. package/templates/starter/scripts/toolcraft-layer-evidence-facade.test.mjs +58 -22
  206. package/templates/starter/scripts/toolcraft-motion-reference-analysis-protocol.mjs +111 -0
  207. package/templates/starter/scripts/toolcraft-motion-reference-analysis-protocol.test.mjs +116 -0
  208. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.d.mts +37 -0
  209. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.mjs +308 -0
  210. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.test.mjs +420 -0
  211. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.types.test.mts +50 -0
  212. package/templates/starter/scripts/toolcraft-motion-reference-command-options.mjs +195 -0
  213. package/templates/starter/scripts/toolcraft-motion-reference-command-options.test.mjs +224 -0
  214. package/templates/starter/scripts/toolcraft-motion-reference-contact-sheet.mjs +122 -0
  215. package/templates/starter/scripts/toolcraft-motion-reference-contact-sheet.test.mjs +153 -0
  216. package/templates/starter/scripts/toolcraft-motion-reference-evidence-assembly.mjs +270 -0
  217. package/templates/starter/scripts/toolcraft-motion-reference-evidence.test.mjs +432 -0
  218. package/templates/starter/scripts/toolcraft-motion-reference-ffmpeg-output.mjs +275 -0
  219. package/templates/starter/scripts/toolcraft-motion-reference-ffmpeg-output.test.mjs +294 -0
  220. package/templates/starter/scripts/toolcraft-motion-reference-group-inventory.mjs +148 -0
  221. package/templates/starter/scripts/toolcraft-motion-reference-image-filter-graph.mjs +101 -0
  222. package/templates/starter/scripts/toolcraft-motion-reference-image-filter-graph.test.mjs +124 -0
  223. package/templates/starter/scripts/toolcraft-motion-reference-image-source.mjs +259 -0
  224. package/templates/starter/scripts/toolcraft-motion-reference-image-source.test.mjs +338 -0
  225. package/templates/starter/scripts/toolcraft-motion-reference-image-timing.mjs +96 -0
  226. package/templates/starter/scripts/toolcraft-motion-reference-image-timing.test.mjs +81 -0
  227. package/templates/starter/scripts/toolcraft-motion-reference-lock-recovery.test.mjs +144 -0
  228. package/templates/starter/scripts/toolcraft-motion-reference-media-source.mjs +165 -0
  229. package/templates/starter/scripts/toolcraft-motion-reference-media-source.test.mjs +299 -0
  230. package/templates/starter/scripts/toolcraft-motion-reference-publication-discovery.test.mjs +142 -0
  231. package/templates/starter/scripts/toolcraft-motion-reference-publication-isolation.test.mjs +234 -0
  232. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-schema.mjs +122 -0
  233. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-store.mjs +89 -0
  234. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-store.test.mjs +74 -0
  235. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal.mjs +264 -0
  236. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal.test.mjs +377 -0
  237. package/templates/starter/scripts/toolcraft-motion-reference-publication-lease.mjs +254 -0
  238. package/templates/starter/scripts/toolcraft-motion-reference-publication-lease.test.mjs +130 -0
  239. package/templates/starter/scripts/toolcraft-motion-reference-publication-staging.mjs +128 -0
  240. package/templates/starter/scripts/toolcraft-motion-reference-publication-staging.test.mjs +209 -0
  241. package/templates/starter/scripts/toolcraft-motion-reference-publication.fixtures.mjs +88 -0
  242. package/templates/starter/scripts/toolcraft-motion-reference-publication.mjs +249 -0
  243. package/templates/starter/scripts/toolcraft-motion-reference-publication.test.mjs +433 -0
  244. package/templates/starter/scripts/toolcraft-motion-reference-review-output.mjs +38 -0
  245. package/templates/starter/scripts/toolcraft-motion-reference-review-output.test.mjs +29 -0
  246. package/templates/starter/scripts/toolcraft-motion-reference-root-safety.test.mjs +84 -0
  247. package/templates/starter/scripts/toolcraft-motion-reference-roots.mjs +83 -0
  248. package/templates/starter/scripts/toolcraft-motion-reference-sampling.mjs +283 -0
  249. package/templates/starter/scripts/toolcraft-motion-reference-sampling.test.mjs +480 -0
  250. package/templates/starter/scripts/toolcraft-motion-reference-stage-registry.mjs +39 -0
  251. package/templates/starter/scripts/toolcraft-motion-reference-stage-registry.test.mjs +59 -0
  252. package/templates/starter/scripts/toolcraft-motion-reference-stage.mjs +71 -0
  253. package/templates/starter/scripts/toolcraft-motion-reference-stage.test.mjs +61 -0
  254. package/templates/starter/scripts/toolcraft-motion-review-numeric.mjs +74 -0
  255. package/templates/starter/scripts/toolcraft-motion-review-numeric.test.mjs +65 -0
  256. package/templates/starter/scripts/toolcraft-motion-review-partitioning.mjs +268 -0
  257. package/templates/starter/scripts/toolcraft-motion-review-partitioning.test.mjs +329 -0
  258. package/templates/starter/scripts/toolcraft-motion-review-protected-units.mjs +120 -0
  259. package/templates/starter/scripts/toolcraft-motion-review-protected-units.test.mjs +111 -0
  260. package/templates/starter/scripts/toolcraft-performance-escalation-policy.test.mjs +77 -345
  261. package/templates/starter/scripts/toolcraft-performance-receipt-validation.test.mjs +19 -21
  262. package/templates/starter/scripts/toolcraft-product-boundary-ast.mjs +1 -1
  263. package/templates/starter/scripts/toolcraft-product-export-boundary.mjs +10 -1
  264. package/templates/starter/scripts/toolcraft-product-export-boundary.test.mjs +5 -1
  265. package/templates/starter/scripts/toolcraft-product-observable-facade.test.mjs +46 -1
  266. package/templates/starter/scripts/toolcraft-receipt-boundary.test.mjs +0 -1
  267. package/templates/starter/scripts/toolcraft-source-inventory.d.mts +5 -0
  268. package/templates/starter/scripts/toolcraft-source-inventory.mjs +25 -14
  269. package/templates/starter/scripts/toolcraft-source-inventory.test.mjs +48 -0
  270. package/templates/starter/scripts/toolcraft-source-ownership.mjs +0 -1
  271. package/templates/starter/scripts/toolcraft-source-ownership.test.mjs +30 -5
  272. package/templates/starter/scripts/toolcraft-verification-receipt-test-helpers.mjs +5 -26
  273. package/templates/starter/scripts/toolcraft-verification-receipt.d.mts +0 -7
  274. package/templates/starter/scripts/toolcraft-verification-receipt.mjs +3 -47
  275. package/templates/starter/scripts/toolcraft-verification-receipt.test.mjs +6 -87
  276. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.d.mts +19 -0
  277. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.mjs +107 -0
  278. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.test.mjs +114 -0
  279. package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.mjs +13 -2
  280. package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.test.mjs +110 -0
  281. package/templates/starter/src/app/acceptance/artifact-export-intent.ts +51 -20
  282. package/templates/starter/src/app/acceptance/canvas-coverage.ts +1 -0
  283. package/templates/starter/src/app/acceptance/color-bank-labels.ts +11 -15
  284. package/templates/starter/src/app/acceptance/color-row-grouping.ts +33 -0
  285. package/templates/starter/src/app/acceptance/control-acceptance-coverage.ts +0 -11
  286. package/templates/starter/src/app/acceptance/control-acceptance-policy.ts +2 -3
  287. package/templates/starter/src/app/acceptance/control-component-rules.ts +0 -10
  288. package/templates/starter/src/app/acceptance/control-labels.ts +30 -1
  289. package/templates/starter/src/app/acceptance/control-layout-section-rules.ts +18 -0
  290. package/templates/starter/src/app/acceptance/export-artifact-coverage.ts +25 -17
  291. package/templates/starter/src/app/acceptance/feature-verification-selection.test.ts +295 -0
  292. package/templates/starter/src/app/acceptance/feature-verification-selection.ts +161 -0
  293. package/templates/starter/src/app/acceptance/infinity-canvas.ts +10 -0
  294. package/templates/starter/src/app/acceptance/interaction-ownership-intent.ts +19 -1
  295. package/templates/starter/src/app/acceptance/interaction-ownership.ts +18 -2
  296. package/templates/starter/src/app/acceptance/motion-reference-evidence-validation.mjs +65 -0
  297. package/templates/starter/src/app/acceptance/motion-reference-evidence-windows.mjs +301 -0
  298. package/templates/starter/src/app/acceptance/motion-reference-evidence.d.mts +11 -0
  299. package/templates/starter/src/app/acceptance/motion-reference-evidence.mjs +145 -0
  300. package/templates/starter/src/app/acceptance/motion-reference-study-behaviors.ts +162 -0
  301. package/templates/starter/src/app/acceptance/motion-reference-study-coverage.ts +206 -0
  302. package/templates/starter/src/app/acceptance/motion-reference-study-identity.ts +129 -0
  303. package/templates/starter/src/app/acceptance/motion-reference-study-partitions.ts +186 -0
  304. package/templates/starter/src/app/acceptance/motion-reference-study.ts +90 -0
  305. package/templates/starter/src/app/acceptance/output-export-actions.test.ts +9 -1
  306. package/templates/starter/src/app/acceptance/output-export-actions.ts +14 -22
  307. package/templates/starter/src/app/acceptance/output-export-layout-rules.ts +5 -1
  308. package/templates/starter/src/app/acceptance/output-export-model.ts +4 -0
  309. package/templates/starter/src/app/acceptance/output-export.ts +4 -1
  310. package/templates/starter/src/app/acceptance/reference-study-types.ts +167 -17
  311. package/templates/starter/src/app/acceptance/runtime-coverage.ts +6 -1
  312. package/templates/starter/src/app/acceptance/selection-scope.test.ts +200 -0
  313. package/templates/starter/src/app/acceptance/selection-scope.ts +151 -0
  314. package/templates/starter/src/app/acceptance/transfer-mode-types.ts +114 -0
  315. package/templates/starter/src/app/acceptance/types.ts +43 -118
  316. package/templates/starter/src/app/acceptance/validate-coverage.ts +14 -3
  317. package/templates/starter/src/app/starter-acceptance-data.ts +1 -0
  318. package/templates/starter/src/app/starter-acceptance.animation-intent.test.ts +3 -0
  319. package/templates/starter/src/app/starter-acceptance.artifact-export-intent.test.ts +81 -8
  320. package/templates/starter/src/app/starter-acceptance.background-export.test.ts +2 -0
  321. package/templates/starter/src/app/starter-acceptance.canvas-sizing.test.ts +2 -0
  322. package/templates/starter/src/app/starter-acceptance.color-row-grouping.test.ts +118 -0
  323. package/templates/starter/src/app/starter-acceptance.compound-part-coverage.test.ts +1 -1
  324. package/templates/starter/src/app/starter-acceptance.contract-fixtures.ts +1 -0
  325. package/templates/starter/src/app/starter-acceptance.control-applicability.test.ts +1 -0
  326. package/templates/starter/src/app/starter-acceptance.control-label-context.test.ts +1 -0
  327. package/templates/starter/src/app/starter-acceptance.control-labels.test.ts +78 -3
  328. package/templates/starter/src/app/starter-acceptance.control-naming-rules.test.ts +77 -1
  329. package/templates/starter/src/app/starter-acceptance.custom-control-fit-check.test.ts +1 -1
  330. package/templates/starter/src/app/starter-acceptance.export-artifact.test.ts +74 -3
  331. package/templates/starter/src/app/starter-acceptance.export-test-utils.ts +5 -1
  332. package/templates/starter/src/app/starter-acceptance.image-export-settings.test.ts +2 -0
  333. package/templates/starter/src/app/starter-acceptance.interaction-ownership.test.ts +19 -3
  334. package/templates/starter/src/app/starter-acceptance.layers.test.ts +2 -1
  335. package/templates/starter/src/app/starter-acceptance.media-upload.test.ts +28 -0
  336. package/templates/starter/src/app/starter-acceptance.motion-reference-evidence.test.ts +17 -0
  337. package/templates/starter/src/app/starter-acceptance.motion-reference-identity.test.ts +163 -0
  338. package/templates/starter/src/app/starter-acceptance.motion-reference-mapping.test.ts +133 -0
  339. package/templates/starter/src/app/starter-acceptance.motion-reference-ownership.test.ts +121 -0
  340. package/templates/starter/src/app/starter-acceptance.motion-reference-partitions.test.ts +210 -0
  341. package/templates/starter/src/app/starter-acceptance.motion-reference-test-utils.ts +313 -0
  342. package/templates/starter/src/app/starter-acceptance.output-export-intent.test.ts +78 -4
  343. package/templates/starter/src/app/starter-acceptance.product-output-export.test.ts +6 -1
  344. package/templates/starter/src/app/starter-acceptance.product-readiness.test.ts +18 -1
  345. package/templates/starter/src/app/starter-acceptance.product-worklog.test.ts +123 -2
  346. package/templates/starter/src/app/starter-acceptance.reference-custom-timeline.test.ts +2 -0
  347. package/templates/starter/src/app/starter-acceptance.reference-foundation.test.ts +8 -0
  348. package/templates/starter/src/app/starter-acceptance.reference-timeline.test.ts +7 -0
  349. package/templates/starter/src/app/starter-acceptance.section-cohesion.test.ts +2 -0
  350. package/templates/starter/src/app/starter-acceptance.timeline-playback.test.ts +5 -0
  351. package/templates/starter/src/app/starter-acceptance.ts +34 -8
  352. package/templates/starter/src/app/starter-acceptance.video-export-settings.test.ts +2 -0
  353. package/templates/starter/src/app/starter-acceptance.video-reference-study.test.ts +34 -236
  354. package/templates/starter/src/app/starter-acceptance.view-interaction.test.ts +4 -0
  355. package/templates/starter/src/app/starter-acceptance.worklog-test-utils.ts +122 -6
  356. package/templates/starter/src/app/starter-acceptance.worklog.test.ts +152 -16
  357. package/templates/starter/src/app/starter-performance.gates.test.ts +20 -18
  358. package/templates/starter/src/app/starter-performance.lifecycle.test.ts +22 -6
  359. package/templates/starter/src/app/test-evidence/browser-runtime-contract.ts +3 -0
  360. package/templates/starter/tsconfig.json +1 -0
  361. package/templates/starter/scripts/toolcraft-browser-impact-selection.mjs +0 -26
  362. package/templates/starter/scripts/toolcraft-delivery-framework-refresh.test.mjs +0 -141
  363. package/templates/starter/scripts/toolcraft-delivery-functional-changed.test.mjs +0 -468
  364. package/templates/starter/scripts/toolcraft-delivery-functional-model-lifecycle.test.mjs +0 -254
  365. package/templates/starter/scripts/toolcraft-delivery-functional-semantic-regression.test.mjs +0 -135
  366. package/templates/starter/scripts/toolcraft-delivery-performance-iteration-durability.test.mjs +0 -329
  367. package/templates/starter/scripts/toolcraft-delivery-plan-errors.test.mjs +0 -430
  368. package/templates/starter/scripts/toolcraft-delivery-plan-functional-model.test.mjs +0 -358
  369. package/templates/starter/scripts/toolcraft-functional-proof-regression-fixtures.mjs +0 -298
  370. package/templates/starter/scripts/toolcraft-verification-impact-inventory.d.mts +0 -62
  371. package/templates/starter/scripts/toolcraft-verification-impact-inventory.mjs +0 -344
  372. package/templates/starter/scripts/toolcraft-verification-impact-inventory.test.mjs +0 -204
  373. package/templates/starter/scripts/toolcraft-verification-impact-performance-candidates.test.mjs +0 -210
  374. package/templates/starter/scripts/toolcraft-verification-impact-resolution.mjs +0 -344
  375. package/templates/starter/scripts/toolcraft-verification-impact-resolution.test.mjs +0 -270
  376. package/templates/starter/scripts/toolcraft-verification-impact-semantic-resolution.test.mjs +0 -449
  377. package/templates/starter/scripts/toolcraft-verification-impact-support-resolution.test.mjs +0 -195
  378. package/templates/starter/scripts/toolcraft-verification-impact.d.mts +0 -132
  379. package/templates/starter/scripts/toolcraft-verification-impact.mjs +0 -169
  380. package/templates/starter/scripts/toolcraft-verification-impact.test.mjs +0 -300
  381. package/templates/starter/scripts/toolcraft-verification-input-roles.mjs +0 -197
  382. package/templates/starter/scripts/toolcraft-verification-input-roles.test.mjs +0 -225
  383. package/templates/starter/src/app/acceptance/video-reference-study.ts +0 -217
  384. package/templates/starter/src/app/starter-verification-impact.json +0 -15
@@ -2,11 +2,16 @@ import assert from "node:assert/strict";
2
2
  import test from "node:test";
3
3
 
4
4
  import {
5
+ TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV,
5
6
  TOOLCRAFT_VITEST_RUNTIME_MARKER_FILE_NAMES,
6
7
  TOOLCRAFT_VITEST_RUNTIME_REQUIREMENTS_ANNOTATION_TYPE,
7
8
  evaluateToolcraftVitestRuntimeEvidence,
8
9
  getToolcraftProductTestProcessArgs,
10
+ getToolcraftProductTestProcessEnvironment,
11
+ parseToolcraftVitestRuntimeAcceptanceSelection,
9
12
  parseToolcraftVitestRuntimeRequirements,
13
+ selectToolcraftVitestRuntimeRequirements,
14
+ serializeToolcraftVitestRuntimeAcceptanceSelection,
10
15
  serializeToolcraftVitestRuntimeRequirements,
11
16
  } from "./toolcraft-vitest-runtime-contract.mjs";
12
17
 
@@ -15,6 +20,11 @@ const requirement = {
15
20
  requirementId: "appearance.opacity",
16
21
  testName: "opacity changes product output",
17
22
  };
23
+ const unrelatedRequirement = {
24
+ kind: "acceptance",
25
+ requirementId: "material.host",
26
+ testName: "keeps the baseline material extension inactive",
27
+ };
18
28
 
19
29
  function requiredTest(overrides = {}) {
20
30
  return {
@@ -61,6 +71,27 @@ test("product-test process args execute only planned files and gate runtime evid
61
71
  }
62
72
  });
63
73
 
74
+ test("product-test process environment distinguishes full and targeted proof", () => {
75
+ const inherited = {
76
+ KEEP_ME: "yes",
77
+ [TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV]: "forged",
78
+ };
79
+ const full = getToolcraftProductTestProcessEnvironment(null, inherited);
80
+ const targeted = getToolcraftProductTestProcessEnvironment([], inherited);
81
+
82
+ assert.deepEqual(full, { KEEP_ME: "yes" });
83
+ assert.deepEqual(
84
+ parseToolcraftVitestRuntimeAcceptanceSelection(
85
+ targeted[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV],
86
+ ),
87
+ [],
88
+ );
89
+ assert.equal(
90
+ inherited[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV],
91
+ "forged",
92
+ );
93
+ });
94
+
64
95
  test("round-trips runtime requirements through a typed annotation", () => {
65
96
  assert.deepEqual(
66
97
  parseToolcraftVitestRuntimeRequirements({
@@ -71,6 +102,89 @@ test("round-trips runtime requirements through a typed annotation", () => {
71
102
  );
72
103
  });
73
104
 
105
+ test("round-trips the protected canonical acceptance selection", () => {
106
+ const serialized = serializeToolcraftVitestRuntimeAcceptanceSelection([
107
+ "appearance.opacity",
108
+ ]);
109
+
110
+ assert.equal(
111
+ TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV,
112
+ "TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION",
113
+ );
114
+ assert.deepEqual(
115
+ parseToolcraftVitestRuntimeAcceptanceSelection(serialized),
116
+ ["appearance.opacity"],
117
+ );
118
+ assert.throws(
119
+ () => serializeToolcraftVitestRuntimeAcceptanceSelection([
120
+ "material.host",
121
+ "appearance.opacity",
122
+ ]),
123
+ /sorted and unique/iu,
124
+ );
125
+ assert.throws(
126
+ () => parseToolcraftVitestRuntimeAcceptanceSelection(
127
+ '{"acceptanceIds":["appearance.opacity","appearance.opacity"],"version":1}',
128
+ ),
129
+ /sorted and unique/iu,
130
+ );
131
+ const sparse = [];
132
+ sparse.length = 1;
133
+ assert.throws(
134
+ () => serializeToolcraftVitestRuntimeAcceptanceSelection(sparse),
135
+ /sorted and unique/iu,
136
+ );
137
+ });
138
+
139
+ test("selects only signed targeted acceptance requirements and fails closed", () => {
140
+ const requirements = [requirement, unrelatedRequirement];
141
+
142
+ assert.deepEqual(
143
+ selectToolcraftVitestRuntimeRequirements(requirements, undefined),
144
+ requirements,
145
+ );
146
+ assert.deepEqual(
147
+ selectToolcraftVitestRuntimeRequirements(
148
+ requirements,
149
+ serializeToolcraftVitestRuntimeAcceptanceSelection([
150
+ "appearance.opacity",
151
+ ]),
152
+ ),
153
+ [requirement],
154
+ );
155
+ assert.throws(
156
+ () => selectToolcraftVitestRuntimeRequirements(
157
+ requirements,
158
+ serializeToolcraftVitestRuntimeAcceptanceSelection([
159
+ "reference.flash-events",
160
+ ]),
161
+ ),
162
+ /unknown acceptance requirement.*reference\.flash-events/iu,
163
+ );
164
+ });
165
+
166
+ test("a selected reference requirement still requires its exact product test", () => {
167
+ const referenceRequirement = {
168
+ kind: "acceptance",
169
+ requirementId: "reference.flash-events",
170
+ testName: "reference flash events change product output",
171
+ };
172
+ const selected = selectToolcraftVitestRuntimeRequirements(
173
+ [referenceRequirement, unrelatedRequirement],
174
+ serializeToolcraftVitestRuntimeAcceptanceSelection([
175
+ "reference.flash-events",
176
+ ]),
177
+ );
178
+
179
+ assert.match(
180
+ evaluateToolcraftVitestRuntimeEvidence({
181
+ requirements: selected,
182
+ tests: [],
183
+ })[0],
184
+ /Missing required automated test.*reference flash events/iu,
185
+ );
186
+ });
187
+
74
188
  test("accepts one passed product-owned test", () => {
75
189
  assert.deepEqual(
76
190
  evaluateToolcraftVitestRuntimeEvidence({
@@ -2,10 +2,12 @@ import path from "node:path";
2
2
 
3
3
  import { collectToolcraftFrameworkOwnedLocalPaths } from "./toolcraft-source-ownership.mjs";
4
4
  import {
5
+ TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV,
5
6
  TOOLCRAFT_VITEST_RUNTIME_MARKER_FILE_NAMES,
6
7
  TOOLCRAFT_VITEST_RUNTIME_MARKER_TEST_NAME,
7
8
  evaluateToolcraftVitestRuntimeEvidence,
8
9
  parseToolcraftVitestRuntimeRequirements,
10
+ selectToolcraftVitestRuntimeRequirements,
9
11
  } from "./toolcraft-vitest-runtime-contract.mjs";
10
12
 
11
13
  function normalizeModulePath(moduleId) {
@@ -59,15 +61,24 @@ export default class ToolcraftVitestRuntimeEvidenceReporter {
59
61
  );
60
62
  }
61
63
 
62
- const requirements = marker
64
+ const publishedRequirements = marker
63
65
  .annotations()
64
66
  .map(parseToolcraftVitestRuntimeRequirements)
65
67
  .find(Boolean);
66
- if (!requirements) {
68
+ if (!publishedRequirements) {
67
69
  throw new Error(
68
70
  "Toolcraft automated runtime marker did not publish valid requirements.",
69
71
  );
70
72
  }
73
+ const requirements = selectToolcraftVitestRuntimeRequirements(
74
+ publishedRequirements,
75
+ process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV],
76
+ );
77
+ if (requirements.length === 0) {
78
+ throw new Error(
79
+ "Toolcraft automated runtime coverage must select at least one runtime requirement.",
80
+ );
81
+ }
71
82
 
72
83
  const appRoot = resolveAppRoot(marker, markerFileName);
73
84
  const protectedPaths = new Set(
@@ -5,8 +5,10 @@ import path from "node:path";
5
5
  import test from "node:test";
6
6
 
7
7
  import {
8
+ TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV,
8
9
  TOOLCRAFT_VITEST_RUNTIME_MARKER_TEST_NAME,
9
10
  TOOLCRAFT_VITEST_RUNTIME_REQUIREMENTS_ANNOTATION_TYPE,
11
+ serializeToolcraftVitestRuntimeAcceptanceSelection,
10
12
  serializeToolcraftVitestRuntimeRequirements,
11
13
  } from "./toolcraft-vitest-runtime-contract.mjs";
12
14
  import ToolcraftVitestRuntimeEvidenceReporter, {
@@ -115,4 +117,112 @@ test("validates generated-app requirements from actual runner tasks", async (con
115
117
  await new ToolcraftVitestRuntimeEvidenceReporter().onTestRunEnd([
116
118
  createTestModule([marker, productTest]),
117
119
  ]);
120
+
121
+ const unrelatedRequirement = {
122
+ kind: "acceptance",
123
+ requirementId: "material.host",
124
+ testName: "keeps the baseline material extension inactive",
125
+ };
126
+ const targetedMarker = createTestTask({
127
+ annotations: [
128
+ {
129
+ message: serializeToolcraftVitestRuntimeRequirements([
130
+ requirement,
131
+ unrelatedRequirement,
132
+ ]),
133
+ type: TOOLCRAFT_VITEST_RUNTIME_REQUIREMENTS_ANNOTATION_TYPE,
134
+ },
135
+ ],
136
+ filePath: markerPath,
137
+ name: TOOLCRAFT_VITEST_RUNTIME_MARKER_TEST_NAME,
138
+ });
139
+ const previousSelection =
140
+ process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV];
141
+ context.after(() => {
142
+ if (previousSelection === undefined) {
143
+ delete process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV];
144
+ } else {
145
+ process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV] =
146
+ previousSelection;
147
+ }
148
+ });
149
+ delete process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV];
150
+ await assert.rejects(
151
+ new ToolcraftVitestRuntimeEvidenceReporter().onTestRunEnd([
152
+ createTestModule([targetedMarker, productTest]),
153
+ ]),
154
+ /Missing required automated test.*baseline material extension/iu,
155
+ );
156
+ process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV] =
157
+ serializeToolcraftVitestRuntimeAcceptanceSelection([
158
+ "appearance.opacity",
159
+ ]);
160
+
161
+ await new ToolcraftVitestRuntimeEvidenceReporter().onTestRunEnd([
162
+ createTestModule([targetedMarker, productTest]),
163
+ ]);
164
+
165
+ const sharedTestMarker = createTestTask({
166
+ annotations: [
167
+ {
168
+ message: serializeToolcraftVitestRuntimeRequirements([
169
+ requirement,
170
+ { ...unrelatedRequirement, testName: requirement.testName },
171
+ ]),
172
+ type: TOOLCRAFT_VITEST_RUNTIME_REQUIREMENTS_ANNOTATION_TYPE,
173
+ },
174
+ ],
175
+ filePath: markerPath,
176
+ name: TOOLCRAFT_VITEST_RUNTIME_MARKER_TEST_NAME,
177
+ });
178
+ process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV] =
179
+ serializeToolcraftVitestRuntimeAcceptanceSelection([
180
+ "appearance.opacity",
181
+ "material.host",
182
+ ]);
183
+ await new ToolcraftVitestRuntimeEvidenceReporter().onTestRunEnd([
184
+ createTestModule([sharedTestMarker, productTest]),
185
+ ]);
186
+
187
+ process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV] =
188
+ serializeToolcraftVitestRuntimeAcceptanceSelection([
189
+ "reference.flash-events",
190
+ ]);
191
+ await assert.rejects(
192
+ new ToolcraftVitestRuntimeEvidenceReporter().onTestRunEnd([
193
+ createTestModule([targetedMarker, productTest]),
194
+ ]),
195
+ /unknown acceptance requirement.*reference\.flash-events/iu,
196
+ );
197
+ });
198
+
199
+ test("full runtime evidence cannot pass with zero published requirements", async () => {
200
+ const marker = createTestTask({
201
+ annotations: [
202
+ {
203
+ message: serializeToolcraftVitestRuntimeRequirements([]),
204
+ type: TOOLCRAFT_VITEST_RUNTIME_REQUIREMENTS_ANNOTATION_TYPE,
205
+ },
206
+ ],
207
+ filePath: "/workspace/src/app/app-automated-runtime-evidence.test.ts",
208
+ name: TOOLCRAFT_VITEST_RUNTIME_MARKER_TEST_NAME,
209
+ });
210
+ const previousSelection =
211
+ process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV];
212
+ delete process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV];
213
+ try {
214
+ await assert.rejects(
215
+ new ToolcraftVitestRuntimeEvidenceReporter().onTestRunEnd([
216
+ createTestModule([marker]),
217
+ ]),
218
+ /at least one runtime requirement/iu,
219
+ );
220
+ } finally {
221
+ if (previousSelection === undefined) {
222
+ delete process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV];
223
+ } else {
224
+ process.env[TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV] =
225
+ previousSelection;
226
+ }
227
+ }
118
228
  });
@@ -1,13 +1,17 @@
1
+ import type { ToolcraftArtifactExportActionRole } from "@repo/toolcraft-runtime";
2
+
1
3
  import type { ToolcraftArtifactExportIntent } from "./types";
2
4
 
3
5
  export type ToolcraftArtifactExportDelivery = Readonly<{
4
6
  imageEnabled: boolean;
7
+ svgEnabled: boolean;
5
8
  videoEnabled: boolean;
6
9
  }>;
7
10
 
8
11
  export type ToolcraftArtifactExportSchemaFacts = Readonly<{
9
12
  hasImageExportAction: boolean;
10
13
  hasImageExportSection: boolean;
14
+ hasSvgExportAction: boolean;
11
15
  hasVideoExportAction: boolean;
12
16
  hasVideoExportSection: boolean;
13
17
  }>;
@@ -22,6 +26,7 @@ export function resolveToolcraftArtifactExportIntent(
22
26
  ): ToolcraftArtifactExportDelivery {
23
27
  return Object.freeze({
24
28
  imageEnabled: intent.image.mode !== "user-removed",
29
+ svgEnabled: intent.svg.mode === "user-requested",
25
30
  videoEnabled: intent.video.mode === "user-requested",
26
31
  });
27
32
  }
@@ -31,6 +36,15 @@ export function getToolcraftArtifactExportIntentEvidenceErrors(
31
36
  ): readonly string[] {
32
37
  const errors: string[] = [];
33
38
 
39
+ if (
40
+ intent.svg.mode === "user-requested" &&
41
+ intent.svg.evidence.trim() === ""
42
+ ) {
43
+ errors.push(
44
+ "SVG export user-requested intent requires non-empty evidence.",
45
+ );
46
+ }
47
+
34
48
  if (
35
49
  intent.image.mode !== "toolcraft-default" &&
36
50
  intent.image.evidence.trim() === ""
@@ -52,6 +66,29 @@ export function getToolcraftArtifactExportIntentEvidenceErrors(
52
66
  return errors;
53
67
  }
54
68
 
69
+ type ToolcraftArtifactCorrespondenceBase = Readonly<{
70
+ actionRole: ToolcraftArtifactExportActionRole;
71
+ artifact: "Image" | "SVG" | "Video";
72
+ enabled: boolean;
73
+ hasAction: boolean;
74
+ intentMode:
75
+ | ToolcraftArtifactExportIntent["image"]["mode"]
76
+ | ToolcraftArtifactExportIntent["svg"]["mode"]
77
+ | ToolcraftArtifactExportIntent["video"]["mode"];
78
+ }>;
79
+
80
+ type ToolcraftArtifactCorrespondence = ToolcraftArtifactCorrespondenceBase &
81
+ (
82
+ | Readonly<{
83
+ hasSection: boolean;
84
+ section: Readonly<{
85
+ article: "a" | "an";
86
+ title: "Image Export" | "Video Export";
87
+ }>;
88
+ }>
89
+ | Readonly<{ hasSection?: never; section?: never }>
90
+ );
91
+
55
92
  function getToolcraftArtifactCorrespondenceErrors({
56
93
  actionRole,
57
94
  artifact,
@@ -59,20 +96,8 @@ function getToolcraftArtifactCorrespondenceErrors({
59
96
  hasAction,
60
97
  hasSection,
61
98
  intentMode,
62
- sectionArticle,
63
- sectionTitle,
64
- }: Readonly<{
65
- actionRole: "export-image" | "export-video";
66
- artifact: "Image" | "Video";
67
- enabled: boolean;
68
- hasAction: boolean;
69
- hasSection: boolean;
70
- intentMode:
71
- | ToolcraftArtifactExportIntent["image"]["mode"]
72
- | ToolcraftArtifactExportIntent["video"]["mode"];
73
- sectionArticle: "a" | "an";
74
- sectionTitle: "Image Export" | "Video Export";
75
- }>): string[] {
99
+ section,
100
+ }: ToolcraftArtifactCorrespondence): string[] {
76
101
  const errors: string[] = [];
77
102
  const requirement = enabled ? "requires" : "must not have";
78
103
 
@@ -82,9 +107,9 @@ function getToolcraftArtifactCorrespondenceErrors({
82
107
  );
83
108
  }
84
109
 
85
- if (hasSection !== enabled) {
110
+ if (section && hasSection !== enabled) {
86
111
  errors.push(
87
- `${artifact} export intent "${intentMode}" ${requirement} ${sectionArticle} "${sectionTitle}" section.`,
112
+ `${artifact} export intent "${intentMode}" ${requirement} ${section.article} "${section.title}" section.`,
88
113
  );
89
114
  }
90
115
 
@@ -94,6 +119,7 @@ function getToolcraftArtifactCorrespondenceErrors({
94
119
  export function validateToolcraftArtifactExportIntentCorrespondence({
95
120
  hasImageExportAction,
96
121
  hasImageExportSection,
122
+ hasSvgExportAction,
97
123
  hasVideoExportAction,
98
124
  hasVideoExportSection,
99
125
  intent,
@@ -111,8 +137,14 @@ export function validateToolcraftArtifactExportIntentCorrespondence({
111
137
  hasAction: hasImageExportAction,
112
138
  hasSection: hasImageExportSection,
113
139
  intentMode: intent.image.mode,
114
- sectionArticle: "an",
115
- sectionTitle: "Image Export",
140
+ section: { article: "an", title: "Image Export" },
141
+ }),
142
+ ...getToolcraftArtifactCorrespondenceErrors({
143
+ actionRole: "export-svg",
144
+ artifact: "SVG",
145
+ enabled: delivery.svgEnabled,
146
+ hasAction: hasSvgExportAction,
147
+ intentMode: intent.svg.mode,
116
148
  }),
117
149
  ...getToolcraftArtifactCorrespondenceErrors({
118
150
  actionRole: "export-video",
@@ -121,8 +153,7 @@ export function validateToolcraftArtifactExportIntentCorrespondence({
121
153
  hasAction: hasVideoExportAction,
122
154
  hasSection: hasVideoExportSection,
123
155
  intentMode: intent.video.mode,
124
- sectionArticle: "a",
125
- sectionTitle: "Video Export",
156
+ section: { article: "a", title: "Video Export" },
126
157
  }),
127
158
  ];
128
159
 
@@ -5,6 +5,7 @@ export type ToolcraftCanvasSizingCoverage =
5
5
  export type ToolcraftInfinityCanvasCoverage =
6
6
  | "mode-and-restoration"
7
7
  | "scene-bounds-image-export"
8
+ | "scene-bounds-svg-export"
8
9
  | "scene-bounds-video-export";
9
10
 
10
11
  export type ToolcraftRenderScaleState =
@@ -114,6 +114,15 @@ export function getToolcraftColorBankLabelErrors({
114
114
  return [];
115
115
  }
116
116
 
117
+ const sequentialColorControls = colorControls.filter(([, control]) =>
118
+ isToolcraftSequentialColorLabel(getControlLabelText(control)),
119
+ );
120
+ const errors = sequentialColorControls.map(([controlId, control]) => {
121
+ const label = getControlLabelText(control).trim();
122
+
123
+ return `${sectionLabel} / ${controlId} uses visible label "${label}" for one of multiple sibling colors. Set label: false when the colors form one shared bank, or use a distinct user-facing role such as Fill, Stroke, Background, Connector, or Object color.`;
124
+ });
125
+
117
126
  const loosePrefixes = new Set(
118
127
  colorControls
119
128
  .map(([, control]) => getToolcraftLooseTargetPrefix(control.target))
@@ -121,12 +130,9 @@ export function getToolcraftColorBankLabelErrors({
121
130
  );
122
131
 
123
132
  if (loosePrefixes.size !== 1) {
124
- return [];
133
+ return errors;
125
134
  }
126
135
 
127
- const sequentialColorControls = colorControls.filter(([, control]) =>
128
- isToolcraftSequentialColorLabel(getControlLabelText(control)),
129
- );
130
136
  const isPaletteVariationBank =
131
137
  colorControls.every(([, control]) =>
132
138
  isToolcraftPaletteVariationTarget(control.target),
@@ -135,14 +141,12 @@ export function getToolcraftColorBankLabelErrors({
135
141
  sequentialColorControls.length > 0);
136
142
 
137
143
  if (!isPaletteVariationBank) {
138
- return [];
144
+ return errors;
139
145
  }
140
146
 
141
147
  const visibleColorControls = colorControls.filter(([, control]) =>
142
148
  hasVisibleControlLabel(control),
143
149
  );
144
- const errors: string[] = [];
145
-
146
150
  if (
147
151
  visibleColorControls.length > 0 &&
148
152
  visibleColorControls.length < colorControls.length
@@ -152,13 +156,5 @@ export function getToolcraftColorBankLabelErrors({
152
156
  );
153
157
  }
154
158
 
155
- for (const [controlId, control] of sequentialColorControls) {
156
- const label = getControlLabelText(control).trim();
157
-
158
- errors.push(
159
- `${sectionLabel} / ${controlId} uses visible label "${label}" for a palette variation color. When colors only add variety to one shared palette, set label: false or use collectionActions with unlabeled items. Keep visible labels only when each color edits a distinct user-facing entity such as Fill, Stroke, Background, Connector, or Object color.`,
160
- );
161
- }
162
-
163
159
  return errors;
164
160
  }
@@ -0,0 +1,33 @@
1
+ import type { ResolvedToolcraftControlSchema } from "@repo/toolcraft-runtime";
2
+
3
+ export function getToolcraftColorRowGroupingErrors({
4
+ controls,
5
+ sectionLabel,
6
+ }: {
7
+ controls: readonly [string, ResolvedToolcraftControlSchema][];
8
+ sectionLabel: string;
9
+ }): string[] {
10
+ const plainColors = controls.filter(
11
+ ([, control]) => control.type === "color",
12
+ );
13
+ const isColorOnlySection =
14
+ controls.length > 0 &&
15
+ controls.every(
16
+ ([, control]) =>
17
+ control.type === "color" || control.type === "colorOpacity",
18
+ );
19
+
20
+ if (isColorOnlySection || plainColors.length < 2) {
21
+ return [];
22
+ }
23
+
24
+ const missingSemanticGroups = plainColors
25
+ .filter(([, control]) => !control.semanticGroup?.trim())
26
+ .map(([controlId]) => controlId);
27
+
28
+ return missingSemanticGroups.length === 0
29
+ ? []
30
+ : [
31
+ `${sectionLabel} has multiple plain Color controls in a mixed section and must declare semanticGroup for every plain Color so runtime rows follow product meaning instead of schema adjacency. Missing: ${missingSemanticGroups.join(", ")}.`,
32
+ ];
33
+ }
@@ -222,7 +222,6 @@ function getControlPartAndRuntimeCoverageErrors({
222
222
  }): string[] {
223
223
  const errors: string[] = [];
224
224
  const keyframeCapability = getToolcraftControlKeyframeCapability(control);
225
- const isSelectedLayerTarget = control.target.startsWith("selectedLayer.");
226
225
  const requiredControlParts = getRequiredToolcraftControlPartCoverage(control);
227
226
 
228
227
  if (
@@ -241,16 +240,6 @@ function getControlPartAndRuntimeCoverageErrors({
241
240
  }
242
241
  }
243
242
 
244
- if (
245
- isSelectedLayerTarget &&
246
- layersEnabled &&
247
- entry.layerCoverage !== "selected-layer-controls"
248
- ) {
249
- errors.push(
250
- `${label} targets selectedLayer.* and must have acceptance layerCoverage "selected-layer-controls" proving the control edits the currently selected layer output.`,
251
- );
252
- }
253
-
254
243
  return errors;
255
244
  }
256
245
 
@@ -18,13 +18,12 @@ function getControlComponentPolicyErrors({
18
18
  control,
19
19
  controlId,
20
20
  label,
21
- sectionTitle,
22
21
  }: Pick<
23
22
  ToolcraftControlRuleContext,
24
- "control" | "controlId" | "label" | "sectionTitle"
23
+ "control" | "controlId" | "label"
25
24
  >): string[] {
26
25
  const errors: string[] = [];
27
- const toggleLabelError = getToggleControlLabelError(control, sectionTitle);
26
+ const toggleLabelError = getToggleControlLabelError(control);
28
27
  const singleActionsLabelError = getSingleActionsControlLabelError(control);
29
28
  const codeTextareaError = getCodeTextareaControlError({
30
29
  control,
@@ -168,7 +168,6 @@ export function getCurveIntentError(
168
168
 
169
169
  export function getToggleControlLabelError(
170
170
  control: ToolcraftControlSchema,
171
- sectionTitle?: string,
172
171
  ): string | undefined {
173
172
  if (control.type !== "switch" && control.type !== "checkbox") {
174
173
  return undefined;
@@ -180,15 +179,6 @@ export function getToggleControlLabelError(
180
179
  return `toggle labels must name the setting context only; use "CRT", "Background", "Glow", or "Loop" instead of "${label}".`;
181
180
  }
182
181
 
183
- if (
184
- label &&
185
- sectionTitle &&
186
- normalizeToolcraftSemanticText(label) ===
187
- normalizeToolcraftSemanticText(sectionTitle)
188
- ) {
189
- return `toggle label "${label}" duplicates section title "${sectionTitle}". Use a shorter contextual label such as "Include" or rename the toggle to a more specific setting.`;
190
- }
191
-
192
182
  return undefined;
193
183
  }
194
184
 
@@ -1,6 +1,9 @@
1
1
  import type { ToolcraftControlSchema } from "@repo/toolcraft-runtime";
2
2
 
3
- import { getControlLabelText } from "./controls";
3
+ import {
4
+ getControlLabelText,
5
+ hasVisibleControlLabel,
6
+ } from "./controls";
4
7
  import {
5
8
  getToolcraftLooseTargetPrefix,
6
9
  getToolcraftTargetParts,
@@ -157,6 +160,32 @@ export function getToolcraftFontPickerOwnedTypographyPart(
157
160
  return undefined;
158
161
  }
159
162
 
163
+ export function getToolcraftDuplicateSectionTitleLabelError({
164
+ control,
165
+ controlId,
166
+ sectionLabel,
167
+ sectionTitle,
168
+ }: {
169
+ control: ToolcraftControlSchema;
170
+ controlId: string;
171
+ sectionLabel: string;
172
+ sectionTitle: string | undefined;
173
+ }): string | undefined {
174
+ if (
175
+ control.type === "tabs" ||
176
+ !sectionTitle ||
177
+ !hasVisibleControlLabel(control) ||
178
+ normalizeToolcraftSemanticText(getControlLabelText(control)) !==
179
+ normalizeToolcraftSemanticText(sectionTitle)
180
+ ) {
181
+ return undefined;
182
+ }
183
+
184
+ const label = getControlLabelText(control).trim();
185
+
186
+ return `${sectionLabel} / ${controlId} visible label "${label}" duplicates section title "${sectionTitle}". Set label: false when the section supplies the complete visible context, or use a more specific label for a distinct setting.`;
187
+ }
188
+
160
189
  export function getToolcraftGenericControlLabelError({
161
190
  control,
162
191
  controlId,