@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,784 @@
|
|
|
1
|
+
import {
|
|
2
|
+
executeSlopcameraOperation,
|
|
3
|
+
executeSlopcameraOperationWithLease,
|
|
4
|
+
vectorizeImage,
|
|
5
|
+
type HostResourceCoordinator,
|
|
6
|
+
type LintFinding,
|
|
7
|
+
type VectorizeOptions,
|
|
8
|
+
type VectorizeResult,
|
|
9
|
+
} from "@hraness/slopcamera";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { randomUUID } from "node:crypto";
|
|
12
|
+
import { constants } from "node:fs";
|
|
13
|
+
import { open, rm } from "node:fs/promises";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
|
|
16
|
+
import { RepositoryRelativePathSchema } from "../../contracts";
|
|
17
|
+
import { canonicalJsonSha256 } from "../../core/canonical-json";
|
|
18
|
+
import type { ApplicationContext } from "../context";
|
|
19
|
+
import { ApplicationError } from "../errors";
|
|
20
|
+
import type { OperationDefinition, OperationExecutionContext } from "../operation";
|
|
21
|
+
import { writeOperationCompletionCheckpoint } from "../operation-completion-checkpoint";
|
|
22
|
+
import { throwIfAborted } from "./shared";
|
|
23
|
+
import {
|
|
24
|
+
MAXIMUM_MEDIA_EFFECT_INPUT_BYTES,
|
|
25
|
+
MediaArtifactReferenceSchema,
|
|
26
|
+
MediaArtifactRequestSchema,
|
|
27
|
+
bindRepositoryMedia,
|
|
28
|
+
createMediaOperationWorkspace,
|
|
29
|
+
loadRepositoryMedia,
|
|
30
|
+
publishContentAddressedMedia,
|
|
31
|
+
publishContentAddressedReceipt,
|
|
32
|
+
type MediaArtifactReference,
|
|
33
|
+
} from "./media/shared";
|
|
34
|
+
|
|
35
|
+
export const MAXIMUM_DIAGRAM_SOURCE_BYTES = 1024 * 1024;
|
|
36
|
+
export const MAXIMUM_DIAGRAM_ARTIFACT_BYTES = 64 * 1024 * 1024;
|
|
37
|
+
export const MAXIMUM_VECTOR_ARTIFACT_BYTES = 64 * 1024 * 1024;
|
|
38
|
+
|
|
39
|
+
const DiagramFindingSchema = z.strictObject({
|
|
40
|
+
code: z.string().min(1).max(128),
|
|
41
|
+
message: z.string().min(1).max(2_048),
|
|
42
|
+
shapeIds: z.array(z.string().min(1).max(128)).max(256),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const SlopcameraMediaInputRequestSchema = z.union([
|
|
46
|
+
RepositoryRelativePathSchema,
|
|
47
|
+
MediaArtifactRequestSchema,
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
export const SlopcameraDiagramCheckInputSchema = z.strictObject({
|
|
51
|
+
path: SlopcameraMediaInputRequestSchema,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export const BoundSlopcameraDiagramCheckInputSchema =
|
|
55
|
+
SlopcameraDiagramCheckInputSchema.extend({
|
|
56
|
+
path: MediaArtifactReferenceSchema,
|
|
57
|
+
}).strict();
|
|
58
|
+
|
|
59
|
+
export const SlopcameraDiagramCheckOutputSchema = z.strictObject({
|
|
60
|
+
findings: z.array(DiagramFindingSchema).max(256),
|
|
61
|
+
source: MediaArtifactReferenceSchema,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
export const SlopcameraDiagramRenderInputSchema =
|
|
65
|
+
SlopcameraDiagramCheckInputSchema.extend({
|
|
66
|
+
scale: z.number().finite().positive().max(4).optional(),
|
|
67
|
+
}).strict();
|
|
68
|
+
|
|
69
|
+
export const BoundSlopcameraDiagramRenderInputSchema =
|
|
70
|
+
SlopcameraDiagramRenderInputSchema.extend({
|
|
71
|
+
path: MediaArtifactReferenceSchema,
|
|
72
|
+
}).strict();
|
|
73
|
+
|
|
74
|
+
export const SlopcameraDiagramArtifactsSchema = z.strictObject({
|
|
75
|
+
darkPng: MediaArtifactReferenceSchema,
|
|
76
|
+
darkSvg: MediaArtifactReferenceSchema,
|
|
77
|
+
lightPng: MediaArtifactReferenceSchema,
|
|
78
|
+
lightSvg: MediaArtifactReferenceSchema,
|
|
79
|
+
tldr: MediaArtifactReferenceSchema,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
export const SlopcameraDiagramRenderOutputSchema = z.strictObject({
|
|
83
|
+
artifacts: SlopcameraDiagramArtifactsSchema,
|
|
84
|
+
created: z.strictObject({
|
|
85
|
+
darkPng: z.boolean(),
|
|
86
|
+
darkSvg: z.boolean(),
|
|
87
|
+
lightPng: z.boolean(),
|
|
88
|
+
lightSvg: z.boolean(),
|
|
89
|
+
tldr: z.boolean(),
|
|
90
|
+
}),
|
|
91
|
+
findings: z.array(DiagramFindingSchema).max(256),
|
|
92
|
+
receipt: MediaArtifactReferenceSchema,
|
|
93
|
+
source: MediaArtifactReferenceSchema,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
export const SlopcameraDiagramRenderReceiptSchema = z.strictObject({
|
|
97
|
+
artifacts: SlopcameraDiagramArtifactsSchema,
|
|
98
|
+
createdAt: z.string().datetime({ offset: true }),
|
|
99
|
+
exactInputSha256: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
100
|
+
findings: z.array(DiagramFindingSchema).max(256),
|
|
101
|
+
kind: z.union([
|
|
102
|
+
z.literal("slopcamera.visual-artifact-receipt"),
|
|
103
|
+
]),
|
|
104
|
+
operation: z.union([
|
|
105
|
+
z.literal("slopcamera.diagram.render"),
|
|
106
|
+
]),
|
|
107
|
+
scale: z.number().finite().positive().max(4),
|
|
108
|
+
schemaVersion: z.literal(1),
|
|
109
|
+
source: MediaArtifactReferenceSchema,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const HexColorSchema = z.string().regex(/^#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$/u);
|
|
113
|
+
|
|
114
|
+
export const SlopcameraImageVectorizeInputSchema = z.strictObject({
|
|
115
|
+
alphaCutoff: z.number().int().min(1).max(64).optional(),
|
|
116
|
+
duotone: z.tuple([HexColorSchema, HexColorSchema]).optional(),
|
|
117
|
+
inputPath: SlopcameraMediaInputRequestSchema,
|
|
118
|
+
timeoutMs: z.number().int().min(1).max(300_000).optional(),
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
export const BoundSlopcameraImageVectorizeInputSchema =
|
|
122
|
+
SlopcameraImageVectorizeInputSchema.extend({
|
|
123
|
+
inputPath: MediaArtifactReferenceSchema,
|
|
124
|
+
}).strict();
|
|
125
|
+
|
|
126
|
+
const VectorizeQualityReceiptSchema = z.strictObject({
|
|
127
|
+
alphaRmse: z.number().finite().nonnegative(),
|
|
128
|
+
colorRmse: z.number().finite().nonnegative(),
|
|
129
|
+
outsideAlphaRatio: z.number().finite().min(0).max(1),
|
|
130
|
+
sampleHeight: z.number().int().positive(),
|
|
131
|
+
sampleWidth: z.number().int().positive(),
|
|
132
|
+
supportRecall: z.number().finite().min(0).max(1),
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const VectorizeReceiptSchema = z.strictObject({
|
|
136
|
+
alphaCutoff: z.number().int().min(1).max(64),
|
|
137
|
+
bytes: z.number().int().positive(),
|
|
138
|
+
candidatesEvaluated: z.number().int().positive(),
|
|
139
|
+
format: z.string().min(1).max(64),
|
|
140
|
+
height: z.number().int().positive(),
|
|
141
|
+
inputBytes: z.number().int().positive(),
|
|
142
|
+
outputMode: z.enum(["color", "duotone"]),
|
|
143
|
+
pathCount: z.number().int().nonnegative(),
|
|
144
|
+
profile: z.enum(["balanced", "detailed", "photo"]),
|
|
145
|
+
provenance: z.strictObject({
|
|
146
|
+
arch: z.string().min(1).max(64),
|
|
147
|
+
platform: z.string().min(1).max(64),
|
|
148
|
+
sharp: z.string().min(1).max(128),
|
|
149
|
+
sharpVersions: z.record(
|
|
150
|
+
z.string().min(1).max(128),
|
|
151
|
+
z.string().min(1).max(128),
|
|
152
|
+
).superRefine((versions, context) => {
|
|
153
|
+
if (Object.keys(versions).length > 64) {
|
|
154
|
+
context.addIssue({ code: "custom", message: "Sharp provenance is too large." });
|
|
155
|
+
}
|
|
156
|
+
}),
|
|
157
|
+
vips: z.string().min(1).max(128),
|
|
158
|
+
vtracerSha256: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
159
|
+
vtracerSource: z.enum(["official-release", "override"]),
|
|
160
|
+
vtracerVersion: z.string().min(1).max(64),
|
|
161
|
+
}),
|
|
162
|
+
quality: VectorizeQualityReceiptSchema,
|
|
163
|
+
receiptVersion: z.literal(1),
|
|
164
|
+
representation: z.enum(["color-paths", "alpha-mask"]),
|
|
165
|
+
sourceSha256: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
166
|
+
svgSha256: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
167
|
+
width: z.number().int().positive(),
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
export const SlopcameraImageVectorizeOutputSchema = z.strictObject({
|
|
171
|
+
artifact: MediaArtifactReferenceSchema,
|
|
172
|
+
created: z.boolean(),
|
|
173
|
+
receipt: MediaArtifactReferenceSchema,
|
|
174
|
+
source: MediaArtifactReferenceSchema,
|
|
175
|
+
vectorizer: VectorizeReceiptSchema,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
export const SlopcameraImageVectorizeReceiptSchema = z.strictObject({
|
|
179
|
+
artifact: MediaArtifactReferenceSchema,
|
|
180
|
+
createdAt: z.string().datetime({ offset: true }),
|
|
181
|
+
exactInputSha256: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
182
|
+
kind: z.union([
|
|
183
|
+
z.literal("slopcamera.visual-artifact-receipt"),
|
|
184
|
+
]),
|
|
185
|
+
operation: z.union([
|
|
186
|
+
z.literal("slopcamera.image.vectorize"),
|
|
187
|
+
]),
|
|
188
|
+
schemaVersion: z.literal(1),
|
|
189
|
+
source: MediaArtifactReferenceSchema,
|
|
190
|
+
vectorizer: VectorizeReceiptSchema,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
export type SlopcameraDiagramCheckInput = z.infer<typeof SlopcameraDiagramCheckInputSchema>;
|
|
194
|
+
export type BoundSlopcameraDiagramCheckInput = z.infer<typeof BoundSlopcameraDiagramCheckInputSchema>;
|
|
195
|
+
export type SlopcameraDiagramCheckOutput = z.infer<typeof SlopcameraDiagramCheckOutputSchema>;
|
|
196
|
+
export type SlopcameraDiagramRenderInput = z.infer<typeof SlopcameraDiagramRenderInputSchema>;
|
|
197
|
+
export type BoundSlopcameraDiagramRenderInput = z.infer<typeof BoundSlopcameraDiagramRenderInputSchema>;
|
|
198
|
+
export type SlopcameraDiagramRenderOutput = z.infer<typeof SlopcameraDiagramRenderOutputSchema>;
|
|
199
|
+
export type SlopcameraImageVectorizeInput = z.infer<typeof SlopcameraImageVectorizeInputSchema>;
|
|
200
|
+
export type BoundSlopcameraImageVectorizeInput = z.infer<typeof BoundSlopcameraImageVectorizeInputSchema>;
|
|
201
|
+
export type SlopcameraImageVectorizeOutput = z.infer<typeof SlopcameraImageVectorizeOutputSchema>;
|
|
202
|
+
|
|
203
|
+
export const SLOPCAMERA_VISUAL_FILE_OPERATION_KINDS = [
|
|
204
|
+
"slopcamera.diagram.check",
|
|
205
|
+
"slopcamera.diagram.render",
|
|
206
|
+
"slopcamera.image.vectorize",
|
|
207
|
+
] as const;
|
|
208
|
+
|
|
209
|
+
export type SlopcameraVisualFileOperationKind =
|
|
210
|
+
typeof SLOPCAMERA_VISUAL_FILE_OPERATION_KINDS[number];
|
|
211
|
+
|
|
212
|
+
type DiagramCheck = (path: string) => Promise<{ readonly findings: readonly LintFinding[] }>;
|
|
213
|
+
type DiagramRender = (input: Readonly<{
|
|
214
|
+
outDirectory: string;
|
|
215
|
+
path: string;
|
|
216
|
+
scale?: number;
|
|
217
|
+
}>) => Promise<Readonly<{
|
|
218
|
+
artifacts: Readonly<{
|
|
219
|
+
darkPng: string;
|
|
220
|
+
darkSvg: string;
|
|
221
|
+
lightPng: string;
|
|
222
|
+
lightSvg: string;
|
|
223
|
+
spec: string;
|
|
224
|
+
tldr: string;
|
|
225
|
+
}>;
|
|
226
|
+
findings: readonly LintFinding[];
|
|
227
|
+
}>>;
|
|
228
|
+
type ImageVectorize = (
|
|
229
|
+
path: string,
|
|
230
|
+
options: VectorizeOptions,
|
|
231
|
+
) => Promise<VectorizeResult>;
|
|
232
|
+
|
|
233
|
+
export interface SlopcameraVisualOperationDependencies {
|
|
234
|
+
readonly checkDiagram?: DiagramCheck;
|
|
235
|
+
readonly hostResourceCoordinator?: HostResourceCoordinator;
|
|
236
|
+
readonly renderDiagram?: DiagramRender;
|
|
237
|
+
readonly vectorize?: ImageVectorize;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function mediaRequest(
|
|
241
|
+
input: z.infer<typeof SlopcameraMediaInputRequestSchema>,
|
|
242
|
+
): z.infer<typeof MediaArtifactRequestSchema> {
|
|
243
|
+
return typeof input === "string" ? { path: input } : input;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export async function bindSlopcameraVisualOperationInput(
|
|
247
|
+
application: ApplicationContext,
|
|
248
|
+
kind: SlopcameraVisualFileOperationKind,
|
|
249
|
+
inputValue: unknown,
|
|
250
|
+
signal: AbortSignal = new AbortController().signal,
|
|
251
|
+
): Promise<
|
|
252
|
+
| BoundSlopcameraDiagramCheckInput
|
|
253
|
+
| BoundSlopcameraDiagramRenderInput
|
|
254
|
+
| BoundSlopcameraImageVectorizeInput
|
|
255
|
+
> {
|
|
256
|
+
switch (kind) {
|
|
257
|
+
case "slopcamera.diagram.check": {
|
|
258
|
+
const input = SlopcameraDiagramCheckInputSchema.parse(inputValue);
|
|
259
|
+
const source = await bindRepositoryMedia(
|
|
260
|
+
application,
|
|
261
|
+
mediaRequest(input.path),
|
|
262
|
+
signal,
|
|
263
|
+
MAXIMUM_DIAGRAM_SOURCE_BYTES,
|
|
264
|
+
);
|
|
265
|
+
return BoundSlopcameraDiagramCheckInputSchema.parse({
|
|
266
|
+
...input,
|
|
267
|
+
path: source.artifact,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
case "slopcamera.diagram.render": {
|
|
271
|
+
const input = SlopcameraDiagramRenderInputSchema.parse(inputValue);
|
|
272
|
+
const source = await bindRepositoryMedia(
|
|
273
|
+
application,
|
|
274
|
+
mediaRequest(input.path),
|
|
275
|
+
signal,
|
|
276
|
+
MAXIMUM_DIAGRAM_SOURCE_BYTES,
|
|
277
|
+
);
|
|
278
|
+
return BoundSlopcameraDiagramRenderInputSchema.parse({
|
|
279
|
+
...input,
|
|
280
|
+
path: source.artifact,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
case "slopcamera.image.vectorize": {
|
|
284
|
+
const input = SlopcameraImageVectorizeInputSchema.parse(inputValue);
|
|
285
|
+
const source = await bindRepositoryMedia(
|
|
286
|
+
application,
|
|
287
|
+
mediaRequest(input.inputPath),
|
|
288
|
+
signal,
|
|
289
|
+
MAXIMUM_MEDIA_EFFECT_INPUT_BYTES,
|
|
290
|
+
);
|
|
291
|
+
return BoundSlopcameraImageVectorizeInputSchema.parse({
|
|
292
|
+
...input,
|
|
293
|
+
inputPath: source.artifact,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function operationFailure(label: string, error: unknown): never {
|
|
300
|
+
if (error instanceof ApplicationError) throw error;
|
|
301
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
302
|
+
throw new ApplicationError(
|
|
303
|
+
"invalid-data",
|
|
304
|
+
`${label}: ${detail.slice(0, 1_024)}`,
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
async function publishDiagramArtifacts(
|
|
309
|
+
context: OperationExecutionContext,
|
|
310
|
+
artifacts: Awaited<ReturnType<DiagramRender>>["artifacts"],
|
|
311
|
+
): Promise<Readonly<{
|
|
312
|
+
artifacts: z.infer<typeof SlopcameraDiagramArtifactsSchema>;
|
|
313
|
+
created: z.infer<typeof SlopcameraDiagramRenderOutputSchema>["created"];
|
|
314
|
+
}>> {
|
|
315
|
+
const published: Partial<Record<keyof z.infer<typeof SlopcameraDiagramArtifactsSchema>, MediaArtifactReference>> = {};
|
|
316
|
+
const created: Partial<Record<keyof z.infer<typeof SlopcameraDiagramArtifactsSchema>, boolean>> = {};
|
|
317
|
+
const entries = [
|
|
318
|
+
["darkPng", artifacts.darkPng, ".png"],
|
|
319
|
+
["darkSvg", artifacts.darkSvg, ".svg"],
|
|
320
|
+
["lightPng", artifacts.lightPng, ".png"],
|
|
321
|
+
["lightSvg", artifacts.lightSvg, ".svg"],
|
|
322
|
+
["tldr", artifacts.tldr, ".tldr"],
|
|
323
|
+
] as const;
|
|
324
|
+
for (const [key, stagedPath, extension] of entries) {
|
|
325
|
+
const result = await publishContentAddressedMedia({
|
|
326
|
+
context,
|
|
327
|
+
extension,
|
|
328
|
+
maximumBytes: MAXIMUM_DIAGRAM_ARTIFACT_BYTES,
|
|
329
|
+
stagedPath,
|
|
330
|
+
});
|
|
331
|
+
published[key] = result.artifact;
|
|
332
|
+
created[key] = result.created;
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
artifacts: SlopcameraDiagramArtifactsSchema.parse(published),
|
|
336
|
+
created: SlopcameraDiagramRenderOutputSchema.shape.created.parse(created),
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function defaultCheckDiagram(
|
|
341
|
+
path: string,
|
|
342
|
+
application: ApplicationContext,
|
|
343
|
+
hostResourceCoordinator?: HostResourceCoordinator,
|
|
344
|
+
): ReturnType<DiagramCheck> {
|
|
345
|
+
const lease = application.hostResourceLease;
|
|
346
|
+
return lease === undefined
|
|
347
|
+
? executeSlopcameraOperation("slopcamera.diagram.check", { path }, {
|
|
348
|
+
...(hostResourceCoordinator === undefined
|
|
349
|
+
? {}
|
|
350
|
+
: { hostResourceCoordinator }),
|
|
351
|
+
})
|
|
352
|
+
: executeSlopcameraOperationWithLease(
|
|
353
|
+
"slopcamera.diagram.check",
|
|
354
|
+
{ path },
|
|
355
|
+
lease,
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function defaultRenderDiagram(
|
|
360
|
+
input: Parameters<DiagramRender>[0],
|
|
361
|
+
application: ApplicationContext,
|
|
362
|
+
hostResourceCoordinator?: HostResourceCoordinator,
|
|
363
|
+
): ReturnType<DiagramRender> {
|
|
364
|
+
const lease = application.hostResourceLease;
|
|
365
|
+
return lease === undefined
|
|
366
|
+
? executeSlopcameraOperation("slopcamera.diagram.render", input, {
|
|
367
|
+
...(hostResourceCoordinator === undefined
|
|
368
|
+
? {}
|
|
369
|
+
: { hostResourceCoordinator }),
|
|
370
|
+
})
|
|
371
|
+
: executeSlopcameraOperationWithLease(
|
|
372
|
+
"slopcamera.diagram.render",
|
|
373
|
+
input,
|
|
374
|
+
lease,
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
async function writeDiagramInputSnapshot(
|
|
379
|
+
directory: string,
|
|
380
|
+
source: Uint8Array,
|
|
381
|
+
): Promise<string> {
|
|
382
|
+
const path = join(
|
|
383
|
+
directory,
|
|
384
|
+
`.diagram-source-${randomUUID()}.json`,
|
|
385
|
+
);
|
|
386
|
+
const handle = await open(
|
|
387
|
+
path,
|
|
388
|
+
constants.O_CREAT
|
|
389
|
+
| constants.O_EXCL
|
|
390
|
+
| constants.O_WRONLY
|
|
391
|
+
| (constants.O_NOFOLLOW ?? 0),
|
|
392
|
+
0o600,
|
|
393
|
+
);
|
|
394
|
+
try {
|
|
395
|
+
await handle.writeFile(source);
|
|
396
|
+
await handle.sync();
|
|
397
|
+
await handle.close();
|
|
398
|
+
return path;
|
|
399
|
+
} catch (error) {
|
|
400
|
+
await handle.close().catch(() => undefined);
|
|
401
|
+
await rm(path, { force: true }).catch(() => undefined);
|
|
402
|
+
throw error;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export function createSlopcameraDiagramCheckOperationDefinition(
|
|
407
|
+
dependencies: SlopcameraVisualOperationDependencies = {},
|
|
408
|
+
): OperationDefinition<
|
|
409
|
+
"slopcamera.diagram.check",
|
|
410
|
+
SlopcameraDiagramCheckInput,
|
|
411
|
+
SlopcameraDiagramCheckOutput
|
|
412
|
+
> {
|
|
413
|
+
const check = dependencies.checkDiagram;
|
|
414
|
+
return {
|
|
415
|
+
inputSchema: SlopcameraDiagramCheckInputSchema,
|
|
416
|
+
inputSchemaId: "slopcamera.operation.diagram.check.input/v1",
|
|
417
|
+
kind: "slopcamera.diagram.check",
|
|
418
|
+
lifecycle: {
|
|
419
|
+
kind: "pure",
|
|
420
|
+
execute: async (context, input) => {
|
|
421
|
+
throwIfAborted(context.abortSignal);
|
|
422
|
+
const parsedInput = SlopcameraDiagramCheckInputSchema.parse(input);
|
|
423
|
+
const source = await loadRepositoryMedia(
|
|
424
|
+
context.application,
|
|
425
|
+
mediaRequest(parsedInput.path),
|
|
426
|
+
context.abortSignal,
|
|
427
|
+
MAXIMUM_DIAGRAM_SOURCE_BYTES,
|
|
428
|
+
);
|
|
429
|
+
const workspace = await createMediaOperationWorkspace(context);
|
|
430
|
+
let snapshotPath: string | undefined;
|
|
431
|
+
try {
|
|
432
|
+
snapshotPath = await writeDiagramInputSnapshot(
|
|
433
|
+
workspace.path,
|
|
434
|
+
source.data,
|
|
435
|
+
);
|
|
436
|
+
throwIfAborted(context.abortSignal);
|
|
437
|
+
const checked = await (check === undefined
|
|
438
|
+
? defaultCheckDiagram(
|
|
439
|
+
snapshotPath,
|
|
440
|
+
context.application,
|
|
441
|
+
dependencies.hostResourceCoordinator,
|
|
442
|
+
)
|
|
443
|
+
: check(snapshotPath));
|
|
444
|
+
throwIfAborted(context.abortSignal);
|
|
445
|
+
await bindRepositoryMedia(
|
|
446
|
+
context.application,
|
|
447
|
+
source.artifact,
|
|
448
|
+
context.abortSignal,
|
|
449
|
+
MAXIMUM_DIAGRAM_SOURCE_BYTES,
|
|
450
|
+
);
|
|
451
|
+
return SlopcameraDiagramCheckOutputSchema.parse({
|
|
452
|
+
findings: checked.findings,
|
|
453
|
+
source: source.artifact,
|
|
454
|
+
});
|
|
455
|
+
} catch (error) {
|
|
456
|
+
return operationFailure("Diagram check failed", error);
|
|
457
|
+
} finally {
|
|
458
|
+
if (snapshotPath !== undefined) {
|
|
459
|
+
await rm(snapshotPath, { force: true }).catch(() => undefined);
|
|
460
|
+
}
|
|
461
|
+
await workspace.dispose();
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
},
|
|
465
|
+
outputSchema: SlopcameraDiagramCheckOutputSchema,
|
|
466
|
+
outputSchemaId: "slopcamera.operation.diagram.check.output/v1",
|
|
467
|
+
policy: {
|
|
468
|
+
cache: "content-addressed",
|
|
469
|
+
cancellable: false,
|
|
470
|
+
effect: "local-read",
|
|
471
|
+
maxDurationMs: 30_000,
|
|
472
|
+
maxFanOut: 0,
|
|
473
|
+
maxInputBytes: 4_096,
|
|
474
|
+
maxOutputBytes: 256 * 1024,
|
|
475
|
+
preparation: ["local-media"],
|
|
476
|
+
resources: [
|
|
477
|
+
{ amount: 1, resource: "cpu" },
|
|
478
|
+
{ amount: 1, resource: "local-io" },
|
|
479
|
+
],
|
|
480
|
+
resume: "deterministic",
|
|
481
|
+
},
|
|
482
|
+
summarize: output => ({
|
|
483
|
+
fields: {
|
|
484
|
+
findings: output.findings.length,
|
|
485
|
+
source: output.source.path,
|
|
486
|
+
sourceSha256: output.source.sha256,
|
|
487
|
+
},
|
|
488
|
+
kind: "slopcamera.diagram.check",
|
|
489
|
+
}),
|
|
490
|
+
version: 1,
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export function createSlopcameraDiagramRenderOperationDefinition(
|
|
495
|
+
dependencies: SlopcameraVisualOperationDependencies = {},
|
|
496
|
+
): OperationDefinition<
|
|
497
|
+
"slopcamera.diagram.render",
|
|
498
|
+
SlopcameraDiagramRenderInput,
|
|
499
|
+
SlopcameraDiagramRenderOutput
|
|
500
|
+
> {
|
|
501
|
+
const render = dependencies.renderDiagram;
|
|
502
|
+
return {
|
|
503
|
+
inputSchema: SlopcameraDiagramRenderInputSchema,
|
|
504
|
+
inputSchemaId: "slopcamera.operation.diagram.render.input/v1",
|
|
505
|
+
kind: "slopcamera.diagram.render",
|
|
506
|
+
lifecycle: {
|
|
507
|
+
kind: "local-artifact",
|
|
508
|
+
execute: async (context, input) => {
|
|
509
|
+
const parsedInput = SlopcameraDiagramRenderInputSchema.parse(input);
|
|
510
|
+
const source = await loadRepositoryMedia(
|
|
511
|
+
context.application,
|
|
512
|
+
mediaRequest(parsedInput.path),
|
|
513
|
+
context.abortSignal,
|
|
514
|
+
MAXIMUM_DIAGRAM_SOURCE_BYTES,
|
|
515
|
+
);
|
|
516
|
+
const boundInput = BoundSlopcameraDiagramRenderInputSchema.parse({
|
|
517
|
+
...parsedInput,
|
|
518
|
+
path: source.artifact,
|
|
519
|
+
});
|
|
520
|
+
const workspace = await createMediaOperationWorkspace(context);
|
|
521
|
+
let snapshotPath: string | undefined;
|
|
522
|
+
try {
|
|
523
|
+
snapshotPath = await writeDiagramInputSnapshot(
|
|
524
|
+
workspace.path,
|
|
525
|
+
source.data,
|
|
526
|
+
);
|
|
527
|
+
throwIfAborted(context.abortSignal);
|
|
528
|
+
const renderInput = {
|
|
529
|
+
outDirectory: join(workspace.path, "diagram"),
|
|
530
|
+
path: snapshotPath,
|
|
531
|
+
...(boundInput.scale === undefined ? {} : { scale: boundInput.scale }),
|
|
532
|
+
};
|
|
533
|
+
const rendered = await (render === undefined
|
|
534
|
+
? defaultRenderDiagram(
|
|
535
|
+
renderInput,
|
|
536
|
+
context.application,
|
|
537
|
+
dependencies.hostResourceCoordinator,
|
|
538
|
+
)
|
|
539
|
+
: render(renderInput));
|
|
540
|
+
throwIfAborted(context.abortSignal);
|
|
541
|
+
await bindRepositoryMedia(
|
|
542
|
+
context.application,
|
|
543
|
+
source.artifact,
|
|
544
|
+
context.abortSignal,
|
|
545
|
+
MAXIMUM_DIAGRAM_SOURCE_BYTES,
|
|
546
|
+
);
|
|
547
|
+
const published = await publishDiagramArtifacts(context, rendered.artifacts);
|
|
548
|
+
const receiptBody = SlopcameraDiagramRenderReceiptSchema.parse({
|
|
549
|
+
artifacts: published.artifacts,
|
|
550
|
+
createdAt: context.application.clock.now().toISOString(),
|
|
551
|
+
exactInputSha256: canonicalJsonSha256(boundInput),
|
|
552
|
+
findings: rendered.findings,
|
|
553
|
+
kind: "slopcamera.visual-artifact-receipt",
|
|
554
|
+
operation: "slopcamera.diagram.render",
|
|
555
|
+
scale: boundInput.scale ?? 2,
|
|
556
|
+
schemaVersion: 1,
|
|
557
|
+
source: source.artifact,
|
|
558
|
+
});
|
|
559
|
+
const receipt = await publishContentAddressedReceipt({
|
|
560
|
+
context,
|
|
561
|
+
receipt: receiptBody,
|
|
562
|
+
workspace,
|
|
563
|
+
});
|
|
564
|
+
const output = SlopcameraDiagramRenderOutputSchema.parse({
|
|
565
|
+
...published,
|
|
566
|
+
findings: rendered.findings,
|
|
567
|
+
receipt,
|
|
568
|
+
source: source.artifact,
|
|
569
|
+
});
|
|
570
|
+
await writeOperationCompletionCheckpoint(context, {
|
|
571
|
+
inputSchemaId: "slopcamera.operation.diagram.render.input/v1",
|
|
572
|
+
kind: "slopcamera.diagram.render",
|
|
573
|
+
outputSchemaId: "slopcamera.operation.diagram.render.output/v1",
|
|
574
|
+
version: 1,
|
|
575
|
+
}, output);
|
|
576
|
+
return output;
|
|
577
|
+
} catch (error) {
|
|
578
|
+
return operationFailure("Diagram render failed", error);
|
|
579
|
+
} finally {
|
|
580
|
+
if (snapshotPath !== undefined) {
|
|
581
|
+
await rm(snapshotPath, { force: true }).catch(() => undefined);
|
|
582
|
+
}
|
|
583
|
+
await workspace.dispose();
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
},
|
|
587
|
+
outputSchema: SlopcameraDiagramRenderOutputSchema,
|
|
588
|
+
outputSchemaId: "slopcamera.operation.diagram.render.output/v1",
|
|
589
|
+
policy: {
|
|
590
|
+
cache: "content-addressed",
|
|
591
|
+
cancellable: false,
|
|
592
|
+
effect: "local-derived-write",
|
|
593
|
+
maxDurationMs: 120_000,
|
|
594
|
+
maxFanOut: 5,
|
|
595
|
+
maxInputBytes: 4_096,
|
|
596
|
+
maxOutputBytes: 5 * MAXIMUM_DIAGRAM_ARTIFACT_BYTES,
|
|
597
|
+
preparation: ["local-media"],
|
|
598
|
+
resources: [
|
|
599
|
+
{ amount: 1, resource: "cpu" },
|
|
600
|
+
{ amount: 1, resource: "local-io" },
|
|
601
|
+
{ amount: 1, resource: "output-publication" },
|
|
602
|
+
],
|
|
603
|
+
resume: "verified-receipt",
|
|
604
|
+
},
|
|
605
|
+
receiptReference: output => output.receipt.path,
|
|
606
|
+
summarize: output => ({
|
|
607
|
+
fields: {
|
|
608
|
+
darkPng: output.artifacts.darkPng.path,
|
|
609
|
+
findings: output.findings.length,
|
|
610
|
+
lightPng: output.artifacts.lightPng.path,
|
|
611
|
+
receipt: output.receipt.path,
|
|
612
|
+
sourceSha256: output.source.sha256,
|
|
613
|
+
},
|
|
614
|
+
kind: "slopcamera.diagram.render",
|
|
615
|
+
}),
|
|
616
|
+
version: 1,
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
export function createSlopcameraImageVectorizeOperationDefinition(
|
|
621
|
+
dependencies: SlopcameraVisualOperationDependencies = {},
|
|
622
|
+
): OperationDefinition<
|
|
623
|
+
"slopcamera.image.vectorize",
|
|
624
|
+
SlopcameraImageVectorizeInput,
|
|
625
|
+
SlopcameraImageVectorizeOutput
|
|
626
|
+
> {
|
|
627
|
+
const vectorize = dependencies.vectorize ?? vectorizeImage;
|
|
628
|
+
return {
|
|
629
|
+
inputSchema: SlopcameraImageVectorizeInputSchema,
|
|
630
|
+
inputSchemaId: "slopcamera.operation.image.vectorize.input/v1",
|
|
631
|
+
kind: "slopcamera.image.vectorize",
|
|
632
|
+
lifecycle: {
|
|
633
|
+
kind: "local-artifact",
|
|
634
|
+
execute: async (context, input) => {
|
|
635
|
+
const parsedInput = SlopcameraImageVectorizeInputSchema.parse(input);
|
|
636
|
+
const source = await bindRepositoryMedia(
|
|
637
|
+
context.application,
|
|
638
|
+
mediaRequest(parsedInput.inputPath),
|
|
639
|
+
context.abortSignal,
|
|
640
|
+
MAXIMUM_MEDIA_EFFECT_INPUT_BYTES,
|
|
641
|
+
);
|
|
642
|
+
const boundInput = BoundSlopcameraImageVectorizeInputSchema.parse({
|
|
643
|
+
...parsedInput,
|
|
644
|
+
inputPath: source.artifact,
|
|
645
|
+
});
|
|
646
|
+
const workspace = await createMediaOperationWorkspace(context);
|
|
647
|
+
const stagedPath = join(workspace.path, "vectorized.svg");
|
|
648
|
+
try {
|
|
649
|
+
await context.application.hostResourceLease?.assertOwned();
|
|
650
|
+
const result = await vectorize(source.absolutePath, {
|
|
651
|
+
cacheDirectory: join(context.application.paths.privateRoot, "vectorize-tool-cache-v1"),
|
|
652
|
+
...(context.application.hostResourceLease === undefined
|
|
653
|
+
? {}
|
|
654
|
+
: {
|
|
655
|
+
inheritedFileDescriptors:
|
|
656
|
+
context.application.hostResourceLease.inheritedFileDescriptors,
|
|
657
|
+
}),
|
|
658
|
+
outputPath: stagedPath,
|
|
659
|
+
...(boundInput.alphaCutoff === undefined
|
|
660
|
+
? {}
|
|
661
|
+
: { alphaCutoff: boundInput.alphaCutoff }),
|
|
662
|
+
...(boundInput.duotone === undefined
|
|
663
|
+
? {}
|
|
664
|
+
: { duotone: boundInput.duotone }),
|
|
665
|
+
...(boundInput.timeoutMs === undefined
|
|
666
|
+
? {}
|
|
667
|
+
: { limits: { maxDurationMs: boundInput.timeoutMs } }),
|
|
668
|
+
});
|
|
669
|
+
if (result.outputPath !== stagedPath) {
|
|
670
|
+
throw new ApplicationError(
|
|
671
|
+
"invalid-data",
|
|
672
|
+
"Vectorization did not publish its exact staged output.",
|
|
673
|
+
);
|
|
674
|
+
}
|
|
675
|
+
const vectorizer = VectorizeReceiptSchema.parse(result.receipt);
|
|
676
|
+
if (
|
|
677
|
+
vectorizer.sourceSha256 !== source.artifact.sha256
|
|
678
|
+
|| vectorizer.inputBytes !== source.artifact.bytes
|
|
679
|
+
) {
|
|
680
|
+
throw new ApplicationError(
|
|
681
|
+
"conflict",
|
|
682
|
+
"Vectorizer receipt source hash or byte length does not match the bound raster input.",
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
const expectedOutputMode = boundInput.duotone === undefined
|
|
686
|
+
? "color"
|
|
687
|
+
: "duotone";
|
|
688
|
+
if (vectorizer.outputMode !== expectedOutputMode) {
|
|
689
|
+
throw new ApplicationError(
|
|
690
|
+
"conflict",
|
|
691
|
+
"Vectorizer receipt output mode does not match the exact color request.",
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
const published = await publishContentAddressedMedia({
|
|
695
|
+
context,
|
|
696
|
+
extension: ".svg",
|
|
697
|
+
maximumBytes: MAXIMUM_VECTOR_ARTIFACT_BYTES,
|
|
698
|
+
stagedPath,
|
|
699
|
+
});
|
|
700
|
+
if (
|
|
701
|
+
vectorizer.svgSha256 !== published.artifact.sha256
|
|
702
|
+
|| vectorizer.bytes !== published.artifact.bytes
|
|
703
|
+
) {
|
|
704
|
+
throw new ApplicationError(
|
|
705
|
+
"conflict",
|
|
706
|
+
"Vectorizer receipt SVG hash or byte length does not match the staged output.",
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
const receiptBody = SlopcameraImageVectorizeReceiptSchema.parse({
|
|
710
|
+
artifact: published.artifact,
|
|
711
|
+
createdAt: context.application.clock.now().toISOString(),
|
|
712
|
+
exactInputSha256: canonicalJsonSha256(boundInput),
|
|
713
|
+
kind: "slopcamera.visual-artifact-receipt",
|
|
714
|
+
operation: "slopcamera.image.vectorize",
|
|
715
|
+
schemaVersion: 1,
|
|
716
|
+
source: source.artifact,
|
|
717
|
+
vectorizer,
|
|
718
|
+
});
|
|
719
|
+
const receipt = await publishContentAddressedReceipt({
|
|
720
|
+
context,
|
|
721
|
+
receipt: receiptBody,
|
|
722
|
+
workspace,
|
|
723
|
+
});
|
|
724
|
+
const output = SlopcameraImageVectorizeOutputSchema.parse({
|
|
725
|
+
artifact: published.artifact,
|
|
726
|
+
created: published.created,
|
|
727
|
+
receipt,
|
|
728
|
+
source: source.artifact,
|
|
729
|
+
vectorizer,
|
|
730
|
+
});
|
|
731
|
+
await writeOperationCompletionCheckpoint(context, {
|
|
732
|
+
inputSchemaId: "slopcamera.operation.image.vectorize.input/v1",
|
|
733
|
+
kind: "slopcamera.image.vectorize",
|
|
734
|
+
outputSchemaId: "slopcamera.operation.image.vectorize.output/v1",
|
|
735
|
+
version: 1,
|
|
736
|
+
}, output);
|
|
737
|
+
return output;
|
|
738
|
+
} catch (error) {
|
|
739
|
+
return operationFailure("Image vectorization failed", error);
|
|
740
|
+
} finally {
|
|
741
|
+
await workspace.dispose();
|
|
742
|
+
}
|
|
743
|
+
},
|
|
744
|
+
},
|
|
745
|
+
outputSchema: SlopcameraImageVectorizeOutputSchema,
|
|
746
|
+
outputSchemaId: "slopcamera.operation.image.vectorize.output/v1",
|
|
747
|
+
policy: {
|
|
748
|
+
cache: "content-addressed",
|
|
749
|
+
cancellable: false,
|
|
750
|
+
effect: "local-derived-write",
|
|
751
|
+
maxDurationMs: 300_000,
|
|
752
|
+
maxFanOut: 1,
|
|
753
|
+
maxInputBytes: 8_192,
|
|
754
|
+
maxOutputBytes: MAXIMUM_VECTOR_ARTIFACT_BYTES,
|
|
755
|
+
preparation: ["local-media"],
|
|
756
|
+
resources: [
|
|
757
|
+
{ amount: 1, resource: "cpu" },
|
|
758
|
+
{ amount: 1, resource: "local-io" },
|
|
759
|
+
{ amount: 1, resource: "output-publication" },
|
|
760
|
+
],
|
|
761
|
+
resume: "verified-receipt",
|
|
762
|
+
},
|
|
763
|
+
receiptReference: output => output.receipt.path,
|
|
764
|
+
summarize: output => ({
|
|
765
|
+
fields: {
|
|
766
|
+
bytes: output.artifact.bytes,
|
|
767
|
+
created: output.created,
|
|
768
|
+
paths: output.vectorizer.pathCount,
|
|
769
|
+
receipt: output.receipt.path,
|
|
770
|
+
sha256: output.artifact.sha256,
|
|
771
|
+
sourceSha256: output.source.sha256,
|
|
772
|
+
},
|
|
773
|
+
kind: "slopcamera.image.vectorize",
|
|
774
|
+
}),
|
|
775
|
+
version: 1,
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
export const slopcameraDiagramCheckOperationDefinition =
|
|
780
|
+
createSlopcameraDiagramCheckOperationDefinition();
|
|
781
|
+
export const slopcameraDiagramRenderOperationDefinition =
|
|
782
|
+
createSlopcameraDiagramRenderOperationDefinition();
|
|
783
|
+
export const slopcameraImageVectorizeOperationDefinition =
|
|
784
|
+
createSlopcameraImageVectorizeOperationDefinition();
|