@muloka/figma-console-mcp 0.3.0 → 0.5.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 +31 -13
- package/dist/apps/design-system-dashboard/mcp-app.html +521 -0
- package/dist/apps/token-browser/mcp-app.html +410 -0
- package/dist/cloudflare/core/figma-tools.js +64 -13
- package/dist/cloudflare/core/tokens-tools.js +1 -1
- package/dist/cloudflare/core/websocket-server.js +60 -7
- package/dist/cloudflare/index.js +3 -3
- package/dist/core/port-discovery.d.ts.map +1 -1
- package/dist/core/port-discovery.js +101 -20
- package/dist/core/port-discovery.js.map +1 -1
- package/dist/core/websocket-server.d.ts +18 -1
- package/dist/core/websocket-server.d.ts.map +1 -1
- package/dist/core/websocket-server.js +44 -3
- package/dist/core/websocket-server.js.map +1 -1
- package/dist/core/write-tools.d.ts.map +1 -1
- package/dist/core/write-tools.js +98 -9
- package/dist/core/write-tools.js.map +1 -1
- package/dist/local.d.ts.map +1 -1
- package/dist/local.js +7 -3
- package/dist/local.js.map +1 -1
- package/figma-desktop-bridge/code.js +57 -27
- package/figma-desktop-bridge/ui.html +76 -7
- package/package.json +1 -1
- package/dist/browser/base.d.ts +0 -58
- package/dist/browser/base.d.ts.map +0 -1
- package/dist/browser/base.js +0 -6
- package/dist/browser/base.js.map +0 -1
- package/dist/browser/local.d.ts +0 -87
- package/dist/browser/local.d.ts.map +0 -1
- package/dist/browser/local.js +0 -318
- package/dist/browser/local.js.map +0 -1
- package/dist/core/figma-desktop-connector.d.ts +0 -312
- package/dist/core/figma-desktop-connector.d.ts.map +0 -1
- package/dist/core/figma-desktop-connector.js +0 -1298
- package/dist/core/figma-desktop-connector.js.map +0 -1
|
@@ -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
|
}
|
|
@@ -158,6 +158,18 @@
|
|
|
158
158
|
white-space: nowrap;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
/* ===== Build version line — plugin files + server, always visible =====
|
|
162
|
+
Deliberately NOT gated on connection state: "is my imported plugin
|
|
163
|
+
stale?" is asked precisely when nothing is connected. */
|
|
164
|
+
.status-version {
|
|
165
|
+
display: flex;
|
|
166
|
+
align-items: center;
|
|
167
|
+
padding-left: 17px; /* same optical alignment as .status-meta */
|
|
168
|
+
font-size: 9px;
|
|
169
|
+
color: var(--figma-color-text-secondary, rgba(255, 255, 255, 0.5));
|
|
170
|
+
white-space: nowrap;
|
|
171
|
+
}
|
|
172
|
+
|
|
161
173
|
/* Visible recovery instruction for the ERROR state */
|
|
162
174
|
.status-error-hint {
|
|
163
175
|
display: none; /* shown from JS while in the error state */
|
|
@@ -484,6 +496,9 @@
|
|
|
484
496
|
<span id="status-last-action"></span>
|
|
485
497
|
</div>
|
|
486
498
|
|
|
499
|
+
<!-- Build versions — imported plugin files + the sidecar they talk to -->
|
|
500
|
+
<div class="status-version" id="status-version" title="Plugin = the files imported into Figma. Server = the npx sidecar this plugin is connected to."></div>
|
|
501
|
+
|
|
487
502
|
<!-- Visible recovery instruction, shown only in the error state -->
|
|
488
503
|
<div class="status-error-hint" id="status-error-hint">Close this window and reopen the plugin.</div>
|
|
489
504
|
|
|
@@ -601,6 +616,25 @@
|
|
|
601
616
|
if (hint) hint.style.display = bridgeError ? 'block' : 'none';
|
|
602
617
|
|
|
603
618
|
renderStatusMeta(live);
|
|
619
|
+
renderVersionLine();
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// Build-version line under the meta row. Two independently-versioned
|
|
623
|
+
// halves, so both are labelled rather than merged into one number:
|
|
624
|
+
// Plugin — figma-desktop-bridge/code.js, cached by Figma at import time
|
|
625
|
+
// and only bumped on releases that actually touch plugin files
|
|
626
|
+
// Server — the npx sidecar's package version, learned over the wire
|
|
627
|
+
// Either can be unknown: the plugin version arrives from code.js ~500ms
|
|
628
|
+
// after open, the server version only once a connection lands. An unknown
|
|
629
|
+
// half renders "—" rather than a stale or guessed number.
|
|
630
|
+
function renderVersionLine() {
|
|
631
|
+
var el = document.getElementById('status-version');
|
|
632
|
+
if (!el) return;
|
|
633
|
+
var server = (typeof window.__wsServerVersion === 'function')
|
|
634
|
+
? window.__wsServerVersion()
|
|
635
|
+
: null;
|
|
636
|
+
el.textContent = 'Plugin ' + (PLUGIN_VERSION || '—') +
|
|
637
|
+
' · Server ' + (server ? 'v' + server : '—');
|
|
604
638
|
}
|
|
605
639
|
|
|
606
640
|
// Small always-visible line under the pill: "Connected to N AI app(s)"
|
|
@@ -1490,8 +1524,16 @@
|
|
|
1490
1524
|
return;
|
|
1491
1525
|
}
|
|
1492
1526
|
|
|
1493
|
-
// Call the handler with a safety timeout, then send back the result
|
|
1494
|
-
|
|
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;
|
|
1495
1537
|
var handlerSettled = false;
|
|
1496
1538
|
var handlerTimeoutId = null;
|
|
1497
1539
|
var handlerPromise = Promise.resolve(handler(message.params || {}));
|
|
@@ -1658,6 +1700,17 @@
|
|
|
1658
1700
|
// The health discovery loop is armed whenever the user hasn't paused —
|
|
1659
1701
|
// used by the status pill to show "Looking for your AI app…" honestly.
|
|
1660
1702
|
window.__wsIsDiscoveryActive = function() { return !userPaused; };
|
|
1703
|
+
// Version of the server we're actually attached to, for the version
|
|
1704
|
+
// line. Reads from the first LIVE connection so a stale entry that
|
|
1705
|
+
// hasn't been reaped yet can't report a version we're no longer using.
|
|
1706
|
+
// Null when nothing is connected — the line then renders "Server —".
|
|
1707
|
+
window.__wsServerVersion = function() {
|
|
1708
|
+
for (var i = 0; i < activeConnections.length; i++) {
|
|
1709
|
+
var c = activeConnections[i];
|
|
1710
|
+
if (c.ws.readyState === 1 && c.serverVersion) return c.serverVersion;
|
|
1711
|
+
}
|
|
1712
|
+
return null;
|
|
1713
|
+
};
|
|
1661
1714
|
|
|
1662
1715
|
// ======================================================================
|
|
1663
1716
|
// HTTP /health DISCOVERY LOOP — replaces the old zero-connection-gated
|
|
@@ -1909,7 +1962,13 @@
|
|
|
1909
1962
|
// STAGE 2 — LOG PANEL, INFO PANEL, CONNECTION, CLIPBOARD EXPORT
|
|
1910
1963
|
// ============================================================================
|
|
1911
1964
|
|
|
1912
|
-
|
|
1965
|
+
// Populated from code.js's own PLUGIN_VERSION via GET_FILE_INFO_RESULT
|
|
1966
|
+
// (fired unconditionally ~500ms after open, so it does not need a server
|
|
1967
|
+
// connection). Deliberately starts null rather than a hardcoded literal:
|
|
1968
|
+
// a literal here is not touched by scripts/release.sh, and the last one
|
|
1969
|
+
// drifted to the package version (0.3.0) while code.js reported the
|
|
1970
|
+
// plugin version (1.35.0) — two different numbers for the same field.
|
|
1971
|
+
var PLUGIN_VERSION = null;
|
|
1913
1972
|
var logHistory = [];
|
|
1914
1973
|
var logEntriesEl = null;
|
|
1915
1974
|
var _ctaBtn = null;
|
|
@@ -1977,7 +2036,7 @@
|
|
|
1977
2036
|
});
|
|
1978
2037
|
var text = 'Figma Desktop Bridge - Session Log\n'
|
|
1979
2038
|
+ 'Exported: ' + new Date().toISOString() + '\n'
|
|
1980
|
-
+ 'Plugin: ' + PLUGIN_VERSION + '\n'
|
|
2039
|
+
+ 'Plugin: ' + (PLUGIN_VERSION || 'unknown') + '\n'
|
|
1981
2040
|
+ '------------------------------------------------\n'
|
|
1982
2041
|
+ lines.join('\n') + '\n';
|
|
1983
2042
|
var ta = document.createElement('textarea');
|
|
@@ -2229,6 +2288,11 @@
|
|
|
2229
2288
|
if (_ctaBtn.style.display === 'none') _ctaBtn.style.display = '';
|
|
2230
2289
|
}
|
|
2231
2290
|
|
|
2291
|
+
// Paint the version line once up front so its row reserves height before
|
|
2292
|
+
// the first reconcile tick, instead of popping in and reflowing the
|
|
2293
|
+
// auto-sized plugin window at 500ms.
|
|
2294
|
+
renderVersionLine();
|
|
2295
|
+
|
|
2232
2296
|
// Periodic reconcile of CTA + status pill/meta (cheap, <1ms). Also
|
|
2233
2297
|
// refreshes "Last action: Xs ago" via renderStatusMeta inside
|
|
2234
2298
|
// deriveAndRenderStatus.
|
|
@@ -2238,9 +2302,11 @@
|
|
|
2238
2302
|
}, 2000);
|
|
2239
2303
|
|
|
2240
2304
|
// One-shot on first ready: render honest initial state and capture the
|
|
2241
|
-
// plugin's own version (
|
|
2242
|
-
// logging a command line — hence the unwrapped sender.
|
|
2243
|
-
// read from the GET_FILE_INFO_RESULT handler below.
|
|
2305
|
+
// plugin's own version (shown in the version line and the Activity export
|
|
2306
|
+
// header) without logging a command line — hence the unwrapped sender.
|
|
2307
|
+
// The version is read from the GET_FILE_INFO_RESULT handler below. This
|
|
2308
|
+
// fires regardless of connection state, which is what lets the version
|
|
2309
|
+
// line show the plugin half while no server is attached.
|
|
2244
2310
|
setTimeout(function() {
|
|
2245
2311
|
reconcileCta();
|
|
2246
2312
|
deriveAndRenderStatus();
|
|
@@ -2707,6 +2773,9 @@
|
|
|
2707
2773
|
var fileInfo = msg.fileInfo || msg.data;
|
|
2708
2774
|
if (fileInfo && fileInfo.pluginVersion) {
|
|
2709
2775
|
PLUGIN_VERSION = 'v' + fileInfo.pluginVersion;
|
|
2776
|
+
// Paint immediately instead of waiting up to 2s for the next
|
|
2777
|
+
// reconcile tick — this is the first moment the version is known.
|
|
2778
|
+
if (typeof renderVersionLine === 'function') renderVersionLine();
|
|
2710
2779
|
}
|
|
2711
2780
|
handleResult('GET_FILE_INFO', 'fileInfo');
|
|
2712
2781
|
break;
|
package/package.json
CHANGED
package/dist/browser/base.d.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Browser Manager Interface
|
|
3
|
-
* Abstract interface for browser automation across different runtimes
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Result of a navigateToFigma call indicating what action was taken
|
|
7
|
-
*/
|
|
8
|
-
export interface NavigationResult {
|
|
9
|
-
page: any;
|
|
10
|
-
action: 'switched_to_existing' | 'navigated';
|
|
11
|
-
url: string;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Browser Manager Interface
|
|
15
|
-
* Provides unified API for browser automation regardless of runtime (Cloudflare/Local)
|
|
16
|
-
*
|
|
17
|
-
* Note: Uses 'any' for Page type to support both puppeteer-core and @cloudflare/puppeteer
|
|
18
|
-
* implementations which have incompatible type definitions but compatible runtime behavior
|
|
19
|
-
*/
|
|
20
|
-
export interface IBrowserManager {
|
|
21
|
-
/**
|
|
22
|
-
* Launch or connect to browser instance
|
|
23
|
-
*/
|
|
24
|
-
launch(): Promise<void>;
|
|
25
|
-
/**
|
|
26
|
-
* Get active page instance
|
|
27
|
-
*/
|
|
28
|
-
getPage(): Promise<any>;
|
|
29
|
-
/**
|
|
30
|
-
* Navigate to Figma URL
|
|
31
|
-
*/
|
|
32
|
-
navigateToFigma(url?: string): Promise<NavigationResult>;
|
|
33
|
-
/**
|
|
34
|
-
* Reload current page
|
|
35
|
-
*/
|
|
36
|
-
reload(hardReload?: boolean): Promise<void>;
|
|
37
|
-
/**
|
|
38
|
-
* Evaluate JavaScript in page context
|
|
39
|
-
*/
|
|
40
|
-
evaluate<T>(fn: () => T): Promise<T>;
|
|
41
|
-
/**
|
|
42
|
-
* Check if browser is running
|
|
43
|
-
*/
|
|
44
|
-
isRunning(): boolean;
|
|
45
|
-
/**
|
|
46
|
-
* Close browser instance
|
|
47
|
-
*/
|
|
48
|
-
close(): Promise<void>;
|
|
49
|
-
/**
|
|
50
|
-
* Get current URL
|
|
51
|
-
*/
|
|
52
|
-
getCurrentUrl(): string | null;
|
|
53
|
-
/**
|
|
54
|
-
* Wait for navigation to complete
|
|
55
|
-
*/
|
|
56
|
-
waitForNavigation(timeout?: number): Promise<void>;
|
|
57
|
-
}
|
|
58
|
-
//# sourceMappingURL=base.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/browser/base.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,EAAE,sBAAsB,GAAG,WAAW,CAAC;IAC7C,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC/B;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IAExB;;OAEG;IACH,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEzD;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5C;;OAEG;IACH,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAKrC;;OAEG;IACH,SAAS,IAAI,OAAO,CAAC;IAErB;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;OAEG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI,CAAC;IAE/B;;OAEG;IACH,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD"}
|
package/dist/browser/base.js
DELETED
package/dist/browser/base.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/browser/base.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
package/dist/browser/local.d.ts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Local Browser Manager (Legacy)
|
|
3
|
-
* Note: This module is maintained for backwards compatibility but is no longer
|
|
4
|
-
* the primary connection method. Use the WebSocket Desktop Bridge plugin instead.
|
|
5
|
-
*/
|
|
6
|
-
import { type Page } from 'puppeteer-core';
|
|
7
|
-
import type { IBrowserManager, NavigationResult } from './base.js';
|
|
8
|
-
/**
|
|
9
|
-
* Local browser configuration
|
|
10
|
-
*/
|
|
11
|
-
export interface LocalBrowserConfig {
|
|
12
|
-
debugPort: number;
|
|
13
|
-
debugHost: string;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Local Browser Manager
|
|
17
|
-
* Connects to existing Figma Desktop instance via remote debugging port
|
|
18
|
-
*/
|
|
19
|
-
export declare class LocalBrowserManager implements IBrowserManager {
|
|
20
|
-
private browser;
|
|
21
|
-
private page;
|
|
22
|
-
private config;
|
|
23
|
-
constructor(config: LocalBrowserConfig);
|
|
24
|
-
/**
|
|
25
|
-
* Connect to Figma Desktop via remote debugging port
|
|
26
|
-
*/
|
|
27
|
-
launch(): Promise<void>;
|
|
28
|
-
/**
|
|
29
|
-
* Find the best page for plugin debugging
|
|
30
|
-
* Actively searches for pages with workers across ALL tabs
|
|
31
|
-
*/
|
|
32
|
-
private findBestPage;
|
|
33
|
-
/**
|
|
34
|
-
* Find an existing browser tab whose URL matches the given Figma file key
|
|
35
|
-
*/
|
|
36
|
-
private findPageByFileKey;
|
|
37
|
-
/**
|
|
38
|
-
* Get active Figma page or create new one
|
|
39
|
-
* Prefers pages with active plugin workers for plugin debugging
|
|
40
|
-
*/
|
|
41
|
-
getPage(): Promise<Page>;
|
|
42
|
-
/**
|
|
43
|
-
* Navigate to Figma URL
|
|
44
|
-
* If the target file is already open in a tab, switches to it instead of navigating.
|
|
45
|
-
*/
|
|
46
|
-
navigateToFigma(figmaUrl?: string): Promise<NavigationResult>;
|
|
47
|
-
/**
|
|
48
|
-
* Reload current page
|
|
49
|
-
*/
|
|
50
|
-
reload(hardReload?: boolean): Promise<void>;
|
|
51
|
-
/**
|
|
52
|
-
* Execute JavaScript in page context
|
|
53
|
-
*/
|
|
54
|
-
evaluate<T>(fn: () => T): Promise<T>;
|
|
55
|
-
/**
|
|
56
|
-
* Check if browser is connected
|
|
57
|
-
*/
|
|
58
|
-
isRunning(): boolean;
|
|
59
|
-
/**
|
|
60
|
-
* Disconnect from browser (doesn't close Figma Desktop)
|
|
61
|
-
*/
|
|
62
|
-
close(): Promise<void>;
|
|
63
|
-
/**
|
|
64
|
-
* Get current page URL
|
|
65
|
-
*/
|
|
66
|
-
getCurrentUrl(): string | null;
|
|
67
|
-
/**
|
|
68
|
-
* Check if the browser connection is still alive
|
|
69
|
-
* Returns false if connection is stale (e.g., after computer sleep)
|
|
70
|
-
*/
|
|
71
|
-
isConnectionAlive(): Promise<boolean>;
|
|
72
|
-
/**
|
|
73
|
-
* Reconnect to Figma Desktop if connection was lost
|
|
74
|
-
* Call this before any operation that requires a live connection
|
|
75
|
-
*/
|
|
76
|
-
ensureConnection(): Promise<void>;
|
|
77
|
-
/**
|
|
78
|
-
* Force a complete reconnection to Figma Desktop
|
|
79
|
-
* Use this when frames become detached or stale even though the browser appears connected
|
|
80
|
-
*/
|
|
81
|
-
forceReconnect(): Promise<void>;
|
|
82
|
-
/**
|
|
83
|
-
* Wait for navigation
|
|
84
|
-
*/
|
|
85
|
-
waitForNavigation(timeout?: number): Promise<void>;
|
|
86
|
-
}
|
|
87
|
-
//# sourceMappingURL=local.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/browser/local.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAkB,EAAgB,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAGpE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAInE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IAC1D,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,MAAM,CAAqB;gBAEvB,MAAM,EAAE,kBAAkB;IAItC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAuC7B;;;OAGG;YACW,YAAY;IA4C1B;;OAEG;YACW,iBAAiB;IAuB/B;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAyC9B;;;OAGG;IACG,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAsCnE;;OAEG;IACG,MAAM,CAAC,UAAU,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB/C;;OAEG;IACG,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAQ1C;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB5B;;OAEG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;IAQ9B;;;OAGG;IACG,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAe3C;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBvC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBrC;;OAEG;IACG,iBAAiB,CAAC,OAAO,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAUvD"}
|