@muloka/figma-console-mcp 0.4.0 → 0.5.1
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 +7 -3
- package/dist/core/websocket-connector.d.ts +2 -1
- package/dist/core/websocket-connector.d.ts.map +1 -1
- package/dist/core/websocket-connector.js +17 -2
- package/dist/core/websocket-connector.js.map +1 -1
- package/dist/core/websocket-server.d.ts +8 -1
- package/dist/core/websocket-server.d.ts.map +1 -1
- package/dist/core/websocket-server.js +19 -3
- package/dist/core/websocket-server.js.map +1 -1
- package/dist/core/write-tools.d.ts +3 -1
- package/dist/core/write-tools.d.ts.map +1 -1
- package/dist/core/write-tools.js +98 -23
- package/dist/core/write-tools.js.map +1 -1
- package/dist/local.d.ts +2 -1
- package/dist/local.d.ts.map +1 -1
- package/dist/local.js +5 -4
- package/dist/local.js.map +1 -1
- package/figma-desktop-bridge/code.js +57 -27
- package/figma-desktop-bridge/ui.html +10 -2
- package/package.json +1 -1
- package/dist/apps/design-system-dashboard/mcp-app.html +0 -521
- package/dist/apps/token-browser/mcp-app.html +0 -410
- package/dist/cloudflare/apps/design-system-dashboard/scoring/accessibility.js +0 -277
- package/dist/cloudflare/apps/design-system-dashboard/scoring/component-metadata.js +0 -357
- package/dist/cloudflare/apps/design-system-dashboard/scoring/consistency.js +0 -341
- package/dist/cloudflare/apps/design-system-dashboard/scoring/coverage.js +0 -230
- package/dist/cloudflare/apps/design-system-dashboard/scoring/engine.js +0 -92
- package/dist/cloudflare/apps/design-system-dashboard/scoring/naming-semantics.js +0 -308
- package/dist/cloudflare/apps/design-system-dashboard/scoring/token-architecture.js +0 -349
- package/dist/cloudflare/apps/design-system-dashboard/scoring/types.js +0 -40
- package/dist/cloudflare/apps/design-system-dashboard/server.js +0 -159
- package/dist/cloudflare/apps/token-browser/server.js +0 -136
- package/dist/cloudflare/browser-manager.js +0 -157
- package/dist/cloudflare/core/accessibility-tools.js +0 -361
- package/dist/cloudflare/core/annotation-tools.js +0 -230
- package/dist/cloudflare/core/cloud-websocket-connector.js +0 -419
- package/dist/cloudflare/core/cloud-websocket-relay.js +0 -198
- package/dist/cloudflare/core/comment-tools.js +0 -292
- package/dist/cloudflare/core/config.js +0 -153
- package/dist/cloudflare/core/console-monitor.js +0 -427
- package/dist/cloudflare/core/deep-component-tools.js +0 -128
- package/dist/cloudflare/core/design-code-tools.js +0 -2793
- package/dist/cloudflare/core/design-system-manifest.js +0 -265
- package/dist/cloudflare/core/design-system-tools.js +0 -882
- package/dist/cloudflare/core/diagnose-tool.js +0 -100
- package/dist/cloudflare/core/diff/changelog-formatter.js +0 -275
- package/dist/cloudflare/core/diff/diff-engine.js +0 -334
- package/dist/cloudflare/core/diff/property-compare.js +0 -36
- package/dist/cloudflare/core/diff/version-cache.js +0 -74
- package/dist/cloudflare/core/enrichment/enrichment-service.js +0 -374
- package/dist/cloudflare/core/enrichment/index.js +0 -7
- package/dist/cloudflare/core/enrichment/relationship-mapper.js +0 -351
- package/dist/cloudflare/core/enrichment/style-resolver.js +0 -346
- package/dist/cloudflare/core/figjam-tools.js +0 -547
- package/dist/cloudflare/core/figma-api.js +0 -509
- package/dist/cloudflare/core/figma-connector.js +0 -7
- package/dist/cloudflare/core/figma-reconstruction-spec.js +0 -402
- package/dist/cloudflare/core/figma-style-extractor.js +0 -311
- package/dist/cloudflare/core/figma-tools.js +0 -3353
- package/dist/cloudflare/core/identity.js +0 -96
- package/dist/cloudflare/core/library-tools.js +0 -580
- package/dist/cloudflare/core/logger.js +0 -53
- package/dist/cloudflare/core/port-discovery.js +0 -935
- package/dist/cloudflare/core/resolve-package-root.js +0 -11
- package/dist/cloudflare/core/slides-tools.js +0 -714
- package/dist/cloudflare/core/slot-tools.js +0 -334
- package/dist/cloudflare/core/snippet-injector.js +0 -96
- package/dist/cloudflare/core/tokens/alias-resolver.js +0 -205
- package/dist/cloudflare/core/tokens/config.js +0 -294
- package/dist/cloudflare/core/tokens/dialect.js +0 -232
- package/dist/cloudflare/core/tokens/figma-converter.js +0 -323
- package/dist/cloudflare/core/tokens/formatters/css-vars.js +0 -338
- package/dist/cloudflare/core/tokens/formatters/dtcg.js +0 -376
- package/dist/cloudflare/core/tokens/formatters/index.js +0 -45
- package/dist/cloudflare/core/tokens/formatters/json.js +0 -205
- package/dist/cloudflare/core/tokens/formatters/less.js +0 -4
- package/dist/cloudflare/core/tokens/formatters/scss.js +0 -258
- package/dist/cloudflare/core/tokens/formatters/stubs.js +0 -13
- package/dist/cloudflare/core/tokens/formatters/style-dictionary-v3.js +0 -213
- package/dist/cloudflare/core/tokens/formatters/tailwind-v3.js +0 -237
- package/dist/cloudflare/core/tokens/formatters/tailwind-v4.js +0 -335
- package/dist/cloudflare/core/tokens/formatters/tokens-studio.js +0 -256
- package/dist/cloudflare/core/tokens/formatters/ts-module.js +0 -198
- package/dist/cloudflare/core/tokens/index.js +0 -16
- package/dist/cloudflare/core/tokens/parsers/css-vars.js +0 -4
- package/dist/cloudflare/core/tokens/parsers/dtcg.js +0 -280
- package/dist/cloudflare/core/tokens/parsers/index.js +0 -138
- package/dist/cloudflare/core/tokens/parsers/json.js +0 -7
- package/dist/cloudflare/core/tokens/parsers/scss.js +0 -4
- package/dist/cloudflare/core/tokens/parsers/stubs.js +0 -20
- package/dist/cloudflare/core/tokens/parsers/style-dictionary-v3.js +0 -4
- package/dist/cloudflare/core/tokens/parsers/tailwind-v3.js +0 -4
- package/dist/cloudflare/core/tokens/parsers/tailwind-v4.js +0 -4
- package/dist/cloudflare/core/tokens/parsers/tokens-studio.js +0 -4
- package/dist/cloudflare/core/tokens/schemas.js +0 -152
- package/dist/cloudflare/core/tokens/transforms/color.js +0 -12
- package/dist/cloudflare/core/tokens/transforms/index.js +0 -29
- package/dist/cloudflare/core/tokens/transforms/size.js +0 -7
- package/dist/cloudflare/core/tokens/types.js +0 -18
- package/dist/cloudflare/core/tokens-tools.js +0 -1788
- package/dist/cloudflare/core/types/design-code.js +0 -4
- package/dist/cloudflare/core/types/enriched.js +0 -5
- package/dist/cloudflare/core/types/index.js +0 -4
- package/dist/cloudflare/core/variable-resolver.js +0 -85
- package/dist/cloudflare/core/version-tools.js +0 -1199
- package/dist/cloudflare/core/websocket-connector.js +0 -436
- package/dist/cloudflare/core/websocket-server.js +0 -1009
- package/dist/cloudflare/core/write-tools.js +0 -2506
- package/dist/cloudflare/index.js +0 -3010
|
@@ -719,40 +719,47 @@ figma.ui.onmessage = async (msg) => {
|
|
|
719
719
|
// CREATE_VARIABLE_COLLECTION - Create a new variable collection
|
|
720
720
|
// ============================================================================
|
|
721
721
|
else if (msg.type === 'CREATE_VARIABLE_COLLECTION') {
|
|
722
|
+
var newCollection = null;
|
|
722
723
|
try {
|
|
723
724
|
console.log('🌉 [Desktop Bridge] Creating collection:', msg.name);
|
|
724
725
|
|
|
725
|
-
|
|
726
|
-
var collection = figma.variables.createVariableCollection(msg.name);
|
|
726
|
+
newCollection = figma.variables.createVariableCollection(msg.name);
|
|
727
727
|
|
|
728
728
|
// Rename the default mode if a name is provided
|
|
729
|
-
if (msg.initialModeName &&
|
|
730
|
-
|
|
729
|
+
if (msg.initialModeName && newCollection.modes.length > 0) {
|
|
730
|
+
newCollection.renameMode(newCollection.modes[0].modeId, msg.initialModeName);
|
|
731
731
|
}
|
|
732
732
|
|
|
733
733
|
// Add additional modes if provided
|
|
734
734
|
if (msg.additionalModes && msg.additionalModes.length > 0) {
|
|
735
735
|
for (var i = 0; i < msg.additionalModes.length; i++) {
|
|
736
|
-
|
|
736
|
+
newCollection.addMode(msg.additionalModes[i]);
|
|
737
737
|
}
|
|
738
738
|
}
|
|
739
739
|
|
|
740
|
-
console.log('🌉 [Desktop Bridge] Collection created:',
|
|
740
|
+
console.log('🌉 [Desktop Bridge] Collection created:', newCollection.id);
|
|
741
741
|
|
|
742
742
|
figma.ui.postMessage({
|
|
743
743
|
type: 'CREATE_VARIABLE_COLLECTION_RESULT',
|
|
744
744
|
requestId: msg.requestId,
|
|
745
745
|
success: true,
|
|
746
|
-
collection: serializeCollection(
|
|
746
|
+
collection: serializeCollection(newCollection)
|
|
747
747
|
});
|
|
748
748
|
|
|
749
749
|
} catch (error) {
|
|
750
|
+
// Mode setup failed after the collection was created — remove the
|
|
751
|
+
// orphan so a retry cannot create twins (mirrors the rollback in the
|
|
752
|
+
// tokens-tools create phase).
|
|
753
|
+
var ccRolledBack = false;
|
|
754
|
+
if (newCollection) {
|
|
755
|
+
try { newCollection.remove(); ccRolledBack = true; } catch (removeErr) {}
|
|
756
|
+
}
|
|
750
757
|
console.error('🌉 [Desktop Bridge] Create collection error:', error);
|
|
751
758
|
figma.ui.postMessage({
|
|
752
759
|
type: 'CREATE_VARIABLE_COLLECTION_RESULT',
|
|
753
760
|
requestId: msg.requestId,
|
|
754
761
|
success: false,
|
|
755
|
-
error: error.message || String(error)
|
|
762
|
+
error: (error.message || String(error)) + (ccRolledBack ? ' (partially-created collection rolled back)' : '')
|
|
756
763
|
});
|
|
757
764
|
}
|
|
758
765
|
}
|
|
@@ -3751,12 +3758,18 @@ figma.ui.onmessage = async (msg) => {
|
|
|
3751
3758
|
|
|
3752
3759
|
} catch (error) {
|
|
3753
3760
|
var errorMsg = error && error.message ? error.message : String(error);
|
|
3761
|
+
// figma.createX() lands the node on the page immediately; a throw from
|
|
3762
|
+
// font load / resize / fills / appendChild would otherwise strand it.
|
|
3763
|
+
var childRemoved = false;
|
|
3764
|
+
if (typeof newNode !== 'undefined' && newNode) {
|
|
3765
|
+
try { newNode.remove(); childRemoved = true; } catch (removeErr) {}
|
|
3766
|
+
}
|
|
3754
3767
|
console.error('🌉 [Desktop Bridge] Create child node error:', errorMsg);
|
|
3755
3768
|
figma.ui.postMessage({
|
|
3756
3769
|
type: 'CREATE_CHILD_NODE_RESULT',
|
|
3757
3770
|
requestId: msg.requestId,
|
|
3758
3771
|
success: false,
|
|
3759
|
-
error: errorMsg
|
|
3772
|
+
error: errorMsg + (childRemoved ? ' (partially-created node was removed)' : '')
|
|
3760
3773
|
});
|
|
3761
3774
|
}
|
|
3762
3775
|
}
|
|
@@ -6022,28 +6035,31 @@ figma.ui.onmessage = async (msg) => {
|
|
|
6022
6035
|
var stickyFontLoaded = false;
|
|
6023
6036
|
|
|
6024
6037
|
for (var si = 0; si < msg.stickies.length; si++) {
|
|
6038
|
+
var batchSticky = null;
|
|
6025
6039
|
try {
|
|
6026
6040
|
var spec = msg.stickies[si];
|
|
6027
|
-
|
|
6041
|
+
batchSticky = figma.createSticky();
|
|
6028
6042
|
if (!stickyFontLoaded) {
|
|
6029
|
-
await figma.loadFontAsync(
|
|
6043
|
+
await figma.loadFontAsync(batchSticky.text.fontName);
|
|
6030
6044
|
stickyFontLoaded = true;
|
|
6031
6045
|
}
|
|
6032
|
-
|
|
6046
|
+
batchSticky.text.characters = spec.text || '';
|
|
6033
6047
|
|
|
6034
|
-
if (typeof spec.x === 'number')
|
|
6035
|
-
if (typeof spec.y === 'number')
|
|
6048
|
+
if (typeof spec.x === 'number') batchSticky.x = spec.x;
|
|
6049
|
+
if (typeof spec.y === 'number') batchSticky.y = spec.y;
|
|
6036
6050
|
|
|
6037
6051
|
if (spec.color) {
|
|
6038
6052
|
var sc = __stickyColors[spec.color.toUpperCase()];
|
|
6039
6053
|
if (sc) {
|
|
6040
|
-
|
|
6054
|
+
batchSticky.fills = [{ type: 'SOLID', color: sc }];
|
|
6041
6055
|
}
|
|
6042
6056
|
}
|
|
6043
6057
|
|
|
6044
|
-
created.push({ id:
|
|
6058
|
+
created.push({ id: batchSticky.id, type: batchSticky.type, name: batchSticky.name, x: batchSticky.x, y: batchSticky.y });
|
|
6045
6059
|
} catch (e) {
|
|
6046
|
-
|
|
6060
|
+
// A sticky created before the throw EXISTS on the board but is in
|
|
6061
|
+
// neither list — report its id so the caller can find or remove it.
|
|
6062
|
+
failed.push({ index: si, id: batchSticky ? batchSticky.id : undefined, error: e.message || String(e) });
|
|
6047
6063
|
}
|
|
6048
6064
|
}
|
|
6049
6065
|
|
|
@@ -6073,15 +6089,17 @@ figma.ui.onmessage = async (msg) => {
|
|
|
6073
6089
|
}
|
|
6074
6090
|
console.log('🌉 [Desktop Bridge] Creating connector');
|
|
6075
6091
|
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
//
|
|
6092
|
+
// Validate endpoints FIRST — a stale nodeId is the most common caller
|
|
6093
|
+
// error, and creating the connector before checking guaranteed an
|
|
6094
|
+
// endpoint-less orphan on every such call.
|
|
6079
6095
|
var startNode = await figma.getNodeByIdAsync(msg.startNodeId);
|
|
6080
6096
|
var endNode = await figma.getNodeByIdAsync(msg.endNodeId);
|
|
6081
6097
|
|
|
6082
6098
|
if (!startNode) throw new Error('Start node not found: ' + msg.startNodeId);
|
|
6083
6099
|
if (!endNode) throw new Error('End node not found: ' + msg.endNodeId);
|
|
6084
6100
|
|
|
6101
|
+
var connector = figma.createConnector();
|
|
6102
|
+
|
|
6085
6103
|
connector.connectorStart = {
|
|
6086
6104
|
endpointNodeId: msg.startNodeId,
|
|
6087
6105
|
magnet: msg.startMagnet || 'AUTO'
|
|
@@ -6263,16 +6281,16 @@ figma.ui.onmessage = async (msg) => {
|
|
|
6263
6281
|
}
|
|
6264
6282
|
console.log('🌉 [Desktop Bridge] Creating table:', msg.rows, 'x', msg.columns);
|
|
6265
6283
|
|
|
6266
|
-
var
|
|
6284
|
+
var ctTable = figma.createTable(msg.rows, msg.columns);
|
|
6267
6285
|
|
|
6268
|
-
if (typeof msg.x === 'number')
|
|
6269
|
-
if (typeof msg.y === 'number')
|
|
6286
|
+
if (typeof msg.x === 'number') ctTable.x = msg.x;
|
|
6287
|
+
if (typeof msg.y === 'number') ctTable.y = msg.y;
|
|
6270
6288
|
|
|
6271
6289
|
// Populate cells if data provided
|
|
6272
6290
|
if (msg.data && Array.isArray(msg.data)) {
|
|
6273
6291
|
for (var row = 0; row < msg.data.length && row < msg.rows; row++) {
|
|
6274
6292
|
for (var col = 0; col < msg.data[row].length && col < msg.columns; col++) {
|
|
6275
|
-
var cell =
|
|
6293
|
+
var cell = ctTable.cellAt(row, col);
|
|
6276
6294
|
if (cell && msg.data[row][col] != null) {
|
|
6277
6295
|
await figma.loadFontAsync(cell.text.fontName);
|
|
6278
6296
|
cell.text.characters = String(msg.data[row][col]);
|
|
@@ -6285,16 +6303,21 @@ figma.ui.onmessage = async (msg) => {
|
|
|
6285
6303
|
type: 'CREATE_TABLE_RESULT',
|
|
6286
6304
|
requestId: msg.requestId,
|
|
6287
6305
|
success: true,
|
|
6288
|
-
data: { id:
|
|
6306
|
+
data: { id: ctTable.id, type: ctTable.type, name: ctTable.name, rows: msg.rows, columns: msg.columns }
|
|
6289
6307
|
});
|
|
6290
6308
|
|
|
6291
6309
|
} catch (error) {
|
|
6310
|
+
// A font-load failure mid cell-loop leaves a half-populated table.
|
|
6311
|
+
var ctTableRemoved = false;
|
|
6312
|
+
if (typeof ctTable !== 'undefined' && ctTable) {
|
|
6313
|
+
try { ctTable.remove(); ctTableRemoved = true; } catch (removeErr) {}
|
|
6314
|
+
}
|
|
6292
6315
|
console.error('🌉 [Desktop Bridge] Create table error:', error);
|
|
6293
6316
|
figma.ui.postMessage({
|
|
6294
6317
|
type: 'CREATE_TABLE_RESULT',
|
|
6295
6318
|
requestId: msg.requestId,
|
|
6296
6319
|
success: false,
|
|
6297
|
-
error: error.message || String(error)
|
|
6320
|
+
error: (error.message || String(error)) + (ctTableRemoved ? ' (partially-created node was removed)' : '')
|
|
6298
6321
|
});
|
|
6299
6322
|
}
|
|
6300
6323
|
}
|
|
@@ -7154,12 +7177,19 @@ figma.ui.onmessage = async (msg) => {
|
|
|
7154
7177
|
});
|
|
7155
7178
|
|
|
7156
7179
|
} catch (error) {
|
|
7180
|
+
// createText() lands on the page; ~7 fallible setters (font load,
|
|
7181
|
+
// textAlign/textCase enums, resize) run before appendChild moves it to
|
|
7182
|
+
// the slide — remove the stranded node on any of their throws.
|
|
7183
|
+
var slideTextRemoved = false;
|
|
7184
|
+
if (typeof textNode !== 'undefined' && textNode) {
|
|
7185
|
+
try { textNode.remove(); slideTextRemoved = true; } catch (removeErr) {}
|
|
7186
|
+
}
|
|
7157
7187
|
console.error('🌉 [Desktop Bridge] Add text to slide error:', error);
|
|
7158
7188
|
figma.ui.postMessage({
|
|
7159
7189
|
type: 'ADD_TEXT_TO_SLIDE_RESULT',
|
|
7160
7190
|
requestId: msg.requestId,
|
|
7161
7191
|
success: false,
|
|
7162
|
-
error: error.message || String(error)
|
|
7192
|
+
error: (error.message || String(error)) + (slideTextRemoved ? ' (partially-created node was removed)' : '')
|
|
7163
7193
|
});
|
|
7164
7194
|
}
|
|
7165
7195
|
}
|
|
@@ -1524,8 +1524,16 @@
|
|
|
1524
1524
|
return;
|
|
1525
1525
|
}
|
|
1526
1526
|
|
|
1527
|
-
// Call the handler with a safety timeout, then send back the result
|
|
1528
|
-
|
|
1527
|
+
// Call the handler with a safety timeout, then send back the result.
|
|
1528
|
+
// The server includes each command's real budget as timeoutMs
|
|
1529
|
+
// (see websocket-server.ts sendCommand); race against that plus a
|
|
1530
|
+
// 5s margin so the command's own wrapper timeout — which produces
|
|
1531
|
+
// the method-specific error — always fires first. No field (older
|
|
1532
|
+
// server) or an invalid value falls back to the old 30s default.
|
|
1533
|
+
var requestedBudget = (typeof message.timeoutMs === 'number' && isFinite(message.timeoutMs) && message.timeoutMs > 0)
|
|
1534
|
+
? message.timeoutMs
|
|
1535
|
+
: null;
|
|
1536
|
+
var HANDLER_TIMEOUT_MS = requestedBudget ? Math.min(requestedBudget + 5000, 310000) : 30000;
|
|
1529
1537
|
var handlerSettled = false;
|
|
1530
1538
|
var handlerTimeoutId = null;
|
|
1531
1539
|
var handlerPromise = Promise.resolve(handler(message.params || {}));
|