@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.
Files changed (441) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +60 -0
  3. package/PRIVACY.md +46 -0
  4. package/README.md +311 -0
  5. package/SECURITY.md +21 -0
  6. package/apps/desktop/README.md +966 -0
  7. package/apps/desktop/analysis/protocol.ts +223 -0
  8. package/apps/desktop/application/capability-binding.ts +594 -0
  9. package/apps/desktop/application/context.ts +97 -0
  10. package/apps/desktop/application/creative-iteration.ts +1385 -0
  11. package/apps/desktop/application/default-registry.ts +146 -0
  12. package/apps/desktop/application/directing-contract.ts +218 -0
  13. package/apps/desktop/application/directing-plan.ts +178 -0
  14. package/apps/desktop/application/errors.ts +18 -0
  15. package/apps/desktop/application/gateway-port.ts +867 -0
  16. package/apps/desktop/application/html-overlay-browser-runtime.ts +687 -0
  17. package/apps/desktop/application/html-overlay-integrity.ts +337 -0
  18. package/apps/desktop/application/html-overlay-renderer.ts +45 -0
  19. package/apps/desktop/application/index.ts +13 -0
  20. package/apps/desktop/application/operation-completion-checkpoint.ts +333 -0
  21. package/apps/desktop/application/operation-effects.ts +94 -0
  22. package/apps/desktop/application/operation.ts +224 -0
  23. package/apps/desktop/application/operations/analysis/faces.ts +244 -0
  24. package/apps/desktop/application/operations/analysis/music.ts +248 -0
  25. package/apps/desktop/application/operations/analysis/project-auto-zooms.ts +302 -0
  26. package/apps/desktop/application/operations/analysis/project-inactivity.ts +381 -0
  27. package/apps/desktop/application/operations/analysis/scenes.ts +272 -0
  28. package/apps/desktop/application/operations/analysis/shared.ts +202 -0
  29. package/apps/desktop/application/operations/derive/edit-batch.ts +967 -0
  30. package/apps/desktop/application/operations/derive/follow-faces.ts +454 -0
  31. package/apps/desktop/application/operations/edit/bind-candidate-revision.ts +91 -0
  32. package/apps/desktop/application/operations/edit/create-candidate-revision.ts +377 -0
  33. package/apps/desktop/application/operations/edit/create-revision.ts +255 -0
  34. package/apps/desktop/application/operations/edit/freeze-revision.ts +182 -0
  35. package/apps/desktop/application/operations/gateway/image.ts +41 -0
  36. package/apps/desktop/application/operations/gateway/index.ts +17 -0
  37. package/apps/desktop/application/operations/gateway/shared.ts +122 -0
  38. package/apps/desktop/application/operations/gateway/speech.ts +41 -0
  39. package/apps/desktop/application/operations/gateway/transcription.ts +42 -0
  40. package/apps/desktop/application/operations/gateway/video.ts +41 -0
  41. package/apps/desktop/application/operations/index.ts +31 -0
  42. package/apps/desktop/application/operations/iteration/create-candidate.ts +240 -0
  43. package/apps/desktop/application/operations/iteration/create-matrix.ts +117 -0
  44. package/apps/desktop/application/operations/iteration/select.ts +155 -0
  45. package/apps/desktop/application/operations/iteration/shared.ts +250 -0
  46. package/apps/desktop/application/operations/media/audio-effects.ts +376 -0
  47. package/apps/desktop/application/operations/media/binding.ts +79 -0
  48. package/apps/desktop/application/operations/media/capabilities.ts +112 -0
  49. package/apps/desktop/application/operations/media/color-grade.ts +343 -0
  50. package/apps/desktop/application/operations/media/html-overlay.ts +802 -0
  51. package/apps/desktop/application/operations/media/index.ts +8 -0
  52. package/apps/desktop/application/operations/media/ingest.ts +303 -0
  53. package/apps/desktop/application/operations/media/overlay.ts +729 -0
  54. package/apps/desktop/application/operations/media/shared.ts +845 -0
  55. package/apps/desktop/application/operations/media/transform-platform.ts +120 -0
  56. package/apps/desktop/application/operations/project/commit-edits.ts +2054 -0
  57. package/apps/desktop/application/operations/project/promote-selection.ts +495 -0
  58. package/apps/desktop/application/operations/project/snapshot.ts +95 -0
  59. package/apps/desktop/application/operations/recording/index.ts +5 -0
  60. package/apps/desktop/application/operations/recording/pause.ts +34 -0
  61. package/apps/desktop/application/operations/recording/resume.ts +34 -0
  62. package/apps/desktop/application/operations/recording/shared.ts +199 -0
  63. package/apps/desktop/application/operations/recording/start.ts +169 -0
  64. package/apps/desktop/application/operations/recording/stop.ts +34 -0
  65. package/apps/desktop/application/operations/render/bind-candidate-output.ts +324 -0
  66. package/apps/desktop/application/operations/render/materialize-selection.ts +322 -0
  67. package/apps/desktop/application/operations/render/project-caption-plan.ts +287 -0
  68. package/apps/desktop/application/operations/render/project-plan.ts +939 -0
  69. package/apps/desktop/application/operations/render/project-spatial-receipt.ts +70 -0
  70. package/apps/desktop/application/operations/render/project.ts +1922 -0
  71. package/apps/desktop/application/operations/shared.ts +67 -0
  72. package/apps/desktop/application/operations/slopcamera-portable.ts +1188 -0
  73. package/apps/desktop/application/operations/slopcamera-visuals.ts +784 -0
  74. package/apps/desktop/application/operations/spatial-project.ts +209 -0
  75. package/apps/desktop/application/operations/spatial-render.ts +415 -0
  76. package/apps/desktop/application/operations/spatial-scene.ts +97 -0
  77. package/apps/desktop/application/operations/studio.ts +143 -0
  78. package/apps/desktop/application/output-publication-lease.ts +163 -0
  79. package/apps/desktop/application/project-publication-lease.ts +233 -0
  80. package/apps/desktop/application/project-store.ts +196 -0
  81. package/apps/desktop/application/receipts.ts +533 -0
  82. package/apps/desktop/application/registry.ts +182 -0
  83. package/apps/desktop/application/spatial-assets.ts +675 -0
  84. package/apps/desktop/application/spatial-compositor-cadence.ts +23 -0
  85. package/apps/desktop/application/spatial-project-authority.ts +35 -0
  86. package/apps/desktop/application/spatial-project-lease.ts +126 -0
  87. package/apps/desktop/application/spatial-project-render-preparation.ts +225 -0
  88. package/apps/desktop/application/spatial-project-store.ts +286 -0
  89. package/apps/desktop/application/spatial-render-projection.ts +201 -0
  90. package/apps/desktop/application/spatial-render.ts +677 -0
  91. package/apps/desktop/application/spatial-spz.ts +44 -0
  92. package/apps/desktop/application/spatial-world-import.ts +135 -0
  93. package/apps/desktop/application/spatial-world-provenance.ts +46 -0
  94. package/apps/desktop/application/studio-port.ts +58 -0
  95. package/apps/desktop/application/verified-receipt-reconciliation.ts +1574 -0
  96. package/apps/desktop/capture/protocol.ts +689 -0
  97. package/apps/desktop/cli/analyzer.ts +406 -0
  98. package/apps/desktop/cli/args.ts +3181 -0
  99. package/apps/desktop/cli/asset-ingest.ts +747 -0
  100. package/apps/desktop/cli/atomic-render-effects.ts +210 -0
  101. package/apps/desktop/cli/atomic-render-platform.ts +205 -0
  102. package/apps/desktop/cli/atomic-render.ts +50 -0
  103. package/apps/desktop/cli/audio-analysis.ts +252 -0
  104. package/apps/desktop/cli/bounded-map.ts +39 -0
  105. package/apps/desktop/cli/bundle-service.ts +256 -0
  106. package/apps/desktop/cli/capabilities.ts +212 -0
  107. package/apps/desktop/cli/capture-bundle.ts +1117 -0
  108. package/apps/desktop/cli/command-host-resources.ts +251 -0
  109. package/apps/desktop/cli/commands.ts +6836 -0
  110. package/apps/desktop/cli/directing-blob.ts +291 -0
  111. package/apps/desktop/cli/directing-media.ts +517 -0
  112. package/apps/desktop/cli/directing-quote.ts +89 -0
  113. package/apps/desktop/cli/directing-service.ts +288 -0
  114. package/apps/desktop/cli/emoji-assets.ts +538 -0
  115. package/apps/desktop/cli/errors.ts +29 -0
  116. package/apps/desktop/cli/face-analysis-service.ts +940 -0
  117. package/apps/desktop/cli/filter-script.ts +76 -0
  118. package/apps/desktop/cli/gateway-application-port.ts +1142 -0
  119. package/apps/desktop/cli/gateway-credential.ts +81 -0
  120. package/apps/desktop/cli/gateway-media-artifacts.ts +723 -0
  121. package/apps/desktop/cli/gateway-media-catalog.ts +922 -0
  122. package/apps/desktop/cli/gateway-media-service.ts +3106 -0
  123. package/apps/desktop/cli/gateway-media-signature.ts +122 -0
  124. package/apps/desktop/cli/gateway-provider-options.ts +562 -0
  125. package/apps/desktop/cli/gateway-scene-provider.ts +391 -0
  126. package/apps/desktop/cli/help.ts +501 -0
  127. package/apps/desktop/cli/html-overlay-gpu.ts +97 -0
  128. package/apps/desktop/cli/html-overlay-renderer.ts +2478 -0
  129. package/apps/desktop/cli/io.ts +290 -0
  130. package/apps/desktop/cli/main.ts +123 -0
  131. package/apps/desktop/cli/media-effects-service.ts +885 -0
  132. package/apps/desktop/cli/media-ingest-model.ts +364 -0
  133. package/apps/desktop/cli/media-ingest-platform.ts +227 -0
  134. package/apps/desktop/cli/media-ingest-program.ts +200 -0
  135. package/apps/desktop/cli/media-ingest.ts +30 -0
  136. package/apps/desktop/cli/music-analysis-service.ts +434 -0
  137. package/apps/desktop/cli/mutation-lock.ts +530 -0
  138. package/apps/desktop/cli/native-assets.d.ts +12 -0
  139. package/apps/desktop/cli/native-media-runtime.macos.ts +7 -0
  140. package/apps/desktop/cli/overlay-playback.ts +177 -0
  141. package/apps/desktop/cli/paths.ts +265 -0
  142. package/apps/desktop/cli/portable-surface.ts +242 -0
  143. package/apps/desktop/cli/project-camera-receipt.ts +112 -0
  144. package/apps/desktop/cli/project-face-camera.ts +394 -0
  145. package/apps/desktop/cli/project-inactivity-service.ts +552 -0
  146. package/apps/desktop/cli/project-media-integrity.ts +121 -0
  147. package/apps/desktop/cli/project-renderer.ts +1526 -0
  148. package/apps/desktop/cli/project-service.ts +519 -0
  149. package/apps/desktop/cli/project-state-transaction.ts +520 -0
  150. package/apps/desktop/cli/query-limits.ts +1 -0
  151. package/apps/desktop/cli/recording-controller.ts +1567 -0
  152. package/apps/desktop/cli/recording-daemon.ts +931 -0
  153. package/apps/desktop/cli/recording-ref.ts +56 -0
  154. package/apps/desktop/cli/renamed-environment.ts +6 -0
  155. package/apps/desktop/cli/renderer.ts +1439 -0
  156. package/apps/desktop/cli/run-cli-test-helper.ts +60 -0
  157. package/apps/desktop/cli/scene-analysis-service.ts +879 -0
  158. package/apps/desktop/cli/spatial-compositor-verifier.ts +213 -0
  159. package/apps/desktop/cli/spatial-project-service.ts +90 -0
  160. package/apps/desktop/cli/spatial-scene-service.ts +105 -0
  161. package/apps/desktop/cli/spatial-world-service.ts +39 -0
  162. package/apps/desktop/cli/speech-analysis-service.ts +682 -0
  163. package/apps/desktop/cli/studio-assemble.ts +58 -0
  164. package/apps/desktop/cli/studio-command.ts +60 -0
  165. package/apps/desktop/cli/studio-custody.ts +60 -0
  166. package/apps/desktop/cli/studio-encode.ts +216 -0
  167. package/apps/desktop/cli/studio-exr.ts +52 -0
  168. package/apps/desktop/cli/studio-files.ts +179 -0
  169. package/apps/desktop/cli/studio-output-validation.ts +162 -0
  170. package/apps/desktop/cli/studio-process.ts +145 -0
  171. package/apps/desktop/cli/studio-runtime.ts +77 -0
  172. package/apps/desktop/cli/studio-scaffold.ts +70 -0
  173. package/apps/desktop/cli/studio-service.ts +301 -0
  174. package/apps/desktop/cli/studio-spatial-asset.ts +248 -0
  175. package/apps/desktop/cli/studio-template-names.ts +3 -0
  176. package/apps/desktop/cli/studio-workflow.ts +19 -0
  177. package/apps/desktop/cli/time.ts +25 -0
  178. package/apps/desktop/cli/workflow-code.ts +584 -0
  179. package/apps/desktop/cli/workflow-runs.ts +576 -0
  180. package/apps/desktop/code/advanced.ts +139 -0
  181. package/apps/desktop/code/application-node-planner.ts +1288 -0
  182. package/apps/desktop/code/compiler.ts +329 -0
  183. package/apps/desktop/code/contracts.ts +13 -0
  184. package/apps/desktop/code/creative-recipes.ts +94 -0
  185. package/apps/desktop/code/define-workflow.ts +115 -0
  186. package/apps/desktop/code/editing.ts +284 -0
  187. package/apps/desktop/code/file-candidate-provenance.ts +420 -0
  188. package/apps/desktop/code/file-candidate.ts +69 -0
  189. package/apps/desktop/code/graph-builder.ts +10 -0
  190. package/apps/desktop/code/host-resource-policy.ts +55 -0
  191. package/apps/desktop/code/plan-contracts.ts +159 -0
  192. package/apps/desktop/code/planning.ts +361 -0
  193. package/apps/desktop/code/public.ts +134 -0
  194. package/apps/desktop/code/reference-projection.ts +62 -0
  195. package/apps/desktop/code/run-contracts.ts +466 -0
  196. package/apps/desktop/code/run-store.ts +2478 -0
  197. package/apps/desktop/code/runtime-identity.ts +328 -0
  198. package/apps/desktop/code/scheduler.ts +3067 -0
  199. package/apps/desktop/code/semantic-builder.ts +1436 -0
  200. package/apps/desktop/code/source-bundle.ts +1641 -0
  201. package/apps/desktop/code/source-typecheck.ts +211 -0
  202. package/apps/desktop/code/testing.ts +79 -0
  203. package/apps/desktop/code/worker-client.ts +1675 -0
  204. package/apps/desktop/code/worker-effects.ts +141 -0
  205. package/apps/desktop/code/worker-entry.ts +435 -0
  206. package/apps/desktop/code/worker-lease-guardian.ts +179 -0
  207. package/apps/desktop/code/worker-process-identity.ts +484 -0
  208. package/apps/desktop/code/worker-protocol.ts +211 -0
  209. package/apps/desktop/code/workflow-effects.ts +132 -0
  210. package/apps/desktop/contracts/analysis.ts +949 -0
  211. package/apps/desktop/contracts/edit.ts +576 -0
  212. package/apps/desktop/contracts/index.ts +9 -0
  213. package/apps/desktop/contracts/media-effects.ts +139 -0
  214. package/apps/desktop/contracts/project-render.ts +644 -0
  215. package/apps/desktop/contracts/project.ts +740 -0
  216. package/apps/desktop/contracts/recording.ts +1434 -0
  217. package/apps/desktop/contracts/render.ts +334 -0
  218. package/apps/desktop/contracts/runtime.ts +155 -0
  219. package/apps/desktop/contracts/spatial-compositor.ts +58 -0
  220. package/apps/desktop/contracts/spatial-project.ts +159 -0
  221. package/apps/desktop/contracts/spatial-world.ts +48 -0
  222. package/apps/desktop/contracts/video-effects.ts +120 -0
  223. package/apps/desktop/core/alignment-apply.ts +400 -0
  224. package/apps/desktop/core/audio-alignment.ts +466 -0
  225. package/apps/desktop/core/auto-zoom.ts +209 -0
  226. package/apps/desktop/core/canonical-json.ts +14 -0
  227. package/apps/desktop/core/emoji.ts +210 -0
  228. package/apps/desktop/core/events.ts +409 -0
  229. package/apps/desktop/core/face-framing.ts +533 -0
  230. package/apps/desktop/core/face-tracks.ts +326 -0
  231. package/apps/desktop/core/inactivity.ts +137 -0
  232. package/apps/desktop/core/index.ts +30 -0
  233. package/apps/desktop/core/intervals.ts +123 -0
  234. package/apps/desktop/core/montage.ts +236 -0
  235. package/apps/desktop/core/music-analysis.ts +518 -0
  236. package/apps/desktop/core/plan.ts +244 -0
  237. package/apps/desktop/core/project-auto-zoom.ts +75 -0
  238. package/apps/desktop/core/project-camera-spatial.ts +676 -0
  239. package/apps/desktop/core/project-camera.ts +403 -0
  240. package/apps/desktop/core/project-captions.ts +888 -0
  241. package/apps/desktop/core/project-inactivity.ts +125 -0
  242. package/apps/desktop/core/project-metadata.ts +927 -0
  243. package/apps/desktop/core/project-plan.ts +375 -0
  244. package/apps/desktop/core/project-render-plan.ts +303 -0
  245. package/apps/desktop/core/project-time.ts +469 -0
  246. package/apps/desktop/core/render-plan.ts +442 -0
  247. package/apps/desktop/core/scene-cache.ts +174 -0
  248. package/apps/desktop/core/scene-sampling.ts +448 -0
  249. package/apps/desktop/core/spatial-compositor.ts +22 -0
  250. package/apps/desktop/core/spatial-durability.ts +99 -0
  251. package/apps/desktop/core/spatial-project.ts +169 -0
  252. package/apps/desktop/core/spatial-shot-clock.ts +32 -0
  253. package/apps/desktop/core/speech-analysis.ts +333 -0
  254. package/apps/desktop/core/storage.ts +970 -0
  255. package/apps/desktop/core/time-map.ts +91 -0
  256. package/apps/desktop/core/time.ts +61 -0
  257. package/apps/desktop/core/video-effects.ts +660 -0
  258. package/apps/desktop/dist/cli/NebulaSans-Bold-26se8aek.otf +0 -0
  259. package/apps/desktop/dist/cli/NebulaSans-Bold-bcz7y08t.woff2 +0 -0
  260. package/apps/desktop/dist/cli/NebulaSans-Book-5ax05zvn.woff2 +0 -0
  261. package/apps/desktop/dist/cli/NebulaSans-Book-8cenzchw.otf +0 -0
  262. package/apps/desktop/dist/cli/main.js +5086 -0
  263. package/apps/desktop/html-overlay/catalog.ts +171 -0
  264. package/apps/desktop/html-overlay/contracts.ts +372 -0
  265. package/apps/desktop/html-overlay/execution-profile.ts +77 -0
  266. package/apps/desktop/html-overlay/index.ts +98 -0
  267. package/apps/desktop/html-overlay/libraries.ts +263 -0
  268. package/apps/desktop/html-overlay/random.ts +49 -0
  269. package/apps/desktop/html-overlay/runtime.ts +813 -0
  270. package/apps/desktop/html-overlay/scaffolds.ts +792 -0
  271. package/apps/desktop/html-overlay/spark-runtime.ts +88 -0
  272. package/apps/desktop/html-overlay/spatial-splat-runtime.ts +60 -0
  273. package/apps/desktop/html-overlay/spatial.ts +720 -0
  274. package/apps/desktop/studio/assets/README.md +39 -0
  275. package/apps/desktop/studio/assets/contracts.ts +129 -0
  276. package/apps/desktop/studio/assets/network.ts +64 -0
  277. package/apps/desktop/studio/assets/poly-haven.ts +148 -0
  278. package/apps/desktop/studio/drivers/blender_driver.py +466 -0
  279. package/apps/desktop/studio/drivers/cadquery_driver.py +176 -0
  280. package/apps/desktop/studio/education/driver.py +308 -0
  281. package/apps/desktop/studio/education/lesson.py +180 -0
  282. package/apps/desktop/studio/education/toolkit.py +249 -0
  283. package/apps/desktop/workflows/chaptered-demo.ts +48 -0
  284. package/apps/desktop/workflows/creative-iteration.ts +107 -0
  285. package/apps/desktop/workflows/creative-selection.ts +92 -0
  286. package/apps/desktop/workflows/fragments.ts +486 -0
  287. package/apps/desktop/workflows/index.ts +93 -0
  288. package/apps/desktop/workflows/polished-screen-demo.ts +128 -0
  289. package/apps/desktop/workflows/scene-direction.ts +12 -0
  290. package/apps/desktop/workflows/social-variants.ts +75 -0
  291. package/apps/desktop/workflows/talking-head-cleanup.ts +53 -0
  292. package/dist/NebulaSans-Bold-26se8aek.otf +0 -0
  293. package/dist/NebulaSans-Bold-bcz7y08t.woff2 +0 -0
  294. package/dist/NebulaSans-Book-5ax05zvn.woff2 +0 -0
  295. package/dist/NebulaSans-Book-8cenzchw.otf +0 -0
  296. package/dist/cli.js +479 -0
  297. package/dist/code/advanced.js +270 -0
  298. package/dist/code/index.js +2240 -0
  299. package/dist/generate.js +24 -0
  300. package/dist/host-resources.js +26 -0
  301. package/dist/index-42zsesc1.js +2257 -0
  302. package/dist/index-7308egqr.js +48 -0
  303. package/dist/index-8txs6fkn.js +712 -0
  304. package/dist/index-mcy8z0br.js +192 -0
  305. package/dist/index-p63wavx0.js +2029 -0
  306. package/dist/index-r7gdhmsp.js +424 -0
  307. package/dist/index-sh6xbav6.js +1219 -0
  308. package/dist/index-z1w83f81.js +4 -0
  309. package/dist/index-z7239b4h.js +2363 -0
  310. package/dist/index-zfeg9hmw.js +2013 -0
  311. package/dist/index.js +241 -0
  312. package/dist/operations.js +29 -0
  313. package/dist/skill-install-dh0ntqba.js +10 -0
  314. package/dist/vectorize/worker.js +142 -0
  315. package/dist/workflow.js +16 -0
  316. package/docs/README.md +38 -0
  317. package/docs/studio.md +215 -0
  318. package/examples/studio/blender/README.md +26 -0
  319. package/examples/studio/blender/character.py +152 -0
  320. package/examples/studio/blender/cloth.py +101 -0
  321. package/examples/studio/blender/color_chart.py +29 -0
  322. package/examples/studio/blender/fluid.py +78 -0
  323. package/examples/studio/blender/import_model.py +74 -0
  324. package/examples/studio/blender/product.py +53 -0
  325. package/examples/studio/blender/shaded_street.py +481 -0
  326. package/examples/studio/blender/studio_scene.py +147 -0
  327. package/examples/studio/cadquery/README.md +13 -0
  328. package/examples/studio/cadquery/bracket.py +36 -0
  329. package/examples/studio/cadquery/import_step.py +12 -0
  330. package/examples/studio/education/README.md +46 -0
  331. package/examples/studio/education/lesson.json +99 -0
  332. package/examples/studio/education/scene.py +7 -0
  333. package/examples/studio/hybrid-scene.ts +96 -0
  334. package/examples/studio/native-workflow.ts +14 -0
  335. package/examples/studio/vgpu/README.md +64 -0
  336. package/examples/studio/vgpu/heat-field.mjs +290 -0
  337. package/package.json +304 -0
  338. package/packages/scene/src/index.ts +1 -0
  339. package/packages/scene/src/scene.ts +215 -0
  340. package/schema/diagram.schema.json +334 -0
  341. package/skills/slopcamera/SKILL.md +45 -0
  342. package/skills/slopcamera/agents/openai.yaml +4 -0
  343. package/skills/slopcamera/references/customization.md +77 -0
  344. package/skills/slopcamera/references/diagrams.md +153 -0
  345. package/skills/slopcamera/references/directed-scenes.md +42 -0
  346. package/skills/slopcamera/references/directing-video.md +18 -0
  347. package/skills/slopcamera/references/educational-video.md +26 -0
  348. package/skills/slopcamera/references/gateway-media.md +134 -0
  349. package/skills/slopcamera/references/install.md +62 -0
  350. package/skills/slopcamera/references/native-studio.md +31 -0
  351. package/skills/slopcamera/references/reference-led-3d.md +140 -0
  352. package/skills/slopcamera/references/rubber-stamp-examples/poster-example-1.jpg +0 -0
  353. package/skills/slopcamera/references/rubber-stamp-examples/poster-example-2.jpg +0 -0
  354. package/skills/slopcamera/references/rubber-stamp-examples/stamp-style-1.png +0 -0
  355. package/skills/slopcamera/references/rubber-stamp-examples/stamp-style-2.png +0 -0
  356. package/skills/slopcamera/references/rubber-stamp-field-notes.md +144 -0
  357. package/skills/slopcamera/references/vectorization.md +29 -0
  358. package/skills/slopcamera/references/video-projects.md +187 -0
  359. package/skills/slopcamera/references/visual-communication.md +120 -0
  360. package/skills/slopcamera/references/workflows-sdk.md +45 -0
  361. package/skills/slopcamera/scripts/compose-rubber-stamp-field-note.ts +229 -0
  362. package/src/artifacts.ts +106 -0
  363. package/src/assets/fonts/nebula-sans/LICENSE.txt +96 -0
  364. package/src/assets/fonts/nebula-sans/NebulaSans-Bold.otf +0 -0
  365. package/src/assets/fonts/nebula-sans/NebulaSans-Bold.woff2 +0 -0
  366. package/src/assets/fonts/nebula-sans/NebulaSans-Book.otf +0 -0
  367. package/src/assets/fonts/nebula-sans/NebulaSans-Book.woff2 +0 -0
  368. package/src/assets/fonts/nebula-sans/PROVENANCE.md +21 -0
  369. package/src/assets.d.ts +9 -0
  370. package/src/cli.ts +601 -0
  371. package/src/cloud-errors.ts +26 -0
  372. package/src/code/advanced.ts +10 -0
  373. package/src/code/boundary.ts +21 -0
  374. package/src/code/canonical-json.ts +129 -0
  375. package/src/code/compiler.ts +953 -0
  376. package/src/code/contracts.ts +576 -0
  377. package/src/code/define-workflow.ts +334 -0
  378. package/src/code/errors.ts +41 -0
  379. package/src/code/graph-builder.ts +945 -0
  380. package/src/code/index.ts +121 -0
  381. package/src/code/json-snapshot.ts +899 -0
  382. package/src/code/json-utf8.ts +88 -0
  383. package/src/code/portable-builder.ts +136 -0
  384. package/src/code/projection.ts +378 -0
  385. package/src/code/public-operations.ts +450 -0
  386. package/src/code/runtime.ts +580 -0
  387. package/src/code/sha256.ts +36 -0
  388. package/src/config.ts +180 -0
  389. package/src/desktop.ts +253 -0
  390. package/src/fs.ts +10 -0
  391. package/src/generate.ts +704 -0
  392. package/src/host-resource-posix.ts +161 -0
  393. package/src/host-resources.ts +1749 -0
  394. package/src/icons.ts +58 -0
  395. package/src/index.ts +200 -0
  396. package/src/label-layout.ts +130 -0
  397. package/src/layout.ts +413 -0
  398. package/src/lint.ts +127 -0
  399. package/src/mcp/boundary.ts +354 -0
  400. package/src/mcp/index.ts +33 -0
  401. package/src/mcp/server.ts +272 -0
  402. package/src/mcp/tools.ts +963 -0
  403. package/src/mcp/types.ts +71 -0
  404. package/src/operations.ts +775 -0
  405. package/src/parse.ts +861 -0
  406. package/src/process-environment.ts +17 -0
  407. package/src/render.ts +437 -0
  408. package/src/skill-install.ts +49 -0
  409. package/src/spatial-scene/authoring.ts +27 -0
  410. package/src/spatial-scene/camera-track.ts +83 -0
  411. package/src/spatial-scene/contracts.ts +277 -0
  412. package/src/spatial-scene/evaluate.ts +145 -0
  413. package/src/spatial-scene/gltf.ts +558 -0
  414. package/src/spatial-scene/identity.ts +260 -0
  415. package/src/spatial-scene/index.ts +10 -0
  416. package/src/spatial-scene/inspect.ts +68 -0
  417. package/src/spatial-scene/math.ts +280 -0
  418. package/src/spatial-scene/patch.ts +131 -0
  419. package/src/spatial-scene/time.ts +53 -0
  420. package/src/studio/contracts.ts +129 -0
  421. package/src/studio/index.ts +2 -0
  422. package/src/studio/plan.ts +156 -0
  423. package/src/studio/shared.ts +41 -0
  424. package/src/theme.ts +68 -0
  425. package/src/tldr.ts +474 -0
  426. package/src/types.ts +212 -0
  427. package/src/vectorize/archive.ts +101 -0
  428. package/src/vectorize/command.ts +797 -0
  429. package/src/vectorize/index.ts +27 -0
  430. package/src/vectorize/limits.ts +61 -0
  431. package/src/vectorize/metrics.ts +351 -0
  432. package/src/vectorize/pixels.ts +323 -0
  433. package/src/vectorize/supervisor.ts +339 -0
  434. package/src/vectorize/svg.ts +188 -0
  435. package/src/vectorize/tool.ts +542 -0
  436. package/src/vectorize/types.ts +113 -0
  437. package/src/vectorize/vectorize.ts +634 -0
  438. package/src/vectorize/worker-protocol.ts +40 -0
  439. package/src/vectorize/worker.ts +209 -0
  440. package/src/version.ts +1 -0
  441. package/src/workflow.ts +409 -0
@@ -0,0 +1,23 @@
1
+ import { createBoundedJsonValueSnapshot } from "../../../src/code/json-snapshot";
2
+ import { spatialFrameCount } from "../../../src/spatial-scene/time";
3
+ import { ProjectRenderPlanV1Schema } from "../contracts/project-render";
4
+ import { canonicalJsonSha256 } from "../core/canonical-json";
5
+ import { assertSpatialCompositorCadence, spatialCompositorCadenceSha256 } from "../core/spatial-compositor";
6
+ import { SceneRenderProjectionV1Schema } from "./spatial-render-projection";
7
+
8
+ /** Bind a verified projection to its exact V1 plan without rewriting either document. */
9
+ export function createSpatialCompositorCadence(input: { readonly projection: unknown; readonly projectionSha256: string; readonly plan: unknown }) {
10
+ const projection = SceneRenderProjectionV1Schema.parse(createBoundedJsonValueSnapshot(input.projection, 16 * 1024 * 1024, "spatial render projection", { maximumDepth: 48, maximumValues: 1_000_000 }).value);
11
+ const plan = ProjectRenderPlanV1Schema.parse(createBoundedJsonValueSnapshot(input.plan, 64 * 1024 * 1024, "spatial composition plan", { maximumDepth: 48, maximumValues: 2_000_000 }).value);
12
+ if (canonicalJsonSha256({ domain: "slopcamera.scene-render-projection/v1", projection }) !== input.projectionSha256) throw new Error("Spatial render projection digest mismatch.");
13
+ if (projection.compositionPlanSha256 !== plan.planSha256
14
+ || projection.output.pixelWidth !== plan.output.pixelWidth || projection.output.pixelHeight !== plan.output.pixelHeight
15
+ || projection.output.background !== plan.output.background) throw new Error("Spatial projection output does not match its composition plan.");
16
+ const cadence = {
17
+ kind: "slopcamera.spatial-compositor-cadence" as const, schemaVersion: 1 as const,
18
+ projectionSha256: input.projectionSha256, compositionPlanSha256: plan.planSha256,
19
+ frameRate: projection.output.frameRate, durationUs: plan.output.durationUs,
20
+ frameCount: spatialFrameCount(plan.output.durationUs, projection.output.frameRate),
21
+ };
22
+ return assertSpatialCompositorCadence({ cadence, cadenceSha256: spatialCompositorCadenceSha256(cadence) }, plan);
23
+ }
@@ -0,0 +1,35 @@
1
+ import { basename, resolve } from "node:path";
2
+
3
+ import { VideoProjectIdSchema } from "../contracts/project";
4
+ import { createNodeSpatialDurability } from "../core/spatial-durability";
5
+ import { createNodeBundleFileSystem } from "../core/storage";
6
+ import type { ApplicationContext } from "./context";
7
+ import { ApplicationError } from "./errors";
8
+ import type { SpatialProjectStorePorts } from "./spatial-project-store";
9
+
10
+ /**
11
+ * Binds the fixed operation input to an adapter-owned, already-held lease.
12
+ * Directory resolution and lease acquisition belong to the caller. Neither
13
+ * serialized paths nor operation input can grant publication authority.
14
+ */
15
+ export async function spatialProjectStorePorts(
16
+ application: ApplicationContext,
17
+ projectInput: string,
18
+ ): Promise<SpatialProjectStorePorts> {
19
+ const projectId = VideoProjectIdSchema.parse(projectInput);
20
+ const custody = application.spatialProjectCustody;
21
+ if (custody === undefined) throw new ApplicationError("conflict", "Spatial project access requires an existing publication lease.");
22
+ if (custody.projectId !== projectId || basename(resolve(custody.projectDirectory)) !== projectId) {
23
+ throw new ApplicationError("conflict", "Spatial project input does not match its adapter-owned directory and lease.");
24
+ }
25
+ await custody.assertHeld();
26
+ return {
27
+ projectId,
28
+ fileSystem: createNodeBundleFileSystem(custody.projectDirectory),
29
+ durability: createNodeSpatialDurability(custody.projectDirectory),
30
+ custody: {
31
+ assertHeld: () => custody.assertHeld(),
32
+ assertLegacyTransactionSettled: () => custody.assertLegacyTransactionSettled(),
33
+ },
34
+ };
35
+ }
@@ -0,0 +1,126 @@
1
+ import type { ApplicationContext } from "./context";
2
+ import { ApplicationError } from "./errors";
3
+ import { createBoundedJsonValueSnapshot, deepFreezeJson } from "../../../src/code/json-snapshot";
4
+ import { SPATIAL_PROJECT_LIMITS, SpatialProjectHeadV2Schema } from "../contracts/spatial-project";
5
+ import { createNodeBundleFileSystem, type BundleFileSystem } from "../core/storage";
6
+ import { acquireMutationLease } from "../cli/mutation-lock";
7
+ import { assertProjectStateTransactionSettled, recoverProjectStateTransaction } from "../cli/project-state-transaction";
8
+ import { resolveProjectDirectory } from "../cli/project-service";
9
+
10
+ const queues = new Map<string, Promise<void>>();
11
+
12
+ /** Adapter-owned seams; never accepted in a serialized operation request. */
13
+ export interface SpatialProjectLeaseDependencies {
14
+ readonly fileSystem?: (directory: string) => BundleFileSystem;
15
+ readonly acquire?: typeof acquireMutationLease;
16
+ }
17
+
18
+ function spatialMarker(authority: unknown): boolean {
19
+ return typeof authority === "object" && authority !== null && !Array.isArray(authority)
20
+ && (("schemaVersion" in authority && authority.schemaVersion === 2)
21
+ || ("kind" in authority && authority.kind === "slopcamera.spatial-project-head"));
22
+ }
23
+
24
+ function completionEvidence(value: unknown): Readonly<Record<string, unknown>> {
25
+ try {
26
+ const completed = deepFreezeJson(createBoundedJsonValueSnapshot(value, SPATIAL_PROJECT_LIMITS.documentBytes,
27
+ "spatial lease completion", { maximumDepth: 48, maximumValues: 2_000_000 }).value);
28
+ const output = typeof completed === "object" && completed !== null && !Array.isArray(completed) && "output" in completed
29
+ ? completed.output : completed;
30
+ return { completed, ...(typeof output === "object" && output !== null && !Array.isArray(output)
31
+ && "kind" in output && output.kind === "completed" ? { spatialPublication: output } : {}) };
32
+ } catch {
33
+ // Generic read callers may return host values. Do not serialize handles,
34
+ // accessors or unbounded objects merely because lease cleanup failed.
35
+ return { completionUnavailable: "The completed host value is not bounded JSON." };
36
+ }
37
+ }
38
+
39
+ /** One existing physical lease for a V1 snapshot/migration or V2 transaction. */
40
+ export async function withSpatialProjectLease<T>(
41
+ application: ApplicationContext,
42
+ project: string,
43
+ execute: (leasedApplication: ApplicationContext) => Promise<T>,
44
+ beforeMutation?: () => Promise<void>,
45
+ access: "read" | "mutation" = "read",
46
+ dependencies: SpatialProjectLeaseDependencies = {},
47
+ ): Promise<T> {
48
+ if (application.spatialProjectCustody !== undefined) throw new ApplicationError("internal", "Spatial project custody cannot be nested.");
49
+ const directory = await resolveProjectDirectory(application.paths.projectRoot, project);
50
+ if (directory.id !== project) throw new ApplicationError("invalid-data", "Spatial operations require the exact project ID.");
51
+ const previous = queues.get(directory.path) ?? Promise.resolve();
52
+ const result = previous.then(async () => {
53
+ const fileSystem = (dependencies.fileSystem ?? createNodeBundleFileSystem)(directory.path);
54
+ const lease = await (dependencies.acquire ?? acquireMutationLease)(directory.path, {
55
+ command: "spatial.project", label: `project ${project}`, now: application.clock.now,
56
+ });
57
+ let active = true;
58
+ let completed: Readonly<Record<string, unknown>> | undefined, value: T | undefined, failed = false, failure: unknown;
59
+ const cleanupErrors: unknown[] = [];
60
+ const custody = {
61
+ projectDirectory: directory.path, projectId: directory.id,
62
+ assertHeld: async () => {
63
+ if (!active) throw new ApplicationError("conflict", "Spatial project lease already ended.");
64
+ await lease.assertOwned();
65
+ await application.hostResourceLease?.assertOwned();
66
+ await beforeMutation?.();
67
+ },
68
+ assertLegacyTransactionSettled: async () => {
69
+ await custody.assertHeld();
70
+ await assertProjectStateTransactionSettled(fileSystem);
71
+ await custody.assertHeld();
72
+ },
73
+ };
74
+ const readAuthority = async () => {
75
+ const authority: unknown = JSON.parse(await fileSystem.readText("project.json", SPATIAL_PROJECT_LIMITS.documentBytes));
76
+ if (typeof authority !== "object" || authority === null || !("projectId" in authority) || authority.projectId !== directory.id) {
77
+ throw new ApplicationError("conflict", "Project authority belongs to a different directory identity.");
78
+ }
79
+ return authority;
80
+ };
81
+ const recoveryFence = async () => {
82
+ await custody.assertHeld();
83
+ if (spatialMarker(await readAuthority())) throw new ApplicationError("unsupported-plan", "Legacy recovery cannot replace spatial V2 authority.");
84
+ await custody.assertHeld();
85
+ };
86
+ try {
87
+ await custody.assertHeld();
88
+ const authority = await readAuthority();
89
+ if (spatialMarker(authority)) SpatialProjectHeadV2Schema.parse(authority);
90
+ else if (access === "mutation") {
91
+ if (fileSystem.writeTextAtomicGuarded === undefined || fileSystem.writeTextNoReplace === undefined) {
92
+ throw new ApplicationError("unsupported-plan", "Spatial migration requires guarded legacy recovery storage.");
93
+ }
94
+ const recoveryFileSystem: BundleFileSystem = {
95
+ ...fileSystem,
96
+ writeTextAtomic: async (path, contents) => await fileSystem.writeTextAtomicGuarded!(path, contents, recoveryFence),
97
+ writeTextNoReplace: async (path, contents) => await fileSystem.writeTextNoReplace!(path, contents, recoveryFence),
98
+ };
99
+ await recoverProjectStateTransaction(recoveryFileSystem, directory.id);
100
+ } else await assertProjectStateTransactionSettled(fileSystem);
101
+ await custody.assertHeld();
102
+ value = await execute({ ...application, spatialProjectCustody: custody });
103
+ completed = completionEvidence(value);
104
+ } catch (error) { failed = true; failure = error; }
105
+ finally {
106
+ active = false;
107
+ try { await lease.close(); } catch (error) { cleanupErrors.push(error); }
108
+ try { await lease.unlinkIfOwned(); } catch (error) { cleanupErrors.push(error); }
109
+ }
110
+ if (cleanupErrors.length > 0) {
111
+ throw new ApplicationError(failure instanceof ApplicationError ? failure.code : "internal",
112
+ failed && failure instanceof Error ? failure.message : "Spatial project lease cleanup failed after execution.", {
113
+ ...(failure instanceof ApplicationError ? failure.details : {}),
114
+ ...completed,
115
+ spatialLeaseCleanup: cleanupErrors.map(error => error instanceof Error ? error.message : String(error)),
116
+ ...(failed ? { executionFailure: failure instanceof Error ? failure.message : String(failure) } : {}),
117
+ });
118
+ }
119
+ if (failed) throw failure;
120
+ return value as T;
121
+ });
122
+ const settled = result.then(() => undefined, () => undefined);
123
+ queues.set(directory.path, settled);
124
+ try { return await result; }
125
+ finally { if (queues.get(directory.path) === settled) queues.delete(directory.path); }
126
+ }
@@ -0,0 +1,225 @@
1
+ import { join, relative } from "node:path";
2
+
3
+ import { z } from "zod";
4
+
5
+ import { createBoundedJsonValueSnapshot, deepFreezeJson } from "../../../src/code/json-snapshot";
6
+ import { SpatialDigestSchema, SpatialTimeUsSchema } from "../../../src/spatial-scene/contracts";
7
+ import { reduceSpatialFrameRate, spatialFrameCount } from "../../../src/spatial-scene/index";
8
+ import { VideoProjectIdSchema } from "../contracts/project";
9
+ import { RepositoryRelativePathSchema } from "../contracts/recording";
10
+ import { SPATIAL_COMPOSITOR_LIMITS } from "../contracts/spatial-compositor";
11
+ import { SpatialProjectBasisSchema } from "../contracts/spatial-project";
12
+ import { canonicalJson, canonicalJsonSha256, sha256Hex } from "../core/canonical-json";
13
+ import { hashProjectStructure } from "../core/project-plan";
14
+ import { compileProjectRenderPlan } from "../core/project-render-plan";
15
+ import { createNodeSpatialDurability, type SpatialDurabilityPort } from "../core/spatial-durability";
16
+ import { spatialProjectDocumentText, spatialShotSha256 } from "../core/spatial-project";
17
+ import { createNodeBundleFileSystem, type BundleFileSystem } from "../core/storage";
18
+ import { exactCapabilityByName } from "./capability-binding";
19
+ import { ApplicationError } from "./errors";
20
+ import { bindHtmlOverlayBrowserRuntime } from "./html-overlay-browser-runtime";
21
+ import type { OperationExecutionContext } from "./operation";
22
+ import { bindExpectedMediaCapabilities } from "./operations/media/capabilities";
23
+ import { type MediaArtifactReference } from "./operations/media/shared";
24
+ import { bindProjectRenderPlanInput } from "./operations/render/project-plan";
25
+ import { ProjectRenderSpatialBindingV1Schema } from "./operations/render/project-spatial-receipt";
26
+ import { throwIfAborted } from "./operations/shared";
27
+ import { hashProjectGeneration } from "./project-store";
28
+ import { hashProjectEditRevisionOutputGeometry, ProjectRenderPlanDocumentSchema, ProjectRenderPlanReferenceSchema, RenderableProjectEditRevisionReferenceSchema } from "./receipts";
29
+ import { createSpatialCompositorCadence } from "./spatial-compositor-cadence";
30
+ import { spatialProjectStorePorts } from "./spatial-project-authority";
31
+ import { readSpatialProjectAuthority } from "./spatial-project-store";
32
+ import { planSpatialRender, renderSpatialScene, SpatialRenderOutputSchema, SpatialRenderReceiptSchema, spatialRenderCapabilityNames, spatialShotRenderRequest, type SpatialRenderDependencies, type SpatialRenderPlan } from "./spatial-render";
33
+ import { createSpatialRenderProjection, SceneRenderProjectionV1Schema, SpatialMaterializedShotVideoSchema, SpatialProjectionOutputSchema, SpatialSceneProgramPolicySchema, type SpatialMaterializedShotVideo } from "./spatial-render-projection";
34
+
35
+ /** Whole-program admission, before any browser starts. Staging is conservatively summed even though shots render sequentially. */
36
+ export const SPATIAL_PROJECT_RENDER_PREPARATION_LIMITS = Object.freeze({
37
+ shots: 64, frames: 1_800, pixels: 1_100_000_000, stagingBytes: 8 * 1024 ** 3,
38
+ retainedVideoBytes: 1024 ** 3, sourceDocumentBytes: 2 * 1024 ** 2, sourceDocumentsBytes: 32 * 1024 ** 2,
39
+ receiptBytes: 1024 ** 2, receiptsBytes: 16 * 1024 ** 2, outputDocumentBytes: 32 * 1024 ** 2,
40
+ });
41
+ const capture = (value: unknown, bytes: number, label: string) => createBoundedJsonValueSnapshot(value, bytes, label, { maximumDepth: 48, maximumValues: 1_000_000 }).value;
42
+ export const SpatialProjectRenderPreparationInputSchema = z.preprocess(value => capture(value, 64 * 1024, "spatial project render preparation input"), z.strictObject({
43
+ project: VideoProjectIdSchema, expected: SpatialProjectBasisSchema,
44
+ profile: SpatialProjectionOutputSchema, policy: SpatialSceneProgramPolicySchema,
45
+ }));
46
+ export const SpatialProjectRenderPreparationOutputSchema = z.preprocess(value => capture(value, SPATIAL_PROJECT_RENDER_PREPARATION_LIMITS.outputDocumentBytes, "spatial project render preparation output"), z.strictObject({
47
+ sourceBasis: SpatialProjectBasisSchema, projection: SceneRenderProjectionV1Schema, projectionSha256: SpatialDigestSchema,
48
+ materializedShots: z.array(SpatialMaterializedShotVideoSchema).max(SPATIAL_PROJECT_RENDER_PREPARATION_LIMITS.shots),
49
+ revisionReference: RenderableProjectEditRevisionReferenceSchema, plan: ProjectRenderPlanReferenceSchema, spatial: ProjectRenderSpatialBindingV1Schema,
50
+ }).superRefine((value, context) => {
51
+ if (value.sourceBasis.version !== 2 || value.sourceBasis.sha256 !== value.projection.source.projectRevisionSha256
52
+ || value.projectionSha256 !== value.spatial.projectionSha256 || canonicalJson(value.projection) !== canonicalJson(value.spatial.projection)
53
+ || canonicalJson(value.materializedShots) !== canonicalJson(value.projection.shots.map(shot => shot.materialized))
54
+ || value.plan.planSha256 !== value.projection.compositionPlanSha256 || value.plan.revisionSha256 !== value.revisionReference.revisionSha256
55
+ || value.revisionReference.revisionSha256 !== value.projection.derivedV1RevisionSha256
56
+ || canonicalJson(value.revisionReference.artifact) !== canonicalJson(value.projection.derivedV1Revision)
57
+ || value.plan.projectId !== value.projection.source.projectId || value.revisionReference.projectId !== value.plan.projectId) context.addIssue({ code: "custom", message: "Prepared render must preserve one exact source, projection, revision and plan identity." });
58
+ if (value.plan.projectSha256 !== value.revisionReference.projectSha256 || value.plan.projectEditPlanSha256 !== value.revisionReference.projectEditPlanSha256
59
+ || value.plan.outputGeometrySha256 !== value.revisionReference.outputGeometrySha256) context.addIssue({ code: "custom", message: "Prepared plan must retain the exact derived V1 project, edit plan and output geometry hashes." });
60
+ }));
61
+ export type SpatialProjectRenderPreparationInput = z.infer<typeof SpatialProjectRenderPreparationInputSchema>;
62
+ export type SpatialProjectRenderPreparationOutput = z.infer<typeof SpatialProjectRenderPreparationOutputSchema>;
63
+ /** Trusted host test seams only; neither ports nor renderer dependencies are accepted in the request. */
64
+ export interface SpatialProjectRenderPreparationDependencies {
65
+ readonly renderDependencies?: SpatialRenderDependencies;
66
+ readonly repositoryFileSystem?: BundleFileSystem;
67
+ readonly durability?: SpatialDurabilityPort;
68
+ }
69
+ function checked(condition: boolean, message: string): asserts condition {
70
+ if (!condition) throw new ApplicationError("conflict", message);
71
+ }
72
+ function failureMessages(error: unknown, depth = 0): string[] {
73
+ const message = (error instanceof Error ? error.message : String(error)).slice(0, 4_096);
74
+ return error instanceof AggregateError && depth < 4
75
+ ? [message, ...error.errors.slice(0, 16).flatMap(child => failureMessages(child, depth + 1))].slice(0, 32)
76
+ : [message];
77
+ }
78
+ function verifyReceipt(plan: SpatialRenderPlan, result: z.infer<typeof SpatialRenderOutputSchema>, receipt: z.infer<typeof SpatialRenderReceiptSchema>, original: MediaArtifactReference) {
79
+ checked(receipt.sceneSha256 === plan.sceneSha256 && receipt.requestSha256 === plan.requestSha256
80
+ && canonicalJson(receipt.request) === canonicalJson(plan.request) && canonicalJson(receipt.samples.map(sample => sample.sample)) === canonicalJson(plan.samples)
81
+ && canonicalJson(receipt.source.originalSceneArtifact) === canonicalJson(original)
82
+ && canonicalJson(receipt.source.canonicalScene) === canonicalJson(result.sceneSource)
83
+ && canonicalJson(receipt.source.retainedAssets) === canonicalJson(result.retainedAssets)
84
+ && canonicalJson(receipt.render) === canonicalJson(result.render) && canonicalJson(receipt.output) === canonicalJson(result.artifact)
85
+ && result.render.kind === "video" && result.render.frameCount === plan.samples.length
86
+ && result.render.width === plan.width && result.render.height === plan.height
87
+ && receipt.color.output === "srgb" && receipt.color.alpha === "straight"
88
+ && receipt.calibratedSourceDimensions.width === plan.width && receipt.calibratedSourceDimensions.height === plan.height,
89
+ "Rendered shot receipt does not bind its exact immutable source, request, samples and output.");
90
+ }
91
+
92
+ /** Materializes an immutable V2 camera program under caller-owned read custody. Never changes project.json or invents a workflow identity. */
93
+ export async function prepareSpatialProjectRender(context: OperationExecutionContext, input: unknown, dependencies: SpatialProjectRenderPreparationDependencies = {}): Promise<SpatialProjectRenderPreparationOutput> {
94
+ const request = SpatialProjectRenderPreparationInputSchema.parse(input);
95
+ if (request.expected.version !== 2 || request.policy.alpha !== "straight") throw new ApplicationError("unsupported-plan", "Spatial project preparation requires an exact V2 basis and the qualified straight-alpha qtrle profile.");
96
+ const ports = await spatialProjectStorePorts(context.application, request.project);
97
+ const projectDirectory = context.application.spatialProjectCustody!.projectDirectory;
98
+ const repositoryRoot = context.application.paths.repositoryRoot;
99
+ const repositoryFileSystem = dependencies.repositoryFileSystem ?? createNodeBundleFileSystem(repositoryRoot);
100
+ const durability = dependencies.durability ?? createNodeSpatialDurability(repositoryRoot);
101
+ const repositoryPath = (path: string) => RepositoryRelativePathSchema.parse(relative(repositoryRoot, join(projectDirectory, path)));
102
+ const fence = async () => { await ports.custody.assertHeld(); await context.application.hostResourceLease?.assertOwned(); throwIfAborted(context.abortSignal); };
103
+ const publicationFence = async () => { await context.workflow?.beforePublication(); await fence(); };
104
+ await fence();
105
+ const snapshot = await readSpatialProjectAuthority(ports);
106
+ checked(snapshot.version === 2 && canonicalJson(snapshot.basis) === canonicalJson(request.expected), "Spatial project render preparation requires the exact current V2 project basis.");
107
+ await fence();
108
+ const profile = { ...request.profile, frameRate: reduceSpatialFrameRate(request.profile.frameRate) };
109
+ const shots = [...snapshot.contents.shots].sort((a, b) => a.range.startUs - b.range.startUs || a.shotId.localeCompare(b.shotId));
110
+ const limits = SPATIAL_PROJECT_RENDER_PREPARATION_LIMITS;
111
+ const legacyPlan = snapshot.contents.legacy.projectEditPlan;
112
+ if (legacyPlan.zooms.length > 0 || legacyPlan.effects.clicks.enabled || legacyPlan.effects.cursor.enabled
113
+ || legacyPlan.effects.keystrokes.enabled || legacyPlan.effects.typedText.enabled) throw new ApplicationError("unsupported-plan",
114
+ "Spatial project preparation does not yet retain recording metadata required by zooms, clicks, cursor, keystrokes or typedText effects. These effects cannot be projected yet.");
115
+ // The final movie includes the whole frozen legacy timeline, even when its scene shots are tiny.
116
+ // Compile cuts, base speed, segment speeds, layouts and camera bindings before any native work.
117
+ const legacyRenderPlan = compileProjectRenderPlan(snapshot.contents.legacy.project, legacyPlan, {
118
+ background: profile.background, pixelWidth: profile.pixelWidth, pixelHeight: profile.pixelHeight,
119
+ frameRate: profile.frameRate.numerator / profile.frameRate.denominator,
120
+ });
121
+ checked(SpatialTimeUsSchema.safeParse(legacyRenderPlan.output.durationUs).success && legacyRenderPlan.output.durationUs > 0,
122
+ "Full project output duration exceeds spatial compositor cadence admission.");
123
+ checked(profile.frameRate.numerator <= 2_147_483_647 && profile.frameRate.denominator <= 2_147_483_647
124
+ && spatialFrameCount(legacyRenderPlan.output.durationUs, profile.frameRate) <= SPATIAL_COMPOSITOR_LIMITS.frames,
125
+ "Full project output exceeds the compositor frame or container cadence admission.");
126
+ checked(snapshot.revision.scenes.every(scene => scene.artifact.bytes <= limits.sourceDocumentBytes)
127
+ && snapshot.revision.scenes.reduce((bytes, scene) => bytes + scene.artifact.bytes, 0) <= limits.sourceDocumentsBytes,
128
+ "Retained scene documents exceed the spatial compositor admission budget.");
129
+ checked(shots.length <= limits.shots, "Spatial project exceeds the admitted total shot count.");
130
+ let previousEnd = 0;
131
+ const planned = shots.map(shot => {
132
+ checked(shot.range.startUs >= previousEnd, "Full-frame camera-program preparation rejects overlapping shot ranges."); previousEnd = shot.range.endUs;
133
+ const scene = snapshot.contents.scenes.find(source => source.sceneSha256 === shot.sceneSha256);
134
+ const source = snapshot.revision.scenes.find(source => source.sceneSha256 === shot.sceneSha256);
135
+ checked(scene !== undefined && source !== undefined && source.artifact.bytes <= limits.sourceDocumentBytes, "Shot source is absent or exceeds native source-document admission.");
136
+ const plan = planSpatialRender(scene.document, spatialShotRenderRequest(shot, profile.frameRate, profile.executionProfile));
137
+ checked(plan.width === profile.pixelWidth && plan.height === profile.pixelHeight, "Shot calibrated dimensions must match the requested profile; preparation does not resize cameras.");
138
+ return { shot, plan, original: { ...source.artifact, path: repositoryPath(source.artifact.path) } };
139
+ });
140
+ const sum = (value: (plan: SpatialRenderPlan) => number) => planned.reduce((total, item) => total + value(item.plan), 0);
141
+ checked(sum(plan => plan.samples.length) <= limits.frames && sum(plan => plan.costs.renderPixels) <= limits.pixels
142
+ && sum(plan => plan.costs.stagingBytesBound) <= limits.stagingBytes && sum(plan => plan.costs.outputBytesBound) <= limits.retainedVideoBytes,
143
+ "Spatial project exceeds aggregate frame, pixel, staging or retained-video admission.");
144
+ const published: MediaArtifactReference[] = [], materializedShots: SpatialMaterializedShotVideo[] = [];
145
+ let uncertainPublication: MediaArtifactReference | undefined, totalReceiptBytes = 0;
146
+ const copy = async (source: MediaArtifactReference, path: string) => {
147
+ checked(repositoryFileSystem.copyFileNoReplace !== undefined, "Repository storage requires immutable exact-copy publication.");
148
+ const destination = { ...source, path: repositoryPath(path) };
149
+ await publicationFence(); uncertainPublication = destination;
150
+ await repositoryFileSystem.copyFileNoReplace(source.path, destination.path, source, publicationFence);
151
+ await durability.syncExactFile(destination.path, destination);
152
+ published.push(destination); uncertainPublication = undefined;
153
+ };
154
+ try {
155
+ for (const { shot, plan, original } of planned) {
156
+ await fence();
157
+ const capabilityBindings = await bindExpectedMediaCapabilities(context.application, spatialRenderCapabilityNames(plan), undefined);
158
+ const browserRuntime = await (dependencies.renderDependencies?.bindBrowserRuntime ?? bindHtmlOverlayBrowserRuntime)(exactCapabilityByName(capabilityBindings, "html-browser"), context.abortSignal);
159
+ await fence();
160
+ const result = SpatialRenderOutputSchema.parse(capture(await renderSpatialScene(context, { scene: plan.scene, assetRoot: projectDirectory, request: plan.request, originalSceneArtifact: original, capabilityBindings, browserRuntime }, dependencies.renderDependencies), limits.outputDocumentBytes, "rendered spatial shot"));
161
+ // The service result remains useful evidence even if project-local installation subsequently fails.
162
+ published.push(result.artifact, result.receipt, result.sceneSource, ...result.retainedAssets.map(asset => asset.artifact));
163
+ totalReceiptBytes += result.receipt.bytes;
164
+ checked(result.receipt.bytes <= limits.receiptBytes && totalReceiptBytes <= limits.receiptsBytes, "Retained shot receipts exceed the spatial compositor admission budget.");
165
+ const receiptText = await repositoryFileSystem.readText(result.receipt.path, limits.receiptBytes);
166
+ checked(Buffer.byteLength(receiptText) === result.receipt.bytes && sha256Hex(receiptText) === result.receipt.sha256, "Spatial shot receipt bytes changed after rendering.");
167
+ const receipt = SpatialRenderReceiptSchema.parse(capture(JSON.parse(receiptText), limits.outputDocumentBytes, "spatial shot receipt"));
168
+ verifyReceipt(plan, result, receipt, original);
169
+ const encoded = result.render.encodedEvidence;
170
+ checked(encoded !== undefined && encoded.colorSpace === "srgb" && canonicalJson(encoded.frameRate) === canonicalJson(profile.frameRate), "Shot encoding must retain the exact rational rate and straight-alpha color profile.");
171
+ const artifact = { ...result.artifact, path: `spatial/outputs/${result.artifact.sha256}.mov` };
172
+ await copy(result.artifact, artifact.path);
173
+ await copy(result.receipt, `spatial/receipts/${result.receipt.sha256}.json`);
174
+ materializedShots.push(SpatialMaterializedShotVideoSchema.parse({ shotId: shot.shotId, shotSha256: spatialShotSha256(shot), sceneSha256: shot.sceneSha256,
175
+ receiptSha256: result.receipt.sha256, artifact, pixelWidth: plan.width, pixelHeight: plan.height, frameRate: encoded.frameRate,
176
+ frameCount: encoded.frameCount, alpha: encoded.alpha, colorSpace: encoded.colorSpace, codec: encoded.codec, container: encoded.container, streamIndex: encoded.streamIndex }));
177
+ }
178
+ const derived = createSpatialRenderProjection({ snapshot, materializedShots, policy: request.policy, output: profile });
179
+ checked(derived.renderPlan.output.durationUs === legacyRenderPlan.output.durationUs, "Spatial projection changed the preflighted legacy output clock.");
180
+ const revisionText = spatialProjectDocumentText(derived.revision);
181
+ const revisionArtifact = { ...derived.projection.derivedV1Revision, path: repositoryPath(derived.projection.derivedV1Revision.path) };
182
+ checked(repositoryFileSystem.writeTextNoReplace !== undefined, "Repository storage requires immutable revision publication.");
183
+ await publicationFence(); uncertainPublication = revisionArtifact;
184
+ await repositoryFileSystem.writeTextNoReplace(revisionArtifact.path, revisionText, publicationFence);
185
+ await durability.syncExactFile(revisionArtifact.path, revisionArtifact);
186
+ published.push(revisionArtifact); uncertainPublication = undefined;
187
+ const revisionReference = RenderableProjectEditRevisionReferenceSchema.parse({ kind: "slopcamera.project-edit-revision-reference", schemaVersion: 1,
188
+ artifact: derived.projection.derivedV1Revision, baseGeneration: hashProjectGeneration(derived.revision.project, derived.revision.projectEditPlan),
189
+ outputGeometrySha256: hashProjectEditRevisionOutputGeometry({ ...profile, revisionSha256: derived.revision.revisionSha256 }),
190
+ pixelWidth: profile.pixelWidth, pixelHeight: profile.pixelHeight, planId: derived.revision.projectEditPlan.planId, projectId: request.project,
191
+ projectEditPlanSha256: derived.revision.projectEditPlanSha256, projectSha256: derived.revision.projectSha256,
192
+ projectStructureSha256: hashProjectStructure(derived.revision.project), revisionSha256: derived.revision.revisionSha256 });
193
+ const planInput = await bindProjectRenderPlanInput(context.application, { revision: revisionReference, settings: { background: profile.background, frameRate: profile.frameRate.numerator / profile.frameRate.denominator } });
194
+ checked(planInput.metadataBindings?.length === 0, "Spatial projection cannot depend on mutable recording metadata.");
195
+ // Preserve the prospective immutable plan address across publication/readback failures.
196
+ const planDocument = ProjectRenderPlanDocumentSchema.parse({ kind: "slopcamera.project-render-plan-document", schemaVersion: 1, plan: derived.renderPlan,
197
+ outputGeometrySha256: revisionReference.outputGeometrySha256, projectEditPlanSha256: derived.revision.projectEditPlanSha256,
198
+ projectSha256: derived.revision.projectSha256, revisionSha256: derived.revision.revisionSha256, renderPlanSha256: canonicalJsonSha256(derived.renderPlan) });
199
+ const planText = spatialProjectDocumentText(planDocument), planSha = sha256Hex(planText);
200
+ await publicationFence(); uncertainPublication = { path: repositoryPath(`renders/plans/${planSha}.json`), sha256: planSha, bytes: Buffer.byteLength(planText) };
201
+ const plan = ProjectRenderPlanReferenceSchema.parse({ kind: "slopcamera.project-render-plan-reference", schemaVersion: 1,
202
+ artifact: { path: `renders/plans/${planSha}.json`, sha256: planSha, bytes: Buffer.byteLength(planText) },
203
+ projectId: request.project, outputGeometrySha256: revisionReference.outputGeometrySha256, planSha256: derived.renderPlan.planSha256,
204
+ projectEditPlanSha256: derived.revision.projectEditPlanSha256, projectSha256: derived.revision.projectSha256,
205
+ renderPlanSha256: planDocument.renderPlanSha256, revisionSha256: derived.revision.revisionSha256 });
206
+ await repositoryFileSystem.writeTextNoReplace(repositoryPath(plan.artifact.path), planText, publicationFence);
207
+ published.push({ ...plan.artifact, path: repositoryPath(plan.artifact.path) });
208
+ checked(plan.planSha256 === derived.projection.compositionPlanSha256 && plan.artifact.sha256 === planSha, "Immutable compositor planning differs from the exact spatial projection.");
209
+ await durability.syncExactFile(repositoryPath(plan.artifact.path), plan.artifact);
210
+ uncertainPublication = undefined;
211
+ await fence();
212
+ const current = await readSpatialProjectAuthority(ports);
213
+ checked(canonicalJson(current.basis) === canonicalJson(snapshot.basis), "Project authority changed during spatial render preparation; retained artifacts still describe the original snapshot.");
214
+ await fence();
215
+ const spatial = { projection: derived.projection, projectionSha256: derived.projectionSha256, cadence: createSpatialCompositorCadence({ ...derived, plan: derived.renderPlan }) };
216
+ return deepFreezeJson(SpatialProjectRenderPreparationOutputSchema.parse({ sourceBasis: snapshot.basis, projection: derived.projection, projectionSha256: derived.projectionSha256, materializedShots, revisionReference, plan, spatial }));
217
+ } catch (error) {
218
+ const failure = new ApplicationError(error instanceof ApplicationError ? error.code : "internal", error instanceof Error ? error.message : "Spatial project render preparation failed.", {
219
+ spatialProjectRenderPreparation: { sourceBasis: snapshot.basis, published, materializedShots, errors: failureMessages(error), ...(uncertainPublication === undefined ? {} : { uncertainPublication }),
220
+ ...(error instanceof ApplicationError ? { causeDetails: error.details } : {}) },
221
+ });
222
+ failure.cause = error;
223
+ throw failure;
224
+ }
225
+ }