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.
- package/.stillmade/sdk-baseline.json +19 -21
- package/AGENTS.md +17 -12
- package/FRAME_VIEWS.md +113 -0
- package/INTERFACE_DESIGN.md +67 -22
- package/MOBILE_UI.md +4 -2
- package/MODULES.md +152 -6
- package/PASTE_TO_LLM.md +42 -32
- package/README.md +3 -2
- package/SDK.md +1028 -563
- package/UI_AESTHETIC.md +30 -3
- package/blocks/generate/package.js +1 -0
- package/blocks/generate/versions/1.0.0/package.js +463 -0
- package/docs/build/audio-to-editor.md +36 -0
- package/docs/build/block-builder-contract.md +150 -0
- package/docs/build/comfyui.md +227 -0
- package/docs/build/concepts.md +40 -0
- package/docs/build/context.md +159 -0
- package/docs/build/cookbook.md +57 -0
- package/docs/build/custom-interface.md +617 -0
- package/docs/build/data-types.md +83 -0
- package/docs/build/frame-views.md +259 -0
- package/docs/build/generate-media.md +59 -0
- package/docs/build/github-applications.md +314 -0
- package/docs/build/hosted-images.md +214 -0
- package/docs/build/hosted-music.md +39 -0
- package/docs/build/hosted-speech.md +157 -0
- package/docs/build/hosted-text.md +246 -0
- package/docs/build/image-description.md +49 -0
- package/docs/build/interface-design.md +343 -0
- package/docs/build/javascript.md +63 -0
- package/docs/build/local-preview.md +61 -0
- package/docs/build/media-analysis.md +27 -0
- package/docs/build/media.md +400 -0
- package/docs/build/mobile-ui.md +106 -0
- package/docs/build/modules.md +487 -0
- package/docs/build/original-blocks.md +70 -0
- package/docs/build/outside-apis.md +128 -0
- package/docs/build/production-context-templates.md +12 -0
- package/docs/build/project-storage.md +94 -0
- package/docs/build/quickstart.md +48 -0
- package/docs/build/recipes.md +103 -0
- package/docs/build/script-handoff.md +45 -0
- package/docs/build/script-writer.md +34 -0
- package/docs/build/state.md +223 -0
- package/docs/build/testing.md +112 -0
- package/docs/build/timeline-edits.md +116 -0
- package/docs/build/timeline-proposals.md +76 -0
- package/docs/build/transcription.md +59 -0
- package/docs/build/triggers.md +59 -0
- package/docs/build/tutorial.md +52 -0
- package/docs/build/typescript.md +34 -0
- package/docs/build/video-generation.md +61 -0
- package/docs/build/web-reading.md +37 -0
- package/docs/build/with-your-ai.md +27 -0
- package/docs/changelog.md +9 -0
- package/docs/creators.md +21 -0
- package/docs/distribute/discovery.md +43 -0
- package/docs/distribute/imports.md +58 -0
- package/docs/distribute/publishing.md +29 -0
- package/docs/distribute/sdk-versions.md +36 -0
- package/docs/distribute/selling.md +14 -0
- package/docs/distribute/teams.md +60 -0
- package/docs/distribute/versioning.md +28 -0
- package/docs/examples.md +23 -0
- package/docs/gallery.md +26 -0
- package/docs/index.md +50 -0
- package/docs/native-mcp.md +307 -0
- package/docs/project-types/automation.md +43 -0
- package/docs/project-types/batches.md +50 -0
- package/docs/project-types/build.md +42 -0
- package/docs/project-types/completion.md +15 -0
- package/docs/project-types/conditions.md +21 -0
- package/docs/project-types/hosted-review.md +115 -0
- package/docs/project-types/onboarding.md +75 -0
- package/docs/project-types/running.md +309 -0
- package/docs/project-types/testing.md +72 -0
- package/docs/reference/application-artifacts.md +87 -0
- package/docs/reference/authoring-guide.md +134 -0
- package/docs/reference/browser-applications.md +267 -0
- package/docs/reference/capabilities.md +45 -0
- package/docs/reference/cli.md +71 -0
- package/docs/reference/connection-api.md +59 -0
- package/docs/reference/cooperative-jobs.md +13 -0
- package/docs/reference/desktop-capabilities.md +172 -0
- package/docs/reference/desktop-execution.md +77 -0
- package/docs/reference/errors.md +233 -0
- package/docs/reference/execution.md +800 -0
- package/docs/reference/first-party-blocks.md +40 -0
- package/docs/reference/generation-models.md +59 -0
- package/docs/reference/limits.md +306 -0
- package/docs/reference/manifest-kinds-controls.md +36 -0
- package/docs/reference/manifest.md +181 -0
- package/docs/reference/operations.md +36 -0
- package/docs/reference/package-jobs.md +35 -0
- package/docs/reference/parity.md +55 -0
- package/docs/reference/permissions.md +86 -0
- package/docs/reference/ports.md +26 -0
- package/docs/reference/types.md +268 -0
- package/docs/reference/universal-resolver.md +303 -0
- package/docs/reference/view-bridge.md +60 -0
- package/docs/reference/view-rules.md +15 -0
- package/docs/reference/workspace-sync.md +25 -0
- package/docs/sdk.md +34 -0
- package/docs/tools/block-remix.md +211 -0
- package/docs/tools/llm.md +2213 -0
- package/docs/tools/repository-adaptation.md +613 -0
- package/examples/check-clip.stillmade.json +8 -1
- package/examples/clean-text.stillmade.json +4 -0
- package/examples/custom-interface.stillmade.json +4 -0
- package/examples/describe-image.stillmade.json +4 -0
- package/examples/foley-cue.stillmade.json +4 -0
- package/examples/generate-image.stillmade.json +4 -0
- package/examples/generate-video.stillmade.json +10 -2
- package/examples/module-word-stats/stillmade.block.json +4 -0
- package/examples/narrate-script.stillmade.json +4 -0
- package/examples/numbered-takes.stillmade.json +4 -0
- package/examples/research-topic.stillmade.json +9 -1
- package/examples/score-a-scene.stillmade.json +4 -0
- package/examples/script-draft.stillmade.json +4 -0
- package/examples/summarize-page.stillmade.json +4 -0
- package/examples/text-workflow.stillmade.json +7 -32
- package/examples/thicken-lines.stillmade.json +4 -0
- package/examples/timeline-polish.stillmade.json +15 -3
- package/examples/transcribe-audio.stillmade.json +15 -3
- package/examples/word-count.stillmade.json +4 -0
- package/package.json +1 -1
- package/packages/block-cli/cli.js +13 -6
- package/packages/block-cli/dev-host/assets/host.js +81 -38
- package/packages/block-cli/dev-host/assets/index.css +1 -1
- package/packages/block-cli/format.js +1 -1
- package/packages/block-cli/ready-gate.js +4 -0
- package/packages/block-cli/templates.js +37 -19
- package/packages/block-cli/type-packages.js +119 -0
- package/packages/block-platform/block-readiness.js +8 -1
- package/packages/block-platform/canvas.js +2 -1
- package/packages/block-platform/catalog.js +27 -48
- package/packages/block-platform/native-host-inventory.js +0 -226
- package/packages/block-platform/plain-descriptions.js +1 -25
- package/packages/block-platform/project-type-starters.js +13 -53
- package/packages/block-platform/script-handoff.js +2 -4
- package/packages/block-platform/type-workspace.js +2 -0
- package/packages/block-sdk/appearance.js +3 -1
- package/packages/block-sdk/audio-generation-example.js +2 -2
- package/packages/block-sdk/block-tier.js +1 -1
- package/packages/block-sdk/builder-contract.js +13 -11
- package/packages/block-sdk/capabilities.js +1 -1
- package/packages/block-sdk/capability-example.js +1 -1
- package/packages/block-sdk/contracts.js +6 -2
- package/packages/block-sdk/examples.js +3 -3
- package/packages/block-sdk/first-party-identities.js +1 -84
- package/packages/block-sdk/first-party-packages.js +3 -85
- package/packages/block-sdk/generation-catalog.js +15 -3
- package/packages/block-sdk/image-description-example.js +1 -1
- package/packages/block-sdk/image-generation-example.js +1 -1
- package/packages/block-sdk/index.d.ts +2 -1
- package/packages/block-sdk/media-analysis-example.js +2 -2
- package/packages/block-sdk/mock-host.js +7 -1
- package/packages/block-sdk/module-example.js +1 -1
- package/packages/block-sdk/module-host-calls.js +35 -10
- package/packages/block-sdk/module-hosted.js +15 -2
- package/packages/block-sdk/module-media-access.js +71 -0
- package/packages/block-sdk/module-node.js +1 -1
- package/packages/block-sdk/portable-media-actions.js +1 -1
- package/packages/block-sdk/runtime.js +1 -1
- package/packages/block-sdk/speech-example.js +1 -1
- package/packages/block-sdk/state-example.js +1 -1
- package/packages/block-sdk/timeline-proposal-example.js +1 -1
- package/packages/block-sdk/transcription-example.js +1 -1
- package/packages/block-sdk/trigger-examples.js +2 -2
- package/packages/block-sdk/video-generation-example.js +1 -1
- package/packages/block-sdk/view-bridge.js +4 -1
- package/packages/block-sdk/view-design.js +44 -15
- package/packages/block-sdk/web-example.js +2 -2
- package/packages/design-system/block-kit.css +53 -12
- package/packages/design-system/block-kit.html +3 -2
- package/blocks/mcp-motion-planner/versions/1.1.0/package.js +0 -97
- package/blocks/motion-designer/versions/1.0.1/package.js +0 -173318
- package/blocks/motion-designer/versions/1.0.2/package.js +0 -173318
- package/blocks/motion-frame-review/versions/1.1.1/package.js +0 -465
- package/blocks/motion-frame-review/versions/1.1.2/package.snapshot.js +0 -572
- package/blocks/narration/package.js +0 -1
- package/blocks/narration/versions/1.0.0/package.js +0 -221
- package/blocks/narration/versions/1.0.1/package.js +0 -221
- package/blocks/native/sm.animated-scene/versions/2.0.0/package.js +0 -475
- package/blocks/native/sm.animated-scene/versions/2.1.0/package.js +0 -498
- package/blocks/native/sm.animated-scene/versions/2.2.0/package.js +0 -524
- package/blocks/native/sm.animated-scene/versions/2.3.0/package.js +0 -618
- package/blocks/native/sm.animated-scene/versions/2.3.1/package.js +0 -618
- package/blocks/native/sm.animated-scene/versions/2.3.2/package.js +0 -723
- package/blocks/native/sm.animated-scene/versions/2.3.3/package.js +0 -723
- package/blocks/native/sm.animated-scene/versions/2.3.4/package.js +0 -676
- package/blocks/native/sm.animated-scene/versions/2.3.5/package.js +0 -693
- package/blocks/native/sm.animated-scene/versions/2.3.6/package.js +0 -700
- package/blocks/native/sm.animated-scene/versions/2.3.7/package.js +0 -747
- package/blocks/native/sm.animated-scene/versions/2.3.8/package.js +0 -769
- package/blocks/native/sm.animated-scene/versions/2.3.9/package.js +0 -769
- package/blocks/native/sm.animated-scene-assistant/versions/1.0.0/package.js +0 -183
- package/blocks/native/sm.blueprint/versions/2.0.0/package.js +0 -358
- package/blocks/native/sm.blueprint/versions/2.1.0/package.js +0 -358
- package/blocks/native/sm.blueprint/versions/2.1.1/package.js +0 -358
- package/blocks/native/sm.blueprint/versions/2.1.2/package.js +0 -358
- package/blocks/native/sm.blueprint/versions/2.1.3/package.js +0 -381
- package/blocks/native/sm.blueprint/versions/2.1.4/package.js +0 -381
- package/blocks/native/sm.blueprint/versions/2.1.5/package.js +0 -339
- package/blocks/native/sm.blueprint/versions/2.1.6/package.js +0 -356
- package/blocks/native/sm.blueprint/versions/2.1.7/package.js +0 -363
- package/blocks/native/sm.blueprint/versions/2.1.8/package.js +0 -410
- package/blocks/native/sm.blueprint/versions/2.1.9/package.js +0 -422
- package/blocks/native/sm.blueprint-assistant/versions/1.0.0/package.js +0 -172
- package/blocks/native/sm.chat/versions/2.0.0/package.js +0 -144
- package/blocks/native/sm.chat/versions/2.0.1/package.js +0 -97
- package/blocks/native/sm.chat/versions/2.0.2/package.js +0 -100
- package/blocks/native/sm.chat/versions/2.0.3/package.js +0 -100
- package/blocks/native/sm.continue-if/versions/1.0.0/package.js +0 -168
- package/blocks/native/sm.describe-media/versions/2.0.0/package.js +0 -153
- package/blocks/native/sm.describe-media/versions/2.0.1/package.js +0 -156
- package/blocks/native/sm.describe-media/versions/2.1.0/package.js +0 -140
- package/blocks/native/sm.image-editor/versions/2.0.0/package.js +0 -183
- package/blocks/native/sm.image-editor/versions/2.0.1/package.js +0 -190
- package/blocks/native/sm.new-items/versions/1.0.0/package.js +0 -191
- package/blocks/native/sm.pick-photos/versions/1.0.0/package.js +0 -334
- package/blocks/native/sm.quality-audit/versions/1.0.0/package.js +0 -192
- package/blocks/native/sm.quality-audit/versions/1.0.1/package.js +0 -192
- package/blocks/native/sm.quality-audit/versions/1.0.2/package.js +0 -195
- package/blocks/native/sm.research/versions/2.0.0/package.js +0 -175
- package/blocks/native/sm.research/versions/2.0.1/package.js +0 -184
- package/blocks/native/sm.research/versions/2.0.2/package.js +0 -187
- package/blocks/native/sm.script/versions/2.0.0/package.js +0 -144
- package/blocks/native/sm.script/versions/2.1.0/package.js +0 -144
- package/blocks/native/sm.script/versions/2.1.1/package.js +0 -144
- package/blocks/native/sm.script/versions/2.1.2/package.js +0 -105
- package/blocks/native/sm.script/versions/2.1.3/package.js +0 -152
- package/blocks/native/sm.script/versions/2.1.4/package.js +0 -156
- package/blocks/native/sm.script/versions/2.1.5/package.js +0 -156
- package/blocks/native/sm.shot-plan/versions/2.0.0/package.js +0 -301
- package/blocks/native/sm.shot-plan/versions/2.1.0/package.js +0 -528
- package/blocks/native/sm.shot-plan/versions/2.1.1/package.js +0 -528
- package/blocks/native/sm.shot-plan/versions/2.1.2/package.js +0 -528
- package/blocks/native/sm.shot-plan/versions/2.1.3/package.js +0 -536
- package/blocks/native/sm.shot-plan/versions/2.2.0/package.js +0 -800
- package/blocks/native/sm.shot-plan/versions/2.2.1/package.js +0 -920
- package/blocks/native/sm.shot-plan-assistant/versions/1.0.0/package.js +0 -173
- package/blocks/native/sm.stock-search/versions/2.0.0/package.js +0 -174
- package/blocks/native/sm.thumbnail/versions/2.0.0/package.js +0 -137
- package/blocks/native/sm.thumbnail/versions/2.0.1/package.js +0 -140
- package/blocks/native/sm.transcribe/versions/2.0.0/package.js +0 -163
- package/blocks/native/sm.transcribe/versions/2.0.1/package.js +0 -168
- package/blocks/native/sm.whiteboard-assistant/versions/1.0.0/package.js +0 -175
- package/blocks/native/sm.youtube/versions/2.0.0/package.js +0 -217
- package/blocks/occasion-story/package.js +0 -1
- package/blocks/occasion-story/versions/1.0.0/package.js +0 -1658
- package/blocks/occasion-story/versions/1.0.1/package.js +0 -1699
- package/blocks/occasion-story/versions/1.0.2/package.js +0 -1682
- package/blocks/photo-reel-composer/versions/1.0.0/package.js +0 -3043
- package/blocks/photo-reel-composer/versions/1.0.1/package.js +0 -3026
- package/blocks/photo-reel-composer/versions/1.0.2/package.js +0 -4149
- package/blocks/product-ad-variants/versions/1.0.0/package.js +0 -2911
- package/blocks/product-launch-director/versions/1.0.0/package.js +0 -103
- package/blocks/release-visuals/package.js +0 -1
- package/blocks/release-visuals/versions/1.0.0/package.js +0 -1492
- package/blocks/release-visuals/versions/1.0.1/package.js +0 -1517
- package/blocks/release-visuals/versions/1.0.2/package.js +0 -1500
- package/blocks/screen-recorder/package.js +0 -1
- package/blocks/screen-recorder/versions/1.0.0/package.js +0 -223
- package/blocks/screen-recorder/versions/1.0.1/package.js +0 -223
- package/blocks/short-form-finish/package.js +0 -1
- package/blocks/short-form-finish/versions/1.0.0/package.js +0 -1043
- package/blocks/short-form-finish/versions/1.0.1/package.js +0 -1043
- package/blocks/short-form-finish/versions/1.0.2/package.js +0 -1043
- package/blocks/short-form-finish/versions/1.0.3/package.js +0 -1026
- package/examples/saas-product-launch-reviewed-source.stillmade.json +0 -383
- package/examples/saas-product-launch.stillmade.json +0 -304
- package/packages/block-platform/dealer-inventory-video-project-type.js +0 -38
- package/packages/block-platform/first-revenue-project-types.js +0 -46
- package/packages/block-platform/fixture-starters.js +0 -13
- package/packages/block-platform/launch-project-source.js +0 -10
- package/packages/block-platform/launch-project.js +0 -30
- package/packages/block-platform/motion-project-types.js +0 -55
- package/packages/block-platform/motion-starters.js +0 -14
- package/packages/block-platform/product-ad-variants-project-type.js +0 -30
- package/packages/block-platform/product-launch-updated.js +0 -90
- package/packages/block-platform/revenue-review-project-types.js +0 -36
- package/packages/block-platform/revenue-review-starters.js +0 -13
- package/packages/block-platform/script-writer.js +0 -29
- package/packages/block-platform/website-source-block.js +0 -14
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Block builder contract
|
|
2
|
+
|
|
3
|
+
Contract `stillmade.block-builder@1.17.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.
|
|
4
|
+
|
|
5
|
+
## Source of truth
|
|
6
|
+
|
|
7
|
+
Treat the current SDK (`stillmade.block.json` manifest, `packages/block-sdk` contracts, validators, examples and published docs) as the source of truth. Before writing code, read the manifest contract, at least two working first-party Blocks closest to the request, the runtime you will use, the typed port and resolver contracts, and the shared-interface contract when you need a custom view. Do not invent runtimes, operations, permissions, ports, host services or bridge calls. If the documentation and the validator disagree, the validator wins and the mismatch should be reported.
|
|
8
|
+
|
|
9
|
+
## Reuse first
|
|
10
|
+
|
|
11
|
+
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.
|
|
12
|
+
|
|
13
|
+
## Three sizes of Block
|
|
14
|
+
|
|
15
|
+
Blocks come in three sizes and the manifest decides which (packages/block-sdk/block-tier.js): an app is a workspace a person works in (Editor, Canvas, Shots), placed in a Type and never wired automatically; a job is one deliverable a person would name (the narration, the captioned clip), built from the hosted operations it needs (`permissions.capabilities`) and reviewed in one place, the unit Chat picks for a Step; an ingredient is one hosted operation with nothing of its own (a declarative capability Block), what a job is made of. When two ingredients would stand in a row to make one deliverable (writing the words, then voicing them), build or pick the job that does both and keep the review point inside it. A job declares a second output when another Block consumes the intermediate (the script beside the voice); split into two jobs only when the intermediate has a life of its own or the halves have different owners or payment.
|
|
16
|
+
|
|
17
|
+
## Choose the runtime
|
|
18
|
+
|
|
19
|
+
Pick the runtime from the job. No hosted AI: a recipe or isolated `javascript`, both able to run unattended. One text, script or brief prompt returning text, script or JSON: a `capability` Block. Hosted operations on other values (a transcript, media, structured data), several hosted operations in a row, or a result shaped in code: one `module` Block, `module/main.js` calling `stillmade.hosted.run(operation, request)` for each operation in `permissions.capabilities` (MODULES.md), never one Block per operation; it runs in the person's browser while StillMade is open. Build a new Block in a folder with `stillmade-block create`, `test`, `ready` and `pack`, and import the file `pack` writes (a module Block writes `<id>-<version>.stillmade-module.json`) through Create, then Import Block. A `.stillmade-block` archive is only for adapting a GitHub repository.
|
|
20
|
+
|
|
21
|
+
## One job per Step
|
|
22
|
+
|
|
23
|
+
A Step is one job: the work between two moments where a person or the outside world must see the result. A guided job, one the person fills in and then gets a result from, is one Step with one Block whose own screen holds everything: the inputs and settings, then a cheap check before the expensive run (the script and a voice sample before the video), then the result. On a wide screen the inputs sit on the left and the result's place on the right; on a phone they stack, the result's place under the button. A cheap check or a review the person does on that screen never starts a new Step. Start a new Step only at one of these points; everything else is a part of the neighboring Step.
|
|
24
|
+
|
|
25
|
+
1. **A person works with the result**: in a workspace they spend a while in (the Editor, a storyboard, a Canvas, a CAD or drawing tool), or someone else approves or takes it over (a hand-off). Turning what a workspace made into something else is the next Step: a CAD tool is its own Step, and the Block that takes pictures of its model and makes a video is the next one. So Bible, Canvas and Editor are separate Steps after Chat.
|
|
26
|
+
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.
|
|
27
|
+
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.
|
|
28
|
+
4. **Setup or a wait**: a one-time setup that is not part of each job (a brand kit, capturing a voice or a likeness), or a render that takes minutes and is delivered later.
|
|
29
|
+
|
|
30
|
+
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 Type whose own Block renders the finished video (`timeline.render`) needs no Editor Step; the Editor (1.0, captions and export built in) is a Step only when the person edits the cut by hand, and Export video is never a Step beside it.
|
|
31
|
+
|
|
32
|
+
A part that only runs in the desktop app cannot share a Step with cloud parts. Before adding a Step, name which of these 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.
|
|
33
|
+
|
|
34
|
+
Build one Block for a job one Block can do: a module Block calls every hosted operation the job needs (it transcribes a sermon, then finds the verses said in it), a JavaScript Block does several local transforms, a workspace owns its whole document. A Block being built never takes an ingredient's result only so the ingredient can be its own part or Step (Transcribe in front of a verse finder): it calls that operation itself. Parts in one Step (`groups` in the Project Type) are for jobs made of Blocks that already exist and app tasks, each keeping its own permission, approval and credit rules. Never invent a combined runtime.
|
|
35
|
+
|
|
36
|
+
Examples: "a listing video from my photos and the home's facts" is one Step: one Block whose page takes the photos and facts, shows the script and a voice sample to check, then makes the video. "every new email with an image becomes a generated image" is two Steps, "Gmail · New emails with images" (When, fetch with an image filter, only new) and "Image from email" (AI write, Generate image); listing When, Fetch, Only new, AI decide, Continue only if, AI write and Generate image as seven Steps splits one job into its parts. "A new Meta lead goes to HubSpot" is three Steps: "Meta Ads · New leads", "Qualify lead" and "HubSpot · Add contact".
|
|
37
|
+
|
|
38
|
+
## Define the capability first
|
|
39
|
+
|
|
40
|
+
Translate the request into an explicit capability contract before implementation: what the Block does; each input with its type, meaning and whether it is required (prefer optional settings with safe defaults over extra required questions); each output with its type and meaning; persistent state; project context it reads; permissions; UI; long-running behavior; expected failures; cancellation; determinism; and whether it needs hosted models, media, desktop tools or shared editing. Keep the public interface as small and general as possible (few required inputs, one primary output) and keep implementation details out of it; small means a small interface, never a fragment of a job. A Block that generates images, video or speech declares only its prompt and output: every Step that runs it gets the host’s generation settings (model, quality, length and resolution, voice, speed, how many), saved with the Step, changed on its page or by Chat, and shown with their cost before each run.
|
|
41
|
+
|
|
42
|
+
## Blocks compose
|
|
43
|
+
|
|
44
|
+
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`.
|
|
45
|
+
|
|
46
|
+
## Feature map
|
|
47
|
+
|
|
48
|
+
Every Block carries a feature map in `manifest.features`, written by whoever builds it while they build, so the person never writes it. Add one entry for each separate thing a person could ask for: a tool, a mode, a preset family or a kind of result (an editor's reaction GIFs, its motion presets, a recorder's screen recording), not one entry covering several tools. Each entry has a lowercase `id`, a `label` of 40 characters or fewer, `does` (what it does, 160 characters or fewer) and `asks`: 1–8 short requests in a customer's own words that this feature answers ("add a fire gif over my car"). `operation` names an id in the Block's own `manifest.operations` (omit it when there are none); `inputs`/`outputs` name declared ports. The gate fails a Block without one. Add or update the entry in the same change that adds or alters a tool, and remove it when the tool goes. List only what the code really does; listings are generated from this map, nobody can edit them, and StillMade matches requests to features. Features are not tested at publish: each shows as new until real use proves it.
|
|
49
|
+
|
|
50
|
+
## Use platform primitives
|
|
51
|
+
|
|
52
|
+
Prefer, in order: an SDK capability; a documented host capability (the hosted operations are text.generate, audio.speech, audio.transcribe, audio.music, audio.sfx, image.generate, video.generate, image.describe, media.analyze, web.fetch, web.research, timeline.propose, workspace.propose, connection.execute; connected third-party apps go through `connection.execute`); an approved dependency the SDK already bundles; small Block-local code. Do not duplicate what StillMade provides. A Block never contains its own asset system, file picker, authentication, project-context system, input resolver, Block connection system, credit system, secrets store, permission system, progress system, multiplayer system, persistence system, model-provider abstraction or execution protocol.
|
|
53
|
+
|
|
54
|
+
## No hidden workarounds
|
|
55
|
+
|
|
56
|
+
Never make a Block look functional through hard-coded local paths, developer-machine dependencies, undocumented environment variables, admin or database access, hidden core modifications, direct database writes, fake or mocked production results, hand-prepared test assets that hide incompatibilities, credentials in code, or assumptions about one user's machine. The finished Block must work through the same interfaces available to any installed Block; `permissions.filesystem` and `permissions.secrets` must be empty arrays, and so must `permissions.network`, except in a module Block, which lists the https origins it calls through `stillmade.net.fetch`.
|
|
57
|
+
|
|
58
|
+
## Name it briefly
|
|
59
|
+
|
|
60
|
+
Give the Block a short, plain name of 40 characters or fewer that says what it does ("Captioned Clip", not "Captioned Business Clip Generator With Review"). The name appears in step bars, Project Type cards and pickers, so put the detail in the description instead. New releases with a longer name do not pass readiness.
|
|
61
|
+
|
|
62
|
+
## Name inputs in the job's words
|
|
63
|
+
|
|
64
|
+
Name each input for what the person brings, in the job's words: `sermonVideo` for a sermon clip Block, `listingPhotos` for a listing, `lessonSlides` for a lesson podcast. StillMade titles the input from that name ("Sermon video") and words its drop area from it ("Drop your sermon video here", the formats, "Choose a video"), in StillMade and the SDK preview, so never draw your own upload box or `<input type="file">`: a Block's screen shows the files as tiles and adds more with `<button class="sm-add" data-stillmade-add="listingPhotos" aria-label="Add photos">`, which opens StillMade's picker and upload, and a list's tiles drop or reorder a file with `data-stillmade-remove="listingPhotos" data-index="2"` and `data-stillmade-move="listingPhotos" data-index="2" data-to="1"` buttons; the files arrive through `onInput`. Keep a bare type name (`video`, `file`) only when any file of that kind does the job. The `description` says what makes a good one.
|
|
65
|
+
|
|
66
|
+
## Speak the job
|
|
67
|
+
|
|
68
|
+
These are StillMade's defaults: unless the person or the creator asked for something else, every screen speaks the job in its own words and adds nothing else. `manifest.action` names the Step's button, {label:"Plan the tour", running:"Planning the tour…"}, and StillMade adds the price ("Plan the tour · 1 credit"). Every Block whose Step shows StillMade's button declares it: any Block without its own screen, and any that calls operations. Without it StillMade can only guess from the Block's name or output ("Make clips"), and the readiness gate and StillMade's own builder send the Block back until it names the job. When the Block makes a picture, video or sound with AI the label starts with Generate and says what ("Generate tour", "Generate voiceover"); one that cuts or renders the person's own media says Make ("Make 6 clips"); never "Make it", "Run", "Submit", "Process" or a bare "Generate". The main button stands out: one solid `sm-primary` in the kit's ink, never restyled to the background; everything else is `sm-quiet` or an `sm-icon`, and close is an X icon. Report progress in the job's units with `stillmade.progress(fraction, label)` ("Moving through the kitchen, 4 of 9 rooms"), never "Processing". Head the result in the job's words ("9 rooms", "Your tour · 44 s"), never "Output". Say a problem in one line with its fix beside it ("No bathroom photo. Guests look for one." and Add photo). Stay quiet: no welcome text, tips under fields, tours or banners, and at most one line of guidance on a screen, only where the next move is not obvious; anything more goes in the input's `description`, which StillMade shows behind an (i). Say nothing about how the Block works (where it runs, saving, syncing, recovery, accounts, credits) or where a file is kept: StillMade tells the person what they need as one short notification, or nothing; never a sentence on the page, and never the same line under each item. Every drop area offers "Use a reference", which fills the Step from the person's saved photos, videos and notes: media inputs fill by kind, so take `video` or `asset` where a clip works as well as a photo, and text inputs fill by plain names and labels (`productName`, `website`, `brandColors`, `fonts`, `voice`, and `details` or `notes` for the reference's note); never build your own reference picker. Days and times are picked, never typed: use the `date` type, which StillMade shows as a calendar, with a list of times when the input is about a time (`postAt`, `startsAt`); a custom view uses `<input type="date">` or `type="datetime-local"`. Posting is a connector Step of its own, and StillMade words its button from the app and action ("Post to Instagram"). Before handing the Block back, clear every Wording note that `gate` and readiness list, unless the person asked for those words.
|
|
69
|
+
|
|
70
|
+
## Interface
|
|
71
|
+
|
|
72
|
+
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 under the button, 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'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. StillMade centers a standard view narrower than its Step and zooms a view to fill its space; 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 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.
|
|
73
|
+
|
|
74
|
+
## Shared editing
|
|
75
|
+
|
|
76
|
+
Projects are multiplayer. A custom view subscribes through `StillMade.onShared(callback)` and publishes every editable field: give static controls a unique `id` and `data-stillmade-share="field"` (the host owns their synchronization), use `StillMade.bindShared(field, elementId)` for controls created dynamically, and `StillMade.updateShared(values, before, options)` for structured values; private variables and DOM values are not shared. Mark a truly device-only control (playback, hover, device selection) with `data-stillmade-local`. Observe shared outputs as well as state, honor `canEdit` in every mutating callback (read-only participants cannot write), never run, click or call a paid integration in response to a remote update, and preserve conflicting drafts. Shared background work uses `sharedWork` with the `work.shared` permission.
|
|
77
|
+
|
|
78
|
+
## External services
|
|
79
|
+
|
|
80
|
+
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.
|
|
81
|
+
|
|
82
|
+
## Dependencies
|
|
83
|
+
|
|
84
|
+
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.
|
|
85
|
+
|
|
86
|
+
## Security
|
|
87
|
+
|
|
88
|
+
Treat Block code, external data, files, repositories, model output and network responses as untrusted. Request the minimum permissions and capabilities; `stillmade-block permissions --fix` declares exactly what the source uses. Do not weaken the sandbox (QuickJS has no fetch, DOM, timers, modules or Node APIs). Validate and bound every value crossing a boundary. Never expose secrets through logs, outputs, project context, UI, error messages or serialized state.
|
|
89
|
+
|
|
90
|
+
## Execution lifecycle
|
|
91
|
+
|
|
92
|
+
A successful run means more than a returned value. Validate inputs before work; return only declared output ports with values matching their types; run long work as a cooperative job (`job.pending` with monotonic progress) instead of blocking; honor cancellation and the host timeout; keep persistent state in `manifest.state` (module Blocks: `stillmade.storage`) with migration routes so a reopened project and a repeated run behave the same; never leave orphaned jobs, temporary values or corrupted project state after cancellation or failure.
|
|
93
|
+
|
|
94
|
+
## Useful failures
|
|
95
|
+
|
|
96
|
+
Errors must say what failed, why it likely failed, whether a retry makes sense and what the user can do, so the native project chat and controller can troubleshoot. In JavaScript, throw an `Error` with that message: the host reports it as a `JAVASCRIPT` run failure carrying your message (guest code cannot set its own error code). Reject invalid or oversized input up front with a message naming the input and the limit. Never reduce a failure to "Something went wrong".
|
|
97
|
+
|
|
98
|
+
## Only supplied facts
|
|
99
|
+
|
|
100
|
+
A text Block that writes from supplied facts must not let its prompt template outrank its own "never invent" rule. Every section that needs a specific fact (phone, website, address, price, inspection, certification, warranty, features) is written only when the input supplies that fact; otherwise the section is left out or replaced by a generic line that asserts nothing (for example "Call us today to schedule your test drive."). Never default to "inspected", "certified", invented features or placeholder contact details such as 555 numbers or example websites. Prefer extract-then-generate: first list the facts the input actually contains, then write using only that list. Add a check after generation that rejects or removes sentences naming a claim, number or address not present in the input. Include fixtures with the facts omitted and with them supplied.
|
|
101
|
+
|
|
102
|
+
## Adapt to the platform
|
|
103
|
+
|
|
104
|
+
Do not modify StillMade core because a request does not fit immediately. First implement the capability entirely through documented SDK and platform primitives. If that is impossible, classify why: A Block implementation problem (fix it), B missing SDK exposure of an existing host capability, C missing generic platform primitive, D security or permission restriction, E runtime or language incompatibility, F fundamentally incompatible capability. For B or C, name the smallest general primitive that would serve this Block and a meaningful class of future Blocks (shaped like `files.watch()` or `media.transform()`, never `supportThisSpecificBlock()`). Return `{"unsupported":"exact reason","gapClass":"B|C|D|E|F","primitive":"..."}` instead of a package that pretends to work.
|
|
105
|
+
|
|
106
|
+
## What StillMade verifies
|
|
107
|
+
|
|
108
|
+
StillMade runs the readiness check on every Block it admits: manifest and contract validation, the source security scan, every fixture in the sandbox, wrong-type and over-limit inputs, declared output types, cancellation and timeout cleanup, state reopen and repeated runs, composition with a real upstream and downstream catalog Block through the resolver, a Project Type preview, the shared-interface contract with two participants editing a custom view in the real preview runtime (their edits must converge and a read-only participant must not write), and phone and desktop layout. Design for all of them and include normal and edge-case fixtures (1 to 50; stateful Blocks also declare `expectedState`). Test materially different inputs within the declared capability, and document limitations instead of overclaiming generality. Two of these checks need StillMade itself: two-participant shared editing and the phone and desktop UI profile run in StillMade's preview runtime when the Block is imported or released, so `ready` in the downloaded SDK reports them as not verified rather than passed.
|
|
109
|
+
|
|
110
|
+
## Project Types
|
|
111
|
+
|
|
112
|
+
A Project Type is an ordered production workflow. Each Step's primary output must be a compatible input for the next Step, secondary values come from permitted project context, and every member Block obeys this contract. Install Blocks into a realistic Project Type: project chat must understand each Step, inputs must resolve intuitively, outputs and execution state must be visible, failures must be diagnosable, and the user must be able to continue through the workflow. Group the parts of one job into one Step instead of listing helper parts as Steps; most automations are two to four Steps.
|
|
113
|
+
|
|
114
|
+
## Readiness report
|
|
115
|
+
|
|
116
|
+
Finish with a Block Readiness Report: capability, contract (inputs, outputs, permissions, dependencies), platform APIs used, tests actually performed and their results, the composition test (upstream, Block, downstream), known limitations, unsupported requirements and any platform gap with its smallest general primitive. Report exactly one status, the one StillMade's readiness check returned (`ready` in the SDK CLI, `check_block_readiness` over MCP), never one you chose: PRODUCTION READY (every applicable check passed), READY WITH DOCUMENTED LIMITATIONS (works reliably within stated boundaries), BLOCKED BY PLATFORM CAPABILITY (needs a missing generic primitive) or FAILED. Never label a Block production ready to satisfy a request, and never claim a check ran when it did not.
|
|
117
|
+
|
|
118
|
+
## Definition of done
|
|
119
|
+
|
|
120
|
+
A Block is done only when every applicable item holds. Passing a compile, one unit test, a rendered UI or one happy-path sample is not done.
|
|
121
|
+
|
|
122
|
+
- DOD-01 Installs through the normal Block mechanism
|
|
123
|
+
- DOD-02 Manifest and contracts validate
|
|
124
|
+
- DOD-03 Runs through the normal runtime
|
|
125
|
+
- DOD-04 Required permissions are declared
|
|
126
|
+
- DOD-05 Required dependencies are reproducible
|
|
127
|
+
- DOD-06 Real inputs work
|
|
128
|
+
- DOD-07 Invalid inputs fail correctly
|
|
129
|
+
- DOD-08 Outputs conform to their declared types
|
|
130
|
+
- DOD-09 Outputs are usable by compatible downstream Blocks
|
|
131
|
+
- DOD-10 Universal resolver integration works
|
|
132
|
+
- DOD-11 Applicable project context works
|
|
133
|
+
- DOD-12 Applicable persistence works
|
|
134
|
+
- DOD-13 Applicable multiplayer behavior works
|
|
135
|
+
- DOD-14 Cancellation and failure cleanup work
|
|
136
|
+
- DOD-15 UI works in relevant states and screen sizes
|
|
137
|
+
- DOD-16 No hidden developer setup is required
|
|
138
|
+
- DOD-17 Security boundaries remain intact
|
|
139
|
+
- DOD-18 Relevant integration tests pass
|
|
140
|
+
- DOD-19 Works after application restart or project reopen
|
|
141
|
+
- DOD-20 A realistic Project Type execution succeeds when applicable
|
|
142
|
+
|
|
143
|
+
## Platform gap classes
|
|
144
|
+
|
|
145
|
+
- A: Block implementation problem
|
|
146
|
+
- B: Missing SDK exposure of an existing host capability
|
|
147
|
+
- C: Missing generic platform primitive
|
|
148
|
+
- D: Security or permission restriction
|
|
149
|
+
- E: Runtime or language incompatibility
|
|
150
|
+
- F: Fundamentally incompatible capability
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# ComfyUI Blocks
|
|
2
|
+
|
|
3
|
+
The reviewed adapter now supports core text-to-image and image-to-image generation. Use `CheckpointLoaderSimple`, `CLIPTextEncode`, `EmptyLatentImage`, `KSampler`, `VAEEncode` and `VAEDecode` with existing `PreviewImage` output. One installed safetensors checkpoint basename, one sampling pass, batch 1 and at most 40 steps are admitted. Generation dimensions are 64–1024 in multiples of 8, subject to the existing four-megapixel aggregate working budget (1024-square image-to-image can exceed it). The connection must report that checkpoint; filenames do not prove file hashes, licenses or GPU readiness. No weights are downloaded. `comfyModelRequirements(workflow)` returns the required model names. Text and numeric controls use typed scalar bindings. The import wizard preserves real sample inputs and prepares padded image-to-image fixture copies; project inputs are never silently resized. See `examples/comfy-text-to-image.stillmade.json` and replace the checkpoint placeholder before review.
|
|
4
|
+
|
|
5
|
+
A ComfyUI Block is a portable declaration of a reviewed image capability. Users
|
|
6
|
+
see its controls and resulting image, not its internal node wiring. Start with
|
|
7
|
+
[the complete example](https://stillmade.shop/block-sdk/examples/comfy-invert.stillmade.json).
|
|
8
|
+
|
|
9
|
+
### Import an existing ComfyUI workflow
|
|
10
|
+
|
|
11
|
+
Choose **Import ComfyUI workflow** in the import tools, or choose its JSON file
|
|
12
|
+
with **Import package**. Export the **API format** from ComfyUI first; its
|
|
13
|
+
[API documentation](https://docs.comfy.org/development/cloud/overview) describes
|
|
14
|
+
the numbered node map. Visual exports containing `nodes` and `links` cannot be
|
|
15
|
+
converted without the exact frontend/node definitions and receive export guidance.
|
|
16
|
+
The importer accepts the prompt map itself or `{ "prompt": { … } }`. A ZIP may
|
|
17
|
+
contain one `workflow.json`, `workflow_api.json`, or `*.comfy.json` file.
|
|
18
|
+
|
|
19
|
+
The mapping screen asks for the Block name, description, source license, input
|
|
20
|
+
and result names, and the main image input/output. Multiple image inputs or
|
|
21
|
+
outputs require an explicit main choice. Optional semantic roles distinguish
|
|
22
|
+
source images from character references. Resize controls can stay fixed or become
|
|
23
|
+
user-editable inputs. Every LoadImage and PreviewImage must be mapped; unknown
|
|
24
|
+
nodes, dependencies, credentials, cycles, and disconnected processing are rejected.
|
|
25
|
+
This adapter accepts the reviewed image and diffusion classes listed below, not arbitrary custom-node workflows.
|
|
26
|
+
|
|
27
|
+
Choose a sample for every image input. The browser creates a copy no larger than
|
|
28
|
+
128 pixels per side, with a combined fixture budget, and includes those pixels
|
|
29
|
+
in the downloaded source. Originals are unchanged. The sample stays local until
|
|
30
|
+
you explicitly run the backend review. Optional expected dimensions add fixture
|
|
31
|
+
assertions; leaving them blank still requires a valid decoded single image.
|
|
32
|
+
Choose sample images you may distribute with this Block.
|
|
33
|
+
|
|
34
|
+
**Continue to tests and preview** creates an SDK package, not an installation or
|
|
35
|
+
a successful test. The existing account connection, real fixtures, separate
|
|
36
|
+
sample execution, preview, rights review and **Confirm Import** follow. Importing
|
|
37
|
+
never republishes third-party code. The original API JSON is retained in
|
|
38
|
+
`manifest.provenance.comfyuiImport.source`; execution uses normalized placeholders
|
|
39
|
+
instead of its saved image filenames. Original `_meta.title` remains attribution,
|
|
40
|
+
not executable behavior. Review this retained source before sharing a release.
|
|
41
|
+
|
|
42
|
+
The downloadable SDK exposes the same static conversion API:
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
import {inspectComfyImport, buildComfyImportPackage}
|
|
46
|
+
from './packages/block-sdk/index.js';
|
|
47
|
+
import {comfyImageInvert} from './packages/block-sdk/comfyui-example.js';
|
|
48
|
+
|
|
49
|
+
// Replace with a supported API export. No backend is contacted by either call.
|
|
50
|
+
const raw = structuredClone(comfyImageInvert.comfyui.prompt);
|
|
51
|
+
raw['1'].inputs.image = 'my-example.png';
|
|
52
|
+
const inspection = inspectComfyImport(raw);
|
|
53
|
+
console.log(inspection.inputCandidates, inspection.outputCandidates);
|
|
54
|
+
|
|
55
|
+
const pkg = buildComfyImportPackage(raw, {
|
|
56
|
+
manifest: {...comfyImageInvert.manifest, id: 'my.invert', name: 'My invert'},
|
|
57
|
+
inputs: comfyImageInvert.comfyui.inputs,
|
|
58
|
+
outputs: comfyImageInvert.comfyui.outputs,
|
|
59
|
+
tests: comfyImageInvert.tests,
|
|
60
|
+
});
|
|
61
|
+
// Save pkg as JSON, then import it for real backend review and confirmation.
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`inspectComfyImport(raw)` returns `format`, inert `source`, normalized `prompt`,
|
|
65
|
+
`nodes`, `inputCandidates`, `outputCandidates`, `warnings`, and
|
|
66
|
+
`execution: "not-run"`. It does not choose names, roles, primary ports or fixtures.
|
|
67
|
+
`buildComfyImportPackage(raw, {manifest, inputs, outputs, tests})` requires those
|
|
68
|
+
explicit choices, validates their contracts and selected resize values, and
|
|
69
|
+
returns a package without execution receipts. Source is limited to 64 KiB and
|
|
70
|
+
the complete package to the usual bounded JSON/import limits.
|
|
71
|
+
|
|
72
|
+
### Package and runtime contract
|
|
73
|
+
|
|
74
|
+
Set `manifest.runtime` to `comfyui`, `entry` to `src/comfyui.json`, and declare
|
|
75
|
+
`permissions: {project: [], capabilities: ["comfyui.execute"]}`. The top-level
|
|
76
|
+
package contains `manifest`, `comfyui`, `tests`, and an optional `view`. It cannot
|
|
77
|
+
contain `code` or `recipe`. Put the workflow in `comfyui` or, in an editable folder,
|
|
78
|
+
`src/comfyui.json`. Endpoints, tokens, connection IDs, file paths, dependencies,
|
|
79
|
+
and Python never belong in the package. Input/output types and semantic roles
|
|
80
|
+
use the same StillMade contract as other Blocks.
|
|
81
|
+
|
|
82
|
+
The workflow has four fields: `schemaVersion: 1`, `prompt`, `inputs`, and
|
|
83
|
+
`outputs`. `prompt` is an API-format map of numbered nodes with `class_type` and
|
|
84
|
+
`inputs`. Supported core classes are `LoadImage`, `ImageInvert`, `ImageScale`, `PreviewImage`, `CheckpointLoaderSimple`, `CLIPTextEncode`, `EmptyLatentImage`, `KSampler`, `VAEEncode` and `VAEDecode`. Every node must contribute to a declared output. A `LoadImage`
|
|
85
|
+
uses an empty filename placeholder and a binding such as
|
|
86
|
+
`image: {node: "1", input: "image", encoding: "uploaded-image"}`. StillMade uploads
|
|
87
|
+
verified input pixels and supplies the generated basename. Resize controls use
|
|
88
|
+
`encoding: "scalar"`. An output selects one image from a declared PreviewImage:
|
|
89
|
+
`image: {node: "3", collection: "images", index: 0}`.
|
|
90
|
+
|
|
91
|
+
Each fixture has `name`, `input`, and `expectations`. For example:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{"name":"One pixel","input":{"image":{"width":1,"height":1,"data":[20,80,200,255]}},"expectations":{"image":{"kind":"image","count":1,"width":1,"height":1,"maxBytes":4096}}}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Every output requires `kind: "image"` and `count: 1`. Optional width, height,
|
|
98
|
+
maximum encoded bytes, and lowercase `sha256` check the host-decoded and
|
|
99
|
+
re-encoded PNG, not a claimed backend descriptor. Use deterministic hash fixtures
|
|
100
|
+
when exact image behavior matters. Bounds: 16 nodes, 8 inputs/outputs, one
|
|
101
|
+
megapixel per single-frame image, and four megapixels total working images.
|
|
102
|
+
Small inline fixtures fit the four-megabyte import limit. Large media inputs
|
|
103
|
+
should use existing account-owned media references.
|
|
104
|
+
|
|
105
|
+
In Settings → ComfyUI connections, save the public HTTPS endpoint and optional
|
|
106
|
+
bearer token. Tokens use the same stable account encryption key as BYOK with a
|
|
107
|
+
separate encryption purpose. They are never returned to the browser or guest UI.
|
|
108
|
+
StillMade rejects private network endpoints, redirects and arbitrary requests.
|
|
109
|
+
The backend is an explicitly selected service you operate or trust. Checking
|
|
110
|
+
its core-node schema is compatibility evidence, not attestation of its Python
|
|
111
|
+
implementation. Desktop loopback and arbitrary custom nodes are not available through this adapter. Reviewed core diffusion nodes may use the backend’s GPU after explicit approval.
|
|
112
|
+
|
|
113
|
+
Import the JSON or ZIP, choose the connection, and click **Run tests and sample**.
|
|
114
|
+
StillMade scans the package, records durable jobs, runs every fixture and a
|
|
115
|
+
separate sample, decodes outputs, and displays the before/after result. Only then
|
|
116
|
+
can you confirm rights and **Confirm Import**. Confirmation revalidates the
|
|
117
|
+
account/source/connection-bound receipt without silently submitting another job.
|
|
118
|
+
Changing source, connection revision, backend contract, or an expired receipt
|
|
119
|
+
requires another review. Saving a connection, opening a page, and custom iframe
|
|
120
|
+
JavaScript cannot confirm remote execution. Preview runs never install or
|
|
121
|
+
publish a Block. Cancellation targets only owned jobs; unsupported remote
|
|
122
|
+
cancellation can leave work running on the selected backend. The SDK rejects a
|
|
123
|
+
cancelled invocation immediately even if its trusted host callback is still
|
|
124
|
+
waiting. Source and input contracts are captured before dispatch; editing the
|
|
125
|
+
caller’s package during execution cannot change output validation.
|
|
126
|
+
|
|
127
|
+
In a saved project, the host checks edit access and finds a completed review for
|
|
128
|
+
this exact package and connection. A current backend compatibility check runs
|
|
129
|
+
without resubmitting fixtures. A successful import review can be reused for
|
|
130
|
+
project execution after its import-confirmation expiry; changed source,
|
|
131
|
+
connection revision, backend schema, or security status invalidates that reuse.
|
|
132
|
+
The host asks for **Run in project** before submitting the actual project input.
|
|
133
|
+
If review is required, **Run tests and sample** and its preview come first, then
|
|
134
|
+
a separate **Run in project** action. Custom interfaces cannot skip these actions.
|
|
135
|
+
Durable production jobs are associated with the saved project. Local demo and
|
|
136
|
+
Marketplace previews remain samples and cannot claim project access.
|
|
137
|
+
|
|
138
|
+
Offline `validate` and `pack` check and package source. For ComfyUI, `pack` returns
|
|
139
|
+
`reviewRequired: true` and zero executed tests. `test` and `preview` return
|
|
140
|
+
`RUNTIME_UNAVAILABLE` without a trusted host executor. A host integration may
|
|
141
|
+
pass `options.comfyui(package, input, {signal})` to `runPackageAsync` or
|
|
142
|
+
`testPackage`, returning `{outputs, metadata}` where every metadata entry has
|
|
143
|
+
verified width, height, bytes, `mimeType: "image/png"`, `frames: 1`, and optionally
|
|
144
|
+
SHA-256. This callback is trusted host code; it is never loaded from a package.
|
|
145
|
+
|
|
146
|
+
The server supports reviewed ComfyUI packages inside Project Types through the
|
|
147
|
+
account-bound envelope below. The import wizard opens each included ComfyUI Block
|
|
148
|
+
in its connection review panel. Unattended ComfyUI automation remains unavailable.
|
|
149
|
+
Existing recipe/JavaScript Project Types and exact-output fixture checks are unchanged.
|
|
150
|
+
|
|
151
|
+
### ComfyUI packages in Project Types: host integration
|
|
152
|
+
|
|
153
|
+
The offline CLI can package ComfyUI-only or mixed hosted/local Project Types:
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
node packages/block-cli/cli.js validate ./workflow.json
|
|
157
|
+
node packages/block-cli/cli.js pack ./workflow.json ./workflow.stillmade.json
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
This performs static/schema checks on every embedded package and preserves exact
|
|
161
|
+
source. It never runs a provider, connects to ComfyUI, or executes local fixtures.
|
|
162
|
+
The result explicitly reports `tests: 0`, `reviewRequired: true`,
|
|
163
|
+
`liveVerified: false`, and `workflowComplete: false`. Import the result into
|
|
164
|
+
StillMade for authenticated backend review, local tests, sample execution, and
|
|
165
|
+
user confirmation. Unsupported ComfyUI nodes still fail the static package scan.
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
The authenticated review/import/release/install APIs accept `typeComfyuiReviews`
|
|
169
|
+
alongside `typeCapabilityReviews`. It is request metadata, never portable source:
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"typeComfyuiReviews": {
|
|
174
|
+
"<exact package SHA-256>": {
|
|
175
|
+
"receiptId": "<account review UUID>",
|
|
176
|
+
"connectionId": "<account connection UUID>",
|
|
177
|
+
"connectionRevision": 1
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Provide exactly one entry for every embedded ComfyUI package, including unused
|
|
184
|
+
or disabled packages. The server authenticates every fixture and sample against
|
|
185
|
+
the selected backend contract, then checks the ledger again at the save boundary.
|
|
186
|
+
Missing, expired, foreign, cancelled, or changed-connection evidence is rejected.
|
|
187
|
+
Saved imports, release reports, and installation reports retain the fixture and
|
|
188
|
+
sample media. Another account must provide its own reviews. No prompt is
|
|
189
|
+
submitted by receipt verification.
|
|
190
|
+
|
|
191
|
+
A trusted SDK host can supply `verifyComfyPackage` in the third argument to
|
|
192
|
+
`verifyHostedProjectTypePackages(type, verifyCapabilityPackage, options)`.
|
|
193
|
+
The callback must return the server-verified Block report, including `receiptId`,
|
|
194
|
+
`connectionId`, and `connectionRevision`. The resulting opaque handle supports
|
|
195
|
+
`testProjectType` and `previewProjectType`; JSON claims cannot substitute for it.
|
|
196
|
+
Offline rehearsal defers reviewed ComfyUI execution and its dependent outputs.
|
|
197
|
+
Interactive rehearsal requires `verifyHostedResult` before downstream execution;
|
|
198
|
+
retained run metadata uses `comfyuiRun`. A passing package admission report still
|
|
199
|
+
does not prove that the complete connected workflow ran.
|
|
200
|
+
|
|
201
|
+
In the import or builder review, choose **Review Block** beside each ComfyUI
|
|
202
|
+
package, select your connection, and run its tests/sample (or reuse a fresh
|
|
203
|
+
matching review). Finish the package checks, inspect the result, and confirm
|
|
204
|
+
import. Connected workflow preview separately confirms each ComfyUI execution
|
|
205
|
+
and refetches its exact run evidence before handing images downstream. These
|
|
206
|
+
interactive controls do not enable unattended remote execution.
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
### Connected ComfyUI execution in a project
|
|
210
|
+
|
|
211
|
+
**Run connected steps** can continue through ComfyUI Blocks when you approve each
|
|
212
|
+
run on your account connection. It reuses the existing reviewed-connection dialog;
|
|
213
|
+
missing fixtures require a separate review before the project input runs. Image
|
|
214
|
+
references reach the broker intact, so the server can check project access and
|
|
215
|
+
bind the exact input. Local image processors decode accepted images as needed.
|
|
216
|
+
|
|
217
|
+
The host uses `planSegment(..., {interactive: true})` and supplies an authenticated
|
|
218
|
+
`verifyHostedResult` callback to `runSegment`. ComfyUI results retain `comfyuiRun`
|
|
219
|
+
and `mediaReceipts`; hosted model results retain `capabilityRun`. These callbacks
|
|
220
|
+
are trusted StillMade integration code, never imported Block code. A resumed run
|
|
221
|
+
or **Use results** re-fetches and verifies each remote result against the current
|
|
222
|
+
project, source, inputs, and connection metadata before accepting it. Waiting for
|
|
223
|
+
consent or a remote backend does not consume the local computation budget.
|
|
224
|
+
|
|
225
|
+
Cancellation or failed verification stops downstream work and retains earlier
|
|
226
|
+
completed results for review. The default non-interactive planner still stops at
|
|
227
|
+
ComfyUI or hosted model Blocks; future-media automation cannot submit those jobs.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Blocks, Steps, and Project Types
|
|
2
|
+
|
|
3
|
+
## Block
|
|
4
|
+
A reusable production workspace or capability. The built-in catalog consists of full screens: Script Writer, Voiceover, Shots, Blueprint, Canvas, Editor, Image Panels, White Board Motion, and Assets. Chat is not a Block: it is the project's own conversation, which every Project Type starts with. Internal canvas nodes and individual editor controls are implementation details inside their workspace, not separate built-in Blocks.
|
|
5
|
+
|
|
6
|
+
External processing Blocks, such as Thicken Line Art or lip sync, add a capability to the workflow. A Block declares input and output ports, permissions, controls, and an implementation runtime.
|
|
7
|
+
|
|
8
|
+
## Step
|
|
9
|
+
An instance of a Block inside a Project Type. Each Step has its own instance ID, pinned Block ID and version, configuration, enabled state, and optional condition. Reusing a Block in two positions creates two independent Steps.
|
|
10
|
+
|
|
11
|
+
## Project Type
|
|
12
|
+
An ordered production workflow. Its persisted `stages` array stores Steps for compatibility with existing projects. Users can add, remove, duplicate, configure, disable, or reorder Steps. The protected starting chat belongs to the host and cannot be replaced or remixed.
|
|
13
|
+
|
|
14
|
+
## One job per Step
|
|
15
|
+
A Step is one job: the work between two moments where a person or the outside world must see the result. A guided job, one the person fills in and then gets a result from, is one Step with one Block whose own screen holds everything: the inputs and settings, then a cheap check before the expensive run (the script and a voice sample before the video), then the result. On a wide screen the inputs sit on the left and the result's place on the right; on a phone they stack, the result's place under the button. A cheap check or a review the person does on that screen never starts a new Step. Start a new Step only at one of these points; everything else is a part of the neighboring Step.
|
|
16
|
+
|
|
17
|
+
1. **A person works with the result**: in a workspace they spend a while in (the Editor, a storyboard, a Canvas, a CAD or drawing tool), or someone else approves or takes it over (a hand-off). Turning what a workspace made into something else is the next Step: a CAD tool is its own Step, and the Block that takes pictures of its model and makes a video is the next one. So Bible, Canvas and Editor are separate Steps after Chat.
|
|
18
|
+
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.
|
|
19
|
+
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.
|
|
20
|
+
4. **Setup or a wait**: a one-time setup that is not part of each job (a brand kit, capturing a voice or a likeness), or a render that takes minutes and is delivered later.
|
|
21
|
+
|
|
22
|
+
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 Type whose own Block renders the finished video (`timeline.render`) needs no Editor Step; the Editor (1.0, captions and export built in) is a Step only when the person edits the cut by hand, and Export video is never a Step beside it.
|
|
23
|
+
|
|
24
|
+
A part that only runs in the desktop app cannot share a Step with cloud parts. Before adding a Step, name which of these 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.
|
|
25
|
+
|
|
26
|
+
Build one Block for a job one Block can do: a module Block calls every hosted operation the job needs (it transcribes a sermon, then finds the verses said in it), a JavaScript Block does several local transforms, a workspace owns its whole document. A Block being built never takes an ingredient's result only so the ingredient can be its own part or Step (Transcribe in front of a verse finder): it calls that operation itself. Parts in one Step (`groups` in the Project Type) are for jobs made of Blocks that already exist and app tasks, each keeping its own permission, approval and credit rules. Never invent a combined runtime.
|
|
27
|
+
|
|
28
|
+
Examples: "a listing video from my photos and the home's facts" is one Step: one Block whose page takes the photos and facts, shows the script and a voice sample to check, then makes the video. "every new email with an image becomes a generated image" is two Steps, "Gmail · New emails with images" (When, fetch with an image filter, only new) and "Image from email" (AI write, Generate image); listing When, Fetch, Only new, AI decide, Continue only if, AI write and Generate image as seven Steps splits one job into its parts. "A new Meta lead goes to HubSpot" is three Steps: "Meta Ads · New leads", "Qualify lead" and "HubSpot · Add contact".
|
|
29
|
+
|
|
30
|
+
## Typed connections
|
|
31
|
+
An image-producing Block can connect to an image-consuming Block. Primary ports make insertion predictable; semantic roles distinguish a source image from a character reference. Secondary inputs can bind to project context.
|
|
32
|
+
|
|
33
|
+
See [types and compatibility](../reference/types.md), [context](context.md), and [Project Type construction](../project-types/build.md).
|
|
34
|
+
|
|
35
|
+
## Complete workspace Blocks
|
|
36
|
+
Built-in Blocks are the existing complete production screens. A Guided Project Type starts with Chat, the project's conversation, then Voiceover → Shots → Blueprint → Canvas → Editor; export belongs to Editor. The reusable Script Writer is the full Narrative Compiler; it and the legacy Script adapter do not replace Chat. Canvas remains the home of persistent visual references and character consistency.
|
|
37
|
+
|
|
38
|
+
The Block boundary follows the complete user-placeable Step. Package and remix the complete workspace, including its related tools. For example, Motion Graphics remains inside the Editor; Image Panels, Blueprint, and the Whiteboard Step are each one Block. The White Board Motion Project Type starts with Chat, then three complete Blocks: Voiceover, Whiteboard, and Editor, with no extra Project-Type Block. Historical component IDs may remain resolvable for saved projects without becoming discoverable Blocks.
|
|
39
|
+
|
|
40
|
+
A source snapshot or host alias alone is not portable. A portable workspace owns its interface and executes through an installable SDK runtime. The first-party sm.blueprint@2.0.0, sm.board-editor@2.0.0, sm.editor@2.0.0, and sm.pipeline@2.0.0 packages in the downloadable SDK demonstrate complete sandboxed workspaces using typed documents and the public before/after workspace proposal contract. Whiteboard retains all boards, placed media, timing, transitions, motion settings, and custom fields as one remixable Block. Editor retains Motion Graphics and every other editing tool inside the Editor Block. Canvas retains its native content and layout while the Project Type builder owns Step placement and wiring. Package-supplied React bundles are not exposed; use [custom sandboxed HTML interfaces](custom-interface.md).
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Read project context
|
|
2
|
+
|
|
3
|
+
A Step can bind an input to an explicit project context field:
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
{
|
|
7
|
+
"inputs": {
|
|
8
|
+
"shots": {"type":"shot[]", "context":"shots"}
|
|
9
|
+
},
|
|
10
|
+
"permissions": {"project":["context.shots.read"]}
|
|
11
|
+
}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Supported fields and exact types:
|
|
15
|
+
|
|
16
|
+
| Context field | Input type | Contents |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| `script` | `script` | `{schemaVersion:1,text}`; selected-shot narration for a narrow selection |
|
|
19
|
+
| `scenes` | `scene[]` | Existing scene IDs, descriptions, and scoped `shotIds` |
|
|
20
|
+
| `shots` | `shot[]` | Existing shot/panel IDs, scene ownership, descriptions, dialogue and timing |
|
|
21
|
+
| `characters` | `character[]` | Canvas-selected visual references with blueprint descriptions |
|
|
22
|
+
| `locations` | `location[]` | Canvas-selected location references with blueprint descriptions |
|
|
23
|
+
| `styles` | `style[]` | Saved Canvas, blueprint, panel and board styles and references |
|
|
24
|
+
| `assets` | `asset[]` | Current media with `assetId`, `versionId`, `kind`, `url`, source and explicit ownership |
|
|
25
|
+
| `generations` | `metadata[]` | Retained generated-media records with `asset`, `active`, `status`, and saved generation metadata |
|
|
26
|
+
| `versions` | `metadata[]` | Retained media versions and project-level shot-plan/timeline version metadata |
|
|
27
|
+
| `timeline` | `timeline` | Current editor document; filtered collections in a scene/shot/asset selection |
|
|
28
|
+
| `metadata` | `metadata` | Project ID/name and host-selected `scope` |
|
|
29
|
+
|
|
30
|
+
Every binding requires its own `context.<field>.read` permission. These are exact
|
|
31
|
+
permissions: `context.assets.read` does not authorize `context.versions.read`.
|
|
32
|
+
The Step workspace, preview, and future-media worker derive this index from the
|
|
33
|
+
project's current source documents. No duplicate production state is saved.
|
|
34
|
+
|
|
35
|
+
Canvas remains authoritative for its existing asset IDs, approved/current version,
|
|
36
|
+
and selected character/location/style reference galleries. Legacy reference
|
|
37
|
+
images remain available without reselecting deliberately deselected images.
|
|
38
|
+
Panels and White Board Motion supply their existing scenes, panels, collage
|
|
39
|
+
media, transitions and voiceover. The editor supplies media-bin items, clips,
|
|
40
|
+
audio, saved score takes and retained timeline media. An editor item explicitly
|
|
41
|
+
linked by Canvas node/version or panel ID reuses that source identity; a stale
|
|
42
|
+
editor copy cannot promote a different Canvas version. URL-only panel histories
|
|
43
|
+
use deterministic version identifiers that survive history trimming. Different
|
|
44
|
+
assets sharing a URL remain distinct. Legacy global `assets`/`library` caches are
|
|
45
|
+
excluded because they can contain other projects' data.
|
|
46
|
+
|
|
47
|
+
Media history entries contain `{schemaVersion:1, id, assetId, versionId, asset,
|
|
48
|
+
source, active}` and only saved metadata such as timestamp, model or duration.
|
|
49
|
+
Generation entries additionally have `status:"completed"`. Missing model/provider
|
|
50
|
+
metadata is omitted, never guessed from a model currently selected in a control.
|
|
51
|
+
Document history entries contain `documentType`, `versionId`, `active` and a saved
|
|
52
|
+
label/name; they have no `asset`. These metadata entries do not contain old script
|
|
53
|
+
bodies. A URL is a reference, not permission for guest code to fetch it.
|
|
54
|
+
|
|
55
|
+
The host narrows context to the Step's selected scene, shots, or assets before
|
|
56
|
+
binding inputs. Only explicit scene/shot ownership and source associations count;
|
|
57
|
+
unowned media is excluded from narrow selections. Scene documents contain only
|
|
58
|
+
selected `shotIds`, script contains only selected narration, and a narrow timeline
|
|
59
|
+
omits unrelated collections, transcript and timeline histories. Unrelated
|
|
60
|
+
character/location references are excluded. `metadata.scope` describes the
|
|
61
|
+
selection. Guest inputs cannot widen it. Project-wide execution receives the
|
|
62
|
+
project-wide snapshot only for the exact requested fields.
|
|
63
|
+
|
|
64
|
+
`resolveContextInputs(manifest, explicitInputs, projectSnapshot)` copies only
|
|
65
|
+
requested fields into input bindings. Context bindings take precedence over manual
|
|
66
|
+
values. Guests have no live project handle, write-through access, credentials or
|
|
67
|
+
ambient filesystem/network access. Fixture inputs must include concrete context
|
|
68
|
+
values; offline execution does not invent a project. Context delivery is implemented
|
|
69
|
+
in the Step workspace, preview and automatic-processing worker, not the advanced
|
|
70
|
+
Canvas block runner.
|
|
71
|
+
|
|
72
|
+
For example, a history-aware Block can declare:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"inputs": {"history": {"type": "metadata[]", "context": "versions"}},
|
|
77
|
+
"permissions": {"project": ["context.versions.read"]}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Its code reads `input.history` and checks for `record.asset` when processing media
|
|
82
|
+
records. It must not assume every version describes a file.
|
|
83
|
+
|
|
84
|
+
## Complete shot-plan context
|
|
85
|
+
Use `{ "type": "shot-plan", "context": "shotPlan", "required": false }`
|
|
86
|
+
with `permissions.project: ["context.shotPlan.read"]` to receive the complete
|
|
87
|
+
saved shot-plan document. This preserves scene grouping, narration, timing and
|
|
88
|
+
other saved planning fields instead of rebuilding a document from flattened
|
|
89
|
+
`shots`. Array-based saved plans are normalized to `{schemaVersion: 1, shots: [...]}`;
|
|
90
|
+
object plans retain their fields with `schemaVersion: 1`.
|
|
91
|
+
|
|
92
|
+
This binding is available only for whole-project context. It is omitted for
|
|
93
|
+
scene, shot and asset selections, and when no plan exists. The host copies the
|
|
94
|
+
value; editing it does not save changes. Use the existing scoped `shots` binding
|
|
95
|
+
for selected-shot processing. Media URLs inside documents grant no media-read
|
|
96
|
+
permission; downloading still requires selected typed asset references and
|
|
97
|
+
`asset.read`. Exporters can also read the saved score from `timeline.audioScore`
|
|
98
|
+
under their existing `context.timeline.read` grant.
|
|
99
|
+
|
|
100
|
+
## Standalone timeline export
|
|
101
|
+
[Download Export timeline 2.0.0](https://stillmade.shop/block-sdk/examples/export-timeline.stillmade-block).
|
|
102
|
+
This independently versioned JavaScript Block owns serialization and uses generated
|
|
103
|
+
SDK controls plus the shared Download result UI. Add it to a project with a timeline,
|
|
104
|
+
choose XML or XML + media, run it, then download. Its timeline, media, Blueprint,
|
|
105
|
+
shot-plan and project-name inputs bind automatically to authorized project context.
|
|
106
|
+
|
|
107
|
+
The canonical archive includes source, typed ports, UI schema, permissions,
|
|
108
|
+
MIT notices, original-source evidence, lineage and three executable fixtures.
|
|
109
|
+
Validate, test and remix it with the public CLI. No dependencies require manual
|
|
110
|
+
installation. The exact package is also available through the first-party catalog.
|
|
111
|
+
|
|
112
|
+
XML retains media links. ZIP bundles selected timeline media and fails if a
|
|
113
|
+
requested transfer is unavailable. Auxiliary project documents are retained as
|
|
114
|
+
metadata; their unrelated external media is not a full project backup. Device-local
|
|
115
|
+
media and bundled sounds depend on supported host transfers. Normal sandbox and
|
|
116
|
+
download limits apply. This is the existing StillMade XML serializer; compatibility
|
|
117
|
+
with every external editing application has not been established.
|
|
118
|
+
|
|
119
|
+
## Timed captions and caption styling
|
|
120
|
+
[Download Captions 2.0.0](https://stillmade.shop/block-sdk/examples/captions.stillmade-block). This
|
|
121
|
+
standalone, remixable Block converts a transcript into editable timeline captions.
|
|
122
|
+
It owns phrase grouping, word timing and caption appearance, runs in the JavaScript
|
|
123
|
+
sandbox, and returns ordinary `timeline-edit` proposals for review and Apply.
|
|
124
|
+
It does not transcribe audio or spend execution credits.
|
|
125
|
+
|
|
126
|
+
The optional context binding `{ "type": "transcript", "context": "transcript",
|
|
127
|
+
"required": false }` requires `context.transcript.read`. At whole-project scope
|
|
128
|
+
it supplies a copied `{schemaVersion:1, words:[{text,start,end}], text, audioUrl?}`
|
|
129
|
+
from the saved voiceover when word timings exist. It is omitted when absent and
|
|
130
|
+
for scene, shot or asset selections. URL metadata grants no media access.
|
|
131
|
+
Explicitly connected transcript inputs remain separate from this fallback.
|
|
132
|
+
|
|
133
|
+
Captions uses a connected transcript first, then entered text, then the project's
|
|
134
|
+
saved transcript. Text without word timings uses estimated timing, identified in
|
|
135
|
+
the proposal title. Start offsets word times into the timeline. Duration zero
|
|
136
|
+
keeps transcript timing; a positive duration clips the result to that interval.
|
|
137
|
+
A proposal supports at most 100 lines and rejects longer results without silently
|
|
138
|
+
truncating them. Existing captions stay intact and locked tracks reject Apply.
|
|
139
|
+
|
|
140
|
+
`caption.add` retains its required `{id,trackId,text,start,end}` values and also
|
|
141
|
+
accepts these optional fields. Unknown fields and values outside these limits
|
|
142
|
+
are rejected by the same SDK validator and host apply path:
|
|
143
|
+
|
|
144
|
+
| Field | Accepted values |
|
|
145
|
+
| --- | --- |
|
|
146
|
+
| `words` | Up to 1,000 `{text,start,end}` entries, ordered by start, contained in the caption interval; nonempty text up to 5,000 characters, end at or after start |
|
|
147
|
+
| `font` | `Hanken Grotesk` |
|
|
148
|
+
| `size` | 8–200 |
|
|
149
|
+
| `color`, `highlightColor` | Three- or six-digit hex color |
|
|
150
|
+
| `background` | `none` or three- or six-digit hex color |
|
|
151
|
+
| `backgroundOpacity`, `backgroundPadding`, `backgroundRadius` | 0–100 |
|
|
152
|
+
| `position` | `top`, `middle`, or `bottom` followed by `left`, `center`, or `right`, separated by one space |
|
|
153
|
+
| `animation` | `none` or `fade` |
|
|
154
|
+
|
|
155
|
+
The host fills omitted appearance values with its existing defaults, preserves
|
|
156
|
+
provided styling and clones word timings before saving through ordinary edit
|
|
157
|
+
history. Caption updates retain their existing `{text,start,end}` contract.
|
|
158
|
+
Package source, MIT notices, lineage and three fixtures are retained in the
|
|
159
|
+
canonical archive; validate, test and remix it using the public CLI.
|