@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,88 @@
1
+ /**
2
+ * Returns the exact UTF-8 byte length of JSON.stringify(value) without first
3
+ * allocating the serialized string. Undefined means the caller-provided byte
4
+ * ceiling was exceeded.
5
+ */
6
+ export function jsonStringUtf8ByteLength(
7
+ value: string,
8
+ maximumBytes = Number.MAX_SAFE_INTEGER,
9
+ ): number | undefined {
10
+ if (!Number.isSafeInteger(maximumBytes) || maximumBytes < 0) return undefined
11
+
12
+ let bytes = 2 // Opening and closing quotes.
13
+ if (bytes > maximumBytes) return undefined
14
+
15
+ for (let index = 0; index < value.length; index += 1) {
16
+ const codeUnit = value.charCodeAt(index)
17
+ let additional: number
18
+
19
+ if (
20
+ codeUnit === 0x22
21
+ || codeUnit === 0x5c
22
+ || codeUnit === 0x08
23
+ || codeUnit === 0x09
24
+ || codeUnit === 0x0a
25
+ || codeUnit === 0x0c
26
+ || codeUnit === 0x0d
27
+ ) {
28
+ additional = 2
29
+ } else if (codeUnit < 0x20) {
30
+ additional = 6
31
+ } else if (codeUnit < 0x80) {
32
+ additional = 1
33
+ } else if (codeUnit < 0x800) {
34
+ additional = 2
35
+ } else if (codeUnit >= 0xd800 && codeUnit <= 0xdbff) {
36
+ const next = value.charCodeAt(index + 1)
37
+ if (next >= 0xdc00 && next <= 0xdfff) {
38
+ additional = 4
39
+ index += 1
40
+ } else {
41
+ // Well-formed JSON.stringify escapes lone UTF-16 surrogates as \udxxx.
42
+ additional = 6
43
+ }
44
+ } else if (codeUnit >= 0xdc00 && codeUnit <= 0xdfff) {
45
+ additional = 6
46
+ } else {
47
+ additional = 3
48
+ }
49
+
50
+ if (additional > maximumBytes - bytes) return undefined
51
+ bytes += additional
52
+ }
53
+
54
+ return bytes
55
+ }
56
+
57
+ /** Exact TextEncoder byte length with an optional allocation-free cutoff. */
58
+ export function utf8ByteLength(
59
+ value: string,
60
+ maximumBytes = Number.MAX_SAFE_INTEGER,
61
+ ): number | undefined {
62
+ if (!Number.isSafeInteger(maximumBytes) || maximumBytes < 0) return undefined
63
+
64
+ let bytes = 0
65
+ for (let index = 0; index < value.length; index += 1) {
66
+ const codeUnit = value.charCodeAt(index)
67
+ let additional: number
68
+ if (codeUnit < 0x80) {
69
+ additional = 1
70
+ } else if (codeUnit < 0x800) {
71
+ additional = 2
72
+ } else if (codeUnit >= 0xd800 && codeUnit <= 0xdbff) {
73
+ const next = value.charCodeAt(index + 1)
74
+ if (next >= 0xdc00 && next <= 0xdfff) {
75
+ additional = 4
76
+ index += 1
77
+ } else {
78
+ // TextEncoder replaces malformed UTF-16 with U+FFFD.
79
+ additional = 3
80
+ }
81
+ } else {
82
+ additional = 3
83
+ }
84
+ if (additional > maximumBytes - bytes) return undefined
85
+ bytes += additional
86
+ }
87
+ return bytes
88
+ }
@@ -0,0 +1,136 @@
1
+ import {
2
+ type AuthoredWorkflowGraphV1,
3
+ type OperationInputValue,
4
+ type Ref,
5
+ type WorkflowIdentity,
6
+ type WorkflowOutputValue,
7
+ } from "./contracts.js"
8
+ import {
9
+ WorkflowGraphBuilder,
10
+ type OperationNodeOptions,
11
+ } from "./graph-builder.js"
12
+ import {
13
+ PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS,
14
+ type SlopcameraDiagramCheckInput,
15
+ type SlopcameraDiagramCheckOutput,
16
+ type SlopcameraDiagramRenderInput,
17
+ type SlopcameraDiagramRenderOutput,
18
+ type SlopcameraImageGenerateInput,
19
+ type SlopcameraImageGenerateOutput,
20
+ type SlopcameraImageVectorizeInput,
21
+ type SlopcameraImageVectorizeOutput,
22
+ } from "./public-operations.js"
23
+ import { PUBLIC_WORKFLOW_REGISTRY_PROJECTION } from "./projection.js"
24
+
25
+ export interface PortableWorkflowFragment<Input, Output> {
26
+ build(builder: PortableWorkflowBuilder, input: Input): Output
27
+ }
28
+
29
+ export function definePortableWorkflowFragment<Input, Output>(
30
+ build: (builder: PortableWorkflowBuilder, input: Input) => Output,
31
+ ): PortableWorkflowFragment<Input, Output> {
32
+ return Object.freeze({ build })
33
+ }
34
+
35
+ export class PortableWorkflowBuilder {
36
+ readonly #builder: WorkflowGraphBuilder
37
+
38
+ readonly diagram: Readonly<{
39
+ check: (
40
+ key: string,
41
+ input: OperationInputValue<SlopcameraDiagramCheckInput>,
42
+ options?: OperationNodeOptions,
43
+ ) => Ref<SlopcameraDiagramCheckOutput>
44
+ render: (
45
+ key: string,
46
+ input: OperationInputValue<SlopcameraDiagramRenderInput>,
47
+ options?: OperationNodeOptions,
48
+ ) => Ref<SlopcameraDiagramRenderOutput>
49
+ }>
50
+
51
+ readonly image: Readonly<{
52
+ generate: (
53
+ key: string,
54
+ input: OperationInputValue<SlopcameraImageGenerateInput>,
55
+ options?: OperationNodeOptions,
56
+ ) => Ref<SlopcameraImageGenerateOutput>
57
+ vectorize: (
58
+ key: string,
59
+ input: OperationInputValue<SlopcameraImageVectorizeInput>,
60
+ options?: OperationNodeOptions,
61
+ ) => Ref<SlopcameraImageVectorizeOutput>
62
+ }>
63
+
64
+ private constructor(builder: WorkflowGraphBuilder) {
65
+ this.#builder = builder
66
+ this.diagram = Object.freeze({
67
+ check: (
68
+ key: string,
69
+ input: OperationInputValue<SlopcameraDiagramCheckInput>,
70
+ options: OperationNodeOptions = {},
71
+ ) => this.#builder.operation(
72
+ key,
73
+ PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS["slopcamera.diagram.check"],
74
+ input,
75
+ options,
76
+ ),
77
+ render: (
78
+ key: string,
79
+ input: OperationInputValue<SlopcameraDiagramRenderInput>,
80
+ options: OperationNodeOptions = {},
81
+ ) => this.#builder.operation(
82
+ key,
83
+ PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS["slopcamera.diagram.render"],
84
+ input,
85
+ options,
86
+ ),
87
+ })
88
+ this.image = Object.freeze({
89
+ generate: (
90
+ key: string,
91
+ input: OperationInputValue<SlopcameraImageGenerateInput>,
92
+ options: OperationNodeOptions = {},
93
+ ) => this.#builder.operation(
94
+ key,
95
+ PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS["slopcamera.image.generate"],
96
+ input,
97
+ options,
98
+ ),
99
+ vectorize: (
100
+ key: string,
101
+ input: OperationInputValue<SlopcameraImageVectorizeInput>,
102
+ options: OperationNodeOptions = {},
103
+ ) => this.#builder.operation(
104
+ key,
105
+ PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS["slopcamera.image.vectorize"],
106
+ input,
107
+ options,
108
+ ),
109
+ })
110
+ }
111
+
112
+ static create(): PortableWorkflowBuilder {
113
+ return new PortableWorkflowBuilder(
114
+ WorkflowGraphBuilder.create(PUBLIC_WORKFLOW_REGISTRY_PROJECTION),
115
+ )
116
+ }
117
+
118
+ namespace(segment: string): PortableWorkflowBuilder {
119
+ return new PortableWorkflowBuilder(this.#builder.namespace(segment))
120
+ }
121
+
122
+ fragment<Input, Output>(
123
+ namespace: string,
124
+ fragment: PortableWorkflowFragment<Input, Output>,
125
+ input: Input,
126
+ ): Output {
127
+ return fragment.build(this.namespace(namespace), input)
128
+ }
129
+
130
+ build(
131
+ workflow: WorkflowIdentity,
132
+ outputs: WorkflowOutputValue,
133
+ ): AuthoredWorkflowGraphV1 {
134
+ return this.#builder.build(workflow, outputs)
135
+ }
136
+ }
@@ -0,0 +1,378 @@
1
+ import {
2
+ MAX_OPERATION_DISCOVERY_ENTRIES,
3
+ OPERATION_PREPARATION_KINDS,
4
+ OPERATION_RESOURCE_KINDS,
5
+ OperationDiscoverySchema,
6
+ SchemaIdSchema,
7
+ WorkflowRegistryProjectionSchema,
8
+ type OperationDiscovery,
9
+ type OperationDiscoverySource,
10
+ type WorkflowRegistryProjection,
11
+ } from "./contracts.js"
12
+ import {
13
+ canonicalJsonSha256,
14
+ canonicalJsonSha256Prefixed,
15
+ } from "./canonical-json.js"
16
+ import { parseCodeBoundary } from "./boundary.js"
17
+ import { SlopcameraCodeError } from "./errors.js"
18
+ import { createBoundedJsonValueSnapshot } from "./json-snapshot.js"
19
+ import {
20
+ PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS,
21
+ PORTABLE_SLOPCAMERA_OPERATION_KINDS,
22
+ } from "./public-operations.js"
23
+
24
+ export const WORKFLOW_REGISTRY_PROJECTION_HASH_DOMAIN =
25
+ "slopcamera.workflow.registry-projection/v1" as const
26
+ export const PUBLIC_WORKFLOW_REGISTRY_PROJECTION_ID =
27
+ "slopcamera.workflow.registry.public/v1" as const
28
+
29
+ export type WorkflowRegistryProjectionSource =
30
+ | OperationDiscoverySource
31
+ | readonly OperationDiscovery[]
32
+
33
+ export interface CreateWorkflowRegistryProjectionOptions {
34
+ readonly trustedCompute?: boolean
35
+ }
36
+
37
+ const OWNED_NORMALIZED_PROJECTIONS = new WeakSet<object>()
38
+ const MAX_OPERATION_DISCOVERY_VALUES = 17
39
+ + OPERATION_PREPARATION_KINDS.length
40
+ + (3 * OPERATION_RESOURCE_KINDS.length)
41
+ const MAX_OPERATION_DISCOVERY_LIST_VALUES = 1
42
+ + (MAX_OPERATION_DISCOVERY_ENTRIES * MAX_OPERATION_DISCOVERY_VALUES)
43
+ const MAX_OPERATION_DISCOVERY_LIST_BYTES = 32 * 1024 * 1024
44
+ const MAX_OPERATION_DISCOVERY_LIST_DEPTH = 8
45
+ const MAX_WORKFLOW_REGISTRY_PROJECTION_BYTES =
46
+ MAX_OPERATION_DISCOVERY_LIST_BYTES + 4_096
47
+ const MAX_WORKFLOW_REGISTRY_PROJECTION_DEPTH =
48
+ MAX_OPERATION_DISCOVERY_LIST_DEPTH + 1
49
+ const MAX_WORKFLOW_REGISTRY_PROJECTION_VALUES =
50
+ MAX_OPERATION_DISCOVERY_LIST_VALUES + 5
51
+
52
+ function discoveryList(
53
+ source: WorkflowRegistryProjectionSource,
54
+ ): unknown {
55
+ return Array.isArray(source)
56
+ ? source
57
+ : (source as OperationDiscoverySource).list()
58
+ }
59
+
60
+ export function boundedOperationDiscoveryList(
61
+ input: unknown,
62
+ name = "operation discovery list",
63
+ ): readonly unknown[] {
64
+ if (!Array.isArray(input)) {
65
+ throw new SlopcameraCodeError("invalid-data", `${name} must be an array.`)
66
+ }
67
+ const length = input.length
68
+ if (length > MAX_OPERATION_DISCOVERY_ENTRIES) {
69
+ throw new SlopcameraCodeError(
70
+ "invalid-data",
71
+ `${name} cannot exceed ${String(MAX_OPERATION_DISCOVERY_ENTRIES)} entries.`,
72
+ )
73
+ }
74
+ const descriptors = Object.getOwnPropertyDescriptors(input)
75
+ if (Object.getOwnPropertySymbols(descriptors).some(
76
+ symbol => (Reflect.get(descriptors, symbol) as PropertyDescriptor | undefined)
77
+ ?.enumerable === true,
78
+ )) {
79
+ throw new SlopcameraCodeError(
80
+ "invalid-data",
81
+ `${name} cannot contain enumerable symbol properties.`,
82
+ )
83
+ }
84
+ const keys = Object.keys(descriptors)
85
+ .filter(key => descriptors[key]?.enumerable === true)
86
+ if (
87
+ keys.length !== length
88
+ || keys.some((key, index) => key !== String(index))
89
+ ) {
90
+ throw new SlopcameraCodeError(
91
+ "invalid-data",
92
+ `${name} must be dense and cannot have named properties.`,
93
+ )
94
+ }
95
+ const punctuationBytes = 2 + Math.max(0, length - 1)
96
+ let bytes = punctuationBytes
97
+ let values = 1
98
+ const captured: unknown[] = []
99
+ for (let index = 0; index < length; index += 1) {
100
+ const descriptor = descriptors[String(index)]
101
+ if (
102
+ descriptor === undefined
103
+ || descriptor.get !== undefined
104
+ || descriptor.set !== undefined
105
+ ) {
106
+ throw new SlopcameraCodeError(
107
+ "invalid-data",
108
+ `${name} must contain plain data elements.`,
109
+ )
110
+ }
111
+ const remainingBytes = MAX_OPERATION_DISCOVERY_LIST_BYTES - bytes
112
+ if (remainingBytes < 1) {
113
+ throw new SlopcameraCodeError(
114
+ "invalid-data",
115
+ `${name} contains more than ${String(MAX_OPERATION_DISCOVERY_LIST_BYTES)} bytes.`,
116
+ )
117
+ }
118
+ const snapshot = createBoundedJsonValueSnapshot(
119
+ descriptor.value,
120
+ remainingBytes,
121
+ `${name} entry ${String(index)}`,
122
+ {
123
+ maximumDepth: MAX_OPERATION_DISCOVERY_LIST_DEPTH - 1,
124
+ maximumValues: MAX_OPERATION_DISCOVERY_VALUES,
125
+ },
126
+ )
127
+ bytes += snapshot.bytes
128
+ values += snapshot.values
129
+ if (values > MAX_OPERATION_DISCOVERY_LIST_VALUES) {
130
+ throw new SlopcameraCodeError(
131
+ "invalid-data",
132
+ `${name} contains more than ${String(MAX_OPERATION_DISCOVERY_LIST_VALUES)} JSON values.`,
133
+ )
134
+ }
135
+ captured.push(snapshot.value)
136
+ }
137
+ return Object.freeze(captured)
138
+ }
139
+
140
+ function operationKey(kind: string, version: number): string {
141
+ return `${kind}@${String(version)}`
142
+ }
143
+
144
+ function uniqueSorted<Value extends string>(
145
+ values: Iterable<Value>,
146
+ ): readonly Value[] {
147
+ return [...new Set(values)].sort((left, right) => left.localeCompare(right))
148
+ }
149
+
150
+ function canonicalSlopcameraIdentity(value: string): string {
151
+ if (value === "studio") return "slopcamera"
152
+ return value.replace(/^studio\./u, "slopcamera.")
153
+ }
154
+
155
+ function normalizeOperationDiscoveryPreservingIdentity(
156
+ input: unknown,
157
+ ): readonly OperationDiscovery[] {
158
+ const normalized = boundedOperationDiscoveryList(input).map((item) => {
159
+ const parsed = parseCodeBoundary(
160
+ OperationDiscoverySchema,
161
+ item,
162
+ "operation discovery entry",
163
+ )
164
+ const preparation = uniqueSorted(parsed.policy.preparation)
165
+ if (preparation.length !== parsed.policy.preparation.length) {
166
+ throw new SlopcameraCodeError(
167
+ "invalid-data",
168
+ `Duplicate preparation requirement for ${operationKey(parsed.kind, parsed.version)}.`,
169
+ { kind: parsed.kind, version: parsed.version },
170
+ )
171
+ }
172
+ const resources = [...parsed.policy.resources]
173
+ .sort((left, right) => (
174
+ left.resource.localeCompare(right.resource)
175
+ ))
176
+ if (new Set(resources.map(resource => resource.resource)).size !== resources.length) {
177
+ throw new SlopcameraCodeError(
178
+ "invalid-data",
179
+ `Duplicate resource claim for ${operationKey(parsed.kind, parsed.version)}.`,
180
+ { kind: parsed.kind, version: parsed.version },
181
+ )
182
+ }
183
+ return parseCodeBoundary(OperationDiscoverySchema, {
184
+ ...parsed,
185
+ policy: { ...parsed.policy, preparation, resources },
186
+ }, "normalized operation discovery entry")
187
+ }).sort((left, right) => (
188
+ left.kind.localeCompare(right.kind) || left.version - right.version
189
+ ))
190
+ const seen = new Set<string>()
191
+ for (const operation of normalized) {
192
+ const key = operationKey(operation.kind, operation.version)
193
+ if (seen.has(key)) {
194
+ throw new SlopcameraCodeError(
195
+ "conflict",
196
+ `Duplicate operation discovery entry: ${key}`,
197
+ { kind: operation.kind, version: operation.version },
198
+ )
199
+ }
200
+ seen.add(key)
201
+ }
202
+ return normalized
203
+ }
204
+
205
+ export function normalizeOperationDiscovery(
206
+ input: unknown,
207
+ ): readonly OperationDiscovery[] {
208
+ return normalizeOperationDiscoveryPreservingIdentity(input).map(operation => (
209
+ parseCodeBoundary(OperationDiscoverySchema, {
210
+ ...operation,
211
+ inputSchemaId: canonicalSlopcameraIdentity(operation.inputSchemaId),
212
+ kind: canonicalSlopcameraIdentity(operation.kind),
213
+ outputSchemaId: canonicalSlopcameraIdentity(operation.outputSchemaId),
214
+ }, "canonical operation discovery entry")
215
+ ))
216
+ }
217
+
218
+ function freezeDiscovery(
219
+ discovery: readonly OperationDiscovery[],
220
+ ): readonly OperationDiscovery[] {
221
+ return Object.freeze(discovery.map(operation => Object.freeze({
222
+ ...operation,
223
+ policy: Object.freeze({
224
+ ...operation.policy,
225
+ preparation: Object.freeze([...operation.policy.preparation]),
226
+ resources: Object.freeze(operation.policy.resources.map(
227
+ resource => Object.freeze({ ...resource }),
228
+ )),
229
+ }),
230
+ })))
231
+ }
232
+
233
+ export function createWorkflowRegistryProjectionHash(input: {
234
+ readonly discovery: readonly OperationDiscovery[]
235
+ readonly id: string
236
+ readonly trustedCompute?: boolean
237
+ }): string {
238
+ const id = canonicalSlopcameraIdentity(
239
+ parseCodeBoundary(SchemaIdSchema, input.id, "registry projection id"),
240
+ )
241
+ const discovery = normalizeOperationDiscovery(input.discovery)
242
+ const trustedCompute = input.trustedCompute ?? false
243
+ return workflowRegistryProjectionHashFromNormalized({
244
+ discovery,
245
+ id,
246
+ trustedCompute,
247
+ })
248
+ }
249
+
250
+ function workflowRegistryProjectionHashFromNormalized(input: {
251
+ readonly discovery: readonly OperationDiscovery[]
252
+ readonly id: string
253
+ readonly trustedCompute: boolean
254
+ }, domain = WORKFLOW_REGISTRY_PROJECTION_HASH_DOMAIN): string {
255
+ return canonicalJsonSha256Prefixed(
256
+ `${domain}\0`,
257
+ {
258
+ discovery: input.discovery,
259
+ id: input.id,
260
+ trustedCompute: input.trustedCompute,
261
+ },
262
+ )
263
+ }
264
+
265
+ export function createWorkflowRegistryProjection(
266
+ idInput: string,
267
+ source: WorkflowRegistryProjectionSource,
268
+ options: CreateWorkflowRegistryProjectionOptions = {},
269
+ ): WorkflowRegistryProjection {
270
+ const id = canonicalSlopcameraIdentity(
271
+ parseCodeBoundary(SchemaIdSchema, idInput, "registry projection id"),
272
+ )
273
+ const discovery = normalizeOperationDiscovery(discoveryList(source))
274
+ const trustedCompute = options.trustedCompute ?? false
275
+ const parsed = parseCodeBoundary(WorkflowRegistryProjectionSchema, {
276
+ discovery,
277
+ id,
278
+ projectionSha256: workflowRegistryProjectionHashFromNormalized({
279
+ discovery,
280
+ id,
281
+ trustedCompute,
282
+ }),
283
+ trustedCompute,
284
+ }, "workflow registry projection")
285
+ const projection = Object.freeze({
286
+ ...parsed,
287
+ discovery: freezeDiscovery(parsed.discovery),
288
+ })
289
+ OWNED_NORMALIZED_PROJECTIONS.add(projection)
290
+ return projection
291
+ }
292
+
293
+ export function parseWorkflowRegistryProjection(
294
+ input: unknown,
295
+ ): WorkflowRegistryProjection {
296
+ if (
297
+ typeof input === "object"
298
+ && input !== null
299
+ && OWNED_NORMALIZED_PROJECTIONS.has(input)
300
+ ) {
301
+ return input as WorkflowRegistryProjection
302
+ }
303
+ const captured = createBoundedJsonValueSnapshot(
304
+ input,
305
+ MAX_WORKFLOW_REGISTRY_PROJECTION_BYTES,
306
+ "workflow registry projection",
307
+ {
308
+ maximumDepth: MAX_WORKFLOW_REGISTRY_PROJECTION_DEPTH,
309
+ maximumValues: MAX_WORKFLOW_REGISTRY_PROJECTION_VALUES,
310
+ },
311
+ ).value
312
+ const parsed = parseCodeBoundary(
313
+ WorkflowRegistryProjectionSchema,
314
+ captured,
315
+ "workflow registry projection",
316
+ )
317
+ const exactDiscovery = normalizeOperationDiscoveryPreservingIdentity(
318
+ parsed.discovery,
319
+ )
320
+ const exactIdentity = {
321
+ discovery: exactDiscovery,
322
+ id: parsed.id,
323
+ trustedCompute: parsed.trustedCompute,
324
+ }
325
+ const expectedProjectionSha256 =
326
+ workflowRegistryProjectionHashFromNormalized(exactIdentity)
327
+ if (parsed.projectionSha256 !== expectedProjectionSha256) {
328
+ throw new SlopcameraCodeError(
329
+ "invalid-data",
330
+ "Workflow registry projection hash does not match its contents.",
331
+ {
332
+ actualProjectionSha256: parsed.projectionSha256,
333
+ expectedProjectionSha256,
334
+ projectionId: parsed.id,
335
+ },
336
+ )
337
+ }
338
+ if (canonicalJsonSha256(parsed.discovery) !== canonicalJsonSha256(exactDiscovery)) {
339
+ throw new SlopcameraCodeError(
340
+ "invalid-data",
341
+ "Workflow registry projection discovery is not normalized.",
342
+ { projectionId: parsed.id },
343
+ )
344
+ }
345
+ return createWorkflowRegistryProjection(
346
+ parsed.id,
347
+ exactDiscovery,
348
+ { trustedCompute: parsed.trustedCompute },
349
+ )
350
+ }
351
+
352
+ function publicDiscovery(): readonly OperationDiscovery[] {
353
+ return PORTABLE_SLOPCAMERA_OPERATION_KINDS.map((kind) => {
354
+ const contract = PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS[kind]
355
+ return {
356
+ inputSchemaId: contract.inputSchemaId,
357
+ kind: contract.kind,
358
+ lifecycle: contract.lifecycle,
359
+ outputSchemaId: contract.outputSchemaId,
360
+ policy: contract.policy,
361
+ version: contract.version,
362
+ }
363
+ })
364
+ }
365
+
366
+ export function createPublicWorkflowRegistryProjection(): WorkflowRegistryProjection {
367
+ return createWorkflowRegistryProjection(
368
+ PUBLIC_WORKFLOW_REGISTRY_PROJECTION_ID,
369
+ publicDiscovery(),
370
+ { trustedCompute: false },
371
+ )
372
+ }
373
+
374
+ export const PUBLIC_WORKFLOW_REGISTRY_PROJECTION =
375
+ createPublicWorkflowRegistryProjection()
376
+
377
+ export const PUBLIC_SLOPCAMERA_WORKFLOW_PROJECTION =
378
+ PUBLIC_WORKFLOW_REGISTRY_PROJECTION