@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,576 @@
1
+ import { z } from "zod";
2
+
3
+ import {
4
+ IsoTimestampSchema,
5
+ MicrosecondsSchema,
6
+ PointSchema,
7
+ RecordingIdSchema,
8
+ RectSchema,
9
+ RepositoryRelativePathSchema,
10
+ Sha256Schema,
11
+ type DeepReadonly,
12
+ type ReadonlyInferred,
13
+ } from "./recording";
14
+
15
+ const EDIT_ID_SUFFIX = /^[a-z0-9][a-z0-9_-]{7,63}$/u;
16
+
17
+ function editId(prefix: string) {
18
+ return z.string().refine(
19
+ (value) => value.startsWith(prefix) && EDIT_ID_SUFFIX.test(value.slice(prefix.length)),
20
+ `Expected an opaque ${prefix} identifier.`,
21
+ );
22
+ }
23
+
24
+ export const EditPlanIdSchema = editId("plan_").brand<"EditPlanId">();
25
+ export const CameraMoveIdSchema = editId("camera_").brand<"CameraMoveId">();
26
+ export const ZoomIdSchema = editId("zoom_").brand<"ZoomId">();
27
+ export const OverlayIdSchema = editId("overlay_").brand<"OverlayId">();
28
+
29
+ export const SourceIntervalSchema = z.strictObject({
30
+ endUs: MicrosecondsSchema,
31
+ startUs: MicrosecondsSchema,
32
+ }).superRefine((interval, context) => {
33
+ if (interval.endUs <= interval.startUs) {
34
+ context.addIssue({ code: "custom", message: "Interval endUs must be greater than startUs." });
35
+ }
36
+ });
37
+
38
+ export const EasingSchema = z.discriminatedUnion("kind", [
39
+ z.strictObject({ kind: z.enum(["linear", "ease-in", "ease-out", "ease-in-out", "spring"]) }),
40
+ z.strictObject({
41
+ kind: z.literal("cubic-bezier"),
42
+ x1: z.number().finite().min(0).max(1),
43
+ x2: z.number().finite().min(0).max(1),
44
+ y1: z.number().finite(),
45
+ y2: z.number().finite(),
46
+ }),
47
+ ]);
48
+
49
+ export const CameraPoseSchema = z.strictObject({
50
+ centerX: z.number().finite().min(0).max(1),
51
+ centerY: z.number().finite().min(0).max(1),
52
+ space: z.literal("prepared-video-layer-normalized-v1"),
53
+ zoom: z.number().finite().min(1).max(10),
54
+ }).superRefine((pose, context) => {
55
+ const halfViewport = 1 / (2 * pose.zoom);
56
+ if (pose.centerX < halfViewport || pose.centerX > 1 - halfViewport) {
57
+ context.addIssue({
58
+ code: "custom",
59
+ message: "Camera pose centerX would move the viewport outside the prepared video layer.",
60
+ });
61
+ }
62
+ if (pose.centerY < halfViewport || pose.centerY > 1 - halfViewport) {
63
+ context.addIssue({
64
+ code: "custom",
65
+ message: "Camera pose centerY would move the viewport outside the prepared video layer.",
66
+ });
67
+ }
68
+ });
69
+
70
+ export const SpeedRangeSchema = z.strictObject({
71
+ range: SourceIntervalSchema,
72
+ rate: z.number().finite().positive().max(64),
73
+ });
74
+
75
+ export const WindowSelectorSchema = z.discriminatedUnion("kind", [
76
+ z.strictObject({ kind: z.literal("window-id"), windowId: z.string().min(1).max(256) }),
77
+ z.strictObject({ applicationBundleId: z.string().min(1).max(512), kind: z.literal("application") }),
78
+ z.strictObject({ kind: z.literal("frontmost") }),
79
+ ]);
80
+
81
+ export const ZoomTargetSchema = z.discriminatedUnion("kind", [
82
+ z.strictObject({ kind: z.literal("rect"), rect: RectSchema }),
83
+ z.strictObject({ kind: z.literal("point"), point: PointSchema }),
84
+ z.strictObject({ kind: z.literal("cursor"), sampling: z.enum(["nearest", "interpolated"]) }),
85
+ z.strictObject({ kind: z.literal("window"), paddingPx: z.number().finite().nonnegative(), selector: WindowSelectorSchema }),
86
+ z.strictObject({ kind: z.literal("focused-input"), paddingPx: z.number().finite().nonnegative() }),
87
+ ]);
88
+
89
+ const ZoomBaseShape = {
90
+ displayId: z.string().min(1).max(256),
91
+ easing: EasingSchema,
92
+ enterDurationUs: MicrosecondsSchema,
93
+ exitDurationUs: MicrosecondsSchema,
94
+ range: SourceIntervalSchema,
95
+ scale: z.number().finite().min(1).max(10),
96
+ target: ZoomTargetSchema,
97
+ zoomId: ZoomIdSchema,
98
+ } as const;
99
+
100
+ export const ManualZoomSchema = z.strictObject({
101
+ ...ZoomBaseShape,
102
+ kind: z.literal("manual"),
103
+ });
104
+
105
+ export const AutomaticZoomSchema = z.strictObject({
106
+ ...ZoomBaseShape,
107
+ confidence: z.number().finite().min(0).max(1),
108
+ kind: z.literal("automatic"),
109
+ reason: z.enum(["click", "focus", "typing", "window-change"]),
110
+ });
111
+
112
+ export const AutomaticZoomPlannerConfigSchema = z.strictObject({
113
+ enterDurationUs: MicrosecondsSchema,
114
+ exitDurationUs: MicrosecondsSchema,
115
+ intentMergeGapUs: MicrosecondsSchema,
116
+ maxDurationUs: MicrosecondsSchema,
117
+ maxScale: z.number().finite().min(1).max(10),
118
+ minDurationUs: MicrosecondsSchema,
119
+ postHandleUs: MicrosecondsSchema,
120
+ preHandleUs: MicrosecondsSchema,
121
+ scale: z.number().finite().min(1).max(10),
122
+ }).superRefine((config, context) => {
123
+ if (config.maxDurationUs < config.minDurationUs) {
124
+ context.addIssue({ code: "custom", message: "maxDurationUs cannot be less than minDurationUs." });
125
+ }
126
+ });
127
+
128
+ export const ZoomOperationSchema = z.discriminatedUnion("kind", [ManualZoomSchema, AutomaticZoomSchema])
129
+ .superRefine((zoom, context) => {
130
+ if (zoom.enterDurationUs + zoom.exitDurationUs > zoom.range.endUs - zoom.range.startUs) {
131
+ context.addIssue({
132
+ code: "custom",
133
+ message: "Zoom enter and exit durations cannot exceed the zoom range.",
134
+ });
135
+ }
136
+ });
137
+
138
+ export const AssetProvenanceSchema = z.discriminatedUnion("kind", [
139
+ z.strictObject({
140
+ kind: z.literal("imported"),
141
+ originalName: z.string().min(1).max(1024),
142
+ sourceSha256: Sha256Schema,
143
+ }),
144
+ z.strictObject({
145
+ command: z.array(z.string().min(1)).min(1),
146
+ generator: z.string().min(1).max(256),
147
+ generatorVersion: z.string().min(1).max(128),
148
+ kind: z.literal("generated"),
149
+ sourceSha256: Sha256Schema,
150
+ }),
151
+ ]);
152
+
153
+ function assetSchema<const MediaTypes extends readonly [string, ...string[]]>(mediaTypes: MediaTypes) {
154
+ return z.strictObject({
155
+ bytes: z.number().int().safe().positive(),
156
+ mediaType: z.enum(mediaTypes),
157
+ path: RepositoryRelativePathSchema,
158
+ provenance: AssetProvenanceSchema,
159
+ sha256: Sha256Schema,
160
+ });
161
+ }
162
+
163
+ export const ImageAssetSchema = assetSchema(["image/jpeg", "image/png", "image/webp"]);
164
+ export const SvgAssetSchema = assetSchema(["image/svg+xml"]);
165
+ export const GifAssetSchema = assetSchema(["image/gif"]);
166
+ export const VideoAssetSchema = assetSchema(["video/mp4", "video/quicktime", "video/webm"]);
167
+ export const EmojiAssetSchema = assetSchema(["image/png", "image/svg+xml"]);
168
+
169
+ export const AnimatedPlaybackSchema = z.strictObject({
170
+ audioEndUs: z.number().int().safe().min(-86_400_000_000).max(86_400_000_000).nullable().default(null),
171
+ audioStartUs: z.number().int().safe().min(-86_400_000_000).max(86_400_000_000).default(0),
172
+ audioStreamIndex: z.number().int().safe().nonnegative().nullable().default(null),
173
+ endBehavior: z.enum(["hide", "loop", "freeze-end"]),
174
+ playbackRate: z.number().finite().positive().max(64),
175
+ sourceInUs: MicrosecondsSchema,
176
+ sourceOutUs: MicrosecondsSchema,
177
+ streamStartUs: z.number().int().safe().min(-86_400_000_000).max(86_400_000_000).default(0),
178
+ videoStreamIndex: z.number().int().safe().nonnegative().nullable().default(null),
179
+ }).superRefine((playback, context) => {
180
+ if (playback.sourceOutUs <= playback.sourceInUs) {
181
+ context.addIssue({ code: "custom", message: "Animated sourceOutUs must be greater than sourceInUs." });
182
+ }
183
+ if (playback.audioEndUs !== null && playback.audioEndUs <= playback.audioStartUs) {
184
+ context.addIssue({ code: "custom", message: "Animated audioEndUs must be greater than audioStartUs." });
185
+ }
186
+ });
187
+
188
+ export const VideoAudioPolicySchema = z.discriminatedUnion("kind", [
189
+ z.strictObject({ kind: z.literal("mute") }),
190
+ z.strictObject({ kind: z.literal("mix"), volume: z.number().finite().min(0).max(4) }),
191
+ z.strictObject({
192
+ duckPrimaryTo: z.number().finite().min(0).max(1),
193
+ kind: z.literal("duck-primary"),
194
+ volume: z.number().finite().min(0).max(4),
195
+ }),
196
+ ]);
197
+
198
+ export const EmojiSelectorSchema = z.discriminatedUnion("kind", [
199
+ z.strictObject({ kind: z.literal("unicode"), value: z.string().min(1).max(64) }),
200
+ z.strictObject({ kind: z.literal("name"), value: z.string().min(1).max(256) }),
201
+ z.strictObject({ kind: z.literal("id"), value: z.string().regex(/^[a-f0-9]+(?:-[a-f0-9]+)*$/u) }),
202
+ ]);
203
+
204
+ export const EmojiOverlaySourceSchema = z.strictObject({
205
+ asset: EmojiAssetSchema,
206
+ kind: z.literal("emoji"),
207
+ provider: z.enum(["apple-emoji-pack", "brand-catalog"]),
208
+ selector: EmojiSelectorSchema,
209
+ });
210
+
211
+ export const OverlaySourceSchema = z.discriminatedUnion("kind", [
212
+ z.strictObject({ asset: ImageAssetSchema, kind: z.literal("image") }),
213
+ z.strictObject({ asset: SvgAssetSchema, kind: z.literal("svg") }),
214
+ z.strictObject({
215
+ asset: GifAssetSchema,
216
+ audioPolicy: z.strictObject({ kind: z.literal("mute") }),
217
+ kind: z.literal("gif"),
218
+ playback: AnimatedPlaybackSchema,
219
+ }),
220
+ z.strictObject({
221
+ asset: VideoAssetSchema,
222
+ audioPolicy: VideoAudioPolicySchema,
223
+ kind: z.literal("video"),
224
+ playback: AnimatedPlaybackSchema,
225
+ }),
226
+ EmojiOverlaySourceSchema,
227
+ ]);
228
+
229
+ export const OverlayAnchorSchema = z.enum([
230
+ "top-left",
231
+ "top",
232
+ "top-right",
233
+ "left",
234
+ "center",
235
+ "right",
236
+ "bottom-left",
237
+ "bottom",
238
+ "bottom-right",
239
+ ]);
240
+
241
+ export const OverlaySizeSchema = z.discriminatedUnion("kind", [
242
+ z.strictObject({ kind: z.literal("intrinsic") }),
243
+ z.strictObject({
244
+ height: z.number().finite().positive().max(16_384),
245
+ kind: z.literal("pixels"),
246
+ width: z.number().finite().positive().max(16_384),
247
+ }).superRefine((size, context) => {
248
+ if (size.width * size.height > 134_217_728) {
249
+ context.addIssue({ code: "custom", message: "Overlay pixel area exceeds the 128-megapixel safety limit." });
250
+ }
251
+ }),
252
+ ]);
253
+
254
+ export const OverlayIntrinsicSizeSchema = z.strictObject({
255
+ height: z.number().int().safe().positive().max(16_384),
256
+ width: z.number().int().safe().positive().max(16_384),
257
+ }).superRefine((size, context) => {
258
+ if (size.width * size.height > 134_217_728) {
259
+ context.addIssue({ code: "custom", message: "Overlay intrinsic pixel area exceeds the 128-megapixel safety limit." });
260
+ }
261
+ });
262
+
263
+ export const OverlayCropSchema = z.discriminatedUnion("kind", [
264
+ z.strictObject({ kind: z.literal("none") }),
265
+ z.strictObject({
266
+ bottom: z.number().finite().min(0).max(1),
267
+ kind: z.literal("normalized-insets"),
268
+ left: z.number().finite().min(0).max(1),
269
+ right: z.number().finite().min(0).max(1),
270
+ top: z.number().finite().min(0).max(1),
271
+ }).superRefine((crop, context) => {
272
+ if (crop.left + crop.right >= 1) {
273
+ context.addIssue({ code: "custom", message: "Overlay horizontal crop insets must leave visible content." });
274
+ }
275
+ if (crop.top + crop.bottom >= 1) {
276
+ context.addIssue({ code: "custom", message: "Overlay vertical crop insets must leave visible content." });
277
+ }
278
+ }),
279
+ ]);
280
+
281
+ export const OverlayMaskSchema = z.discriminatedUnion("kind", [
282
+ z.strictObject({ kind: z.literal("none") }),
283
+ z.strictObject({
284
+ kind: z.literal("rounded-rectangle"),
285
+ radiusPx: z.number().finite().positive().max(16_384),
286
+ }),
287
+ ]);
288
+
289
+ export const OverlayTransformKeyframeSchema = z.strictObject({
290
+ easing: EasingSchema,
291
+ offset: z.number().finite().min(0).max(1),
292
+ opacityMultiplier: z.number().finite().min(0).max(1),
293
+ positionOffset: PointSchema,
294
+ rotationOffsetDegrees: z.number().finite().min(-3_600).max(3_600),
295
+ scaleMultiplier: z.number().finite().positive().max(128),
296
+ });
297
+
298
+ export const OverlayMotionSchema = z.discriminatedUnion("kind", [
299
+ z.strictObject({ kind: z.literal("none") }),
300
+ z.strictObject({
301
+ keyframes: z.array(OverlayTransformKeyframeSchema).min(2).max(256),
302
+ kind: z.literal("keyframes"),
303
+ timeline: z.literal("visible-output"),
304
+ }).superRefine((motion, context) => {
305
+ if (motion.keyframes[0]?.offset !== 0 || motion.keyframes.at(-1)?.offset !== 1) {
306
+ context.addIssue({ code: "custom", message: "Overlay motion keyframes must begin at offset 0 and end at offset 1." });
307
+ }
308
+ for (let index = 1; index < motion.keyframes.length; index += 1) {
309
+ if (motion.keyframes[index]!.offset <= motion.keyframes[index - 1]!.offset) {
310
+ context.addIssue({ code: "custom", message: "Overlay motion keyframe offsets must be strictly increasing." });
311
+ break;
312
+ }
313
+ }
314
+ }),
315
+ ]);
316
+
317
+ export const OverlayAnimationSchema = z.discriminatedUnion("kind", [
318
+ z.strictObject({ kind: z.literal("none") }),
319
+ z.strictObject({ durationUs: MicrosecondsSchema, easing: EasingSchema, kind: z.literal("fade") }),
320
+ z.strictObject({
321
+ durationUs: MicrosecondsSchema,
322
+ easing: EasingSchema,
323
+ fromScale: z.number().finite().nonnegative().max(32),
324
+ kind: z.literal("scale"),
325
+ }),
326
+ z.strictObject({
327
+ direction: z.enum(["up", "down", "left", "right"]),
328
+ distancePx: z.number().finite().nonnegative().max(32_768),
329
+ durationUs: MicrosecondsSchema,
330
+ easing: EasingSchema,
331
+ kind: z.literal("slide"),
332
+ }),
333
+ ]);
334
+
335
+ export const OverlayOperationSchema = z.strictObject({
336
+ anchor: OverlayAnchorSchema,
337
+ blendMode: z.enum(["normal", "addition", "darken", "lighten", "multiply", "overlay", "screen"]).default("normal"),
338
+ coordinateSpace: z.literal("output-pixels").default("output-pixels"),
339
+ crop: OverlayCropSchema.default({ kind: "none" }),
340
+ entrance: OverlayAnimationSchema,
341
+ exit: OverlayAnimationSchema,
342
+ fit: z.enum(["contain", "cover", "fill"]).default("fill"),
343
+ intrinsicSize: OverlayIntrinsicSizeSchema,
344
+ mask: OverlayMaskSchema.default({ kind: "none" }),
345
+ motion: OverlayMotionSchema.default({ kind: "none" }),
346
+ opacity: z.number().finite().min(0).max(1),
347
+ overlayId: OverlayIdSchema,
348
+ position: PointSchema,
349
+ range: SourceIntervalSchema,
350
+ rotationDegrees: z.number().finite().min(-3600).max(3600),
351
+ scale: z.number().finite().positive().max(128),
352
+ size: OverlaySizeSchema,
353
+ source: OverlaySourceSchema,
354
+ zIndex: z.number().int().safe(),
355
+ }).superRefine((overlay, context) => {
356
+ const durationUs = overlay.range.endUs - overlay.range.startUs;
357
+ const entranceDurationUs = overlay.entrance.kind === "none" ? 0 : overlay.entrance.durationUs;
358
+ const exitDurationUs = overlay.exit.kind === "none" ? 0 : overlay.exit.durationUs;
359
+ if (entranceDurationUs + exitDurationUs > durationUs) {
360
+ context.addIssue({
361
+ code: "custom",
362
+ message: "Overlay entrance and exit durations cannot exceed the overlay duration.",
363
+ });
364
+ }
365
+ const baseSize = overlay.size.kind === "pixels" ? overlay.size : overlay.intrinsicSize;
366
+ const animationScale = Math.max(
367
+ 1,
368
+ overlay.entrance.kind === "scale" ? overlay.entrance.fromScale : 1,
369
+ overlay.exit.kind === "scale" ? overlay.exit.fromScale : 1,
370
+ );
371
+ const motionScale = overlay.motion.kind === "keyframes"
372
+ ? Math.max(1, ...overlay.motion.keyframes.map(keyframe => keyframe.scaleMultiplier))
373
+ : 1;
374
+ const maximumScale = overlay.scale * animationScale * motionScale;
375
+ const width = Math.ceil(baseSize.width * maximumScale);
376
+ const height = Math.ceil(baseSize.height * maximumScale);
377
+ const canRotate = overlay.rotationDegrees !== 0 || (
378
+ overlay.motion.kind === "keyframes"
379
+ && overlay.motion.keyframes.some(keyframe => keyframe.rotationOffsetDegrees !== 0)
380
+ );
381
+ const maximumDimension = canRotate ? width + height : Math.max(width, height);
382
+ const maximumArea = canRotate ? (width + height) ** 2 : width * height;
383
+ if (maximumDimension > 16_384 || maximumArea > 134_217_728) {
384
+ context.addIssue({
385
+ code: "custom",
386
+ message: "Overlay transforms can exceed the 16384-pixel or 128-megapixel render safety limit.",
387
+ });
388
+ }
389
+ });
390
+
391
+ export const CursorEffectSchema = z.discriminatedUnion("enabled", [
392
+ z.strictObject({ enabled: z.literal(false) }),
393
+ z.strictObject({
394
+ enabled: z.literal(true),
395
+ scale: z.number().finite().positive().max(16),
396
+ smoothing: z.strictObject({
397
+ algorithm: z.enum(["exponential", "none"]),
398
+ strength: z.number().finite().min(0).max(1),
399
+ }),
400
+ style: z.enum(["captured", "dot", "ring"]),
401
+ }),
402
+ ]);
403
+
404
+ export const ClickEffectSchema = z.discriminatedUnion("enabled", [
405
+ z.strictObject({ enabled: z.literal(false) }),
406
+ z.strictObject({
407
+ color: z.string().regex(/^#[a-fA-F0-9]{6}(?:[a-fA-F0-9]{2})?$/u),
408
+ durationUs: MicrosecondsSchema,
409
+ enabled: z.literal(true),
410
+ radiusPx: z.number().finite().positive().max(4_096),
411
+ style: z.enum(["pulse", "ring", "fill"]),
412
+ }),
413
+ ]);
414
+
415
+ export const KeystrokeEffectSchema = z.discriminatedUnion("enabled", [
416
+ z.strictObject({ enabled: z.literal(false) }),
417
+ z.strictObject({
418
+ enabled: z.literal(true),
419
+ holdUs: MicrosecondsSchema,
420
+ maxKeys: z.number().int().safe().positive().max(32),
421
+ position: z.enum(["bottom-left", "bottom-center", "bottom-right"]),
422
+ secureText: z.literal("hide"),
423
+ }),
424
+ ]);
425
+
426
+ export const TypedTextEffectSchema = z.discriminatedUnion("enabled", [
427
+ z.strictObject({ enabled: z.literal(false) }),
428
+ z.strictObject({
429
+ enabled: z.literal(true),
430
+ idleTimeoutUs: MicrosecondsSchema,
431
+ maxCharacters: z.number().int().safe().positive().max(4096),
432
+ placement: z.enum(["input", "caption"]),
433
+ secureText: z.literal("hide"),
434
+ }),
435
+ ]);
436
+
437
+ function intervalsAreNormalized(intervals: readonly { readonly startUs: number; readonly endUs: number }[]): boolean {
438
+ let priorEnd = -1;
439
+ for (const interval of intervals) {
440
+ if (interval.startUs <= priorEnd) return false;
441
+ priorEnd = interval.endUs;
442
+ }
443
+ return true;
444
+ }
445
+
446
+ function rangesAreOrderedAndDisjoint(
447
+ ranges: readonly { readonly range: { readonly startUs: number; readonly endUs: number } }[],
448
+ ): boolean {
449
+ let priorEnd = -1;
450
+ for (const { range } of ranges) {
451
+ if (range.startUs < priorEnd) return false;
452
+ priorEnd = range.endUs;
453
+ }
454
+ return true;
455
+ }
456
+
457
+ function zoomRangesAreDisjointPerDisplay(
458
+ zooms: readonly {
459
+ readonly displayId: string;
460
+ readonly range: { readonly startUs: number; readonly endUs: number };
461
+ }[],
462
+ ): boolean {
463
+ const priorEndByDisplay = new Map<string, number>();
464
+ for (const zoom of [...zooms].sort((left, right) => (
465
+ left.displayId.localeCompare(right.displayId)
466
+ || left.range.startUs - right.range.startUs
467
+ || left.range.endUs - right.range.endUs
468
+ ))) {
469
+ const priorEndUs = priorEndByDisplay.get(zoom.displayId);
470
+ if (priorEndUs !== undefined && zoom.range.startUs < priorEndUs) return false;
471
+ priorEndByDisplay.set(zoom.displayId, zoom.range.endUs);
472
+ }
473
+ return true;
474
+ }
475
+
476
+ function intervalIsKept(
477
+ interval: { readonly startUs: number; readonly endUs: number },
478
+ keep: readonly { readonly startUs: number; readonly endUs: number }[],
479
+ ): boolean {
480
+ return keep.some(({ startUs, endUs }) => startUs <= interval.startUs && endUs >= interval.endUs);
481
+ }
482
+
483
+ function intervalOverlapsKeep(
484
+ interval: { readonly startUs: number; readonly endUs: number },
485
+ keep: readonly { readonly startUs: number; readonly endUs: number }[],
486
+ ): boolean {
487
+ return keep.some(({ startUs, endUs }) => startUs < interval.endUs && endUs > interval.startUs);
488
+ }
489
+
490
+ export const EditPlanV1Schema = z.strictObject({
491
+ baseSpeed: z.number().finite().positive().max(64),
492
+ createdAt: IsoTimestampSchema,
493
+ effects: z.strictObject({
494
+ clicks: ClickEffectSchema,
495
+ cursor: CursorEffectSchema,
496
+ keystrokes: KeystrokeEffectSchema,
497
+ typedText: TypedTextEffectSchema,
498
+ }),
499
+ keep: z.array(SourceIntervalSchema),
500
+ kind: z.union([
501
+ z.literal("slopcamera.edit-plan"),
502
+ z.literal("studio.edit-plan"),
503
+ ]),
504
+ overlays: z.array(OverlayOperationSchema),
505
+ planId: EditPlanIdSchema,
506
+ recordingId: RecordingIdSchema,
507
+ schemaVersion: z.literal(1),
508
+ sourceDurationUs: MicrosecondsSchema,
509
+ speed: z.array(SpeedRangeSchema),
510
+ updatedAt: IsoTimestampSchema,
511
+ zooms: z.array(ZoomOperationSchema),
512
+ }).superRefine((plan, context) => {
513
+ if (Date.parse(plan.updatedAt) < Date.parse(plan.createdAt)) {
514
+ context.addIssue({ code: "custom", message: "updatedAt cannot precede createdAt." });
515
+ }
516
+ if (!intervalsAreNormalized(plan.keep)) {
517
+ context.addIssue({ code: "custom", message: "Keep intervals must be sorted, disjoint, and non-adjacent." });
518
+ }
519
+ if (plan.keep.some(({ endUs }) => endUs > plan.sourceDurationUs)) {
520
+ context.addIssue({ code: "custom", message: "Keep intervals cannot exceed sourceDurationUs." });
521
+ }
522
+ if (!rangesAreOrderedAndDisjoint(plan.speed)) {
523
+ context.addIssue({ code: "custom", message: "Speed ranges must be sorted and non-overlapping." });
524
+ }
525
+ if (plan.speed.some(({ range }) => !intervalIsKept(range, plan.keep))) {
526
+ context.addIssue({ code: "custom", message: "Every speed range must be contained in one keep interval." });
527
+ }
528
+ if (plan.speed.some(({ rate }) => rate === plan.baseSpeed)) {
529
+ context.addIssue({ code: "custom", message: "Speed ranges equal to baseSpeed are redundant." });
530
+ }
531
+ if (plan.zooms.some(({ range }) => !intervalOverlapsKeep(range, plan.keep))) {
532
+ context.addIssue({ code: "custom", message: "Every zoom range must overlap kept source time." });
533
+ }
534
+ if (!zoomRangesAreDisjointPerDisplay(plan.zooms)) {
535
+ context.addIssue({
536
+ code: "custom",
537
+ message: "Zoom ranges on the same display must not overlap; resolve manual and automatic precedence before saving.",
538
+ });
539
+ }
540
+ if (plan.overlays.some(({ range }) => !intervalOverlapsKeep(range, plan.keep))) {
541
+ context.addIssue({ code: "custom", message: "Every overlay range must overlap kept source time." });
542
+ }
543
+ for (const [label, ids] of [
544
+ ["Zoom IDs", plan.zooms.map(({ zoomId }) => String(zoomId))],
545
+ ["Overlay IDs", plan.overlays.map(({ overlayId }) => String(overlayId))],
546
+ ] satisfies readonly (readonly [string, readonly string[]])[]) {
547
+ if (new Set(ids).size !== ids.length) {
548
+ context.addIssue({ code: "custom", message: `${label} must be unique.` });
549
+ }
550
+ }
551
+ });
552
+
553
+ export type SourceInterval = ReadonlyInferred<typeof SourceIntervalSchema>;
554
+ export type SpeedRange = ReadonlyInferred<typeof SpeedRangeSchema>;
555
+ export type CameraPose = ReadonlyInferred<typeof CameraPoseSchema>;
556
+ export type Easing = ReadonlyInferred<typeof EasingSchema>;
557
+ export type ZoomTarget = ReadonlyInferred<typeof ZoomTargetSchema>;
558
+ export type WindowSelector = ReadonlyInferred<typeof WindowSelectorSchema>;
559
+ export type ZoomOperation = ReadonlyInferred<typeof ZoomOperationSchema>;
560
+ export type AutomaticZoom = ReadonlyInferred<typeof AutomaticZoomSchema>;
561
+ export type AutomaticZoomPlannerConfig = ReadonlyInferred<typeof AutomaticZoomPlannerConfigSchema>;
562
+ export type OverlaySource = ReadonlyInferred<typeof OverlaySourceSchema>;
563
+ export type OverlayIntrinsicSize = ReadonlyInferred<typeof OverlayIntrinsicSizeSchema>;
564
+ export type EmojiOverlaySource = ReadonlyInferred<typeof EmojiOverlaySourceSchema>;
565
+ export type OverlayCrop = ReadonlyInferred<typeof OverlayCropSchema>;
566
+ export type OverlayMask = ReadonlyInferred<typeof OverlayMaskSchema>;
567
+ export type OverlayMotion = ReadonlyInferred<typeof OverlayMotionSchema>;
568
+ export type OverlayTransformKeyframe = ReadonlyInferred<typeof OverlayTransformKeyframeSchema>;
569
+ export type OverlayOperation = DeepReadonly<z.input<typeof OverlayOperationSchema>>;
570
+ export type EditPlanV1 = ReadonlyInferred<typeof EditPlanV1Schema>;
571
+ export type EditPlanDraft = DeepReadonly<z.input<typeof EditPlanV1Schema>>;
572
+ export type EmojiSelector = ReadonlyInferred<typeof EmojiSelectorSchema>;
573
+
574
+ export function parseEditPlanV1(input: unknown): EditPlanV1 {
575
+ return EditPlanV1Schema.parse(input);
576
+ }
@@ -0,0 +1,9 @@
1
+ export * from "./analysis";
2
+ export * from "./edit";
3
+ export * from "./media-effects";
4
+ export * from "./project";
5
+ export * from "./project-render";
6
+ export * from "./recording";
7
+ export * from "./render";
8
+ export * from "./runtime";
9
+ export * from "./video-effects";