@ufira/vibma 1.1.2 → 1.1.3-rc2
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 +122 -8
- package/dist/mcp.js +122 -8
- package/dist/tools/generated/guards.cjs +59 -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 +58 -0
- package/dist/tools/registry.cjs +61 -4
- package/dist/tools/registry.js +61 -4
- package/package.json +1 -1
package/dist/mcp.cjs
CHANGED
|
@@ -412,7 +412,7 @@ Create frame-like containers
|
|
|
412
412
|
|
|
413
413
|
Example: frames(method:"create", type:"auto_layout", layoutMode:"VERTICAL", itemSpacing:16, padding:24)
|
|
414
414
|
|
|
415
|
-
Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line | group | boolean_operation | svg)
|
|
415
|
+
Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line | group | boolean_operation | svg | slot)
|
|
416
416
|
|
|
417
417
|
## frame \u2014 General-purpose frame \u2014 shrinks to content by default, static when width+height given
|
|
418
418
|
name (string, optional) \u2014 Node name
|
|
@@ -631,7 +631,64 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
|
|
|
631
631
|
name (string, optional) \u2014 Layer name (default: 'SVG')
|
|
632
632
|
parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
|
|
633
633
|
x (number, optional) \u2014 X position (default: 0)
|
|
634
|
-
y (number, optional) \u2014 Y position (default: 0)
|
|
634
|
+
y (number, optional) \u2014 Y position (default: 0)
|
|
635
|
+
|
|
636
|
+
## slot \u2014 Create a slot inside a component. Slots are placeholder containers that instance users fill with content. Defaults to VERTICAL auto-layout with FILL/HUG sizing \u2014 ready to receive children. Accepts all frame layout properties.
|
|
637
|
+
name (string, optional) \u2014 Node name
|
|
638
|
+
parentId (string, optional) \u2014 Parent node ID inside the owning component. Required unless componentId is provided.
|
|
639
|
+
x (number, optional) \u2014 X position (default: 0)
|
|
640
|
+
y (number, optional) \u2014 Y position (default: 0)
|
|
641
|
+
width (number, optional) \u2014 Width in px (omit to shrink-to-content via HUG)
|
|
642
|
+
height (number, optional) \u2014 Height in px (omit to shrink-to-content via HUG)
|
|
643
|
+
rotation (number, optional) \u2014 Rotation in degrees (0-360)
|
|
644
|
+
visible (boolean, optional) \u2014 Show/hide (default true)
|
|
645
|
+
locked (boolean, optional) \u2014 Lock/unlock (default false)
|
|
646
|
+
opacity (string, optional) \u2014 Opacity (0-1) or variable name
|
|
647
|
+
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)
|
|
648
|
+
effectStyleName (string, optional) \u2014 Effect style name (e.g. 'Shadow/Card') for shadows, blurs
|
|
649
|
+
fills (array, optional) \u2014 Fill paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] for transparent. Primary way to set fills.
|
|
650
|
+
fillColor (Color, optional) \u2014 Shorthand \u2014 sets a single solid fill (auto-binds to matching variable/style)
|
|
651
|
+
fillStyleName (string, optional) \u2014 Paint style name for fill
|
|
652
|
+
fillVariableName (string, optional) \u2014 Color variable by name e.g. 'bg/primary'
|
|
653
|
+
imageUrl (string, optional) \u2014 Image source \u2014 'pexel:<id>' for Pexels photos, a public URL, or a local file path. SVGs are inserted as vectors; raster images become IMAGE fills.
|
|
654
|
+
imageScaleMode (FILL | FIT | CROP | TILE, optional) \u2014 How the image is scaled within the frame (default: FILL)
|
|
655
|
+
strokes (array, optional) \u2014 Stroke paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] to clear. Primary way to set strokes.
|
|
656
|
+
strokeColor (Color, optional) \u2014 Shorthand \u2014 sets a single solid stroke (auto-binds to matching variable/style)
|
|
657
|
+
strokeStyleName (string, optional) \u2014 Paint style name for stroke
|
|
658
|
+
strokeVariableName (string, optional) \u2014 Color variable by name for stroke
|
|
659
|
+
strokeWeight (string, optional) \u2014 All sides (number) or variable name (string). Per-side: strokeTopWeight, strokeBottomWeight, strokeLeftWeight, strokeRightWeight.
|
|
660
|
+
strokeTopWeight (string, optional)
|
|
661
|
+
strokeBottomWeight (string, optional)
|
|
662
|
+
strokeLeftWeight (string, optional)
|
|
663
|
+
strokeRightWeight (string, optional)
|
|
664
|
+
strokeAlign (INSIDE | OUTSIDE | CENTER, optional) \u2014 Stroke position (default: INSIDE)
|
|
665
|
+
cornerRadius (string, optional) \u2014 All corners (number) or variable name (string). Per-corner: topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius.
|
|
666
|
+
topLeftRadius (string, optional)
|
|
667
|
+
topRightRadius (string, optional)
|
|
668
|
+
bottomRightRadius (string, optional)
|
|
669
|
+
bottomLeftRadius (string, optional)
|
|
670
|
+
layoutMode (NONE | HORIZONTAL | VERTICAL, optional) \u2014 Layout direction (default: auto \u2014 NONE when width+height set, otherwise inferred from layout props)
|
|
671
|
+
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.
|
|
672
|
+
padding (string, optional) \u2014 All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft.
|
|
673
|
+
paddingTop (string, optional)
|
|
674
|
+
paddingRight (string, optional)
|
|
675
|
+
paddingBottom (string, optional)
|
|
676
|
+
paddingLeft (string, optional)
|
|
677
|
+
primaryAxisAlignItems (MIN | MAX | CENTER | SPACE_BETWEEN, optional)
|
|
678
|
+
counterAxisAlignItems (MIN | MAX | CENTER | BASELINE, optional)
|
|
679
|
+
itemSpacing (string, optional) \u2014 Spacing between children (number or variable name string, default: 0)
|
|
680
|
+
counterAxisSpacing (string, optional) \u2014 Gap between wrapped rows (requires layoutWrap: WRAP)
|
|
681
|
+
strokesIncludedInLayout (boolean, optional) \u2014 Include stroke width in layout measurements (default: false)
|
|
682
|
+
overflowDirection (NONE | HORIZONTAL | VERTICAL | BOTH, optional) \u2014 Scroll overflow in prototype (default: NONE)
|
|
683
|
+
layoutPositioning (AUTO | ABSOLUTE, optional) \u2014 ABSOLUTE = floating inside auto-layout parent
|
|
684
|
+
layoutSizingHorizontal (FIXED | HUG | FILL, optional)
|
|
685
|
+
layoutSizingVertical (FIXED | HUG | FILL, optional)
|
|
686
|
+
minWidth (number, optional) \u2014 Min width for responsive auto-layout
|
|
687
|
+
maxWidth (number, optional) \u2014 Max width for responsive auto-layout
|
|
688
|
+
minHeight (number, optional) \u2014 Min height for responsive auto-layout
|
|
689
|
+
maxHeight (number, optional) \u2014 Max height for responsive auto-layout
|
|
690
|
+
annotations (array, optional) \u2014 Set annotations \u2014 [{label?, labelMarkdown?, properties?, categoryId?}]. Properties validated per node type.
|
|
691
|
+
componentId (string, optional) \u2014 Owning component ID. Optional \u2014 auto-resolved from parentId by walking up ancestors.`,
|
|
635
692
|
"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',
|
|
636
693
|
"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)"
|
|
637
694
|
}
|
|
@@ -914,7 +971,7 @@ Methods:
|
|
|
914
971
|
// "fixed-in-autolayout" \u2014 FIXED-size children in auto-layout parents [heuristic]
|
|
915
972
|
// "unbounded-hug" \u2014 HUG on both axes [unsafe; short leaf text\u2192style]
|
|
916
973
|
// "hug-cross-axis" \u2014 HUG on cross-axis of constrained parent [heuristic; leaf nodes\u2192style]
|
|
917
|
-
// "empty-container" \u2014 empty frames [style]
|
|
974
|
+
// "empty-container" \u2014 empty frames, excludes SLOT nodes [style]
|
|
918
975
|
// Token rules [token]:
|
|
919
976
|
// "hardcoded-color" \u2014 colors not using styles or variables [heuristic]
|
|
920
977
|
// "hardcoded-token" \u2014 numeric values not bound to FLOAT variable [heuristic]
|
|
@@ -1180,7 +1237,7 @@ Params:
|
|
|
1180
1237
|
}
|
|
1181
1238
|
};
|
|
1182
1239
|
var helpTopics = {
|
|
1183
|
-
"missing_tools": '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
1240
|
+
"missing_tools": '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma@latest", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
1184
1241
|
};
|
|
1185
1242
|
var allEndpointNames = Object.keys(helpEndpoints);
|
|
1186
1243
|
var allTopicNames = Object.keys(helpTopics);
|
|
@@ -1746,7 +1803,7 @@ var tools = [
|
|
|
1746
1803
|
},
|
|
1747
1804
|
{
|
|
1748
1805
|
name: "frames",
|
|
1749
|
-
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 \u2014 produces a same-type copy (frame\u2192frame, instance\u2192instance, component\u2192component). Instance clones reference the same source component; they do not duplicate the component definition.\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 commit (id) \u2192 { results: {id}[] } // Commit a staged node \u2014 unwraps from [STAGED] container into the original target location.\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).',
|
|
1806
|
+
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 \u2014 produces a same-type copy (frame\u2192frame, instance\u2192instance, component\u2192component). Instance clones reference the same source component; they do not duplicate the component definition.\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|slot, items: (FrameItem | AutoLayoutItem | SectionItem | RectangleItem | EllipseItem | LineItem | GroupItem | BooleanOperationItem | SvgItem | SlotItem)[]) \u2192 { results: {id}[] } // Create frame-like containers\n commit (id) \u2192 { results: {id}[] } // Commit a staged node \u2014 unwraps from [STAGED] container into the original target location.\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).',
|
|
1750
1807
|
schema: (caps2) => filterMethodsByTier({
|
|
1751
1808
|
method: import_zod4.z.enum(["get", "list", "update", "delete", "clone", "audit", "reparent", "create", "commit", "export", "help"]),
|
|
1752
1809
|
id: import_zod4.z.string().optional().describe("Node ID"),
|
|
@@ -1767,7 +1824,7 @@ var tools = [
|
|
|
1767
1824
|
maxFindings: import_zod4.z.coerce.number().optional().describe("Max findings (default: 50)"),
|
|
1768
1825
|
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."),
|
|
1769
1826
|
skipInstances: flexBool(import_zod4.z.boolean()).optional().describe("Skip instance internals \u2014 findings inside instances are owned by the component (default: true)"),
|
|
1770
|
-
type: import_zod4.z.enum(["frame", "auto_layout", "section", "rectangle", "ellipse", "line", "group", "boolean_operation", "svg"]).optional().describe("Discriminant for create method"),
|
|
1827
|
+
type: import_zod4.z.enum(["frame", "auto_layout", "section", "rectangle", "ellipse", "line", "group", "boolean_operation", "svg", "slot"]).optional().describe("Discriminant for create method"),
|
|
1771
1828
|
format: import_zod4.z.enum(["PNG", "JPG", "SVG", "SVG_STRING", "PDF"]).optional().describe("Export format (default: PNG). SVG_STRING returns raw SVG text."),
|
|
1772
1829
|
scale: import_zod4.z.coerce.number().optional().describe("Export scale (default: 1, only for PNG/JPG)"),
|
|
1773
1830
|
topic: import_zod4.z.string().optional().describe('Help topic \u2014 method name for endpoint help, e.g. "create"')
|
|
@@ -2000,6 +2057,63 @@ var tools = [
|
|
|
2000
2057
|
parentId: import_zod4.z.string().optional().describe("Parent node ID. Omit to place at current page root."),
|
|
2001
2058
|
x: import_zod4.z.coerce.number().optional().describe("X position (default: 0)"),
|
|
2002
2059
|
y: import_zod4.z.coerce.number().optional().describe("Y position (default: 0)")
|
|
2060
|
+
}).passthrough(),
|
|
2061
|
+
"slot": import_zod4.z.object({
|
|
2062
|
+
name: import_zod4.z.string().optional().describe("Node name"),
|
|
2063
|
+
parentId: import_zod4.z.string().optional().describe("Parent node ID inside the owning component. Required unless componentId is provided."),
|
|
2064
|
+
x: import_zod4.z.coerce.number().optional().describe("X position (default: 0)"),
|
|
2065
|
+
y: import_zod4.z.coerce.number().optional().describe("Y position (default: 0)"),
|
|
2066
|
+
width: import_zod4.z.coerce.number().optional().describe("Width in px (omit to shrink-to-content via HUG)"),
|
|
2067
|
+
height: import_zod4.z.coerce.number().optional().describe("Height in px (omit to shrink-to-content via HUG)"),
|
|
2068
|
+
rotation: import_zod4.z.coerce.number().optional().describe("Rotation in degrees (0-360)"),
|
|
2069
|
+
visible: flexBool(import_zod4.z.boolean()).optional().describe("Show/hide (default true)"),
|
|
2070
|
+
locked: flexBool(import_zod4.z.boolean()).optional().describe("Lock/unlock (default false)"),
|
|
2071
|
+
opacity: token.optional().describe("Opacity (0-1) or variable name"),
|
|
2072
|
+
blendMode: import_zod4.z.enum(["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(),
|
|
2073
|
+
effectStyleName: import_zod4.z.string().optional().describe("Effect style name (e.g. 'Shadow/Card') for shadows, blurs"),
|
|
2074
|
+
fills: import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown())).optional().describe("Fill paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] for transparent. Primary way to set fills."),
|
|
2075
|
+
fillColor: colorRgba.optional().describe("Shorthand \u2014 sets a single solid fill (auto-binds to matching variable/style)"),
|
|
2076
|
+
fillStyleName: import_zod4.z.string().optional().describe("Paint style name for fill"),
|
|
2077
|
+
fillVariableName: import_zod4.z.string().optional().describe("Color variable by name e.g. 'bg/primary'"),
|
|
2078
|
+
imageUrl: import_zod4.z.string().optional().describe("Image source \u2014 'pexel:<id>' for Pexels photos, a public URL, or a local file path. SVGs are inserted as vectors; raster images become IMAGE fills."),
|
|
2079
|
+
imageScaleMode: import_zod4.z.enum(["FILL", "FIT", "CROP", "TILE"]).optional().describe("How the image is scaled within the frame (default: FILL)"),
|
|
2080
|
+
strokes: import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown())).optional().describe("Stroke paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] to clear. Primary way to set strokes."),
|
|
2081
|
+
strokeColor: colorRgba.optional().describe("Shorthand \u2014 sets a single solid stroke (auto-binds to matching variable/style)"),
|
|
2082
|
+
strokeStyleName: import_zod4.z.string().optional().describe("Paint style name for stroke"),
|
|
2083
|
+
strokeVariableName: import_zod4.z.string().optional().describe("Color variable by name for stroke"),
|
|
2084
|
+
strokeWeight: token.optional().describe("All sides (number) or variable name (string). Per-side: strokeTopWeight, strokeBottomWeight, strokeLeftWeight, strokeRightWeight."),
|
|
2085
|
+
strokeTopWeight: token.optional(),
|
|
2086
|
+
strokeBottomWeight: token.optional(),
|
|
2087
|
+
strokeLeftWeight: token.optional(),
|
|
2088
|
+
strokeRightWeight: token.optional(),
|
|
2089
|
+
strokeAlign: import_zod4.z.enum(["INSIDE", "OUTSIDE", "CENTER"]).optional().describe("Stroke position (default: INSIDE)"),
|
|
2090
|
+
cornerRadius: token.optional().describe("All corners (number) or variable name (string). Per-corner: topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius."),
|
|
2091
|
+
topLeftRadius: token.optional(),
|
|
2092
|
+
topRightRadius: token.optional(),
|
|
2093
|
+
bottomRightRadius: token.optional(),
|
|
2094
|
+
bottomLeftRadius: token.optional(),
|
|
2095
|
+
layoutMode: import_zod4.z.enum(["NONE", "HORIZONTAL", "VERTICAL"]).optional().describe("Layout direction (default: auto \u2014 NONE when width+height set, otherwise inferred from layout props)"),
|
|
2096
|
+
layoutWrap: import_zod4.z.enum(["NO_WRAP", "WRAP"]).optional().describe("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."),
|
|
2097
|
+
padding: token.optional().describe("All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft."),
|
|
2098
|
+
paddingTop: token.optional(),
|
|
2099
|
+
paddingRight: token.optional(),
|
|
2100
|
+
paddingBottom: token.optional(),
|
|
2101
|
+
paddingLeft: token.optional(),
|
|
2102
|
+
primaryAxisAlignItems: import_zod4.z.enum(["MIN", "MAX", "CENTER", "SPACE_BETWEEN"]).optional(),
|
|
2103
|
+
counterAxisAlignItems: import_zod4.z.enum(["MIN", "MAX", "CENTER", "BASELINE"]).optional(),
|
|
2104
|
+
itemSpacing: token.optional().describe("Spacing between children (number or variable name string, default: 0)"),
|
|
2105
|
+
counterAxisSpacing: token.optional().describe("Gap between wrapped rows (requires layoutWrap: WRAP)"),
|
|
2106
|
+
strokesIncludedInLayout: flexBool(import_zod4.z.boolean()).optional().describe("Include stroke width in layout measurements (default: false)"),
|
|
2107
|
+
overflowDirection: import_zod4.z.enum(["NONE", "HORIZONTAL", "VERTICAL", "BOTH"]).optional().describe("Scroll overflow in prototype (default: NONE)"),
|
|
2108
|
+
layoutPositioning: import_zod4.z.enum(["AUTO", "ABSOLUTE"]).optional().describe("ABSOLUTE = floating inside auto-layout parent"),
|
|
2109
|
+
layoutSizingHorizontal: import_zod4.z.enum(["FIXED", "HUG", "FILL"]).optional(),
|
|
2110
|
+
layoutSizingVertical: import_zod4.z.enum(["FIXED", "HUG", "FILL"]).optional(),
|
|
2111
|
+
minWidth: import_zod4.z.coerce.number().optional().describe("Min width for responsive auto-layout"),
|
|
2112
|
+
maxWidth: import_zod4.z.coerce.number().optional().describe("Max width for responsive auto-layout"),
|
|
2113
|
+
minHeight: import_zod4.z.coerce.number().optional().describe("Min height for responsive auto-layout"),
|
|
2114
|
+
maxHeight: import_zod4.z.coerce.number().optional().describe("Max height for responsive auto-layout"),
|
|
2115
|
+
annotations: flexJson(import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))).optional().describe("Set annotations \u2014 [{label?, labelMarkdown?, properties?, categoryId?}]. Properties validated per node type."),
|
|
2116
|
+
componentId: import_zod4.z.string().optional().describe("Owning component ID. Optional \u2014 auto-resolved from parentId by walking up ancestors.")
|
|
2003
2117
|
}).passthrough()
|
|
2004
2118
|
};
|
|
2005
2119
|
const s = params.type && schemas[params.type];
|
|
@@ -3032,7 +3146,7 @@ var guidelinesList = [
|
|
|
3032
3146
|
}
|
|
3033
3147
|
];
|
|
3034
3148
|
var guidelinesContent = {
|
|
3035
|
-
"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- 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.',
|
|
3149
|
+
"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- 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## Slots\n\nSlots are placeholder containers inside components that instance users can fill with custom content.\n\n- Create at component root: `frames(method:"create", type:"slot", items:[{parentId:"<comp_id>", name:"Content"}])`\n- Create nested inside a frame within a component: `frames(method:"create", type:"slot", items:[{parentId:"<frame_id>", name:"Content"}])`\n- In instances, add content by using the slot\'s ID as `parentId` on any create/reparent call\n- Empty slots are normal \u2014 they don\'t trigger lint warnings\n\n## Checking\n\nRun `components(method:"audit", id)` \u2014 checks both lint rules and property bindings in one call.',
|
|
3036
3150
|
"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).',
|
|
3037
3151
|
"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## Wrapping Layouts (layoutWrap)\n\n`layoutWrap: WRAP` enables children to flow into new rows when they exceed the container width \u2014 like CSS `flex-wrap`. This only works with **HORIZONTAL** auto-layout. Figma does not support wrap on VERTICAL layouts.\n\n**When to use wrap:**\n- Card grids with a fixed number of columns at a known width\n- Tag/chip collections where items flow into multiple rows\n- Any layout where items should reflow based on available width\n\n**Horizontal wrap pattern:**\n```\nframes.create(type: "auto_layout", layoutMode: "HORIZONTAL", layoutWrap: "WRAP",\n itemSpacing: "space/16", counterAxisSpacing: "space/16")\n```\nChildren use FIXED width to control column count. `counterAxisSpacing` sets the gap between wrapped rows.\n\n**Vertical grid alternative:**\nSince VERTICAL layouts cannot wrap, build column-based grids by nesting VERTICAL columns inside a HORIZONTAL parent:\n```\nouter (HORIZONTAL, itemSpacing: 20, FILL width)\n col-1 (VERTICAL, FILL width, HUG height, itemSpacing: 20)\n col-2 (VERTICAL, FILL width, HUG height, itemSpacing: 20)\n col-3 (VERTICAL, FILL width, HUG height, itemSpacing: 20)\n```\nEach column gets equal width via FILL. Reparent items into columns for column-first ordering. This handles variable card heights per column independently.\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',
|
|
3038
3152
|
"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.',
|
|
@@ -3139,7 +3253,7 @@ function registerPrompts(server2) {
|
|
|
3139
3253
|
role: "assistant",
|
|
3140
3254
|
content: {
|
|
3141
3255
|
type: "text",
|
|
3142
|
-
text: '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
3256
|
+
text: '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma@latest", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
3143
3257
|
}
|
|
3144
3258
|
}],
|
|
3145
3259
|
description: "Why create or edit tools are missing and how to fix it"
|
package/dist/mcp.js
CHANGED
|
@@ -390,7 +390,7 @@ Create frame-like containers
|
|
|
390
390
|
|
|
391
391
|
Example: frames(method:"create", type:"auto_layout", layoutMode:"VERTICAL", itemSpacing:16, padding:24)
|
|
392
392
|
|
|
393
|
-
Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line | group | boolean_operation | svg)
|
|
393
|
+
Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line | group | boolean_operation | svg | slot)
|
|
394
394
|
|
|
395
395
|
## frame \u2014 General-purpose frame \u2014 shrinks to content by default, static when width+height given
|
|
396
396
|
name (string, optional) \u2014 Node name
|
|
@@ -609,7 +609,64 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
|
|
|
609
609
|
name (string, optional) \u2014 Layer name (default: 'SVG')
|
|
610
610
|
parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
|
|
611
611
|
x (number, optional) \u2014 X position (default: 0)
|
|
612
|
-
y (number, optional) \u2014 Y position (default: 0)
|
|
612
|
+
y (number, optional) \u2014 Y position (default: 0)
|
|
613
|
+
|
|
614
|
+
## slot \u2014 Create a slot inside a component. Slots are placeholder containers that instance users fill with content. Defaults to VERTICAL auto-layout with FILL/HUG sizing \u2014 ready to receive children. Accepts all frame layout properties.
|
|
615
|
+
name (string, optional) \u2014 Node name
|
|
616
|
+
parentId (string, optional) \u2014 Parent node ID inside the owning component. Required unless componentId is provided.
|
|
617
|
+
x (number, optional) \u2014 X position (default: 0)
|
|
618
|
+
y (number, optional) \u2014 Y position (default: 0)
|
|
619
|
+
width (number, optional) \u2014 Width in px (omit to shrink-to-content via HUG)
|
|
620
|
+
height (number, optional) \u2014 Height in px (omit to shrink-to-content via HUG)
|
|
621
|
+
rotation (number, optional) \u2014 Rotation in degrees (0-360)
|
|
622
|
+
visible (boolean, optional) \u2014 Show/hide (default true)
|
|
623
|
+
locked (boolean, optional) \u2014 Lock/unlock (default false)
|
|
624
|
+
opacity (string, optional) \u2014 Opacity (0-1) or variable name
|
|
625
|
+
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)
|
|
626
|
+
effectStyleName (string, optional) \u2014 Effect style name (e.g. 'Shadow/Card') for shadows, blurs
|
|
627
|
+
fills (array, optional) \u2014 Fill paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] for transparent. Primary way to set fills.
|
|
628
|
+
fillColor (Color, optional) \u2014 Shorthand \u2014 sets a single solid fill (auto-binds to matching variable/style)
|
|
629
|
+
fillStyleName (string, optional) \u2014 Paint style name for fill
|
|
630
|
+
fillVariableName (string, optional) \u2014 Color variable by name e.g. 'bg/primary'
|
|
631
|
+
imageUrl (string, optional) \u2014 Image source \u2014 'pexel:<id>' for Pexels photos, a public URL, or a local file path. SVGs are inserted as vectors; raster images become IMAGE fills.
|
|
632
|
+
imageScaleMode (FILL | FIT | CROP | TILE, optional) \u2014 How the image is scaled within the frame (default: FILL)
|
|
633
|
+
strokes (array, optional) \u2014 Stroke paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] to clear. Primary way to set strokes.
|
|
634
|
+
strokeColor (Color, optional) \u2014 Shorthand \u2014 sets a single solid stroke (auto-binds to matching variable/style)
|
|
635
|
+
strokeStyleName (string, optional) \u2014 Paint style name for stroke
|
|
636
|
+
strokeVariableName (string, optional) \u2014 Color variable by name for stroke
|
|
637
|
+
strokeWeight (string, optional) \u2014 All sides (number) or variable name (string). Per-side: strokeTopWeight, strokeBottomWeight, strokeLeftWeight, strokeRightWeight.
|
|
638
|
+
strokeTopWeight (string, optional)
|
|
639
|
+
strokeBottomWeight (string, optional)
|
|
640
|
+
strokeLeftWeight (string, optional)
|
|
641
|
+
strokeRightWeight (string, optional)
|
|
642
|
+
strokeAlign (INSIDE | OUTSIDE | CENTER, optional) \u2014 Stroke position (default: INSIDE)
|
|
643
|
+
cornerRadius (string, optional) \u2014 All corners (number) or variable name (string). Per-corner: topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius.
|
|
644
|
+
topLeftRadius (string, optional)
|
|
645
|
+
topRightRadius (string, optional)
|
|
646
|
+
bottomRightRadius (string, optional)
|
|
647
|
+
bottomLeftRadius (string, optional)
|
|
648
|
+
layoutMode (NONE | HORIZONTAL | VERTICAL, optional) \u2014 Layout direction (default: auto \u2014 NONE when width+height set, otherwise inferred from layout props)
|
|
649
|
+
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.
|
|
650
|
+
padding (string, optional) \u2014 All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft.
|
|
651
|
+
paddingTop (string, optional)
|
|
652
|
+
paddingRight (string, optional)
|
|
653
|
+
paddingBottom (string, optional)
|
|
654
|
+
paddingLeft (string, optional)
|
|
655
|
+
primaryAxisAlignItems (MIN | MAX | CENTER | SPACE_BETWEEN, optional)
|
|
656
|
+
counterAxisAlignItems (MIN | MAX | CENTER | BASELINE, optional)
|
|
657
|
+
itemSpacing (string, optional) \u2014 Spacing between children (number or variable name string, default: 0)
|
|
658
|
+
counterAxisSpacing (string, optional) \u2014 Gap between wrapped rows (requires layoutWrap: WRAP)
|
|
659
|
+
strokesIncludedInLayout (boolean, optional) \u2014 Include stroke width in layout measurements (default: false)
|
|
660
|
+
overflowDirection (NONE | HORIZONTAL | VERTICAL | BOTH, optional) \u2014 Scroll overflow in prototype (default: NONE)
|
|
661
|
+
layoutPositioning (AUTO | ABSOLUTE, optional) \u2014 ABSOLUTE = floating inside auto-layout parent
|
|
662
|
+
layoutSizingHorizontal (FIXED | HUG | FILL, optional)
|
|
663
|
+
layoutSizingVertical (FIXED | HUG | FILL, optional)
|
|
664
|
+
minWidth (number, optional) \u2014 Min width for responsive auto-layout
|
|
665
|
+
maxWidth (number, optional) \u2014 Max width for responsive auto-layout
|
|
666
|
+
minHeight (number, optional) \u2014 Min height for responsive auto-layout
|
|
667
|
+
maxHeight (number, optional) \u2014 Max height for responsive auto-layout
|
|
668
|
+
annotations (array, optional) \u2014 Set annotations \u2014 [{label?, labelMarkdown?, properties?, categoryId?}]. Properties validated per node type.
|
|
669
|
+
componentId (string, optional) \u2014 Owning component ID. Optional \u2014 auto-resolved from parentId by walking up ancestors.`,
|
|
613
670
|
"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',
|
|
614
671
|
"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)"
|
|
615
672
|
}
|
|
@@ -892,7 +949,7 @@ Methods:
|
|
|
892
949
|
// "fixed-in-autolayout" \u2014 FIXED-size children in auto-layout parents [heuristic]
|
|
893
950
|
// "unbounded-hug" \u2014 HUG on both axes [unsafe; short leaf text\u2192style]
|
|
894
951
|
// "hug-cross-axis" \u2014 HUG on cross-axis of constrained parent [heuristic; leaf nodes\u2192style]
|
|
895
|
-
// "empty-container" \u2014 empty frames [style]
|
|
952
|
+
// "empty-container" \u2014 empty frames, excludes SLOT nodes [style]
|
|
896
953
|
// Token rules [token]:
|
|
897
954
|
// "hardcoded-color" \u2014 colors not using styles or variables [heuristic]
|
|
898
955
|
// "hardcoded-token" \u2014 numeric values not bound to FLOAT variable [heuristic]
|
|
@@ -1158,7 +1215,7 @@ Params:
|
|
|
1158
1215
|
}
|
|
1159
1216
|
};
|
|
1160
1217
|
var helpTopics = {
|
|
1161
|
-
"missing_tools": '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
1218
|
+
"missing_tools": '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma@latest", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
1162
1219
|
};
|
|
1163
1220
|
var allEndpointNames = Object.keys(helpEndpoints);
|
|
1164
1221
|
var allTopicNames = Object.keys(helpTopics);
|
|
@@ -1724,7 +1781,7 @@ var tools = [
|
|
|
1724
1781
|
},
|
|
1725
1782
|
{
|
|
1726
1783
|
name: "frames",
|
|
1727
|
-
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 \u2014 produces a same-type copy (frame\u2192frame, instance\u2192instance, component\u2192component). Instance clones reference the same source component; they do not duplicate the component definition.\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 commit (id) \u2192 { results: {id}[] } // Commit a staged node \u2014 unwraps from [STAGED] container into the original target location.\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).',
|
|
1784
|
+
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 \u2014 produces a same-type copy (frame\u2192frame, instance\u2192instance, component\u2192component). Instance clones reference the same source component; they do not duplicate the component definition.\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|slot, items: (FrameItem | AutoLayoutItem | SectionItem | RectangleItem | EllipseItem | LineItem | GroupItem | BooleanOperationItem | SvgItem | SlotItem)[]) \u2192 { results: {id}[] } // Create frame-like containers\n commit (id) \u2192 { results: {id}[] } // Commit a staged node \u2014 unwraps from [STAGED] container into the original target location.\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).',
|
|
1728
1785
|
schema: (caps2) => filterMethodsByTier({
|
|
1729
1786
|
method: z3.enum(["get", "list", "update", "delete", "clone", "audit", "reparent", "create", "commit", "export", "help"]),
|
|
1730
1787
|
id: z3.string().optional().describe("Node ID"),
|
|
@@ -1745,7 +1802,7 @@ var tools = [
|
|
|
1745
1802
|
maxFindings: z3.coerce.number().optional().describe("Max findings (default: 50)"),
|
|
1746
1803
|
minSeverity: z3.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."),
|
|
1747
1804
|
skipInstances: flexBool(z3.boolean()).optional().describe("Skip instance internals \u2014 findings inside instances are owned by the component (default: true)"),
|
|
1748
|
-
type: z3.enum(["frame", "auto_layout", "section", "rectangle", "ellipse", "line", "group", "boolean_operation", "svg"]).optional().describe("Discriminant for create method"),
|
|
1805
|
+
type: z3.enum(["frame", "auto_layout", "section", "rectangle", "ellipse", "line", "group", "boolean_operation", "svg", "slot"]).optional().describe("Discriminant for create method"),
|
|
1749
1806
|
format: z3.enum(["PNG", "JPG", "SVG", "SVG_STRING", "PDF"]).optional().describe("Export format (default: PNG). SVG_STRING returns raw SVG text."),
|
|
1750
1807
|
scale: z3.coerce.number().optional().describe("Export scale (default: 1, only for PNG/JPG)"),
|
|
1751
1808
|
topic: z3.string().optional().describe('Help topic \u2014 method name for endpoint help, e.g. "create"')
|
|
@@ -1978,6 +2035,63 @@ var tools = [
|
|
|
1978
2035
|
parentId: z3.string().optional().describe("Parent node ID. Omit to place at current page root."),
|
|
1979
2036
|
x: z3.coerce.number().optional().describe("X position (default: 0)"),
|
|
1980
2037
|
y: z3.coerce.number().optional().describe("Y position (default: 0)")
|
|
2038
|
+
}).passthrough(),
|
|
2039
|
+
"slot": z3.object({
|
|
2040
|
+
name: z3.string().optional().describe("Node name"),
|
|
2041
|
+
parentId: z3.string().optional().describe("Parent node ID inside the owning component. Required unless componentId is provided."),
|
|
2042
|
+
x: z3.coerce.number().optional().describe("X position (default: 0)"),
|
|
2043
|
+
y: z3.coerce.number().optional().describe("Y position (default: 0)"),
|
|
2044
|
+
width: z3.coerce.number().optional().describe("Width in px (omit to shrink-to-content via HUG)"),
|
|
2045
|
+
height: z3.coerce.number().optional().describe("Height in px (omit to shrink-to-content via HUG)"),
|
|
2046
|
+
rotation: z3.coerce.number().optional().describe("Rotation in degrees (0-360)"),
|
|
2047
|
+
visible: flexBool(z3.boolean()).optional().describe("Show/hide (default true)"),
|
|
2048
|
+
locked: flexBool(z3.boolean()).optional().describe("Lock/unlock (default false)"),
|
|
2049
|
+
opacity: token.optional().describe("Opacity (0-1) or variable name"),
|
|
2050
|
+
blendMode: z3.enum(["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(),
|
|
2051
|
+
effectStyleName: z3.string().optional().describe("Effect style name (e.g. 'Shadow/Card') for shadows, blurs"),
|
|
2052
|
+
fills: z3.array(z3.record(z3.string(), z3.unknown())).optional().describe("Fill paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] for transparent. Primary way to set fills."),
|
|
2053
|
+
fillColor: colorRgba.optional().describe("Shorthand \u2014 sets a single solid fill (auto-binds to matching variable/style)"),
|
|
2054
|
+
fillStyleName: z3.string().optional().describe("Paint style name for fill"),
|
|
2055
|
+
fillVariableName: z3.string().optional().describe("Color variable by name e.g. 'bg/primary'"),
|
|
2056
|
+
imageUrl: z3.string().optional().describe("Image source \u2014 'pexel:<id>' for Pexels photos, a public URL, or a local file path. SVGs are inserted as vectors; raster images become IMAGE fills."),
|
|
2057
|
+
imageScaleMode: z3.enum(["FILL", "FIT", "CROP", "TILE"]).optional().describe("How the image is scaled within the frame (default: FILL)"),
|
|
2058
|
+
strokes: z3.array(z3.record(z3.string(), z3.unknown())).optional().describe("Stroke paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] to clear. Primary way to set strokes."),
|
|
2059
|
+
strokeColor: colorRgba.optional().describe("Shorthand \u2014 sets a single solid stroke (auto-binds to matching variable/style)"),
|
|
2060
|
+
strokeStyleName: z3.string().optional().describe("Paint style name for stroke"),
|
|
2061
|
+
strokeVariableName: z3.string().optional().describe("Color variable by name for stroke"),
|
|
2062
|
+
strokeWeight: token.optional().describe("All sides (number) or variable name (string). Per-side: strokeTopWeight, strokeBottomWeight, strokeLeftWeight, strokeRightWeight."),
|
|
2063
|
+
strokeTopWeight: token.optional(),
|
|
2064
|
+
strokeBottomWeight: token.optional(),
|
|
2065
|
+
strokeLeftWeight: token.optional(),
|
|
2066
|
+
strokeRightWeight: token.optional(),
|
|
2067
|
+
strokeAlign: z3.enum(["INSIDE", "OUTSIDE", "CENTER"]).optional().describe("Stroke position (default: INSIDE)"),
|
|
2068
|
+
cornerRadius: token.optional().describe("All corners (number) or variable name (string). Per-corner: topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius."),
|
|
2069
|
+
topLeftRadius: token.optional(),
|
|
2070
|
+
topRightRadius: token.optional(),
|
|
2071
|
+
bottomRightRadius: token.optional(),
|
|
2072
|
+
bottomLeftRadius: token.optional(),
|
|
2073
|
+
layoutMode: z3.enum(["NONE", "HORIZONTAL", "VERTICAL"]).optional().describe("Layout direction (default: auto \u2014 NONE when width+height set, otherwise inferred from layout props)"),
|
|
2074
|
+
layoutWrap: z3.enum(["NO_WRAP", "WRAP"]).optional().describe("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."),
|
|
2075
|
+
padding: token.optional().describe("All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft."),
|
|
2076
|
+
paddingTop: token.optional(),
|
|
2077
|
+
paddingRight: token.optional(),
|
|
2078
|
+
paddingBottom: token.optional(),
|
|
2079
|
+
paddingLeft: token.optional(),
|
|
2080
|
+
primaryAxisAlignItems: z3.enum(["MIN", "MAX", "CENTER", "SPACE_BETWEEN"]).optional(),
|
|
2081
|
+
counterAxisAlignItems: z3.enum(["MIN", "MAX", "CENTER", "BASELINE"]).optional(),
|
|
2082
|
+
itemSpacing: token.optional().describe("Spacing between children (number or variable name string, default: 0)"),
|
|
2083
|
+
counterAxisSpacing: token.optional().describe("Gap between wrapped rows (requires layoutWrap: WRAP)"),
|
|
2084
|
+
strokesIncludedInLayout: flexBool(z3.boolean()).optional().describe("Include stroke width in layout measurements (default: false)"),
|
|
2085
|
+
overflowDirection: z3.enum(["NONE", "HORIZONTAL", "VERTICAL", "BOTH"]).optional().describe("Scroll overflow in prototype (default: NONE)"),
|
|
2086
|
+
layoutPositioning: z3.enum(["AUTO", "ABSOLUTE"]).optional().describe("ABSOLUTE = floating inside auto-layout parent"),
|
|
2087
|
+
layoutSizingHorizontal: z3.enum(["FIXED", "HUG", "FILL"]).optional(),
|
|
2088
|
+
layoutSizingVertical: z3.enum(["FIXED", "HUG", "FILL"]).optional(),
|
|
2089
|
+
minWidth: z3.coerce.number().optional().describe("Min width for responsive auto-layout"),
|
|
2090
|
+
maxWidth: z3.coerce.number().optional().describe("Max width for responsive auto-layout"),
|
|
2091
|
+
minHeight: z3.coerce.number().optional().describe("Min height for responsive auto-layout"),
|
|
2092
|
+
maxHeight: z3.coerce.number().optional().describe("Max height for responsive auto-layout"),
|
|
2093
|
+
annotations: flexJson(z3.array(z3.record(z3.string(), z3.unknown()))).optional().describe("Set annotations \u2014 [{label?, labelMarkdown?, properties?, categoryId?}]. Properties validated per node type."),
|
|
2094
|
+
componentId: z3.string().optional().describe("Owning component ID. Optional \u2014 auto-resolved from parentId by walking up ancestors.")
|
|
1981
2095
|
}).passthrough()
|
|
1982
2096
|
};
|
|
1983
2097
|
const s = params.type && schemas[params.type];
|
|
@@ -3010,7 +3124,7 @@ var guidelinesList = [
|
|
|
3010
3124
|
}
|
|
3011
3125
|
];
|
|
3012
3126
|
var guidelinesContent = {
|
|
3013
|
-
"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- 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.',
|
|
3127
|
+
"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- 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## Slots\n\nSlots are placeholder containers inside components that instance users can fill with custom content.\n\n- Create at component root: `frames(method:"create", type:"slot", items:[{parentId:"<comp_id>", name:"Content"}])`\n- Create nested inside a frame within a component: `frames(method:"create", type:"slot", items:[{parentId:"<frame_id>", name:"Content"}])`\n- In instances, add content by using the slot\'s ID as `parentId` on any create/reparent call\n- Empty slots are normal \u2014 they don\'t trigger lint warnings\n\n## Checking\n\nRun `components(method:"audit", id)` \u2014 checks both lint rules and property bindings in one call.',
|
|
3014
3128
|
"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).',
|
|
3015
3129
|
"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## Wrapping Layouts (layoutWrap)\n\n`layoutWrap: WRAP` enables children to flow into new rows when they exceed the container width \u2014 like CSS `flex-wrap`. This only works with **HORIZONTAL** auto-layout. Figma does not support wrap on VERTICAL layouts.\n\n**When to use wrap:**\n- Card grids with a fixed number of columns at a known width\n- Tag/chip collections where items flow into multiple rows\n- Any layout where items should reflow based on available width\n\n**Horizontal wrap pattern:**\n```\nframes.create(type: "auto_layout", layoutMode: "HORIZONTAL", layoutWrap: "WRAP",\n itemSpacing: "space/16", counterAxisSpacing: "space/16")\n```\nChildren use FIXED width to control column count. `counterAxisSpacing` sets the gap between wrapped rows.\n\n**Vertical grid alternative:**\nSince VERTICAL layouts cannot wrap, build column-based grids by nesting VERTICAL columns inside a HORIZONTAL parent:\n```\nouter (HORIZONTAL, itemSpacing: 20, FILL width)\n col-1 (VERTICAL, FILL width, HUG height, itemSpacing: 20)\n col-2 (VERTICAL, FILL width, HUG height, itemSpacing: 20)\n col-3 (VERTICAL, FILL width, HUG height, itemSpacing: 20)\n```\nEach column gets equal width via FILL. Reparent items into columns for column-first ordering. This handles variable card heights per column independently.\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',
|
|
3016
3130
|
"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.',
|
|
@@ -3117,7 +3231,7 @@ function registerPrompts(server2) {
|
|
|
3117
3231
|
role: "assistant",
|
|
3118
3232
|
content: {
|
|
3119
3233
|
type: "text",
|
|
3120
|
-
text: '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
3234
|
+
text: '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma@latest", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
3121
3235
|
}
|
|
3122
3236
|
}],
|
|
3123
3237
|
description: "Why create or edit tools are missing and how to fix it"
|
|
@@ -35,6 +35,7 @@ __export(guards_exports, {
|
|
|
35
35
|
framesCreateLine: () => framesCreateLine,
|
|
36
36
|
framesCreateRectangle: () => framesCreateRectangle,
|
|
37
37
|
framesCreateSection: () => framesCreateSection,
|
|
38
|
+
framesCreateSlot: () => framesCreateSlot,
|
|
38
39
|
framesCreateSvg: () => framesCreateSvg,
|
|
39
40
|
instancesCreate: () => instancesCreate,
|
|
40
41
|
instancesDetach: () => instancesDetach,
|
|
@@ -499,6 +500,63 @@ var framesCreateSvg = /* @__PURE__ */ new Set([
|
|
|
499
500
|
"x",
|
|
500
501
|
"y"
|
|
501
502
|
]);
|
|
503
|
+
var framesCreateSlot = /* @__PURE__ */ new Set([
|
|
504
|
+
"annotations",
|
|
505
|
+
"blendMode",
|
|
506
|
+
"bottomLeftRadius",
|
|
507
|
+
"bottomRightRadius",
|
|
508
|
+
"componentId",
|
|
509
|
+
"cornerRadius",
|
|
510
|
+
"counterAxisAlignItems",
|
|
511
|
+
"counterAxisSpacing",
|
|
512
|
+
"effectStyleName",
|
|
513
|
+
"fillColor",
|
|
514
|
+
"fillStyleName",
|
|
515
|
+
"fillVariableName",
|
|
516
|
+
"fills",
|
|
517
|
+
"height",
|
|
518
|
+
"imageScaleMode",
|
|
519
|
+
"imageUrl",
|
|
520
|
+
"itemSpacing",
|
|
521
|
+
"layoutMode",
|
|
522
|
+
"layoutPositioning",
|
|
523
|
+
"layoutSizingHorizontal",
|
|
524
|
+
"layoutSizingVertical",
|
|
525
|
+
"layoutWrap",
|
|
526
|
+
"locked",
|
|
527
|
+
"maxHeight",
|
|
528
|
+
"maxWidth",
|
|
529
|
+
"minHeight",
|
|
530
|
+
"minWidth",
|
|
531
|
+
"name",
|
|
532
|
+
"opacity",
|
|
533
|
+
"overflowDirection",
|
|
534
|
+
"padding",
|
|
535
|
+
"paddingBottom",
|
|
536
|
+
"paddingLeft",
|
|
537
|
+
"paddingRight",
|
|
538
|
+
"paddingTop",
|
|
539
|
+
"parentId",
|
|
540
|
+
"primaryAxisAlignItems",
|
|
541
|
+
"rotation",
|
|
542
|
+
"strokeAlign",
|
|
543
|
+
"strokeBottomWeight",
|
|
544
|
+
"strokeColor",
|
|
545
|
+
"strokeLeftWeight",
|
|
546
|
+
"strokeRightWeight",
|
|
547
|
+
"strokeStyleName",
|
|
548
|
+
"strokeTopWeight",
|
|
549
|
+
"strokeVariableName",
|
|
550
|
+
"strokeWeight",
|
|
551
|
+
"strokes",
|
|
552
|
+
"strokesIncludedInLayout",
|
|
553
|
+
"topLeftRadius",
|
|
554
|
+
"topRightRadius",
|
|
555
|
+
"visible",
|
|
556
|
+
"width",
|
|
557
|
+
"x",
|
|
558
|
+
"y"
|
|
559
|
+
]);
|
|
502
560
|
var instancesCreate = /* @__PURE__ */ new Set([
|
|
503
561
|
"blendMode",
|
|
504
562
|
"componentId",
|
|
@@ -853,6 +911,7 @@ var mixinVectorStyleParams = /* @__PURE__ */ new Set(["fillStyleName", "fillVari
|
|
|
853
911
|
framesCreateLine,
|
|
854
912
|
framesCreateRectangle,
|
|
855
913
|
framesCreateSection,
|
|
914
|
+
framesCreateSlot,
|
|
856
915
|
framesCreateSvg,
|
|
857
916
|
instancesCreate,
|
|
858
917
|
instancesDetach,
|
|
@@ -40,6 +40,8 @@ declare const framesCreateGroup: ReadonlySet<string>;
|
|
|
40
40
|
declare const framesCreateBooleanOperation: ReadonlySet<string>;
|
|
41
41
|
/** frames create type="svg" */
|
|
42
42
|
declare const framesCreateSvg: ReadonlySet<string>;
|
|
43
|
+
/** frames create type="slot" */
|
|
44
|
+
declare const framesCreateSlot: ReadonlySet<string>;
|
|
43
45
|
/** instances.create item params */
|
|
44
46
|
declare const instancesCreate: ReadonlySet<string>;
|
|
45
47
|
/** instances.update item params */
|
|
@@ -111,4 +113,4 @@ declare const mixinTextParams: ReadonlySet<string>;
|
|
|
111
113
|
/** vector_style_params */
|
|
112
114
|
declare const mixinVectorStyleParams: ReadonlySet<string>;
|
|
113
115
|
|
|
114
|
-
export { annotationsAdd, annotationsGet, annotationsRemove, annotationsSet, componentsCreateComponent, componentsCreateFromNode, componentsCreateVariantSet, componentsUpdate, framesCreateAutoLayout, framesCreateBooleanOperation, framesCreateEllipse, framesCreateFrame, framesCreateGroup, framesCreateLine, framesCreateRectangle, framesCreateSection, framesCreateSvg, instancesCreate, instancesDetach, instancesResetOverrides, instancesSwap, instancesUpdate, lintFix, mixinAutoLayoutParams, mixinBlendParams, mixinCornerParams, mixinFillParams, mixinFrameParams, mixinGeometryParams, mixinSceneParams, mixinSizingParams, mixinStrokeParams, mixinTextParams, mixinVectorStyleParams, nodeClone, nodeDelete, nodeReparent, nodeUpdate, prototypingAdd, stylesCreateEffect, stylesCreateGrid, stylesCreatePaint, stylesCreateText, stylesDelete, stylesUpdate, textCreate, textSetContent, variableCollectionsAddMode, variableCollectionsCreate, variableCollectionsDelete, variableCollectionsRemoveMode, variableCollectionsRenameMode, variableCollectionsUpdate, variablesCreate, variablesDelete, variablesUpdate };
|
|
116
|
+
export { annotationsAdd, annotationsGet, annotationsRemove, annotationsSet, componentsCreateComponent, componentsCreateFromNode, componentsCreateVariantSet, componentsUpdate, framesCreateAutoLayout, framesCreateBooleanOperation, framesCreateEllipse, framesCreateFrame, framesCreateGroup, framesCreateLine, framesCreateRectangle, framesCreateSection, framesCreateSlot, framesCreateSvg, instancesCreate, instancesDetach, instancesResetOverrides, instancesSwap, instancesUpdate, lintFix, mixinAutoLayoutParams, mixinBlendParams, mixinCornerParams, mixinFillParams, mixinFrameParams, mixinGeometryParams, mixinSceneParams, mixinSizingParams, mixinStrokeParams, mixinTextParams, mixinVectorStyleParams, nodeClone, nodeDelete, nodeReparent, nodeUpdate, prototypingAdd, stylesCreateEffect, stylesCreateGrid, stylesCreatePaint, stylesCreateText, stylesDelete, stylesUpdate, textCreate, textSetContent, variableCollectionsAddMode, variableCollectionsCreate, variableCollectionsDelete, variableCollectionsRemoveMode, variableCollectionsRenameMode, variableCollectionsUpdate, variablesCreate, variablesDelete, variablesUpdate };
|
|
@@ -40,6 +40,8 @@ declare const framesCreateGroup: ReadonlySet<string>;
|
|
|
40
40
|
declare const framesCreateBooleanOperation: ReadonlySet<string>;
|
|
41
41
|
/** frames create type="svg" */
|
|
42
42
|
declare const framesCreateSvg: ReadonlySet<string>;
|
|
43
|
+
/** frames create type="slot" */
|
|
44
|
+
declare const framesCreateSlot: ReadonlySet<string>;
|
|
43
45
|
/** instances.create item params */
|
|
44
46
|
declare const instancesCreate: ReadonlySet<string>;
|
|
45
47
|
/** instances.update item params */
|
|
@@ -111,4 +113,4 @@ declare const mixinTextParams: ReadonlySet<string>;
|
|
|
111
113
|
/** vector_style_params */
|
|
112
114
|
declare const mixinVectorStyleParams: ReadonlySet<string>;
|
|
113
115
|
|
|
114
|
-
export { annotationsAdd, annotationsGet, annotationsRemove, annotationsSet, componentsCreateComponent, componentsCreateFromNode, componentsCreateVariantSet, componentsUpdate, framesCreateAutoLayout, framesCreateBooleanOperation, framesCreateEllipse, framesCreateFrame, framesCreateGroup, framesCreateLine, framesCreateRectangle, framesCreateSection, framesCreateSvg, instancesCreate, instancesDetach, instancesResetOverrides, instancesSwap, instancesUpdate, lintFix, mixinAutoLayoutParams, mixinBlendParams, mixinCornerParams, mixinFillParams, mixinFrameParams, mixinGeometryParams, mixinSceneParams, mixinSizingParams, mixinStrokeParams, mixinTextParams, mixinVectorStyleParams, nodeClone, nodeDelete, nodeReparent, nodeUpdate, prototypingAdd, stylesCreateEffect, stylesCreateGrid, stylesCreatePaint, stylesCreateText, stylesDelete, stylesUpdate, textCreate, textSetContent, variableCollectionsAddMode, variableCollectionsCreate, variableCollectionsDelete, variableCollectionsRemoveMode, variableCollectionsRenameMode, variableCollectionsUpdate, variablesCreate, variablesDelete, variablesUpdate };
|
|
116
|
+
export { annotationsAdd, annotationsGet, annotationsRemove, annotationsSet, componentsCreateComponent, componentsCreateFromNode, componentsCreateVariantSet, componentsUpdate, framesCreateAutoLayout, framesCreateBooleanOperation, framesCreateEllipse, framesCreateFrame, framesCreateGroup, framesCreateLine, framesCreateRectangle, framesCreateSection, framesCreateSlot, framesCreateSvg, instancesCreate, instancesDetach, instancesResetOverrides, instancesSwap, instancesUpdate, lintFix, mixinAutoLayoutParams, mixinBlendParams, mixinCornerParams, mixinFillParams, mixinFrameParams, mixinGeometryParams, mixinSceneParams, mixinSizingParams, mixinStrokeParams, mixinTextParams, mixinVectorStyleParams, nodeClone, nodeDelete, nodeReparent, nodeUpdate, prototypingAdd, stylesCreateEffect, stylesCreateGrid, stylesCreatePaint, stylesCreateText, stylesDelete, stylesUpdate, textCreate, textSetContent, variableCollectionsAddMode, variableCollectionsCreate, variableCollectionsDelete, variableCollectionsRemoveMode, variableCollectionsRenameMode, variableCollectionsUpdate, variablesCreate, variablesDelete, variablesUpdate };
|
|
@@ -421,6 +421,63 @@ var framesCreateSvg = /* @__PURE__ */ new Set([
|
|
|
421
421
|
"x",
|
|
422
422
|
"y"
|
|
423
423
|
]);
|
|
424
|
+
var framesCreateSlot = /* @__PURE__ */ new Set([
|
|
425
|
+
"annotations",
|
|
426
|
+
"blendMode",
|
|
427
|
+
"bottomLeftRadius",
|
|
428
|
+
"bottomRightRadius",
|
|
429
|
+
"componentId",
|
|
430
|
+
"cornerRadius",
|
|
431
|
+
"counterAxisAlignItems",
|
|
432
|
+
"counterAxisSpacing",
|
|
433
|
+
"effectStyleName",
|
|
434
|
+
"fillColor",
|
|
435
|
+
"fillStyleName",
|
|
436
|
+
"fillVariableName",
|
|
437
|
+
"fills",
|
|
438
|
+
"height",
|
|
439
|
+
"imageScaleMode",
|
|
440
|
+
"imageUrl",
|
|
441
|
+
"itemSpacing",
|
|
442
|
+
"layoutMode",
|
|
443
|
+
"layoutPositioning",
|
|
444
|
+
"layoutSizingHorizontal",
|
|
445
|
+
"layoutSizingVertical",
|
|
446
|
+
"layoutWrap",
|
|
447
|
+
"locked",
|
|
448
|
+
"maxHeight",
|
|
449
|
+
"maxWidth",
|
|
450
|
+
"minHeight",
|
|
451
|
+
"minWidth",
|
|
452
|
+
"name",
|
|
453
|
+
"opacity",
|
|
454
|
+
"overflowDirection",
|
|
455
|
+
"padding",
|
|
456
|
+
"paddingBottom",
|
|
457
|
+
"paddingLeft",
|
|
458
|
+
"paddingRight",
|
|
459
|
+
"paddingTop",
|
|
460
|
+
"parentId",
|
|
461
|
+
"primaryAxisAlignItems",
|
|
462
|
+
"rotation",
|
|
463
|
+
"strokeAlign",
|
|
464
|
+
"strokeBottomWeight",
|
|
465
|
+
"strokeColor",
|
|
466
|
+
"strokeLeftWeight",
|
|
467
|
+
"strokeRightWeight",
|
|
468
|
+
"strokeStyleName",
|
|
469
|
+
"strokeTopWeight",
|
|
470
|
+
"strokeVariableName",
|
|
471
|
+
"strokeWeight",
|
|
472
|
+
"strokes",
|
|
473
|
+
"strokesIncludedInLayout",
|
|
474
|
+
"topLeftRadius",
|
|
475
|
+
"topRightRadius",
|
|
476
|
+
"visible",
|
|
477
|
+
"width",
|
|
478
|
+
"x",
|
|
479
|
+
"y"
|
|
480
|
+
]);
|
|
424
481
|
var instancesCreate = /* @__PURE__ */ new Set([
|
|
425
482
|
"blendMode",
|
|
426
483
|
"componentId",
|
|
@@ -774,6 +831,7 @@ export {
|
|
|
774
831
|
framesCreateLine,
|
|
775
832
|
framesCreateRectangle,
|
|
776
833
|
framesCreateSection,
|
|
834
|
+
framesCreateSlot,
|
|
777
835
|
framesCreateSvg,
|
|
778
836
|
instancesCreate,
|
|
779
837
|
instancesDetach,
|
package/dist/tools/registry.cjs
CHANGED
|
@@ -399,7 +399,7 @@ Create frame-like containers
|
|
|
399
399
|
|
|
400
400
|
Example: frames(method:"create", type:"auto_layout", layoutMode:"VERTICAL", itemSpacing:16, padding:24)
|
|
401
401
|
|
|
402
|
-
Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line | group | boolean_operation | svg)
|
|
402
|
+
Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line | group | boolean_operation | svg | slot)
|
|
403
403
|
|
|
404
404
|
## frame \u2014 General-purpose frame \u2014 shrinks to content by default, static when width+height given
|
|
405
405
|
name (string, optional) \u2014 Node name
|
|
@@ -618,7 +618,64 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
|
|
|
618
618
|
name (string, optional) \u2014 Layer name (default: 'SVG')
|
|
619
619
|
parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
|
|
620
620
|
x (number, optional) \u2014 X position (default: 0)
|
|
621
|
-
y (number, optional) \u2014 Y position (default: 0)
|
|
621
|
+
y (number, optional) \u2014 Y position (default: 0)
|
|
622
|
+
|
|
623
|
+
## slot \u2014 Create a slot inside a component. Slots are placeholder containers that instance users fill with content. Defaults to VERTICAL auto-layout with FILL/HUG sizing \u2014 ready to receive children. Accepts all frame layout properties.
|
|
624
|
+
name (string, optional) \u2014 Node name
|
|
625
|
+
parentId (string, optional) \u2014 Parent node ID inside the owning component. Required unless componentId is provided.
|
|
626
|
+
x (number, optional) \u2014 X position (default: 0)
|
|
627
|
+
y (number, optional) \u2014 Y position (default: 0)
|
|
628
|
+
width (number, optional) \u2014 Width in px (omit to shrink-to-content via HUG)
|
|
629
|
+
height (number, optional) \u2014 Height in px (omit to shrink-to-content via HUG)
|
|
630
|
+
rotation (number, optional) \u2014 Rotation in degrees (0-360)
|
|
631
|
+
visible (boolean, optional) \u2014 Show/hide (default true)
|
|
632
|
+
locked (boolean, optional) \u2014 Lock/unlock (default false)
|
|
633
|
+
opacity (string, optional) \u2014 Opacity (0-1) or variable name
|
|
634
|
+
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)
|
|
635
|
+
effectStyleName (string, optional) \u2014 Effect style name (e.g. 'Shadow/Card') for shadows, blurs
|
|
636
|
+
fills (array, optional) \u2014 Fill paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] for transparent. Primary way to set fills.
|
|
637
|
+
fillColor (Color, optional) \u2014 Shorthand \u2014 sets a single solid fill (auto-binds to matching variable/style)
|
|
638
|
+
fillStyleName (string, optional) \u2014 Paint style name for fill
|
|
639
|
+
fillVariableName (string, optional) \u2014 Color variable by name e.g. 'bg/primary'
|
|
640
|
+
imageUrl (string, optional) \u2014 Image source \u2014 'pexel:<id>' for Pexels photos, a public URL, or a local file path. SVGs are inserted as vectors; raster images become IMAGE fills.
|
|
641
|
+
imageScaleMode (FILL | FIT | CROP | TILE, optional) \u2014 How the image is scaled within the frame (default: FILL)
|
|
642
|
+
strokes (array, optional) \u2014 Stroke paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] to clear. Primary way to set strokes.
|
|
643
|
+
strokeColor (Color, optional) \u2014 Shorthand \u2014 sets a single solid stroke (auto-binds to matching variable/style)
|
|
644
|
+
strokeStyleName (string, optional) \u2014 Paint style name for stroke
|
|
645
|
+
strokeVariableName (string, optional) \u2014 Color variable by name for stroke
|
|
646
|
+
strokeWeight (string, optional) \u2014 All sides (number) or variable name (string). Per-side: strokeTopWeight, strokeBottomWeight, strokeLeftWeight, strokeRightWeight.
|
|
647
|
+
strokeTopWeight (string, optional)
|
|
648
|
+
strokeBottomWeight (string, optional)
|
|
649
|
+
strokeLeftWeight (string, optional)
|
|
650
|
+
strokeRightWeight (string, optional)
|
|
651
|
+
strokeAlign (INSIDE | OUTSIDE | CENTER, optional) \u2014 Stroke position (default: INSIDE)
|
|
652
|
+
cornerRadius (string, optional) \u2014 All corners (number) or variable name (string). Per-corner: topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius.
|
|
653
|
+
topLeftRadius (string, optional)
|
|
654
|
+
topRightRadius (string, optional)
|
|
655
|
+
bottomRightRadius (string, optional)
|
|
656
|
+
bottomLeftRadius (string, optional)
|
|
657
|
+
layoutMode (NONE | HORIZONTAL | VERTICAL, optional) \u2014 Layout direction (default: auto \u2014 NONE when width+height set, otherwise inferred from layout props)
|
|
658
|
+
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.
|
|
659
|
+
padding (string, optional) \u2014 All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft.
|
|
660
|
+
paddingTop (string, optional)
|
|
661
|
+
paddingRight (string, optional)
|
|
662
|
+
paddingBottom (string, optional)
|
|
663
|
+
paddingLeft (string, optional)
|
|
664
|
+
primaryAxisAlignItems (MIN | MAX | CENTER | SPACE_BETWEEN, optional)
|
|
665
|
+
counterAxisAlignItems (MIN | MAX | CENTER | BASELINE, optional)
|
|
666
|
+
itemSpacing (string, optional) \u2014 Spacing between children (number or variable name string, default: 0)
|
|
667
|
+
counterAxisSpacing (string, optional) \u2014 Gap between wrapped rows (requires layoutWrap: WRAP)
|
|
668
|
+
strokesIncludedInLayout (boolean, optional) \u2014 Include stroke width in layout measurements (default: false)
|
|
669
|
+
overflowDirection (NONE | HORIZONTAL | VERTICAL | BOTH, optional) \u2014 Scroll overflow in prototype (default: NONE)
|
|
670
|
+
layoutPositioning (AUTO | ABSOLUTE, optional) \u2014 ABSOLUTE = floating inside auto-layout parent
|
|
671
|
+
layoutSizingHorizontal (FIXED | HUG | FILL, optional)
|
|
672
|
+
layoutSizingVertical (FIXED | HUG | FILL, optional)
|
|
673
|
+
minWidth (number, optional) \u2014 Min width for responsive auto-layout
|
|
674
|
+
maxWidth (number, optional) \u2014 Max width for responsive auto-layout
|
|
675
|
+
minHeight (number, optional) \u2014 Min height for responsive auto-layout
|
|
676
|
+
maxHeight (number, optional) \u2014 Max height for responsive auto-layout
|
|
677
|
+
annotations (array, optional) \u2014 Set annotations \u2014 [{label?, labelMarkdown?, properties?, categoryId?}]. Properties validated per node type.
|
|
678
|
+
componentId (string, optional) \u2014 Owning component ID. Optional \u2014 auto-resolved from parentId by walking up ancestors.`,
|
|
622
679
|
"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',
|
|
623
680
|
"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)"
|
|
624
681
|
}
|
|
@@ -901,7 +958,7 @@ Methods:
|
|
|
901
958
|
// "fixed-in-autolayout" \u2014 FIXED-size children in auto-layout parents [heuristic]
|
|
902
959
|
// "unbounded-hug" \u2014 HUG on both axes [unsafe; short leaf text\u2192style]
|
|
903
960
|
// "hug-cross-axis" \u2014 HUG on cross-axis of constrained parent [heuristic; leaf nodes\u2192style]
|
|
904
|
-
// "empty-container" \u2014 empty frames [style]
|
|
961
|
+
// "empty-container" \u2014 empty frames, excludes SLOT nodes [style]
|
|
905
962
|
// Token rules [token]:
|
|
906
963
|
// "hardcoded-color" \u2014 colors not using styles or variables [heuristic]
|
|
907
964
|
// "hardcoded-token" \u2014 numeric values not bound to FLOAT variable [heuristic]
|
|
@@ -1167,7 +1224,7 @@ Params:
|
|
|
1167
1224
|
}
|
|
1168
1225
|
};
|
|
1169
1226
|
var helpTopics = {
|
|
1170
|
-
"missing_tools": '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
1227
|
+
"missing_tools": '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma@latest", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
1171
1228
|
};
|
|
1172
1229
|
var allEndpointNames = Object.keys(helpEndpoints);
|
|
1173
1230
|
var allTopicNames = Object.keys(helpTopics);
|
package/dist/tools/registry.js
CHANGED
|
@@ -376,7 +376,7 @@ Create frame-like containers
|
|
|
376
376
|
|
|
377
377
|
Example: frames(method:"create", type:"auto_layout", layoutMode:"VERTICAL", itemSpacing:16, padding:24)
|
|
378
378
|
|
|
379
|
-
Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line | group | boolean_operation | svg)
|
|
379
|
+
Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line | group | boolean_operation | svg | slot)
|
|
380
380
|
|
|
381
381
|
## frame \u2014 General-purpose frame \u2014 shrinks to content by default, static when width+height given
|
|
382
382
|
name (string, optional) \u2014 Node name
|
|
@@ -595,7 +595,64 @@ Discriminant: type (frame | auto_layout | section | rectangle | ellipse | line |
|
|
|
595
595
|
name (string, optional) \u2014 Layer name (default: 'SVG')
|
|
596
596
|
parentId (string, optional) \u2014 Parent node ID. Omit to place at current page root.
|
|
597
597
|
x (number, optional) \u2014 X position (default: 0)
|
|
598
|
-
y (number, optional) \u2014 Y position (default: 0)
|
|
598
|
+
y (number, optional) \u2014 Y position (default: 0)
|
|
599
|
+
|
|
600
|
+
## slot \u2014 Create a slot inside a component. Slots are placeholder containers that instance users fill with content. Defaults to VERTICAL auto-layout with FILL/HUG sizing \u2014 ready to receive children. Accepts all frame layout properties.
|
|
601
|
+
name (string, optional) \u2014 Node name
|
|
602
|
+
parentId (string, optional) \u2014 Parent node ID inside the owning component. Required unless componentId is provided.
|
|
603
|
+
x (number, optional) \u2014 X position (default: 0)
|
|
604
|
+
y (number, optional) \u2014 Y position (default: 0)
|
|
605
|
+
width (number, optional) \u2014 Width in px (omit to shrink-to-content via HUG)
|
|
606
|
+
height (number, optional) \u2014 Height in px (omit to shrink-to-content via HUG)
|
|
607
|
+
rotation (number, optional) \u2014 Rotation in degrees (0-360)
|
|
608
|
+
visible (boolean, optional) \u2014 Show/hide (default true)
|
|
609
|
+
locked (boolean, optional) \u2014 Lock/unlock (default false)
|
|
610
|
+
opacity (string, optional) \u2014 Opacity (0-1) or variable name
|
|
611
|
+
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)
|
|
612
|
+
effectStyleName (string, optional) \u2014 Effect style name (e.g. 'Shadow/Card') for shadows, blurs
|
|
613
|
+
fills (array, optional) \u2014 Fill paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] for transparent. Primary way to set fills.
|
|
614
|
+
fillColor (Color, optional) \u2014 Shorthand \u2014 sets a single solid fill (auto-binds to matching variable/style)
|
|
615
|
+
fillStyleName (string, optional) \u2014 Paint style name for fill
|
|
616
|
+
fillVariableName (string, optional) \u2014 Color variable by name e.g. 'bg/primary'
|
|
617
|
+
imageUrl (string, optional) \u2014 Image source \u2014 'pexel:<id>' for Pexels photos, a public URL, or a local file path. SVGs are inserted as vectors; raster images become IMAGE fills.
|
|
618
|
+
imageScaleMode (FILL | FIT | CROP | TILE, optional) \u2014 How the image is scaled within the frame (default: FILL)
|
|
619
|
+
strokes (array, optional) \u2014 Stroke paints array \u2014 e.g. [{type: 'SOLID', color: '#hex'}] or [] to clear. Primary way to set strokes.
|
|
620
|
+
strokeColor (Color, optional) \u2014 Shorthand \u2014 sets a single solid stroke (auto-binds to matching variable/style)
|
|
621
|
+
strokeStyleName (string, optional) \u2014 Paint style name for stroke
|
|
622
|
+
strokeVariableName (string, optional) \u2014 Color variable by name for stroke
|
|
623
|
+
strokeWeight (string, optional) \u2014 All sides (number) or variable name (string). Per-side: strokeTopWeight, strokeBottomWeight, strokeLeftWeight, strokeRightWeight.
|
|
624
|
+
strokeTopWeight (string, optional)
|
|
625
|
+
strokeBottomWeight (string, optional)
|
|
626
|
+
strokeLeftWeight (string, optional)
|
|
627
|
+
strokeRightWeight (string, optional)
|
|
628
|
+
strokeAlign (INSIDE | OUTSIDE | CENTER, optional) \u2014 Stroke position (default: INSIDE)
|
|
629
|
+
cornerRadius (string, optional) \u2014 All corners (number) or variable name (string). Per-corner: topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius.
|
|
630
|
+
topLeftRadius (string, optional)
|
|
631
|
+
topRightRadius (string, optional)
|
|
632
|
+
bottomRightRadius (string, optional)
|
|
633
|
+
bottomLeftRadius (string, optional)
|
|
634
|
+
layoutMode (NONE | HORIZONTAL | VERTICAL, optional) \u2014 Layout direction (default: auto \u2014 NONE when width+height set, otherwise inferred from layout props)
|
|
635
|
+
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.
|
|
636
|
+
padding (string, optional) \u2014 All edges (number) or variable name (string). Per-edge: paddingTop, paddingRight, paddingBottom, paddingLeft.
|
|
637
|
+
paddingTop (string, optional)
|
|
638
|
+
paddingRight (string, optional)
|
|
639
|
+
paddingBottom (string, optional)
|
|
640
|
+
paddingLeft (string, optional)
|
|
641
|
+
primaryAxisAlignItems (MIN | MAX | CENTER | SPACE_BETWEEN, optional)
|
|
642
|
+
counterAxisAlignItems (MIN | MAX | CENTER | BASELINE, optional)
|
|
643
|
+
itemSpacing (string, optional) \u2014 Spacing between children (number or variable name string, default: 0)
|
|
644
|
+
counterAxisSpacing (string, optional) \u2014 Gap between wrapped rows (requires layoutWrap: WRAP)
|
|
645
|
+
strokesIncludedInLayout (boolean, optional) \u2014 Include stroke width in layout measurements (default: false)
|
|
646
|
+
overflowDirection (NONE | HORIZONTAL | VERTICAL | BOTH, optional) \u2014 Scroll overflow in prototype (default: NONE)
|
|
647
|
+
layoutPositioning (AUTO | ABSOLUTE, optional) \u2014 ABSOLUTE = floating inside auto-layout parent
|
|
648
|
+
layoutSizingHorizontal (FIXED | HUG | FILL, optional)
|
|
649
|
+
layoutSizingVertical (FIXED | HUG | FILL, optional)
|
|
650
|
+
minWidth (number, optional) \u2014 Min width for responsive auto-layout
|
|
651
|
+
maxWidth (number, optional) \u2014 Max width for responsive auto-layout
|
|
652
|
+
minHeight (number, optional) \u2014 Min height for responsive auto-layout
|
|
653
|
+
maxHeight (number, optional) \u2014 Max height for responsive auto-layout
|
|
654
|
+
annotations (array, optional) \u2014 Set annotations \u2014 [{label?, labelMarkdown?, properties?, categoryId?}]. Properties validated per node type.
|
|
655
|
+
componentId (string, optional) \u2014 Owning component ID. Optional \u2014 auto-resolved from parentId by walking up ancestors.`,
|
|
599
656
|
"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',
|
|
600
657
|
"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)"
|
|
601
658
|
}
|
|
@@ -878,7 +935,7 @@ Methods:
|
|
|
878
935
|
// "fixed-in-autolayout" \u2014 FIXED-size children in auto-layout parents [heuristic]
|
|
879
936
|
// "unbounded-hug" \u2014 HUG on both axes [unsafe; short leaf text\u2192style]
|
|
880
937
|
// "hug-cross-axis" \u2014 HUG on cross-axis of constrained parent [heuristic; leaf nodes\u2192style]
|
|
881
|
-
// "empty-container" \u2014 empty frames [style]
|
|
938
|
+
// "empty-container" \u2014 empty frames, excludes SLOT nodes [style]
|
|
882
939
|
// Token rules [token]:
|
|
883
940
|
// "hardcoded-color" \u2014 colors not using styles or variables [heuristic]
|
|
884
941
|
// "hardcoded-token" \u2014 numeric values not bound to FLOAT variable [heuristic]
|
|
@@ -1144,7 +1201,7 @@ Params:
|
|
|
1144
1201
|
}
|
|
1145
1202
|
};
|
|
1146
1203
|
var helpTopics = {
|
|
1147
|
-
"missing_tools": '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
1204
|
+
"missing_tools": '# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find create/edit methods on endpoint tools, the MCP server was started without the correct access tier flag.\n\nVibma filters available methods at startup based on CLI flags passed in the MCP config `args` array:\n\n| Flag | Methods available |\n|------|-----------------|\n| _(none)_ | Read-only (get, list, check, scan, export) |\n| `--create` | Read + creation methods (create, clone) |\n| `--edit` | All methods (read + create + update + delete) |\n\nAsk the user to add `--edit` (or `--create`) to their MCP config args:\n\n```json\n{\n "mcpServers": {\n "Vibma": {\n "command": "npx",\n "args": ["-y", "@ufira/vibma@latest", "--edit"]\n }\n }\n}\n```\n\nAfter updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.'
|
|
1148
1205
|
};
|
|
1149
1206
|
var allEndpointNames = Object.keys(helpEndpoints);
|
|
1150
1207
|
var allTopicNames = Object.keys(helpTopics);
|
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.1.
|
|
4
|
+
"version": "1.1.3-rc2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ufira <https://github.com/ufira-ai>",
|
|
7
7
|
"homepage": "https://github.com/ufira-ai/vibma",
|