stillmade-sdk 0.1.42 → 0.1.44
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
|
@@ -19,16 +19,18 @@ export const BLOCK_KIT_CLASSES=Object.freeze({
|
|
|
19
19
|
'sm-actions':'The action row: one .sm-primary, optional .sm-quiet buttons and .sm-icon buttons (aria-label and title required).',
|
|
20
20
|
'sm-status':'Live state beside the action: data-state="loading|success|waiting|error" and a few words.',
|
|
21
21
|
'sm-more':'A <details> for secondary settings; starts closed.',
|
|
22
|
-
'sm-hint':'A <details>
|
|
22
|
+
'sm-hint':'A <details> (i) for an explanation that might help; its words show on hover or focus, or a tap on touch screens.',
|
|
23
23
|
'sm-gallery':'A grid of results or media. data-size="small" for input files: more tiles per row as the screen widens, never bigger tiles.',
|
|
24
24
|
'sm-media-off':'A picture or clip that cannot show here (on another device, or it did not open): a quiet tile in its own shape (--sm-photo-ratio, the tile\'s shape in a gallery) holding the image-off glyph, with the reason in aria-label and title and no words inside.',
|
|
25
|
-
'sm-
|
|
25
|
+
'sm-add':'The add tile for an input\'s files: <button class="sm-add" data-stillmade-add="<input>" aria-label="Add photos">. StillMade opens its own picker and saves the files; never an <input type=file>. Each tile of a list can carry .sm-tile-tools with data-stillmade-move and data-stillmade-remove buttons (data-index, data-to).',
|
|
26
|
+
'sm-scrim':'Words over a photo or video, in a positioned box such as an sm-stage: a see-through shade of the page under them, in every theme. var(--scrim) is the same shade for your own rules; never color-mix() or a fixed rgba().',
|
|
27
|
+
'sm-glyph':'A small icon drawn in currentColor: data-glyph="play|pause|plus|close|check|chevron|chevron-left|chevron-right|upload|image|image-off|video|audio|text|spark|info|warning|spinner".',
|
|
26
28
|
});
|
|
27
29
|
|
|
28
30
|
// The design principles for every Block interface, in priority order.
|
|
29
31
|
export const BLOCK_INTERFACE_PRINCIPLES=Object.freeze([
|
|
30
32
|
'Function first: unless the person asks for a design direction, build from the Block kit (`sm-block`, `sm-stage`, `sm-choices`, `sm-actions`, `sm-more`) and ship little or no CSS of your own. A direction the person names wins over the kit.',
|
|
31
|
-
'Show the thing being made: the preview, media or result gets the largest area (`sm-stage`). A picture or clip the Block makes fills it in its own shape, as large as fits; several fill it as a grid, each big enough to watch. Small tiles are for the files a person gives the Block, never for what it makes. A clip is a `<video controls>`, which StillMade plays in its own player with full screen, and a picture in `sm-stage` or `sm-gallery` (or marked `data-stillmade-expand`) gets StillMade\'s full-screen button; leave out `controls` only when the Block drives playback itself. Never a JSON dump, source editor, manifest or diagnostic panel unless the task is about source.',
|
|
33
|
+
'Show the thing being made: the preview, media or result gets the largest area (`sm-stage`), and every part shows at once: before the first run the result\'s place is drawn in the shape and size of what is coming (a 9:16 frame for a vertical clip, lines for text, a player bar for sound), so the result fills it instead of popping in. On a wide screen what goes in sits on the left and the result on the right; they stack only on narrow screens and phones. A picture or clip the Block makes fills it in its own shape, as large as fits; several fill it as a grid, each big enough to watch. Small tiles are for the files a person gives the Block, never for what it makes. A clip is a `<video controls>`, which StillMade plays in its own player with full screen, and a picture in `sm-stage` or `sm-gallery` (or marked `data-stillmade-expand`) gets StillMade\'s full-screen button; leave out `controls` only when the Block drives playback itself. Never a JSON dump, source editor, manifest or diagnostic panel unless the task is about source.',
|
|
32
34
|
'One obvious next action: one solid `sm-primary` in the kit\'s ink, never restyled to the background or a ghost outline; peers are `sm-quiet` buttons or named icons, and close is an X icon. Seven or fewer choices in view.',
|
|
33
35
|
'Speak the job unless the person or creator asks otherwise. The action button names what it does in the job\'s words (`manifest.action`: "Plan the tour"; AI pictures, video and sound start with Generate and say what, the person\'s own media cut or rendered says Make: "Generate voiceover", "Make 6 clips"), never "Make it", "Run", "Run step", "Submit", "Process" or a bare "Generate"; progress counts the job\'s units ("4 of 9 rooms"), never "Processing"; results and problems use its words in one line. Show no credit numbers: StillMade puts the price beside the verb on its own run button ("Write · 1 credit"), with a chip for the model, quality or count when they can change. Pressing it runs at that price; a confirmation appears only when the server price is higher than the one shown.',
|
|
34
36
|
'Pictures over words: choices people see or hear are thumbnails, swatches, samples or glyphs (`sm-choices`), not word lists. Icons carry an accessible name and tooltip; never emoji.',
|
|
@@ -38,13 +40,14 @@ export const BLOCK_INTERFACE_PRINCIPLES=Object.freeze([
|
|
|
38
40
|
'Strong defaults; secondary settings go in `sm-more`, closed.',
|
|
39
41
|
'Compact: the whole Block fits one laptop screen without scrolling. A short setting is one row, its label beside the control; no card around a single control.',
|
|
40
42
|
'Status is a dot or a few words ("No narration yet"), never a paragraph; the reason sits behind an `sm-hint`.',
|
|
41
|
-
'Files are tiles: a saved file is a thumbnail or chip and adding one is
|
|
43
|
+
'Files are tiles: a saved file is a thumbnail or chip and adding one is the + tile (`<button class="sm-add" data-stillmade-add="<input>">`), which opens StillMade\'s picker. Never an `<input type="file">` or the bare browser file picker, and no size limits in view until a file is too big.',
|
|
42
44
|
'Rare tools (update, schedule, history, reload) are named icon buttons beside the action, never sections under the work.',
|
|
43
45
|
'An (i) beside anything a newcomer could misread: a setting, status or number whose effect is not obvious from its label gets a closed `sm-hint` with one or two sentences. Give every input that needs one a `description`; StillMade shows it as that (i). Obvious controls get none.',
|
|
44
46
|
'One workspace: no cards inside cards, no second title, step counter or Back/Next bar; the host owns navigation.',
|
|
47
|
+
'One page per job (November 3, 2026): a guided job\'s screen holds the inputs and settings, then a cheap check before the expensive run (the script and a voice sample before the video, a second `StillMade.run` that StillMade prices on its own), then the result; never a second Block or Step for the check. A workspace a person works in (a CAD tool, a canvas, an editor) is its own Block, and turning what it made into something else is the next one.',
|
|
45
48
|
'Status sits beside the action it describes (`sm-status`), in a few words.',
|
|
46
49
|
'Keep the page in normal scroll flow; no sticky media or control strips unless the editing task needs them.',
|
|
47
|
-
'Use the width: from 860px wide the kit puts the controls on the left at a reading width (300–380px) and the result (`sm-stage`) fills the right, in its real shape; under that everything stacks
|
|
50
|
+
'Use the width: from 860px wide the kit puts the controls on the left at a reading width (300–380px) and the result (`sm-stage`) fills the right, in its real shape; under that everything stacks in the page\'s order: the inputs, the action in normal flow (never pinned), then the result\'s place under it, so put `sm-stage` after `sm-actions`. Extra width goes to the result, never to wider text fields. Before there is a result, the stage previews what will be made from the inputs. `data-layout="stack"` opts out.',
|
|
48
51
|
'Size with the kit, never fixed sizes: no fixed pixel widths or heights for the workspace or stage, no 100vh, no position:fixed panels. StillMade zooms a Block\'s screen to fill the space it has (up to 150%, never down to a phone layout on a computer), so a Block laid out with the kit\'s spacing fills its Step without empty space, and it centers a standard view narrower than its Step. 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.',
|
|
49
52
|
'Group what the person sets in one `sm-fields` (or `sm-settings` for short ones): the kit gives the group its own surface, so the inputs, the settings and the result read as separate parts. Settings sit side by side (`sm-settings`), next to what they change. Three or four short options are one segmented row (`data-segmented`), not a row of big tiles.',
|
|
50
53
|
'Lists fill the width at a small size: input files are small tiles (`sm-gallery data-size="small"`), many items are one line each (`sm-list`): a thumbnail, one line of text, a short fact. Tapping an item opens all of its fields in place. Extra width means more items per row, never bigger cards.',
|
|
@@ -68,16 +71,14 @@ export const INTERFACE_DESIGN_RULES=Object.freeze([
|
|
|
68
71
|
]);
|
|
69
72
|
|
|
70
73
|
const occurrences=(source,pattern)=>(source.match(pattern)||[]).length;
|
|
71
|
-
// A file input
|
|
74
|
+
// A file input of the view's own, shown or hidden in a label tile (November 3, 2026: a hidden one behind a label
|
|
75
|
+
// still skips StillMade's picker, its working copies and device media). Files are added with the sm-add tile.
|
|
72
76
|
// One forward scan with indexOf, so odd source never makes it slow.
|
|
73
|
-
function
|
|
77
|
+
function ownFileInput(html){
|
|
74
78
|
const lower=html.toLowerCase();
|
|
75
79
|
for(let at=lower.indexOf('<input');at!==-1;at=lower.indexOf('<input',at+6)){
|
|
76
80
|
const end=lower.indexOf('>',at);if(end===-1)return false;
|
|
77
|
-
|
|
78
|
-
if(!/\btype\s*=\s*["']?file\b/.test(tag)||/\bhidden\b|display\s*:\s*none|\bsm-sr\b/.test(tag))continue;
|
|
79
|
-
const label=lower.lastIndexOf('<label',at),closed=lower.lastIndexOf('</label>',at);
|
|
80
|
-
if(label===-1||closed>label)return true;
|
|
81
|
+
if(/\btype\s*=\s*["']?file\b/.test(lower.slice(at,end)))return true;
|
|
81
82
|
}
|
|
82
83
|
return false;
|
|
83
84
|
}
|
|
@@ -308,8 +309,8 @@ export function reviewViewDesign(view){
|
|
|
308
309
|
const longText=[...primary.matchAll(/<p\b[^>]*>([\s\S]*?)<\/p>/gi)].filter(match=>words(match[1])>20).length;
|
|
309
310
|
if(longText)warnings.push('A visible paragraph runs past twenty words. Drop words nobody needs; put helpful explanation in a closed <details class="sm-hint">.');
|
|
310
311
|
if(/<select\b/i.test(primary)&&/<(?:img|video|audio)\b/i.test(primary)===false&&/\b(?:voice|font|look|style|color|colour|template|theme|music|sound)\b/i.test(primary))warnings.push('People choose something they see or hear from a word list. Show each option as a picture or sample in <fieldset class="sm-choices">.');
|
|
311
|
-
// Compact:
|
|
312
|
-
if(
|
|
312
|
+
// Compact: the view's own file picker and printed size limits each take rows nobody needs.
|
|
313
|
+
if(ownFileInput(primary))warnings.push('The view has a file input of its own. Show files as tiles: a thumbnail or chip for each saved file and the + tile, <button class="sm-add" data-stillmade-add="<input>" aria-label="Add photos">, which opens StillMade\'s picker and saves the files.');
|
|
313
314
|
if(/\bup to \d+\s*(?:mb|gb|kb)\b/i.test(primary.replace(/<[^<>]*>/g,' ')))warnings.push('A size limit is printed in view. Say it only when a file is too big.');
|
|
314
315
|
if(stackedLabel(primary,view.css))warnings.push('A short setting has its label above the control. Put the label beside it: <div class="sm-field"><label for="x">Label</label><input id="x"></div>, or several side by side in .sm-settings.');
|
|
315
316
|
const rareTool=rareToolSection(html);
|
|
@@ -328,12 +329,14 @@ export function reviewViewDesign(view){
|
|
|
328
329
|
|
|
329
330
|
// October 30, 2026: Chat presses a button on a Block's own screen only when it carries data-stillmade-action
|
|
330
331
|
// (naming what it does); an unmarked button is out of Chat's reach. The number of buttons in view.html without one.
|
|
332
|
+
// The + tile (data-stillmade-add) is not counted: StillMade's picker opens only from the person's own click.
|
|
331
333
|
export function unmarkedButtons(view){
|
|
332
334
|
const html=String(view?.html||''),lower=html.toLowerCase();let count=0;
|
|
333
335
|
for(let start=lower.indexOf('<button');start!==-1;start=lower.indexOf('<button',start+7)){
|
|
334
336
|
if(!/[\s>/]/.test(lower[start+7]||''))continue;
|
|
335
337
|
const end=lower.indexOf('>',start);if(end===-1)break;
|
|
336
|
-
|
|
338
|
+
const tag=lower.slice(start,end);
|
|
339
|
+
if(!/\sdata-stillmade-(?:action|add)\s*=/.test(tag))count++;
|
|
337
340
|
}
|
|
338
341
|
return count;
|
|
339
342
|
}
|
|
@@ -8,7 +8,7 @@ export const webFetch={
|
|
|
8
8
|
tests:[{name:'Read a public page',input:{url:'https://en.wikipedia.org/wiki/Tide'},expectations:{summary:{kind:'text',minLength:20,maxLength:4000}}}],
|
|
9
9
|
};
|
|
10
10
|
export const webResearch={
|
|
11
|
-
manifest:{schemaVersion:1,sdkVersion:'0.1.0',id:'example.research-topic',action:{label:'Research topic',running:'Researching topic…'},version:'1.0.0',name:'Research a topic',description:'Search the web for a topic and return a cited summary.',kind:'task',runtime:'capability',entry:'src/capability.json',license:'MIT',provenance:EXAMPLE_PROVENANCE,inputs:{topic:{type:'text',primary:true,semantic:'research_topic',required:true,description:'What to research.'}},outputs:{findings:{type:'json',primary:true,semantic:'research_findings',description:'Summary and the sources it came from.'}},permissions:{project:[],capabilities:['web.research'],network:[],filesystem:[],secrets:[]},ui:[{control:'text',port:'topic'}]},
|
|
11
|
+
manifest:{schemaVersion:1,sdkVersion:'0.1.0',id:'example.research-topic',action:{label:'Research topic',running:'Researching topic…'},version:'1.0.0',name:'Research a topic',description:'Search the web for a topic and return a cited summary.',kind:'task',runtime:'capability',entry:'src/capability.json',license:'MIT',provenance:EXAMPLE_PROVENANCE,inputs:{topic:{type:'text',primary:true,semantic:'research_topic',required:true,description:'What to research.'}},outputs:{findings:{type:'json',primary:true,semantic:'research_findings',description:'Summary and the sources it came from.',schema:{summary:'text',sources:'json[]'}}},permissions:{project:[],capabilities:['web.research'],network:[],filesystem:[],secrets:[]},ui:[{control:'text',port:'topic'}]},
|
|
12
12
|
capability:{schemaVersion:1,operation:'web.research',topic:{$input:'topic'},output:'findings'},
|
|
13
13
|
tests:[{name:'Tides',input:{topic:'How tides work'},expectations:{findings:{kind:'json',includes:['summary']}}}],
|
|
14
14
|
};
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
.sm-actions one .sm-primary, optional .sm-quiet / .sm-icon
|
|
17
17
|
.sm-status short live state beside the action
|
|
18
18
|
.sm-more everything secondary, collapsed
|
|
19
|
-
.sm-hint an
|
|
19
|
+
.sm-hint an (i) whose words show on hover or focus (a tap on touch screens)
|
|
20
20
|
.sm-empty what an empty stage shows: a glyph, a few words, one action
|
|
21
21
|
.sm-glyph icons drawn in CSS with currentColor (no SVG or url needed)
|
|
22
22
|
.sm-media-off a picture or clip that cannot show here: a quiet tile, no words
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
:where(.sm-block[data-layout="split"]) > :where(.sm-stage){grid-row:span 6}
|
|
36
36
|
}
|
|
37
37
|
/* Wide views (October 19, 2026): the controls keep a reading width on the left and
|
|
38
|
-
the result fills the rest on the right. Under 860px everything stacks
|
|
39
|
-
result
|
|
38
|
+
the result fills the rest on the right. Under 860px everything stacks in page order, so
|
|
39
|
+
the stage goes after the actions: the result's place under the button. data-layout="stack" opts out; "split" keeps its older layout. */
|
|
40
40
|
@container (min-width:860px){
|
|
41
41
|
:where(.sm-block:not([data-layout]):has(> .sm-stage)){grid-template-columns:minmax(300px,380px) minmax(0,1fr);align-items:start;column-gap:var(--s-5,24px);row-gap:var(--s-4,16px)}
|
|
42
42
|
:where(.sm-block:not([data-layout]):has(> .sm-stage)) > :where(*){grid-column:1}
|
|
@@ -52,11 +52,13 @@
|
|
|
52
52
|
|
|
53
53
|
/* ---------- The stage: the object being made gets the main surface ---------- */
|
|
54
54
|
:where(.sm-stage){position:relative;display:grid;place-items:center;min-height:220px;padding:var(--s-3,12px);border-radius:var(--r-3,8px);background:var(--bg-inset);overflow:hidden}
|
|
55
|
-
:where(.sm-stage[data-ratio="16:9"]){aspect-ratio:16/9;min-height:0}
|
|
56
|
-
:where(.sm-stage[data-ratio="9:16"]){aspect-ratio:9/16;min-height:0;max-height:70vh;justify-self:center;width:auto;height:min(70vh,640px)}
|
|
57
|
-
:where(.sm-stage[data-ratio="1:1"]){aspect-ratio:1;min-height:0}
|
|
55
|
+
:where(.sm-stage:is([data-ratio="16:9"],[data-ratio="16/9"])){aspect-ratio:16/9;min-height:0}
|
|
56
|
+
:where(.sm-stage:is([data-ratio="9:16"],[data-ratio="9/16"])){aspect-ratio:9/16;min-height:0;max-height:70vh;justify-self:center;width:auto;height:min(70vh,640px)}
|
|
57
|
+
:where(.sm-stage:is([data-ratio="1:1"],[data-ratio="1/1"])){aspect-ratio:1;min-height:0}
|
|
58
58
|
:where(.sm-stage) > :where(img,video,canvas){display:block;max-width:100%;max-height:100%;object-fit:contain;border-radius:var(--r-2,4px)}
|
|
59
59
|
:where(.sm-stage[data-fill]) > :where(img,video,canvas){width:100%;height:100%;object-fit:cover}
|
|
60
|
+
/* A picture the view has not filled yet draws nothing, never a broken-image icon (November 3, 2026). */
|
|
61
|
+
:where(.sm-stage) :where(img:not([src]),img[src=""]){display:none}
|
|
60
62
|
|
|
61
63
|
/* ---------- Empty state: a picture and a few words, never a paragraph ---------- */
|
|
62
64
|
:where(.sm-empty){display:grid;justify-items:center;gap:var(--s-3,12px);padding:var(--s-5,24px) var(--s-4,16px);text-align:center;color:var(--fg-muted)}
|
|
@@ -130,8 +132,8 @@
|
|
|
130
132
|
:where(.sm-choices) > :where(label:has(input:disabled):not(:has(input:checked))){opacity:.45}
|
|
131
133
|
:where(.sm-choices) :where(img,video,canvas,.sm-swatch){display:block;width:100%;aspect-ratio:var(--sm-tile-ratio,1);object-fit:cover;border-radius:var(--r-2,4px);background:var(--bg-inset)}
|
|
132
134
|
:where(.sm-choices) :where(.sm-glyph){--sm-glyph-size:28px;margin:10px 0 4px}
|
|
133
|
-
:where(.sm-choices[data-ratio="16:9"]){--sm-tile-ratio:16/9}
|
|
134
|
-
:where(.sm-choices[data-ratio="9:16"]){--sm-tile-ratio:9/16}
|
|
135
|
+
:where(.sm-choices:is([data-ratio="16:9"],[data-ratio="16/9"])){--sm-tile-ratio:16/9}
|
|
136
|
+
:where(.sm-choices:is([data-ratio="9:16"],[data-ratio="9/16"])){--sm-tile-ratio:9/16}
|
|
135
137
|
:where(.sm-choices[data-compact]) > :where(label){grid-auto-flow:column;justify-content:center;align-content:center;align-items:center;min-height:var(--touch-target,44px);padding:6px 12px}
|
|
136
138
|
:where(.sm-choices[data-compact]) :where(.sm-glyph){--sm-glyph-size:18px;margin:0}
|
|
137
139
|
:where(.sm-choices) :where(audio){width:100%;height:32px;position:relative;z-index:1}
|
|
@@ -199,6 +201,36 @@
|
|
|
199
201
|
Its edge separates it from a stage or gallery tile of the same colour; in a gallery it takes the tile's shape. */
|
|
200
202
|
:where(.sm-media-off){display:inline-grid;place-items:center;box-sizing:border-box;width:min(100%,320px);aspect-ratio:var(--sm-photo-ratio,4/3);border:1px solid var(--border-tok);border-radius:var(--r-2,4px);background:var(--bg-inset);color:var(--fg-subtle,var(--fg-muted));vertical-align:top}
|
|
201
203
|
:where(.sm-gallery) :where(.sm-media-off){display:grid;width:100%;aspect-ratio:var(--sm-tile-ratio,1);border-radius:inherit}
|
|
204
|
+
/* The add tile (November 3, 2026): a dashed + after an input's files, as on StillMade's Step page. With
|
|
205
|
+
data-stillmade-add naming the input, StillMade opens its own picker and saves the files as its own tiles do; they
|
|
206
|
+
arrive through onInput. Never an <input type="file"> of the Block's own.
|
|
207
|
+
<button type="button" class="sm-add" data-stillmade-add="listingPhotos" aria-label="Add photos" title="Add photos"></button>
|
|
208
|
+
Alone it is a small square; in an .sm-gallery it takes the tile's shape. Words inside show under the +. A viewer and
|
|
209
|
+
an input an earlier Step fills see no tile. */
|
|
210
|
+
:where(.sm-add){display:inline-grid;place-items:center;align-content:center;gap:2px;box-sizing:border-box;min-width:52px;min-height:52px;margin:0;padding:6px;border:1px dashed var(--border-strong);border-radius:var(--r-2,4px);background:transparent;color:var(--fg-muted);font:inherit;font-size:max(12px,var(--fs-caption,.8125rem));line-height:1.2;cursor:pointer}
|
|
211
|
+
:where(.sm-add)::before{content:"+";font-size:20px;line-height:1}
|
|
212
|
+
:where(.sm-add):hover{color:var(--fg);border-style:solid}
|
|
213
|
+
:where(.sm-add):focus-visible{outline:2px solid var(--signal);outline-offset:3px}
|
|
214
|
+
:where(.sm-add):disabled,:where(.sm-add[aria-busy="true"]){opacity:.45;cursor:default}
|
|
215
|
+
:where(.sm-gallery) :where(.sm-add){display:grid;width:100%;aspect-ratio:var(--sm-tile-ratio,1);border-radius:var(--r-3,8px);background:transparent}
|
|
216
|
+
/* A scrim (November 3, 2026): words over a photo or video read in every theme (a listing Block could not write one:
|
|
217
|
+
a Block's CSS takes only theme tokens, and color-mix() over them is refused). --scrim is the page's background, partly
|
|
218
|
+
see-through, for a Block's own rules (background:var(--scrim)); .sm-scrim lays it over the bottom of a positioned box
|
|
219
|
+
(an sm-stage, a gallery tile) under the words inside it.
|
|
220
|
+
<figure class="sm-stage" data-fill><img src="..." alt=""><figcaption class="sm-scrim">12 Elm Street</figcaption></figure> */
|
|
221
|
+
:where(:root,[data-mode]){--scrim:color-mix(in srgb,var(--bg) 72%,transparent)}
|
|
222
|
+
:where(.sm-scrim){position:absolute;inset:auto 0 0 0;margin:0;padding:var(--s-5,24px) var(--s-3,12px) var(--s-3,12px);background:linear-gradient(to top,var(--scrim) 55%,transparent);color:var(--fg)}
|
|
223
|
+
/* A tile's own tools (the same day): move and remove buttons in an .sm-tile-tools inside a gallery tile, wired by
|
|
224
|
+
data-stillmade-move and data-stillmade-remove (FRAME_VIEWS.md, "Removing and reordering files"). They sit in the
|
|
225
|
+
tile's top corner on a solid chip, show on hover or focus where there is a pointer and always on touch, and are hidden
|
|
226
|
+
with the + tile from viewers and for an input an earlier Step fills. */
|
|
227
|
+
:where(.sm-gallery) :where(.sm-tile-tools){position:absolute;top:4px;right:4px;display:flex;gap:2px}
|
|
228
|
+
:where(.sm-gallery) :where(.sm-tile-tools) > :where(button){--sm-glyph-size:14px;display:grid;place-items:center;box-sizing:border-box;min-width:24px;height:24px;margin:0;padding:0 4px;border:0;border-radius:var(--r-2,4px);background:var(--bg);color:var(--fg);font:inherit;font-size:16px;line-height:1;cursor:pointer}
|
|
229
|
+
:where(.sm-gallery) :where(.sm-tile-tools) > :where(button):focus-visible{outline:2px solid var(--signal);outline-offset:1px}
|
|
230
|
+
:where(.sm-gallery) :where(.sm-tile-tools) > :where(button:disabled,button[aria-busy="true"]){opacity:.45;cursor:default}
|
|
231
|
+
/* Three tools fit a 92px small tile on touch: 3 x 28 + gaps. */
|
|
232
|
+
@media (pointer:coarse){:where(.sm-gallery) :where(.sm-tile-tools) > :where(button){min-width:28px;height:28px}}
|
|
233
|
+
@media (hover:hover){:where(.sm-gallery) > :where(:not(:hover,:focus-within)) :where(.sm-tile-tools){opacity:0}}
|
|
202
234
|
|
|
203
235
|
/* ---------- Status: a glyph and a few words, next to the action ---------- */
|
|
204
236
|
:where(.sm-status){display:inline-flex;align-items:center;gap:var(--s-2,8px);min-height:24px;font-size:var(--fs-body-s,.875rem);color:var(--fg-muted)}
|
|
@@ -233,11 +265,12 @@
|
|
|
233
265
|
:where(.sm-hint) > :where(summary){display:inline-grid;place-items:center;width:var(--touch-target,44px);height:var(--touch-target,44px);margin:-8px;min-height:0;padding:0;border:0;list-style:none;color:var(--fg-subtle);cursor:pointer}
|
|
234
266
|
:where(.sm-hint) > :where(summary)::-webkit-details-marker{display:none}
|
|
235
267
|
:where(.sm-hint) > :where(summary)::before{content:"i";display:grid;place-items:center;width:15px;height:15px;border:1.5px solid currentColor;border-radius:50%;font:600 10px/1 var(--font-body);font-style:normal}
|
|
236
|
-
:where(.sm-hint
|
|
268
|
+
:where(.sm-hint:hover,.sm-hint:focus-within,.sm-hint[open]) > :where(summary){color:var(--fg)}
|
|
269
|
+
/* The words float over the page and never push it around (owner, November 3, 2026: "it makes me click and makes the ui weird"). */
|
|
237
270
|
:where(.sm-hint) > :where(:not(summary)){position:absolute;z-index:5;inset-inline-start:0;top:100%;width:max-content;max-width:min(280px,calc(100cqi - 32px));margin:4px 0 0;padding:10px 12px;border:1px solid var(--border-tok);border-radius:var(--r-3,8px);background:var(--bg-elev-2);color:var(--fg);font-size:var(--fs-body-s,.875rem);line-height:1.45;box-shadow:var(--shadow-1)}
|
|
238
|
-
|
|
239
|
-
:
|
|
240
|
-
|
|
271
|
+
:where(.sm-hint:hover,.sm-hint:focus-within)::details-content{content-visibility:visible}
|
|
272
|
+
/* With a mouse, hovering shows the words and a click does nothing: the click lands on the closed <details>, not its summary. Touch screens keep the tap. */
|
|
273
|
+
@media (hover:hover){:where(.sm-hint) > :where(summary){pointer-events:none}}
|
|
241
274
|
|
|
242
275
|
/* ---------- Glyphs: small icons drawn with currentColor ----------
|
|
243
276
|
<span class="sm-glyph" data-glyph="upload" aria-hidden="true"></span>
|
|
@@ -250,6 +283,9 @@
|
|
|
250
283
|
:where(.sm-glyph[data-glyph="close"])::before{transform:rotate(45deg)}
|
|
251
284
|
:where(.sm-glyph[data-glyph="check"])::before{left:36%;top:12%;width:30%;height:58%;border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg)}
|
|
252
285
|
:where(.sm-glyph[data-glyph="chevron"])::before{left:30%;top:22%;width:40%;height:40%;border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg)}
|
|
286
|
+
/* Earlier and later (a tile's move tools, November 3, 2026). */
|
|
287
|
+
:where(.sm-glyph[data-glyph="chevron-left"])::before{left:36%;top:30%;width:40%;height:40%;border:solid currentColor;border-width:0 0 2px 2px;transform:rotate(45deg)}
|
|
288
|
+
:where(.sm-glyph[data-glyph="chevron-right"])::before{left:24%;top:30%;width:40%;height:40%;border:solid currentColor;border-width:2px 2px 0 0;transform:rotate(45deg)}
|
|
253
289
|
:where(.sm-glyph[data-glyph="upload"])::before{left:10%;right:10%;bottom:10%;height:35%;border:2px solid currentColor;border-top:0;border-radius:0 0 3px 3px}
|
|
254
290
|
:where(.sm-glyph[data-glyph="upload"])::after{left:25%;right:25%;top:4%;height:62%;background:currentColor;clip-path:polygon(50% 0,100% 45%,60% 45%,60% 100%,40% 100%,40% 45%,0 45%)}
|
|
255
291
|
:where(.sm-glyph[data-glyph="image"])::before{inset:12%;border:2px solid currentColor;border-radius:3px}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
Drop it if nobody needs it to finish the task (intros, "how it works",
|
|
22
22
|
restating the Block name, describing what is already visible).
|
|
23
23
|
Picture it if a glyph, thumbnail, swatch or sample says the same thing.
|
|
24
|
-
Collapse it if it might help some people: .sm-hint (
|
|
24
|
+
Collapse it if it might help some people: .sm-hint (an (i) that shows on hover) for an
|
|
25
25
|
explanation, .sm-more for secondary settings.
|
|
26
26
|
Keep it for errors, spending or credit approvals, stale inputs and
|
|
27
27
|
anything destructive. Keep those visible, in few words.
|
|
@@ -111,7 +111,8 @@
|
|
|
111
111
|
<li><span class="sm-swatch swatch-a" style="display:block;aspect-ratio:3/2"></span></li>
|
|
112
112
|
<li><span class="sm-swatch swatch-b" style="display:block;aspect-ratio:3/2"></span></li>
|
|
113
113
|
<li><span class="sm-swatch swatch-c" style="display:block;aspect-ratio:3/2"></span></li>
|
|
114
|
-
|
|
114
|
+
<!-- The add tile: StillMade opens its own picker for the named input and saves the files; they arrive through onInput. -->
|
|
115
|
+
<li><button type="button" class="sm-add" data-stillmade-add="listingPhotos" aria-label="Add photos" title="Add photos"></button></li>
|
|
115
116
|
</ul>
|
|
116
117
|
</div>
|
|
117
118
|
<ol class="sm-list" data-peek>
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
// Generated immutable package data.
|
|
2
|
-
export default {
|
|
3
|
-
"manifest": {
|
|
4
|
-
"schemaVersion": 1,
|
|
5
|
-
"sdkVersion": "0.1.0",
|
|
6
|
-
"id": "stillmade.mcp-motion-planner",
|
|
7
|
-
"name": "Motion Plan",
|
|
8
|
-
"version": "1.1.0",
|
|
9
|
-
"kind": "workspace",
|
|
10
|
-
"runtime": "javascript",
|
|
11
|
-
"entry": "src/run.js",
|
|
12
|
-
"description": "Review a visual scene plan authored through StillMade MCP, adjust its source only when needed, and hand the approved structure to Frame Review locally.",
|
|
13
|
-
"inputs": {
|
|
14
|
-
"plan": {
|
|
15
|
-
"type": "text",
|
|
16
|
-
"primary": true,
|
|
17
|
-
"required": false,
|
|
18
|
-
"semantic": "project_brief",
|
|
19
|
-
"sources": [
|
|
20
|
-
"project",
|
|
21
|
-
"user"
|
|
22
|
-
],
|
|
23
|
-
"description": "A complete motion-design-package between BEGIN_MOTION_PLAN and END_MOTION_PLAN, or a concise fallback brief."
|
|
24
|
-
},
|
|
25
|
-
"brief": {
|
|
26
|
-
"type": "text",
|
|
27
|
-
"required": false,
|
|
28
|
-
"description": "Optional plain-language fallback when an MCP-authored plan has not been supplied."
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"outputs": {
|
|
32
|
-
"designPackage": {
|
|
33
|
-
"type": "text",
|
|
34
|
-
"primary": true,
|
|
35
|
-
"role": "motion_design_package",
|
|
36
|
-
"description": "Validated version 1 motion design package for Frame Review and Motion Designer."
|
|
37
|
-
},
|
|
38
|
-
"report": {
|
|
39
|
-
"type": "metadata",
|
|
40
|
-
"description": "Local scene-count, duration, source, and zero-credit validation report."
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
"permissions": {
|
|
44
|
-
"project": [],
|
|
45
|
-
"actions": [],
|
|
46
|
-
"network": [],
|
|
47
|
-
"filesystem": [],
|
|
48
|
-
"secrets": []
|
|
49
|
-
},
|
|
50
|
-
"ui": [
|
|
51
|
-
{
|
|
52
|
-
"control": "text",
|
|
53
|
-
"port": "plan"
|
|
54
|
-
}
|
|
55
|
-
],
|
|
56
|
-
"platforms": {
|
|
57
|
-
"phone": {
|
|
58
|
-
"supported": true
|
|
59
|
-
},
|
|
60
|
-
"browser": {
|
|
61
|
-
"supported": true
|
|
62
|
-
},
|
|
63
|
-
"desktop": {
|
|
64
|
-
"supported": true
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
"license": "MIT",
|
|
68
|
-
"provenance": {
|
|
69
|
-
"notice": "MIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and \nassociated documentation files (the \"Software\"), to deal in the Software without restriction, including \nwithout limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell \ncopies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the \nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial \nportions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT \nLIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO \nEVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER \nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE \nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n"
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
"code": "\n const text=value=>value==null?'':String(value),clone=value=>JSON.parse(JSON.stringify(value));\n const source=text(input.plan||input.brief).trim();\n const begin='BEGIN_MOTION_PLAN',end='END_MOTION_PLAN';\n let candidate=null;\n const start=source.indexOf(begin),finish=source.indexOf(end,start+begin.length);\n const encoded=start>=0&&finish>start?source.slice(start+begin.length,finish).trim():source;\n if(encoded.startsWith('{')){try{candidate=JSON.parse(encoded)}catch{throw new Error('The MCP motion plan is not valid JSON. Ask the connected assistant to repair the exact plan before continuing.')}}\n if(!candidate){\n const brief=source||'Create a concise product motion graphic.';\n candidate={schemaVersion:1,revision:'local-'+brief.length,kind:'motion-design-package',brief,audience:'Product-minded creative teams',creativeIntent:{idea:'Show the product as a living creative system',tone:'confident, precise, cinematic',visualLanguage:'editorial product UI, oversized type, clean vector geometry',motionCharacter:'restrained acceleration with decisive cuts',density:'open',avoid:['generic slideshow','floating mockup carousel','invented product claims']},constraints:{required:['Use only supplied product evidence and exact saved assets','Keep the composition editable'],preferences:['Prefer coded SVG, kinetic type, masks, camera moves, and real UI'],locks:[]},references:[],intendedOutputs:[{aspect:'16:9',durationSec:30,channel:'product launch'}],style:{background:'#0A0A0A',foreground:'#F7F0DB',accent:'#F2A93B',fontDirection:'editorial grotesk with monospace details'},product:{name:'StillMade',url:'',targetBuyer:'creative teams',promise:'Build complete visual productions from connected modular Blocks',availability:'',cta:{label:'Build with StillMade',destination:''},benefits:[]},scenes:[\n {id:'scene-1',goal:'Open with a singular promise',copy:{eyebrow:'STILLMADE',headline:'Make the whole thing.',support:'One connected creative system.'},durationSec:4,visualApproach:'Oversized masked typography and a precise vector aperture',layout:'centered poster',motionIntent:'restrained reveal, then sharp exit',assetIds:[],evidenceRefs:[],locks:[]},\n {id:'scene-2',goal:'Establish the modular workflow',copy:{eyebrow:'BLOCKS THAT WORK TOGETHER',headline:'From idea to final cut.',support:'Plan, review, design, and edit in one flow.'},durationSec:5,visualApproach:'Editable node path with semantic icons and cropped UI evidence when supplied',layout:'offset editorial',motionIntent:'measured camera push with sequential connections',assetIds:[],evidenceRefs:[],locks:[]},\n {id:'scene-3',goal:'Show visual review before animation',copy:{eyebrow:'APPROVE THE LOOK FIRST',headline:'See the frames. Then make them move.',support:'Choose a 3, 5, or 10 second review cadence.'},durationSec:5,visualApproach:'A grid of exact approved styleframes with one selected frame expanding full bleed',layout:'modular proof grid',motionIntent:'staggered tiles, magnetic selection, mask expansion',assetIds:[],evidenceRefs:[],locks:[]},\n {id:'scene-4',goal:'Reveal coded construction',copy:{eyebrow:'EDITABLE BY DESIGN',headline:'Real layers. Real timing. Real control.',support:'SVG, kinetic type, camera, transitions, and exact assets.'},durationSec:6,visualApproach:'Split view between coded vector layers and the live composition',layout:'copy on the left with product UI on the right',motionIntent:'typewriter detail, controlled parallax, precise callouts',assetIds:[],evidenceRefs:[],locks:[]},\n {id:'scene-5',goal:'Show the final editor handoff',copy:{eyebrow:'FINISH IN YOUR EDITOR',headline:'Polish without starting over.',support:'Every scene arrives as an editable timeline.'},durationSec:5,visualApproach:'Full-width timeline with layered motion scene clips and a final export target',layout:'full-bleed product UI',motionIntent:'timeline scrub, clip focus, restrained zoom',assetIds:[],evidenceRefs:[],locks:[]},\n {id:'scene-6',goal:'Close on the product promise',copy:{eyebrow:'STILLMADE',headline:'Make more than a clip.',support:'Build the system behind it.'},durationSec:5,visualApproach:'Return to the opening aperture as the product mark resolves',layout:'centered hero statement',motionIntent:'confident lockup and clean hold',assetIds:[],evidenceRefs:[],locks:[]}\n ],audio:{mode:'silent',assetIds:[],captions:[],notes:'Designed to work silently; optional sound design can accent transitions.'},unresolved:['Add exact StillMade UI screenshots or recordings as content assets before claiming visible product behavior.'],branch:{intent:'create',parentRevision:null}};\n }\n if(!candidate||Array.isArray(candidate)||candidate.schemaVersion!==1||candidate.kind!=='motion-design-package')throw new Error('Connect a version 1 motion-design-package authored by the StillMade MCP assistant.');\n if(!Array.isArray(candidate.scenes)||candidate.scenes.length<1||candidate.scenes.length>12)throw new Error('The MCP motion plan needs 1 to 12 scenes.');\n const ids=new Set();let duration=0;\n for(const scene of candidate.scenes){\n if(!scene||typeof scene!=='object'||Array.isArray(scene)||!text(scene.id).trim()||ids.has(scene.id))throw new Error('Every planned scene needs a distinct stable ID.');\n ids.add(scene.id);const seconds=Number(scene.durationSec);if(!Number.isFinite(seconds)||seconds<1||seconds>20)throw new Error('Every planned scene needs a duration from 1 to 20 seconds.');duration+=seconds;\n if(!scene.copy||typeof scene.copy!=='object'||!text(scene.copy.headline||scene.goal).trim())throw new Error('Every planned scene needs a communication goal or approved headline.');\n }\n if(duration>180)throw new Error('The complete MCP motion plan cannot exceed 180 seconds.');\n const plan=clone(candidate);plan.revision=text(plan.revision).trim()||'mcp-authored-1';plan.branch=plan.branch&&typeof plan.branch==='object'?plan.branch:{intent:'create',parentRevision:null};\n return {designPackage:JSON.stringify(plan),report:{schemaVersion:1,source:start>=0?'mcp-authored':'local-fallback',sceneCount:plan.scenes.length,durationSec:duration,creditCost:0,ready:true}};\n",
|
|
73
|
-
"view": {
|
|
74
|
-
"html": "<main class=\"planner\"><section class=\"overview\"><div class=\"ready\"><i class=\"plan-icon\" aria-hidden=\"true\"></i><div><small>CONNECTED PLAN</small><h2 id=\"planTitle\">Motion plan</h2></div></div><div class=\"metrics\" aria-label=\"Plan summary\"><span><i class=\"scene-icon\" aria-hidden=\"true\"></i><strong id=\"sceneCount\">—</strong> scenes</span><span><i class=\"time-icon\" aria-hidden=\"true\"></i><strong id=\"duration\">—</strong></span><span><i class=\"local-icon\" aria-hidden=\"true\"></i>Local · 0 credits</span></div><p id=\"idea\">Connect a brief or an assistant-authored plan to begin.</p><button id=\"use\" type=\"button\">Use this plan</button><output id=\"status\" role=\"status\">Waiting for a motion plan.</output></section><section class=\"storyboard\"><header><div><small>STORYBOARD</small><h2>Scenes and motion</h2></div><span id=\"format\">16:9</span></header><div id=\"scenes\" class=\"scenes\"></div></section><details><summary>Plan source</summary><p>Edit the structured source only when you need exact copy, timing, or scene IDs.</p><textarea id=\"source\" rows=\"14\" aria-label=\"Motion plan source\"></textarea></details></main>",
|
|
75
|
-
"css": ".planner{container:motion-plan/inline-size;max-width:1160px;margin:0 auto;padding:12px;color:var(--fg);font-family:var(--font-body)}section,details{border:1px solid var(--border-tok);border-radius:var(--r-3);background:var(--bg-elev-1)}.overview{padding:20px}.ready,section header,.metrics,.metrics span,.scene-head,.scene-meta{display:flex;align-items:center}.ready{gap:12px}.ready h2,section header h2{margin:2px 0 0;font-family:var(--font-display);font-size:26px;font-style:italic;font-weight:200}.ready small,section header small,.scene small{font:600 11px/1.2 var(--font-mono);letter-spacing:.09em;color:var(--fg-muted)}.plan-icon{position:relative;width:30px;height:30px;border:1px solid var(--border-strong);border-radius:var(--r-2)}.plan-icon:before,.plan-icon:after{content:\"\";position:absolute;left:7px;right:7px;height:1px;background:var(--fg)}.plan-icon:before{top:10px;box-shadow:0 5px 0 var(--fg)}.plan-icon:after{top:20px;width:9px}.metrics{gap:8px;flex-wrap:wrap;margin:18px 0 12px}.metrics span,.scene-meta span{gap:7px;padding:7px 10px;border:1px solid var(--border-tok);border-radius:999px;color:var(--fg-muted);font-size:12px}.metrics strong{color:var(--fg)}.scene-icon,.local-icon{position:relative;width:14px;height:12px;border:1px solid currentColor}.scene-icon:after{content:\"\";position:absolute;inset:2px;border-top:1px solid currentColor;border-bottom:1px solid currentColor}.time-icon{position:relative;width:13px;height:13px;border:1px solid currentColor;border-radius:50%}.time-icon:before{content:\"\";position:absolute;left:6px;top:2px;width:1px;height:5px;background:currentColor;transform-origin:bottom;transform:rotate(-35deg)}.local-icon{border-radius:50%;width:12px;height:12px}.local-icon:after{content:\"\";position:absolute;left:3px;top:3px;width:4px;height:2px;border-left:1px solid currentColor;border-bottom:1px solid currentColor;transform:rotate(-45deg)}#idea{max-width:720px;margin:0 0 16px;color:var(--fg-muted);line-height:1.5}button{min-height:44px;padding:10px 18px;border:0;border-radius:999px;background:var(--fg);color:var(--bg);font:600 14px var(--font-body)}button:disabled{opacity:.5}output{display:inline-block;margin-left:12px;color:var(--fg-muted);font-size:13px}.storyboard{margin-top:12px;padding:20px}.storyboard>header{justify-content:space-between;gap:16px}.storyboard>header>span{font:600 12px var(--font-mono);color:var(--fg-muted)}.scenes{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:16px}.scene{min-width:0;padding:14px;border:1px solid var(--border-tok);border-radius:var(--r-2);background:var(--bg)}.scene-head{justify-content:space-between;gap:10px}.scene-index{font:600 11px var(--font-mono);color:var(--fg-muted)}.scene-duration{font:600 11px var(--font-mono);color:var(--fg)}.scene h3{margin:14px 0 6px;font-size:16px;line-height:1.15}.scene p{margin:0;color:var(--fg-muted);font-size:13px;line-height:1.4}.scene-meta{gap:6px;flex-wrap:wrap;margin-top:14px}.scene-meta span{padding:5px 8px;font-size:11px}.empty{grid-column:1/-1;padding:28px;text-align:center;color:var(--fg-muted)}details{margin-top:12px;padding:14px 16px}summary{cursor:pointer;font-weight:600}details p{color:var(--fg-muted);font-size:13px}textarea{box-sizing:border-box;width:100%;min-height:240px;padding:12px;border:1px solid var(--border-tok);border-radius:var(--r-2);background:var(--bg);color:var(--fg);font:12px/1.5 var(--font-mono);resize:vertical}@container motion-plan (max-width:760px){.scenes{grid-template-columns:repeat(2,minmax(0,1fr))}}@container motion-plan (max-width:500px){.planner{padding:4px}.overview,.storyboard{padding:14px}.scenes{grid-template-columns:1fr}output{display:block;margin:10px 0 0}}",
|
|
76
|
-
"javascript": "const e=id=>document.getElementById(id),source=e('source'),button=e('use');let current=null;const text=value=>value==null?'':String(value);const read=value=>{const raw=text(value).trim(),begin='BEGIN_MOTION_PLAN',end='END_MOTION_PLAN',start=raw.indexOf(begin),finish=raw.indexOf(end,start+begin.length),encoded=start>=0&&finish>start?raw.slice(start+begin.length,finish).trim():raw;if(!encoded.startsWith('{'))return null;try{return JSON.parse(encoded)}catch{return null}};const card=(scene,index)=>({tag:'article',className:'scene',children:[{tag:'div',className:'scene-head',children:[{tag:'span',className:'scene-index',text:String(index+1).padStart(2,'0')},{tag:'span',className:'scene-duration',text:String(scene.durationSec||0)+'s'}]},{tag:'small',text:text(scene.copy&&scene.copy.eyebrow||scene.goal||'SCENE')},{tag:'h3',text:text(scene.copy&&scene.copy.headline||scene.goal||'Untitled scene')},{tag:'p',text:text(scene.visualApproach||scene.copy&&scene.copy.support||'Visual direction will be resolved in Frame Review.')},{tag:'div',className:'scene-meta',children:[{tag:'span',text:text(scene.layout||'Layout')},{tag:'span',text:text(scene.motionIntent||'Motion')}]}]});const show=plan=>{current=plan;const scenes=Array.isArray(plan&&plan.scenes)?plan.scenes:[],duration=scenes.reduce((sum,scene)=>sum+(Number(scene.durationSec)||0),0);e('sceneCount').textContent=scenes.length?String(scenes.length):'—';e('duration').textContent=scenes.length?String(duration)+' sec':'—';e('idea').textContent=text(plan&&plan.creativeIntent&&plan.creativeIntent.idea||plan&&plan.brief||'Connect a brief or an assistant-authored plan to begin.');e('format').textContent=text(plan&&plan.intendedOutputs&&plan.intendedOutputs[0]&&plan.intendedOutputs[0].aspect||'16:9');e('planTitle').textContent=text(plan&&plan.product&&plan.product.name?plan.product.name+' motion plan':'Motion plan');StillMade.render('scenes',scenes.length?scenes.map(card):[{tag:'p',className:'empty',text:'Your scene cards will appear here. The structured source stays out of the way.'}]);button.textContent=scenes.length?'Use this plan':'Create plan from brief'};StillMade.onInput(values=>{const incoming=values.plan||values.brief||'';source.value=incoming;show(read(incoming))});source.addEventListener('input',()=>show(read(source.value)));button.addEventListener('click',async()=>{button.disabled=true;e('status').textContent='Checking copy, timing, and scene IDs…';try{const result=await StillMade.run({plan:source.value});const plan=read(result.designPackage);show(plan);e('status').textContent=String(result.report.sceneCount)+' scenes · '+String(result.report.durationSec)+' seconds · ready for Frame Review.'}catch(error){e('status').textContent=error.message||'The plan could not be prepared.'}finally{button.disabled=false}});show(null);"
|
|
77
|
-
},
|
|
78
|
-
"tests": [
|
|
79
|
-
{
|
|
80
|
-
"name": "Build a zero-credit fallback motion plan",
|
|
81
|
-
"input": {
|
|
82
|
-
"brief": "Create a StillMade product-launch motion graphic."
|
|
83
|
-
},
|
|
84
|
-
"expected": {
|
|
85
|
-
"designPackage": "{\"schemaVersion\":1,\"revision\":\"local-49\",\"kind\":\"motion-design-package\",\"brief\":\"Create a StillMade product-launch motion graphic.\",\"audience\":\"Product-minded creative teams\",\"creativeIntent\":{\"idea\":\"Show the product as a living creative system\",\"tone\":\"confident, precise, cinematic\",\"visualLanguage\":\"editorial product UI, oversized type, clean vector geometry\",\"motionCharacter\":\"restrained acceleration with decisive cuts\",\"density\":\"open\",\"avoid\":[\"generic slideshow\",\"floating mockup carousel\",\"invented product claims\"]},\"constraints\":{\"required\":[\"Use only supplied product evidence and exact saved assets\",\"Keep the composition editable\"],\"preferences\":[\"Prefer coded SVG, kinetic type, masks, camera moves, and real UI\"],\"locks\":[]},\"references\":[],\"intendedOutputs\":[{\"aspect\":\"16:9\",\"durationSec\":30,\"channel\":\"product launch\"}],\"style\":{\"background\":\"#0A0A0A\",\"foreground\":\"#F7F0DB\",\"accent\":\"#F2A93B\",\"fontDirection\":\"editorial grotesk with monospace details\"},\"product\":{\"name\":\"StillMade\",\"url\":\"\",\"targetBuyer\":\"creative teams\",\"promise\":\"Build complete visual productions from connected modular Blocks\",\"availability\":\"\",\"cta\":{\"label\":\"Build with StillMade\",\"destination\":\"\"},\"benefits\":[]},\"scenes\":[{\"id\":\"scene-1\",\"goal\":\"Open with a singular promise\",\"copy\":{\"eyebrow\":\"STILLMADE\",\"headline\":\"Make the whole thing.\",\"support\":\"One connected creative system.\"},\"durationSec\":4,\"visualApproach\":\"Oversized masked typography and a precise vector aperture\",\"layout\":\"centered poster\",\"motionIntent\":\"restrained reveal, then sharp exit\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]},{\"id\":\"scene-2\",\"goal\":\"Establish the modular workflow\",\"copy\":{\"eyebrow\":\"BLOCKS THAT WORK TOGETHER\",\"headline\":\"From idea to final cut.\",\"support\":\"Plan, review, design, and edit in one flow.\"},\"durationSec\":5,\"visualApproach\":\"Editable node path with semantic icons and cropped UI evidence when supplied\",\"layout\":\"offset editorial\",\"motionIntent\":\"measured camera push with sequential connections\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]},{\"id\":\"scene-3\",\"goal\":\"Show visual review before animation\",\"copy\":{\"eyebrow\":\"APPROVE THE LOOK FIRST\",\"headline\":\"See the frames. Then make them move.\",\"support\":\"Choose a 3, 5, or 10 second review cadence.\"},\"durationSec\":5,\"visualApproach\":\"A grid of exact approved styleframes with one selected frame expanding full bleed\",\"layout\":\"modular proof grid\",\"motionIntent\":\"staggered tiles, magnetic selection, mask expansion\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]},{\"id\":\"scene-4\",\"goal\":\"Reveal coded construction\",\"copy\":{\"eyebrow\":\"EDITABLE BY DESIGN\",\"headline\":\"Real layers. Real timing. Real control.\",\"support\":\"SVG, kinetic type, camera, transitions, and exact assets.\"},\"durationSec\":6,\"visualApproach\":\"Split view between coded vector layers and the live composition\",\"layout\":\"copy on the left with product UI on the right\",\"motionIntent\":\"typewriter detail, controlled parallax, precise callouts\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]},{\"id\":\"scene-5\",\"goal\":\"Show the final editor handoff\",\"copy\":{\"eyebrow\":\"FINISH IN YOUR EDITOR\",\"headline\":\"Polish without starting over.\",\"support\":\"Every scene arrives as an editable timeline.\"},\"durationSec\":5,\"visualApproach\":\"Full-width timeline with layered motion scene clips and a final export target\",\"layout\":\"full-bleed product UI\",\"motionIntent\":\"timeline scrub, clip focus, restrained zoom\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]},{\"id\":\"scene-6\",\"goal\":\"Close on the product promise\",\"copy\":{\"eyebrow\":\"STILLMADE\",\"headline\":\"Make more than a clip.\",\"support\":\"Build the system behind it.\"},\"durationSec\":5,\"visualApproach\":\"Return to the opening aperture as the product mark resolves\",\"layout\":\"centered hero statement\",\"motionIntent\":\"confident lockup and clean hold\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]}],\"audio\":{\"mode\":\"silent\",\"assetIds\":[],\"captions\":[],\"notes\":\"Designed to work silently; optional sound design can accent transitions.\"},\"unresolved\":[\"Add exact StillMade UI screenshots or recordings as content assets before claiming visible product behavior.\"],\"branch\":{\"intent\":\"create\",\"parentRevision\":null}}",
|
|
86
|
-
"report": {
|
|
87
|
-
"schemaVersion": 1,
|
|
88
|
-
"source": "local-fallback",
|
|
89
|
-
"sceneCount": 6,
|
|
90
|
-
"durationSec": 30,
|
|
91
|
-
"creditCost": 0,
|
|
92
|
-
"ready": true
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
]
|
|
97
|
-
};
|