stillmade-sdk 0.1.41 → 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 (285) hide show
  1. package/.stillmade/sdk-baseline.json +19 -21
  2. package/AGENTS.md +17 -12
  3. package/FRAME_VIEWS.md +113 -0
  4. package/INTERFACE_DESIGN.md +67 -22
  5. package/MOBILE_UI.md +4 -2
  6. package/MODULES.md +152 -6
  7. package/PASTE_TO_LLM.md +42 -32
  8. package/README.md +3 -2
  9. package/SDK.md +1028 -563
  10. package/UI_AESTHETIC.md +30 -3
  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 +8 -1
  108. package/examples/clean-text.stillmade.json +4 -0
  109. package/examples/custom-interface.stillmade.json +4 -0
  110. package/examples/describe-image.stillmade.json +4 -0
  111. package/examples/foley-cue.stillmade.json +4 -0
  112. package/examples/generate-image.stillmade.json +4 -0
  113. package/examples/generate-video.stillmade.json +10 -2
  114. package/examples/module-word-stats/stillmade.block.json +4 -0
  115. package/examples/narrate-script.stillmade.json +4 -0
  116. package/examples/numbered-takes.stillmade.json +4 -0
  117. package/examples/research-topic.stillmade.json +9 -1
  118. package/examples/score-a-scene.stillmade.json +4 -0
  119. package/examples/script-draft.stillmade.json +4 -0
  120. package/examples/summarize-page.stillmade.json +4 -0
  121. package/examples/text-workflow.stillmade.json +7 -32
  122. package/examples/thicken-lines.stillmade.json +4 -0
  123. package/examples/timeline-polish.stillmade.json +15 -3
  124. package/examples/transcribe-audio.stillmade.json +15 -3
  125. package/examples/word-count.stillmade.json +4 -0
  126. package/package.json +1 -1
  127. package/packages/block-cli/cli.js +13 -6
  128. package/packages/block-cli/dev-host/assets/host.js +81 -38
  129. package/packages/block-cli/dev-host/assets/index.css +1 -1
  130. package/packages/block-cli/format.js +1 -1
  131. package/packages/block-cli/ready-gate.js +4 -0
  132. package/packages/block-cli/templates.js +37 -19
  133. package/packages/block-cli/type-packages.js +119 -0
  134. package/packages/block-platform/block-readiness.js +8 -1
  135. package/packages/block-platform/canvas.js +2 -1
  136. package/packages/block-platform/catalog.js +27 -48
  137. package/packages/block-platform/native-host-inventory.js +0 -226
  138. package/packages/block-platform/plain-descriptions.js +1 -25
  139. package/packages/block-platform/project-type-starters.js +13 -53
  140. package/packages/block-platform/script-handoff.js +2 -4
  141. package/packages/block-platform/type-workspace.js +2 -0
  142. package/packages/block-sdk/appearance.js +3 -1
  143. package/packages/block-sdk/audio-generation-example.js +2 -2
  144. package/packages/block-sdk/block-tier.js +1 -1
  145. package/packages/block-sdk/builder-contract.js +13 -11
  146. package/packages/block-sdk/capabilities.js +1 -1
  147. package/packages/block-sdk/capability-example.js +1 -1
  148. package/packages/block-sdk/contracts.js +6 -2
  149. package/packages/block-sdk/examples.js +3 -3
  150. package/packages/block-sdk/first-party-identities.js +1 -84
  151. package/packages/block-sdk/first-party-packages.js +3 -85
  152. package/packages/block-sdk/generation-catalog.js +15 -3
  153. package/packages/block-sdk/image-description-example.js +1 -1
  154. package/packages/block-sdk/image-generation-example.js +1 -1
  155. package/packages/block-sdk/index.d.ts +2 -1
  156. package/packages/block-sdk/media-analysis-example.js +2 -2
  157. package/packages/block-sdk/mock-host.js +7 -1
  158. package/packages/block-sdk/module-example.js +1 -1
  159. package/packages/block-sdk/module-host-calls.js +35 -10
  160. package/packages/block-sdk/module-hosted.js +15 -2
  161. package/packages/block-sdk/module-media-access.js +71 -0
  162. package/packages/block-sdk/module-node.js +1 -1
  163. package/packages/block-sdk/portable-media-actions.js +1 -1
  164. package/packages/block-sdk/runtime.js +1 -1
  165. package/packages/block-sdk/speech-example.js +1 -1
  166. package/packages/block-sdk/state-example.js +1 -1
  167. package/packages/block-sdk/timeline-proposal-example.js +1 -1
  168. package/packages/block-sdk/transcription-example.js +1 -1
  169. package/packages/block-sdk/trigger-examples.js +2 -2
  170. package/packages/block-sdk/video-generation-example.js +1 -1
  171. package/packages/block-sdk/view-bridge.js +4 -1
  172. package/packages/block-sdk/view-design.js +44 -15
  173. package/packages/block-sdk/web-example.js +2 -2
  174. package/packages/design-system/block-kit.css +53 -12
  175. package/packages/design-system/block-kit.html +3 -2
  176. package/blocks/mcp-motion-planner/versions/1.1.0/package.js +0 -97
  177. package/blocks/motion-designer/versions/1.0.1/package.js +0 -173318
  178. package/blocks/motion-designer/versions/1.0.2/package.js +0 -173318
  179. package/blocks/motion-frame-review/versions/1.1.1/package.js +0 -465
  180. package/blocks/motion-frame-review/versions/1.1.2/package.snapshot.js +0 -572
  181. package/blocks/narration/package.js +0 -1
  182. package/blocks/narration/versions/1.0.0/package.js +0 -221
  183. package/blocks/narration/versions/1.0.1/package.js +0 -221
  184. package/blocks/native/sm.animated-scene/versions/2.0.0/package.js +0 -475
  185. package/blocks/native/sm.animated-scene/versions/2.1.0/package.js +0 -498
  186. package/blocks/native/sm.animated-scene/versions/2.2.0/package.js +0 -524
  187. package/blocks/native/sm.animated-scene/versions/2.3.0/package.js +0 -618
  188. package/blocks/native/sm.animated-scene/versions/2.3.1/package.js +0 -618
  189. package/blocks/native/sm.animated-scene/versions/2.3.2/package.js +0 -723
  190. package/blocks/native/sm.animated-scene/versions/2.3.3/package.js +0 -723
  191. package/blocks/native/sm.animated-scene/versions/2.3.4/package.js +0 -676
  192. package/blocks/native/sm.animated-scene/versions/2.3.5/package.js +0 -693
  193. package/blocks/native/sm.animated-scene/versions/2.3.6/package.js +0 -700
  194. package/blocks/native/sm.animated-scene/versions/2.3.7/package.js +0 -747
  195. package/blocks/native/sm.animated-scene/versions/2.3.8/package.js +0 -769
  196. package/blocks/native/sm.animated-scene/versions/2.3.9/package.js +0 -769
  197. package/blocks/native/sm.animated-scene-assistant/versions/1.0.0/package.js +0 -183
  198. package/blocks/native/sm.blueprint/versions/2.0.0/package.js +0 -358
  199. package/blocks/native/sm.blueprint/versions/2.1.0/package.js +0 -358
  200. package/blocks/native/sm.blueprint/versions/2.1.1/package.js +0 -358
  201. package/blocks/native/sm.blueprint/versions/2.1.2/package.js +0 -358
  202. package/blocks/native/sm.blueprint/versions/2.1.3/package.js +0 -381
  203. package/blocks/native/sm.blueprint/versions/2.1.4/package.js +0 -381
  204. package/blocks/native/sm.blueprint/versions/2.1.5/package.js +0 -339
  205. package/blocks/native/sm.blueprint/versions/2.1.6/package.js +0 -356
  206. package/blocks/native/sm.blueprint/versions/2.1.7/package.js +0 -363
  207. package/blocks/native/sm.blueprint/versions/2.1.8/package.js +0 -410
  208. package/blocks/native/sm.blueprint/versions/2.1.9/package.js +0 -422
  209. package/blocks/native/sm.blueprint-assistant/versions/1.0.0/package.js +0 -172
  210. package/blocks/native/sm.chat/versions/2.0.0/package.js +0 -144
  211. package/blocks/native/sm.chat/versions/2.0.1/package.js +0 -97
  212. package/blocks/native/sm.chat/versions/2.0.2/package.js +0 -100
  213. package/blocks/native/sm.chat/versions/2.0.3/package.js +0 -100
  214. package/blocks/native/sm.continue-if/versions/1.0.0/package.js +0 -168
  215. package/blocks/native/sm.describe-media/versions/2.0.0/package.js +0 -153
  216. package/blocks/native/sm.describe-media/versions/2.0.1/package.js +0 -156
  217. package/blocks/native/sm.describe-media/versions/2.1.0/package.js +0 -140
  218. package/blocks/native/sm.image-editor/versions/2.0.0/package.js +0 -183
  219. package/blocks/native/sm.image-editor/versions/2.0.1/package.js +0 -190
  220. package/blocks/native/sm.new-items/versions/1.0.0/package.js +0 -191
  221. package/blocks/native/sm.pick-photos/versions/1.0.0/package.js +0 -334
  222. package/blocks/native/sm.quality-audit/versions/1.0.0/package.js +0 -192
  223. package/blocks/native/sm.quality-audit/versions/1.0.1/package.js +0 -192
  224. package/blocks/native/sm.quality-audit/versions/1.0.2/package.js +0 -195
  225. package/blocks/native/sm.research/versions/2.0.0/package.js +0 -175
  226. package/blocks/native/sm.research/versions/2.0.1/package.js +0 -184
  227. package/blocks/native/sm.research/versions/2.0.2/package.js +0 -187
  228. package/blocks/native/sm.script/versions/2.0.0/package.js +0 -144
  229. package/blocks/native/sm.script/versions/2.1.0/package.js +0 -144
  230. package/blocks/native/sm.script/versions/2.1.1/package.js +0 -144
  231. package/blocks/native/sm.script/versions/2.1.2/package.js +0 -105
  232. package/blocks/native/sm.script/versions/2.1.3/package.js +0 -152
  233. package/blocks/native/sm.script/versions/2.1.4/package.js +0 -156
  234. package/blocks/native/sm.script/versions/2.1.5/package.js +0 -156
  235. package/blocks/native/sm.shot-plan/versions/2.0.0/package.js +0 -301
  236. package/blocks/native/sm.shot-plan/versions/2.1.0/package.js +0 -528
  237. package/blocks/native/sm.shot-plan/versions/2.1.1/package.js +0 -528
  238. package/blocks/native/sm.shot-plan/versions/2.1.2/package.js +0 -528
  239. package/blocks/native/sm.shot-plan/versions/2.1.3/package.js +0 -536
  240. package/blocks/native/sm.shot-plan/versions/2.2.0/package.js +0 -800
  241. package/blocks/native/sm.shot-plan/versions/2.2.1/package.js +0 -920
  242. package/blocks/native/sm.shot-plan-assistant/versions/1.0.0/package.js +0 -173
  243. package/blocks/native/sm.stock-search/versions/2.0.0/package.js +0 -174
  244. package/blocks/native/sm.thumbnail/versions/2.0.0/package.js +0 -137
  245. package/blocks/native/sm.thumbnail/versions/2.0.1/package.js +0 -140
  246. package/blocks/native/sm.transcribe/versions/2.0.0/package.js +0 -163
  247. package/blocks/native/sm.transcribe/versions/2.0.1/package.js +0 -168
  248. package/blocks/native/sm.whiteboard-assistant/versions/1.0.0/package.js +0 -175
  249. package/blocks/native/sm.youtube/versions/2.0.0/package.js +0 -217
  250. package/blocks/occasion-story/package.js +0 -1
  251. package/blocks/occasion-story/versions/1.0.0/package.js +0 -1658
  252. package/blocks/occasion-story/versions/1.0.1/package.js +0 -1699
  253. package/blocks/occasion-story/versions/1.0.2/package.js +0 -1682
  254. package/blocks/photo-reel-composer/versions/1.0.0/package.js +0 -3043
  255. package/blocks/photo-reel-composer/versions/1.0.1/package.js +0 -3026
  256. package/blocks/photo-reel-composer/versions/1.0.2/package.js +0 -4149
  257. package/blocks/product-ad-variants/versions/1.0.0/package.js +0 -2911
  258. package/blocks/product-launch-director/versions/1.0.0/package.js +0 -103
  259. package/blocks/release-visuals/package.js +0 -1
  260. package/blocks/release-visuals/versions/1.0.0/package.js +0 -1492
  261. package/blocks/release-visuals/versions/1.0.1/package.js +0 -1517
  262. package/blocks/release-visuals/versions/1.0.2/package.js +0 -1500
  263. package/blocks/screen-recorder/package.js +0 -1
  264. package/blocks/screen-recorder/versions/1.0.0/package.js +0 -223
  265. package/blocks/screen-recorder/versions/1.0.1/package.js +0 -223
  266. package/blocks/short-form-finish/package.js +0 -1
  267. package/blocks/short-form-finish/versions/1.0.0/package.js +0 -1043
  268. package/blocks/short-form-finish/versions/1.0.1/package.js +0 -1043
  269. package/blocks/short-form-finish/versions/1.0.2/package.js +0 -1043
  270. package/blocks/short-form-finish/versions/1.0.3/package.js +0 -1026
  271. package/examples/saas-product-launch-reviewed-source.stillmade.json +0 -383
  272. package/examples/saas-product-launch.stillmade.json +0 -304
  273. package/packages/block-platform/dealer-inventory-video-project-type.js +0 -38
  274. package/packages/block-platform/first-revenue-project-types.js +0 -46
  275. package/packages/block-platform/fixture-starters.js +0 -13
  276. package/packages/block-platform/launch-project-source.js +0 -10
  277. package/packages/block-platform/launch-project.js +0 -30
  278. package/packages/block-platform/motion-project-types.js +0 -55
  279. package/packages/block-platform/motion-starters.js +0 -14
  280. package/packages/block-platform/product-ad-variants-project-type.js +0 -30
  281. package/packages/block-platform/product-launch-updated.js +0 -90
  282. package/packages/block-platform/revenue-review-project-types.js +0 -36
  283. package/packages/block-platform/revenue-review-starters.js +0 -13
  284. package/packages/block-platform/script-writer.js +0 -29
  285. package/packages/block-platform/website-source-block.js +0 -14
@@ -0,0 +1,83 @@
1
+ # Data types: files, documents, tables, links, dates and colors
2
+
3
+ Ports can carry general files and structured data, not only media and text.
4
+ Each type has a checked value shape, a generated control and a result layout,
5
+ so a Block that declares them needs no custom view.
6
+
7
+ | Type | Value | Generated control | Default result layout |
8
+ | --- | --- | --- | --- |
9
+ | `file` | `{kind: "file", assetId, versionId, mimeType, url?, name?, bytes?}`; `mimeType` is `application/pdf`, `text/plain`, `text/csv`, `text/markdown`, `application/json` or `application/zip` | `file` (upload) | `download` |
10
+ | `document` | `{schemaVersion: 1, format: "markdown" \| "plain", text, title?}`, up to 1,000,000 characters | `richtext` | `document` |
11
+ | `table` | `{columns: [name], rows: [{name: text \| number \| boolean \| null}]}`, up to 500 columns and 100,000 rows | `grid` | `table` (with CSV download) |
12
+ | `url` | An absolute `http` or `https` address without credentials | `url` | a link |
13
+ | `date` | ISO 8601: `2026-10-09` or `2026-10-09T14:30` (seconds and an offset optional) | `date` (`time: true` for date and time) | a formatted date |
14
+ | `color` | `#rrggbb` or `#rrggbbaa` | `color` | a swatch |
15
+
16
+ Lists of these types (`file[]`, `url[]`, `date[]`, `color[]`) work like other
17
+ lists; the `list` control edits `text[]`, `number[]`, `integer[]`, `url[]`,
18
+ `date[]` and `color[]` item by item.
19
+
20
+ Output presentations in `manifest.ui` choose a layout for an output:
21
+ `{control: "table", port}`, `{control: "document", port}` (a `document` or
22
+ Markdown `text`), `{control: "chart", port, chart: "bar" | "line", x, y}` (a
23
+ `table` with optional column names, or a `number[]`), `{control: "code", port,
24
+ language}` (`text`, `json` or `object`), `{control: "player", port}` (`audio` or
25
+ `video`) and `{control: "download", port}` (`file`, `file[]` or `file-bundle`).
26
+ Each control is checked against its port's type when the manifest is
27
+ validated. Layouts show Block data as text: links in a document are displayed,
28
+ not followed, and downloads go through the host's export policy.
29
+
30
+ ### Files
31
+
32
+ People upload files to a `file` input from the Block's controls. The host
33
+ checks the extension, the declared type, the size (50 MB) and the bytes (a PDF
34
+ or ZIP signature, valid UTF-8 text, parseable JSON) before the Block receives a
35
+ saved reference. Module Blocks read the bytes with
36
+ `stillmade.files.read(input.script)` and save new files with
37
+ `stillmade.files.write(bytes, {mediaType: "text/csv", name: "shots.csv"})`,
38
+ which returns a `file` value. Files a person uploaded to a Block, or a Block
39
+ saved, are indexed in project context as `files` (`file[]`, permission
40
+ `context.files.read`), apart from media so media lists stay media.
41
+
42
+ ### Helpers
43
+
44
+ `@stillmade/block-sdk/data` (also exported from the main entry) has the checks
45
+ and builders: `isFileValue`, `isDocumentValue`, `isTableValue`, `isUrlValue`,
46
+ `isDateValue`, `isColorValue`, `createTable(columns, rows)`,
47
+ `createDocument(text, {format, title})`, `tableToCsv(table)`,
48
+ `fileFormatFor(name)`, `checkFileSignature(bytes, mimeType)`, and the
49
+ `DATA_VALUE_LIMITS`, `FILE_FORMATS`, `FILE_MEDIA_TYPES` and `DOCUMENT_FORMATS`
50
+ tables. `IMPORT_FORMATS` lists every upload the host stores (media and files),
51
+ and `inspectMediaImportFile(file, {kinds: ["file"]})` checks a chosen file.
52
+
53
+ ### Conversions
54
+
55
+ Connections convert between these types with host-owned conversions, version 1:
56
+
57
+ | Conversion | From | To |
58
+ | --- | --- | --- |
59
+ | `text-to-url`, `url-to-text` | `text` | `url` (checked), and back |
60
+ | `text-to-table`, `table-to-text` | CSV `text` | `table`, and back to CSV |
61
+ | `object-to-table`, `table-to-object` | an `object` shaped as a table (for example from `csv-to-table`) | `table`, and back |
62
+ | `text-to-document`, `document-to-text` | `text` | a plain `document`, and back |
63
+ | `shots-to-shot-plan` | `shot[]` | the Shots workspace's version 1 `shot-plan` |
64
+
65
+ A shot list reaches the Shots workspace when the output declares the
66
+ workspace's meaning: `{"type": "shot[]", "semantic": "production_shot_plan"}`.
67
+
68
+ Shots 2.2.0 and Image Panels 2.4.0 take narration from an earlier Step. A
69
+ script whose output declares another meaning (or none), script-named `text`, or
70
+ a transcript reaches their `narrationScript` and `narrationTiming` inputs
71
+ through `script-as-narration`, `text-as-narration` and
72
+ `transcript-as-narration-timing` (version 1, words unchanged; listed in
73
+ `NARRATION_ADAPTERS`, not `ADAPTERS`). These are never
74
+ chosen by matching: StillMade pins one on the connection when such a Step is
75
+ added or replaced, or when the person picks "Use <Step>'s script". Declare
76
+ `"semantic": "narration_script"` on a narration output to connect without one.
77
+
78
+ ### Example: PDF to shot list
79
+
80
+ `examples/module-pdf-shot-list` is a module Block that takes an uploaded PDF,
81
+ reads its text with pdf.js (bundled, its worker code imported directly so
82
+ nothing is fetched), plans the shots with one `text.generate` call that has a
83
+ JSON schema, and returns a `table` and a `shot[]` the Shots workspace accepts.
@@ -0,0 +1,259 @@
1
+ # Frame views: any interface code
2
+
3
+ # Frame views: any interface code
4
+
5
+ A frame view (`"runtime": "frame"` in the view) is an interface written with
6
+ ordinary web code: React, Svelte, Vue or Preact bundles, SVG, canvas and
7
+ WebGL, pointer capture and drag, timers, loops, recursion, classes and Web
8
+ Workers. Use it when the reviewed subset of standard views is too small for
9
+ the interface you want.
10
+
11
+ ## Folder layout
12
+
13
+ ```
14
+ my-block/
15
+ stillmade.block.json
16
+ src/run.js or another runtime (recipe, module, capability)
17
+ src/view.html markup, for example <div id="root"></div>
18
+ src/view.css styles; use StillMade's theme variables
19
+ src/view.js ONE classic script: bundle with --format=iife
20
+ src/view.config.json {"runtime": "frame"}
21
+ tests/fixtures.json
22
+ ```
23
+
24
+ `src/view.config.json` may also set `"appearance"` and `"files"` (assets, see
25
+ below). Bundle npm dependencies into `src/view.js` as an IIFE, for example:
26
+
27
+ ```sh
28
+ esbuild src/view.jsx --bundle --format=iife --minify --jsx=automatic \
29
+ --define:process.env.NODE_ENV='"production"' --outfile=src/view.js
30
+ ```
31
+
32
+ Limits: markup and each stylesheet up to 256 KiB, `view.js` up to 4 MiB,
33
+ and up to 32 asset files with 8 MiB in total.
34
+
35
+ ## The `StillMade` object
36
+
37
+ Frame views get the same `StillMade` object as standard views: `input` and
38
+ `onInput`, `run`, `useOutput`, `getShared`, `onShared`, `updateShared`,
39
+ `bindShared`, `connectDocument`, `previewImage`, `previewMedia`, `render`
40
+ and the rest of the interface bridge. In addition:
41
+
42
+ | Member | What it does |
43
+ | --- | --- |
44
+ | `StillMade.asset(path)` | A `blob:` URL for one of the view's asset files, for `<img>`, `new FontFace()` or `<video>`. |
45
+ | `StillMade.assetBytes(path)` | A copy of an asset file's bytes as an `ArrayBuffer`. |
46
+
47
+ `StillMade.live` gives any view the camera and microphone as they happen, after the
48
+ person presses Start (see Live camera and microphone in
49
+ [Desktop capabilities](DESKTOP_CAPABILITIES.md)). A frame view can hand the frames to a
50
+ Worker it starts from a `blob:` URL.
51
+
52
+ Shared state works as in every view: keep each independently edited value in
53
+ its own field (for example `point0`, `point1`) so two people editing
54
+ different values never conflict.
55
+
56
+ ## Adding files to an input
57
+
58
+ A one-page Block shows its input's files on its own screen as tiles and adds
59
+ more there. Never draw an upload box or an `<input type="file">` of your own:
60
+ the + tile asks StillMade, which opens its own file picker and saves the
61
+ files exactly as the Step's own tiles do (working copies, files kept on the
62
+ person's device, the limits and the error messages).
63
+
64
+ ```html
65
+ <ul class="sm-gallery" data-size="small" id="photos">
66
+ <!-- one <li> per photo, drawn from onInput -->
67
+ <li><button type="button" class="sm-add" data-stillmade-add="listingPhotos"
68
+ aria-label="Add photos" title="Add photos"></button></li>
69
+ </ul>
70
+ ```
71
+
72
+ `data-stillmade-add` names a declared `image`, `video`, `audio`, `asset` or
73
+ `file` input, or a list of one of them (`image[]`). It needs no code: a click
74
+ or key press on the tile opens StillMade's picker. A list gets every chosen
75
+ file added; a single input takes the first. The saved values reach the view
76
+ the way every input does, so draw the tiles from `onInput`:
77
+
78
+ ```js
79
+ StillMade.onInput(async input => {
80
+ for (const photo of input.listingPhotos || []) {
81
+ const preview = await StillMade.previewImage(photo); // display copy
82
+ // ...add an <li><img src="preview.url"></li> before the + tile
83
+ }
84
+ });
85
+ ```
86
+
87
+ From your own button, call `await StillMade.addFiles('listingPhotos')` inside
88
+ its click handler. It resolves to `{added}` (0 when the person closes the
89
+ picker) and rejects with a message for an undeclared input, an input that is
90
+ not a file input, an input an earlier Step fills, a person who can only view
91
+ the project, or a call that does not come from a click or key press in the
92
+ view. The view never receives a `File` or a `blob:` URL, only the saved
93
+ values. StillMade hides `[data-stillmade-add]` tiles from viewers and for
94
+ inputs an earlier Step fills. In the SDK preview, the tile opens your
95
+ computer's file chooser and the preview keeps the files like your own picks.
96
+
97
+ ### Removing and reordering files
98
+
99
+ A list input's files are removed and put in order on the same screen, so a
100
+ person drops a bad photo or sets the tour's order without leaving the Block.
101
+ Put the buttons in each tile, with `data-index` (from 0) naming its place in
102
+ the list `onInput` gave you:
103
+
104
+ ```html
105
+ <li>
106
+ <img src="..." alt="Photo 3">
107
+ <span class="sm-tile-tools">
108
+ <button type="button" data-stillmade-move="listingPhotos" data-index="2" data-to="1"
109
+ aria-label="Move earlier" title="Move earlier"><span class="sm-glyph" data-glyph="chevron-left" aria-hidden="true"></span></button>
110
+ <button type="button" data-stillmade-move="listingPhotos" data-index="2" data-to="3"
111
+ aria-label="Move later" title="Move later"><span class="sm-glyph" data-glyph="chevron-right" aria-hidden="true"></span></button>
112
+ <button type="button" data-stillmade-remove="listingPhotos" data-index="2"
113
+ aria-label="Remove" title="Remove"><span class="sm-glyph" data-glyph="close" aria-hidden="true"></span></button>
114
+ </span>
115
+ </li>
116
+ ```
117
+
118
+ `data-stillmade-remove` removes the file at `data-index`; `data-stillmade-move`
119
+ moves it to the place `data-to`. A `data-to` past either end of the list does
120
+ nothing, so the first tile's Move earlier is harmless (disable it if you like).
121
+ From your own code, call `await StillMade.removeFile('listingPhotos', 2)` or
122
+ `await StillMade.moveFile('listingPhotos', 2, 1)` inside a click handler; each
123
+ resolves to `{files}`, how many the list now holds. StillMade changes the
124
+ Step's list as its own tile buttons do, keeping each saved file's upload record
125
+ with it, and the new list reaches the view through `onInput`: redraw the tiles
126
+ from it, never from your own copy.
127
+
128
+ Both work only on list inputs (`image[]`, `video[]`, `audio[]`, `asset[]`,
129
+ `file[]`); `addFiles` replaces a single input's file. They are refused, as
130
+ `addFiles` is, for an undeclared input, an input an earlier Step fills, a
131
+ viewer, Chat and a call that does not come from a click or key press in the
132
+ view, and also when the file at that place changed after the view was given it
133
+ (another person edited the list): the view gets the current list and the person
134
+ tries again. StillMade hides these buttons wherever it hides the + tile. The SDK
135
+ preview changes its example input the same way.
136
+
137
+ ## Theming
138
+
139
+ The theme variables from StillMade's design system are always defined:
140
+ `var(--bg)`, `var(--bg-elev-1)`, `var(--fg)`, `var(--fg-muted)`,
141
+ `var(--accent)`, `var(--border-tok)`, `var(--divider)`, `var(--r-3)` and the
142
+ rest. Colors written with them follow Light, Dark and White automatically.
143
+ Frame views are not required to use them; the appearance check reports
144
+ hard-coded colors as advice instead of refusing the view.
145
+
146
+ A color the check takes is a theme variable, `transparent` or `currentColor`,
147
+ or a gradient of them (`linear-gradient(to top, var(--bg), transparent)`).
148
+ `opacity` is not a color and is always allowed. `color-mix()`, `rgba()`,
149
+ `#rrggbbaa` and other written colors are what it reports. For words over a
150
+ photo or video, use the kit's shade: `var(--scrim)` is the page's background,
151
+ partly see-through, in every theme, and `class="sm-scrim"` lays it over the
152
+ bottom of a positioned box (an `sm-stage`) under the words inside it:
153
+
154
+ ```html
155
+ <figure class="sm-stage" data-fill>
156
+ <img src="..." alt="">
157
+ <figcaption class="sm-scrim">12 Elm Street · 3 bed</figcaption>
158
+ </figure>
159
+ ```
160
+
161
+ `--scrim` and `sm-scrim` are the only shade a Block uses; StillMade's own
162
+ `--scrim-top` and `--scrim-bottom` (theme.css) are for its pages and the check
163
+ reports them.
164
+
165
+ ## Layout
166
+
167
+ StillMade zooms a view to fill the space its Step gives it (up to 150%), and
168
+ Ctrl/Cmd +, - and 0 size the view while it has focus. It never centers a frame
169
+ view; a standard view narrower than its Step is centered by its margins.
170
+
171
+ An app that lays itself out (a full-size canvas or WebGL, its own scroll, pan
172
+ or zoom, its own Ctrl/Cmd +/- keys, as in a CAD or drawing tool) puts
173
+ `data-stillmade-layout="own"` on its outermost element:
174
+
175
+ ```html
176
+ <div id="root" data-stillmade-layout="own"></div>
177
+ ```
178
+
179
+ StillMade then never centers or zooms it and leaves Ctrl/Cmd +, - and 0 to the
180
+ app. Without the attribute StillMade also stays out of the way when the view
181
+ looks like an app: no page padding, a clipped page, a root as tall as the frame,
182
+ fixed over half of it or scrolling over half of it, a canvas, SVG or
183
+ `touch-action: none` surface over 40% of it, or a canvas or SVG of 300x200 or
184
+ more with `touch-action: none` (as Three.js's controls set it). Mark the root
185
+ anyway, in `view.html` rather than from code: StillMade reads it before the view
186
+ starts, so the app never shows StillMade's size control or loses a key to it,
187
+ even while it is still loading.
188
+
189
+ A `<video controls>` plays in StillMade's player, the same one as everywhere in
190
+ StillMade: play, timeline, time, sound and full screen along the bottom, shown
191
+ while the pointer is on the video, with keys on the focused video (Space or K,
192
+ the arrows, M, F) and touch. Full screen goes through StillMade, right after a
193
+ click or key in the view; the frame itself has no `allow="fullscreen"`. A
194
+ `<video>` without `controls` is the Block's own and StillMade never touches it,
195
+ so a Block that drives playback (its own timeline, an editor or CAD viewer)
196
+ leaves `controls` out, and `data-stillmade-player="native"` keeps the browser's
197
+ controls. Result pictures from `StillMade.previewImage` in `sm-stage` or
198
+ `sm-gallery`, and any element marked `data-stillmade-expand`, get a full-screen
199
+ button in the bottom-right corner while the pointer is on them; pictures with
200
+ the same value (`data-stillmade-expand="shots"`) open as one set, and
201
+ `data-stillmade-expand="off"` removes the button. The keyboard reaches them
202
+ too: such a picture without a `tabindex` of its own joins the tab order,
203
+ keyboard focus on it shows the button, Enter or Space opens the viewer, and
204
+ closing the viewer gives the focus back to the picture.
205
+
206
+ ## A job on one page: a check, then the run
207
+
208
+ A job the person fills in and gets a result from is one page: the inputs on the
209
+ left and the result's place on the right on a wide screen; on a phone they
210
+ stack in the page's order, the inputs, the button in normal flow (never a sticky
211
+ bar), then the result's place under it. When the expensive run needs a cheap
212
+ check first (the script and a voice sample before the video), keep it on the
213
+ same page: call `StillMade.run({make: 'check'})`, show what comes back, then
214
+ `StillMade.run({make: 'video', script})` with what the person checked. Each run
215
+ is priced and approved by StillMade on its own, so the view shows no price. The
216
+ module side and what the person sees are in MODULES.md, "A check, then the
217
+ expensive run, on one page".
218
+
219
+ ## Assets
220
+
221
+ Images, fonts, JSON, audio and video the view needs ship as files named by
222
+ SHA-256, like module files:
223
+
224
+ ```json
225
+ {"runtime": "frame", "files": {"schemaVersion": 1, "files": {
226
+ "fonts/inter.woff2": {"sha256": "…", "bytes": 48256, "mediaType": "font/woff2"}
227
+ }}}
228
+ ```
229
+
230
+ `stillmade-block pack` fills in the digests and sizes. StillMade checks every
231
+ file against its SHA-256 before the view starts.
232
+
233
+ ## What the frame does not allow
234
+
235
+ The view runs in an opaque-origin frame with its own policy:
236
+
237
+ - no network (`fetch`, WebSocket and remote images, fonts or scripts fail);
238
+ - no code from strings (`eval`, `new Function`, inline event attributes) and
239
+ no extra script elements;
240
+ - no navigation, popups, downloads, forms that submit, or dialogs;
241
+ - no WebAssembly on the page (run heavy computation in the Block's runtime,
242
+ for example a module Block, and call it with `StillMade.run`);
243
+ - no storage or access to StillMade's page.
244
+
245
+ Workers created from `blob:` URLs are allowed and run off the page's thread.
246
+
247
+ ## Run limits
248
+
249
+ StillMade compiles the view so every function and loop checks a time budget.
250
+ One task may run for 250 ms; past that it is stopped with an error, and a view
251
+ that keeps the page busy most of the time, stops answering, or navigates its
252
+ frame is closed with a message. A single built-in operation that blocks for a
253
+ second or more (a huge sort, or a regular expression that backtracks) also closes
254
+ the view where the browser reports it. Move long computation into a Worker or the
255
+ Block's runtime.
256
+
257
+ The host enforces every permission itself: a view's code can message the host
258
+ directly, so a read-only viewer cannot run the Block or save outputs from any
259
+ view.
@@ -0,0 +1,59 @@
1
+ # Generate media from JavaScript
2
+
3
+ A JavaScript Block can generate images and videos with any model in the shared
4
+ catalog (the same models the app's own Canvas and Image Panels use), speech in
5
+ any catalog voice, music and sound effects by returning a declared
6
+ `media.generate` action. Declare it in the manifest:
7
+
8
+ ```json
9
+ "permissions": {"project": [], "actions": ["media.generate"], "network": [], "filesystem": [], "secrets": []},
10
+ "outputs": {"request": {"type": "json"}, "media": {"type": "asset[]"}}
11
+ ```
12
+
13
+ Return the action from your code. Each item is an `image`, `video`, `speech`,
14
+ `music` or `sfx` item with a prompt and optional `settings`. Image and video
15
+ items may also set `references` (images), `firstFrame`/`lastFrame` (video),
16
+ `negativePrompt` and `seed`. Audio items take only `settings`:
17
+
18
+ - `speech`: the prompt is the text to speak (up to 3,800 characters);
19
+ `settings: {voice, speed}` with a catalog voice id and a speed from 0.25 to 4.
20
+ - `music`: `settings: {durationSec}`, 5 to 240 whole seconds (default 30).
21
+ - `sfx`: `settings: {durationSec}`, 0.5 to 22 seconds in tenths (default 4).
22
+
23
+ Video items take `settings: {model, duration, resolution, aspectRatio, generateAudio}`.
24
+ With no `model`, an `aspectRatio` the default model (Vidu Q3 Turbo, which takes none)
25
+ cannot make picks the cheapest catalog model that makes it with the frames and
26
+ `duration` given, so `{aspectRatio: "9:16"}` alone asks for a vertical clip.
27
+
28
+ ```js
29
+ return {request: {
30
+ schemaVersion: 1, kind: "stillmade.media-action", operation: "media.generate",
31
+ resultPort: "media",
32
+ request: {items: [
33
+ {key: "hero", operation: "image", prompt: input.prompt,
34
+ settings: {model: "nano-banana-pro", aspectRatio: "16:9", resolution: "2K"},
35
+ references: input.styleImages},
36
+ {key: "clip", operation: "video", prompt: "Slow push in on the harbor",
37
+ settings: {model: "kling-v3-turbo", duration: 5, aspectRatio: "16:9"}},
38
+ {key: "intro", operation: "speech", prompt: "Welcome back to the show.",
39
+ settings: {voice: "adam", speed: 1}},
40
+ {key: "bed", operation: "music", prompt: "Warm lo-fi piano", settings: {durationSec: 30}},
41
+ {key: "whoosh", operation: "sfx", prompt: "A fast whoosh", settings: {durationSec: 1.5}}
42
+ ]}
43
+ }};
44
+ ```
45
+
46
+ StillMade turns every item into one exact generation request and asks the server
47
+ for one maximum price for the whole batch, using StillMade's own prices. The user
48
+ sees that maximum and approves it once; credits are reserved before any provider
49
+ call, each call is settled from provider evidence, and unused credits are
50
+ returned when the batch closes. The approval is bound to this Block's exact
51
+ content digest, so changed code needs a new approval. A Block cannot name a
52
+ price, a provider, a key or another Block. References and frames must be images
53
+ saved in the user's own library. Up to 50 items per action.
54
+
55
+ When it finishes, the declared `resultPort` receives an array of
56
+ `{key, kind, assetId, versionId, url, duration?}` in item order (`kind` is `image`,
57
+ `video` or `audio`; `duration`, in seconds, is the length a video, music or sound
58
+ effect item asked for; speech has none, so decode it with `audio.decode` to time it); failed items are listed
59
+ separately and are not charged beyond what the provider actually received.