pixoo-mcp-server
An MCP server that renders and pushes styled text, pixel art, scenes, dashboards, and animations to Divoom Pixoo LED displays (Pixoo-64/32/16) over the local network.
Render styled text —
pixoo_display_text: themes, gradient palettes, shadows, outlines, auto-fit, positioning, optional brightness control, with a preview image returned.Compose full scenes —
pixoo_compose_scene: up to 50 layered elements (text, icons, rects, circles, lines, progress bars, sparklines, bitmaps, pixels, images, sprites), gradients/themes, and animations via effect presets or keyframes.Push images —
pixoo_push_image: load an image from a local path or HTTPS URL, resize it (contain/cover/fill, nearest/lanczos3/mitchell kernels), and push it to the display.Device-native text overlays —
pixoo_overlay_text: set or clear persistent scrolling overlays on 20 slots using 115 device-rendered fonts.Control the device —
pixoo_control_device: read or change brightness, screen on/off, channel, and clock face, returning live status.Discover devices —
pixoo_discover_devices: find Pixoo devices on the LAN via Divoom's cloud endpoint and report their IPs.Get design guidance —
pixoo_design_brief: craft rules, live device context, and pre-filled next-tool suggestions for text, scene, dashboard, animation, pixel-art, or troubleshooting topics.Reference resources — live device status plus icon, theme, and design-guide registries via MCP resources.
Allows using Cloudflare R2, KV, or D1 as swappable storage backends for managing server data and display assets.
Enables loading, resizing, and pushing JPEG images directly to Divoom Pixoo LED matrices.
Includes support for OpenTelemetry instrumentation to provide observability and monitoring of server operations.
Provides support for using Supabase as a storage backend provider for server data and configurations.
Supports loading and pushing SVG vector graphics to Divoom Pixoo devices with automatic resizing to the display grid.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pixoo-mcp-serverdisplay 'Meeting in Progress' in red scrolling text and set brightness to 50"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Overview
Divoom Pixoo LED matrix displays (Pixoo-64 primary; 16 and 32 also supported) on the local network. Render and push styled text, layered scenes, dashboards, and animations, or control device state, from any MCP client. Runs as a stdio process or a local Streamable HTTP server.
Tools
Tool | Description |
| Render styled text (theme, gradient, shadow, outline, auto-fit) onto the display and push it. Returns the rendered frame as an image. |
| Compose a full scene: layered elements (text, icons, widgets, shapes, bitmaps, images, sprites) with per-element effects and keyframes, static or animated. Returns the rendered scene as an image. |
| Load an image (absolute local path or https URL), resize it to the LED grid, and push it. Returns the downsampled result as an image. |
| Set or clear a device-native scrolling text overlay. Uses device-rendered fonts; overlays persist across channel switches until cleared. |
| Read or change device state: brightness, screen on/off, channel, or clock face. Call with no params for a status read. |
| Find Pixoo devices on the local network via Divoom's cloud discovery endpoint. Run once during setup to find device IPs. |
| Return craft guidance and live device context for a design topic. Covers legibility rules, palette discipline, layout zones, animation budget, and pre-filled next-tool suggestions. |
Resources
Resource | Description |
| Live snapshot of the connected Pixoo display: reachable, channel, brightness, screen state, and display size |
| Theme and palette registry with background gradients, default text palettes, accent colors, and swatch values |
| Built-in icon names organized by category (weather, arrows, status, media) |
| Long-form 64px craft guide: legibility floors, palette discipline, layout zones, animation budget, and known device behaviors |
All resource data is also reachable via tools. pixoo_design_brief surfaces the design guide content per topic; pixoo_control_device returns live device state equivalent to pixoo://device/status.
Related MCP server: mcp-divoom-lan
Capability reference
pixoo_display_text tool
Named scene themes set background gradient and default text palette in one parameter (
midnight,ember,claude,ice,neon,forest,mono)Style block: palette ramps (
ember,ice,neon,fire,lavender,claude,mono) or a custom gradient/flat color, optional drop shadow, 1px outline, integer scale 1–8Semantic positioning (
x: "center",y: "bottom") or absolute pixel coordinates; multi-line text stacks vertically with configurable alignmentAuto-fit overflow tries standard font, then compact, then scroll; every fit decision is reported in
layout[]with anaction(shrunk-to-compact,scrolling,wrapped,truncated,clipped)Optional
brightness(0–100) applied before push — a failure is a warning via an enrichment notice, not a tool errorReturns the rendered frame as an image content block;
outputFilesis populated only whenPIXOO_OUTPUT_DIRis configured
pixoo_compose_scene tool
Up to 50 layered elements rendered back-to-front:
text,icon,rect,circle,line,progress,sparkline,bitmap,pixels,image,spriteBackground: solid color, gradient (vertical, horizontal, or radial), or named theme
Animation via named effect presets (
float,scroll-left,scroll-right,pulse,blink,twinkle,drift,fade-in,fade-out) or raw per-property keyframe arrays — 1–40 frames at 10–2000ms per frame (default 150ms)imageandspriteelements accept an absolute local path or an https URL; a suppliedoutputpath must be absolute with no traversal segmentsStatic scenes return a PNG preview; animations return a labeled contact-sheet PNG plus a saved GIF (GIF preview is inconsistent across MCP clients)
Typed failures for
asset_not_found,invalid_color, andunknown_icon, alongside the shared device-error reasons
pixoo_push_image tool
Accepts an absolute local file path or an https (not http) URL
Three fit modes:
contain(letterbox),cover(crop to fill),fill(stretch)Three resize kernels:
nearestfor pixel art (default),lanczos3for photos,mitchellfor a balanceReturns the exact resized result as an image content block before it is pushed
pixoo_overlay_text tool
mode: "set"adds or updates an overlay on one of 20 independent slots (id0–19);mode: "clear"removes it115 device-rendered font IDs (0–114); overlays persist across channel switches until explicitly cleared
Configurable
x/y(0–64), scrolldirection(left/right),speed(0–100), andalign; color is#RRGGBBhex only — named colors aren't supported hereDevice-rendered, not previewable — for styled, previewable text use
pixoo_display_text
pixoo_control_device tool
Call with no params to read state only; supply any of
brightness(0–100),screen(on/off),channel(faces/cloud/visualizer/custom), orclockFaceIdto apply changes before the read-backappliedlists which requested settings succeeded; a failed setting is omitted fromappliedand reported via an enrichment notice instead of failing the callAlways returns current
reachable,channel,brightness,screenOn, andclockId(the latter three absent when the device is unreachable)
pixoo_discover_devices tool
Queries Divoom's cloud discovery endpoint (
app.divoom-gz.com) — requires internet access even for local device controlReturns each device's name, numeric ID, and LAN IP to set as
PIXOO_IPWhen
PIXOO_IPis already configured, flags whether it matches a discovered device (configuredIpFound) and notes a mismatchtimeoutMsconfigurable 1000–30000ms (default 5000ms)
pixoo_design_brief tool
Six topics:
text,scene,dashboard,animation,pixel-art,troubleshootingReturns markdown craft guidance (legibility floors, palette discipline, layout zones, animation budgets) plus a live
deviceContextsnapshotnextToolSuggestionsare pre-filled with ready-to-use arguments tailored to the topic and current device state (e.g. suggestspixoo_discover_deviceswhen the device is unreachable)Also returns
availableThemesandiconCategoriesfor direct use in other tools
pixoo://device/status resource
Live snapshot:
reachable,channel,brightness,screenOn,clockId,displaySize,configuredIpNo cache — every read reaches the device; degrades to
reachable: falseinstead of erroring when the device is unreachableEquivalent to calling
pixoo_control_devicewith no params
pixoo://reference/themes resource
Every registered theme (background gradient or solid, default text palette, accent color, shadow flag) and every named palette (gradient stop pair)
themeNames/paletteNamesarrays for direct use in thetheme/paletteparametersCompile-time constants — cached for 24h
pixoo://reference/icons resource
Every built-in icon name, its category, and its SVG
viewBox, plus abyCategorygrouping (weather, arrows, status, media)Use a
namefrom this registry inpixoo_compose_sceneicon elementsCompile-time constants — cached for 24h
pixoo://reference/design-guide resource
Long-form markdown: legibility floors, palette discipline, layout zones (top/middle/bottom strip pixel ranges), animation budget, pixel art rules, and known device behaviors (e.g. channel must be
customto show pushed content)text/markdownmime type; compile-time constant, cached for 24hSame content
pixoo_design_briefsurfaces per topic — this resource is the complete reference in one document
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
Pixoo-specific:
Requires a Divoom Pixoo LED matrix display on the local network; primary target is the Pixoo-64 (16 and 32 also supported)
All composition happens in an RGBA canvas pipeline on the host (
@cyanheads/pixoo-toolkit) — the device receives final RGB frames, never raw drawing commandsStyled text engine: gradient palette ramps, drop shadows, outlines, integer scale, semantic alignment — no manual pixel math or bitmap letterforms required
Push pacing: device commands serialized with a configurable minimum inter-push interval (default 1000ms) to prevent device freezes
Animation capped at 40 frames (device instability beyond this); contact-sheet PNG preview for animations (GIF preview is inconsistent across MCP clients)
Agent-friendly output:
Preview-as-content — render tools return the upscaled (8×, 512px) output as an image content block, so the calling model sees exactly what was drawn, before and after push
Layout transparency — every silent renderer decision (font fallback, truncation, scroll engaged, element clipped) is reported in
layout[]so agents can inspect and refineDevice truth —
pushedreflects the device ACK;deviceStateafter a push flags visibility issues (screen off, brightness ≤ 10, wrong channel) as enrichment notices rather than failuresGraceful degradation — render succeeds and returns the preview even when the device is unreachable, so the agent keeps its work
Getting started
Add the following to your MCP client configuration file. Run pixoo_discover_devices to find your Pixoo's IP, then set PIXOO_IP below.
{
"mcpServers": {
"pixoo-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/pixoo-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"PIXOO_IP": "192.168.1.50"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"pixoo-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/pixoo-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"PIXOO_IP": "192.168.1.50"
}
}
}
}Or with Docker:
{
"mcpServers": {
"pixoo-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"-e", "PIXOO_IP=192.168.1.50",
"ghcr.io/cyanheads/pixoo-mcp-server:latest"
]
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 PIXOO_IP=192.168.1.50 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.4.0 or higher (or Node.js v24+).
A Divoom Pixoo LED matrix display on the local network (Pixoo-64, Pixoo-32, or Pixoo-16). Discovery tools and pure-render tools (
push: false) work without a configured device.
Installation
Clone the repository:
git clone https://github.com/cyanheads/pixoo-mcp-server.gitNavigate into the directory:
cd pixoo-mcp-serverInstall dependencies:
bun installConfigure environment:
cp .env.example .env
# edit .env and set PIXOO_IPConfiguration
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
Variable | Description | Default |
| Device IP address on the local network. Required for device tools ( | — |
| Display size in pixels: |
|
| Directory for auto-saving preview PNG and GIF files. When unset, previews are returned in-response only. | — |
| Minimum interval between device pushes in milliseconds. Prevents device freeze from rapid-fire commands. |
|
| Transport: |
|
| HTTP server port. |
|
| HTTP session handling: |
|
| Authentication: |
|
| Log level ( |
|
| Directory for log files (Node.js only). |
|
| Storage backend: |
|
| Enable OpenTelemetry instrumentation (spans, metrics, completion logs). |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Build and run:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:httpRun checks and tests:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t pixoo-mcp-server .
docker run --rm -e PIXOO_IP=192.168.1.50 -p 3010:3010 pixoo-mcp-serverThe Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/pixoo-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| Resource definitions ( |
|
|
| Pure rendering pipeline: element renderers, styled-text engine, themes, icons, effect compiler, preview encoding. No device dependency. |
| Unit and integration tests mirroring |
Development guide
See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storageThe renderer (
src/renderer/) is pure — no device dependency, testable without hardwareAll device calls go through
PixooService; everyPixooResultis checked — never assume a push succeeded
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
Available Tools
7 toolspixoo_compose_scenepixoo_compose_sceneAIdempotent
Compose a full scene: layered elements (text, icons, widgets, shapes, bitmaps, images, sprites) with per-element effects and keyframes, static or animated. Returns the rendered scene as an image content block for immediate inspection. Elements render back-to-front in array order. For text-only display use pixoo_display_text; run pixoo_design_brief with topic "scene" or "dashboard" for layout and palette guidance.
| Name | Required | Description | Default |
|---|---|---|---|
| push | No | Push to device (default: true). | |
| speed | No | Milliseconds per frame for animations (default: 150ms). | |
| frames | No | Number of animation frames (1–40, default: 1). 20 frames at 150ms ≈ 3s loop. | |
| output | No | Absolute, already-normalized path to save the first frame to, in addition to the PIXOO_OUTPUT_DIR auto-save when that is configured. Both paths are reported in outputFiles. | |
| elements | Yes | Scene elements rendered back-to-front. Up to 50 elements. | |
| background | Yes | Scene background: solid color, gradient, or named theme. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| frames | No | Number of frames in the rendered output (1 for static, 2–40 for animations). |
| layout | No | Layout report for each element. |
| notice | No | Warning or informational notice about the render or push. |
| pushed | No | True when the device acknowledged the push. False when push: false or push failed. |
| deviceState | No | Device state after the push. Absent when push: false. |
| outputFiles | No | Absolute paths to saved output files (PNG for static, GIF for animations). Present only when PIXOO_OUTPUT_DIR is configured or output is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With idempotentHint=true and destructiveHint=false covering safety, the description adds useful runtime context: it returns an image content block for immediate inspection and states back-to-front array rendering order. It does not mention the default push=true behavior or output-file side effects, but those are visible in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning their place: core capability, return behavior, rendering order, then routing/guidance. Core information is front-loaded and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool, the description covers what the tool does, what the agent gets back, how layering works, and which sibling to use instead. The rich input schema and output schema handle the parameter and return-value details, so nothing critical for selecting or invoking the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters and element variants. The description adds no parameter-specific meaning beyond the z-order note, which echoes the schema's 'elements rendered back-to-front' text, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource, "Compose a full scene," and enumerates the element categories and animation modes. It also distinguishes itself from pixoo_display_text, so an agent can tell composition apart from a simpler text-only sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly routes text-only cases to pixoo_display_text and points to pixoo_design_brief with topic "scene" or "dashboard" for layout and palette guidance. This is an explicit when-to-use/alternative signal rather than a generic hint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pixoo_control_devicepixoo_control_deviceAIdempotent
Read or change device state: brightness (0–100), screen on/off, channel, or clock face. Call with no params to read current state only. Supply any params to apply changes before reading back state. Use pixoo_discover_devices first if PIXOO_IP is not yet configured.
| Name | Required | Description | Default |
|---|---|---|---|
| screen | No | Turn the display screen on or off. | |
| channel | No | Switch to a channel: faces, cloud, visualizer, or custom. | |
| brightness | No | Set display brightness (0–100). | |
| clockFaceId | No | Select a clock face by ID (channel must be faces). |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| applied | No | Settings successfully applied in this call (e.g. "brightness:80", "screen:on"). Empty when called with no params or all changes failed. A requested setting that failed is absent here and reported in a notice instead. |
| channel | No | Current channel name (faces, cloud, visualizer, or custom). Absent when device is unreachable. |
| clockId | No | Current clock face ID (faces channel only). Absent on other channels or when device is unreachable. |
| screenOn | No | True if the screen is on. Absent when device is unreachable. |
| reachable | No | True if device responded to the status read. |
| brightness | No | Current brightness level (0–100). Absent when device is unreachable. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the call idempotent and non-destructive, so the description's main job is to disclose the threshold value of calling it with no params vs applying changes before reading back state. It also usefully notes that pixoo_discover_devices may be needed first. It does not provide deeper details like persistence or authentication, but none are essential here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, no filler, operationally efficient. The first sentence defines the tool's scope, the second explains the two calling patterns, and the third handles the environment prerequisite.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an optional padded 4-param device-control tool with fully described input fields and an existing output schema, the description covers the main workflow and prerequisite. An agent has enough to invoke it correctly: choose only params if changing state, else omit them to read state.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents every parameter at 100% coverage, so a baseline of 3 applies. The description adds helpful usage semantics by making the interaction rule explicit: 'no params = read', 'any params = apply then read back'. That is valuable beyond the schema structure.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific operation ('Read or change device state') and enumerates the exact dimensions affected: brightness, screen on/off, channel, and clock face. This clearly separates it from the sibling content-related tools like pixoo_display_text and pixoo_push_image.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly explains when to call with no params (read only) versus with params (apply changes), and names pixoo_discover_devices as a prerequisite when PIXOO_IP is unknown. It could slightly strengthen by naming which siblings are NOT appropriate for device-state changes, but the guidance is otherwise clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pixoo_design_briefpixoo_design_briefARead-only
Return craft guidance and live device context for a design topic. Covers legibility rules, palette discipline, layout zones, animation budget, and pre-filled next-tool suggestions based on current device state. The orientation tool to run before authoring a scene, dashboard, or animation — or when troubleshooting display issues.
| Name | Required | Description | Default |
|---|---|---|---|
| topic | Yes | Design topic: text (styled text guidance), scene (composition + layout zones), dashboard (widgets + metrics), animation (motion budget + effects), pixel-art (bitmap + sprite guidance), troubleshooting (device + display issues). |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| topic | No | The topic that was requested. |
| craftGuidance | No | Markdown-formatted craft rules: legibility floors, palette discipline, layout zones, and technique guidance specific to the topic. |
| deviceContext | No | Live device state snapshot at the time of the request. |
| iconCategories | No | Built-in icon names grouped by category (weather, arrows, status, media). Use names in pixoo_compose_scene icon elements. |
| availableThemes | No | Available named scene themes (e.g. "midnight", "ember"). Use in background.theme or pixoo_display_text theme param. |
| nextToolSuggestions | No | Suggested next steps based on topic and device state. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already tells agents this is a safe read-only operation, and the description adds useful context about what it returns: craft guidance, live device context, and next-tool suggestions. It does not disclose details about device unavailability or failure modes, but the annotation lowers the burden on the description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loads the core purpose, and wastes no words. It covers scope, coverage areas, and a clear temporal use case without over-explaining.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with a full enum description, an output schema, and a readOnly annotation, the description is sufficiently complete. It tells agents what the tool does, what topics it covers, when to run it, and how it relates to downstream authoring tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully documents the only parameter, 'topic,' including an enum and per-value descriptions. The description's mention of topics like legibility rules, palette discipline, layout zones, and animation budget reinforces the enum but does not add essential meaning beyond the schema already covers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pair ('Return craft guidance and live device context for a design topic') and clearly defines the tool's role as an orientation tool rather than an authoring tool. It distinguishes itself from sibling tools by framing it as the step to run before authoring or troubleshooting.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: before authoring a scene, dashboard, or animation, and when troubleshooting display issues. It does not explicitly name alternative tools or exclusion criteria, but the guidance is clear enough to route an agent correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pixoo_discover_devicespixoo_discover_devicesARead-only
Find Pixoo devices on the local network via Divoom's cloud discovery endpoint (requires internet — queries app.divoom-gz.com). Run once during initial setup to find device IPs; set PIXOO_IP in server configuration to enable all other tools. For ongoing device control use pixoo_control_device.
| Name | Required | Description | Default |
|---|---|---|---|
| timeoutMs | No | Discovery timeout in milliseconds (default: 5000ms). |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Recovery hint when no devices found or IP mismatch. |
| devices | No | Discovered Pixoo devices on the local network. |
| configuredIp | No | Currently configured PIXOO_IP value (absent if not set). |
| configuredIpFound | No | True if PIXOO_IP matches a discovered device; false signals an IP mismatch. Absent when PIXOO_IP is not set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly and openWorld hints. The description adds value by disclosing the network dependency (requires internet) and the specific external endpoint (app.divoom-gz.com), which are important behavioral traits not captured by annotations. Does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, front-loaded with the primary purpose, then the setup context and routing to an alternative. Every sentence earns its place; no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Moderate-low complexity tool with an output schema, so return values need not be described. The description covers purpose, network prerequisites, and post-condition (set PIXOO_IP). Slightly more could be said about what discovery returns, but the output schema already handles that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with clear description, default, minimum, and maximum for timeoutMs. The narrative description adds nothing about the parameter, but with full schema coverage the baseline of 3 is appropriate since no extra meaning is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('Find Pixoo devices on the local network') and identifies the method via Divoom's cloud discovery endpoint. It distinguishes itself from all sibling tools, which are for display, control, or composition, by being the discovery step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States explicitly when to use this tool ('Run once during initial setup'), what to do with the result (set PIXOO_IP in server configuration), and names the alternative for ongoing control (pixoo_control_device). This gives an agent complete routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pixoo_display_textpixoo_display_textAIdempotent
Render styled text (theme, gradient, shadow, outline, auto-fit) onto the Pixoo display and push it. Returns the rendered frame as an image content block for immediate inspection. The primary tool for text-only display — for layers, icons, widgets, or animations use pixoo_compose_scene. Run pixoo_design_brief with topic "text" first for palette and legibility guidance.
| Name | Required | Description | Default |
|---|---|---|---|
| font | No | Font variant: standard (5×7) or compact (3×5). Auto-fit will choose if omitted. | |
| push | No | Push the rendered frame to the device (default: true). | |
| text | Yes | Text to display. String or array of lines. | |
| align | No | Multi-line text alignment (default: center). | |
| style | No | Text style: palette, shadow, outline, scale. | |
| theme | No | Named scene theme — sets background gradient and default text palette. | |
| effect | No | Animation effect. auto = scroll only when text overflows. Produces a multi-frame result. | |
| position | No | Text position on the display. | |
| background | No | Background color or gradient. Overrides theme background when set. | |
| brightness | No | Set device brightness before push (0–100). Failure is a warning, not an error. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| layout | No | Layout report: every fit decision the renderer made. |
| notice | No | Warning or informational message about the render or push. |
| pushed | No | True when the device acknowledged the push. |
| deviceState | No | Device state after the push. Absent when push: false. |
| outputFiles | No | Absolute paths to saved PNG preview files. Present only when PIXOO_OUTPUT_DIR is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the annotations (idempotentHint true, destructiveHint false) by exposing the push-to-device side effect and the fact that the tool returns the rendered frame as an image content block for inspection. This is valuable behavioral information about what physically happens to the display and what the agent should expect in the output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, front-loaded with the primary purpose, and every sentence earns its place. It covers the core action, the output behavior, the sibling distinction, and a design brief next step all without significantly bloating.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Combined with the thorough input schema, output schema, and annotations, the description is complete enough for an agent to decide when to call this tool, what parameters to consider, what to expect from the return, and what to do for richer scenes. The shape does not have an obvious missing aspect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema is fully documented at 100% coverage with detailed descriptions for font, text, align, style, theme, effect, position, background, brightness, and push. The tool description adds no substantive param-level semantics beyond the schema already provides. It names a few style aspects, but the schema itself explains those concepts in detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Render'), a specific resource ('text onto the Pixoo display'), and a push-and-return behavior, ending with an image content block. It also fully differentiates itself from the available sibling ('ptixoo_compose_sceene') by declaring itself as the primary text-on-console display tool. This gives the agent enough high-level directional information before inspecting the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says this is the primary tool for text-only display and directs the agent to 'pixoo_compose_cene' for layers, icons, widgets, or animations. It also recommends running 'pixoo_design_brief' with topic 'text' first. That is a useful when-to-use vs. when-not-to-use instruction sequence.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pixoo_overlay_textpixoo_overlay_textAIdempotent
Set or clear a device-native scrolling text overlay. Use mode "set" to add or update an overlay on a slot (0–19); use mode "clear" to remove it. Overlays use device-rendered fonts (115 font IDs, 0–114) and persist across channel switches until explicitly cleared with mode "clear". Not previewable — rendering happens on-device. Best for persistent tickers over pushed scenes; for styled, previewable text use pixoo_display_text instead.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | X start position on display (default: 0). | |
| y | No | Y start position on display (default: 0). | |
| id | Yes | Overlay slot ID (0–19). Each ID is an independent overlay layer. | |
| font | No | Device font ID (0–114). 0 = default, 18 = arrows, 20 = °C/°F. Device-rendered; no preview. | |
| mode | Yes | set = add/update overlay; clear = remove it. | |
| text | No | Text to display (required for mode=set). | |
| align | No | Text alignment (default: left). | left |
| color | No | Text color as CSS hex color (default: white). | #ffffff |
| speed | No | Scroll speed (0–100, device units; default: 50). | |
| width | No | Text region width in pixels (optional; defaults to display width). | |
| direction | No | Scroll direction (default: left). | left |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | The overlay slot ID (0–19) that was operated on. |
| mode | No | Operation performed: "set" (overlay added/updated) or "clear" (overlay removed). |
| error | No | Present when the call failed. Absent on success. |
| acknowledged | No | True when the device confirmed the overlay command (error_code: 0). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover idempotency and non-destructiveness, so the description correctly adds behavioral context beyond them: overlays persist across channel switches, rendering happens on-device, and the feature is not previewable. This is genuinely useful invocation-relevant detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief, front-loaded with the core action, and every sentence contributes: action, mode usage, persistence detail, limitation, and sibling routing. No filler or tautology.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 11 parameters, 2 required, and a rich input schema, the description captures the behavioral context an agent needs: mode semantics, overlay slots, persistence, and when to choose this tool versus pixoo_display_text. No meaningful selection or invocation context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the description reinforces slot/font semantics and mode behavior, but every parameter already has a descriptive schema helper. It does not need to repeat the full parameter list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses specific verbs ('Set or clear') and a specific resource ('device-native scrolling text overlay'), immediately distinguishing its function. It also names the sibling it is not — pixoo_display_text — so an agent can tell them apart without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Describes exactly when to invoke 'set' versus 'clear', and explicitly recommends pixoo_display_text for styled, previewable text. This gives clear routing guidance for the main alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pixoo_push_imagepixoo_push_imageAIdempotent
Load an image (absolute local path or https URL), resize it to fit the LED grid, and optionally push it to the display. Returns the downsampled result as an image content block so you see exactly what the display received. Nearest-neighbor kernel preserves pixel art; use lanczos3 or mitchell for photos.
| Name | Required | Description | Default |
|---|---|---|---|
| fit | No | Resize fit mode: contain (letterbox), cover (crop to fill), fill (stretch). | contain |
| push | No | Push the resized image to the device (default: true). | |
| kernel | No | Resize kernel: nearest for pixel art, lanczos3 for photos, mitchell for a balance. | nearest |
| source | Yes | Absolute local file path or https (not http) URL of the image to display. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Warning or informational message. |
| pushed | No | True when the device acknowledged the push. |
| deviceState | No | Device state after the push. Absent when push: false. |
| outputFiles | No | Absolute paths to saved PNG preview files. Present only when PIXOO_OUTPUT_DIR is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover idempotency (indy), open-world behavior, and not destructive. The description adds valuable behavioral detail: it returns the exact downsampled result as an image content block, and it makes explicit the resize/display pipeline. It doesn' t contradict the annotations. Slight gaps such as failure modes, but for a non-destuctive image utility this is solid.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three compact sentences with no filler. It front-loads the main pipeline, then covers optional push behavior, return value, and kernel guidance. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given only 4 parameters, 1 required, and no output schema explain, the description is sufficient: covers input source, resizing modes, kernel choice, push default, and return-value semantics. The agent can select parameters from either schema or description, and know exactly what to expect back from the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already defines fit, kernel, push, and source. The description adds real selection guidance on which kernel to choose (nearest for pixel art, lanczos3/mitchell for photos), which is above the baseline and helps the agent pick semantic effective values. Small extra value beyond schema, hence a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the operation clearly: load an image from a local path or HTTPS URL, resize it to fit the LED grid, optionally push to the display, and return the downsampled result. This is a specific verb-plus-resource description. It is functionally distinct from the text/device sibling tools, though it does not explicitly name them or contrast itself with a tool like pixoo_compose_scene.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description outlines the pipeline and the 'optionally push' behavior, which implies a preview-only use case when push=false. It does not explicitly state when to use this tool over siblings such as pixoo_compose_scene, pixoo_overlay_text, or pixoo_control_device. There is enough context for the agent to infer, but no direct that when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v1.1.2- Changed
pixoo_compose_scene1 field changed- changed
Input schema / properties / elements / items / oneOfPrevious value: -[ - { - "description": "Styled text element rendered at a position.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "prefixItems": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "color": { - "description": "Flat text color.", - "type": "string" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "font": { - "description": "Font variant.", - "enum": [ - "standard", - "compact" - ], - "type": "string" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "style": { - "description": "Text style options.", - "properties": { - "color": { - "description": "Flat color override.", - "type": "string" - }, - "outline": { - "description": "1px outline.", - "type": "boolean" - }, - "palette": { - "anyOf": [ - { - "description": "Named built-in color palette for the vertical ramp.", - "enum": [ - "ember", - "ice", - "neon", - "fire", - "lavender", - "claude", - "mono" - ], - "type": "string" - }, - { - "description": "Custom gradient stop: specify top and bottom colors directly.", - "properties": { - "from": { - "description": "Top color.", - "type": "string" - }, - "to": { - "description": "Bottom color.", - "type": "string" - } - }, - "required": [ - "from", - "to" - ], - "type": "object" - } - ], - "description": "Palette name or custom gradient stop for vertical color ramp." - }, - "scale": { - "description": "Integer pixel scale multiplier.", - "maximum": 8, - "minimum": 1, - "type": "integer" - }, - "shadow": { - "description": "Drop shadow.", - "type": "boolean" - } - }, - "type": "object" - }, - "text": { - "description": "Text content to render.", - "type": "string" - }, - "type": { - "const": "text", - "description": "Text element type.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "x": { - "anyOf": [ - { - "description": "Absolute pixel X coordinate (0 = left edge).", - "type": "number" - }, - { - "description": "Semantic horizontal alignment.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - } - ], - "description": "X position (default: 0)." - }, - "y": { - "anyOf": [ - { - "description": "Absolute pixel Y coordinate (0 = top edge).", - "type": "number" - }, - { - "description": "Semantic vertical alignment.", - "enum": [ - "top", - "center", - "bottom" - ], - "type": "string" - } - ], - "description": "Y position (default: 0)." - } - }, - "required": [ - "type", - "text" - ], - "type": "object" - }, - { - "description": "Built-in or custom SVG icon element.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "prefixItems": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "color": { - "description": "Icon fill color.", - "type": "string" - }, - "d": { - "description": "Custom SVG path d attribute.", - "type": "string" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "h": { - "description": "Render height in pixels (default: 12).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "name": { - "description": "Built-in icon name (see pixoo://reference/icons).", - "type": "string" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "palette": { - "description": "Named palette for colored icon.", - "enum": [ - "ember", - "ice", - "neon", - "fire", - "lavender", - "claude", - "mono" - ], - "type": "string" - }, - "type": { - "const": "icon", - "description": "Icon element type.", - "type": "string" - }, - "viewBox": { - "description": "SVG viewBox string (default: \"0 0 16 16\").", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "w": { - "description": "Render width in pixels (default: 12).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "x": { - "anyOf": [ - { - "description": "Absolute pixel X coordinate (0 = left edge).", - "type": "number" - }, - { - "description": "Semantic horizontal alignment.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - } - ], - "description": "X position." - }, - "y": { - "anyOf": [ - { - "description": "Absolute pixel Y coordinate (0 = top edge).", - "type": "number" - }, - { - "description": "Semantic vertical alignment.", - "enum": [ - "top", - "center", - "bottom" - ], - "type": "string" - } - ], - "description": "Y position." - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "description": "Filled or gradient rectangle element.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "prefixItems": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "borderColor": { - "description": "1px border color.", - "type": "string" - }, - "color": { - "description": "Fill color.", - "type": "string" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "gradient": { - "description": "Gradient fill.", - "properties": { - "from": { - "description": "Start color.", - "type": "string" - }, - "to": { - "description": "End color.", - "type": "string" - }, - "type": { - "description": "v = vertical, h = horizontal.", - "enum": [ - "v", - "h" - ], - "type": "string" - } - }, - "required": [ - "type", - "from", - "to" - ], - "type": "object" - }, - "h": { - "description": "Height in pixels.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "rect", - "description": "Rectangle element type.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "w": { - "description": "Width in pixels.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "x": { - "description": "X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "x", - "y", - "w", - "h" - ], - "type": "object" - }, - { - "description": "Filled or outline circle element.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "prefixItems": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "color": { - "description": "Circle color.", - "type": "string" - }, - "cx": { - "description": "Center X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "cy": { - "description": "Center Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "fill": { - "description": "Filled or outline only (default: true).", - "type": "boolean" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "radius": { - "description": "Radius in pixels.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "type": { - "const": "circle", - "description": "Circle element type.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - } - }, - "required": [ - "type", - "cx", - "cy", - "radius" - ], - "type": "object" - }, - { - "description": "Single-pixel line element.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "prefixItems": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "color": { - "description": "Line color.", - "type": "string" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "line", - "description": "Line element type.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "x0": { - "description": "Start X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "x1": { - "description": "End X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y0": { - "description": "Start Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y1": { - "description": "End Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "x0", - "y0", - "x1", - "y1" - ], - "type": "object" - }, - { - "description": "Horizontal progress bar widget.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "prefixItems": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "h": { - "description": "Height in pixels.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "label": { - "description": "Optional label rendered on the bar.", - "type": "string" - }, - "max": { - "description": "Maximum value.", - "type": "number" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "palette": { - "description": "Named palette for gradient fill.", - "enum": [ - "ember", - "ice", - "neon", - "fire", - "lavender", - "claude", - "mono" - ], - "type": "string" - }, - "trackColor": { - "description": "Background track color.", - "type": "string" - }, - "type": { - "const": "progress", - "description": "Progress bar widget type.", - "type": "string" - }, - "value": { - "description": "Current value.", - "type": "number" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "w": { - "description": "Width in pixels.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "x": { - "description": "X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "x", - "y", - "w", - "h", - "value", - "max" - ], - "type": "object" - }, - { - "description": "Sparkline chart widget (line or bar).", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "prefixItems": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "color": { - "description": "Line or bar color.", - "type": "string" - }, - "data": { - "description": "Data points for the chart.", - "items": { - "type": "number" - }, - "minItems": 2, - "type": "array" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "h": { - "description": "Height in pixels.", - "maximum": 9007199254740991, - "minimum": 2, - "type": "integer" - }, - "kind": { - "description": "Chart style (default: line).", - "enum": [ - "line", - "bar" - ], - "type": "string" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "sparkline", - "description": "Sparkline chart widget type.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "w": { - "description": "Width in pixels.", - "maximum": 9007199254740991, - "minimum": 2, - "type": "integer" - }, - "x": { - "description": "X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "x", - "y", - "w", - "h", - "data" - ], - "type": "object" - }, - { - "description": "Bitmap element using explicit palette indices.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "prefixItems": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "palette": { - "description": "Color palette: array of hex colors indexed 0-F.", - "items": { - "type": "string" - }, - "type": "array" - }, - "rows": { - "description": "Row strings of hex palette indices (0-F, space = transparent).", - "items": { - "type": "string" - }, - "type": "array" - }, - "type": { - "const": "bitmap", - "description": "Bitmap element using palette indices.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "x": { - "description": "X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "x", - "y", - "rows", - "palette" - ], - "type": "object" - }, - { - "description": "Sparse scatter of individually colored pixels.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "prefixItems": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "data": { - "description": "Array of pixel positions and colors.", - "items": { - "description": "A single pixel: position and color.", - "properties": { - "color": { - "description": "Pixel color.", - "type": "string" - }, - "x": { - "description": "Pixel X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Pixel Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "x", - "y", - "color" - ], - "type": "object" - }, - "type": "array" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "pixels", - "description": "Sparse pixel dots element.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - } - }, - "required": [ - "type", - "data" - ], - "type": "object" - }, - { - "description": "External image element (local path or https URL).", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "prefixItems": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "fit": { - "description": "Resize fit mode (default: contain).", - "enum": [ - "contain", - "cover", - "fill" - ], - "type": "string" - }, - "h": { - "description": "Target height (default: canvas height).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "kernel": { - "description": "Resize kernel: nearest for pixel art, lanczos3 for photos (default: nearest).", - "enum": [ - "nearest", - "lanczos3", - "mitchell" - ], - "type": "string" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "source": { - "description": "Absolute local file path or https (not http) URL.", - "type": "string" - }, - "type": { - "const": "image", - "description": "Image element (local path or https URL).", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "w": { - "description": "Target width (default: canvas width).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "x": { - "description": "X offset on canvas (default: 0).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Y offset on canvas (default: 0).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "source" - ], - "type": "object" - }, - { - "description": "Sprite sheet element for character or tile art.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "prefixItems": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "bodyColor": { - "description": "Override body color.", - "type": "string" - }, - "cols": { - "description": "Number of columns in the sprite grid.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "darkColor": { - "description": "Override dark/eye color.", - "type": "string" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "path": { - "description": "Absolute local path to the sprite sheet image.", - "type": "string" - }, - "rows": { - "description": "Number of rows in the sprite grid.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "scale": { - "description": "Pixel scale factor.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "type": { - "const": "sprite", - "description": "Sprite sheet element.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "x": { - "anyOf": [ - { - "description": "Absolute pixel X coordinate (0 = left edge).", - "type": "number" - }, - { - "description": "Semantic horizontal alignment.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - } - ], - "description": "X position (default: center)." - }, - "y": { - "description": "Y position (default: 0).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "path", - "cols", - "rows" - ], - "type": "object" - } -]New value: +[ + { + "description": "Styled text element rendered at a position.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "description": "Value at this frame.", + "type": [ + "number", + "string", + "boolean" + ] + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "color": { + "description": "Flat text color.", + "type": "string" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "font": { + "description": "Font variant.", + "enum": [ + "standard", + "compact" + ], + "type": "string" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "style": { + "description": "Text style options.", + "properties": { + "color": { + "description": "Flat color override.", + "type": "string" + }, + "outline": { + "description": "1px outline.", + "type": "boolean" + }, + "palette": { + "anyOf": [ + { + "description": "Named built-in color palette for the vertical ramp.", + "enum": [ + "ember", + "ice", + "neon", + "fire", + "lavender", + "claude", + "mono" + ], + "type": "string" + }, + { + "description": "Custom gradient stop: specify top and bottom colors directly.", + "properties": { + "from": { + "description": "Top color.", + "type": "string" + }, + "to": { + "description": "Bottom color.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ], + "type": "object" + } + ], + "description": "Palette name or custom gradient stop for vertical color ramp." + }, + "scale": { + "description": "Integer pixel scale multiplier.", + "maximum": 8, + "minimum": 1, + "type": "integer" + }, + "shadow": { + "description": "Drop shadow.", + "type": "boolean" + } + }, + "type": "object" + }, + "text": { + "description": "Text content to render.", + "type": "string" + }, + "type": { + "const": "text", + "description": "Text element type.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "x": { + "anyOf": [ + { + "description": "Absolute pixel X coordinate (0 = left edge).", + "type": "number" + }, + { + "description": "Semantic horizontal alignment.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + } + ], + "description": "X position (default: 0)." + }, + "y": { + "anyOf": [ + { + "description": "Absolute pixel Y coordinate (0 = top edge).", + "type": "number" + }, + { + "description": "Semantic vertical alignment.", + "enum": [ + "top", + "center", + "bottom" + ], + "type": "string" + } + ], + "description": "Y position (default: 0)." + } + }, + "required": [ + "type", + "text" + ], + "type": "object" + }, + { + "description": "Built-in or custom SVG icon element.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "description": "Value at this frame.", + "type": [ + "number", + "string", + "boolean" + ] + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "color": { + "description": "Icon fill color.", + "type": "string" + }, + "d": { + "description": "Custom SVG path d attribute.", + "type": "string" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "h": { + "description": "Render height in pixels (default: 12).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "name": { + "description": "Built-in icon name (see pixoo://reference/icons).", + "type": "string" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "palette": { + "description": "Named palette for colored icon.", + "enum": [ + "ember", + "ice", + "neon", + "fire", + "lavender", + "claude", + "mono" + ], + "type": "string" + }, + "type": { + "const": "icon", + "description": "Icon element type.", + "type": "string" + }, + "viewBox": { + "description": "SVG viewBox string (default: \"0 0 16 16\").", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "w": { + "description": "Render width in pixels (default: 12).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "x": { + "anyOf": [ + { + "description": "Absolute pixel X coordinate (0 = left edge).", + "type": "number" + }, + { + "description": "Semantic horizontal alignment.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + } + ], + "description": "X position." + }, + "y": { + "anyOf": [ + { + "description": "Absolute pixel Y coordinate (0 = top edge).", + "type": "number" + }, + { + "description": "Semantic vertical alignment.", + "enum": [ + "top", + "center", + "bottom" + ], + "type": "string" + } + ], + "description": "Y position." + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "description": "Filled or gradient rectangle element.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "description": "Value at this frame.", + "type": [ + "number", + "string", + "boolean" + ] + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "borderColor": { + "description": "1px border color.", + "type": "string" + }, + "color": { + "description": "Fill color.", + "type": "string" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "gradient": { + "description": "Gradient fill.", + "properties": { + "from": { + "description": "Start color.", + "type": "string" + }, + "to": { + "description": "End color.", + "type": "string" + }, + "type": { + "description": "v = vertical, h = horizontal.", + "enum": [ + "v", + "h" + ], + "type": "string" + } + }, + "required": [ + "type", + "from", + "to" + ], + "type": "object" + }, + "h": { + "description": "Height in pixels.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "rect", + "description": "Rectangle element type.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "w": { + "description": "Width in pixels.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "x": { + "description": "X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "x", + "y", + "w", + "h" + ], + "type": "object" + }, + { + "description": "Filled or outline circle element.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "description": "Value at this frame.", + "type": [ + "number", + "string", + "boolean" + ] + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "color": { + "description": "Circle color.", + "type": "string" + }, + "cx": { + "description": "Center X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "cy": { + "description": "Center Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "fill": { + "description": "Filled or outline only (default: true).", + "type": "boolean" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "radius": { + "description": "Radius in pixels.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "type": { + "const": "circle", + "description": "Circle element type.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + } + }, + "required": [ + "type", + "cx", + "cy", + "radius" + ], + "type": "object" + }, + { + "description": "Single-pixel line element.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "description": "Value at this frame.", + "type": [ + "number", + "string", + "boolean" + ] + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "color": { + "description": "Line color.", + "type": "string" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "line", + "description": "Line element type.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "x0": { + "description": "Start X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "x1": { + "description": "End X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y0": { + "description": "Start Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y1": { + "description": "End Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "x0", + "y0", + "x1", + "y1" + ], + "type": "object" + }, + { + "description": "Horizontal progress bar widget.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "description": "Value at this frame.", + "type": [ + "number", + "string", + "boolean" + ] + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "h": { + "description": "Height in pixels.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "label": { + "description": "Optional label rendered on the bar.", + "type": "string" + }, + "max": { + "description": "Maximum value.", + "type": "number" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "palette": { + "description": "Named palette for gradient fill.", + "enum": [ + "ember", + "ice", + "neon", + "fire", + "lavender", + "claude", + "mono" + ], + "type": "string" + }, + "trackColor": { + "description": "Background track color.", + "type": "string" + }, + "type": { + "const": "progress", + "description": "Progress bar widget type.", + "type": "string" + }, + "value": { + "description": "Current value.", + "type": "number" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "w": { + "description": "Width in pixels.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "x": { + "description": "X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "x", + "y", + "w", + "h", + "value", + "max" + ], + "type": "object" + }, + { + "description": "Sparkline chart widget (line or bar).", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "description": "Value at this frame.", + "type": [ + "number", + "string", + "boolean" + ] + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "color": { + "description": "Line or bar color.", + "type": "string" + }, + "data": { + "description": "Data points for the chart.", + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "h": { + "description": "Height in pixels.", + "maximum": 9007199254740991, + "minimum": 2, + "type": "integer" + }, + "kind": { + "description": "Chart style (default: line).", + "enum": [ + "line", + "bar" + ], + "type": "string" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "sparkline", + "description": "Sparkline chart widget type.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "w": { + "description": "Width in pixels.", + "maximum": 9007199254740991, + "minimum": 2, + "type": "integer" + }, + "x": { + "description": "X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "x", + "y", + "w", + "h", + "data" + ], + "type": "object" + }, + { + "description": "Bitmap element using explicit palette indices.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "description": "Value at this frame.", + "type": [ + "number", + "string", + "boolean" + ] + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "palette": { + "description": "Color palette: array of hex colors indexed 0-F.", + "items": { + "type": "string" + }, + "type": "array" + }, + "rows": { + "description": "Row strings of hex palette indices (0-F, space = transparent).", + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "const": "bitmap", + "description": "Bitmap element using palette indices.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "x": { + "description": "X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "x", + "y", + "rows", + "palette" + ], + "type": "object" + }, + { + "description": "Sparse scatter of individually colored pixels.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "description": "Value at this frame.", + "type": [ + "number", + "string", + "boolean" + ] + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "data": { + "description": "Array of pixel positions and colors.", + "items": { + "description": "A single pixel: position and color.", + "properties": { + "color": { + "description": "Pixel color.", + "type": "string" + }, + "x": { + "description": "Pixel X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Pixel Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "x", + "y", + "color" + ], + "type": "object" + }, + "type": "array" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "pixels", + "description": "Sparse pixel dots element.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + } + }, + "required": [ + "type", + "data" + ], + "type": "object" + }, + { + "description": "External image element (local path or https URL).", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "description": "Value at this frame.", + "type": [ + "number", + "string", + "boolean" + ] + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "fit": { + "description": "Resize fit mode (default: contain).", + "enum": [ + "contain", + "cover", + "fill" + ], + "type": "string" + }, + "h": { + "description": "Target height (default: canvas height).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "kernel": { + "description": "Resize kernel: nearest for pixel art, lanczos3 for photos (default: nearest).", + "enum": [ + "nearest", + "lanczos3", + "mitchell" + ], + "type": "string" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "source": { + "description": "Absolute local file path or https (not http) URL.", + "type": "string" + }, + "type": { + "const": "image", + "description": "Image element (local path or https URL).", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "w": { + "description": "Target width (default: canvas width).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "x": { + "description": "X offset on canvas (default: 0).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Y offset on canvas (default: 0).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "source" + ], + "type": "object" + }, + { + "description": "Sprite sheet element for character or tile art.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "description": "Value at this frame.", + "type": [ + "number", + "string", + "boolean" + ] + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "bodyColor": { + "description": "Override body color.", + "type": "string" + }, + "cols": { + "description": "Number of columns in the sprite grid.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "darkColor": { + "description": "Override dark/eye color.", + "type": "string" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "path": { + "description": "Absolute local path to the sprite sheet image.", + "type": "string" + }, + "rows": { + "description": "Number of rows in the sprite grid.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "scale": { + "description": "Pixel scale factor.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "type": { + "const": "sprite", + "description": "Sprite sheet element.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "x": { + "anyOf": [ + { + "description": "Absolute pixel X coordinate (0 = left edge).", + "type": "number" + }, + { + "description": "Semantic horizontal alignment.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + } + ], + "description": "X position (default: center)." + }, + "y": { + "description": "Y position (default: 0).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "path", + "cols", + "rows" + ], + "type": "object" + } +]
7 tool updates
v1.1.1- Changed
pixoo_compose_scene10 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / elements / items / oneOfPrevious value: -[ - { - "description": "Styled text element rendered at a position.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "items": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "color": { - "description": "Flat text color.", - "type": "string" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "font": { - "description": "Font variant.", - "enum": [ - "standard", - "compact" - ], - "type": "string" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "style": { - "description": "Text style options.", - "properties": { - "color": { - "description": "Flat color override.", - "type": "string" - }, - "outline": { - "description": "1px outline.", - "type": "boolean" - }, - "palette": { - "anyOf": [ - { - "description": "Named built-in color palette for the vertical ramp.", - "enum": [ - "ember", - "ice", - "neon", - "fire", - "lavender", - "claude", - "mono" - ], - "type": "string" - }, - { - "description": "Custom gradient stop: specify top and bottom colors directly.", - "properties": { - "from": { - "description": "Top color.", - "type": "string" - }, - "to": { - "description": "Bottom color.", - "type": "string" - } - }, - "required": [ - "from", - "to" - ], - "type": "object" - } - ], - "description": "Palette name or custom gradient stop for vertical color ramp." - }, - "scale": { - "description": "Integer pixel scale multiplier.", - "maximum": 8, - "minimum": 1, - "type": "integer" - }, - "shadow": { - "description": "Drop shadow.", - "type": "boolean" - } - }, - "type": "object" - }, - "text": { - "description": "Text content to render.", - "type": "string" - }, - "type": { - "const": "text", - "description": "Text element type.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "x": { - "anyOf": [ - { - "description": "Absolute pixel X coordinate (0 = left edge).", - "type": "number" - }, - { - "description": "Semantic horizontal alignment.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - } - ], - "description": "X position (default: 0)." - }, - "y": { - "anyOf": [ - { - "description": "Absolute pixel Y coordinate (0 = top edge).", - "type": "number" - }, - { - "description": "Semantic vertical alignment.", - "enum": [ - "top", - "center", - "bottom" - ], - "type": "string" - } - ], - "description": "Y position (default: 0)." - } - }, - "required": [ - "type", - "text" - ], - "type": "object" - }, - { - "description": "Built-in or custom SVG icon element.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "items": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "color": { - "description": "Icon fill color.", - "type": "string" - }, - "d": { - "description": "Custom SVG path d attribute.", - "type": "string" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "h": { - "description": "Render height in pixels (default: 12).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "name": { - "description": "Built-in icon name (see pixoo://reference/icons).", - "type": "string" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "palette": { - "description": "Named palette for colored icon.", - "enum": [ - "ember", - "ice", - "neon", - "fire", - "lavender", - "claude", - "mono" - ], - "type": "string" - }, - "type": { - "const": "icon", - "description": "Icon element type.", - "type": "string" - }, - "viewBox": { - "description": "SVG viewBox string (default: \"0 0 16 16\").", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "w": { - "description": "Render width in pixels (default: 12).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "x": { - "anyOf": [ - { - "description": "Absolute pixel X coordinate (0 = left edge).", - "type": "number" - }, - { - "description": "Semantic horizontal alignment.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - } - ], - "description": "X position." - }, - "y": { - "anyOf": [ - { - "description": "Absolute pixel Y coordinate (0 = top edge).", - "type": "number" - }, - { - "description": "Semantic vertical alignment.", - "enum": [ - "top", - "center", - "bottom" - ], - "type": "string" - } - ], - "description": "Y position." - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "description": "Filled or gradient rectangle element.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "items": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "borderColor": { - "description": "1px border color.", - "type": "string" - }, - "color": { - "description": "Fill color.", - "type": "string" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "gradient": { - "description": "Gradient fill.", - "properties": { - "from": { - "description": "Start color.", - "type": "string" - }, - "to": { - "description": "End color.", - "type": "string" - }, - "type": { - "description": "v = vertical, h = horizontal.", - "enum": [ - "v", - "h" - ], - "type": "string" - } - }, - "required": [ - "type", - "from", - "to" - ], - "type": "object" - }, - "h": { - "description": "Height in pixels.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "rect", - "description": "Rectangle element type.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "w": { - "description": "Width in pixels.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "x": { - "description": "X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "x", - "y", - "w", - "h" - ], - "type": "object" - }, - { - "description": "Filled or outline circle element.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "items": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "color": { - "description": "Circle color.", - "type": "string" - }, - "cx": { - "description": "Center X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "cy": { - "description": "Center Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "fill": { - "description": "Filled or outline only (default: true).", - "type": "boolean" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "radius": { - "description": "Radius in pixels.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "type": { - "const": "circle", - "description": "Circle element type.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - } - }, - "required": [ - "type", - "cx", - "cy", - "radius" - ], - "type": "object" - }, - { - "description": "Single-pixel line element.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "items": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "color": { - "description": "Line color.", - "type": "string" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "line", - "description": "Line element type.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "x0": { - "description": "Start X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "x1": { - "description": "End X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y0": { - "description": "Start Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y1": { - "description": "End Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "x0", - "y0", - "x1", - "y1" - ], - "type": "object" - }, - { - "description": "Horizontal progress bar widget.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "items": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "h": { - "description": "Height in pixels.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "label": { - "description": "Optional label rendered on the bar.", - "type": "string" - }, - "max": { - "description": "Maximum value.", - "type": "number" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "palette": { - "description": "Named palette for gradient fill.", - "enum": [ - "ember", - "ice", - "neon", - "fire", - "lavender", - "claude", - "mono" - ], - "type": "string" - }, - "trackColor": { - "description": "Background track color.", - "type": "string" - }, - "type": { - "const": "progress", - "description": "Progress bar widget type.", - "type": "string" - }, - "value": { - "description": "Current value.", - "type": "number" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "w": { - "description": "Width in pixels.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "x": { - "description": "X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "x", - "y", - "w", - "h", - "value", - "max" - ], - "type": "object" - }, - { - "description": "Sparkline chart widget (line or bar).", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "items": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "color": { - "description": "Line or bar color.", - "type": "string" - }, - "data": { - "description": "Data points for the chart.", - "items": { - "type": "number" - }, - "minItems": 2, - "type": "array" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "h": { - "description": "Height in pixels.", - "maximum": 9007199254740991, - "minimum": 2, - "type": "integer" - }, - "kind": { - "description": "Chart style (default: line).", - "enum": [ - "line", - "bar" - ], - "type": "string" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "sparkline", - "description": "Sparkline chart widget type.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "w": { - "description": "Width in pixels.", - "maximum": 9007199254740991, - "minimum": 2, - "type": "integer" - }, - "x": { - "description": "X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "x", - "y", - "w", - "h", - "data" - ], - "type": "object" - }, - { - "description": "Bitmap element using explicit palette indices.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "items": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "palette": { - "description": "Color palette: array of hex colors indexed 0-F.", - "items": { - "type": "string" - }, - "type": "array" - }, - "rows": { - "description": "Row strings of hex palette indices (0-F, space = transparent).", - "items": { - "type": "string" - }, - "type": "array" - }, - "type": { - "const": "bitmap", - "description": "Bitmap element using palette indices.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "x": { - "description": "X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "x", - "y", - "rows", - "palette" - ], - "type": "object" - }, - { - "description": "Sparse scatter of individually colored pixels.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "items": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "data": { - "description": "Array of pixel positions and colors.", - "items": { - "description": "A single pixel: position and color.", - "properties": { - "color": { - "description": "Pixel color.", - "type": "string" - }, - "x": { - "description": "Pixel X coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Pixel Y coordinate.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "x", - "y", - "color" - ], - "type": "object" - }, - "type": "array" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "pixels", - "description": "Sparse pixel dots element.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - } - }, - "required": [ - "type", - "data" - ], - "type": "object" - }, - { - "description": "External image element (local path or https URL).", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "items": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "fit": { - "description": "Resize fit mode (default: contain).", - "enum": [ - "contain", - "cover", - "fill" - ], - "type": "string" - }, - "h": { - "description": "Target height (default: canvas height).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "kernel": { - "description": "Resize kernel: nearest for pixel art, lanczos3 for photos (default: nearest).", - "enum": [ - "nearest", - "lanczos3", - "mitchell" - ], - "type": "string" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "source": { - "description": "Absolute local file path or https (not http) URL.", - "type": "string" - }, - "type": { - "const": "image", - "description": "Image element (local path or https URL).", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "w": { - "description": "Target width (default: canvas width).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "x": { - "description": "X offset on canvas (default: 0).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "y": { - "description": "Y offset on canvas (default: 0).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "source" - ], - "type": "object" - }, - { - "description": "Sprite sheet element for character or tile art.", - "properties": { - "animate": { - "additionalProperties": { - "description": "Keyframe entries: [[frame, value], ...].", - "items": { - "items": [ - { - "description": "Frame index.", - "type": "number" - }, - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ], - "description": "Value at this frame." - } - ], - "type": "array" - }, - "type": "array" - }, - "description": "Raw keyframe animation map for this element.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "bodyColor": { - "description": "Override body color.", - "type": "string" - }, - "cols": { - "description": "Number of columns in the sprite grid.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "darkColor": { - "description": "Override dark/eye color.", - "type": "string" - }, - "dx": { - "description": "X offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "dy": { - "description": "Y offset nudge in pixels.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "effect": { - "description": "Named animation preset for this element.", - "properties": { - "amplitude": { - "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", - "type": "number" - }, - "name": { - "description": "Named animation preset.", - "enum": [ - "float", - "scroll-left", - "scroll-right", - "pulse", - "blink", - "twinkle", - "drift", - "fade-in", - "fade-out" - ], - "type": "string" - }, - "period": { - "description": "Effect period in frames. Defaults to total scene frame count.", - "type": "number" - }, - "phase": { - "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", - "type": "number" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "opacity": { - "description": "Opacity 0–100 (default: 100).", - "maximum": 100, - "minimum": 0, - "type": "integer" - }, - "path": { - "description": "Absolute local path to the sprite sheet image.", - "type": "string" - }, - "rows": { - "description": "Number of rows in the sprite grid.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "scale": { - "description": "Pixel scale factor.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "type": { - "const": "sprite", - "description": "Sprite sheet element.", - "type": "string" - }, - "visible": { - "description": "Whether the element is visible (default: true).", - "type": "boolean" - }, - "x": { - "anyOf": [ - { - "description": "Absolute pixel X coordinate (0 = left edge).", - "type": "number" - }, - { - "description": "Semantic horizontal alignment.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - } - ], - "description": "X position (default: center)." - }, - "y": { - "description": "Y position (default: 0).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "type", - "path", - "cols", - "rows" - ], - "type": "object" - } -]New value: +[ + { + "description": "Styled text element rendered at a position.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ], + "description": "Value at this frame." + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "color": { + "description": "Flat text color.", + "type": "string" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "font": { + "description": "Font variant.", + "enum": [ + "standard", + "compact" + ], + "type": "string" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "style": { + "description": "Text style options.", + "properties": { + "color": { + "description": "Flat color override.", + "type": "string" + }, + "outline": { + "description": "1px outline.", + "type": "boolean" + }, + "palette": { + "anyOf": [ + { + "description": "Named built-in color palette for the vertical ramp.", + "enum": [ + "ember", + "ice", + "neon", + "fire", + "lavender", + "claude", + "mono" + ], + "type": "string" + }, + { + "description": "Custom gradient stop: specify top and bottom colors directly.", + "properties": { + "from": { + "description": "Top color.", + "type": "string" + }, + "to": { + "description": "Bottom color.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ], + "type": "object" + } + ], + "description": "Palette name or custom gradient stop for vertical color ramp." + }, + "scale": { + "description": "Integer pixel scale multiplier.", + "maximum": 8, + "minimum": 1, + "type": "integer" + }, + "shadow": { + "description": "Drop shadow.", + "type": "boolean" + } + }, + "type": "object" + }, + "text": { + "description": "Text content to render.", + "type": "string" + }, + "type": { + "const": "text", + "description": "Text element type.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "x": { + "anyOf": [ + { + "description": "Absolute pixel X coordinate (0 = left edge).", + "type": "number" + }, + { + "description": "Semantic horizontal alignment.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + } + ], + "description": "X position (default: 0)." + }, + "y": { + "anyOf": [ + { + "description": "Absolute pixel Y coordinate (0 = top edge).", + "type": "number" + }, + { + "description": "Semantic vertical alignment.", + "enum": [ + "top", + "center", + "bottom" + ], + "type": "string" + } + ], + "description": "Y position (default: 0)." + } + }, + "required": [ + "type", + "text" + ], + "type": "object" + }, + { + "description": "Built-in or custom SVG icon element.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ], + "description": "Value at this frame." + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "color": { + "description": "Icon fill color.", + "type": "string" + }, + "d": { + "description": "Custom SVG path d attribute.", + "type": "string" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "h": { + "description": "Render height in pixels (default: 12).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "name": { + "description": "Built-in icon name (see pixoo://reference/icons).", + "type": "string" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "palette": { + "description": "Named palette for colored icon.", + "enum": [ + "ember", + "ice", + "neon", + "fire", + "lavender", + "claude", + "mono" + ], + "type": "string" + }, + "type": { + "const": "icon", + "description": "Icon element type.", + "type": "string" + }, + "viewBox": { + "description": "SVG viewBox string (default: \"0 0 16 16\").", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "w": { + "description": "Render width in pixels (default: 12).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "x": { + "anyOf": [ + { + "description": "Absolute pixel X coordinate (0 = left edge).", + "type": "number" + }, + { + "description": "Semantic horizontal alignment.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + } + ], + "description": "X position." + }, + "y": { + "anyOf": [ + { + "description": "Absolute pixel Y coordinate (0 = top edge).", + "type": "number" + }, + { + "description": "Semantic vertical alignment.", + "enum": [ + "top", + "center", + "bottom" + ], + "type": "string" + } + ], + "description": "Y position." + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "description": "Filled or gradient rectangle element.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ], + "description": "Value at this frame." + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "borderColor": { + "description": "1px border color.", + "type": "string" + }, + "color": { + "description": "Fill color.", + "type": "string" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "gradient": { + "description": "Gradient fill.", + "properties": { + "from": { + "description": "Start color.", + "type": "string" + }, + "to": { + "description": "End color.", + "type": "string" + }, + "type": { + "description": "v = vertical, h = horizontal.", + "enum": [ + "v", + "h" + ], + "type": "string" + } + }, + "required": [ + "type", + "from", + "to" + ], + "type": "object" + }, + "h": { + "description": "Height in pixels.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "rect", + "description": "Rectangle element type.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "w": { + "description": "Width in pixels.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "x": { + "description": "X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "x", + "y", + "w", + "h" + ], + "type": "object" + }, + { + "description": "Filled or outline circle element.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ], + "description": "Value at this frame." + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "color": { + "description": "Circle color.", + "type": "string" + }, + "cx": { + "description": "Center X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "cy": { + "description": "Center Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "fill": { + "description": "Filled or outline only (default: true).", + "type": "boolean" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "radius": { + "description": "Radius in pixels.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "type": { + "const": "circle", + "description": "Circle element type.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + } + }, + "required": [ + "type", + "cx", + "cy", + "radius" + ], + "type": "object" + }, + { + "description": "Single-pixel line element.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ], + "description": "Value at this frame." + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "color": { + "description": "Line color.", + "type": "string" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "line", + "description": "Line element type.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "x0": { + "description": "Start X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "x1": { + "description": "End X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y0": { + "description": "Start Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y1": { + "description": "End Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "x0", + "y0", + "x1", + "y1" + ], + "type": "object" + }, + { + "description": "Horizontal progress bar widget.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ], + "description": "Value at this frame." + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "h": { + "description": "Height in pixels.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "label": { + "description": "Optional label rendered on the bar.", + "type": "string" + }, + "max": { + "description": "Maximum value.", + "type": "number" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "palette": { + "description": "Named palette for gradient fill.", + "enum": [ + "ember", + "ice", + "neon", + "fire", + "lavender", + "claude", + "mono" + ], + "type": "string" + }, + "trackColor": { + "description": "Background track color.", + "type": "string" + }, + "type": { + "const": "progress", + "description": "Progress bar widget type.", + "type": "string" + }, + "value": { + "description": "Current value.", + "type": "number" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "w": { + "description": "Width in pixels.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "x": { + "description": "X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "x", + "y", + "w", + "h", + "value", + "max" + ], + "type": "object" + }, + { + "description": "Sparkline chart widget (line or bar).", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ], + "description": "Value at this frame." + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "color": { + "description": "Line or bar color.", + "type": "string" + }, + "data": { + "description": "Data points for the chart.", + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "h": { + "description": "Height in pixels.", + "maximum": 9007199254740991, + "minimum": 2, + "type": "integer" + }, + "kind": { + "description": "Chart style (default: line).", + "enum": [ + "line", + "bar" + ], + "type": "string" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "sparkline", + "description": "Sparkline chart widget type.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "w": { + "description": "Width in pixels.", + "maximum": 9007199254740991, + "minimum": 2, + "type": "integer" + }, + "x": { + "description": "X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "x", + "y", + "w", + "h", + "data" + ], + "type": "object" + }, + { + "description": "Bitmap element using explicit palette indices.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ], + "description": "Value at this frame." + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "palette": { + "description": "Color palette: array of hex colors indexed 0-F.", + "items": { + "type": "string" + }, + "type": "array" + }, + "rows": { + "description": "Row strings of hex palette indices (0-F, space = transparent).", + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "const": "bitmap", + "description": "Bitmap element using palette indices.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "x": { + "description": "X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "x", + "y", + "rows", + "palette" + ], + "type": "object" + }, + { + "description": "Sparse scatter of individually colored pixels.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ], + "description": "Value at this frame." + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "data": { + "description": "Array of pixel positions and colors.", + "items": { + "description": "A single pixel: position and color.", + "properties": { + "color": { + "description": "Pixel color.", + "type": "string" + }, + "x": { + "description": "Pixel X coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Pixel Y coordinate.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "x", + "y", + "color" + ], + "type": "object" + }, + "type": "array" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "pixels", + "description": "Sparse pixel dots element.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + } + }, + "required": [ + "type", + "data" + ], + "type": "object" + }, + { + "description": "External image element (local path or https URL).", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ], + "description": "Value at this frame." + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "fit": { + "description": "Resize fit mode (default: contain).", + "enum": [ + "contain", + "cover", + "fill" + ], + "type": "string" + }, + "h": { + "description": "Target height (default: canvas height).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "kernel": { + "description": "Resize kernel: nearest for pixel art, lanczos3 for photos (default: nearest).", + "enum": [ + "nearest", + "lanczos3", + "mitchell" + ], + "type": "string" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "source": { + "description": "Absolute local file path or https (not http) URL.", + "type": "string" + }, + "type": { + "const": "image", + "description": "Image element (local path or https URL).", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "w": { + "description": "Target width (default: canvas width).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "x": { + "description": "X offset on canvas (default: 0).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "y": { + "description": "Y offset on canvas (default: 0).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "source" + ], + "type": "object" + }, + { + "description": "Sprite sheet element for character or tile art.", + "properties": { + "animate": { + "additionalProperties": { + "description": "Keyframe entries: [[frame, value], ...].", + "items": { + "prefixItems": [ + { + "description": "Frame index.", + "type": "number" + }, + { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ], + "description": "Value at this frame." + } + ], + "type": "array" + }, + "type": "array" + }, + "description": "Raw keyframe animation map for this element.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "bodyColor": { + "description": "Override body color.", + "type": "string" + }, + "cols": { + "description": "Number of columns in the sprite grid.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "darkColor": { + "description": "Override dark/eye color.", + "type": "string" + }, + "dx": { + "description": "X offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "dy": { + "description": "Y offset nudge in pixels.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "effect": { + "description": "Named animation preset for this element.", + "properties": { + "amplitude": { + "description": "Effect intensity: pixels of movement for float/scroll/drift, 0–1 scale for fade/pulse. Default varies by effect (float: 2px).", + "type": "number" + }, + "name": { + "description": "Named animation preset.", + "enum": [ + "float", + "scroll-left", + "scroll-right", + "pulse", + "blink", + "twinkle", + "drift", + "fade-in", + "fade-out" + ], + "type": "string" + }, + "period": { + "description": "Effect period in frames. Defaults to total scene frame count.", + "type": "number" + }, + "phase": { + "description": "Phase offset 0–1 to stagger this element relative to others (0.5 = half-cycle offset).", + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "opacity": { + "description": "Opacity 0–100 (default: 100).", + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "path": { + "description": "Absolute local path to the sprite sheet image.", + "type": "string" + }, + "rows": { + "description": "Number of rows in the sprite grid.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "scale": { + "description": "Pixel scale factor.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "type": { + "const": "sprite", + "description": "Sprite sheet element.", + "type": "string" + }, + "visible": { + "description": "Whether the element is visible (default: true).", + "type": "boolean" + }, + "x": { + "anyOf": [ + { + "description": "Absolute pixel X coordinate (0 = left edge).", + "type": "number" + }, + { + "description": "Semantic horizontal alignment.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + } + ], + "description": "X position (default: center)." + }, + "y": { + "description": "Y position (default: 0).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "type", + "path", + "cols", + "rows" + ], + "type": "object" + } +] - changed
Input schema / properties / output / descriptionPrevious value: -"Explicit output file path for saving (overrides PIXOO_OUTPUT_DIR)."New value: +"Absolute, already-normalized path to save the first frame to, in addition to the PIXOO_OUTPUT_DIR auto-save when that is configured. Both paths are reported in outputFiles." - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "pushed", + "frames", + "layout" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `device_unreachable`: Device is not reachable over the network. `device_rejected`: Device firmware returned a non-zero error code. `no_device_configured`: PIXOO_IP is not set and push was requested. `asset_not_found`: An image or sprite path could not be read. `invalid_color`: A color value could not be resolved. `unknown_icon`: Icon name not found in the registry. `invalid_output_path`: The output path is relative or contains traversal segments. Other values are possible when a failure originates below the handler.", + "examples": [ + "device_unreachable", + "device_rejected", + "no_device_configured", + "asset_not_found", + "invalid_color", + "unknown_icon", + "invalid_output_path" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / properties / previewDataRemoved value: -{ - "description": "Base64-encoded PNG preview of the rendered scene (8× upscaled, 512px). For animations: the middle frame.", - "type": "string" -} - removed
Output schema / properties / previewMimeTypeRemoved value: -{ - "description": "MIME type of the preview image.", - "enum": [ - "image/png" - ], - "type": "string" -} - removed
Output schema / requiredRemoved value: -[ - "pushed", - "frames", - "layout" -]
- Changed
pixoo_control_device6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "reachable", + "applied" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `device_unreachable`: Device is not reachable. `device_rejected`: Device rejected the command. `no_device_configured`: PIXOO_IP is not set. Other values are possible when a failure originates below the handler.", + "examples": [ + "device_unreachable", + "device_rejected", + "no_device_configured" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "reachable", - "applied" -]
- Changed
pixoo_design_brief6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "topic", + "craftGuidance", + "deviceContext", + "nextToolSuggestions", + "availableThemes", + "iconCategories" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode.", + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "topic", - "craftGuidance", - "deviceContext", - "nextToolSuggestions", - "availableThemes", - "iconCategories" -]
- Changed
pixoo_discover_devices6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "devices" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `discovery_failed`: Divoom cloud discovery endpoint is unreachable. Other values are possible when a failure originates below the handler.", + "examples": [ + "discovery_failed" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "devices" -]
- Changed
pixoo_display_text8 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "pushed", + "layout" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `device_unreachable`: Device is not reachable over the network. `device_rejected`: Device firmware returned a non-zero error code. `no_device_configured`: PIXOO_IP is not set. `invalid_color`: A color value could not be resolved. Other values are possible when a failure originates below the handler.", + "examples": [ + "device_unreachable", + "device_rejected", + "no_device_configured", + "invalid_color" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / properties / previewDataRemoved value: -{ - "description": "Base64-encoded PNG preview of the rendered frame (8× upscaled, 512px).", - "type": "string" -} - removed
Output schema / properties / previewMimeTypeRemoved value: -{ - "description": "MIME type of the preview image.", - "enum": [ - "image/png" - ], - "type": "string" -} - removed
Output schema / requiredRemoved value: -[ - "pushed", - "layout" -]
- Changed
pixoo_overlay_text6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "acknowledged", + "mode", + "id" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `device_unreachable`: Device is not reachable. `device_rejected`: Device firmware rejected the command. `no_device_configured`: PIXOO_IP is not set. `invalid_color`: The color value could not be resolved. Other values are possible when a failure originates below the handler.", + "examples": [ + "device_unreachable", + "device_rejected", + "no_device_configured", + "invalid_color" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "acknowledged", - "mode", - "id" -]
- Changed
pixoo_push_image8 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "pushed" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `device_unreachable`: Device is not reachable. `device_rejected`: Device firmware returned a non-zero error code. `no_device_configured`: PIXOO_IP is not set. `asset_not_found`: Image path or URL could not be read. Other values are possible when a failure originates below the handler.", + "examples": [ + "device_unreachable", + "device_rejected", + "no_device_configured", + "asset_not_found" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / properties / previewDataRemoved value: -{ - "description": "Base64-encoded PNG preview of the downsampled 64×64 result (8× upscaled, 512px).", - "type": "string" -} - removed
Output schema / properties / previewMimeTypeRemoved value: -{ - "description": "MIME type of the preview image.", - "enum": [ - "image/png" - ], - "type": "string" -} - removed
Output schema / requiredRemoved value: -[ - "pushed" -]
7 tool updates
v1.0.0- First observed
pixoo_compose_scene - First observed
pixoo_control_device - First observed
pixoo_design_brief - First observed
pixoo_discover_devices - First observed
pixoo_display_text - First observed
pixoo_overlay_text - First observed
pixoo_push_image
TDQS
Scored across 7 tools
Each tool has a distinct responsibility—discovery, device state, design guidance, scene composition, text rendering, persistent overlays, and image pushing. Cross-references explicitly delineate when to use which tool, minimizing any risk of misselection.
All tools follow a uniform pixoo_<verb>_<noun> pattern with imperative verbs and snake_case, creating a predictable and consistent API surface.
7 tools tightly scope the domain: device setup, device control, design guidance, and four distinct content-display methods. Each tool earns its place with no redundancy or bloat.
The surface covers discovery, state control, guidance, and content types including scenes, styled text, images, and overlays. A dedicated display-clearing operation is absent, but workarounds exist via pushing blank content or toggling the screen state.
Maintenance
Related MCP Connectors
Manage digital signage screens, playlists and media from your AI assistant.
Generate pixel art sprites, animations, 8-direction rotations and palettes for games.
Display delivery platform for AI agents. Push HTML, dashboards and live data to screens.
LLM chat, text tools, image generation, editing, batch image jobs, and asynchronous video generation
Related MCP Servers
- AlicenseBqualityBmaintenanceEnables AI assistants to create and manipulate pixel art by providing tools for drawing, layer management, and animation frame control. It supports exporting projects to PNG, GIF, and sprite sheet formats via the Model Context Protocol.2216Apache 2.0

mcp-divoom-lanofficial
AlicenseBqualityCmaintenanceEnables AI clients to control Divoom LAN devices, including watchface management, brightness adjustment, and screen control through natural language.1834 npm4MIT- AlicenseBqualityCmaintenanceEnables LLMs to create and edit pixel art reliably with support for layers, frames, symmetry, and various drawing tools.70MIT No Attribution
- FlicenseAqualityDmaintenanceEnables Claude to create, update, and manage LED patterns on a PixelBlaze controller, including setting brightness and reading device info, through a set of tools that interact with the device's API.14-