@sxl-studio/bridge 1.7.2 → 1.8.0
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/README.md +342 -16
- package/dist/agent-recipes.d.ts +781 -11
- package/dist/agent-recipes.js +886 -13
- package/dist/agent-recipes.js.map +1 -1
- package/dist/agent-runbook.d.ts +50 -0
- package/dist/agent-runbook.js +243 -0
- package/dist/agent-runbook.js.map +1 -0
- package/dist/asset-upload.d.ts +63 -0
- package/dist/asset-upload.js +225 -0
- package/dist/asset-upload.js.map +1 -0
- package/dist/audit-store.d.ts +15 -0
- package/dist/audit-store.js +100 -0
- package/dist/audit-store.js.map +1 -0
- package/dist/audit.d.ts +4 -3
- package/dist/audit.js +37 -4
- package/dist/audit.js.map +1 -1
- package/dist/auth.d.ts +8 -1
- package/dist/auth.js +41 -1
- package/dist/auth.js.map +1 -1
- package/dist/bridge-agent-workflow-validation-cli.d.ts +2 -0
- package/dist/bridge-agent-workflow-validation-cli.js +68 -0
- package/dist/bridge-agent-workflow-validation-cli.js.map +1 -0
- package/dist/bridge-agent-workflow-validation.d.ts +42 -0
- package/dist/bridge-agent-workflow-validation.js +170 -0
- package/dist/bridge-agent-workflow-validation.js.map +1 -0
- package/dist/bridge-contract-audit.d.ts +45 -0
- package/dist/bridge-contract-audit.js +345 -0
- package/dist/bridge-contract-audit.js.map +1 -0
- package/dist/bridge-health-cli.d.ts +2 -0
- package/dist/bridge-health-cli.js +115 -0
- package/dist/bridge-health-cli.js.map +1 -0
- package/dist/bridge-health.d.ts +33 -0
- package/dist/bridge-health.js +594 -0
- package/dist/bridge-health.js.map +1 -0
- package/dist/bridge-live-validation-cli.d.ts +2 -0
- package/dist/bridge-live-validation-cli.js +114 -0
- package/dist/bridge-live-validation-cli.js.map +1 -0
- package/dist/bridge-live-validation.d.ts +39 -0
- package/dist/bridge-live-validation.js +1141 -0
- package/dist/bridge-live-validation.js.map +1 -0
- package/dist/bridge-performance-profile.d.ts +81 -0
- package/dist/bridge-performance-profile.js +227 -0
- package/dist/bridge-performance-profile.js.map +1 -0
- package/dist/bridge-readiness-cli.d.ts +30 -0
- package/dist/bridge-readiness-cli.js +242 -0
- package/dist/bridge-readiness-cli.js.map +1 -0
- package/dist/bridge-runtime-summary.d.ts +50 -0
- package/dist/bridge-runtime-summary.js +112 -0
- package/dist/bridge-runtime-summary.js.map +1 -0
- package/dist/bridge-workflow-smoke-cli.d.ts +2 -0
- package/dist/bridge-workflow-smoke-cli.js +126 -0
- package/dist/bridge-workflow-smoke-cli.js.map +1 -0
- package/dist/bridge-workflow-smoke.d.ts +39 -0
- package/dist/bridge-workflow-smoke.js +431 -0
- package/dist/bridge-workflow-smoke.js.map +1 -0
- package/dist/codeconnect-suggestions.d.ts +74 -0
- package/dist/codeconnect-suggestions.js +398 -0
- package/dist/codeconnect-suggestions.js.map +1 -0
- package/dist/codeconnect-template.d.ts +98 -0
- package/dist/codeconnect-template.js +280 -0
- package/dist/codeconnect-template.js.map +1 -0
- package/dist/command-queue.d.ts +11 -1
- package/dist/command-queue.js +200 -1
- package/dist/command-queue.js.map +1 -1
- package/dist/command-safety.d.ts +13 -0
- package/dist/command-safety.js +59 -0
- package/dist/command-safety.js.map +1 -0
- package/dist/enabled-library-search.d.ts +49 -0
- package/dist/enabled-library-search.js +151 -0
- package/dist/enabled-library-search.js.map +1 -0
- package/dist/figma-mcp-parity.d.ts +49 -0
- package/dist/figma-mcp-parity.js +368 -0
- package/dist/figma-mcp-parity.js.map +1 -0
- package/dist/figma-mcp-skills-parity.d.ts +61 -0
- package/dist/figma-mcp-skills-parity.js +434 -0
- package/dist/figma-mcp-skills-parity.js.map +1 -0
- package/dist/figma-rest-diagnostics.d.ts +50 -0
- package/dist/figma-rest-diagnostics.js +314 -0
- package/dist/figma-rest-diagnostics.js.map +1 -0
- package/dist/figma-rest.d.ts +27 -0
- package/dist/figma-rest.js +116 -0
- package/dist/figma-rest.js.map +1 -0
- package/dist/http-api.d.ts +16 -2
- package/dist/http-api.js +329 -17
- package/dist/http-api.js.map +1 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-factory.d.ts +6 -1
- package/dist/mcp-factory.js +23 -4
- package/dist/mcp-factory.js.map +1 -1
- package/dist/mcp-runtime-probe.d.ts +22 -0
- package/dist/mcp-runtime-probe.js +777 -0
- package/dist/mcp-runtime-probe.js.map +1 -0
- package/dist/mcp-server.d.ts +2 -1
- package/dist/mcp-server.js +2 -2
- package/dist/mcp-server.js.map +1 -1
- package/dist/sxl-mcp-instructions.js +99 -26
- package/dist/sxl-mcp-instructions.js.map +1 -1
- package/dist/tools/audit.d.ts +22 -6
- package/dist/tools/audit.js +49 -7
- package/dist/tools/audit.js.map +1 -1
- package/dist/tools/capability-matrix.d.ts +22 -0
- package/dist/tools/capability-matrix.js +38 -0
- package/dist/tools/capability-matrix.js.map +1 -0
- package/dist/tools/catalogue-bootstrap.d.ts +1 -0
- package/dist/tools/catalogue-bootstrap.js +665 -30
- package/dist/tools/catalogue-bootstrap.js.map +1 -1
- package/dist/tools/code-connect-context.d.ts +3 -0
- package/dist/tools/code-connect-context.js +319 -0
- package/dist/tools/code-connect-context.js.map +1 -0
- package/dist/tools/code-connect-template.d.ts +3 -0
- package/dist/tools/code-connect-template.js +111 -0
- package/dist/tools/code-connect-template.js.map +1 -0
- package/dist/tools/composition.js +15 -30
- package/dist/tools/composition.js.map +1 -1
- package/dist/tools/compositions-orchestration.d.ts +14 -14
- package/dist/tools/compositions-orchestration.js +2 -2
- package/dist/tools/compositions-orchestration.js.map +1 -1
- package/dist/tools/data.js +839 -27
- package/dist/tools/data.js.map +1 -1
- package/dist/tools/design-context.d.ts +3 -0
- package/dist/tools/design-context.js +197 -0
- package/dist/tools/design-context.js.map +1 -0
- package/dist/tools/destructive-confirmation.d.ts +10 -0
- package/dist/tools/destructive-confirmation.js +25 -0
- package/dist/tools/destructive-confirmation.js.map +1 -0
- package/dist/tools/diagnostics.js +76 -51
- package/dist/tools/diagnostics.js.map +1 -1
- package/dist/tools/figma-mcp-design.d.ts +3 -0
- package/dist/tools/figma-mcp-design.js +377 -0
- package/dist/tools/figma-mcp-design.js.map +1 -0
- package/dist/tools/figma-nodes.js +57 -43
- package/dist/tools/figma-nodes.js.map +1 -1
- package/dist/tools/figma-rc-extended.js +23 -6
- package/dist/tools/figma-rc-extended.js.map +1 -1
- package/dist/tools/figma-rest.d.ts +39 -0
- package/dist/tools/figma-rest.js +279 -0
- package/dist/tools/figma-rest.js.map +1 -0
- package/dist/tools/git.js +11 -7
- package/dist/tools/git.js.map +1 -1
- package/dist/tools/large-data.d.ts +14 -0
- package/dist/tools/large-data.js +189 -0
- package/dist/tools/large-data.js.map +1 -0
- package/dist/tools/meta.d.ts +6 -1
- package/dist/tools/meta.js +89 -11
- package/dist/tools/meta.js.map +1 -1
- package/dist/tools/metadata.d.ts +3 -0
- package/dist/tools/metadata.js +140 -0
- package/dist/tools/metadata.js.map +1 -0
- package/dist/tools/mockup.d.ts +15 -156
- package/dist/tools/mockup.js +54 -121
- package/dist/tools/mockup.js.map +1 -1
- package/dist/tools/orchestration.js +75 -47
- package/dist/tools/orchestration.js.map +1 -1
- package/dist/tools/prompts.d.ts +3 -0
- package/dist/tools/prompts.js +219 -0
- package/dist/tools/prompts.js.map +1 -0
- package/dist/tools/registry.d.ts +19 -1
- package/dist/tools/registry.js +4 -4
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/resources.d.ts +19 -2
- package/dist/tools/resources.js +149 -5
- package/dist/tools/resources.js.map +1 -1
- package/dist/tools/schema-contracts.d.ts +4763 -0
- package/dist/tools/schema-contracts.js +814 -0
- package/dist/tools/schema-contracts.js.map +1 -0
- package/dist/tools/screenshot.d.ts +3 -0
- package/dist/tools/screenshot.js +144 -0
- package/dist/tools/screenshot.js.map +1 -0
- package/dist/tools/shared.d.ts +11 -1
- package/dist/tools/shared.js +55 -2
- package/dist/tools/shared.js.map +1 -1
- package/dist/tools/styles-orchestration.d.ts +2 -2
- package/dist/tools/styles-orchestration.js +13 -5
- package/dist/tools/styles-orchestration.js.map +1 -1
- package/dist/tools/styles.js +22 -8
- package/dist/tools/styles.js.map +1 -1
- package/dist/tools/tokens.d.ts +31 -692
- package/dist/tools/tokens.js +175 -135
- package/dist/tools/tokens.js.map +1 -1
- package/dist/tools/variable-defs.d.ts +3 -0
- package/dist/tools/variable-defs.js +338 -0
- package/dist/tools/variable-defs.js.map +1 -0
- package/dist/tools/variables-orchestration.js +13 -5
- package/dist/tools/variables-orchestration.js.map +1 -1
- package/dist/tools/variables.js +18 -15
- package/dist/tools/variables.js.map +1 -1
- package/dist/types.d.ts +53 -0
- package/dist/ultimate-readiness-audit.d.ts +37 -0
- package/dist/ultimate-readiness-audit.js +431 -0
- package/dist/ultimate-readiness-audit.js.map +1 -0
- package/dist/workflow-planner.d.ts +57 -0
- package/dist/workflow-planner.js +464 -0
- package/dist/workflow-planner.js.map +1 -0
- package/dist/workspace-blob-store.d.ts +6 -0
- package/dist/workspace-blob-store.js +9 -0
- package/dist/workspace-blob-store.js.map +1 -1
- package/dist/workspace-path-http.d.ts +24 -0
- package/dist/workspace-path-http.js +146 -0
- package/dist/workspace-path-http.js.map +1 -0
- package/dist/ws-server.js +16 -3
- package/dist/ws-server.js.map +1 -1
- package/package.json +21 -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
33
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49
|
-
|
|
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
|
-
|
|
63
|
-
|
|
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
|
-
|
|
73
|
-
|
|
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
|
-
|
|
83
|
-
|
|
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
|
-
|
|
93
|
-
|
|
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
|
-
|
|
108
|
-
|
|
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
|
-
|
|
122
|
-
|
|
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
|
-
|
|
178
|
-
|
|
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
|
-
|
|
210
|
-
|
|
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
|
-
|
|
229
|
-
|
|
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
|
-
|
|
277
|
-
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
return
|
|
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
|
-
|
|
290
|
-
|
|
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
|
-
|
|
306
|
-
|
|
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
|
-
|
|
323
|
-
|
|
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
|
-
|
|
333
|
-
|
|
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
|
-
|
|
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
|