@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,520 @@
1
+ import { randomUUID } from "node:crypto";
2
+
3
+ import { z } from "zod";
4
+
5
+ import {
6
+ ProjectEditPlanV1Schema,
7
+ RepositoryRelativePathSchema,
8
+ Sha256Schema,
9
+ VideoProjectIdSchema,
10
+ VideoProjectV1Schema,
11
+ type ProjectEditPlanV1,
12
+ type VideoProjectV1,
13
+ } from "../contracts";
14
+ import {
15
+ canonicalJson,
16
+ canonicalJsonSha256,
17
+ canonicalSlopcameraPersistenceDocument,
18
+ hashProjectStructure,
19
+ loadProjectEditPlan,
20
+ loadVideoProject,
21
+ saveImmutableText,
22
+ saveProjectEditPlan,
23
+ saveVideoProject,
24
+ sha256Hex,
25
+ type BundleFileSystem,
26
+ } from "../core";
27
+ import { CliError } from "./errors";
28
+
29
+ export const PROJECT_STATE_TRANSACTION_PATH = "state/project-transaction.json";
30
+
31
+ const TransactionIdSchema = z.string().regex(/^transaction_[a-f0-9]{32}$/u);
32
+
33
+ const GenerationReferenceSchema = z.strictObject({
34
+ plan: z.strictObject({
35
+ path: RepositoryRelativePathSchema,
36
+ sha256: Sha256Schema,
37
+ }),
38
+ project: z.strictObject({
39
+ path: RepositoryRelativePathSchema,
40
+ sha256: Sha256Schema,
41
+ }),
42
+ });
43
+
44
+ const TransactionBaseShape = {
45
+ after: GenerationReferenceSchema,
46
+ before: GenerationReferenceSchema,
47
+ kind: z.union([
48
+ z.literal("slopcamera.project-state-transaction"),
49
+ z.literal("studio.project-state-transaction"),
50
+ ]),
51
+ projectId: VideoProjectIdSchema,
52
+ schemaVersion: z.literal(1),
53
+ transactionId: TransactionIdSchema,
54
+ } as const;
55
+
56
+ function assertCanonicalTransactionPaths(
57
+ transaction: Readonly<{
58
+ after: z.infer<typeof GenerationReferenceSchema>;
59
+ before: z.infer<typeof GenerationReferenceSchema>;
60
+ transactionId: string;
61
+ }>,
62
+ context: z.RefinementCtx,
63
+ ): void {
64
+ const root = `state/transactions/${transaction.transactionId}`;
65
+ const expected = {
66
+ after: {
67
+ plan: `${root}/after-plan.json`,
68
+ project: `${root}/after-project.json`,
69
+ },
70
+ before: {
71
+ plan: `${root}/before-plan.json`,
72
+ project: `${root}/before-project.json`,
73
+ },
74
+ } as const;
75
+ for (const generation of ["before", "after"] as const) {
76
+ if (transaction[generation].plan.path !== expected[generation].plan) {
77
+ context.addIssue({ code: "custom", message: `Project transaction ${generation} plan path is not canonical.` });
78
+ }
79
+ if (transaction[generation].project.path !== expected[generation].project) {
80
+ context.addIssue({ code: "custom", message: `Project transaction ${generation} project path is not canonical.` });
81
+ }
82
+ }
83
+ }
84
+
85
+ export const ProjectStateTransactionV1Schema = z.discriminatedUnion("phase", [
86
+ z.strictObject({ ...TransactionBaseShape, phase: z.literal("prepare") }),
87
+ z.strictObject({ ...TransactionBaseShape, phase: z.literal("commit-ready") }),
88
+ z.strictObject({
89
+ ...TransactionBaseShape,
90
+ active: z.enum(["before", "after"]),
91
+ phase: z.literal("settled"),
92
+ }),
93
+ ]).superRefine((transaction, context) => {
94
+ assertCanonicalTransactionPaths(transaction, context);
95
+ });
96
+
97
+ export type ProjectStateTransactionV1 = Readonly<z.infer<typeof ProjectStateTransactionV1Schema>>;
98
+
99
+ export const ProjectStateTransactionSettlementV1Schema = z.strictObject({
100
+ active: z.enum(["before", "after"]),
101
+ after: GenerationReferenceSchema,
102
+ before: GenerationReferenceSchema,
103
+ kind: z.union([
104
+ z.literal("slopcamera.project-state-transaction-settlement"),
105
+ ]),
106
+ projectId: VideoProjectIdSchema,
107
+ schemaVersion: z.literal(1),
108
+ transactionId: TransactionIdSchema,
109
+ }).superRefine(assertCanonicalTransactionPaths);
110
+
111
+ export type ProjectStateTransactionSettlementV1 = Readonly<
112
+ z.infer<typeof ProjectStateTransactionSettlementV1Schema>
113
+ >;
114
+
115
+ export function projectStateTransactionSettlementPath(
116
+ transactionId: string,
117
+ ): string {
118
+ return `state/transactions/${TransactionIdSchema.parse(transactionId)}/settlement.json`;
119
+ }
120
+
121
+ export function projectStateTransactionMayHaveCommitted(error: unknown): boolean {
122
+ return error instanceof CliError
123
+ && error.details?.projectStateTransaction === "unresolved";
124
+ }
125
+
126
+ interface ProjectGeneration {
127
+ readonly plan: ProjectEditPlanV1;
128
+ readonly project: VideoProjectV1;
129
+ }
130
+
131
+ function missing(error: unknown): boolean {
132
+ return error instanceof Error && "code" in error && error.code === "ENOENT";
133
+ }
134
+
135
+ function validateGeneration(input: ProjectGeneration, label: string): ProjectGeneration {
136
+ const project = VideoProjectV1Schema.parse(input.project);
137
+ const plan = ProjectEditPlanV1Schema.parse(input.plan);
138
+ if (plan.projectId !== project.projectId) {
139
+ throw new CliError("invalid-data", `${label} project state uses different project identities.`);
140
+ }
141
+ if (plan.projectStructureSha256 !== hashProjectStructure(project)) {
142
+ throw new CliError("invalid-data", `${label} project state has an edit plan for another structure generation.`);
143
+ }
144
+ return {
145
+ plan: canonicalSlopcameraPersistenceDocument(plan),
146
+ project: canonicalSlopcameraPersistenceDocument(project),
147
+ };
148
+ }
149
+
150
+ function referenceFor(
151
+ transactionId: string,
152
+ generation: "before" | "after",
153
+ value: ProjectGeneration,
154
+ ): z.infer<typeof GenerationReferenceSchema> {
155
+ const root = `state/transactions/${transactionId}`;
156
+ return GenerationReferenceSchema.parse({
157
+ plan: {
158
+ path: `${root}/${generation}-plan.json`,
159
+ sha256: canonicalJsonSha256(value.plan),
160
+ },
161
+ project: {
162
+ path: `${root}/${generation}-project.json`,
163
+ sha256: canonicalJsonSha256(value.project),
164
+ },
165
+ });
166
+ }
167
+
168
+ async function readTransaction(
169
+ fileSystem: BundleFileSystem,
170
+ ): Promise<ProjectStateTransactionV1 | null> {
171
+ let text: string;
172
+ try {
173
+ text = await fileSystem.readText(PROJECT_STATE_TRANSACTION_PATH);
174
+ } catch (error) {
175
+ if (missing(error)) return null;
176
+ throw error;
177
+ }
178
+ let value: unknown;
179
+ try {
180
+ value = JSON.parse(text) as unknown;
181
+ } catch {
182
+ throw new CliError("invalid-data", "Project state transaction marker is not valid JSON.");
183
+ }
184
+ const parsed = ProjectStateTransactionV1Schema.safeParse(value);
185
+ if (!parsed.success) {
186
+ throw new CliError("invalid-data", `Project state transaction marker is invalid: ${parsed.error.message}`);
187
+ }
188
+ return parsed.data;
189
+ }
190
+
191
+ async function writeTransaction(
192
+ fileSystem: BundleFileSystem,
193
+ transaction: ProjectStateTransactionV1,
194
+ ): Promise<void> {
195
+ const parsed = ProjectStateTransactionV1Schema.parse({
196
+ ...transaction,
197
+ kind: "slopcamera.project-state-transaction",
198
+ });
199
+ await fileSystem.writeTextAtomic(PROJECT_STATE_TRANSACTION_PATH, `${canonicalJson(parsed)}\n`);
200
+ }
201
+
202
+ async function saveGeneration(
203
+ fileSystem: BundleFileSystem,
204
+ reference: z.infer<typeof GenerationReferenceSchema>,
205
+ generation: ProjectGeneration,
206
+ ): Promise<void> {
207
+ await saveProjectEditPlan(fileSystem, generation.plan, reference.plan.path);
208
+ await saveVideoProject(fileSystem, generation.project, reference.project.path);
209
+ }
210
+
211
+ async function loadGeneration(
212
+ fileSystem: BundleFileSystem,
213
+ reference: z.infer<typeof GenerationReferenceSchema>,
214
+ label: string,
215
+ ): Promise<ProjectGeneration> {
216
+ const [rawPlanText, rawProjectText] = await Promise.all([
217
+ fileSystem.readText(reference.plan.path),
218
+ fileSystem.readText(reference.project.path),
219
+ ]);
220
+ let rawGeneration: ProjectGeneration;
221
+ try {
222
+ rawGeneration = {
223
+ plan: ProjectEditPlanV1Schema.parse(JSON.parse(rawPlanText) as unknown),
224
+ project: VideoProjectV1Schema.parse(JSON.parse(rawProjectText) as unknown),
225
+ };
226
+ } catch {
227
+ throw new CliError(
228
+ "invalid-data",
229
+ `${label} project transaction generation is not valid structured state.`,
230
+ );
231
+ }
232
+ if (
233
+ canonicalJsonSha256(rawGeneration.plan) !== reference.plan.sha256
234
+ || canonicalJsonSha256(rawGeneration.project) !== reference.project.sha256
235
+ ) {
236
+ throw new CliError("invalid-data", `${label} project transaction generation failed its integrity check.`);
237
+ }
238
+ return validateGeneration(rawGeneration, label);
239
+ }
240
+
241
+ export async function loadProjectStateTransactionSettlement(
242
+ fileSystem: BundleFileSystem,
243
+ transactionId: string,
244
+ ): Promise<ProjectStateTransactionSettlementV1 | null> {
245
+ const path = projectStateTransactionSettlementPath(transactionId);
246
+ let text: string;
247
+ try {
248
+ text = await fileSystem.readText(path);
249
+ } catch (error) {
250
+ if (missing(error)) return null;
251
+ throw error;
252
+ }
253
+ let value: unknown;
254
+ try {
255
+ value = JSON.parse(text) as unknown;
256
+ } catch {
257
+ throw new CliError(
258
+ "invalid-data",
259
+ `Project transaction settlement ${transactionId} is not valid JSON.`,
260
+ );
261
+ }
262
+ const rawSettlement = ProjectStateTransactionSettlementV1Schema.parse(value);
263
+ if (rawSettlement.transactionId !== TransactionIdSchema.parse(transactionId)) {
264
+ throw new CliError(
265
+ "invalid-data",
266
+ `Project transaction settlement path does not match ${transactionId}.`,
267
+ );
268
+ }
269
+ if (text !== `${canonicalJson(rawSettlement)}\n`) {
270
+ throw new CliError(
271
+ "invalid-data",
272
+ `Project transaction settlement ${transactionId} is not canonical immutable JSON.`,
273
+ );
274
+ }
275
+ const [before, after] = await Promise.all([
276
+ loadGeneration(fileSystem, rawSettlement.before, `before ${transactionId}`),
277
+ loadGeneration(fileSystem, rawSettlement.after, `after ${transactionId}`),
278
+ ]);
279
+ if (
280
+ before.project.projectId !== rawSettlement.projectId
281
+ || after.project.projectId !== rawSettlement.projectId
282
+ ) {
283
+ throw new CliError(
284
+ "invalid-data",
285
+ `Project transaction settlement ${transactionId} references another project.`,
286
+ );
287
+ }
288
+ return ProjectStateTransactionSettlementV1Schema.parse({
289
+ ...rawSettlement,
290
+ kind: "slopcamera.project-state-transaction-settlement",
291
+ });
292
+ }
293
+
294
+ async function publishTransactionSettlement(
295
+ fileSystem: BundleFileSystem,
296
+ transaction: Extract<ProjectStateTransactionV1, { readonly phase: "settled" }>,
297
+ ): Promise<void> {
298
+ const settlement = ProjectStateTransactionSettlementV1Schema.parse({
299
+ active: transaction.active,
300
+ after: transaction.after,
301
+ before: transaction.before,
302
+ kind: "slopcamera.project-state-transaction-settlement",
303
+ projectId: transaction.projectId,
304
+ schemaVersion: 1,
305
+ transactionId: transaction.transactionId,
306
+ });
307
+ const existing = await loadProjectStateTransactionSettlement(
308
+ fileSystem,
309
+ transaction.transactionId,
310
+ );
311
+ if (existing !== null) {
312
+ if (canonicalJson(existing) !== canonicalJson(settlement)) {
313
+ throw new CliError(
314
+ "invalid-data",
315
+ `Project transaction ${transaction.transactionId} has conflicting immutable settlement evidence.`,
316
+ );
317
+ }
318
+ return;
319
+ }
320
+ const current = validateGeneration({
321
+ plan: await loadProjectEditPlan(fileSystem),
322
+ project: await loadVideoProject(fileSystem),
323
+ }, "Settled current");
324
+ const active = transaction[transaction.active];
325
+ const activeGeneration = await loadGeneration(
326
+ fileSystem,
327
+ active,
328
+ `settled active ${transaction.transactionId}`,
329
+ );
330
+ if (
331
+ canonicalJsonSha256(current.plan) !== canonicalJsonSha256(activeGeneration.plan)
332
+ || canonicalJsonSha256(current.project) !== canonicalJsonSha256(activeGeneration.project)
333
+ ) {
334
+ throw new CliError(
335
+ "invalid-data",
336
+ `Project transaction ${transaction.transactionId} cannot prove its settled active generation.`,
337
+ );
338
+ }
339
+ const contents = `${canonicalJson(settlement)}\n`;
340
+ try {
341
+ await saveImmutableText(
342
+ fileSystem,
343
+ projectStateTransactionSettlementPath(transaction.transactionId),
344
+ contents,
345
+ sha256Hex(contents),
346
+ );
347
+ } catch (error) {
348
+ throw new CliError(
349
+ "invalid-data",
350
+ `Project transaction ${transaction.transactionId} could not publish immutable settlement evidence.`,
351
+ { failure: error instanceof Error ? error.message : String(error) },
352
+ );
353
+ }
354
+ }
355
+
356
+ async function installGeneration(
357
+ fileSystem: BundleFileSystem,
358
+ generation: ProjectGeneration,
359
+ ): Promise<void> {
360
+ // The marker remains non-settled across both replacements, so unlocked readers
361
+ // reject either intermediate pairing instead of observing a mixed generation.
362
+ await saveProjectEditPlan(fileSystem, generation.plan);
363
+ await saveVideoProject(fileSystem, generation.project);
364
+ }
365
+
366
+ function transactionWithPhase(
367
+ transaction: ProjectStateTransactionV1,
368
+ phase: "prepare" | "commit-ready",
369
+ ): ProjectStateTransactionV1 {
370
+ return ProjectStateTransactionV1Schema.parse({
371
+ after: transaction.after,
372
+ before: transaction.before,
373
+ kind: "slopcamera.project-state-transaction",
374
+ phase,
375
+ projectId: transaction.projectId,
376
+ schemaVersion: transaction.schemaVersion,
377
+ transactionId: transaction.transactionId,
378
+ });
379
+ }
380
+
381
+ function settledTransaction(
382
+ transaction: ProjectStateTransactionV1,
383
+ active: "before" | "after",
384
+ ): ProjectStateTransactionV1 {
385
+ return ProjectStateTransactionV1Schema.parse({
386
+ after: transaction.after,
387
+ before: transaction.before,
388
+ active,
389
+ kind: "slopcamera.project-state-transaction",
390
+ phase: "settled",
391
+ projectId: transaction.projectId,
392
+ schemaVersion: transaction.schemaVersion,
393
+ transactionId: transaction.transactionId,
394
+ });
395
+ }
396
+
397
+ export async function assertProjectStateTransactionSettled(
398
+ fileSystem: BundleFileSystem,
399
+ ): Promise<void> {
400
+ const transaction = await readTransaction(fileSystem);
401
+ if (transaction === null || transaction.phase === "settled") return;
402
+ throw new CliError(
403
+ "conflict",
404
+ "The project has an interrupted state transaction. Run any mutating project command to recover it under the project lock.",
405
+ { phase: transaction.phase, transactionId: transaction.transactionId },
406
+ );
407
+ }
408
+
409
+ export async function recoverProjectStateTransaction(
410
+ fileSystem: BundleFileSystem,
411
+ expectedProjectId?: string,
412
+ ): Promise<"none" | "settled" | "rolled-back" | "rolled-forward"> {
413
+ const transaction = await readTransaction(fileSystem);
414
+ if (transaction === null) return "none";
415
+ if (expectedProjectId !== undefined && transaction.projectId !== expectedProjectId) throw new CliError("conflict", "Legacy recovery journal belongs to a different project directory.");
416
+ // A historical V1 journal must never restore the pair over a V2 authority.
417
+ // Inspect the version marker before any recovery write, even for corrupt V2.
418
+ const authority: unknown = JSON.parse(await fileSystem.readText("project.json"));
419
+ if (typeof authority === "object" && authority !== null && !Array.isArray(authority)
420
+ && (("schemaVersion" in authority && authority.schemaVersion === 2)
421
+ || ("kind" in authority && authority.kind === "slopcamera.spatial-project-head"))) {
422
+ throw new CliError("unsupported-plan", "This project uses spatial V2 authority. Use slopcamera scene project commands; legacy recovery cannot modify it.");
423
+ }
424
+ if (transaction.phase === "settled") {
425
+ await publishTransactionSettlement(fileSystem, transaction);
426
+ return "settled";
427
+ }
428
+ const active = transaction.phase === "prepare" ? "before" : "after";
429
+ const generation = await loadGeneration(
430
+ fileSystem,
431
+ transaction[active],
432
+ `${active} ${transaction.transactionId}`,
433
+ );
434
+ if (generation.project.projectId !== transaction.projectId) {
435
+ throw new CliError("invalid-data", "Project transaction generation belongs to another project.");
436
+ }
437
+ await installGeneration(fileSystem, generation);
438
+ const settled = settledTransaction(transaction, active);
439
+ await writeTransaction(fileSystem, settled);
440
+ if (settled.phase !== "settled") {
441
+ throw new CliError("internal", "Project transaction settlement lost its phase.");
442
+ }
443
+ await publishTransactionSettlement(fileSystem, settled);
444
+ return active === "before" ? "rolled-back" : "rolled-forward";
445
+ }
446
+
447
+ export async function commitProjectStateTransaction(options: {
448
+ readonly after: ProjectGeneration;
449
+ readonly before: ProjectGeneration;
450
+ readonly fileSystem: BundleFileSystem;
451
+ readonly transactionId?: string;
452
+ }): Promise<ProjectGeneration> {
453
+ const before = validateGeneration(options.before, "Prior");
454
+ const after = validateGeneration(options.after, "Next");
455
+ if (before.project.projectId !== after.project.projectId) {
456
+ throw new CliError("invalid-data", "Project state transaction cannot cross project identities.");
457
+ }
458
+ const current = validateGeneration({
459
+ plan: await loadProjectEditPlan(options.fileSystem),
460
+ project: await loadVideoProject(options.fileSystem),
461
+ }, "Current");
462
+ if (
463
+ canonicalJsonSha256(current.plan) !== canonicalJsonSha256(before.plan)
464
+ || canonicalJsonSha256(current.project) !== canonicalJsonSha256(before.project)
465
+ ) {
466
+ throw new CliError("conflict", "Project state changed before its structural transaction could begin.");
467
+ }
468
+ const transactionId = TransactionIdSchema.parse(
469
+ options.transactionId ?? `transaction_${randomUUID().replaceAll("-", "")}`,
470
+ );
471
+ const transaction = ProjectStateTransactionV1Schema.parse({
472
+ after: referenceFor(transactionId, "after", after),
473
+ before: referenceFor(transactionId, "before", before),
474
+ kind: "slopcamera.project-state-transaction",
475
+ phase: "prepare",
476
+ projectId: before.project.projectId,
477
+ schemaVersion: 1,
478
+ transactionId,
479
+ });
480
+
481
+ await saveGeneration(options.fileSystem, transaction.before, before);
482
+ await saveGeneration(options.fileSystem, transaction.after, after);
483
+ await writeTransaction(options.fileSystem, transaction);
484
+ let commitReady = false;
485
+ try {
486
+ await installGeneration(options.fileSystem, after);
487
+ await writeTransaction(options.fileSystem, transactionWithPhase(transaction, "commit-ready"));
488
+ commitReady = true;
489
+ const settled = settledTransaction(transaction, "after");
490
+ await writeTransaction(options.fileSystem, settled);
491
+ if (settled.phase !== "settled") {
492
+ throw new CliError("internal", "Project transaction settlement lost its phase.");
493
+ }
494
+ await publishTransactionSettlement(options.fileSystem, settled);
495
+ } catch (error) {
496
+ const active = commitReady ? "after" : "before";
497
+ try {
498
+ await installGeneration(options.fileSystem, active === "after" ? after : before);
499
+ const settled = settledTransaction(transaction, active);
500
+ await writeTransaction(options.fileSystem, settled);
501
+ if (settled.phase !== "settled") {
502
+ throw new CliError("internal", "Project transaction settlement lost its phase.");
503
+ }
504
+ await publishTransactionSettlement(options.fileSystem, settled);
505
+ } catch (recoveryError) {
506
+ throw new CliError(
507
+ "invalid-data",
508
+ `Project state transaction ${transactionId} could not settle; the next mutating project command must recover it.`,
509
+ {
510
+ failure: error instanceof Error ? error.message : String(error),
511
+ projectStateTransaction: "unresolved",
512
+ recoveryFailure: recoveryError instanceof Error ? recoveryError.message : String(recoveryError),
513
+ transactionId,
514
+ },
515
+ );
516
+ }
517
+ if (!commitReady) throw error;
518
+ }
519
+ return after;
520
+ }
@@ -0,0 +1 @@
1
+ export const MAX_EVENT_QUERY_LIMIT = 10_000;