mcp-figma-toolkit 1.0.9 → 1.0.10
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/package.json +1 -1
- package/plugin/plugin.js +98 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-figma-toolkit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "MCP server that enables AI agents to manipulate Figma documents - create shapes, text, styles, components, variables, and more",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/server.js",
|
package/plugin/plugin.js
CHANGED
|
@@ -53,6 +53,22 @@ function serializeEffects(effects) {
|
|
|
53
53
|
base.hex = rgbToHex(e.color);
|
|
54
54
|
base.opacity = e.color.a != null ? e.color.a : 1;
|
|
55
55
|
}
|
|
56
|
+
if (e.boundVariables) {
|
|
57
|
+
var ebv = {};
|
|
58
|
+
var ebvKeys = ["radius", "spread", "color", "offsetX", "offsetY"];
|
|
59
|
+
for (var ei = 0; ei < ebvKeys.length; ei++) {
|
|
60
|
+
var ek = ebvKeys[ei];
|
|
61
|
+
try {
|
|
62
|
+
var eb = e.boundVariables[ek];
|
|
63
|
+
if (eb && eb.id) {
|
|
64
|
+
ebv[ek] = { type: eb.type, id: eb.id };
|
|
65
|
+
var ev = figma.variables.getVariableById(eb.id);
|
|
66
|
+
if (ev) { ebv[ek].name = ev.name; ebv[ek].resolvedType = ev.resolvedType; }
|
|
67
|
+
}
|
|
68
|
+
} catch (_) {}
|
|
69
|
+
}
|
|
70
|
+
if (Object.keys(ebv).length > 0) base.boundVariables = ebv;
|
|
71
|
+
}
|
|
56
72
|
return base;
|
|
57
73
|
});
|
|
58
74
|
}
|
|
@@ -718,6 +734,45 @@ function getNodeInfo({ nodeId }) {
|
|
|
718
734
|
try { info.effects = serializeEffects(node.effects); } catch (_) {}
|
|
719
735
|
}
|
|
720
736
|
|
|
737
|
+
// Constraints
|
|
738
|
+
if ("constraints" in node) {
|
|
739
|
+
info.constraints = {
|
|
740
|
+
horizontal: node.constraints.horizontal,
|
|
741
|
+
vertical: node.constraints.vertical
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// Clips content (for frames)
|
|
746
|
+
if ("clipsContent" in node) info.clipsContent = node.clipsContent;
|
|
747
|
+
|
|
748
|
+
// Layout positioning within auto-layout parent
|
|
749
|
+
if ("layoutAlign" in node) info.layoutAlign = node.layoutAlign;
|
|
750
|
+
if ("layoutGrow" in node) info.layoutGrow = node.layoutGrow;
|
|
751
|
+
if ("layoutPositioning" in node) info.layoutPositioning = node.layoutPositioning;
|
|
752
|
+
|
|
753
|
+
// Style IDs (paint styles, text styles, effect styles)
|
|
754
|
+
if ("fillStyleId" in node && node.fillStyleId && node.fillStyleId !== "") {
|
|
755
|
+
info.fillStyleId = node.fillStyleId;
|
|
756
|
+
}
|
|
757
|
+
if ("strokeStyleId" in node && node.strokeStyleId && node.strokeStyleId !== "") {
|
|
758
|
+
info.strokeStyleId = node.strokeStyleId;
|
|
759
|
+
}
|
|
760
|
+
if ("effectStyleId" in node && node.effectStyleId && node.effectStyleId !== "") {
|
|
761
|
+
info.effectStyleId = node.effectStyleId;
|
|
762
|
+
}
|
|
763
|
+
if ("textStyleId" in node && node.textStyleId && node.textStyleId !== "") {
|
|
764
|
+
info.textStyleId = node.textStyleId;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
// Mask
|
|
768
|
+
if ("isMask" in node) info.isMask = node.isMask;
|
|
769
|
+
|
|
770
|
+
// Min/max size
|
|
771
|
+
if ("minWidth" in node && node.minWidth != null) info.minWidth = node.minWidth;
|
|
772
|
+
if ("maxWidth" in node && node.maxWidth != null) info.maxWidth = node.maxWidth;
|
|
773
|
+
if ("minHeight" in node && node.minHeight != null) info.minHeight = node.minHeight;
|
|
774
|
+
if ("maxHeight" in node && node.maxHeight != null) info.maxHeight = node.maxHeight;
|
|
775
|
+
|
|
721
776
|
// Auto-layout properties
|
|
722
777
|
if ("layoutMode" in node && node.layoutMode !== "NONE") {
|
|
723
778
|
info.autoLayout = {
|
|
@@ -731,7 +786,8 @@ function getNodeInfo({ nodeId }) {
|
|
|
731
786
|
primaryAxisAlignItems: node.primaryAxisAlignItems,
|
|
732
787
|
counterAxisAlignItems: node.counterAxisAlignItems,
|
|
733
788
|
layoutSizingHorizontal: node.layoutSizingHorizontal,
|
|
734
|
-
layoutSizingVertical: node.layoutSizingVertical
|
|
789
|
+
layoutSizingVertical: node.layoutSizingVertical,
|
|
790
|
+
layoutWrap: node.layoutWrap
|
|
735
791
|
};
|
|
736
792
|
}
|
|
737
793
|
|
|
@@ -783,10 +839,25 @@ function getNodeInfo({ nodeId }) {
|
|
|
783
839
|
try {
|
|
784
840
|
var bv = node.boundVariables;
|
|
785
841
|
var bvResult = {};
|
|
786
|
-
|
|
787
|
-
|
|
842
|
+
var knownBVKeys = [
|
|
843
|
+
"fills", "strokes", "effects",
|
|
844
|
+
"layoutGrids", "componentProperties",
|
|
845
|
+
"fontSize", "fontFamily", "fontStyle", "fontWeight",
|
|
846
|
+
"lineHeight", "letterSpacing", "paragraphSpacing", "paragraphIndent",
|
|
847
|
+
"textCase", "textDecoration",
|
|
848
|
+
"visible", "opacity",
|
|
849
|
+
"topLeftRadius", "topRightRadius", "bottomLeftRadius", "bottomRightRadius",
|
|
850
|
+
"itemSpacing", "counterAxisSpacing",
|
|
851
|
+
"paddingLeft", "paddingRight", "paddingTop", "paddingBottom",
|
|
852
|
+
"strokeWeight", "strokeTopWeight", "strokeBottomWeight", "strokeLeftWeight", "strokeRightWeight",
|
|
853
|
+
"width", "height",
|
|
854
|
+
"minWidth", "maxWidth", "minHeight", "maxHeight",
|
|
855
|
+
"characters"
|
|
856
|
+
];
|
|
857
|
+
|
|
858
|
+
function extractBinding(binding) {
|
|
788
859
|
if (Array.isArray(binding)) {
|
|
789
|
-
|
|
860
|
+
return binding.map(function(b) {
|
|
790
861
|
var entry = { type: b.type, id: b.id };
|
|
791
862
|
try {
|
|
792
863
|
var v = figma.variables.getVariableById(b.id);
|
|
@@ -795,10 +866,31 @@ function getNodeInfo({ nodeId }) {
|
|
|
795
866
|
return entry;
|
|
796
867
|
});
|
|
797
868
|
} else if (binding && binding.id) {
|
|
798
|
-
|
|
869
|
+
var single = { type: binding.type, id: binding.id };
|
|
799
870
|
try {
|
|
800
871
|
var v2 = figma.variables.getVariableById(binding.id);
|
|
801
|
-
if (v2) {
|
|
872
|
+
if (v2) { single.name = v2.name; single.resolvedType = v2.resolvedType; }
|
|
873
|
+
} catch (_) {}
|
|
874
|
+
return single;
|
|
875
|
+
}
|
|
876
|
+
return null;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// First try for...in (catches any enumerable keys)
|
|
880
|
+
for (var key in bv) {
|
|
881
|
+
var result = extractBinding(bv[key]);
|
|
882
|
+
if (result != null) bvResult[key] = result;
|
|
883
|
+
}
|
|
884
|
+
// Supplement with explicit key access (Figma proxies may not enumerate all keys)
|
|
885
|
+
for (var ki = 0; ki < knownBVKeys.length; ki++) {
|
|
886
|
+
var bvKey = knownBVKeys[ki];
|
|
887
|
+
if (!(bvKey in bvResult)) {
|
|
888
|
+
try {
|
|
889
|
+
var val = bv[bvKey];
|
|
890
|
+
if (val != null) {
|
|
891
|
+
var r = extractBinding(val);
|
|
892
|
+
if (r != null) bvResult[bvKey] = r;
|
|
893
|
+
}
|
|
802
894
|
} catch (_) {}
|
|
803
895
|
}
|
|
804
896
|
}
|