@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,966 @@
|
|
|
1
|
+
# Slopcamera desktop and CLI
|
|
2
|
+
|
|
3
|
+
Slopcamera captures synchronized raw inputs into repository-local bundles, combines independent camera and audio takes on one typed project clock, then applies non-destructive edits through the `slopcamera` CLI. The CLI is the product surface for agents. The macOS window remains only start, pause, resume, stop, and input status.
|
|
4
|
+
|
|
5
|
+
## Recording bundles
|
|
6
|
+
|
|
7
|
+
The default root is `artifacts/slopcamera/recordings/`, resolved from the Slopcamera checkout. `artifacts/` is gitignored and excluded from Vercel uploads. Slopcamera never falls back to an external data directory.
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
rec_<id>/
|
|
11
|
+
├── manifest.json
|
|
12
|
+
├── events/
|
|
13
|
+
│ ├── segment_0001-cursor.jsonl
|
|
14
|
+
│ ├── segment_0001-input.jsonl
|
|
15
|
+
│ ├── segment_0001-windows.jsonl
|
|
16
|
+
│ └── segment_0001-focus.jsonl
|
|
17
|
+
├── segments/
|
|
18
|
+
│ ├── segment_0001/
|
|
19
|
+
│ │ ├── display_<id>.mp4
|
|
20
|
+
│ │ ├── camera_<id>.mov
|
|
21
|
+
│ │ └── microphone_<id>.m4a
|
|
22
|
+
│ └── segment_0002/
|
|
23
|
+
├── edits/
|
|
24
|
+
├── analysis/
|
|
25
|
+
└── renders/
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Each connected display is recorded independently. System audio, microphone audio, and webcam video remain independently addressable logical tracks even when a native container carries multiple streams. Pause finalizes the current synchronized segment; resume opens another. Finalized media and event streams are immutable.
|
|
29
|
+
|
|
30
|
+
Cursor, click, key activity, focused-input bounds, window geometry, display topology, and lifecycle metadata use integer source-time microseconds plus native monotonic timestamps. Typed-text capture is disabled by default. Secure fields are always redacted.
|
|
31
|
+
|
|
32
|
+
## Multi-asset projects
|
|
33
|
+
|
|
34
|
+
Projects live under the equally gitignored `artifacts/slopcamera/projects/` root. Generated images, videos, speech, transcripts, local effects, and immutable invocation receipts live under `artifacts/slopcamera/generated/`. A project owns references to immutable recording tracks and content-addressed imported media, not rewritten raw files.
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
project_<id>/
|
|
38
|
+
├── project.json # assets, streams, placements, sync maps, analysis refs
|
|
39
|
+
├── imports/ # extension-independent, content-addressed camera/audio takes
|
|
40
|
+
├── edits/current.json # one global project-time edit plan
|
|
41
|
+
├── analysis/
|
|
42
|
+
│ ├── alignment/ # immutable audio-alignment evidence
|
|
43
|
+
│ ├── faces/ # local face boxes and geometry-continuity tracks
|
|
44
|
+
│ ├── inactivity/ # synchronized freeze, silence, and interaction evidence
|
|
45
|
+
│ ├── music/ # presence, tempo/changes, and musical key
|
|
46
|
+
│ ├── scenes/ # sampled-frame descriptions and upload provenance
|
|
47
|
+
│ ├── speech/ # words, utterances, and filler candidates
|
|
48
|
+
│ └── scene-frames/ # bounded derived JPEG samples
|
|
49
|
+
├── assets/ # content-addressed overlay inputs
|
|
50
|
+
└── renders/ # immutable plans plus verified video receipts
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Every imported take starts with an `unverified` placement. Audio alignment produces immutable candidates; applying one creates a checked, drift-aware map from that asset clock into project time. Cuts, trims, speed changes, camera moves, metadata zooms, and overlays exist once in project time, so all video and audio placements remain synchronized. Every asset-derived filler decision records the placement sync hash used to project it; stale decisions fail closed.
|
|
54
|
+
|
|
55
|
+
One output-time camera evaluator drives both the rendered video crop and the
|
|
56
|
+
metadata compositor. Cursor samples, click cues, and focused-input typing
|
|
57
|
+
therefore follow manual or face-derived pans and pushes through cuts and speed
|
|
58
|
+
changes instead of detaching from the pixels they annotate.
|
|
59
|
+
|
|
60
|
+
## CLI
|
|
61
|
+
|
|
62
|
+
Run commands from the repository root:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
# Capture and inspect one synchronized recording.
|
|
66
|
+
slopcamera doctor
|
|
67
|
+
slopcamera record start
|
|
68
|
+
slopcamera record start \
|
|
69
|
+
--display <display-id> \
|
|
70
|
+
--camera-device <camera-id> \
|
|
71
|
+
--microphone-device <microphone-id>
|
|
72
|
+
slopcamera record pause
|
|
73
|
+
slopcamera record resume
|
|
74
|
+
slopcamera record stop
|
|
75
|
+
slopcamera recordings list --json
|
|
76
|
+
slopcamera inspect <recording>
|
|
77
|
+
slopcamera events <recording> --kind click --around 12.5s --jsonl
|
|
78
|
+
slopcamera render plan <recording> --display primary --json
|
|
79
|
+
slopcamera render run <recording> --output renders/final.mp4
|
|
80
|
+
|
|
81
|
+
# Build and align a multi-angle project.
|
|
82
|
+
slopcamera projects create --from-recording <recording> --name 'Slopcamera take'
|
|
83
|
+
slopcamera project add <project> camera-a.mov --role camera
|
|
84
|
+
slopcamera project add <project> field-recorder.wav --role portable-audio
|
|
85
|
+
slopcamera align analyze <project> --reference <asset:audio-stream> --target <asset:audio-stream> --apply
|
|
86
|
+
slopcamera project inspect <project> --json
|
|
87
|
+
|
|
88
|
+
# Discover and run every current Vercel AI Gateway media model.
|
|
89
|
+
slopcamera ai models list --type image --json
|
|
90
|
+
slopcamera ai models list --type video --json
|
|
91
|
+
slopcamera ai models show google/veo-3.1-generate-001 --json
|
|
92
|
+
AI_GATEWAY_API_KEY="$AI_GATEWAY_API_KEY" slopcamera ai models list --type image
|
|
93
|
+
slopcamera ai image generate --model openai/gpt-image-1.5 --prompt 'minimal chapter card'
|
|
94
|
+
slopcamera ai image generate --model google/gemini-3.1-flash-image \
|
|
95
|
+
--prompt 'revise this composition' --image reference.png --allow-cloud-upload
|
|
96
|
+
slopcamera ai video generate --model google/veo-3.1-generate-001 \
|
|
97
|
+
--prompt-file shot.txt --frame first=opening.png --frame last=closing.png \
|
|
98
|
+
--duration 8 --resolution 1080p --generate-audio true --allow-cloud-upload
|
|
99
|
+
slopcamera ai video generate --model alibaba/wan-v2.7-r2v \
|
|
100
|
+
--prompt 'continue the camera move' \
|
|
101
|
+
--reference 'https://cdn.example/source.mp4' \
|
|
102
|
+
--provider-options artifacts/slopcamera/private/wan-reference.json --allow-cloud-upload
|
|
103
|
+
slopcamera ai speech generate --model xai/grok-tts --text-file narration.txt --voice eve
|
|
104
|
+
slopcamera ai transcribe interview.wav --model openai/whisper-1 \
|
|
105
|
+
--allow-cloud-audio-upload --format all
|
|
106
|
+
|
|
107
|
+
# Create non-destructive local derivatives.
|
|
108
|
+
slopcamera media audio interview.wav --denoise --compressor --volume-db -2
|
|
109
|
+
slopcamera media audio screen.mp4 --delay-ms 160 --reverb room
|
|
110
|
+
slopcamera media color screen.mp4 --preset cinematic --temperature 0.08
|
|
111
|
+
|
|
112
|
+
# Structure local media evidence.
|
|
113
|
+
slopcamera analyze inactivity <project> --min-duration 3s --handle cut
|
|
114
|
+
slopcamera analyze inactivity <project> --min-duration 3s --handle cut --apply
|
|
115
|
+
slopcamera analyze music <project> --source <asset:audio-stream> --window 20s
|
|
116
|
+
slopcamera analyze faces <project> --source <asset:video-stream>
|
|
117
|
+
slopcamera faces list <project> <face-analysis-id> --min-duration 750ms
|
|
118
|
+
slopcamera analyze scenes <project> --source <asset:video-stream>
|
|
119
|
+
AI_GATEWAY_API_KEY=… slopcamera doctor
|
|
120
|
+
slopcamera analyze scenes <project> --source <asset:video-stream> --execute --allow-cloud-upload
|
|
121
|
+
slopcamera analyze speech <project> --source <asset:audio-stream> --model /path/to/ggml-model.bin
|
|
122
|
+
slopcamera fillers list <project> <speech-analysis-id> --auto-only
|
|
123
|
+
slopcamera fillers apply <project> <speech-analysis-id> <candidate-id>
|
|
124
|
+
|
|
125
|
+
# Project-wide edits and output.
|
|
126
|
+
slopcamera project edit <project> cut 8s 11.2s
|
|
127
|
+
slopcamera project edit <project> speed 20s 35s 1.5
|
|
128
|
+
slopcamera project edit <project> camera push --placement <id> --stream <id> --from 4s --to 6s --center 0.68,0.42 --end-zoom 1.8
|
|
129
|
+
slopcamera project edit <project> camera reframe --placement <id> --stream <id> --from 10s --to 14s --from-frame 0.5,0.5,1 --to-frame 0.67,0.45,2
|
|
130
|
+
slopcamera project edit <project> camera path --placement <id> --stream <id> --keyframe 0s,0.5,0.5,1 --keyframe 2s,0.65,0.42,1.4 --keyframe 5s,0.4,0.5,2
|
|
131
|
+
slopcamera project edit <project> camera follow-faces --placement <id> --analysis <face-analysis-id> --from 20s --to 35s --select largest
|
|
132
|
+
slopcamera project edit <project> zoom --from 12s --to 16s --target focused-input --source-placement <recording-placement>
|
|
133
|
+
slopcamera project edit <project> cursor on --click-highlight true --source-placement <recording-placement>
|
|
134
|
+
slopcamera project edit <project> typed-text on --idle-timeout 900ms --source-placement <recording-placement>
|
|
135
|
+
slopcamera project edit <project> overlay add --kind gif --source reaction.gif --from 4s --to 9s --loop
|
|
136
|
+
slopcamera project render plan <project> --json
|
|
137
|
+
slopcamera project render run <project> --output renders/final.mp4
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`record start` defaults to every connected display, system audio, the default
|
|
141
|
+
camera, and the default microphone. `doctor --json` exposes the exact selectable
|
|
142
|
+
IDs. Repeat `--display` for a bounded display subset, or pass
|
|
143
|
+
`--camera-device`/`--microphone-device` to pin a device instead of following the
|
|
144
|
+
system default. Duplicate IDs, unavailable IDs, and selections above the
|
|
145
|
+
16-display capture bound fail before media starts.
|
|
146
|
+
|
|
147
|
+
Read commands default to a bounded text summary and accept `--json`; event queries also accept `--jsonl`. Mutations write atomically and return a normalized plan hash. Camera mutation receipts additionally return the created move ID, keyframe count, bounded face selection when applicable, and exact `camera show`/`camera remove` next commands.
|
|
148
|
+
|
|
149
|
+
### Agent code mode
|
|
150
|
+
|
|
151
|
+
Code mode lets an agent describe the whole edit as a typed TypeScript graph instead of issuing one CLI command after another. Built-in workflows, custom programs, and the migrated CLI slices resolve through the same closed application-operation registry; legacy CLI-only analyzers and mutations remain characterized adapters until they are migrated operation by operation. The host owns every registered operation's schema, privacy classification, resource claims, retry rules, and receipts.
|
|
152
|
+
|
|
153
|
+
The surface is progressively disclosed:
|
|
154
|
+
|
|
155
|
+
| Need | Surface |
|
|
156
|
+
| --- | --- |
|
|
157
|
+
| One edit or analysis | Existing `slopcamera` command |
|
|
158
|
+
| A common complete recipe | `slopcamera workflows ...` |
|
|
159
|
+
| A project-specific composition | `@hraness/slopcamera/local/code` semantic builder |
|
|
160
|
+
| A reusable operation set | A namespaced TypeScript workflow fragment |
|
|
161
|
+
| A new privileged capability | A reviewed application operation and registry entry |
|
|
162
|
+
|
|
163
|
+
Discover the installed vocabulary and the six reusable recipes:
|
|
164
|
+
|
|
165
|
+
```sh
|
|
166
|
+
slopcamera operations list --json
|
|
167
|
+
slopcamera operations show render.project@2 --json
|
|
168
|
+
slopcamera workflows list --json
|
|
169
|
+
slopcamera workflows show polished-screen-demo --json
|
|
170
|
+
slopcamera workflows show creative-iteration --json
|
|
171
|
+
slopcamera workflows show creative-selection --json
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
List output stays compact; `operations show <kind>[@<version>] --json`
|
|
175
|
+
expands the selected operation's owned input and output JSON Schemas. A kind
|
|
176
|
+
with multiple registered versions must include `@<version>`.
|
|
177
|
+
`workflows show --json` expands the selected workflow's input JSON Schema. An
|
|
178
|
+
agent can therefore discover one contract without loading the entire catalog.
|
|
179
|
+
|
|
180
|
+
`code check`, `code plan`, and `code run` semantically typecheck custom
|
|
181
|
+
TypeScript before evaluating it. Planning then builds and validates the
|
|
182
|
+
complete graph, derives its effect and resource envelope, binds the current
|
|
183
|
+
structural project state, and prints deterministic dependency waves. It does
|
|
184
|
+
not execute registered operations. Typechecking and bundling consume the same
|
|
185
|
+
private immutable snapshot of the bytes that passed import-policy scanning.
|
|
186
|
+
Running with an expected custom-code plan hash fails if source, input,
|
|
187
|
+
registry, Bun revision, worker implementation, selected native-helper bytes,
|
|
188
|
+
or a bound subject changed.
|
|
189
|
+
|
|
190
|
+
```sh
|
|
191
|
+
# A built-in workflow: independent analyses join at one checked edit commit,
|
|
192
|
+
# then a face-derived camera path becomes the immutable render revision.
|
|
193
|
+
slopcamera workflows plan polished-screen-demo \
|
|
194
|
+
--input artifacts/slopcamera/private/polished-input.json --json
|
|
195
|
+
slopcamera workflows run polished-screen-demo \
|
|
196
|
+
--input artifacts/slopcamera/private/polished-input.json --jobs 4 --jsonl
|
|
197
|
+
|
|
198
|
+
# A custom workflow starts from a non-overwriting typed template.
|
|
199
|
+
slopcamera code init artifacts/slopcamera/private/workflows/my-demo.ts
|
|
200
|
+
slopcamera code check artifacts/slopcamera/private/workflows/my-demo.ts --json
|
|
201
|
+
slopcamera code plan artifacts/slopcamera/private/workflows/my-demo.ts \
|
|
202
|
+
--input artifacts/slopcamera/private/my-demo-input.json --json
|
|
203
|
+
slopcamera code run artifacts/slopcamera/private/workflows/my-demo.ts \
|
|
204
|
+
--input artifacts/slopcamera/private/my-demo-input.json \
|
|
205
|
+
--plan <graph-plan-sha256> --jobs 4 --jsonl
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
The polished input names the exact camera placement and project-time range; the
|
|
209
|
+
workflow never guesses which layer contains the presenter. Selecting `all`
|
|
210
|
+
uses group framing by default, while `largest` uses medium framing:
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"cameraSource": "asset_camera01:stream_camera01",
|
|
215
|
+
"faceFollow": {
|
|
216
|
+
"placementId": "placement_camera01",
|
|
217
|
+
"projectRange": { "startUs": 0, "endUs": 30000000 },
|
|
218
|
+
"selection": { "kind": "all" }
|
|
219
|
+
},
|
|
220
|
+
"musicSource": "asset_music01:stream_music01",
|
|
221
|
+
"project": "project_demo01"
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Workflow construction is declarative: a method returns a typed `Ref<T>`, and embedding that reference in another node infers and independently verifies the dependency. Namespaces give reusable fragments stable node identities. Ordinary TypeScript remains available for loops over known variants, calculations from validated inputs, and composition:
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
import { z } from "zod";
|
|
229
|
+
import { defineWorkflow } from "@hraness/slopcamera/local/code";
|
|
230
|
+
import {
|
|
231
|
+
renderFrozenProject,
|
|
232
|
+
resolveWorkflowRenderOptions,
|
|
233
|
+
} from "@hraness/slopcamera/local/code/workflows";
|
|
234
|
+
|
|
235
|
+
const Input = z.strictObject({
|
|
236
|
+
project: z.string(),
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
export default defineWorkflow({
|
|
240
|
+
id: "my-demo",
|
|
241
|
+
inputSchema: Input,
|
|
242
|
+
inputSchemaId: "example.workflow.my-demo.input/v1",
|
|
243
|
+
version: 1,
|
|
244
|
+
build(workflow, input) {
|
|
245
|
+
const project = workflow.project.snapshot("project", input.project);
|
|
246
|
+
const evidence = workflow.namespace("evidence");
|
|
247
|
+
const inactivity = evidence.analysis.inactivity("inactivity", { project });
|
|
248
|
+
const edits = workflow.edits.batch("edits", {
|
|
249
|
+
cutRanges: inactivity.select("cuts"),
|
|
250
|
+
});
|
|
251
|
+
const committed = workflow.project.commitEdits("commit", {
|
|
252
|
+
batch: edits,
|
|
253
|
+
project,
|
|
254
|
+
});
|
|
255
|
+
const rendered = renderFrozenProject(workflow, "final", {
|
|
256
|
+
target: {
|
|
257
|
+
canvas: { kind: "profile", profileId: "landscape" },
|
|
258
|
+
tier: "final",
|
|
259
|
+
},
|
|
260
|
+
output: resolveWorkflowRenderOptions(
|
|
261
|
+
undefined,
|
|
262
|
+
"renders/my-demo/final.mp4",
|
|
263
|
+
),
|
|
264
|
+
project: committed,
|
|
265
|
+
});
|
|
266
|
+
return { render: rendered.output };
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
`social-variants@3` uses the same target model for 16:9, 9:16, 1:1, and 4:5.
|
|
272
|
+
It defaults to full-duration 24 fps preview geometry and accepts
|
|
273
|
+
`"tier": "final"` for the 30 fps final canvas sizes. When captions are requested,
|
|
274
|
+
clean and burn-in outputs share one immutable geometry revision; independent
|
|
275
|
+
geometry branches remain explicit in the graph. V2 render nodes reserve the
|
|
276
|
+
shared bounded CPU and FFmpeg pools plus one exclusive video-encode slot. Every
|
|
277
|
+
other FFmpeg operation also reserves the complete pools until its recipe binds
|
|
278
|
+
and proves a smaller execution-wide thread budget. On
|
|
279
|
+
macOS and Linux, that admission state is machine-global across Slopcamera
|
|
280
|
+
processes and Git worktrees, so encodes from parallel agents cannot contend
|
|
281
|
+
with one another. Other ready work remains eligible when its declared
|
|
282
|
+
resources fit.
|
|
283
|
+
|
|
284
|
+
`creative-iteration@1` takes two through sixteen stable variant keys. Every
|
|
285
|
+
candidate uses the same frozen project snapshot, owns an immutable edit
|
|
286
|
+
revision, and renders a full-length preview at the selected standard profile.
|
|
287
|
+
The workflow closes the verified candidate set into a matrix and stops. It
|
|
288
|
+
does not choose or promote a winner:
|
|
289
|
+
|
|
290
|
+
```json
|
|
291
|
+
{
|
|
292
|
+
"project": "project_demo01",
|
|
293
|
+
"previewProfile": "portrait",
|
|
294
|
+
"candidates": [
|
|
295
|
+
{ "variantKey": "baseline" },
|
|
296
|
+
{
|
|
297
|
+
"variantKey": "tight-cut",
|
|
298
|
+
"ordered": [
|
|
299
|
+
{ "kind": "trim", "range": { "startUs": 0, "endUs": 30000000 } }
|
|
300
|
+
]
|
|
301
|
+
}
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Use `creative-selection@1` with the matrix reference returned by that run.
|
|
307
|
+
The selection is always an immutable artifact. Setting `"promote": true`
|
|
308
|
+
adds a checked editorial compare-and-swap. Named deliveries copy a selected
|
|
309
|
+
verified render without changing the current edit plan:
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
{
|
|
313
|
+
"matrix": { "...": "the exact matrix reference from the prior run" },
|
|
314
|
+
"variantKey": "tight-cut",
|
|
315
|
+
"promote": true,
|
|
316
|
+
"deliveries": [
|
|
317
|
+
{
|
|
318
|
+
"deliveryKey": "review-copy",
|
|
319
|
+
"renderName": "preview",
|
|
320
|
+
"destinationPath": "renders/review/selected.mp4"
|
|
321
|
+
}
|
|
322
|
+
]
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Custom Bun workflows can split this lifecycle across agents. Parse prior run
|
|
327
|
+
outputs with `ProjectSnapshotOutputSchema`,
|
|
328
|
+
`CreativeCandidateReferenceV1Schema`, `VariantMatrixReferenceV1Schema`, or
|
|
329
|
+
`VariantSelectionReferenceV1Schema`. Then adopt them with
|
|
330
|
+
`workflow.iteration.baseFromSnapshot`, `candidateFromReference`,
|
|
331
|
+
`matrixFromReference`, or `selectionFromReference`. Immutable candidate
|
|
332
|
+
publication can overlap across processes. One canonical project store owns the
|
|
333
|
+
media state; worktrees are for code authoring, not competing project copies.
|
|
334
|
+
Promotion accepts only the exact frozen edit basis. A concurrent editorial
|
|
335
|
+
change leaves every candidate intact and rejects the promotion.
|
|
336
|
+
Candidate preview outputs use a stable full derivation identity. An exact run
|
|
337
|
+
can adopt the original immutable output and verified receipt before any FFmpeg
|
|
338
|
+
preparation; a changed revision, plan, target, encoder recipe, byte policy,
|
|
339
|
+
sync policy, Slopcamera renderer ABI, or probed toolchain receives a distinct
|
|
340
|
+
path. This specialized
|
|
341
|
+
reuse does not claim that unrelated render operations share a generic cache.
|
|
342
|
+
|
|
343
|
+
References embedded in node inputs create data dependencies. For causal order
|
|
344
|
+
without passing a value, every semantic helper also accepts `after`:
|
|
345
|
+
|
|
346
|
+
```ts
|
|
347
|
+
const started = workflow.recording.start("start", recordingOptions);
|
|
348
|
+
const paused = workflow.recording.pause("pause", { after: started });
|
|
349
|
+
const resumed = workflow.recording.resume("resume", { after: paused });
|
|
350
|
+
const stopped = workflow.recording.stop("stop", { after: resumed });
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
An `after` reference must already belong to the same builder, so control edges
|
|
354
|
+
cannot point forward, cross graphs, or create a cycle.
|
|
355
|
+
|
|
356
|
+
Overlay preparation is also a first-class operation. Independent image, SVG,
|
|
357
|
+
GIF, video, and checked emoji preparations run in parallel; `addOverlays`
|
|
358
|
+
becomes their explicit join, and one checked project transaction publishes the
|
|
359
|
+
complete composition. A Gateway output reference can feed an overlay directly
|
|
360
|
+
without converting it to an ambient path:
|
|
361
|
+
|
|
362
|
+
```ts
|
|
363
|
+
const title = workflow.media.overlay("title", {
|
|
364
|
+
project,
|
|
365
|
+
range: { startUs: 0, endUs: 3_000_000 },
|
|
366
|
+
source: { artifact: { path: "assets/title.svg" }, kind: "svg" },
|
|
367
|
+
});
|
|
368
|
+
const generated = workflow.gateway.image("generated-card", {
|
|
369
|
+
model: "openai/gpt-image-1.5",
|
|
370
|
+
prompt: "A restrained chapter card on transparent black.",
|
|
371
|
+
});
|
|
372
|
+
const generatedCard = workflow.media.overlay("generated-overlay", {
|
|
373
|
+
project,
|
|
374
|
+
range: { startUs: 3_000_000, endUs: 6_000_000 },
|
|
375
|
+
source: {
|
|
376
|
+
artifact: generated.select("outputs").at(0),
|
|
377
|
+
kind: "image",
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
const overlayBatch = workflow.edits.addOverlays(
|
|
381
|
+
"overlay-batch",
|
|
382
|
+
[title, generatedCard],
|
|
383
|
+
);
|
|
384
|
+
const composed = workflow.project.commitEdits("overlay-commit", {
|
|
385
|
+
batch: overlayBatch,
|
|
386
|
+
project,
|
|
387
|
+
});
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Each prepared layer receives a content-derived ID, an immutable preparation
|
|
391
|
+
receipt, and a project-local content-addressed asset. Stable `identityKey`
|
|
392
|
+
values distinguish deliberate duplicate uses of the same bytes. The built-in
|
|
393
|
+
`chaptered-demo@3` packages the same prepare-many/commit-once pattern behind a
|
|
394
|
+
bounded overlay-set input.
|
|
395
|
+
|
|
396
|
+
Complete edit transactions are an explicit second layer. Ordinary
|
|
397
|
+
`edits.batch` / `commitEdits` nodes stay on the metadata-free version-1
|
|
398
|
+
contract. A workflow that needs interaction effects, manual camera moves, or
|
|
399
|
+
zoom operations opts into the stable `completeBatch` /
|
|
400
|
+
`commitCompleteEdits` semantic surface. Those names advance to the newest
|
|
401
|
+
resource-bounded host contract; workflow authors do not select storage
|
|
402
|
+
versions:
|
|
403
|
+
|
|
404
|
+
```ts
|
|
405
|
+
import {
|
|
406
|
+
polishedInteractionEffects,
|
|
407
|
+
} from "@hraness/slopcamera/local/code";
|
|
408
|
+
|
|
409
|
+
const autoZooms = workflow.analysis.projectAutoZooms("auto-zooms", {
|
|
410
|
+
project,
|
|
411
|
+
});
|
|
412
|
+
const complete = workflow.edits.completeBatch("complete-edit", {
|
|
413
|
+
ordered: [
|
|
414
|
+
{
|
|
415
|
+
kind: "add-zooms",
|
|
416
|
+
zooms: autoZooms.select("operations"),
|
|
417
|
+
},
|
|
418
|
+
polishedInteractionEffects(autoZooms.select("sourcePlacementId")),
|
|
419
|
+
],
|
|
420
|
+
});
|
|
421
|
+
const polished = workflow.project.commitCompleteEdits("commit-complete", {
|
|
422
|
+
batch: complete,
|
|
423
|
+
project,
|
|
424
|
+
});
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
Manual zoom intent is the next additive layer. `manualZoom` accepts ordinary
|
|
428
|
+
string IDs and may omit both placement and display selectors. The host
|
|
429
|
+
transaction resolves those selectors from the current project and recording,
|
|
430
|
+
then binds the stopped manifest and accepted placement synchronization before
|
|
431
|
+
publishing:
|
|
432
|
+
|
|
433
|
+
```ts
|
|
434
|
+
import { manualZoom } from "@hraness/slopcamera/local/code";
|
|
435
|
+
|
|
436
|
+
const focus = manualZoom({
|
|
437
|
+
placementId: "placement_screen01",
|
|
438
|
+
range: { startUs: 12_000_000, endUs: 16_000_000 },
|
|
439
|
+
scale: 2,
|
|
440
|
+
target: { kind: "focused-input", paddingPx: 24 },
|
|
441
|
+
zoomId: "zoom_focusedinput01",
|
|
442
|
+
});
|
|
443
|
+
const zoomBatch = workflow.edits.addManualZooms("focus-zoom", [focus]);
|
|
444
|
+
const zoomed = workflow.project.commitCompleteEdits("commit-focus-zoom", {
|
|
445
|
+
batch: zoomBatch,
|
|
446
|
+
project,
|
|
447
|
+
});
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
The complete metadata edit replaces cursor, click, keystroke, typed-text, and
|
|
451
|
+
metadata-placement settings together, so a recipe never inherits hidden prior
|
|
452
|
+
state. `setMetadataEffects` exposes the exact form; the conservative
|
|
453
|
+
`polishedInteractionEffects` preset keeps typed text off. `cameraPush` and
|
|
454
|
+
`cameraReframe` create binding-free normalized keyframes, while
|
|
455
|
+
`addManualCameraMoves`, `removeCameraMoves`, and `removeZooms` compose them into
|
|
456
|
+
the same ordered batch. Camera poses apply only inside each move range, so
|
|
457
|
+
adjacent moves should share a boundary pose when the shot must remain
|
|
458
|
+
continuous. The host—not workflow code—binds camera geometry, manual-zoom
|
|
459
|
+
display/recording identity, placement synchronization, and the exact
|
|
460
|
+
recording-manifest hash needed by metadata-driven effects. It rechecks that
|
|
461
|
+
evidence at the publication gate. Persisted version-1 and version-2 graphs
|
|
462
|
+
remain runnable; exact historical authoring is intentionally isolated under
|
|
463
|
+
the advanced namespace for immutable built-in workflows and migrations.
|
|
464
|
+
The current complete-batch contract accepts at most 10,000 expanded atomic
|
|
465
|
+
edits arranged into at most 64 adjacent normalization phases. Put related
|
|
466
|
+
additions or removals in one array: the host reduces each phase in linear time,
|
|
467
|
+
then validates the normalized boundary once. Workflows that must reproduce an
|
|
468
|
+
older, more highly alternating version-2 graph can select the exact historical
|
|
469
|
+
contract through `workflow.advanced`.
|
|
470
|
+
|
|
471
|
+
Local media passed directly to a media or Gateway node becomes a structural
|
|
472
|
+
file candidate automatically. If trusted compute must choose among files,
|
|
473
|
+
declare each workflow-input choice with `fileCandidate(...)` and validate it
|
|
474
|
+
with `WorkflowFileCandidateSchema`. Static planning binds the declared path,
|
|
475
|
+
media type, and optional exact byte/hash constraints without opening the file.
|
|
476
|
+
Only the chosen registered operation may then open and hash it while producing
|
|
477
|
+
the exact node plan; a compute-minted undeclared path fails before host
|
|
478
|
+
preparation or an approval prompt.
|
|
479
|
+
|
|
480
|
+
`workflow.analysis.scenes` runs the local FFmpeg scene planner without
|
|
481
|
+
uploading frames. Its node output contains the complete bounded scene ranges,
|
|
482
|
+
requested sample times, and sample reasons, while the ordinary completion
|
|
483
|
+
summary keeps only the plan digest and counts. Return the needed fields as
|
|
484
|
+
workflow outputs, or inspect the persisted evidence with
|
|
485
|
+
`slopcamera runs show <run-id> --nodes all --json`. Gateway scene descriptions
|
|
486
|
+
remain an explicit local `slopcamera analyze scenes ... --execute
|
|
487
|
+
--allow-cloud-upload` action.
|
|
488
|
+
|
|
489
|
+
The scheduler runs dependency-ready nodes concurrently while obeying the stricter of `--jobs`, the four-worker hard cap, and host resource pools for FFmpeg, Vision, local I/O, paid calls, output publication, project publication, and capture. Parallel analyses bind an append-only project edit basis, so one sibling may publish while another is paused without authorizing structural or prior-evidence drift. Mutable edits join into one ordered recoverable project transaction. Rendering first freezes the complete project and edit documents into an immutable geometry-bound revision, resolves an exact tool, media, and recording-metadata-bound plan, and publishes video plus receipt through an output-specific lease and durable precommit. Landscape, square, and portrait branches therefore remain independent.
|
|
490
|
+
|
|
491
|
+
Every run is durable under `artifacts/slopcamera/private/workflow-runs/<run-id>/`. Inspect it with `runs list` and `runs show`; use `runs resume`, `runs approve`, or `runs cancel` when the bounded summary provides that next action. A normal resume reconstructs unfinished host operations from the persisted graph without evaluating the workflow bundle. Exact canonical analysis orphans and output-only render commits are adopted only through their run-bound recovery evidence. An interrupted arbitrary compute callback becomes `ambiguous-code` and requires an exact node-specific replay acknowledgement. Attached cancellation first aborts that callback's real signal, then force-retires an uncooperative worker after a bounded grace period. A paid request uses an exact request ID and durable dispatch journal; an unknown post-dispatch outcome is never submitted again automatically. Live recording actions reconcile against the same controller used by the desktop app and are never automatically replayed.
|
|
492
|
+
|
|
493
|
+
Custom code mode is trusted code, not a sandbox. Module top-level code and explicitly replayed compute callbacks run as the current user and can use ambient filesystem, process and network authority. Slopcamera keeps its own credentials and privileged handles out of the worker, but it cannot contain malicious repository code. Review custom source before `code check`, `code plan`, or `code run`.
|
|
494
|
+
|
|
495
|
+
### Gateway media
|
|
496
|
+
|
|
497
|
+
`slopcamera ai models` reads Vercel AI Gateway's public live catalog rather than a checked model allowlist. It includes image-model endpoints, image-generating language models, video, speech, and transcription. The cache uses conditional requests, a canonical revision, and stale-last-good fallback; `models show` preserves raw capabilities and exposes common settings plus the non-conflicting provider-option vocabulary known to this release. Batch and streaming transcription operations are labeled separately; the batch command rejects streaming-only models before credential access or dispatch. A bounded JSON object supplied with `--provider-options` remains the forward-compatible escape hatch for new service-owned fields. Gateway `models` fallback configuration is deliberately rejected because every paid model must be independently catalog-validated and durably accounted. Provider-specific sample-count fields are also rejected; use `--count` with `--max-per-call` at least as large so one Slopcamera job maps to one AI SDK call.
|
|
498
|
+
|
|
499
|
+
Slopcamera reads Vercel AI Gateway credentials from `AI_GATEWAY_API_KEY`, falling back to the `VERCEL_OIDC_TOKEN` injected by `vercel env run`. It never persists, prints, forwards to subprocesses, or accepts either value through argv.
|
|
500
|
+
|
|
501
|
+
Every paid invocation validates its live model kind, prompt, options, and all local files before dispatch. Reference images/videos require `--allow-cloud-upload`; transcription audio requires the separate `--allow-cloud-audio-upload`. Consent is per invocation. Slopcamera resolves only each explicitly named physical file, bounds its bytes and media type, and records its SHA-256 without enumerating adjacent bundle files. The same image/video flags accept credential-free public HTTPS sources when the live catalog permits `url` or does not declare a source restriction; a catalog that explicitly lists only other source forms fails locally. Use the URL directly when its path has a recognized extension, or `<media-type>=<https-url>` when it does not. URLs with credentials, fragments, local hostnames, or private literal addresses fail locally. Remote bytes and intrinsic geometry remain provider-validated; durable state stores only a URL digest and declared media type, never the URL itself. Direct URL arguments remain visible to shell and process history, so use only references safe for that exposure.
|
|
502
|
+
|
|
503
|
+
Image generation exposes prompt/edit images, mask, count, batch size, dimensions, aspect ratio, and seed. Video exposes every AI SDK media input and common parameter: primary image, first/last frames, image/audio/video references, count, batch size, aspect ratio, resolution (including provider values such as `1080p`), duration, FPS, seed, and generated audio. Illegal precedence combinations fail locally: frames cannot accompany generic references, and a primary image cannot accompany a first frame. `--provider-options` accepts a bounded nested vocabulary spanning Google Vertex/Veo, Kling, Alibaba Wan, ByteDance Seedance, xAI Grok, Gateway routing, image-provider, speech, and transcription parameters; fields that can change model selection or duplicate a paid sample count are rejected in favor of the validated first-class flags. Those options can include BYOK credentials, webhook secrets, or similarly sensitive values: keep the source JSON gitignored and mode `0600`. Slopcamera refuses a group- or world-accessible options file, forwards the parsed object for that invocation, and persists only its SHA-256 and namespace list—never the raw option values.
|
|
504
|
+
|
|
505
|
+
Video is one long-lived Gateway SSE request; Gateway does not expose a resumable job/status API. Slopcamera writes a local pre-dispatch receipt, sets the AI SDK client's `maxRetries` to zero, and never resubmits an interrupted paid call. AI Gateway may still route or fail over that one request across multiple providers, so a single command can produce multiple provider attempts, and provider timeouts may still incur charges; receipts retain bounded generation/provider-attempt metadata when the SDK returns it, including on failures. An interrupted dispatched request remains visibly ambiguous. Retrying is always a new explicit command and may charge again. Successful media downloads reject private/local network targets, validate every redirect, share a per-request aggregate byte budget, and are preserved with privacy-safe warning hashes, catalog revision, normalized settings, input/output hashes, and explicit complete/partial/overproduced sample fulfillment. Slopcamera fully decodes self-describing generated media locally before emitting an exact project-add command. Failed decode keeps the paid bytes and a hash-only quarantine receipt but returns an error and emits no import command. Headerless `audio/pcm`, `audio/l16`, `audio/alaw`, `audio/basic`, and `audio/mulaw` speech remains saved and hashed but deliberately receives no project-add suggestion; convert it with explicit sample metadata first.
|
|
506
|
+
|
|
507
|
+
`slopcamera media audio` and `slopcamera media color` never contact the network. Audio uses one documented deterministic order—denoise, compression, volume, delay, then deterministic multi-tap reverb—while omitting unrequested stages. Color combines seven common presets with brightness, contrast, saturation, gamma, temperature, tint, and hue. Both use bounded typed controls, checked FFmpeg argv, a verified descriptor-pinned input, fresh no-replace output publication, SHA-256 receipts, and leave the source unchanged. A path swap or in-place input mutation before publication fails closed without exposing the derived output. Output publication and receipt publication are sequential rather than one atomic pair: a process crash between them can leave an output without a receipt, and the next run reports a conflict so an agent can inspect and remove that orphan explicitly.
|
|
508
|
+
|
|
509
|
+
Resolved render plans are stored by their full composition hash, including the selected display. Every successful recording or project render writes a strict receipt beside the video that points to the immutable plan and records the output path, byte count, and SHA-256. Failed encodes never relabel an older output, and a receipt-publication failure removes any stale receipt.
|
|
510
|
+
|
|
511
|
+
Structural project mutations publish `project.json` and the current edit plan as one recoverable generation. Immutable before/after evidence lives under `state/transactions/`; an interrupted mutating command recovers it while holding the project lease, while unlocked readers fail closed until that recovery occurs.
|
|
512
|
+
|
|
513
|
+
### Overlay model
|
|
514
|
+
|
|
515
|
+
Overlay sources may be images, sanitized SVGs, GIFs, videos, or generated emoji. Animated sources have explicit source trim, loop/hide/freeze-end behavior, playback rate, volume, and mix/duck policy. Every overlay supports contain/cover/fill, normalized crop, anchor and pixel position, size, rotation, opacity, z-index, blend mode, rounded mask, entrance/exit motion, and repeatable transform/opacity keyframes. Playback stays continuous through project cuts and speed boundaries.
|
|
516
|
+
|
|
517
|
+
Diagrams, vectorization, generated media, and timeline composition share the
|
|
518
|
+
same application-operation registry and content-addressed artifact references.
|
|
519
|
+
The CLI therefore returns outputs that can be passed directly to media ingest
|
|
520
|
+
or overlay operations rather than copied through ambient temporary paths:
|
|
521
|
+
|
|
522
|
+
```sh
|
|
523
|
+
slopcamera diagram init concepts/system-map.diagram.json
|
|
524
|
+
slopcamera diagram check concepts/system-map.diagram.json --strict
|
|
525
|
+
slopcamera diagram render concepts/system-map.diagram.json --scale 2
|
|
526
|
+
slopcamera image vectorize artwork/mark.png \
|
|
527
|
+
--output artwork/mark.svg --duotone '#111827,#f9fafb' --alpha-cutoff 8 --json
|
|
528
|
+
slopcamera html catalog
|
|
529
|
+
slopcamera html scaffold paper-shaders --output overlays/title.html
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
Diagram rendering publishes light and dark SVG/PNG variants plus editable
|
|
533
|
+
`.tldr` source. Vectorization publishes an inert bounded SVG and a quality
|
|
534
|
+
receipt. Both bind the exact input bytes and publish by content hash under
|
|
535
|
+
`artifacts/slopcamera/generated/`; repeated equivalent work reuses the same
|
|
536
|
+
artifact. PNG outputs can feed `media.ingest`, while SVG outputs already match
|
|
537
|
+
the `media.overlay` artifact contract. This is the common interchange layer
|
|
538
|
+
for stills, diagrams, animated loops, generated imagery, and final video.
|
|
539
|
+
|
|
540
|
+
### Deterministic HTML overlays
|
|
541
|
+
|
|
542
|
+
`workflow.media.htmlOverlay` turns ordinary HTML, CSS, SVG, Canvas, WebGL, or a
|
|
543
|
+
declared local image into a transparent alpha-video layer. Start from the
|
|
544
|
+
portable authoring package instead of hand-writing CDN tags:
|
|
545
|
+
|
|
546
|
+
```ts
|
|
547
|
+
import { createHtmlOverlayScaffoldInput } from "@hraness/slopcamera/local/html-overlay";
|
|
548
|
+
|
|
549
|
+
const scaffold = createHtmlOverlayScaffoldInput("paper-shaders");
|
|
550
|
+
const title = workflow.media.htmlOverlay("chapter-title", {
|
|
551
|
+
canvas: { deviceScaleFactor: 1, height: 1080, width: 1920 },
|
|
552
|
+
...scaffold,
|
|
553
|
+
parameters: { label: "A new shape" },
|
|
554
|
+
project,
|
|
555
|
+
range: { startUs: 0, endUs: 3_000_000 },
|
|
556
|
+
resources: [{
|
|
557
|
+
artifact: { path: "artwork/logo.png" },
|
|
558
|
+
mediaType: "image/png",
|
|
559
|
+
name: "logo",
|
|
560
|
+
urlPath: "images/logo.png",
|
|
561
|
+
}],
|
|
562
|
+
seed: 42,
|
|
563
|
+
timing: { durationUs: 3_000_000, fps: 30 },
|
|
564
|
+
});
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
The seven scaffolds are `plain`, `motion`, `p5`, `two`, `paper-shaders`,
|
|
568
|
+
`three`, and `vgpu`. Use `plain` for native layout and SVG, `motion` for DOM/SVG
|
|
569
|
+
choreography, `p5` for immediate Canvas 2D sketches, `two` for retained vector
|
|
570
|
+
2D scenes, Paper Shaders for parameterized textures, Three.js for retained 3D, and
|
|
571
|
+
[vgpu](https://vgpu.sh) for explicit WGSL and WebGPU passes. `slopcamera html catalog
|
|
572
|
+
--json` returns this selection model with exact active library versions. The
|
|
573
|
+
[creative toolkit guide](../../docs/html-overlay-creative-toolkit.md) classifies
|
|
574
|
+
the wider ecosystem without adding those tools to Slopcamera's executable allowlist.
|
|
575
|
+
|
|
576
|
+
The p5 starter uses instance-mode P2D, makes p5's mandatory startup draw empty,
|
|
577
|
+
disables its native loop, and awaits one manual redraw from each absolute Slopcamera
|
|
578
|
+
frame. The Two.js starter selects WebGL explicitly, leaves autostart disabled,
|
|
579
|
+
preallocates a bounded retained vector scene, and calls one manual render per
|
|
580
|
+
Slopcamera frame. Both clear to transparent, use keyed Slopcamera randomness, avoid system
|
|
581
|
+
fonts and remote assets, and release their resources on page exit. Their exact
|
|
582
|
+
browser modules, versions, byte lengths, licenses, and SHA-256 values are
|
|
583
|
+
allowlisted. Author code imports only the scaffold's bare specifier; the host
|
|
584
|
+
supplies the canonical private import map.
|
|
585
|
+
|
|
586
|
+
The vgpu starter compiles its shader before readiness, submits one pass from
|
|
587
|
+
each absolute Slopcamera frame, waits for GPU completion, and clears to transparent.
|
|
588
|
+
It fails closed when the selected browser runtime cannot acquire WebGPU; it does
|
|
589
|
+
not silently replace the effect with another renderer.
|
|
590
|
+
|
|
591
|
+
The Three.js starter defines the authoring contract.
|
|
592
|
+
It has explicit sRGB output and ACES tone mapping, no shadows or postprocessing,
|
|
593
|
+
automatic camera framing, reusable tracked GPU resources, shader precompilation,
|
|
594
|
+
context-loss failure, and cleanup. Its default ceiling is 64 draw calls and
|
|
595
|
+
200,000 triangles per frame. Motion comes only from the absolute Slopcamera frame
|
|
596
|
+
clock. `orbitTurns`, `zoom`, and `explode` are bounded parameters. Use a 1x
|
|
597
|
+
`deviceScaleFactor` for full-length previews and raise it only for a selected
|
|
598
|
+
final render.
|
|
599
|
+
|
|
600
|
+
Reference-image code generation is deliberately staged. Generate or select one
|
|
601
|
+
image, inspect it, create the `three` scaffold, and let the agent replace only
|
|
602
|
+
its `createSubject()` function. Review the source and several preview angles
|
|
603
|
+
before execution. The final workflow binds the exact reference artifact even
|
|
604
|
+
when the image is not visible in the scene:
|
|
605
|
+
|
|
606
|
+
```ts
|
|
607
|
+
import { createThreeReferenceScaffoldInput } from "@hraness/slopcamera/local/html-overlay";
|
|
608
|
+
|
|
609
|
+
const generated = workflow.gateway.image("reference", imageOptions);
|
|
610
|
+
const reference = generated.select("outputs").at(0);
|
|
611
|
+
const binding = createThreeReferenceScaffoldInput(
|
|
612
|
+
reference,
|
|
613
|
+
reference.select("mediaType"),
|
|
614
|
+
);
|
|
615
|
+
const scene = workflow.media.htmlOverlay("reviewed-three-scene", {
|
|
616
|
+
...binding,
|
|
617
|
+
document: { path: "overlays/reviewed-scene.html" },
|
|
618
|
+
canvas: { deviceScaleFactor: 1, height: 1080, width: 1920 },
|
|
619
|
+
parameters: { explode: 0.35, orbitTurns: 1, zoom: 1 },
|
|
620
|
+
project,
|
|
621
|
+
range: { startUs: 0, endUs: 3_000_000 },
|
|
622
|
+
timing: { durationUs: 3_000_000, fps: 30 },
|
|
623
|
+
});
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
The reference is a normal generated output with exact bytes, media type, path,
|
|
627
|
+
and SHA-256. HTML resource binding verifies those facts and rejects a declared
|
|
628
|
+
media type that disagrees with the generated artifact. Slopcamera never accepts
|
|
629
|
+
model-produced JavaScript as an executable operation input. Code Mode evaluates
|
|
630
|
+
only the local workflow and scene source that the agent or user reviewed.
|
|
631
|
+
|
|
632
|
+
For a texture that should be visible, load only the declared private asset and
|
|
633
|
+
settle it before frame zero:
|
|
634
|
+
|
|
635
|
+
```js
|
|
636
|
+
const texture = new THREE.TextureLoader()
|
|
637
|
+
.loadAsync(SlopcameraOverlay.asset("reference-image"))
|
|
638
|
+
.then((loaded) => {
|
|
639
|
+
loaded.colorSpace = THREE.SRGBColorSpace;
|
|
640
|
+
return loaded;
|
|
641
|
+
});
|
|
642
|
+
SlopcameraOverlay.ready(texture);
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
Reference-led image treatments remain generated image derivatives in the same
|
|
646
|
+
Code Mode graph. The metallic-logo recipe preserves the supplied mark as the
|
|
647
|
+
shape authority and varies only the named brand, background color, and metal
|
|
648
|
+
color:
|
|
649
|
+
|
|
650
|
+
```ts
|
|
651
|
+
import { createMetallicLogoImageRequest } from "@hraness/slopcamera/local/code";
|
|
652
|
+
|
|
653
|
+
const metallic = workflow.gateway.image("metallic-logo",
|
|
654
|
+
createMetallicLogoImageRequest({
|
|
655
|
+
backgroundColor: "warm gray",
|
|
656
|
+
brandName: "Hraness",
|
|
657
|
+
model: input.imageModel,
|
|
658
|
+
objectColor: "brushed cobalt",
|
|
659
|
+
reference: input.logo,
|
|
660
|
+
}));
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
The model stays explicit because image-reference support is a live provider
|
|
664
|
+
capability. For CLI use, save the output of `createMetallicLogoPrompt(...)` as
|
|
665
|
+
`metallic-logo-prompt.txt`, inspect the live model first, and run a complete
|
|
666
|
+
reference-led request:
|
|
667
|
+
|
|
668
|
+
```sh
|
|
669
|
+
slopcamera ai models show <reference-capable-model-id>
|
|
670
|
+
slopcamera ai image generate \
|
|
671
|
+
--model <reference-capable-model-id> \
|
|
672
|
+
--prompt-file metallic-logo-prompt.txt \
|
|
673
|
+
--image reference-logo.png \
|
|
674
|
+
--aspect-ratio 1:1 \
|
|
675
|
+
--count 1 \
|
|
676
|
+
--allow-cloud-upload
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
Treat the output as a candidate until its silhouette, negative space,
|
|
680
|
+
proportions, and any lettering match the reference.
|
|
681
|
+
|
|
682
|
+
Author documents use the frozen `SlopcameraOverlay` API:
|
|
683
|
+
|
|
684
|
+
- `onFrame(({ frame, timeMs, deltaMs, progress, width, height }) => …)` updates
|
|
685
|
+
the document from Slopcamera's absolute frame clock.
|
|
686
|
+
- `ready(promise)` holds frame zero for bounded asset or setup work, and
|
|
687
|
+
`trackAnimation(controls)` lets the host seek Motion or Web Animations.
|
|
688
|
+
- `asset(name)` returns the private URL of a declared resource;
|
|
689
|
+
`parameters`, `seed`, `random()`, and `randomFor(key)` provide immutable input
|
|
690
|
+
and reproducible variation.
|
|
691
|
+
- `width`, `height`, `fps`, and `durationMs` expose the exact render geometry.
|
|
692
|
+
|
|
693
|
+
Keep `html` and `body` transparent and let the compositor place the result.
|
|
694
|
+
Remote fetches, popups, child frames, workers, object URLs, and undeclared
|
|
695
|
+
resources fail closed. Declare images, fonts, JSON, audio, and other local
|
|
696
|
+
bytes in `resources` and resolve them with `asset(name)`. Browser time, timers,
|
|
697
|
+
animation frames, `Date`, performance time, and entropy are virtualized so a
|
|
698
|
+
given input renders the same frames. Every render receipt carries a SHA-256
|
|
699
|
+
Merkle root over the full injected runtime, authored document, import map,
|
|
700
|
+
locked modules, declared resources, authoring configuration, and exact Chrome
|
|
701
|
+
runtime tree—not only its launcher. The same Merkle root binds the exact
|
|
702
|
+
Playwright Core version plus launch flags, fixed environment, context, routing,
|
|
703
|
+
CSP, and transparent-screenshot policy. Production accepts only a directly
|
|
704
|
+
launched native executable inside a supported Google Chrome app signed by
|
|
705
|
+
Google's `EQHXZ8M8AV` team; PATH shims, shell wrappers, other Chromium
|
|
706
|
+
distributions, and malformed app bundles are rejected.
|
|
707
|
+
|
|
708
|
+
Slopcamera binds every sorted bundle path, entry kind, mode, file length and
|
|
709
|
+
hash, or internal symlink target. Abort-aware bounded reads copy the complete
|
|
710
|
+
signed app bundle into a fresh mode-0700 snapshot while source-before,
|
|
711
|
+
source-after, snapshot, and code-signature provenance checks bracket the copy.
|
|
712
|
+
The browser snapshot is never placed beneath the caller-selected module cache
|
|
713
|
+
or ambient `TMPDIR`. On macOS it is a unique direct child of validated physical,
|
|
714
|
+
root-owned, sticky `/private/tmp`; Slopcamera binds that anchor's exact stable
|
|
715
|
+
metadata and watches the unique child basename. The verified app tree is then
|
|
716
|
+
recursively user-immutable. After private mode-0700 `HOME` and `TMPDIR`
|
|
717
|
+
siblings are created, Chrome launches only from that snapshot with a minimal
|
|
718
|
+
fixed environment. The mutable outer container is bound by exact identity and
|
|
719
|
+
anchor events while the app tree itself remains recursively immutable. The
|
|
720
|
+
parent is watched recursively, and its exact
|
|
721
|
+
device/inode/ctime/mode/size identity plus the full app manifest and child path
|
|
722
|
+
identities are rechecked after launch and through shutdown. macOS may change
|
|
723
|
+
only the app root's first-launch metadata; bound parent identity and root rename
|
|
724
|
+
events independently prove that the pathname was never swapped, while
|
|
725
|
+
every child ctime remains enforced. Signature checks and snapshot copying are
|
|
726
|
+
bounded and cancellation-aware, and the app-tree flags are released before the
|
|
727
|
+
private snapshot is removed afterward. A strict mode-0600 lease is held open for
|
|
728
|
+
the render lifetime. On startup, a bounded scavenger preserves every ambiguous,
|
|
729
|
+
live, open, foreign, or changing tree. It accepts either an authenticated
|
|
730
|
+
released cleanup or a stale, same-host, dead-owner tree, then atomically moves
|
|
731
|
+
the closed, identity-stable tree into a one-use quarantine pathname and proves
|
|
732
|
+
the moved tree closed a second time before cleanup. Normal teardown
|
|
733
|
+
rechecks the complete runtime manifest and every direct child, then
|
|
734
|
+
atomically changes its held active lease to a released marker before removing
|
|
735
|
+
validated children; that marker is unlinked last, so an interrupted cleanup is
|
|
736
|
+
recoverable even while the desktop process remains alive. These gates prevent
|
|
737
|
+
deletion from colliding with a new render container or a swapped peer subtree.
|
|
738
|
+
The signed snapshot is prepared once per render request and shared by every
|
|
739
|
+
frame in that sequence; callers should submit a complete loop or overlay range
|
|
740
|
+
rather than issuing one render request per frame.
|
|
741
|
+
The injected Playwright launcher remains a trusted host adapter. Authored
|
|
742
|
+
documents use the `SlopcameraOverlay` API.
|
|
743
|
+
|
|
744
|
+
The prepared HTML result is the same overlay handle returned by image, SVG,
|
|
745
|
+
GIF, video, and emoji preparation, so it joins `edits.addOverlays` and one
|
|
746
|
+
recoverable `project.commitEdits` transaction. Set its range to one loop cycle
|
|
747
|
+
when authoring a reusable animated loop; ordinary video-overlay playback policy
|
|
748
|
+
can then loop, trim, hide, or freeze that immutable asset in later compositions.
|
|
749
|
+
|
|
750
|
+
The optional emoji provider reads ignored local outputs under `apps/desktop/.generated/emoji-pack/`. All non-emoji editing remains available without that pack.
|
|
751
|
+
|
|
752
|
+
### Camera motion and face following
|
|
753
|
+
|
|
754
|
+
Project camera moves provide Ken Burns-style digital push-ins, pull-outs, and pans for any enabled video layer. Coordinates are normalized against the prepared video layer after its crop and fit:
|
|
755
|
+
|
|
756
|
+
```sh
|
|
757
|
+
# Move from a centered 1x frame to the requested center and zoom.
|
|
758
|
+
slopcamera project edit <project> camera push \
|
|
759
|
+
--placement <id> --stream <id> --from 4s --to 6s \
|
|
760
|
+
--center 0.68,0.42 --start-zoom 1 --end-zoom 1.8 --easing ease-in-out
|
|
761
|
+
|
|
762
|
+
# Move between two explicit center-x,center-y,zoom poses.
|
|
763
|
+
slopcamera project edit <project> camera reframe \
|
|
764
|
+
--placement <id> --stream <id> --from 10s --to 14s \
|
|
765
|
+
--from-frame 0.5,0.5,1 --to-frame 0.67,0.45,2 --easing ease-in-out
|
|
766
|
+
|
|
767
|
+
# Author an arbitrary path; the first and last keyframes define its range.
|
|
768
|
+
slopcamera project edit <project> camera path \
|
|
769
|
+
--placement <id> --stream <id> \
|
|
770
|
+
--keyframe 20s,0.5,0.5,1 \
|
|
771
|
+
--keyframe 22s,0.68,0.4,1.5 \
|
|
772
|
+
--keyframe 25s,0.42,0.52,2
|
|
773
|
+
|
|
774
|
+
slopcamera project edit <project> camera show
|
|
775
|
+
slopcamera project edit <project> camera remove <camera-move-id>
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
Zoom ranges from 1x through 10x, and each center must keep the viewport inside the prepared layer. Camera moves interpolate zoom in log space for symmetric push-ins and pull-outs. They are bound to the selected placement synchronization and prepared-layer geometry; changing either makes the move stale instead of silently retargeting it.
|
|
779
|
+
|
|
780
|
+
On macOS 15 or newer, the offline Apple Vision analyzer can detect and track multiple faces in one immutable project video stream:
|
|
781
|
+
|
|
782
|
+
```sh
|
|
783
|
+
slopcamera analyze faces <project> --source <asset:video-stream> \
|
|
784
|
+
--backend vision --sample-fps 8 --min-confidence 0.6 \
|
|
785
|
+
--max-track-gap 500ms --max-faces 32
|
|
786
|
+
|
|
787
|
+
slopcamera faces list <project> <face-analysis-id> \
|
|
788
|
+
--at 12s --min-duration 750ms --min-confidence 0.7 --limit 20
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
`faces list` uses asset time. Face analysis is local-only, and normalized bounding boxes are the only stored visual evidence. Track IDs mean geometry continuity within that one analysis; Slopcamera performs no face recognition or biometric identification and stores no names, embeddings, crops, or thumbnails.
|
|
792
|
+
|
|
793
|
+
Apply that evidence as an ordinary, deterministic camera move by choosing the largest currently visible face, every active face, or one or more explicit tracks:
|
|
794
|
+
|
|
795
|
+
```sh
|
|
796
|
+
slopcamera project edit <project> camera follow-faces \
|
|
797
|
+
--placement <id> --analysis <face-analysis-id> --from 20s --to 35s \
|
|
798
|
+
--select largest
|
|
799
|
+
|
|
800
|
+
slopcamera project edit <project> camera follow-faces \
|
|
801
|
+
--placement <id> --analysis <face-analysis-id> --from 20s --to 35s \
|
|
802
|
+
--select all --framing group
|
|
803
|
+
|
|
804
|
+
slopcamera project edit <project> camera follow-faces \
|
|
805
|
+
--placement <id> --analysis <face-analysis-id> --from 20s --to 35s \
|
|
806
|
+
--track <face-track-id> --track <another-face-track-id> \
|
|
807
|
+
--require-all-selected --gap-policy hold
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
`--select largest` reevaluates each analyzed frame after crop/fit mapping: visible box area wins, then confidence, then lexical track ID for a stable tie. `--framing tight|medium|wide|group` controls the space around visible faces. By default, multi-face framing continues with whichever selected faces remain visible. Add `--require-all-selected` with explicit `--track` values or `--select all` when one missing selected face should trigger `--gap-policy hold|fallback|fail`: briefly keep the last frame, return to the full prepared layer, or reject the edit. Use `--min-zoom` and `--max-zoom` to bound the crop, `--smoothing` for a 0–1 second response time, `--headroom` for a 0–1 top-padding ratio, and `--output-width`/`--output-height` to declare the even-pixel render dimensions used for framing. The defaults are 1920×1080, 1x–2.2x zoom, 0.75 seconds of smoothing, and 0.18 headroom.
|
|
811
|
+
|
|
812
|
+
For a normalized video-layer layout, face following records the declared output aspect ratio. Render planning rejects a different aspect ratio because it would change face framing; rerun `camera follow-faces` with the intended dimensions before switching, for example, between 16:9 and vertical output. The generated move also remains bound to the exact analysis file, analyzed media, selected tracks, placement sync, and prepared-layer geometry.
|
|
813
|
+
|
|
814
|
+
### Analysis boundaries
|
|
815
|
+
|
|
816
|
+
- Audio alignment uses bounded 8 kHz envelopes, reports ambiguity and drift, and never mutates a placement until a candidate is explicitly or safely automatically accepted.
|
|
817
|
+
- Face analysis runs only in the local macOS Apple Vision helper and persists normalized boxes with geometry-continuity track IDs. Face-follow application resolves that evidence into an ordinary camera path; rendering never invokes the detector.
|
|
818
|
+
- Project inactivity analysis requires simultaneous freeze evidence from every enabled screen stream and, by default, silence from every enabled audio stream. It projects asset detections and reference-recording interactions through each placement's current sync map, writes an immutable sidecar, and applies only global project-time cuts or speed ranges with analysis provenance.
|
|
819
|
+
- Music analysis writes presence regions, tempo regions and changes, beat evidence, and key regions into a sidecar referenced by the project.
|
|
820
|
+
- Scene analysis follows PySceneDetect's scene-boundary ergonomics as a reference while keeping an owned FFmpeg-native detector and typed evidence. Planning is local by default. Execution uploads only selected, resized derived frames, never a raw video, directly to Vercel AI Gateway through the same environment credential as other paid media commands and requires `--allow-cloud-upload`. Exact duplicate frames are collapsed per scene, and completed descriptions are reused only when the input, sampled-frame hashes, model, prompt, and sampling version all match.
|
|
821
|
+
- Speech analysis runs a caller-selected local whisper.cpp model and requires word timestamps. Before `fillers apply` can create a global cut, every enabled audio stream must have a current integrity-checked music analysis, and every other audible placement-stream must have complete current speech/no-speech evidence. Music regions and words are mapped through accepted placement sync into project time. Missing coverage, stale evidence, music, or speech overlap fails closed. Editorial overrides use an ordinary manual project cut.
|
|
822
|
+
|
|
823
|
+
## Development
|
|
824
|
+
|
|
825
|
+
Use Bun 1.3.14. Portable checks do not compile native capture:
|
|
826
|
+
|
|
827
|
+
```sh
|
|
828
|
+
bun test apps/desktop
|
|
829
|
+
bun x tsc --noEmit -p apps/desktop/tsconfig.json
|
|
830
|
+
bun x eslint apps/desktop
|
|
831
|
+
bun run build:desktop
|
|
832
|
+
bun run test:cli:compiled:macos
|
|
833
|
+
bun run test:html-overlay
|
|
834
|
+
bun run benchmark:code-concurrency
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
Native capture targets Apple Silicon macOS 15 or newer. It uses ScreenCaptureKit for every display and system audio, plus AVFoundation for independent webcam and microphone files.
|
|
838
|
+
|
|
839
|
+
```sh
|
|
840
|
+
bun x native doctor --manifest apps/desktop/app.zon --strict
|
|
841
|
+
bun run apps/desktop/capture/build.ts
|
|
842
|
+
bun run apps/desktop/analysis/build.ts
|
|
843
|
+
bun run dev:desktop
|
|
844
|
+
bun run build:desktop:macos
|
|
845
|
+
bun run package:desktop:macos
|
|
846
|
+
bun run verify:html-overlay:macos
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
`test:html-overlay` is portable and leaves the real-browser tests registered as
|
|
850
|
+
skipped. `test:html-overlay:browser:macos` runs the real Chrome frame suite,
|
|
851
|
+
including a declared PNG. `test:html-overlay:libraries:macos` additionally
|
|
852
|
+
downloads and verifies every exact Motion, p5.js, Two.js, Paper Shaders,
|
|
853
|
+
Three.js, and vgpu lock. The integrity-bound Chrome contract selects WebGPU's
|
|
854
|
+
SwiftShader fallback
|
|
855
|
+
adapter so identical browser receipts do not silently choose different GPUs.
|
|
856
|
+
`test:html-overlay:operation:macos` runs the complete Chrome → PNG frames →
|
|
857
|
+
FFmpeg qtrle/argb → project-ingest operation. The combined
|
|
858
|
+
`verify:html-overlay:macos` requires Google Chrome, FFmpeg, and FFprobe at the
|
|
859
|
+
paths reported by `slopcamera doctor`.
|
|
860
|
+
|
|
861
|
+
`build:cli` emits the current-host Bun bundle used by the portable workspace
|
|
862
|
+
build. `build:cli:macos` emits `dist/slopcamera`, a copied-binary-tested Apple Silicon macOS
|
|
863
|
+
CLI. It bundles the headless diagram renderer, the isolated VTracer worker, the
|
|
864
|
+
exact Sharp native addon, and libvips; the bootstrap expands native media assets
|
|
865
|
+
into a fresh private temporary runtime and removes them when the command exits.
|
|
866
|
+
The compiled smoke copies the executable away from the checkout and proves
|
|
867
|
+
diagram initialization/rendering plus PNG-to-SVG vectorization without
|
|
868
|
+
`node_modules`.
|
|
869
|
+
|
|
870
|
+
Screen recording, microphone, camera, Input Monitoring, and Accessibility are separate macOS permissions. A missing optional source becomes a typed diagnostic; strict-input mode fails before recording begins. Packaged local builds are ad hoc signed evidence until a release workflow adds Developer ID signing, notarization, and updates.
|
|
871
|
+
|
|
872
|
+
### Real capture hardware smoke
|
|
873
|
+
|
|
874
|
+
The real hardware smoke is deliberately outside portable and ordinary macOS
|
|
875
|
+
checks. Without the exact confirmation below it is registered as skipped and
|
|
876
|
+
does not build or probe the helper, inspect permissions, or create artifact
|
|
877
|
+
directories:
|
|
878
|
+
|
|
879
|
+
```sh
|
|
880
|
+
SLOPCAMERA_CAPTURE_HARDWARE_CONFIRM=record-local-displays-and-selected-inputs \
|
|
881
|
+
bun run test:capture:hardware:macos
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
The default profile records every connected display twice, with a pause between
|
|
885
|
+
the two immutable segments. It leaves system audio, camera, microphone, and
|
|
886
|
+
typed text disabled. Enable selected inputs explicitly:
|
|
887
|
+
|
|
888
|
+
```sh
|
|
889
|
+
SLOPCAMERA_CAPTURE_HARDWARE_CONFIRM=record-local-displays-and-selected-inputs \
|
|
890
|
+
SLOPCAMERA_CAPTURE_HARDWARE_SYSTEM_AUDIO=true \
|
|
891
|
+
SLOPCAMERA_CAPTURE_HARDWARE_CAMERA=true \
|
|
892
|
+
SLOPCAMERA_CAPTURE_HARDWARE_MICROPHONE=true \
|
|
893
|
+
SLOPCAMERA_CAPTURE_HARDWARE_MIN_DISPLAYS=2 \
|
|
894
|
+
bun run test:capture:hardware:macos
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
Add `SLOPCAMERA_CAPTURE_HARDWARE_INTERACTIONS=true` for the owned interaction
|
|
898
|
+
fixture. The fixture activates its nonce-titled window, performs one fixed
|
|
899
|
+
public → secure → public exercise against its own fields, and remains open with
|
|
900
|
+
neutral focus until capture stops. It can post only the built-in `a`, `s`, and
|
|
901
|
+
`b` canaries to its own PID at verified coordinates inside its focused window;
|
|
902
|
+
it accepts no arbitrary text, key, coordinate, or target from the caller. Do
|
|
903
|
+
not type, click, or switch applications until the command exits because doing
|
|
904
|
+
so can disturb focus or fixture timing. The fixture-PID event tap excludes
|
|
905
|
+
clicks and keys delivered to other applications from the exact evidence gate.
|
|
906
|
+
The profile binds the fixture's native-clock receipt to exact ordered click/key
|
|
907
|
+
pairs, display identity, fixture process identity, public and secure focus
|
|
908
|
+
transitions, and one native `focused` window transition. With the default
|
|
909
|
+
typed-text opt-out, the stopped bundle must contain no `typing.input` event and
|
|
910
|
+
no key cadence from the secure phase.
|
|
911
|
+
|
|
912
|
+
Set `SLOPCAMERA_CAPTURE_HARDWARE_TYPED_TEXT=true` together with the interaction
|
|
913
|
+
profile to verify explicit typed-text capture. That profile accepts exactly the
|
|
914
|
+
public `a` and `b` canaries in metadata; a native focus-identity allowlist binds
|
|
915
|
+
text persistence to the fixture's nonce-derived field ID, PID, window ID, and
|
|
916
|
+
nonce title. Text from any other input remains unpersisted, and the secure `s`
|
|
917
|
+
canary must remain absent. Failed typed-text evidence is deleted regardless of
|
|
918
|
+
the artifact retention setting. Typed-text hardware verification is
|
|
919
|
+
unavailable without the owned fixture.
|
|
920
|
+
|
|
921
|
+
Before capture, the smoke performs the helper's read-only strict probe. Screen
|
|
922
|
+
Recording, Input Monitoring, Accessibility, and window metadata must already be
|
|
923
|
+
authorized; each selected optional input must also be authorized and present.
|
|
924
|
+
An explicitly requested run fails before `start` when a prerequisite is
|
|
925
|
+
missing, so it cannot open a surprise permission prompt. Grant permissions by
|
|
926
|
+
running Slopcamera interactively first. Strict capture also creates and disables
|
|
927
|
+
the listen-only input event tap before starting any media recorder, then waits
|
|
928
|
+
for the tap's run-loop thread to confirm that it is enabled. Metadata writes
|
|
929
|
+
display, focus, window, and cursor boundary snapshots only after that handshake
|
|
930
|
+
and before a recorder can emit its first sample. At pause or stop, the
|
|
931
|
+
user-visible clock freezes, every recorder drains, all metadata pollers are
|
|
932
|
+
cancelled and joined on one serial queue, and metadata takes a final boundary
|
|
933
|
+
snapshot; finalization latency therefore does not become blank footage.
|
|
934
|
+
Tap creation or activation failure aborts the strict segment instead of
|
|
935
|
+
silently losing clicks and keys. Window focus comes from the frontmost
|
|
936
|
+
application's actual Accessibility-focused window matched back to its
|
|
937
|
+
positioned Core Graphics record, not the first enumerated window owned by that
|
|
938
|
+
process.
|
|
939
|
+
|
|
940
|
+
The smoke writes to a unique directory below
|
|
941
|
+
`artifacts/slopcamera/recordings/.hardware-smoke/`, verifies that Git ignores the
|
|
942
|
+
directory, drives the real start/pause/resume/stop controller, probes every
|
|
943
|
+
finalized media stream with FFprobe, and validates verified `capture-sync-v1`
|
|
944
|
+
sample-clock measurements in the manifest. Controller-lifecycle and
|
|
945
|
+
container-length checks are supplemental diagnostics, not substitutes for
|
|
946
|
+
sample timing. It also re-hashes every physical media file, streams and
|
|
947
|
+
re-hashes every event file through the production event parser, checks its
|
|
948
|
+
declared record count and time interval, and requires real cursor, display
|
|
949
|
+
topology, positioned-window, focus, and exact pause/resume lifecycle events.
|
|
950
|
+
For both active segments, opening lifecycle and environment snapshots must
|
|
951
|
+
precede the earliest retained sample across every selected display, system
|
|
952
|
+
audio, camera, and microphone stream, while a closing cursor and lifecycle
|
|
953
|
+
marker must follow the latest retained sample across that same complete
|
|
954
|
+
envelope.
|
|
955
|
+
Any native dropped-event diagnostic fails the run. Typed-text opt-out and any
|
|
956
|
+
observed secure-focus interval are checked directly against the parsed input
|
|
957
|
+
events.
|
|
958
|
+
|
|
959
|
+
Failed evidence is retained by default and its absolute path is printed. Set
|
|
960
|
+
`SLOPCAMERA_CAPTURE_HARDWARE_KEEP_ARTIFACTS=never` to remove every run or `always`
|
|
961
|
+
to keep successful runs too. Optional-input values must be exactly `true` or
|
|
962
|
+
`false`; the minimum-display value is bounded from 1 through 16.
|
|
963
|
+
|
|
964
|
+
## Direct
|
|
965
|
+
|
|
966
|
+
`bun run direct:slopcamera` opens the deterministic recorder and project-evidence lab without native capture, FFmpeg, whisper.cpp, Python, or cloud calls. It exposes compact fixtures for multi-angle placement, alignment, music, scene boundaries/descriptions, speech fillers, synchronized edits, and all overlay kinds. Permission, analyzer, and project worlds are fixture evidence, not claims about live native execution. `bun run verify:slopcamera:direct` drives every declared browser scenario and writes agent-readable evidence.
|