@sxl-studio/bridge 1.7.2 → 1.7.3

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.
Files changed (197) hide show
  1. package/README.md +342 -16
  2. package/dist/agent-recipes.d.ts +781 -11
  3. package/dist/agent-recipes.js +886 -13
  4. package/dist/agent-recipes.js.map +1 -1
  5. package/dist/agent-runbook.d.ts +50 -0
  6. package/dist/agent-runbook.js +243 -0
  7. package/dist/agent-runbook.js.map +1 -0
  8. package/dist/asset-upload.d.ts +63 -0
  9. package/dist/asset-upload.js +225 -0
  10. package/dist/asset-upload.js.map +1 -0
  11. package/dist/audit-store.d.ts +15 -0
  12. package/dist/audit-store.js +100 -0
  13. package/dist/audit-store.js.map +1 -0
  14. package/dist/audit.d.ts +4 -3
  15. package/dist/audit.js +37 -4
  16. package/dist/audit.js.map +1 -1
  17. package/dist/auth.d.ts +8 -1
  18. package/dist/auth.js +41 -1
  19. package/dist/auth.js.map +1 -1
  20. package/dist/bridge-agent-workflow-validation-cli.d.ts +2 -0
  21. package/dist/bridge-agent-workflow-validation-cli.js +68 -0
  22. package/dist/bridge-agent-workflow-validation-cli.js.map +1 -0
  23. package/dist/bridge-agent-workflow-validation.d.ts +42 -0
  24. package/dist/bridge-agent-workflow-validation.js +170 -0
  25. package/dist/bridge-agent-workflow-validation.js.map +1 -0
  26. package/dist/bridge-contract-audit.d.ts +45 -0
  27. package/dist/bridge-contract-audit.js +345 -0
  28. package/dist/bridge-contract-audit.js.map +1 -0
  29. package/dist/bridge-health-cli.d.ts +2 -0
  30. package/dist/bridge-health-cli.js +115 -0
  31. package/dist/bridge-health-cli.js.map +1 -0
  32. package/dist/bridge-health.d.ts +33 -0
  33. package/dist/bridge-health.js +594 -0
  34. package/dist/bridge-health.js.map +1 -0
  35. package/dist/bridge-live-validation-cli.d.ts +2 -0
  36. package/dist/bridge-live-validation-cli.js +114 -0
  37. package/dist/bridge-live-validation-cli.js.map +1 -0
  38. package/dist/bridge-live-validation.d.ts +39 -0
  39. package/dist/bridge-live-validation.js +1141 -0
  40. package/dist/bridge-live-validation.js.map +1 -0
  41. package/dist/bridge-performance-profile.d.ts +81 -0
  42. package/dist/bridge-performance-profile.js +227 -0
  43. package/dist/bridge-performance-profile.js.map +1 -0
  44. package/dist/bridge-readiness-cli.d.ts +30 -0
  45. package/dist/bridge-readiness-cli.js +242 -0
  46. package/dist/bridge-readiness-cli.js.map +1 -0
  47. package/dist/bridge-runtime-summary.d.ts +50 -0
  48. package/dist/bridge-runtime-summary.js +112 -0
  49. package/dist/bridge-runtime-summary.js.map +1 -0
  50. package/dist/bridge-workflow-smoke-cli.d.ts +2 -0
  51. package/dist/bridge-workflow-smoke-cli.js +126 -0
  52. package/dist/bridge-workflow-smoke-cli.js.map +1 -0
  53. package/dist/bridge-workflow-smoke.d.ts +39 -0
  54. package/dist/bridge-workflow-smoke.js +431 -0
  55. package/dist/bridge-workflow-smoke.js.map +1 -0
  56. package/dist/codeconnect-suggestions.d.ts +74 -0
  57. package/dist/codeconnect-suggestions.js +398 -0
  58. package/dist/codeconnect-suggestions.js.map +1 -0
  59. package/dist/codeconnect-template.d.ts +98 -0
  60. package/dist/codeconnect-template.js +280 -0
  61. package/dist/codeconnect-template.js.map +1 -0
  62. package/dist/command-queue.d.ts +11 -1
  63. package/dist/command-queue.js +200 -1
  64. package/dist/command-queue.js.map +1 -1
  65. package/dist/command-safety.d.ts +13 -0
  66. package/dist/command-safety.js +59 -0
  67. package/dist/command-safety.js.map +1 -0
  68. package/dist/enabled-library-search.d.ts +49 -0
  69. package/dist/enabled-library-search.js +151 -0
  70. package/dist/enabled-library-search.js.map +1 -0
  71. package/dist/figma-mcp-parity.d.ts +49 -0
  72. package/dist/figma-mcp-parity.js +368 -0
  73. package/dist/figma-mcp-parity.js.map +1 -0
  74. package/dist/figma-mcp-skills-parity.d.ts +61 -0
  75. package/dist/figma-mcp-skills-parity.js +434 -0
  76. package/dist/figma-mcp-skills-parity.js.map +1 -0
  77. package/dist/figma-rest-diagnostics.d.ts +50 -0
  78. package/dist/figma-rest-diagnostics.js +314 -0
  79. package/dist/figma-rest-diagnostics.js.map +1 -0
  80. package/dist/figma-rest.d.ts +27 -0
  81. package/dist/figma-rest.js +116 -0
  82. package/dist/figma-rest.js.map +1 -0
  83. package/dist/http-api.d.ts +14 -2
  84. package/dist/http-api.js +323 -17
  85. package/dist/http-api.js.map +1 -1
  86. package/dist/index.js +25 -1
  87. package/dist/index.js.map +1 -1
  88. package/dist/mcp-factory.d.ts +6 -1
  89. package/dist/mcp-factory.js +23 -4
  90. package/dist/mcp-factory.js.map +1 -1
  91. package/dist/mcp-runtime-probe.d.ts +22 -0
  92. package/dist/mcp-runtime-probe.js +777 -0
  93. package/dist/mcp-runtime-probe.js.map +1 -0
  94. package/dist/mcp-server.d.ts +2 -1
  95. package/dist/mcp-server.js +2 -2
  96. package/dist/mcp-server.js.map +1 -1
  97. package/dist/sxl-mcp-instructions.js +97 -25
  98. package/dist/sxl-mcp-instructions.js.map +1 -1
  99. package/dist/tools/audit.d.ts +22 -6
  100. package/dist/tools/audit.js +49 -7
  101. package/dist/tools/audit.js.map +1 -1
  102. package/dist/tools/capability-matrix.d.ts +22 -0
  103. package/dist/tools/capability-matrix.js +38 -0
  104. package/dist/tools/capability-matrix.js.map +1 -0
  105. package/dist/tools/catalogue-bootstrap.d.ts +1 -0
  106. package/dist/tools/catalogue-bootstrap.js +665 -30
  107. package/dist/tools/catalogue-bootstrap.js.map +1 -1
  108. package/dist/tools/code-connect-context.d.ts +3 -0
  109. package/dist/tools/code-connect-context.js +319 -0
  110. package/dist/tools/code-connect-context.js.map +1 -0
  111. package/dist/tools/code-connect-template.d.ts +3 -0
  112. package/dist/tools/code-connect-template.js +111 -0
  113. package/dist/tools/code-connect-template.js.map +1 -0
  114. package/dist/tools/composition.js +13 -28
  115. package/dist/tools/composition.js.map +1 -1
  116. package/dist/tools/compositions-orchestration.d.ts +14 -14
  117. package/dist/tools/compositions-orchestration.js +2 -2
  118. package/dist/tools/compositions-orchestration.js.map +1 -1
  119. package/dist/tools/data.js +839 -27
  120. package/dist/tools/data.js.map +1 -1
  121. package/dist/tools/design-context.d.ts +3 -0
  122. package/dist/tools/design-context.js +197 -0
  123. package/dist/tools/design-context.js.map +1 -0
  124. package/dist/tools/destructive-confirmation.d.ts +10 -0
  125. package/dist/tools/destructive-confirmation.js +22 -0
  126. package/dist/tools/destructive-confirmation.js.map +1 -0
  127. package/dist/tools/diagnostics.js +76 -51
  128. package/dist/tools/diagnostics.js.map +1 -1
  129. package/dist/tools/figma-mcp-design.d.ts +3 -0
  130. package/dist/tools/figma-mcp-design.js +377 -0
  131. package/dist/tools/figma-mcp-design.js.map +1 -0
  132. package/dist/tools/figma-nodes.js +57 -43
  133. package/dist/tools/figma-nodes.js.map +1 -1
  134. package/dist/tools/figma-rc-extended.js +23 -6
  135. package/dist/tools/figma-rc-extended.js.map +1 -1
  136. package/dist/tools/figma-rest.d.ts +39 -0
  137. package/dist/tools/figma-rest.js +279 -0
  138. package/dist/tools/figma-rest.js.map +1 -0
  139. package/dist/tools/git.js +11 -7
  140. package/dist/tools/git.js.map +1 -1
  141. package/dist/tools/large-data.d.ts +14 -0
  142. package/dist/tools/large-data.js +189 -0
  143. package/dist/tools/large-data.js.map +1 -0
  144. package/dist/tools/meta.d.ts +6 -1
  145. package/dist/tools/meta.js +89 -11
  146. package/dist/tools/meta.js.map +1 -1
  147. package/dist/tools/metadata.d.ts +3 -0
  148. package/dist/tools/metadata.js +140 -0
  149. package/dist/tools/metadata.js.map +1 -0
  150. package/dist/tools/mockup.d.ts +15 -156
  151. package/dist/tools/mockup.js +54 -121
  152. package/dist/tools/mockup.js.map +1 -1
  153. package/dist/tools/orchestration.js +73 -45
  154. package/dist/tools/orchestration.js.map +1 -1
  155. package/dist/tools/prompts.d.ts +3 -0
  156. package/dist/tools/prompts.js +219 -0
  157. package/dist/tools/prompts.js.map +1 -0
  158. package/dist/tools/registry.d.ts +19 -1
  159. package/dist/tools/registry.js +4 -4
  160. package/dist/tools/registry.js.map +1 -1
  161. package/dist/tools/resources.d.ts +19 -2
  162. package/dist/tools/resources.js +149 -5
  163. package/dist/tools/resources.js.map +1 -1
  164. package/dist/tools/schema-contracts.d.ts +4763 -0
  165. package/dist/tools/schema-contracts.js +814 -0
  166. package/dist/tools/schema-contracts.js.map +1 -0
  167. package/dist/tools/screenshot.d.ts +3 -0
  168. package/dist/tools/screenshot.js +144 -0
  169. package/dist/tools/screenshot.js.map +1 -0
  170. package/dist/tools/shared.d.ts +11 -1
  171. package/dist/tools/shared.js +55 -2
  172. package/dist/tools/shared.js.map +1 -1
  173. package/dist/tools/styles-orchestration.d.ts +2 -2
  174. package/dist/tools/styles-orchestration.js +13 -5
  175. package/dist/tools/styles-orchestration.js.map +1 -1
  176. package/dist/tools/styles.js +22 -8
  177. package/dist/tools/styles.js.map +1 -1
  178. package/dist/tools/tokens.d.ts +31 -692
  179. package/dist/tools/tokens.js +175 -135
  180. package/dist/tools/tokens.js.map +1 -1
  181. package/dist/tools/variable-defs.d.ts +3 -0
  182. package/dist/tools/variable-defs.js +338 -0
  183. package/dist/tools/variable-defs.js.map +1 -0
  184. package/dist/tools/variables-orchestration.js +13 -5
  185. package/dist/tools/variables-orchestration.js.map +1 -1
  186. package/dist/tools/variables.js +18 -15
  187. package/dist/tools/variables.js.map +1 -1
  188. package/dist/types.d.ts +53 -0
  189. package/dist/ultimate-readiness-audit.d.ts +37 -0
  190. package/dist/ultimate-readiness-audit.js +431 -0
  191. package/dist/ultimate-readiness-audit.js.map +1 -0
  192. package/dist/workflow-planner.d.ts +57 -0
  193. package/dist/workflow-planner.js +464 -0
  194. package/dist/workflow-planner.js.map +1 -0
  195. package/dist/ws-server.js +16 -3
  196. package/dist/ws-server.js.map +1 -1
  197. package/package.json +18 -2
@@ -0,0 +1,377 @@
1
+ import { z } from "zod";
2
+ import { buildEnabledLibrarySearchResult } from "../enabled-library-search.js";
3
+ import { figmaRestGet, fileKeyFromArgs, FigmaRestError, } from "../figma-rest.js";
4
+ import { largeDataResponseArgs, normalizeLargeDataResult } from "./large-data.js";
5
+ import { err, executePluginCommand, ok } from "./shared.js";
6
+ import { searchFigmaRestDesignSystem } from "./figma-rest.js";
7
+ const authModeZod = z.enum(["bearer", "x-figma-token"]);
8
+ const sourceZod = z.enum(["active-file", "enabled-libraries", "rest-known", "all"]);
9
+ const librarySearchKindZod = z.enum(["components", "componentSets", "styles", "variables", "variableCollections"]);
10
+ const restAuthArgs = {
11
+ tokenEnv: z
12
+ .string()
13
+ .regex(/^[A-Z0-9_]+$/)
14
+ .optional()
15
+ .describe("Environment variable containing the Figma REST token. Default: FIGMA_TOKEN, FIGMA_ACCESS_TOKEN, or FIGMA_REST_TOKEN."),
16
+ authMode: authModeZod.optional().describe("Figma REST auth header mode. Default: FIGMA_AUTH_MODE or x-figma-token."),
17
+ apiBaseUrl: z.string().url().optional().describe("Figma REST API base URL. Default: https://api.figma.com."),
18
+ };
19
+ const knownRestSourceArgs = {
20
+ fileKey: z.string().optional().describe("Known Figma library file key. Provide this or url for REST file-library reads."),
21
+ url: z.string().url().optional().describe("Known Figma file/library URL. Used to extract fileKey when fileKey is omitted."),
22
+ teamId: z.string().optional().describe("Known Figma team id for REST team-library reads."),
23
+ };
24
+ function isRecord(value) {
25
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
26
+ }
27
+ function readArray(body, key) {
28
+ if (!isRecord(body))
29
+ return [];
30
+ const meta = isRecord(body.meta) ? body.meta : body;
31
+ const value = meta[key];
32
+ return Array.isArray(value) ? value : [];
33
+ }
34
+ function readVariableArray(body) {
35
+ if (!isRecord(body) || !isRecord(body.meta) || !isRecord(body.meta.variables))
36
+ return [];
37
+ return Object.values(body.meta.variables);
38
+ }
39
+ function clientOptions(args) {
40
+ return {
41
+ tokenEnv: args.tokenEnv,
42
+ authMode: args.authMode,
43
+ apiBaseUrl: args.apiBaseUrl,
44
+ };
45
+ }
46
+ function restErrorInfo(error) {
47
+ if (error instanceof FigmaRestError) {
48
+ return {
49
+ message: error.message,
50
+ status: error.status,
51
+ endpoint: error.endpoint,
52
+ retryable: error.status === 429 || error.status >= 500,
53
+ };
54
+ }
55
+ return {
56
+ message: error instanceof Error ? error.message : String(error),
57
+ retryable: false,
58
+ };
59
+ }
60
+ function hasRestSource(args) {
61
+ return Boolean(args.fileKey || args.url || args.teamId);
62
+ }
63
+ function limitPerKind(args) {
64
+ return Math.max(1, Math.min(200, Math.floor(args.limitPerKind ?? 100)));
65
+ }
66
+ async function collectRestArray(errors, source, bodyPromise, key) {
67
+ try {
68
+ return readArray(await bodyPromise, key);
69
+ }
70
+ catch (error) {
71
+ errors.push({ source, ...restErrorInfo(error) });
72
+ return [];
73
+ }
74
+ }
75
+ async function collectKnownRestLibraries(args) {
76
+ if (!hasRestSource(args))
77
+ return null;
78
+ const opts = clientOptions(args);
79
+ const fileKey = args.fileKey || args.url ? fileKeyFromArgs(args) : null;
80
+ const teamId = args.teamId ?? null;
81
+ const errors = [];
82
+ const result = {
83
+ ok: true,
84
+ source: "figma-rest-known-libraries",
85
+ fileKey,
86
+ teamId,
87
+ components: [],
88
+ componentSets: [],
89
+ styles: [],
90
+ variables: [],
91
+ errors,
92
+ };
93
+ if (fileKey) {
94
+ if (args.includeComponents !== false) {
95
+ result.components = await collectRestArray(errors, "file.components", figmaRestGet(`/v1/files/${fileKey}/components`, opts), "components");
96
+ }
97
+ if (args.includeComponentSets !== false) {
98
+ result.componentSets = await collectRestArray(errors, "file.component_sets", figmaRestGet(`/v1/files/${fileKey}/component_sets`, opts), "component_sets");
99
+ }
100
+ if (args.includeStyles !== false) {
101
+ result.styles = await collectRestArray(errors, "file.styles", figmaRestGet(`/v1/files/${fileKey}/styles`, opts), "styles");
102
+ }
103
+ if (args.includeVariables === true) {
104
+ try {
105
+ result.variables = readVariableArray(await figmaRestGet(`/v1/files/${fileKey}/variables/local`, opts));
106
+ }
107
+ catch (error) {
108
+ errors.push({ source: "file.variables.local", ...restErrorInfo(error) });
109
+ }
110
+ }
111
+ }
112
+ if (teamId) {
113
+ const pageSize = limitPerKind(args);
114
+ if (args.includeComponents !== false) {
115
+ result.teamComponents = await collectRestArray(errors, "team.components", figmaRestGet(`/v1/teams/${teamId}/components`, { ...opts, query: { page_size: pageSize } }), "components");
116
+ }
117
+ if (args.includeComponentSets !== false) {
118
+ result.teamComponentSets = await collectRestArray(errors, "team.component_sets", figmaRestGet(`/v1/teams/${teamId}/component_sets`, { ...opts, query: { page_size: pageSize } }), "component_sets");
119
+ }
120
+ if (args.includeStyles !== false) {
121
+ result.teamStyles = await collectRestArray(errors, "team.styles", figmaRestGet(`/v1/teams/${teamId}/styles`, { ...opts, query: { page_size: pageSize } }), "styles");
122
+ }
123
+ }
124
+ return result;
125
+ }
126
+ function enabledKinds(include) {
127
+ if (!include || include.length === 0)
128
+ return ["component", "style", "variable", "variableCollection"];
129
+ const kinds = new Set();
130
+ if (include.includes("components") || include.includes("componentSets"))
131
+ kinds.add("component");
132
+ if (include.includes("styles"))
133
+ kinds.add("style");
134
+ if (include.includes("variables"))
135
+ kinds.add("variable");
136
+ if (include.includes("variableCollections"))
137
+ kinds.add("variableCollection");
138
+ return [...kinds];
139
+ }
140
+ function restKinds(include) {
141
+ if (!include || include.length === 0)
142
+ return ["components", "componentSets", "styles", "variables"];
143
+ return include.filter((kind) => kind === "components" || kind === "componentSets" || kind === "styles" || kind === "variables");
144
+ }
145
+ function shouldUseEnabledLibraries(source) {
146
+ return source !== "rest-known";
147
+ }
148
+ function shouldUseLocalComponents(source) {
149
+ return source === undefined || source === "all" || source === "active-file";
150
+ }
151
+ function shouldUseRest(source) {
152
+ return source === "rest-known" || source === "all" || source === undefined;
153
+ }
154
+ function readComponents(result) {
155
+ if (!isRecord(result) || !Array.isArray(result.components))
156
+ return [];
157
+ return result.components.filter(isRecord);
158
+ }
159
+ function textMatches(query, item) {
160
+ const haystack = [item.name, item.description, item.key, item.id]
161
+ .filter((value) => typeof value === "string")
162
+ .join(" ")
163
+ .toLowerCase();
164
+ return haystack.includes(query.trim().toLowerCase());
165
+ }
166
+ export function registerFigmaMcpDesignCompatibilityTools(server, queue) {
167
+ server.tool("get_libraries", "Figma MCP-compatible library discovery for Bridge. Returns libraries/assets available through the active SXL plugin file and/or known REST file/team library sources. It cannot enumerate arbitrary community/org libraries or add libraries to a file.", {
168
+ source: sourceZod.optional().describe("Default all. active-file/enabled-libraries uses Remote Connect; rest-known uses fileKey/url/teamId."),
169
+ query: z.string().optional(),
170
+ includeComponents: z.boolean().optional(),
171
+ includeComponentSets: z.boolean().optional(),
172
+ includeStyles: z.boolean().optional(),
173
+ includeVariables: z.boolean().optional().describe("Default false for get_libraries to avoid huge scans."),
174
+ limitPerKind: z.number().int().positive().max(5_000).optional(),
175
+ ...knownRestSourceArgs,
176
+ ...restAuthArgs,
177
+ ...largeDataResponseArgs,
178
+ }, async (args) => {
179
+ const source = args.source ?? "all";
180
+ const warnings = [];
181
+ const errors = [];
182
+ const result = {
183
+ ok: true,
184
+ tool: "get_libraries",
185
+ compatibility: "figma-mcp-design",
186
+ source,
187
+ limitations: [
188
+ "Bridge covers active-file enabled libraries through SXL Studio Remote Connect.",
189
+ "Bridge covers known file/team libraries through Figma REST when fileKey/url/teamId and token are configured.",
190
+ "Bridge cannot enumerate arbitrary available community/org libraries or add libraries to a file.",
191
+ ],
192
+ activeFile: null,
193
+ knownRest: null,
194
+ warnings,
195
+ errors,
196
+ };
197
+ if (shouldUseEnabledLibraries(source)) {
198
+ try {
199
+ const descriptors = await executePluginCommand(queue, "inspect_enabled_libraries", {
200
+ query: args.query,
201
+ limitPerKind: args.limitPerKind ?? 500,
202
+ includeVariableCollections: true,
203
+ includeStyles: args.includeStyles !== false,
204
+ includeComponents: args.includeComponents !== false,
205
+ });
206
+ const activeFile = { descriptors };
207
+ if (args.includeVariables === true) {
208
+ activeFile.variables = await executePluginCommand(queue, "list_enabled_library_variables", {
209
+ query: args.query,
210
+ includeAllCollections: true,
211
+ limit: args.limitPerKind ?? 1_000,
212
+ });
213
+ }
214
+ result.activeFile = activeFile;
215
+ }
216
+ catch (error) {
217
+ errors.push({ source: "active-file.enabled-libraries", message: error instanceof Error ? error.message : String(error) });
218
+ }
219
+ }
220
+ if (shouldUseRest(source)) {
221
+ try {
222
+ result.knownRest = await collectKnownRestLibraries({
223
+ ...args,
224
+ includeVariables: args.includeVariables === true,
225
+ });
226
+ if (!result.knownRest && source === "rest-known") {
227
+ warnings.push("rest-known source requires fileKey, url, or teamId.");
228
+ }
229
+ }
230
+ catch (error) {
231
+ errors.push({ source: "rest-known", ...restErrorInfo(error) });
232
+ }
233
+ }
234
+ if (!result.activeFile && !result.knownRest && errors.length > 0) {
235
+ return err("get_libraries could not read any configured library source.", {
236
+ code: "GET_LIBRARIES_NO_SOURCE",
237
+ retryable: errors.some((entry) => entry.retryable === true),
238
+ errors,
239
+ warnings,
240
+ });
241
+ }
242
+ return ok(normalizeLargeDataResult("get_libraries", args, result));
243
+ });
244
+ server.tool("search_design_system", "Figma MCP-compatible design-system search for Bridge. Searches active-file components, enabled libraries, and/or known REST file/team libraries for components, component sets, styles, variables, and variable collections.", {
245
+ query: z.string().min(1),
246
+ source: sourceZod.optional().describe("Default all. active-file includes local components and enabled libraries; rest-known uses fileKey/url/teamId."),
247
+ include: z.array(librarySearchKindZod).optional(),
248
+ limit: z.number().int().positive().max(500).optional(),
249
+ maxVariables: z.number().int().positive().max(10_000).optional(),
250
+ libraryName: z.string().optional(),
251
+ collectionKey: z.string().optional(),
252
+ collectionName: z.string().optional(),
253
+ ...knownRestSourceArgs,
254
+ ...restAuthArgs,
255
+ ...largeDataResponseArgs,
256
+ }, async (args) => {
257
+ const source = args.source ?? "all";
258
+ const include = args.include ?? ["components", "componentSets", "styles", "variables", "variableCollections"];
259
+ const warnings = [];
260
+ const errors = [];
261
+ const items = [];
262
+ const sections = {};
263
+ if (shouldUseLocalComponents(source) && include.some((kind) => kind === "components" || kind === "componentSets")) {
264
+ try {
265
+ const local = await executePluginCommand(queue, "find_components", {
266
+ query: args.query,
267
+ kind: "ALL",
268
+ includeProperties: true,
269
+ includeRemoteInstances: true,
270
+ limit: args.limit ?? 100,
271
+ });
272
+ const components = readComponents(local).filter((item) => textMatches(args.query, item));
273
+ sections.localComponents = { ...isRecord(local) ? local : {}, components };
274
+ for (const component of components) {
275
+ items.push({ source: "active-file-components", kind: "component", ...component });
276
+ }
277
+ }
278
+ catch (error) {
279
+ errors.push({ source: "active-file.components", message: error instanceof Error ? error.message : String(error) });
280
+ }
281
+ }
282
+ if (shouldUseEnabledLibraries(source)) {
283
+ try {
284
+ const inspectResult = await executePluginCommand(queue, "inspect_enabled_libraries", {
285
+ query: args.query,
286
+ limitPerKind: args.limit ?? 100,
287
+ includeComponents: include.includes("components") || include.includes("componentSets"),
288
+ includeStyles: include.includes("styles"),
289
+ includeVariableCollections: include.includes("variableCollections") || include.includes("variables"),
290
+ });
291
+ let variableResult;
292
+ if (include.includes("variables")) {
293
+ try {
294
+ variableResult = await executePluginCommand(queue, "list_enabled_library_variables", {
295
+ query: args.query,
296
+ collectionKey: args.collectionKey,
297
+ collectionName: args.collectionName,
298
+ libraryName: args.libraryName,
299
+ includeAllCollections: !args.collectionKey && !args.collectionName && !args.libraryName,
300
+ limit: args.maxVariables ?? 1_000,
301
+ });
302
+ }
303
+ catch (error) {
304
+ warnings.push(`Enabled-library variable scan failed: ${error instanceof Error ? error.message : String(error)}`);
305
+ }
306
+ }
307
+ const enabled = buildEnabledLibrarySearchResult({
308
+ args: {
309
+ query: args.query,
310
+ kinds: enabledKinds(include),
311
+ libraryName: args.libraryName,
312
+ collectionKey: args.collectionKey,
313
+ collectionName: args.collectionName,
314
+ maxMatches: args.limit,
315
+ },
316
+ inspectResult,
317
+ variableResult,
318
+ warnings,
319
+ });
320
+ sections.enabledLibraries = enabled;
321
+ for (const match of enabled.matches) {
322
+ items.push({ source: "enabled-library", ...match });
323
+ }
324
+ }
325
+ catch (error) {
326
+ errors.push({ source: "enabled-libraries", message: error instanceof Error ? error.message : String(error) });
327
+ }
328
+ }
329
+ if (shouldUseRest(source) && hasRestSource(args)) {
330
+ try {
331
+ const rest = await searchFigmaRestDesignSystem({
332
+ ...args,
333
+ include: restKinds(include),
334
+ limit: args.limit,
335
+ });
336
+ sections.knownRest = rest;
337
+ for (const item of rest.items) {
338
+ items.push({ ...item, source: `rest-${item.source}`, restSource: item.source });
339
+ }
340
+ }
341
+ catch (error) {
342
+ errors.push({ source: "rest-known", ...restErrorInfo(error) });
343
+ }
344
+ }
345
+ else if (source === "rest-known") {
346
+ warnings.push("rest-known source requires fileKey, url, or teamId.");
347
+ }
348
+ const limitedItems = items.slice(0, args.limit ?? 100);
349
+ if (limitedItems.length === 0 && errors.length > 0) {
350
+ return err("search_design_system could not read any configured design-system source.", {
351
+ code: "SEARCH_DESIGN_SYSTEM_NO_SOURCE",
352
+ retryable: errors.some((entry) => entry.retryable === true),
353
+ errors,
354
+ warnings,
355
+ });
356
+ }
357
+ return ok(normalizeLargeDataResult("search_design_system", args, {
358
+ ok: true,
359
+ tool: "search_design_system",
360
+ compatibility: "figma-mcp-design",
361
+ source,
362
+ query: args.query,
363
+ count: limitedItems.length,
364
+ truncated: items.length > limitedItems.length,
365
+ items: limitedItems,
366
+ sections,
367
+ warnings,
368
+ errors,
369
+ limitations: [
370
+ "Bridge searches active-file components and enabled libraries through SXL Studio Remote Connect.",
371
+ "Bridge searches known file/team libraries through Figma REST when fileKey/url/teamId and token are configured.",
372
+ "Bridge cannot discover arbitrary available community/org libraries without an official remote Figma MCP source.",
373
+ ],
374
+ }));
375
+ });
376
+ }
377
+ //# sourceMappingURL=figma-mcp-design.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-mcp-design.js","sourceRoot":"","sources":["../../src/tools/figma-mcp-design.ts"],"names":[],"mappings":"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"}
@@ -5,13 +5,14 @@
5
5
  * reading nodes, modifying properties, navigation, creation, deletion.
6
6
  */
7
7
  import { z } from "zod";
8
+ import { callPluginCommand, callPluginWriteCommand } from "./shared.js";
9
+ import { destructiveConfirmationArgs, withDestructiveConfirmation } from "./destructive-confirmation.js";
8
10
  export function registerFigmaNodeTools(server, queue) {
9
11
  // ─── Reading ───
10
12
  server.tool("get_node_info", "Get detailed information about selected nodes or a specific node by ID. Returns type, name, size, position, text content, component properties, composition binding, and child count.", {
11
13
  nodeId: z.string().optional().describe("Specific node ID. Omit to use current selection."),
12
14
  }, async ({ nodeId }) => {
13
- const result = await queue.execute("get_node_info", nodeId ? { nodeId } : {});
14
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
15
+ return callPluginCommand(queue, "get_node_info", nodeId ? { nodeId } : {});
15
16
  });
16
17
  server.tool("get_node_tree", "Get the node tree (hierarchy) of selected nodes or a specific node. Returns nested children up to a specified depth.", {
17
18
  nodeId: z.string().optional().describe("Root node ID. Omit to use current selection."),
@@ -22,19 +23,18 @@ export function registerFigmaNodeTools(server, queue) {
22
23
  payload.nodeId = nodeId;
23
24
  if (depth)
24
25
  payload.depth = depth;
25
- const result = await queue.execute("get_node_tree", payload);
26
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
26
+ return callPluginCommand(queue, "get_node_tree", payload);
27
27
  });
28
28
  // ─── Selection & Navigation ───
29
29
  server.tool("select_nodes", "Select specific nodes in Figma by their IDs. Scrolls viewport to show selected nodes.", {
30
30
  nodeIds: z.array(z.string()).describe("Array of node IDs to select"),
31
31
  }, async ({ nodeIds }) => {
32
- const result = await queue.execute("select_nodes", { nodeIds });
33
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
32
+ return callPluginWriteCommand(queue, "select_nodes", { nodeIds }, {
33
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
34
+ });
34
35
  });
35
36
  server.tool("get_pages", "List all pages in the current Figma file. Shows which page is currently active.", {}, async () => {
36
- const result = await queue.execute("get_pages", {});
37
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
37
+ return callPluginCommand(queue, "get_pages", {});
38
38
  });
39
39
  server.tool("set_current_page", "Switch to a different page in the Figma file.", {
40
40
  pageId: z.string().optional().describe("Page ID to switch to"),
@@ -45,8 +45,9 @@ export function registerFigmaNodeTools(server, queue) {
45
45
  payload.pageId = pageId;
46
46
  if (pageName)
47
47
  payload.pageName = pageName;
48
- const result = await queue.execute("set_current_page", payload);
49
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
48
+ return callPluginWriteCommand(queue, "set_current_page", payload, {
49
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
50
+ });
50
51
  });
51
52
  // ─── Visual Properties ───
52
53
  server.tool("set_node_fill", "Set the fill color of selected nodes or a specific node. Uses hex color format.", {
@@ -59,8 +60,9 @@ export function registerFigmaNodeTools(server, queue) {
59
60
  payload.opacity = opacity;
60
61
  if (nodeId)
61
62
  payload.nodeId = nodeId;
62
- const result = await queue.execute("set_node_fill", payload);
63
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
63
+ return callPluginWriteCommand(queue, "set_node_fill", payload, {
64
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
65
+ });
64
66
  });
65
67
  server.tool("set_node_fill_variable", "Bind the first fill of selected nodes (or a node by ID) to a local COLOR variable. Requires variableId from the current file (e.g. from export_variables / variables API).", {
66
68
  variableId: z.string().describe("Figma variable id (COLOR)"),
@@ -69,8 +71,9 @@ export function registerFigmaNodeTools(server, queue) {
69
71
  const payload = { variableId };
70
72
  if (nodeId)
71
73
  payload.nodeId = nodeId;
72
- const result = await queue.execute("set_node_fill_variable", payload);
73
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
74
+ return callPluginWriteCommand(queue, "set_node_fill_variable", payload, {
75
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
76
+ });
74
77
  });
75
78
  server.tool("rename_node", "Rename selected nodes or a specific node.", {
76
79
  name: z.string().describe("New name for the node(s)"),
@@ -79,8 +82,9 @@ export function registerFigmaNodeTools(server, queue) {
79
82
  const payload = { name };
80
83
  if (nodeId)
81
84
  payload.nodeId = nodeId;
82
- const result = await queue.execute("rename_node", payload);
83
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
85
+ return callPluginWriteCommand(queue, "rename_node", payload, {
86
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
87
+ });
84
88
  });
85
89
  server.tool("set_node_visibility", "Show or hide selected nodes or a specific node.", {
86
90
  visible: z.boolean().describe("true = visible, false = hidden"),
@@ -89,8 +93,9 @@ export function registerFigmaNodeTools(server, queue) {
89
93
  const payload = { visible };
90
94
  if (nodeId)
91
95
  payload.nodeId = nodeId;
92
- const result = await queue.execute("set_node_visibility", payload);
93
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
96
+ return callPluginWriteCommand(queue, "set_node_visibility", payload, {
97
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
98
+ });
94
99
  });
95
100
  server.tool("set_node_size", "Resize selected nodes or a specific node.", {
96
101
  width: z.number().optional().describe("New width in pixels"),
@@ -104,8 +109,9 @@ export function registerFigmaNodeTools(server, queue) {
104
109
  payload.height = height;
105
110
  if (nodeId)
106
111
  payload.nodeId = nodeId;
107
- const result = await queue.execute("set_node_size", payload);
108
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
112
+ return callPluginWriteCommand(queue, "set_node_size", payload, {
113
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
114
+ });
109
115
  });
110
116
  // ─── Batch Data Insertion ───
111
117
  server.tool("insert_data", "Insert data into selected nodes by matching layer names to data keys. Supports single object or array of objects. When array is provided, each row maps to one selected node. Example: { 'label': 'Hello', 'description': 'World' } sets text on layers named 'label' and 'description'.", {
@@ -118,8 +124,9 @@ export function registerFigmaNodeTools(server, queue) {
118
124
  const payload = { data };
119
125
  if (nodeId)
120
126
  payload.nodeId = nodeId;
121
- const result = await queue.execute("insert_data", payload);
122
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
127
+ return callPluginWriteCommand(queue, "insert_data", payload, {
128
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
129
+ });
123
130
  });
124
131
  // ─── Create Nodes ───
125
132
  server.tool("create_frame", "Create a new frame on the current page or under an optional parent. Supports Auto Layout fields when layoutMode is HORIZONTAL or VERTICAL.", {
@@ -174,8 +181,9 @@ export function registerFigmaNodeTools(server, queue) {
174
181
  if (v !== undefined)
175
182
  payload[k] = v;
176
183
  }
177
- const result = await queue.execute("create_frame", payload);
178
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
184
+ return callPluginWriteCommand(queue, "create_frame", payload, {
185
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
186
+ });
179
187
  });
180
188
  server.tool("create_text", "Create a new text node on the current page or inside a parent (e.g. Auto Layout frame). Optional layout* fields apply when the parent uses Auto Layout.", {
181
189
  text: z.string().describe("Text content"),
@@ -206,8 +214,9 @@ export function registerFigmaNodeTools(server, queue) {
206
214
  if (v !== undefined)
207
215
  payload[k] = v;
208
216
  }
209
- const result = await queue.execute("create_text", payload);
210
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
217
+ return callPluginWriteCommand(queue, "create_text", payload, {
218
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
219
+ });
211
220
  });
212
221
  server.tool("create_rectangle", "Create a rectangle shape on the page or inside a parent frame. Optional hex fill and corner radius.", {
213
222
  name: z.string().optional(),
@@ -225,8 +234,9 @@ export function registerFigmaNodeTools(server, queue) {
225
234
  if (v !== undefined)
226
235
  payload[k] = v;
227
236
  }
228
- const result = await queue.execute("create_rectangle", payload);
229
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
237
+ return callPluginWriteCommand(queue, "create_rectangle", payload, {
238
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
239
+ });
230
240
  });
231
241
  server.tool("set_auto_layout", "Configure Auto Layout on a single FRAME, COMPONENT, or INSTANCE (same payload fields as create_frame layout*: layoutMode or direction alias, padding, itemSpacing or spacing alias, alignment, etc.).", {
232
242
  nodeId: z.string().optional().describe("Target node; omit if exactly one node is selected"),
@@ -273,21 +283,23 @@ export function registerFigmaNodeTools(server, queue) {
273
283
  if (v !== undefined)
274
284
  payload[k] = v;
275
285
  }
276
- const result = await queue.execute("set_auto_layout", payload);
277
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
286
+ return callPluginWriteCommand(queue, "set_auto_layout", payload, {
287
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
288
+ });
278
289
  });
279
290
  // ─── Delete / Clone ───
280
291
  server.tool("delete_nodes", "Delete nodes by their IDs or delete the current selection.", {
281
292
  nodeIds: z.array(z.string()).optional().describe("Node IDs to delete. Omit to delete current selection."),
282
- }, async ({ nodeIds }) => {
283
- const result = await queue.execute("delete_nodes", nodeIds ? { nodeIds } : {});
284
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
293
+ ...destructiveConfirmationArgs,
294
+ }, async ({ nodeIds, confirmDestructive, destructiveReason }) => {
295
+ return callPluginWriteCommand(queue, "delete_nodes", withDestructiveConfirmation(nodeIds ? { nodeIds } : {}, { confirmDestructive, destructiveReason }), { okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED" });
285
296
  });
286
297
  server.tool("clone_node", "Clone (duplicate) selected nodes or a specific node. The clone is placed next to the original.", {
287
298
  nodeId: z.string().optional().describe("Node ID to clone. Omit to clone current selection."),
288
299
  }, async ({ nodeId }) => {
289
- const result = await queue.execute("clone_node", nodeId ? { nodeId } : {});
290
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
300
+ return callPluginWriteCommand(queue, "clone_node", nodeId ? { nodeId } : {}, {
301
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
302
+ });
291
303
  });
292
304
  server.tool("duplicate_subtree", "Deep-clone a node subtree and append it under targetParentId (documentation templates, layout duplication).", {
293
305
  sourceNodeId: z.string().optional().describe("Root of subtree to clone; omit if exactly one node selected"),
@@ -302,8 +314,9 @@ export function registerFigmaNodeTools(server, queue) {
302
314
  payload.offsetX = offsetX;
303
315
  if (offsetY !== undefined)
304
316
  payload.offsetY = offsetY;
305
- const result = await queue.execute("duplicate_subtree", payload);
306
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
317
+ return callPluginWriteCommand(queue, "duplicate_subtree", payload, {
318
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
319
+ });
307
320
  });
308
321
  server.tool("create_component_instance", "Create an instance from a local COMPONENT (mainComponentId or componentId alias) or a published library (componentKey).", {
309
322
  mainComponentId: z.string().optional().describe("Node id of a COMPONENT in the current file"),
@@ -319,8 +332,9 @@ export function registerFigmaNodeTools(server, queue) {
319
332
  if (v !== undefined)
320
333
  payload[k] = v;
321
334
  }
322
- const result = await queue.execute("create_component_instance", payload);
323
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
335
+ return callPluginWriteCommand(queue, "create_component_instance", payload, {
336
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
337
+ });
324
338
  });
325
339
  server.tool("apply_documentation_payload", "Fill TEXT layers by layer name under targetRootId. Use after duplicating a doc template (entries: { layerName, text }[]).", {
326
340
  targetRootId: z.string().describe("Frame or group root to search under"),
@@ -329,8 +343,9 @@ export function registerFigmaNodeTools(server, queue) {
329
343
  text: z.string(),
330
344
  })).describe("Match TextNode.name; set characters"),
331
345
  }, async ({ targetRootId, entries }) => {
332
- const result = await queue.execute("apply_documentation_payload", { targetRootId, entries });
333
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
346
+ return callPluginWriteCommand(queue, "apply_documentation_payload", { targetRootId, entries }, {
347
+ okFalseErrorCode: "SXL_CANVAS_WRITE_FAILED",
348
+ });
334
349
  });
335
350
  // ─── Notifications ───
336
351
  server.tool("notify", "Show a notification message in Figma. Useful for user feedback during automated workflows.", {
@@ -340,8 +355,7 @@ export function registerFigmaNodeTools(server, queue) {
340
355
  const payload = { message };
341
356
  if (error)
342
357
  payload.error = error;
343
- const result = await queue.execute("notify", payload);
344
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
358
+ return callPluginCommand(queue, "notify", payload);
345
359
  });
346
360
  }
347
361
  //# sourceMappingURL=figma-nodes.js.map