@ufira/vibma 0.3.2 → 1.0.0-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.
@@ -22,9 +22,14 @@ __export(schemas_exports, {
22
22
  colorRgba: () => colorRgba,
23
23
  depth: () => depth,
24
24
  effectEntry: () => effectEntry,
25
+ letterSpacing: () => letterSpacing,
26
+ lineHeight: () => lineHeight,
25
27
  nodeId: () => nodeId,
26
28
  nodeIds: () => nodeIds,
27
29
  parentId: () => parentId,
30
+ stringOrBoolean: () => stringOrBoolean,
31
+ token: () => token,
32
+ variableValue: () => variableValue,
28
33
  xPos: () => xPos,
29
34
  yPos: () => yPos
30
35
  });
@@ -72,12 +77,39 @@ function parseHex(hex) {
72
77
  var colorRgba = import_zod2.z.preprocess((v) => {
73
78
  if (typeof v === "string") return parseHex(v) ?? v;
74
79
  return v;
75
- }, import_zod2.z.object({
76
- r: import_zod2.z.coerce.number().min(0).max(1),
77
- g: import_zod2.z.coerce.number().min(0).max(1),
78
- b: import_zod2.z.coerce.number().min(0).max(1),
79
- a: import_zod2.z.coerce.number().min(0).max(1).optional()
80
- })).describe('Hex "#FF0000" or {r,g,b,a?} with values 0-1.');
80
+ }, import_zod2.z.union([
81
+ import_zod2.z.object({
82
+ r: import_zod2.z.coerce.number().min(0).max(1),
83
+ g: import_zod2.z.coerce.number().min(0).max(1),
84
+ b: import_zod2.z.coerce.number().min(0).max(1),
85
+ a: import_zod2.z.coerce.number().min(0).max(1).optional()
86
+ }),
87
+ import_zod2.z.string()
88
+ // Non-hex strings pass through for handler-level style/variable resolution
89
+ ])).describe('Hex "#FF0000", {r,g,b,a?} 0-1, or style/variable name.');
90
+ var variableValue = import_zod2.z.preprocess((v) => {
91
+ if (typeof v === "string") return parseHex(v) ?? v;
92
+ return v;
93
+ }, import_zod2.z.union([
94
+ import_zod2.z.number(),
95
+ import_zod2.z.boolean(),
96
+ import_zod2.z.string(),
97
+ import_zod2.z.object({ r: import_zod2.z.number(), g: import_zod2.z.number(), b: import_zod2.z.number(), a: import_zod2.z.number().optional() }),
98
+ import_zod2.z.object({ type: import_zod2.z.literal("VARIABLE_ALIAS"), name: import_zod2.z.string() })
99
+ ])).describe('number, boolean, string, hex "#FF0000", {r,g,b,a?}, or {type:"VARIABLE_ALIAS",name:"other/variable"}');
100
+ var lineHeight = import_zod2.z.union([
101
+ import_zod2.z.coerce.number(),
102
+ import_zod2.z.object({ value: import_zod2.z.coerce.number(), unit: import_zod2.z.enum(["PIXELS", "PERCENT", "AUTO"]) })
103
+ ]).describe('number (px) or {value, unit: "PIXELS"|"PERCENT"|"AUTO"}');
104
+ var letterSpacing = import_zod2.z.union([
105
+ import_zod2.z.coerce.number(),
106
+ import_zod2.z.object({ value: import_zod2.z.coerce.number(), unit: import_zod2.z.enum(["PIXELS", "PERCENT"]) })
107
+ ]).describe('number (px) or {value, unit: "PIXELS"|"PERCENT"}');
108
+ var stringOrBoolean = import_zod2.z.union([import_zod2.z.string(), import_zod2.z.boolean()]);
109
+ var token = import_zod2.z.preprocess((v) => {
110
+ if (typeof v === "number") return String(v);
111
+ return v;
112
+ }, import_zod2.z.string()).describe('number as string ("8") or variable name ("Radii/Medium")');
81
113
  var effectEntry = import_zod2.z.object({
82
114
  type: import_zod2.z.enum(["DROP_SHADOW", "INNER_SHADOW", "LAYER_BLUR", "BACKGROUND_BLUR"]),
83
115
  color: flexJson(colorRgba).optional(),
@@ -92,9 +124,14 @@ var effectEntry = import_zod2.z.object({
92
124
  colorRgba,
93
125
  depth,
94
126
  effectEntry,
127
+ letterSpacing,
128
+ lineHeight,
95
129
  nodeId,
96
130
  nodeIds,
97
131
  parentId,
132
+ stringOrBoolean,
133
+ token,
134
+ variableValue,
98
135
  xPos,
99
136
  yPos
100
137
  });
@@ -18,13 +18,45 @@ declare const depth: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
18
18
  declare const xPos: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
19
19
  /** Y position for creation tools */
20
20
  declare const yPos: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
21
- /** RGBA color — accepts {r,g,b,a?} object (0-1) or hex string (#RGB, #RRGGBB, #RRGGBBAA) */
22
- declare const colorRgba: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
21
+ /** RGBA color — accepts {r,g,b,a?} object (0-1), hex string (#RGB, #RRGGBB, #RRGGBBAA), or style/variable name string */
22
+ declare const colorRgba: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodUnion<readonly [z.ZodObject<{
23
23
  r: z.ZodCoercedNumber<unknown>;
24
24
  g: z.ZodCoercedNumber<unknown>;
25
25
  b: z.ZodCoercedNumber<unknown>;
26
26
  a: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
27
- }, z.core.$strip>>;
27
+ }, z.core.$strip>, z.ZodString]>>;
28
+ /** Variable value — color (hex or RGBA), number, boolean, string, or alias */
29
+ declare const variableValue: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodUnion<readonly [z.ZodNumber, z.ZodBoolean, z.ZodString, z.ZodObject<{
30
+ r: z.ZodNumber;
31
+ g: z.ZodNumber;
32
+ b: z.ZodNumber;
33
+ a: z.ZodOptional<z.ZodNumber>;
34
+ }, z.core.$strip>, z.ZodObject<{
35
+ type: z.ZodLiteral<"VARIABLE_ALIAS">;
36
+ name: z.ZodString;
37
+ }, z.core.$strip>]>>;
38
+ /** Line height — number (px) or {value, unit} */
39
+ declare const lineHeight: z.ZodUnion<readonly [z.ZodCoercedNumber<unknown>, z.ZodObject<{
40
+ value: z.ZodCoercedNumber<unknown>;
41
+ unit: z.ZodEnum<{
42
+ PIXELS: "PIXELS";
43
+ PERCENT: "PERCENT";
44
+ AUTO: "AUTO";
45
+ }>;
46
+ }, z.core.$strip>]>;
47
+ /** Letter spacing — number (px) or {value, unit} */
48
+ declare const letterSpacing: z.ZodUnion<readonly [z.ZodCoercedNumber<unknown>, z.ZodObject<{
49
+ value: z.ZodCoercedNumber<unknown>;
50
+ unit: z.ZodEnum<{
51
+ PIXELS: "PIXELS";
52
+ PERCENT: "PERCENT";
53
+ }>;
54
+ }, z.core.$strip>]>;
55
+ /** String or boolean — for component property defaults */
56
+ declare const stringOrBoolean: z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>;
57
+ /** Design token — accepts a string that is either a numeric value ("8") or a variable name/ID ("Radii/Medium").
58
+ * Numeric strings are parsed to numbers in the handler; non-numeric strings are variable references. */
59
+ declare const token: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodString>;
28
60
  /** Single effect entry — shared by set_effects and styles create */
29
61
  declare const effectEntry: z.ZodObject<{
30
62
  type: z.ZodEnum<{
@@ -33,12 +65,12 @@ declare const effectEntry: z.ZodObject<{
33
65
  LAYER_BLUR: "LAYER_BLUR";
34
66
  BACKGROUND_BLUR: "BACKGROUND_BLUR";
35
67
  }>;
36
- color: z.ZodOptional<z.ZodPipe<z.ZodTransform<any, unknown>, z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
68
+ color: z.ZodOptional<z.ZodPipe<z.ZodTransform<any, unknown>, z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodUnion<readonly [z.ZodObject<{
37
69
  r: z.ZodCoercedNumber<unknown>;
38
70
  g: z.ZodCoercedNumber<unknown>;
39
71
  b: z.ZodCoercedNumber<unknown>;
40
72
  a: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
41
- }, z.core.$strip>>>>;
73
+ }, z.core.$strip>, z.ZodString]>>>>;
42
74
  offset: z.ZodOptional<z.ZodPipe<z.ZodTransform<any, unknown>, z.ZodObject<{
43
75
  x: z.ZodCoercedNumber<unknown>;
44
76
  y: z.ZodCoercedNumber<unknown>;
@@ -49,4 +81,4 @@ declare const effectEntry: z.ZodObject<{
49
81
  blendMode: z.ZodOptional<z.ZodString>;
50
82
  }, z.core.$strip>;
51
83
 
52
- export { colorRgba, depth, effectEntry, nodeId, nodeIds, parentId, xPos, yPos };
84
+ export { colorRgba, depth, effectEntry, letterSpacing, lineHeight, nodeId, nodeIds, parentId, stringOrBoolean, token, variableValue, xPos, yPos };
@@ -18,13 +18,45 @@ declare const depth: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
18
18
  declare const xPos: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
19
19
  /** Y position for creation tools */
20
20
  declare const yPos: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
21
- /** RGBA color — accepts {r,g,b,a?} object (0-1) or hex string (#RGB, #RRGGBB, #RRGGBBAA) */
22
- declare const colorRgba: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
21
+ /** RGBA color — accepts {r,g,b,a?} object (0-1), hex string (#RGB, #RRGGBB, #RRGGBBAA), or style/variable name string */
22
+ declare const colorRgba: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodUnion<readonly [z.ZodObject<{
23
23
  r: z.ZodCoercedNumber<unknown>;
24
24
  g: z.ZodCoercedNumber<unknown>;
25
25
  b: z.ZodCoercedNumber<unknown>;
26
26
  a: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
27
- }, z.core.$strip>>;
27
+ }, z.core.$strip>, z.ZodString]>>;
28
+ /** Variable value — color (hex or RGBA), number, boolean, string, or alias */
29
+ declare const variableValue: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodUnion<readonly [z.ZodNumber, z.ZodBoolean, z.ZodString, z.ZodObject<{
30
+ r: z.ZodNumber;
31
+ g: z.ZodNumber;
32
+ b: z.ZodNumber;
33
+ a: z.ZodOptional<z.ZodNumber>;
34
+ }, z.core.$strip>, z.ZodObject<{
35
+ type: z.ZodLiteral<"VARIABLE_ALIAS">;
36
+ name: z.ZodString;
37
+ }, z.core.$strip>]>>;
38
+ /** Line height — number (px) or {value, unit} */
39
+ declare const lineHeight: z.ZodUnion<readonly [z.ZodCoercedNumber<unknown>, z.ZodObject<{
40
+ value: z.ZodCoercedNumber<unknown>;
41
+ unit: z.ZodEnum<{
42
+ PIXELS: "PIXELS";
43
+ PERCENT: "PERCENT";
44
+ AUTO: "AUTO";
45
+ }>;
46
+ }, z.core.$strip>]>;
47
+ /** Letter spacing — number (px) or {value, unit} */
48
+ declare const letterSpacing: z.ZodUnion<readonly [z.ZodCoercedNumber<unknown>, z.ZodObject<{
49
+ value: z.ZodCoercedNumber<unknown>;
50
+ unit: z.ZodEnum<{
51
+ PIXELS: "PIXELS";
52
+ PERCENT: "PERCENT";
53
+ }>;
54
+ }, z.core.$strip>]>;
55
+ /** String or boolean — for component property defaults */
56
+ declare const stringOrBoolean: z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>;
57
+ /** Design token — accepts a string that is either a numeric value ("8") or a variable name/ID ("Radii/Medium").
58
+ * Numeric strings are parsed to numbers in the handler; non-numeric strings are variable references. */
59
+ declare const token: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodString>;
28
60
  /** Single effect entry — shared by set_effects and styles create */
29
61
  declare const effectEntry: z.ZodObject<{
30
62
  type: z.ZodEnum<{
@@ -33,12 +65,12 @@ declare const effectEntry: z.ZodObject<{
33
65
  LAYER_BLUR: "LAYER_BLUR";
34
66
  BACKGROUND_BLUR: "BACKGROUND_BLUR";
35
67
  }>;
36
- color: z.ZodOptional<z.ZodPipe<z.ZodTransform<any, unknown>, z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
68
+ color: z.ZodOptional<z.ZodPipe<z.ZodTransform<any, unknown>, z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodUnion<readonly [z.ZodObject<{
37
69
  r: z.ZodCoercedNumber<unknown>;
38
70
  g: z.ZodCoercedNumber<unknown>;
39
71
  b: z.ZodCoercedNumber<unknown>;
40
72
  a: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
41
- }, z.core.$strip>>>>;
73
+ }, z.core.$strip>, z.ZodString]>>>>;
42
74
  offset: z.ZodOptional<z.ZodPipe<z.ZodTransform<any, unknown>, z.ZodObject<{
43
75
  x: z.ZodCoercedNumber<unknown>;
44
76
  y: z.ZodCoercedNumber<unknown>;
@@ -49,4 +81,4 @@ declare const effectEntry: z.ZodObject<{
49
81
  blendMode: z.ZodOptional<z.ZodString>;
50
82
  }, z.core.$strip>;
51
83
 
52
- export { colorRgba, depth, effectEntry, nodeId, nodeIds, parentId, xPos, yPos };
84
+ export { colorRgba, depth, effectEntry, letterSpacing, lineHeight, nodeId, nodeIds, parentId, stringOrBoolean, token, variableValue, xPos, yPos };
@@ -42,12 +42,39 @@ function parseHex(hex) {
42
42
  var colorRgba = z2.preprocess((v) => {
43
43
  if (typeof v === "string") return parseHex(v) ?? v;
44
44
  return v;
45
- }, z2.object({
46
- r: z2.coerce.number().min(0).max(1),
47
- g: z2.coerce.number().min(0).max(1),
48
- b: z2.coerce.number().min(0).max(1),
49
- a: z2.coerce.number().min(0).max(1).optional()
50
- })).describe('Hex "#FF0000" or {r,g,b,a?} with values 0-1.');
45
+ }, z2.union([
46
+ z2.object({
47
+ r: z2.coerce.number().min(0).max(1),
48
+ g: z2.coerce.number().min(0).max(1),
49
+ b: z2.coerce.number().min(0).max(1),
50
+ a: z2.coerce.number().min(0).max(1).optional()
51
+ }),
52
+ z2.string()
53
+ // Non-hex strings pass through for handler-level style/variable resolution
54
+ ])).describe('Hex "#FF0000", {r,g,b,a?} 0-1, or style/variable name.');
55
+ var variableValue = z2.preprocess((v) => {
56
+ if (typeof v === "string") return parseHex(v) ?? v;
57
+ return v;
58
+ }, z2.union([
59
+ z2.number(),
60
+ z2.boolean(),
61
+ z2.string(),
62
+ z2.object({ r: z2.number(), g: z2.number(), b: z2.number(), a: z2.number().optional() }),
63
+ z2.object({ type: z2.literal("VARIABLE_ALIAS"), name: z2.string() })
64
+ ])).describe('number, boolean, string, hex "#FF0000", {r,g,b,a?}, or {type:"VARIABLE_ALIAS",name:"other/variable"}');
65
+ var lineHeight = z2.union([
66
+ z2.coerce.number(),
67
+ z2.object({ value: z2.coerce.number(), unit: z2.enum(["PIXELS", "PERCENT", "AUTO"]) })
68
+ ]).describe('number (px) or {value, unit: "PIXELS"|"PERCENT"|"AUTO"}');
69
+ var letterSpacing = z2.union([
70
+ z2.coerce.number(),
71
+ z2.object({ value: z2.coerce.number(), unit: z2.enum(["PIXELS", "PERCENT"]) })
72
+ ]).describe('number (px) or {value, unit: "PIXELS"|"PERCENT"}');
73
+ var stringOrBoolean = z2.union([z2.string(), z2.boolean()]);
74
+ var token = z2.preprocess((v) => {
75
+ if (typeof v === "number") return String(v);
76
+ return v;
77
+ }, z2.string()).describe('number as string ("8") or variable name ("Radii/Medium")');
51
78
  var effectEntry = z2.object({
52
79
  type: z2.enum(["DROP_SHADOW", "INNER_SHADOW", "LAYER_BLUR", "BACKGROUND_BLUR"]),
53
80
  color: flexJson(colorRgba).optional(),
@@ -61,9 +88,14 @@ export {
61
88
  colorRgba,
62
89
  depth,
63
90
  effectEntry,
91
+ letterSpacing,
92
+ lineHeight,
64
93
  nodeId,
65
94
  nodeIds,
66
95
  parentId,
96
+ stringOrBoolean,
97
+ token,
98
+ variableValue,
67
99
  xPos,
68
100
  yPos
69
101
  };
@@ -17,14 +17,18 @@ interface ToolDef {
17
17
  description: string;
18
18
  schema: Record<string, z.ZodTypeAny> | ((caps: Capabilities) => Record<string, z.ZodTypeAny>);
19
19
  tier: ToolTier;
20
- /** Figma command name. Defaults to name. */
20
+ /** Figma command name. Defaults to name. For legacy standalone tools. */
21
21
  command?: string;
22
+ /** Method → Figma command dispatch map. For endpoint tools (generated by schema compiler). */
23
+ commandMap?: Record<string, string>;
22
24
  /** sendCommand timeout in ms (default: 30 000) */
23
25
  timeout?: number;
24
26
  /** Pre-send validation (e.g. per-method item parsing for endpoints) */
25
27
  validate?: (params: any) => void;
26
28
  /** Custom response formatter. Default: mcpJson */
27
29
  formatResponse?: (result: unknown) => any;
30
+ /** Per-method response formatters. Overrides formatResponse for specific methods. */
31
+ methodFormatters?: Record<string, (result: unknown) => any>;
28
32
  }
29
33
  /** Standard batch result from Figma handlers */
30
34
  interface BatchResult<T = unknown> {
@@ -17,14 +17,18 @@ interface ToolDef {
17
17
  description: string;
18
18
  schema: Record<string, z.ZodTypeAny> | ((caps: Capabilities) => Record<string, z.ZodTypeAny>);
19
19
  tier: ToolTier;
20
- /** Figma command name. Defaults to name. */
20
+ /** Figma command name. Defaults to name. For legacy standalone tools. */
21
21
  command?: string;
22
+ /** Method → Figma command dispatch map. For endpoint tools (generated by schema compiler). */
23
+ commandMap?: Record<string, string>;
22
24
  /** sendCommand timeout in ms (default: 30 000) */
23
25
  timeout?: number;
24
26
  /** Pre-send validation (e.g. per-method item parsing for endpoints) */
25
27
  validate?: (params: any) => void;
26
28
  /** Custom response formatter. Default: mcpJson */
27
29
  formatResponse?: (result: unknown) => any;
30
+ /** Per-method response formatters. Overrides formatResponse for specific methods. */
31
+ methodFormatters?: Record<string, (result: unknown) => any>;
28
32
  }
29
33
  /** Standard batch result from Figma handlers */
30
34
  interface BatchResult<T = unknown> {
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": "0.3.2",
4
+ "version": "1.0.0-rc2",
5
5
  "license": "MIT",
6
6
  "author": "ufira <https://github.com/ufira-ai>",
7
7
  "homepage": "https://github.com/ufira-ai/vibma",
@@ -21,6 +21,7 @@
21
21
  "module": "dist/mcp.js",
22
22
  "main": "dist/mcp.js",
23
23
  "bin": {
24
+ "vibma": "dist/mcp.js",
24
25
  "vibma-mcp": "dist/mcp.js"
25
26
  },
26
27
  "exports": {
@@ -44,6 +45,10 @@
44
45
  "import": "./dist/tools/registry.js",
45
46
  "require": "./dist/tools/registry.cjs"
46
47
  },
48
+ "./guards": {
49
+ "import": "./dist/tools/generated/guards.js",
50
+ "require": "./dist/tools/generated/guards.cjs"
51
+ },
47
52
  "./utils/color": {
48
53
  "import": "./dist/utils/color.js",
49
54
  "require": "./dist/utils/color.cjs"
@@ -59,6 +64,7 @@
59
64
  },
60
65
  "files": [
61
66
  "dist",
67
+ "!dist/**/*.map",
62
68
  "README.md",
63
69
  "LICENSE"
64
70
  ],
@@ -75,7 +81,7 @@
75
81
  "zod": "4.3.6"
76
82
  },
77
83
  "devDependencies": {
78
- "@types/node": "^25.3.3",
84
+ "@types/node": "^25.4.0",
79
85
  "@types/ws": "^8.18.1",
80
86
  "tsup": "^8.5.1",
81
87
  "typescript": "^5.9.3"