panelKey. The definition controls presentation and behavior; state is stored separately per serverId and instanceKey.
Definition
Bindings
Use a binding as the entire property value, such as
"value": "$item.locked". For text containing other words, use interpolation such as "Fuel: {{item.fuel}}%" or "Active: {{state.summary.active}}".
Saving one repeated item
$inputs includes controls from the entire panel instance. Repeated controls use keys such as sign-12:line1. Avoid sending the entire $inputs object when an action edits just one item. Inside a repeat, use $itemInputs for a complete item form or $itemChanges for a partial edit:
id within its repeated item and every item a stable, unique id within the panel instance. These bindings collect controls under the nearest repeat, including controls inside layout containers; they exclude nested repeats, other items, and local search/sort settings. Without a repeated-item context, both objects are empty. Without an item ID, controls use their original source-array index; stable IDs are recommended when the collection can change.
$itemInputs includes untouched defaults. $itemChanges compares current values with the controls’ default value bindings, usually sourced from the latest published $item state. Reverting a field to its default removes it from the changes object. Deliberate "", false, 0, and null values are preserved. No differences produces {}; the button still emits an action. Your integration should treat missing fields as unchanged and an empty changes object as a successful no-op. Validate and apply only allowed field IDs, then acknowledge and publish the complete authoritative state. CAD does not apply the partial edit to state automatically.
The changes name is your integration’s payload convention, not a reserved API property. Use "fields": "$itemInputs" instead if your handler expects all fields for one item. Existing explicit bindings such as "line1": "$inputs.line1" remain supported for non-repeated forms. Deploy a CAD frontend with these item bindings before changing your manifest; they are currently available on staging.
Node Types
Common layout properties are
grow, columns from 1-12, and gap using none, xs, sm, md, lg, or xl.
Select options may be primitive values or { "label": "Display", "value": "stored-value" } objects.
SVG icon picker
AniconPicker is a 40-pixel square, matching the height of a dense text input. Clicking it opens a scrollable menu. Supply a flat options array, or group icons with sections: [{ "name": "Response", "options": [...] }]. Each section needs a heading in name. When sections is present, it takes precedence over options. Each icon needs a stable string value and inline SVG markup in svg. An optional icon name supplies the tooltip and accessible name; without it, the picker uses value.
Set searchable to true to show a local search field. It matches an icon’s name or value, showing only sections with matching icons. A matching section heading shows all its icons. Search is off by default. The selected value is stored locally and available as $value in its action; your integration should process the action and publish the updated state.
Typing fi narrows the menu to Fire in its section:
options use the same icon object format.
Conditions
AddvisibleWhen to any node. Use one comparison with a bound path.
equals, notEquals, and in. With no comparison, visibility follows the truthiness of path.
Actions
Controls use the same action envelope. The CAD creates an event containing the action ID, resolved values, actor, panel, instance, and server.confirm is optional. It displays a CAD confirmation dialog before the action is queued.
Resolved action values must fit within 32 KiB of UTF-8 JSON. This is an application and database budget for each queued command, independent of the larger panel-state limit. An oversized action is rejected before queueing or push delivery. Keep actions limited to the affected item’s fields or changes; state updates remain full replacements of up to 512 KiB.
input, number, and textarea actions are emitted once when the user leaves a changed field. Selects, toggles, checkboxes, and icon pickers emit on selection or click. Successful action acknowledgments are quiet; failures show an error notification.
Repeated Collections
Setsource to a state array. Child nodes can bind to the current $item.
minItemWidth accepts 120-800 pixels. The grid automatically changes its column count with the panel width.
Search
Search is local to the CAD client and does not call the API.fields is omitted, primitive properties on the item are searched.
Sort
Each option has a stablevalue and ordered rules. A rule can use direction (asc or desc) or an explicit order array.
Theme-Safe Styling
Arbitrary CSS is not accepted. This keeps community panels safe and compatible with every CAD theme.appearance supports positive, negative, warning, primary, info, muted, and neutral.
Color fields and style.backgroundColor, style.borderColor, or style.color must use one of these v2 token names:
amber, amber-text, background, blue, blue-text, component-border, foreground, foreground-light, icon, positive, positive-text, primary, primary-faded, primary-text, text-inverse, text-primary, text-subtitle, or text-title.
Allowed non-color style properties are borderRadius, borderStyle, borderWidth, fontSize, fontWeight, margin, maxHeight, minHeight, opacity, padding, and textAlign.
Built-in animations are pulse-negative, pulse-warning, and pulse-positive. Animation values may be bound to state.
Sounds
Sound URLs must use HTTPS. Local paths and localhost HTTP are accepted while developing. Browser autoplay rules may require the user to interact with the CAD before audio can play.
State sounds compare the prior and current values and do not play on initial load. Duplicate playback is suppressed for 500 ms.

