stillmade-sdk 0.1.42 → 0.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.stillmade/sdk-baseline.json +6 -8
- package/AGENTS.md +15 -10
- package/FRAME_VIEWS.md +113 -0
- package/INTERFACE_DESIGN.md +62 -22
- package/MOBILE_UI.md +4 -2
- package/MODULES.md +152 -6
- package/PASTE_TO_LLM.md +35 -25
- package/README.md +3 -2
- package/SDK.md +994 -550
- package/UI_AESTHETIC.md +22 -2
- 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 +4 -1
- package/examples/generate-video.stillmade.json +6 -2
- package/examples/research-topic.stillmade.json +5 -1
- package/examples/text-workflow.stillmade.json +3 -32
- package/examples/timeline-polish.stillmade.json +11 -3
- package/examples/transcribe-audio.stillmade.json +11 -3
- package/package.json +1 -1
- package/packages/block-cli/cli.js +13 -6
- package/packages/block-cli/dev-host/assets/host.js +76 -38
- package/packages/block-cli/dev-host/assets/index.css +1 -1
- package/packages/block-cli/format.js +1 -1
- package/packages/block-cli/templates.js +31 -13
- package/packages/block-cli/type-packages.js +119 -0
- package/packages/block-platform/block-readiness.js +5 -0
- 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/block-tier.js +1 -1
- package/packages/block-sdk/builder-contract.js +10 -8
- package/packages/block-sdk/capabilities.js +1 -1
- package/packages/block-sdk/contracts.js +6 -2
- 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/index.d.ts +2 -1
- package/packages/block-sdk/media-analysis-example.js +1 -1
- package/packages/block-sdk/mock-host.js +7 -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/timeline-proposal-example.js +1 -1
- package/packages/block-sdk/transcription-example.js +1 -1
- 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 +17 -14
- package/packages/block-sdk/web-example.js +1 -1
- package/packages/design-system/block-kit.css +48 -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
|
@@ -1,22 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import shortFormFinishV101 from '../../blocks/short-form-finish/versions/1.0.1/package.js';
|
|
3
|
-
import shortFormFinishV102 from '../../blocks/short-form-finish/versions/1.0.2/package.js';
|
|
4
|
-
import shortFormFinish from '../../blocks/short-form-finish/package.js';
|
|
5
|
-
import screenRecorderV100 from '../../blocks/screen-recorder/versions/1.0.0/package.js';
|
|
6
|
-
import screenRecorder from '../../blocks/screen-recorder/package.js';
|
|
7
|
-
import narrationV100 from '../../blocks/narration/versions/1.0.0/package.js';
|
|
8
|
-
import narration from '../../blocks/narration/package.js';
|
|
9
|
-
import occasionStoryV100 from '../../blocks/occasion-story/versions/1.0.0/package.js';
|
|
10
|
-
import releaseVisualsV100 from '../../blocks/release-visuals/versions/1.0.0/package.js';
|
|
11
|
-
import occasionStoryV101 from '../../blocks/occasion-story/versions/1.0.1/package.js';
|
|
12
|
-
import releaseVisualsV101 from '../../blocks/release-visuals/versions/1.0.1/package.js';
|
|
13
|
-
import occasionStory from '../../blocks/occasion-story/package.js';
|
|
14
|
-
import releaseVisuals from '../../blocks/release-visuals/package.js';
|
|
1
|
+
import generate from '../../blocks/generate/package.js';
|
|
15
2
|
import importMedia from '../../blocks/native/sm.import-media/versions/2.0.0/package.js';
|
|
16
|
-
import photoReelComposerV100 from '../../blocks/photo-reel-composer/versions/1.0.0/package.js';
|
|
17
|
-
import photoReelComposerV101 from '../../blocks/photo-reel-composer/versions/1.0.1/package.js';
|
|
18
|
-
import photoReelComposer from '../../blocks/photo-reel-composer/versions/1.0.2/package.js';
|
|
19
|
-
import productAdVariants from '../../blocks/product-ad-variants/versions/1.0.0/package.js';
|
|
20
3
|
import importMediaV201 from '../../blocks/native/sm.import-media/versions/2.0.1/package.js';
|
|
21
4
|
import importMediaV202 from '../../blocks/native/sm.import-media/versions/2.0.2/package.js';
|
|
22
5
|
import editorV229 from '../../blocks/native/sm.editor/versions/2.2.9/package.js';
|
|
@@ -34,9 +17,6 @@ import gradeV202 from '../../blocks/native/sm.grade/versions/2.0.2/package.js';
|
|
|
34
17
|
import compare from '../../blocks/native/sm.compare/versions/2.0.0/package.js';
|
|
35
18
|
import compareV201 from '../../blocks/native/sm.compare/versions/2.0.1/package.js';
|
|
36
19
|
import compareV202 from '../../blocks/native/sm.compare/versions/2.0.2/package.js';
|
|
37
|
-
import qualityAuditV102 from '../../blocks/native/sm.quality-audit/versions/1.0.2/package.js';
|
|
38
|
-
import stockSearch from '../../blocks/native/sm.stock-search/versions/2.0.0/package.js';
|
|
39
|
-
import youtubePublication from '../../blocks/native/sm.youtube/versions/2.0.0/package.js';
|
|
40
20
|
import exportVideo from '../../blocks/native/sm.export-video/versions/2.0.0/package.js';
|
|
41
21
|
import exportVideoV210 from '../../blocks/native/sm.export-video/versions/2.1.0/package.js';
|
|
42
22
|
import exportAudio from '../../blocks/native/sm.export-audio/versions/2.0.0/package.js';
|
|
@@ -44,14 +24,10 @@ import motionGraphics from '../../blocks/native/sm.motion-graphics/versions/2.0.
|
|
|
44
24
|
import audioScore from '../../blocks/native/sm.score/versions/2.0.0/package.js';
|
|
45
25
|
import generateImage from '../../blocks/native/sm.generate-image/versions/2.0.0/package.js';
|
|
46
26
|
import generateImageV210 from '../../blocks/native/sm.generate-image/versions/2.1.0/package.js';
|
|
47
|
-
import thumbnail from '../../blocks/native/sm.thumbnail/versions/2.0.0/package.js';
|
|
48
|
-
import thumbnailV201 from '../../blocks/native/sm.thumbnail/versions/2.0.1/package.js';
|
|
49
27
|
import writeSummary from '../../blocks/native/sm.write-summary/versions/1.0.0/package.js';
|
|
50
28
|
import automationWhen from '../../blocks/native/sm.when/versions/1.0.0/package.js';
|
|
51
29
|
import automationV110 from '../../blocks/native/sm.when/versions/1.1.0/package.js';
|
|
52
|
-
import automationNewItems from '../../blocks/native/sm.new-items/versions/1.0.0/package.js';
|
|
53
30
|
import automationAiDecide from '../../blocks/native/sm.ai-decide/versions/1.0.0/package.js';
|
|
54
|
-
import automationContinueIf from '../../blocks/native/sm.continue-if/versions/1.0.0/package.js';
|
|
55
31
|
import connectApp from '../../blocks/native/sm.connect-app/versions/1.0.0/package.js';
|
|
56
32
|
import automationAiWrite from '../../blocks/native/sm.ai-write/versions/1.0.0/package.js';
|
|
57
33
|
import automationMetaCreative from '../../blocks/native/sm.meta-creative/versions/1.0.0/package.js';
|
|
@@ -64,35 +40,16 @@ import voiceoverV213 from '../../blocks/native/sm.voiceover/versions/2.1.3/packa
|
|
|
64
40
|
import voiceoverV214 from '../../blocks/native/sm.voiceover/versions/2.1.4/package.js';
|
|
65
41
|
import voiceoverV215 from '../../blocks/native/sm.voiceover/versions/2.1.5/package.js';
|
|
66
42
|
import voiceoverV216 from '../../blocks/native/sm.voiceover/versions/2.1.6/package.js';
|
|
67
|
-
import script from '../../blocks/native/sm.script/versions/2.0.0/package.js';
|
|
68
|
-
import scriptV210 from '../../blocks/native/sm.script/versions/2.1.0/package.js';
|
|
69
|
-
import scriptV211 from '../../blocks/native/sm.script/versions/2.1.1/package.js';
|
|
70
|
-
import scriptV212 from '../../blocks/native/sm.script/versions/2.1.2/package.js';
|
|
71
|
-
import scriptV213 from '../../blocks/native/sm.script/versions/2.1.3/package.js';
|
|
72
|
-
import scriptV214 from '../../blocks/native/sm.script/versions/2.1.4/package.js';
|
|
73
|
-
import scriptV215 from '../../blocks/native/sm.script/versions/2.1.5/package.js';
|
|
74
43
|
import generateVideo from '../../blocks/native/sm.generate-video/versions/2.0.0/package.js';
|
|
75
44
|
import generateVideoV201 from '../../blocks/native/sm.generate-video/versions/2.0.1/package.js';
|
|
76
|
-
import chat from '../../blocks/native/sm.chat/versions/2.0.0/package.js';
|
|
77
|
-
import chatV201 from '../../blocks/native/sm.chat/versions/2.0.1/package.js';
|
|
78
|
-
import chatV202 from '../../blocks/native/sm.chat/versions/2.0.2/package.js';
|
|
79
|
-
import chatV203 from '../../blocks/native/sm.chat/versions/2.0.3/package.js';
|
|
80
45
|
import character from '../../blocks/native/sm.character/versions/2.0.0/package.js';
|
|
81
46
|
import characterV201 from '../../blocks/native/sm.character/versions/2.0.1/package.js';
|
|
82
47
|
import location from '../../blocks/native/sm.location/versions/2.0.0/package.js';
|
|
83
48
|
import locationV201 from '../../blocks/native/sm.location/versions/2.0.1/package.js';
|
|
84
49
|
import style from '../../blocks/native/sm.style/versions/2.0.0/package.js';
|
|
85
50
|
import styleV201 from '../../blocks/native/sm.style/versions/2.0.1/package.js';
|
|
86
|
-
import research from '../../blocks/native/sm.research/versions/2.0.0/package.js';
|
|
87
|
-
import researchV201 from '../../blocks/native/sm.research/versions/2.0.1/package.js';
|
|
88
|
-
import researchV202 from '../../blocks/native/sm.research/versions/2.0.2/package.js';
|
|
89
|
-
import imageEditor from '../../blocks/native/sm.image-editor/versions/2.0.0/package.js';
|
|
90
|
-
import imageEditorV201 from '../../blocks/native/sm.image-editor/versions/2.0.1/package.js';
|
|
91
|
-
import describeMedia from '../../blocks/native/sm.describe-media/versions/2.0.0/package.js';
|
|
92
|
-
import describeMediaV201 from '../../blocks/native/sm.describe-media/versions/2.0.1/package.js';
|
|
93
51
|
// October 29, 2026: StillMade credits stopped paying for image.describe on September 13, so Describe media 2.1.0
|
|
94
52
|
// and Photo notes 1.1.0 run on media.analyze (credits, per image); the image.describe releases stay for exact pins.
|
|
95
|
-
import describeMediaV210 from '../../blocks/native/sm.describe-media/versions/2.1.0/package.js';
|
|
96
53
|
import videoAssets from '../../blocks/native/sm.video-assets/versions/2.0.0/package.js';
|
|
97
54
|
import videoAssetsV210 from '../../blocks/native/sm.video-assets/versions/2.1.0/package.js';
|
|
98
55
|
import videoAssetsV211 from '../../blocks/native/sm.video-assets/versions/2.1.1/package.js';
|
|
@@ -108,31 +65,9 @@ import finalEditV202 from '../../blocks/native/sm.final-edit/versions/2.0.2/pack
|
|
|
108
65
|
import editAssistant from '../../blocks/native/sm.edit-assistant/versions/2.0.0/package.js';
|
|
109
66
|
import editAssistantV201 from '../../blocks/native/sm.edit-assistant/versions/2.0.1/package.js';
|
|
110
67
|
import editAssistantV202 from '../../blocks/native/sm.edit-assistant/versions/2.0.2/package.js';
|
|
111
|
-
import transcribe from '../../blocks/native/sm.transcribe/versions/2.0.0/package.js';
|
|
112
|
-
import transcribeV201 from '../../blocks/native/sm.transcribe/versions/2.0.1/package.js';
|
|
113
|
-
import blueprint from '../../blocks/native/sm.blueprint/versions/2.0.0/package.js';
|
|
114
|
-
import blueprintV210 from '../../blocks/native/sm.blueprint/versions/2.1.0/package.js';
|
|
115
|
-
import blueprintV211 from '../../blocks/native/sm.blueprint/versions/2.1.1/package.js';
|
|
116
|
-
import blueprintV212 from '../../blocks/native/sm.blueprint/versions/2.1.2/package.js';
|
|
117
|
-
import blueprintV213 from '../../blocks/native/sm.blueprint/versions/2.1.3/package.js';
|
|
118
|
-
import blueprintV214 from '../../blocks/native/sm.blueprint/versions/2.1.4/package.js';
|
|
119
|
-
import blueprintV215 from '../../blocks/native/sm.blueprint/versions/2.1.5/package.js';
|
|
120
|
-
import blueprintV216 from '../../blocks/native/sm.blueprint/versions/2.1.6/package.js';
|
|
121
|
-
import blueprintV218 from '../../blocks/native/sm.blueprint/versions/2.1.8/package.js';
|
|
122
|
-
import blueprintV219 from '../../blocks/native/sm.blueprint/versions/2.1.9/package.js';
|
|
123
|
-
import blueprintV217 from '../../blocks/native/sm.blueprint/versions/2.1.7/package.js';
|
|
124
|
-
import shotPlan from '../../blocks/native/sm.shot-plan/versions/2.0.0/package.js';
|
|
125
|
-
import shotPlanV210 from '../../blocks/native/sm.shot-plan/versions/2.1.0/package.js';
|
|
126
|
-
import shotPlanV211 from '../../blocks/native/sm.shot-plan/versions/2.1.1/package.js';
|
|
127
|
-
import shotPlanV212 from '../../blocks/native/sm.shot-plan/versions/2.1.2/package.js';
|
|
128
|
-
import shotPlanV213 from '../../blocks/native/sm.shot-plan/versions/2.1.3/package.js';
|
|
129
|
-
import shotPlanV220 from '../../blocks/native/sm.shot-plan/versions/2.2.0/package.js';
|
|
130
|
-
import shotPlanV221 from '../../blocks/native/sm.shot-plan/versions/2.2.1/package.js';
|
|
131
68
|
import boardEditor from '../../blocks/native/sm.board-editor/versions/2.0.0/package.js';
|
|
132
69
|
import panelStripV200 from '../../blocks/native/sm.panel-strip/versions/2.0.0/package.js';
|
|
133
70
|
import panelStrip from '../../blocks/native/sm.panel-strip/versions/2.1.0/package.js';
|
|
134
|
-
import animatedSceneV200 from '../../blocks/native/sm.animated-scene/versions/2.0.0/package.js';
|
|
135
|
-
import animatedScene from '../../blocks/native/sm.animated-scene/versions/2.1.0/package.js';
|
|
136
71
|
import editor from '../../blocks/native/sm.editor/versions/2.0.0/package.js';
|
|
137
72
|
import pipelineV200 from '../../blocks/native/sm.pipeline/versions/2.0.0/package.js';
|
|
138
73
|
import pipeline from '../../blocks/native/sm.pipeline/versions/2.1.0/package.js';
|
|
@@ -143,11 +78,6 @@ import pipelineV225 from '../../blocks/native/sm.pipeline/versions/2.2.5/package
|
|
|
143
78
|
import pipelineV226 from '../../blocks/native/sm.pipeline/versions/2.2.6/package.js';
|
|
144
79
|
import pipelineV224 from '../../blocks/native/sm.pipeline/versions/2.2.4/package.js';
|
|
145
80
|
import pipelineV222 from '../../blocks/native/sm.pipeline/versions/2.2.2/package.js';
|
|
146
|
-
import shotPlanAssistant from '../../blocks/native/sm.shot-plan-assistant/versions/1.0.0/package.js';
|
|
147
|
-
import animatedSceneAssistant from '../../blocks/native/sm.animated-scene-assistant/versions/1.0.0/package.js';
|
|
148
|
-
import whiteboardAssistant from '../../blocks/native/sm.whiteboard-assistant/versions/1.0.0/package.js';
|
|
149
|
-
import qualityAudit from '../../blocks/native/sm.quality-audit/versions/1.0.0/package.js';
|
|
150
|
-
import qualityAuditV101 from '../../blocks/native/sm.quality-audit/versions/1.0.1/package.js';
|
|
151
81
|
import editorV210 from '../../blocks/native/sm.editor/versions/2.1.0/package.js';
|
|
152
82
|
import editorV220 from '../../blocks/native/sm.editor/versions/2.2.0/package.js';
|
|
153
83
|
import editorV221 from '../../blocks/native/sm.editor/versions/2.2.1/package.js';
|
|
@@ -183,24 +113,12 @@ import boardEditorV228 from '../../blocks/native/sm.board-editor/versions/2.2.8/
|
|
|
183
113
|
import boardEditorV229 from '../../blocks/native/sm.board-editor/versions/2.2.9/package.js';
|
|
184
114
|
import boardEditorV2210 from '../../blocks/native/sm.board-editor/versions/2.2.10/package.js';
|
|
185
115
|
import boardEditorV2211 from '../../blocks/native/sm.board-editor/versions/2.2.11/package.js';
|
|
186
|
-
|
|
187
|
-
import animatedSceneV230 from '../../blocks/native/sm.animated-scene/versions/2.3.0/package.js';
|
|
188
|
-
import animatedSceneV231 from '../../blocks/native/sm.animated-scene/versions/2.3.1/package.js';
|
|
189
|
-
import animatedSceneV232 from '../../blocks/native/sm.animated-scene/versions/2.3.2/package.js';
|
|
190
|
-
import animatedSceneV233 from '../../blocks/native/sm.animated-scene/versions/2.3.3/package.js';
|
|
191
|
-
import animatedSceneV234 from '../../blocks/native/sm.animated-scene/versions/2.3.4/package.js';
|
|
192
|
-
import animatedSceneV235 from '../../blocks/native/sm.animated-scene/versions/2.3.5/package.js';
|
|
193
|
-
import animatedSceneV236 from '../../blocks/native/sm.animated-scene/versions/2.3.6/package.js';
|
|
194
|
-
import animatedSceneV237 from '../../blocks/native/sm.animated-scene/versions/2.3.7/package.js';
|
|
195
|
-
import animatedSceneV238 from '../../blocks/native/sm.animated-scene/versions/2.3.8/package.js';
|
|
196
|
-
import animatedSceneV239 from '../../blocks/native/sm.animated-scene/versions/2.3.9/package.js';
|
|
197
|
-
import blueprintAssistant from '../../blocks/native/sm.blueprint-assistant/versions/1.0.0/package.js';
|
|
116
|
+
|
|
198
117
|
import photoNotes from '../../blocks/native/sm.photo-notes/versions/1.0.0/package.js';
|
|
199
118
|
import photoNotesV110 from '../../blocks/native/sm.photo-notes/versions/1.1.0/package.js';
|
|
200
|
-
import pickPhotos from '../../blocks/native/sm.pick-photos/versions/1.0.0/package.js';
|
|
201
119
|
|
|
202
120
|
// Exact, independently executable first-party releases. Host workspaces do not
|
|
203
121
|
// belong here. Changing implementation requires a new immutable version.
|
|
204
122
|
const freeze=value=>{if(value&&typeof value==='object'&&!Object.isFrozen(value)){Object.values(value).forEach(freeze);Object.freeze(value);}return value;};
|
|
205
|
-
export const FIRST_PARTY_SDK_PACKAGES = Object.freeze([freeze(
|
|
123
|
+
export const FIRST_PARTY_SDK_PACKAGES = Object.freeze([freeze(generate),freeze(photoNotesV110),freeze(photoNotes),freeze(exportVideoV210),freeze(exportVideo),freeze(exportAudio),freeze(motionGraphics),freeze(audioScore),freeze(importMediaV202),freeze(importMediaV201),freeze(editorV2212),freeze(editorV2211),freeze(editorV2210),freeze(editorV229),freeze(editorV228),freeze(panelStripV242),freeze(panelStripV241),freeze(panelStripV240),freeze(panelStripV237),freeze(panelStripV236),freeze(boardEditorV2211),freeze(boardEditorV2210),freeze(boardEditorV229),freeze(pipelineV226),freeze(pipelineV225),freeze(pipelineV224),freeze(videoAssetsV214),freeze(videoAssetsV213),freeze(voiceoverV216),freeze(voiceoverV215),freeze(voiceoverV214),freeze(voiceoverV213),freeze(roughCutV202),freeze(roughCutV201),freeze(finalEditV202),freeze(finalEditV201),freeze(editAssistantV202),freeze(editAssistantV201),freeze(gradeV202),freeze(gradeV201),freeze(transitionV202),freeze(transitionV201),freeze(compareV202),freeze(compareV201),freeze(compare),freeze(grade),freeze(transition),freeze(exportTimeline),freeze(captions),freeze(importMedia),freeze(generateImageV210),freeze(generateImage),freeze(writeSummary),freeze(automationV110),freeze(automationWhen),freeze(automationAiDecide),freeze(connectApp),freeze(automationContactFields),freeze(automationAiWrite),freeze(automationMetaCreative),freeze(voiceover),freeze(voiceoverV210),freeze(voiceoverV211),freeze(voiceoverV212),freeze(generateVideoV201),freeze(generateVideo),freeze(characterV201),freeze(character),freeze(locationV201),freeze(location),freeze(styleV201),freeze(style),freeze(videoAssets),freeze(videoAssetsV210),freeze(videoAssetsV211),freeze(videoAssetsV212),freeze(roughCut),freeze(finalEdit),freeze(editAssistant),freeze(boardEditor),freeze(boardEditorV210),freeze(boardEditorV220),freeze(boardEditorV221),freeze(boardEditorV222),freeze(boardEditorV223),freeze(boardEditorV224),freeze(boardEditorV225),freeze(boardEditorV226),freeze(boardEditorV227),freeze(boardEditorV228),freeze(panelStripV200),freeze(panelStrip),freeze(panelStripV220),freeze(panelStripV230),freeze(panelStripV231),freeze(panelStripV232),freeze(panelStripV233),freeze(panelStripV234),freeze(panelStripV235),freeze(editor),freeze(editorV210),freeze(editorV220),freeze(editorV221),freeze(editorV222),freeze(editorV223),freeze(editorV224),freeze(editorV225),freeze(editorV226),freeze(editorV227),freeze(pipelineV200),freeze(pipeline),freeze(pipelineV220),freeze(pipelineV221),freeze(pipelineV223),freeze(pipelineV222) ]);
|
|
206
124
|
export const firstPartySdkPackage = manifest => FIRST_PARTY_SDK_PACKAGES.find(pkg => pkg.manifest.id === manifest?.id && pkg.manifest.version === manifest?.version);
|
|
@@ -64,10 +64,22 @@ export function imageSettings(value,{strict=false}={}){
|
|
|
64
64
|
return {model,aspectRatio:axis('aspectRatio',entry.aspectRatios,entry.aspectRatios.includes('1:1')?'1:1':undefined),resolution:axis('resolution',entry.resolutions),quality:axis('quality',entry.qualities,entry.qualities.includes('medium')?'medium':undefined)};
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
// November 3, 2026: a listing Block asked for a 9:16 clip and named no model, and the default (Vidu Q3 Turbo) takes no
|
|
68
|
+
// aspect ratio. With no model named, a shape the default cannot make picks the cheapest model here that makes it and
|
|
69
|
+
// takes the frames and the duration asked (prices in server/services/tiers.js); a named model is always kept.
|
|
70
|
+
export const VIDEO_SHAPE_MODELS=Object.freeze(['wan-2.6-flash','veo-3.1-lite','seedance-2.0-mini','kling-v3-turbo','seedance-2.0-fast','seedance-2.0']);
|
|
71
|
+
function defaultVideoModel(raw,{firstFrame,lastFrame}){
|
|
72
|
+
const shape=raw.aspectRatio;
|
|
73
|
+
if(shape===undefined||shape===DEFAULT_SETTING||shape==='auto'||VIDEO_GENERATION_MODELS[DEFAULT_VIDEO_MODEL].aspectRatios.includes(shape))return DEFAULT_VIDEO_MODEL;
|
|
74
|
+
const fits=entry=>entry.aspectRatios.includes(shape)&&(firstFrame||!entry.requiresFirstFrame)&&(!lastFrame||entry.lastFrame)&&(raw.duration===undefined||entry.durations.includes(raw.duration));
|
|
75
|
+
return VIDEO_SHAPE_MODELS.find(model=>fits(VIDEO_GENERATION_MODELS[model]))??DEFAULT_VIDEO_MODEL;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Fill and check video settings, including Veo's 1080p-is-8-seconds rule. With no model named, the default model is
|
|
79
|
+
* the one that makes the asked aspect ratio (VIDEO_SHAPE_MODELS). */
|
|
80
|
+
export function videoSettings(value,{strict=false,firstFrame=false,lastFrame=false}={}){
|
|
69
81
|
const raw=settingsObject(value,VIDEO_SETTING_KEYS,'Video');
|
|
70
|
-
const model=raw.model??
|
|
82
|
+
const model=raw.model??defaultVideoModel(raw,{firstFrame,lastFrame}),entry=VIDEO_GENERATION_MODELS[model];
|
|
71
83
|
assert(entry,'CAPABILITY_SETTINGS',`Choose a video model from: ${Object.keys(VIDEO_GENERATION_MODELS).join(', ')}`);
|
|
72
84
|
const axis=(name,allowed,fallback)=>{
|
|
73
85
|
const chosen=pick(allowed,raw[name],fallback);
|
|
@@ -278,7 +278,8 @@ export const GENERATION_LIMITS: Readonly<{references:8;negativePrompt:2000;seed:
|
|
|
278
278
|
/** Fill and check image settings; `strict` rejects values the model does not accept. */
|
|
279
279
|
export function imageSettings(value?:Partial<ImageSettings>,options?:{strict?:boolean}):ImageSettings;
|
|
280
280
|
/** Fill and check video settings, including Veo's 1080p-is-8-seconds rule. */
|
|
281
|
-
|
|
281
|
+
/** With no model named, the default is the cheapest model that makes the asked aspect ratio and takes the frames given. */
|
|
282
|
+
export function videoSettings(value?:Partial<VideoSettings>,options?:{strict?:boolean;firstFrame?:boolean;lastFrame?:boolean}):VideoSettings;
|
|
282
283
|
export function validateSeed(seed:number):number;
|
|
283
284
|
export const MEDIA_GENERATE_LIMITS: Readonly<{items:50;prompt:4000}>;
|
|
284
285
|
export const MEDIA_GENERATE_OPERATIONS: readonly ['image','video','speech','music','sfx'];
|
|
@@ -4,7 +4,7 @@ import {EXAMPLE_PROVENANCE} from './example-license.js';
|
|
|
4
4
|
export const mediaAnalysis={
|
|
5
5
|
manifest:{schemaVersion:1,sdkVersion:'0.1.0',id:'example.check-clip',action:{label:'Check clip',running:'Checking clip…'},version:'1.0.0',name:'Check a clip',description:'Answer a production question about a saved video clip, with timestamps.',kind:'task',runtime:'capability',entry:'src/capability.json',license:'MIT',provenance:EXAMPLE_PROVENANCE,
|
|
6
6
|
inputs:{clip:{type:'video',primary:true,semantic:'source_video',required:true,description:'Saved video to check.'},start:{type:'number',required:false,min:0,semantic:'range_start',description:'Optional start of the range to look at closely, in seconds.'},end:{type:'number',required:false,min:0,semantic:'range_end',description:'Optional end of the range, in seconds (at most 12 seconds after the start).'}},
|
|
7
|
-
outputs:{report:{type:'json',primary:true,semantic:'media_findings',description:'Summary, timeline, on-screen text and issues found.'}},
|
|
7
|
+
outputs:{report:{type:'json',primary:true,semantic:'media_findings',description:'Summary, timeline, on-screen text and issues found.',schema:{items:'json[]'}}},
|
|
8
8
|
permissions:{project:[],capabilities:['media.analyze'],network:[],filesystem:[],secrets:[]},ui:[{control:'asset',port:'clip'},{control:'number',port:'start'},{control:'number',port:'end'}]},
|
|
9
9
|
capability:{schemaVersion:1,operation:'media.analyze',media:{$input:'clip'},question:'Is the product logo clearly visible, and when? List any on-screen text and visible defects.',range:{start:{$input:'start'},end:{$input:'end'}},output:'report'},
|
|
10
10
|
tests:[{name:'A saved clip',input:{clip:{kind:'video',assetId:'clip-1',versionId:'v1',url:'/api/media/owner/clip.mp4'}},expectations:{report:{kind:'json',includes:['summary']}}}],
|
|
@@ -13,6 +13,7 @@ import {createMemoryStorage,storageKey} from './cloud-storage.js';
|
|
|
13
13
|
import {mediaTransformRequest,decodeWav} from './media-transform.js';
|
|
14
14
|
import {FILE_FORMATS} from './data-values.js';
|
|
15
15
|
import {mockPng,mockWav,mockMp4,MOCK_IMAGE_SIZE,MOCK_VIDEO_SIZE} from './mock-media.js';
|
|
16
|
+
import {videoSettings,audioSettings} from './generation-catalog.js';
|
|
16
17
|
// The words of a simple PDF whose pages are uncompressed text, such as the example lesson.pdf, page by page; null for
|
|
17
18
|
// anything else. StillMade reads real PDFs on the person's device; a local test of another PDF mocks document.text
|
|
18
19
|
// (November 1, 2026: the stand-in read a PDF's own code as its words).
|
|
@@ -201,7 +202,12 @@ export function createMockHost({mocks:given={},readLocalFile,manifest,pickedMedi
|
|
|
201
202
|
const operation=action?.operation;
|
|
202
203
|
if(recorded('actions',operation)){note('actions.run',operation,'mocks');return pick(mocks.actions[operation],count(`action:${operation}`));}
|
|
203
204
|
note('actions.run',operation,'recorded');
|
|
204
|
-
|
|
205
|
+
// As in StillMade: a video, music or sound effect carries the length it asked for; speech carries none (decode it).
|
|
206
|
+
if(operation==='media.generate')return {value:action.request.items.map(item=>{
|
|
207
|
+
const seconds=item.operation==='video'?videoSettings(item.settings,{firstFrame:item.firstFrame!==undefined,lastFrame:item.lastFrame!==undefined}).duration:['music','sfx'].includes(item.operation)?audioSettings(item.operation,item.settings).durationSec:undefined;
|
|
208
|
+
const made=item.operation==='image'||item.operation==='video'?reference[item.operation]():reference.audio(seconds?{seconds,sampleRate:8000}:undefined);
|
|
209
|
+
return {key:item.key,kind:made.kind,assetId:made.assetId,versionId:made.versionId,url:made.url,...(Number.isFinite(seconds)?{duration:seconds}:{})};
|
|
210
|
+
}),failures:[]};
|
|
205
211
|
if(operation==='stock.search')return {results:[]};
|
|
206
212
|
fail(`There is no recorded stand-in for the ${operation} action. Add one under actions["${operation}"] in ${MOCKS_FILE}.`);
|
|
207
213
|
},
|
|
@@ -4,20 +4,45 @@
|
|
|
4
4
|
import {networkDeclarations,networkRequest,connectionDeclarations,connectionCall} from './network.js';
|
|
5
5
|
import {storageHostHandlers} from './cloud-storage.js';
|
|
6
6
|
import {projectReadSnapshot} from './context.js';
|
|
7
|
+
import {mediaReferences,moduleMediaAccess,MEDIA_RESULT_OPERATIONS} from './module-media-access.js';
|
|
7
8
|
|
|
8
|
-
/**
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* {api: args => Promise} for one run of `pkg` against `host` (see createNodeModuleExecutor). `input` is the run's input:
|
|
11
|
+
* files, transforms, actions, hosted calls and asset changes use only files the run received or the host made in it,
|
|
12
|
+
* the rule StillMade's own host applies (module-media-access.js).
|
|
13
|
+
*/
|
|
14
|
+
export function moduleHostCalls(pkg,host,storage,input){
|
|
15
|
+
const access=moduleMediaAccess(input);
|
|
16
|
+
const made=async pending=>access.remember(await pending);
|
|
10
17
|
return {
|
|
11
|
-
'files.read':args=>host.readFile?host.readFile(args.ref):Promise.reject(Object.assign(new Error('files.read needs a host file reader in local runs.'),{code:'MODULE_HOST_UNAVAILABLE'})),
|
|
12
|
-
'files.write':args=>host.writeFile?host.writeFile(args.buffer,args.options):Promise.reject(Object.assign(new Error('files.write saves to the StillMade library; pass a host writer in local runs.'),{code:'MODULE_HOST_UNAVAILABLE'})),
|
|
13
|
-
'media.transform':args=>host.transformMedia?host.transformMedia(args.request):Promise.reject(Object.assign(new Error('Media transforms run in StillMade; pass a host transformMedia in local runs.'),{code:'MODULE_HOST_UNAVAILABLE'})),
|
|
14
|
-
'actions.run':args=>
|
|
15
|
-
|
|
18
|
+
'files.read':async args=>{access.checkFile(args.ref,'files.read reads');return host.readFile?host.readFile(args.ref):Promise.reject(Object.assign(new Error('files.read needs a host file reader in local runs.'),{code:'MODULE_HOST_UNAVAILABLE'}));},
|
|
19
|
+
'files.write':args=>host.writeFile?made(host.writeFile(args.buffer,args.options)):Promise.reject(Object.assign(new Error('files.write saves to the StillMade library; pass a host writer in local runs.'),{code:'MODULE_HOST_UNAVAILABLE'})),
|
|
20
|
+
'media.transform':async args=>{access.check(args.request,'Media transforms');return host.transformMedia?made(host.transformMedia(args.request)):Promise.reject(Object.assign(new Error('Media transforms run in StillMade; pass a host transformMedia in local runs.'),{code:'MODULE_HOST_UNAVAILABLE'}));},
|
|
21
|
+
'actions.run':async args=>{
|
|
22
|
+
access.check(args.action,'Actions');
|
|
23
|
+
if(!host.runAction)throw Object.assign(new Error('Actions run in StillMade.'),{code:'MODULE_HOST_UNAVAILABLE'});
|
|
24
|
+
const result=await host.runAction(args.action);
|
|
25
|
+
if(args.action?.operation==='media.generate')for(const ref of mediaReferences(result?.value))access.remember(ref);
|
|
26
|
+
return result;
|
|
27
|
+
},
|
|
28
|
+
'hosted.run':async args=>{
|
|
29
|
+
access.check(args.request,'Hosted operations');
|
|
30
|
+
if(!host.runHosted)throw Object.assign(new Error('Hosted operations run in StillMade.'),{code:'MODULE_HOST_UNAVAILABLE'});
|
|
31
|
+
const result=await host.runHosted(args.operation,args.request);
|
|
32
|
+
return MEDIA_RESULT_OPERATIONS.includes(args.operation)?access.remember(result):result;
|
|
33
|
+
},
|
|
16
34
|
'connections.call':async args=>{const request=connectionCall(args.request,connectionDeclarations(pkg.manifest.permissions?.connections));return host.callConnection?host.callConnection(request):Promise.reject(Object.assign(new Error('Connections run through StillMade, which adds your account; pass a host callConnection in local runs.'),{code:'MODULE_HOST_UNAVAILABLE'}));},
|
|
17
35
|
...storageHostHandlers(storage),
|
|
18
|
-
|
|
19
|
-
'
|
|
20
|
-
|
|
36
|
+
// Only the host-built media indexes make media usable, as in StillMade: free-form documents can hold media-shaped values.
|
|
37
|
+
'project.read':async args=>{
|
|
38
|
+
if(!host.project)throw Object.assign(new Error('project.read needs a project snapshot; pass host.project in local runs.'),{code:'MODULE_HOST_UNAVAILABLE'});
|
|
39
|
+
const snapshot=projectReadSnapshot(pkg.manifest,host.project,args.fields);
|
|
40
|
+
for(const field of ['assets','files'])for(const ref of mediaReferences(snapshot[field]))access.add(ref);
|
|
41
|
+
for(const shot of Array.isArray(snapshot.shots)?snapshot.shots:[])if(shot?.selectedImage)access.remember(shot.selectedImage);
|
|
42
|
+
return snapshot;
|
|
43
|
+
},
|
|
44
|
+
'assets.create':async args=>{if(!(pkg.manifest.permissions?.project||[]).includes('asset.create'))throw Object.assign(new Error('Declare asset.create to add project assets.'),{code:'MODULE_PERMISSION'});access.checkFile(args.file,'assets.create adds');return host.createAsset?made(host.createAsset(args.file,args.options||{})):Promise.reject(Object.assign(new Error('Project assets are saved in StillMade; pass a host createAsset in local runs.'),{code:'MODULE_HOST_UNAVAILABLE'}));},
|
|
45
|
+
'assets.appendVersion':async args=>{if(!(pkg.manifest.permissions?.project||[]).includes('asset.version.append'))throw Object.assign(new Error('Declare asset.version.append to add asset versions.'),{code:'MODULE_PERMISSION'});access.checkFile(args.file,'assets.appendVersion adds');return host.appendAssetVersion?made(host.appendAssetVersion(args.asset,args.file)):Promise.reject(Object.assign(new Error('Project assets are saved in StillMade; pass a host appendAssetVersion in local runs.'),{code:'MODULE_HOST_UNAVAILABLE'}));},
|
|
21
46
|
'net.fetch':async args=>{const request=networkRequest(args.request,networkDeclarations(pkg.manifest.permissions?.network));return host.netFetch?host.netFetch(request):Promise.reject(Object.assign(new Error('Network calls run through StillMade, which adds your key; pass a host netFetch in local runs.'),{code:'MODULE_HOST_UNAVAILABLE'}));},
|
|
22
47
|
};
|
|
23
48
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// operation in `permissions.capabilities`.
|
|
6
6
|
import {assert,plain,stableStringify} from './contracts.js';
|
|
7
7
|
import {defaultCapabilityExpectations,MEDIA_ANALYZE_LIMITS} from './capabilities.js';
|
|
8
|
-
import {GENERATION_LIMITS,IMAGE_GENERATION_MODELS} from './generation-catalog.js';
|
|
8
|
+
import {GENERATION_LIMITS,IMAGE_GENERATION_MODELS,VIDEO_GENERATION_MODELS} from './generation-catalog.js';
|
|
9
9
|
|
|
10
10
|
const text=(value,max)=>typeof value==='string'&&value.trim().length>0&&value.length<=max;
|
|
11
11
|
const media=(value,kind)=>plain(value)&&value.kind===kind&&['assetId','versionId','url'].every(key=>typeof value[key]==='string'&&value[key].trim());
|
|
@@ -32,7 +32,20 @@ const SHAPES={
|
|
|
32
32
|
},
|
|
33
33
|
'video.generate':request=>{
|
|
34
34
|
if(!text(request.prompt,32000))fail('video.generate needs a prompt');
|
|
35
|
-
|
|
35
|
+
// firstFrame and lastFrame: saved images the video starts and ends on, bound as a capability Block binds them; and the
|
|
36
|
+
// negativePrompt (November 3, 2026: they were dropped, so a listing video's camera move over each photo was made from
|
|
37
|
+
// the words alone, and the stand-in host passed it).
|
|
38
|
+
const {firstFrame,lastFrame,negativePrompt}=request;
|
|
39
|
+
for(const [name,frame] of [['firstFrame',firstFrame],['lastFrame',lastFrame]])if(frame!==undefined&&!media(frame,'image'))fail(`video.generate ${name} is one saved image`);
|
|
40
|
+
if(lastFrame!==undefined&&firstFrame===undefined)fail('video.generate lastFrame needs a firstFrame');
|
|
41
|
+
if(negativePrompt!==undefined&&!(typeof negativePrompt==='string'&&negativePrompt.length<=GENERATION_LIMITS.negativePrompt))fail(`video.generate negativePrompt is text of at most ${GENERATION_LIMITS.negativePrompt.toLocaleString('en-US')} characters`);
|
|
42
|
+
// A model named in settings must take those frames (every model takes a first frame; Kling 3.0 Turbo and Wan 2.6 Flash
|
|
43
|
+
// take no last frame; Wan 2.6 Flash and Wan 2.7 need a first frame).
|
|
44
|
+
const model=VIDEO_GENERATION_MODELS[request.settings?.model];
|
|
45
|
+
if(model&&firstFrame&&!model.firstFrame)fail(`${model.label} takes no first frame: choose a model that does, or leave the model to the person`);
|
|
46
|
+
if(model&&lastFrame&&!model.lastFrame)fail(`${model.label} takes no last frame: choose a model that does, or leave the model to the person`);
|
|
47
|
+
if(model?.requiresFirstFrame&&!firstFrame)fail(`${model.label} needs a firstFrame`);
|
|
48
|
+
return {inputs:{prompt:port('text','Video prompt'),...(firstFrame?{firstFrame:port('image','First frame')}:{}),...(lastFrame?{lastFrame:port('image','Last frame')}:{})},outputs:{result:port('video','Generated video')},capability:{prompt:{$input:'prompt'},output:'result',...(firstFrame?{firstFrame:{$input:'firstFrame'}}:{}),...(lastFrame?{lastFrame:{$input:'lastFrame'}}:{}),...(request.settings?{settings:request.settings}:{}),...(negativePrompt?{negativePrompt}:{})},input:{prompt:request.prompt,...(firstFrame?{firstFrame}:{}),...(lastFrame?{lastFrame}:{})}};
|
|
36
49
|
},
|
|
37
50
|
'audio.speech':request=>{
|
|
38
51
|
if(!text(request.text,3800))fail('audio.speech needs text of up to 3,800 characters');
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Which saved files a module Block may use in one run: the references it
|
|
2
|
+
// received as input, and those the host made during the run (files it wrote,
|
|
3
|
+
// transform results, generated media, project media it read). files.read,
|
|
4
|
+
// transforms, actions, hosted calls and project asset changes use only these.
|
|
5
|
+
// StillMade's browser host (client/src/blocks/moduleRuntimeHost.js) and the
|
|
6
|
+
// SDK's local runners (module-host-calls.js: `test --mock`, `ready`, `gate`,
|
|
7
|
+
// and the QuickJS runner for Blocks built in StillMade) apply this one rule, so
|
|
8
|
+
// a Block gets the same verdict on a creator's machine and in the import review.
|
|
9
|
+
import {stableStringify} from './contracts.js';
|
|
10
|
+
|
|
11
|
+
const fail=(message,code)=>Object.assign(new Error(message),{code});
|
|
12
|
+
export const MODULE_MEDIA_KINDS=Object.freeze(['image','video','audio','asset','file']);
|
|
13
|
+
// Hosted operations whose result is media the host generated and checked.
|
|
14
|
+
export const MEDIA_RESULT_OPERATIONS=Object.freeze(['image.generate','video.generate','audio.speech','audio.music','audio.sfx']);
|
|
15
|
+
// A reference names its file by these fields. Its other fields describe the
|
|
16
|
+
// file (a media.generate item's key, a duration, a name) and may be dropped or
|
|
17
|
+
// added (November 3, 2026: a listing video Block rebuilt each generated clip as
|
|
18
|
+
// {kind, assetId, versionId, url}, without the result item's `key`, and every
|
|
19
|
+
// render was refused although the clips were generated in that run).
|
|
20
|
+
export const MEDIA_REFERENCE_FIELDS=Object.freeze(['kind','assetId','versionId','url']);
|
|
21
|
+
const isReference=value=>MODULE_MEDIA_KINDS.includes(value.kind)&&(typeof value.url==='string'||typeof value.assetId==='string');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Saved references in a value: anything shaped like media (a media kind with a
|
|
25
|
+
* url or assetId), at any depth. With `strict`, a value too large to inspect is
|
|
26
|
+
* refused. With `within`, the other fields of a reference are searched too, so
|
|
27
|
+
* a reference cannot carry another file past the check.
|
|
28
|
+
*/
|
|
29
|
+
export function mediaReferences(input,{strict=false,within=false}={}){
|
|
30
|
+
const found=[];let visited=0;
|
|
31
|
+
const visit=(value,depth)=>{
|
|
32
|
+
if(!value||typeof value!=='object'||value instanceof ArrayBuffer||ArrayBuffer.isView(value))return;
|
|
33
|
+
if(++visited>20000||depth>16){if(strict)throw fail('This request is too large or too deeply nested to check.','MODULE_HOST');return;}
|
|
34
|
+
if(Array.isArray(value)){for(const item of value)visit(item,depth+1);return;}
|
|
35
|
+
if(isReference(value)){
|
|
36
|
+
found.push(value);
|
|
37
|
+
if(within)for(const [key,item] of Object.entries(value))if(!MEDIA_REFERENCE_FIELDS.includes(key))visit(item,depth+1);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
for(const item of Object.values(value))visit(item,depth+1);
|
|
41
|
+
};
|
|
42
|
+
visit(input,0);return found;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The file a reference names, as a comparable string. */
|
|
46
|
+
export function mediaReferenceKey(ref){
|
|
47
|
+
return stableStringify(MEDIA_REFERENCE_FIELDS.map(key=>typeof ref?.[key]==='string'?ref[key]:null));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const RULE='this Block received, wrote or generated in this run';
|
|
51
|
+
const FIX='Pass the reference the Block received as input, or the one StillMade returned in this run (files.write, a transform, hosted.run or actions.run media.generate), keeping its kind, assetId, versionId and url.';
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The run's usable files, starting from its input. `remember` adds a value the
|
|
55
|
+
* host made when the value is itself a reference (a text, JSON or web result
|
|
56
|
+
* can contain media-shaped values chosen by a model or a web page, so only
|
|
57
|
+
* references the host returned count); `add` adds a reference the host
|
|
58
|
+
* vouches for (project media it read). The checks throw MODULE_FILE_READ.
|
|
59
|
+
*/
|
|
60
|
+
export function moduleMediaAccess(input){
|
|
61
|
+
const usable=new Set(mediaReferences(input).map(mediaReferenceKey));
|
|
62
|
+
const allowed=ref=>!!ref&&typeof ref==='object'&&usable.has(mediaReferenceKey(ref));
|
|
63
|
+
return {
|
|
64
|
+
allowed,
|
|
65
|
+
add(ref){usable.add(mediaReferenceKey(ref));},
|
|
66
|
+
remember(value){if(value&&typeof value==='object'&&mediaReferences(value)[0]===value)usable.add(mediaReferenceKey(value));return value;},
|
|
67
|
+
// Every reference in a request, and inside its references, must be usable.
|
|
68
|
+
check(value,what){if(!mediaReferences(value,{strict:true,within:true}).every(allowed))throw fail(`${what} use only files ${RULE}. ${FIX}`,'MODULE_FILE_READ');},
|
|
69
|
+
checkFile(ref,call){if(!allowed(ref))throw fail(`${call} only files ${RULE}. ${FIX}`,'MODULE_FILE_READ');},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -43,7 +43,7 @@ export function createNodeModuleExecutor({files,host={},onProgress,onLog,now=()=
|
|
|
43
43
|
try{declared=networkDeclarations(pkg.manifest.permissions?.network);}catch{/* no valid origins */}
|
|
44
44
|
const sockets=createModuleSockets({declarations:declared,open:host.netConnect,post:(message,transfer)=>worker.postMessage(message,transfer)});
|
|
45
45
|
// The shared host calls (files, media, hosted operations, connections, storage, project, assets, net.fetch) plus live connections.
|
|
46
|
-
const handlers={...sockets.handlers,...moduleHostCalls(pkg,host,storage)};
|
|
46
|
+
const handlers={...sockets.handlers,...moduleHostCalls(pkg,host,storage,input)};
|
|
47
47
|
try{
|
|
48
48
|
return await new Promise((resolve,reject)=>{
|
|
49
49
|
const stop=error=>{clearInterval(timer);reject(error);};
|
|
@@ -37,7 +37,7 @@ export function mediaGenerateRequest(request){
|
|
|
37
37
|
if(item.references!==undefined)assert(Array.isArray(item.references)&&item.references.length>0&&item.references.length<=Math.min(GENERATION_LIMITS.references,IMAGE_GENERATION_MODELS[settings.model].references)&&item.references.every(asset),'PORTABLE_ACTION',`${IMAGE_GENERATION_MODELS[settings.model].label} accepts up to ${IMAGE_GENERATION_MODELS[settings.model].references} saved reference images.`);
|
|
38
38
|
}else{
|
|
39
39
|
assert(item.references===undefined,'PORTABLE_ACTION','References apply to image items; use firstFrame and lastFrame for video.');
|
|
40
|
-
const settings=videoSettings(item.settings,{strict:true,firstFrame:item.firstFrame!==undefined}),entry=VIDEO_GENERATION_MODELS[settings.model];
|
|
40
|
+
const settings=videoSettings(item.settings,{strict:true,firstFrame:item.firstFrame!==undefined,lastFrame:item.lastFrame!==undefined}),entry=VIDEO_GENERATION_MODELS[settings.model];
|
|
41
41
|
if(item.firstFrame!==undefined)assert(entry.firstFrame&&asset(item.firstFrame),'PORTABLE_ACTION',`${entry.label} needs a saved image as its first frame.`);
|
|
42
42
|
if(item.lastFrame!==undefined)assert(entry.lastFrame&&item.firstFrame!==undefined&&asset(item.lastFrame),'PORTABLE_ACTION',`${entry.label} cannot use this last frame.`);
|
|
43
43
|
}
|
|
@@ -58,7 +58,7 @@ export async function runPackageAsync(pkg, values, options = {}) {
|
|
|
58
58
|
// A module runs only through an injected executor: StillMade's sandboxed
|
|
59
59
|
// browser Worker, or the CLI's local Node worker for the creator's own tests.
|
|
60
60
|
const pinned=structuredClone(pkg),input=validateValues(pinned.manifest.inputs,values);
|
|
61
|
-
assert(typeof options.module==='function','RUNTIME_UNAVAILABLE','Module Blocks run in StillMade in the browser, or
|
|
61
|
+
assert(typeof options.module==='function','RUNTIME_UNAVAILABLE','Module Blocks run in StillMade in the browser, or on your own machine with the SDK CLI (test, preview and pack for a Block or a Project Type, and ready for a Block), which passes them a local module executor; code calling the SDK directly passes options.module (createNodeModuleExecutor in module-node.js). They cannot run unattended: StillMade has no server sandbox for module Blocks.');
|
|
62
62
|
const result=await executeHostCall(structuredClone(pinned),input,{signal:options.signal,execute:options.module});
|
|
63
63
|
assert(!options.signal?.aborted,'CANCELLED','Run cancelled');
|
|
64
64
|
assert(result&&typeof result==='object'&&Object.keys(result).every(key=>['outputs','logs'].includes(key)),'MODULE_RESULT','The module host returned an unexpected result');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {EXAMPLE_PROVENANCE} from './example-license.js';
|
|
2
2
|
|
|
3
3
|
export const timelinePolish={
|
|
4
|
-
manifest:{schemaVersion:1,sdkVersion:'0.1.0',id:'example.timeline-polish',action:{label:'Suggest edit',running:'Suggesting edit…'},version:'1.0.0',name:'Timeline polish',description:'Turn a timeline and editing direction into a bounded proposal that remains reviewable before Apply.',kind:'task',runtime:'capability',entry:'src/capability.json',license:'MIT',provenance:EXAMPLE_PROVENANCE,inputs:{timeline:{type:'timeline',context:'timeline',primary:true},direction:{type:'text',default:'Polish this cut conservatively.'}},outputs:{edit:{type:'timeline-edit',primary:true}},permissions:{project:['context.timeline.read','timeline.propose'],capabilities:['timeline.propose'],network:[],filesystem:[],secrets:[]},ui:[{control:'text',port:'direction'}]},
|
|
4
|
+
manifest:{schemaVersion:1,sdkVersion:'0.1.0',id:'example.timeline-polish',action:{label:'Suggest edit',running:'Suggesting edit…'},version:'1.0.0',name:'Timeline polish',description:'Turn a timeline and editing direction into a bounded proposal that remains reviewable before Apply.',kind:'task',runtime:'capability',entry:'src/capability.json',license:'MIT',provenance:EXAMPLE_PROVENANCE,inputs:{timeline:{type:'timeline',context:'timeline',primary:true,required:true,semantic:'edit_timeline',description:'The cut to improve.'},direction:{type:'text',default:'Polish this cut conservatively.',required:false,semantic:'edit_direction',description:'How to change the cut, in a sentence.'}},outputs:{edit:{type:'timeline-edit',primary:true,semantic:'timeline_edit',description:'The proposed changes to review before they apply.'}},permissions:{project:['context.timeline.read','timeline.propose'],capabilities:['timeline.propose'],network:[],filesystem:[],secrets:[]},ui:[{control:'text',port:'direction'}]},
|
|
5
5
|
capability:{schemaVersion:1,operation:'timeline.propose',context:{timeline:{$input:'timeline'},direction:{$input:'direction'}},instruction:'Use only supported timeline-edit commands, exact before snapshots, and the current activeTimelineId. Preserve media and locked items. Return strict JSON only.',maxTokens:2000,output:'edit'},
|
|
6
6
|
tests:[{name:'one restrained edit',input:{timeline:{schemaVersion:1,activeTimelineId:'timeline-1',tracks:[{id:'video'}],clips:[{id:'clip-1',trackId:'video',start:0,duration:4}],audioItems:[],captions:[]},direction:'Add a soft transition.'},expectations:{edit:{kind:'timeline-edit',minCommands:1,maxCommands:10}}}],
|
|
7
7
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {EXAMPLE_PROVENANCE} from './example-license.js';
|
|
2
2
|
|
|
3
3
|
export const audioTranscription={
|
|
4
|
-
manifest:{schemaVersion:1,sdkVersion:'0.1.0',id:'example.transcribe-audio',action:{label:'Transcribe audio',running:'Transcribing…'},version:'1.0.0',name:'Transcribe audio',description:'Turn one persistent audio file into reviewed text with word timings.',kind:'task',runtime:'capability',entry:'src/capability.json',license:'MIT',provenance:EXAMPLE_PROVENANCE,inputs:{audio:{type:'audio',primary:true},language:{type:'text',default:'auto'}},outputs:{transcript:{type:'transcript',primary:true}},permissions:{project:[],capabilities:['audio.transcribe'],network:[],filesystem:[],secrets:[]},ui:[{control:'asset',port:'audio'},{control:'select',port:'language',options:['auto','en','es','fr','de','it','pt','ja','ko','zh']}]},
|
|
4
|
+
manifest:{schemaVersion:1,sdkVersion:'0.1.0',id:'example.transcribe-audio',action:{label:'Transcribe audio',running:'Transcribing…'},version:'1.0.0',name:'Transcribe audio',description:'Turn one persistent audio file into reviewed text with word timings.',kind:'task',runtime:'capability',entry:'src/capability.json',license:'MIT',provenance:EXAMPLE_PROVENANCE,inputs:{audio:{type:'audio',primary:true,required:true,semantic:'source_audio',description:'The recording to turn into text.'},language:{type:'text',default:'auto',required:false,semantic:'language_code',description:'auto, or a two-letter language code such as en.'}},outputs:{transcript:{type:'transcript',primary:true,semantic:'timed_transcript',description:'The spoken words with their timings.'}},permissions:{project:[],capabilities:['audio.transcribe'],network:[],filesystem:[],secrets:[]},ui:[{control:'asset',port:'audio'},{control:'select',port:'language',options:['auto','en','es','fr','de','it','pt','ja','ko','zh']}]},
|
|
5
5
|
capability:{schemaVersion:1,operation:'audio.transcribe',audio:{$input:'audio'},language:{$input:'language'},output:'transcript'},
|
|
6
6
|
tests:[{name:'timed speech',input:{audio:{kind:'audio',assetId:'audio-1',versionId:'version-1',url:'/api/media/example/audio.mp3',mimeType:'audio/mpeg'},language:'en'},expectations:{transcript:{kind:'transcript',minWords:1,maxWords:1000}}}]
|
|
7
7
|
};
|
|
@@ -2,7 +2,7 @@ import {EXAMPLE_PROVENANCE} from './example-license.js';
|
|
|
2
2
|
// Declarative request; the host chooses provider, model, duration, payment and
|
|
3
3
|
// storage. This fixture is executed only after explicit host approval.
|
|
4
4
|
export const videoGenerate={
|
|
5
|
-
manifest:{schemaVersion:1,id:'example.generate-video',action:{label:'Generate video',running:'Generating video…'},name:'Generate video',version:'1.0.0',sdkVersion:'0.1.0',description:'Turn a production prompt into a short video using an approved host provider.',kind:'task',runtime:'capability',entry:'src/capability.json',license:'MIT',provenance:EXAMPLE_PROVENANCE,inputs:{prompt:{type:'text',primary:true,required:true}},outputs:{video:{type:'video',primary:true}},permissions:{project:[],capabilities:['video.generate'],network:[],filesystem:[],secrets:[]},ui:[{port:'prompt',control:'text'}]},
|
|
5
|
+
manifest:{schemaVersion:1,id:'example.generate-video',action:{label:'Generate video',running:'Generating video…'},name:'Generate video',version:'1.0.0',sdkVersion:'0.1.0',description:'Turn a production prompt into a short video using an approved host provider.',kind:'task',runtime:'capability',entry:'src/capability.json',license:'MIT',provenance:EXAMPLE_PROVENANCE,inputs:{prompt:{type:'text',primary:true,required:true,semantic:'video_prompt',description:'What the clip shows: subject, action, setting and camera, in a sentence or two.'}},outputs:{video:{type:'video',primary:true,semantic:'generated_video',description:'The generated clip.'}},permissions:{project:[],capabilities:['video.generate'],network:[],filesystem:[],secrets:[]},ui:[{port:'prompt',control:'text'}]},
|
|
6
6
|
capability:{schemaVersion:1,operation:'video.generate',prompt:{$input:'prompt'},output:'video'},
|
|
7
7
|
tests:[{name:'Produces a bounded MP4 sample',input:{prompt:'A paper boat floating across a calm blue pond. Gentle camera movement.'},expectations:{video:{kind:'video',format:'mp4',minDuration:1,maxDuration:60,minBytes:32,maxBytes:67108864,minWidth:1,maxWidth:3840,minHeight:1,maxHeight:3840}}}],
|
|
8
8
|
};
|
|
@@ -11,7 +11,10 @@ export const VIEW_BRIDGE=Object.freeze([
|
|
|
11
11
|
// Inputs and runs
|
|
12
12
|
{name:'input',group:'Inputs and runs',signature:'readonly input: Partial<In>',summary:'A copy of the current input values. Read it after `onInput` first fires.',where:all},
|
|
13
13
|
{name:'onInput',group:'Inputs and runs',signature:'onInput(callback: (input: Partial<In>) => void): () => void',summary:'Receives the input when the view starts and each time the host changes it. Returns a function that stops listening. Initialize controls here.',where:all},
|
|
14
|
-
{name:'
|
|
14
|
+
{name:'addFiles',group:'Inputs and runs',signature:'addFiles(port: string): Promise<{added: number}>',summary:'Opens StillMade\'s own file picker for a declared `image`, `video`, `audio`, `asset` or `file` input (or a list of them) and saves what the person chooses through StillMade\'s upload, as the Step\'s own tiles do. Call it from a click or key press in the view; a list gets the files added, a single input the first. The saved values arrive through `onInput`; the view never receives a File. A `<button class="sm-add" data-stillmade-add="port">` does this with no code. Refused for an undeclared or non-file input, an input an earlier Step fills, a viewer, and without a gesture.',where:`${saved} and the SDK preview`},
|
|
15
|
+
{name:'removeFile',group:'Inputs and runs',signature:'removeFile(port: string, index: number): Promise<{files: number}>',summary:'Removes the file at `index` (from 0) of a declared list input (`image[]`, `video[]`, `audio[]`, `asset[]` or `file[]`), as the remove button on the Step\'s own tile does, and resolves to how many files the list now holds. Call it from a click or key press in the view; the new list arrives through `onInput`. A `<button data-stillmade-remove="port" data-index="2">` does this with no code. Refused for an undeclared, non-file or single input, an input an earlier Step fills, a viewer, Chat, a file that changed since the view was given it, and without a gesture.',where:`${saved} and the SDK preview`},
|
|
16
|
+
{name:'moveFile',group:'Inputs and runs',signature:'moveFile(port: string, from: number, to: number): Promise<{files: number}>',summary:'Moves the file at `from` to the place `to` (both from 0) in a declared list input, as the Step\'s own move earlier and move later buttons do, so the person sets the order (a tour, a slideshow) on the Block\'s own screen. Same gesture and refusals as `removeFile`. A `<button data-stillmade-move="port" data-index="2" data-to="1">` does this with no code; a `data-to` past either end does nothing.',where:`${saved} and the SDK preview`},
|
|
17
|
+
{name:'run',group:'Inputs and runs',signature:'run(values: In): Promise<Out>',summary:'Checks the named input values, runs the Block (its recipe, JavaScript, module or hosted operation, after any approval the host asks for) and resolves to the checked outputs. On a project Step and in the SDK preview, inputs it leaves out run with the Step\'s current values (its photos, an earlier Step\'s result), so a view passes only what it sets; what it passes is kept as the Step\'s input. One run at a time, 30 a minute.',where:all},
|
|
15
18
|
{name:'useOutput',group:'Inputs and runs',signature:'useOutput(outputs: Partial<Out>): Promise<Record<string, unknown>>',summary:'Chooses media the view already holds (input media or a desktop recording) as the Block outputs without running. Only complete references the host issued are accepted.',where:saved},
|
|
16
19
|
{name:'schemaFields',group:'Inputs and runs',signature:'readonly schemaFields: Readonly<Record<string, unknown>>',summary:'Helpers that build form fields from the input ports and their schemas, honoring inputs the host locked.',where:all},
|
|
17
20
|
// Shared state
|