@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,967 @@
1
+ import { z } from "zod";
2
+
3
+ import {
4
+ CameraMoveIdSchema,
5
+ ClickEffectSchema,
6
+ CursorEffectSchema,
7
+ EasingSchema,
8
+ KeystrokeEffectSchema,
9
+ OverlayIdSchema,
10
+ OverlayOperationSchema,
11
+ ProjectCameraTransformKeyframeSchema,
12
+ ProjectPlacementIdSchema,
13
+ ProjectStreamIdSchema,
14
+ ProjectZoomOperationSchema,
15
+ Sha256Schema,
16
+ SourceIntervalSchema,
17
+ TypedTextEffectSchema,
18
+ ZoomIdSchema,
19
+ ZoomTargetSchema,
20
+ } from "../../../contracts";
21
+ import { canonicalJsonSha256 } from "../../../core/canonical-json";
22
+ import type { OperationDefinition } from "../../operation";
23
+ import { throwIfAborted } from "../shared";
24
+
25
+ export const OrderedProjectEditSchema = z.discriminatedUnion("kind", [
26
+ z.strictObject({
27
+ kind: z.literal("cut"),
28
+ range: SourceIntervalSchema,
29
+ }),
30
+ z.strictObject({
31
+ kind: z.literal("trim"),
32
+ range: SourceIntervalSchema,
33
+ }),
34
+ z.strictObject({
35
+ kind: z.literal("speed"),
36
+ range: SourceIntervalSchema,
37
+ rate: z.number().finite().positive().max(64),
38
+ }),
39
+ z.strictObject({
40
+ kind: z.literal("add-zooms"),
41
+ zooms: z.array(ProjectZoomOperationSchema).min(1).max(10_000),
42
+ }),
43
+ z.strictObject({
44
+ kind: z.literal("add-overlays"),
45
+ overlays: z.array(OverlayOperationSchema).min(1).max(10_000),
46
+ }),
47
+ z.strictObject({
48
+ kind: z.literal("remove-overlays"),
49
+ overlayIds: z.array(OverlayIdSchema).min(1).max(10_000),
50
+ }),
51
+ ]).superRefine((edit, context) => {
52
+ if (
53
+ edit.kind === "add-overlays"
54
+ && new Set(edit.overlays.map(overlay => overlay.overlayId)).size
55
+ !== edit.overlays.length
56
+ ) {
57
+ context.addIssue({
58
+ code: "custom",
59
+ message: "One add-overlays edit cannot contain duplicate overlay IDs.",
60
+ path: ["overlays"],
61
+ });
62
+ }
63
+ if (
64
+ edit.kind === "remove-overlays"
65
+ && new Set(edit.overlayIds).size !== edit.overlayIds.length
66
+ ) {
67
+ context.addIssue({
68
+ code: "custom",
69
+ message: "One remove-overlays edit cannot contain duplicate overlay IDs.",
70
+ path: ["overlayIds"],
71
+ });
72
+ }
73
+ });
74
+
75
+ function refineOrderedOverlayTransitions(
76
+ ordered: readonly (
77
+ | {
78
+ readonly kind: "add-overlays";
79
+ readonly overlays: readonly { readonly overlayId: string }[];
80
+ }
81
+ | {
82
+ readonly kind: "remove-overlays";
83
+ readonly overlayIds: readonly string[];
84
+ }
85
+ )[],
86
+ context: z.RefinementCtx,
87
+ ): void {
88
+ const added = new Set<string>();
89
+ for (const [editIndex, edit] of ordered.entries()) {
90
+ if (edit.kind === "remove-overlays") {
91
+ for (const overlayId of edit.overlayIds) added.delete(overlayId);
92
+ continue;
93
+ }
94
+ if (edit.kind !== "add-overlays") continue;
95
+ for (const [overlayIndex, overlay] of edit.overlays.entries()) {
96
+ if (added.has(overlay.overlayId)) {
97
+ context.addIssue({
98
+ code: "custom",
99
+ message:
100
+ "An ordered edit batch cannot add the same overlay ID twice without removing it between additions.",
101
+ path: ["ordered", editIndex, "overlays", overlayIndex, "overlayId"],
102
+ });
103
+ }
104
+ added.add(overlay.overlayId);
105
+ }
106
+ }
107
+ }
108
+
109
+ export const ProjectEditBatchInputSchema = z.strictObject({
110
+ cutRanges: z.array(SourceIntervalSchema).max(10_000).optional(),
111
+ ordered: z.array(OrderedProjectEditSchema).max(10_000).optional(),
112
+ }).superRefine((input, context) => {
113
+ const total = (input.cutRanges?.length ?? 0) + (input.ordered?.reduce(
114
+ (sum, edit) => {
115
+ switch (edit.kind) {
116
+ case "add-zooms":
117
+ return sum + edit.zooms.length;
118
+ case "add-overlays":
119
+ return sum + edit.overlays.length;
120
+ case "remove-overlays":
121
+ return sum + edit.overlayIds.length;
122
+ case "cut":
123
+ case "speed":
124
+ case "trim":
125
+ return sum + 1;
126
+ default: {
127
+ const exhaustive: never = edit;
128
+ return exhaustive;
129
+ }
130
+ }
131
+ },
132
+ 0,
133
+ ) ?? 0);
134
+ if (total < 1) {
135
+ context.addIssue({
136
+ code: "custom",
137
+ message: "An edit batch requires at least one explicit edit or derived cut range.",
138
+ });
139
+ }
140
+ if (total > 10_000) {
141
+ context.addIssue({
142
+ code: "custom",
143
+ message: "An edit batch cannot expand beyond 10,000 ordered edits.",
144
+ });
145
+ }
146
+ refineOrderedOverlayTransitions(
147
+ (input.ordered ?? []).filter(edit => (
148
+ edit.kind === "add-overlays" || edit.kind === "remove-overlays"
149
+ )),
150
+ context,
151
+ );
152
+ });
153
+
154
+ const ProjectEditBatchBodySchema = z.strictObject({
155
+ kind: z.union([
156
+ z.literal("slopcamera.project-edit-batch"),
157
+ z.literal("studio.project-edit-batch"),
158
+ ]),
159
+ ordered: z.array(OrderedProjectEditSchema).min(1).max(10_000),
160
+ schemaVersion: z.literal(1),
161
+ });
162
+
163
+ export const ProjectEditBatchSchema = ProjectEditBatchBodySchema.extend({
164
+ sha256: Sha256Schema,
165
+ }).strict().superRefine((batch, context) => {
166
+ refineOrderedOverlayTransitions(
167
+ batch.ordered.filter(edit => (
168
+ edit.kind === "add-overlays" || edit.kind === "remove-overlays"
169
+ )),
170
+ context,
171
+ );
172
+ const actual = canonicalJsonSha256({
173
+ kind: batch.kind,
174
+ ordered: batch.ordered,
175
+ schemaVersion: batch.schemaVersion,
176
+ });
177
+ if (actual !== batch.sha256) {
178
+ context.addIssue({
179
+ code: "custom",
180
+ message: "Project edit batch hash does not match its ordered edit data.",
181
+ path: ["sha256"],
182
+ });
183
+ }
184
+ });
185
+
186
+ export type OrderedProjectEdit = z.infer<typeof OrderedProjectEditSchema>;
187
+ export type ProjectEditBatchInput = z.infer<typeof ProjectEditBatchInputSchema>;
188
+ export type ProjectEditBatch = z.infer<typeof ProjectEditBatchSchema>;
189
+
190
+ export function deriveProjectEditBatch(
191
+ orderedInput: readonly OrderedProjectEdit[],
192
+ ): ProjectEditBatch {
193
+ const body = ProjectEditBatchBodySchema.parse({
194
+ kind: "slopcamera.project-edit-batch",
195
+ ordered: orderedInput,
196
+ schemaVersion: 1,
197
+ });
198
+ return ProjectEditBatchSchema.parse({
199
+ ...body,
200
+ sha256: canonicalJsonSha256(body),
201
+ });
202
+ }
203
+
204
+ export const deriveEditBatchOperationDefinition = {
205
+ inputSchema: ProjectEditBatchInputSchema,
206
+ inputSchemaId: "slopcamera.operation.derive.edit-batch.input/v1",
207
+ kind: "derive.edit-batch",
208
+ lifecycle: {
209
+ kind: "pure",
210
+ execute: (context, input) => {
211
+ throwIfAborted(context.abortSignal);
212
+ return Promise.resolve(deriveProjectEditBatch([
213
+ ...(input.cutRanges ?? []).map(range => ({ kind: "cut" as const, range })),
214
+ ...(input.ordered ?? []),
215
+ ]));
216
+ },
217
+ },
218
+ outputSchema: ProjectEditBatchSchema,
219
+ outputSchemaId: "slopcamera.operation.derive.edit-batch.output/v1",
220
+ policy: {
221
+ cache: "content-addressed",
222
+ cancellable: true,
223
+ effect: "pure",
224
+ maxDurationMs: 5_000,
225
+ maxFanOut: 0,
226
+ maxInputBytes: 16 * 1024 * 1024,
227
+ maxOutputBytes: 16 * 1024 * 1024,
228
+ preparation: [],
229
+ resources: [{ amount: 1, resource: "cpu" }],
230
+ resume: "deterministic",
231
+ },
232
+ summarize: output => ({
233
+ fields: {
234
+ edits: output.ordered.length,
235
+ sha256: output.sha256,
236
+ },
237
+ kind: "derive.edit-batch",
238
+ }),
239
+ version: 1,
240
+ } satisfies OperationDefinition<
241
+ "derive.edit-batch",
242
+ ProjectEditBatchInput,
243
+ ProjectEditBatch
244
+ >;
245
+
246
+ export const ProjectMetadataEffectsInputV2Schema = z.strictObject({
247
+ clicks: ClickEffectSchema,
248
+ cursor: CursorEffectSchema,
249
+ keystrokes: KeystrokeEffectSchema,
250
+ metadataPlacementId: ProjectPlacementIdSchema.nullable(),
251
+ typedText: TypedTextEffectSchema,
252
+ }).superRefine((effects, context) => {
253
+ const enabled = effects.clicks.enabled
254
+ || effects.cursor.enabled
255
+ || effects.keystrokes.enabled
256
+ || effects.typedText.enabled;
257
+ if (enabled && effects.metadataPlacementId === null) {
258
+ context.addIssue({
259
+ code: "custom",
260
+ message: "Enabled metadata effects require a non-null metadata placement.",
261
+ path: ["metadataPlacementId"],
262
+ });
263
+ }
264
+ });
265
+
266
+ export const ManualProjectCameraMoveInputV2Schema = z.strictObject({
267
+ cameraMoveId: CameraMoveIdSchema,
268
+ keyframes: z.array(ProjectCameraTransformKeyframeSchema).min(2).max(4_096),
269
+ placementId: ProjectPlacementIdSchema,
270
+ projectRange: SourceIntervalSchema,
271
+ streamId: ProjectStreamIdSchema,
272
+ }).superRefine((move, context) => {
273
+ if (
274
+ move.keyframes[0]?.projectTimeUs !== move.projectRange.startUs
275
+ || move.keyframes.at(-1)?.projectTimeUs !== move.projectRange.endUs
276
+ ) {
277
+ context.addIssue({
278
+ code: "custom",
279
+ message: "Camera move keyframes must exactly match both project range endpoints.",
280
+ path: ["keyframes"],
281
+ });
282
+ }
283
+ for (let index = 1; index < move.keyframes.length; index += 1) {
284
+ if (
285
+ move.keyframes[index]!.projectTimeUs
286
+ <= move.keyframes[index - 1]!.projectTimeUs
287
+ ) {
288
+ context.addIssue({
289
+ code: "custom",
290
+ message: "Camera move keyframe project times must increase strictly.",
291
+ path: ["keyframes", index, "projectTimeUs"],
292
+ });
293
+ break;
294
+ }
295
+ }
296
+ });
297
+
298
+ const SetMetadataEffectsEditV2Schema = ProjectMetadataEffectsInputV2Schema
299
+ .extend({
300
+ kind: z.literal("set-metadata-effects"),
301
+ })
302
+ .strict();
303
+
304
+ const AddManualCameraMovesEditV2Schema = z.strictObject({
305
+ cameraMoves: z.array(ManualProjectCameraMoveInputV2Schema).min(1).max(4_096),
306
+ kind: z.literal("add-manual-camera-moves"),
307
+ }).superRefine((edit, context) => {
308
+ if (
309
+ new Set(edit.cameraMoves.map(move => move.cameraMoveId)).size
310
+ !== edit.cameraMoves.length
311
+ ) {
312
+ context.addIssue({
313
+ code: "custom",
314
+ message: "One add-manual-camera-moves edit cannot contain duplicate camera move IDs.",
315
+ path: ["cameraMoves"],
316
+ });
317
+ }
318
+ });
319
+
320
+ const RemoveCameraMovesEditV2Schema = z.strictObject({
321
+ cameraMoveIds: z.array(CameraMoveIdSchema).min(1).max(4_096),
322
+ kind: z.literal("remove-camera-moves"),
323
+ }).superRefine((edit, context) => {
324
+ if (new Set(edit.cameraMoveIds).size !== edit.cameraMoveIds.length) {
325
+ context.addIssue({
326
+ code: "custom",
327
+ message: "One remove-camera-moves edit cannot contain duplicate camera move IDs.",
328
+ path: ["cameraMoveIds"],
329
+ });
330
+ }
331
+ });
332
+
333
+ export const OrderedProjectEditV2Schema = z.discriminatedUnion("kind", [
334
+ z.strictObject({
335
+ kind: z.literal("cut"),
336
+ range: SourceIntervalSchema,
337
+ }),
338
+ z.strictObject({
339
+ kind: z.literal("trim"),
340
+ range: SourceIntervalSchema,
341
+ }),
342
+ z.strictObject({
343
+ kind: z.literal("speed"),
344
+ range: SourceIntervalSchema,
345
+ rate: z.number().finite().positive().max(64),
346
+ }),
347
+ z.strictObject({
348
+ kind: z.literal("add-zooms"),
349
+ zooms: z.array(ProjectZoomOperationSchema).min(1).max(10_000),
350
+ }),
351
+ z.strictObject({
352
+ kind: z.literal("add-overlays"),
353
+ overlays: z.array(OverlayOperationSchema).min(1).max(10_000),
354
+ }),
355
+ z.strictObject({
356
+ kind: z.literal("remove-overlays"),
357
+ overlayIds: z.array(OverlayIdSchema).min(1).max(10_000),
358
+ }),
359
+ z.strictObject({
360
+ kind: z.literal("remove-zooms"),
361
+ zoomIds: z.array(ZoomIdSchema).min(1).max(10_000),
362
+ }).superRefine((edit, context) => {
363
+ if (new Set(edit.zoomIds).size !== edit.zoomIds.length) {
364
+ context.addIssue({
365
+ code: "custom",
366
+ message: "One remove-zooms edit cannot contain duplicate zoom IDs.",
367
+ path: ["zoomIds"],
368
+ });
369
+ }
370
+ }),
371
+ SetMetadataEffectsEditV2Schema,
372
+ AddManualCameraMovesEditV2Schema,
373
+ RemoveCameraMovesEditV2Schema,
374
+ ]).superRefine((edit, context) => {
375
+ if (
376
+ edit.kind === "add-overlays"
377
+ && new Set(edit.overlays.map(overlay => overlay.overlayId)).size
378
+ !== edit.overlays.length
379
+ ) {
380
+ context.addIssue({
381
+ code: "custom",
382
+ message: "One add-overlays edit cannot contain duplicate overlay IDs.",
383
+ path: ["overlays"],
384
+ });
385
+ }
386
+ if (
387
+ edit.kind === "remove-overlays"
388
+ && new Set(edit.overlayIds).size !== edit.overlayIds.length
389
+ ) {
390
+ context.addIssue({
391
+ code: "custom",
392
+ message: "One remove-overlays edit cannot contain duplicate overlay IDs.",
393
+ path: ["overlayIds"],
394
+ });
395
+ }
396
+ if (
397
+ edit.kind === "add-zooms"
398
+ && new Set(edit.zooms.map(zoom => zoom.operation.zoomId)).size
399
+ !== edit.zooms.length
400
+ ) {
401
+ context.addIssue({
402
+ code: "custom",
403
+ message: "One add-zooms edit cannot contain duplicate zoom IDs.",
404
+ path: ["zooms"],
405
+ });
406
+ }
407
+ });
408
+
409
+ type OrderedProjectEditV2Input = z.infer<typeof OrderedProjectEditV2Schema>;
410
+
411
+ function refineOrderedV2Transitions(
412
+ ordered: readonly OrderedProjectEditV2Input[],
413
+ context: z.RefinementCtx,
414
+ ): void {
415
+ const added = new Set<string>();
416
+ const removed = new Set<string>();
417
+ const addedZooms = new Set<string>();
418
+ const removedZooms = new Set<string>();
419
+ let metadataEffects = 0;
420
+ for (const [editIndex, edit] of ordered.entries()) {
421
+ if (edit.kind === "add-zooms") {
422
+ for (const [zoomIndex, zoom] of edit.zooms.entries()) {
423
+ const zoomId = zoom.operation.zoomId;
424
+ if (addedZooms.has(zoomId)) {
425
+ context.addIssue({
426
+ code: "custom",
427
+ message: "An ordered edit batch cannot add the same zoom ID twice.",
428
+ path: ["ordered", editIndex, "zooms", zoomIndex, "operation", "zoomId"],
429
+ });
430
+ }
431
+ addedZooms.add(zoomId);
432
+ }
433
+ continue;
434
+ }
435
+ if (edit.kind === "remove-zooms") {
436
+ for (const [zoomIndex, zoomId] of edit.zoomIds.entries()) {
437
+ if (removedZooms.has(zoomId)) {
438
+ context.addIssue({
439
+ code: "custom",
440
+ message: "An ordered edit batch cannot remove the same zoom ID twice.",
441
+ path: ["ordered", editIndex, "zoomIds", zoomIndex],
442
+ });
443
+ }
444
+ removedZooms.add(zoomId);
445
+ }
446
+ continue;
447
+ }
448
+ if (edit.kind === "set-metadata-effects") {
449
+ metadataEffects += 1;
450
+ if (metadataEffects > 1) {
451
+ context.addIssue({
452
+ code: "custom",
453
+ message: "An ordered edit batch can replace metadata effects only once.",
454
+ path: ["ordered", editIndex],
455
+ });
456
+ }
457
+ continue;
458
+ }
459
+ if (edit.kind === "add-manual-camera-moves") {
460
+ for (const [moveIndex, move] of edit.cameraMoves.entries()) {
461
+ if (added.has(move.cameraMoveId)) {
462
+ context.addIssue({
463
+ code: "custom",
464
+ message: "An ordered edit batch cannot add the same camera move ID twice.",
465
+ path: ["ordered", editIndex, "cameraMoves", moveIndex, "cameraMoveId"],
466
+ });
467
+ }
468
+ added.add(move.cameraMoveId);
469
+ }
470
+ continue;
471
+ }
472
+ if (edit.kind === "remove-camera-moves") {
473
+ for (const [moveIndex, cameraMoveId] of edit.cameraMoveIds.entries()) {
474
+ if (removed.has(cameraMoveId)) {
475
+ context.addIssue({
476
+ code: "custom",
477
+ message: "An ordered edit batch cannot remove the same camera move ID twice.",
478
+ path: ["ordered", editIndex, "cameraMoveIds", moveIndex],
479
+ });
480
+ }
481
+ removed.add(cameraMoveId);
482
+ }
483
+ }
484
+ }
485
+ }
486
+
487
+ function countV2Edits(input: {
488
+ readonly cutRanges?: readonly unknown[] | undefined;
489
+ readonly ordered?: readonly OrderedProjectEditV2Input[] | undefined;
490
+ }): number {
491
+ return (input.cutRanges?.length ?? 0) + (input.ordered?.reduce(
492
+ (sum, edit) => {
493
+ switch (edit.kind) {
494
+ case "add-zooms":
495
+ return sum + edit.zooms.length;
496
+ case "add-overlays":
497
+ return sum + edit.overlays.length;
498
+ case "remove-overlays":
499
+ return sum + edit.overlayIds.length;
500
+ case "remove-zooms":
501
+ return sum + edit.zoomIds.length;
502
+ case "add-manual-camera-moves":
503
+ return sum + edit.cameraMoves.length;
504
+ case "remove-camera-moves":
505
+ return sum + edit.cameraMoveIds.length;
506
+ case "cut":
507
+ case "set-metadata-effects":
508
+ case "speed":
509
+ case "trim":
510
+ return sum + 1;
511
+ default: {
512
+ const exhaustive: never = edit;
513
+ return exhaustive;
514
+ }
515
+ }
516
+ },
517
+ 0,
518
+ ) ?? 0);
519
+ }
520
+
521
+ export const ProjectEditBatchInputV2Schema = z.strictObject({
522
+ cutRanges: z.array(SourceIntervalSchema).max(10_000).optional(),
523
+ ordered: z.array(OrderedProjectEditV2Schema).max(10_000).optional(),
524
+ }).superRefine((input, context) => {
525
+ const total = countV2Edits(input);
526
+ if (total < 1) {
527
+ context.addIssue({
528
+ code: "custom",
529
+ message: "An edit batch requires at least one explicit edit or derived cut range.",
530
+ });
531
+ }
532
+ if (total > 10_000) {
533
+ context.addIssue({
534
+ code: "custom",
535
+ message: "An edit batch cannot expand beyond 10,000 ordered edits.",
536
+ });
537
+ }
538
+ refineOrderedOverlayTransitions(
539
+ (input.ordered ?? []).filter(edit => (
540
+ edit.kind === "add-overlays" || edit.kind === "remove-overlays"
541
+ )),
542
+ context,
543
+ );
544
+ refineOrderedV2Transitions(input.ordered ?? [], context);
545
+ });
546
+
547
+ const ProjectEditBatchBodyV2Schema = z.strictObject({
548
+ kind: z.union([
549
+ z.literal("slopcamera.project-edit-batch"),
550
+ z.literal("studio.project-edit-batch"),
551
+ ]),
552
+ ordered: z.array(OrderedProjectEditV2Schema).min(1).max(10_000),
553
+ schemaVersion: z.literal(2),
554
+ });
555
+
556
+ export const ProjectEditBatchV2Schema = ProjectEditBatchBodyV2Schema.extend({
557
+ sha256: Sha256Schema,
558
+ }).strict().superRefine((batch, context) => {
559
+ refineOrderedOverlayTransitions(
560
+ batch.ordered.filter(edit => (
561
+ edit.kind === "add-overlays" || edit.kind === "remove-overlays"
562
+ )),
563
+ context,
564
+ );
565
+ refineOrderedV2Transitions(batch.ordered, context);
566
+ const actual = canonicalJsonSha256({
567
+ kind: batch.kind,
568
+ ordered: batch.ordered,
569
+ schemaVersion: batch.schemaVersion,
570
+ });
571
+ if (actual !== batch.sha256) {
572
+ context.addIssue({
573
+ code: "custom",
574
+ message: "Project edit batch hash does not match its ordered edit data.",
575
+ path: ["sha256"],
576
+ });
577
+ }
578
+ });
579
+
580
+ export type ProjectMetadataEffectsInputV2 = z.infer<
581
+ typeof ProjectMetadataEffectsInputV2Schema
582
+ >;
583
+ export type ManualProjectCameraMoveInputV2 = z.infer<
584
+ typeof ManualProjectCameraMoveInputV2Schema
585
+ >;
586
+ export type OrderedProjectEditV2 = z.infer<typeof OrderedProjectEditV2Schema>;
587
+ export type ProjectEditBatchInputV2 = z.infer<
588
+ typeof ProjectEditBatchInputV2Schema
589
+ >;
590
+ export type ProjectEditBatchV2 = z.infer<typeof ProjectEditBatchV2Schema>;
591
+
592
+ export function deriveProjectEditBatchV2(
593
+ orderedInput: readonly OrderedProjectEditV2[],
594
+ ): ProjectEditBatchV2 {
595
+ const body = ProjectEditBatchBodyV2Schema.parse({
596
+ kind: "slopcamera.project-edit-batch",
597
+ ordered: orderedInput,
598
+ schemaVersion: 2,
599
+ });
600
+ return ProjectEditBatchV2Schema.parse({
601
+ ...body,
602
+ sha256: canonicalJsonSha256(body),
603
+ });
604
+ }
605
+
606
+ export const deriveEditBatchOperationDefinitionV2 = {
607
+ inputSchema: ProjectEditBatchInputV2Schema,
608
+ inputSchemaId: "slopcamera.operation.derive.edit-batch.input/v2",
609
+ kind: "derive.edit-batch",
610
+ lifecycle: {
611
+ kind: "pure",
612
+ execute: (context, input) => {
613
+ throwIfAborted(context.abortSignal);
614
+ return Promise.resolve(deriveProjectEditBatchV2([
615
+ ...(input.cutRanges ?? []).map(range => ({
616
+ kind: "cut" as const,
617
+ range,
618
+ })),
619
+ ...(input.ordered ?? []),
620
+ ]));
621
+ },
622
+ },
623
+ outputSchema: ProjectEditBatchV2Schema,
624
+ outputSchemaId: "slopcamera.operation.derive.edit-batch.output/v2",
625
+ policy: {
626
+ cache: "content-addressed",
627
+ cancellable: true,
628
+ effect: "pure",
629
+ maxDurationMs: 5_000,
630
+ maxFanOut: 0,
631
+ maxInputBytes: 16 * 1024 * 1024,
632
+ maxOutputBytes: 16 * 1024 * 1024,
633
+ preparation: [],
634
+ resources: [{ amount: 1, resource: "cpu" }],
635
+ resume: "deterministic",
636
+ },
637
+ summarize: output => ({
638
+ fields: {
639
+ edits: output.ordered.length,
640
+ sha256: output.sha256,
641
+ },
642
+ kind: "derive.edit-batch",
643
+ }),
644
+ version: 2,
645
+ } satisfies OperationDefinition<
646
+ "derive.edit-batch",
647
+ ProjectEditBatchInputV2,
648
+ ProjectEditBatchV2
649
+ >;
650
+
651
+ /**
652
+ * Editorial intent for one manual project zoom. Placement, display, recording
653
+ * manifest, and synchronization identities are deliberately absent here (or
654
+ * optional selectors): the project transaction binds them from current
655
+ * host-owned state before execution.
656
+ */
657
+ export const ManualProjectZoomInputV3Schema = z.strictObject({
658
+ displayId: z.string().min(1).max(256).optional(),
659
+ easing: EasingSchema,
660
+ enterDurationUs: z.number().int().safe().nonnegative(),
661
+ exitDurationUs: z.number().int().safe().nonnegative(),
662
+ placementId: ProjectPlacementIdSchema.optional(),
663
+ range: SourceIntervalSchema,
664
+ scale: z.number().finite().min(1).max(10),
665
+ target: ZoomTargetSchema,
666
+ zoomId: ZoomIdSchema,
667
+ }).superRefine((zoom, context) => {
668
+ if (
669
+ zoom.enterDurationUs + zoom.exitDurationUs
670
+ > zoom.range.endUs - zoom.range.startUs
671
+ ) {
672
+ context.addIssue({
673
+ code: "custom",
674
+ message: "Zoom enter and exit durations cannot exceed the zoom range.",
675
+ path: ["enterDurationUs"],
676
+ });
677
+ }
678
+ });
679
+
680
+ const AddManualZoomsEditV3Schema = z.strictObject({
681
+ kind: z.literal("add-manual-zooms"),
682
+ zooms: z.array(ManualProjectZoomInputV3Schema).min(1).max(10_000),
683
+ }).superRefine((edit, context) => {
684
+ if (
685
+ new Set(edit.zooms.map(zoom => zoom.zoomId)).size
686
+ !== edit.zooms.length
687
+ ) {
688
+ context.addIssue({
689
+ code: "custom",
690
+ message: "One add-manual-zooms edit cannot contain duplicate zoom IDs.",
691
+ path: ["zooms"],
692
+ });
693
+ }
694
+ });
695
+
696
+ export const OrderedProjectEditV3Schema = z.union([
697
+ OrderedProjectEditV2Schema,
698
+ AddManualZoomsEditV3Schema,
699
+ ]);
700
+
701
+ type OrderedProjectEditV3Input = z.infer<typeof OrderedProjectEditV3Schema>;
702
+
703
+ export type ProjectEditNormalizationPhaseV3 =
704
+ | "add"
705
+ | "metadata"
706
+ | "remove"
707
+ | "structural";
708
+
709
+ export function projectEditNormalizationPhaseV3(
710
+ edit: OrderedProjectEditV3Input,
711
+ ): ProjectEditNormalizationPhaseV3 {
712
+ switch (edit.kind) {
713
+ case "cut":
714
+ case "speed":
715
+ case "trim":
716
+ return "structural";
717
+ case "add-manual-camera-moves":
718
+ case "add-manual-zooms":
719
+ case "add-overlays":
720
+ case "add-zooms":
721
+ return "add";
722
+ case "remove-camera-moves":
723
+ case "remove-overlays":
724
+ case "remove-zooms":
725
+ return "remove";
726
+ case "set-metadata-effects":
727
+ return "metadata";
728
+ default: {
729
+ const exhaustive: never = edit;
730
+ return exhaustive;
731
+ }
732
+ }
733
+ }
734
+
735
+ const MAX_V3_NORMALIZATION_PHASES = 64;
736
+
737
+ function countV3NormalizationPhases(input: {
738
+ readonly cutRanges?: readonly unknown[] | undefined;
739
+ readonly ordered?: readonly OrderedProjectEditV3Input[] | undefined;
740
+ }): number {
741
+ let count = input.cutRanges?.length === 0 || input.cutRanges === undefined
742
+ ? 0
743
+ : 1;
744
+ let prior: ProjectEditNormalizationPhaseV3 | undefined = count === 0
745
+ ? undefined
746
+ : "structural";
747
+ for (const edit of input.ordered ?? []) {
748
+ const phase = projectEditNormalizationPhaseV3(edit);
749
+ if (phase !== prior) {
750
+ count += 1;
751
+ prior = phase;
752
+ }
753
+ }
754
+ return count;
755
+ }
756
+
757
+ function refineOrderedV3Transitions(
758
+ ordered: readonly OrderedProjectEditV3Input[],
759
+ context: z.RefinementCtx,
760
+ ): void {
761
+ refineOrderedV2Transitions(
762
+ ordered.filter(
763
+ (edit): edit is OrderedProjectEditV2Input => (
764
+ edit.kind !== "add-manual-zooms"
765
+ ),
766
+ ),
767
+ context,
768
+ );
769
+ const addedZooms = new Set<string>();
770
+ for (const [editIndex, edit] of ordered.entries()) {
771
+ const zooms = edit.kind === "add-zooms"
772
+ ? edit.zooms.map(zoom => ({
773
+ path: ["operation", "zoomId"] as const,
774
+ zoomId: zoom.operation.zoomId,
775
+ }))
776
+ : edit.kind === "add-manual-zooms"
777
+ ? edit.zooms.map(zoom => ({
778
+ path: ["zoomId"] as const,
779
+ zoomId: zoom.zoomId,
780
+ }))
781
+ : [];
782
+ for (const [zoomIndex, zoom] of zooms.entries()) {
783
+ if (addedZooms.has(zoom.zoomId)) {
784
+ context.addIssue({
785
+ code: "custom",
786
+ message: "An ordered edit batch cannot add the same zoom ID twice.",
787
+ path: [
788
+ "ordered",
789
+ editIndex,
790
+ "zooms",
791
+ zoomIndex,
792
+ ...zoom.path,
793
+ ],
794
+ });
795
+ }
796
+ addedZooms.add(zoom.zoomId);
797
+ }
798
+ }
799
+ }
800
+
801
+ function countV3Edits(input: {
802
+ readonly cutRanges?: readonly unknown[] | undefined;
803
+ readonly ordered?: readonly OrderedProjectEditV3Input[] | undefined;
804
+ }): number {
805
+ return (input.cutRanges?.length ?? 0) + (input.ordered?.reduce(
806
+ (sum, edit) => edit.kind === "add-manual-zooms"
807
+ ? sum + edit.zooms.length
808
+ : sum + countV2Edits({ ordered: [edit] }),
809
+ 0,
810
+ ) ?? 0);
811
+ }
812
+
813
+ export const ProjectEditBatchInputV3Schema = z.strictObject({
814
+ cutRanges: z.array(SourceIntervalSchema).max(10_000).optional(),
815
+ ordered: z.array(OrderedProjectEditV3Schema).max(10_000).optional(),
816
+ }).superRefine((input, context) => {
817
+ const total = countV3Edits(input);
818
+ if (total < 1) {
819
+ context.addIssue({
820
+ code: "custom",
821
+ message: "An edit batch requires at least one explicit edit or derived cut range.",
822
+ });
823
+ }
824
+ if (total > 10_000) {
825
+ context.addIssue({
826
+ code: "custom",
827
+ message: "An edit batch cannot expand beyond 10,000 ordered edits.",
828
+ });
829
+ }
830
+ if (
831
+ countV3NormalizationPhases(input)
832
+ > MAX_V3_NORMALIZATION_PHASES
833
+ ) {
834
+ context.addIssue({
835
+ code: "custom",
836
+ message:
837
+ `An edit batch cannot contain more than ${String(MAX_V3_NORMALIZATION_PHASES)} ordered normalization phases.`,
838
+ path: ["ordered"],
839
+ });
840
+ }
841
+ refineOrderedOverlayTransitions(
842
+ (input.ordered ?? []).filter(edit => (
843
+ edit.kind === "add-overlays" || edit.kind === "remove-overlays"
844
+ )),
845
+ context,
846
+ );
847
+ refineOrderedV3Transitions(input.ordered ?? [], context);
848
+ });
849
+
850
+ const ProjectEditBatchBodyV3Schema = z.strictObject({
851
+ kind: z.union([
852
+ z.literal("slopcamera.project-edit-batch"),
853
+ z.literal("studio.project-edit-batch"),
854
+ ]),
855
+ ordered: z.array(OrderedProjectEditV3Schema).min(1).max(10_000),
856
+ schemaVersion: z.literal(3),
857
+ });
858
+
859
+ export const ProjectEditBatchV3Schema = ProjectEditBatchBodyV3Schema.extend({
860
+ sha256: Sha256Schema,
861
+ }).strict().superRefine((batch, context) => {
862
+ if (countV3Edits({ ordered: batch.ordered }) > 10_000) {
863
+ context.addIssue({
864
+ code: "custom",
865
+ message: "An edit batch cannot expand beyond 10,000 ordered edits.",
866
+ path: ["ordered"],
867
+ });
868
+ }
869
+ if (
870
+ countV3NormalizationPhases({ ordered: batch.ordered })
871
+ > MAX_V3_NORMALIZATION_PHASES
872
+ ) {
873
+ context.addIssue({
874
+ code: "custom",
875
+ message:
876
+ `An edit batch cannot contain more than ${String(MAX_V3_NORMALIZATION_PHASES)} ordered normalization phases.`,
877
+ path: ["ordered"],
878
+ });
879
+ }
880
+ refineOrderedOverlayTransitions(
881
+ batch.ordered.filter(edit => (
882
+ edit.kind === "add-overlays" || edit.kind === "remove-overlays"
883
+ )),
884
+ context,
885
+ );
886
+ refineOrderedV3Transitions(batch.ordered, context);
887
+ const actual = canonicalJsonSha256({
888
+ kind: batch.kind,
889
+ ordered: batch.ordered,
890
+ schemaVersion: batch.schemaVersion,
891
+ });
892
+ if (actual !== batch.sha256) {
893
+ context.addIssue({
894
+ code: "custom",
895
+ message: "Project edit batch hash does not match its ordered edit data.",
896
+ path: ["sha256"],
897
+ });
898
+ }
899
+ });
900
+
901
+ export type ManualProjectZoomInputV3 = z.infer<
902
+ typeof ManualProjectZoomInputV3Schema
903
+ >;
904
+ export type OrderedProjectEditV3 = z.infer<typeof OrderedProjectEditV3Schema>;
905
+ export type ProjectEditBatchInputV3 = z.infer<
906
+ typeof ProjectEditBatchInputV3Schema
907
+ >;
908
+ export type ProjectEditBatchV3 = z.infer<typeof ProjectEditBatchV3Schema>;
909
+
910
+ export function deriveProjectEditBatchV3(
911
+ orderedInput: readonly OrderedProjectEditV3[],
912
+ ): ProjectEditBatchV3 {
913
+ const body = ProjectEditBatchBodyV3Schema.parse({
914
+ kind: "slopcamera.project-edit-batch",
915
+ ordered: orderedInput,
916
+ schemaVersion: 3,
917
+ });
918
+ return ProjectEditBatchV3Schema.parse({
919
+ ...body,
920
+ sha256: canonicalJsonSha256(body),
921
+ });
922
+ }
923
+
924
+ export const deriveEditBatchOperationDefinitionV3 = {
925
+ inputSchema: ProjectEditBatchInputV3Schema,
926
+ inputSchemaId: "slopcamera.operation.derive.edit-batch.input/v3",
927
+ kind: "derive.edit-batch",
928
+ lifecycle: {
929
+ kind: "pure",
930
+ execute: (context, input) => {
931
+ throwIfAborted(context.abortSignal);
932
+ return Promise.resolve(deriveProjectEditBatchV3([
933
+ ...(input.cutRanges ?? []).map(range => ({
934
+ kind: "cut" as const,
935
+ range,
936
+ })),
937
+ ...(input.ordered ?? []),
938
+ ]));
939
+ },
940
+ },
941
+ outputSchema: ProjectEditBatchV3Schema,
942
+ outputSchemaId: "slopcamera.operation.derive.edit-batch.output/v3",
943
+ policy: {
944
+ cache: "content-addressed",
945
+ cancellable: true,
946
+ effect: "pure",
947
+ maxDurationMs: 5_000,
948
+ maxFanOut: 0,
949
+ maxInputBytes: 16 * 1024 * 1024,
950
+ maxOutputBytes: 16 * 1024 * 1024,
951
+ preparation: [],
952
+ resources: [{ amount: 1, resource: "cpu" }],
953
+ resume: "deterministic",
954
+ },
955
+ summarize: output => ({
956
+ fields: {
957
+ edits: output.ordered.length,
958
+ sha256: output.sha256,
959
+ },
960
+ kind: "derive.edit-batch",
961
+ }),
962
+ version: 3,
963
+ } satisfies OperationDefinition<
964
+ "derive.edit-batch",
965
+ ProjectEditBatchInputV3,
966
+ ProjectEditBatchV3
967
+ >;