@mp3wizard/figma-console-mcp 1.14.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/LICENSE +21 -0
- package/README.md +816 -0
- package/dist/apps/design-system-dashboard/scoring/accessibility.d.ts +14 -0
- package/dist/apps/design-system-dashboard/scoring/accessibility.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/accessibility.js +278 -0
- package/dist/apps/design-system-dashboard/scoring/accessibility.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/component-metadata.d.ts +29 -0
- package/dist/apps/design-system-dashboard/scoring/component-metadata.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/component-metadata.js +358 -0
- package/dist/apps/design-system-dashboard/scoring/component-metadata.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/consistency.d.ts +14 -0
- package/dist/apps/design-system-dashboard/scoring/consistency.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/consistency.js +342 -0
- package/dist/apps/design-system-dashboard/scoring/consistency.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/coverage.d.ts +14 -0
- package/dist/apps/design-system-dashboard/scoring/coverage.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/coverage.js +231 -0
- package/dist/apps/design-system-dashboard/scoring/coverage.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/engine.d.ts +27 -0
- package/dist/apps/design-system-dashboard/scoring/engine.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/engine.js +93 -0
- package/dist/apps/design-system-dashboard/scoring/engine.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/naming-semantics.d.ts +14 -0
- package/dist/apps/design-system-dashboard/scoring/naming-semantics.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/naming-semantics.js +309 -0
- package/dist/apps/design-system-dashboard/scoring/naming-semantics.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/token-architecture.d.ts +14 -0
- package/dist/apps/design-system-dashboard/scoring/token-architecture.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/token-architecture.js +350 -0
- package/dist/apps/design-system-dashboard/scoring/token-architecture.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/types.d.ts +89 -0
- package/dist/apps/design-system-dashboard/scoring/types.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/types.js +41 -0
- package/dist/apps/design-system-dashboard/scoring/types.js.map +1 -0
- package/dist/apps/design-system-dashboard/server.d.ts +24 -0
- package/dist/apps/design-system-dashboard/server.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/server.js +160 -0
- package/dist/apps/design-system-dashboard/server.js.map +1 -0
- package/dist/apps/token-browser/server.d.ts +26 -0
- package/dist/apps/token-browser/server.d.ts.map +1 -0
- package/dist/apps/token-browser/server.js +137 -0
- package/dist/apps/token-browser/server.js.map +1 -0
- package/dist/browser/base.d.ts +58 -0
- package/dist/browser/base.d.ts.map +1 -0
- package/dist/browser/base.js +6 -0
- package/dist/browser/base.js.map +1 -0
- package/dist/browser/local.d.ts +87 -0
- package/dist/browser/local.d.ts.map +1 -0
- package/dist/browser/local.js +318 -0
- package/dist/browser/local.js.map +1 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/accessibility.js +277 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/component-metadata.js +357 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/consistency.js +341 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/coverage.js +230 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/engine.js +92 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/naming-semantics.js +308 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/token-architecture.js +349 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/types.js +40 -0
- package/dist/cloudflare/apps/design-system-dashboard/server.js +159 -0
- package/dist/cloudflare/apps/token-browser/server.js +136 -0
- package/dist/cloudflare/browser/base.js +5 -0
- package/dist/cloudflare/browser/cloudflare.js +156 -0
- package/dist/cloudflare/browser-manager.js +157 -0
- package/dist/cloudflare/core/cloud-websocket-connector.js +267 -0
- package/dist/cloudflare/core/cloud-websocket-relay.js +199 -0
- package/dist/cloudflare/core/comment-tools.js +292 -0
- package/dist/cloudflare/core/config.js +161 -0
- package/dist/cloudflare/core/console-monitor.js +427 -0
- package/dist/cloudflare/core/design-code-tools.js +2504 -0
- package/dist/cloudflare/core/design-system-manifest.js +260 -0
- package/dist/cloudflare/core/design-system-tools.js +863 -0
- package/dist/cloudflare/core/enrichment/enrichment-service.js +272 -0
- package/dist/cloudflare/core/enrichment/index.js +7 -0
- package/dist/cloudflare/core/enrichment/relationship-mapper.js +351 -0
- package/dist/cloudflare/core/enrichment/style-resolver.js +326 -0
- package/dist/cloudflare/core/figma-api.js +409 -0
- package/dist/cloudflare/core/figma-connector.js +7 -0
- package/dist/cloudflare/core/figma-desktop-connector.js +1184 -0
- package/dist/cloudflare/core/figma-reconstruction-spec.js +402 -0
- package/dist/cloudflare/core/figma-style-extractor.js +311 -0
- package/dist/cloudflare/core/figma-tools.js +2947 -0
- package/dist/cloudflare/core/logger.js +53 -0
- package/dist/cloudflare/core/port-discovery.js +282 -0
- package/dist/cloudflare/core/snippet-injector.js +96 -0
- package/dist/cloudflare/core/types/design-code.js +4 -0
- package/dist/cloudflare/core/types/enriched.js +5 -0
- package/dist/cloudflare/core/types/index.js +4 -0
- package/dist/cloudflare/core/websocket-connector.js +256 -0
- package/dist/cloudflare/core/websocket-server.js +646 -0
- package/dist/cloudflare/core/write-tools.js +2091 -0
- package/dist/cloudflare/index.js +2899 -0
- package/dist/cloudflare/test-browser.js +88 -0
- package/dist/core/comment-tools.d.ts +11 -0
- package/dist/core/comment-tools.d.ts.map +1 -0
- package/dist/core/comment-tools.js +293 -0
- package/dist/core/comment-tools.js.map +1 -0
- package/dist/core/config.d.ts +17 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +162 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/console-monitor.d.ts +82 -0
- package/dist/core/console-monitor.d.ts.map +1 -0
- package/dist/core/console-monitor.js +428 -0
- package/dist/core/console-monitor.js.map +1 -0
- package/dist/core/design-code-tools.d.ts +127 -0
- package/dist/core/design-code-tools.d.ts.map +1 -0
- package/dist/core/design-code-tools.js +2505 -0
- package/dist/core/design-code-tools.js.map +1 -0
- package/dist/core/design-system-manifest.d.ts +272 -0
- package/dist/core/design-system-manifest.d.ts.map +1 -0
- package/dist/core/design-system-manifest.js +261 -0
- package/dist/core/design-system-manifest.js.map +1 -0
- package/dist/core/design-system-tools.d.ts +17 -0
- package/dist/core/design-system-tools.d.ts.map +1 -0
- package/dist/core/design-system-tools.js +864 -0
- package/dist/core/design-system-tools.js.map +1 -0
- package/dist/core/enrichment/enrichment-service.d.ts +52 -0
- package/dist/core/enrichment/enrichment-service.d.ts.map +1 -0
- package/dist/core/enrichment/enrichment-service.js +273 -0
- package/dist/core/enrichment/enrichment-service.js.map +1 -0
- package/dist/core/enrichment/index.d.ts +8 -0
- package/dist/core/enrichment/index.d.ts.map +1 -0
- package/dist/core/enrichment/index.js +8 -0
- package/dist/core/enrichment/index.js.map +1 -0
- package/dist/core/enrichment/relationship-mapper.d.ts +106 -0
- package/dist/core/enrichment/relationship-mapper.d.ts.map +1 -0
- package/dist/core/enrichment/relationship-mapper.js +352 -0
- package/dist/core/enrichment/relationship-mapper.js.map +1 -0
- package/dist/core/enrichment/style-resolver.d.ts +80 -0
- package/dist/core/enrichment/style-resolver.d.ts.map +1 -0
- package/dist/core/enrichment/style-resolver.js +327 -0
- package/dist/core/enrichment/style-resolver.js.map +1 -0
- package/dist/core/figma-api.d.ts +201 -0
- package/dist/core/figma-api.d.ts.map +1 -0
- package/dist/core/figma-api.js +410 -0
- package/dist/core/figma-api.js.map +1 -0
- package/dist/core/figma-connector.d.ts +48 -0
- package/dist/core/figma-connector.d.ts.map +1 -0
- package/dist/core/figma-connector.js +8 -0
- package/dist/core/figma-connector.js.map +1 -0
- package/dist/core/figma-desktop-connector.d.ts +265 -0
- package/dist/core/figma-desktop-connector.d.ts.map +1 -0
- package/dist/core/figma-desktop-connector.js +1184 -0
- package/dist/core/figma-desktop-connector.js.map +1 -0
- package/dist/core/figma-reconstruction-spec.d.ts +166 -0
- package/dist/core/figma-reconstruction-spec.d.ts.map +1 -0
- package/dist/core/figma-reconstruction-spec.js +403 -0
- package/dist/core/figma-reconstruction-spec.js.map +1 -0
- package/dist/core/figma-style-extractor.d.ts +76 -0
- package/dist/core/figma-style-extractor.d.ts.map +1 -0
- package/dist/core/figma-style-extractor.js +312 -0
- package/dist/core/figma-style-extractor.js.map +1 -0
- package/dist/core/figma-tools.d.ts +23 -0
- package/dist/core/figma-tools.d.ts.map +1 -0
- package/dist/core/figma-tools.js +2948 -0
- package/dist/core/figma-tools.js.map +1 -0
- package/dist/core/logger.d.ts +22 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +54 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/port-discovery.d.ts +110 -0
- package/dist/core/port-discovery.d.ts.map +1 -0
- package/dist/core/port-discovery.js +283 -0
- package/dist/core/port-discovery.js.map +1 -0
- package/dist/core/snippet-injector.d.ts +24 -0
- package/dist/core/snippet-injector.d.ts.map +1 -0
- package/dist/core/snippet-injector.js +97 -0
- package/dist/core/snippet-injector.js.map +1 -0
- package/dist/core/types/design-code.d.ts +262 -0
- package/dist/core/types/design-code.d.ts.map +1 -0
- package/dist/core/types/design-code.js +5 -0
- package/dist/core/types/design-code.js.map +1 -0
- package/dist/core/types/enriched.d.ts +213 -0
- package/dist/core/types/enriched.d.ts.map +1 -0
- package/dist/core/types/enriched.js +6 -0
- package/dist/core/types/enriched.js.map +1 -0
- package/dist/core/types/index.d.ts +112 -0
- package/dist/core/types/index.d.ts.map +1 -0
- package/dist/core/types/index.js +5 -0
- package/dist/core/types/index.js.map +1 -0
- package/dist/core/websocket-connector.d.ts +55 -0
- package/dist/core/websocket-connector.d.ts.map +1 -0
- package/dist/core/websocket-connector.js +257 -0
- package/dist/core/websocket-connector.js.map +1 -0
- package/dist/core/websocket-server.d.ts +191 -0
- package/dist/core/websocket-server.d.ts.map +1 -0
- package/dist/core/websocket-server.js +647 -0
- package/dist/core/websocket-server.js.map +1 -0
- package/dist/core/write-tools.d.ts +7 -0
- package/dist/core/write-tools.d.ts.map +1 -0
- package/dist/core/write-tools.js +2092 -0
- package/dist/core/write-tools.js.map +1 -0
- package/dist/local.d.ts +84 -0
- package/dist/local.d.ts.map +1 -0
- package/dist/local.js +5039 -0
- package/dist/local.js.map +1 -0
- package/figma-desktop-bridge/README.md +313 -0
- package/figma-desktop-bridge/code.js +2818 -0
- package/figma-desktop-bridge/manifest.json +67 -0
- package/figma-desktop-bridge/ui.html +1236 -0
- package/package.json +87 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket Figma Connector
|
|
3
|
+
*
|
|
4
|
+
* Implements IFigmaConnector using the WebSocket Desktop Bridge transport.
|
|
5
|
+
* Each method sends a command to the plugin UI via WebSocket and waits
|
|
6
|
+
* for the response — same window.* functions, different transport.
|
|
7
|
+
*
|
|
8
|
+
* Data flow: MCP Server ←WebSocket→ ui.html ←postMessage→ code.js ←figma.*→ Figma
|
|
9
|
+
*/
|
|
10
|
+
import { createChildLogger } from './logger.js';
|
|
11
|
+
const logger = createChildLogger({ component: 'websocket-connector' });
|
|
12
|
+
export class WebSocketConnector {
|
|
13
|
+
constructor(wsServer) {
|
|
14
|
+
this.wsServer = wsServer;
|
|
15
|
+
}
|
|
16
|
+
async initialize() {
|
|
17
|
+
if (!this.wsServer.isClientConnected()) {
|
|
18
|
+
throw new Error('No WebSocket client connected. Make sure the Desktop Bridge plugin is open in Figma.');
|
|
19
|
+
}
|
|
20
|
+
logger.info('WebSocket connector initialized');
|
|
21
|
+
}
|
|
22
|
+
getTransportType() {
|
|
23
|
+
return 'websocket';
|
|
24
|
+
}
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Core execution
|
|
27
|
+
// ============================================================================
|
|
28
|
+
async executeInPluginContext(code) {
|
|
29
|
+
return this.wsServer.sendCommand('EXECUTE_CODE', { code, timeout: 5000 }, 7000);
|
|
30
|
+
}
|
|
31
|
+
async getVariablesFromPluginUI(fileKey) {
|
|
32
|
+
// Request the cached variables data that the plugin UI holds in window.__figmaVariablesData
|
|
33
|
+
return this.wsServer.sendCommand('GET_VARIABLES_DATA', {}, 10000, fileKey);
|
|
34
|
+
}
|
|
35
|
+
async getVariables(fileKey) {
|
|
36
|
+
// Execute the same variables-fetching code in the plugin worker context
|
|
37
|
+
const code = `
|
|
38
|
+
(async () => {
|
|
39
|
+
try {
|
|
40
|
+
if (typeof figma === 'undefined') {
|
|
41
|
+
throw new Error('Figma API not available in this context');
|
|
42
|
+
}
|
|
43
|
+
const variables = await figma.variables.getLocalVariablesAsync();
|
|
44
|
+
const collections = await figma.variables.getLocalVariableCollectionsAsync();
|
|
45
|
+
return {
|
|
46
|
+
success: true,
|
|
47
|
+
timestamp: Date.now(),
|
|
48
|
+
fileMetadata: { fileName: figma.root.name, fileKey: figma.fileKey || null },
|
|
49
|
+
variables: variables.map(function(v) { return { id: v.id, name: v.name, key: v.key, resolvedType: v.resolvedType, valuesByMode: v.valuesByMode, variableCollectionId: v.variableCollectionId, scopes: v.scopes, description: v.description, hiddenFromPublishing: v.hiddenFromPublishing }; }),
|
|
50
|
+
variableCollections: collections.map(function(c) { return { id: c.id, name: c.name, key: c.key, modes: c.modes, defaultModeId: c.defaultModeId, variableIds: c.variableIds }; })
|
|
51
|
+
};
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return { success: false, error: error.message };
|
|
54
|
+
}
|
|
55
|
+
})()
|
|
56
|
+
`;
|
|
57
|
+
return this.wsServer.sendCommand('EXECUTE_CODE', { code, timeout: 30000 }, 32000, fileKey);
|
|
58
|
+
}
|
|
59
|
+
async executeCodeViaUI(code, timeoutMs = 5000) {
|
|
60
|
+
return this.wsServer.sendCommand('EXECUTE_CODE', { code, timeout: timeoutMs }, timeoutMs + 2000);
|
|
61
|
+
}
|
|
62
|
+
// ============================================================================
|
|
63
|
+
// Variable operations
|
|
64
|
+
// ============================================================================
|
|
65
|
+
async updateVariable(variableId, modeId, value) {
|
|
66
|
+
return this.wsServer.sendCommand('UPDATE_VARIABLE', { variableId, modeId, value });
|
|
67
|
+
}
|
|
68
|
+
async createVariable(name, collectionId, resolvedType, options) {
|
|
69
|
+
const params = { name, collectionId, resolvedType };
|
|
70
|
+
if (options) {
|
|
71
|
+
if (options.valuesByMode)
|
|
72
|
+
params.valuesByMode = options.valuesByMode;
|
|
73
|
+
if (options.description)
|
|
74
|
+
params.description = options.description;
|
|
75
|
+
if (options.scopes)
|
|
76
|
+
params.scopes = options.scopes;
|
|
77
|
+
}
|
|
78
|
+
return this.wsServer.sendCommand('CREATE_VARIABLE', params);
|
|
79
|
+
}
|
|
80
|
+
async deleteVariable(variableId) {
|
|
81
|
+
return this.wsServer.sendCommand('DELETE_VARIABLE', { variableId });
|
|
82
|
+
}
|
|
83
|
+
async refreshVariables() {
|
|
84
|
+
return this.wsServer.sendCommand('REFRESH_VARIABLES', {}, 300000);
|
|
85
|
+
}
|
|
86
|
+
async renameVariable(variableId, newName) {
|
|
87
|
+
const result = await this.wsServer.sendCommand('RENAME_VARIABLE', { variableId, newName });
|
|
88
|
+
// oldName may be embedded in variable data if ui.html handleResult doesn't pass it through
|
|
89
|
+
if (!result.oldName && result.variable?.oldName)
|
|
90
|
+
result.oldName = result.variable.oldName;
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
async setVariableDescription(variableId, description) {
|
|
94
|
+
return this.wsServer.sendCommand('SET_VARIABLE_DESCRIPTION', { variableId, description });
|
|
95
|
+
}
|
|
96
|
+
// ============================================================================
|
|
97
|
+
// Mode operations
|
|
98
|
+
// ============================================================================
|
|
99
|
+
async addMode(collectionId, modeName) {
|
|
100
|
+
return this.wsServer.sendCommand('ADD_MODE', { collectionId, modeName });
|
|
101
|
+
}
|
|
102
|
+
async renameMode(collectionId, modeId, newName) {
|
|
103
|
+
const result = await this.wsServer.sendCommand('RENAME_MODE', { collectionId, modeId, newName });
|
|
104
|
+
// oldName may be embedded in collection data if ui.html handleResult doesn't pass it through
|
|
105
|
+
if (!result.oldName && result.collection?.oldName)
|
|
106
|
+
result.oldName = result.collection.oldName;
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// Collection operations
|
|
111
|
+
// ============================================================================
|
|
112
|
+
async createVariableCollection(name, options) {
|
|
113
|
+
const params = { name };
|
|
114
|
+
if (options) {
|
|
115
|
+
if (options.initialModeName)
|
|
116
|
+
params.initialModeName = options.initialModeName;
|
|
117
|
+
if (options.additionalModes)
|
|
118
|
+
params.additionalModes = options.additionalModes;
|
|
119
|
+
}
|
|
120
|
+
return this.wsServer.sendCommand('CREATE_VARIABLE_COLLECTION', params);
|
|
121
|
+
}
|
|
122
|
+
async deleteVariableCollection(collectionId) {
|
|
123
|
+
return this.wsServer.sendCommand('DELETE_VARIABLE_COLLECTION', { collectionId });
|
|
124
|
+
}
|
|
125
|
+
// ============================================================================
|
|
126
|
+
// Component operations
|
|
127
|
+
// ============================================================================
|
|
128
|
+
async getComponentFromPluginUI(nodeId) {
|
|
129
|
+
return this.wsServer.sendCommand('GET_COMPONENT', { nodeId }, 10000);
|
|
130
|
+
}
|
|
131
|
+
async getLocalComponents() {
|
|
132
|
+
return this.wsServer.sendCommand('GET_LOCAL_COMPONENTS', {}, 300000);
|
|
133
|
+
}
|
|
134
|
+
async setNodeDescription(nodeId, description, descriptionMarkdown) {
|
|
135
|
+
return this.wsServer.sendCommand('SET_NODE_DESCRIPTION', { nodeId, description, descriptionMarkdown });
|
|
136
|
+
}
|
|
137
|
+
async addComponentProperty(nodeId, propertyName, type, defaultValue, options) {
|
|
138
|
+
const params = { nodeId, propertyName, propertyType: type, defaultValue };
|
|
139
|
+
if (options?.preferredValues)
|
|
140
|
+
params.preferredValues = options.preferredValues;
|
|
141
|
+
return this.wsServer.sendCommand('ADD_COMPONENT_PROPERTY', params);
|
|
142
|
+
}
|
|
143
|
+
async editComponentProperty(nodeId, propertyName, newValue) {
|
|
144
|
+
return this.wsServer.sendCommand('EDIT_COMPONENT_PROPERTY', { nodeId, propertyName, newValue });
|
|
145
|
+
}
|
|
146
|
+
async deleteComponentProperty(nodeId, propertyName) {
|
|
147
|
+
return this.wsServer.sendCommand('DELETE_COMPONENT_PROPERTY', { nodeId, propertyName });
|
|
148
|
+
}
|
|
149
|
+
async instantiateComponent(componentKey, options) {
|
|
150
|
+
const params = { componentKey };
|
|
151
|
+
if (options) {
|
|
152
|
+
if (options.nodeId)
|
|
153
|
+
params.nodeId = options.nodeId;
|
|
154
|
+
if (options.position)
|
|
155
|
+
params.position = options.position;
|
|
156
|
+
if (options.size)
|
|
157
|
+
params.size = options.size;
|
|
158
|
+
if (options.overrides)
|
|
159
|
+
params.overrides = options.overrides;
|
|
160
|
+
if (options.variant)
|
|
161
|
+
params.variant = options.variant;
|
|
162
|
+
if (options.parentId)
|
|
163
|
+
params.parentId = options.parentId;
|
|
164
|
+
}
|
|
165
|
+
return this.wsServer.sendCommand('INSTANTIATE_COMPONENT', params);
|
|
166
|
+
}
|
|
167
|
+
// ============================================================================
|
|
168
|
+
// Node manipulation
|
|
169
|
+
// ============================================================================
|
|
170
|
+
async resizeNode(nodeId, width, height, withConstraints = true) {
|
|
171
|
+
return this.wsServer.sendCommand('RESIZE_NODE', { nodeId, width, height, withConstraints });
|
|
172
|
+
}
|
|
173
|
+
async moveNode(nodeId, x, y) {
|
|
174
|
+
return this.wsServer.sendCommand('MOVE_NODE', { nodeId, x, y });
|
|
175
|
+
}
|
|
176
|
+
async setNodeFills(nodeId, fills) {
|
|
177
|
+
return this.wsServer.sendCommand('SET_NODE_FILLS', { nodeId, fills });
|
|
178
|
+
}
|
|
179
|
+
async setNodeStrokes(nodeId, strokes, strokeWeight) {
|
|
180
|
+
const params = { nodeId, strokes };
|
|
181
|
+
if (strokeWeight !== undefined)
|
|
182
|
+
params.strokeWeight = strokeWeight;
|
|
183
|
+
return this.wsServer.sendCommand('SET_NODE_STROKES', params);
|
|
184
|
+
}
|
|
185
|
+
async setNodeOpacity(nodeId, opacity) {
|
|
186
|
+
return this.wsServer.sendCommand('SET_NODE_OPACITY', { nodeId, opacity });
|
|
187
|
+
}
|
|
188
|
+
async setNodeCornerRadius(nodeId, radius) {
|
|
189
|
+
return this.wsServer.sendCommand('SET_NODE_CORNER_RADIUS', { nodeId, radius });
|
|
190
|
+
}
|
|
191
|
+
async cloneNode(nodeId) {
|
|
192
|
+
return this.wsServer.sendCommand('CLONE_NODE', { nodeId });
|
|
193
|
+
}
|
|
194
|
+
async deleteNode(nodeId) {
|
|
195
|
+
return this.wsServer.sendCommand('DELETE_NODE', { nodeId });
|
|
196
|
+
}
|
|
197
|
+
async renameNode(nodeId, newName) {
|
|
198
|
+
return this.wsServer.sendCommand('RENAME_NODE', { nodeId, newName });
|
|
199
|
+
}
|
|
200
|
+
async setTextContent(nodeId, characters, options) {
|
|
201
|
+
const params = { nodeId, text: characters };
|
|
202
|
+
if (options) {
|
|
203
|
+
if (options.fontSize)
|
|
204
|
+
params.fontSize = options.fontSize;
|
|
205
|
+
if (options.fontWeight)
|
|
206
|
+
params.fontWeight = options.fontWeight;
|
|
207
|
+
if (options.fontFamily)
|
|
208
|
+
params.fontFamily = options.fontFamily;
|
|
209
|
+
}
|
|
210
|
+
return this.wsServer.sendCommand('SET_TEXT_CONTENT', params);
|
|
211
|
+
}
|
|
212
|
+
async createChildNode(parentId, nodeType, properties) {
|
|
213
|
+
return this.wsServer.sendCommand('CREATE_CHILD_NODE', { parentId, nodeType, properties: properties || {} });
|
|
214
|
+
}
|
|
215
|
+
// ============================================================================
|
|
216
|
+
// Screenshot & instance properties
|
|
217
|
+
// ============================================================================
|
|
218
|
+
async captureScreenshot(nodeId, options) {
|
|
219
|
+
const params = { nodeId };
|
|
220
|
+
if (options?.format)
|
|
221
|
+
params.format = options.format;
|
|
222
|
+
if (options?.scale)
|
|
223
|
+
params.scale = options.scale;
|
|
224
|
+
return this.wsServer.sendCommand('CAPTURE_SCREENSHOT', params, 30000);
|
|
225
|
+
}
|
|
226
|
+
async setInstanceProperties(nodeId, properties) {
|
|
227
|
+
return this.wsServer.sendCommand('SET_INSTANCE_PROPERTIES', { nodeId, properties });
|
|
228
|
+
}
|
|
229
|
+
// ============================================================================
|
|
230
|
+
// Image fill
|
|
231
|
+
// ============================================================================
|
|
232
|
+
async setImageFill(nodeIds, imageData, scaleMode = 'FILL') {
|
|
233
|
+
return this.wsServer.sendCommand('SET_IMAGE_FILL', { nodeIds, imageData, scaleMode }, 60000);
|
|
234
|
+
}
|
|
235
|
+
// ============================================================================
|
|
236
|
+
// Design lint
|
|
237
|
+
// ============================================================================
|
|
238
|
+
async lintDesign(nodeId, rules, maxDepth, maxFindings) {
|
|
239
|
+
const params = {};
|
|
240
|
+
if (nodeId)
|
|
241
|
+
params.nodeId = nodeId;
|
|
242
|
+
if (rules)
|
|
243
|
+
params.rules = rules;
|
|
244
|
+
if (maxDepth !== undefined)
|
|
245
|
+
params.maxDepth = maxDepth;
|
|
246
|
+
if (maxFindings !== undefined)
|
|
247
|
+
params.maxFindings = maxFindings;
|
|
248
|
+
return this.wsServer.sendCommand('LINT_DESIGN', params, 120000);
|
|
249
|
+
}
|
|
250
|
+
// ============================================================================
|
|
251
|
+
// Cache management (no-op for WebSocket — no frame cache)
|
|
252
|
+
// ============================================================================
|
|
253
|
+
clearFrameCache() {
|
|
254
|
+
// No frame cache in WebSocket mode
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=websocket-connector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-connector.js","sourceRoot":"","sources":["../../src/core/websocket-connector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket Bridge Server (Multi-Client)
|
|
3
|
+
*
|
|
4
|
+
* Creates a WebSocket server that multiple Desktop Bridge plugin instances connect to.
|
|
5
|
+
* Each instance represents a different Figma file and is identified by its fileKey
|
|
6
|
+
* (sent via FILE_INFO on connection). Per-file state (selection, document changes,
|
|
7
|
+
* console logs) is maintained independently.
|
|
8
|
+
*
|
|
9
|
+
* Active file tracking: The "active" file is automatically switched when the user
|
|
10
|
+
* interacts with a file (selection/page changes) or can be set explicitly via
|
|
11
|
+
* setActiveFile(). All backward-compatible getters return data from the active file.
|
|
12
|
+
*
|
|
13
|
+
* Data flow: MCP Server ←WebSocket→ ui.html ←postMessage→ code.js ←figma.*→ Figma
|
|
14
|
+
*/
|
|
15
|
+
import { WebSocket } from 'ws';
|
|
16
|
+
import { EventEmitter } from 'events';
|
|
17
|
+
import type { ConsoleLogEntry } from './types/index.js';
|
|
18
|
+
export interface WebSocketServerOptions {
|
|
19
|
+
port: number;
|
|
20
|
+
host?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface ConnectedFileInfo {
|
|
23
|
+
fileName: string;
|
|
24
|
+
fileKey: string | null;
|
|
25
|
+
currentPage?: string;
|
|
26
|
+
currentPageId?: string;
|
|
27
|
+
connectedAt: number;
|
|
28
|
+
}
|
|
29
|
+
export interface SelectionInfo {
|
|
30
|
+
nodes: Array<{
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
type: string;
|
|
34
|
+
width?: number;
|
|
35
|
+
height?: number;
|
|
36
|
+
}>;
|
|
37
|
+
count: number;
|
|
38
|
+
page: string;
|
|
39
|
+
timestamp: number;
|
|
40
|
+
}
|
|
41
|
+
export interface DocumentChangeEntry {
|
|
42
|
+
hasStyleChanges: boolean;
|
|
43
|
+
hasNodeChanges: boolean;
|
|
44
|
+
changedNodeIds: string[];
|
|
45
|
+
changeCount: number;
|
|
46
|
+
timestamp: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Per-file client connection state.
|
|
50
|
+
* Each Figma file with the Desktop Bridge plugin open gets its own ClientConnection.
|
|
51
|
+
*/
|
|
52
|
+
export interface ClientConnection {
|
|
53
|
+
ws: WebSocket;
|
|
54
|
+
fileInfo: ConnectedFileInfo;
|
|
55
|
+
selection: SelectionInfo | null;
|
|
56
|
+
documentChanges: DocumentChangeEntry[];
|
|
57
|
+
consoleLogs: ConsoleLogEntry[];
|
|
58
|
+
lastActivity: number;
|
|
59
|
+
gracePeriodTimer: ReturnType<typeof setTimeout> | null;
|
|
60
|
+
}
|
|
61
|
+
export declare class FigmaWebSocketServer extends EventEmitter {
|
|
62
|
+
private wss;
|
|
63
|
+
/** Named clients indexed by fileKey — each represents a connected Figma file */
|
|
64
|
+
private clients;
|
|
65
|
+
/** Clients awaiting FILE_INFO identification, mapped to their pending timeout */
|
|
66
|
+
private _pendingClients;
|
|
67
|
+
/** The fileKey of the currently active (targeted) file */
|
|
68
|
+
private _activeFileKey;
|
|
69
|
+
private pendingRequests;
|
|
70
|
+
private requestIdCounter;
|
|
71
|
+
private options;
|
|
72
|
+
private _isStarted;
|
|
73
|
+
private _startedAt;
|
|
74
|
+
private consoleBufferSize;
|
|
75
|
+
private documentChangeBufferSize;
|
|
76
|
+
constructor(options: WebSocketServerOptions);
|
|
77
|
+
/**
|
|
78
|
+
* Start the WebSocket server
|
|
79
|
+
*/
|
|
80
|
+
start(): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Find a named client connection by its WebSocket reference
|
|
83
|
+
*/
|
|
84
|
+
private findClientByWs;
|
|
85
|
+
/**
|
|
86
|
+
* Handle incoming message from a plugin UI WebSocket connection
|
|
87
|
+
*/
|
|
88
|
+
private handleMessage;
|
|
89
|
+
/**
|
|
90
|
+
* Handle FILE_INFO message — promotes pending clients to named clients.
|
|
91
|
+
* This is the critical multi-client identification step: each plugin reports
|
|
92
|
+
* its fileKey on connect, allowing the server to track multiple files.
|
|
93
|
+
*/
|
|
94
|
+
private handleFileInfo;
|
|
95
|
+
/**
|
|
96
|
+
* Handle a client WebSocket disconnecting.
|
|
97
|
+
* Starts a grace period before removing the client to allow reconnection.
|
|
98
|
+
*/
|
|
99
|
+
private handleClientDisconnect;
|
|
100
|
+
/**
|
|
101
|
+
* Send a command to a plugin UI and wait for the response.
|
|
102
|
+
* By default targets the active file. Pass targetFileKey to target a specific file.
|
|
103
|
+
*/
|
|
104
|
+
sendCommand(method: string, params?: Record<string, any>, timeoutMs?: number, targetFileKey?: string): Promise<any>;
|
|
105
|
+
/**
|
|
106
|
+
* Check if any named client is connected (transport availability check)
|
|
107
|
+
*/
|
|
108
|
+
isClientConnected(): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Whether the server has been started
|
|
111
|
+
*/
|
|
112
|
+
isStarted(): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Get the bound address info (port, host, family).
|
|
115
|
+
* Only available after the server has started listening.
|
|
116
|
+
* Returns the actual port — critical when using port 0 for OS-assigned ports.
|
|
117
|
+
*/
|
|
118
|
+
address(): import('net').AddressInfo | null;
|
|
119
|
+
/**
|
|
120
|
+
* Get info about the currently active Figma file.
|
|
121
|
+
* Returns null if no file is active or connected.
|
|
122
|
+
*/
|
|
123
|
+
getConnectedFileInfo(): ConnectedFileInfo | null;
|
|
124
|
+
/**
|
|
125
|
+
* Get the current user selection in the active Figma file
|
|
126
|
+
*/
|
|
127
|
+
getCurrentSelection(): SelectionInfo | null;
|
|
128
|
+
/**
|
|
129
|
+
* Get buffered document change events from the active file
|
|
130
|
+
*/
|
|
131
|
+
getDocumentChanges(options?: {
|
|
132
|
+
count?: number;
|
|
133
|
+
since?: number;
|
|
134
|
+
}): DocumentChangeEntry[];
|
|
135
|
+
/**
|
|
136
|
+
* Clear document change buffer for the active file
|
|
137
|
+
*/
|
|
138
|
+
clearDocumentChanges(): number;
|
|
139
|
+
/**
|
|
140
|
+
* Get console logs from the active file with optional filtering
|
|
141
|
+
*/
|
|
142
|
+
getConsoleLogs(options?: {
|
|
143
|
+
count?: number;
|
|
144
|
+
level?: ConsoleLogEntry['level'] | 'all';
|
|
145
|
+
since?: number;
|
|
146
|
+
}): ConsoleLogEntry[];
|
|
147
|
+
/**
|
|
148
|
+
* Clear console log buffer for the active file
|
|
149
|
+
*/
|
|
150
|
+
clearConsoleLogs(): number;
|
|
151
|
+
/**
|
|
152
|
+
* Get console monitoring status for the active file
|
|
153
|
+
*/
|
|
154
|
+
getConsoleStatus(): {
|
|
155
|
+
isMonitoring: boolean;
|
|
156
|
+
anyClientConnected: boolean;
|
|
157
|
+
logCount: number;
|
|
158
|
+
bufferSize: number;
|
|
159
|
+
workerCount: number;
|
|
160
|
+
oldestTimestamp: number;
|
|
161
|
+
newestTimestamp: number;
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* Get info about all connected Figma files.
|
|
165
|
+
* Returns an array of ConnectedFileInfo for each file with an active WebSocket.
|
|
166
|
+
*/
|
|
167
|
+
getConnectedFiles(): (ConnectedFileInfo & {
|
|
168
|
+
isActive: boolean;
|
|
169
|
+
})[];
|
|
170
|
+
/**
|
|
171
|
+
* Set the active file by fileKey. Returns true if the file is connected.
|
|
172
|
+
*/
|
|
173
|
+
setActiveFile(fileKey: string): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Get the currently active file's key
|
|
176
|
+
*/
|
|
177
|
+
getActiveFileKey(): string | null;
|
|
178
|
+
/**
|
|
179
|
+
* Reject pending requests that were sent to a specific file
|
|
180
|
+
*/
|
|
181
|
+
private rejectPendingRequestsForFile;
|
|
182
|
+
/**
|
|
183
|
+
* Reject all pending requests (used during shutdown)
|
|
184
|
+
*/
|
|
185
|
+
private rejectPendingRequests;
|
|
186
|
+
/**
|
|
187
|
+
* Stop the server and clean up all connections
|
|
188
|
+
*/
|
|
189
|
+
stop(): Promise<void>;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=websocket-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-server.d.ts","sourceRoot":"","sources":["../../src/core/websocket-server.ts"],"names":[],"mappings":"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"}
|