@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,580 @@
1
+ import type { z } from "zod"
2
+
3
+ import {
4
+ isComputeGraphNode,
5
+ isOperationGraphNode,
6
+ type AuthoredGraphNodeV1,
7
+ type CompiledWorkflowGraph,
8
+ type GraphCompilerLimits,
9
+ type GraphInputValue,
10
+ type JsonValue,
11
+ type OperationPolicy,
12
+ type Ref,
13
+ type SerializedRefV1,
14
+ type WorkflowOutputBinding,
15
+ type WorkflowOutputValue,
16
+ } from "./contracts.js"
17
+ import {
18
+ compileWorkflowGraph,
19
+ } from "./compiler.js"
20
+ import {
21
+ canonicalJsonSha256Prefixed,
22
+ } from "./canonical-json.js"
23
+ import { parseCodeBoundary } from "./boundary.js"
24
+ import {
25
+ buildWorkflow,
26
+ type BuiltWorkflow,
27
+ type WorkflowDefinition,
28
+ } from "./define-workflow.js"
29
+ import {
30
+ SlopcameraCodeError,
31
+ slopcameraCodeErrorMessage,
32
+ type SlopcameraCodeErrorCode,
33
+ } from "./errors.js"
34
+ import {
35
+ PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS,
36
+ isPortableSlopcameraOperationKind,
37
+ type PortableSlopcameraOperationInputMap,
38
+ type PortableSlopcameraOperationKind,
39
+ type PortableSlopcameraOperationResultMap,
40
+ } from "./public-operations.js"
41
+ import { PUBLIC_WORKFLOW_REGISTRY_PROJECTION } from "./projection.js"
42
+ import {
43
+ createBoundedJsonSnapshot,
44
+ createBoundedJsonValueSnapshot,
45
+ type BoundedJsonSnapshot,
46
+ } from "./json-snapshot.js"
47
+
48
+ export const WORKFLOW_NODE_RECEIPT_VERSION =
49
+ "slopcamera-workflow-node-receipt-v1" as const
50
+ export const WORKFLOW_NODE_RECEIPT_HASH_DOMAIN =
51
+ "slopcamera.workflow.node-receipt/v1" as const
52
+ export const MAX_WORKFLOW_RESULT_BYTES = 96 * 1024 * 1024
53
+ // Output bindings and one resolved node output compose at this boundary.
54
+ export const MAX_WORKFLOW_RESULT_DEPTH = 320
55
+ export const MAX_WORKFLOW_RESULT_VALUES = 1_300_000
56
+
57
+ export interface SlopcameraCodeExecutionRequest<
58
+ Kind extends PortableSlopcameraOperationKind = PortableSlopcameraOperationKind,
59
+ > {
60
+ readonly input: PortableSlopcameraOperationInputMap[Kind]
61
+ readonly kind: Kind
62
+ readonly nodeKey: string
63
+ readonly version: 2
64
+ }
65
+
66
+ export interface SlopcameraCodeExecutionContext {
67
+ readonly signal: AbortSignal
68
+ }
69
+
70
+ export type SlopcameraCodeExecutor = <Kind extends PortableSlopcameraOperationKind>(
71
+ request: SlopcameraCodeExecutionRequest<Kind>,
72
+ context: SlopcameraCodeExecutionContext,
73
+ ) => Promise<PortableSlopcameraOperationResultMap[Kind]>
74
+
75
+ export interface SlopcameraCodeAdmissionRequest {
76
+ readonly kind: PortableSlopcameraOperationKind
77
+ readonly nodeKey: string
78
+ readonly policy: OperationPolicy
79
+ readonly version: 2
80
+ }
81
+
82
+ export type SlopcameraCodeAdmission = <Result>(
83
+ request: SlopcameraCodeAdmissionRequest,
84
+ execute: () => Promise<Result>,
85
+ context: SlopcameraCodeExecutionContext,
86
+ ) => Promise<Result>
87
+
88
+ export interface SlopcameraCodeHost {
89
+ readonly admit?: SlopcameraCodeAdmission
90
+ readonly execute: SlopcameraCodeExecutor
91
+ }
92
+
93
+ export interface CreateSlopcameraCodeHostOptions {
94
+ readonly admit?: SlopcameraCodeAdmission
95
+ readonly execute: SlopcameraCodeExecutor
96
+ }
97
+
98
+ export function createSlopcameraCodeHost(
99
+ options: CreateSlopcameraCodeHostOptions,
100
+ ): SlopcameraCodeHost {
101
+ if (typeof options !== "object" || options === null) {
102
+ throw new SlopcameraCodeError(
103
+ "invalid-data",
104
+ "An Slopcamera Code host must be an object.",
105
+ )
106
+ }
107
+ if (typeof options.execute !== "function") {
108
+ throw new SlopcameraCodeError(
109
+ "invalid-data",
110
+ "An Slopcamera Code host requires an execute function.",
111
+ )
112
+ }
113
+ if (options.admit !== undefined && typeof options.admit !== "function") {
114
+ throw new SlopcameraCodeError(
115
+ "invalid-data",
116
+ "An Slopcamera Code host admit value must be a function when provided.",
117
+ )
118
+ }
119
+ return Object.freeze({
120
+ ...(options.admit === undefined ? {} : { admit: options.admit }),
121
+ execute: options.execute,
122
+ })
123
+ }
124
+
125
+ export interface WorkflowNodeReceipt {
126
+ readonly index: number
127
+ readonly inputSha256: string
128
+ readonly kind: PortableSlopcameraOperationKind
129
+ readonly nodeKey: string
130
+ readonly outputSha256: string
131
+ readonly receiptSha256: string
132
+ readonly version: typeof WORKFLOW_NODE_RECEIPT_VERSION
133
+ readonly operationVersion: 2
134
+ }
135
+
136
+ export interface FailedWorkflowNode {
137
+ readonly kind: PortableSlopcameraOperationKind
138
+ readonly nodeKey: string
139
+ readonly version: 2
140
+ }
141
+
142
+ export class SlopcameraWorkflowRunError extends SlopcameraCodeError {
143
+ readonly completedReceipts: readonly WorkflowNodeReceipt[]
144
+ readonly failedNode: FailedWorkflowNode | undefined
145
+ readonly runCause: unknown
146
+
147
+ constructor(
148
+ code: SlopcameraCodeErrorCode,
149
+ message: string,
150
+ options: {
151
+ readonly cause: unknown
152
+ readonly completedReceipts: readonly WorkflowNodeReceipt[]
153
+ readonly failedNode?: FailedWorkflowNode
154
+ },
155
+ ) {
156
+ const failedNode = options.failedNode === undefined
157
+ ? undefined
158
+ : Object.freeze({ ...options.failedNode })
159
+ const completedReceipts = Object.freeze([...options.completedReceipts])
160
+ super(code, message, {
161
+ completedReceiptCount: completedReceipts.length,
162
+ ...(failedNode === undefined ? {} : { failedNode }),
163
+ })
164
+ this.name = "SlopcameraWorkflowRunError"
165
+ this.completedReceipts = completedReceipts
166
+ this.failedNode = failedNode
167
+ this.runCause = options.cause
168
+ }
169
+ }
170
+
171
+ export type ResolvedWorkflowOutput<Value> =
172
+ Value extends Ref<infer Output>
173
+ ? Output
174
+ : Value extends readonly (infer Item)[]
175
+ ? readonly ResolvedWorkflowOutput<Item>[]
176
+ : Value extends Readonly<Record<string, unknown>>
177
+ ? { readonly [Key in keyof Value]: ResolvedWorkflowOutput<Value[Key]> }
178
+ : never
179
+
180
+ export interface WorkflowRunResult<Output = JsonValue> {
181
+ readonly compilation: CompiledWorkflowGraph
182
+ readonly output: Output
183
+ readonly receipts: readonly WorkflowNodeReceipt[]
184
+ }
185
+
186
+ export interface RunBuiltWorkflowOptions {
187
+ readonly host: SlopcameraCodeHost
188
+ readonly limits?: Partial<GraphCompilerLimits>
189
+ readonly signal?: AbortSignal
190
+ }
191
+
192
+ function isSerializedRef(value: unknown): value is SerializedRefV1 {
193
+ return typeof value === "object"
194
+ && value !== null
195
+ && !Array.isArray(value)
196
+ && Object.hasOwn(value, "$ref")
197
+ }
198
+
199
+ function projectedValue(
200
+ reference: SerializedRefV1,
201
+ values: ReadonlyMap<string, JsonValue>,
202
+ ): JsonValue {
203
+ let current = values.get(reference.$ref.nodeKey)
204
+ if (current === undefined) {
205
+ throw new SlopcameraCodeError(
206
+ "internal",
207
+ `Workflow reference producer ${reference.$ref.nodeKey} has not completed.`,
208
+ { nodeKey: reference.$ref.nodeKey },
209
+ )
210
+ }
211
+ for (const segment of reference.$ref.path ?? []) {
212
+ if (typeof segment === "number") {
213
+ if (!Array.isArray(current) || segment >= current.length) {
214
+ throw new SlopcameraCodeError(
215
+ "invalid-data",
216
+ `Workflow reference ${reference.$ref.nodeKey} has an invalid array projection.`,
217
+ { nodeKey: reference.$ref.nodeKey, segment },
218
+ )
219
+ }
220
+ const currentArray = current as readonly JsonValue[]
221
+ current = currentArray[segment]
222
+ } else {
223
+ if (
224
+ typeof current !== "object"
225
+ || current === null
226
+ || Array.isArray(current)
227
+ || !Object.hasOwn(current, segment)
228
+ ) {
229
+ throw new SlopcameraCodeError(
230
+ "invalid-data",
231
+ `Workflow reference ${reference.$ref.nodeKey} has an invalid object projection.`,
232
+ { nodeKey: reference.$ref.nodeKey, segment },
233
+ )
234
+ }
235
+ current = (current as Readonly<Record<string, JsonValue>>)[segment]
236
+ }
237
+ if (current === undefined) {
238
+ throw new SlopcameraCodeError(
239
+ "invalid-data",
240
+ `Workflow reference ${reference.$ref.nodeKey} projected an undefined value.`,
241
+ { nodeKey: reference.$ref.nodeKey, segment },
242
+ )
243
+ }
244
+ }
245
+ return current
246
+ }
247
+
248
+ function resolveValue(
249
+ value: GraphInputValue | WorkflowOutputBinding,
250
+ values: ReadonlyMap<string, JsonValue>,
251
+ ): JsonValue {
252
+ if (isSerializedRef(value)) return projectedValue(value, values)
253
+ if (Array.isArray(value)) {
254
+ const items = value as readonly (GraphInputValue | WorkflowOutputBinding)[]
255
+ return items.map(item => resolveValue(item, values))
256
+ }
257
+ if (typeof value === "object" && value !== null) {
258
+ const record = value as Readonly<Record<string, GraphInputValue | WorkflowOutputBinding>>
259
+ const output: Record<string, JsonValue> = {}
260
+ for (const key of Object.keys(record).sort()) {
261
+ const item = record[key]
262
+ if (item === undefined) {
263
+ throw new SlopcameraCodeError(
264
+ "internal",
265
+ `Compiled workflow value ${key} is undefined.`,
266
+ )
267
+ }
268
+ output[key] = resolveValue(item, values)
269
+ }
270
+ return output
271
+ }
272
+ return value
273
+ }
274
+
275
+ function createNodeReceipt(
276
+ index: number,
277
+ nodeKey: string,
278
+ kind: PortableSlopcameraOperationKind,
279
+ inputSha256: string,
280
+ outputSha256: string,
281
+ ): WorkflowNodeReceipt {
282
+ const unsigned = {
283
+ index,
284
+ inputSha256,
285
+ kind,
286
+ nodeKey,
287
+ operationVersion: 2 as const,
288
+ outputSha256,
289
+ version: WORKFLOW_NODE_RECEIPT_VERSION,
290
+ }
291
+ return Object.freeze({
292
+ ...unsigned,
293
+ receiptSha256: canonicalJsonSha256Prefixed(
294
+ `${WORKFLOW_NODE_RECEIPT_HASH_DOMAIN}\0`,
295
+ unsigned,
296
+ ),
297
+ })
298
+ }
299
+
300
+ function publicOperationNode(
301
+ node: AuthoredGraphNodeV1,
302
+ ): asserts node is AuthoredGraphNodeV1 & {
303
+ readonly executor: {
304
+ readonly kind: "operation"
305
+ readonly operation: {
306
+ readonly kind: PortableSlopcameraOperationKind
307
+ readonly version: 2
308
+ }
309
+ }
310
+ } {
311
+ if (isComputeGraphNode(node)) {
312
+ throw new SlopcameraCodeError(
313
+ "unsupported-plan",
314
+ `The public projection does not support trusted compute at node ${node.key}.`,
315
+ {
316
+ executorKind: "compute",
317
+ nodeKey: node.key,
318
+ projectionId: PUBLIC_WORKFLOW_REGISTRY_PROJECTION.id,
319
+ },
320
+ )
321
+ }
322
+ if (!isOperationGraphNode(node)) {
323
+ throw new SlopcameraCodeError(
324
+ "unsupported-plan",
325
+ `The public projection does not support the executor at node ${node.key}.`,
326
+ { nodeKey: node.key, projectionId: PUBLIC_WORKFLOW_REGISTRY_PROJECTION.id },
327
+ )
328
+ }
329
+ const operation = node.executor.operation
330
+ if (
331
+ operation.version !== 2
332
+ || !isPortableSlopcameraOperationKind(operation.kind)
333
+ ) {
334
+ throw new SlopcameraCodeError(
335
+ "unsupported-plan",
336
+ `Unsupported operation: ${operation.kind}@${String(operation.version)}`,
337
+ {
338
+ kind: operation.kind,
339
+ nodeKey: node.key,
340
+ projectionId: PUBLIC_WORKFLOW_REGISTRY_PROJECTION.id,
341
+ version: operation.version,
342
+ },
343
+ )
344
+ }
345
+ }
346
+
347
+ function throwIfAborted(signal: AbortSignal): void {
348
+ if (signal.aborted) {
349
+ throw new SlopcameraCodeError("cancelled", "Workflow execution was cancelled.")
350
+ }
351
+ }
352
+
353
+ function workflowNodeFailure(
354
+ error: unknown,
355
+ node: AuthoredGraphNodeV1 & {
356
+ readonly executor: {
357
+ readonly kind: "operation"
358
+ readonly operation: {
359
+ readonly kind: PortableSlopcameraOperationKind
360
+ readonly version: 2
361
+ }
362
+ }
363
+ },
364
+ completedReceipts: readonly WorkflowNodeReceipt[],
365
+ ): SlopcameraWorkflowRunError {
366
+ const code = error instanceof SlopcameraCodeError ? error.code : "subprocess"
367
+ return new SlopcameraWorkflowRunError(
368
+ code,
369
+ `Workflow node ${node.key} (${node.executor.operation.kind}@2) failed: `
370
+ + slopcameraCodeErrorMessage(error),
371
+ {
372
+ cause: error,
373
+ completedReceipts,
374
+ failedNode: {
375
+ kind: node.executor.operation.kind,
376
+ nodeKey: node.key,
377
+ version: 2,
378
+ },
379
+ },
380
+ )
381
+ }
382
+
383
+ function workflowRunFailure(
384
+ error: unknown,
385
+ message: string,
386
+ completedReceipts: readonly WorkflowNodeReceipt[],
387
+ ): SlopcameraWorkflowRunError {
388
+ const code = error instanceof SlopcameraCodeError ? error.code : "internal"
389
+ return new SlopcameraWorkflowRunError(code, message, {
390
+ cause: error,
391
+ completedReceipts,
392
+ })
393
+ }
394
+
395
+ async function executePublicNode(
396
+ host: SlopcameraCodeHost,
397
+ node: AuthoredGraphNodeV1 & {
398
+ readonly executor: {
399
+ readonly kind: "operation"
400
+ readonly operation: {
401
+ readonly kind: PortableSlopcameraOperationKind
402
+ readonly version: 2
403
+ }
404
+ }
405
+ },
406
+ values: ReadonlyMap<string, JsonValue>,
407
+ context: SlopcameraCodeExecutionContext,
408
+ ): Promise<{
409
+ readonly input: BoundedJsonSnapshot
410
+ readonly output: BoundedJsonSnapshot
411
+ }> {
412
+ const { kind } = node.executor.operation
413
+ const contract = PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS[kind]
414
+ const resolvedInput = resolveValue(node.input, values)
415
+ const rawInput = createBoundedJsonValueSnapshot(
416
+ resolvedInput,
417
+ contract.policy.maxInputBytes,
418
+ `${kind} raw input at node ${node.key}`,
419
+ )
420
+ const parsedInput = parseCodeBoundary(
421
+ contract.inputSchema as z.ZodType<unknown>,
422
+ rawInput.value,
423
+ `${kind} input at node ${node.key}`,
424
+ ) as PortableSlopcameraOperationInputMap[typeof kind]
425
+ const boundedInput = createBoundedJsonSnapshot(
426
+ parsedInput,
427
+ contract.policy.maxInputBytes,
428
+ `${kind} input at node ${node.key}`,
429
+ )
430
+ const request: SlopcameraCodeExecutionRequest<typeof kind> = Object.freeze({
431
+ input: boundedInput.value as unknown as PortableSlopcameraOperationInputMap[
432
+ typeof kind
433
+ ],
434
+ kind,
435
+ nodeKey: node.key,
436
+ version: 2,
437
+ })
438
+ throwIfAborted(context.signal)
439
+ const dispatch = async () => await host.execute(request, context)
440
+ const rawOutput = host.admit === undefined
441
+ ? await dispatch()
442
+ : await host.admit(Object.freeze({
443
+ kind,
444
+ nodeKey: node.key,
445
+ policy: contract.policy,
446
+ version: 2,
447
+ }), dispatch, context)
448
+ const boundedRawOutput = createBoundedJsonValueSnapshot(
449
+ rawOutput,
450
+ contract.policy.maxOutputBytes,
451
+ `${kind} raw output at node ${node.key}`,
452
+ )
453
+ const parsedOutput = parseCodeBoundary(
454
+ contract.outputSchema as z.ZodType<unknown>,
455
+ boundedRawOutput.value,
456
+ `${kind} output at node ${node.key}`,
457
+ )
458
+ return Object.freeze({
459
+ input: boundedInput,
460
+ output: createBoundedJsonSnapshot(
461
+ parsedOutput,
462
+ contract.policy.maxOutputBytes,
463
+ `${kind} output at node ${node.key}`,
464
+ ),
465
+ })
466
+ }
467
+
468
+ export async function runBuiltWorkflow<
469
+ Input extends JsonValue,
470
+ Output extends WorkflowOutputValue,
471
+ >(
472
+ built: BuiltWorkflow<Input, Output>,
473
+ options: RunBuiltWorkflowOptions,
474
+ ): Promise<WorkflowRunResult<ResolvedWorkflowOutput<Output>>> {
475
+ // Compilation and the public capability check intentionally precede every
476
+ // host callback, including host-owned admission.
477
+ const compilation = compileWorkflowGraph({
478
+ graph: built.graph,
479
+ limits: options.limits,
480
+ projection: PUBLIC_WORKFLOW_REGISTRY_PROJECTION,
481
+ })
482
+ for (const node of compilation.graph.nodes) publicOperationNode(node)
483
+ const host = createSlopcameraCodeHost(options.host)
484
+ const context = Object.freeze({
485
+ signal: options.signal ?? new AbortController().signal,
486
+ })
487
+ throwIfAborted(context.signal)
488
+
489
+ const nodes = new Map(compilation.graph.nodes.map(node => [node.key, node]))
490
+ const values = new Map<string, JsonValue>()
491
+ const receipts: WorkflowNodeReceipt[] = []
492
+ for (const wave of compilation.topologicalWaves) {
493
+ const outcomes = await Promise.all(wave.map(async (nodeKey) => {
494
+ const node = nodes.get(nodeKey)
495
+ if (node === undefined) {
496
+ throw new SlopcameraCodeError(
497
+ "internal",
498
+ `Compiled workflow topology lost node ${nodeKey}.`,
499
+ { nodeKey },
500
+ )
501
+ }
502
+ publicOperationNode(node)
503
+ try {
504
+ return {
505
+ executed: await executePublicNode(host, node, values, context),
506
+ kind: "executed",
507
+ node,
508
+ } as const
509
+ } catch (error) {
510
+ return { error, kind: "failed", node } as const
511
+ }
512
+ }))
513
+ // Each callback converts rejection to data, so Promise.all drains the
514
+ // complete dispatched wave before the runtime returns an error.
515
+ for (const outcome of outcomes) {
516
+ if (outcome.kind !== "executed") continue
517
+ values.set(outcome.node.key, outcome.executed.output.value)
518
+ receipts.push(createNodeReceipt(
519
+ receipts.length,
520
+ outcome.node.key,
521
+ outcome.node.executor.operation.kind,
522
+ outcome.executed.input.sha256,
523
+ outcome.executed.output.sha256,
524
+ ))
525
+ }
526
+ const failure = outcomes.find(
527
+ (outcome): outcome is Extract<typeof outcome, { readonly kind: "failed" }> => (
528
+ outcome.kind === "failed"
529
+ ),
530
+ )
531
+ if (failure !== undefined) {
532
+ throw workflowNodeFailure(failure.error, failure.node, receipts)
533
+ }
534
+ if (context.signal.aborted) {
535
+ const cause = new SlopcameraCodeError(
536
+ "cancelled",
537
+ "Workflow execution was cancelled.",
538
+ )
539
+ throw workflowRunFailure(
540
+ cause,
541
+ "Workflow execution was cancelled after the current wave settled.",
542
+ receipts,
543
+ )
544
+ }
545
+ }
546
+ let output: ResolvedWorkflowOutput<Output>
547
+ try {
548
+ output = createBoundedJsonValueSnapshot(
549
+ resolveValue(compilation.graph.outputs, values),
550
+ MAX_WORKFLOW_RESULT_BYTES,
551
+ "workflow output",
552
+ {
553
+ maximumDepth: MAX_WORKFLOW_RESULT_DEPTH,
554
+ maximumValues: MAX_WORKFLOW_RESULT_VALUES,
555
+ },
556
+ ).value as ResolvedWorkflowOutput<Output>
557
+ } catch (error) {
558
+ throw workflowRunFailure(
559
+ error,
560
+ `Workflow output resolution failed: ${slopcameraCodeErrorMessage(error)}`,
561
+ receipts,
562
+ )
563
+ }
564
+ return Object.freeze({
565
+ compilation,
566
+ output,
567
+ receipts: Object.freeze(receipts),
568
+ })
569
+ }
570
+
571
+ export async function runWorkflow<
572
+ Input,
573
+ Output extends WorkflowOutputValue,
574
+ >(
575
+ definition: WorkflowDefinition<Input, Output>,
576
+ input: unknown,
577
+ options: RunBuiltWorkflowOptions,
578
+ ): Promise<WorkflowRunResult<ResolvedWorkflowOutput<Output>>> {
579
+ return await runBuiltWorkflow(buildWorkflow(definition, input), options)
580
+ }
@@ -0,0 +1,36 @@
1
+ import { sha256 } from "@noble/hashes/sha2.js"
2
+ import { bytesToHex } from "@noble/hashes/utils.js"
3
+
4
+ const UTF8_ENCODER = new TextEncoder()
5
+
6
+ export interface Sha256HexHasher {
7
+ readonly digestHex: () => string
8
+ readonly update: (input: string | Uint8Array) => void
9
+ }
10
+
11
+ /** Native on Bun, with the same synchronous audited fallback for browsers. */
12
+ export function createSha256HexHasher(): Sha256HexHasher {
13
+ if (typeof Bun !== "undefined") {
14
+ const hasher = new Bun.CryptoHasher("sha256")
15
+ return {
16
+ digestHex: () => hasher.digest("hex"),
17
+ update: (input) => {
18
+ hasher.update(input)
19
+ },
20
+ }
21
+ }
22
+ const hasher = sha256.create()
23
+ return {
24
+ digestHex: () => bytesToHex(hasher.digest()),
25
+ update: (input) => {
26
+ hasher.update(typeof input === "string" ? UTF8_ENCODER.encode(input) : input)
27
+ },
28
+ }
29
+ }
30
+
31
+ /** Synchronous SHA-256 over exact UTF-8 bytes in Bun, Node, and browsers. */
32
+ export function sha256Hex(input: string): string {
33
+ const hasher = createSha256HexHasher()
34
+ hasher.update(input)
35
+ return hasher.digestHex()
36
+ }