rx/ in the current
folder or any parent. Studio covers the setup in full.
What you get
resources/subscribe β updated mechanism that live-updates production channels.
The top nav is flat: Apps Β· Components Β· Styles Β· Nodes Β· AI, and a header org switcher scopes the whole Studio: the Apps list, the Components list (the design system + the selected orgβs own components only), and the preview theme. All shows everything cross-org, with an org badge per card. Atoms have no Studio view: theyβre authoring-time only; the server expands them before anything is served.
Mode A: Mock (isolation)
Render a component or template with mock data and mock history, no backend logic involved. This is your daily loop while designing.Mock data = prop defaults. The state picker = the states/ folder.
Two mechanisms, zero hand-maintained fixtures:
-
Prop
defaults are the mock data. Studio renders every definition from its declared defaults: which is why defaults should be realistic content, not empty strings. -
Two docks: layouts on top, states on the left. A component has two axes, and Studio never shares one control between them:
- its layout faces: the root
Switch on defaultStatecases (inline,focused, a customproduct), are a toggle at the top of the toolbar (first control after the name). Any face name appears automatically;inlinealways leads; a flat component with no face switch shows no toggle. Any non-inline face gets the grow container. - its own
states/files (a wizardβs private steps,goals.json β¦ results.json) are the left-rail list under the componentβs name.
defaultStateinto the slice; picking a state walks the wizard: both via the same genericsetValuea real componentβs buttons use. (Templates work the same way: the appβsstates/are the picker, one active at a time; acting inside the preview transitions state like the runtime.) - its layout faces: the root
Switch cases is the same folder Studio reads. Use the picker to exercise every discriminant value (each wizard step, inline/focused, each callState phase), and vary prop defaults to check edge data (empty lists, long text: how you catch a bind without a default).
Apps show their widgetβs states too. Selecting an app template (a single-widget shell) also lists its seeded componentβs states as pills: a wizardβs steps are one click each, activated by writing the widgetβs Switch discriminant into its slice, exactly what its own buttons do.
Copy for Canvas: drop a component onto a workflow
When a component is selected, Studio shows aβ§ Copy for Canvas button. It copies the component as a Canvas node to your clipboard; then Cmd+V on any workflow Canvas pastes it in, sized to the componentβs nodeSize. This is how a design component reaches a workflow: the node library no longer lists components, so you preview it here, copy it, and paste it where the workflow needs it. (No file edit, no restart; itβs just placing the node.)
Mode B: Live (the proof)
Flip the toggle and Studio connects as an MCP client to your real running platform. Real workflows stream real components, select real templates, deliver real data: into the local preview. You are watching production behavior before shipping. Use Live mode to verify the things mock canβt:- your componentβs node receives and merges streamed
COMPONENT_DATAcorrectly, - the template selection picks your app for the intents you wrote
whenToUsefor, - reaction flow: the widget streams in (or is clicked) into a state, the templateβs
wheresurface frames it, its β returns it inline cleanly, - turn lifecycle: thinking indicators derived from
isStreamingappear and, critically, clear.
DevTools: when something looks wrong
Debugging order, always: stream log (did it arrive?) β state inspector (is it in the bucket I read?) β the definition (is my bind/condition right?). Never start by editing the definition on a guess: see the data first.
The full loop
Next: 08. Validate & Ship.

