@pixel-point/toolcraft 0.0.16 → 0.0.18
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.
- package/package.json +1 -1
- package/src/generate-performance-iteration-execution.test.mjs +2 -2
- package/src/generate-test-demand-only-lifecycle.mjs +14 -3
- package/src/generate-test-dependency-sandbox.mjs +42 -5
- package/src/generate-test-doc-assertions.mjs +109 -69
- package/src/generate-test-doc-assertions.test.mjs +65 -0
- package/src/generate-test-doc-policy-assertions.mjs +92 -0
- package/src/generate-test-file-assertions.mjs +36 -118
- package/src/generate-test-output-assertions.mjs +95 -0
- package/src/generate-test-package-assertions.mjs +6 -0
- package/src/generate-test-performance-boundary-assertions.mjs +45 -0
- package/src/generate-test-product-fixture.mjs +1 -0
- package/src/generate-test-product-fixture.test.mjs +18 -0
- package/src/generate-test-product-iteration.mjs +1 -0
- package/src/generate-test-product-iteration.test.mjs +18 -0
- package/src/generate-test-runtime-boundary-assertions.mjs +158 -0
- package/src/generate-test-standalone-assertions.mjs +10 -0
- package/src/generate-test-standalone-delivery-stages.mjs +14 -6
- package/src/generate.test.mjs +14 -0
- package/templates/runtime/contracts/component-contracts.choices.test.ts +59 -12
- package/templates/runtime/contracts/component-contracts.choices.ts +58 -12
- package/templates/runtime/contracts/component-contracts.inputs.test.ts +6 -6
- package/templates/runtime/contracts/component-contracts.inputs.ts +6 -6
- package/templates/runtime/contracts/component-contracts.media-custom.test.ts +8 -2
- package/templates/runtime/contracts/component-contracts.media-custom.ts +8 -2
- package/templates/runtime/contracts/component-contracts.runtime-acceptance.test.ts +21 -6
- package/templates/runtime/contracts/component-contracts.runtime-labels.test.ts +7 -1
- package/templates/runtime/contracts/component-contracts.runtime-panels.test.ts +4 -1
- package/templates/runtime/contracts/component-contracts.runtime-shell.test.ts +4 -1
- package/templates/runtime/contracts/component-contracts.runtime.ts +15 -10
- package/templates/runtime/contracts/component-contracts.test.ts +2 -0
- package/templates/runtime/contracts/decision-contracts.test.ts +43 -4
- package/templates/runtime/contracts/decision-contracts.ts +10 -10
- package/templates/runtime/contracts/performance-verification-policy.test.ts +59 -6
- package/templates/runtime/contracts/performance-verification-policy.ts +5 -2
- package/templates/runtime/export/artifact-download.test.ts +71 -0
- package/templates/runtime/export/artifact-download.ts +80 -0
- package/templates/runtime/export/artifact-export-request.ts +23 -0
- package/templates/runtime/export/artifact-export-settings.test.ts +75 -0
- package/templates/runtime/export/artifact-export-settings.ts +96 -0
- package/templates/runtime/export/artifact-frame-renderer.test.ts +107 -0
- package/templates/runtime/export/artifact-frame-renderer.ts +96 -0
- package/templates/runtime/export/artifact-frame-state.test.ts +54 -0
- package/templates/runtime/export/artifact-frame-state.ts +44 -0
- package/templates/runtime/export/artifact-scene-frame.test.ts +84 -0
- package/templates/runtime/export/artifact-scene-frame.ts +118 -0
- package/templates/runtime/export/export-background.ts +46 -0
- package/templates/runtime/export/export-error.ts +43 -0
- package/templates/runtime/export/export.test.ts +49 -226
- package/templates/runtime/export/image-artifact-export.test.ts +111 -0
- package/templates/runtime/export/image-artifact-export.ts +145 -0
- package/templates/runtime/export/index.ts +44 -3
- package/templates/runtime/export/product-export-renderer.test.ts +77 -0
- package/templates/runtime/export/product-export-renderer.ts +63 -0
- package/templates/runtime/export/video-artifact-export.test.ts +166 -0
- package/templates/runtime/export/video-artifact-export.ts +164 -0
- package/templates/runtime/export/video-encoding-backend.ts +124 -0
- package/templates/runtime/export/video-encoding-policy.test.ts +68 -0
- package/templates/runtime/export/video-encoding-policy.ts +86 -0
- package/templates/runtime/export/video-frame-schedule.test.ts +58 -0
- package/templates/runtime/export/video-frame-schedule.ts +42 -0
- package/templates/runtime/index.ts +3 -0
- package/templates/runtime/model-import/model-import-limits.ts +15 -4
- package/templates/runtime/react/app-shell/runtime-public-api-runtime.test.tsx +291 -0
- package/templates/runtime/react/app-shell/runtime-public-api-test-support.ts +21 -0
- package/templates/runtime/react/app-shell/runtime-public-api.test.tsx +15 -304
- package/templates/runtime/react/app-shell/toolcraft-app.scene-export.test.tsx +41 -27
- package/templates/runtime/react/app-shell/toolcraft-app.tsx +39 -11
- package/templates/runtime/react/app-shell/toolcraft-source-asset-context.test.tsx +16 -57
- package/templates/runtime/react/app-shell/toolcraft-source-asset-context.tsx +75 -434
- package/templates/runtime/react/app-shell/toolcraft-source-asset-owner.test.ts +194 -0
- package/templates/runtime/react/app-shell/toolcraft-source-asset-owner.ts +227 -0
- package/templates/runtime/react/app-shell/toolcraft-source-asset-provider-ownership.test.tsx +243 -0
- package/templates/runtime/react/app-shell/toolcraft-source-asset-test-support.ts +51 -0
- package/templates/runtime/react/app-shell/toolcraft-unavailable-resource-proof.test.ts +138 -0
- package/templates/runtime/react/app-shell/toolcraft-unavailable-resource-proof.ts +378 -0
- package/templates/runtime/react/canvas/canvas-shell-rendering.test.tsx +76 -0
- package/templates/runtime/react/canvas/canvas-shell-test-utils.tsx +13 -1
- package/templates/runtime/react/canvas/canvas-shell.tsx +16 -1
- package/templates/runtime/react/canvas/product-scene-surface.test.tsx +195 -0
- package/templates/runtime/react/canvas/product-scene-surface.tsx +155 -0
- package/templates/runtime/react/canvas/runtime-scene-export.ts +1 -1
- package/templates/runtime/react/controls-panel/__tests__/control-conditions.test.ts +61 -0
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.collection-actions.test.tsx +89 -0
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.control-visibility.test.tsx +40 -19
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.footer-actions.test.tsx +7 -12
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.scene-export-actions.test.tsx +18 -84
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-collection.test.tsx +62 -0
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-color-bank.test.tsx +67 -0
- package/templates/runtime/react/controls-panel/actions/controls-panel-actions.ts +43 -87
- package/templates/runtime/react/controls-panel/actions/export-action-runner.ts +68 -0
- package/templates/runtime/react/controls-panel/conditions/control-conditions.ts +32 -119
- package/templates/runtime/react/controls-panel/layout/controls-panel-control-group.tsx +5 -2
- package/templates/runtime/react/controls-panel/layout/controls-panel-layout.tsx +10 -8
- package/templates/runtime/react/controls-panel/layout/controls-panel-section.tsx +3 -3
- package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-item-fields.test.tsx +63 -0
- package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-item-fields.tsx +138 -0
- package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-items.tsx +104 -0
- package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-renderer.tsx +115 -236
- package/templates/runtime/react/controls-panel/renderers/controls-panel-file-drop-item-controls.test.tsx +95 -0
- package/templates/runtime/react/controls-panel/renderers/controls-panel-file-drop-item-controls.tsx +82 -0
- package/templates/runtime/react/controls-panel/renderers/controls-panel-media-renderer.test.tsx +73 -1
- package/templates/runtime/react/controls-panel/renderers/controls-panel-media-renderer.tsx +50 -1
- package/templates/runtime/react/controls-panel/renderers/controls-panel-renderer-registry.test.ts +1 -1
- package/templates/runtime/react/controls-panel/renderers/controls-panel-renderer-registry.ts +2 -1
- package/templates/runtime/react/controls-panel/values/controls-panel-collection-values.ts +38 -6
- package/templates/runtime/react/controls-panel/values/controls-panel-value-labels.ts +1 -0
- package/templates/runtime/react/index.ts +4 -0
- package/templates/runtime/react/model-rendering/model-export.ts +1 -1
- package/templates/runtime/react/orientation-gizmo/orientation-gizmo-selection.ts +5 -5
- package/templates/runtime/react/orientation-gizmo/use-toolcraft-orientation-control-selection.ts +2 -2
- package/templates/runtime/react/panel-host/panel-host-runtime-placement.test.tsx +30 -0
- package/templates/runtime/react/panel-host/panel-host.tsx +4 -0
- package/templates/runtime/scene/scene-bounds.test.ts +23 -0
- package/templates/runtime/scene/scene-bounds.ts +32 -19
- package/templates/runtime/schema/app-capabilities.test.ts +4 -0
- package/templates/runtime/schema/canvas-render-scale.ts +62 -0
- package/templates/runtime/schema/collection-item-controls.ts +29 -0
- package/templates/runtime/schema/control-applicability.test.ts +127 -0
- package/templates/runtime/schema/control-applicability.ts +433 -0
- package/templates/runtime/schema/control-schema-normalization.ts +177 -11
- package/templates/runtime/schema/controls-panel-actions.ts +2 -2
- package/templates/runtime/schema/controls-panel-section-id.test.ts +1 -1
- package/templates/runtime/schema/controls-panel-section-layout.ts +14 -9
- package/templates/runtime/schema/controls-panel-section-roundtrip.test.ts +62 -3
- package/templates/runtime/schema/define-toolcraft.collection-actions-item-controls.test.ts +127 -0
- package/templates/runtime/schema/define-toolcraft.control-sections.test.ts +10 -4
- package/templates/runtime/schema/define-toolcraft.file-drop-item-controls.test.ts +98 -0
- package/templates/runtime/schema/define-toolcraft.file-drop-normalization.test.ts +27 -0
- package/templates/runtime/schema/define-toolcraft.segmented-control-fit.test.ts +20 -2
- package/templates/runtime/schema/define-toolcraft.setup-background.test.ts +1 -1
- package/templates/runtime/schema/define-toolcraft.setup-canvas.test.ts +16 -3
- package/templates/runtime/schema/define-toolcraft.setup-render-scale-timeline.test.ts +71 -3
- package/templates/runtime/schema/define-toolcraft.source-collection.test.ts +79 -0
- package/templates/runtime/schema/define-toolcraft.ts +1 -1
- package/templates/runtime/schema/runtime-setup-section.ts +24 -5
- package/templates/runtime/schema/schema-resolvers.ts +0 -56
- package/templates/runtime/schema/types.ts +72 -17
- package/templates/runtime/state/canvas-background-state.ts +6 -0
- package/templates/runtime/testing/performance-render-plan-integration.test.ts +64 -0
- package/templates/runtime/testing/performance-renderer-pipeline-validation.ts +18 -1
- package/templates/starter/AGENTS.md +18 -15
- package/templates/starter/NOTICE.md +6 -0
- package/templates/starter/docs/toolcraft/README.md +2 -1
- package/templates/starter/docs/toolcraft/acceptance-testing.md +23 -35
- package/templates/starter/docs/toolcraft/agent-worklog.md +18 -3
- package/templates/starter/docs/toolcraft/assembly-workflow.md +13 -5
- package/templates/starter/docs/toolcraft/component-rules.md +8 -6
- package/templates/starter/docs/toolcraft/core/control-selection.md +9 -3
- package/templates/starter/docs/toolcraft/core/layout.md +7 -7
- package/templates/starter/docs/toolcraft/core/media-upload.md +4 -2
- package/templates/starter/docs/toolcraft/core/performance.md +14 -3
- package/templates/starter/docs/toolcraft/core/runtime-boundary.md +16 -3
- package/templates/starter/docs/toolcraft/core/setup-export.md +49 -19
- package/templates/starter/docs/toolcraft/core/timeline-animation.md +4 -4
- package/templates/starter/docs/toolcraft/custom-controls.md +6 -4
- package/templates/starter/docs/toolcraft/decision-contract.md +3 -1
- package/templates/starter/docs/toolcraft/performance.md +20 -6
- package/templates/starter/docs/toolcraft/renderer-technique.md +5 -1
- package/templates/starter/docs/toolcraft/schema-reference.md +23 -25
- package/templates/starter/docs/toolcraft/workflow.md +7 -2
- package/templates/starter/e2e/app-browser-control-applicability-requirements.spec.ts +163 -0
- package/templates/starter/e2e/app-browser-control-coverage.spec.ts +33 -0
- package/templates/starter/e2e/app-browser-infinity-canvas-evidence.spec.ts +50 -3
- package/templates/starter/e2e/app-browser-orientation-evidence.spec.ts +174 -21
- package/templates/starter/e2e/app-browser-render-scale-evidence.spec.ts +60 -6
- package/templates/starter/e2e/app-browser-render-scale-requirements.spec.ts +77 -1
- package/templates/starter/e2e/app-browser-runtime-provenance.spec.ts +8 -0
- package/templates/starter/e2e/app-browser-runtime-reporter.spec.ts +35 -0
- package/templates/starter/e2e/app-browser-runtime-requirements.spec.ts +5 -34
- package/templates/starter/e2e/app-browser-semantic-evidence.spec.ts +61 -16
- package/templates/starter/e2e/app-browser-shell.spec.ts +13 -5
- package/templates/starter/e2e/app-performance-path-adapters.ts +8 -1
- package/templates/starter/e2e/app-performance.spec.ts +16 -9
- package/templates/starter/e2e/{browser-conditional-output-evidence-helpers.ts → browser-background-output-evidence.ts} +0 -68
- package/templates/starter/e2e/browser-control-applicability-evidence.ts +114 -0
- package/templates/starter/e2e/browser-infinity-canvas-evidence.ts +29 -341
- package/templates/starter/e2e/browser-infinity-canvas-unavailable-image-evidence.ts +370 -0
- package/templates/starter/e2e/browser-media-export-evidence.spec.ts +77 -0
- package/templates/starter/e2e/browser-media-export-evidence.ts +208 -0
- package/templates/starter/e2e/browser-orientation-gizmo-evidence-helpers.ts +4 -0
- package/templates/starter/e2e/browser-orientation-gizmo-live-preconditions.ts +86 -0
- package/templates/starter/e2e/browser-render-scale-evidence.ts +37 -29
- package/templates/starter/e2e/browser-runtime-applicability-requirements.ts +84 -0
- package/templates/starter/e2e/browser-runtime-evidence-reporter.ts +13 -3
- package/templates/starter/e2e/browser-runtime-evidence-requirements.ts +72 -35
- package/templates/starter/e2e/browser-semantic-evidence-test-helpers.ts +25 -0
- package/templates/starter/e2e/browser-standard-timeline-evidence.ts +106 -0
- package/templates/starter/e2e/decoded-pixel-observation.spec.ts +74 -0
- package/templates/starter/e2e/decoded-pixel-observation.ts +227 -0
- package/templates/starter/e2e/export-artifact-helpers.ts +206 -25
- package/templates/starter/e2e/image-artifact-inspection.spec.ts +41 -0
- package/templates/starter/e2e/image-artifact-inspection.ts +99 -0
- package/templates/starter/e2e/performance-canvas-helpers.ts +22 -21
- package/templates/starter/e2e/performance-canvas-quality-guard.spec.ts +312 -0
- package/templates/starter/e2e/performance-canvas-quality-guard.ts +196 -0
- package/templates/starter/e2e/performance-canvas-quality-observer.ts +351 -0
- package/templates/starter/e2e/performance-control-layout-helpers.ts +2 -2
- package/templates/starter/e2e/performance-path-adapter-contract.ts +4 -4
- package/templates/starter/e2e/performance-path-helpers.spec.ts +203 -70
- package/templates/starter/e2e/performance-path-helpers.ts +210 -91
- package/templates/starter/e2e/performance-pipeline-evidence-continuity.spec.ts +76 -0
- package/templates/starter/e2e/performance-pipeline-evidence-test-fixtures.ts +11 -2
- package/templates/starter/e2e/performance-pipeline-invariants.ts +47 -4
- package/templates/starter/e2e/performance-render-scale-runner.spec.ts +140 -38
- package/templates/starter/e2e/video-artifact-inspection.spec.ts +64 -0
- package/templates/starter/e2e/video-artifact-inspection.ts +281 -0
- package/templates/starter/gitignore +1 -0
- package/templates/starter/package.json +1 -0
- package/templates/starter/scripts/check-toolcraft-docs.mjs +17 -0
- package/templates/starter/scripts/toolcraft-contract-manifest.json +1 -0
- package/templates/starter/scripts/toolcraft-delivery-plan-authority.test.mjs +60 -0
- package/templates/starter/scripts/toolcraft-delivery-plan-errors.test.mjs +7 -2
- package/templates/starter/scripts/toolcraft-delivery-plan.mjs +7 -3
- package/templates/starter/scripts/toolcraft-product-boundary-ast.mjs +95 -103
- package/templates/starter/scripts/toolcraft-product-boundary-module-policy.mjs +101 -0
- package/templates/starter/scripts/toolcraft-product-boundary.mjs +12 -0
- package/templates/starter/scripts/toolcraft-product-boundary.test.mjs +0 -26
- package/templates/starter/scripts/toolcraft-product-control-bindings.mjs +182 -0
- package/templates/starter/scripts/toolcraft-product-control-boundary.mjs +146 -0
- package/templates/starter/scripts/toolcraft-product-control-boundary.test.mjs +186 -0
- package/templates/starter/scripts/toolcraft-product-evidence-boundary.test.mjs +85 -20
- package/templates/starter/scripts/toolcraft-product-evidence-import-policy.mjs +43 -0
- package/templates/starter/scripts/toolcraft-product-export-boundary.mjs +157 -0
- package/templates/starter/scripts/toolcraft-product-export-boundary.test.mjs +196 -0
- package/templates/starter/scripts/toolcraft-typescript-analysis.d.mts +73 -0
- package/templates/starter/scripts/toolcraft-typescript-source-evidence-structure.test.mjs +20 -0
- package/templates/starter/scripts/toolcraft-typescript-source-evidence.mjs +1 -0
- package/templates/starter/scripts/toolcraft-unavailable-resource-evidence-facade-test-helpers.mjs +318 -0
- package/templates/starter/scripts/toolcraft-unavailable-resource-evidence-facade.test.mjs +157 -206
- package/templates/starter/scripts/toolcraft-verification-inventory.mjs +1 -0
- package/templates/starter/scripts/toolcraft-verification-receipt.test.mjs +51 -0
- package/templates/starter/scripts/toolcraft-vite-env-activation.test.mjs +128 -59
- package/templates/starter/src/app/acceptance/artifact-export-intent.ts +130 -0
- package/templates/starter/src/app/acceptance/conditions.ts +1 -1
- package/templates/starter/src/app/acceptance/control-acceptance-context.ts +2 -2
- package/templates/starter/src/app/acceptance/control-acceptance-coverage.ts +6 -20
- package/templates/starter/src/app/acceptance/control-acceptance-kind-rules.ts +24 -5
- package/templates/starter/src/app/acceptance/control-acceptance-policy.ts +2 -13
- package/templates/starter/src/app/acceptance/control-applicability-cases.test.ts +321 -0
- package/templates/starter/src/app/acceptance/control-applicability-cases.ts +290 -0
- package/templates/starter/src/app/acceptance/control-applicability.ts +332 -0
- package/templates/starter/src/app/acceptance/control-layout-dependency-rules.ts +20 -9
- package/templates/starter/src/app/acceptance/control-layout-entity-rules.ts +4 -6
- package/templates/starter/src/app/acceptance/control-layout-model.ts +4 -4
- package/templates/starter/src/app/acceptance/control-layout-section-rules.ts +3 -10
- package/templates/starter/src/app/acceptance/control-parts.ts +8 -0
- package/templates/starter/src/app/acceptance/control-section-entity-cohesion.test.ts +215 -0
- package/templates/starter/src/app/acceptance/control-section-entity-cohesion.ts +132 -0
- package/templates/starter/src/app/acceptance/control-section-inventory.test.ts +87 -0
- package/templates/starter/src/app/acceptance/control-section-inventory.ts +74 -44
- package/templates/starter/src/app/acceptance/custom-controls.ts +11 -3
- package/templates/starter/src/app/acceptance/export-artifact-coverage.ts +113 -0
- package/templates/starter/src/app/acceptance/inline-layout.ts +64 -9
- package/templates/starter/src/app/acceptance/media-upload.ts +5 -1
- package/templates/starter/src/app/acceptance/orientation-gizmo.ts +18 -11
- package/templates/starter/src/app/acceptance/output-background-rules.ts +2 -2
- package/templates/starter/src/app/acceptance/output-export-layout-rules.ts +18 -10
- package/templates/starter/src/app/acceptance/output-export-model.ts +54 -11
- package/templates/starter/src/app/acceptance/output-export.ts +35 -12
- package/templates/starter/src/app/acceptance/output-video-export-rules.ts +99 -0
- package/templates/starter/src/app/acceptance/types.ts +30 -8
- package/templates/starter/src/app/acceptance/validate-coverage.ts +20 -2
- package/templates/starter/src/app/starter-acceptance.artifact-export-intent.test.ts +239 -0
- package/templates/starter/src/app/starter-acceptance.background-export.test.ts +33 -0
- package/templates/starter/src/app/starter-acceptance.canvas-sizing.test.ts +16 -1
- package/templates/starter/src/app/starter-acceptance.compound-part-coverage.test.ts +65 -0
- package/templates/starter/src/app/starter-acceptance.contract-fixtures.test.ts +41 -0
- package/templates/starter/src/app/starter-acceptance.contract-fixtures.ts +112 -16
- package/templates/starter/src/app/starter-acceptance.control-applicability.test.ts +224 -0
- package/templates/starter/src/app/starter-acceptance.control-order.test.ts +58 -3
- package/templates/starter/src/app/starter-acceptance.control-state.test.ts +0 -111
- package/templates/starter/src/app/starter-acceptance.custom-control-collections.test.ts +3 -1
- package/templates/starter/src/app/starter-acceptance.custom-control-valid.test.ts +1 -1
- package/templates/starter/src/app/starter-acceptance.export-artifact.test.ts +131 -0
- package/templates/starter/src/app/starter-acceptance.export-test-utils.ts +22 -0
- package/templates/starter/src/app/{starter-acceptance.image-video-export-settings.test.ts → starter-acceptance.image-export-settings.test.ts} +37 -9
- package/templates/starter/src/app/starter-acceptance.interaction-ownership.test.ts +12 -0
- package/templates/starter/src/app/starter-acceptance.keyframes.test.ts +14 -4
- package/templates/starter/src/app/starter-acceptance.media-upload.fixtures.ts +11 -1
- package/templates/starter/src/app/starter-acceptance.media-upload.test.ts +28 -0
- package/templates/starter/src/app/starter-acceptance.output-export-intent.test.ts +384 -0
- package/templates/starter/src/app/starter-acceptance.output-export-rules.test.ts +46 -1
- package/templates/starter/src/app/starter-acceptance.product-output-export.test.ts +112 -105
- package/templates/starter/src/app/starter-acceptance.product-readiness.test.ts +12 -0
- package/templates/starter/src/app/starter-acceptance.section-cohesion.test.ts +1 -1
- package/templates/starter/src/app/starter-acceptance.section-dependencies.test.ts +35 -24
- package/templates/starter/src/app/starter-acceptance.section-size.test.ts +72 -0
- package/templates/starter/src/app/starter-acceptance.ts +13 -2
- package/templates/starter/src/app/starter-acceptance.video-export-settings.test.ts +336 -0
- package/templates/starter/src/app/starter-acceptance.view-interaction.test.ts +8 -0
- package/templates/starter/src/app/starter-performance-test-utils.ts +103 -0
- package/templates/starter/src/app/starter-performance.gates.test.ts +231 -278
- package/templates/starter/src/app/starter-performance.lifecycle.test.ts +261 -0
- package/templates/starter/src/app/test-evidence/browser-runtime-contract.ts +4 -2
- package/templates/starter/src/routes/index.tsx +2 -0
- package/templates/ui/components/composites/tabs.tsx +2 -2
- package/templates/ui/components/controls/collection-actions/collection-item-groups.test.tsx +38 -0
- package/templates/ui/components/controls/collection-actions/collection-item-groups.tsx +36 -0
- package/templates/ui/components/controls/collection-actions/index.ts +2 -0
- package/templates/ui/components/controls/file-drop/file-drop-collection-control.tsx +137 -0
- package/templates/ui/components/controls/file-drop/file-drop-control.test.tsx +189 -0
- package/templates/ui/components/controls/file-drop/file-drop-control.tsx +81 -88
- package/templates/ui/components/controls/file-drop/file-drop-presentation.tsx +131 -9
- package/templates/ui/components/controls/file-drop/file-drop-types.ts +36 -22
- package/templates/ui/components/controls/file-drop/index.ts +1 -0
- package/templates/ui/components/controls/index.ts +3 -0
- package/templates/ui/components/controls/range-slider/range-slider-control.tsx +1 -1
- package/templates/ui/components/controls/range-slider/range-slider-value.test.ts +14 -0
- package/templates/ui/components/controls/range-slider/range-slider-value.ts +3 -2
- package/templates/runtime/export/export.ts +0 -166
- package/templates/starter/src/app/acceptance/condition-exclusivity.test.ts +0 -60
- package/templates/starter/src/app/acceptance/condition-exclusivity.ts +0 -221
|
@@ -64,6 +64,12 @@ export function getToolcraftInfiniteCanvasBackgroundColor(
|
|
|
64
64
|
return undefined;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
return getToolcraftRuntimeBackgroundColor(state);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function getToolcraftRuntimeBackgroundColor(
|
|
71
|
+
state: ToolcraftState,
|
|
72
|
+
): string | undefined {
|
|
67
73
|
const background = getToolcraftRuntimeSetupBackgroundControls(state.schema);
|
|
68
74
|
const value = background
|
|
69
75
|
? state.values[background.color.target] ?? background.color.defaultValue
|
|
@@ -34,6 +34,70 @@ describe("Toolcraft render plan integration", () => {
|
|
|
34
34
|
);
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
+
it("allows off-main retina rasterization to preserve exact backing during viewport zoom", () => {
|
|
38
|
+
const pass = createPass({
|
|
39
|
+
cacheKey: undefined,
|
|
40
|
+
cost: {
|
|
41
|
+
dimensions: ["output-units"],
|
|
42
|
+
frequency: "interaction",
|
|
43
|
+
relationship: "linear",
|
|
44
|
+
},
|
|
45
|
+
id: "viewport-raster",
|
|
46
|
+
inputs: ["canvas.viewport.zoom"],
|
|
47
|
+
invalidatedBy: ["canvas.viewport.zoom"],
|
|
48
|
+
kind: "rasterize",
|
|
49
|
+
lifecycle: { cache: "none", resourceScope: "interaction" },
|
|
50
|
+
quality: "retina",
|
|
51
|
+
runsOn: "worker",
|
|
52
|
+
});
|
|
53
|
+
const baseConfig = createEnvelopeConfig({ pass });
|
|
54
|
+
const rendererPipeline = {
|
|
55
|
+
...baseConfig.rendererPipeline!,
|
|
56
|
+
interactionInvalidation: [
|
|
57
|
+
{
|
|
58
|
+
interaction: "viewport-zoom" as const,
|
|
59
|
+
invalidates: [pass.id],
|
|
60
|
+
targets: ["canvas.viewport.zoom"],
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
const renderScaleSchema = {
|
|
65
|
+
...testSchema,
|
|
66
|
+
canvas: {
|
|
67
|
+
...testSchema.canvas,
|
|
68
|
+
renderScale: { ...testSchema.canvas.renderScale, enabled: true },
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const errors = validateToolcraftPerformanceCoverage(
|
|
72
|
+
renderScaleSchema,
|
|
73
|
+
{ ...baseConfig, rendererPipeline },
|
|
74
|
+
TOOLCRAFT_FUNCTIONAL_PERFORMANCE_COVERAGE_POLICY,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
expect(errors).not.toContainEqual(
|
|
78
|
+
expect.stringContaining(
|
|
79
|
+
'viewport-zoom must not invalidate expensive pass "viewport-raster"',
|
|
80
|
+
),
|
|
81
|
+
);
|
|
82
|
+
expect(
|
|
83
|
+
validateToolcraftPerformanceCoverage(
|
|
84
|
+
renderScaleSchema,
|
|
85
|
+
{
|
|
86
|
+
...baseConfig,
|
|
87
|
+
rendererPipeline: {
|
|
88
|
+
...rendererPipeline,
|
|
89
|
+
passes: [{ ...pass, quality: "full" }],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
TOOLCRAFT_FUNCTIONAL_PERFORMANCE_COVERAGE_POLICY,
|
|
93
|
+
),
|
|
94
|
+
).toContainEqual(
|
|
95
|
+
expect.stringContaining(
|
|
96
|
+
'viewport-zoom must not invalidate expensive pass "viewport-raster"',
|
|
97
|
+
),
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
|
|
37
101
|
it.each(["memoized", "retained-resource"] as const)(
|
|
38
102
|
"requires cacheKey for a composite pass with %s cache",
|
|
39
103
|
(cache) => {
|
|
@@ -106,6 +106,22 @@ function hasPipelineReference(value: string): boolean {
|
|
|
106
106
|
return value.trim().length > 0 && !vaguePipelineReferencePattern.test(value.trim());
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
function isRetinaViewportZoomRaster(
|
|
110
|
+
schema: ResolvedToolcraftAppSchema,
|
|
111
|
+
interaction: ToolcraftPipelineInteraction,
|
|
112
|
+
pass: ToolcraftRenderPass,
|
|
113
|
+
): boolean {
|
|
114
|
+
return (
|
|
115
|
+
interaction === "viewport-zoom" &&
|
|
116
|
+
schema.canvas.renderScale.enabled &&
|
|
117
|
+
pass.kind === "rasterize" &&
|
|
118
|
+
pass.quality === "retina" &&
|
|
119
|
+
(pass.runsOn === "worker" ||
|
|
120
|
+
pass.runsOn === "gpu" ||
|
|
121
|
+
pass.runsOn === "worker-or-gpu")
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
109
125
|
function getPipelineReferenceErrors(
|
|
110
126
|
passId: string,
|
|
111
127
|
field: string,
|
|
@@ -317,7 +333,8 @@ function getRendererPipelineErrorsFromParsedPipeline(
|
|
|
317
333
|
|
|
318
334
|
if (
|
|
319
335
|
highFrequencyViewportInteractions.has(invalidation.interaction) &&
|
|
320
|
-
expensiveRenderPassKinds.has(pass.kind)
|
|
336
|
+
expensiveRenderPassKinds.has(pass.kind) &&
|
|
337
|
+
!isRetinaViewportZoomRaster(schema, invalidation.interaction, pass)
|
|
321
338
|
) {
|
|
322
339
|
errors.push(
|
|
323
340
|
`rendererPipeline ${invalidation.interaction} must not invalidate expensive pass "${passId}" (${pass.kind}). Move viewport work to transforms/uniforms or explain it through a cheaper pass.`,
|
|
@@ -20,10 +20,10 @@ Process matching routes sequentially within the current phase and skip repeated
|
|
|
20
20
|
|
|
21
21
|
1. Build through `defineToolcraft` and `ToolcraftApp`.
|
|
22
22
|
2. Keep app state in Toolcraft runtime schema and commands.
|
|
23
|
-
3. Keep product output in `canvasContent`; never render app UI there. The signed host owns `ToolcraftApp`, bootstrap, routes,
|
|
24
|
-
4. Use built-in Toolcraft controls before custom controls. Before controls or canvas interactions, declare typed `interactionOwnership`: user request, inspected reference, or product usability selects one primary surface for each operation; complementary operations may share related state, but canvas and panel must not mirror the same operation. Every product also declares typed `viewInteraction` before renderer code; a visible editable spatial scene defaults to `orbit` and uses schema `orientationGizmo` plus runtime model-orbit interaction. Fixed or timeline-owned cameras require an explicit user request or inspected-reference evidence.
|
|
25
|
-
5. Do not hand-compose runtime surfaces or render built-in control components directly in app code; use `ToolcraftApp`, schema controls, `canvasContent`, `controlRenderers`, `onPanelAction`, and runtime commands.
|
|
26
|
-
6. Before writing controls,
|
|
23
|
+
3. Keep product output in `canvasContent`; never render app UI there. The signed host owns `ToolcraftApp`, bootstrap, routes, global runtime styles, and the finite/infinite product scene surface; product code supplies only `ToolcraftAppComposition`. Infinite custom raster/WebGL output declares `sceneBoundsProvider` and consumes `useToolcraftProductSceneFrame` instead of dormant finite `canvas.size`. A preview-only environment that must fill the complete Infinity viewport uses `infiniteCanvasContent`; it remains pointer-transparent and outside world transforms, scene bounds, and export. Model upload preserves supported authored appearance from standalone files, folders, and bounded ZIP packages; declare typed `modelPresentation`, using runtime presentation by default and checked consumers for custom presentation. `renderDefaultCanvasMedia={false}` never hides runtime model layers. If upload/import is part of the source-material flow, do not invent canvas placeholder artwork, CTA copy, helper text, fake sample output, or preset source designs before real content exists.
|
|
24
|
+
4. Use built-in Toolcraft controls before custom controls. Use `sourceCollection` when a source/runtime workflow owns array cardinality and users edit existing built-in item values; use `collectionActions` when users own add/remove cardinality. Before controls or canvas interactions, declare typed `interactionOwnership`: user request, inspected reference, or product usability selects one primary surface for each operation; complementary operations may share related state, but canvas and panel must not mirror the same operation. Every product also declares typed `viewInteraction` before renderer code; a visible editable spatial scene defaults to `orbit` and uses schema `orientationGizmo` plus runtime model-orbit interaction. Fixed or timeline-owned cameras require an explicit user request or inspected-reference evidence.
|
|
25
|
+
5. Do not hand-compose runtime surfaces or render built-in control components directly in app code; use `ToolcraftApp`, schema controls, `canvasContent`, `controlRenderers`, `onPanelAction`, and runtime commands. Product code never imports modules below `src/toolcraft/ui/components/controls/**` or substitutes native `color`, `range`, `file`, `checkbox`, `radio`, `select`, or `textarea` value models for schema controls. Product artifact surfaces must correspond exactly to required `productReadiness.exportIntent`; use `docs/toolcraft/core/setup-export.md` for the canonical export decision sequence.
|
|
26
|
+
6. Before writing controls, export `starterControlSectionInventory`. Every product section declares stable `entityId`, human-readable `entity`, exact targets, and `groupingReason`. Every product control explicitly declares `applicability` as `always` or `conditional`; inactive branches are absent, and every visible finite sibling branch must prove the control's accepted product outcome. Keep one entity in one section through ten controls; sections with eight to ten controls declare `semanticGroup` on every control. Entities above ten controls split into balanced two-to-ten-control workflow stages that keep the same entity identity and declare unique `workflowStage` plus `splitReason`. Group by product meaning, never by UI component type or target namespace.
|
|
27
27
|
7. Keep control `label` short but semantically sufficient with the nearest visible section/group context, and put product-specific behavior help in schema `description`; runtime renders the label help tooltip only when that description adds meaning beyond the label.
|
|
28
28
|
8. Enable layers and timeline only when product behavior requires them, then test the real UI. Product animation loops are seamless forward-only by default: first and last frames stitch, direction does not reverse, and mirror/yoyo/ping-pong behavior requires explicit user intent.
|
|
29
29
|
9. Animated preview renderers suspend or coalesce non-essential animation work during canvas drag, pan, pinch, zoom, and radar/center interactions, then resume without changing user playback state.
|
|
@@ -33,7 +33,7 @@ Process matching routes sequentially within the current phase and skip repeated
|
|
|
33
33
|
13. Generated apps follow the mandatory runtime Setup, Infinity canvas/finite canvas sizing, render scale, Timeline switch, Background, Image Export, Video Export, and sticky action rules in `docs/toolcraft/core/setup-export.md`. Do not duplicate or reinterpret those controls in app-authored sections.
|
|
34
34
|
14. Media uploads, image/file mode, source images, multi-upload sorting, default assets, and image transform actions follow `docs/toolcraft/core/media-upload.md`.
|
|
35
35
|
15. Keep `docs/toolcraft/agent-worklog.md` current with a decision trail, product decisions, explicit reference inputs, evidence, verification, and risks. Reference-runtime-clone apps also declare `referenceStudy` plus `referenceFeatureInventory` so every inspected reference feature has feature-level behavior evidence and maps to Toolcraft implementation and acceptance coverage.
|
|
36
|
-
16. Prove every visible entity through acceptance, browser, and performance coverage. Browser acceptance and performance pass only when protected helpers emit matching runtime evidence after successful assertions; source-code spelling and acceptance prose are not outcome authority.
|
|
36
|
+
16. Prove every visible entity through acceptance, browser, and performance coverage. Browser acceptance and performance pass only when protected helpers emit matching runtime evidence after successful assertions; source-code spelling and acceptance prose are not outcome authority. Control applicability derives case-scoped presence/absence and product-outcome evidence from semantic section peers; background output keeps its fixed typed recipe. Raster products with `canvas.renderScale` declare `renderScaleCoverage` for interaction and steady state, plus playback when timeline is enabled, and prove real backing pixels with `canvas-render-scale-backing`; clamping quality is a functional failure without measured performance. Every measured path in a render-scale-enabled raster product proves actual CSS × devicePixelRatio × 2 backing after each measured phase. Generic acceptance outcomes prove command side effects only; use the fixed media, persistence, viewport, compound-control, layer, and timeline semantic recipes for specialized evidence.
|
|
37
37
|
17. Performance planning follows one sequence: reachable controls and inputs; workload dimensions and enforced boundaries; pass cost, frequency, lifecycle, and invalidation; render-plan assessment and protected kernel benchmark when required; derived paths and combined fixtures; targeted functional/browser development checks; lifecycle-appropriate delivery proof. Keep `src/app/app-verification-impact.json` complete so later functional changes derive exact verification scope. Only exact request authority may create a measured targeted performance iteration. Details live in `docs/toolcraft/core/performance.md` and `docs/toolcraft/performance.md`.
|
|
38
38
|
18. Custom renderer apps compile one canonical `rendererPipelineRegistration`, supply it through `ToolcraftAppComposition`, reuse that registration as `rendererPipeline` in performance assessment, and derive paths and fixtures from it. The neutral starter has no registration, runtime provider, or fixture adapters.
|
|
39
39
|
19. Classify each coherent user-visible delivery batch with a verification tier before editing. Steering and fixes inside the same request stay in that batch. Use targeted checks for development feedback, then run the protected delivery gate once when the batch is ready.
|
|
@@ -42,7 +42,7 @@ Process matching routes sequentially within the current phase and skip repeated
|
|
|
42
42
|
|
|
43
43
|
The generated folder starts as a neutral Toolcraft shell: canvas upload plus toolbar. It intentionally does not include demo controls, prompt fields, layers, or timeline. Do not treat test fixtures or documentation examples as product requirements. Add controls, timeline, layers, sticky actions, and custom renderers only after the requested product or reference app requires them; base workspace persistence already exists.
|
|
44
44
|
|
|
45
|
-
When the folder becomes a real product, update `src/app/app-acceptance-data.ts` from `appProductReadiness.mode: "starter"` to `mode: "product"` and fill `productName`, `productSummary`, `requestedBehavior`, typed `interactionOwnership`, and typed `viewInteraction`. Compare canvas and panel for each operation that could plausibly live on either surface. A visible editable 3D scene uses `orbit`; `fixed-camera` and `timeline-camera` require explicit request/reference evidence. Renamed product folders are not allowed to keep neutral starter readiness.
|
|
45
|
+
When the folder becomes a real product, update `src/app/app-acceptance-data.ts` from `appProductReadiness.mode: "starter"` to `mode: "product"` and fill `productName`, `productSummary`, `requestedBehavior`, required typed `exportIntent`, typed `interactionOwnership`, and typed `viewInteraction`. Compare canvas and panel for each operation that could plausibly live on either surface. A visible editable 3D scene uses `orbit`; `fixed-camera` and `timeline-camera` require explicit request/reference evidence. Renamed product folders are not allowed to keep neutral starter readiness.
|
|
46
46
|
|
|
47
47
|
## License
|
|
48
48
|
|
|
@@ -119,11 +119,13 @@ These ids mirror `TOOLCRAFT_DECISION_CONTRACT` in `@/toolcraft/runtime`. Keep th
|
|
|
119
119
|
|
|
120
120
|
- Use `defineToolcraft` from `@/toolcraft/runtime`.
|
|
121
121
|
- Export an `appComposition` satisfying `ToolcraftAppComposition` from `src/app/app-composition.tsx`.
|
|
122
|
-
- Keep product composition limited to `schema`, `canvasContent`, `controlRenderers`, `modelPresentation`, `onPanelAction`, `renderDefaultCanvasMedia`, and optional `rendererPipelineRegistration`; host `className` and `style` are not product extension points.
|
|
122
|
+
- Keep product composition limited to `schema`, `canvasContent`, `infiniteCanvasContent`, `controlRenderers`, `exportRenderer`, `sceneBoundsProvider`, `modelPresentation`, `onPanelAction`, `renderDefaultCanvasMedia`, and optional `rendererPipelineRegistration`; host `className` and `style` are not product extension points.
|
|
123
|
+
- Infinite product output fills the runtime-owned scene surface derived from `sceneBoundsProvider`. Raster/WebGL renderers call `useToolcraftProductSceneFrame` for backing size and coordinate translation; they never position a second bounds wrapper or use dormant finite `canvas.size` while infinite.
|
|
123
124
|
- Custom renderers use one compiled `rendererPipelineRegistration` as the canonical declaration for runtime execution and new-envelope performance assessment. Product code receives only the disposal-free pipeline client through hooks and panel action context.
|
|
124
|
-
- Do not import `ToolcraftApp`, low-level runtime surfaces,
|
|
125
|
+
- Do not import `ToolcraftApp`, low-level runtime surfaces, built-in controls, or modules below `src/toolcraft/ui/components/controls/**` into product modules. Do not recreate schema control value models with native form elements. The signed host renders the shell; product modules use schema controls and supported composition fields.
|
|
125
126
|
- Use `renderDefaultCanvasMedia={false}` when a custom renderer replaces generic image/file preview. This flag does not suppress runtime model layers; use typed `modelPresentation` custom mode with checked consumers for declared model targets.
|
|
126
|
-
- Use `ToolcraftApp onPanelAction` for sticky footer product actions such as Generate, Apply,
|
|
127
|
+
- Use `ToolcraftApp onPanelAction` for non-export sticky footer product actions such as Generate, Apply, Copy, or Download. Typed `export-image` and `export-video` actions are executed by the runtime from the shared `ToolcraftAppComposition.exportRenderer`.
|
|
128
|
+
- Product export renderers draw one deterministic scene-coordinate frame and return/await their real work. Product modules never allocate export canvases, choose encoders, encode blobs, create download URLs, or duplicate image/video composition.
|
|
127
129
|
- Keep final app behavior in the schema and runtime command bus, not in isolated local control state.
|
|
128
130
|
- For animated products, write an Animation Intent Inventory before coding: use top playback timeline for product transport, keyframes timeline for editable property animation, and no timeline only for explicitly autonomous decorative output with no video export. Any app with `Export Video` must enable the top Toolcraft timeline.
|
|
129
131
|
- For keyframes timeline apps, renderers read keyframed settings through Toolcraft evaluated-value helpers/hooks. Do not parse timeline `valueLabel` strings or read raw `state.values` for keyframed targets.
|
|
@@ -172,7 +174,7 @@ Do not rerun `pnpm install` after every edit. Run it after fresh export, depende
|
|
|
172
174
|
|
|
173
175
|
Do not run the full browser performance suite for Tier 0-2 edits.
|
|
174
176
|
|
|
175
|
-
The automatic lifecycle is sequential. First product delivery uses bare `pnpm verify:delivery` for complete product contracts, one production build, full functional acceptance, and zero measured performance. Later delivery is functional-targeted: it compares the immediately previous and current semantic functional proof models and derives exact direct-owner, domain, and affected-unit-graph proof.
|
|
177
|
+
The automatic lifecycle is sequential. First product delivery uses bare `pnpm verify:delivery` for complete product contracts, one production build, full functional acceptance, and zero measured performance. Later delivery is functional-targeted: it compares the immediately previous and current semantic functional proof models and derives exact direct-owner, domain, and affected-unit-graph proof. Classifier output establishes complaint authority only, never path localization. For a localized performance complaint, select affected canonical paths and run one targeted iteration without clarification. When localization remains unresolved, regardless of whether classification is high-confidence `performance-iteration` or `needs-agent-judgment`, ask one user-facing question naming visible operations and offering targeted diagnosis or a complete review; unresolved localization creates neither performance-iteration intent nor canonical path authority, and internal path IDs are never user choices. A broad or unlocalizable problem may justify recommending the complete review in that single choice, but the user still chooses; an explicit complete-review request runs `pnpm verify:perf` directly. The canonical selection and evidence rules live in `docs/toolcraft/workflow.md`, `docs/toolcraft/acceptance-testing.md`, and `docs/toolcraft/performance.md`; do not duplicate their algorithm here.
|
|
176
178
|
|
|
177
179
|
Feature loops after the first working version run only the smallest focused functional and browser checks while implementation is changing, then one bare `verify:delivery` at the coherent boundary. Do not rerun aggregate, export, or performance matrices after every edit. An unchanged `sourceHash` uses the protected fast path and does not recollect semantic proof inputs.
|
|
178
180
|
|
|
@@ -187,7 +189,7 @@ pnpm verify:delivery
|
|
|
187
189
|
pnpm dev
|
|
188
190
|
```
|
|
189
191
|
|
|
190
|
-
The protected runner selects first-delivery functional proof, later `functional-targeted` ownership-derived proof, or one
|
|
192
|
+
The protected runner selects first-delivery functional proof, later `functional-targeted` ownership-derived proof, or one localized-or-clarified targeted performance iteration from protected state. Classifier output alone never supplies path localization; unresolved localization creates neither performance-iteration intent nor canonical path authority regardless of classifier result. `pnpm verify:perf` is the separate operator/CI full-audit command; run it only after an explicit user request or accepted agent offer, never as an inferred continuation of a complaint.
|
|
191
193
|
|
|
192
194
|
Use `pnpm install` before this final gate when the folder is fresh or dependencies changed.
|
|
193
195
|
|
|
@@ -202,14 +204,15 @@ The app is complete only when:
|
|
|
202
204
|
- the Toolcraft runtime shell is present;
|
|
203
205
|
- `canvasContent` contains product output only;
|
|
204
206
|
- the runtime canvas backing remains visible behind product output;
|
|
205
|
-
-
|
|
207
|
+
- infinite product output uses the runtime-owned product scene surface, exact provider bounds, and real edge-pixel proof without clipping to dormant finite `canvas.size`;
|
|
208
|
+
- every product control declares explicit applicability, every non-matching finite branch hides it, and every visible finite branch proves product output or the accepted command side effect;
|
|
206
209
|
- reset returns schema controls to `defaultValue`;
|
|
207
210
|
- sticky footer export actions operate on final product output at `state.canvas.size`;
|
|
208
|
-
-
|
|
211
|
+
- artifact actions and settings correspond exactly to `productReadiness.exportIntent`; image export is the product default, video requires explicit user-request evidence, and image removal requires explicit user-removal evidence;
|
|
209
212
|
- PNG export uses the background controls normalized into runtime Setup: `Background` beside `Infinity canvas`, then `Background color`; live preview hides product background when Background is off, and video keeps background;
|
|
210
|
-
- every PNG export includes `Image Export` format/resolution `select` controls
|
|
213
|
+
- every PNG export includes `Image Export` format/resolution `select` controls; runtime resolves the selected settings and exact output size;
|
|
211
214
|
- products with both PNG and video export place `Image Export` immediately before `Video Export`;
|
|
212
|
-
-
|
|
215
|
+
- one shared `exportRenderer` draws product pixels for both image and video; runtime owns selected settings, scene crop, background, runtime media/model compositing, canvas allocation, encoding, download, progress, and typed errors;
|
|
213
216
|
- layers are absent for single-layer apps and fully working when enabled;
|
|
214
217
|
- timeline is absent, playback, keyframes, or custom reference timeline according to product behavior;
|
|
215
218
|
- performance checks cover workload and responsiveness for all relevant controls;
|
|
@@ -6,3 +6,9 @@ starter, UI component, documentation, and template source code.
|
|
|
6
6
|
Use of that Toolcraft code is governed by the MIT License in `LICENSE.md`.
|
|
7
7
|
Product-specific design, content, configuration, and application code that you
|
|
8
8
|
create remain yours.
|
|
9
|
+
|
|
10
|
+
## Mediabunny
|
|
11
|
+
|
|
12
|
+
Video export uses Mediabunny 1.52.2, Copyright © 2026 Vanilagy,
|
|
13
|
+
licensed under the Mozilla Public License 2.0 (MPL-2.0).
|
|
14
|
+
Source: https://github.com/Vanilagy/mediabunny
|
|
@@ -40,7 +40,8 @@ Use focused tests while a coherent user-visible delivery batch is changing. Stee
|
|
|
40
40
|
|
|
41
41
|
- **First product delivery:** bare `pnpm verify:delivery` proves complete product contracts, performs one production build, runs full functional acceptance, and runs no measured performance. It preserves any independent performance baseline.
|
|
42
42
|
- **Later functional delivery:** the same bare command compares with the immediately previous successful delivery and derives exact ownership-required proof.
|
|
43
|
-
- **
|
|
43
|
+
- **Localized or clarified targeted work:** classifier output establishes complaint authority only and never path localization. Only a localized complaint or a post-clarification targeted choice records an exact request quote and canonical affected path IDs in the worklog, then one bare delivery runs one targeted iteration and returns the verified app for evaluation. Unresolved localization creates neither performance-iteration intent nor canonical path authority regardless of classifier result.
|
|
44
|
+
- **Adaptive complaint route:** a localized complaint lets the agent choose affected paths without a question; an ambiguous complaint gets one visible-operation choice between targeted diagnosis and a complete performance review; a broad problem may receive the same recommendation, while only an explicit request or accepted offer authorizes the full review.
|
|
44
45
|
- **Full audit:** only an explicit operator request or accepted offer authorizes `pnpm verify:perf`, which performs one fresh build and the complete maximum-fixture performance matrix.
|
|
45
46
|
|
|
46
47
|
Use the current AI agent's controlled browser for targeted diagnosis and visual checks.
|
|
@@ -26,9 +26,12 @@ The exported starter may keep `appProductReadiness.mode: "starter"` only while i
|
|
|
26
26
|
|
|
27
27
|
- `productName`;
|
|
28
28
|
- `productSummary`;
|
|
29
|
-
- `requestedBehavior
|
|
29
|
+
- `requestedBehavior`;
|
|
30
|
+
- required `exportIntent`;
|
|
30
31
|
- `viewInteraction`.
|
|
31
32
|
|
|
33
|
+
`productReadiness.exportIntent` is the typed authority for artifact delivery. Acceptance, schema actions, and export settings must correspond exactly to its resolved image and video capabilities. The evidence-bearing modes and decision sequence live in `core/setup-export.md`; do not infer export intent from animation or timeline state.
|
|
34
|
+
|
|
32
35
|
`viewInteraction` classifies the product as `non-spatial`, `orbit`,
|
|
33
36
|
`fixed-camera`, or `timeline-camera`. Editable spatial scenes default to orbit;
|
|
34
37
|
fixed/timeline modes require explicit request/reference evidence.
|
|
@@ -82,6 +85,8 @@ The `e2e/app-browser-*` prefix is reserved for signed framework specs.
|
|
|
82
85
|
|
|
83
86
|
Every runtime production module/resource has a direct owner in `src/app/app-verification-impact.json`; proof and test paths cannot own them. Each browser file owns one acceptance domain (the first ID segment). Later delivery compares semantic models and selects changed contracts, owners/domains, and product-unit tests—not filenames or reverse imports. Additive owner deltas select only new IDs; other deltas retain affected IDs.
|
|
84
87
|
|
|
88
|
+
Classifier output establishes complaint authority only; unresolved localization creates no intent/path regardless of result. Only localized/clarified work starts an iteration.
|
|
89
|
+
|
|
85
90
|
Contract docs are signed except product-owned `agent-worklog.md` and optional `workflow-observation.md`; only the observation stays outside `sourceHash`.
|
|
86
91
|
|
|
87
92
|
Framework meta-tests are product-invariant: their synthetic validator cases use protected neutral contract fixtures, never the editable app schema, product acceptance rows, transfer intent, or section inventory. Put exact product targets, defaults, option values, and product-specific expectations in separate app-owned tests. The product gates still read `app-schema.ts`, `app-acceptance-data.ts`, product test names, worklog evidence, and browser scenarios dynamically.
|
|
@@ -94,13 +99,13 @@ Slider and range slider rows must prove live behavior. Browser tests should drag
|
|
|
94
99
|
|
|
95
100
|
## Infinity Canvas Coverage
|
|
96
101
|
|
|
97
|
-
Every editable-output
|
|
102
|
+
Every editable-output app proves `infinityCanvasCoverage`. Background proof covers color, viewport, disable/restore, and finite size. Preview checks the runtime scene against its exact `sceneBoundsProvider` union and real edge pixels; app selectors fail. Raster backing follows `useToolcraftProductSceneFrame`, not dormant finite size. Image/video decode the same bounds; video unions scheduled states. Fixed recipes cover excluded, empty, unavailable, and oversized scenes. See `core/setup-export.md`.
|
|
98
103
|
|
|
99
104
|
## Render Scale Coverage
|
|
100
105
|
|
|
101
|
-
|
|
106
|
+
For a raster product with render scale, add one `canvas.renderScale` browser row: `renderScaleCoverage: { kind: "selected-backing-pixels", states: ["interaction", "steady"] }`; timeline adds `"playback"`.
|
|
102
107
|
|
|
103
|
-
|
|
108
|
+
Run `expectToolcraftCanvasRenderScaleEvidence` per state. CSS size stays fixed and backing must equal `CSS × devicePixelRatio × selected scale` within one pixel before `canvas-render-scale-backing`; mismatch fails. Every measured path in that product proves exact `CSS × devicePixelRatio × 2` after each phase.
|
|
104
109
|
|
|
105
110
|
Default local persistence requires one runtime row with `evidence: "persistence-state"`, `persistenceCoverage: "reload"`, and `persistenceSlices` equal to the resolved plan. Browser proof changes each slice, waits for status `success`, reloads, then verifies restored state and real output before evidence. Settings import/export is not reload proof.
|
|
106
111
|
|
|
@@ -115,6 +120,7 @@ Required parts:
|
|
|
115
120
|
| `anchorGrid` | `anchorGrid.position` |
|
|
116
121
|
| `channelMixer` | `channelMixer.activeChannel`, `channelMixer.values`; only for RGB channel matrix behavior |
|
|
117
122
|
| `collectionActions` | `collectionActions.add`, `collectionActions.remove`, `collectionActions.items` |
|
|
123
|
+
| `sourceCollection` | `sourceCollection.items` |
|
|
118
124
|
| `colorOpacity` | `colorOpacity.hex`, `colorOpacity.opacity` |
|
|
119
125
|
| `curves` | RGB variant: `curves.activeChannel`, `curves.points`; `variant: "single"`: `curves.points` |
|
|
120
126
|
| `fontPicker` | `fontPicker.fontId`, `fontPicker.fontWeight`, `fontPicker.fontSize`, `fontPicker.letterSpacing`, `fontPicker.lineHeight`, `fontPicker.textCase`, `fontPicker.color`, `fontPicker.opacity` |
|
|
@@ -147,6 +153,8 @@ choosing a fixed camera and thereby escaping gizmo acceptance.
|
|
|
147
153
|
|
|
148
154
|
Use protected `expectToolcraftOrientationAxisDrag`/`AxisSnap`/`ModelDrag`/`CanvasMissPan`/`UndoReset` recipes. Axis drag finds blank circular background and performs the pointer drag; axis snap projects and clicks the requested endpoint from canonical pose. Evidence follows pose/output/ownership/history assertions. Arbitrary mutations, endpoint-only or generic drag, source spelling, and value changes do not qualify. Use `expectExportExcludesCanvasHandles` for export-clean proof.
|
|
149
155
|
|
|
156
|
+
`expectToolcraftOrientationAxisDrag` validates paused playback and maximum `canvas.renderScale` when those standard controls are present. Product tests prepare those states through real UI before capturing their baseline; the protected helper does not toggle playback or quality, so one drag remains one history transaction. This is functional browser proof, not measured performance evidence.
|
|
157
|
+
|
|
150
158
|
## Control Selection Gates
|
|
151
159
|
|
|
152
160
|
Acceptance must catch wrong-substitution failures. If the prompt, spec, or app behavior needs a value model owned by a built-in control, the schema must use that built-in or include a documented built-in fit check.
|
|
@@ -157,7 +165,7 @@ High-confidence wrong-substitution cases:
|
|
|
157
165
|
- typography without `fontPicker`;
|
|
158
166
|
- sibling typography controls that split case, color, opacity, size, weight, letter spacing, or line height away from `fontPicker`;
|
|
159
167
|
- color plus opacity without `colorOpacity`;
|
|
160
|
-
-
|
|
168
|
+
- source-sized repeated item sets without `sourceCollection`, or user-editable cardinality without `collectionActions`;
|
|
161
169
|
- from/to range without `rangeSlider` or `rangeInput`;
|
|
162
170
|
- curve, remap, easing, or response without `curves`;
|
|
163
171
|
- manual stable two-axis position, direction, focus, anchor, light, or vector parameters without `vector`;
|
|
@@ -179,34 +187,14 @@ A model `fileDrop` row declares `modelImportCoverage: "all-required-model-import
|
|
|
179
187
|
|
|
180
188
|
Protected browser evidence imports every format plus folder/ZIP; proves first-root choice, runtime/custom readiness, nontransparent RGBA, and authored signatures versus fallback. Metadata, changed pose, or a canvas node is not proof. Fatal input keeps the prior commit. `Fix model` requires a deterministic topology plan and verified result; appearance warnings never expose it. Processing preview is `40%`; committed preview/export is `100%`. Both share document, appearance key, pose pixels, and omit gizmo chrome. Reload proves repository-backed appearance; corrupt refs become `unavailable`. History/reset proves removal, enabled undo/redo, and default restore through import.
|
|
181
189
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
```ts
|
|
185
|
-
builtInFitCheck: {
|
|
186
|
-
capabilities: [
|
|
187
|
-
"collection",
|
|
188
|
-
"reorder",
|
|
189
|
-
"selection",
|
|
190
|
-
"commands",
|
|
191
|
-
"custom-value-model",
|
|
192
|
-
],
|
|
193
|
-
checkedBuiltIns: ["fileDrop", "collectionActions", "imagePicker"],
|
|
194
|
-
closestBuiltIn: "fileDrop",
|
|
195
|
-
whyInsufficient:
|
|
196
|
-
"FileDrop imports, previews, orders, and removes source files, but this product also needs per-glyph density thresholds stored with each item.",
|
|
197
|
-
productObservable:
|
|
198
|
-
"Changing a glyph density threshold changes which uploaded glyph renders for the same depth-map tone.",
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
The fit check declares broad typed capabilities, names real checked built-ins, the closest built-in or `"none"`, why it is insufficient, and the product-observable evidence that proves the custom control works. At least one of `custom-interaction`, `custom-value-model`, or `custom-visualization` is required; collection/command chrome alone does not justify custom UI.
|
|
190
|
+
Custom-control rows require `customControlCoverage` and typed `builtInFitCheck`; see `custom-controls.md` for the canonical shape. The fit check records capabilities, checked controls, the closest control (or `"none"`), the missing interaction, and observable proof. One `custom-*` capability is required; collection/command chrome alone is insufficient.
|
|
203
191
|
|
|
204
192
|
A fit check containing `custom-interaction` also requires `interactionId` and a
|
|
205
193
|
panel ownership entry. The fit check compares built-in controls; ownership
|
|
206
194
|
separately proves why the operation belongs in the panel instead of directly on
|
|
207
195
|
the canvas. Passing one gate never bypasses the other.
|
|
208
196
|
|
|
209
|
-
|
|
197
|
+
Collection-like custom controls must check `sourceCollection` and `collectionActions`, plus `actions` when commands exist. Arrays, `{ items: [...] }`, selection, cardinality, ordering, or item commands establish collection behavior; product nouns and unrelated controls do not.
|
|
210
198
|
|
|
211
199
|
Custom controls cannot be justified by icons, layout, styling, compactness, or custom buttons alone. `whyInsufficient` must name the product interaction or value model that built-ins cannot express.
|
|
212
200
|
|
|
@@ -224,25 +212,25 @@ Valid acceptance evidence includes:
|
|
|
224
212
|
- changed timeline playback state plus rendered frame.
|
|
225
213
|
- restored persisted value or product output after browser reload.
|
|
226
214
|
|
|
227
|
-
Product apps
|
|
215
|
+
Product apps include artifact acceptance only for the delivery enabled by `productReadiness.exportIntent`. Image-only products prove complete image coverage; image-plus-video products prove both; video-only products prove complete video coverage; explicit no-export products have no image/video artifact rows. Timeline playback, keyframes, or animation never add video acceptance. Clipboard copy can be tested as an additional behavior, but it cannot substitute for the recorded artifact intent.
|
|
228
216
|
|
|
229
217
|
Export-content proof is distinct from export mechanics: content inspects selected artifact semantics; mechanics proves lifecycle, format, dimensions, transport, and errors. Neither substitutes.
|
|
230
218
|
|
|
231
|
-
Every app with `Export PNG` must exercise the separate `Image Export` section: choose at least two `export.image.format` values, choose at least two `export.image.resolution` values, export the image, and decode the result to prove file type and actual pixel dimensions changed.
|
|
219
|
+
Every app with `Export PNG` must exercise the separate `Image Export` section: choose at least two `export.image.format` values, choose at least two `export.image.resolution` values, export the image, and decode the result to prove file type and actual pixel dimensions changed. Apps with both `Export PNG` and explicitly requested `Export Video` still need this image-export coverage; `Video Export` does not replace it.
|
|
232
220
|
|
|
233
|
-
|
|
221
|
+
Runtime Export acceptance must prove the sticky footer top accent indicator advances through real render/encode/download work and hides only after the artifact settles. Async non-export Download, Copy, Generate, or Apply acceptance must prove the indicator is visible while the returned `onPanelAction` Promise is pending, advances when `reportProgress(0..1)` is called, and hides after it settles.
|
|
234
222
|
|
|
235
|
-
|
|
223
|
+
Every video-enabled app exercises two video formats and resolutions. It proves real bytes, dimensions, actual MIME/container or typed capability failure, timeline duration, 30 FPS timestamps/durations from actual encoded packet metadata, decoded product motion, current even-safe sizing, and aspect-preserving 4K inside 3840x2160. Renderer/encoder/muxer errors reject; `blobSize`, metadata alone, assumed FPS, synthetic frame counts, or substituted expectations are invalid. Animated output requires distinct decoded frame hashes.
|
|
236
224
|
|
|
237
225
|
Footer action acceptance must not include Reset. Reset is already available in the controls panel header and uses schema `defaultValue`; duplicating it in sticky `panelActions` fails acceptance.
|
|
238
226
|
|
|
239
227
|
Local `actions` acceptance must click every visible action and prove the nearby entity changed through runtime state or product output. A section-level `Randomize palette` must change palette output, `Normalize weights` must change weights/output, and `Clear selection` must clear only the scoped selection. Do not accept a test that only proves the button rendered. A single-button `actions` control fails validation when the control label duplicates the button label; the label must add concise context. Visual acceptance rejects side-label actions; labels sit above a two-column button grid where each button cell is 50% width.
|
|
240
228
|
|
|
241
|
-
`collectionActions`
|
|
229
|
+
`collectionActions` keeps parts `collectionActions.add`, `collectionActions.remove`, `collectionActions.items`. Prove limits, full-default add, sibling-preserving edit, preview/export, and whole-record removal. `sourceCollection` proves source count, item edit, output, and no add/remove.
|
|
242
230
|
|
|
243
|
-
|
|
231
|
+
Image export proves background changes in preview/artifact/infinite viewport; Background off restores finite mode, disables Infinity, hides bounded preview background, and makes PNG transparent while JPEG/video stay opaque. Restoring it enables Infinity availability without entering that mode. Protected proof decodes real type, selected dimensions, product bounds/pixels, and pixel hash; bytes or dimensions alone are insufficient.
|
|
244
232
|
|
|
245
|
-
Hard acceptance semantics are typed, not inferred from English prose.
|
|
233
|
+
Hard acceptance semantics are typed, not inferred from English prose. Control applicability derives exact pairwise cases from the control's section-inventory peers for both `always` and `conditional` controls. Each non-matching case requires target absence. Each matching case requires target presence plus every existing product outcome on that acceptance row, under a canonical case-suffixed requirement ID. A missing predicate therefore cannot hide behind a passing default branch. The `export.includeBackground` row separately declares `backgroundOutputCoverage` for preview exclusion and transparent image alpha, plus preserved video background when the schema exposes video export. Its protected recipe verifies the preview transition, decodes a non-empty image artifact and checks background alpha, and inspects video background behavior when applicable. `expectedObservable` and `userAction` remain human-readable context and may use any language; matching words such as “hidden”, “PNG”, or “video” never satisfy these requirements by themselves.
|
|
246
234
|
|
|
247
235
|
Invalid final acceptance evidence:
|
|
248
236
|
|
|
@@ -330,6 +318,6 @@ Performance browser tests use the derived path matrix. Each path has one browser
|
|
|
330
318
|
|
|
331
319
|
## Fixtures
|
|
332
320
|
|
|
333
|
-
Use fixtures that make each behavior visible. For example, background character-size controls need visible background characters, transparency needs alpha-sensitive pixels, selected-layer controls need multiple layers, timeline controls need deterministic playback or keyframe fixtures, and mode-specific controls need fixtures for every mode branch.
|
|
321
|
+
Use fixtures that make each behavior visible. For example, background character-size controls need visible background characters, transparency needs alpha-sensitive pixels, selected-layer controls need multiple layers, timeline controls need deterministic playback or keyframe fixtures, and mode-specific controls need fixtures for every mode branch. Applicability coverage proves matching controls visible, non-matching controls absent, values preserved after switching away and back, and the accepted renderer/export outcome in every visible finite sibling branch. Count-controlled control banks prove the numeric boundary states; the test fails if inactive controls remain visible or a visible control is ignored by the renderer.
|
|
334
322
|
|
|
335
323
|
Generic hash differences are not enough for semantic controls. If a control promises a direction, test that direction.
|
|
@@ -12,13 +12,13 @@ The neutral starter has no product renderer, timeline, layers, export behavior,
|
|
|
12
12
|
|
|
13
13
|
Keep this worklog human-shaped. For the first product delivery, record the request, decisions, state/output mapping, reference evidence, rejected alternatives, and known risks; one bare `pnpm verify:delivery` derives complete contract proof, one build, full functional acceptance, and no measured performance. For later `functional-targeted` delivery, record only the new intent and decisions; the same bare command derives exact ownership-required proof from protected state.
|
|
14
14
|
|
|
15
|
-
A performance complaint adds
|
|
15
|
+
Classifier output establishes complaint authority only and never path localization. A localized performance complaint adds the domain authority below, then one bare `pnpm verify:delivery` runs one targeted iteration. If localization remains unresolved regardless of classifier result, ask one user-facing question naming visible operations and offering targeted diagnosis or a complete review; record neither `performance-iteration` intent nor canonical path authority until the answer supplies exact localization evidence. Never ask the user to choose internal path IDs. A broad or honestly unlocalizable problem may present that single choice with a recommendation for complete review, but the user still chooses. A direct complete-review request needs no further clarification. The full audit remains separate and requires an explicit operator request or accepted offer before `pnpm verify:perf` may run. Protected receipts own changed files, plans, checks, reports, measurements, and pass/fail evidence.
|
|
16
16
|
|
|
17
17
|
When `canvas.renderScale` is enabled, record the renderer decision to preserve selected backing quality and map it to functional `renderScaleCoverage` for interaction and steady state, plus playback when timeline is enabled. The worklog may name the protected `canvas-render-scale-backing` recipe, but it cannot claim its evidence or turn a quality failure into performance authority.
|
|
18
18
|
|
|
19
19
|
## Performance Iteration Entry Contract
|
|
20
20
|
|
|
21
|
-
For high-confidence ordinary work, record `Performance intent: ordinary-product-work`. For a performance complaint or
|
|
21
|
+
For high-confidence ordinary work, record `Performance intent: ordinary-product-work`. For unresolved localization, whether classification returned high-confidence `performance-iteration` or `needs-agent-judgment`, record the unresolved visible operation but no `Performance intent: performance-iteration` field or `Performance paths` until the user's one clarification provides exact localization. For a localized performance complaint or post-clarification targeted choice, record exactly these domain fields in the latest iteration:
|
|
22
22
|
|
|
23
23
|
```md
|
|
24
24
|
- Performance intent: performance-iteration
|
|
@@ -27,7 +27,7 @@ For high-confidence ordinary work, record `Performance intent: ordinary-product-
|
|
|
27
27
|
- Verification: One bare `pnpm verify:delivery` will derive and run the protected proof.
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
The quoted evidence must be an exact nontrivial raw substring of `Request` with identical whitespace and Unicode code units. `Performance paths` must be a non-empty unique JSON array of canonical path IDs. Do not record command arguments, changed-file inventory, executed checks, reports, or measurements; the protected planner and receipt own that machine evidence.
|
|
30
|
+
The quoted evidence must be an exact nontrivial raw substring of `Request` with identical whitespace and Unicode code units. `Performance paths` must be a non-empty unique JSON array of canonical path IDs. Do not record command arguments, changed-file inventory, executed checks, reports, or measurements; the protected planner and receipt own that machine evidence. Each localized complaint or post-clarification targeted choice authorizes one bounded iteration; after it passes, return the app and wait for user evaluation. Classifier output or complaint evidence alone never supplies path localization or authorizes full certification. The separate operator command is permitted only after the user explicitly requests a complete audit or explicitly accepts the agent's offer; the user does not need to name the command.
|
|
31
31
|
|
|
32
32
|
## Decision Trail
|
|
33
33
|
|
|
@@ -116,6 +116,21 @@ The quoted evidence must be an exact nontrivial raw substring of `Request` with
|
|
|
116
116
|
- Verification: One bare `pnpm verify:delivery` will derive and run the protected proof.
|
|
117
117
|
- Risks: Already-exported applications retain their copied runtime until regenerated. Browser proof relies on the runtime gizmo's canonical pose/target attributes and intentionally fails closed if the real handle is absent or ambiguous.
|
|
118
118
|
|
|
119
|
+
### Iteration 6 — Executable product-control applicability
|
|
120
|
+
|
|
121
|
+
- Request: Fix starter contracts so generated products show only settings that apply to the selected type and cannot pass delivery with a visible control that the renderer ignores.
|
|
122
|
+
- Task type: Shared runtime schema, controls-panel visibility, starter acceptance, protected browser evidence, generated fixtures, CLI, and documentation.
|
|
123
|
+
- User-visible result: Every generated product control explicitly declares `always` or `conditional` applicability. Non-matching controls disappear without losing their values, while every visible finite sibling branch must prove the control's real accepted product outcome.
|
|
124
|
+
- Source/reference checked: Badge behavior was used only as failure evidence; implementation scope remained the Toolcraft runtime and starter contracts. The legacy `visibleWhen` runtime path, control-section inventory, acceptance requirement derivation, reporter, and generated image/video/material fixtures were inspected.
|
|
125
|
+
- Contract rules applied: `controls-product-coverage`, `controls-section-inventory-required`, `controls-component-layout-invariants`, `acceptance-product-observable`, and `workflow-required`.
|
|
126
|
+
- Interaction ownership: The runtime owns applicability normalization and panel presence. Product schemas own explicit applicability claims. Existing product acceptance owns actions and outcomes; the applicability layer only derives the branch cases in which those outcomes must be reproved.
|
|
127
|
+
- Decision: Normalize explicit applicability, legacy `visibleWhen`, and omitted low-level input into one resolved model with origin metadata; reject legacy/implicit origins for product controls; combine conditional predicates with AND; derive pairwise cases from semantic section peers; preserve the authored `Background` inventory ownership after runtime relocates its product controls into `Setup`; attach case-scoped evidence only after exact presence/absence and real outcome assertions pass.
|
|
128
|
+
- Alternatives rejected: Extending optional `visibleWhen`, selector-owned target lists, renderer dependency inference, acceptance prose heuristics, Cartesian branch enumeration, and Badge-specific logic.
|
|
129
|
+
- State/output mapping: Applicability reads canonical runtime target values and changes only panel presence. Hidden values remain in runtime state, persistence, transfer, and history. Matching cases reuse the control's existing preview, rendered-pixel, artifact, command, or semantic proof.
|
|
130
|
+
- Performance intent: ordinary-product-work
|
|
131
|
+
- Verification: One bare `pnpm verify:delivery` remains the generated-app delivery authority; this runtime/template contract delivery also runs the monorepo checks required by the repository entry contract.
|
|
132
|
+
- Risks: Pairwise proof depends on truthful Control Section Inventory grouping; unsupported selector domains fail acceptance instead of silently skipping cases. Legacy low-level consumers remain readable but cannot satisfy generated product acceptance.
|
|
133
|
+
|
|
119
134
|
## Decisions
|
|
120
135
|
|
|
121
136
|
### Renderer
|
|
@@ -25,7 +25,7 @@ export const appComposition = {
|
|
|
25
25
|
} satisfies ToolcraftAppComposition;
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
Edit `src/app/app-composition.tsx`, not the signed route. Product composition may provide only `schema`, `canvasContent`, `controlRenderers`, `modelPresentation`, `onPanelAction`, `renderDefaultCanvasMedia`, and optional `rendererPipelineRegistration`; the protected route owns `className` and other host layout. Model products default to `modelPresentation: { mode: "runtime" }`. Custom presentation declares checked consumers and suppresses only their model targets; `renderDefaultCanvasMedia={false}` affects generic image/file preview, not runtime models. Do not compose `ToolcraftRoot`, `CanvasShell`, `ControlsPanel`, `LayersPanel`, `TimelinePanel`, or `ToolbarPanel` by hand. If a runtime surface has a performance or behavior issue, fix the shared runtime instead of replacing the surface locally.
|
|
28
|
+
Edit `src/app/app-composition.tsx`, not the signed route. Product composition may provide only `schema`, `canvasContent`, `infiniteCanvasContent`, `controlRenderers`, `exportRenderer`, `modelPresentation`, `onPanelAction`, `renderDefaultCanvasMedia`, `sceneBoundsProvider`, and optional `rendererPipelineRegistration`; the protected route owns `className` and other host layout. `infiniteCanvasContent` is editor-only product output for a full Infinity viewport backdrop; it does not inherit world transforms or participate in scene bounds/export. Model products default to `modelPresentation: { mode: "runtime" }`. Custom presentation declares checked consumers and suppresses only their model targets; `renderDefaultCanvasMedia={false}` affects generic image/file preview, not runtime models. Do not compose `ToolcraftRoot`, `CanvasShell`, `ControlsPanel`, `LayersPanel`, `TimelinePanel`, or `ToolbarPanel` by hand. If a runtime surface has a performance or behavior issue, fix the shared runtime instead of replacing the surface locally.
|
|
29
29
|
|
|
30
30
|
Supporting product modules may be organized anywhere under `src`; there is no folder allowlist. The product boundary follows all product production files and rejects host/runtime surface imports, built-in control imports/re-exports, dynamic bypasses, and production dependencies on test/spec modules.
|
|
31
31
|
|
|
@@ -35,8 +35,10 @@ Allowed app extension points:
|
|
|
35
35
|
| --- | --- |
|
|
36
36
|
| Schema controls | Built-in controls, targets, defaults, visibility, panel actions. |
|
|
37
37
|
| `canvasContent` | Product output only. |
|
|
38
|
+
| `infiniteCanvasContent` | Editor-only full-viewport product environment under the Infinity world; never app UI or export content. |
|
|
38
39
|
| `controlRenderers` | True custom controls only after the built-in fit check. |
|
|
39
|
-
| `
|
|
40
|
+
| `exportRenderer` | One deterministic scene-coordinate product frame shared by runtime image and video export. |
|
|
41
|
+
| `onPanelAction` | Non-export sticky footer product actions. |
|
|
40
42
|
| `rendererPipelineRegistration` | One compiled executable pipeline shared by render work, actions, evidence, and new-envelope assessment. |
|
|
41
43
|
| Runtime commands/hooks | History, media, canvas, timeline, layers, and controlled app behavior. |
|
|
42
44
|
|
|
@@ -50,6 +52,10 @@ Once the folder is a real product, switch `src/app/app-acceptance-data.ts` from
|
|
|
50
52
|
|
|
51
53
|
```ts
|
|
52
54
|
export const appProductReadiness = {
|
|
55
|
+
exportIntent: {
|
|
56
|
+
image: { mode: "toolcraft-default" },
|
|
57
|
+
video: { mode: "not-requested" },
|
|
58
|
+
},
|
|
53
59
|
interactionOwnership: [],
|
|
54
60
|
mode: "product",
|
|
55
61
|
productName: "Product name",
|
|
@@ -62,6 +68,8 @@ export const appProductReadiness = {
|
|
|
62
68
|
} as const;
|
|
63
69
|
```
|
|
64
70
|
|
|
71
|
+
Every product declaration requires `productReadiness.exportIntent`. It is the authority for exact image/video schema actions, settings sections, and artifact acceptance. Use `core/setup-export.md` for the single export-intent decision sequence; animation and timeline choices do not supply delivery intent.
|
|
72
|
+
|
|
65
73
|
Populate `interactionOwnership` before adding canvas handles or custom
|
|
66
74
|
interactions. One operation has one primary `canvas` or `panel` surface chosen
|
|
67
75
|
from user request, inspected reference, or product usability evidence. Different
|
|
@@ -74,7 +82,7 @@ the prompt did not separately request rotation.
|
|
|
74
82
|
|
|
75
83
|
## Controls
|
|
76
84
|
|
|
77
|
-
Before
|
|
85
|
+
Before choosing component layout, export `starterControlSectionInventory` and make the entity-first grouping decision. Every product section declares stable `entityId`, human-readable `entity`, exact targets, and `groupingReason`; one entity stays in one section through ten controls, while larger entities split only into explicit balanced workflow stages.
|
|
78
86
|
|
|
79
87
|
Use `core/layout.md` for section grouping, dependency cohesion, headers, reset, collapse, spacing, dividers, labels, and inline rows. Use `core/control-selection.md` and `component-rules.md` before choosing concrete controls. Built-in compound controls stay compound; extend the kit instead of splitting owned fields into neighboring controls.
|
|
80
88
|
|
|
@@ -98,7 +106,7 @@ When porting an existing app, use `transferMode: "reference-runtime-clone"` unle
|
|
|
98
106
|
|
|
99
107
|
## Timeline And Animation
|
|
100
108
|
|
|
101
|
-
Before adding animation controls, write an Animation Intent Inventory. Product animation, keyframes,
|
|
109
|
+
Before adding animation controls, write an Animation Intent Inventory. Product animation, keyframes, and playback use the top Toolcraft timeline. Explicitly requested video export also requires that timeline, but the timeline never authorizes video delivery. Autonomous no-timeline animation is allowed only for non-product decorative motion with no user-facing transport and no video export.
|
|
102
110
|
|
|
103
111
|
Use `core/timeline-animation.md` for timeline mode, compact/extended timeline, seamless forward loops, duration changes, keyframes, viewport interaction performance, and video export timing.
|
|
104
112
|
|
|
@@ -116,7 +124,7 @@ Use one normal sequence: assemble or change the product, gather focused function
|
|
|
116
124
|
|
|
117
125
|
1. First product delivery uses bare `pnpm verify:delivery` for complete product contracts, one production build, full functional acceptance, and no measured performance.
|
|
118
126
|
2. Later `functional-targeted` delivery uses the same bare command for exact ownership-derived functional proof relative to the immediately previous successful delivery.
|
|
119
|
-
3.
|
|
127
|
+
3. Classifier output establishes complaint authority only and never path localization. Only a localized complaint or a post-clarification targeted choice records an exact request quote and canonical affected path IDs in the worklog, then one bare delivery runs one targeted iteration and returns the app for evaluation. Unresolved localization creates neither performance-iteration intent nor canonical path authority regardless of classifier result.
|
|
120
128
|
4. A full audit requires an explicit operator request or accepted offer; only then run `pnpm verify:perf` for one fresh build and the complete maximum-fixture performance matrix.
|
|
121
129
|
|
|
122
130
|
Protected receipts own changed files, the derived plan, executed checks, reports, measurements, and pass/fail evidence. The worklog keeps product intent and decisions.
|