@ufira/vibma 1.0.0-rc5 → 1.0.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.
@@ -62,9 +62,9 @@ Use help(topic: "<endpoint>") for endpoint details.
62
62
  Use help(topic: "<endpoint>.<method>") for method details.`;
63
63
  var helpEndpoints = {
64
64
  "components": {
65
- "summary": '# components\nCreate and manage reusable components and variant sets.\n\nMethods:\n clone Duplicate nodes [create]\n audit Run lint on a node \u2014 returns severity-ranked findings [read]\n reparent Move nodes into a new parent [edit]\n list List local component names (variant sets as single entries) [read]\n get Get component detail \u2014 property definitions + optional node tree for structural inspection [read]\n create Create components [create]\n update Add, edit, or delete component properties [edit]\n delete Delete components or component sets [edit]\n\n// depth: omit \u2192 id+name stubs | 0 \u2192 props + child stubs | N \u2192 recurse N | -1 \u2192 full tree\n// fields: whitelist e.g. ["fills","opacity"] \u2014 id, name, type always included. Pass ["*"] for all.\n// layoutSizingHorizontal/Vertical: FIXED | HUG | FILL \u2014 how the node sizes within auto-layout.\n// Colors: fillVariableName/strokeVariableName bind by name \u2014 preferred over raw color values.\n// Note: node-based endpoints (frames, text, instances, components) use `results` as the list key.\n// Standalone endpoints (styles, variables, variable_collections) use `items`. Components.list uses `items` (catalog view).\n// ---\n// visible: false hides the node. Omitted from response when true (the default).\n// locked: true prevents editing in Figma UI. Omitted when false (the default).\n// rotation: degrees (0-360). Omitted when 0.\n// blendMode: layer blend mode. Omitted when PASS_THROUGH (the default).\n// layoutPositioning: ABSOLUTE = floating inside auto-layout parent. Omitted when AUTO (the default).\n// minWidth/maxWidth/minHeight/maxHeight: responsive constraints for auto-layout children.\n// constraints: position behavior in non-auto-layout parents. Ignored inside auto-layout frames.\n// bindings: bind design variables to node properties. field uses slash path: "fills/0/color" (first fill), "strokes/0/color", "opacity", "width", "height", "cornerRadius", "paddingLeft", "itemSpacing".\n// explicitMode: pin a variable mode on this node. Use { collectionName, modeName } (preferred) or { collectionId, modeId }.\n// properties: escape hatch \u2014 set any Figma node property directly. Use only when no dedicated field exists.\ninterface Node {\n id: string; name: string; type: string;\n visible?: boolean; // omitted when true\n locked?: boolean; // omitted when false\n opacity?: number; // omitted when 1\n rotation?: number; // omitted when 0\n blendMode?: string; // omitted when PASS_THROUGH\n layoutPositioning?: "AUTO" | "ABSOLUTE";\n layoutSizingHorizontal?: "FIXED" | "HUG" | "FILL";\n layoutSizingVertical?: "FIXED" | "HUG" | "FILL";\n minWidth?: number; maxWidth?: number; minHeight?: number; maxHeight?: number;\n absoluteBoundingBox: { x: number; y: number; width: number; height: number };\n fills?: Paint[]; // solid: {type: "SOLID", color: {r, g, b, a}}\n strokes?: Paint[];\n effects?: Effect[]; // DROP_SHADOW | INNER_SHADOW | LAYER_BLUR | BACKGROUND_BLUR\n children?: NodeStub[]; // stubs: {id, name, type} \u2014 use depth to expand\n}\n// PatchItem uses flat params matching create shape \u2014 no nested sub-objects.\n// Fill/stroke/corner/layout/text params are identical to frames.create and text.create.\n// Unknown keys produce a warning, preventing silent failures.\n// Components are reusable design elements. Instances stay linked to the component and inherit changes.\n// Workflow: create component (with properties) \u2192 add children \u2192 create instances via instances.create.\n// ---\n// A component set (variant set) groups related components as variants (e.g. Button/Primary, Button/Secondary).\n// Property types: BOOLEAN (toggle visibility), TEXT (editable text), INSTANCE_SWAP (swap child instance), VARIANT (variant picker).\n// exposeText: when creating from_node, text children become editable TEXT properties on the component.\n// Auto-bind: TEXT properties auto-bind to text children with matching names (case-insensitive).\n// Example: properties:[{propertyName:"Label", type:"TEXT", defaultValue:"Click"}] binds to a child text node named "Label".\n// text.create accepts componentPropertyName to bind on creation \u2014 walks up ancestors to find the nearest component.\n// For nested text (text inside frames inside a component), componentPropertyName resolves via ancestor walk. Alternatively, pass componentId explicitly.\n// For existing nodes with many text children, prefer components(method:"create", type:"from_node", exposeText:true) \u2014 it auto-discovers, creates TEXT properties, and binds all text nodes in one operation.\n// Property keys: read returns clean names ("Label"), write requires the #suffix ("Label#1:0"). Call components.get(id) to discover exact keys before edit/delete.\n// ComponentItem accepts the same params as FrameItem (layout, fill, stroke, sizing, min/max).\n// A component IS a frame \u2014 create it directly with all layout properties, then add children.\n// SIZING: Components with text need a width constraint \u2014 set width + layoutSizingHorizontal:"FIXED".\n// Without it, text won\'t wrap and the component grows unboundedly.\n// HUG on both axes is only correct for intrinsically-sized elements (buttons, badges, icons).\n// action: "add" (default) \u2014 requires type + defaultValue. "edit" \u2014 pass defaultValue to change value, name to rename property. "delete" \u2014 just propertyName#suffix.\n// action: "rename_variant" \u2014 renames a variant option VALUE (not the property). Pass defaultValue=current option name, name=new option name.\n// For VARIANT properties: "edit" with defaultValue reorders children to set the default variant.\n// Adding variants: clone an existing variant into the set with a new name. See guidelines(topic:"component-structure") for workflow.\n\nUse components(method: "help", topic: "<method>") for method details.',
65
+ "summary": '# components\nCreate and manage reusable components and variant sets.\n\nMethods:\n clone Duplicate nodes [create]\n audit Run lint on a node \u2014 returns severity-ranked findings [read]\n reparent Move nodes into a new parent [edit]\n list List local component names (variant sets as single entries) [read]\n get Get component detail \u2014 property definitions + optional node tree for structural inspection [read]\n create Create components [create]\n commit Commit a staged component \u2014 unwraps from [STAGED] container into the original target location. [edit]\n update Add, edit, or delete component properties [edit]\n delete Delete components or component sets [edit]\n\n// depth: omit \u2192 id+name stubs | 0 \u2192 props + child stubs | N \u2192 recurse N | -1 \u2192 full tree\n// fields: whitelist e.g. ["fills","opacity"] \u2014 id, name, type always included. Pass ["*"] for all.\n// layoutSizingHorizontal/Vertical: FIXED | HUG | FILL \u2014 how the node sizes within auto-layout.\n// Colors: fillVariableName/strokeVariableName bind by name \u2014 preferred over raw color values.\n// Note: node-based endpoints (frames, text, instances, components) use `results` as the list key.\n// Standalone endpoints (styles, variables, variable_collections) use `items`. Components.list uses `items` (catalog view).\n// ---\n// visible: false hides the node. Omitted from response when true (the default).\n// locked: true prevents editing in Figma UI. Omitted when false (the default).\n// rotation: degrees (0-360). Omitted when 0.\n// blendMode: layer blend mode. Omitted when PASS_THROUGH (the default).\n// layoutPositioning: ABSOLUTE = floating inside auto-layout parent. Omitted when AUTO (the default).\n// minWidth/maxWidth/minHeight/maxHeight: responsive constraints for auto-layout children.\n// constraints: position behavior in non-auto-layout parents. Ignored inside auto-layout frames.\n// bindings: bind design variables to node properties. field uses slash path: "fills/0/color" (first fill), "strokes/0/color", "opacity", "width", "height", "cornerRadius", "paddingLeft", "itemSpacing".\n// explicitMode: pin a variable mode on this node. Use { collectionName, modeName } (preferred) or { collectionId, modeId }.\n// properties: escape hatch \u2014 set any Figma node property directly. Use only when no dedicated field exists.\ninterface Node {\n id: string; name: string; type: string;\n visible?: boolean; // omitted when true\n locked?: boolean; // omitted when false\n opacity?: number; // omitted when 1\n rotation?: number; // omitted when 0\n blendMode?: string; // omitted when PASS_THROUGH\n layoutPositioning?: "AUTO" | "ABSOLUTE";\n layoutSizingHorizontal?: "FIXED" | "HUG" | "FILL";\n layoutSizingVertical?: "FIXED" | "HUG" | "FILL";\n minWidth?: number; maxWidth?: number; minHeight?: number; maxHeight?: number;\n absoluteBoundingBox: { x: number; y: number; width: number; height: number };\n fills?: Paint[]; // solid: {type: "SOLID", color: {r, g, b, a}}\n strokes?: Paint[];\n effects?: Effect[]; // DROP_SHADOW | INNER_SHADOW | LAYER_BLUR | BACKGROUND_BLUR\n children?: NodeStub[]; // stubs: {id, name, type} \u2014 use depth to expand\n}\n// PatchItem uses flat params matching create shape \u2014 no nested sub-objects.\n// Fill/stroke/corner/layout/text params are identical to frames.create and text.create.\n// Unknown keys produce a warning, preventing silent failures.\n// Components are reusable design elements. Instances stay linked to the component and inherit changes.\n// Workflow: create component (with properties) \u2192 add children \u2192 create instances via instances.create.\n// ---\n// A component set (variant set) groups related components as variants (e.g. Button/Primary, Button/Secondary).\n// Property types: BOOLEAN (toggle visibility), TEXT (editable text), INSTANCE_SWAP (swap child instance), VARIANT (variant picker).\n// exposeText: when creating from_node, text children become editable TEXT properties on the component.\n// Auto-bind: TEXT properties auto-bind to text children with matching names (case-insensitive).\n// Example: properties:[{propertyName:"Label", type:"TEXT", defaultValue:"Click"}] binds to a child text node named "Label".\n// text.create accepts componentPropertyName to bind on creation \u2014 walks up ancestors to find the nearest component.\n// For nested text (text inside frames inside a component), componentPropertyName resolves via ancestor walk. Alternatively, pass componentId explicitly.\n// For existing nodes with many text children, prefer components(method:"create", type:"from_node", exposeText:true) \u2014 it auto-discovers, creates TEXT properties, and binds all text nodes in one operation.\n// Property keys: read returns clean names ("Label"), write requires the #suffix ("Label#1:0"). Call components.get(id) to discover exact keys before edit/delete.\n// ComponentItem accepts the same params as FrameItem (layout, fill, stroke, sizing, min/max).\n// A component IS a frame \u2014 create it directly with all layout properties, then add children.\n// SIZING: Components with text need a width constraint \u2014 set width + layoutSizingHorizontal:"FIXED".\n// Without it, text won\'t wrap and the component grows unboundedly.\n// HUG on both axes is only correct for intrinsically-sized elements (buttons, badges, icons).\n// action: "add" (default) \u2014 requires type + defaultValue. "edit" \u2014 pass defaultValue to change value, name to rename property. "delete" \u2014 just propertyName#suffix.\n// action: "rename_variant" \u2014 renames a variant option VALUE (not the property). Pass defaultValue=current option name, name=new option name.\n// For VARIANT properties: "edit" with defaultValue reorders children to set the default variant.\n// Adding variants: clone an existing variant into the set with a new name. See guidelines(topic:"component-structure") for workflow.\n\nUse components(method: "help", topic: "<method>") for method details.',
66
66
  "methods": {
67
- "clone": "# components.clone\nDuplicate nodes\n\nParams:\n id (string, optional) \u2014 Node ID\n name (string, optional) \u2014 Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)\n parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.\n x (number, optional) \u2014 X position (default: 0)\n y (number, optional) \u2014 Y position (default: 0)\n items (array, optional) \u2014 Batch: [{id, name?, parentId?, x?, y?}, ...]. Alternative to single-item params.\n id (string, required) \u2014 Node ID to clone\n name (string, optional) \u2014 Rename the clone\n parentId (string, optional) \u2014 Target parent\n x (number, optional)\n y (number, optional)\n depth (number, optional) \u2014 Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.",
67
+ "clone": "# components.clone\nDuplicate nodes\n\nParams:\n id (string, optional) \u2014 Node ID\n name (string, optional) \u2014 Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)\n parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.\n x (number, optional) \u2014 X position (default: 0)\n y (number, optional) \u2014 Y position (default: 0)\n items (array, optional) \u2014 Batch: [{id, name?, parentId?, x?, y?}, ...]. Alternative to single-item params.\n id (string, required) \u2014 Node ID to clone\n name (string, optional) \u2014 Rename the clone\n parentId (string, optional) \u2014 Target parent\n x (number, optional)\n y (number, optional)\n depth (number, optional) \u2014 Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.",
68
68
  "audit": `# components.audit
69
69
  Run lint on a node \u2014 returns severity-ranked findings
70
70
 
@@ -87,7 +87,7 @@ Discriminant: type (component | from_node | variant_set)
87
87
 
88
88
  ## component \u2014 Create component with full frame properties (layout, fill, stroke, sizing). A component IS a frame \u2014 build directly, no need to create a frame first.
89
89
  name (string, required) \u2014 Component name
90
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
90
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
91
91
  x (number, optional) \u2014 X position (default: 0)
92
92
  y (number, optional) \u2014 Y position (default: 0)
93
93
  width (number, optional) \u2014 Width in px (omit to shrink-to-content via HUG)
@@ -120,7 +120,7 @@ Discriminant: type (component | from_node | variant_set)
120
120
  bottomLeftRadius (string, optional)
121
121
  effectStyleName (string, optional) \u2014 Effect style name (e.g. 'Shadow/Card') for shadows, blurs
122
122
  layoutMode (NONE | HORIZONTAL | VERTICAL, optional) \u2014 Layout direction (default: auto \u2014 NONE when width+height set, otherwise inferred from layout props)
123
- layoutWrap (NO_WRAP | WRAP, optional)
123
+ layoutWrap (NO_WRAP | WRAP, optional) \u2014 Wrap children to new rows (HORIZONTAL layout only \u2014 Figma does not support WRAP on VERTICAL layouts). Use column frames inside a HORIZONTAL parent for vertical grid patterns.
124
124
  padding (string, optional) \u2014 All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft.
125
125
  paddingTop (string, optional)
126
126
  paddingRight (string, optional)
@@ -138,6 +138,8 @@ Discriminant: type (component | from_node | variant_set)
138
138
  maxHeight (number, optional) \u2014 Max height for responsive auto-layout
139
139
  overflowDirection (NONE | HORIZONTAL | VERTICAL | BOTH, optional) \u2014 Scroll overflow in prototype (default: NONE)
140
140
  description (string, optional) \u2014 Component description (shown in Figma's component panel)
141
+ children (array, optional) \u2014 Inline child nodes \u2014 build nested trees in one call. Types: text: {type:"text", text, componentPropertyName?, fontFamily?, fontSize?, fontWeight?, fontStyle?, fontColor?, layoutSizingHorizontal?}. frame: {type:"frame", name?, layoutMode?, fillColor?, width?, layoutSizingHorizontal?, children?}. instance: {type:"instance", componentId, componentPropertyName?, variantProperties?, properties?}. component: {type:"component", name, children?}. All params from text/frame endpoints are supported on their respective types. componentPropertyName auto-creates and binds a TEXT (text) or INSTANCE_SWAP (instance) property. Always set layoutSizingHorizontal + layoutSizingVertical on children inside auto-layout parents (FILL, HUG, or FIXED). Example: children:[{type:"text", text:"Label", componentPropertyName:"Label", fontSize:14, fontColorVariableName:"text/primary", layoutSizingHorizontal:"FILL", layoutSizingVertical:"HUG"}, {type:"frame", name:"Actions", layoutMode:"HORIZONTAL", layoutSizingHorizontal:"FILL", layoutSizingVertical:"HUG", itemSpacing:8, children:[{type:"instance", componentId:"1:2", componentPropertyName:"Action", layoutSizingHorizontal:"FILL", layoutSizingVertical:"HUG"}]}]
142
+
141
143
  properties (array, optional) \u2014 Component properties to define at creation: [{propertyName, type, defaultValue}]. TEXT properties for inline children with componentPropertyName are created automatically.
142
144
  propertyName (string, required) \u2014 Property name
143
145
  type (BOOLEAN | TEXT | INSTANCE_SWAP, required) \u2014 Property type
@@ -146,11 +148,12 @@ Discriminant: type (component | from_node | variant_set)
146
148
 
147
149
  ## from_node \u2014 Convert existing nodes to components. Text children auto-exposed as editable properties (exposeText: true).
148
150
  nodeId (string, required) \u2014 Node ID to convert
151
+ name (string, optional) \u2014 Rename the component (default: keeps the node's current name)
149
152
  exposeText (boolean, optional) \u2014 Auto-expose text as editable properties (default: true)
150
153
 
151
154
  ## variant_set \u2014 Combine components into a variant set. The resulting set is a frame \u2014 accepts all frame properties for layout/styling.
152
155
  name (string, optional) \u2014 Node name
153
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
156
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
154
157
  x (number, optional) \u2014 X position (default: 0)
155
158
  y (number, optional) \u2014 Y position (default: 0)
156
159
  width (number, optional) \u2014 Width in px (omit to shrink-to-content via HUG)
@@ -183,7 +186,7 @@ Discriminant: type (component | from_node | variant_set)
183
186
  bottomLeftRadius (string, optional)
184
187
  effectStyleName (string, optional) \u2014 Effect style name (e.g. 'Shadow/Card') for shadows, blurs
185
188
  layoutMode (NONE | HORIZONTAL | VERTICAL, optional) \u2014 Layout direction (default: auto \u2014 NONE when width+height set, otherwise inferred from layout props)
186
- layoutWrap (NO_WRAP | WRAP, optional)
189
+ layoutWrap (NO_WRAP | WRAP, optional) \u2014 Wrap children to new rows (HORIZONTAL layout only \u2014 Figma does not support WRAP on VERTICAL layouts). Use column frames inside a HORIZONTAL parent for vertical grid patterns.
187
190
  padding (string, optional) \u2014 All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft.
188
191
  paddingTop (string, optional)
189
192
  paddingRight (string, optional)
@@ -201,7 +204,9 @@ Discriminant: type (component | from_node | variant_set)
201
204
  maxHeight (number, optional) \u2014 Max height for responsive auto-layout
202
205
  overflowDirection (NONE | HORIZONTAL | VERTICAL | BOTH, optional) \u2014 Scroll overflow in prototype (default: NONE)
203
206
  componentIds (string[], optional) \u2014 Existing component IDs to combine (min 2). Alternative to children.
204
- variantPropertyName (string, optional) \u2014 Rename the auto-generated variant property (default: 'Property 1')`,
207
+ variantPropertyName (string, optional) \u2014 Rename the auto-generated variant property (default: 'Property 1')
208
+ children (array, optional) \u2014 Inline variant components. Each must be {type:"component", name, children?, ...frame_params}. All variants must share the same child structure. Alternative to componentIds \u2014 do not combine both.`,
209
+ "commit": '# components.commit\nCommit a staged component \u2014 unwraps from [STAGED] container into the original target location.\n\nExample: components(method:"commit", id:"1:234")\n\nParams:\n id (string, required) \u2014 Staged node ID to commit',
205
210
  "update": '# components.update\nAdd, edit, or delete component properties\n\nExample: components(method:"update", items:[{id:"1:23", propertyName:"Label", action:"edit", defaultValue:"Click Me"}])\n\nParams:\n items (UpdatePropertyItem[], required) \u2014 Array of {id, propertyName, action?, type?, defaultValue?, name?, preferredValues?}\n id (string, required) \u2014 Component or component set ID\n propertyName (string, required) \u2014 Property name with #suffix for edit/delete (e.g. "Label#1:0"). Call components.get to find exact keys. For add, plain name works.\n action (add | edit | delete | rename_variant, optional) \u2014 "add" (default): requires type + defaultValue. "edit": pass defaultValue to change default, name to rename property. "delete": just propertyName. "rename_variant": pass defaultValue=current option name, name=new option name.\n type (BOOLEAN | TEXT | INSTANCE_SWAP | VARIANT, optional) \u2014 Property type (required for add)\n defaultValue (string_or_boolean, optional) \u2014 Default value (add/edit). For rename_variant: the CURRENT option name to rename\n name (string, optional) \u2014 New name \u2014 for edit: renames the property itself, for rename_variant: the new option value name\n preferredValues (array, optional) \u2014 Preferred values for INSTANCE_SWAP\n depth (number, optional) \u2014 Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.',
206
211
  "delete": "# components.delete\nDelete components or component sets\n\nParams:\n id (string, required) \u2014 Component or component set ID"
207
212
  }
@@ -232,7 +237,7 @@ Discriminant: type (component | from_node | variant_set)
232
237
  }
233
238
  },
234
239
  "frames": {
235
- "summary": '# frames\nCreate and manage frames, shapes, auto-layout containers, sections, and SVG nodes.\n\nMethods:\n get Get serialized node data [read]\n list Search for nodes (returns stubs only \u2014 use get with depth for full properties) [read]\n update Patch node properties [edit]\n delete Delete nodes [edit]\n clone Duplicate nodes [create]\n audit Run lint on a node \u2014 returns severity-ranked findings [read]\n reparent Move nodes into a new parent [edit]\n create Create frame-like containers [create]\n export Export a node as PNG, JPG, SVG, SVG_STRING, or PDF [read]\n\n// depth: omit \u2192 id+name stubs | 0 \u2192 props + child stubs | N \u2192 recurse N | -1 \u2192 full tree\n// fields: whitelist e.g. ["fills","opacity"] \u2014 id, name, type always included. Pass ["*"] for all.\n// layoutSizingHorizontal/Vertical: FIXED | HUG | FILL \u2014 how the node sizes within auto-layout.\n// Colors: fillVariableName/strokeVariableName bind by name \u2014 preferred over raw color values.\n// Note: node-based endpoints (frames, text, instances, components) use `results` as the list key.\n// Standalone endpoints (styles, variables, variable_collections) use `items`. Components.list uses `items` (catalog view).\n// ---\n// visible: false hides the node. Omitted from response when true (the default).\n// locked: true prevents editing in Figma UI. Omitted when false (the default).\n// rotation: degrees (0-360). Omitted when 0.\n// blendMode: layer blend mode. Omitted when PASS_THROUGH (the default).\n// layoutPositioning: ABSOLUTE = floating inside auto-layout parent. Omitted when AUTO (the default).\n// minWidth/maxWidth/minHeight/maxHeight: responsive constraints for auto-layout children.\n// constraints: position behavior in non-auto-layout parents. Ignored inside auto-layout frames.\n// bindings: bind design variables to node properties. field uses slash path: "fills/0/color" (first fill), "strokes/0/color", "opacity", "width", "height", "cornerRadius", "paddingLeft", "itemSpacing".\n// explicitMode: pin a variable mode on this node. Use { collectionName, modeName } (preferred) or { collectionId, modeId }.\n// properties: escape hatch \u2014 set any Figma node property directly. Use only when no dedicated field exists.\ninterface Node {\n id: string; name: string; type: string;\n visible?: boolean; // omitted when true\n locked?: boolean; // omitted when false\n opacity?: number; // omitted when 1\n rotation?: number; // omitted when 0\n blendMode?: string; // omitted when PASS_THROUGH\n layoutPositioning?: "AUTO" | "ABSOLUTE";\n layoutSizingHorizontal?: "FIXED" | "HUG" | "FILL";\n layoutSizingVertical?: "FIXED" | "HUG" | "FILL";\n minWidth?: number; maxWidth?: number; minHeight?: number; maxHeight?: number;\n absoluteBoundingBox: { x: number; y: number; width: number; height: number };\n fills?: Paint[]; // solid: {type: "SOLID", color: {r, g, b, a}}\n strokes?: Paint[];\n effects?: Effect[]; // DROP_SHADOW | INNER_SHADOW | LAYER_BLUR | BACKGROUND_BLUR\n children?: NodeStub[]; // stubs: {id, name, type} \u2014 use depth to expand\n}\n// PatchItem uses flat params matching create shape \u2014 no nested sub-objects.\n// Fill/stroke/corner/layout/text params are identical to frames.create and text.create.\n// Unknown keys produce a warning, preventing silent failures.\n// Frames are the primary container in Figma. Use auto_layout for responsive containers.\n// Sizing: FIXED = explicit size, HUG = shrink to children, FILL = expand to fill parent.\n// Fill: pass fills:[{type:"SOLID", color:"#hex"}] or [] for transparent. Shorthand: fillColor:"#3B82F6" (auto-binds to matching variable/style).\n// Also: fillVariableName:"bg/primary", fillStyleName:"Surface/Primary".\n// Stroke: pass strokes:[{type:"SOLID", color:"#hex"}] or [] to clear. Shorthand: strokeColor:"#000", strokeVariableName:"border/default".\n// Token fields (cornerRadius, opacity, itemSpacing, padding, strokeWeight): pass number for value, string for variable name/ID.\n// ---\n// SIZING: Always think about both axes. Containers with text need a width constraint \u2014 set width + layoutSizingHorizontal:"FIXED".\n// HUG/HUG is only correct for intrinsically-sized elements (buttons, badges, icons).\n// Smart defaults inside auto-layout parent: cross-axis defaults to FILL, primary axis stays HUG.\n// FILL only works inside an auto-layout parent. Use FIXED for top-level frames.\n// minWidth/maxWidth/minHeight/maxHeight: responsive constraints for auto-layout children.\n// clipsContent: true (default) clips children to the frame bounds. Set false for overflow-visible.\n// Sections are top-level organizers (like artboards) \u2014 they cannot be nested inside frames.\n// Shape primitives: rectangle, ellipse, line \u2014 for decorative/visual elements (not containers).\n// group: wraps existing nodes into a Group. boolean_operation: UNION/SUBTRACT/INTERSECT/EXCLUDE combines shapes.\n// SVG create: pass raw SVG markup string (e.g. "<svg>...</svg>") \u2014 Figma converts it to vector nodes.\n\nUse frames(method: "help", topic: "<method>") for method details.',
240
+ "summary": '# frames\nCreate and manage frames, shapes, auto-layout containers, sections, and SVG nodes.\n\nMethods:\n get Get serialized node data [read]\n list Search for nodes (returns stubs only \u2014 use get with depth for full properties) [read]\n update Patch node properties [edit]\n delete Delete nodes [edit]\n clone Duplicate nodes [create]\n audit Run lint on a node \u2014 returns severity-ranked findings [read]\n reparent Move nodes into a new parent [edit]\n create Create frame-like containers [create]\n commit Commit a staged node \u2014 unwraps from [STAGED] container into the original target location. [edit]\n export Export a node as PNG, JPG, SVG, SVG_STRING, or PDF [read]\n\n// depth: omit \u2192 id+name stubs | 0 \u2192 props + child stubs | N \u2192 recurse N | -1 \u2192 full tree\n// fields: whitelist e.g. ["fills","opacity"] \u2014 id, name, type always included. Pass ["*"] for all.\n// layoutSizingHorizontal/Vertical: FIXED | HUG | FILL \u2014 how the node sizes within auto-layout.\n// Colors: fillVariableName/strokeVariableName bind by name \u2014 preferred over raw color values.\n// Note: node-based endpoints (frames, text, instances, components) use `results` as the list key.\n// Standalone endpoints (styles, variables, variable_collections) use `items`. Components.list uses `items` (catalog view).\n// ---\n// visible: false hides the node. Omitted from response when true (the default).\n// locked: true prevents editing in Figma UI. Omitted when false (the default).\n// rotation: degrees (0-360). Omitted when 0.\n// blendMode: layer blend mode. Omitted when PASS_THROUGH (the default).\n// layoutPositioning: ABSOLUTE = floating inside auto-layout parent. Omitted when AUTO (the default).\n// minWidth/maxWidth/minHeight/maxHeight: responsive constraints for auto-layout children.\n// constraints: position behavior in non-auto-layout parents. Ignored inside auto-layout frames.\n// bindings: bind design variables to node properties. field uses slash path: "fills/0/color" (first fill), "strokes/0/color", "opacity", "width", "height", "cornerRadius", "paddingLeft", "itemSpacing".\n// explicitMode: pin a variable mode on this node. Use { collectionName, modeName } (preferred) or { collectionId, modeId }.\n// properties: escape hatch \u2014 set any Figma node property directly. Use only when no dedicated field exists.\ninterface Node {\n id: string; name: string; type: string;\n visible?: boolean; // omitted when true\n locked?: boolean; // omitted when false\n opacity?: number; // omitted when 1\n rotation?: number; // omitted when 0\n blendMode?: string; // omitted when PASS_THROUGH\n layoutPositioning?: "AUTO" | "ABSOLUTE";\n layoutSizingHorizontal?: "FIXED" | "HUG" | "FILL";\n layoutSizingVertical?: "FIXED" | "HUG" | "FILL";\n minWidth?: number; maxWidth?: number; minHeight?: number; maxHeight?: number;\n absoluteBoundingBox: { x: number; y: number; width: number; height: number };\n fills?: Paint[]; // solid: {type: "SOLID", color: {r, g, b, a}}\n strokes?: Paint[];\n effects?: Effect[]; // DROP_SHADOW | INNER_SHADOW | LAYER_BLUR | BACKGROUND_BLUR\n children?: NodeStub[]; // stubs: {id, name, type} \u2014 use depth to expand\n}\n// PatchItem uses flat params matching create shape \u2014 no nested sub-objects.\n// Fill/stroke/corner/layout/text params are identical to frames.create and text.create.\n// Unknown keys produce a warning, preventing silent failures.\n// Frames are the primary container in Figma. Use auto_layout for responsive containers.\n// Sizing: FIXED = explicit size, HUG = shrink to children, FILL = expand to fill parent.\n// Fill: pass fills:[{type:"SOLID", color:"#hex"}] or [] for transparent. Shorthand: fillColor:"#3B82F6" (auto-binds to matching variable/style).\n// Also: fillVariableName:"bg/primary", fillStyleName:"Surface/Primary".\n// Stroke: pass strokes:[{type:"SOLID", color:"#hex"}] or [] to clear. Shorthand: strokeColor:"#000", strokeVariableName:"border/default".\n// Token fields (cornerRadius, opacity, itemSpacing, padding, strokeWeight): pass number for value, string for variable name/ID.\n// ---\n// SIZING: Always think about both axes. Containers with text need a width constraint \u2014 set width + layoutSizingHorizontal:"FIXED".\n// HUG/HUG is only correct for intrinsically-sized elements (buttons, badges, icons).\n// Smart defaults inside auto-layout parent: cross-axis defaults to FILL, primary axis stays HUG.\n// FILL only works inside an auto-layout parent. Use FIXED for top-level frames.\n// minWidth/maxWidth/minHeight/maxHeight: responsive constraints for auto-layout children.\n// clipsContent: true (default) clips children to the frame bounds. Set false for overflow-visible.\n// Sections are top-level organizers (like artboards) \u2014 they cannot be nested inside frames.\n// Shape primitives: rectangle, ellipse, line \u2014 for decorative/visual elements (not containers).\n// group: wraps existing nodes into a Group. boolean_operation: UNION/SUBTRACT/INTERSECT/EXCLUDE combines shapes.\n// SVG create: pass raw SVG markup string (e.g. "<svg>...</svg>") \u2014 Figma converts it to vector nodes.\n\nUse frames(method: "help", topic: "<method>") for method details.',
236
241
  "methods": {
237
242
  "get": '# frames.get\nGet serialized node data\n\nParams:\n id (string, required) \u2014 Node ID\n fields (string[], optional) \u2014 Property whitelist. Identity fields (id, name, type) always included. Omit for stubs on list, full on get. Pass ["*"] for all.\n depth (number, optional) \u2014 Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.\n verbose (boolean, optional) \u2014 Include all properties (bounding box, constraints, text style details). Default false \u2014 returns slim, actionable output.',
238
243
  "list": '# frames.list\nSearch for nodes (returns stubs only \u2014 use get with depth for full properties)\n\nParams:\n query (string, optional) \u2014 Name search query (case-insensitive substring match)\n types (string[], optional) \u2014 Filter by node types (e.g. ["FRAME", "TEXT"])\n parentId (string, optional) \u2014 Search only within this subtree\n fields (string[], optional) \u2014 Property whitelist. Identity fields (id, name, type) always included. Omit for stubs on list, full on get. Pass ["*"] for all.\n offset (number, optional) \u2014 Skip N items for pagination (default 0)\n limit (number, optional) \u2014 Max items per page (default 100)',
@@ -267,7 +272,7 @@ Params:
267
272
  blendMode (PASS_THROUGH | NORMAL | DARKEN | MULTIPLY | LINEAR_BURN | COLOR_BURN | LIGHTEN | SCREEN | LINEAR_DODGE | COLOR_DODGE | OVERLAY | SOFT_LIGHT | HARD_LIGHT | DIFFERENCE | EXCLUSION | HUE | SATURATION | COLOR | LUMINOSITY, optional)
268
273
  effectStyleName (string, optional) \u2014 Effect style name (e.g. 'Shadow/Card') for shadows, blurs
269
274
  layoutMode (NONE | HORIZONTAL | VERTICAL, optional) \u2014 Layout direction (default: NONE)
270
- layoutWrap (NO_WRAP | WRAP, optional)
275
+ layoutWrap (NO_WRAP | WRAP, optional) \u2014 Wrap children to new rows (HORIZONTAL layout only \u2014 Figma does not support WRAP on VERTICAL layouts). Use column frames inside a HORIZONTAL parent for vertical grid patterns.
271
276
  padding (string, optional) \u2014 All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft.
272
277
  paddingTop (string, optional)
273
278
  paddingRight (string, optional)
@@ -288,6 +293,10 @@ Params:
288
293
  fontFamily (string, optional) \u2014 Font family
289
294
  fontStyle (string, optional) \u2014 Font variant e.g. "Bold", "Italic" \u2014 overrides fontWeight
290
295
  fontWeight (number, optional) \u2014 100-900. Ignored when fontStyle is set.
296
+ lineHeight (number | {value, unit: "PIXELS"|"PERCENT"|"AUTO"}, optional)
297
+ letterSpacing (number | {value, unit: "PIXELS"|"PERCENT"}, optional)
298
+ textCase (ORIGINAL | UPPER | LOWER | TITLE | SMALL_CAPS | SMALL_CAPS_FORCED, optional)
299
+ textDecoration (NONE | UNDERLINE | STRIKETHROUGH, optional)
291
300
  fontColor (Color, optional) \u2014 Shorthand \u2014 sets text color (auto-binds to matching variable/style)
292
301
  fontColorVariableName (string, optional) \u2014 Bind color variable by name e.g. 'text/primary'
293
302
  fontColorStyleName (string, optional) \u2014 Apply paint style \u2014 overrides fontColor
@@ -315,7 +324,7 @@ Params:
315
324
  exportSettings (array, optional) \u2014 Export settings
316
325
  properties (object, optional) \u2014 Direct Figma API props (escape hatch)`,
317
326
  "delete": "# frames.delete\nDelete nodes\n\nParams:\n id (string, optional) \u2014 Single node ID\n items (array, optional) \u2014 Batch: [{id}, ...]\n id (string, optional)",
318
- "clone": "# frames.clone\nDuplicate nodes\n\nParams:\n id (string, optional) \u2014 Node ID\n name (string, optional) \u2014 Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)\n parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.\n x (number, optional) \u2014 X position (default: 0)\n y (number, optional) \u2014 Y position (default: 0)\n items (array, optional) \u2014 Batch: [{id, name?, parentId?, x?, y?}, ...]. Alternative to single-item params.\n id (string, required) \u2014 Node ID to clone\n name (string, optional) \u2014 Rename the clone\n parentId (string, optional) \u2014 Target parent\n x (number, optional)\n y (number, optional)\n depth (number, optional) \u2014 Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.",
327
+ "clone": "# frames.clone\nDuplicate nodes\n\nParams:\n id (string, optional) \u2014 Node ID\n name (string, optional) \u2014 Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)\n parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.\n x (number, optional) \u2014 X position (default: 0)\n y (number, optional) \u2014 Y position (default: 0)\n items (array, optional) \u2014 Batch: [{id, name?, parentId?, x?, y?}, ...]. Alternative to single-item params.\n id (string, required) \u2014 Node ID to clone\n name (string, optional) \u2014 Rename the clone\n parentId (string, optional) \u2014 Target parent\n x (number, optional)\n y (number, optional)\n depth (number, optional) \u2014 Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.",
319
328
  "audit": `# frames.audit
320
329
  Run lint on a node \u2014 returns severity-ranked findings
321
330
 
@@ -336,7 +345,7 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
336
345
 
337
346
  ## frame \u2014 General-purpose frame \u2014 shrinks to content by default, static when width+height given
338
347
  name (string, optional) \u2014 Node name
339
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
348
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
340
349
  x (number, optional) \u2014 X position (default: 0)
341
350
  y (number, optional) \u2014 Y position (default: 0)
342
351
  width (number, optional) \u2014 Width in px (omit to shrink-to-content via HUG)
@@ -369,7 +378,7 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
369
378
  bottomLeftRadius (string, optional)
370
379
  effectStyleName (string, optional) \u2014 Effect style name (e.g. 'Shadow/Card') for shadows, blurs
371
380
  layoutMode (NONE | HORIZONTAL | VERTICAL, optional) \u2014 Layout direction (default: auto \u2014 NONE when width+height set, otherwise inferred from layout props)
372
- layoutWrap (NO_WRAP | WRAP, optional)
381
+ layoutWrap (NO_WRAP | WRAP, optional) \u2014 Wrap children to new rows (HORIZONTAL layout only \u2014 Figma does not support WRAP on VERTICAL layouts). Use column frames inside a HORIZONTAL parent for vertical grid patterns.
373
382
  padding (string, optional) \u2014 All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft.
374
383
  paddingTop (string, optional)
375
384
  paddingRight (string, optional)
@@ -387,10 +396,12 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
387
396
  maxHeight (number, optional) \u2014 Max height for responsive auto-layout
388
397
  overflowDirection (NONE | HORIZONTAL | VERTICAL | BOTH, optional) \u2014 Scroll overflow in prototype (default: NONE)
389
398
  clipsContent (boolean, optional)
399
+ children (array, optional) \u2014 Inline child nodes \u2014 build nested trees in one call. Types: text: {type:"text", text, fontFamily?, fontSize?, fontWeight?, fontStyle?, fontColor?, layoutSizingHorizontal?}. frame: {type:"frame", name?, layoutMode?, fillColor?, width?, layoutSizingHorizontal?, children?}. instance: {type:"instance", componentId, variantProperties?, properties?}. component: {type:"component", name, children?}. All params from text/frame endpoints are supported on their respective types. Always set layoutSizingHorizontal + layoutSizingVertical on children inside auto-layout parents (FILL, HUG, or FIXED). Example: children:[{type:"text", text:"Title", fontSize:20, layoutSizingHorizontal:"FILL", layoutSizingVertical:"HUG"}, {type:"frame", name:"Row", layoutMode:"HORIZONTAL", layoutSizingHorizontal:"FILL", layoutSizingVertical:"HUG", itemSpacing:8, children:[{type:"instance", componentId:"1:2", layoutSizingHorizontal:"FILL", layoutSizingVertical:"HUG"}]}] Inside components: add componentPropertyName to auto-bind TEXT or INSTANCE_SWAP properties.
400
+
390
401
 
391
402
  ## auto_layout \u2014 Auto-layout frame that arranges children automatically
392
403
  name (string, optional) \u2014 Node name
393
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
404
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
394
405
  x (number, optional) \u2014 X position (default: 0)
395
406
  y (number, optional) \u2014 Y position (default: 0)
396
407
  width (number, optional) \u2014 Width in px (omit to shrink-to-content via HUG)
@@ -423,7 +434,7 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
423
434
  bottomLeftRadius (string, optional)
424
435
  effectStyleName (string, optional) \u2014 Effect style name (e.g. 'Shadow/Card') for shadows, blurs
425
436
  layoutMode (HORIZONTAL | VERTICAL, required) \u2014 Primary axis direction
426
- layoutWrap (NO_WRAP | WRAP, optional)
437
+ layoutWrap (NO_WRAP | WRAP, optional) \u2014 Wrap children to new rows (HORIZONTAL layout only \u2014 Figma does not support WRAP on VERTICAL layouts). Use column frames inside a HORIZONTAL parent for vertical grid patterns.
427
438
  padding (string, optional) \u2014 All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft.
428
439
  paddingTop (string, optional)
429
440
  paddingRight (string, optional)
@@ -442,10 +453,12 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
442
453
  overflowDirection (NONE | HORIZONTAL | VERTICAL | BOTH, optional) \u2014 Scroll overflow in prototype (default: NONE)
443
454
  clipsContent (boolean, optional)
444
455
  nodeIds (string[], optional) \u2014 Existing node IDs to wrap into auto-layout
456
+ children (array, optional) \u2014 Inline child nodes \u2014 build nested trees in one call. Types: text: {type:"text", text, fontFamily?, fontSize?, fontWeight?, fontStyle?, fontColor?, layoutSizingHorizontal?}. frame: {type:"frame", name?, layoutMode?, fillColor?, width?, layoutSizingHorizontal?, children?}. instance: {type:"instance", componentId, variantProperties?, properties?}. component: {type:"component", name, children?}. All params from text/frame endpoints are supported on their respective types. Always set layoutSizingHorizontal + layoutSizingVertical on children inside auto-layout parents (FILL, HUG, or FIXED). Example: children:[{type:"text", text:"Title", fontSize:20, layoutSizingHorizontal:"FILL", layoutSizingVertical:"HUG"}, {type:"frame", name:"Row", layoutMode:"HORIZONTAL", layoutSizingHorizontal:"FILL", layoutSizingVertical:"HUG", itemSpacing:8, children:[{type:"instance", componentId:"1:2", layoutSizingHorizontal:"FILL", layoutSizingVertical:"HUG"}]}] Inside components: add componentPropertyName to auto-bind TEXT or INSTANCE_SWAP properties.
457
+
445
458
 
446
459
  ## section \u2014 Figma section (top-level organizer)
447
460
  name (string, required) \u2014 Section name
448
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
461
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
449
462
  x (number, optional) \u2014 X position (default: 0)
450
463
  y (number, optional) \u2014 Y position (default: 0)
451
464
  width (number, optional) \u2014 Width (default: 500)
@@ -457,7 +470,7 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
457
470
 
458
471
  ## rectangle \u2014 Rectangle shape node
459
472
  name (string, optional) \u2014 Layer name (default: 'Rectangle')
460
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
473
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
461
474
  x (number, optional) \u2014 X position (default: 0)
462
475
  y (number, optional) \u2014 Y position (default: 0)
463
476
  width (number, optional) \u2014 Width in px (default: 100)
@@ -481,7 +494,7 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
481
494
 
482
495
  ## ellipse \u2014 Ellipse/circle shape node
483
496
  name (string, optional) \u2014 Layer name (default: 'Ellipse')
484
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
497
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
485
498
  x (number, optional) \u2014 X position (default: 0)
486
499
  y (number, optional) \u2014 Y position (default: 0)
487
500
  width (number, optional) \u2014 Width in px (default: 100)
@@ -500,7 +513,7 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
500
513
 
501
514
  ## line \u2014 Line shape node
502
515
  name (string, optional) \u2014 Layer name (default: 'Line')
503
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
516
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
504
517
  x (number, optional) \u2014 X position (default: 0)
505
518
  y (number, optional) \u2014 Y position (default: 0)
506
519
  length (number, optional) \u2014 Line length in px (default: 100)
@@ -515,24 +528,25 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
515
528
  ## group \u2014 Group existing nodes together
516
529
  nodeIds (string[], required) \u2014 Node IDs to group (min 1)
517
530
  name (string, optional) \u2014 Group name
518
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
531
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
519
532
 
520
533
  ## boolean_operation \u2014 Combine shapes with boolean operations (union, subtract, intersect, exclude)
521
534
  operation (UNION | SUBTRACT | INTERSECT | EXCLUDE, required) \u2014 Boolean operation type
522
535
  nodeIds (string[], required) \u2014 Node IDs to combine (min 2, first node is the base for SUBTRACT)
523
536
  name (string, optional) \u2014 Result node name
524
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
537
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
525
538
 
526
539
  ## svg \u2014 Create node from SVG markup
527
540
  svg (string, required) \u2014 SVG markup string
528
541
  name (string, optional) \u2014 Layer name (default: 'SVG')
529
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
542
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
530
543
  x (number, optional) \u2014 X position (default: 0)
531
544
  y (number, optional) \u2014 Y position (default: 0)
532
545
  fillStyleName (string, optional) \u2014 Paint style to apply to vector fills
533
546
  fillVariableName (string, optional) \u2014 Color variable by name for vector fills
534
547
  strokeStyleName (string, optional) \u2014 Paint style to apply to vector strokes
535
548
  strokeVariableName (string, optional) \u2014 Color variable by name for vector strokes`,
549
+ "commit": '# frames.commit\nCommit a staged node \u2014 unwraps from [STAGED] container into the original target location.\n\nExample: frames(method:"commit", id:"1:234")\n\nParams:\n id (string, required) \u2014 Staged node ID to commit',
536
550
  "export": "# frames.export\nExport a node as PNG, JPG, SVG, SVG_STRING, or PDF\n\nParams:\n id (string, required) \u2014 Node ID to export\n format (PNG | JPG | SVG | SVG_STRING | PDF, optional) \u2014 Export format (default: PNG). SVG_STRING returns raw SVG text.\n scale (number, optional) \u2014 Export scale (default: 1, only for PNG/JPG)"
537
551
  }
538
552
  },
@@ -541,7 +555,7 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
541
555
  "methods": {
542
556
  "list": '# instances.list\nSearch for nodes (returns stubs only \u2014 use get with depth for full properties)\n\nParams:\n query (string, optional) \u2014 Name search query (case-insensitive substring match)\n types (string[], optional) \u2014 Filter by node types (e.g. ["FRAME", "TEXT"])\n parentId (string, optional) \u2014 Search only within this subtree\n fields (string[], optional) \u2014 Property whitelist. Identity fields (id, name, type) always included. Omit for stubs on list, full on get. Pass ["*"] for all.\n offset (number, optional) \u2014 Skip N items for pagination (default 0)\n limit (number, optional) \u2014 Max items per page (default 100)',
543
557
  "delete": "# instances.delete\nDelete nodes\n\nParams:\n id (string, optional) \u2014 Single node ID\n items (array, optional) \u2014 Batch: [{id}, ...]\n id (string, optional)",
544
- "clone": "# instances.clone\nDuplicate nodes\n\nParams:\n id (string, optional) \u2014 Node ID\n name (string, optional) \u2014 Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)\n parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.\n x (number, optional) \u2014 X position (default: 0)\n y (number, optional) \u2014 Y position (default: 0)\n items (array, optional) \u2014 Batch: [{id, name?, parentId?, x?, y?}, ...]. Alternative to single-item params.\n id (string, required) \u2014 Node ID to clone\n name (string, optional) \u2014 Rename the clone\n parentId (string, optional) \u2014 Target parent\n x (number, optional)\n y (number, optional)\n depth (number, optional) \u2014 Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.",
558
+ "clone": "# instances.clone\nDuplicate nodes\n\nParams:\n id (string, optional) \u2014 Node ID\n name (string, optional) \u2014 Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)\n parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.\n x (number, optional) \u2014 X position (default: 0)\n y (number, optional) \u2014 Y position (default: 0)\n items (array, optional) \u2014 Batch: [{id, name?, parentId?, x?, y?}, ...]. Alternative to single-item params.\n id (string, required) \u2014 Node ID to clone\n name (string, optional) \u2014 Rename the clone\n parentId (string, optional) \u2014 Target parent\n x (number, optional)\n y (number, optional)\n depth (number, optional) \u2014 Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.",
545
559
  "audit": `# instances.audit
546
560
  Run lint on a node \u2014 returns severity-ranked findings
547
561
 
@@ -582,7 +596,7 @@ Params:
582
596
  y (number, optional)
583
597
  width (number, optional) \u2014 Override width (resize)
584
598
  height (number, optional) \u2014 Override height (resize)
585
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
599
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
586
600
  depth (number, optional) \u2014 Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.`,
587
601
  "update": `# instances.update
588
602
  Set instance properties
@@ -617,7 +631,7 @@ Params:
617
631
  blendMode (PASS_THROUGH | NORMAL | DARKEN | MULTIPLY | LINEAR_BURN | COLOR_BURN | LIGHTEN | SCREEN | LINEAR_DODGE | COLOR_DODGE | OVERLAY | SOFT_LIGHT | HARD_LIGHT | DIFFERENCE | EXCLUSION | HUE | SATURATION | COLOR | LUMINOSITY, optional)
618
632
  effectStyleName (string, optional) \u2014 Effect style name (e.g. 'Shadow/Card') for shadows, blurs
619
633
  layoutMode (NONE | HORIZONTAL | VERTICAL, optional) \u2014 Layout direction (default: NONE)
620
- layoutWrap (NO_WRAP | WRAP, optional)
634
+ layoutWrap (NO_WRAP | WRAP, optional) \u2014 Wrap children to new rows (HORIZONTAL layout only \u2014 Figma does not support WRAP on VERTICAL layouts). Use column frames inside a HORIZONTAL parent for vertical grid patterns.
621
635
  padding (string, optional) \u2014 All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft.
622
636
  paddingTop (string, optional)
623
637
  paddingRight (string, optional)
@@ -638,6 +652,10 @@ Params:
638
652
  fontFamily (string, optional) \u2014 Font family
639
653
  fontStyle (string, optional) \u2014 Font variant e.g. "Bold", "Italic" \u2014 overrides fontWeight
640
654
  fontWeight (number, optional) \u2014 100-900. Ignored when fontStyle is set.
655
+ lineHeight (number | {value, unit: "PIXELS"|"PERCENT"|"AUTO"}, optional)
656
+ letterSpacing (number | {value, unit: "PIXELS"|"PERCENT"}, optional)
657
+ textCase (ORIGINAL | UPPER | LOWER | TITLE | SMALL_CAPS | SMALL_CAPS_FORCED, optional)
658
+ textDecoration (NONE | UNDERLINE | STRIKETHROUGH, optional)
641
659
  fontColor (Color, optional) \u2014 Shorthand \u2014 sets text color (auto-binds to matching variable/style)
642
660
  fontColorVariableName (string, optional) \u2014 Bind color variable by name e.g. 'text/primary'
643
661
  fontColorStyleName (string, optional) \u2014 Apply paint style \u2014 overrides fontColor
@@ -735,7 +753,7 @@ Use lint(method: "help", topic: "<method>") for method details.`,
735
753
  "summary": '# prototyping\nManage prototype interactions, reactions, and navigation flows.\n\nMethods:\n get Get reactions and overflow direction on a node [read]\n add Add a prototype reaction to a node [edit]\n set Replace all reactions on a node (raw reactions array) [edit]\n remove Remove a reaction from a node by index [edit]\n\n// Reactions wire up interactions: trigger (ON_CLICK, ON_HOVER, ...) \u2192 action (navigate, swap, overlay).\n// Common patterns: button ON_CLICK \u2192 NAVIGATE to detail frame; card ON_HOVER \u2192 CHANGE_TO hover variant.\n// Multi-action: pass actions[] array to run multiple actions on one trigger (e.g. navigate + set variable mode).\n// ---\n// IMPORTANT: destination rules depend on navigation type:\n// NAVIGATE/SWAP/OVERLAY/SCROLL_TO \u2192 destination must be a top-level frame (direct child of a page). Nested frames are rejected.\n// CHANGE_TO \u2192 destination must be a variant (COMPONENT inside a COMPONENT_SET). Used for hover/state swaps within the same component.\n// ---\n// TRIGGERS: ON_CLICK | ON_HOVER | ON_PRESS | ON_DRAG | AFTER_TIMEOUT(timeout) | MOUSE_ENTER(delay) | MOUSE_LEAVE(delay) | ON_KEY_DOWN(keyCodes)\n// NAVIGATION: NAVIGATE (go to frame) | SWAP (swap overlay) | OVERLAY (show overlay) | SCROLL_TO | CHANGE_TO (swap component variant)\n// TRANSITIONS: DISSOLVE | SMART_ANIMATE | MOVE_IN | MOVE_OUT | PUSH | SLIDE_IN | SLIDE_OUT (+ direction for directional)\n// EASING: EASE_IN | EASE_OUT | EASE_IN_AND_OUT | LINEAR | GENTLE | QUICK | BOUNCY | SLOW\n// ACTIONS: NODE (navigate/swap) | BACK (go back) | CLOSE (close overlay) | URL (open link) | SET_VARIABLE_MODE (switch theme/mode)\n\nUse prototyping(method: "help", topic: "<method>") for method details.',
736
754
  "methods": {
737
755
  "get": "# prototyping.get\nGet reactions and overflow direction on a node\n\nParams:\n id (string, required) \u2014 Node ID",
738
- "add": '# prototyping.add\nAdd a prototype reaction to a node\n\nExample: prototyping(method:"add", id:"btn-1", trigger:"ON_CLICK", destination:"detail-frame-id", navigation:"NAVIGATE")\n\nParams:\n id (string, required) \u2014 Node ID\n trigger (ON_CLICK | ON_HOVER | ON_PRESS | ON_DRAG | AFTER_TIMEOUT | MOUSE_ENTER | MOUSE_LEAVE | ON_KEY_DOWN, required) \u2014 Trigger type\n triggerDelay (number, optional) \u2014 Delay in ms for AFTER_TIMEOUT / MOUSE_ENTER / MOUSE_LEAVE triggers\n triggerKeyCodes (number[], optional) \u2014 Key codes for ON_KEY_DOWN trigger\n triggerDevice (KEYBOARD | XBOX_ONE | PS4 | SWITCH_PRO, optional) \u2014 Device for ON_KEY_DOWN (default: KEYBOARD)\n destination (string, optional) \u2014 Target node ID (required for NODE actions). NAVIGATE/SWAP/OVERLAY: must be a top-level frame. CHANGE_TO: must be a variant (component inside a component set).\n navigation (NAVIGATE | SWAP | OVERLAY | SCROLL_TO | CHANGE_TO, optional) \u2014 Navigation type (default: NAVIGATE)\n transition (DISSOLVE | SMART_ANIMATE | MOVE_IN | MOVE_OUT | PUSH | SLIDE_IN | SLIDE_OUT | INSTANT, optional) \u2014 Transition animation (default: DISSOLVE). INSTANT = no animation.\n transitionDirection (LEFT | RIGHT | TOP | BOTTOM, optional) \u2014 Direction for MOVE_IN, MOVE_OUT, PUSH, SLIDE_IN, SLIDE_OUT\n duration (number, optional) \u2014 Transition duration in seconds (default: 0.3)\n easing (EASE_IN | EASE_OUT | EASE_IN_AND_OUT | LINEAR | GENTLE | QUICK | BOUNCY | SLOW, optional) \u2014 Easing function (default: EASE_OUT)\n actionType (NODE | BACK | CLOSE | URL | SET_VARIABLE_MODE, optional) \u2014 Action type (default: NODE). SET_VARIABLE_MODE switches a variable collection mode.\n url (string, optional) \u2014 URL for URL action type\n collectionName (string, optional) \u2014 Variable collection name (for SET_VARIABLE_MODE)\n modeName (string, optional) \u2014 Mode name to switch to (for SET_VARIABLE_MODE)\n resetScrollPosition (boolean, optional) \u2014 Reset scroll position on navigate (default: true)\n actions (array, optional) \u2014 Multi-action: [{actionType, destination?, navigation?, collectionName?, modeName?, ...}]. Overrides single-action params.',
756
+ "add": '# prototyping.add\nAdd a prototype reaction to a node\n\nExample: prototyping(method:"add", items:[{id:"btn-1", trigger:"ON_CLICK", destination:"frame-2", navigation:"NAVIGATE", transition:"SMART_ANIMATE"}, {id:"btn-2", trigger:"ON_CLICK", destination:"frame-3"}])\n\nParams:\n id (string, optional) \u2014 Node ID\n trigger (ON_CLICK | ON_HOVER | ON_PRESS | ON_DRAG | AFTER_TIMEOUT | MOUSE_ENTER | MOUSE_LEAVE | ON_KEY_DOWN, optional) \u2014 Trigger type\n triggerDelay (number, optional) \u2014 Delay in ms for AFTER_TIMEOUT / MOUSE_ENTER / MOUSE_LEAVE triggers\n triggerKeyCodes (number[], optional) \u2014 Key codes for ON_KEY_DOWN trigger\n triggerDevice (KEYBOARD | XBOX_ONE | PS4 | SWITCH_PRO, optional) \u2014 Device for ON_KEY_DOWN (default: KEYBOARD)\n destination (string, optional) \u2014 Target node ID (required for NODE actions). NAVIGATE/SWAP/OVERLAY: must be a top-level frame. CHANGE_TO: must be a variant (component inside a component set).\n navigation (NAVIGATE | SWAP | OVERLAY | SCROLL_TO | CHANGE_TO, optional) \u2014 Navigation type (default: NAVIGATE)\n transition (DISSOLVE | SMART_ANIMATE | MOVE_IN | MOVE_OUT | PUSH | SLIDE_IN | SLIDE_OUT | INSTANT, optional) \u2014 Transition animation (default: DISSOLVE). INSTANT = no animation.\n transitionDirection (LEFT | RIGHT | TOP | BOTTOM, optional) \u2014 Direction for MOVE_IN, MOVE_OUT, PUSH, SLIDE_IN, SLIDE_OUT\n duration (number, optional) \u2014 Transition duration in seconds (default: 0.3)\n easing (EASE_IN | EASE_OUT | EASE_IN_AND_OUT | LINEAR | GENTLE | QUICK | BOUNCY | SLOW, optional) \u2014 Easing function (default: EASE_OUT)\n actionType (NODE | BACK | CLOSE | URL | SET_VARIABLE_MODE, optional) \u2014 Action type (default: NODE). SET_VARIABLE_MODE switches a variable collection mode.\n url (string, optional) \u2014 URL for URL action type\n collectionName (string, optional) \u2014 Variable collection name (for SET_VARIABLE_MODE)\n modeName (string, optional) \u2014 Mode name to switch to (for SET_VARIABLE_MODE)\n resetScrollPosition (boolean, optional) \u2014 Reset scroll position on navigate (default: true)\n actions (array, optional) \u2014 Multi-action: [{actionType, destination?, navigation?, collectionName?, modeName?, ...}]. Overrides single-action params.\n items (array, optional) \u2014 Batch: array of {id, trigger, destination?, ...} reaction items\n id (string, required) \u2014 Node ID\n trigger (ON_CLICK | ON_HOVER | ON_PRESS | ON_DRAG | AFTER_TIMEOUT | MOUSE_ENTER | MOUSE_LEAVE | ON_KEY_DOWN, required) \u2014 Trigger type\n destination (string, optional) \u2014 Target node ID\n navigation (NAVIGATE | SWAP | OVERLAY | SCROLL_TO | CHANGE_TO, optional)\n transition (DISSOLVE | SMART_ANIMATE | MOVE_IN | MOVE_OUT | PUSH | SLIDE_IN | SLIDE_OUT | INSTANT, optional)\n transitionDirection (LEFT | RIGHT | TOP | BOTTOM, optional)\n duration (number, optional)\n easing (EASE_IN | EASE_OUT | EASE_IN_AND_OUT | LINEAR | GENTLE | QUICK | BOUNCY | SLOW, optional)\n actionType (NODE | BACK | CLOSE | URL | SET_VARIABLE_MODE, optional)\n triggerDelay (number, optional)\n url (string, optional)\n collectionName (string, optional)\n modeName (string, optional)\n resetScrollPosition (boolean, optional)\n actions (array, optional)',
739
757
  "set": "# prototyping.set\nReplace all reactions on a node (raw reactions array)\n\nParams:\n id (string, required) \u2014 Node ID\n reactions (array, required) \u2014 Full reactions array \u2014 [{trigger:{type}, actions:[{type, destinationId, navigation, transition}]}]",
740
758
  "remove": "# prototyping.remove\nRemove a reaction from a node by index\n\nParams:\n id (string, required) \u2014 Node ID\n index (number, required) \u2014 Reaction index (0-based)"
741
759
  }
@@ -752,8 +770,8 @@ Use lint(method: "help", topic: "<method>") for method details.`,
752
770
  "methods": {
753
771
  "list": '# styles.list\nList local styles with optional type filter\n\nParams:\n type (paint | text | effect | grid, optional) \u2014 Filter by style type\n fields (string[], optional) \u2014 Property whitelist. Identity fields (id, name, type) always included. Omit for stubs on list, full on get. Pass ["*"] for all.\n offset (number, optional) \u2014 Skip N items for pagination (default 0)\n limit (number, optional) \u2014 Max items per page (default 100)',
754
772
  "get": '# styles.get\nGet full style detail by ID\n\nParams:\n id (string, required) \u2014 Style ID or name\n fields (string[], optional) \u2014 Property whitelist. Identity fields (id, name, type) always included. Omit for stubs on list, full on get. Pass ["*"] for all.',
755
- "create": '# styles.create\nCreate local styles\n\nExample: styles(method:"create", type:"effect", name:"Shadow/Medium", effects:[{type:"DROP_SHADOW", color:"#00000040", offset:{x:0,y:4}, radius:8}])\n\nDiscriminant: type (paint | text | effect | grid)\n\n ## paint \u2014 Paint/color style\n name (string, required) \u2014 Style name\n color (Color, optional) \u2014 Color value. Optional when colorVariableName is provided.\n colorVariableName (string, optional) \u2014 Bind to a COLOR variable by name (style tracks the variable). Can be used alone \u2014 color is resolved from the variable.\n description (string, optional) \u2014 Style description\n\n ## text \u2014 Text style\n name (string, required) \u2014 Style name\n fontFamily (string, required) \u2014 Font family\n fontStyle (string, optional) \u2014 Font style (default: Regular)\n fontSize (number, required) \u2014 Font size\n lineHeight (line_height, optional)\n letterSpacing (letter_spacing, optional)\n textCase (ORIGINAL | UPPER | LOWER | TITLE | SMALL_CAPS | SMALL_CAPS_FORCED, optional)\n textDecoration (NONE | UNDERLINE | STRIKETHROUGH, optional)\n paragraphIndent (number, optional) \u2014 Paragraph indent (px)\n paragraphSpacing (number, optional) \u2014 Paragraph spacing (px)\n leadingTrim (CAP_HEIGHT | NONE, optional) \u2014 Leading trim mode\n description (string, optional) \u2014 Style description\n\n ## effect \u2014 Effect style\n name (string, required) \u2014 Style name\n effects (array, required) \u2014 Array of Effect objects\n description (string, optional) \u2014 Style description\n\n ## grid \u2014 Grid/layout grid style\n name (string, required) \u2014 Style name\n layoutGrids (array, required) \u2014 Array of LayoutGrid objects\n description (string, optional) \u2014 Style description',
756
- "update": '# styles.update\nUpdate styles by ID or name\n\nExample: styles(method:"update", items:[{id:"Surface/Primary", color:"#F5F5F5"}])\n\nParams:\n type (paint | text | effect | grid, optional) \u2014 Style type hint for strict validation (optional, auto-detected)\n items (PatchStyleItem[], required) \u2014 Array of {id, ...fields} to update\n id (string, required) \u2014 Style ID or name\n name (string, optional) \u2014 Rename the style\n description (string, optional) \u2014 Style description\n color (Color, optional) \u2014 New color (paint styles)\n colorVariableName (string, optional) \u2014 Bind to a COLOR variable by name (paint styles)\n fontFamily (string, optional)\n fontStyle (string, optional)\n fontSize (number, optional)\n lineHeight (line_height, optional)\n letterSpacing (letter_spacing, optional)\n textCase (ORIGINAL | UPPER | LOWER | TITLE | SMALL_CAPS | SMALL_CAPS_FORCED, optional)\n textDecoration (NONE | UNDERLINE | STRIKETHROUGH, optional)\n paragraphIndent (number, optional) \u2014 Paragraph indent (px)\n paragraphSpacing (number, optional) \u2014 Paragraph spacing (px)\n leadingTrim (CAP_HEIGHT | NONE, optional)\n effects (array, optional) \u2014 Array of Effect objects\n layoutGrids (array, optional) \u2014 Array of LayoutGrid objects (grid styles)',
773
+ "create": '# styles.create\nCreate local styles\n\nExample: styles(method:"create", type:"effect", name:"Shadow/Medium", effects:[{type:"DROP_SHADOW", color:"#00000040", offset:{x:0,y:4}, radius:8}])\n\nDiscriminant: type (paint | text | effect | grid)\n\n ## paint \u2014 Paint/color style\n name (string, required) \u2014 Style name\n color (Color, optional) \u2014 Color value. Optional when colorVariableName is provided.\n colorVariableName (string, optional) \u2014 Bind to a COLOR variable by name (style tracks the variable). Can be used alone \u2014 color is resolved from the variable.\n description (string, optional) \u2014 Style description\n\n ## text \u2014 Text style\n name (string, required) \u2014 Style name\n fontFamily (string, required) \u2014 Font family\n fontStyle (string, optional) \u2014 Font style (default: Regular)\n fontSize (number, required) \u2014 Font size\n lineHeight (number | {value, unit: "PIXELS"|"PERCENT"|"AUTO"}, optional)\n letterSpacing (number | {value, unit: "PIXELS"|"PERCENT"}, optional)\n textCase (ORIGINAL | UPPER | LOWER | TITLE | SMALL_CAPS | SMALL_CAPS_FORCED, optional)\n textDecoration (NONE | UNDERLINE | STRIKETHROUGH, optional)\n paragraphIndent (number, optional) \u2014 Paragraph indent (px)\n paragraphSpacing (number, optional) \u2014 Paragraph spacing (px)\n leadingTrim (CAP_HEIGHT | NONE, optional) \u2014 Leading trim mode\n description (string, optional) \u2014 Style description\n\n ## effect \u2014 Effect style\n name (string, required) \u2014 Style name\n effects (array, required) \u2014 Array of Effect objects\n description (string, optional) \u2014 Style description\n\n ## grid \u2014 Grid/layout grid style\n name (string, required) \u2014 Style name\n layoutGrids (array, required) \u2014 Array of LayoutGrid objects\n description (string, optional) \u2014 Style description',
774
+ "update": '# styles.update\nUpdate styles by ID or name\n\nExample: styles(method:"update", items:[{id:"Surface/Primary", color:"#F5F5F5"}])\n\nParams:\n type (paint | text | effect | grid, optional) \u2014 Style type hint for strict validation (optional, auto-detected)\n items (PatchStyleItem[], required) \u2014 Array of {id, ...fields} to update\n id (string, required) \u2014 Style ID or name\n name (string, optional) \u2014 Rename the style\n description (string, optional) \u2014 Style description\n color (Color, optional) \u2014 New color (paint styles)\n colorVariableName (string, optional) \u2014 Bind to a COLOR variable by name (paint styles)\n fontFamily (string, optional)\n fontStyle (string, optional)\n fontSize (number, optional)\n lineHeight (number | {value, unit: "PIXELS"|"PERCENT"|"AUTO"}, optional)\n letterSpacing (number | {value, unit: "PIXELS"|"PERCENT"}, optional)\n textCase (ORIGINAL | UPPER | LOWER | TITLE | SMALL_CAPS | SMALL_CAPS_FORCED, optional)\n textDecoration (NONE | UNDERLINE | STRIKETHROUGH, optional)\n paragraphIndent (number, optional) \u2014 Paragraph indent (px)\n paragraphSpacing (number, optional) \u2014 Paragraph spacing (px)\n leadingTrim (CAP_HEIGHT | NONE, optional)\n effects (array, optional) \u2014 Array of Effect objects\n layoutGrids (array, optional) \u2014 Array of LayoutGrid objects (grid styles)',
757
775
  "delete": "# styles.delete\nDelete styles\n\nParams:\n id (string, optional) \u2014 Style ID or name\n items (array, optional) \u2014 Batch: [{id}, ...]\n id (string, required) \u2014 Style ID or name"
758
776
  }
759
777
  },
@@ -793,7 +811,7 @@ Params:
793
811
  blendMode (PASS_THROUGH | NORMAL | DARKEN | MULTIPLY | LINEAR_BURN | COLOR_BURN | LIGHTEN | SCREEN | LINEAR_DODGE | COLOR_DODGE | OVERLAY | SOFT_LIGHT | HARD_LIGHT | DIFFERENCE | EXCLUSION | HUE | SATURATION | COLOR | LUMINOSITY, optional)
794
812
  effectStyleName (string, optional) \u2014 Effect style name (e.g. 'Shadow/Card') for shadows, blurs
795
813
  layoutMode (NONE | HORIZONTAL | VERTICAL, optional) \u2014 Layout direction (default: NONE)
796
- layoutWrap (NO_WRAP | WRAP, optional)
814
+ layoutWrap (NO_WRAP | WRAP, optional) \u2014 Wrap children to new rows (HORIZONTAL layout only \u2014 Figma does not support WRAP on VERTICAL layouts). Use column frames inside a HORIZONTAL parent for vertical grid patterns.
797
815
  padding (string, optional) \u2014 All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft.
798
816
  paddingTop (string, optional)
799
817
  paddingRight (string, optional)
@@ -814,6 +832,10 @@ Params:
814
832
  fontFamily (string, optional) \u2014 Font family
815
833
  fontStyle (string, optional) \u2014 Font variant e.g. "Bold", "Italic" \u2014 overrides fontWeight
816
834
  fontWeight (number, optional) \u2014 100-900. Ignored when fontStyle is set.
835
+ lineHeight (number | {value, unit: "PIXELS"|"PERCENT"|"AUTO"}, optional)
836
+ letterSpacing (number | {value, unit: "PIXELS"|"PERCENT"}, optional)
837
+ textCase (ORIGINAL | UPPER | LOWER | TITLE | SMALL_CAPS | SMALL_CAPS_FORCED, optional)
838
+ textDecoration (NONE | UNDERLINE | STRIKETHROUGH, optional)
817
839
  fontColor (Color, optional) \u2014 Shorthand \u2014 sets text color (auto-binds to matching variable/style)
818
840
  fontColorVariableName (string, optional) \u2014 Bind color variable by name e.g. 'text/primary'
819
841
  fontColorStyleName (string, optional) \u2014 Apply paint style \u2014 overrides fontColor
@@ -841,7 +863,7 @@ Params:
841
863
  exportSettings (array, optional) \u2014 Export settings
842
864
  properties (object, optional) \u2014 Direct Figma API props (escape hatch)`,
843
865
  "delete": "# text.delete\nDelete nodes\n\nParams:\n id (string, optional) \u2014 Single node ID\n items (array, optional) \u2014 Batch: [{id}, ...]\n id (string, optional)",
844
- "clone": "# text.clone\nDuplicate nodes\n\nParams:\n id (string, optional) \u2014 Node ID\n name (string, optional) \u2014 Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)\n parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.\n x (number, optional) \u2014 X position (default: 0)\n y (number, optional) \u2014 Y position (default: 0)\n items (array, optional) \u2014 Batch: [{id, name?, parentId?, x?, y?}, ...]. Alternative to single-item params.\n id (string, required) \u2014 Node ID to clone\n name (string, optional) \u2014 Rename the clone\n parentId (string, optional) \u2014 Target parent\n x (number, optional)\n y (number, optional)\n depth (number, optional) \u2014 Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.",
866
+ "clone": "# text.clone\nDuplicate nodes\n\nParams:\n id (string, optional) \u2014 Node ID\n name (string, optional) \u2014 Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)\n parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.\n x (number, optional) \u2014 X position (default: 0)\n y (number, optional) \u2014 Y position (default: 0)\n items (array, optional) \u2014 Batch: [{id, name?, parentId?, x?, y?}, ...]. Alternative to single-item params.\n id (string, required) \u2014 Node ID to clone\n name (string, optional) \u2014 Rename the clone\n parentId (string, optional) \u2014 Target parent\n x (number, optional)\n y (number, optional)\n depth (number, optional) \u2014 Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.",
845
867
  "audit": `# text.audit
846
868
  Run lint on a node \u2014 returns severity-ranked findings
847
869
 
@@ -865,11 +887,15 @@ Params:
865
887
  x (number, optional)
866
888
  y (number, optional)
867
889
  width (number, optional) \u2014 Fixed width in px \u2014 implies layoutSizingHorizontal: FIXED and textAutoResize: HEIGHT
868
- parentId (string, optional) \u2014 Parent node ID. Omit to place on current page.
890
+ parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
869
891
  fontFamily (string, optional) \u2014 Font family (default: Inter). Use fonts.list to find installed fonts.
870
892
  fontStyle (string, optional) \u2014 Font variant e.g. "Bold", "Italic" \u2014 overrides fontWeight
871
893
  fontSize (number, optional) \u2014 Font size (default: 14)
872
894
  fontWeight (number, optional) \u2014 100-900 (default: 400). Ignored when fontStyle is set.
895
+ lineHeight (number | {value, unit: "PIXELS"|"PERCENT"|"AUTO"}, optional)
896
+ letterSpacing (number | {value, unit: "PIXELS"|"PERCENT"}, optional)
897
+ textCase (ORIGINAL | UPPER | LOWER | TITLE | SMALL_CAPS | SMALL_CAPS_FORCED, optional)
898
+ textDecoration (NONE | UNDERLINE | STRIKETHROUGH, optional)
873
899
  fills (array, optional) \u2014 Text color paints \u2014 e.g. [{type: 'SOLID', color: '#hex'}]. Same as node fills.
874
900
  fontColor (Color, optional) \u2014 Shorthand \u2014 sets text color (auto-binds to matching variable/style)
875
901
  fontColorVariableName (string, optional) \u2014 Bind color variable by name e.g. 'text/primary'
@@ -905,7 +931,7 @@ Params:
905
931
  variables (array, optional) \u2014 Variables to create inside this collection
906
932
  name (string, required) \u2014 Variable name (unique within collection)
907
933
  type (COLOR | FLOAT | STRING | BOOLEAN, required) \u2014 Variable type
908
- value (variable_value, optional) \u2014 Shorthand \u2014 sets the default mode value. Use valuesByMode for multi-mode.
934
+ value (variable_value, optional) \u2014 Sets all modes to this value. Use valuesByMode for per-mode control.
909
935
  valuesByMode (object, optional) \u2014 Values keyed by mode name (e.g. {"Light": "#FFF", "Dark": "#111"})
910
936
  description (string, optional)
911
937
  scopes (string[], optional) \u2014 Restrict where variable can be applied (default: ALL_SCOPES)`,
@@ -917,11 +943,11 @@ Params:
917
943
  }
918
944
  },
919
945
  "variables": {
920
- "summary": '# variables\nSearch and update design variables within a collection.\n\nMethods:\n list Search variables within a collection [read]\n get Get variable detail by name [read]\n create Create variables in a collection. Use valuesByMode for multi-mode, or value for default mode only. [create]\n update Update variable metadata and/or set values [edit]\n delete Delete variables [edit]\n\n// Search and update variables within a collection. collectionId is required on all methods.\n// Use variable_collections to create full token sets (collection + modes + variables in one call).\n// ---\n// query: prefix match first, then substring. "bg/" matches bg/canvas, bg/surface, etc.\n// valuesByMode: values keyed by mode name. value is shorthand for the default mode.\n// Aliases: {type: "VARIABLE_ALIAS", name: "other/variable"}.\n// scopes: ALL_SCOPES, TEXT_CONTENT, WIDTH_HEIGHT, GAP, CORNER_RADIUS, ALL_FILLS, FRAME_FILL, SHAPE_FILL,\n// TEXT_FILL, STROKE_COLOR, STROKE_FLOAT, EFFECT_FLOAT, EFFECT_COLOR, OPACITY, FONT_FAMILY, FONT_STYLE,\n// FONT_WEIGHT, FONT_SIZE, LINE_HEIGHT, LETTER_SPACING, PARAGRAPH_SPACING, PARAGRAPH_INDENT\n\nUse variables(method: "help", topic: "<method>") for method details.',
946
+ "summary": '# variables\nSearch and update design variables within a collection.\n\nMethods:\n list Search variables within a collection [read]\n get Get variable detail by name [read]\n create Create variables in a collection. Use valuesByMode for per-mode control, or value to set all modes at once. [create]\n update Update variable metadata and/or set values [edit]\n delete Delete variables [edit]\n\n// Search and update variables within a collection. collectionId is required on all methods.\n// Use variable_collections to create full token sets (collection + modes + variables in one call).\n// ---\n// query: prefix match first, then substring. "bg/" matches bg/canvas, bg/surface, etc.\n// valuesByMode: values keyed by mode name. On create, value sets all modes; on update, value sets the default mode only.\n// Aliases: {type: "VARIABLE_ALIAS", name: "other/variable"}.\n// scopes: ALL_SCOPES, TEXT_CONTENT, WIDTH_HEIGHT, GAP, CORNER_RADIUS, ALL_FILLS, FRAME_FILL, SHAPE_FILL,\n// TEXT_FILL, STROKE_COLOR, STROKE_FLOAT, EFFECT_FLOAT, EFFECT_COLOR, OPACITY, FONT_FAMILY, FONT_STYLE,\n// FONT_WEIGHT, FONT_SIZE, LINE_HEIGHT, LETTER_SPACING, PARAGRAPH_SPACING, PARAGRAPH_INDENT\n\nUse variables(method: "help", topic: "<method>") for method details.',
921
947
  "methods": {
922
948
  "list": '# variables.list\nSearch variables within a collection\n\nExample: variables(method:"list", collectionId:"Colors", query:"bg/")\n\nParams:\n collectionId (string, required) \u2014 Collection ID or name\n query (string, optional) \u2014 Search query \u2014 prefix match first, then substring fallback\n type (COLOR | FLOAT | STRING | BOOLEAN, optional) \u2014 Filter by variable type\n fields (string[], optional) \u2014 Property whitelist. Identity fields (id, name, type) always included. Omit for stubs on list, full on get. Pass ["*"] for all.\n offset (number, optional) \u2014 Skip N items for pagination (default 0)\n limit (number, optional) \u2014 Max items per page (default 100)',
923
949
  "get": '# variables.get\nGet variable detail by name\n\nParams:\n name (string, required) \u2014 Variable name (unique within collection)\n collectionId (string, required) \u2014 Collection ID or name\n fields (string[], optional) \u2014 Property whitelist. Identity fields (id, name, type) always included. Omit for stubs on list, full on get. Pass ["*"] for all.',
924
- "create": '# variables.create\nCreate variables in a collection. Use valuesByMode for multi-mode, or value for default mode only.\n\nExample: variables(method:"create", collectionId:"Colors", items:[{name:"bg/primary", type:"COLOR", valuesByMode:{"Light":"#FFF","Dark":"#111"}, scopes:["ALL_FILLS"]}])\n\nParams:\n collectionId (string, required) \u2014 Collection ID or name\n items (VariableCreateItem[], required) \u2014 Array of variables to create\n name (string, required) \u2014 Variable name (must be unique within collection)\n type (COLOR | FLOAT | STRING | BOOLEAN, required) \u2014 Variable type\n value (variable_value, optional) \u2014 Shorthand \u2014 sets the default mode value. Use valuesByMode for multi-mode.\n valuesByMode (object, optional) \u2014 Values keyed by mode name (e.g. {"Light": "#FFF", "Dark": "#111"}). Takes precedence over value.\n description (string, optional) \u2014 Variable description\n scopes (string[], optional) \u2014 Restrict where variable can be applied (default: ALL_SCOPES)',
950
+ "create": '# variables.create\nCreate variables in a collection. Use valuesByMode for per-mode control, or value to set all modes at once.\n\nExample: variables(method:"create", collectionId:"Colors", items:[{name:"bg/primary", type:"COLOR", valuesByMode:{"Light":"#FFF","Dark":"#111"}, scopes:["ALL_FILLS"]}])\n\nParams:\n collectionId (string, required) \u2014 Collection ID or name\n items (VariableCreateItem[], required) \u2014 Array of variables to create\n name (string, required) \u2014 Variable name (must be unique within collection)\n type (COLOR | FLOAT | STRING | BOOLEAN, required) \u2014 Variable type\n value (variable_value, optional) \u2014 Sets all modes to this value. Use valuesByMode for per-mode control.\n valuesByMode (object, optional) \u2014 Values keyed by mode name (e.g. {"Light": "#FFF", "Dark": "#111"}). Takes precedence over value.\n description (string, optional) \u2014 Variable description\n scopes (string[], optional) \u2014 Restrict where variable can be applied (default: ALL_SCOPES)',
925
951
  "update": '# variables.update\nUpdate variable metadata and/or set values\n\nExample: variables(method:"update", collectionId:"Colors", items:[{name:"bg/primary", valuesByMode:{"Light":"#FFF","Dark":"#222"}}])\n\nParams:\n collectionId (string, required) \u2014 Collection ID or name\n items (VariableUpdateItem[], required) \u2014 Array of variable updates\n name (string, required) \u2014 Variable name\n rename (string, optional) \u2014 Rename the variable\n description (string, optional) \u2014 Set description\n scopes (string[], optional) \u2014 Update scopes\n value (variable_value, optional) \u2014 Shorthand \u2014 sets the default mode value. Use valuesByMode for multi-mode.\n valuesByMode (object, optional) \u2014 Values keyed by mode name. Takes precedence over value.',
926
952
  "delete": "# variables.delete\nDelete variables\n\nParams:\n collectionId (string, required) \u2014 Collection ID or name\n name (string, optional) \u2014 Variable name\n items (array, optional) \u2014 Batch: [{name}, ...]\n name (string, required)"
927
953
  }
@@ -1007,6 +1033,7 @@ function registerTools(server, sendCommand, caps, tools) {
1007
1033
  }
1008
1034
  if (tool.validate) tool.validate(params);
1009
1035
  const command = resolveCommand(tool, params);
1036
+ params._caps = caps;
1010
1037
  const result = await sendCommand(command, params, timeout);
1011
1038
  const format = tool.methodFormatters?.[params.method] ?? defaultFormat;
1012
1039
  return format(result);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ufira/vibma",
3
3
  "description": "Vibma — Vibe Design meets Figma. AI-powered MCP bridge for designing in Figma.",
4
- "version": "1.0.0-rc5",
4
+ "version": "1.0.0",
5
5
  "license": "MIT",
6
6
  "author": "ufira <https://github.com/ufira-ai>",
7
7
  "homepage": "https://github.com/ufira-ai/vibma",
@@ -80,7 +80,7 @@
80
80
  "zod": "4.3.6"
81
81
  },
82
82
  "devDependencies": {
83
- "@types/node": "^25.4.0",
83
+ "@types/node": "^25.5.0",
84
84
  "@types/ws": "^8.18.1",
85
85
  "tsup": "^8.5.1",
86
86
  "typescript": "^5.9.3"