@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,576 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
createDefaultHostResourceCoordinator,
|
|
6
|
+
HOST_RESOURCE_MAX_WAIT_MILLISECONDS,
|
|
7
|
+
HostResourceError,
|
|
8
|
+
type HostResourceCoordinator,
|
|
9
|
+
type HostResourceLease,
|
|
10
|
+
} from "@hraness/slopcamera/host-resources";
|
|
11
|
+
|
|
12
|
+
import type { ApplicationContext } from "../application/context";
|
|
13
|
+
import { ApplicationError } from "../application/errors";
|
|
14
|
+
import type { OperationRegistry } from "../application/registry";
|
|
15
|
+
import { canonicalJson } from "../core/canonical-json";
|
|
16
|
+
import { createApplicationNodePlanner } from "../code/application-node-planner";
|
|
17
|
+
import { compileGraphPlan } from "../code/compiler";
|
|
18
|
+
import {
|
|
19
|
+
isComputeGraphNode,
|
|
20
|
+
isOperationGraphNode,
|
|
21
|
+
type GraphPlanV1,
|
|
22
|
+
type WorkflowNodePolicy,
|
|
23
|
+
} from "../code/contracts";
|
|
24
|
+
import {
|
|
25
|
+
RUN_STORE_VERSION,
|
|
26
|
+
type NewRunGrant,
|
|
27
|
+
type RunEvent,
|
|
28
|
+
type RunGrant,
|
|
29
|
+
type RunNodeRecord,
|
|
30
|
+
type RunSummary,
|
|
31
|
+
type RunWorkflowRecord,
|
|
32
|
+
} from "../code/run-contracts";
|
|
33
|
+
import { RunStore } from "../code/run-store";
|
|
34
|
+
import {
|
|
35
|
+
createHostApplicationBuildIdentity,
|
|
36
|
+
createWorkflowRuntimeIdentity,
|
|
37
|
+
} from "../code/runtime-identity";
|
|
38
|
+
import {
|
|
39
|
+
DurableWorkflowScheduler,
|
|
40
|
+
type SchedulerComputeRuntime,
|
|
41
|
+
type SchedulerAuthorization,
|
|
42
|
+
type SchedulerRunResult,
|
|
43
|
+
} from "../code/scheduler";
|
|
44
|
+
import { restoreWorkflowSourceBundle } from "../code/source-bundle";
|
|
45
|
+
import {
|
|
46
|
+
startCodeWorkerPool,
|
|
47
|
+
type CodeWorkerPool,
|
|
48
|
+
} from "../code/worker-client";
|
|
49
|
+
import {
|
|
50
|
+
codePreparationHostResourceClaims,
|
|
51
|
+
replayComputeWorkerPoolSize,
|
|
52
|
+
} from "./command-host-resources";
|
|
53
|
+
|
|
54
|
+
const RUN_DIRECTORY = "workflow-runs";
|
|
55
|
+
const EVENT_POLL_MILLISECONDS = 100;
|
|
56
|
+
|
|
57
|
+
async function withCodePreparationHostResources<Value>(
|
|
58
|
+
coordinator: HostResourceCoordinator,
|
|
59
|
+
callback: (lease: HostResourceLease) => Promise<Value>,
|
|
60
|
+
options: {
|
|
61
|
+
readonly signal?: AbortSignal;
|
|
62
|
+
readonly waitTimeoutMilliseconds?: number;
|
|
63
|
+
} = {},
|
|
64
|
+
): Promise<Value> {
|
|
65
|
+
try {
|
|
66
|
+
return await coordinator.withLease(
|
|
67
|
+
codePreparationHostResourceClaims(coordinator),
|
|
68
|
+
async lease => {
|
|
69
|
+
await lease.assertOwned();
|
|
70
|
+
return await callback(lease);
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
74
|
+
waitTimeoutMilliseconds: options.waitTimeoutMilliseconds
|
|
75
|
+
?? HOST_RESOURCE_MAX_WAIT_MILLISECONDS,
|
|
76
|
+
},
|
|
77
|
+
);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (!(error instanceof HostResourceError)) throw error;
|
|
80
|
+
switch (error.code) {
|
|
81
|
+
case "WAIT_ABORTED":
|
|
82
|
+
throw new ApplicationError("cancelled", error.message);
|
|
83
|
+
case "OWNERSHIP_LOST":
|
|
84
|
+
throw new ApplicationError("conflict", error.message);
|
|
85
|
+
case "INVALID_CLAIMS":
|
|
86
|
+
case "INVALID_PROFILE":
|
|
87
|
+
case "PROFILE_MISMATCH":
|
|
88
|
+
case "UNSAFE_STATE":
|
|
89
|
+
case "UNSUPPORTED_PLATFORM":
|
|
90
|
+
case "WAIT_TIMEOUT":
|
|
91
|
+
throw new ApplicationError("unavailable", error.message, {
|
|
92
|
+
hostResourceCode: error.code,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface CreateWorkflowRunOptions {
|
|
99
|
+
readonly application: ApplicationContext;
|
|
100
|
+
readonly bundleBytes: Uint8Array;
|
|
101
|
+
readonly graphPlan: GraphPlanV1;
|
|
102
|
+
readonly registry: OperationRegistry;
|
|
103
|
+
readonly sourceLocator: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface CreatedWorkflowRun {
|
|
107
|
+
readonly runId: string;
|
|
108
|
+
readonly store: RunStore;
|
|
109
|
+
readonly summary: RunSummary;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface RunWorkflowOptions {
|
|
113
|
+
readonly application: ApplicationContext;
|
|
114
|
+
readonly compute?: SchedulerComputeRuntime;
|
|
115
|
+
readonly hostResourceCoordinator?: HostResourceCoordinator;
|
|
116
|
+
readonly jobs: number;
|
|
117
|
+
readonly onEvent?: (event: RunEvent) => void;
|
|
118
|
+
readonly replayAmbiguousCode?: readonly string[];
|
|
119
|
+
readonly registry: OperationRegistry;
|
|
120
|
+
readonly runId: string;
|
|
121
|
+
readonly store?: RunStore;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function loadPersistedComputePool(options: {
|
|
125
|
+
readonly application: ApplicationContext;
|
|
126
|
+
readonly currentApplicationBuild: string;
|
|
127
|
+
readonly inheritedHostResourceFileDescriptor?: number;
|
|
128
|
+
readonly maximumWorkers: number;
|
|
129
|
+
readonly registry: OperationRegistry;
|
|
130
|
+
readonly runId: string;
|
|
131
|
+
readonly store: RunStore;
|
|
132
|
+
}): Promise<CodeWorkerPool> {
|
|
133
|
+
const [graphPlan, bundleBytes] = await Promise.all([
|
|
134
|
+
options.store.graphPlan(options.runId),
|
|
135
|
+
options.store.bundle(options.runId),
|
|
136
|
+
]);
|
|
137
|
+
if (
|
|
138
|
+
graphPlan.runtime.externals.kind === "deny-all"
|
|
139
|
+
&& graphPlan.runtime.externals.modules.length !== 0
|
|
140
|
+
) {
|
|
141
|
+
throw new ApplicationError(
|
|
142
|
+
"incompatible",
|
|
143
|
+
"A deny-all trusted-code runtime cannot contain external modules.",
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
const bundle = restoreWorkflowSourceBundle({
|
|
147
|
+
bundle: graphPlan.bundle,
|
|
148
|
+
bytes: bundleBytes,
|
|
149
|
+
externalModules: graphPlan.runtime.externals.modules,
|
|
150
|
+
});
|
|
151
|
+
const currentRuntime = await createWorkflowRuntimeIdentity({
|
|
152
|
+
applicationBuild: options.currentApplicationBuild,
|
|
153
|
+
bundle,
|
|
154
|
+
});
|
|
155
|
+
if (canonicalJson(currentRuntime) !== canonicalJson(graphPlan.runtime)) {
|
|
156
|
+
throw new ApplicationError(
|
|
157
|
+
"incompatible",
|
|
158
|
+
"The trusted-code runtime changed since this run was planned.",
|
|
159
|
+
{
|
|
160
|
+
current: currentRuntime,
|
|
161
|
+
planned: graphPlan.runtime,
|
|
162
|
+
},
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
const recompiled = compileGraphPlan({
|
|
166
|
+
bundle: graphPlan.bundle,
|
|
167
|
+
graph: graphPlan.graph,
|
|
168
|
+
limits: graphPlan.limits,
|
|
169
|
+
registry: options.registry,
|
|
170
|
+
runtime: currentRuntime,
|
|
171
|
+
staticBindings: graphPlan.staticBindings,
|
|
172
|
+
workflowInput: graphPlan.workflowInput,
|
|
173
|
+
});
|
|
174
|
+
if (canonicalJson(recompiled) !== canonicalJson(graphPlan)) {
|
|
175
|
+
throw new ApplicationError(
|
|
176
|
+
"incompatible",
|
|
177
|
+
"Persisted trusted code no longer compiles to the exact authorized graph plan.",
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
return await startCodeWorkerPool({
|
|
181
|
+
bundle,
|
|
182
|
+
expectedBuild: {
|
|
183
|
+
graph: graphPlan.graph,
|
|
184
|
+
input: graphPlan.workflowInput,
|
|
185
|
+
},
|
|
186
|
+
...(options.inheritedHostResourceFileDescriptor === undefined
|
|
187
|
+
? {}
|
|
188
|
+
: {
|
|
189
|
+
inheritedHostResourceFileDescriptor:
|
|
190
|
+
options.inheritedHostResourceFileDescriptor,
|
|
191
|
+
}),
|
|
192
|
+
maximumWorkers: options.maximumWorkers,
|
|
193
|
+
registry: options.registry,
|
|
194
|
+
temporaryRoot: options.application.paths.privateRoot,
|
|
195
|
+
workflowInput: graphPlan.workflowInput,
|
|
196
|
+
workflowInputMode: "parsed",
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export interface WorkflowRunDetails {
|
|
201
|
+
readonly graphPlanSha256: string;
|
|
202
|
+
readonly nodes: readonly RunNodeRecord[];
|
|
203
|
+
readonly outputs: unknown;
|
|
204
|
+
readonly summary: RunSummary;
|
|
205
|
+
readonly workflow: RunWorkflowRecord["workflow"];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function schedulerOwner(): string {
|
|
209
|
+
return `slopcamera-cli:${String(process.pid)}:${randomUUID()}`;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function runId(): string {
|
|
213
|
+
return `run_${randomUUID().replaceAll("-", "")}`;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function operationRuntimeIdentities(
|
|
217
|
+
graphPlan: GraphPlanV1,
|
|
218
|
+
): Extract<
|
|
219
|
+
GraphPlanV1["graph"]["nodes"][number]["executor"],
|
|
220
|
+
{ readonly kind: "operation" }
|
|
221
|
+
>["operation"][] {
|
|
222
|
+
type Identity = Extract<
|
|
223
|
+
GraphPlanV1["graph"]["nodes"][number]["executor"],
|
|
224
|
+
{ readonly kind: "operation" }
|
|
225
|
+
>["operation"];
|
|
226
|
+
const identities = new Map<string, Identity>();
|
|
227
|
+
for (const node of graphPlan.graph.nodes) {
|
|
228
|
+
if (!isOperationGraphNode(node)) continue;
|
|
229
|
+
const operation = node.executor.operation;
|
|
230
|
+
identities.set(
|
|
231
|
+
`${operation.kind}@${String(operation.version)}`,
|
|
232
|
+
operation,
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
return [...identities.entries()]
|
|
236
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
237
|
+
.map(([, identity]) => identity);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function computeRuntimeIdentities(
|
|
241
|
+
graphPlan: GraphPlanV1,
|
|
242
|
+
) {
|
|
243
|
+
const identities = new Map<
|
|
244
|
+
string,
|
|
245
|
+
Extract<
|
|
246
|
+
GraphPlanV1["graph"]["nodes"][number]["executor"],
|
|
247
|
+
{ readonly kind: "compute" }
|
|
248
|
+
>["compute"]
|
|
249
|
+
>();
|
|
250
|
+
for (const node of graphPlan.graph.nodes) {
|
|
251
|
+
if (isComputeGraphNode(node)) {
|
|
252
|
+
identities.set(node.executor.compute.key, node.executor.compute);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return [...identities.entries()]
|
|
256
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
257
|
+
.map(([, identity]) => identity);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export function workflowRunStore(application: ApplicationContext): RunStore {
|
|
261
|
+
return new RunStore({
|
|
262
|
+
root: join(application.paths.privateRoot, RUN_DIRECTORY),
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export async function createWorkflowRun(
|
|
267
|
+
options: CreateWorkflowRunOptions,
|
|
268
|
+
): Promise<CreatedWorkflowRun> {
|
|
269
|
+
const store = workflowRunStore(options.application);
|
|
270
|
+
const createdRunId = runId();
|
|
271
|
+
const summary = await store.create({
|
|
272
|
+
bundleBytes: new Uint8Array(options.bundleBytes),
|
|
273
|
+
graphPlan: options.graphPlan,
|
|
274
|
+
runId: createdRunId,
|
|
275
|
+
runtime: {
|
|
276
|
+
computes: computeRuntimeIdentities(options.graphPlan),
|
|
277
|
+
operations: operationRuntimeIdentities(options.graphPlan),
|
|
278
|
+
runtime: options.graphPlan.runtime,
|
|
279
|
+
version: RUN_STORE_VERSION,
|
|
280
|
+
},
|
|
281
|
+
sourceLocator: options.sourceLocator,
|
|
282
|
+
workflow: {
|
|
283
|
+
bundle: options.graphPlan.bundle,
|
|
284
|
+
sourceLocator: options.sourceLocator,
|
|
285
|
+
workflow: options.graphPlan.graph.workflow,
|
|
286
|
+
},
|
|
287
|
+
});
|
|
288
|
+
return { runId: createdRunId, store, summary };
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function localPreparationAllowed(policy: WorkflowNodePolicy): boolean {
|
|
292
|
+
const automaticallyAllowed = new Set([
|
|
293
|
+
"local-media",
|
|
294
|
+
"project-state",
|
|
295
|
+
]);
|
|
296
|
+
return policy.preparation.every(requirement => (
|
|
297
|
+
automaticallyAllowed.has(requirement)
|
|
298
|
+
));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function localEffectAllowed(policy: WorkflowNodePolicy): boolean {
|
|
302
|
+
return policy.effect !== "paid-cloud"
|
|
303
|
+
&& policy.effect !== "live-control";
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function localCliAuthorization(): SchedulerAuthorization {
|
|
307
|
+
return {
|
|
308
|
+
authorizeEffect: request => Promise.resolve(
|
|
309
|
+
localEffectAllowed(request.policy),
|
|
310
|
+
),
|
|
311
|
+
authorizePreparation: request => Promise.resolve(
|
|
312
|
+
localPreparationAllowed(request.policy),
|
|
313
|
+
),
|
|
314
|
+
grantedBy: "slopcamera-local-cli",
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
async function readNewEvents(
|
|
319
|
+
store: RunStore,
|
|
320
|
+
runIdValue: string,
|
|
321
|
+
afterSequence: number,
|
|
322
|
+
emit: (event: RunEvent) => void,
|
|
323
|
+
): Promise<number> {
|
|
324
|
+
let events: readonly RunEvent[];
|
|
325
|
+
try {
|
|
326
|
+
events = await store.events(runIdValue);
|
|
327
|
+
} catch (error) {
|
|
328
|
+
if (error instanceof ApplicationError && error.code === "conflict") {
|
|
329
|
+
return afterSequence;
|
|
330
|
+
}
|
|
331
|
+
throw error;
|
|
332
|
+
}
|
|
333
|
+
let latest = afterSequence;
|
|
334
|
+
for (const event of events) {
|
|
335
|
+
if (event.sequence <= afterSequence) continue;
|
|
336
|
+
emit(event);
|
|
337
|
+
latest = Math.max(latest, event.sequence);
|
|
338
|
+
}
|
|
339
|
+
return latest;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export async function runWorkflow(
|
|
343
|
+
options: RunWorkflowOptions,
|
|
344
|
+
): Promise<SchedulerRunResult> {
|
|
345
|
+
const store = options.store ?? workflowRunStore(options.application);
|
|
346
|
+
const hostResourceCoordinator = options.hostResourceCoordinator
|
|
347
|
+
?? createDefaultHostResourceCoordinator();
|
|
348
|
+
const currentApplicationBuild = await withCodePreparationHostResources(
|
|
349
|
+
hostResourceCoordinator,
|
|
350
|
+
async lease => await createHostApplicationBuildIdentity(
|
|
351
|
+
options.application,
|
|
352
|
+
lease.inheritedFileDescriptor < 3
|
|
353
|
+
? {}
|
|
354
|
+
: { inheritedFileDescriptors: [lease.inheritedFileDescriptor] },
|
|
355
|
+
),
|
|
356
|
+
);
|
|
357
|
+
const replayNodeKeys = options.replayAmbiguousCode ?? [];
|
|
358
|
+
if (options.compute !== undefined && replayNodeKeys.length > 0) {
|
|
359
|
+
throw new ApplicationError(
|
|
360
|
+
"usage",
|
|
361
|
+
"A workflow run cannot use a fresh code worker and persisted compute replay together.",
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
let replayLoadStarted = false;
|
|
365
|
+
const compute: SchedulerComputeRuntime | undefined = replayNodeKeys.length === 0
|
|
366
|
+
? options.compute
|
|
367
|
+
: {
|
|
368
|
+
kind: "replay" as const,
|
|
369
|
+
load: async ({ signal, waitTimeoutMilliseconds }) => {
|
|
370
|
+
if (replayLoadStarted) {
|
|
371
|
+
throw new ApplicationError(
|
|
372
|
+
"conflict",
|
|
373
|
+
"The persisted trusted-code worker pool was already loaded.",
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
replayLoadStarted = true;
|
|
377
|
+
const replayPool = await withCodePreparationHostResources(
|
|
378
|
+
hostResourceCoordinator,
|
|
379
|
+
async lease => await loadPersistedComputePool({
|
|
380
|
+
application: options.application,
|
|
381
|
+
currentApplicationBuild,
|
|
382
|
+
inheritedHostResourceFileDescriptor: lease.inheritedFileDescriptor,
|
|
383
|
+
maximumWorkers: replayComputeWorkerPoolSize(
|
|
384
|
+
options.jobs,
|
|
385
|
+
replayNodeKeys,
|
|
386
|
+
hostResourceCoordinator,
|
|
387
|
+
),
|
|
388
|
+
registry: options.registry,
|
|
389
|
+
runId: options.runId,
|
|
390
|
+
store,
|
|
391
|
+
}),
|
|
392
|
+
{ signal, waitTimeoutMilliseconds },
|
|
393
|
+
);
|
|
394
|
+
return {
|
|
395
|
+
executor: replayPool,
|
|
396
|
+
release: async () => await replayPool.close(),
|
|
397
|
+
};
|
|
398
|
+
},
|
|
399
|
+
nodeKeys: replayNodeKeys,
|
|
400
|
+
};
|
|
401
|
+
const scheduler = new DurableWorkflowScheduler({
|
|
402
|
+
application: options.application,
|
|
403
|
+
authorization: localCliAuthorization(),
|
|
404
|
+
currentApplicationBuild,
|
|
405
|
+
...(compute === undefined ? {} : { compute }),
|
|
406
|
+
hostLimits: {
|
|
407
|
+
maxJobs: options.jobs,
|
|
408
|
+
},
|
|
409
|
+
hostResourceCoordinator,
|
|
410
|
+
jobs: options.jobs,
|
|
411
|
+
nodePlanner: createApplicationNodePlanner(options.application),
|
|
412
|
+
owner: schedulerOwner(),
|
|
413
|
+
registry: options.registry,
|
|
414
|
+
store,
|
|
415
|
+
});
|
|
416
|
+
if (options.onEvent === undefined) return await scheduler.run(options.runId);
|
|
417
|
+
|
|
418
|
+
const outcome = scheduler.run(options.runId).then(
|
|
419
|
+
result => ({ kind: "result" as const, result }),
|
|
420
|
+
(error: unknown) => ({ error, kind: "error" as const }),
|
|
421
|
+
);
|
|
422
|
+
let sequence = 0;
|
|
423
|
+
while (true) {
|
|
424
|
+
const settled = await Promise.race([
|
|
425
|
+
outcome,
|
|
426
|
+
new Promise<undefined>(resolveDelay => {
|
|
427
|
+
setTimeout(resolveDelay, EVENT_POLL_MILLISECONDS);
|
|
428
|
+
}),
|
|
429
|
+
]);
|
|
430
|
+
sequence = await readNewEvents(
|
|
431
|
+
store,
|
|
432
|
+
options.runId,
|
|
433
|
+
sequence,
|
|
434
|
+
options.onEvent,
|
|
435
|
+
);
|
|
436
|
+
if (settled === undefined) continue;
|
|
437
|
+
if (settled.kind === "error") throw settled.error;
|
|
438
|
+
return settled.result;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
export async function approveWorkflowRun(options: {
|
|
443
|
+
readonly application: ApplicationContext;
|
|
444
|
+
readonly nodeKey: string;
|
|
445
|
+
readonly planHash: string;
|
|
446
|
+
readonly planKind: "effect" | "preparation";
|
|
447
|
+
readonly runId: string;
|
|
448
|
+
}): Promise<RunGrant> {
|
|
449
|
+
const store = workflowRunStore(options.application);
|
|
450
|
+
const owner = schedulerOwner();
|
|
451
|
+
const fence = await store.acquireClaim(options.runId, { owner });
|
|
452
|
+
try {
|
|
453
|
+
const [graphPlan, node] = await Promise.all([
|
|
454
|
+
store.graphPlan(options.runId),
|
|
455
|
+
store.node(options.runId, options.nodeKey),
|
|
456
|
+
]);
|
|
457
|
+
if (node.status !== "approval-required") {
|
|
458
|
+
throw new ApplicationError(
|
|
459
|
+
"conflict",
|
|
460
|
+
`Node ${options.nodeKey} is not awaiting approval.`,
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
const common = {
|
|
464
|
+
createdAt: new Date().toISOString(),
|
|
465
|
+
graphPlanSha256: graphPlan.graphPlanSha256,
|
|
466
|
+
grantedBy: "slopcamera-local-cli",
|
|
467
|
+
grantId: randomUUID(),
|
|
468
|
+
nodeKey: options.nodeKey,
|
|
469
|
+
} as const;
|
|
470
|
+
let grant: NewRunGrant;
|
|
471
|
+
if (options.planKind === "preparation") {
|
|
472
|
+
const actual = node.preparationPlan?.preparationPlanSha256;
|
|
473
|
+
if (actual !== options.planHash) {
|
|
474
|
+
throw new ApplicationError(
|
|
475
|
+
"conflict",
|
|
476
|
+
"The preparation approval hash does not match the pending node plan.",
|
|
477
|
+
{ actual, requested: options.planHash },
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
grant = {
|
|
481
|
+
...common,
|
|
482
|
+
kind: "preparation",
|
|
483
|
+
preparationPlanSha256: options.planHash,
|
|
484
|
+
};
|
|
485
|
+
} else {
|
|
486
|
+
const actual = node.executionPlan?.nodePlanSha256;
|
|
487
|
+
if (actual !== options.planHash) {
|
|
488
|
+
throw new ApplicationError(
|
|
489
|
+
"conflict",
|
|
490
|
+
"The effect approval hash does not match the pending node plan.",
|
|
491
|
+
{ actual, requested: options.planHash },
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
grant = {
|
|
495
|
+
...common,
|
|
496
|
+
kind: "effect",
|
|
497
|
+
nodePlanSha256: options.planHash,
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
return await store.appendGrant(fence, grant);
|
|
501
|
+
} finally {
|
|
502
|
+
await store.releaseClaim(fence).catch(() => undefined);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
export async function cancelWorkflowRun(options: {
|
|
507
|
+
readonly application: ApplicationContext;
|
|
508
|
+
readonly runId: string;
|
|
509
|
+
}) {
|
|
510
|
+
return await workflowRunStore(options.application).requestCancellation(
|
|
511
|
+
options.runId,
|
|
512
|
+
"slopcamera-local-cli",
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
export async function listWorkflowRuns(
|
|
517
|
+
application: ApplicationContext,
|
|
518
|
+
limit: number,
|
|
519
|
+
): Promise<readonly RunSummary[]> {
|
|
520
|
+
return (await workflowRunStore(application).list()).slice(0, limit);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
export async function workflowRunDetails(options: {
|
|
524
|
+
readonly application: ApplicationContext;
|
|
525
|
+
readonly nodes: "all" | "failed";
|
|
526
|
+
readonly runId: string;
|
|
527
|
+
}): Promise<WorkflowRunDetails> {
|
|
528
|
+
const store = workflowRunStore(options.application);
|
|
529
|
+
const [summary, workflow, records, outputs] = await Promise.all([
|
|
530
|
+
store.summary(options.runId),
|
|
531
|
+
store.workflow(options.runId),
|
|
532
|
+
store.nodes(options.runId),
|
|
533
|
+
store.outputs(options.runId),
|
|
534
|
+
]);
|
|
535
|
+
const visibleNodes = options.nodes === "all"
|
|
536
|
+
? records
|
|
537
|
+
: records.filter(record => [
|
|
538
|
+
"ambiguous",
|
|
539
|
+
"ambiguous-code",
|
|
540
|
+
"approval-required",
|
|
541
|
+
"failed",
|
|
542
|
+
"incompatible",
|
|
543
|
+
].includes(record.status));
|
|
544
|
+
return {
|
|
545
|
+
graphPlanSha256: summary.graphPlanSha256,
|
|
546
|
+
nodes: visibleNodes,
|
|
547
|
+
outputs: outputs?.outputs ?? null,
|
|
548
|
+
summary,
|
|
549
|
+
workflow: workflow.workflow,
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
export function humanRunSummary(
|
|
554
|
+
result: SchedulerRunResult,
|
|
555
|
+
): string {
|
|
556
|
+
const summary = result.summary;
|
|
557
|
+
const lines = [
|
|
558
|
+
`${summary.runId} ${summary.status} ${summary.graphPlanSha256}`,
|
|
559
|
+
`nodes completed=${String(summary.counts.completed)} failed=${String(summary.counts.failed)} skipped=${String(summary.counts.skipped)} pending=${String(summary.counts.pending)} cancelled=${String(summary.counts.cancelled)}`,
|
|
560
|
+
];
|
|
561
|
+
if (result.pause !== undefined) {
|
|
562
|
+
const option = result.pause.phase === "effect"
|
|
563
|
+
? "--node-plan"
|
|
564
|
+
: "--preparation-plan";
|
|
565
|
+
lines.push(
|
|
566
|
+
`next slopcamera runs approve ${summary.runId} ${result.pause.nodeKey} ${option} ${result.pause.planSha256}`,
|
|
567
|
+
`then slopcamera runs resume ${summary.runId}`,
|
|
568
|
+
);
|
|
569
|
+
} else if (
|
|
570
|
+
summary.status !== "completed"
|
|
571
|
+
&& summary.status !== "cancelled"
|
|
572
|
+
) {
|
|
573
|
+
lines.push(`next slopcamera runs show ${summary.runId} --nodes failed`);
|
|
574
|
+
}
|
|
575
|
+
return lines.join("\n");
|
|
576
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
export * from "./public";
|
|
2
|
+
export {
|
|
3
|
+
PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS,
|
|
4
|
+
PORTABLE_SLOPCAMERA_OPERATION_KINDS,
|
|
5
|
+
PUBLIC_SLOPCAMERA_WORKFLOW_PROJECTION,
|
|
6
|
+
PUBLIC_WORKFLOW_REGISTRY_PROJECTION,
|
|
7
|
+
PUBLIC_WORKFLOW_REGISTRY_PROJECTION_ID,
|
|
8
|
+
PortableWorkflowBuilder,
|
|
9
|
+
compileWorkflowGraph,
|
|
10
|
+
createGraphHash,
|
|
11
|
+
createSlopcameraCodeHost,
|
|
12
|
+
createWorkflowCompilationHash,
|
|
13
|
+
createWorkflowGraphHash,
|
|
14
|
+
createWorkflowRegistryProjection,
|
|
15
|
+
definePortableWorkflowFragment,
|
|
16
|
+
parseCompiledWorkflowGraph,
|
|
17
|
+
parseWorkflowRegistryProjection,
|
|
18
|
+
runBuiltWorkflow,
|
|
19
|
+
runWorkflow,
|
|
20
|
+
type CompiledWorkflowGraph,
|
|
21
|
+
type PortableSlopcameraOperationInputMap,
|
|
22
|
+
type PortableSlopcameraOperationKind,
|
|
23
|
+
type PortableSlopcameraOperationResultMap,
|
|
24
|
+
type PortableWorkflowFragment,
|
|
25
|
+
type RunBuiltWorkflowOptions,
|
|
26
|
+
type SlopcameraCodeHost,
|
|
27
|
+
type WorkflowRegistryProjection,
|
|
28
|
+
type WorkflowRunResult,
|
|
29
|
+
} from "@hraness/slopcamera/code/advanced";
|
|
30
|
+
export {
|
|
31
|
+
DEFAULT_GRAPH_COMPILER_LIMITS,
|
|
32
|
+
EMPTY_STATIC_BINDINGS,
|
|
33
|
+
GRAPH_PLAN_HASH_DOMAIN,
|
|
34
|
+
REGISTRY_DISCOVERY_HASH_DOMAIN,
|
|
35
|
+
compileGraphPlan,
|
|
36
|
+
createGraphPlanHash,
|
|
37
|
+
createRegistryDiscoveryHash,
|
|
38
|
+
parseGraphPlan,
|
|
39
|
+
type CompileGraphPlanOptions,
|
|
40
|
+
type ValidatedGraphTopology,
|
|
41
|
+
} from "./compiler";
|
|
42
|
+
export {
|
|
43
|
+
WorkflowGraphBuilder,
|
|
44
|
+
defineWorkflowFragment as defineRawWorkflowFragment,
|
|
45
|
+
operationContract,
|
|
46
|
+
type OperationDiscoverySource,
|
|
47
|
+
type OperationNodeOptions,
|
|
48
|
+
type UntypedOperationRequest,
|
|
49
|
+
type WorkflowFragment as RawWorkflowFragment,
|
|
50
|
+
} from "./graph-builder";
|
|
51
|
+
export {
|
|
52
|
+
AuthoredGraphNodeV1Schema,
|
|
53
|
+
AuthoredComputeIdentitySchema,
|
|
54
|
+
AuthoredNodeExecutorSchema,
|
|
55
|
+
AuthoredOperationIdentitySchema,
|
|
56
|
+
AuthoredWorkflowGraphV1Schema,
|
|
57
|
+
CandidateDescriptorSchema,
|
|
58
|
+
CODE_WORKER_ABI,
|
|
59
|
+
ComputeKeySchema,
|
|
60
|
+
ExternalsPolicyIdentitySchema,
|
|
61
|
+
GRAPH_ABI,
|
|
62
|
+
GRAPH_COMPILER_ABI,
|
|
63
|
+
GRAPH_PLAN_VERSION,
|
|
64
|
+
GRAPH_SCHEDULER_ABI,
|
|
65
|
+
GraphCompilerLimitsSchema,
|
|
66
|
+
GraphPlanV1Schema,
|
|
67
|
+
GraphRegistryIdentitySchema,
|
|
68
|
+
InitialSubjectBindingSchema,
|
|
69
|
+
JsonValueSchema,
|
|
70
|
+
MAX_SERIALIZED_GRAPH_NODES,
|
|
71
|
+
MAX_SERIALIZED_NODE_DEPENDENCIES,
|
|
72
|
+
MAX_TRUSTED_COMPUTE_DURATION_MS,
|
|
73
|
+
MAX_TRUSTED_COMPUTE_INPUT_BYTES,
|
|
74
|
+
MAX_TRUSTED_COMPUTE_OUTPUT_BYTES,
|
|
75
|
+
NodeKeySchema,
|
|
76
|
+
NodeKeySegmentSchema,
|
|
77
|
+
RefPathSegmentSchema,
|
|
78
|
+
OPERATION_EFFECT_CLASSES,
|
|
79
|
+
OPERATION_FAMILIES,
|
|
80
|
+
OPERATION_LIFECYCLE_KINDS,
|
|
81
|
+
OPERATION_PREPARATION_KINDS,
|
|
82
|
+
OPERATION_RESUME_CLASSES,
|
|
83
|
+
OperationDiscoverySchema,
|
|
84
|
+
OperationKindSchema,
|
|
85
|
+
OperationPolicySchema,
|
|
86
|
+
OperationResourceClaimSchema,
|
|
87
|
+
REQUIREMENT_ENVELOPE_VERSION,
|
|
88
|
+
RequirementEnvelopeSchema,
|
|
89
|
+
STATIC_BINDINGS_VERSION,
|
|
90
|
+
SchemaIdSchema,
|
|
91
|
+
SerializedRefV1Schema,
|
|
92
|
+
Sha256Schema,
|
|
93
|
+
StaticBindingsSchema,
|
|
94
|
+
TRUSTED_COMPUTE_VERSION,
|
|
95
|
+
TrustedComputePolicySchema,
|
|
96
|
+
UNRESOLVED_REQUIREMENT_KINDS,
|
|
97
|
+
UnsignedGraphPlanV1Schema,
|
|
98
|
+
WORKFLOW_GRAPH_VERSION,
|
|
99
|
+
WORKFLOW_REF_VERSION,
|
|
100
|
+
WORKFLOW_EFFECT_CLASSES,
|
|
101
|
+
WORKFLOW_RESUME_CLASSES,
|
|
102
|
+
WorkflowBundleIdentitySchema,
|
|
103
|
+
WorkflowIdSchema,
|
|
104
|
+
WorkflowIdentitySchema,
|
|
105
|
+
WorkflowOutputBindingSchema,
|
|
106
|
+
WorkflowRuntimeIdentitySchema,
|
|
107
|
+
isComputeGraphNode,
|
|
108
|
+
isOperationGraphNode,
|
|
109
|
+
trustedComputePolicy,
|
|
110
|
+
type AnyTrustedComputeDefinition,
|
|
111
|
+
type AuthoredComputeGraphNodeV1,
|
|
112
|
+
type AuthoredGraphNodeV1,
|
|
113
|
+
type AuthoredNodeExecutor,
|
|
114
|
+
type AuthoredOperationGraphNodeV1,
|
|
115
|
+
type AuthoredWorkflowGraphV1,
|
|
116
|
+
type CandidateDescriptor,
|
|
117
|
+
type GraphCompilerLimits,
|
|
118
|
+
type GraphInputValue,
|
|
119
|
+
type GraphOperationDiscovery,
|
|
120
|
+
type GraphPlanV1,
|
|
121
|
+
type InitialSubjectBinding,
|
|
122
|
+
type JsonPrimitive,
|
|
123
|
+
type JsonValue,
|
|
124
|
+
type OperationFamily,
|
|
125
|
+
type OperationPreparationKind,
|
|
126
|
+
type RequirementEnvelope,
|
|
127
|
+
type SerializedRefV1,
|
|
128
|
+
type StaticBindings,
|
|
129
|
+
type TrustedComputeDefinition,
|
|
130
|
+
type TrustedComputePolicy,
|
|
131
|
+
type UnsignedGraphPlanV1,
|
|
132
|
+
type WorkflowBundleIdentity,
|
|
133
|
+
type WorkflowEffectClass,
|
|
134
|
+
type WorkflowIdentity,
|
|
135
|
+
type WorkflowOutputBinding,
|
|
136
|
+
type WorkflowNodePolicy,
|
|
137
|
+
type WorkflowResumeClass,
|
|
138
|
+
type WorkflowRuntimeIdentity,
|
|
139
|
+
} from "./contracts";
|