@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
|
@@ -239,6 +239,66 @@ test("creates a changed authorized iteration with exact affected proof", () => {
|
|
|
239
239
|
assert.equal(getToolcraftDeliveryDiagnosticTier(plan), 3);
|
|
240
240
|
});
|
|
241
241
|
|
|
242
|
+
test("creates an authorized iteration for a passless viewport path", () => {
|
|
243
|
+
const passlessPathId =
|
|
244
|
+
"performance-path:%5B%22interactive-continuous%22%2C%22viewport-drag%22%2C%5B%5D%2C%5B%5D%2C%5B%5D%5D";
|
|
245
|
+
const testName = `browser perf: toolcraft path ${passlessPathId}`;
|
|
246
|
+
const source = {
|
|
247
|
+
heading: "Delivery 2 - Slow viewport drag",
|
|
248
|
+
pathIds: [passlessPathId],
|
|
249
|
+
request: "The canvas is slow while panning.",
|
|
250
|
+
requestEvidence: "The canvas is slow while panning.",
|
|
251
|
+
};
|
|
252
|
+
const planningInputs = inputs({
|
|
253
|
+
requestAuthority: {
|
|
254
|
+
hash: createToolcraftPerformanceRequestAuthorityHash(source),
|
|
255
|
+
...source,
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
planningInputs.catalog = {
|
|
259
|
+
...catalog,
|
|
260
|
+
performance: [{ passIds: [], pathId: passlessPathId, testName }],
|
|
261
|
+
};
|
|
262
|
+
planningInputs.changeSet.impact.performanceCandidates = {
|
|
263
|
+
passIds: [],
|
|
264
|
+
pathIds: [passlessPathId],
|
|
265
|
+
testNames: [testName],
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const plan = createToolcraftDeliveryPlan(planningInputs);
|
|
269
|
+
|
|
270
|
+
assert.equal(plan.kind, "performance-iteration");
|
|
271
|
+
assert.deepEqual(
|
|
272
|
+
plan.steps.find(({ kind }) => kind === "browser-performance"),
|
|
273
|
+
{
|
|
274
|
+
kind: "browser-performance",
|
|
275
|
+
passIds: [],
|
|
276
|
+
pathIds: [passlessPathId],
|
|
277
|
+
testNames: [testName],
|
|
278
|
+
},
|
|
279
|
+
);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
test("keeps performance-adapter-only changes functional without inferred measurement", () => {
|
|
283
|
+
const planningInputs = inputs();
|
|
284
|
+
planningInputs.changeSet.impact = {
|
|
285
|
+
acceptanceIds: [],
|
|
286
|
+
browserTestNames: [],
|
|
287
|
+
buildRequired: false,
|
|
288
|
+
performanceCandidates: {
|
|
289
|
+
passIds: ["preview-composite"],
|
|
290
|
+
pathIds: [pathId],
|
|
291
|
+
testNames: [performanceTestName],
|
|
292
|
+
},
|
|
293
|
+
productTestFiles: [],
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const plan = createToolcraftDeliveryPlan(planningInputs);
|
|
297
|
+
|
|
298
|
+
assert.equal(plan.kind, "functional");
|
|
299
|
+
assert.deepEqual(plan.steps, [{ kind: "code-health" }]);
|
|
300
|
+
});
|
|
301
|
+
|
|
242
302
|
test("rejects malformed basis and functional performance proof", () => {
|
|
243
303
|
const valid = createToolcraftDeliveryPlan(inputs());
|
|
244
304
|
for (const basis of [
|
|
@@ -203,14 +203,19 @@ test("rejects malformed catalogs and inconsistent exact impact relations", () =>
|
|
|
203
203
|
}
|
|
204
204
|
});
|
|
205
205
|
|
|
206
|
-
test("
|
|
206
|
+
test("impact cannot omit both functional and performance proof", () => {
|
|
207
207
|
const value = inputs();
|
|
208
208
|
value.changeSet.impact.acceptanceIds = [];
|
|
209
209
|
value.changeSet.impact.browserTestNames = [];
|
|
210
210
|
value.changeSet.impact.productTestFiles = [];
|
|
211
|
+
value.changeSet.impact.performanceCandidates = {
|
|
212
|
+
passIds: [],
|
|
213
|
+
pathIds: [],
|
|
214
|
+
testNames: [],
|
|
215
|
+
};
|
|
211
216
|
assert.throws(
|
|
212
217
|
() => createToolcraftDeliveryPlan(value),
|
|
213
|
-
/functional proof/iu,
|
|
218
|
+
/functional or performance proof/iu,
|
|
214
219
|
);
|
|
215
220
|
});
|
|
216
221
|
|
|
@@ -124,8 +124,9 @@ function impactError(impact, catalog, allTests) {
|
|
|
124
124
|
impact.acceptanceIds.includes(row.acceptanceId));
|
|
125
125
|
const performance = catalog.performance.filter((row) =>
|
|
126
126
|
impact.performanceCandidates.pathIds.includes(row.pathId));
|
|
127
|
-
if (!impact.browserTestNames.length && !impact.productTestFiles.length
|
|
128
|
-
|
|
127
|
+
if (!impact.browserTestNames.length && !impact.productTestFiles.length &&
|
|
128
|
+
!impact.performanceCandidates.pathIds.length)
|
|
129
|
+
return "Verification impact does not select functional or performance proof.";
|
|
129
130
|
if (acceptance.length !== impact.acceptanceIds.length ||
|
|
130
131
|
!same(acceptance.map((row) => row.testName).sort(compare), impact.browserTestNames) ||
|
|
131
132
|
performance.length !== impact.performanceCandidates.pathIds.length ||
|
|
@@ -227,7 +228,10 @@ function stepError(step) {
|
|
|
227
228
|
if (step.kind === "dependencies" && !managers.has(step.packageManager))
|
|
228
229
|
return "Dependency proof has an invalid package manager.";
|
|
229
230
|
const badTarget = ["files", "testNames", "pathIds", "passIds"].find((key) =>
|
|
230
|
-
Object.hasOwn(step, key) && !targets(step[key], {
|
|
231
|
+
Object.hasOwn(step, key) && !targets(step[key], {
|
|
232
|
+
empty: step.kind === "browser-performance" && key === "passIds",
|
|
233
|
+
paths: key === "files",
|
|
234
|
+
}));
|
|
231
235
|
if (badTarget)
|
|
232
236
|
return `Delivery proof ${badTarget} must be nonempty, sorted, and unique.`;
|
|
233
237
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
|
|
3
1
|
import ts from "typescript";
|
|
4
2
|
|
|
5
3
|
import {
|
|
6
4
|
builtInControlExportNames,
|
|
7
5
|
runtimeSurfaceComponentNames,
|
|
8
6
|
} from "./toolcraft-integrity-policy.mjs";
|
|
7
|
+
import {
|
|
8
|
+
createToolcraftProductExportInspector,
|
|
9
|
+
isForbiddenToolcraftRuntimeExport,
|
|
10
|
+
} from "./toolcraft-product-export-boundary.mjs";
|
|
11
|
+
import { createToolcraftProductControlInspector } from "./toolcraft-product-control-boundary.mjs";
|
|
12
|
+
import { getToolcraftSensitiveModuleKind } from "./toolcraft-product-boundary-module-policy.mjs";
|
|
9
13
|
import { inspectToolcraftProductStyleNode } from "./toolcraft-product-style-boundary.mjs";
|
|
10
14
|
|
|
11
15
|
const runtimeSurfaceNames = new Set(runtimeSurfaceComponentNames);
|
|
@@ -18,82 +22,9 @@ const runtimeModelPresentationInternalNames = new Set([
|
|
|
18
22
|
"useToolcraftModelRenderHost",
|
|
19
23
|
]);
|
|
20
24
|
|
|
21
|
-
function toPosixPath(value) {
|
|
22
|
-
return value.split(path.sep).join("/");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function resolveSpecifierPath(sourceFilePath, moduleSpecifier, rootDir) {
|
|
26
|
-
if (moduleSpecifier.startsWith("@/") || moduleSpecifier.startsWith("#/")) {
|
|
27
|
-
return toPosixPath(path.resolve(rootDir, "src", moduleSpecifier.slice(2)));
|
|
28
|
-
}
|
|
29
|
-
if (moduleSpecifier.startsWith("/")) {
|
|
30
|
-
return toPosixPath(path.resolve(rootDir, moduleSpecifier.slice(1)));
|
|
31
|
-
}
|
|
32
|
-
if (moduleSpecifier.startsWith(".")) {
|
|
33
|
-
return toPosixPath(path.resolve(path.dirname(sourceFilePath), moduleSpecifier));
|
|
34
|
-
}
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function getSensitiveModuleKind(sourceFilePath, moduleSpecifier, rootDir) {
|
|
39
|
-
const normalizedSpecifier = moduleSpecifier.replaceAll("\\", "/");
|
|
40
|
-
const resolvedSpecifier = resolveSpecifierPath(
|
|
41
|
-
sourceFilePath,
|
|
42
|
-
normalizedSpecifier,
|
|
43
|
-
rootDir,
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
/^@repo\/toolcraft-runtime\/react\/model-rendering(?:\/|$)/u.test(
|
|
48
|
-
normalizedSpecifier,
|
|
49
|
-
) ||
|
|
50
|
-
/^[#@]\/toolcraft\/runtime\/react\/model-rendering(?:\/|$)/u.test(
|
|
51
|
-
normalizedSpecifier,
|
|
52
|
-
) ||
|
|
53
|
-
resolvedSpecifier?.includes("/src/toolcraft/runtime/react/model-rendering")
|
|
54
|
-
) {
|
|
55
|
-
return "runtime-model-presentation";
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (
|
|
59
|
-
/^three\/(?:addons|examples\/jsm)\/loaders(?:\/|$)/u.test(
|
|
60
|
-
normalizedSpecifier,
|
|
61
|
-
) ||
|
|
62
|
-
/^@gltf-transform(?:\/|$)/u.test(normalizedSpecifier) ||
|
|
63
|
-
/^@repo\/toolcraft-runtime\/model-import(?:\/|$)/u.test(
|
|
64
|
-
normalizedSpecifier,
|
|
65
|
-
) ||
|
|
66
|
-
/^[#@]\/toolcraft\/runtime\/model-import(?:\/|$)/u.test(
|
|
67
|
-
normalizedSpecifier,
|
|
68
|
-
) ||
|
|
69
|
-
resolvedSpecifier?.includes("/src/toolcraft/runtime/model-import")
|
|
70
|
-
) {
|
|
71
|
-
return "runtime-model-import";
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
-
/^@repo\/toolcraft-runtime\/react(?:\/|$)/u.test(normalizedSpecifier) ||
|
|
76
|
-
/^[#@]\/toolcraft\/runtime\/react(?:\/|$)/u.test(normalizedSpecifier) ||
|
|
77
|
-
resolvedSpecifier?.includes("/src/toolcraft/runtime/react")
|
|
78
|
-
) {
|
|
79
|
-
return "runtime-react";
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
/^@repo\/ui(?:\/controls(?:\/|$)|$)/u.test(normalizedSpecifier) ||
|
|
84
|
-
/^[#@]\/toolcraft\/ui(?:\/components\/controls(?:\/|$)|\/controls(?:\/|$)|$)/u.test(
|
|
85
|
-
normalizedSpecifier,
|
|
86
|
-
) ||
|
|
87
|
-
resolvedSpecifier?.includes("/src/toolcraft/ui/components/controls") ||
|
|
88
|
-
/\/src\/toolcraft\/ui$/u.test(resolvedSpecifier ?? "")
|
|
89
|
-
) {
|
|
90
|
-
return "ui-controls";
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
25
|
function isForbiddenNamedExport(moduleKind, importedName) {
|
|
26
|
+
if (moduleKind === "ui-control-implementation") return true;
|
|
27
|
+
if (isForbiddenToolcraftRuntimeExport(moduleKind)) return true;
|
|
97
28
|
if (
|
|
98
29
|
moduleKind === "runtime-model-import" ||
|
|
99
30
|
moduleKind === "runtime-model-presentation"
|
|
@@ -106,6 +37,42 @@ function isForbiddenNamedExport(moduleKind, importedName) {
|
|
|
106
37
|
importedName !== "createControlHistoryGroupId");
|
|
107
38
|
}
|
|
108
39
|
|
|
40
|
+
function getImportViolationKind(moduleKind, importedName) {
|
|
41
|
+
switch (moduleKind) {
|
|
42
|
+
case "runtime-export-mechanics":
|
|
43
|
+
return "runtime-export-ownership";
|
|
44
|
+
case "runtime-model-presentation":
|
|
45
|
+
return "runtime-model-presentation-ownership";
|
|
46
|
+
case "runtime-react":
|
|
47
|
+
return runtimeModelPresentationInternalNames.has(importedName)
|
|
48
|
+
? "runtime-model-presentation-ownership"
|
|
49
|
+
: "runtime-surface";
|
|
50
|
+
case "runtime-model-import":
|
|
51
|
+
return "runtime-model-import-ownership";
|
|
52
|
+
case "ui-control-implementation":
|
|
53
|
+
return "built-in-control-implementation";
|
|
54
|
+
default:
|
|
55
|
+
return "built-in-control";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getViolationMessage(kind, subject, moduleSpecifier) {
|
|
60
|
+
switch (kind) {
|
|
61
|
+
case "runtime-export-ownership":
|
|
62
|
+
return `Product source must not own artifact encoding, recording, or download mechanics${subject} from ${moduleSpecifier}. Declare exportRenderer and let runtime export actions encode and download the artifact.`;
|
|
63
|
+
case "runtime-surface":
|
|
64
|
+
return `Product source must not import or re-export host-owned runtime surface${subject} from ${moduleSpecifier}. Use ToolcraftAppComposition, schema, canvasContent, controlRenderers, onPanelAction, and runtime commands.`;
|
|
65
|
+
case "runtime-model-presentation-ownership":
|
|
66
|
+
return `Product source must not import raw model render hosts or standard model canvas internals${subject} from ${moduleSpecifier}. Declare modelPresentation and use useToolcraftModelPresentationConsumer for visible custom model output.`;
|
|
67
|
+
case "runtime-model-import-ownership":
|
|
68
|
+
return `Product source must not import or re-export model loaders, topology/repair infrastructure, or runtime model-import internals${subject} from ${moduleSpecifier}. Declare a model fileDrop in schema and use the runtime-owned import, analysis, repair, persistence, preview, and export pipeline.`;
|
|
69
|
+
case "built-in-control-implementation":
|
|
70
|
+
return `Product source must not import or re-export a deep control implementation${subject} from ${moduleSpecifier}. Use the public schema control instead of copying or composing its private mechanics.`;
|
|
71
|
+
default:
|
|
72
|
+
return `Product source must not import or re-export built-in control${subject} from ${moduleSpecifier}. Declare it through schema or justify a true custom controlRenderer.`;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
109
76
|
function createViolation({
|
|
110
77
|
getNodeLocation,
|
|
111
78
|
importedName,
|
|
@@ -116,24 +83,17 @@ function createViolation({
|
|
|
116
83
|
sourceFile,
|
|
117
84
|
}) {
|
|
118
85
|
const subject = importedName ? ` ${importedName}` : "";
|
|
119
|
-
const message =
|
|
120
|
-
kind === "runtime-surface"
|
|
121
|
-
? `Product source must not import or re-export host-owned runtime surface${subject} from ${moduleSpecifier}. Use ToolcraftAppComposition, schema, canvasContent, controlRenderers, onPanelAction, and runtime commands.`
|
|
122
|
-
: kind === "runtime-model-presentation-ownership"
|
|
123
|
-
? `Product source must not import raw model render hosts or standard model canvas internals${subject} from ${moduleSpecifier}. Declare modelPresentation and use useToolcraftModelPresentationConsumer for visible custom model output.`
|
|
124
|
-
: kind === "runtime-model-import-ownership"
|
|
125
|
-
? `Product source must not import or re-export model loaders, topology/repair infrastructure, or runtime model-import internals${subject} from ${moduleSpecifier}. Declare a model fileDrop in schema and use the runtime-owned import, analysis, repair, persistence, preview, and export pipeline.`
|
|
126
|
-
: `Product source must not import or re-export built-in control${subject} from ${moduleSpecifier}. Declare it through schema or justify a true custom controlRenderer.`;
|
|
127
86
|
return {
|
|
128
87
|
...getNodeLocation(sourceFile, node),
|
|
129
88
|
kind,
|
|
130
|
-
message,
|
|
89
|
+
message: getViolationMessage(kind, subject, moduleSpecifier),
|
|
131
90
|
repoPath,
|
|
132
91
|
};
|
|
133
92
|
}
|
|
134
93
|
|
|
135
94
|
export function inspectToolcraftProductSource({
|
|
136
95
|
absolutePath,
|
|
96
|
+
checker,
|
|
137
97
|
getNodeLocation,
|
|
138
98
|
repoPath,
|
|
139
99
|
resolveStaticString,
|
|
@@ -141,6 +101,18 @@ export function inspectToolcraftProductSource({
|
|
|
141
101
|
sourceFile,
|
|
142
102
|
}) {
|
|
143
103
|
const violations = [];
|
|
104
|
+
const inspectExportMechanics = createToolcraftProductExportInspector({
|
|
105
|
+
getNodeLocation,
|
|
106
|
+
repoPath,
|
|
107
|
+
sourceFile,
|
|
108
|
+
});
|
|
109
|
+
const inspectControls = createToolcraftProductControlInspector({
|
|
110
|
+
checker,
|
|
111
|
+
getNodeLocation,
|
|
112
|
+
repoPath,
|
|
113
|
+
resolveStaticString,
|
|
114
|
+
sourceFile,
|
|
115
|
+
});
|
|
144
116
|
|
|
145
117
|
function report(node, moduleSpecifier, moduleKind, importedName) {
|
|
146
118
|
if (importedName && !isForbiddenNamedExport(moduleKind, importedName)) {
|
|
@@ -150,16 +122,7 @@ export function inspectToolcraftProductSource({
|
|
|
150
122
|
createViolation({
|
|
151
123
|
getNodeLocation,
|
|
152
124
|
importedName,
|
|
153
|
-
kind:
|
|
154
|
-
moduleKind === "runtime-model-presentation"
|
|
155
|
-
? "runtime-model-presentation-ownership"
|
|
156
|
-
: moduleKind === "runtime-react"
|
|
157
|
-
? runtimeModelPresentationInternalNames.has(importedName)
|
|
158
|
-
? "runtime-model-presentation-ownership"
|
|
159
|
-
: "runtime-surface"
|
|
160
|
-
: moduleKind === "runtime-model-import"
|
|
161
|
-
? "runtime-model-import-ownership"
|
|
162
|
-
: "built-in-control",
|
|
125
|
+
kind: getImportViolationKind(moduleKind, importedName),
|
|
163
126
|
moduleSpecifier,
|
|
164
127
|
node,
|
|
165
128
|
repoPath,
|
|
@@ -169,7 +132,25 @@ export function inspectToolcraftProductSource({
|
|
|
169
132
|
}
|
|
170
133
|
|
|
171
134
|
function getModuleKind(moduleSpecifier) {
|
|
172
|
-
return
|
|
135
|
+
return getToolcraftSensitiveModuleKind({
|
|
136
|
+
moduleSpecifier,
|
|
137
|
+
rootDir,
|
|
138
|
+
sourceFilePath: absolutePath,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function inspectModuleSpecifier(node, moduleSpecifier) {
|
|
143
|
+
const moduleKind = getModuleKind(moduleSpecifier);
|
|
144
|
+
if (!moduleKind) return null;
|
|
145
|
+
if (moduleKind === "ui-control-implementation") {
|
|
146
|
+
report(node, moduleSpecifier, moduleKind);
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
if (isForbiddenToolcraftRuntimeExport(moduleKind)) {
|
|
150
|
+
report(node, moduleSpecifier, moduleKind);
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
return moduleKind;
|
|
173
154
|
}
|
|
174
155
|
|
|
175
156
|
function visit(node) {
|
|
@@ -180,6 +161,8 @@ export function inspectToolcraftProductSource({
|
|
|
180
161
|
resolveStaticString,
|
|
181
162
|
sourceFile,
|
|
182
163
|
}),
|
|
164
|
+
...inspectExportMechanics(node),
|
|
165
|
+
...inspectControls.inspectNode(node),
|
|
183
166
|
);
|
|
184
167
|
|
|
185
168
|
if (
|
|
@@ -187,7 +170,7 @@ export function inspectToolcraftProductSource({
|
|
|
187
170
|
ts.isStringLiteralLike(node.moduleSpecifier)
|
|
188
171
|
) {
|
|
189
172
|
const moduleSpecifier = node.moduleSpecifier.text;
|
|
190
|
-
const moduleKind =
|
|
173
|
+
const moduleKind = inspectModuleSpecifier(node, moduleSpecifier);
|
|
191
174
|
const importClause = node.importClause;
|
|
192
175
|
|
|
193
176
|
if (moduleKind && importClause && !importClause.isTypeOnly) {
|
|
@@ -216,7 +199,7 @@ export function inspectToolcraftProductSource({
|
|
|
216
199
|
ts.isStringLiteralLike(node.moduleSpecifier)
|
|
217
200
|
) {
|
|
218
201
|
const moduleSpecifier = node.moduleSpecifier.text;
|
|
219
|
-
const moduleKind =
|
|
202
|
+
const moduleKind = inspectModuleSpecifier(node, moduleSpecifier);
|
|
220
203
|
|
|
221
204
|
if (moduleKind && !node.isTypeOnly) {
|
|
222
205
|
if (!node.exportClause || ts.isNamespaceExport(node.exportClause)) {
|
|
@@ -238,14 +221,23 @@ export function inspectToolcraftProductSource({
|
|
|
238
221
|
|
|
239
222
|
if (
|
|
240
223
|
ts.isImportEqualsDeclaration(node) &&
|
|
241
|
-
!node.isTypeOnly &&
|
|
242
224
|
ts.isExternalModuleReference(node.moduleReference) &&
|
|
243
225
|
node.moduleReference.expression &&
|
|
244
226
|
ts.isStringLiteralLike(node.moduleReference.expression)
|
|
245
227
|
) {
|
|
246
228
|
const moduleSpecifier = node.moduleReference.expression.text;
|
|
247
|
-
const moduleKind =
|
|
248
|
-
if (moduleKind
|
|
229
|
+
const moduleKind = inspectModuleSpecifier(node, moduleSpecifier);
|
|
230
|
+
if (moduleKind && !node.isTypeOnly) {
|
|
231
|
+
report(node, moduleSpecifier, moduleKind);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (
|
|
236
|
+
ts.isImportTypeNode(node) &&
|
|
237
|
+
ts.isLiteralTypeNode(node.argument) &&
|
|
238
|
+
ts.isStringLiteralLike(node.argument.literal)
|
|
239
|
+
) {
|
|
240
|
+
inspectModuleSpecifier(node, node.argument.literal.text);
|
|
249
241
|
}
|
|
250
242
|
|
|
251
243
|
if (
|
|
@@ -266,7 +258,7 @@ export function inspectToolcraftProductSource({
|
|
|
266
258
|
ts.forEachChild(node, visit);
|
|
267
259
|
return;
|
|
268
260
|
}
|
|
269
|
-
const moduleKind =
|
|
261
|
+
const moduleKind = inspectModuleSpecifier(node, moduleSpecifier);
|
|
270
262
|
if (moduleKind) report(node, moduleSpecifier, moduleKind);
|
|
271
263
|
}
|
|
272
264
|
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
getToolcraftProductExportModuleKind,
|
|
5
|
+
} from "./toolcraft-product-export-boundary.mjs";
|
|
6
|
+
import {
|
|
7
|
+
isToolcraftPrivateControlImplementationModule,
|
|
8
|
+
} from "./toolcraft-product-control-boundary.mjs";
|
|
9
|
+
|
|
10
|
+
function toPosixPath(value) {
|
|
11
|
+
return value.split(path.sep).join("/");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function resolveSpecifierPath(sourceFilePath, moduleSpecifier, rootDir) {
|
|
15
|
+
if (moduleSpecifier.startsWith("@/") || moduleSpecifier.startsWith("#/")) {
|
|
16
|
+
return toPosixPath(path.resolve(rootDir, "src", moduleSpecifier.slice(2)));
|
|
17
|
+
}
|
|
18
|
+
if (moduleSpecifier.startsWith("/")) {
|
|
19
|
+
return toPosixPath(path.resolve(rootDir, moduleSpecifier.slice(1)));
|
|
20
|
+
}
|
|
21
|
+
if (moduleSpecifier.startsWith(".")) {
|
|
22
|
+
return toPosixPath(path.resolve(path.dirname(sourceFilePath), moduleSpecifier));
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getToolcraftSensitiveModuleKind({
|
|
28
|
+
moduleSpecifier,
|
|
29
|
+
rootDir,
|
|
30
|
+
sourceFilePath,
|
|
31
|
+
}) {
|
|
32
|
+
const normalizedSpecifier = moduleSpecifier.replaceAll("\\", "/");
|
|
33
|
+
const resolvedSpecifier = resolveSpecifierPath(
|
|
34
|
+
sourceFilePath,
|
|
35
|
+
normalizedSpecifier,
|
|
36
|
+
rootDir,
|
|
37
|
+
);
|
|
38
|
+
const exportModuleKind = getToolcraftProductExportModuleKind(
|
|
39
|
+
normalizedSpecifier,
|
|
40
|
+
resolvedSpecifier,
|
|
41
|
+
);
|
|
42
|
+
if (exportModuleKind) return exportModuleKind;
|
|
43
|
+
|
|
44
|
+
if (
|
|
45
|
+
isToolcraftPrivateControlImplementationModule({
|
|
46
|
+
moduleSpecifier: normalizedSpecifier,
|
|
47
|
+
resolvedSpecifier,
|
|
48
|
+
})
|
|
49
|
+
) {
|
|
50
|
+
return "ui-control-implementation";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (
|
|
54
|
+
/^@repo\/toolcraft-runtime\/react\/model-rendering(?:\/|$)/u.test(
|
|
55
|
+
normalizedSpecifier,
|
|
56
|
+
) ||
|
|
57
|
+
/^[#@]\/toolcraft\/runtime\/react\/model-rendering(?:\/|$)/u.test(
|
|
58
|
+
normalizedSpecifier,
|
|
59
|
+
) ||
|
|
60
|
+
resolvedSpecifier?.includes("/src/toolcraft/runtime/react/model-rendering")
|
|
61
|
+
) {
|
|
62
|
+
return "runtime-model-presentation";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (
|
|
66
|
+
/^three\/(?:addons|examples\/jsm)\/loaders(?:\/|$)/u.test(
|
|
67
|
+
normalizedSpecifier,
|
|
68
|
+
) ||
|
|
69
|
+
/^@gltf-transform(?:\/|$)/u.test(normalizedSpecifier) ||
|
|
70
|
+
/^@repo\/toolcraft-runtime\/model-import(?:\/|$)/u.test(
|
|
71
|
+
normalizedSpecifier,
|
|
72
|
+
) ||
|
|
73
|
+
/^[#@]\/toolcraft\/runtime\/model-import(?:\/|$)/u.test(
|
|
74
|
+
normalizedSpecifier,
|
|
75
|
+
) ||
|
|
76
|
+
resolvedSpecifier?.includes("/src/toolcraft/runtime/model-import")
|
|
77
|
+
) {
|
|
78
|
+
return "runtime-model-import";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (
|
|
82
|
+
/^@repo\/toolcraft-runtime\/react(?:\/|$)/u.test(normalizedSpecifier) ||
|
|
83
|
+
/^[#@]\/toolcraft\/runtime\/react(?:\/|$)/u.test(normalizedSpecifier) ||
|
|
84
|
+
resolvedSpecifier?.includes("/src/toolcraft/runtime/react")
|
|
85
|
+
) {
|
|
86
|
+
return "runtime-react";
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (
|
|
90
|
+
/^@repo\/ui(?:\/controls(?:\/|$)|$)/u.test(normalizedSpecifier) ||
|
|
91
|
+
/^[#@]\/toolcraft\/ui(?:\/components\/controls(?:\/|$)|\/controls(?:\/|$)|$)/u.test(
|
|
92
|
+
normalizedSpecifier,
|
|
93
|
+
) ||
|
|
94
|
+
resolvedSpecifier?.includes("/src/toolcraft/ui/components/controls") ||
|
|
95
|
+
/\/src\/toolcraft\/ui$/u.test(resolvedSpecifier ?? "")
|
|
96
|
+
) {
|
|
97
|
+
return "ui-controls";
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
@@ -4,6 +4,7 @@ import fs from "node:fs";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
|
|
7
|
+
import { createToolcraftPrivateEvidenceImportViolation } from "./toolcraft-product-evidence-import-policy.mjs";
|
|
7
8
|
import { isToolcraftTypeScriptCompilerAvailable } from "./toolcraft-typescript-source-evidence.mjs";
|
|
8
9
|
|
|
9
10
|
function compareCodeUnits(left, right) {
|
|
@@ -94,6 +95,15 @@ export async function evaluateToolcraftProductBoundary({
|
|
|
94
95
|
importerEvidence.push(evidence);
|
|
95
96
|
importsByImporter.set(evidence.importerRepoPath, importerEvidence);
|
|
96
97
|
}
|
|
98
|
+
const appendPrivateEvidenceImportViolations = (entry) => {
|
|
99
|
+
for (const moduleImport of importsByImporter.get(entry.repoPath) ?? []) {
|
|
100
|
+
const violation = createToolcraftPrivateEvidenceImportViolation({
|
|
101
|
+
importerRepoPath: entry.repoPath,
|
|
102
|
+
moduleImport,
|
|
103
|
+
});
|
|
104
|
+
if (violation) violations.push(violation);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
97
107
|
|
|
98
108
|
for (const entry of productEntries) {
|
|
99
109
|
const sourceRecord = localDependencyGraph.sourceRecords.get(entry.repoPath);
|
|
@@ -113,6 +123,7 @@ export async function evaluateToolcraftProductBoundary({
|
|
|
113
123
|
...boundaryEvidence.reservedEvidenceViolations,
|
|
114
124
|
...boundaryEvidence.playwrightAuthorityViolations,
|
|
115
125
|
);
|
|
126
|
+
appendPrivateEvidenceImportViolations(entry);
|
|
116
127
|
for (const evidence of importsByImporter.get(entry.repoPath) ?? []) {
|
|
117
128
|
if (evidence.resolution === "outside-inventory") {
|
|
118
129
|
violations.push({
|
|
@@ -165,6 +176,7 @@ export async function evaluateToolcraftProductBoundary({
|
|
|
165
176
|
...boundaryEvidence.playwrightAuthorityViolations,
|
|
166
177
|
...boundaryEvidence.moduleLoadingViolations,
|
|
167
178
|
);
|
|
179
|
+
appendPrivateEvidenceImportViolations(entry);
|
|
168
180
|
}
|
|
169
181
|
|
|
170
182
|
return {
|
|
@@ -75,32 +75,6 @@ test("checks Vite root-absolute imports against the same product boundary", asyn
|
|
|
75
75
|
);
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
-
test("finds built-in controls through re-exports, aliases, namespaces, and dynamic imports", async (context) => {
|
|
79
|
-
const rootDir = await createFixture(context, {
|
|
80
|
-
"src/features/control-bridge.ts": `
|
|
81
|
-
export { SliderControl as ProductSlider } from "@repo/ui/controls";
|
|
82
|
-
export { Color as ProductColor } from "@/toolcraft/ui";
|
|
83
|
-
`,
|
|
84
|
-
"src/features/dynamic.ts": `
|
|
85
|
-
export async function loadControls() {
|
|
86
|
-
return import("@/toolcraft/ui/components/controls/slider");
|
|
87
|
-
}
|
|
88
|
-
`,
|
|
89
|
-
"src/features/namespace.ts": `
|
|
90
|
-
import * as Controls from "@repo/ui";
|
|
91
|
-
export const Slider = Controls.Slider;
|
|
92
|
-
`,
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
const result = await evaluateToolcraftProductBoundary({ rootDir });
|
|
96
|
-
|
|
97
|
-
assert.equal(result.violations.length, 4);
|
|
98
|
-
assert.equal(
|
|
99
|
-
result.violations.every((violation) => violation.kind === "built-in-control"),
|
|
100
|
-
true,
|
|
101
|
-
);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
78
|
test("keeps model import, topology, and repair infrastructure runtime-owned", async (context) => {
|
|
105
79
|
const rootDir = await createFixture(context, {
|
|
106
80
|
"src/features/direct-loaders.ts": `
|