@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,867 @@
1
+ import { z } from "zod";
2
+
3
+ import {
4
+ RepositoryRelativePathSchema,
5
+ Sha256Schema,
6
+ } from "../contracts";
7
+ import {
8
+ canonicalJson,
9
+ sha256Hex,
10
+ } from "../core/canonical-json";
11
+ import type { ApplicationContext } from "./context";
12
+ import { ApplicationError } from "./errors";
13
+ import type { OperationKind } from "./operation";
14
+
15
+ const GATEWAY_REQUEST_ID_DOMAIN = "studio.gateway-operation-request/v1";
16
+ const MAXIMUM_GATEWAY_OUTPUT_BYTES = 1024 * 1024 * 1024;
17
+ const MAXIMUM_GATEWAY_OUTPUTS = 32;
18
+ const MAXIMUM_GATEWAY_RECEIPT_BYTES = 256 * 1024;
19
+ const MAXIMUM_IMAGE_INPUT_BYTES = 50 * 1024 * 1024;
20
+ const MAXIMUM_IMAGE_INPUT_TOTAL_BYTES = 200 * 1024 * 1024;
21
+ const MAXIMUM_REFERENCE_INPUT_BYTES = 256 * 1024 * 1024;
22
+ const MAXIMUM_REFERENCE_INPUT_TOTAL_BYTES = 512 * 1024 * 1024;
23
+
24
+ const BoundedTextSchema = z.string().max(100_000).refine(
25
+ value => [...value].every((character) => {
26
+ const codePoint = character.codePointAt(0);
27
+ return codePoint !== undefined
28
+ && codePoint !== 0
29
+ && (
30
+ codePoint >= 32
31
+ || codePoint === 9
32
+ || codePoint === 10
33
+ || codePoint === 13
34
+ );
35
+ }),
36
+ "Gateway text contains a disallowed control character.",
37
+ );
38
+
39
+ export const GatewayModelIdSchema = z.string()
40
+ .min(3)
41
+ .max(256)
42
+ .regex(
43
+ /^[^\s/]+(?:\/[^\s/]+)+$/u,
44
+ "Gateway model IDs must be nonempty slash-separated identifiers.",
45
+ );
46
+
47
+ export const GatewayMediaTypeSchema = z.string()
48
+ .min(3)
49
+ .max(128)
50
+ .regex(
51
+ /^[a-z0-9][a-z0-9!#$&^_.+-]*\/[a-z0-9][a-z0-9!#$&^_.+-]*$/u,
52
+ "Expected a normalized media type.",
53
+ );
54
+
55
+ export const GatewayProviderOptionsReferenceSchema = z.strictObject({
56
+ namespaces: z.array(
57
+ z.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/u),
58
+ ).max(64),
59
+ sha256: Sha256Schema,
60
+ }).superRefine((reference, context) => {
61
+ const canonical = [...new Set(reference.namespaces)].sort((left, right) =>
62
+ left.localeCompare(right));
63
+ if (
64
+ canonical.length !== reference.namespaces.length
65
+ || canonical.some((namespace, index) =>
66
+ namespace !== reference.namespaces[index])
67
+ ) {
68
+ context.addIssue({
69
+ code: "custom",
70
+ message: "Provider-option namespaces must be unique and canonically sorted.",
71
+ });
72
+ }
73
+ });
74
+
75
+ export const GatewayMediaSourceReferenceSchema = z.strictObject({
76
+ bytes: z.number().int().safe().positive().max(512 * 1024 * 1024),
77
+ facts: z.strictObject({
78
+ durationSeconds: z.number().finite().positive().max(1_000_000_000).optional(),
79
+ height: z.number().int().safe().positive().max(1_000_000).optional(),
80
+ width: z.number().int().safe().positive().max(1_000_000).optional(),
81
+ }).optional(),
82
+ mediaType: GatewayMediaTypeSchema,
83
+ path: RepositoryRelativePathSchema,
84
+ sha256: Sha256Schema,
85
+ });
86
+
87
+ const GatewayCommonRequestFields = {
88
+ model: GatewayModelIdSchema,
89
+ providerOptions: GatewayProviderOptionsReferenceSchema.optional(),
90
+ timeoutMs: z.number().int().safe().positive().max(30 * 60_000).optional(),
91
+ } as const;
92
+
93
+ export const GatewayImageOperationInputSchema = z.strictObject({
94
+ ...GatewayCommonRequestFields,
95
+ aspectRatio: z.string()
96
+ .max(32)
97
+ .regex(/^[1-9]\d{0,5}:[1-9]\d{0,5}$/u)
98
+ .optional(),
99
+ images: z.array(GatewayMediaSourceReferenceSchema).max(32).optional(),
100
+ mask: GatewayMediaSourceReferenceSchema.optional(),
101
+ maxImagesPerCall: z.number().int().safe().min(1).max(32).optional(),
102
+ maxOutputTokens: z.number().int().safe().min(1).max(1_000_000).optional(),
103
+ n: z.number().int().safe().min(1).max(32).optional(),
104
+ prompt: BoundedTextSchema,
105
+ seed: z.number().int().safe().min(0).max(0xffff_ffff).optional(),
106
+ size: z.string()
107
+ .max(32)
108
+ .regex(/^[1-9]\d{0,5}x[1-9]\d{0,5}$/u)
109
+ .optional(),
110
+ stopSequences: z.array(z.string().min(1).max(1_024)).max(64).optional(),
111
+ temperature: z.number().finite().min(0).max(100).optional(),
112
+ }).superRefine((input, context) => {
113
+ const images = input.images ?? [];
114
+ const totalBytes = images.reduce(
115
+ (total, image) => total + image.bytes,
116
+ input.mask?.bytes ?? 0,
117
+ );
118
+ if (totalBytes > MAXIMUM_IMAGE_INPUT_TOTAL_BYTES) {
119
+ context.addIssue({
120
+ code: "custom",
121
+ message: "Gateway image inputs exceed the 200 MiB aggregate bound.",
122
+ });
123
+ }
124
+ if (
125
+ images.some(image => image.bytes > MAXIMUM_IMAGE_INPUT_BYTES)
126
+ || (
127
+ input.mask !== undefined
128
+ && input.mask.bytes > MAXIMUM_IMAGE_INPUT_BYTES
129
+ )
130
+ ) {
131
+ context.addIssue({
132
+ code: "custom",
133
+ message: "An individual Gateway image input exceeds the 50 MiB bound.",
134
+ });
135
+ }
136
+ if (images.some(image => !image.mediaType.startsWith("image/"))) {
137
+ context.addIssue({
138
+ code: "custom",
139
+ message: "Gateway image references must use image media types.",
140
+ });
141
+ }
142
+ if (
143
+ input.mask !== undefined
144
+ && !input.mask.mediaType.startsWith("image/")
145
+ ) {
146
+ context.addIssue({
147
+ code: "custom",
148
+ message: "Gateway image masks must use an image media type.",
149
+ });
150
+ }
151
+ if (input.mask !== undefined && images.length === 0) {
152
+ context.addIssue({
153
+ code: "custom",
154
+ message: "A Gateway image mask requires at least one source image.",
155
+ });
156
+ }
157
+ if (input.size !== undefined && input.aspectRatio !== undefined) {
158
+ context.addIssue({
159
+ code: "custom",
160
+ message: "Gateway image size and aspect ratio are mutually exclusive.",
161
+ });
162
+ }
163
+ if (
164
+ (input.n ?? 1) > 1
165
+ && (
166
+ input.maxImagesPerCall === undefined
167
+ || input.maxImagesPerCall < (input.n ?? 1)
168
+ )
169
+ ) {
170
+ context.addIssue({
171
+ code: "custom",
172
+ message: "Multiple Gateway images require a matching per-call bound.",
173
+ });
174
+ }
175
+ if (input.prompt.trim().length === 0 && images.length === 0) {
176
+ context.addIssue({
177
+ code: "custom",
178
+ message: "A Gateway image request without source images requires a prompt.",
179
+ });
180
+ }
181
+ });
182
+
183
+ const GatewayVideoFrameSchema = z.strictObject({
184
+ frameType: z.enum(["first_frame", "last_frame"]),
185
+ source: GatewayMediaSourceReferenceSchema,
186
+ });
187
+
188
+ export const GatewayVideoOperationInputSchema = z.strictObject({
189
+ ...GatewayCommonRequestFields,
190
+ aspectRatio: z.string()
191
+ .max(32)
192
+ .regex(/^[1-9]\d{0,5}:[1-9]\d{0,5}$/u)
193
+ .optional(),
194
+ durationSeconds: z.number().finite().min(0.01).max(3_600).optional(),
195
+ fps: z.number().finite().min(0.01).max(1_000).optional(),
196
+ frames: z.array(GatewayVideoFrameSchema).max(32).optional(),
197
+ generateAudio: z.boolean().optional(),
198
+ maxVideosPerCall: z.number().int().safe().min(1).max(32).optional(),
199
+ n: z.number().int().safe().min(1).max(32).optional(),
200
+ prompt: BoundedTextSchema,
201
+ promptImage: GatewayMediaSourceReferenceSchema.optional(),
202
+ references: z.array(GatewayMediaSourceReferenceSchema).max(32).optional(),
203
+ resolution: z.string()
204
+ .max(32)
205
+ .regex(/^(?:[1-9]\d{0,5}x[1-9]\d{0,5}|[1-9]\d{2,4}p|[1-9]\d{0,2}k)$/iu)
206
+ .optional(),
207
+ seed: z.number().int().safe().min(0).max(0xffff_ffff).optional(),
208
+ }).superRefine((input, context) => {
209
+ const frames = input.frames ?? [];
210
+ const references = input.references ?? [];
211
+ if (references.reduce(
212
+ (total, source) => total + source.bytes,
213
+ 0,
214
+ ) > MAXIMUM_REFERENCE_INPUT_TOTAL_BYTES) {
215
+ context.addIssue({
216
+ code: "custom",
217
+ message: "Gateway video inputs exceed the 512 MiB aggregate bound.",
218
+ });
219
+ }
220
+ if (
221
+ references.some(reference =>
222
+ reference.bytes > MAXIMUM_REFERENCE_INPUT_BYTES)
223
+ ) {
224
+ context.addIssue({
225
+ code: "custom",
226
+ message: "A Gateway video reference exceeds the 256 MiB bound.",
227
+ });
228
+ }
229
+ if (
230
+ [
231
+ ...(input.promptImage === undefined ? [] : [input.promptImage]),
232
+ ...frames.map(frame => frame.source),
233
+ ].some(source => source.bytes > MAXIMUM_IMAGE_INPUT_BYTES)
234
+ ) {
235
+ context.addIssue({
236
+ code: "custom",
237
+ message: "A Gateway video image input exceeds the 50 MiB bound.",
238
+ });
239
+ }
240
+ if (
241
+ frames.reduce((total, frame) => total + frame.source.bytes, 0)
242
+ > MAXIMUM_IMAGE_INPUT_TOTAL_BYTES
243
+ ) {
244
+ context.addIssue({
245
+ code: "custom",
246
+ message: "Gateway video frames exceed the 200 MiB aggregate bound.",
247
+ });
248
+ }
249
+ if (
250
+ input.promptImage !== undefined
251
+ && !input.promptImage.mediaType.startsWith("image/")
252
+ ) {
253
+ context.addIssue({
254
+ code: "custom",
255
+ message: "A Gateway video prompt image must use an image media type.",
256
+ });
257
+ }
258
+ if (frames.some(frame => !frame.source.mediaType.startsWith("image/"))) {
259
+ context.addIssue({
260
+ code: "custom",
261
+ message: "Gateway video frames must use image media types.",
262
+ });
263
+ }
264
+ if (new Set(frames.map(frame => frame.frameType)).size !== frames.length) {
265
+ context.addIssue({
266
+ code: "custom",
267
+ message: "Gateway video frame roles must be unique.",
268
+ });
269
+ }
270
+ if (
271
+ references.some(reference => ![
272
+ "audio/",
273
+ "image/",
274
+ "video/",
275
+ ].some(prefix => reference.mediaType.startsWith(prefix)))
276
+ ) {
277
+ context.addIssue({
278
+ code: "custom",
279
+ message: "Gateway video references must be image, video, or audio media.",
280
+ });
281
+ }
282
+ if (frames.length > 0 && references.length > 0) {
283
+ context.addIssue({
284
+ code: "custom",
285
+ message: "Gateway video frames and references are mutually exclusive.",
286
+ });
287
+ }
288
+ if (
289
+ input.promptImage !== undefined
290
+ && frames.some(frame => frame.frameType === "first_frame")
291
+ ) {
292
+ context.addIssue({
293
+ code: "custom",
294
+ message: "A Gateway video prompt image conflicts with a first frame.",
295
+ });
296
+ }
297
+ if (
298
+ frames.some(frame => frame.frameType === "last_frame")
299
+ && input.promptImage === undefined
300
+ && !frames.some(frame => frame.frameType === "first_frame")
301
+ ) {
302
+ context.addIssue({
303
+ code: "custom",
304
+ message: "A Gateway video last frame requires a first image.",
305
+ });
306
+ }
307
+ if (
308
+ (input.n ?? 1) > 1
309
+ && (
310
+ input.maxVideosPerCall === undefined
311
+ || input.maxVideosPerCall < (input.n ?? 1)
312
+ )
313
+ ) {
314
+ context.addIssue({
315
+ code: "custom",
316
+ message: "Multiple Gateway videos require a matching per-call bound.",
317
+ });
318
+ }
319
+ if (
320
+ input.prompt.trim().length === 0
321
+ && input.promptImage === undefined
322
+ && frames.length === 0
323
+ && references.length === 0
324
+ ) {
325
+ context.addIssue({
326
+ code: "custom",
327
+ message: "A Gateway video request without media inputs requires a prompt.",
328
+ });
329
+ }
330
+ });
331
+
332
+ export const GatewaySpeechOperationInputSchema = z.strictObject({
333
+ ...GatewayCommonRequestFields,
334
+ instructions: BoundedTextSchema.optional(),
335
+ language: z.string().min(1).max(64).optional(),
336
+ outputFormat: z.string()
337
+ .max(64)
338
+ .regex(/^[a-z0-9][a-z0-9._+-]*$/iu)
339
+ .optional(),
340
+ speed: z.number().finite().min(0.01).max(100).optional(),
341
+ text: BoundedTextSchema.min(1),
342
+ voice: z.string().min(1).max(256).optional(),
343
+ });
344
+
345
+ export const GatewayTranscriptionOperationInputSchema = z.strictObject({
346
+ ...GatewayCommonRequestFields,
347
+ audio: GatewayMediaSourceReferenceSchema,
348
+ }).superRefine((input, context) => {
349
+ if (!input.audio.mediaType.startsWith("audio/")) {
350
+ context.addIssue({
351
+ code: "custom",
352
+ message: "Gateway transcription input must use an audio media type.",
353
+ });
354
+ }
355
+ if (input.audio.bytes > 256 * 1024 * 1024) {
356
+ context.addIssue({
357
+ code: "custom",
358
+ message: "Gateway transcription input exceeds the 256 MiB bound.",
359
+ });
360
+ }
361
+ });
362
+
363
+ export const GatewayOperationNameSchema = z.enum([
364
+ "image",
365
+ "video",
366
+ "speech",
367
+ "transcription",
368
+ ]);
369
+
370
+ export const GatewayPortRequestSchema = z.union([
371
+ z.strictObject({
372
+ operation: z.literal("image"),
373
+ request: GatewayImageOperationInputSchema,
374
+ }),
375
+ z.strictObject({
376
+ operation: z.literal("video"),
377
+ request: GatewayVideoOperationInputSchema,
378
+ }),
379
+ z.strictObject({
380
+ operation: z.literal("speech"),
381
+ request: GatewaySpeechOperationInputSchema,
382
+ }),
383
+ z.strictObject({
384
+ operation: z.literal("transcription"),
385
+ request: GatewayTranscriptionOperationInputSchema,
386
+ }),
387
+ ]);
388
+
389
+ export const GatewayRequestIdSchema = z.string()
390
+ .regex(/^gateway_[a-f0-9]{64}$/u);
391
+
392
+ export const GatewayOutputArtifactReferenceSchema = z.strictObject({
393
+ bytes: z.number().int().safe().positive().max(512 * 1024 * 1024),
394
+ mediaType: GatewayMediaTypeSchema,
395
+ path: RepositoryRelativePathSchema,
396
+ sha256: Sha256Schema,
397
+ });
398
+
399
+ export const GatewayReceiptReferenceSchema = z.strictObject({
400
+ bytes: z.number().int().safe().positive().max(MAXIMUM_GATEWAY_RECEIPT_BYTES),
401
+ path: RepositoryRelativePathSchema,
402
+ sha256: Sha256Schema,
403
+ });
404
+
405
+ const GatewayOperationResultBaseFields = {
406
+ model: GatewayModelIdSchema,
407
+ outputs: z.array(GatewayOutputArtifactReferenceSchema)
408
+ .min(1)
409
+ .max(MAXIMUM_GATEWAY_OUTPUTS),
410
+ receipt: GatewayReceiptReferenceSchema,
411
+ requestId: GatewayRequestIdSchema,
412
+ } as const;
413
+
414
+ export const GatewayImageOperationResultSchema = z.strictObject({
415
+ ...GatewayOperationResultBaseFields,
416
+ operation: z.literal("image"),
417
+ });
418
+
419
+ export const GatewayVideoOperationResultSchema = z.strictObject({
420
+ ...GatewayOperationResultBaseFields,
421
+ operation: z.literal("video"),
422
+ });
423
+
424
+ export const GatewaySpeechOperationResultSchema = z.strictObject({
425
+ ...GatewayOperationResultBaseFields,
426
+ operation: z.literal("speech"),
427
+ });
428
+
429
+ export const GatewayTranscriptionOperationResultSchema = z.strictObject({
430
+ ...GatewayOperationResultBaseFields,
431
+ operation: z.literal("transcription"),
432
+ transcript: z.strictObject({
433
+ characters: z.number().int().safe().nonnegative().max(10_000_000),
434
+ durationSeconds: z.number().finite().nonnegative().max(7 * 24 * 60 * 60),
435
+ language: z.string().min(1).max(64).optional(),
436
+ segments: z.number().int().safe().nonnegative().max(100_000),
437
+ textSha256: Sha256Schema,
438
+ }),
439
+ });
440
+
441
+ export const GatewayOperationResultSchema = z.union([
442
+ GatewayImageOperationResultSchema,
443
+ GatewayVideoOperationResultSchema,
444
+ GatewaySpeechOperationResultSchema,
445
+ GatewayTranscriptionOperationResultSchema,
446
+ ]).superRefine((result, context) => {
447
+ if (
448
+ result.outputs.reduce((total, output) => total + output.bytes, 0)
449
+ > MAXIMUM_GATEWAY_OUTPUT_BYTES
450
+ ) {
451
+ context.addIssue({
452
+ code: "custom",
453
+ message: "Gateway outputs exceed the 1 GiB aggregate bound.",
454
+ });
455
+ }
456
+ const identities = result.outputs.map(output => output.sha256);
457
+ if (new Set(identities).size !== identities.length) {
458
+ context.addIssue({
459
+ code: "custom",
460
+ message: "Gateway output content identities must be unique.",
461
+ });
462
+ }
463
+ const wrongMediaType = result.operation === "image"
464
+ ? result.outputs.some(output => !output.mediaType.startsWith("image/"))
465
+ : result.operation === "video"
466
+ ? result.outputs.some(output => !output.mediaType.startsWith("video/"))
467
+ : result.operation === "speech"
468
+ ? result.outputs.some(output => !output.mediaType.startsWith("audio/"))
469
+ : result.outputs.some(output => ![
470
+ "application/json",
471
+ "application/x-subrip",
472
+ "text/plain",
473
+ "text/vtt",
474
+ ].includes(output.mediaType));
475
+ if (wrongMediaType) {
476
+ context.addIssue({
477
+ code: "custom",
478
+ message: `Gateway ${result.operation} output has the wrong media type.`,
479
+ });
480
+ }
481
+ });
482
+
483
+ export type GatewayImageOperationInput =
484
+ z.infer<typeof GatewayImageOperationInputSchema>;
485
+ export type GatewayMediaSourceReference =
486
+ z.infer<typeof GatewayMediaSourceReferenceSchema>;
487
+ export type GatewayVideoOperationInput =
488
+ z.infer<typeof GatewayVideoOperationInputSchema>;
489
+ export type GatewaySpeechOperationInput =
490
+ z.infer<typeof GatewaySpeechOperationInputSchema>;
491
+ export type GatewayTranscriptionOperationInput =
492
+ z.infer<typeof GatewayTranscriptionOperationInputSchema>;
493
+ export type GatewayPortRequest = z.infer<typeof GatewayPortRequestSchema>;
494
+ export type GatewayOperationResult = z.infer<
495
+ typeof GatewayOperationResultSchema
496
+ >;
497
+ export type GatewayImageOperationResult =
498
+ z.infer<typeof GatewayImageOperationResultSchema>;
499
+ export type GatewayVideoOperationResult =
500
+ z.infer<typeof GatewayVideoOperationResultSchema>;
501
+ export type GatewaySpeechOperationResult =
502
+ z.infer<typeof GatewaySpeechOperationResultSchema>;
503
+ export type GatewayTranscriptionOperationResult =
504
+ z.infer<typeof GatewayTranscriptionOperationResultSchema>;
505
+ export type GatewayOperationName = GatewayPortRequest["operation"];
506
+
507
+ export const GatewayPortReconciliationSchema = z.union([
508
+ z.strictObject({
509
+ operation: GatewayOperationNameSchema,
510
+ requestId: GatewayRequestIdSchema,
511
+ result: GatewayOperationResultSchema,
512
+ status: z.literal("completed"),
513
+ }),
514
+ z.strictObject({
515
+ operation: GatewayOperationNameSchema,
516
+ requestId: GatewayRequestIdSchema,
517
+ status: z.literal("not-dispatched"),
518
+ }),
519
+ z.strictObject({
520
+ operation: GatewayOperationNameSchema,
521
+ requestId: GatewayRequestIdSchema,
522
+ status: z.literal("dispatched"),
523
+ }),
524
+ z.strictObject({
525
+ failureReceipt: GatewayReceiptReferenceSchema,
526
+ operation: GatewayOperationNameSchema,
527
+ requestId: GatewayRequestIdSchema,
528
+ status: z.literal("failed"),
529
+ }),
530
+ z.strictObject({
531
+ operation: GatewayOperationNameSchema,
532
+ reasonSha256: Sha256Schema,
533
+ requestId: GatewayRequestIdSchema,
534
+ status: z.literal("conflict"),
535
+ }),
536
+ ]);
537
+
538
+ export type GatewayPortReconciliation = z.infer<
539
+ typeof GatewayPortReconciliationSchema
540
+ >;
541
+
542
+ export interface GatewayPortDispatch {
543
+ /**
544
+ * Revalidate adapter-owned custody immediately before the durable paid
545
+ * dispatch transition. Rejection must leave the request undispatched.
546
+ * This callback is ephemeral authority, outside request identity and receipts.
547
+ */
548
+ readonly beforeDispatch?: () => Promise<void>;
549
+ /**
550
+ * Revalidates the workflow fence immediately before generated artifacts are
551
+ * atomically published. The host service must invoke this at its final safe
552
+ * publication boundary.
553
+ */
554
+ readonly beforePublication: () => Promise<void>;
555
+ /**
556
+ * Callback-scoped machine admission held by the active operation. This is
557
+ * host authority, never part of the persisted or hashed Gateway request.
558
+ */
559
+ readonly hostResourceLease?: ApplicationContext["hostResourceLease"];
560
+ /**
561
+ * Optional trusted video transport for URL-only providers. The host first
562
+ * verifies this exact local source, then passes an isolated copy of its bytes.
563
+ * The adapter owns upload consent and must expose those same bytes. Returning
564
+ * undefined keeps inline transport. URLs and this hook are never serialized;
565
+ * completed request replay must not invoke the adapter again.
566
+ */
567
+ readonly resolveSourceUrl?: (
568
+ source: GatewayMediaSourceReference,
569
+ data: Uint8Array,
570
+ signal: AbortSignal,
571
+ ) => Promise<string | undefined>;
572
+ /**
573
+ * The host must durably claim this key before crossing the paid-dispatch
574
+ * boundary. Repeating it may return a completed receipt but must never cause
575
+ * another provider call.
576
+ */
577
+ readonly requestId: string;
578
+ readonly request: GatewayPortRequest;
579
+ readonly signal: AbortSignal;
580
+ }
581
+
582
+ export interface GatewayPortPrepare {
583
+ readonly hostResourceLease?: ApplicationContext["hostResourceLease"];
584
+ readonly request: GatewayPortRequest;
585
+ readonly signal: AbortSignal;
586
+ }
587
+
588
+ export interface GatewayPortReconcile {
589
+ /**
590
+ * The host compares this complete authority-free request with the durable
591
+ * dispatch-intent digest. A matching request ID alone is insufficient.
592
+ */
593
+ readonly request: GatewayPortRequest;
594
+ readonly requestId: string;
595
+ readonly signal: AbortSignal;
596
+ }
597
+
598
+ /**
599
+ * Host-owned paid-media boundary.
600
+ *
601
+ * Credentials, cloud consent, and raw provider options remain encapsulated by
602
+ * this port. Only their separately prepared, secret-free integrity summary is
603
+ * present in a request. Implementations must durably distinguish
604
+ * `not-dispatched` from `dispatched`; absence of a result alone is not proof
605
+ * that retrying a paid call is safe.
606
+ */
607
+ export interface ApplicationGatewayPort {
608
+ dispatch(input: GatewayPortDispatch): Promise<unknown>;
609
+ prepare(input: GatewayPortPrepare): Promise<unknown>;
610
+ reconcile(input: GatewayPortReconcile): Promise<unknown>;
611
+ }
612
+
613
+ export interface GatewayRequestIdentity {
614
+ readonly nodeKey: string;
615
+ readonly nodePlanSha256: string;
616
+ readonly operation: GatewayOperationName;
617
+ readonly runId: string;
618
+ }
619
+
620
+ export function gatewayRequestId(
621
+ identity: GatewayRequestIdentity,
622
+ ): string {
623
+ if (
624
+ identity.runId.length < 1
625
+ || identity.runId.length > 256
626
+ || identity.nodeKey.length < 1
627
+ || identity.nodeKey.length > 256
628
+ || identity.runId.includes("\0")
629
+ || identity.nodeKey.includes("\0")
630
+ ) {
631
+ throw new ApplicationError(
632
+ "invalid-data",
633
+ "Gateway request identity is outside its bounded envelope.",
634
+ );
635
+ }
636
+ const nodePlanSha256 = Sha256Schema.parse(identity.nodePlanSha256);
637
+ return GatewayRequestIdSchema.parse(
638
+ `gateway_${sha256Hex(
639
+ `${GATEWAY_REQUEST_ID_DOMAIN}\0${canonicalJson({
640
+ nodeKey: identity.nodeKey,
641
+ nodePlanSha256,
642
+ operation: identity.operation,
643
+ runId: identity.runId,
644
+ })}`,
645
+ )}`,
646
+ );
647
+ }
648
+
649
+ type GatewayOperationKind = Extract<OperationKind, `gateway.${string}`>;
650
+
651
+ export function gatewayPortRequestForOperation(
652
+ kind: GatewayOperationKind,
653
+ input: unknown,
654
+ ): GatewayPortRequest {
655
+ switch (kind) {
656
+ case "gateway.image":
657
+ return GatewayPortRequestSchema.parse({
658
+ operation: "image",
659
+ request: GatewayImageOperationInputSchema.parse(input),
660
+ });
661
+ case "gateway.video":
662
+ return GatewayPortRequestSchema.parse({
663
+ operation: "video",
664
+ request: GatewayVideoOperationInputSchema.parse(input),
665
+ });
666
+ case "gateway.speech":
667
+ return GatewayPortRequestSchema.parse({
668
+ operation: "speech",
669
+ request: GatewaySpeechOperationInputSchema.parse(input),
670
+ });
671
+ case "gateway.transcription":
672
+ return GatewayPortRequestSchema.parse({
673
+ operation: "transcription",
674
+ request: GatewayTranscriptionOperationInputSchema.parse(input),
675
+ });
676
+ }
677
+ }
678
+
679
+ function withoutSourceFacts(
680
+ source: z.infer<typeof GatewayMediaSourceReferenceSchema>,
681
+ ) {
682
+ return {
683
+ bytes: source.bytes,
684
+ mediaType: source.mediaType,
685
+ path: source.path,
686
+ sha256: source.sha256,
687
+ };
688
+ }
689
+
690
+ function gatewayRequestAuthority(request: GatewayPortRequest): unknown {
691
+ switch (request.operation) {
692
+ case "image":
693
+ return {
694
+ ...request,
695
+ request: {
696
+ ...request.request,
697
+ ...(request.request.images === undefined
698
+ ? {}
699
+ : {
700
+ images: request.request.images.map(withoutSourceFacts),
701
+ }),
702
+ ...(request.request.mask === undefined
703
+ ? {}
704
+ : { mask: withoutSourceFacts(request.request.mask) }),
705
+ },
706
+ };
707
+ case "video":
708
+ return {
709
+ ...request,
710
+ request: {
711
+ ...request.request,
712
+ ...(request.request.frames === undefined
713
+ ? {}
714
+ : {
715
+ frames: request.request.frames.map(frame => ({
716
+ ...frame,
717
+ source: withoutSourceFacts(frame.source),
718
+ })),
719
+ }),
720
+ ...(request.request.promptImage === undefined
721
+ ? {}
722
+ : {
723
+ promptImage: withoutSourceFacts(
724
+ request.request.promptImage,
725
+ ),
726
+ }),
727
+ ...(request.request.references === undefined
728
+ ? {}
729
+ : {
730
+ references:
731
+ request.request.references.map(withoutSourceFacts),
732
+ }),
733
+ },
734
+ };
735
+ case "speech":
736
+ return request;
737
+ case "transcription":
738
+ return {
739
+ ...request,
740
+ request: {
741
+ ...request.request,
742
+ audio: withoutSourceFacts(request.request.audio),
743
+ },
744
+ };
745
+ }
746
+ }
747
+
748
+ function requireGatewayPort(
749
+ application: ApplicationContext,
750
+ ): ApplicationGatewayPort {
751
+ if (application.gatewayPort === undefined) {
752
+ throw new ApplicationError(
753
+ "unavailable",
754
+ "The host Gateway media port is unavailable.",
755
+ );
756
+ }
757
+ return application.gatewayPort;
758
+ }
759
+
760
+ export async function prepareGatewayOperation(
761
+ application: ApplicationContext,
762
+ input: GatewayPortPrepare,
763
+ ): Promise<GatewayPortRequest> {
764
+ const request = GatewayPortRequestSchema.parse(input.request);
765
+ const prepared = GatewayPortRequestSchema.parse(
766
+ await requireGatewayPort(application).prepare({
767
+ ...(application.hostResourceLease === undefined
768
+ ? {}
769
+ : { hostResourceLease: application.hostResourceLease }),
770
+ request,
771
+ signal: input.signal,
772
+ }),
773
+ );
774
+ if (
775
+ canonicalJson(gatewayRequestAuthority(prepared))
776
+ !== canonicalJson(gatewayRequestAuthority(request))
777
+ ) {
778
+ throw new ApplicationError(
779
+ "conflict",
780
+ "Gateway preparation changed request authority instead of deriving media facts.",
781
+ { operation: request.operation },
782
+ );
783
+ }
784
+ return prepared;
785
+ }
786
+
787
+ function assertReconciliationIdentity(
788
+ reconciliation: GatewayPortReconciliation,
789
+ request: GatewayPortRequest,
790
+ requestId: string,
791
+ ): void {
792
+ if (
793
+ reconciliation.operation !== request.operation
794
+ || reconciliation.requestId !== requestId
795
+ || (
796
+ reconciliation.status === "completed"
797
+ && (
798
+ reconciliation.result.operation !== request.operation
799
+ || reconciliation.result.requestId !== requestId
800
+ || reconciliation.result.model !== request.request.model
801
+ )
802
+ )
803
+ ) {
804
+ throw new ApplicationError(
805
+ "conflict",
806
+ "Gateway reconciliation did not match the exact paid request.",
807
+ { operation: request.operation, requestId },
808
+ );
809
+ }
810
+ }
811
+
812
+ export async function reconcileGatewayOperation(
813
+ application: ApplicationContext,
814
+ input: GatewayPortReconcile,
815
+ ): Promise<GatewayPortReconciliation> {
816
+ const request = GatewayPortRequestSchema.parse(input.request);
817
+ const requestId = GatewayRequestIdSchema.parse(input.requestId);
818
+ const reconciliation = GatewayPortReconciliationSchema.parse(
819
+ await requireGatewayPort(application).reconcile({
820
+ request,
821
+ requestId,
822
+ signal: input.signal,
823
+ }),
824
+ );
825
+ assertReconciliationIdentity(reconciliation, request, requestId);
826
+ return reconciliation;
827
+ }
828
+
829
+ export async function dispatchGatewayOperation(
830
+ application: ApplicationContext,
831
+ input: GatewayPortDispatch,
832
+ ): Promise<GatewayOperationResult> {
833
+ const request = GatewayPortRequestSchema.parse(input.request);
834
+ const requestId = GatewayRequestIdSchema.parse(input.requestId);
835
+ const result = GatewayOperationResultSchema.parse(
836
+ await requireGatewayPort(application).dispatch({
837
+ ...(input.beforeDispatch === undefined
838
+ ? {}
839
+ : { beforeDispatch: input.beforeDispatch }),
840
+ beforePublication: input.beforePublication,
841
+ ...(input.resolveSourceUrl === undefined
842
+ ? {}
843
+ : { resolveSourceUrl: input.resolveSourceUrl }),
844
+ ...(application.hostResourceLease === undefined
845
+ ? {}
846
+ : { hostResourceLease: application.hostResourceLease }),
847
+ request,
848
+ requestId,
849
+ signal: input.signal,
850
+ }),
851
+ );
852
+ if (
853
+ result.requestId !== requestId
854
+ || result.operation !== request.operation
855
+ || result.model !== request.request.model
856
+ ) {
857
+ throw new ApplicationError(
858
+ "conflict",
859
+ "Gateway dispatch result did not match the exact paid request.",
860
+ {
861
+ operation: request.operation,
862
+ requestId,
863
+ },
864
+ );
865
+ }
866
+ return result;
867
+ }