@hraness/slopcamera 3.2.4
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/LICENSE +21 -0
- package/NOTICE.md +60 -0
- package/PRIVACY.md +46 -0
- package/README.md +311 -0
- package/SECURITY.md +21 -0
- package/apps/desktop/README.md +966 -0
- package/apps/desktop/analysis/protocol.ts +223 -0
- package/apps/desktop/application/capability-binding.ts +594 -0
- package/apps/desktop/application/context.ts +97 -0
- package/apps/desktop/application/creative-iteration.ts +1385 -0
- package/apps/desktop/application/default-registry.ts +146 -0
- package/apps/desktop/application/directing-contract.ts +218 -0
- package/apps/desktop/application/directing-plan.ts +178 -0
- package/apps/desktop/application/errors.ts +18 -0
- package/apps/desktop/application/gateway-port.ts +867 -0
- package/apps/desktop/application/html-overlay-browser-runtime.ts +687 -0
- package/apps/desktop/application/html-overlay-integrity.ts +337 -0
- package/apps/desktop/application/html-overlay-renderer.ts +45 -0
- package/apps/desktop/application/index.ts +13 -0
- package/apps/desktop/application/operation-completion-checkpoint.ts +333 -0
- package/apps/desktop/application/operation-effects.ts +94 -0
- package/apps/desktop/application/operation.ts +224 -0
- package/apps/desktop/application/operations/analysis/faces.ts +244 -0
- package/apps/desktop/application/operations/analysis/music.ts +248 -0
- package/apps/desktop/application/operations/analysis/project-auto-zooms.ts +302 -0
- package/apps/desktop/application/operations/analysis/project-inactivity.ts +381 -0
- package/apps/desktop/application/operations/analysis/scenes.ts +272 -0
- package/apps/desktop/application/operations/analysis/shared.ts +202 -0
- package/apps/desktop/application/operations/derive/edit-batch.ts +967 -0
- package/apps/desktop/application/operations/derive/follow-faces.ts +454 -0
- package/apps/desktop/application/operations/edit/bind-candidate-revision.ts +91 -0
- package/apps/desktop/application/operations/edit/create-candidate-revision.ts +377 -0
- package/apps/desktop/application/operations/edit/create-revision.ts +255 -0
- package/apps/desktop/application/operations/edit/freeze-revision.ts +182 -0
- package/apps/desktop/application/operations/gateway/image.ts +41 -0
- package/apps/desktop/application/operations/gateway/index.ts +17 -0
- package/apps/desktop/application/operations/gateway/shared.ts +122 -0
- package/apps/desktop/application/operations/gateway/speech.ts +41 -0
- package/apps/desktop/application/operations/gateway/transcription.ts +42 -0
- package/apps/desktop/application/operations/gateway/video.ts +41 -0
- package/apps/desktop/application/operations/index.ts +31 -0
- package/apps/desktop/application/operations/iteration/create-candidate.ts +240 -0
- package/apps/desktop/application/operations/iteration/create-matrix.ts +117 -0
- package/apps/desktop/application/operations/iteration/select.ts +155 -0
- package/apps/desktop/application/operations/iteration/shared.ts +250 -0
- package/apps/desktop/application/operations/media/audio-effects.ts +376 -0
- package/apps/desktop/application/operations/media/binding.ts +79 -0
- package/apps/desktop/application/operations/media/capabilities.ts +112 -0
- package/apps/desktop/application/operations/media/color-grade.ts +343 -0
- package/apps/desktop/application/operations/media/html-overlay.ts +802 -0
- package/apps/desktop/application/operations/media/index.ts +8 -0
- package/apps/desktop/application/operations/media/ingest.ts +303 -0
- package/apps/desktop/application/operations/media/overlay.ts +729 -0
- package/apps/desktop/application/operations/media/shared.ts +845 -0
- package/apps/desktop/application/operations/media/transform-platform.ts +120 -0
- package/apps/desktop/application/operations/project/commit-edits.ts +2054 -0
- package/apps/desktop/application/operations/project/promote-selection.ts +495 -0
- package/apps/desktop/application/operations/project/snapshot.ts +95 -0
- package/apps/desktop/application/operations/recording/index.ts +5 -0
- package/apps/desktop/application/operations/recording/pause.ts +34 -0
- package/apps/desktop/application/operations/recording/resume.ts +34 -0
- package/apps/desktop/application/operations/recording/shared.ts +199 -0
- package/apps/desktop/application/operations/recording/start.ts +169 -0
- package/apps/desktop/application/operations/recording/stop.ts +34 -0
- package/apps/desktop/application/operations/render/bind-candidate-output.ts +324 -0
- package/apps/desktop/application/operations/render/materialize-selection.ts +322 -0
- package/apps/desktop/application/operations/render/project-caption-plan.ts +287 -0
- package/apps/desktop/application/operations/render/project-plan.ts +939 -0
- package/apps/desktop/application/operations/render/project-spatial-receipt.ts +70 -0
- package/apps/desktop/application/operations/render/project.ts +1922 -0
- package/apps/desktop/application/operations/shared.ts +67 -0
- package/apps/desktop/application/operations/slopcamera-portable.ts +1188 -0
- package/apps/desktop/application/operations/slopcamera-visuals.ts +784 -0
- package/apps/desktop/application/operations/spatial-project.ts +209 -0
- package/apps/desktop/application/operations/spatial-render.ts +415 -0
- package/apps/desktop/application/operations/spatial-scene.ts +97 -0
- package/apps/desktop/application/operations/studio.ts +143 -0
- package/apps/desktop/application/output-publication-lease.ts +163 -0
- package/apps/desktop/application/project-publication-lease.ts +233 -0
- package/apps/desktop/application/project-store.ts +196 -0
- package/apps/desktop/application/receipts.ts +533 -0
- package/apps/desktop/application/registry.ts +182 -0
- package/apps/desktop/application/spatial-assets.ts +675 -0
- package/apps/desktop/application/spatial-compositor-cadence.ts +23 -0
- package/apps/desktop/application/spatial-project-authority.ts +35 -0
- package/apps/desktop/application/spatial-project-lease.ts +126 -0
- package/apps/desktop/application/spatial-project-render-preparation.ts +225 -0
- package/apps/desktop/application/spatial-project-store.ts +286 -0
- package/apps/desktop/application/spatial-render-projection.ts +201 -0
- package/apps/desktop/application/spatial-render.ts +677 -0
- package/apps/desktop/application/spatial-spz.ts +44 -0
- package/apps/desktop/application/spatial-world-import.ts +135 -0
- package/apps/desktop/application/spatial-world-provenance.ts +46 -0
- package/apps/desktop/application/studio-port.ts +58 -0
- package/apps/desktop/application/verified-receipt-reconciliation.ts +1574 -0
- package/apps/desktop/capture/protocol.ts +689 -0
- package/apps/desktop/cli/analyzer.ts +406 -0
- package/apps/desktop/cli/args.ts +3181 -0
- package/apps/desktop/cli/asset-ingest.ts +747 -0
- package/apps/desktop/cli/atomic-render-effects.ts +210 -0
- package/apps/desktop/cli/atomic-render-platform.ts +205 -0
- package/apps/desktop/cli/atomic-render.ts +50 -0
- package/apps/desktop/cli/audio-analysis.ts +252 -0
- package/apps/desktop/cli/bounded-map.ts +39 -0
- package/apps/desktop/cli/bundle-service.ts +256 -0
- package/apps/desktop/cli/capabilities.ts +212 -0
- package/apps/desktop/cli/capture-bundle.ts +1117 -0
- package/apps/desktop/cli/command-host-resources.ts +251 -0
- package/apps/desktop/cli/commands.ts +6836 -0
- package/apps/desktop/cli/directing-blob.ts +291 -0
- package/apps/desktop/cli/directing-media.ts +517 -0
- package/apps/desktop/cli/directing-quote.ts +89 -0
- package/apps/desktop/cli/directing-service.ts +288 -0
- package/apps/desktop/cli/emoji-assets.ts +538 -0
- package/apps/desktop/cli/errors.ts +29 -0
- package/apps/desktop/cli/face-analysis-service.ts +940 -0
- package/apps/desktop/cli/filter-script.ts +76 -0
- package/apps/desktop/cli/gateway-application-port.ts +1142 -0
- package/apps/desktop/cli/gateway-credential.ts +81 -0
- package/apps/desktop/cli/gateway-media-artifacts.ts +723 -0
- package/apps/desktop/cli/gateway-media-catalog.ts +922 -0
- package/apps/desktop/cli/gateway-media-service.ts +3106 -0
- package/apps/desktop/cli/gateway-media-signature.ts +122 -0
- package/apps/desktop/cli/gateway-provider-options.ts +562 -0
- package/apps/desktop/cli/gateway-scene-provider.ts +391 -0
- package/apps/desktop/cli/help.ts +501 -0
- package/apps/desktop/cli/html-overlay-gpu.ts +97 -0
- package/apps/desktop/cli/html-overlay-renderer.ts +2478 -0
- package/apps/desktop/cli/io.ts +290 -0
- package/apps/desktop/cli/main.ts +123 -0
- package/apps/desktop/cli/media-effects-service.ts +885 -0
- package/apps/desktop/cli/media-ingest-model.ts +364 -0
- package/apps/desktop/cli/media-ingest-platform.ts +227 -0
- package/apps/desktop/cli/media-ingest-program.ts +200 -0
- package/apps/desktop/cli/media-ingest.ts +30 -0
- package/apps/desktop/cli/music-analysis-service.ts +434 -0
- package/apps/desktop/cli/mutation-lock.ts +530 -0
- package/apps/desktop/cli/native-assets.d.ts +12 -0
- package/apps/desktop/cli/native-media-runtime.macos.ts +7 -0
- package/apps/desktop/cli/overlay-playback.ts +177 -0
- package/apps/desktop/cli/paths.ts +265 -0
- package/apps/desktop/cli/portable-surface.ts +242 -0
- package/apps/desktop/cli/project-camera-receipt.ts +112 -0
- package/apps/desktop/cli/project-face-camera.ts +394 -0
- package/apps/desktop/cli/project-inactivity-service.ts +552 -0
- package/apps/desktop/cli/project-media-integrity.ts +121 -0
- package/apps/desktop/cli/project-renderer.ts +1526 -0
- package/apps/desktop/cli/project-service.ts +519 -0
- package/apps/desktop/cli/project-state-transaction.ts +520 -0
- package/apps/desktop/cli/query-limits.ts +1 -0
- package/apps/desktop/cli/recording-controller.ts +1567 -0
- package/apps/desktop/cli/recording-daemon.ts +931 -0
- package/apps/desktop/cli/recording-ref.ts +56 -0
- package/apps/desktop/cli/renamed-environment.ts +6 -0
- package/apps/desktop/cli/renderer.ts +1439 -0
- package/apps/desktop/cli/run-cli-test-helper.ts +60 -0
- package/apps/desktop/cli/scene-analysis-service.ts +879 -0
- package/apps/desktop/cli/spatial-compositor-verifier.ts +213 -0
- package/apps/desktop/cli/spatial-project-service.ts +90 -0
- package/apps/desktop/cli/spatial-scene-service.ts +105 -0
- package/apps/desktop/cli/spatial-world-service.ts +39 -0
- package/apps/desktop/cli/speech-analysis-service.ts +682 -0
- package/apps/desktop/cli/studio-assemble.ts +58 -0
- package/apps/desktop/cli/studio-command.ts +60 -0
- package/apps/desktop/cli/studio-custody.ts +60 -0
- package/apps/desktop/cli/studio-encode.ts +216 -0
- package/apps/desktop/cli/studio-exr.ts +52 -0
- package/apps/desktop/cli/studio-files.ts +179 -0
- package/apps/desktop/cli/studio-output-validation.ts +162 -0
- package/apps/desktop/cli/studio-process.ts +145 -0
- package/apps/desktop/cli/studio-runtime.ts +77 -0
- package/apps/desktop/cli/studio-scaffold.ts +70 -0
- package/apps/desktop/cli/studio-service.ts +301 -0
- package/apps/desktop/cli/studio-spatial-asset.ts +248 -0
- package/apps/desktop/cli/studio-template-names.ts +3 -0
- package/apps/desktop/cli/studio-workflow.ts +19 -0
- package/apps/desktop/cli/time.ts +25 -0
- package/apps/desktop/cli/workflow-code.ts +584 -0
- package/apps/desktop/cli/workflow-runs.ts +576 -0
- package/apps/desktop/code/advanced.ts +139 -0
- package/apps/desktop/code/application-node-planner.ts +1288 -0
- package/apps/desktop/code/compiler.ts +329 -0
- package/apps/desktop/code/contracts.ts +13 -0
- package/apps/desktop/code/creative-recipes.ts +94 -0
- package/apps/desktop/code/define-workflow.ts +115 -0
- package/apps/desktop/code/editing.ts +284 -0
- package/apps/desktop/code/file-candidate-provenance.ts +420 -0
- package/apps/desktop/code/file-candidate.ts +69 -0
- package/apps/desktop/code/graph-builder.ts +10 -0
- package/apps/desktop/code/host-resource-policy.ts +55 -0
- package/apps/desktop/code/plan-contracts.ts +159 -0
- package/apps/desktop/code/planning.ts +361 -0
- package/apps/desktop/code/public.ts +134 -0
- package/apps/desktop/code/reference-projection.ts +62 -0
- package/apps/desktop/code/run-contracts.ts +466 -0
- package/apps/desktop/code/run-store.ts +2478 -0
- package/apps/desktop/code/runtime-identity.ts +328 -0
- package/apps/desktop/code/scheduler.ts +3067 -0
- package/apps/desktop/code/semantic-builder.ts +1436 -0
- package/apps/desktop/code/source-bundle.ts +1641 -0
- package/apps/desktop/code/source-typecheck.ts +211 -0
- package/apps/desktop/code/testing.ts +79 -0
- package/apps/desktop/code/worker-client.ts +1675 -0
- package/apps/desktop/code/worker-effects.ts +141 -0
- package/apps/desktop/code/worker-entry.ts +435 -0
- package/apps/desktop/code/worker-lease-guardian.ts +179 -0
- package/apps/desktop/code/worker-process-identity.ts +484 -0
- package/apps/desktop/code/worker-protocol.ts +211 -0
- package/apps/desktop/code/workflow-effects.ts +132 -0
- package/apps/desktop/contracts/analysis.ts +949 -0
- package/apps/desktop/contracts/edit.ts +576 -0
- package/apps/desktop/contracts/index.ts +9 -0
- package/apps/desktop/contracts/media-effects.ts +139 -0
- package/apps/desktop/contracts/project-render.ts +644 -0
- package/apps/desktop/contracts/project.ts +740 -0
- package/apps/desktop/contracts/recording.ts +1434 -0
- package/apps/desktop/contracts/render.ts +334 -0
- package/apps/desktop/contracts/runtime.ts +155 -0
- package/apps/desktop/contracts/spatial-compositor.ts +58 -0
- package/apps/desktop/contracts/spatial-project.ts +159 -0
- package/apps/desktop/contracts/spatial-world.ts +48 -0
- package/apps/desktop/contracts/video-effects.ts +120 -0
- package/apps/desktop/core/alignment-apply.ts +400 -0
- package/apps/desktop/core/audio-alignment.ts +466 -0
- package/apps/desktop/core/auto-zoom.ts +209 -0
- package/apps/desktop/core/canonical-json.ts +14 -0
- package/apps/desktop/core/emoji.ts +210 -0
- package/apps/desktop/core/events.ts +409 -0
- package/apps/desktop/core/face-framing.ts +533 -0
- package/apps/desktop/core/face-tracks.ts +326 -0
- package/apps/desktop/core/inactivity.ts +137 -0
- package/apps/desktop/core/index.ts +30 -0
- package/apps/desktop/core/intervals.ts +123 -0
- package/apps/desktop/core/montage.ts +236 -0
- package/apps/desktop/core/music-analysis.ts +518 -0
- package/apps/desktop/core/plan.ts +244 -0
- package/apps/desktop/core/project-auto-zoom.ts +75 -0
- package/apps/desktop/core/project-camera-spatial.ts +676 -0
- package/apps/desktop/core/project-camera.ts +403 -0
- package/apps/desktop/core/project-captions.ts +888 -0
- package/apps/desktop/core/project-inactivity.ts +125 -0
- package/apps/desktop/core/project-metadata.ts +927 -0
- package/apps/desktop/core/project-plan.ts +375 -0
- package/apps/desktop/core/project-render-plan.ts +303 -0
- package/apps/desktop/core/project-time.ts +469 -0
- package/apps/desktop/core/render-plan.ts +442 -0
- package/apps/desktop/core/scene-cache.ts +174 -0
- package/apps/desktop/core/scene-sampling.ts +448 -0
- package/apps/desktop/core/spatial-compositor.ts +22 -0
- package/apps/desktop/core/spatial-durability.ts +99 -0
- package/apps/desktop/core/spatial-project.ts +169 -0
- package/apps/desktop/core/spatial-shot-clock.ts +32 -0
- package/apps/desktop/core/speech-analysis.ts +333 -0
- package/apps/desktop/core/storage.ts +970 -0
- package/apps/desktop/core/time-map.ts +91 -0
- package/apps/desktop/core/time.ts +61 -0
- package/apps/desktop/core/video-effects.ts +660 -0
- package/apps/desktop/dist/cli/NebulaSans-Bold-26se8aek.otf +0 -0
- package/apps/desktop/dist/cli/NebulaSans-Bold-bcz7y08t.woff2 +0 -0
- package/apps/desktop/dist/cli/NebulaSans-Book-5ax05zvn.woff2 +0 -0
- package/apps/desktop/dist/cli/NebulaSans-Book-8cenzchw.otf +0 -0
- package/apps/desktop/dist/cli/main.js +5086 -0
- package/apps/desktop/html-overlay/catalog.ts +171 -0
- package/apps/desktop/html-overlay/contracts.ts +372 -0
- package/apps/desktop/html-overlay/execution-profile.ts +77 -0
- package/apps/desktop/html-overlay/index.ts +98 -0
- package/apps/desktop/html-overlay/libraries.ts +263 -0
- package/apps/desktop/html-overlay/random.ts +49 -0
- package/apps/desktop/html-overlay/runtime.ts +813 -0
- package/apps/desktop/html-overlay/scaffolds.ts +792 -0
- package/apps/desktop/html-overlay/spark-runtime.ts +88 -0
- package/apps/desktop/html-overlay/spatial-splat-runtime.ts +60 -0
- package/apps/desktop/html-overlay/spatial.ts +720 -0
- package/apps/desktop/studio/assets/README.md +39 -0
- package/apps/desktop/studio/assets/contracts.ts +129 -0
- package/apps/desktop/studio/assets/network.ts +64 -0
- package/apps/desktop/studio/assets/poly-haven.ts +148 -0
- package/apps/desktop/studio/drivers/blender_driver.py +466 -0
- package/apps/desktop/studio/drivers/cadquery_driver.py +176 -0
- package/apps/desktop/studio/education/driver.py +308 -0
- package/apps/desktop/studio/education/lesson.py +180 -0
- package/apps/desktop/studio/education/toolkit.py +249 -0
- package/apps/desktop/workflows/chaptered-demo.ts +48 -0
- package/apps/desktop/workflows/creative-iteration.ts +107 -0
- package/apps/desktop/workflows/creative-selection.ts +92 -0
- package/apps/desktop/workflows/fragments.ts +486 -0
- package/apps/desktop/workflows/index.ts +93 -0
- package/apps/desktop/workflows/polished-screen-demo.ts +128 -0
- package/apps/desktop/workflows/scene-direction.ts +12 -0
- package/apps/desktop/workflows/social-variants.ts +75 -0
- package/apps/desktop/workflows/talking-head-cleanup.ts +53 -0
- package/dist/NebulaSans-Bold-26se8aek.otf +0 -0
- package/dist/NebulaSans-Bold-bcz7y08t.woff2 +0 -0
- package/dist/NebulaSans-Book-5ax05zvn.woff2 +0 -0
- package/dist/NebulaSans-Book-8cenzchw.otf +0 -0
- package/dist/cli.js +479 -0
- package/dist/code/advanced.js +270 -0
- package/dist/code/index.js +2240 -0
- package/dist/generate.js +24 -0
- package/dist/host-resources.js +26 -0
- package/dist/index-42zsesc1.js +2257 -0
- package/dist/index-7308egqr.js +48 -0
- package/dist/index-8txs6fkn.js +712 -0
- package/dist/index-mcy8z0br.js +192 -0
- package/dist/index-p63wavx0.js +2029 -0
- package/dist/index-r7gdhmsp.js +424 -0
- package/dist/index-sh6xbav6.js +1219 -0
- package/dist/index-z1w83f81.js +4 -0
- package/dist/index-z7239b4h.js +2363 -0
- package/dist/index-zfeg9hmw.js +2013 -0
- package/dist/index.js +241 -0
- package/dist/operations.js +29 -0
- package/dist/skill-install-dh0ntqba.js +10 -0
- package/dist/vectorize/worker.js +142 -0
- package/dist/workflow.js +16 -0
- package/docs/README.md +38 -0
- package/docs/studio.md +215 -0
- package/examples/studio/blender/README.md +26 -0
- package/examples/studio/blender/character.py +152 -0
- package/examples/studio/blender/cloth.py +101 -0
- package/examples/studio/blender/color_chart.py +29 -0
- package/examples/studio/blender/fluid.py +78 -0
- package/examples/studio/blender/import_model.py +74 -0
- package/examples/studio/blender/product.py +53 -0
- package/examples/studio/blender/shaded_street.py +481 -0
- package/examples/studio/blender/studio_scene.py +147 -0
- package/examples/studio/cadquery/README.md +13 -0
- package/examples/studio/cadquery/bracket.py +36 -0
- package/examples/studio/cadquery/import_step.py +12 -0
- package/examples/studio/education/README.md +46 -0
- package/examples/studio/education/lesson.json +99 -0
- package/examples/studio/education/scene.py +7 -0
- package/examples/studio/hybrid-scene.ts +96 -0
- package/examples/studio/native-workflow.ts +14 -0
- package/examples/studio/vgpu/README.md +64 -0
- package/examples/studio/vgpu/heat-field.mjs +290 -0
- package/package.json +304 -0
- package/packages/scene/src/index.ts +1 -0
- package/packages/scene/src/scene.ts +215 -0
- package/schema/diagram.schema.json +334 -0
- package/skills/slopcamera/SKILL.md +45 -0
- package/skills/slopcamera/agents/openai.yaml +4 -0
- package/skills/slopcamera/references/customization.md +77 -0
- package/skills/slopcamera/references/diagrams.md +153 -0
- package/skills/slopcamera/references/directed-scenes.md +42 -0
- package/skills/slopcamera/references/directing-video.md +18 -0
- package/skills/slopcamera/references/educational-video.md +26 -0
- package/skills/slopcamera/references/gateway-media.md +134 -0
- package/skills/slopcamera/references/install.md +62 -0
- package/skills/slopcamera/references/native-studio.md +31 -0
- package/skills/slopcamera/references/reference-led-3d.md +140 -0
- package/skills/slopcamera/references/rubber-stamp-examples/poster-example-1.jpg +0 -0
- package/skills/slopcamera/references/rubber-stamp-examples/poster-example-2.jpg +0 -0
- package/skills/slopcamera/references/rubber-stamp-examples/stamp-style-1.png +0 -0
- package/skills/slopcamera/references/rubber-stamp-examples/stamp-style-2.png +0 -0
- package/skills/slopcamera/references/rubber-stamp-field-notes.md +144 -0
- package/skills/slopcamera/references/vectorization.md +29 -0
- package/skills/slopcamera/references/video-projects.md +187 -0
- package/skills/slopcamera/references/visual-communication.md +120 -0
- package/skills/slopcamera/references/workflows-sdk.md +45 -0
- package/skills/slopcamera/scripts/compose-rubber-stamp-field-note.ts +229 -0
- package/src/artifacts.ts +106 -0
- package/src/assets/fonts/nebula-sans/LICENSE.txt +96 -0
- package/src/assets/fonts/nebula-sans/NebulaSans-Bold.otf +0 -0
- package/src/assets/fonts/nebula-sans/NebulaSans-Bold.woff2 +0 -0
- package/src/assets/fonts/nebula-sans/NebulaSans-Book.otf +0 -0
- package/src/assets/fonts/nebula-sans/NebulaSans-Book.woff2 +0 -0
- package/src/assets/fonts/nebula-sans/PROVENANCE.md +21 -0
- package/src/assets.d.ts +9 -0
- package/src/cli.ts +601 -0
- package/src/cloud-errors.ts +26 -0
- package/src/code/advanced.ts +10 -0
- package/src/code/boundary.ts +21 -0
- package/src/code/canonical-json.ts +129 -0
- package/src/code/compiler.ts +953 -0
- package/src/code/contracts.ts +576 -0
- package/src/code/define-workflow.ts +334 -0
- package/src/code/errors.ts +41 -0
- package/src/code/graph-builder.ts +945 -0
- package/src/code/index.ts +121 -0
- package/src/code/json-snapshot.ts +899 -0
- package/src/code/json-utf8.ts +88 -0
- package/src/code/portable-builder.ts +136 -0
- package/src/code/projection.ts +378 -0
- package/src/code/public-operations.ts +450 -0
- package/src/code/runtime.ts +580 -0
- package/src/code/sha256.ts +36 -0
- package/src/config.ts +180 -0
- package/src/desktop.ts +253 -0
- package/src/fs.ts +10 -0
- package/src/generate.ts +704 -0
- package/src/host-resource-posix.ts +161 -0
- package/src/host-resources.ts +1749 -0
- package/src/icons.ts +58 -0
- package/src/index.ts +200 -0
- package/src/label-layout.ts +130 -0
- package/src/layout.ts +413 -0
- package/src/lint.ts +127 -0
- package/src/mcp/boundary.ts +354 -0
- package/src/mcp/index.ts +33 -0
- package/src/mcp/server.ts +272 -0
- package/src/mcp/tools.ts +963 -0
- package/src/mcp/types.ts +71 -0
- package/src/operations.ts +775 -0
- package/src/parse.ts +861 -0
- package/src/process-environment.ts +17 -0
- package/src/render.ts +437 -0
- package/src/skill-install.ts +49 -0
- package/src/spatial-scene/authoring.ts +27 -0
- package/src/spatial-scene/camera-track.ts +83 -0
- package/src/spatial-scene/contracts.ts +277 -0
- package/src/spatial-scene/evaluate.ts +145 -0
- package/src/spatial-scene/gltf.ts +558 -0
- package/src/spatial-scene/identity.ts +260 -0
- package/src/spatial-scene/index.ts +10 -0
- package/src/spatial-scene/inspect.ts +68 -0
- package/src/spatial-scene/math.ts +280 -0
- package/src/spatial-scene/patch.ts +131 -0
- package/src/spatial-scene/time.ts +53 -0
- package/src/studio/contracts.ts +129 -0
- package/src/studio/index.ts +2 -0
- package/src/studio/plan.ts +156 -0
- package/src/studio/shared.ts +41 -0
- package/src/theme.ts +68 -0
- package/src/tldr.ts +474 -0
- package/src/types.ts +212 -0
- package/src/vectorize/archive.ts +101 -0
- package/src/vectorize/command.ts +797 -0
- package/src/vectorize/index.ts +27 -0
- package/src/vectorize/limits.ts +61 -0
- package/src/vectorize/metrics.ts +351 -0
- package/src/vectorize/pixels.ts +323 -0
- package/src/vectorize/supervisor.ts +339 -0
- package/src/vectorize/svg.ts +188 -0
- package/src/vectorize/tool.ts +542 -0
- package/src/vectorize/types.ts +113 -0
- package/src/vectorize/vectorize.ts +634 -0
- package/src/vectorize/worker-protocol.ts +40 -0
- package/src/vectorize/worker.ts +209 -0
- package/src/version.ts +1 -0
- package/src/workflow.ts +409 -0
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
PROJECT_EXPORT_PROFILE_IDS,
|
|
5
|
+
ProjectExportVariantSchema,
|
|
6
|
+
ProjectRenderOutputPathSchema,
|
|
7
|
+
ProjectRenderSyncPolicySchema,
|
|
8
|
+
projectExportVariantId,
|
|
9
|
+
resolveProjectRenderTarget,
|
|
10
|
+
} from "../contracts";
|
|
11
|
+
import type {
|
|
12
|
+
ProjectCaptionRequest,
|
|
13
|
+
ProjectExportVariant,
|
|
14
|
+
ProjectRenderTarget,
|
|
15
|
+
ProjectRenderTier,
|
|
16
|
+
} from "../contracts";
|
|
17
|
+
import {
|
|
18
|
+
MediaOverlayInputSchema as MediaOverlayOperationInputSchema,
|
|
19
|
+
type ProjectRenderOutput,
|
|
20
|
+
type ProjectRenderPlanOutput,
|
|
21
|
+
} from "../application/operations";
|
|
22
|
+
import type {
|
|
23
|
+
CommittedProjectHandle,
|
|
24
|
+
PreparedOverlayHandle,
|
|
25
|
+
ProjectEditRevisionHandle,
|
|
26
|
+
ProjectHandle,
|
|
27
|
+
Ref,
|
|
28
|
+
WorkflowBuilder,
|
|
29
|
+
} from "../code/public";
|
|
30
|
+
|
|
31
|
+
const WorkflowOverlayBodySchema = MediaOverlayOperationInputSchema.omit({
|
|
32
|
+
capabilityBindings: true,
|
|
33
|
+
project: true,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export const WorkflowOverlayRequestSchema = WorkflowOverlayBodySchema.extend({
|
|
37
|
+
key: z.string()
|
|
38
|
+
.regex(/^[a-z0-9][a-z0-9-]{0,63}$/u),
|
|
39
|
+
}).strict().superRefine((overlay, context) => {
|
|
40
|
+
if (overlay.source.kind === "emoji" && overlay.source.resolved !== undefined) {
|
|
41
|
+
context.addIssue({
|
|
42
|
+
code: "custom",
|
|
43
|
+
message: "Workflow overlay inputs cannot carry host-resolved emoji authority.",
|
|
44
|
+
path: ["source", "resolved"],
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export type WorkflowOverlayRequest = z.infer<
|
|
50
|
+
typeof WorkflowOverlayRequestSchema
|
|
51
|
+
>;
|
|
52
|
+
|
|
53
|
+
export const WorkflowOverlaySetSchema = z.array(WorkflowOverlayRequestSchema)
|
|
54
|
+
.min(1)
|
|
55
|
+
.max(256)
|
|
56
|
+
.superRefine((overlays, context) => {
|
|
57
|
+
const seen = new Set<string>();
|
|
58
|
+
for (const [index, overlay] of overlays.entries()) {
|
|
59
|
+
if (seen.has(overlay.key)) {
|
|
60
|
+
context.addIssue({
|
|
61
|
+
code: "custom",
|
|
62
|
+
message: "Workflow overlay keys must be unique.",
|
|
63
|
+
path: [index, "key"],
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
seen.add(overlay.key);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export interface ComposedOverlaySet {
|
|
71
|
+
readonly prepared: readonly PreparedOverlayHandle[];
|
|
72
|
+
readonly project: CommittedProjectHandle;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function prepareAndCommitOverlays(
|
|
76
|
+
workflow: WorkflowBuilder,
|
|
77
|
+
key: string,
|
|
78
|
+
input: {
|
|
79
|
+
readonly overlays: readonly WorkflowOverlayRequest[];
|
|
80
|
+
readonly project: ProjectHandle;
|
|
81
|
+
},
|
|
82
|
+
): ComposedOverlaySet {
|
|
83
|
+
const overlays = WorkflowOverlaySetSchema.parse(input.overlays);
|
|
84
|
+
const fragment = workflow.namespace(key);
|
|
85
|
+
const preparation = fragment.namespace("prepare");
|
|
86
|
+
const prepared = overlays.map((overlay) => {
|
|
87
|
+
const { key: overlayKey, ...request } = overlay;
|
|
88
|
+
return preparation.media.overlay(overlayKey, {
|
|
89
|
+
...request,
|
|
90
|
+
identityKey: request.identityKey ?? overlayKey,
|
|
91
|
+
project: input.project,
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
const batch = fragment.edits.addOverlays("batch", prepared);
|
|
95
|
+
const project = fragment.project.commitEdits("commit", {
|
|
96
|
+
batch,
|
|
97
|
+
project: input.project,
|
|
98
|
+
});
|
|
99
|
+
return Object.freeze({
|
|
100
|
+
prepared: Object.freeze(prepared),
|
|
101
|
+
project,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const WorkflowRenderOptionsSchema = z.strictObject({
|
|
106
|
+
maximumBytes: z.number()
|
|
107
|
+
.int()
|
|
108
|
+
.safe()
|
|
109
|
+
.positive()
|
|
110
|
+
.max(1_099_511_627_776)
|
|
111
|
+
.optional(),
|
|
112
|
+
output: ProjectRenderOutputPathSchema.optional(),
|
|
113
|
+
syncPolicy: ProjectRenderSyncPolicySchema.optional(),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
export type WorkflowRenderOptions = z.infer<
|
|
117
|
+
typeof WorkflowRenderOptionsSchema
|
|
118
|
+
>;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Exact render geometry has one owner. New workflows select a render target;
|
|
122
|
+
* legacy callers may still provide explicit dimensions without a render tier.
|
|
123
|
+
*/
|
|
124
|
+
export type WorkflowProjectRenderGeometry =
|
|
125
|
+
| {
|
|
126
|
+
readonly target: ProjectRenderTarget;
|
|
127
|
+
readonly frameRate?: never;
|
|
128
|
+
readonly pixelHeight?: never;
|
|
129
|
+
readonly pixelWidth?: never;
|
|
130
|
+
}
|
|
131
|
+
| {
|
|
132
|
+
readonly target?: undefined;
|
|
133
|
+
readonly frameRate?: number;
|
|
134
|
+
readonly pixelHeight: number;
|
|
135
|
+
readonly pixelWidth: number;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export interface ResolvedWorkflowRenderOptions {
|
|
139
|
+
readonly maximumBytes: number;
|
|
140
|
+
readonly output: z.infer<typeof ProjectRenderOutputPathSchema>;
|
|
141
|
+
readonly syncPolicy: z.infer<typeof ProjectRenderSyncPolicySchema>;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function resolveWorkflowRenderOptions(
|
|
145
|
+
options: WorkflowRenderOptions | undefined,
|
|
146
|
+
defaultOutput: string,
|
|
147
|
+
): ResolvedWorkflowRenderOptions {
|
|
148
|
+
return {
|
|
149
|
+
maximumBytes: options?.maximumBytes ?? 8 * 1024 * 1024 * 1024,
|
|
150
|
+
output: ProjectRenderOutputPathSchema.parse(
|
|
151
|
+
options?.output ?? defaultOutput,
|
|
152
|
+
),
|
|
153
|
+
syncPolicy: options?.syncPolicy ?? "require-verified",
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function renderFrozenProjectPresentations(
|
|
158
|
+
workflow: WorkflowBuilder,
|
|
159
|
+
key: string,
|
|
160
|
+
input: {
|
|
161
|
+
readonly captioned?: {
|
|
162
|
+
readonly captions: ProjectCaptionRequest;
|
|
163
|
+
readonly output: ResolvedWorkflowRenderOptions;
|
|
164
|
+
};
|
|
165
|
+
readonly output?: ResolvedWorkflowRenderOptions;
|
|
166
|
+
readonly project: ProjectHandle;
|
|
167
|
+
} & WorkflowProjectRenderGeometry,
|
|
168
|
+
) {
|
|
169
|
+
if (input.output === undefined && input.captioned === undefined) {
|
|
170
|
+
throw new Error("A frozen project target requires at least one presentation.");
|
|
171
|
+
}
|
|
172
|
+
const fragment = workflow.namespace(key);
|
|
173
|
+
const geometry = input.target === undefined
|
|
174
|
+
? {
|
|
175
|
+
frameRate: input.frameRate,
|
|
176
|
+
pixelHeight: input.pixelHeight,
|
|
177
|
+
pixelWidth: input.pixelWidth,
|
|
178
|
+
}
|
|
179
|
+
: resolveProjectRenderTarget(input.target);
|
|
180
|
+
const revision = fragment.project.freezeRevision("revision", {
|
|
181
|
+
pixelHeight: geometry.pixelHeight,
|
|
182
|
+
pixelWidth: geometry.pixelWidth,
|
|
183
|
+
project: input.project,
|
|
184
|
+
});
|
|
185
|
+
const clean = input.output === undefined
|
|
186
|
+
? undefined
|
|
187
|
+
: (() => {
|
|
188
|
+
const plan = fragment.render.plan("plan", {
|
|
189
|
+
revision,
|
|
190
|
+
...(geometry.frameRate === undefined
|
|
191
|
+
? {}
|
|
192
|
+
: { settings: { frameRate: geometry.frameRate } }),
|
|
193
|
+
});
|
|
194
|
+
return Object.freeze({
|
|
195
|
+
output: fragment.render.project("output", {
|
|
196
|
+
...(input.target === undefined
|
|
197
|
+
? {}
|
|
198
|
+
: { target: input.target }),
|
|
199
|
+
output: {
|
|
200
|
+
maximumBytes: input.output.maximumBytes,
|
|
201
|
+
path: input.output.output,
|
|
202
|
+
},
|
|
203
|
+
plan,
|
|
204
|
+
syncPolicy: input.output.syncPolicy,
|
|
205
|
+
}),
|
|
206
|
+
plan,
|
|
207
|
+
});
|
|
208
|
+
})();
|
|
209
|
+
const captioned = input.captioned === undefined
|
|
210
|
+
? undefined
|
|
211
|
+
: (() => {
|
|
212
|
+
const fragmentCaptioned = fragment.namespace("captioned");
|
|
213
|
+
const plan = fragmentCaptioned.render.captionedPlan("plan", {
|
|
214
|
+
revision,
|
|
215
|
+
settings: {
|
|
216
|
+
captions: input.captioned.captions,
|
|
217
|
+
...(geometry.frameRate === undefined
|
|
218
|
+
? {}
|
|
219
|
+
: { frameRate: geometry.frameRate }),
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
return Object.freeze({
|
|
223
|
+
output: fragmentCaptioned.render.project("output", {
|
|
224
|
+
...(input.target === undefined
|
|
225
|
+
? {}
|
|
226
|
+
: { target: input.target }),
|
|
227
|
+
output: {
|
|
228
|
+
maximumBytes: input.captioned.output.maximumBytes,
|
|
229
|
+
path: input.captioned.output.output,
|
|
230
|
+
},
|
|
231
|
+
plan,
|
|
232
|
+
syncPolicy: input.captioned.output.syncPolicy,
|
|
233
|
+
}),
|
|
234
|
+
plan,
|
|
235
|
+
});
|
|
236
|
+
})();
|
|
237
|
+
return Object.freeze({ captioned, clean, revision });
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export function renderFrozenProject(
|
|
241
|
+
workflow: WorkflowBuilder,
|
|
242
|
+
key: string,
|
|
243
|
+
input: {
|
|
244
|
+
readonly captioned?: {
|
|
245
|
+
readonly captions: ProjectCaptionRequest;
|
|
246
|
+
readonly output: ResolvedWorkflowRenderOptions;
|
|
247
|
+
};
|
|
248
|
+
readonly output: ResolvedWorkflowRenderOptions;
|
|
249
|
+
readonly project: ProjectHandle;
|
|
250
|
+
} & WorkflowProjectRenderGeometry,
|
|
251
|
+
) {
|
|
252
|
+
const rendered = renderFrozenProjectPresentations(workflow, key, input);
|
|
253
|
+
if (rendered.clean === undefined) {
|
|
254
|
+
throw new Error("A frozen project render omitted its required clean presentation.");
|
|
255
|
+
}
|
|
256
|
+
return Object.freeze({
|
|
257
|
+
captioned: rendered.captioned,
|
|
258
|
+
output: rendered.clean.output,
|
|
259
|
+
plan: rendered.clean.plan,
|
|
260
|
+
revision: rendered.revision,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export interface RenderedProjectVariant {
|
|
265
|
+
readonly output: Ref<ProjectRenderOutput>;
|
|
266
|
+
readonly plan: Ref<ProjectRenderPlanOutput>;
|
|
267
|
+
readonly revision: ProjectEditRevisionHandle;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export const WorkflowProjectVariantMatrixSchema = z.array(
|
|
271
|
+
ProjectExportVariantSchema,
|
|
272
|
+
).min(1).max(16).superRefine((variants, context) => {
|
|
273
|
+
const identities = new Set<string>();
|
|
274
|
+
for (const [index, variant] of variants.entries()) {
|
|
275
|
+
const identity = projectExportVariantId(variant);
|
|
276
|
+
if (identities.has(identity)) {
|
|
277
|
+
context.addIssue({
|
|
278
|
+
code: "custom",
|
|
279
|
+
message: "Project export variants must be unique.",
|
|
280
|
+
path: [index],
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
identities.add(identity);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Expands orthogonal canvas, quality, and caption choices into independent
|
|
289
|
+
* graph branches. Clean and captioned presentations of one concrete target
|
|
290
|
+
* share the same immutable revision. The graph keeps distinct geometries
|
|
291
|
+
* independent even though today's conservative project-render resource
|
|
292
|
+
* serializes their expensive FFmpeg work.
|
|
293
|
+
*/
|
|
294
|
+
export function renderProjectVariantMatrix(
|
|
295
|
+
workflow: WorkflowBuilder,
|
|
296
|
+
key: string,
|
|
297
|
+
input: {
|
|
298
|
+
readonly captions?: ProjectCaptionRequest;
|
|
299
|
+
readonly maximumBytes: number;
|
|
300
|
+
readonly outputDirectory: string;
|
|
301
|
+
readonly outputLayout?: "flat" | "tiered";
|
|
302
|
+
readonly project: ProjectHandle;
|
|
303
|
+
readonly syncPolicy: z.infer<typeof ProjectRenderSyncPolicySchema>;
|
|
304
|
+
readonly variants: readonly ProjectExportVariant[];
|
|
305
|
+
},
|
|
306
|
+
): Readonly<Record<string, RenderedProjectVariant>> {
|
|
307
|
+
const directory = input.outputDirectory.replace(/\/+$/u, "");
|
|
308
|
+
const requested = WorkflowProjectVariantMatrixSchema.parse(input.variants);
|
|
309
|
+
const outputLayout = z.enum(["flat", "tiered"]).parse(
|
|
310
|
+
input.outputLayout ?? "tiered",
|
|
311
|
+
);
|
|
312
|
+
if (
|
|
313
|
+
outputLayout === "flat"
|
|
314
|
+
&& new Set(requested.map(variant => variant.tier)).size > 1
|
|
315
|
+
) {
|
|
316
|
+
throw new Error("A flat project export matrix cannot contain multiple tiers.");
|
|
317
|
+
}
|
|
318
|
+
if (
|
|
319
|
+
requested.some(variant => variant.captionMode === "burn-in")
|
|
320
|
+
&& input.captions === undefined
|
|
321
|
+
) {
|
|
322
|
+
throw new Error("Captioned project export variants require a caption request.");
|
|
323
|
+
}
|
|
324
|
+
const namespace = workflow.namespace(key);
|
|
325
|
+
const groups = new Map<string, {
|
|
326
|
+
readonly profileId: ProjectExportVariant["profileId"];
|
|
327
|
+
readonly tier: ProjectRenderTier;
|
|
328
|
+
readonly modes: ReadonlySet<ProjectExportVariant["captionMode"]>;
|
|
329
|
+
}>();
|
|
330
|
+
for (const variant of requested) {
|
|
331
|
+
const groupId = `${variant.tier}/${variant.profileId}`;
|
|
332
|
+
if (groups.has(groupId)) continue;
|
|
333
|
+
groups.set(groupId, {
|
|
334
|
+
modes: new Set(requested
|
|
335
|
+
.filter(candidate => (
|
|
336
|
+
candidate.tier === variant.tier
|
|
337
|
+
&& candidate.profileId === variant.profileId
|
|
338
|
+
))
|
|
339
|
+
.map(candidate => candidate.captionMode)),
|
|
340
|
+
profileId: variant.profileId,
|
|
341
|
+
tier: variant.tier,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
const outputs: Record<string, RenderedProjectVariant> = {};
|
|
345
|
+
for (const group of groups.values()) {
|
|
346
|
+
const groupDirectory = outputLayout === "tiered"
|
|
347
|
+
? `${directory}/${group.tier}`
|
|
348
|
+
: directory;
|
|
349
|
+
const rendered = renderFrozenProjectPresentations(
|
|
350
|
+
outputLayout === "tiered" ? namespace.namespace(group.tier) : namespace,
|
|
351
|
+
group.profileId,
|
|
352
|
+
{
|
|
353
|
+
...(group.modes.has("burn-in") && input.captions !== undefined
|
|
354
|
+
? {
|
|
355
|
+
captioned: {
|
|
356
|
+
captions: input.captions,
|
|
357
|
+
output: {
|
|
358
|
+
maximumBytes: input.maximumBytes,
|
|
359
|
+
output: ProjectRenderOutputPathSchema.parse(
|
|
360
|
+
`${groupDirectory}/${group.profileId}-captioned.mp4`,
|
|
361
|
+
),
|
|
362
|
+
syncPolicy: input.syncPolicy,
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
}
|
|
366
|
+
: {}),
|
|
367
|
+
...(group.modes.has("clean")
|
|
368
|
+
? {
|
|
369
|
+
output: {
|
|
370
|
+
maximumBytes: input.maximumBytes,
|
|
371
|
+
output: ProjectRenderOutputPathSchema.parse(
|
|
372
|
+
`${groupDirectory}/${group.profileId}.mp4`,
|
|
373
|
+
),
|
|
374
|
+
syncPolicy: input.syncPolicy,
|
|
375
|
+
},
|
|
376
|
+
}
|
|
377
|
+
: {}),
|
|
378
|
+
target: {
|
|
379
|
+
canvas: { kind: "profile", profileId: group.profileId },
|
|
380
|
+
tier: group.tier,
|
|
381
|
+
},
|
|
382
|
+
project: input.project,
|
|
383
|
+
},
|
|
384
|
+
);
|
|
385
|
+
if (group.modes.has("clean")) {
|
|
386
|
+
if (rendered.clean === undefined) {
|
|
387
|
+
throw new Error("Clean project export branch was not constructed.");
|
|
388
|
+
}
|
|
389
|
+
outputs[projectExportVariantId({
|
|
390
|
+
captionMode: "clean",
|
|
391
|
+
profileId: group.profileId,
|
|
392
|
+
tier: group.tier,
|
|
393
|
+
})] = Object.freeze({
|
|
394
|
+
output: rendered.clean.output,
|
|
395
|
+
plan: rendered.clean.plan,
|
|
396
|
+
revision: rendered.revision,
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
if (group.modes.has("burn-in")) {
|
|
400
|
+
if (rendered.captioned === undefined) {
|
|
401
|
+
throw new Error("Captioned project export branch was not constructed.");
|
|
402
|
+
}
|
|
403
|
+
outputs[projectExportVariantId({
|
|
404
|
+
captionMode: "burn-in",
|
|
405
|
+
profileId: group.profileId,
|
|
406
|
+
tier: group.tier,
|
|
407
|
+
})] = Object.freeze({
|
|
408
|
+
output: rendered.captioned.output,
|
|
409
|
+
plan: rendered.captioned.plan,
|
|
410
|
+
revision: rendered.revision,
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return Object.freeze(outputs);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
export function renderCommonProjectVariants(
|
|
418
|
+
workflow: WorkflowBuilder,
|
|
419
|
+
key: string,
|
|
420
|
+
input: {
|
|
421
|
+
readonly captions?: ProjectCaptionRequest;
|
|
422
|
+
readonly maximumBytes: number;
|
|
423
|
+
readonly outputDirectory: string;
|
|
424
|
+
readonly project: ProjectHandle;
|
|
425
|
+
readonly syncPolicy: z.infer<typeof ProjectRenderSyncPolicySchema>;
|
|
426
|
+
readonly tier?: ProjectRenderTier;
|
|
427
|
+
},
|
|
428
|
+
) {
|
|
429
|
+
const explicitTier = input.tier !== undefined;
|
|
430
|
+
const tier = input.tier ?? "final";
|
|
431
|
+
const variants = PROJECT_EXPORT_PROFILE_IDS.flatMap(profileId => [
|
|
432
|
+
ProjectExportVariantSchema.parse({
|
|
433
|
+
captionMode: "clean",
|
|
434
|
+
profileId,
|
|
435
|
+
tier,
|
|
436
|
+
}),
|
|
437
|
+
...(input.captions === undefined
|
|
438
|
+
? []
|
|
439
|
+
: [ProjectExportVariantSchema.parse({
|
|
440
|
+
captionMode: "burn-in",
|
|
441
|
+
profileId,
|
|
442
|
+
tier,
|
|
443
|
+
})]),
|
|
444
|
+
]);
|
|
445
|
+
const outputs = renderProjectVariantMatrix(workflow, key, {
|
|
446
|
+
...(input.captions === undefined ? {} : { captions: input.captions }),
|
|
447
|
+
maximumBytes: input.maximumBytes,
|
|
448
|
+
outputDirectory: input.outputDirectory,
|
|
449
|
+
outputLayout: explicitTier ? "tiered" : "flat",
|
|
450
|
+
project: input.project,
|
|
451
|
+
syncPolicy: input.syncPolicy,
|
|
452
|
+
variants,
|
|
453
|
+
});
|
|
454
|
+
const profile = (profileId: ProjectExportVariant["profileId"]) => {
|
|
455
|
+
const rendered = outputs[projectExportVariantId({
|
|
456
|
+
captionMode: "clean",
|
|
457
|
+
profileId,
|
|
458
|
+
tier,
|
|
459
|
+
})]!;
|
|
460
|
+
const captioned = input.captions === undefined
|
|
461
|
+
? undefined
|
|
462
|
+
: (() => {
|
|
463
|
+
const variant = outputs[projectExportVariantId({
|
|
464
|
+
captionMode: "burn-in",
|
|
465
|
+
profileId,
|
|
466
|
+
tier,
|
|
467
|
+
})]!;
|
|
468
|
+
return Object.freeze({
|
|
469
|
+
output: variant.output,
|
|
470
|
+
plan: variant.plan,
|
|
471
|
+
});
|
|
472
|
+
})();
|
|
473
|
+
return Object.freeze({
|
|
474
|
+
captioned,
|
|
475
|
+
output: rendered.output,
|
|
476
|
+
plan: rendered.plan,
|
|
477
|
+
revision: rendered.revision,
|
|
478
|
+
});
|
|
479
|
+
};
|
|
480
|
+
return Object.freeze({
|
|
481
|
+
feedPortrait: profile("feed-portrait"),
|
|
482
|
+
landscape: profile("landscape"),
|
|
483
|
+
portrait: profile("portrait"),
|
|
484
|
+
square: profile("square"),
|
|
485
|
+
});
|
|
486
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import type { OperationRegistry } from "../application/registry";
|
|
4
|
+
import {
|
|
5
|
+
buildWorkflow,
|
|
6
|
+
type BuiltWorkflow,
|
|
7
|
+
type WorkflowDefinition,
|
|
8
|
+
} from "../code/define-workflow";
|
|
9
|
+
import type { WorkflowOutputValue } from "../code/contracts";
|
|
10
|
+
import { chapteredDemo } from "./chaptered-demo";
|
|
11
|
+
import { directedScene } from "./scene-direction";
|
|
12
|
+
import { creativeIteration } from "./creative-iteration";
|
|
13
|
+
import { creativeSelection } from "./creative-selection";
|
|
14
|
+
import { polishedScreenDemo } from "./polished-screen-demo";
|
|
15
|
+
import { socialVariants } from "./social-variants";
|
|
16
|
+
import { talkingHeadCleanup } from "./talking-head-cleanup";
|
|
17
|
+
|
|
18
|
+
export * from "./fragments";
|
|
19
|
+
|
|
20
|
+
export interface BuiltInWorkflow {
|
|
21
|
+
readonly description: string;
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly inputSchema: z.ZodType<unknown>;
|
|
24
|
+
readonly inputSchemaId: string;
|
|
25
|
+
readonly title: string;
|
|
26
|
+
readonly version: number;
|
|
27
|
+
build(registry: Pick<OperationRegistry, "list">, input: unknown): BuiltWorkflow;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function catalogEntry<Input, Output extends WorkflowOutputValue>(
|
|
31
|
+
definition: WorkflowDefinition<Input, Output>,
|
|
32
|
+
metadata: {
|
|
33
|
+
readonly description: string;
|
|
34
|
+
readonly title: string;
|
|
35
|
+
},
|
|
36
|
+
): BuiltInWorkflow {
|
|
37
|
+
return Object.freeze({
|
|
38
|
+
build: (registry: Pick<OperationRegistry, "list">, input: unknown) => (
|
|
39
|
+
buildWorkflow(definition, registry, input)
|
|
40
|
+
),
|
|
41
|
+
description: metadata.description,
|
|
42
|
+
id: definition.id,
|
|
43
|
+
inputSchema: definition.inputSchema,
|
|
44
|
+
inputSchemaId: definition.inputSchemaId,
|
|
45
|
+
title: metadata.title,
|
|
46
|
+
version: definition.version,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const BUILT_IN_WORKFLOWS: readonly BuiltInWorkflow[] = Object.freeze([
|
|
51
|
+
catalogEntry(directedScene, {
|
|
52
|
+
description: "Render a prepared immutable spatial scene composition with exact frame timing and retained project audio.",
|
|
53
|
+
title: "Directed scene",
|
|
54
|
+
}),
|
|
55
|
+
catalogEntry(chapteredDemo, {
|
|
56
|
+
description: "Freeze the current chapter, overlay, and media composition and render an exact video.",
|
|
57
|
+
title: "Chaptered demo",
|
|
58
|
+
}),
|
|
59
|
+
catalogEntry(creativeIteration, {
|
|
60
|
+
description: "Render independent low-cost candidates from one frozen project and close them into an explicit selection matrix.",
|
|
61
|
+
title: "Creative iteration",
|
|
62
|
+
}),
|
|
63
|
+
catalogEntry(creativeSelection, {
|
|
64
|
+
description: "Record an explicit matrix choice, then optionally promote it and materialize verified deliveries.",
|
|
65
|
+
title: "Creative selection",
|
|
66
|
+
}),
|
|
67
|
+
catalogEntry(polishedScreenDemo, {
|
|
68
|
+
description: "Analyze cleanup and media evidence in parallel, then render a provenance-bearing multi-face camera revision.",
|
|
69
|
+
title: "Polished screen demo",
|
|
70
|
+
}),
|
|
71
|
+
catalogEntry(socialVariants, {
|
|
72
|
+
description: "Freeze and render landscape, square, and vertical videos as independent parallel branches.",
|
|
73
|
+
title: "Social variants",
|
|
74
|
+
}),
|
|
75
|
+
catalogEntry(talkingHeadCleanup, {
|
|
76
|
+
description: "Remove long pauses, retain local face evidence, and render a landscape talking-head video.",
|
|
77
|
+
title: "Talking-head cleanup",
|
|
78
|
+
}),
|
|
79
|
+
].sort((left, right) => left.id.localeCompare(right.id)));
|
|
80
|
+
|
|
81
|
+
export function builtInWorkflow(id: string): BuiltInWorkflow | undefined {
|
|
82
|
+
return BUILT_IN_WORKFLOWS.find(workflow => workflow.id === id);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export {
|
|
86
|
+
chapteredDemo,
|
|
87
|
+
directedScene,
|
|
88
|
+
creativeIteration,
|
|
89
|
+
creativeSelection,
|
|
90
|
+
polishedScreenDemo,
|
|
91
|
+
socialVariants,
|
|
92
|
+
talkingHeadCleanup,
|
|
93
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
defineWorkflow,
|
|
5
|
+
polishedInteractionEffects,
|
|
6
|
+
} from "../code/public";
|
|
7
|
+
import {
|
|
8
|
+
FaceFollowRequestOptionsSchema,
|
|
9
|
+
} from "../application/operations";
|
|
10
|
+
import { resolveProjectExportProfile } from "../contracts";
|
|
11
|
+
import {
|
|
12
|
+
resolveWorkflowRenderOptions,
|
|
13
|
+
WorkflowRenderOptionsSchema,
|
|
14
|
+
} from "./fragments";
|
|
15
|
+
|
|
16
|
+
export const PolishedScreenDemoInputSchema = z.strictObject({
|
|
17
|
+
cameraSource: z.string().min(1).max(256),
|
|
18
|
+
faceFollow: FaceFollowRequestOptionsSchema,
|
|
19
|
+
musicSource: z.string().min(1).max(256),
|
|
20
|
+
project: z.string().regex(/^project_[A-Za-z0-9][A-Za-z0-9_-]*$/u),
|
|
21
|
+
render: WorkflowRenderOptionsSchema.optional(),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const polishedScreenDemo = defineWorkflow({
|
|
25
|
+
id: "polished-screen-demo",
|
|
26
|
+
inputSchema: PolishedScreenDemoInputSchema,
|
|
27
|
+
inputSchemaId: "slopcamera.workflow.polished-screen-demo.input/v4",
|
|
28
|
+
version: 4,
|
|
29
|
+
build(workflow, input) {
|
|
30
|
+
const project = workflow.project.snapshot("project", input.project);
|
|
31
|
+
const parallel = workflow.namespace("analyze");
|
|
32
|
+
const inactivity = parallel.analysis.inactivity("inactivity", { project });
|
|
33
|
+
const autoZooms = parallel.analysis.projectAutoZooms("auto-zooms", {
|
|
34
|
+
project,
|
|
35
|
+
});
|
|
36
|
+
const faces = parallel.analysis.faces("faces", {
|
|
37
|
+
project,
|
|
38
|
+
source: input.cameraSource,
|
|
39
|
+
});
|
|
40
|
+
const music = parallel.analysis.music("music", {
|
|
41
|
+
project,
|
|
42
|
+
source: input.musicSource,
|
|
43
|
+
});
|
|
44
|
+
const edits = workflow.advanced.edits.completeBatchV2(
|
|
45
|
+
"editorial-decisions",
|
|
46
|
+
{
|
|
47
|
+
cutRanges: inactivity.select("cuts"),
|
|
48
|
+
ordered: [
|
|
49
|
+
{
|
|
50
|
+
kind: "add-zooms",
|
|
51
|
+
zooms: autoZooms.select("operations"),
|
|
52
|
+
},
|
|
53
|
+
polishedInteractionEffects(autoZooms.select("sourcePlacementId")),
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
const committed = workflow.advanced.project.commitCompleteEditsV2(
|
|
58
|
+
"commit-base-edits",
|
|
59
|
+
{
|
|
60
|
+
batch: edits,
|
|
61
|
+
project,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
// The analyses publish append-only project references. Make their
|
|
65
|
+
// completion causally precede the mutable edit commit so its receipt is
|
|
66
|
+
// the exact post-analysis generation used by face framing.
|
|
67
|
+
after: [faces, music],
|
|
68
|
+
},
|
|
69
|
+
);
|
|
70
|
+
const selection = input.faceFollow.selection ?? { kind: "largest" as const };
|
|
71
|
+
const faceFraming = workflow.edits.followFaces("face-framing", {
|
|
72
|
+
analysisId: faces.select("analysisId"),
|
|
73
|
+
aspect: "16:9",
|
|
74
|
+
easing: input.faceFollow.easing ?? { kind: "ease-in-out" },
|
|
75
|
+
framing: input.faceFollow.framing
|
|
76
|
+
?? (selection.kind === "all" ? "group" : "medium"),
|
|
77
|
+
gapPolicy: input.faceFollow.gapPolicy ?? "hold",
|
|
78
|
+
headroom: input.faceFollow.headroom ?? 0.08,
|
|
79
|
+
maximumZoom: input.faceFollow.maximumZoom ?? 4,
|
|
80
|
+
minimumZoom: input.faceFollow.minimumZoom ?? 1,
|
|
81
|
+
placementId: input.faceFollow.placementId,
|
|
82
|
+
project: committed,
|
|
83
|
+
projectRange: input.faceFollow.projectRange,
|
|
84
|
+
requireAllSelectedFaces:
|
|
85
|
+
input.faceFollow.requireAllSelectedFaces ?? false,
|
|
86
|
+
selection,
|
|
87
|
+
smoothingSeconds: input.faceFollow.smoothingSeconds ?? 0.25,
|
|
88
|
+
});
|
|
89
|
+
const render = workflow.namespace("render");
|
|
90
|
+
const revision = render.project.createRevision("revision", {
|
|
91
|
+
draft: faceFraming,
|
|
92
|
+
project: committed,
|
|
93
|
+
});
|
|
94
|
+
const renderProfile = resolveProjectExportProfile("landscape", "final");
|
|
95
|
+
const renderPlan = render.render.plan("plan", {
|
|
96
|
+
revision,
|
|
97
|
+
settings: { frameRate: renderProfile.frameRate },
|
|
98
|
+
});
|
|
99
|
+
const output = resolveWorkflowRenderOptions(
|
|
100
|
+
input.render,
|
|
101
|
+
"renders/polished-screen-demo/final.mp4",
|
|
102
|
+
);
|
|
103
|
+
const rendered = render.render.project("output", {
|
|
104
|
+
target: {
|
|
105
|
+
canvas: { kind: "profile", profileId: "landscape" },
|
|
106
|
+
tier: "final",
|
|
107
|
+
},
|
|
108
|
+
output: {
|
|
109
|
+
maximumBytes: output.maximumBytes,
|
|
110
|
+
path: output.output,
|
|
111
|
+
},
|
|
112
|
+
plan: renderPlan,
|
|
113
|
+
syncPolicy: output.syncPolicy,
|
|
114
|
+
});
|
|
115
|
+
return {
|
|
116
|
+
autoZooms,
|
|
117
|
+
faceFollow: {
|
|
118
|
+
cameraMoveId: faceFraming.select("cameraMove").select("cameraMoveId"),
|
|
119
|
+
revision: revision.revision,
|
|
120
|
+
selectedTrackIds: faceFraming.select("selectedTrackIds"),
|
|
121
|
+
},
|
|
122
|
+
faces,
|
|
123
|
+
music,
|
|
124
|
+
render: rendered,
|
|
125
|
+
renderPlan,
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
});
|