@ufira/vibma 1.0.0-rc3 → 1.0.0-rc4
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.
- package/dist/mcp.cjs +86 -32
- package/dist/mcp.js +86 -32
- package/dist/tools/generated/guards.cjs +4 -0
- package/dist/tools/generated/guards.d.cts +3 -1
- package/dist/tools/generated/guards.d.ts +3 -1
- package/dist/tools/generated/guards.js +3 -0
- package/dist/tools/registry.cjs +56 -16
- package/dist/tools/registry.js +56 -16
- package/package.json +1 -1
package/dist/mcp.cjs
CHANGED
|
@@ -98,13 +98,22 @@ Use help(topic: "<endpoint>") for endpoint details.
|
|
|
98
98
|
Use help(topic: "<endpoint>.<method>") for method details.`;
|
|
99
99
|
var helpEndpoints = {
|
|
100
100
|
"components": {
|
|
101
|
-
"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 +
|
|
101
|
+
"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.',
|
|
102
102
|
"methods": {
|
|
103
|
-
"clone": "# components.clone\nDuplicate nodes\n\nParams:\n id (string,
|
|
104
|
-
"audit":
|
|
103
|
+
"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.",
|
|
104
|
+
"audit": `# components.audit
|
|
105
|
+
Run lint on a node \u2014 returns severity-ranked findings
|
|
106
|
+
|
|
107
|
+
Params:
|
|
108
|
+
id (string, required) \u2014 Node ID to audit
|
|
109
|
+
rules (string[], optional) \u2014 Rules to check. Default: ["all"]. Categories: "component", "composition", "token", "naming", "wcag".
|
|
110
|
+
maxDepth (number, optional) \u2014 Max tree depth (default: 10)
|
|
111
|
+
maxFindings (number, optional) \u2014 Max findings (default: 50)
|
|
112
|
+
minSeverity (error | unsafe | heuristic | style | verbose, optional) \u2014 Minimum severity to report (default: style). Set to 'verbose' to include AAA contrast and line-height checks.
|
|
113
|
+
skipInstances (boolean, optional) \u2014 Skip instance internals \u2014 findings inside instances are owned by the component (default: true)`,
|
|
105
114
|
"reparent": "# components.reparent\nMove nodes into a new parent\n\nParams:\n items (array, required) \u2014 Array of {id, parentId, index?}\n id (string, required)\n parentId (string, required)\n index (number, optional)",
|
|
106
115
|
"list": "# components.list\nList local component names (variant sets as single entries)\n\nParams:\n query (string, optional) \u2014 Name search query (case-insensitive substring match)\n offset (number, optional) \u2014 Skip N items for pagination (default 0)\n limit (number, optional) \u2014 Max items per page (default 100)",
|
|
107
|
-
"get": "# components.get\nGet component detail \u2014 property definitions +
|
|
116
|
+
"get": "# components.get\nGet component detail \u2014 property definitions + optional node tree for structural inspection\n\nParams:\n id (string, optional) \u2014 Component or component set ID\n names (string[], optional) \u2014 Batch lookup by name (case-insensitive). Either id or names is required.\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.",
|
|
108
117
|
"create": `# components.create
|
|
109
118
|
Create components
|
|
110
119
|
|
|
@@ -165,7 +174,8 @@ Discriminant: type (component | from_node | variant_set)
|
|
|
165
174
|
maxHeight (number, optional) \u2014 Max height for responsive auto-layout
|
|
166
175
|
overflowDirection (NONE | HORIZONTAL | VERTICAL | BOTH, optional) \u2014 Scroll overflow in prototype (default: NONE)
|
|
167
176
|
description (string, optional) \u2014 Component description (shown in Figma's component panel)
|
|
168
|
-
children (array, optional) \u2014 Inline child nodes.
|
|
177
|
+
children (array, optional) \u2014 Inline child nodes \u2014 build nested trees in one call. Types: text: {type:"text", text, componentPropertyName?, fontFamily?, fontSize?, 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"}]}]
|
|
178
|
+
|
|
169
179
|
properties (array, optional) \u2014 Component properties to define at creation: [{propertyName, type, defaultValue}]. TEXT properties for inline children with componentPropertyName are created automatically.
|
|
170
180
|
propertyName (string, required) \u2014 Property name
|
|
171
181
|
type (BOOLEAN | TEXT | INSTANCE_SWAP, required) \u2014 Property type
|
|
@@ -344,8 +354,17 @@ Params:
|
|
|
344
354
|
exportSettings (array, optional) \u2014 Export settings
|
|
345
355
|
properties (object, optional) \u2014 Direct Figma API props (escape hatch)`,
|
|
346
356
|
"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)",
|
|
347
|
-
"clone": "# frames.clone\nDuplicate nodes\n\nParams:\n id (string,
|
|
348
|
-
"audit":
|
|
357
|
+
"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.",
|
|
358
|
+
"audit": `# frames.audit
|
|
359
|
+
Run lint on a node \u2014 returns severity-ranked findings
|
|
360
|
+
|
|
361
|
+
Params:
|
|
362
|
+
id (string, required) \u2014 Node ID to audit
|
|
363
|
+
rules (string[], optional) \u2014 Rules to check. Default: ["all"]. Categories: "component", "composition", "token", "naming", "wcag".
|
|
364
|
+
maxDepth (number, optional) \u2014 Max tree depth (default: 10)
|
|
365
|
+
maxFindings (number, optional) \u2014 Max findings (default: 50)
|
|
366
|
+
minSeverity (error | unsafe | heuristic | style | verbose, optional) \u2014 Minimum severity to report (default: style). Set to 'verbose' to include AAA contrast and line-height checks.
|
|
367
|
+
skipInstances (boolean, optional) \u2014 Skip instance internals \u2014 findings inside instances are owned by the component (default: true)`,
|
|
349
368
|
"reparent": "# frames.reparent\nMove nodes into a new parent\n\nParams:\n items (array, required) \u2014 Array of {id, parentId, index?}\n id (string, required)\n parentId (string, required)\n index (number, optional)",
|
|
350
369
|
"create": `# frames.create
|
|
351
370
|
Create frame-like containers
|
|
@@ -407,7 +426,8 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
|
|
|
407
426
|
maxHeight (number, optional) \u2014 Max height for responsive auto-layout
|
|
408
427
|
overflowDirection (NONE | HORIZONTAL | VERTICAL | BOTH, optional) \u2014 Scroll overflow in prototype (default: NONE)
|
|
409
428
|
clipsContent (boolean, optional)
|
|
410
|
-
children (array, optional) \u2014 Inline child nodes.
|
|
429
|
+
children (array, optional) \u2014 Inline child nodes \u2014 build nested trees in one call. Types: text: {type:"text", text, fontFamily?, fontSize?, 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.
|
|
430
|
+
|
|
411
431
|
|
|
412
432
|
## auto_layout \u2014 Auto-layout frame that arranges children automatically
|
|
413
433
|
name (string, optional) \u2014 Node name
|
|
@@ -463,7 +483,8 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
|
|
|
463
483
|
overflowDirection (NONE | HORIZONTAL | VERTICAL | BOTH, optional) \u2014 Scroll overflow in prototype (default: NONE)
|
|
464
484
|
clipsContent (boolean, optional)
|
|
465
485
|
nodeIds (string[], optional) \u2014 Existing node IDs to wrap into auto-layout
|
|
466
|
-
children (array, optional) \u2014 Inline child nodes.
|
|
486
|
+
children (array, optional) \u2014 Inline child nodes \u2014 build nested trees in one call. Types: text: {type:"text", text, fontFamily?, fontSize?, 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.
|
|
487
|
+
|
|
467
488
|
|
|
468
489
|
## section \u2014 Figma section (top-level organizer)
|
|
469
490
|
name (string, required) \u2014 Section name
|
|
@@ -563,8 +584,17 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
|
|
|
563
584
|
"methods": {
|
|
564
585
|
"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)',
|
|
565
586
|
"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)",
|
|
566
|
-
"clone": "# instances.clone\nDuplicate nodes\n\nParams:\n id (string,
|
|
567
|
-
"audit":
|
|
587
|
+
"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.",
|
|
588
|
+
"audit": `# instances.audit
|
|
589
|
+
Run lint on a node \u2014 returns severity-ranked findings
|
|
590
|
+
|
|
591
|
+
Params:
|
|
592
|
+
id (string, required) \u2014 Node ID to audit
|
|
593
|
+
rules (string[], optional) \u2014 Rules to check. Default: ["all"]. Categories: "component", "composition", "token", "naming", "wcag".
|
|
594
|
+
maxDepth (number, optional) \u2014 Max tree depth (default: 10)
|
|
595
|
+
maxFindings (number, optional) \u2014 Max findings (default: 50)
|
|
596
|
+
minSeverity (error | unsafe | heuristic | style | verbose, optional) \u2014 Minimum severity to report (default: style). Set to 'verbose' to include AAA contrast and line-height checks.
|
|
597
|
+
skipInstances (boolean, optional) \u2014 Skip instance internals \u2014 findings inside instances are owned by the component (default: true)`,
|
|
568
598
|
"reparent": "# instances.reparent\nMove nodes into a new parent\n\nParams:\n items (array, required) \u2014 Array of {id, parentId, index?}\n id (string, required)\n parentId (string, required)\n index (number, optional)",
|
|
569
599
|
"get": '# instances.get\nGet instance detail with component properties and overrides\n\nParams:\n id (string, required) \u2014 Instance 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.',
|
|
570
600
|
"create": `# instances.create
|
|
@@ -587,6 +617,7 @@ Params:
|
|
|
587
617
|
minHeight (number, optional) \u2014 Min height for responsive auto-layout
|
|
588
618
|
maxHeight (number, optional) \u2014 Max height for responsive auto-layout
|
|
589
619
|
componentId (string, required) \u2014 Component or component set ID
|
|
620
|
+
sizing (contextual, optional) \u2014 "contextual": infer FILL/HUG from parent layout (e.g. FILL horizontally in a VERTICAL auto-layout parent). Omit to inherit sizing from the component definition.
|
|
590
621
|
variantProperties (object, optional) \u2014 Pick variant e.g. {"Style":"Secondary"}
|
|
591
622
|
properties (object, optional) \u2014 Set component properties inline e.g. {"Label":"Click me", "ShowIcon":true}. Same as instances.update properties.
|
|
592
623
|
name (string, optional) \u2014 Instance layer name
|
|
@@ -744,10 +775,10 @@ Use lint(method: "help", topic: "<method>") for method details.`,
|
|
|
744
775
|
}
|
|
745
776
|
},
|
|
746
777
|
"prototyping": {
|
|
747
|
-
"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// 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.',
|
|
778
|
+
"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.',
|
|
748
779
|
"methods": {
|
|
749
780
|
"get": "# prototyping.get\nGet reactions and overflow direction on a node\n\nParams:\n id (string, required) \u2014 Node ID",
|
|
750
|
-
"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)
|
|
781
|
+
"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.',
|
|
751
782
|
"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}]}]",
|
|
752
783
|
"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)"
|
|
753
784
|
}
|
|
@@ -764,7 +795,7 @@ Use lint(method: "help", topic: "<method>") for method details.`,
|
|
|
764
795
|
"methods": {
|
|
765
796
|
"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)',
|
|
766
797
|
"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.',
|
|
767
|
-
"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,
|
|
798
|
+
"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',
|
|
768
799
|
"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)',
|
|
769
800
|
"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"
|
|
770
801
|
}
|
|
@@ -853,8 +884,17 @@ Params:
|
|
|
853
884
|
exportSettings (array, optional) \u2014 Export settings
|
|
854
885
|
properties (object, optional) \u2014 Direct Figma API props (escape hatch)`,
|
|
855
886
|
"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)",
|
|
856
|
-
"clone": "# text.clone\nDuplicate nodes\n\nParams:\n id (string,
|
|
857
|
-
"audit":
|
|
887
|
+
"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.",
|
|
888
|
+
"audit": `# text.audit
|
|
889
|
+
Run lint on a node \u2014 returns severity-ranked findings
|
|
890
|
+
|
|
891
|
+
Params:
|
|
892
|
+
id (string, required) \u2014 Node ID to audit
|
|
893
|
+
rules (string[], optional) \u2014 Rules to check. Default: ["all"]. Categories: "component", "composition", "token", "naming", "wcag".
|
|
894
|
+
maxDepth (number, optional) \u2014 Max tree depth (default: 10)
|
|
895
|
+
maxFindings (number, optional) \u2014 Max findings (default: 50)
|
|
896
|
+
minSeverity (error | unsafe | heuristic | style | verbose, optional) \u2014 Minimum severity to report (default: style). Set to 'verbose' to include AAA contrast and line-height checks.
|
|
897
|
+
skipInstances (boolean, optional) \u2014 Skip instance internals \u2014 findings inside instances are owned by the component (default: true)`,
|
|
858
898
|
"reparent": "# text.reparent\nMove nodes into a new parent\n\nParams:\n items (array, required) \u2014 Array of {id, parentId, index?}\n id (string, required)\n parentId (string, required)\n index (number, optional)",
|
|
859
899
|
"create": `# text.create
|
|
860
900
|
Create text nodes
|
|
@@ -1129,22 +1169,26 @@ function filterMethodsByTier(schema, caps2, methodTiers) {
|
|
|
1129
1169
|
var tools = [
|
|
1130
1170
|
{
|
|
1131
1171
|
name: "components",
|
|
1132
|
-
description: '/** Create and manage reusable components and variant sets. Use method "help" for detailed parameter docs. */\n clone (id
|
|
1172
|
+
description: '/** Create and manage reusable components and variant sets. Use method "help" for detailed parameter docs. */\n clone (id?, name?, parentId?, x?, y?, items?: { id: string; name?: string; parentId?: string; x?: number; y?: number }[], depth?) \u2192 { results: {id}[] } // Duplicate nodes\n audit (id, rules?, maxDepth?, maxFindings?, minSeverity?: error|unsafe|heuristic|style|verbose, skipInstances?) \u2192 { nodeId?, nodeName?, categories? } // Run lint on a node \u2014 returns severity-ranked findings\n reparent (items: { id: string; parentId: string; index?: number }[]) \u2192 { results: "ok"[] } // Move nodes into a new parent\n list (query?, offset?, limit?) \u2192 { totalCount, items } // List local component names (variant sets as single entries)\n get (id?, names?, depth?, verbose?) \u2192 { results, _truncated? } // Get component detail \u2014 property definitions + optional node tree for structural inspection\n create (type: component|from_node|variant_set, items: (ComponentItem | FromNodeItem | VariantSetItem)[]) \u2192 { results: {id}[] } // Create components\n update (items: UpdatePropertyItem[], depth?) \u2192 { results: ("ok" | {error})[] } // Add, edit, or delete component properties\n delete (id) \u2192 { results: "ok"[] } // Delete components or component sets\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).',
|
|
1133
1173
|
schema: (caps2) => filterMethodsByTier({
|
|
1134
1174
|
method: import_zod4.z.enum(["clone", "audit", "reparent", "list", "get", "create", "update", "delete", "help"]),
|
|
1135
1175
|
id: import_zod4.z.string().optional().describe("Node ID"),
|
|
1176
|
+
name: import_zod4.z.string().optional().describe("Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)"),
|
|
1136
1177
|
parentId: import_zod4.z.string().optional().describe("Parent node ID. Omit to place on current page."),
|
|
1137
1178
|
x: import_zod4.z.coerce.number().optional().describe("X position (default: 0)"),
|
|
1138
1179
|
y: import_zod4.z.coerce.number().optional().describe("Y position (default: 0)"),
|
|
1180
|
+
items: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe("Array of {id, ...properties} to clone/reparent/update"),
|
|
1139
1181
|
depth: import_zod4.z.coerce.number().optional().describe("Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited."),
|
|
1140
1182
|
rules: flexJson(import_zod4.z.array(import_zod4.z.string())).optional().describe('Rules to check. Default: ["all"]. Categories: "component", "composition", "token", "naming", "wcag".'),
|
|
1141
1183
|
maxDepth: import_zod4.z.coerce.number().optional().describe("Max tree depth (default: 10)"),
|
|
1142
1184
|
maxFindings: import_zod4.z.coerce.number().optional().describe("Max findings (default: 50)"),
|
|
1143
|
-
|
|
1185
|
+
minSeverity: import_zod4.z.enum(["error", "unsafe", "heuristic", "style", "verbose"]).optional().describe("Minimum severity to report (default: style). Set to 'verbose' to include AAA contrast and line-height checks."),
|
|
1186
|
+
skipInstances: flexBool(import_zod4.z.boolean()).optional().describe("Skip instance internals \u2014 findings inside instances are owned by the component (default: true)"),
|
|
1144
1187
|
query: import_zod4.z.string().optional().describe("Name search query (case-insensitive substring match)"),
|
|
1145
1188
|
offset: import_zod4.z.coerce.number().optional().default(0).describe("Skip N items for pagination (default 0)"),
|
|
1146
1189
|
limit: import_zod4.z.coerce.number().optional().default(100).describe("Max items per page (default 100)"),
|
|
1147
1190
|
names: flexJson(import_zod4.z.array(import_zod4.z.string())).optional().describe("Batch lookup by name (case-insensitive). Either id or names is required."),
|
|
1191
|
+
verbose: import_zod4.z.boolean().optional().describe("Include all properties (bounding box, constraints, text style details). Default false \u2014 returns slim, actionable output."),
|
|
1148
1192
|
type: import_zod4.z.enum(["component", "from_node", "variant_set"]).optional().describe("Discriminant for create method"),
|
|
1149
1193
|
topic: import_zod4.z.string().optional().describe('Help topic \u2014 method name for endpoint help, e.g. "create"')
|
|
1150
1194
|
}, caps2, { "clone": "create", "audit": "read", "reparent": "edit", "list": "read", "get": "read", "create": "create", "update": "edit", "delete": "edit", "help": "read" }),
|
|
@@ -1218,7 +1262,7 @@ var tools = [
|
|
|
1218
1262
|
maxHeight: import_zod4.z.coerce.number().optional().describe("Max height for responsive auto-layout"),
|
|
1219
1263
|
overflowDirection: import_zod4.z.enum(["NONE", "HORIZONTAL", "VERTICAL", "BOTH"]).optional().describe("Scroll overflow in prototype (default: NONE)"),
|
|
1220
1264
|
description: import_zod4.z.string().optional().describe("Component description (shown in Figma's component panel)"),
|
|
1221
|
-
children: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe('Inline child nodes.
|
|
1265
|
+
children: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe('Inline child nodes \u2014 build nested trees in one call. Types: text: {type:"text", text, componentPropertyName?, fontFamily?, fontSize?, 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"}]}]\n'),
|
|
1222
1266
|
properties: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe("Component properties to define at creation: [{propertyName, type, defaultValue}]. TEXT properties for inline children with componentPropertyName are created automatically.")
|
|
1223
1267
|
}).passthrough(),
|
|
1224
1268
|
"from_node": import_zod4.z.object({
|
|
@@ -1374,7 +1418,7 @@ var tools = [
|
|
|
1374
1418
|
},
|
|
1375
1419
|
{
|
|
1376
1420
|
name: "frames",
|
|
1377
|
-
description: '/** Create and manage frames, shapes, auto-layout containers, sections, and SVG nodes. Use method "help" for detailed parameter docs. */\n get (id, fields?, depth?, verbose?) \u2192 { results: Node[], _truncated?, _notice? } // Get serialized node data\n list (query?, types?, parentId?, fields?, offset?, limit?) \u2192 { totalCount, returned?, offset?, limit?, results } // Search for nodes (returns stubs only \u2014 use get with depth for full properties)\n update (items: PatchItem[]) \u2192 { results: ("ok" | {error})[] } // Patch node properties\n delete (id?, items?: { id?: string }[]) \u2192 { results: "ok"[] } // Delete nodes\n clone (id
|
|
1421
|
+
description: '/** Create and manage frames, shapes, auto-layout containers, sections, and SVG nodes. Use method "help" for detailed parameter docs. */\n get (id, fields?, depth?, verbose?) \u2192 { results: Node[], _truncated?, _notice? } // Get serialized node data\n list (query?, types?, parentId?, fields?, offset?, limit?) \u2192 { totalCount, returned?, offset?, limit?, results } // Search for nodes (returns stubs only \u2014 use get with depth for full properties)\n update (items: PatchItem[]) \u2192 { results: ("ok" | {error})[] } // Patch node properties\n delete (id?, items?: { id?: string }[]) \u2192 { results: "ok"[] } // Delete nodes\n clone (id?, name?, parentId?, x?, y?, items?: { id: string; name?: string; parentId?: string; x?: number; y?: number }[], depth?) \u2192 { results: {id}[] } // Duplicate nodes\n audit (id, rules?, maxDepth?, maxFindings?, minSeverity?: error|unsafe|heuristic|style|verbose, skipInstances?) \u2192 { nodeId?, nodeName?, categories? } // Run lint on a node \u2014 returns severity-ranked findings\n reparent (items: { id: string; parentId: string; index?: number }[]) \u2192 { results: "ok"[] } // Move nodes into a new parent\n create (type: frame|auto_layout|section|rectangle|ellipse|line|group|boolean_operation|svg, items: (FrameItem | AutoLayoutItem | SectionItem | RectangleItem | EllipseItem | LineItem | GroupItem | BooleanOperationItem | SvgItem)[]) \u2192 { results: {id}[] } // Create frame-like containers\n export (id, format?: PNG|JPG|SVG|SVG_STRING|PDF, scale?) \u2192 { imageData?, mimeType? } // Export a node as PNG, JPG, SVG, SVG_STRING, or PDF\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).',
|
|
1378
1422
|
schema: (caps2) => filterMethodsByTier({
|
|
1379
1423
|
method: import_zod4.z.enum(["get", "list", "update", "delete", "clone", "audit", "reparent", "create", "export", "help"]),
|
|
1380
1424
|
id: import_zod4.z.string().optional().describe("Node ID"),
|
|
@@ -1386,12 +1430,15 @@ var tools = [
|
|
|
1386
1430
|
parentId: import_zod4.z.string().optional().describe("Search only within this subtree"),
|
|
1387
1431
|
offset: import_zod4.z.coerce.number().optional().default(0).describe("Skip N items for pagination (default 0)"),
|
|
1388
1432
|
limit: import_zod4.z.coerce.number().optional().default(100).describe("Max items per page (default 100)"),
|
|
1389
|
-
items: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe("Array of {id, ...properties} to update/delete/reparent"),
|
|
1433
|
+
items: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe("Array of {id, ...properties} to update/delete/clone/reparent"),
|
|
1434
|
+
name: import_zod4.z.string().optional().describe("Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)"),
|
|
1390
1435
|
x: import_zod4.z.coerce.number().optional().describe("X position (default: 0)"),
|
|
1391
1436
|
y: import_zod4.z.coerce.number().optional().describe("Y position (default: 0)"),
|
|
1392
1437
|
rules: flexJson(import_zod4.z.array(import_zod4.z.string())).optional().describe('Rules to check. Default: ["all"]. Categories: "component", "composition", "token", "naming", "wcag".'),
|
|
1393
1438
|
maxDepth: import_zod4.z.coerce.number().optional().describe("Max tree depth (default: 10)"),
|
|
1394
1439
|
maxFindings: import_zod4.z.coerce.number().optional().describe("Max findings (default: 50)"),
|
|
1440
|
+
minSeverity: import_zod4.z.enum(["error", "unsafe", "heuristic", "style", "verbose"]).optional().describe("Minimum severity to report (default: style). Set to 'verbose' to include AAA contrast and line-height checks."),
|
|
1441
|
+
skipInstances: flexBool(import_zod4.z.boolean()).optional().describe("Skip instance internals \u2014 findings inside instances are owned by the component (default: true)"),
|
|
1395
1442
|
type: import_zod4.z.enum(["frame", "auto_layout", "section", "rectangle", "ellipse", "line", "group", "boolean_operation", "svg"]).optional().describe("Discriminant for create method"),
|
|
1396
1443
|
format: import_zod4.z.enum(["PNG", "JPG", "SVG", "SVG_STRING", "PDF"]).optional().describe("Export format (default: PNG). SVG_STRING returns raw SVG text."),
|
|
1397
1444
|
scale: import_zod4.z.coerce.number().optional().describe("Export scale (default: 1, only for PNG/JPG)"),
|
|
@@ -1459,7 +1506,7 @@ var tools = [
|
|
|
1459
1506
|
maxHeight: import_zod4.z.coerce.number().optional().describe("Max height for responsive auto-layout"),
|
|
1460
1507
|
overflowDirection: import_zod4.z.enum(["NONE", "HORIZONTAL", "VERTICAL", "BOTH"]).optional().describe("Scroll overflow in prototype (default: NONE)"),
|
|
1461
1508
|
clipsContent: flexBool(import_zod4.z.boolean()).optional(),
|
|
1462
|
-
children: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe('Inline child nodes.
|
|
1509
|
+
children: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe('Inline child nodes \u2014 build nested trees in one call. Types: text: {type:"text", text, fontFamily?, fontSize?, 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.\n')
|
|
1463
1510
|
}).passthrough(),
|
|
1464
1511
|
"auto_layout": import_zod4.z.object({
|
|
1465
1512
|
name: import_zod4.z.string().optional().describe("Node name"),
|
|
@@ -1515,7 +1562,7 @@ var tools = [
|
|
|
1515
1562
|
overflowDirection: import_zod4.z.enum(["NONE", "HORIZONTAL", "VERTICAL", "BOTH"]).optional().describe("Scroll overflow in prototype (default: NONE)"),
|
|
1516
1563
|
clipsContent: flexBool(import_zod4.z.boolean()).optional(),
|
|
1517
1564
|
nodeIds: flexJson(import_zod4.z.array(import_zod4.z.string())).optional().describe("Existing node IDs to wrap into auto-layout"),
|
|
1518
|
-
children: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe('Inline child nodes.
|
|
1565
|
+
children: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe('Inline child nodes \u2014 build nested trees in one call. Types: text: {type:"text", text, fontFamily?, fontSize?, 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.\n')
|
|
1519
1566
|
}).passthrough(),
|
|
1520
1567
|
"section": import_zod4.z.object({
|
|
1521
1568
|
name: import_zod4.z.string().describe("Section name"),
|
|
@@ -1631,7 +1678,7 @@ var tools = [
|
|
|
1631
1678
|
},
|
|
1632
1679
|
{
|
|
1633
1680
|
name: "instances",
|
|
1634
|
-
description: '/** Create and manage component instances. Use method "help" for detailed parameter docs. */\n list (query?, types?, parentId?, fields?, offset?, limit?) \u2192 { totalCount, returned?, offset?, limit?, results } // Search for nodes (returns stubs only \u2014 use get with depth for full properties)\n delete (id?, items?: { id?: string }[]) \u2192 { results: "ok"[] } // Delete nodes\n clone (id
|
|
1681
|
+
description: '/** Create and manage component instances. Use method "help" for detailed parameter docs. */\n list (query?, types?, parentId?, fields?, offset?, limit?) \u2192 { totalCount, returned?, offset?, limit?, results } // Search for nodes (returns stubs only \u2014 use get with depth for full properties)\n delete (id?, items?: { id?: string }[]) \u2192 { results: "ok"[] } // Delete nodes\n clone (id?, name?, parentId?, x?, y?, items?: { id: string; name?: string; parentId?: string; x?: number; y?: number }[], depth?) \u2192 { results: {id}[] } // Duplicate nodes\n audit (id, rules?, maxDepth?, maxFindings?, minSeverity?: error|unsafe|heuristic|style|verbose, skipInstances?) \u2192 { nodeId?, nodeName?, categories? } // Run lint on a node \u2014 returns severity-ranked findings\n reparent (items: { id: string; parentId: string; index?: number }[]) \u2192 { results: "ok"[] } // Move nodes into a new parent\n get (id, fields?, depth?, verbose?) \u2192 { results, _truncated? } // Get instance detail with component properties and overrides\n create (items: InstanceCreateItem[], depth?) \u2192 { results: {id}[] } // Create component instances\n update (items: InstanceUpdateItem[]) \u2192 { results: ("ok" | {error})[] } // Set instance properties\n swap (items: { id: string; componentId: string }[]) \u2192 { results: ("ok" | {error})[] } // Swap instance component (preserves overrides)\n detach (items: { id: string }[]) \u2192 { results: {id}[] } // Detach instances from their component (converts to frame)\n reset_overrides(items: { id: string }[]) \u2192 { results: ("ok" | {error})[] } // Reset all overrides on instances to match their main component\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).',
|
|
1635
1682
|
schema: (caps2) => filterMethodsByTier({
|
|
1636
1683
|
method: import_zod4.z.enum(["list", "delete", "clone", "audit", "reparent", "get", "create", "update", "swap", "detach", "reset_overrides", "help"]),
|
|
1637
1684
|
query: import_zod4.z.string().optional().describe("Name search query (case-insensitive substring match)"),
|
|
@@ -1641,13 +1688,16 @@ var tools = [
|
|
|
1641
1688
|
offset: import_zod4.z.coerce.number().optional().default(0).describe("Skip N items for pagination (default 0)"),
|
|
1642
1689
|
limit: import_zod4.z.coerce.number().optional().default(100).describe("Max items per page (default 100)"),
|
|
1643
1690
|
id: import_zod4.z.string().optional().describe("Single node ID"),
|
|
1644
|
-
items: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe("Array of {id, ...properties} to delete/reparent/create/update/swap/detach/reset_overrides"),
|
|
1691
|
+
items: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe("Array of {id, ...properties} to delete/clone/reparent/create/update/swap/detach/reset_overrides"),
|
|
1692
|
+
name: import_zod4.z.string().optional().describe("Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)"),
|
|
1645
1693
|
x: import_zod4.z.coerce.number().optional().describe("X position (default: 0)"),
|
|
1646
1694
|
y: import_zod4.z.coerce.number().optional().describe("Y position (default: 0)"),
|
|
1647
1695
|
depth: import_zod4.z.coerce.number().optional().describe("Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited."),
|
|
1648
1696
|
rules: flexJson(import_zod4.z.array(import_zod4.z.string())).optional().describe('Rules to check. Default: ["all"]. Categories: "component", "composition", "token", "naming", "wcag".'),
|
|
1649
1697
|
maxDepth: import_zod4.z.coerce.number().optional().describe("Max tree depth (default: 10)"),
|
|
1650
1698
|
maxFindings: import_zod4.z.coerce.number().optional().describe("Max findings (default: 50)"),
|
|
1699
|
+
minSeverity: import_zod4.z.enum(["error", "unsafe", "heuristic", "style", "verbose"]).optional().describe("Minimum severity to report (default: style). Set to 'verbose' to include AAA contrast and line-height checks."),
|
|
1700
|
+
skipInstances: flexBool(import_zod4.z.boolean()).optional().describe("Skip instance internals \u2014 findings inside instances are owned by the component (default: true)"),
|
|
1651
1701
|
verbose: import_zod4.z.boolean().optional().describe("Include all properties (bounding box, constraints, text style details). Default false \u2014 returns slim, actionable output."),
|
|
1652
1702
|
topic: import_zod4.z.string().optional().describe('Help topic \u2014 method name for endpoint help, e.g. "create"')
|
|
1653
1703
|
}, caps2, { "list": "read", "delete": "edit", "clone": "create", "audit": "read", "reparent": "edit", "get": "read", "create": "create", "update": "edit", "swap": "edit", "detach": "edit", "reset_overrides": "edit", "help": "read" }),
|
|
@@ -1679,6 +1729,7 @@ var tools = [
|
|
|
1679
1729
|
minHeight: import_zod4.z.coerce.number().optional().describe("Min height for responsive auto-layout"),
|
|
1680
1730
|
maxHeight: import_zod4.z.coerce.number().optional().describe("Max height for responsive auto-layout"),
|
|
1681
1731
|
componentId: import_zod4.z.string().describe("Component or component set ID"),
|
|
1732
|
+
sizing: import_zod4.z.enum(["contextual"]).optional().describe('"contextual": infer FILL/HUG from parent layout (e.g. FILL horizontally in a VERTICAL auto-layout parent). Omit to inherit sizing from the component definition.'),
|
|
1682
1733
|
variantProperties: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()).optional().describe('Pick variant e.g. {"Style":"Secondary"}'),
|
|
1683
1734
|
properties: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()).optional().describe('Set component properties inline e.g. {"Label":"Click me", "ShowIcon":true}. Same as instances.update properties.'),
|
|
1684
1735
|
name: import_zod4.z.string().optional().describe("Instance layer name"),
|
|
@@ -1906,7 +1957,7 @@ var tools = [
|
|
|
1906
1957
|
triggerDelay: import_zod4.z.coerce.number().optional().describe("Delay in ms for AFTER_TIMEOUT / MOUSE_ENTER / MOUSE_LEAVE triggers"),
|
|
1907
1958
|
triggerKeyCodes: import_zod4.z.unknown().optional().describe("Key codes for ON_KEY_DOWN trigger"),
|
|
1908
1959
|
triggerDevice: import_zod4.z.enum(["KEYBOARD", "XBOX_ONE", "PS4", "SWITCH_PRO"]).optional().describe("Device for ON_KEY_DOWN (default: KEYBOARD)"),
|
|
1909
|
-
destination: import_zod4.z.string().optional().describe("Target node ID (required for NODE actions)"),
|
|
1960
|
+
destination: import_zod4.z.string().optional().describe("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)."),
|
|
1910
1961
|
navigation: import_zod4.z.enum(["NAVIGATE", "SWAP", "OVERLAY", "SCROLL_TO", "CHANGE_TO"]).optional().describe("Navigation type (default: NAVIGATE)"),
|
|
1911
1962
|
transition: import_zod4.z.enum(["DISSOLVE", "SMART_ANIMATE", "MOVE_IN", "MOVE_OUT", "PUSH", "SLIDE_IN", "SLIDE_OUT", "INSTANT"]).optional().describe("Transition animation (default: DISSOLVE). INSTANT = no animation."),
|
|
1912
1963
|
transitionDirection: import_zod4.z.enum(["LEFT", "RIGHT", "TOP", "BOTTOM"]).optional().describe("Direction for MOVE_IN, MOVE_OUT, PUSH, SLIDE_IN, SLIDE_OUT"),
|
|
@@ -1986,8 +2037,8 @@ var tools = [
|
|
|
1986
2037
|
const schemas = {
|
|
1987
2038
|
"paint": import_zod4.z.object({
|
|
1988
2039
|
name: import_zod4.z.string().describe("Style name"),
|
|
1989
|
-
color: colorRgba.describe("Color value"),
|
|
1990
|
-
colorVariableName: import_zod4.z.string().optional().describe("Bind to a COLOR variable by name (style tracks the variable)"),
|
|
2040
|
+
color: colorRgba.optional().describe("Color value. Optional when colorVariableName is provided."),
|
|
2041
|
+
colorVariableName: import_zod4.z.string().optional().describe("Bind to a COLOR variable by name (style tracks the variable). Can be used alone \u2014 color is resolved from the variable."),
|
|
1991
2042
|
description: import_zod4.z.string().optional().describe("Style description")
|
|
1992
2043
|
}).passthrough(),
|
|
1993
2044
|
"text": import_zod4.z.object({
|
|
@@ -2089,7 +2140,7 @@ var tools = [
|
|
|
2089
2140
|
},
|
|
2090
2141
|
{
|
|
2091
2142
|
name: "text",
|
|
2092
|
-
description: '/** Create and manage text nodes. Use method "help" for detailed parameter docs. */\n get (id, fields?, depth?, verbose?) \u2192 { results: Node[], _truncated?, _notice? } // Get serialized node data\n list (query?, types?, parentId?, fields?, offset?, limit?) \u2192 { totalCount, returned?, offset?, limit?, results } // Search for nodes (returns stubs only \u2014 use get with depth for full properties)\n update (items: PatchItem[]) \u2192 { results: ("ok" | {error})[] } // Patch node properties\n delete (id?, items?: { id?: string }[]) \u2192 { results: "ok"[] } // Delete nodes\n clone (id
|
|
2143
|
+
description: '/** Create and manage text nodes. Use method "help" for detailed parameter docs. */\n get (id, fields?, depth?, verbose?) \u2192 { results: Node[], _truncated?, _notice? } // Get serialized node data\n list (query?, types?, parentId?, fields?, offset?, limit?) \u2192 { totalCount, returned?, offset?, limit?, results } // Search for nodes (returns stubs only \u2014 use get with depth for full properties)\n update (items: PatchItem[]) \u2192 { results: ("ok" | {error})[] } // Patch node properties\n delete (id?, items?: { id?: string }[]) \u2192 { results: "ok"[] } // Delete nodes\n clone (id?, name?, parentId?, x?, y?, items?: { id: string; name?: string; parentId?: string; x?: number; y?: number }[], depth?) \u2192 { results: {id}[] } // Duplicate nodes\n audit (id, rules?, maxDepth?, maxFindings?, minSeverity?: error|unsafe|heuristic|style|verbose, skipInstances?) \u2192 { nodeId?, nodeName?, categories? } // Run lint on a node \u2014 returns severity-ranked findings\n reparent (items: { id: string; parentId: string; index?: number }[]) \u2192 { results: "ok"[] } // Move nodes into a new parent\n create (items: TextItem[], depth?) \u2192 { results: {id}[] } // Create text nodes\n set_content(items: { nodeId: string; text: string }[], depth?) \u2192 { results: "ok"[] } // Replace text content on existing text nodes\n scan (items: { nodeId: string; limit?: number; includePath?: boolean; includeGeometry?: boolean }[]) \u2192 { results: ("ok" | {error})[] } // Scan all text nodes within a subtree\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).',
|
|
2093
2144
|
schema: (caps2) => filterMethodsByTier({
|
|
2094
2145
|
method: import_zod4.z.enum(["get", "list", "update", "delete", "clone", "audit", "reparent", "create", "set_content", "scan", "help"]),
|
|
2095
2146
|
id: import_zod4.z.string().optional().describe("Node ID"),
|
|
@@ -2101,12 +2152,15 @@ var tools = [
|
|
|
2101
2152
|
parentId: import_zod4.z.string().optional().describe("Search only within this subtree"),
|
|
2102
2153
|
offset: import_zod4.z.coerce.number().optional().default(0).describe("Skip N items for pagination (default 0)"),
|
|
2103
2154
|
limit: import_zod4.z.coerce.number().optional().default(100).describe("Max items per page (default 100)"),
|
|
2104
|
-
items: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe("Array of {id, ...properties} to update/delete/reparent/create/set_content/scan"),
|
|
2155
|
+
items: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe("Array of {id, ...properties} to update/delete/clone/reparent/create/set_content/scan"),
|
|
2156
|
+
name: import_zod4.z.string().optional().describe("Rename the clone (set before appending to parent \u2014 required when cloning a variant into its component set to avoid duplicate names)"),
|
|
2105
2157
|
x: import_zod4.z.coerce.number().optional().describe("X position (default: 0)"),
|
|
2106
2158
|
y: import_zod4.z.coerce.number().optional().describe("Y position (default: 0)"),
|
|
2107
2159
|
rules: flexJson(import_zod4.z.array(import_zod4.z.string())).optional().describe('Rules to check. Default: ["all"]. Categories: "component", "composition", "token", "naming", "wcag".'),
|
|
2108
2160
|
maxDepth: import_zod4.z.coerce.number().optional().describe("Max tree depth (default: 10)"),
|
|
2109
2161
|
maxFindings: import_zod4.z.coerce.number().optional().describe("Max findings (default: 50)"),
|
|
2162
|
+
minSeverity: import_zod4.z.enum(["error", "unsafe", "heuristic", "style", "verbose"]).optional().describe("Minimum severity to report (default: style). Set to 'verbose' to include AAA contrast and line-height checks."),
|
|
2163
|
+
skipInstances: flexBool(import_zod4.z.boolean()).optional().describe("Skip instance internals \u2014 findings inside instances are owned by the component (default: true)"),
|
|
2110
2164
|
topic: import_zod4.z.string().optional().describe('Help topic \u2014 method name for endpoint help, e.g. "create"')
|
|
2111
2165
|
}, caps2, { "get": "read", "list": "read", "update": "edit", "delete": "edit", "clone": "create", "audit": "read", "reparent": "edit", "create": "create", "set_content": "edit", "scan": "read", "help": "read" }),
|
|
2112
2166
|
tier: "read",
|
|
@@ -2478,9 +2532,9 @@ var guidelinesList = [
|
|
|
2478
2532
|
}
|
|
2479
2533
|
];
|
|
2480
2534
|
var guidelinesContent = {
|
|
2481
|
-
"component-structure": '# Component Structure\n\nComponents need correct sizing, property bindings, and token usage to work well as instances.\n\n## Width Constraints\n\nComponents with text content need a width \u2014 otherwise text never wraps.\n\n- Set `width` and `layoutSizingHorizontal:"FIXED"` on cards, panels, list items\n- HUG on both axes is only correct for buttons, badges, icons \u2014 intrinsically-sized elements\n\n## Property Bindings\n\nEvery text node inside a component should be bound to a TEXT property so instances can edit the content.\n\n- On creation: `children:[{type:"text", text:"Title", componentPropertyName:"Title"}]` auto-creates and binds\n- After creation: `frames(method:"update", items:[{id:"<textNodeId>", componentPropertyName:"<propName>"}])`\n- For existing nodes with many text children: `components(method:"create", type:"from_node", exposeText:true)`\n\nOrphaned properties (defined but not bound to any node) should be deleted:\n```\ncomponents(method:"update", items:[{id, propertyName:"<key>", action:"delete"}])\n```\n\n## Variant Sets\n\nGroup related components as variants \u2014 don\'t leave them as separate components.\n\n- Name variants with the property format: `Style=Primary`, `Style=Secondary`\n- Combine: `components(method:"create", type:"variant_set", items:[{componentIds:[...], name:"Button"}])`\n- Instances pick variants via `variantProperties:{"Style":"Primary"}`\n\n## Checking\n\nRun `components(method:"audit", id)` \u2014 checks both lint rules and property bindings in one call.',
|
|
2535
|
+
"component-structure": '# Component Structure\n\nComponents need correct sizing, property bindings, and token usage to work well as instances.\n\n## Width Constraints\n\nComponents with text content need a width \u2014 otherwise text never wraps.\n\n- Set `width` and `layoutSizingHorizontal:"FIXED"` on cards, panels, list items\n- HUG on both axes is only correct for buttons, badges, icons \u2014 intrinsically-sized elements\n\n## Property Bindings\n\nEvery text node inside a component should be bound to a TEXT property so instances can edit the content.\n\n- On creation: `children:[{type:"text", text:"Title", componentPropertyName:"Title"}]` auto-creates and binds\n- After creation: `frames(method:"update", items:[{id:"<textNodeId>", componentPropertyName:"<propName>"}])`\n- For existing nodes with many text children: `components(method:"create", type:"from_node", exposeText:true)`\n\nOrphaned properties (defined but not bound to any node) should be deleted:\n```\ncomponents(method:"update", items:[{id, propertyName:"<key>", action:"delete"}])\n```\n\n## Variant Sets\n\nGroup related components as variants \u2014 don\'t leave them as separate components.\n\n- Name variants with the property format: `Style=Primary`, `Style=Secondary`\n- Combine: `components(method:"create", type:"variant_set", items:[{componentIds:[...], name:"Button"}])`\n- Instances pick variants via `variantProperties:{"Style":"Primary"}`\n\n### Adding Variants to an Existing Set\n\nClone an existing variant into the same set with a new name. The `name` param is required \u2014 without it, the duplicate name corrupts the set.\n\n**Add a new value to an existing dimension** (e.g. State=Hover):\n```\ncomponents(method:"clone", id:"<variant_id>", name:"Style=Primary, State=Hover", parentId:"<set_id>")\n```\nClone one variant per combination. For a Style\xD7State set, adding State=Hover requires two clones (one per Style). Use batch `items` for efficiency:\n```\ncomponents(method:"clone", items:[\n {id:"<Primary/Default>", name:"Style=Primary, State=Hover", parentId:"<set_id>"},\n {id:"<Secondary/Default>", name:"Style=Secondary, State=Hover", parentId:"<set_id>"}\n])\n```\nThen patch the new variants: `frames(method:"update", items:[{id:"<new>", fillVariableName:"color/hover"}])`\n\n**Add a new dimension** (e.g. Size=sm to a Style\xD7State set):\n1. Batch rename existing variants to include the new dimension: `frames(method:"update", items:[{id:"<each>", name:"..., Size=md"}])`\n2. Batch clone all variants with the new value: `components(method:"clone", items:[{id:"<each>", name:"..., Size=sm", parentId:"<set_id>"}])`\n3. Batch patch the new variants: `frames(method:"update", items:[{id:"<each>", padding:8, minHeight:32}])`\n\nProperty bindings (TEXT, INSTANCE_SWAP) are preserved on cloned variants.\n\n## Checking\n\nRun `components(method:"audit", id)` \u2014 checks both lint rules and property bindings in one call.',
|
|
2482
2536
|
"library-components": '# Working with Library Components\n\nLibrary components are read-only \u2014 they come from external team libraries and cannot be edited in the current file.\n\n## Reading\n\nWhen reading nodes, library instances appear as stubs with their overridable properties:\n```\n{name: "Header", type: "INSTANCE", componentProperties: {"Platform": "Desktop"}}\n```\n\nLibrary internals are hidden: no `componentId`, no variable names, no style names. You see resolved values (hex colors, numbers) instead.\n\n## Using\n\nPlace library instances via `instances(method:"create", items:[{componentId:"<id>"}])` when you have a local component ID. For library components, instances are already placed by the designer \u2014 interact via `instances(method:"update")` to set properties.\n\n## Customizing\n\nTo edit a library component, clone it into the local file first:\n\n```\ncomponents(method:"clone", id:"<instanceId>")\n```\n\nThis resolves the instance to its source component (or full component set) and creates a local copy with a new ID. Edit the local copy freely \u2014 it is independent of the library.\n\nDo not attempt to `components(method:"get")` or `components(method:"update")` a library component directly \u2014 these will error.\n\n## Overriding Instance Properties\n\nUse `instances(method:"update")` to change overridable properties on library instances:\n```\ninstances(method:"update", items:[{id:"<instanceId>", properties:{"Label":"New Text", "State":"Hover"}}])\n```\n\nProperty names are clean (no hash suffixes needed for update \u2014 the system resolves partial keys).',
|
|
2483
|
-
"responsive-designs":
|
|
2537
|
+
"responsive-designs": '# Responsive Sizing\n\n## Workflow: Top-Down Sizing\n\nBuild layouts from the outside in:\n\n1. **Set the container first.** Every container needs an explicit width \u2014 either `width` + `layoutSizingHorizontal:"FIXED"` for shells and bounded panels, or `layoutSizingHorizontal:"FILL"` inside an auto-layout parent. Set `layoutMode` (VERTICAL or HORIZONTAL) and spacing/padding.\n2. **Children fill the container.** Use `layoutSizingHorizontal:"FILL"` on children so they stretch to the available space. Use `layoutSizingVertical:"HUG"` so height follows content.\n3. **Only leaves use HUG on both axes.** Buttons, badges, icons \u2014 elements with short, predictable content that should shrink-wrap.\n\nThis ensures every level of the tree has a clear width constraint. Text wraps, FILL children stretch, and the layout adapts when the container resizes.\n\nAlways set BOTH axes explicitly on every node. Omitting sizing leads to unintended defaults.\n\n## FIXED / FILL / HUG\n\n- **FIXED** \u2014 explicit bounded widths: page shell, sidebar, modal max-width, specimen frames\n- **FILL** \u2014 children that adapt to parent: cards, rows, panels, nav stacks, text that should wrap. Use `minWidth`/`maxWidth` for responsive constraints.\n- **HUG** \u2014 content-sized leaves only: icons, badges, pills, button labels\n\n## Anti-patterns: HUG/HUG\n\nHUG on both axes is the most common cause of broken layouts. It means "shrink to fit my content on both axes" \u2014 the container has no opinion about its own size and collapses to whatever its children measure.\n\n**Why HUG/HUG breaks designs:**\n\n1. **Text never wraps.** A HUG-width container grows to fit the longest text line. Body text becomes a single very long line instead of wrapping at a readable width. The design looks correct with short placeholder text but breaks with real content.\n\n2. **Layouts don\'t adapt.** HUG/HUG containers ignore their parent\'s width. A card inside a responsive column won\'t stretch to fill available space \u2014 it stays at its content width, leaving gaps or overflowing.\n\n3. **FILL children become under-constrained.** A child with `layoutSizingHorizontal:"FILL"` inside a HUG-width parent has no space to fill \u2014 the parent defers its width to its children, but the FILL child defers its width to the parent. The result is under-constrained sizing that produces unpredictable or collapsed layouts.\n\n4. **Cascading failures.** One HUG/HUG container at the top of a tree forces every child to resolve its own width. The entire layout becomes rigid and content-dependent instead of responsive.\n\n**HUG/HUG is only correct for:**\n- Buttons, pills, badges, chips \u2014 intrinsically-sized leaf elements with short, predictable content\n- Icon containers with fixed-size children\n- Inline tags and status indicators\n\n**For everything else, set at least one axis to FIXED or FILL:**\n- Cards, panels, list rows \u2192 `layoutSizingHorizontal:"FILL"`, vertical `HUG`. Add `minWidth`/`maxWidth` for responsive bounds.\n- Shells, sidebars, modals \u2192 `width` + `layoutSizingHorizontal:"FIXED"`, vertical `FILL` or `HUG`\n- Full-width sections \u2192 `layoutSizingHorizontal:"FILL"`, `layoutSizingVertical:"HUG"`\n\n## Component Sizing\n\nComponent roots use `FILL` when placed in a parent \u2014 they adapt to context, not a fixed specimen width. Use `FIXED` only for the specimen (the component definition itself when it needs a specific preview width).\n\nExample sidebar item:\n- Instance: `FILL` in parent nav stack\n- Icon child: fixed 18x18\n- Label child: `FILL`\n- Badge child: `HUG`\n\n## Text Sizing\n\n- Body text inside containers: prefer `FILL` width, `HUG` height (auto-wraps)\n- Single-line labels: prefer `FILL` horizontal (truncates if needed)\n- Standalone headings: `HUG` is fine\n\nInside auto-layout parents, target `layoutSizingHorizontal:"FILL"` + `layoutSizingVertical:"HUG"` + `textAutoResize:"HEIGHT"` for text that should wrap. These are not auto-applied \u2014 set them explicitly on text.create or text.update.\n\n## Checklist\n\nBefore finalizing a layout, verify:\n1. No container with text has HUG on the horizontal axis (unless it\'s a button/badge)\n2. Children use FILL on the axis that should absorb available space \u2014 not blindly on both axes. Compact controls in horizontal rows often stay HUG vertically.\n3. Top-level containers have an explicit width (FIXED) or stretch to their parent (FILL)\n4. Run `lint(method:"check", nodeId:"<rootId>", rules:["composition"])` to catch overflow-parent, unbounded-hug, and fixed-in-autolayout issues',
|
|
2484
2538
|
"token-discipline": '# Token Discipline\n\nEvery color, spacing value, and text style should come from a design token \u2014 not hardcoded values.\n\n## Colors\n\nBind fills and strokes to color variables instead of hex values.\n\n- Fill: `fillVariableName:"bg/primary"` or `fillStyleName:"Surface/Primary"`\n- Stroke: `strokeVariableName:"border/default"`\n- Text color: `fontColorVariableName:"text/primary"`\n\nIf no matching variable exists, create one first:\n```\nvariables(method:"create", collectionId:"Colors", items:[{name:"bg/accent", type:"COLOR", valuesByMode:{"Light":"#E8F0FE","Dark":"#1A3A5C"}, scopes:["ALL_FILLS"]}])\n```\n\n## Spacing and Radius\n\nPass a variable name string instead of a number for cornerRadius, padding, itemSpacing, strokeWeight, opacity.\n\n- `cornerRadius:"radius/8"` not `cornerRadius:8`\n- `paddingTop:"space/16"` not `paddingTop:16`\n- `itemSpacing:"space/8"` not `itemSpacing:8`\n\nCreate FLOAT variables with appropriate scopes:\n```\nvariables(method:"create", collectionId:"Metrics", items:[{name:"space/12", type:"FLOAT", value:12, scopes:["GAP","WIDTH_HEIGHT"]}])\n```\n\n## Text Styles\n\nApply text styles by name \u2014 don\'t set fontSize/fontFamily/fontWeight manually.\n\n- `textStyleName:"Body/M"` on text.create or frames.update\n- Create styles with `styles(method:"create", type:"text", items:[{name:"Body/M", fontFamily:"Inter", fontSize:14, lineHeight:{value:20, unit:"PIXELS"}}])`\n\n## Common Scopes\n\nCOLOR variables:\n- `ALL_FILLS` \u2014 background fills\n- `TEXT_FILL` \u2014 text color\n- `STROKE_COLOR` \u2014 borders and outlines\n\nFLOAT variables:\n- `GAP`, `WIDTH_HEIGHT` \u2014 spacing and padding\n- `CORNER_RADIUS` \u2014 border radius\n- `STROKE_FLOAT` \u2014 stroke weight\n- `OPACITY` \u2014 transparency\n\n## Checking\n\nLint rules `hardcoded-color`, `hardcoded-token`, `no-text-style` catch unbound values. Run `audit` on any node to check.',
|
|
2485
2539
|
"vibma-workflow": '# Vibma Workflow\n\nWork with the tool in a predictable sequence: read before writing, create parents before children, verify after mutations.\n\n## Build Order\n\n1. `connection.create` \u2192 `connection.get` to verify\n2. Inspect existing structure: `document.get`, `variables.list`, `styles.list`, `components.list`\n3. Create design tokens: variable collections \u2192 variables \u2192 text styles \u2192 effect styles\n4. Create components from tokens\n5. Assemble screens from component instances\n6. Verify with `lint.check` and `frames.export`\n\n## Parent-First Rule\n\nCreate parent containers before children. Dependent creates must be sequential \u2014 never parallelize when the child needs the parent ID.\n\n## Component Creation\n\nBuild components early \u2014 they are the building blocks for screens. A component IS a frame: create it directly with layout properties, then add children.\n\n- Use `components.create(type: "component")` with properties for TEXT, BOOLEAN, INSTANCE_SWAP\n- TEXT properties auto-bind to child text nodes with matching names\n- Group related components into variant sets with `components.create(type: "variant_set")` for state dimensions (Style, Size, State)\n- Use flat components (not variant sets) for INSTANCE_SWAP slots like icons or avatars\n- Assemble screens from `instances.create`, not by cloning frames\n\n## Placement Rule\n\nAlways pass `x` and `y` for top-level nodes and clones. Do not stack everything at `0,0`.\n\n## Instance Rule\n\nCall `components.get` or `instances.get` to discover property keys (including `#suffix`) before setting overrides. Do not guess property names.\n\n## Verify After Mutations\n\n`"ok"` means the write succeeded, not that the result is correct. Read back the node after clone, swap, mode pinning, or large batch updates.'
|
|
2486
2540
|
};
|