validate_scene
Validate a scene spec against the schema without rendering. Get { ok, errors } to confirm structure before render.
Instructions
Validate a scene spec against the schema without rendering. Returns { ok, errors? }. Useful to check structure before render_scene. PICK THE TRACK KIND BY CONTENT SHAPE, not by default. Do not reach for 'list-reveal' unless the content is genuinely a flat enumeration of >=3 peer items. Use 'flow' when describing a pipeline / sequence / before→after path (A → B → C). Use 'hub' when one central concept connects to 2-4 related satellites. Use 'comparison' for a two-sided contrast (old vs new, before vs after). Use 'title-overlay' for a hero text card with no diagram. Call list_examples first to see a canonical spec for each kind before authoring. Both portrait (1080x1920, default — reels / shorts / TikTok) and landscape (1920x1080 — YouTube / LinkedIn / web embeds) are supported; ask the user or infer from context which they want. Layouts auto-flip (e.g. 'flow' is vertical in portrait, horizontal in landscape).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| spec | Yes | A scene spec. Top-level: { id, durationFrames, fps?, width?, height?, theme?, background?, backgroundImage?, palette?, tracks[] }. durationFrames/fps MUST be between 4 and 6 seconds. Default fps=30, width=1080, height=1920. theme='light' (default) or 'dark' selects the Wednesday Solutions palette. background overrides the theme's canvas color; set 'transparent' for an alpha-channel .mov render. backgroundImage={source(URL or public/ path), opacity?=1, fit?='cover'|'contain', tint?, tintOpacity?=0} renders behind tracks. palette={background?, ink?, inkMuted?, inkDim?, accent?, accentDeep?, hairline?} overrides individual theme colors. Each track has { kind, id, startFrame, endFrame, enter?, exit? } plus kind-specific fields. Kinds: 'title-overlay' (text), 'list-reveal' (rows[].{text, iconName?, revealAtFrame}, position{x,y}), 'flow' (nodes[].{iconName, label}, position{x,y}, direction='horizontal', revealCadenceFrames=35 — left-to-right icon flow with arrows drawing between them), 'comparison' (left{iconName,label,subLabel?}, right{iconName,label,subLabel?}, divider{label='vs', showLine=true} — side-by-side contrast with a center divider), 'hub' (center{iconName,label}, satellites[2-4].{iconName,label}, position{x,y}, revealCadenceFrames=22 — central icon with N satellites connecting in via lines), 'icon' (name, position, sizePx?, color?), 'text' (text, position, fontSizePx?, color?), 'lottie' (source, position, sizePx?, loop?). Position x,y are 0..1 fractions of canvas. |