stillmade-sdk 0.1.49 → 0.1.51
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.
- package/AGENTS.md +6 -2
- package/AGENT_CONTROL.md +15 -0
- package/FRAME_VIEWS.md +30 -0
- package/INTERFACE_DESIGN.md +84 -7
- package/MODULES.md +2 -2
- package/PASTE_TO_LLM.md +26 -19
- package/SDK.md +180 -45
- package/UI_AESTHETIC.md +15 -0
- package/blocks/generate/package.js +1 -1
- package/blocks/generate/versions/1.1.0/package.js +471 -0
- package/blocks/generate/versions/1.2.0/package.js +555 -0
- package/blocks/native/sm.board-editor/versions/3.0.0/package.js +50 -17
- package/blocks/native/sm.board-editor/versions/3.1.0/package.js +1037 -0
- package/blocks/native/sm.editor/versions/3.0.0/package.js +128 -83
- package/blocks/native/sm.editor/versions/3.1.0/package.js +1299 -0
- package/blocks/native/sm.panel-strip/versions/3.0.0/package.js +45 -12
- package/blocks/native/sm.panel-strip/versions/3.1.0/package.js +479 -0
- package/blocks/native/sm.voiceover/versions/3.0.0/package.js +9 -3
- package/docs/build/block-builder-contract.md +6 -2
- package/docs/build/frame-views.md +30 -0
- package/docs/build/interface-design.md +84 -7
- package/docs/build/modules.md +2 -2
- package/docs/reference/authoring-guide.md +4 -4
- package/docs/reference/errors.md +1 -1
- package/docs/reference/execution.md +18 -4
- package/docs/reference/first-party-blocks.md +4 -4
- package/docs/reference/parity.md +1 -1
- package/docs/reference/ports.md +1 -1
- package/docs/reference/view-bridge.md +3 -0
- package/docs/tools/llm.md +26 -19
- package/package.json +1 -1
- package/packages/block-cli/dev-host/assets/host.js +161 -33
- package/packages/block-cli/dev-host/assets/index.css +1 -1
- package/packages/block-platform/block-readiness.js +16 -3
- package/packages/block-platform/canvas.js +4 -1
- package/packages/block-platform/catalog.js +32 -5
- package/packages/block-platform/flow-inspection.js +30 -2
- package/packages/block-platform/listings.js +16 -2
- package/packages/block-platform/steps.js +4 -1
- package/packages/block-sdk/admission.js +2 -2
- package/packages/block-sdk/agent-inputs.js +4 -2
- package/packages/block-sdk/appearance.js +19 -4
- package/packages/block-sdk/builder-contract.js +7 -4
- package/packages/block-sdk/first-party-identities.js +9 -1
- package/packages/block-sdk/first-party-packages.js +11 -1
- package/packages/block-sdk/generation-catalog.js +55 -5
- package/packages/block-sdk/generation-models.js +60 -0
- package/packages/block-sdk/index.d.ts +18 -4
- package/packages/block-sdk/index.js +2 -1
- package/packages/block-sdk/input-source-policy.js +2 -1
- package/packages/block-sdk/module-hosted.js +13 -5
- package/packages/block-sdk/module-worker.js +1 -1
- package/packages/block-sdk/port-types.js +6 -2
- package/packages/block-sdk/semantic-contracts.d.ts +1 -1
- package/packages/block-sdk/semantic-relationships.js +3 -0
- package/packages/block-sdk/semantic-schema.js +4 -1
- package/packages/block-sdk/shared-controls.js +4 -1
- package/packages/block-sdk/staged-releases.js +2 -1
- package/packages/block-sdk/testing.js +3 -0
- package/packages/block-sdk/view-bridge.js +3 -0
- package/packages/block-sdk/view-design.js +56 -12
- package/packages/block-sdk/view-renderer.js +19 -6
- package/packages/block-sdk/view.js +3 -2
- package/packages/design-system/block-kit.css +12 -3
package/AGENTS.md
CHANGED
|
@@ -6,7 +6,7 @@ This folder is the StillMade Block SDK. Read this file before writing code; it i
|
|
|
6
6
|
|
|
7
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.
|
|
9
|
+
Contract `stillmade.block-builder@1.21.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
|
|
|
@@ -75,7 +75,7 @@ These are StillMade's defaults: unless the person or the creator asked for somet
|
|
|
75
75
|
|
|
76
76
|
## Interface
|
|
77
77
|
|
|
78
|
-
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`, drawn before the first run in the shape and size of what is coming (`data-ratio="9:16"` for a vertical clip, lines for text, a player bar for sound) so every part of the screen is in place at once and the result fills a place the person already sees instead of popping in somewhere unexpected; StillMade draws it the same way on the Steps it draws; on a wide screen what goes in sits on the left and the result on the right, side by side, and they stack only on narrow screens and phones, the result's place after the inputs with the job's action row on it (`sm-actions` and `sm-status` inside `sm-stage`: the kit puts the status top-left and the actions top-right in the player's cream blocks, over a band above the media; the run button is always the rightmost, so a button that spends credits never moves and making again is pressed where it made the first time, with Download and other result actions to its left), picks as pictures in `sm-choices`, the picked one in the kit's ink fill (never restyled to an outline, a tint or the page's background) so it reads at a glance, one solid `sm-primary` naming the action in the job's words ("Plan the tour", "Generate voiceover"; never "Run" or "Make it") and no price (StillMade
|
|
78
|
+
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`, drawn before the first run in the shape and size of what is coming (`data-ratio="9:16"` for a vertical clip, lines for text, a player bar for sound) so every part of the screen is in place at once and the result fills a place the person already sees instead of popping in somewhere unexpected; StillMade draws it the same way on the Steps it draws; on a wide screen what goes in sits on the left and the result on the right, side by side, and they stack only on narrow screens and phones, the result's place after the inputs with the job's action row on it (`sm-actions` and `sm-status` inside `sm-stage`: the kit puts the status top-left and the actions top-right in the player's cream blocks, over a band above the media; the run button is always the rightmost, so a button that spends credits never moves and making again is pressed where it made the first time, with Download (`data-stillmade-action="download"`, which needs no code: StillMade saves the stage's picture or clip under the export policy) and other result actions to its left), picks as pictures in `sm-choices`, the picked one in the kit's ink fill (never restyled to an outline, a tint or the page's background) so it reads at a glance, one solid `sm-primary` naming the action in the job's words ("Plan the tour", "Generate voiceover"; never "Run" or "Make it") and no price (StillMade adds it) once the view says what its next run makes (`StillMade.nextRun`: its `media.generate` items or hosted operations), 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, photo editor), declares `manifest.kind: "workspace"` and looks and works like that kind of app instead of a compact page, and StillMade's checks (admission, readiness, its own builder) then apply the app rules instead of the compact ones: no limit on controls in view, no Block kit page, its own layout, the craft's own words, and only its run button (`data-stillmade-action="run"`) held to naming what it makes: 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 unless it sets view `appearance: "none"` (`src/view.config.json`), which only an app may: StillMade then adds none of its theme, colors, fonts, page or Block kit, the app's own CSS styles everything from the browser's defaults and the style checks are its own call, while shared state, inputs and outputs, hosted operations, the run button's price and StillMade's picker work as before; 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. StillMade centers a standard view narrower than its Step and zooms a view to fill its space; a stage shows what it holds in its middle as one group (a caption stays with its picture) and several results fill its width as one row, on a Block's screen and on the pages StillMade draws; an app that lays itself out (full-size canvas or WebGL, its own scroll, pan or zoom, its own Ctrl/Cmd +/- keys) puts `data-stillmade-layout="own"` on its outermost element, and StillMade then never centers, zooms or takes those keys. StillMade draws one player for every `<video controls>` (play, timeline, time, sound and full screen, shown for 3 s the first time it comes into view, then while the pointer is on the video, with keys and touch) and a full-screen button on result pictures in `sm-stage` or `sm-gallery` and on any element marked `data-stillmade-expand` (the same value makes one set of pictures, `off` removes it); `data-stillmade-player="native"` keeps the browser's controls, and a `<video>` without `controls` is the Block's own and is never touched. A picture or clip that cannot show here (kept on another device, or it did not open) keeps its place as a quiet `sm-media-off` tile in its own shape with the `image-off` glyph and the reason in its label, never words in its place. Drop words nobody needs; put helpful ones in a closed `sm-hint`. Mark each button `data-stillmade-action` (`run` on the one that runs the Block, which the device checks press once; a page that checks first keeps `run` on that button for both presses; what it does on the others, `"play sample"`) 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 (the inputs, the button in normal flow, never pinned, then the result's place under it), 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.
|
|
79
79
|
|
|
80
80
|
## Shared editing
|
|
81
81
|
|
|
@@ -85,6 +85,10 @@ Projects are multiplayer, and StillMade builds it: every ordinary control on a B
|
|
|
85
85
|
|
|
86
86
|
Reach external services only through StillMade's hosted operations, the connections service (`connection.execute`), or, in a module Block, `stillmade.net.fetch` to origins declared in `permissions.network` (with the key each needs), `stillmade.net.connect` for a live WebSocket to one of them, and `stillmade.connections.call` to adapters or catalog apps in `permissions.connections`; never put keys in code, inputs or headers: StillMade adds each person's own key on its servers. The host owns the model and provider choice, BYOK keys, StillMade credits, spending consent, authorization, token refresh, rate limits, retries and provider errors; a Block never receives a secret and never names a provider unless it must. Treat provider unavailability, timeout, cancellation and partial failure as outcomes the Block reports, not crashes: a call the result needs throws and fails the run (see Useful failures); an optional part's failure is caught, given its fallback and named in an optional `notes` text output. Generated images, video, voices, music and sound effects come from hosted operations or the `media.generate` action, paid with the user's StillMade credits at StillMade's prices; for structured model output declare a `json` output with `capability.schema` instead of parsing prose. When a Block needs npm libraries, WebAssembly (threaded: `"threads": true` in module.json) or heavy compute, use `runtime: "module"` and reach hosted operations through `stillmade.hosted.run` with the operations listed in `permissions.capabilities`. Decode, cut, join, re-encode, extract or normalise audio and video with `stillmade.media.transform` on the device; never ask for a server render. For a rich interactive interface (React or another framework, SVG, canvas, drag), use a frame view: `src/view.config.json` with `{"runtime":"frame"}` and `src/view.js` bundled as one IIFE, colored with StillMade's theme variables. For files and structured data use the `file`, `document`, `table`, `url`, `date` and `color` types and their generated controls and presentations, not JSON text.
|
|
87
87
|
|
|
88
|
+
## Models come from StillMade
|
|
89
|
+
|
|
90
|
+
A Block never names a model, in its capability, its module code or its screen, and never keeps a list of models: the person picks the model on the Step from the models StillMade runs that day, so models StillMade adds or retires later reach the Block with no new version (owner, November 8, 2026). Ask for what the result needs instead, in `settings` (`aspectRatio`, `resolution`, `quality`, `duration`, `generateAudio`): with no model picked StillMade runs its default model, or the first one that makes what was asked, and a value the chosen model does not make falls back to its own. A screen that offers its own model picker draws it from `StillMade.models(operation)` when it opens (each model's settings arrive as data, so a setting StillMade adds later draws too) and passes the picked `id` as `settings.model`. A model StillMade retires runs on the one that replaced it.
|
|
91
|
+
|
|
88
92
|
## Dependencies
|
|
89
93
|
|
|
90
94
|
A Block must declare everything it requires and must not assume anything is installed. Portable packages carry no package dependencies (`portable.dependencies` is empty): inline small, license-compatible code and record its license and notice in `manifest.license` and `manifest.provenance`. The copyright holder in the Block's own `provenance.notice` is the person it is made for: replace the placeholder `create` writes with their name, never StillMade, the SDK or yourself. Desktop-only tools are reached solely through declared desktop permissions and the host desktop bridge. If a dependency cannot be delivered through the Block runtime, report the incompatibility instead of assuming the user's machine has it.
|
package/AGENT_CONTROL.md
CHANGED
|
@@ -127,6 +127,21 @@ returns its exact current dependency vector as ordinal `native-control-signals`.
|
|
|
127
127
|
That fallback prevents a changed control revision from silently returning stale
|
|
128
128
|
persisted state, but named fields remain the optimized manual for small models.
|
|
129
129
|
|
|
130
|
+
A mounted module can also pass `undo: {read, restore, same}` to
|
|
131
|
+
`useNativeAgentControls`. With it, every `edit` control that has no undo of its
|
|
132
|
+
own gets one, so a change Chat made can be undone from Chat's change card.
|
|
133
|
+
`read()` returns what the workspace holds now; `same(a, b)` says whether two reads
|
|
134
|
+
hold the same work (default `Object.is`; leave view-only details such as a
|
|
135
|
+
playhead out of it); `restore(before, now)` puts an earlier read back. The undo
|
|
136
|
+
restores the earlier state only while the workspace still holds exactly what the
|
|
137
|
+
edit left. Anything changed since is kept, and the undo says so. The Editor's
|
|
138
|
+
`editor/agentUndo.js` is one example.
|
|
139
|
+
|
|
140
|
+
Screen Blocks get the same undo from the host with nothing to write: a Chat press on
|
|
141
|
+
a marked control is undone by putting each shared view field it changed back to
|
|
142
|
+
its earlier value, on the condition that the field still holds what the press
|
|
143
|
+
left. A press that created a new shared field has no undo.
|
|
144
|
+
|
|
130
145
|
`pause_app_context` stores the exact visible revision baseline and blocks new app
|
|
131
146
|
actions. `resume_app_context` does not clear that pause until the tab publishes a
|
|
132
147
|
matching `manualHandoff.pauseId` for every current surface. Changed shared Blocks
|
package/FRAME_VIEWS.md
CHANGED
|
@@ -196,6 +196,30 @@ view, and also when the file at that place changed after the view was given it
|
|
|
196
196
|
tries again. StillMade hides these buttons wherever it hides the + tile. The SDK
|
|
197
197
|
preview changes its example input the same way.
|
|
198
198
|
|
|
199
|
+
## What Chat can use
|
|
200
|
+
|
|
201
|
+
The project's Chat reads and uses a frame view's controls the way a person does:
|
|
202
|
+
every labelled field (`<label>`, `aria-label` or `title`), and every button
|
|
203
|
+
with words of its own, by those words. A frame view's screen is built by its
|
|
204
|
+
code as it runs, so no check reads it beforehand; a button marked
|
|
205
|
+
`data-stillmade-action` is offered by that name instead (`run` for the button
|
|
206
|
+
that runs the Block). A button with no words, an icon alone, needs an
|
|
207
|
+
`aria-label` to be offered. Fields inside `data-stillmade-local` are the
|
|
208
|
+
person's own and never offered. Whatever a press starts keeps its own
|
|
209
|
+
approval: spending still asks the person (`StillMade.allowSpending` refuses
|
|
210
|
+
Chat).
|
|
211
|
+
|
|
212
|
+
The one exception is a run of every Step that the person approved on Chat's
|
|
213
|
+
card for the whole project. There StillMade presses the screen's run control
|
|
214
|
+
for them: the button marked `data-stillmade-action="run"`, else the button
|
|
215
|
+
worded as the Block's `manifest.action.label`. Move that mark to whichever
|
|
216
|
+
button moves the job forward now (plan, then build, then save): StillMade
|
|
217
|
+
presses it, waits for the runs it starts, and presses the next one until the
|
|
218
|
+
Step's result is saved. Only while StillMade presses it, the runs it starts,
|
|
219
|
+
and one `StillMade.allowSpending` request for each press, draw on that approval,
|
|
220
|
+
and only while they fit what is left; past it, or at any other time, the person
|
|
221
|
+
is asked as usual.
|
|
222
|
+
|
|
199
223
|
## Theming
|
|
200
224
|
|
|
201
225
|
The theme variables from StillMade's design system are always defined:
|
|
@@ -205,6 +229,12 @@ rest. Colors written with them follow Light, Dark and White automatically.
|
|
|
205
229
|
Frame views are not required to use them; the appearance check reports
|
|
206
230
|
hard-coded colors as advice instead of refusing the view.
|
|
207
231
|
|
|
232
|
+
An app (`"kind": "workspace"`) that wants none of StillMade's style sets
|
|
233
|
+
`"appearance": "none"` in `src/view.config.json`: StillMade then defines none of
|
|
234
|
+
these variables and adds no fonts, page styles or Block kit, so the app's own CSS
|
|
235
|
+
styles everything
|
|
236
|
+
([An app with its own style](INTERFACE_DESIGN.md#an-app-with-its-own-style)).
|
|
237
|
+
|
|
208
238
|
A color the check takes is a theme variable, `transparent` or `currentColor`,
|
|
209
239
|
or a gradient of them (`linear-gradient(to top, var(--bg), transparent)`).
|
|
210
240
|
`opacity` is not a color and is always allowed. `color-mix()`, `rgba()`,
|
package/INTERFACE_DESIGN.md
CHANGED
|
@@ -30,10 +30,14 @@ operations and credits, StillMade's file picker, no prices on screen, a run
|
|
|
30
30
|
button that names what it makes. The mode changes how the screen is laid out
|
|
31
31
|
and worded; it grants no extra runtime or host access.
|
|
32
32
|
|
|
33
|
+
An app can also drop StillMade's style: see
|
|
34
|
+
[An app with its own style](#an-app-with-its-own-style). A job always keeps it.
|
|
35
|
+
|
|
33
36
|
## 1. Start from the Block kit
|
|
34
37
|
|
|
35
38
|
StillMade adds the Block kit stylesheet (`packages/design-system/block-kit.css`)
|
|
36
|
-
to every Block view, standard and frame
|
|
39
|
+
to every Block view, standard and frame, except an app that sets
|
|
40
|
+
`appearance: "none"`. Use its classes and ship little or no
|
|
37
41
|
CSS of your own. Every kit rule has zero specificity, so your own CSS always
|
|
38
42
|
wins. Open `packages/design-system/block-kit.html` in a browser to see every
|
|
39
43
|
piece in Light, Dark and White.
|
|
@@ -99,7 +103,7 @@ place (rule 24).
|
|
|
99
103
|
| `sm-media-off` | A picture or clip that cannot show here (on another device, or it did not open): a quiet tile in its own shape (`--sm-photo-ratio`, the tile's shape in a gallery) holding the `image-off` glyph, the reason in `aria-label` and `title`, no words inside. |
|
|
100
104
|
| `sm-add` | The + tile that adds files to an input: `<button type="button" class="sm-add" data-stillmade-add="listingPhotos" aria-label="Add photos">`. StillMade opens its own picker and saves the files; they arrive through `onInput`. In an `sm-gallery` it takes the tile's shape. |
|
|
101
105
|
| `sm-scrim` | Words over a photo or video, inside a positioned box such as an `sm-stage`: a see-through shade of the page under them, in every theme. `var(--scrim)` is the same shade for your own rules. |
|
|
102
|
-
| `sm-glyph` | A small icon in `currentColor`: `play`, `pause`, `plus`, `close`, `check`, `chevron`, `chevron-left`, `chevron-right`, `upload`, `image`, `image-off`, `video`, `audio`, `text`, `spark`, `info`, `warning`, `spinner`. Works in standard views, which cannot use SVG. |
|
|
106
|
+
| `sm-glyph` | A small icon in `currentColor`: `play`, `pause`, `plus`, `close`, `check`, `chevron`, `chevron-left`, `chevron-right`, `upload`, `download`, `image`, `image-off`, `video`, `audio`, `text`, `spark`, `info`, `warning`, `spinner`. Works in standard views, which cannot use SVG. |
|
|
103
107
|
|
|
104
108
|
**Function first.** When the person building a Block does not ask for a look,
|
|
105
109
|
use the kit as is: they want it to work and be easy to use. When they name a
|
|
@@ -131,6 +135,17 @@ the same single priced button. Pressing a priced button runs at that price; a
|
|
|
131
135
|
confirmation appears only when the server's price is higher than the one shown.
|
|
132
136
|
Do not write credit numbers in the Block.
|
|
133
137
|
|
|
138
|
+
A custom view's own run button gets its price the same way (November 8, 2026):
|
|
139
|
+
the view tells StillMade what its next run makes, and StillMade writes the price
|
|
140
|
+
after the button's words, "Generate image · 4 credits". Call
|
|
141
|
+
`StillMade.nextRun({items})` with the `media.generate` items the run will ask for
|
|
142
|
+
(the prompt left out), or `StillMade.nextRun({hosted: ["text.generate"]})` for
|
|
143
|
+
the hosted operations it calls, whenever a choice that changes the price changes.
|
|
144
|
+
StillMade waits until the choices settle, prices them as the run will be priced,
|
|
145
|
+
leaves the button where it is, shows no price while the run works or to a
|
|
146
|
+
viewer, and the Block never sees the number. `StillMade.nextRun(null)` takes it
|
|
147
|
+
off.
|
|
148
|
+
|
|
134
149
|
## 3. Speak the job
|
|
135
150
|
|
|
136
151
|
These are StillMade's defaults for every Block, and they apply wherever the
|
|
@@ -287,7 +302,9 @@ exception, never unrelated technical UI.
|
|
|
287
302
|
segmented control in StillMade); never restyle it to an outline, a tint or
|
|
288
303
|
the page's background. A locked row (`disabled`, or a person who can only
|
|
289
304
|
view) keeps its pick filled, fades the other options and does not react to
|
|
290
|
-
the pointer.
|
|
305
|
+
the pointer. A picture, or a pick shown by its picture (a thumbnail, a
|
|
306
|
+
shot, a swatch), is a rounded rectangle in the kit's radii, never a circle,
|
|
307
|
+
unless the person asks for one; readiness notes a circle.
|
|
291
308
|
22. Media that cannot show here (kept on another device, or it did not open)
|
|
292
309
|
keeps its place as a quiet `sm-media-off` tile in its own shape with the
|
|
293
310
|
`image-off` glyph, the reason in its `aria-label` and `title`. Never words
|
|
@@ -318,8 +335,12 @@ exception, never unrelated technical UI.
|
|
|
318
335
|
then "Make video again"); what the result adds (Download, Share) goes to
|
|
319
336
|
its left. Controls on media (StillMade's player, the full-screen square)
|
|
320
337
|
show for 3 seconds the first time the media comes into view, then only
|
|
321
|
-
while it is hovered or tapped.
|
|
322
|
-
|
|
338
|
+
while it is hovered or tapped. Under a rendered video the stage shows its
|
|
339
|
+
shots with their times and the line being said: a video from
|
|
340
|
+
`timeline.render` carries them as `parts` (`shots` with `start`, `end` and
|
|
341
|
+
the `source` each shows, `lines` with `start`, `end` and `text`), and the
|
|
342
|
+
status carries its length. StillMade's own Step pages do the same. An app
|
|
343
|
+
that lays itself out keeps its own toolbar.
|
|
323
344
|
|
|
324
345
|
```html
|
|
325
346
|
<section class="sm-stage" data-ratio="9:16">
|
|
@@ -332,6 +353,17 @@ exception, never unrelated technical UI.
|
|
|
332
353
|
</section>
|
|
333
354
|
```
|
|
334
355
|
|
|
356
|
+
The Download button needs no code (November 8, 2026): StillMade saves the
|
|
357
|
+
largest picture or clip the stage shows (one the view showed with
|
|
358
|
+
`previewImage` or `previewMedia`) through its own download, under the
|
|
359
|
+
export policy, as the Library does. It works in frame views. An icon fits
|
|
360
|
+
as well: `<button type="button" class="sm-icon" data-stillmade-action="download"
|
|
361
|
+
aria-label="Download" title="Download"><span class="sm-glyph"
|
|
362
|
+
data-glyph="download" aria-hidden="true"></span></button>`. From the view's
|
|
363
|
+
own code, `StillMade.download(media)` saves one picture, clip or sound
|
|
364
|
+
StillMade gave the screen. The run button's price is StillMade's too
|
|
365
|
+
(`StillMade.nextRun`, under "Decide every sentence").
|
|
366
|
+
|
|
335
367
|
## 4a. App rules
|
|
336
368
|
|
|
337
369
|
An app (`"kind": "workspace"`) follows these instead of the job-only rules
|
|
@@ -353,12 +385,48 @@ An app (`"kind": "workspace"`) follows these instead of the job-only rules
|
|
|
353
385
|
view, rare ones in menus. No intros or paragraphs on the surface.
|
|
354
386
|
6. StillMade's appearance (Light, Dark and White) and the kit's controls
|
|
355
387
|
wherever they fit; the layout is the app's own. A look the person names wins.
|
|
388
|
+
An app may drop StillMade's style instead (below).
|
|
356
389
|
7. On a phone the work surface stays usable and the panels fold into sheets or
|
|
357
390
|
one tool strip.
|
|
358
391
|
8. What the person makes leaves the app as the Block's outputs (and, while they
|
|
359
392
|
work, its shared state), so the next Step and the other people in the
|
|
360
393
|
project get it.
|
|
361
394
|
|
|
395
|
+
### An app with its own style
|
|
396
|
+
|
|
397
|
+
An app that should look like nothing but itself (a photo editor in its own
|
|
398
|
+
dark chrome, a CAD tool with its own palette) sets the view's appearance to
|
|
399
|
+
`"none"`: in `src/view.config.json` for an SDK folder, or `view.appearance` in
|
|
400
|
+
a package.
|
|
401
|
+
|
|
402
|
+
```json
|
|
403
|
+
{"runtime": "frame", "appearance": "none"}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
StillMade then adds none of its style to the view: no theme variables (`--bg`,
|
|
407
|
+
`--fg` and the rest are undefined unless the app defines them), no StillMade
|
|
408
|
+
fonts, no page padding or background, no control styles and no Block kit, in
|
|
409
|
+
the local preview and in the app alike. The page starts from the browser's own
|
|
410
|
+
defaults, as if it were opened on its own (an opaque page in the canvas color
|
|
411
|
+
of its `color-scheme`, so the Step behind it never shows through), and the
|
|
412
|
+
app's CSS styles everything. The preview's appearance picker does not apply to
|
|
413
|
+
it. `<html data-mode>` still says whether the person uses Light, Dark or White,
|
|
414
|
+
for an app that wants to follow it.
|
|
415
|
+
|
|
416
|
+
Only an app may set it: `validatePackage` refuses `appearance: "none"` on a job
|
|
417
|
+
(`"kind": "task"`, or a capability Block with one hosted operation), which
|
|
418
|
+
keeps StillMade's style. The style rules are then the app's own call: its own
|
|
419
|
+
colors and tokens, filters, blending and animations are fine, the appearance
|
|
420
|
+
check passes, and the kit checks on round pictures and the page heading do not
|
|
421
|
+
apply. Everything else stays exactly as it is: shared state and multiplayer
|
|
422
|
+
controls, inputs and outputs, hosted operations and credits, the run button's
|
|
423
|
+
name and the price StillMade writes on it, StillMade's file picker
|
|
424
|
+
(`data-stillmade-add`), StillMade's player on `<video controls>`, the wording
|
|
425
|
+
rules and every security check. A standard (non-frame) view still uses no CSS
|
|
426
|
+
escapes and sets no styles from code: both guard its no-remote-resources rule.
|
|
427
|
+
Layout is separate: `data-stillmade-layout="own"` still decides whether
|
|
428
|
+
StillMade centers or zooms the view.
|
|
429
|
+
|
|
362
430
|
## 5. What StillMade checks
|
|
363
431
|
|
|
364
432
|
For an app (`"kind": "workspace"`) only the shared checks run: a file input of
|
|
@@ -368,7 +436,9 @@ is kept), and the action-name rules on its run button
|
|
|
368
436
|
(`data-stillmade-action="run"`) alone, so "OK" and "Go" are fine on its dialogs
|
|
369
437
|
and tools. It is never asked for the Block kit page, a control or row count,
|
|
370
438
|
labels beside fields, `data-stillmade-action` on every tool, or a visual
|
|
371
|
-
surface instead of text (a code editor is an app).
|
|
439
|
+
surface instead of text (a code editor is an app). An app with
|
|
440
|
+
`appearance: "none"` is also not asked for theme colors, rounded rather than
|
|
441
|
+
round pictures, or no page heading. Everything below is the job
|
|
372
442
|
check list.
|
|
373
443
|
|
|
374
444
|
- Admission rejects a primary textarea of 12 or more rows when no task
|
|
@@ -395,7 +465,14 @@ check list.
|
|
|
395
465
|
- Admission also warns, and `stillmade-block ready` fails the "UI works" check
|
|
396
466
|
(DOD-15), when a button says "Run", "Run step" or "Submit", when the
|
|
397
467
|
interface shows a credit price, or when it has a page heading
|
|
398
|
-
(`blockKitProblems`; the failing rules are `BLOCK_KIT_READINESS_RULES`).
|
|
468
|
+
(`blockKitProblems`; the failing rules are `BLOCK_KIT_READINESS_RULES`).
|
|
469
|
+
The same goes, standard and frame views alike, for a job page built from the
|
|
470
|
+
kit (`sm-block`) whose result is a picture, clip, sound, asset or document
|
|
471
|
+
and that has no `sm-stage`, or whose own run button
|
|
472
|
+
(`data-stillmade-action="run"`) is not in the stage's own `sm-actions` with
|
|
473
|
+
an `sm-status` beside it on the stage (rule 24; November 8, 2026). A page not
|
|
474
|
+
built from the kit is held to the kit rule instead, and a frame view that
|
|
475
|
+
builds its stage in code is not checked by the source. StillMade's own Block builder also sends back a custom
|
|
399
476
|
view that is not built from `sm-block`, unless the person asked for their
|
|
400
477
|
own look (`appearance: "original"`).
|
|
401
478
|
- Admission warns, and readiness lists a "Wording" limitation, when a button
|
package/MODULES.md
CHANGED
|
@@ -54,7 +54,7 @@ against the manifest's port types.
|
|
|
54
54
|
| --- | --- |
|
|
55
55
|
| `input` | The validated input values (the same object as the first argument). |
|
|
56
56
|
| `signal` | An `AbortSignal` that fires when the person cancels. |
|
|
57
|
-
| `progress(value, label)` | Reports progress from 0 to 1 with a short label. Each report extends the run limit. |
|
|
57
|
+
| `progress(value, label, items)` | Reports progress from 0 to 1 with a short label. Each report extends the run limit. `items` (`{done, total}`, optional) says how many of the run's items are finished, such as pictures made; StillMade shows it ("9 of 14") while Chat runs the project's Steps. |
|
|
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
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. |
|
|
@@ -117,7 +117,7 @@ const { value, failures } = await stillmade.actions.run({
|
|
|
117
117
|
resultPort: null,
|
|
118
118
|
request: { items: [
|
|
119
119
|
{ key: 'front', operation: 'image', prompt: `The front of ${input.address} at dusk`,
|
|
120
|
-
settings: {
|
|
120
|
+
settings: { aspectRatio: '16:9' } },
|
|
121
121
|
{ key: 'tour', operation: 'speech', prompt: input.script },
|
|
122
122
|
] },
|
|
123
123
|
});
|