stillmade-sdk 0.1.42 → 0.1.43

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 (262) hide show
  1. package/.stillmade/sdk-baseline.json +6 -8
  2. package/AGENTS.md +15 -10
  3. package/FRAME_VIEWS.md +113 -0
  4. package/INTERFACE_DESIGN.md +62 -22
  5. package/MOBILE_UI.md +4 -2
  6. package/MODULES.md +152 -6
  7. package/PASTE_TO_LLM.md +35 -25
  8. package/README.md +3 -2
  9. package/SDK.md +994 -550
  10. package/UI_AESTHETIC.md +22 -2
  11. package/blocks/generate/package.js +1 -0
  12. package/blocks/generate/versions/1.0.0/package.js +463 -0
  13. package/docs/build/audio-to-editor.md +36 -0
  14. package/docs/build/block-builder-contract.md +150 -0
  15. package/docs/build/comfyui.md +227 -0
  16. package/docs/build/concepts.md +40 -0
  17. package/docs/build/context.md +159 -0
  18. package/docs/build/cookbook.md +57 -0
  19. package/docs/build/custom-interface.md +617 -0
  20. package/docs/build/data-types.md +83 -0
  21. package/docs/build/frame-views.md +259 -0
  22. package/docs/build/generate-media.md +59 -0
  23. package/docs/build/github-applications.md +314 -0
  24. package/docs/build/hosted-images.md +214 -0
  25. package/docs/build/hosted-music.md +39 -0
  26. package/docs/build/hosted-speech.md +157 -0
  27. package/docs/build/hosted-text.md +246 -0
  28. package/docs/build/image-description.md +49 -0
  29. package/docs/build/interface-design.md +343 -0
  30. package/docs/build/javascript.md +63 -0
  31. package/docs/build/local-preview.md +61 -0
  32. package/docs/build/media-analysis.md +27 -0
  33. package/docs/build/media.md +400 -0
  34. package/docs/build/mobile-ui.md +106 -0
  35. package/docs/build/modules.md +487 -0
  36. package/docs/build/original-blocks.md +70 -0
  37. package/docs/build/outside-apis.md +128 -0
  38. package/docs/build/production-context-templates.md +12 -0
  39. package/docs/build/project-storage.md +94 -0
  40. package/docs/build/quickstart.md +48 -0
  41. package/docs/build/recipes.md +103 -0
  42. package/docs/build/script-handoff.md +45 -0
  43. package/docs/build/script-writer.md +34 -0
  44. package/docs/build/state.md +223 -0
  45. package/docs/build/testing.md +112 -0
  46. package/docs/build/timeline-edits.md +116 -0
  47. package/docs/build/timeline-proposals.md +76 -0
  48. package/docs/build/transcription.md +59 -0
  49. package/docs/build/triggers.md +59 -0
  50. package/docs/build/tutorial.md +52 -0
  51. package/docs/build/typescript.md +34 -0
  52. package/docs/build/video-generation.md +61 -0
  53. package/docs/build/web-reading.md +37 -0
  54. package/docs/build/with-your-ai.md +27 -0
  55. package/docs/changelog.md +9 -0
  56. package/docs/creators.md +21 -0
  57. package/docs/distribute/discovery.md +43 -0
  58. package/docs/distribute/imports.md +58 -0
  59. package/docs/distribute/publishing.md +29 -0
  60. package/docs/distribute/sdk-versions.md +36 -0
  61. package/docs/distribute/selling.md +14 -0
  62. package/docs/distribute/teams.md +60 -0
  63. package/docs/distribute/versioning.md +28 -0
  64. package/docs/examples.md +23 -0
  65. package/docs/gallery.md +26 -0
  66. package/docs/index.md +50 -0
  67. package/docs/native-mcp.md +307 -0
  68. package/docs/project-types/automation.md +43 -0
  69. package/docs/project-types/batches.md +50 -0
  70. package/docs/project-types/build.md +42 -0
  71. package/docs/project-types/completion.md +15 -0
  72. package/docs/project-types/conditions.md +21 -0
  73. package/docs/project-types/hosted-review.md +115 -0
  74. package/docs/project-types/onboarding.md +75 -0
  75. package/docs/project-types/running.md +309 -0
  76. package/docs/project-types/testing.md +72 -0
  77. package/docs/reference/application-artifacts.md +87 -0
  78. package/docs/reference/authoring-guide.md +134 -0
  79. package/docs/reference/browser-applications.md +267 -0
  80. package/docs/reference/capabilities.md +45 -0
  81. package/docs/reference/cli.md +71 -0
  82. package/docs/reference/connection-api.md +59 -0
  83. package/docs/reference/cooperative-jobs.md +13 -0
  84. package/docs/reference/desktop-capabilities.md +172 -0
  85. package/docs/reference/desktop-execution.md +77 -0
  86. package/docs/reference/errors.md +233 -0
  87. package/docs/reference/execution.md +800 -0
  88. package/docs/reference/first-party-blocks.md +40 -0
  89. package/docs/reference/generation-models.md +59 -0
  90. package/docs/reference/limits.md +306 -0
  91. package/docs/reference/manifest-kinds-controls.md +36 -0
  92. package/docs/reference/manifest.md +181 -0
  93. package/docs/reference/operations.md +36 -0
  94. package/docs/reference/package-jobs.md +35 -0
  95. package/docs/reference/parity.md +55 -0
  96. package/docs/reference/permissions.md +86 -0
  97. package/docs/reference/ports.md +26 -0
  98. package/docs/reference/types.md +268 -0
  99. package/docs/reference/universal-resolver.md +303 -0
  100. package/docs/reference/view-bridge.md +60 -0
  101. package/docs/reference/view-rules.md +15 -0
  102. package/docs/reference/workspace-sync.md +25 -0
  103. package/docs/sdk.md +34 -0
  104. package/docs/tools/block-remix.md +211 -0
  105. package/docs/tools/llm.md +2213 -0
  106. package/docs/tools/repository-adaptation.md +613 -0
  107. package/examples/check-clip.stillmade.json +4 -1
  108. package/examples/generate-video.stillmade.json +6 -2
  109. package/examples/research-topic.stillmade.json +5 -1
  110. package/examples/text-workflow.stillmade.json +3 -32
  111. package/examples/timeline-polish.stillmade.json +11 -3
  112. package/examples/transcribe-audio.stillmade.json +11 -3
  113. package/package.json +1 -1
  114. package/packages/block-cli/cli.js +13 -6
  115. package/packages/block-cli/dev-host/assets/host.js +76 -38
  116. package/packages/block-cli/dev-host/assets/index.css +1 -1
  117. package/packages/block-cli/format.js +1 -1
  118. package/packages/block-cli/templates.js +31 -13
  119. package/packages/block-cli/type-packages.js +119 -0
  120. package/packages/block-platform/block-readiness.js +5 -0
  121. package/packages/block-platform/canvas.js +2 -1
  122. package/packages/block-platform/catalog.js +27 -48
  123. package/packages/block-platform/native-host-inventory.js +0 -226
  124. package/packages/block-platform/plain-descriptions.js +1 -25
  125. package/packages/block-platform/project-type-starters.js +13 -53
  126. package/packages/block-platform/script-handoff.js +2 -4
  127. package/packages/block-platform/type-workspace.js +2 -0
  128. package/packages/block-sdk/appearance.js +3 -1
  129. package/packages/block-sdk/block-tier.js +1 -1
  130. package/packages/block-sdk/builder-contract.js +10 -8
  131. package/packages/block-sdk/capabilities.js +1 -1
  132. package/packages/block-sdk/contracts.js +6 -2
  133. package/packages/block-sdk/first-party-identities.js +1 -84
  134. package/packages/block-sdk/first-party-packages.js +3 -85
  135. package/packages/block-sdk/generation-catalog.js +15 -3
  136. package/packages/block-sdk/index.d.ts +2 -1
  137. package/packages/block-sdk/media-analysis-example.js +1 -1
  138. package/packages/block-sdk/mock-host.js +7 -1
  139. package/packages/block-sdk/module-host-calls.js +35 -10
  140. package/packages/block-sdk/module-hosted.js +15 -2
  141. package/packages/block-sdk/module-media-access.js +71 -0
  142. package/packages/block-sdk/module-node.js +1 -1
  143. package/packages/block-sdk/portable-media-actions.js +1 -1
  144. package/packages/block-sdk/runtime.js +1 -1
  145. package/packages/block-sdk/timeline-proposal-example.js +1 -1
  146. package/packages/block-sdk/transcription-example.js +1 -1
  147. package/packages/block-sdk/video-generation-example.js +1 -1
  148. package/packages/block-sdk/view-bridge.js +4 -1
  149. package/packages/block-sdk/view-design.js +17 -14
  150. package/packages/block-sdk/web-example.js +1 -1
  151. package/packages/design-system/block-kit.css +48 -12
  152. package/packages/design-system/block-kit.html +3 -2
  153. package/blocks/mcp-motion-planner/versions/1.1.0/package.js +0 -97
  154. package/blocks/motion-designer/versions/1.0.1/package.js +0 -173318
  155. package/blocks/motion-designer/versions/1.0.2/package.js +0 -173318
  156. package/blocks/motion-frame-review/versions/1.1.1/package.js +0 -465
  157. package/blocks/motion-frame-review/versions/1.1.2/package.snapshot.js +0 -572
  158. package/blocks/narration/package.js +0 -1
  159. package/blocks/narration/versions/1.0.0/package.js +0 -221
  160. package/blocks/narration/versions/1.0.1/package.js +0 -221
  161. package/blocks/native/sm.animated-scene/versions/2.0.0/package.js +0 -475
  162. package/blocks/native/sm.animated-scene/versions/2.1.0/package.js +0 -498
  163. package/blocks/native/sm.animated-scene/versions/2.2.0/package.js +0 -524
  164. package/blocks/native/sm.animated-scene/versions/2.3.0/package.js +0 -618
  165. package/blocks/native/sm.animated-scene/versions/2.3.1/package.js +0 -618
  166. package/blocks/native/sm.animated-scene/versions/2.3.2/package.js +0 -723
  167. package/blocks/native/sm.animated-scene/versions/2.3.3/package.js +0 -723
  168. package/blocks/native/sm.animated-scene/versions/2.3.4/package.js +0 -676
  169. package/blocks/native/sm.animated-scene/versions/2.3.5/package.js +0 -693
  170. package/blocks/native/sm.animated-scene/versions/2.3.6/package.js +0 -700
  171. package/blocks/native/sm.animated-scene/versions/2.3.7/package.js +0 -747
  172. package/blocks/native/sm.animated-scene/versions/2.3.8/package.js +0 -769
  173. package/blocks/native/sm.animated-scene/versions/2.3.9/package.js +0 -769
  174. package/blocks/native/sm.animated-scene-assistant/versions/1.0.0/package.js +0 -183
  175. package/blocks/native/sm.blueprint/versions/2.0.0/package.js +0 -358
  176. package/blocks/native/sm.blueprint/versions/2.1.0/package.js +0 -358
  177. package/blocks/native/sm.blueprint/versions/2.1.1/package.js +0 -358
  178. package/blocks/native/sm.blueprint/versions/2.1.2/package.js +0 -358
  179. package/blocks/native/sm.blueprint/versions/2.1.3/package.js +0 -381
  180. package/blocks/native/sm.blueprint/versions/2.1.4/package.js +0 -381
  181. package/blocks/native/sm.blueprint/versions/2.1.5/package.js +0 -339
  182. package/blocks/native/sm.blueprint/versions/2.1.6/package.js +0 -356
  183. package/blocks/native/sm.blueprint/versions/2.1.7/package.js +0 -363
  184. package/blocks/native/sm.blueprint/versions/2.1.8/package.js +0 -410
  185. package/blocks/native/sm.blueprint/versions/2.1.9/package.js +0 -422
  186. package/blocks/native/sm.blueprint-assistant/versions/1.0.0/package.js +0 -172
  187. package/blocks/native/sm.chat/versions/2.0.0/package.js +0 -144
  188. package/blocks/native/sm.chat/versions/2.0.1/package.js +0 -97
  189. package/blocks/native/sm.chat/versions/2.0.2/package.js +0 -100
  190. package/blocks/native/sm.chat/versions/2.0.3/package.js +0 -100
  191. package/blocks/native/sm.continue-if/versions/1.0.0/package.js +0 -168
  192. package/blocks/native/sm.describe-media/versions/2.0.0/package.js +0 -153
  193. package/blocks/native/sm.describe-media/versions/2.0.1/package.js +0 -156
  194. package/blocks/native/sm.describe-media/versions/2.1.0/package.js +0 -140
  195. package/blocks/native/sm.image-editor/versions/2.0.0/package.js +0 -183
  196. package/blocks/native/sm.image-editor/versions/2.0.1/package.js +0 -190
  197. package/blocks/native/sm.new-items/versions/1.0.0/package.js +0 -191
  198. package/blocks/native/sm.pick-photos/versions/1.0.0/package.js +0 -334
  199. package/blocks/native/sm.quality-audit/versions/1.0.0/package.js +0 -192
  200. package/blocks/native/sm.quality-audit/versions/1.0.1/package.js +0 -192
  201. package/blocks/native/sm.quality-audit/versions/1.0.2/package.js +0 -195
  202. package/blocks/native/sm.research/versions/2.0.0/package.js +0 -175
  203. package/blocks/native/sm.research/versions/2.0.1/package.js +0 -184
  204. package/blocks/native/sm.research/versions/2.0.2/package.js +0 -187
  205. package/blocks/native/sm.script/versions/2.0.0/package.js +0 -144
  206. package/blocks/native/sm.script/versions/2.1.0/package.js +0 -144
  207. package/blocks/native/sm.script/versions/2.1.1/package.js +0 -144
  208. package/blocks/native/sm.script/versions/2.1.2/package.js +0 -105
  209. package/blocks/native/sm.script/versions/2.1.3/package.js +0 -152
  210. package/blocks/native/sm.script/versions/2.1.4/package.js +0 -156
  211. package/blocks/native/sm.script/versions/2.1.5/package.js +0 -156
  212. package/blocks/native/sm.shot-plan/versions/2.0.0/package.js +0 -301
  213. package/blocks/native/sm.shot-plan/versions/2.1.0/package.js +0 -528
  214. package/blocks/native/sm.shot-plan/versions/2.1.1/package.js +0 -528
  215. package/blocks/native/sm.shot-plan/versions/2.1.2/package.js +0 -528
  216. package/blocks/native/sm.shot-plan/versions/2.1.3/package.js +0 -536
  217. package/blocks/native/sm.shot-plan/versions/2.2.0/package.js +0 -800
  218. package/blocks/native/sm.shot-plan/versions/2.2.1/package.js +0 -920
  219. package/blocks/native/sm.shot-plan-assistant/versions/1.0.0/package.js +0 -173
  220. package/blocks/native/sm.stock-search/versions/2.0.0/package.js +0 -174
  221. package/blocks/native/sm.thumbnail/versions/2.0.0/package.js +0 -137
  222. package/blocks/native/sm.thumbnail/versions/2.0.1/package.js +0 -140
  223. package/blocks/native/sm.transcribe/versions/2.0.0/package.js +0 -163
  224. package/blocks/native/sm.transcribe/versions/2.0.1/package.js +0 -168
  225. package/blocks/native/sm.whiteboard-assistant/versions/1.0.0/package.js +0 -175
  226. package/blocks/native/sm.youtube/versions/2.0.0/package.js +0 -217
  227. package/blocks/occasion-story/package.js +0 -1
  228. package/blocks/occasion-story/versions/1.0.0/package.js +0 -1658
  229. package/blocks/occasion-story/versions/1.0.1/package.js +0 -1699
  230. package/blocks/occasion-story/versions/1.0.2/package.js +0 -1682
  231. package/blocks/photo-reel-composer/versions/1.0.0/package.js +0 -3043
  232. package/blocks/photo-reel-composer/versions/1.0.1/package.js +0 -3026
  233. package/blocks/photo-reel-composer/versions/1.0.2/package.js +0 -4149
  234. package/blocks/product-ad-variants/versions/1.0.0/package.js +0 -2911
  235. package/blocks/product-launch-director/versions/1.0.0/package.js +0 -103
  236. package/blocks/release-visuals/package.js +0 -1
  237. package/blocks/release-visuals/versions/1.0.0/package.js +0 -1492
  238. package/blocks/release-visuals/versions/1.0.1/package.js +0 -1517
  239. package/blocks/release-visuals/versions/1.0.2/package.js +0 -1500
  240. package/blocks/screen-recorder/package.js +0 -1
  241. package/blocks/screen-recorder/versions/1.0.0/package.js +0 -223
  242. package/blocks/screen-recorder/versions/1.0.1/package.js +0 -223
  243. package/blocks/short-form-finish/package.js +0 -1
  244. package/blocks/short-form-finish/versions/1.0.0/package.js +0 -1043
  245. package/blocks/short-form-finish/versions/1.0.1/package.js +0 -1043
  246. package/blocks/short-form-finish/versions/1.0.2/package.js +0 -1043
  247. package/blocks/short-form-finish/versions/1.0.3/package.js +0 -1026
  248. package/examples/saas-product-launch-reviewed-source.stillmade.json +0 -383
  249. package/examples/saas-product-launch.stillmade.json +0 -304
  250. package/packages/block-platform/dealer-inventory-video-project-type.js +0 -38
  251. package/packages/block-platform/first-revenue-project-types.js +0 -46
  252. package/packages/block-platform/fixture-starters.js +0 -13
  253. package/packages/block-platform/launch-project-source.js +0 -10
  254. package/packages/block-platform/launch-project.js +0 -30
  255. package/packages/block-platform/motion-project-types.js +0 -55
  256. package/packages/block-platform/motion-starters.js +0 -14
  257. package/packages/block-platform/product-ad-variants-project-type.js +0 -30
  258. package/packages/block-platform/product-launch-updated.js +0 -90
  259. package/packages/block-platform/revenue-review-project-types.js +0 -36
  260. package/packages/block-platform/revenue-review-starters.js +0 -13
  261. package/packages/block-platform/script-writer.js +0 -29
  262. package/packages/block-platform/website-source-block.js +0 -14
package/MODULES.md CHANGED
@@ -57,13 +57,18 @@ against the manifest's port types.
57
57
  | `progress(value, label)` | Reports progress from 0 to 1 with a short label. Each report extends the run limit. |
58
58
  | `log(...values)` | Adds a line to the run log (up to 500 lines). |
59
59
  | `asset(path)` | A copy of one of the module's own files, such as a `.wasm` build, as an `ArrayBuffer`. |
60
- | `files.read(ref)` | The bytes, as an `ArrayBuffer`, of a saved image, video, audio, asset or file (a PDF, text, CSV, Markdown or JSON file on a `file` input) the Block received as input, or that StillMade made in this run: files it wrote, transform results and generated media. Media the person kept on their device (a `sm-media://device/...` address in a project Step) reads the same way, without leaving the device. Other files cannot be read, and transforms, hosted calls and actions accept only these references too; a hosted call or action gets a cloud copy of device media, made once per version. |
60
+ | `files.read(ref)` | The bytes, as an `ArrayBuffer`, of a saved image, video, audio, asset or file (a PDF, text, CSV, Markdown or JSON file on a `file` input) the Block received as input, or that StillMade made in this run: files it wrote, transform results and generated media. Media the person kept on their device (a `sm-media://device/...` address in a project Step) reads the same way, without leaving the device. Other files cannot be read, and transforms, hosted calls and actions accept only these references too; a hosted call or action gets a cloud copy of device media, made once per version. A reference is the file its `kind`, `assetId`, `versionId` and `url` name, so `{kind, assetId, versionId, url}` rebuilt from a `media.generate` result item (without its `key`) is the same file; any other file is refused with `MODULE_FILE_READ`, by `stillmade-block test --mock`, `ready` and `gate` as by StillMade. |
61
61
  | `files.write(data, {mediaType, name})` | Saves PNG, JPEG, WebP, GIF, MP4, WebM, MP3, WAV, M4A or OGG media, or a PDF, TXT, CSV, Markdown, JSON or ZIP file (`application/pdf`, `text/plain`, `text/csv`, `text/markdown`, `application/json`, `application/zip`; a `{kind: 'file'}` reference), to the runner's library and returns a reference you can return as an output. At most 64 files per run. |
62
62
  | `media.transform(request)` | On-device media work done by StillMade: decode audio to samples, extract or loudness-normalise audio, cut, join or re-encode video, and take thumbnails. Results are saved like `files.write`. See [Media processing](#media-processing). |
63
- | `actions.run(action)` | Runs a declared portable action. `media.generate` asks the person to approve one StillMade credit maximum for the batch; `stock.search` runs directly. |
63
+ | `actions.run(action)` | Runs a declared portable action. `media.generate` opens one approval for its whole batch, naming the most it can cost in StillMade credits; `stock.search` runs directly. |
64
64
  | `hosted.run(operation, request)` | Calls a hosted operation the manifest lists in `permissions.capabilities` (for example `text.generate`, `image.generate`, `audio.speech`, `web.research`). Each call is quoted and approved like a capability Block and paid with StillMade credits. |
65
- | `net.fetch(url, {method, headers, body})` | Calls one of the origins declared in `permissions.network` through StillMade, which adds the person's own key or OAuth token. Returns a standard `Response`. |
65
+ | `net.fetch(url, {method, headers, body})` | Calls one of the origins declared in `permissions.network` through StillMade, which adds the person's own key or OAuth token. Returns a standard `Response`. See [Outside APIs](/docs/build/outside-apis). |
66
66
  | `net.connect(url, {protocols})` | Opens a live WebSocket to the `wss://` form of a declared origin and resolves with the open socket. No key is added. See [Live connections](#live-connections). |
67
+ | `connections.call(appId, operationId, input)` | Calls an operation of a published adapter declared in `permissions.connections`, with the person's own account. Returns the checked JSON result. |
68
+ | `storage.get/set/remove/list/info(...)` | The Block's own cloud storage in the current project: JSON values up to 1 MiB under folder-like keys. Kept across runs, devices and the Block's versions. See [Project storage, reads and assets](/docs/build/project-storage). |
69
+ | `storage.putFile(key, data, {mediaType})` / `storage.getFile(key)` | Files up to 64 MiB in the same storage; `getFile` returns `{key, mediaType, bytes, data}` with `data` as an `ArrayBuffer`, or `null`. |
70
+ | `project.read(fields?)` | A copy of the current project limited to the fields the manifest may read (`project.read` plus `context.<field>.read`), such as `timeline`, `shots` or `assets`. |
71
+ | `assets.create(file, {name})` / `assets.appendVersion(asset, file)` | Adds a saved image, video or audio file to the project's media as a new asset (`asset.create`), or as the newest version of an asset the Block received, read or created (`asset.version.append`). |
67
72
 
68
73
  Hosted calls take the operation's request fields, for example:
69
74
 
@@ -82,19 +87,158 @@ saved video, whose own sound it transcribes, so there is no need to extract the
82
87
  audio first. `media.analyze` returns `{schemaVersion: 1, items}`, one item per
83
88
  picture or video, and for one video takes an optional `range: {start, end}` in
84
89
  seconds, at most 12 apart, to look closely at that part. `image.generate` takes `prompt` and optional
85
- `references`, one to eight saved images the new picture keeps. Look at pictures with `media.analyze`:
90
+ `references`, one to eight saved images the new picture keeps. `video.generate` takes `prompt` and optional
91
+ `firstFrame` (a saved image the video starts on, for image-to-video), `lastFrame` (one it ends on; needs
92
+ `firstFrame`), `negativePrompt` (up to 2,000 characters) and `settings`; a model named in `settings` must take
93
+ those frames (Kling 3.0 Turbo and Wan 2.6 Flash take no last frame; Wan 2.6 Flash and Wan 2.7 need a first frame).
94
+ For a vertical or square clip, set `settings.aspectRatio` (`'9:16'`, `'1:1'`) and name no model: the default
95
+ model (Vidu Q3 Turbo) takes no aspect ratio, so StillMade uses the cheapest model that makes that shape with the
96
+ frames and `duration` given (Wan 2.6 Flash with a first frame, else Veo 3.1 Lite, else Seedance 2.0 Mini; see
97
+ [Generation models](/docs/reference/generation-models)). A model you name is kept, and one that cannot make the shape
98
+ is refused. Look at pictures with `media.analyze`:
86
99
  StillMade credits pay for it, while `image.describe` runs only on the person's
87
100
  own OpenRouter key. `web.fetch` takes `url` and `instruction`;
88
101
  `web.research` takes `topic`; music and sound effects take `prompt` and
89
102
  `durationSec`.
90
103
 
104
+ ### Actions (`permissions.actions`)
105
+
106
+ `actions.run` runs only the actions listed in `permissions.actions`, the same list a
107
+ JavaScript Block declares: `"actions": ["media.generate"]` (or `"stock.search"`). A
108
+ module that runs actions and calls no hosted operation leaves
109
+ `permissions.capabilities` out; an empty list means the same.
110
+
111
+ ```js
112
+ const { value, failures } = await stillmade.actions.run({
113
+ schemaVersion: 1, kind: 'stillmade.media-action', operation: 'media.generate',
114
+ resultPort: null,
115
+ request: { items: [
116
+ { key: 'front', operation: 'image', prompt: `The front of ${input.address} at dusk`,
117
+ settings: { model: 'nano-banana-pro', aspectRatio: '16:9' } },
118
+ { key: 'tour', operation: 'speech', prompt: input.script },
119
+ ] },
120
+ });
121
+ ```
122
+
123
+ The action is the object a JavaScript Block returns, with every key present; its
124
+ items, settings and limits are in [Generate media from
125
+ JavaScript](/docs/build/generate-media). Pass `resultPort: null`: no
126
+ output port receives the media, `actions.run` returns it to your code and `run()`
127
+ returns what the Block outputs. Before anything is generated StillMade opens one
128
+ approval for the whole batch with the most it can cost in StillMade credits; credits
129
+ the batch does not use come back when it closes. Each `actions.run` call is its own
130
+ approval, so put every item one run needs in one batch: one clip per photo, the
131
+ voice and the music are one `media.generate` call of up to 50 items (StillMade makes
132
+ four at a time), never a call per photo, and never `hosted.run('video.generate')` once
133
+ per photo, which asks again from the second call. Video items take the same
134
+ `settings` as `video.generate` above, `aspectRatio` included. `actions.run` resolves with:
135
+
136
+ - `value`: the items that were made, in request order, each
137
+ `{key, kind, assetId, versionId, url, duration?}` with `kind` `image`, `video` or `audio`
138
+ (speech, music and sound effects). `duration` is the length in seconds of a
139
+ video, music or sound effect item: the length it asked for (`settings.duration`,
140
+ `settings.durationSec`, or the model's default). A speech item has none, since
141
+ its length is what the words take: decode it with
142
+ `media.transform({operation: 'audio.decode', source})`, whose result has
143
+ `duration`, before timing a cut to it. Return them as outputs, or pass them to
144
+ `files.read`, `media.transform` or a hosted call.
145
+ - `failures`: one `{key, message}` for each item that was not made; those items are
146
+ not in `value`.
147
+
148
+ It throws when no item was made, when the person declines (`MODULE_ACTION_DECLINED`)
149
+ and when the action is not declared (`MODULE_PERMISSION`). `stock.search` resolves
150
+ with `{results}`. With `--mock` or a `tests/mocks.json`, `media.generate` answers
151
+ with stand-in media and no failures; record your own answer under
152
+ `actions["media.generate"]`.
153
+
154
+ ## A check, then the expensive run, on one page
155
+
156
+ A job the person fills in and then gets a result from is one Block on one page
157
+ (builder contract, "One job per Step"): the inputs, a cheap check before the
158
+ expensive run, and the result. A listing video writes the script and voices a
159
+ few seconds of it first, and makes the video only once the person has read the
160
+ script and heard the voice. Build that as one module Block with a custom view,
161
+ never as two Blocks or two Steps.
162
+
163
+ The manifest takes the mode and the checked values as optional inputs, and the
164
+ outputs the check leaves out are optional (a run may leave out any output with
165
+ `"required": false`). `action` names the main button, the expensive run:
166
+
167
+ ```json
168
+ "inputs": {
169
+ "listingPhotos": { "type": "image[]", "primary": true, "description": "Photos of the home, in the order of the tour." },
170
+ "homeFacts": { "type": "text", "description": "Address, rooms and what stands out." },
171
+ "make": { "type": "text", "required": false, "default": "video", "description": "check: the script and a voice sample; video: the tour." },
172
+ "script": { "type": "script", "required": false, "description": "The checked script, as the person left it." }
173
+ },
174
+ "outputs": {
175
+ "tour": { "type": "video", "primary": true, "required": false },
176
+ "script": { "type": "script", "required": false },
177
+ "voiceSample": { "type": "audio", "required": false }
178
+ },
179
+ "action": { "label": "Generate tour", "running": "Generating tour…" },
180
+ "permissions": { "capabilities": ["text.generate", "audio.speech"] }
181
+ ```
182
+
183
+ The module does only the cheap work when asked for the check:
184
+
185
+ ```js
186
+ export default async function run(input, stillmade) {
187
+ const write = async () => (await stillmade.hosted.run('text.generate', {
188
+ prompt: `A 40-second listing tour script from these facts: ${input.homeFacts}`,
189
+ schema: { type: 'object', required: ['script'], properties: { script: { type: 'string' } } },
190
+ })).script;
191
+ if (input.make === 'check') {
192
+ const script = await write();
193
+ const voiceSample = await stillmade.hosted.run('audio.speech', { text: script.split(/(?<=[.!?])\s/)[0] });
194
+ return { script, voiceSample };
195
+ }
196
+ const script = input.script || await write();
197
+ const voice = await stillmade.hosted.run('audio.speech', { text: script });
198
+ const { duration } = await stillmade.media.transform({ operation: 'audio.decode', source: voice });
199
+ const each = duration / input.listingPhotos.length;
200
+ const tour = await stillmade.media.transform({
201
+ operation: 'timeline.render', aspect: '9:16',
202
+ clips: input.listingPhotos.map((photo, index) => ({ source: photo, start: index * each, duration: each, motion: 'zoom-in' })),
203
+ audio: [{ source: voice, start: 0, duration }],
204
+ });
205
+ return { tour, script };
206
+ }
207
+ ```
208
+
209
+ The view runs it twice with `StillMade.run`, which takes the inputs the view
210
+ sets (StillMade keeps them on the Step and fills the rest): `{make: 'check'}`
211
+ first ("Write the script"), then `{make: 'video', script}` with the script the
212
+ person checked or edited. One `sm-primary` at a time: the check until there is
213
+ a script, then the expensive run, labelled with `manifest.action`, while
214
+ "Write again" stays a quiet button. The result's place
215
+ (`sm-stage data-ratio="9:16"`) is drawn before either run; the script and the sample sit in it or beside the inputs
216
+ until the video replaces them. Each run starts empty: return the script again
217
+ with the video so it stays on the Step. StillMade saves the inputs a view sets,
218
+ so the mode last pressed stays on the Step; until the view first sets it, a run
219
+ started elsewhere (Chat, an automation) takes the default and makes the video.
220
+
221
+ Each run is priced and approved by StillMade on its own. Beside the Block's
222
+ page StillMade shows what each hosted call costs at the Step's saved or default
223
+ model ("Write · 1 credit · Make voiceover · 3 credits"), with an (i) saying that
224
+ pressing the Block's button is the approval. A run started by the person's own
225
+ click or key in the view then runs each hosted operation once without a dialog,
226
+ up to that price. StillMade checks the price with the provider first and opens
227
+ its approval dialog, with the quote, only when the quote is higher, when the run
228
+ calls the same operation a second time, or when the run did not come from the
229
+ person's press (in a preview outside a project every call shows the dialog;
230
+ `stillmade-block dev` answers with stand-ins and spends nothing). The view shows
231
+ no prices. `media.transform`, `timeline.render` included, runs on the device
232
+ and costs nothing; `actions.run` `media.generate` always asks first.
233
+
91
234
  ## Media processing
92
235
 
93
236
  `stillmade.media.transform(request)` asks StillMade to do heavy media work on
94
237
  the person's device: Web Audio for audio, and the same renderer as Final
95
238
  Render for video (WebCodecs in the browser, the native renderer on desktop).
96
239
  It never runs on StillMade's servers and costs no credits. A transform reads
97
- only files the Block received, wrote or generated in this run, and saves its
240
+ only files the Block received, wrote or generated in this run (including media
241
+ from `actions.run` `media.generate`; see `files.read` above), and saves its
98
242
  result to the runner's library, so you can return it as an output or pass it
99
243
  to the next transform.
100
244
 
@@ -117,7 +261,9 @@ from?, transition?: {type, duration?}, look?, mute?, motion?, fit?, focus?}` (a
117
261
  image or video; a video keeps its own sound unless `mute`; `motion` is a slow
118
262
  camera move over the clip: `zoom-in`, `zoom-out`, `pan-left`, `pan-right`,
119
263
  `pan-up` or `pan-down`, which always keeps the picture filling the frame), each
120
- audio item `{source, start, duration, from?, volume?}`, and each caption
264
+ audio item `{source, start, duration, from?, volume?}` (`volume` is a percentage of the
265
+ recording's own level, 0 to 200: 100, the default, plays it as recorded, 50 at half
266
+ the level, 0 silent; put music under a voice at about 20 to 30), and each caption
121
267
  `{text, start, end, words?, position?, highlight?, animation?, size?}`, where
122
268
  `words` (`[{text, start, end}]`) highlights each word as it is spoken and `size`
123
269
  is the text height in pixels of the rendered frame (16 to 200; default 44, so