High-Level Structure
Every Playground Definition uses the following JSON signature:Top-Level Properties
Layout Types
A Playground Definition is rendered with one of two layouts. The layout type is chosen when the playground is created and is immutable — it cannot be changed later. Attempting to upload a definition whoselayout block differs from the persisted layout will fail with invalid_layout.
Free-Form Layout
The default. Widgets are positioned with absolute pixel coordinates on a 2D canvas; widget size comes fromwidth / height ports declared per-widget. Suited to ad-hoc canvases where widgets are placed anywhere by drag-and-drop.
layout block, version: "1.0.1") is equivalent to {"type": "free_form"} and continues to be served as-is. Newly created free-form playgrounds always carry the explicit layout block.
zoom is optional on free-form layouts as well — same range and semantics as in grid (see zoom below): the value is the canvas zoom level the user last saved, and it’s the only mutable field on layout.
Grid Layout
Widgets are placed on a fixed-column grid. Widget position and size are expressed in grid units rather than pixels, and the grid configuration (columns, row_height) is set at creation time.
layout Properties (grid)
columns, row_height, margin, and container_padding are immutable for the lifetime of the playground. zoom, vertical_sizing, and reference_rows may be updated freely across uploads.
Vertical Sizing
vertical_sizing controls how the effective row height is derived from the viewport. There are three modes:
-
pitch(default, and the behavior when the field is absent):row_heightis used as a fixed pixel pitch. The number of visible rows depends on the viewport height, and content that extends beyond the viewport scrolls normally. This is the historical behavior. -
fit: the grid scales so that all occupied rows fit exactly within the viewport height — effective row height = viewport height ÷ (bottom-most occupied row). Adding widgets proportionally shrinks all rows; the grid never scrolls. If the grid is empty,reference_rowsis used as the fallback row count. -
fixed_rows: a fixed number of rows (set byreference_rows) always fills the viewport height, giving each widget a stable share of the screen across different resolutions. Content placed beyondreference_rowsscrolls as normal.
reference_rows is consulted only when vertical_sizing is "fixed_rows" (and as the empty-grid fallback for "fit"). It has no effect in "pitch" mode. Similarly, row_height is only meaningful in "pitch" mode — in "fit" and "fixed_rows" the effective row height is derived from the viewport.
Playground Widgets (Components)
Just like Workflow Components, Playground widgets rely on interfaces to define their behavior. However, they generally pertain to user-facing interactions. The shape of each component’sposition field depends on the layout type.
Free-Form Component
position.x and position.y are pixel coordinates on the canvas (negative values are valid — they correspond to panning offsets). Widget size is read from the width / height ports.
Grid Component
position field carries grid-unit coordinates and dimensions:
Constraint:
position.x + position.width must not exceed layout.columns. Violations are rejected with invalid_component_position.
Grid components do not carry width / height ports — widget size is derived from the grid units and the playground’s row_height / column width.
