@yahoo/uds-create-config 3.1.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/configs/CanvasConfig.d.ts +66 -3
  2. package/dist/configs/react-native-system.d.ts +46 -2
  3. package/dist/configs/react-native-system.js +4 -0
  4. package/dist/configs/system.d.ts +46 -2
  5. package/dist/configs/system.js +4 -0
  6. package/dist/entities/system/Component.d.ts +40 -2
  7. package/dist/entities/system/Component.js +74 -9
  8. package/dist/entities/system/File.d.ts +1 -0
  9. package/dist/entities/system/File.js +27 -2
  10. package/dist/entities/system/style-bag.js +24 -5
  11. package/dist/framework/Config.d.ts +1 -1
  12. package/dist/framework/Config.js +1 -1
  13. package/dist/framework/anatomy-check.d.ts +99 -0
  14. package/dist/framework/anatomy-check.js +337 -0
  15. package/dist/framework/class-names.js +6 -2
  16. package/dist/framework/defineEntity.d.ts +1 -0
  17. package/dist/framework/ref-integrity.js +17 -3
  18. package/dist/framework/registry.d.ts +1 -0
  19. package/dist/framework/render-spec.d.ts +12 -1
  20. package/dist/framework/render-spec.js +122 -28
  21. package/dist/framework/schema-version.d.ts +1 -1
  22. package/dist/framework/schema-version.js +5 -5
  23. package/dist/index.d.ts +5 -3
  24. package/dist/index.js +5 -3
  25. package/dist/migrations/2.0.0/v1-artifact.d.ts +23 -1
  26. package/dist/migrations/20260914155048_component_create_blank_op.d.ts +13 -0
  27. package/dist/migrations/20260914155048_component_create_blank_op.js +8 -0
  28. package/dist/migrations/20260914181845_anatomy_harness.d.ts +23 -0
  29. package/dist/migrations/20260914181845_anatomy_harness.js +10 -0
  30. package/dist/renderer/assetEntries.js +2 -3
  31. package/dist/renderer/spec-content.js +1 -1
  32. package/dist/renderer/wrappers/inline-styles.js +21 -1
  33. package/dist/spec/index.d.ts +1 -1
  34. package/dist/spec/specToJsx.js +26 -2
  35. package/dist/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +2 -2
@@ -382,7 +382,7 @@ declare const Node: EntityClass<z.ZodObject<{
382
382
  }, z.core.$strip>>;
383
383
  export: z.ZodOptional<z.ZodString>;
384
384
  }, z.core.$strict>;
385
- readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
385
+ readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
386
386
  readonly example: ({
387
387
  config
388
388
  }: {
@@ -394,6 +394,27 @@ declare const Node: EntityClass<z.ZodObject<{
394
394
  data: Record<string, unknown>;
395
395
  };
396
396
  };
397
+ readonly 'create-blank': {
398
+ readonly input: z.ZodObject<{
399
+ path: z.ZodType<string, string | undefined, z.core.$ZodTypeInternals<string, string | undefined>>;
400
+ }, z.core.$strip>;
401
+ readonly readOnly: false;
402
+ readonly label: "Create blank";
403
+ readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
404
+ readonly scope: "item";
405
+ readonly creates: true;
406
+ readonly title: (entity: string) => string;
407
+ readonly example: ({
408
+ config
409
+ }: {
410
+ config: Config;
411
+ kind: string;
412
+ path: string;
413
+ }) => {
414
+ path: string;
415
+ };
416
+ readonly handler: (input: Record<string, unknown>, config: Config) => Config;
417
+ };
397
418
  readonly 'sub-create/anatomy': {
398
419
  readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
399
420
  };
@@ -1248,7 +1269,7 @@ declare const CanvasConfig: ConfigClass<{
1248
1269
  }, z.core.$strip>>;
1249
1270
  export: z.ZodOptional<z.ZodString>;
1250
1271
  }, z.core.$strict>;
1251
- readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
1272
+ readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
1252
1273
  readonly example: ({
1253
1274
  config
1254
1275
  }: {
@@ -1260,6 +1281,27 @@ declare const CanvasConfig: ConfigClass<{
1260
1281
  data: Record<string, unknown>;
1261
1282
  };
1262
1283
  };
1284
+ readonly 'create-blank': {
1285
+ readonly input: z.ZodObject<{
1286
+ path: z.ZodType<string, string | undefined, z.core.$ZodTypeInternals<string, string | undefined>>;
1287
+ }, z.core.$strip>;
1288
+ readonly readOnly: false;
1289
+ readonly label: "Create blank";
1290
+ readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
1291
+ readonly scope: "item";
1292
+ readonly creates: true;
1293
+ readonly title: (entity: string) => string;
1294
+ readonly example: ({
1295
+ config
1296
+ }: {
1297
+ config: Config;
1298
+ kind: string;
1299
+ path: string;
1300
+ }) => {
1301
+ path: string;
1302
+ };
1303
+ readonly handler: (input: Record<string, unknown>, config: Config) => Config;
1304
+ };
1263
1305
  readonly 'sub-create/anatomy': {
1264
1306
  readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
1265
1307
  };
@@ -2379,7 +2421,7 @@ declare function createCanvasConfig(system: AnySystemConfig): ConfigInstance<{
2379
2421
  }, z.core.$strip>>;
2380
2422
  export: z.ZodOptional<z.ZodString>;
2381
2423
  }, z.core.$strict>;
2382
- readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
2424
+ readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
2383
2425
  readonly example: ({
2384
2426
  config
2385
2427
  }: {
@@ -2391,6 +2433,27 @@ declare function createCanvasConfig(system: AnySystemConfig): ConfigInstance<{
2391
2433
  data: Record<string, unknown>;
2392
2434
  };
2393
2435
  };
2436
+ readonly 'create-blank': {
2437
+ readonly input: z.ZodObject<{
2438
+ path: z.ZodType<string, string | undefined, z.core.$ZodTypeInternals<string, string | undefined>>;
2439
+ }, z.core.$strip>;
2440
+ readonly readOnly: false;
2441
+ readonly label: "Create blank";
2442
+ readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
2443
+ readonly scope: "item";
2444
+ readonly creates: true;
2445
+ readonly title: (entity: string) => string;
2446
+ readonly example: ({
2447
+ config
2448
+ }: {
2449
+ config: Config;
2450
+ kind: string;
2451
+ path: string;
2452
+ }) => {
2453
+ path: string;
2454
+ };
2455
+ readonly handler: (input: Record<string, unknown>, config: Config) => Config;
2456
+ };
2394
2457
  readonly 'sub-create/anatomy': {
2395
2458
  readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
2396
2459
  };
@@ -309,7 +309,7 @@ declare const ReactNativeSystem: ConfigClass<{
309
309
  }, _$zod_v4_core0.$strip>>;
310
310
  export: _$zod.ZodOptional<_$zod.ZodString>;
311
311
  }, _$zod_v4_core0.$strict>;
312
- readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
312
+ readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
313
313
  readonly example: ({
314
314
  config
315
315
  }: {
@@ -321,6 +321,27 @@ declare const ReactNativeSystem: ConfigClass<{
321
321
  data: Record<string, unknown>;
322
322
  };
323
323
  };
324
+ readonly 'create-blank': {
325
+ readonly input: _$zod.ZodObject<{
326
+ path: _$zod.ZodType<string, string | undefined, _$zod_v4_core0.$ZodTypeInternals<string, string | undefined>>;
327
+ }, _$zod_v4_core0.$strip>;
328
+ readonly readOnly: false;
329
+ readonly label: "Create blank";
330
+ readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
331
+ readonly scope: "item";
332
+ readonly creates: true;
333
+ readonly title: (entity: string) => string;
334
+ readonly example: ({
335
+ config
336
+ }: {
337
+ config: Config;
338
+ kind: string;
339
+ path: string;
340
+ }) => {
341
+ path: string;
342
+ };
343
+ readonly handler: (input: Record<string, unknown>, config: Config) => Config;
344
+ };
324
345
  readonly 'sub-create/anatomy': {
325
346
  readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
326
347
  };
@@ -1088,6 +1109,7 @@ declare const ReactNativeSystem: ConfigClass<{
1088
1109
  target: _$zod.ZodType<Ref, unknown, _$zod_v4_core0.$ZodTypeInternals<Ref, unknown>>;
1089
1110
  names: _$zod.ZodOptional<_$zod.ZodArray<_$zod.ZodString>>;
1090
1111
  }, _$zod_v4_core0.$strip>>>;
1112
+ exports: _$zod.ZodOptional<SubEntityClass<_$zod.ZodObject<{}, _$zod_v4_core0.$strict>>>;
1091
1113
  }, _$zod_v4_core0.$strict>, _$zod.ZodObject<Record<never, never>, _$zod_v4_core0.$strip>, "file", Record<never, never>, {
1092
1114
  readonly binary: ({
1093
1115
  path
@@ -1812,7 +1834,7 @@ declare const ReactNativeSystem: ConfigClass<{
1812
1834
  }, _$zod_v4_core0.$strip>>;
1813
1835
  export: _$zod.ZodOptional<_$zod.ZodString>;
1814
1836
  }, _$zod_v4_core0.$strict>;
1815
- readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
1837
+ readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
1816
1838
  readonly example: ({
1817
1839
  config
1818
1840
  }: {
@@ -1824,6 +1846,27 @@ declare const ReactNativeSystem: ConfigClass<{
1824
1846
  data: Record<string, unknown>;
1825
1847
  };
1826
1848
  };
1849
+ readonly 'create-blank': {
1850
+ readonly input: _$zod.ZodObject<{
1851
+ path: _$zod.ZodType<string, string | undefined, _$zod_v4_core0.$ZodTypeInternals<string, string | undefined>>;
1852
+ }, _$zod_v4_core0.$strip>;
1853
+ readonly readOnly: false;
1854
+ readonly label: "Create blank";
1855
+ readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
1856
+ readonly scope: "item";
1857
+ readonly creates: true;
1858
+ readonly title: (entity: string) => string;
1859
+ readonly example: ({
1860
+ config
1861
+ }: {
1862
+ config: Config;
1863
+ kind: string;
1864
+ path: string;
1865
+ }) => {
1866
+ path: string;
1867
+ };
1868
+ readonly handler: (input: Record<string, unknown>, config: Config) => Config;
1869
+ };
1827
1870
  readonly 'sub-create/anatomy': {
1828
1871
  readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
1829
1872
  };
@@ -2591,6 +2634,7 @@ declare const ReactNativeSystem: ConfigClass<{
2591
2634
  target: _$zod.ZodType<Ref, unknown, _$zod_v4_core0.$ZodTypeInternals<Ref, unknown>>;
2592
2635
  names: _$zod.ZodOptional<_$zod.ZodArray<_$zod.ZodString>>;
2593
2636
  }, _$zod_v4_core0.$strip>>>;
2637
+ exports: _$zod.ZodOptional<SubEntityClass<_$zod.ZodObject<{}, _$zod_v4_core0.$strict>>>;
2594
2638
  }, _$zod_v4_core0.$strict>, _$zod.ZodObject<Record<never, never>, _$zod_v4_core0.$strip>, "file", Record<never, never>, {
2595
2639
  readonly binary: ({
2596
2640
  path
@@ -17,6 +17,8 @@ import { settingsAsKindMigration } from "../migrations/20260908171448_settings_a
17
17
  import { visibleStatePointerMigration } from "../migrations/20260908194245_visible_state_pointer.js";
18
18
  import { iconKnockoutVariantsMigration } from "../migrations/20260909183001_icon_knockout_variants.js";
19
19
  import { linkedSystemLinkOpsMigration } from "../migrations/20260910212453_linked_system_link_ops.js";
20
+ import { componentCreateBlankOpMigration } from "../migrations/20260914155048_component_create_blank_op.js";
21
+ import { anatomyHarnessMigration } from "../migrations/20260914181845_anatomy_harness.js";
20
22
  import { NativeModifier } from "../entities/native/NativeModifier.js";
21
23
  import { NativeSettings } from "../entities/native/NativeSettings.js";
22
24
  import { NativeStyleProperty } from "../entities/native/NativeStyleProperty.js";
@@ -60,5 +62,7 @@ if (!registeredSchemaMigrations().has(20260908171448)) registerSchemaMigrations(
60
62
  if (!registeredSchemaMigrations().has(20260908194245)) registerSchemaMigrations(visibleStatePointerMigration);
61
63
  if (!registeredSchemaMigrations().has(20260909183001)) registerSchemaMigrations(iconKnockoutVariantsMigration);
62
64
  if (!registeredSchemaMigrations().has(20260910212453)) registerSchemaMigrations(linkedSystemLinkOpsMigration);
65
+ if (!registeredSchemaMigrations().has(20260914155048)) registerSchemaMigrations(componentCreateBlankOpMigration);
66
+ if (!registeredSchemaMigrations().has(20260914181845)) registerSchemaMigrations(anatomyHarnessMigration);
63
67
  //#endregion
64
68
  export { ReactNativeSystem };
@@ -298,7 +298,7 @@ declare const System: ConfigClass<{
298
298
  }, _$zod_v4_core0.$strip>>;
299
299
  export: _$zod.ZodOptional<_$zod.ZodString>;
300
300
  }, _$zod_v4_core0.$strict>;
301
- readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
301
+ readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
302
302
  readonly example: ({
303
303
  config
304
304
  }: {
@@ -310,6 +310,27 @@ declare const System: ConfigClass<{
310
310
  data: Record<string, unknown>;
311
311
  };
312
312
  };
313
+ readonly 'create-blank': {
314
+ readonly input: _$zod.ZodObject<{
315
+ path: _$zod.ZodType<string, string | undefined, _$zod_v4_core0.$ZodTypeInternals<string, string | undefined>>;
316
+ }, _$zod_v4_core0.$strip>;
317
+ readonly readOnly: false;
318
+ readonly label: "Create blank";
319
+ readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
320
+ readonly scope: "item";
321
+ readonly creates: true;
322
+ readonly title: (entity: string) => string;
323
+ readonly example: ({
324
+ config
325
+ }: {
326
+ config: Config;
327
+ kind: string;
328
+ path: string;
329
+ }) => {
330
+ path: string;
331
+ };
332
+ readonly handler: (input: Record<string, unknown>, config: Config) => Config;
333
+ };
313
334
  readonly 'sub-create/anatomy': {
314
335
  readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
315
336
  };
@@ -952,6 +973,7 @@ declare const System: ConfigClass<{
952
973
  target: _$zod.ZodType<Ref, unknown, _$zod_v4_core0.$ZodTypeInternals<Ref, unknown>>;
953
974
  names: _$zod.ZodOptional<_$zod.ZodArray<_$zod.ZodString>>;
954
975
  }, _$zod_v4_core0.$strip>>>;
976
+ exports: _$zod.ZodOptional<SubEntityClass<_$zod.ZodObject<{}, _$zod_v4_core0.$strict>>>;
955
977
  }, _$zod_v4_core0.$strict>, _$zod.ZodObject<Record<never, never>, _$zod_v4_core0.$strip>, "file", Record<never, never>, {
956
978
  readonly binary: ({
957
979
  path
@@ -1685,7 +1707,7 @@ declare const System: ConfigClass<{
1685
1707
  }, _$zod_v4_core0.$strip>>;
1686
1708
  export: _$zod.ZodOptional<_$zod.ZodString>;
1687
1709
  }, _$zod_v4_core0.$strict>;
1688
- readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
1710
+ readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
1689
1711
  readonly example: ({
1690
1712
  config
1691
1713
  }: {
@@ -1697,6 +1719,27 @@ declare const System: ConfigClass<{
1697
1719
  data: Record<string, unknown>;
1698
1720
  };
1699
1721
  };
1722
+ readonly 'create-blank': {
1723
+ readonly input: _$zod.ZodObject<{
1724
+ path: _$zod.ZodType<string, string | undefined, _$zod_v4_core0.$ZodTypeInternals<string, string | undefined>>;
1725
+ }, _$zod_v4_core0.$strip>;
1726
+ readonly readOnly: false;
1727
+ readonly label: "Create blank";
1728
+ readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
1729
+ readonly scope: "item";
1730
+ readonly creates: true;
1731
+ readonly title: (entity: string) => string;
1732
+ readonly example: ({
1733
+ config
1734
+ }: {
1735
+ config: Config;
1736
+ kind: string;
1737
+ path: string;
1738
+ }) => {
1739
+ path: string;
1740
+ };
1741
+ readonly handler: (input: Record<string, unknown>, config: Config) => Config;
1742
+ };
1700
1743
  readonly 'sub-create/anatomy': {
1701
1744
  readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
1702
1745
  };
@@ -2339,6 +2382,7 @@ declare const System: ConfigClass<{
2339
2382
  target: _$zod.ZodType<Ref, unknown, _$zod_v4_core0.$ZodTypeInternals<Ref, unknown>>;
2340
2383
  names: _$zod.ZodOptional<_$zod.ZodArray<_$zod.ZodString>>;
2341
2384
  }, _$zod_v4_core0.$strip>>>;
2385
+ exports: _$zod.ZodOptional<SubEntityClass<_$zod.ZodObject<{}, _$zod_v4_core0.$strict>>>;
2342
2386
  }, _$zod_v4_core0.$strict>, _$zod.ZodObject<Record<never, never>, _$zod_v4_core0.$strip>, "file", Record<never, never>, {
2343
2387
  readonly binary: ({
2344
2388
  path
@@ -27,6 +27,8 @@ import { iconKnockoutVariantsMigration } from "../migrations/20260909183001_icon
27
27
  import { linkedSystemLinkOpsMigration } from "../migrations/20260910212453_linked_system_link_ops.js";
28
28
  import { previewConditionsMigration } from "../migrations/20260912161840_preview_conditions.js";
29
29
  import { fontVariableMigration } from "../migrations/20260912164927_font_variable.js";
30
+ import { componentCreateBlankOpMigration } from "../migrations/20260914155048_component_create_blank_op.js";
31
+ import { anatomyHarnessMigration } from "../migrations/20260914181845_anatomy_harness.js";
30
32
  //#region src/configs/system.ts
31
33
  /**
32
34
  * `System` — the design-system config TYPE. Declares the exact kinds a design system owns (tokens,
@@ -74,5 +76,7 @@ if (!registeredSchemaMigrations().has(20260909183001)) registerSchemaMigrations(
74
76
  if (!registeredSchemaMigrations().has(20260910212453)) registerSchemaMigrations(linkedSystemLinkOpsMigration);
75
77
  if (!registeredSchemaMigrations().has(20260912161840)) registerSchemaMigrations(previewConditionsMigration);
76
78
  if (!registeredSchemaMigrations().has(20260912164927)) registerSchemaMigrations(fontVariableMigration);
79
+ if (!registeredSchemaMigrations().has(20260914155048)) registerSchemaMigrations(componentCreateBlankOpMigration);
80
+ if (!registeredSchemaMigrations().has(20260914181845)) registerSchemaMigrations(anatomyHarnessMigration);
77
81
  //#endregion
78
82
  export { System };
@@ -438,6 +438,17 @@ declare const componentFields: z.ZodObject<{
438
438
  * a surface that needs a field the schema doesn't declare is a gap in the schema, not a cast.
439
439
  */
440
440
  type ComponentBody = z.infer<typeof componentFields>;
441
+ /**
442
+ * The body a blank component is created with: one intrinsic `div` layer and the anatomy node that
443
+ * renders it, nothing else. Studio's "+" and the `create-blank` op both write exactly this.
444
+ *
445
+ * Both halves are needed. The kind requires a `root` layer, but layers alone project the component
446
+ * rendering itself, a painting with nothing to compose into; the node is what puts a real `div`
447
+ * carrying the editor's selection markers on the canvas. `div` is an intrinsic tag rather than a
448
+ * system component, so no system is without it. Anything more (a `children` slot, preview content, a
449
+ * style rule) makes the component authored rather than blank, and the editor's drop frame stands down.
450
+ */
451
+ declare function blankComponentBody(): ComponentBody;
441
452
  declare const ComponentEntity: EntityClass<z.ZodObject<{
442
453
  layers: SubEntityClass<z.ZodUnion<readonly [z.ZodString, z.ZodLazy<z.ZodType<Ref, unknown, z.core.$ZodTypeInternals<Ref, unknown>>>, EntityClass<z.ZodObject<{
443
454
  version: z.ZodOptional<z.ZodString>;
@@ -671,7 +682,7 @@ declare const ComponentEntity: EntityClass<z.ZodObject<{
671
682
  }, z.core.$strip>>;
672
683
  export: z.ZodOptional<z.ZodString>;
673
684
  }, z.core.$strict>;
674
- readonly description: "Create a component at a new qualified `path`. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
685
+ readonly description: "Create a component at a new qualified `path`. For a component with nothing in it yet, one to design on the canvas before it has props or variants, use `create-blank` with only a `path` instead of authoring a minimal body here. When its complete body is known, include all layers, anatomy, props, defaults, and styles in this one operation. `data.layers` maps each stable layer name to the element it renders and must include `root` — a tag for a primitive (`{ \"layers\": { \"root\": \"div\" } }`), and for anything built on top, a ref to a primitive (`{ \"root\": { \"__ref\": \"component:Box\" }, \"label\": { \"__ref\": \"component:Text\" } }`), which is what lets the layer take that primitive's style props. A primitive exposes style props as `{ \"type\": \"styleProperty\", \"value\": { \"__ref\": \"style-property:bg\" } }` and declares `children: { \"type\": \"slot\", \"text\": true }` when it holds content — without the slot, nothing nested inside it renders. A composed component exposes a layer's props at its own top level through `forwards`, keyed by layer: `{ \"forwards\": { \"root\": \"*\" } }` passes every prop the root's element takes (so `<Button width=\"full\">` reaches the root's `width`), and a list of member refs (`[{ \"__ref\": \"component:Box#props/width\" }]`, each naming the component that declares the prop) passes only those. A prop a layer already exposes is forwarded, never redeclared in `props`; a `props` entry of `{ \"type\": \"forward\" }` is the reverse route, one of this component's props into a layer's. `anatomy` is the tree the build would read off a render: each node renders a layer (`{ \"__ref\": \"layer:<name>\" }`), an intrinsic tag, or `Slot` (`{ \"element\": \"Slot\", \"props\": { \"name\": \"children\" } }`, where a slot prop's content lands — but a declared slot fills `root` by default, so a primitive still declares its `children` slot prop yet needs no `Slot` node or `children` entry for it, and a `Slot` node is only for landing that content in a nested layer); `children` lists sibling node keys from the `root` node, never a prop name; `text` is a fixed string; `visible` is a condition on a prop (`{ \"$state\": \"<prop>\" }`, or with `eq`); content shown in a nested layer is a route, `children: { \"type\": \"forward\", \"target\": \"label/children\" }`. `$state` appears only in `visible` and in an `element` a prop chooses, never as a prop value. A glyph is a node of its own, `{ \"element\": { \"__ref\": \"icon:<library>/<Name>\" } }`, listed in the `children` of the layer node that holds it, never a prop value. Text a prop supplies to a text layer is never a node either: declare the prop `{ \"type\": \"forward\", \"target\": \"<layer>/children\" }` and the layer shows it; a `Slot` node goes only under a layer that takes nodes. A style rule is `\"styles\": { \"*\": { \"when\": null, \"layers\": { \"root\": { \"bg\": \"surface\" } } } }`, keyed by a name, with each layer's bag under `layers`. A composed component carries its own styles: give it an unconditional (`\"*\"`) rule that lays out and surfaces it through the system's style properties — spacing, alignment and gap on the container, a background and color where it has one — rather than leaning on the bare primitives, which paint flat. Style a layer only with the style props the primitive it renders exposes, set to the values those props accept: `component/get` on the primitive lists both, so read it and choose from that rather than reaching for a CSS name or value the system has no style property for. Set `previewProps` (or `defaultProps`) so the component previews with content; a root that takes children renders empty otherwise. A style rule's layer bag is keyed by style-prop name (`fontWeight`, `color`), never by CSS property name, and each value is one of that prop's values.";
675
686
  readonly example: ({
676
687
  config
677
688
  }: {
@@ -683,6 +694,33 @@ declare const ComponentEntity: EntityClass<z.ZodObject<{
683
694
  data: Record<string, unknown>;
684
695
  };
685
696
  };
697
+ /**
698
+ * A component with nothing in it yet, as Studio's "+" makes one. Its own op because `create`
699
+ * teaches the full grammar, and a model asked for a blank component authors a `children` slot and
700
+ * preview content from it, at which point the component is no longer blank. Decomposes into the one
701
+ * `create` patch the rail writes, so the changes list and undo read both gestures alike.
702
+ */
703
+ readonly 'create-blank': {
704
+ readonly input: z.ZodObject<{
705
+ path: z.ZodType<string, string | undefined, z.core.$ZodTypeInternals<string, string | undefined>>;
706
+ }, z.core.$strip>;
707
+ readonly readOnly: false;
708
+ readonly label: "Create blank";
709
+ readonly description: "Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio's \"+\" creates. Takes only `path`. Use it for \"a new component\", \"a blank component\" or \"start a component from nothing\"; `create` is for a component whose body is already known.";
710
+ readonly scope: "item";
711
+ readonly creates: true;
712
+ readonly title: (entity: string) => string;
713
+ readonly example: ({
714
+ config
715
+ }: {
716
+ config: Config;
717
+ kind: string;
718
+ path: string;
719
+ }) => {
720
+ path: string;
721
+ };
722
+ readonly handler: (input: Record<string, unknown>, config: Config) => Config;
723
+ };
686
724
  readonly 'sub-create/anatomy': {
687
725
  readonly description: "Add one anatomy node (`key` + `data`) to a component. In a batch, create child nodes before a parent whose `children` or `slots` names them; each referenced node must already exist when this operation runs.";
688
726
  };
@@ -1297,4 +1335,4 @@ declare const Component: Omit<typeof ComponentEntity, "ref"> & {
1297
1335
  ref<const Path extends PathOf<"component">>(path: Path): ComponentReference<ComponentContractOf<Path>>;
1298
1336
  };
1299
1337
  //#endregion
1300
- export { AuthoredPropBody, Component, ComponentBody, ComponentElementBody, ComponentPropBody, ComponentReference, ComponentStyleBody, ElementVisibility, ElementVisibilityInput, ExtendedComponentRef, ProjectedVisibility, VariantValueBody, VariantValues, canonicalWhen, forwardedNames, layerRef, ownValues, ownsItsValues, valueRef };
1338
+ export { AuthoredPropBody, Component, ComponentBody, ComponentElementBody, ComponentPropBody, ComponentReference, ComponentStyleBody, ElementVisibility, ElementVisibilityInput, ExtendedComponentRef, ProjectedVisibility, VariantValueBody, VariantValues, blankComponentBody, canonicalWhen, forwardedNames, layerRef, ownValues, ownsItsValues, valueRef };