stillmade-sdk 0.1.36 → 0.1.38

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 (60) hide show
  1. package/AGENTS.md +8 -8
  2. package/IMAGE_DESCRIPTION.md +2 -0
  3. package/MODULES.md +68 -10
  4. package/NATIVE_MCP.md +18 -7
  5. package/PASTE_TO_LLM.md +121 -50
  6. package/PORTABLE.md +7 -3
  7. package/README.md +19 -6
  8. package/REMIX.md +6 -0
  9. package/SDK.md +226 -103
  10. package/TRANSCRIPTION.md +4 -2
  11. package/UI_AESTHETIC.md +2 -0
  12. package/api-index.json +1 -1
  13. package/blocks/narration/package.js +1 -1
  14. package/blocks/narration/versions/1.0.1/package.js +221 -0
  15. package/blocks/native/sm.animated-scene/versions/2.3.9/package.js +769 -0
  16. package/blocks/native/sm.board-editor/versions/2.2.11/package.js +551 -0
  17. package/blocks/native/sm.describe-media/versions/2.1.0/package.js +140 -0
  18. package/blocks/native/sm.panel-strip/versions/2.4.2/package.js +1316 -0
  19. package/blocks/native/sm.photo-notes/versions/1.1.0/package.js +170 -0
  20. package/blocks/native/sm.pipeline/versions/2.2.6/package.js +1095 -0
  21. package/blocks/screen-recorder/package.js +1 -1
  22. package/blocks/screen-recorder/versions/1.0.1/package.js +223 -0
  23. package/package.json +1 -1
  24. package/packages/block-cli/cli.js +91 -35
  25. package/packages/block-cli/dev-host/assets/host.js +35 -32
  26. package/packages/block-cli/dev-host/assets/index.css +1 -1
  27. package/packages/block-cli/dev-server.js +4 -0
  28. package/packages/block-cli/ready-gate.js +19 -4
  29. package/packages/block-cli/templates.js +33 -21
  30. package/packages/block-platform/block-readiness.js +10 -1
  31. package/packages/block-platform/catalog.js +14 -3
  32. package/packages/block-platform/chat-packages.js +6 -0
  33. package/packages/block-platform/flow-inspection.js +3 -1
  34. package/packages/block-platform/project-target.js +57 -0
  35. package/packages/block-platform/project-type-composer.js +4 -3
  36. package/packages/block-platform/project-types.js +5 -2
  37. package/packages/block-sdk/admission.js +4 -1
  38. package/packages/block-sdk/block-tier.js +23 -0
  39. package/packages/block-sdk/builder-contract.js +12 -10
  40. package/packages/block-sdk/capabilities.js +23 -10
  41. package/packages/block-sdk/collaboration-admission.js +3 -0
  42. package/packages/block-sdk/contracts.js +13 -1
  43. package/packages/block-sdk/example-media-data.js +16 -0
  44. package/packages/block-sdk/example-media.js +42 -0
  45. package/packages/block-sdk/first-party-identities.js +8 -0
  46. package/packages/block-sdk/first-party-packages.js +11 -1
  47. package/packages/block-sdk/index.d.ts +6 -2
  48. package/packages/block-sdk/local-admission.js +6 -5
  49. package/packages/block-sdk/media-transform.js +59 -3
  50. package/packages/block-sdk/mock-host.js +23 -2
  51. package/packages/block-sdk/mocks.js +4 -1
  52. package/packages/block-sdk/module-hosted.js +12 -2
  53. package/packages/block-sdk/port-types.d.ts +6 -0
  54. package/packages/block-sdk/port-types.js +32 -10
  55. package/packages/block-sdk/shared-agent-controls.js +25 -2
  56. package/packages/block-sdk/shared-controls.js +17 -3
  57. package/packages/block-sdk/testing.js +46 -3
  58. package/packages/block-sdk/view-design.js +67 -0
  59. package/packages/block-sdk/view-renderer.js +50 -8
  60. package/packages/design-system/block-kit.css +6 -4
package/AGENTS.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # Building StillMade Blocks in this folder
2
2
 
3
- This folder is the StillMade Block SDK. Read this file before writing code; it is the same contract StillMade's own AI and importers follow. Commands below use the downloaded SDK folder form `node packages/block-cli/cli.js`; when the SDK came from `npm install --save-dev stillmade-sdk`, type `npx stillmade-block` in its place. Scaffold with `node packages/block-cli/cli.js create my-block javascript`, then iterate with `validate my-block` and `test my-block`, check admission with `pack my-block /tmp/my-block.stillmade-block --original`, and finish with `ready my-block`, the same readiness check StillMade runs before an install or a release. `SDK.md` is the complete reference and `PASTE_TO_LLM.md` the detailed authoring guide.
3
+ This folder is the StillMade Block SDK. Read this file before writing code; it is the same contract StillMade's own AI and importers follow. Commands below use the downloaded SDK folder form `node packages/block-cli/cli.js`; when the SDK came from `npm install --save-dev stillmade-sdk`, type `npx stillmade-block` in its place. Scaffold with `node packages/block-cli/cli.js create my-block javascript`, then iterate with `validate my-block` and `test my-block`, check it with `gate my-block`, the same readiness check StillMade runs before an install or a release, and write the file to import in StillMade with `pack my-block`: `<id>-<version>.stillmade-module.json` for a module Block, `<id>-<version>.stillmade.json` for the other runtimes. `SDK.md` is the complete reference and `PASTE_TO_LLM.md` the detailed authoring guide.
4
4
 
5
5
  ## Readiness gate
6
6
 
7
- Do not tell the user a Block is ready, done or working until `node packages/block-cli/cli.js gate .` passes after your last edit, and report the exact status it prints. In this folder Claude Code (`.claude/settings.json`) and Cursor (`.cursor/hooks.json`) run the gate when you finish a turn and send any failures back to you, but only in a session started in this folder: if you downloaded the SDK during the current session, run the gate yourself. Other agents must also run it themselves. A module Block runs code, so the gate a hook starts does not run it and says so: run `gate` or `ready` on it yourself. If you cannot fix a failure, say plainly that the Block is not ready and list the failing checks.
7
+ Do not tell the user a Block is ready, done or working until `node packages/block-cli/cli.js gate .` (`gate <block-folder>` for a Block outside this SDK folder) passes after your last edit, and report the exact status it prints. In this folder Claude Code (`.claude/settings.json`) and Cursor (`.cursor/hooks.json`) run the gate when you finish a turn and send any failures back to you, but only in a session started in this folder: if you downloaded the SDK during the current session, run the gate yourself. Other agents must also run it themselves. A module Block runs code, so the gate a hook starts does not run it and says so: run `gate` or `ready` on it yourself. If you cannot fix a failure, say plainly that the Block is not ready and list the failing checks.
8
8
 
9
- Contract `stillmade.block-builder@1.10.0`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
9
+ Contract `stillmade.block-builder@1.11.0`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
10
10
 
11
11
  ## Source of truth
12
12
 
@@ -14,7 +14,7 @@ Treat the current SDK (`stillmade.block.json` manifest, `packages/block-sdk` con
14
14
 
15
15
  ## Reuse first
16
16
 
17
- Before building, check what already exists (`find_existing_blocks` over MCP, or the Marketplace and your library) by the inputs, results and operations the goal needs. Use an installed or reviewed Block that already does it; remix a close one so its license, notices and creator credit stay attached; chain existing Blocks and build only the missing step. Never republish another creator's source without remix lineage: public copies are refused. Build a new Block when nothing fits or the person asks for their own version, and say which similar Blocks you considered.
17
+ Before building, check what exists (`find_existing_blocks` over MCP, or the Marketplace and your library) by the goal's inputs, results and operations. Only a `likely` or `verified-contract` match (a Block or a chain of two) does the job: use it. `partial` is a close Block to look at: remix it (license, notices and credit stay attached) or build only the missing step. Never republish another creator's source without remix lineage: public copies are refused. Build new when nothing does the job or the person wants their own, and name similar Blocks you considered.
18
18
 
19
19
  ## Three sizes of Block
20
20
 
@@ -28,11 +28,11 @@ Pick the runtime from the job. No hosted AI: a recipe or isolated `javascript`,
28
28
 
29
29
  A Step is one job: the work between two moments where a person or the outside world must see the result. Start a new Step only at one of three points; everything else is a part of the neighboring Step.
30
30
 
31
- 1. **A person works with the result**: reads, edits, picks or approves it (a workspace Block such as a script, a Canvas or an Editor, or an approval). That is why Chat, Bible, Canvas and Editor are four Steps.
31
+ 1. **A person works with the result**: reads, edits, picks or approves it (a workspace Block such as a script, a Canvas or an Editor, or an approval). So Bible, Canvas and Editor are separate Steps after Chat.
32
32
  2. **Finding new things turns into handling each one**: the trigger (a schedule or an app event), the app read, its filter and "only new" are the first job; what is done with each item is the next job. A trigger is a setting of the first job, never a Step of its own.
33
33
  3. **The result leaves StillMade**: it is sent, posted, published, paid or written into another app. Consecutive writes to the same app, with the glue that shapes data for them, are one job.
34
34
 
35
- In a production the Steps are the workspaces a person opens: work feeding the next workspace is its part, else it joins the one before; neighbouring workspaces with one main result type are one Step unless another part feeds the second. A video ends in the Editor (1.0), which has captions and export built in, so Export video is never a Step beside it.
35
+ In a production the Steps are the workspaces a person opens: work feeding the next workspace is its part, else it joins the one before. A Block with its own interface (a workspace, editor or picker) is always its own Step; two such Steps are never one. A video ends in the Editor (1.0), which has captions and export built in, so Export video is never a Step beside it.
36
36
 
37
37
  A part that only runs in the desktop app cannot share a Step with cloud parts. Before adding a Step, name which of the three reasons makes it separate; if none applies, make it a part of a neighbor. A Step nobody would ever open must not exist on its own. Prefer an app task's own filter (a Gmail query such as `has:attachment filename:png`) to an AI check, and use AI decide only for judgement.
38
38
 
@@ -46,7 +46,7 @@ Translate the request into an explicit capability contract before implementation
46
46
 
47
47
  ## Blocks compose
48
48
 
49
- A Block is one job: not a mini-app of many jobs and not a fragment of one. Its outputs become other Blocks' inputs and its inputs come from other Blocks, project context or the user. Use the typed port system: shared StillMade types (`image`, `video`, `audio`, `asset`, `script`, `shot[]`, ...), a `semantic` meaning on every port, `required` and a short `description`. Mark exactly one primary input and one primary output so Project Type Steps connect automatically, and use `kind: "task"`: a `workspace` Block owns a project document and is never connected automatically. Inputs marked `context` read the project and cannot receive a connection from another Step. Output reusable StillMade values: media references (`{kind,assetId,versionId,url}`) and structured production values with `schemaVersion: 1`, preserving provenance, versions and relationships downstream Blocks need. Never make ordinary users wire JSON, copy IDs, understand internal paths or translate one Block's output into another: `createUniversalResolver()` (the same engine as the Project Type composer) resolves inputs from compatible upstream outputs, permitted project context and, for optional non-context inputs, `StillMade.requestFromUser`.
49
+ A Block is one job: not a mini-app of many jobs and not a fragment of one. Its outputs become other Blocks' inputs and its inputs come from other Blocks, project context or the user. Use the typed port system: shared StillMade types (`image`, `video`, `audio`, `asset`, `script`, `shot[]`, ...), `required`, a short `description`, and a `semantic` only where it narrows what fits. Mark exactly one primary input and one primary output so Project Type Steps connect automatically, and use `kind: "task"`: a `workspace` Block owns a project document and is never connected automatically. Inputs marked `context` read the project and cannot receive a connection from another Step. Output reusable StillMade values: media references (`{kind,assetId,versionId,url}`) and structured production values with `schemaVersion: 1`, preserving provenance, versions and relationships downstream Blocks need. Never make ordinary users wire JSON, copy IDs, understand internal paths or translate one Block's output into another: `createUniversalResolver()` resolves inputs from compatible upstream outputs, permitted project context and, for optional non-context inputs, `StillMade.requestFromUser`.
50
50
 
51
51
  ## Feature map
52
52
 
@@ -66,7 +66,7 @@ Give the Block a short, plain name of 40 characters or fewer that says what it d
66
66
 
67
67
  ## Interface
68
68
 
69
- If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction genuinely needs one. Build custom views from the Block kit the host injects (`block-kit.css`): the result in `sm-stage`, picks as pictures in `sm-choices`, one `sm-primary` naming the action (Write, Generate; never "Run") and no price (StillMade's run button adds it), extras in a closed `sm-more`; a look the person names wins. Fit one laptop screen without scrolling: label beside control, status in a few words, files as tiles, rare tools as icons, (i) on unclear controls. These compact rules are for a job or an ingredient. Size the view to the Block's tier (block-tier.js): an app, a workspace a person works in for a while (a video editor, a 3D configurator, a CAD or drawing tool), looks and works like that kind of app instead of a compact page: its canvas or stage fills the view, with the panels, toolbars, inspector or timeline such an app has, direct manipulation (select, drag, zoom), keyboard shortcuts and undo; it keeps the host appearance and Block kit controls, its panels may scroll, and on a phone its tools fold into sheets while the canvas stays usable. Never shrink an app into a form of fields and one button. Drop words nobody needs; put helpful ones in a closed `sm-hint`. Expose the capability, not the implementation: sensible defaults, previews, progress, clear errors, visible outputs. Do not show raw JSON, internal IDs, filesystem details, provider terminology or developer settings unless the Block is itself a developer tool. When a person chooses among options they need to hear or see (voices, music, sounds, fonts, looks, colors, templates or images), let them preview each option before choosing: a sample to play or a thumbnail, from the Block's own files or the host's free samples, never a paid generation. Leave previews out only when the builder states there is nothing to preview. Choices StillMade owns, such as voices and models in the run review, already show their samples. Follow the host appearance (Light, Dark and White) and one elastic layout: stacked on a 320px phone with no sideways scroll (result first, action pinned), and from 860px the controls left (≤380px), the result filling the right. Short settings sit side by side, each label beside its control (`sm-field`, `sm-settings`; three or four short options as one `data-segmented` row); many items are one line each (`sm-list`) that open in place; input files are small tiles (`sm-gallery data-size="small"`); on a phone chip rows scroll sideways and long lists show three. Compacting moves controls, never deletes them.
69
+ If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction needs one. Build custom views from the Block kit the host injects (`block-kit.css`): the result in `sm-stage`, picks as pictures in `sm-choices`, one `sm-primary` naming the action (Write, Generate; never "Run") and no price (StillMade's run button adds it), extras in a closed `sm-more`; a look the person names wins. Fit one laptop screen without scrolling: label beside control, status in a few words, files as tiles, rare tools as icons, (i) on unclear controls. These compact rules are for a job or an ingredient. Size the view to the Block's tier (block-tier.js): an app, a workspace a person works in for a while (video editor, 3D configurator, CAD or drawing tool), looks and works like that kind of app instead of a compact page: its canvas or stage fills the view, with the panels, toolbars, inspector or timeline such an app has, direct manipulation (select, drag, zoom), keyboard shortcuts and undo; it keeps the host appearance and Block kit controls, its panels may scroll, and on a phone its tools fold into sheets while the canvas stays usable. Never shrink an app into a form of fields and one button. Drop words nobody needs; put helpful ones in a closed `sm-hint`. Mark each button `data-stillmade-action="what it does"` and label each field: Chat presses and fills them. Expose the capability, not the implementation: sensible defaults, previews, progress, clear errors, visible outputs. Show no raw JSON, internal IDs, filesystem details, provider terms or developer settings unless the Block is a developer tool. When a person chooses among options they need to hear or see (voices, music, fonts, looks, templates, images), let them preview each option before choosing: a sample or thumbnail from the Block's own files or the host's free samples, never a paid generation. Skip previews only when there is nothing to preview. Choices StillMade owns (voices, models in the run review) already show samples. Follow the host appearance (Light, Dark and White) and one elastic layout: stacked on a 320px phone with no sideways scroll (result first, action pinned), and from 860px the controls left (≤380px), the result filling the right. Short settings sit side by side, each label beside its control (`sm-field`, `sm-settings`; three or four short options as one `data-segmented` row); many items are one line each (`sm-list`) that open in place; input files are small tiles (`sm-gallery data-size="small"`); on a phone chip rows scroll sideways and long lists show three. Compacting moves controls, never deletes them.
70
70
 
71
71
  ## Shared editing
72
72
 
@@ -1,5 +1,7 @@
1
1
  Use `runtime: "capability"` with `operation: "image.describe"` when a Block must inspect one image and return plain text. This is the portable boundary for visual analysis: the Block declares its image input, analysis instructions, output, tests, and license; StillMade owns image loading, provider credentials, model/payment selection, approval, accounting, and the retained execution record.
2
2
 
3
+ **StillMade credits do not pay for `image.describe`** (since September 13, 2026). A Block that calls it runs only for people who added their own OpenRouter key in Settings → API keys, and stops for everyone else. For a Block anyone can run on StillMade credits, use `media.analyze` instead (`stillmade-block create my-block analyze-media`): it takes one image or one to four images, answers one question about each, and is priced per image. The built-in Describe media 2.1.0 and Photo notes 1.1.0 moved to it; their earlier releases stay for projects pinned to them.
4
+
3
5
  The downloaded SDK includes `examples/describe-image.stillmade.json` and `packages/block-sdk/image-description-example.js`.
4
6
 
5
7
  ```json
package/MODULES.md CHANGED
@@ -7,7 +7,9 @@ any npm package you bundle into it, including C and C++ libraries compiled to
7
7
  WebAssembly (OpenCV, libvips builds, codecs, solvers), threaded WebAssembly
8
8
  (see Threads) and live WebSocket connections to declared origins (see Live
9
9
  connections). Use it when a recipe or the QuickJS `javascript` runtime is too
10
- small for the job.
10
+ small for the job. (StillMade's in-app builder writes `main.js` as one file that
11
+ imports nothing and uses no browser APIs; that single-file rule is the builder's,
12
+ not the runtime's. A module Block you build with the SDK can use all of this.)
11
13
 
12
14
  ## Folder layout
13
15
 
@@ -18,10 +20,14 @@ my-block/
18
20
  main.js the entry (bundle npm dependencies into it)
19
21
  filters.wasm optional WebAssembly and data files
20
22
  module.json optional: {"entry": "other.js", "threads": true}
21
- tests/fixtures.json [{name, input, expected}]
23
+ tests/fixtures.json [{name, input, expected, mocks?}]
22
24
  ```
23
25
 
24
- Start one with `stillmade-block create my-block module`. Bundle npm
26
+ Start one with `stillmade-block create my-block module` (`module-hosted` for
27
+ one that calls hosted operations). `stillmade-block` is the SDK's command line:
28
+ `npx stillmade-block` with the npm package `stillmade-sdk`, or
29
+ `node <sdk>/packages/block-cli/cli.js` where `<sdk>` is the extracted
30
+ `/block-sdk/stillmade-sdk-0.1.0.zip`. Bundle npm
25
31
  dependencies into `module/main.js` with any ES module bundler (esbuild,
26
32
  rolldown, Vite). A module holds up to 64 files, 64 MiB each and 128 MiB in
27
33
  total.
@@ -51,8 +57,8 @@ against the manifest's port types.
51
57
  | `progress(value, label)` | Reports progress from 0 to 1 with a short label. Each report extends the run limit. |
52
58
  | `log(...values)` | Adds a line to the run log (up to 500 lines). |
53
59
  | `asset(path)` | A copy of one of the module's own files, such as a `.wasm` build, as an `ArrayBuffer`. |
54
- | `files.read(ref)` | The bytes of a saved image, video, audio or asset 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. |
55
- | `files.write(data, {mediaType, name})` | Saves PNG, JPEG, WebP, GIF, MP4, WebM, MP3, WAV, M4A or OGG to the runner's library and returns a reference you can return as an output. At most 64 files per run. |
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. |
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. |
56
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). |
57
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. |
58
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. |
@@ -71,7 +77,10 @@ const voice = await stillmade.hosted.run('audio.speech', { text: plan.script, se
71
77
  ```
72
78
 
73
79
  `image.describe`, `media.analyze` and `audio.transcribe` take saved references
74
- (`image`/`images`, `media`, `audio`); `web.fetch` takes `url` and `instruction`;
80
+ (`image`/`images`, `media`, `audio`); `image.generate` takes `prompt` and optional
81
+ `references`, one to eight saved images the new picture keeps. Look at pictures with `media.analyze`:
82
+ StillMade credits pay for it, while `image.describe` runs only on the person's
83
+ own OpenRouter key. `web.fetch` takes `url` and `instruction`;
75
84
  `web.research` takes `topic`; music and sound effects take `prompt` and
76
85
  `durationSec`.
77
86
 
@@ -94,6 +103,8 @@ to the next transform.
94
103
  | `{operation: 'video.concat', sources, settings?}` | A saved MP4 of 2 to 50 videos in order. |
95
104
  | `{operation: 'video.resize', source, settings}` | A saved MP4 re-encoded with new settings. |
96
105
  | `{operation: 'image.thumbnail', source, at?, width?}` | A saved PNG of one frame (default the first frame, 1280 px wide). |
106
+ | `{operation: 'document.text', source}` | `{text, pages}`: the words of a PDF or text file the person gave, page by page (up to 500 pages). |
107
+ | `{operation: 'image.compose', width, height, layers, background?, format?, text?}` | A saved PNG (or JPEG) of saved images joined into one picture: side by side, a grid, a contact sheet, a poster with a title. |
97
108
  | `{operation: 'timeline.render', clips, kind?, aspect?, audio?, captions?, settings?}` | A saved MP4 (or, with `kind: 'audio'`, an MP3) of your own timeline, rendered the way the Editor exports. |
98
109
 
99
110
  `timeline.render` is how a Block exports: there is no separate Export, Captions,
@@ -102,19 +113,40 @@ from?, transition?: {type, duration?}, look?, mute?}` (a saved image or video; a
102
113
  video keeps its own sound unless `mute`), each audio item `{source, start,
103
114
  duration, from?, volume?}`, and each caption `{text, start, end, words?,
104
115
  position?, highlight?, animation?}`, where `words` (`[{text, start, end}]`)
105
- highlights each word as it is spoken. Times are seconds on the timeline.
116
+ highlights each word as it is spoken. Times are seconds on the timeline: each
117
+ clip starts where the one before it ends, less the transition on that earlier
118
+ clip, which blends it into the next one; clips that overlap more are refused.
106
119
  `aspect` is `16:9`, `9:16`, `1:1` or `4:5`. Looks, transitions and caption
107
120
  animations use the Editor's names (`TIMELINE_LOOKS`, `TIMELINE_TRANSITIONS`,
108
121
  `CAPTION_ANIMATIONS`). The render follows the person's export plan, like any
109
122
  export from StillMade.
110
123
 
124
+ `image.compose` draws on a canvas `width` by `height` pixels (16 to 4096),
125
+ filled with `background` (`#rrggbb`, default white). Each layer is `{source, x,
126
+ y, width, height, fit?}`: a saved image placed in that box, in order, cropped
127
+ to fill it (`fit: 'cover'`, the default) or fitted whole inside it (`'contain'`).
128
+ Each piece of text is `{text, x, y, size?, color?, background?, align?,
129
+ weight?, width?}`, drawn on top: `y` is the top of the line, `size` is 8 to 400
130
+ pixels (default 48), `color` defaults to black, `background` puts a box behind it
131
+ (for a Before label over a photo; `color` and `background` are `#rrggbb`, or `#rrggbbaa`
132
+ or `rgba()` for a see-through box such as `#00000099`), `align` is `left`, `center` or `right` around
133
+ `x`, and `weight` is `bold` (default) or `normal`. `width` wraps the words onto
134
+ lines no wider than it, 1.2 times `size` apart, breaking a word wider than a line
135
+ (or a caption with no spaces) between its characters: give a caption under a
136
+ frame the frame's width so it never runs into the next one. Up to 64 layers and 64 pieces of
137
+ text; `format` is `png` (default) or `jpeg`. A grid is arithmetic in your code:
138
+ for 9 photos on a 1800 by 1800 sheet, three columns of 600 pixels.
139
+
111
140
  `source`/`sources` are saved references (`{kind, assetId, versionId, url}`).
112
141
  Render `settings` are `{fps: 24|30|60, resolution: 720|1080|2160, quality:
113
142
  'low'|'medium'|'high'}`; the default is 30 fps, 1080, high. Video keeps the
114
143
  source's aspect ratio. Rendering follows the person's export plan, like any
115
144
  export.
116
145
 
117
- Pure helpers ship as `@stillmade/block-sdk/media` for you to bundle:
146
+ Pure helpers ship as `@stillmade/block-sdk/media` for you to bundle (the file is
147
+ `stillmade-sdk/packages/block-sdk/media-transform.js` in the npm package and
148
+ `<sdk>/packages/block-sdk/media-transform.js` in the extracted download; alias
149
+ the name in your bundler or import that path):
118
150
  `silentRanges(samples, sampleRate, {thresholdDb, minSilence})`,
119
151
  `keepRanges(silent, duration, {padding})`, `integratedLoudness(channels,
120
152
  sampleRate)` (ITU-R BS.1770), `loudnessGain`, `encodeWav` and `decodeWav`.
@@ -216,13 +248,37 @@ false and `SharedArrayBuffer` is missing, so check it and fall back to one threa
216
248
  ```sh
217
249
  stillmade-block test my-block # runs fixtures in a local Node worker
218
250
  stillmade-block preview my-block input.json
251
+ stillmade-block dev my-block # the interface in your browser, reloaded on save
252
+ stillmade-block gate my-block # StillMade's readiness check
219
253
  stillmade-block pack my-block # writes <id>-<version>.stillmade-module.json
220
254
  ```
221
255
 
256
+ `dev` serves the Block's real controls or view at `http://127.0.0.1:4800`
257
+ (`--port` picks another) and answers hosted calls with stand-ins, never credits.
258
+ The Block is not ready until `gate` passes. Name the Block's own folder: `gate .`
259
+ in a folder that also holds the extracted SDK checks the SDK's examples too.
260
+ `pack my-block` is the only packing step for a module Block, and it never takes
261
+ `--original` (original `.stillmade-block` archives hold recipe, JavaScript,
262
+ capability and ComfyUI source only and refuse a module Block).
263
+
222
264
  `test` and `preview` run your code on your machine in a disposable Node worker
223
265
  with the same host API and run limits (not a security sandbox; it is your own
224
266
  code). `files.read`, `files.write`, `media.transform`, actions and hosted calls need StillMade, or
225
- a host you pass to `createNodeModuleExecutor` in your own tests.
267
+ a host you pass to `createNodeModuleExecutor` in your own tests. The Node worker has no
268
+ `OffscreenCanvas` or `createImageBitmap`: a Block that decodes or draws images there
269
+ needs its own fallback for tests, or tests only what it does without drawing.
270
+
271
+ A fixture's `files` mock is a path inside the Block folder (local runs only: it does not
272
+ travel in the pack), `{"text": "..."}` for a text file, or `{"base64": "..."}` for a small
273
+ binary file (at most 256 KB), which travels in the pack and the import review. Text can
274
+ never hold a NUL character (`\u0000`): StillMade cannot store it, and import refuses it.
275
+
276
+ A fixture's photo, recording, clip or file can be one of StillMade's example files,
277
+ named by address: `/api/media/example/photo-1.jpg` to `photo-4.jpg`, `sheet.png`,
278
+ `room.png`, `kitchen.wav`, `hall.wav`, `click-120.wav`, `audio.mp3`, `clip.mp4`,
279
+ `notes.txt` and `sales.csv` (sizes in PASTE_TO_LLM.md). `test` reads their real bytes
280
+ when the fixture gives no mock for them, and StillMade, its preview and its phone and
281
+ browser check serve the same files, so the example a person sees is the one you tested.
226
282
 
227
283
  A fixture can record what the host answers, so a test of a Block that calls
228
284
  hosted operations costs nothing and gives the same result every run:
@@ -243,7 +299,9 @@ hosted operations costs nothing and gives the same result every run:
243
299
 
244
300
  `mocks` has the shape of `tests/mocks.json` (`hosted`, `transforms`, `actions`,
245
301
  `files`, `storage`, `project`, `connections`, `network`); a list answers
246
- successive calls in order. A fixture's own `mocks` take the place of
302
+ successive calls in order. `files` maps an input's asset ID to a file in the Block
303
+ folder, or to `{"text": "..."}` for a text file, so a Block that reads a notes or
304
+ CSV file the person gives it is tested without a folder (StillMade's builder has none). A fixture's own `mocks` take the place of
247
305
  `tests/mocks.json` for that fixture. StillMade's own builder writes module
248
306
  Blocks the same way and runs their tests before anyone sees them.
249
307
 
package/NATIVE_MCP.md CHANGED
@@ -126,13 +126,24 @@ known, the inputs it starts from and the results it must produce. It searches
126
126
  reviewed Marketplace listings, tested Community Blocks, built-ins and, for a
127
127
  connection that may read creations (`creations:read`), the person's own drafts
128
128
  and private Blocks, by function and name, with no model, provider or credit
129
- cost, and returns one outcome:
130
-
131
- - `use` or `use-own`: an existing Block already does it; offer it instead of building.
132
- - `remix`: a close Block allows an attributed remix. `begin_block_remix` creates a
133
- private draft from that exact version, with its license, notices and creator
134
- credit; retrying the same `requestId` returns the same draft.
135
- - `compose` or `build-gap`: existing Blocks chain together; build only the missing step.
129
+ cost, and returns one outcome with a confidence. Only confidence `likely` (the
130
+ Block's name and description cover the goal) or `verified-contract` (its declared
131
+ inputs and results match by meaning) means existing Blocks already do the job.
132
+ `partial` means a close Block, not one that does the job: the client shows it as a
133
+ close Block the person can open and keeps building unless they choose it.
134
+
135
+ - `use` or `use-own` (likely or verified-contract): an existing Block already does
136
+ it; offer it instead of building. `use-own` with confidence `partial` is the
137
+ person's own close Block: show it, and keep building.
138
+ - `remix` (partial): a close Block allows an attributed remix. `begin_block_remix`
139
+ creates a private draft from that exact version, with its license, notices and
140
+ creator credit; retrying the same `requestId` returns the same draft. Offer it
141
+ beside the build.
142
+ - `compose` (verified-contract): two existing Blocks chained by declared meanings
143
+ do it; offer them in order. Blocks that only share a kind of value (text into
144
+ text) are never composed.
145
+ - `build-gap` (partial): a Block makes the results but needs an input the person
146
+ does not have; they can build only that missing step in front of it.
136
147
  - `build`: nothing close exists, or the person wants their own version.
137
148
 
138
149
  `validate_block_source` and `save_creation` also list up to three similar existing