@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
@@ -33,7 +33,9 @@ const COMMAND_REFERENCE_DELIMITER_PATTERN =
33
33
  export const GENERATED_SCRIPT_COMMANDS = [
34
34
  "build",
35
35
  "dev",
36
+ "reference:study",
36
37
  "test",
38
+ "test:feature",
37
39
  "typecheck",
38
40
  "verify:delivery",
39
41
  "verify:perf",
@@ -68,7 +68,9 @@ describe("package manager commands", () => {
68
68
  assert.deepEqual(GENERATED_SCRIPT_COMMANDS, [
69
69
  "build",
70
70
  "dev",
71
+ "reference:study",
71
72
  "test",
73
+ "test:feature",
72
74
  "typecheck",
73
75
  "verify:delivery",
74
76
  "verify:perf",
@@ -96,8 +98,10 @@ describe("package manager commands", () => {
96
98
  "pnpm verify:perf",
97
99
  "pnpm typecheck",
98
100
  "pnpm test",
101
+ "pnpm test:feature -- material.layer",
99
102
  "pnpm build",
100
103
  "pnpm dev",
104
+ "pnpm reference:study -- --source /absolute/reference.mp4",
101
105
  "pnpm verify:quick",
102
106
  "pnpm exec vite dev --host 127.0.0.1",
103
107
  ].join("\n");
@@ -110,8 +114,10 @@ describe("package manager commands", () => {
110
114
  "npm run verify:perf",
111
115
  "npm run typecheck",
112
116
  "npm run test",
117
+ "npm run test:feature -- material.layer",
113
118
  "npm run build",
114
119
  "npm run dev",
120
+ "npm run reference:study -- --source /absolute/reference.mp4",
115
121
  "pnpm verify:quick",
116
122
  "npm exec -- vite dev --host 127.0.0.1",
117
123
  ].join("\n"),
@@ -129,6 +135,7 @@ describe("package manager commands", () => {
129
135
  "pnpm test:browser",
130
136
  "pnpm test:delivery",
131
137
  "pnpm dev:restart",
138
+ "pnpm reference:study:legacy",
132
139
  "pnpm verify:perf:record-iteration",
133
140
  "pnpm verify:delivery:legacy",
134
141
  "pnpm testing",
@@ -147,6 +154,7 @@ describe("package manager commands", () => {
147
154
  "pnpm test:browser",
148
155
  "pnpm test:delivery",
149
156
  "pnpm dev:restart",
157
+ "pnpm reference:study:legacy",
150
158
  "pnpm verify:perf:record-iteration",
151
159
  "pnpm verify:delivery:legacy",
152
160
  "pnpm testing",
@@ -0,0 +1,254 @@
1
+ import assert from "node:assert/strict";
2
+ import { execFile } from "node:child_process";
3
+ import { createHash } from "node:crypto";
4
+ import fs from "node:fs/promises";
5
+ import path from "node:path";
6
+ import { fileURLToPath, pathToFileURL } from "node:url";
7
+ import { promisify } from "node:util";
8
+
9
+ import { copyDirectory } from "./copy-recursive.mjs";
10
+
11
+ const execFileAsync = promisify(execFile);
12
+ const cliSrcDir = path.dirname(fileURLToPath(import.meta.url));
13
+ const repoRoot = path.resolve(cliSrcDir, "../..");
14
+
15
+ export async function readUtf8(rootDir, relativePath) {
16
+ return fs.readFile(path.join(rootDir, relativePath), "utf8");
17
+ }
18
+
19
+ export async function execFileWithDiagnostics(command, args, options) {
20
+ try {
21
+ return await execFileAsync(command, args, options);
22
+ } catch (error) {
23
+ const stdout = String(error.stdout ?? "").trim();
24
+ const stderr = String(error.stderr ?? "").trim();
25
+ assert.fail([
26
+ `Command failed: ${command} ${args.join(" ")}`,
27
+ stdout ? `stdout:\n${stdout}` : undefined,
28
+ stderr ? `stderr:\n${stderr}` : undefined,
29
+ !stdout && !stderr ? String(error) : undefined,
30
+ ].filter(Boolean).join("\n"));
31
+ }
32
+ }
33
+
34
+ export async function importModule(rootDir, relativePath) {
35
+ return import(pathToFileURL(path.join(rootDir, relativePath)).href);
36
+ }
37
+
38
+ export async function stagePackageRepository(stagedRepoRoot) {
39
+ await Promise.all([
40
+ copyDirectory(path.join(repoRoot, "cli"), path.join(stagedRepoRoot, "cli")),
41
+ copyDirectory(path.join(repoRoot, "starter"), path.join(stagedRepoRoot, "starter")),
42
+ copyDirectory(
43
+ path.join(repoRoot, "packages/ui/src"),
44
+ path.join(stagedRepoRoot, "packages/ui/src"),
45
+ ),
46
+ copyDirectory(
47
+ path.join(repoRoot, "packages/toolcraft-runtime/src"),
48
+ path.join(stagedRepoRoot, "packages/toolcraft-runtime/src"),
49
+ ),
50
+ ]);
51
+ }
52
+
53
+ async function collectRelativeFiles(rootDir, relativeDir = "") {
54
+ const entries = await fs.readdir(path.join(rootDir, relativeDir), {
55
+ withFileTypes: true,
56
+ });
57
+ const files = [];
58
+
59
+ for (const entry of entries) {
60
+ const relativePath = path.posix.join(relativeDir, entry.name);
61
+ if (entry.isDirectory()) {
62
+ files.push(...(await collectRelativeFiles(rootDir, relativePath)));
63
+ } else if (entry.isFile() || entry.isSymbolicLink()) {
64
+ files.push(relativePath);
65
+ }
66
+ }
67
+ return files.sort();
68
+ }
69
+
70
+ async function assertPreparedTemplateSource({
71
+ derivedTargetFiles = [],
72
+ sourceDir,
73
+ targetDir,
74
+ }) {
75
+ const [sourceFiles, targetFiles] = await Promise.all([
76
+ collectRelativeFiles(sourceDir),
77
+ collectRelativeFiles(targetDir),
78
+ ]);
79
+ assert.deepEqual(
80
+ targetFiles,
81
+ [
82
+ ...sourceFiles,
83
+ ...derivedTargetFiles.map(([targetPath]) => targetPath),
84
+ ].sort(),
85
+ `Prepared template inventory must match ${sourceDir}.`,
86
+ );
87
+ for (const relativePath of sourceFiles) {
88
+ assert.deepEqual(
89
+ await fs.readFile(path.join(targetDir, relativePath)),
90
+ await fs.readFile(path.join(sourceDir, relativePath)),
91
+ `Prepared template content mismatch: ${relativePath}`,
92
+ );
93
+ }
94
+ for (const [targetPath, sourcePath] of derivedTargetFiles) {
95
+ assert.deepEqual(
96
+ await fs.readFile(path.join(targetDir, targetPath)),
97
+ await fs.readFile(path.join(sourceDir, sourcePath)),
98
+ `Prepared derived template content mismatch: ${targetPath}`,
99
+ );
100
+ }
101
+ }
102
+
103
+ export async function prepareStagedCliPackage(stagedCliRoot, environment) {
104
+ const packageJson = JSON.parse(await readUtf8(stagedCliRoot, "package.json"));
105
+ assert.equal(
106
+ packageJson.scripts.prepack,
107
+ "node scripts/prepare-pack.mjs",
108
+ "The published package must keep the canonical prepare entry point.",
109
+ );
110
+ await fs.rm(path.join(stagedCliRoot, "templates"), {
111
+ force: true,
112
+ recursive: true,
113
+ });
114
+ await execFileWithDiagnostics(
115
+ process.execPath,
116
+ [path.join(stagedCliRoot, "scripts/prepare-pack.mjs")],
117
+ { cwd: stagedCliRoot, env: environment },
118
+ );
119
+ const stagedRepoRoot = path.resolve(stagedCliRoot, "..");
120
+ const starterTemplateRoot = path.join(stagedCliRoot, "templates/starter");
121
+ await Promise.all([
122
+ assertPreparedTemplateSource({
123
+ derivedTargetFiles: [["gitignore", ".gitignore"]],
124
+ sourceDir: path.join(stagedRepoRoot, "starter"),
125
+ targetDir: starterTemplateRoot,
126
+ }),
127
+ assertPreparedTemplateSource({
128
+ sourceDir: path.join(stagedRepoRoot, "packages/toolcraft-runtime/src"),
129
+ targetDir: path.join(stagedCliRoot, "templates/runtime"),
130
+ }),
131
+ assertPreparedTemplateSource({
132
+ sourceDir: path.join(stagedRepoRoot, "packages/ui/src"),
133
+ targetDir: path.join(stagedCliRoot, "templates/ui"),
134
+ }),
135
+ ]);
136
+ return collectPackagedTemplateOwnership(starterTemplateRoot);
137
+ }
138
+
139
+ export async function linkPackagedCliDependencies(packageRoot) {
140
+ const packageJson = JSON.parse(
141
+ await fs.readFile(path.join(packageRoot, "package.json"), "utf8"),
142
+ );
143
+
144
+ for (const packageName of Object.keys(packageJson.dependencies ?? {})) {
145
+ const sourcePath = await fs.realpath(
146
+ path.join(repoRoot, "cli/node_modules", packageName),
147
+ );
148
+ const targetPath = path.join(packageRoot, "node_modules", packageName);
149
+ await fs.mkdir(path.dirname(targetPath), { recursive: true });
150
+ await fs.symlink(sourcePath, targetPath, "dir");
151
+ }
152
+ }
153
+
154
+ export function createPassedTestTask({ annotations = [], filePath, name }) {
155
+ return {
156
+ annotations: () => annotations,
157
+ module: { moduleId: filePath },
158
+ name,
159
+ options: { fails: false },
160
+ result: () => ({ state: "passed" }),
161
+ };
162
+ }
163
+
164
+ export async function collectPackagedTemplateOwnership(templateRoot) {
165
+ const sourceOwnership = await importModule(
166
+ templateRoot,
167
+ "scripts/toolcraft-source-ownership.mjs",
168
+ );
169
+ const [expectedPaths, templateLocalPaths] = await Promise.all([
170
+ sourceOwnership.collectToolcraftFrameworkOwnedGeneratedPaths(templateRoot),
171
+ sourceOwnership.collectToolcraftFrameworkOwnedLocalPaths(templateRoot),
172
+ ]);
173
+ assert.equal(
174
+ templateLocalPaths.length,
175
+ expectedPaths.length,
176
+ "Packaged template ownership normalization must not hide path collisions.",
177
+ );
178
+ const templateSourcePaths = Object.fromEntries(
179
+ templateLocalPaths.map((relativePath) => [
180
+ sourceOwnership.toToolcraftGeneratedPath(relativePath),
181
+ relativePath,
182
+ ]),
183
+ );
184
+ assert.deepEqual(
185
+ Object.keys(templateSourcePaths).sort(),
186
+ expectedPaths,
187
+ "Packaged template ownership normalization must be complete and unique.",
188
+ );
189
+ const templateHashes = Object.fromEntries(
190
+ await Promise.all(
191
+ expectedPaths.map(async (relativePath) => [
192
+ relativePath,
193
+ createHash("sha256")
194
+ .update(
195
+ await fs.readFile(
196
+ path.join(templateRoot, templateSourcePaths[relativePath]),
197
+ ),
198
+ )
199
+ .digest("hex"),
200
+ ]),
201
+ ),
202
+ );
203
+ return { expectedPaths, templateHashes, templateSourcePaths };
204
+ }
205
+
206
+ export async function verifyCanonicalProtectedManifest({
207
+ expectedPaths,
208
+ generatedManifest,
209
+ integrityPolicy,
210
+ targetDir,
211
+ templateHashes,
212
+ templateRoot,
213
+ templateSourcePaths,
214
+ }) {
215
+ const protectedPaths = Object.keys(generatedManifest.protectedFiles).sort();
216
+ assert.deepEqual(
217
+ protectedPaths,
218
+ expectedPaths,
219
+ "The package manifest must cover the complete canonical ownership set.",
220
+ );
221
+ for (const relativePath of integrityPolicy.requiredProtectedTrustRootFilePaths) {
222
+ assert.ok(
223
+ protectedPaths.includes(relativePath),
224
+ `Missing canonical generated trust root: ${relativePath}`,
225
+ );
226
+ }
227
+ for (const relativePath of expectedPaths) {
228
+ const templatePath = path.join(
229
+ templateRoot,
230
+ templateSourcePaths[relativePath],
231
+ );
232
+ const generatedPath = path.join(targetDir, relativePath);
233
+ assert.equal(
234
+ (await fs.stat(templatePath)).isFile(),
235
+ true,
236
+ `Missing packaged template owner: ${templateSourcePaths[relativePath]}`,
237
+ );
238
+ assert.equal(
239
+ createHash("sha256").update(await fs.readFile(templatePath)).digest("hex"),
240
+ templateHashes[relativePath],
241
+ `Packaged template owner hash mismatch: ${templateSourcePaths[relativePath]}`,
242
+ );
243
+ assert.equal(
244
+ (await fs.stat(generatedPath)).isFile(),
245
+ true,
246
+ `Missing generated protected owner: ${relativePath}`,
247
+ );
248
+ assert.equal(
249
+ generatedManifest.protectedFiles[relativePath],
250
+ createHash("sha256").update(await fs.readFile(generatedPath)).digest("hex"),
251
+ `Generated protected owner hash mismatch: ${relativePath}`,
252
+ );
253
+ }
254
+ }
@@ -1,47 +1,25 @@
1
1
  import assert from "node:assert/strict";
2
- import { execFile } from "node:child_process";
3
2
  import fs from "node:fs/promises";
4
3
  import os from "node:os";
5
4
  import path from "node:path";
6
- import { fileURLToPath } from "node:url";
7
- import { promisify } from "node:util";
8
5
  import { it } from "node:test";
9
6
 
10
- import { copyDirectory } from "./copy-recursive.mjs";
11
-
12
- const execFileAsync = promisify(execFile);
13
- const cliSrcDir = path.dirname(fileURLToPath(import.meta.url));
14
- const repoRoot = path.resolve(cliSrcDir, "../..");
15
-
16
- async function stagePackageRepository(stagedRepoRoot) {
17
- await Promise.all([
18
- copyDirectory(path.join(repoRoot, "cli"), path.join(stagedRepoRoot, "cli")),
19
- copyDirectory(path.join(repoRoot, "starter"), path.join(stagedRepoRoot, "starter")),
20
- copyDirectory(
21
- path.join(repoRoot, "packages/ui/src"),
22
- path.join(stagedRepoRoot, "packages/ui/src"),
23
- ),
24
- copyDirectory(
25
- path.join(repoRoot, "packages/toolcraft-runtime/src"),
26
- path.join(stagedRepoRoot, "packages/toolcraft-runtime/src"),
27
- ),
28
- ]);
29
- }
30
-
31
- async function linkPackagedCliDependencies(packageRoot) {
32
- const packageJson = JSON.parse(
33
- await fs.readFile(path.join(packageRoot, "package.json"), "utf8"),
34
- );
35
-
36
- for (const packageName of Object.keys(packageJson.dependencies ?? {})) {
37
- const sourcePath = await fs.realpath(
38
- path.join(repoRoot, "cli/node_modules", packageName),
39
- );
40
- const targetPath = path.join(packageRoot, "node_modules", packageName);
41
- await fs.mkdir(path.dirname(targetPath), { recursive: true });
42
- await fs.symlink(sourcePath, targetPath, "dir");
43
- }
44
- }
7
+ import {
8
+ createGeneratedCommandEnvironment,
9
+ } from "./generate-test-dependency-sandbox.mjs";
10
+ import {
11
+ collectPackagedTemplateOwnership,
12
+ execFileWithDiagnostics,
13
+ importModule,
14
+ linkPackagedCliDependencies,
15
+ prepareStagedCliPackage,
16
+ readUtf8,
17
+ stagePackageRepository,
18
+ verifyCanonicalProtectedManifest,
19
+ } from "./packaged-template-fallback-helpers.mjs";
20
+ import {
21
+ verifyPackagedRuntimeSelection,
22
+ } from "./packaged-template-runtime-assertions.mjs";
45
23
 
46
24
  it("packs, executes, and verifies the isolated npm package fallback", async () => {
47
25
  const tempRoot = await fs.mkdtemp(
@@ -59,19 +37,42 @@ it("packs, executes, and verifies the isolated npm package fallback", async () =
59
37
  fs.mkdir(tarballRoot, { recursive: true }),
60
38
  fs.mkdir(extractedRoot, { recursive: true }),
61
39
  fs.mkdir(outputRoot, { recursive: true }),
40
+ fs.mkdir(path.join(tempRoot, "npm-cache"), { recursive: true }),
62
41
  ]);
63
42
 
64
- const packResult = await execFileAsync(
43
+ const packageEnvironment = createGeneratedCommandEnvironment("npm", {
44
+ NODE_TEST_CONTEXT: "reserved-parent-test-state",
45
+ npm_config_cache: path.join(tempRoot, "npm-cache"),
46
+ });
47
+ assert.equal(
48
+ Object.hasOwn(packageEnvironment, "NODE_TEST_CONTEXT"),
49
+ false,
50
+ "npm lifecycle commands must not inherit Node's parent test context.",
51
+ );
52
+ assert.equal(
53
+ packageEnvironment.npm_config_cache,
54
+ path.join(tempRoot, "npm-cache"),
55
+ "npm package tests must isolate their cache under the test root.",
56
+ );
57
+ const preparedTemplateOwnership = await prepareStagedCliPackage(
58
+ stagedCliRoot,
59
+ packageEnvironment,
60
+ );
61
+ const packResult = await execFileWithDiagnostics(
65
62
  "npm",
66
- ["pack", "--silent", "--json", "--pack-destination", tarballRoot],
67
- { cwd: stagedCliRoot },
63
+ ["pack", "--ignore-scripts", "--json", "--pack-destination", tarballRoot],
64
+ { cwd: stagedCliRoot, env: packageEnvironment },
68
65
  );
69
66
  const [packedArtifact] = JSON.parse(packResult.stdout);
70
67
  assert.ok(packedArtifact?.filename, "npm pack must report its tarball filename.");
71
68
 
72
69
  const tarballPath = path.join(tarballRoot, packedArtifact.filename);
73
- await execFileAsync("tar", ["-xzf", tarballPath, "-C", extractedRoot]);
70
+ await execFileWithDiagnostics(
71
+ "tar",
72
+ ["-xzf", tarballPath, "-C", extractedRoot],
73
+ );
74
74
  const packageRoot = path.join(extractedRoot, "package");
75
+ const templateRoot = path.join(packageRoot, "templates/starter");
75
76
  const packagedFiles = [
76
77
  "bin/create-toolcraft-app.mjs",
77
78
  "bin/toolcraft.mjs",
@@ -80,6 +81,9 @@ it("packs, executes, and verifies the isolated npm package fallback", async () =
80
81
  "src/generate-test-windows-job.mjs",
81
82
  "src/generate-test-windows-job.ps1",
82
83
  "templates/starter/package.json",
84
+ "templates/starter/scripts/toolcraft-delivery-plan.mjs",
85
+ "templates/starter/scripts/toolcraft-vitest-runtime-contract.mjs",
86
+ "templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.mjs",
83
87
  "templates/runtime/index.ts",
84
88
  "templates/ui/index.ts",
85
89
  ];
@@ -90,9 +94,17 @@ it("packs, executes, and verifies the isolated npm package fallback", async () =
90
94
  `Missing packaged file: ${relativePath}`,
91
95
  );
92
96
  }
93
-
97
+ const packagedTemplateOwnership =
98
+ await collectPackagedTemplateOwnership(templateRoot);
99
+ assert.deepEqual(
100
+ packagedTemplateOwnership,
101
+ preparedTemplateOwnership,
102
+ "The tarball must preserve the complete prepared ownership inventory.",
103
+ );
104
+ const { expectedPaths, templateHashes, templateSourcePaths } =
105
+ packagedTemplateOwnership;
94
106
  await linkPackagedCliDependencies(packageRoot);
95
- await execFileAsync(
107
+ await execFileWithDiagnostics(
96
108
  process.execPath,
97
109
  [
98
110
  path.join(packageRoot, "bin/toolcraft.mjs"),
@@ -107,7 +119,7 @@ it("packs, executes, and verifies the isolated npm package fallback", async () =
107
119
  ],
108
120
  { cwd: outputRoot },
109
121
  );
110
- const compatibilityHelp = await execFileAsync(
122
+ const compatibilityHelp = await execFileWithDiagnostics(
111
123
  process.execPath,
112
124
  [path.join(packageRoot, "bin/create-toolcraft-app.mjs"), "--help"],
113
125
  { cwd: outputRoot },
@@ -115,7 +127,70 @@ it("packs, executes, and verifies the isolated npm package fallback", async () =
115
127
  assert.match(compatibilityHelp.stdout, /Usage:/);
116
128
 
117
129
  const targetDir = path.join(outputRoot, "packaged-app");
118
- const integrityResult = await execFileAsync(
130
+ const [
131
+ planModule,
132
+ runtimeContract,
133
+ runtimeReporter,
134
+ integrityPolicy,
135
+ ] =
136
+ await Promise.all([
137
+ importModule(targetDir, "scripts/toolcraft-delivery-plan.mjs"),
138
+ importModule(targetDir, "scripts/toolcraft-vitest-runtime-contract.mjs"),
139
+ importModule(
140
+ targetDir,
141
+ "scripts/toolcraft-vitest-runtime-evidence-reporter.mjs",
142
+ ),
143
+ importModule(targetDir, "scripts/toolcraft-integrity-policy.mjs"),
144
+ ]);
145
+ assert.equal(planModule.TOOLCRAFT_DELIVERY_PLAN_VERSION, 6);
146
+ await verifyPackagedRuntimeSelection({
147
+ runtimeContract,
148
+ runtimeReporter,
149
+ targetDir,
150
+ });
151
+ const generatedPackageJson = JSON.parse(
152
+ await readUtf8(targetDir, "package.json"),
153
+ );
154
+ assert.equal(
155
+ generatedPackageJson.scripts["reference:study"],
156
+ "node scripts/create-toolcraft-motion-reference-study.mjs",
157
+ );
158
+ const generatedManifest = JSON.parse(
159
+ await readUtf8(targetDir, "src/toolcraft/.toolcraft-manifest.json"),
160
+ );
161
+ await verifyCanonicalProtectedManifest({
162
+ expectedPaths,
163
+ generatedManifest,
164
+ integrityPolicy,
165
+ targetDir,
166
+ templateHashes,
167
+ templateRoot,
168
+ templateSourcePaths,
169
+ });
170
+ const trustRootPaths = new Set(
171
+ integrityPolicy.requiredProtectedTrustRootFilePaths,
172
+ );
173
+ const omittedPath = expectedPaths.find(
174
+ (relativePath) =>
175
+ relativePath.startsWith("scripts/") && !trustRootPaths.has(relativePath),
176
+ );
177
+ assert.equal(typeof omittedPath, "string");
178
+ assert.equal(trustRootPaths.has(omittedPath), false);
179
+ const incompleteManifest = structuredClone(generatedManifest);
180
+ delete incompleteManifest.protectedFiles[omittedPath];
181
+ await assert.rejects(
182
+ verifyCanonicalProtectedManifest({
183
+ expectedPaths,
184
+ generatedManifest: incompleteManifest,
185
+ integrityPolicy,
186
+ targetDir,
187
+ templateHashes,
188
+ templateRoot,
189
+ templateSourcePaths,
190
+ }),
191
+ /complete canonical ownership set/iu,
192
+ );
193
+ const integrityResult = await execFileWithDiagnostics(
119
194
  process.execPath,
120
195
  [
121
196
  path.join(targetDir, "scripts/check-toolcraft-integrity.mjs"),
@@ -0,0 +1,150 @@
1
+ import assert from "node:assert/strict";
2
+ import path from "node:path";
3
+
4
+ import { createPassedTestTask } from "./packaged-template-fallback-helpers.mjs";
5
+
6
+ export async function verifyPackagedRuntimeSelection({
7
+ runtimeContract,
8
+ runtimeReporter,
9
+ targetDir,
10
+ }) {
11
+ const runtimeRequirements = [
12
+ {
13
+ kind: "acceptance",
14
+ requirementId: "appearance.opacity",
15
+ testName: "opacity changes product output",
16
+ },
17
+ {
18
+ kind: "acceptance",
19
+ requirementId: "material.host",
20
+ testName: "keeps the material host valid",
21
+ },
22
+ ];
23
+ const targetedSelection =
24
+ runtimeContract.serializeToolcraftVitestRuntimeAcceptanceSelection([
25
+ "appearance.opacity",
26
+ ]);
27
+ assert.deepEqual(
28
+ runtimeContract.parseToolcraftVitestRuntimeAcceptanceSelection(
29
+ targetedSelection,
30
+ ),
31
+ ["appearance.opacity"],
32
+ );
33
+ const inheritedEnvironment = {
34
+ KEEP_ME: "yes",
35
+ [runtimeContract.TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV]:
36
+ "stale-selection",
37
+ };
38
+ const fullEnvironment =
39
+ runtimeContract.getToolcraftProductTestProcessEnvironment(
40
+ null,
41
+ inheritedEnvironment,
42
+ );
43
+ assert.equal(fullEnvironment.KEEP_ME, "yes");
44
+ assert.equal(
45
+ Object.hasOwn(
46
+ fullEnvironment,
47
+ runtimeContract.TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV,
48
+ ),
49
+ false,
50
+ );
51
+ const targetedEnvironment =
52
+ runtimeContract.getToolcraftProductTestProcessEnvironment(
53
+ ["appearance.opacity"],
54
+ inheritedEnvironment,
55
+ );
56
+ assert.deepEqual(
57
+ runtimeContract.selectToolcraftVitestRuntimeRequirements(
58
+ runtimeRequirements,
59
+ targetedEnvironment[
60
+ runtimeContract.TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV
61
+ ],
62
+ ),
63
+ [runtimeRequirements[0]],
64
+ );
65
+ assert.throws(
66
+ () => runtimeContract.selectToolcraftVitestRuntimeRequirements(
67
+ runtimeRequirements,
68
+ runtimeContract.serializeToolcraftVitestRuntimeAcceptanceSelection([
69
+ "unknown.requirement",
70
+ ]),
71
+ ),
72
+ /unknown acceptance requirement/iu,
73
+ );
74
+ assert.equal(typeof runtimeReporter.default, "function");
75
+ await assert.rejects(
76
+ new runtimeReporter.default().onTestRunEnd([]),
77
+ /marker was not executed/iu,
78
+ );
79
+
80
+ const previousSelection =
81
+ process.env[runtimeContract.TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV];
82
+ try {
83
+ const marker = createPassedTestTask({
84
+ annotations: [{
85
+ message:
86
+ runtimeContract.serializeToolcraftVitestRuntimeRequirements(
87
+ runtimeRequirements,
88
+ ),
89
+ type:
90
+ runtimeContract.TOOLCRAFT_VITEST_RUNTIME_REQUIREMENTS_ANNOTATION_TYPE,
91
+ }],
92
+ filePath: path.join(
93
+ targetDir,
94
+ "src/app/app-automated-runtime-evidence.test.ts",
95
+ ),
96
+ name: runtimeContract.TOOLCRAFT_VITEST_RUNTIME_MARKER_TEST_NAME,
97
+ });
98
+ const selectedProductTest = createPassedTestTask({
99
+ filePath: path.join(targetDir, "src/app/app-schema.test.ts"),
100
+ name: runtimeRequirements[0].testName,
101
+ });
102
+ const selectedTestModule = {
103
+ children: {
104
+ allTests: () => [marker, selectedProductTest],
105
+ },
106
+ };
107
+ process.env[
108
+ runtimeContract.TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV
109
+ ] = targetedSelection;
110
+ await new runtimeReporter.default().onTestRunEnd([selectedTestModule]);
111
+
112
+ delete process.env[
113
+ runtimeContract.TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV
114
+ ];
115
+ await assert.rejects(
116
+ new runtimeReporter.default().onTestRunEnd([selectedTestModule]),
117
+ /Missing required automated test.*material host/iu,
118
+ );
119
+
120
+ const emptyMarker = createPassedTestTask({
121
+ annotations: [{
122
+ message:
123
+ runtimeContract.serializeToolcraftVitestRuntimeRequirements([]),
124
+ type:
125
+ runtimeContract.TOOLCRAFT_VITEST_RUNTIME_REQUIREMENTS_ANNOTATION_TYPE,
126
+ }],
127
+ filePath: path.join(
128
+ targetDir,
129
+ "src/app/app-automated-runtime-evidence.test.ts",
130
+ ),
131
+ name: runtimeContract.TOOLCRAFT_VITEST_RUNTIME_MARKER_TEST_NAME,
132
+ });
133
+ await assert.rejects(
134
+ new runtimeReporter.default().onTestRunEnd([{
135
+ children: { allTests: () => [emptyMarker] },
136
+ }]),
137
+ /at least one runtime requirement/iu,
138
+ );
139
+ } finally {
140
+ if (previousSelection === undefined) {
141
+ delete process.env[
142
+ runtimeContract.TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV
143
+ ];
144
+ } else {
145
+ process.env[
146
+ runtimeContract.TOOLCRAFT_VITEST_RUNTIME_ACCEPTANCE_SELECTION_ENV
147
+ ] = previousSelection;
148
+ }
149
+ }
150
+ }