@mp3wizard/figma-console-mcp 1.25.1 → 1.27.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/README.md +49 -33
  2. package/dist/cloudflare/core/config.js +0 -8
  3. package/dist/cloudflare/core/console-monitor.js +3 -3
  4. package/dist/cloudflare/core/diagnose-tool.js +96 -0
  5. package/dist/cloudflare/core/figma-tools.js +69 -229
  6. package/dist/cloudflare/core/identity.js +96 -0
  7. package/dist/cloudflare/core/tokens/alias-resolver.js +98 -0
  8. package/dist/cloudflare/core/tokens/config.js +284 -0
  9. package/dist/cloudflare/core/tokens/figma-converter.js +195 -0
  10. package/dist/cloudflare/core/tokens/formatters/css-vars.js +329 -0
  11. package/dist/cloudflare/core/tokens/formatters/dtcg.js +300 -0
  12. package/dist/cloudflare/core/tokens/formatters/index.js +45 -0
  13. package/dist/cloudflare/core/tokens/formatters/json.js +7 -0
  14. package/dist/cloudflare/core/tokens/formatters/less.js +4 -0
  15. package/dist/cloudflare/core/tokens/formatters/scss.js +4 -0
  16. package/dist/cloudflare/core/tokens/formatters/stubs.js +11 -0
  17. package/dist/cloudflare/core/tokens/formatters/style-dictionary-v3.js +4 -0
  18. package/dist/cloudflare/core/tokens/formatters/tailwind-v3.js +4 -0
  19. package/dist/cloudflare/core/tokens/formatters/tailwind-v4.js +4 -0
  20. package/dist/cloudflare/core/tokens/formatters/tokens-studio.js +4 -0
  21. package/dist/cloudflare/core/tokens/formatters/ts-module.js +4 -0
  22. package/dist/cloudflare/core/tokens/index.js +15 -0
  23. package/dist/cloudflare/core/tokens/parsers/css-vars.js +4 -0
  24. package/dist/cloudflare/core/tokens/parsers/dtcg.js +253 -0
  25. package/dist/cloudflare/core/tokens/parsers/index.js +138 -0
  26. package/dist/cloudflare/core/tokens/parsers/json.js +7 -0
  27. package/dist/cloudflare/core/tokens/parsers/scss.js +4 -0
  28. package/dist/cloudflare/core/tokens/parsers/stubs.js +13 -0
  29. package/dist/cloudflare/core/tokens/parsers/style-dictionary-v3.js +4 -0
  30. package/dist/cloudflare/core/tokens/parsers/tailwind-v3.js +4 -0
  31. package/dist/cloudflare/core/tokens/parsers/tailwind-v4.js +4 -0
  32. package/dist/cloudflare/core/tokens/parsers/tokens-studio.js +4 -0
  33. package/dist/cloudflare/core/tokens/schemas.js +148 -0
  34. package/dist/cloudflare/core/tokens/transforms/color.js +12 -0
  35. package/dist/cloudflare/core/tokens/transforms/index.js +29 -0
  36. package/dist/cloudflare/core/tokens/transforms/size.js +7 -0
  37. package/dist/cloudflare/core/tokens/types.js +18 -0
  38. package/dist/cloudflare/core/tokens-tools.js +849 -0
  39. package/dist/cloudflare/core/websocket-server.js +5 -55
  40. package/dist/cloudflare/index.js +37 -26
  41. package/dist/core/config.d.ts.map +1 -1
  42. package/dist/core/config.js +0 -8
  43. package/dist/core/config.js.map +1 -1
  44. package/dist/core/console-monitor.d.ts +2 -2
  45. package/dist/core/console-monitor.d.ts.map +1 -1
  46. package/dist/core/console-monitor.js +3 -3
  47. package/dist/core/console-monitor.js.map +1 -1
  48. package/dist/core/diagnose-tool.d.ts +33 -0
  49. package/dist/core/diagnose-tool.d.ts.map +1 -0
  50. package/dist/core/diagnose-tool.js +97 -0
  51. package/dist/core/diagnose-tool.js.map +1 -0
  52. package/dist/core/figma-connector.d.ts +1 -1
  53. package/dist/core/figma-connector.d.ts.map +1 -1
  54. package/dist/core/figma-tools.d.ts +1 -2
  55. package/dist/core/figma-tools.d.ts.map +1 -1
  56. package/dist/core/figma-tools.js +69 -229
  57. package/dist/core/figma-tools.js.map +1 -1
  58. package/dist/core/identity.d.ts +41 -0
  59. package/dist/core/identity.d.ts.map +1 -0
  60. package/dist/core/identity.js +97 -0
  61. package/dist/core/identity.js.map +1 -0
  62. package/dist/core/tokens/alias-resolver.d.ts +40 -0
  63. package/dist/core/tokens/alias-resolver.d.ts.map +1 -0
  64. package/dist/core/tokens/alias-resolver.js +99 -0
  65. package/dist/core/tokens/alias-resolver.js.map +1 -0
  66. package/dist/core/tokens/config.d.ts +352 -0
  67. package/dist/core/tokens/config.d.ts.map +1 -0
  68. package/dist/core/tokens/config.js +285 -0
  69. package/dist/core/tokens/config.js.map +1 -0
  70. package/dist/core/tokens/figma-converter.d.ts +81 -0
  71. package/dist/core/tokens/figma-converter.d.ts.map +1 -0
  72. package/dist/core/tokens/figma-converter.js +196 -0
  73. package/dist/core/tokens/figma-converter.js.map +1 -0
  74. package/dist/core/tokens/formatters/css-vars.d.ts +24 -0
  75. package/dist/core/tokens/formatters/css-vars.d.ts.map +1 -0
  76. package/dist/core/tokens/formatters/css-vars.js +330 -0
  77. package/dist/core/tokens/formatters/css-vars.js.map +1 -0
  78. package/dist/core/tokens/formatters/dtcg.d.ts +28 -0
  79. package/dist/core/tokens/formatters/dtcg.d.ts.map +1 -0
  80. package/dist/core/tokens/formatters/dtcg.js +301 -0
  81. package/dist/core/tokens/formatters/dtcg.js.map +1 -0
  82. package/dist/core/tokens/formatters/index.d.ts +30 -0
  83. package/dist/core/tokens/formatters/index.d.ts.map +1 -0
  84. package/dist/core/tokens/formatters/index.js +46 -0
  85. package/dist/core/tokens/formatters/index.js.map +1 -0
  86. package/dist/core/tokens/formatters/json.d.ts +5 -0
  87. package/dist/core/tokens/formatters/json.d.ts.map +1 -0
  88. package/dist/core/tokens/formatters/json.js +8 -0
  89. package/dist/core/tokens/formatters/json.js.map +1 -0
  90. package/dist/core/tokens/formatters/less.d.ts +4 -0
  91. package/dist/core/tokens/formatters/less.d.ts.map +1 -0
  92. package/dist/core/tokens/formatters/less.js +5 -0
  93. package/dist/core/tokens/formatters/less.js.map +1 -0
  94. package/dist/core/tokens/formatters/scss.d.ts +4 -0
  95. package/dist/core/tokens/formatters/scss.d.ts.map +1 -0
  96. package/dist/core/tokens/formatters/scss.js +5 -0
  97. package/dist/core/tokens/formatters/scss.js.map +1 -0
  98. package/dist/core/tokens/formatters/stubs.d.ts +9 -0
  99. package/dist/core/tokens/formatters/stubs.d.ts.map +1 -0
  100. package/dist/core/tokens/formatters/stubs.js +12 -0
  101. package/dist/core/tokens/formatters/stubs.js.map +1 -0
  102. package/dist/core/tokens/formatters/style-dictionary-v3.d.ts +4 -0
  103. package/dist/core/tokens/formatters/style-dictionary-v3.d.ts.map +1 -0
  104. package/dist/core/tokens/formatters/style-dictionary-v3.js +5 -0
  105. package/dist/core/tokens/formatters/style-dictionary-v3.js.map +1 -0
  106. package/dist/core/tokens/formatters/tailwind-v3.d.ts +4 -0
  107. package/dist/core/tokens/formatters/tailwind-v3.d.ts.map +1 -0
  108. package/dist/core/tokens/formatters/tailwind-v3.js +5 -0
  109. package/dist/core/tokens/formatters/tailwind-v3.js.map +1 -0
  110. package/dist/core/tokens/formatters/tailwind-v4.d.ts +4 -0
  111. package/dist/core/tokens/formatters/tailwind-v4.d.ts.map +1 -0
  112. package/dist/core/tokens/formatters/tailwind-v4.js +5 -0
  113. package/dist/core/tokens/formatters/tailwind-v4.js.map +1 -0
  114. package/dist/core/tokens/formatters/tokens-studio.d.ts +4 -0
  115. package/dist/core/tokens/formatters/tokens-studio.d.ts.map +1 -0
  116. package/dist/core/tokens/formatters/tokens-studio.js +5 -0
  117. package/dist/core/tokens/formatters/tokens-studio.js.map +1 -0
  118. package/dist/core/tokens/formatters/ts-module.d.ts +4 -0
  119. package/dist/core/tokens/formatters/ts-module.d.ts.map +1 -0
  120. package/dist/core/tokens/formatters/ts-module.js +5 -0
  121. package/dist/core/tokens/formatters/ts-module.js.map +1 -0
  122. package/dist/core/tokens/index.d.ts +17 -0
  123. package/dist/core/tokens/index.d.ts.map +1 -0
  124. package/dist/core/tokens/index.js +16 -0
  125. package/dist/core/tokens/index.js.map +1 -0
  126. package/dist/core/tokens/parsers/css-vars.d.ts +3 -0
  127. package/dist/core/tokens/parsers/css-vars.d.ts.map +1 -0
  128. package/dist/core/tokens/parsers/css-vars.js +5 -0
  129. package/dist/core/tokens/parsers/css-vars.js.map +1 -0
  130. package/dist/core/tokens/parsers/dtcg.d.ts +21 -0
  131. package/dist/core/tokens/parsers/dtcg.d.ts.map +1 -0
  132. package/dist/core/tokens/parsers/dtcg.js +254 -0
  133. package/dist/core/tokens/parsers/dtcg.js.map +1 -0
  134. package/dist/core/tokens/parsers/index.d.ts +37 -0
  135. package/dist/core/tokens/parsers/index.d.ts.map +1 -0
  136. package/dist/core/tokens/parsers/index.js +139 -0
  137. package/dist/core/tokens/parsers/index.js.map +1 -0
  138. package/dist/core/tokens/parsers/json.d.ts +4 -0
  139. package/dist/core/tokens/parsers/json.d.ts.map +1 -0
  140. package/dist/core/tokens/parsers/json.js +8 -0
  141. package/dist/core/tokens/parsers/json.js.map +1 -0
  142. package/dist/core/tokens/parsers/scss.d.ts +3 -0
  143. package/dist/core/tokens/parsers/scss.d.ts.map +1 -0
  144. package/dist/core/tokens/parsers/scss.js +5 -0
  145. package/dist/core/tokens/parsers/scss.js.map +1 -0
  146. package/dist/core/tokens/parsers/stubs.d.ts +11 -0
  147. package/dist/core/tokens/parsers/stubs.d.ts.map +1 -0
  148. package/dist/core/tokens/parsers/stubs.js +14 -0
  149. package/dist/core/tokens/parsers/stubs.js.map +1 -0
  150. package/dist/core/tokens/parsers/style-dictionary-v3.d.ts +3 -0
  151. package/dist/core/tokens/parsers/style-dictionary-v3.d.ts.map +1 -0
  152. package/dist/core/tokens/parsers/style-dictionary-v3.js +5 -0
  153. package/dist/core/tokens/parsers/style-dictionary-v3.js.map +1 -0
  154. package/dist/core/tokens/parsers/tailwind-v3.d.ts +3 -0
  155. package/dist/core/tokens/parsers/tailwind-v3.d.ts.map +1 -0
  156. package/dist/core/tokens/parsers/tailwind-v3.js +5 -0
  157. package/dist/core/tokens/parsers/tailwind-v3.js.map +1 -0
  158. package/dist/core/tokens/parsers/tailwind-v4.d.ts +3 -0
  159. package/dist/core/tokens/parsers/tailwind-v4.d.ts.map +1 -0
  160. package/dist/core/tokens/parsers/tailwind-v4.js +5 -0
  161. package/dist/core/tokens/parsers/tailwind-v4.js.map +1 -0
  162. package/dist/core/tokens/parsers/tokens-studio.d.ts +3 -0
  163. package/dist/core/tokens/parsers/tokens-studio.d.ts.map +1 -0
  164. package/dist/core/tokens/parsers/tokens-studio.js +5 -0
  165. package/dist/core/tokens/parsers/tokens-studio.js.map +1 -0
  166. package/dist/core/tokens/schemas.d.ts +152 -0
  167. package/dist/core/tokens/schemas.d.ts.map +1 -0
  168. package/dist/core/tokens/schemas.js +149 -0
  169. package/dist/core/tokens/schemas.js.map +1 -0
  170. package/dist/core/tokens/transforms/color.d.ts +9 -0
  171. package/dist/core/tokens/transforms/color.d.ts.map +1 -0
  172. package/dist/core/tokens/transforms/color.js +13 -0
  173. package/dist/core/tokens/transforms/color.js.map +1 -0
  174. package/dist/core/tokens/transforms/index.d.ts +36 -0
  175. package/dist/core/tokens/transforms/index.d.ts.map +1 -0
  176. package/dist/core/tokens/transforms/index.js +30 -0
  177. package/dist/core/tokens/transforms/index.js.map +1 -0
  178. package/dist/core/tokens/transforms/size.d.ts +7 -0
  179. package/dist/core/tokens/transforms/size.d.ts.map +1 -0
  180. package/dist/core/tokens/transforms/size.js +8 -0
  181. package/dist/core/tokens/transforms/size.js.map +1 -0
  182. package/dist/core/tokens/types.d.ts +228 -0
  183. package/dist/core/tokens/types.d.ts.map +1 -0
  184. package/dist/core/tokens/types.js +19 -0
  185. package/dist/core/tokens/types.js.map +1 -0
  186. package/dist/core/tokens-tools.d.ts +42 -0
  187. package/dist/core/tokens-tools.d.ts.map +1 -0
  188. package/dist/core/tokens-tools.js +850 -0
  189. package/dist/core/tokens-tools.js.map +1 -0
  190. package/dist/core/types/index.d.ts +0 -8
  191. package/dist/core/types/index.d.ts.map +1 -1
  192. package/dist/core/websocket-connector.d.ts +1 -1
  193. package/dist/core/websocket-connector.d.ts.map +1 -1
  194. package/dist/core/websocket-server.d.ts +4 -3
  195. package/dist/core/websocket-server.d.ts.map +1 -1
  196. package/dist/core/websocket-server.js +5 -55
  197. package/dist/core/websocket-server.js.map +1 -1
  198. package/dist/local.d.ts +0 -12
  199. package/dist/local.d.ts.map +1 -1
  200. package/dist/local.js +959 -3406
  201. package/dist/local.js.map +1 -1
  202. package/figma-desktop-bridge/code.js +11 -63
  203. package/figma-desktop-bridge/ui.html +72 -11
  204. package/package.json +10 -9
  205. package/figma-desktop-bridge/ui-full.html +0 -1353
@@ -1,22 +1,23 @@
1
1
  // Figma Desktop Bridge - MCP Plugin
2
- // Bridges Figma API to MCP clients via plugin UI window
3
- // Supports: Variables, Components, Styles, and more
4
- // Uses postMessage to communicate with UI, bypassing worker sandbox limitations
5
- // Puppeteer can access UI iframe's window context to retrieve data
2
+ // Bridges the Figma Plugin API to MCP clients via the plugin's UI iframe.
3
+ // Supports: Variables, Components, Styles, and more.
4
+ // Uses postMessage to communicate with ui.html (bypassing worker sandbox limitations),
5
+ // which then forwards messages to the MCP server over the WebSocket bridge.
6
6
 
7
7
  // Plugin version — sent in FILE_INFO for server-side version compatibility checks.
8
8
  // The server compares this against its own version to detect stale cached plugins.
9
- var PLUGIN_VERSION = '1.25.0'; // Kept in sync with package.json by scripts/release.sh — see issue #62.
9
+ var PLUGIN_VERSION = '1.27.1'; // Kept in sync with package.json by scripts/release.sh — see issue #62.
10
10
 
11
11
  console.log('🌉 [Desktop Bridge] Plugin loaded (v' + PLUGIN_VERSION + ')');
12
12
 
13
13
  // Show minimal UI - compact status indicator
14
- figma.showUI(__html__, { width: 140, height: 50, visible: true, themeColors: true });
14
+ figma.showUI(__html__, { width: 180, height: 50, visible: true, themeColors: true });
15
15
 
16
16
  // ============================================================================
17
17
  // CONSOLE CAPTURE — Intercept console.* in the QuickJS sandbox and forward
18
18
  // to ui.html via postMessage so the WebSocket bridge can relay them to the MCP
19
- // server. This enables console monitoring without CDP.
19
+ // server. This is the only console-capture path in local mode (no browser
20
+ // process is involved).
20
21
  // ============================================================================
21
22
  (function() {
22
23
  var levels = ['log', 'info', 'warn', 'error', 'debug'];
@@ -220,59 +221,6 @@ function hexToFigmaRGB(hex) {
220
221
  // Listen for requests from UI (e.g., component data requests, write operations)
221
222
  figma.ui.onmessage = async (msg) => {
222
223
 
223
- // ============================================================================
224
- // BOOT_LOAD_UI - Bootloader fetched fresh UI HTML from the MCP server.
225
- // Replace the bootloader with the full, always-up-to-date plugin UI.
226
- // This uses figma.showUI() with the HTML string directly — no redirects,
227
- // no cross-origin, no CSP issues.
228
- // ============================================================================
229
- if (msg.type === 'BOOT_LOAD_UI' && msg.html) {
230
- console.log('🌉 [Desktop Bridge] Bootloader delivered fresh UI (' + msg.html.length + ' bytes), loading...');
231
- figma.showUI(msg.html, { width: 140, height: 50, visible: true, themeColors: true });
232
-
233
- // Re-send variables data to the fresh UI — the original send went to the
234
- // bootloader which discarded it. The fresh UI needs it to show "ready" status.
235
- (async function() {
236
- try {
237
- var variables = await figma.variables.getLocalVariablesAsync();
238
- var collections = await figma.variables.getLocalVariableCollectionsAsync();
239
- figma.ui.postMessage({
240
- type: 'VARIABLES_DATA',
241
- data: {
242
- success: true,
243
- timestamp: Date.now(),
244
- fileKey: figma.fileKey || null,
245
- variables: variables.map(function(v) { return {
246
- id: v.id, name: v.name, key: v.key, resolvedType: v.resolvedType,
247
- valuesByMode: v.valuesByMode, variableCollectionId: v.variableCollectionId,
248
- scopes: v.scopes, codeSyntax: v.codeSyntax || {}, description: v.description, hiddenFromPublishing: v.hiddenFromPublishing
249
- }; }),
250
- variableCollections: collections.map(function(c) { return {
251
- id: c.id, name: c.name, key: c.key, modes: c.modes,
252
- defaultModeId: c.defaultModeId, variableIds: c.variableIds
253
- }; })
254
- }
255
- });
256
- console.log('🌉 [Desktop Bridge] Re-sent variables to fresh UI (' + variables.length + ' vars)');
257
- } catch (e) {
258
- console.log('🌉 [Desktop Bridge] Could not re-send variables:', e.message || e);
259
- }
260
- })();
261
- return;
262
- }
263
-
264
- // ============================================================================
265
- // BOOT_FALLBACK - Bootloader found an old server that doesn't support the
266
- // bootloader protocol. Fall back to reloading the cached __html__ which
267
- // contains the full UI (for users who haven't switched to the bootloader yet,
268
- // __html__ IS the full UI; for bootloader users, this is a no-op reload).
269
- // ============================================================================
270
- if (msg.type === 'BOOT_FALLBACK') {
271
- console.log('🌉 [Desktop Bridge] Old server detected on port ' + msg.port + ', using cached UI');
272
- figma.showUI(__html__, { width: 140, height: 50, visible: true, themeColors: true });
273
- return;
274
- }
275
-
276
224
  // ============================================================================
277
225
  // EXECUTE_CODE - Arbitrary code execution (Power Tool)
278
226
  // ============================================================================
@@ -376,7 +324,7 @@ figma.ui.onmessage = async (msg) => {
376
324
  var errorMsg = error && error.message ? error.message : String(error);
377
325
  var errorStack = error && error.stack ? error.stack : '';
378
326
 
379
- // Log error details as strings so they show up properly in Puppeteer
327
+ // Log error details as strings so they survive intact through the WebSocket bridge into figma_get_console_logs
380
328
  console.error('🌉 [Desktop Bridge] Code execution error: [' + errorName + '] ' + errorMsg);
381
329
  if (errorStack) {
382
330
  console.error('🌉 [Desktop Bridge] Stack:', errorStack);
@@ -3101,7 +3049,7 @@ figma.ui.onmessage = async (msg) => {
3101
3049
  });
3102
3050
  // Short delay to let the response message be sent before reload
3103
3051
  setTimeout(function() {
3104
- figma.showUI(__html__, { width: 140, height: 50, visible: true, themeColors: true });
3052
+ figma.showUI(__html__, { width: 180, height: 50, visible: true, themeColors: true });
3105
3053
  }, 100);
3106
3054
  } catch (error) {
3107
3055
  var errorMsg = error && error.message ? error.message : String(error);
@@ -6424,4 +6372,4 @@ console.log('🌉 [Desktop Bridge] Ready to handle component requests');
6424
6372
  console.log('🌉 [Desktop Bridge] Plugin will stay open until manually closed');
6425
6373
 
6426
6374
  // Plugin stays open - no auto-close
6427
- // UI iframe remains accessible for Puppeteer to read data from window object
6375
+ // UI iframe remains accessible so the in-iframe WebSocket bridge client can keep relaying state to the MCP server
@@ -217,7 +217,7 @@
217
217
 
218
218
  <script>
219
219
  // ============================================================================
220
- // GLOBAL STATE - Data storage for Puppeteer/MCP access
220
+ // GLOBAL STATE backing store for the in-iframe WebSocket bridge client
221
221
  // ============================================================================
222
222
  window.__figmaVariablesData = null;
223
223
  window.__figmaVariablesReady = false;
@@ -227,13 +227,67 @@
227
227
 
228
228
  let requestIdCounter = 0;
229
229
 
230
- // UI update helper
231
- function updateStatus(state, isActive, isError) {
232
- const dot = document.getElementById('status-dot');
233
- const stateText = document.getElementById('status-state');
230
+ // Status pill state — captured here so we can re-render whenever the
231
+ // mode (local port count, cloud paired) changes without losing the
232
+ // ready/connecting/error state set by the data layer.
233
+ let _currentStatusState = 'connecting';
234
+ let _currentStatusActive = false;
235
+ let _currentStatusError = false;
236
+
237
+ // Compute the mode label shown in place of the static "MCP" prefix.
238
+ // Returns "Local", "Cloud", "Local + Cloud", or "" (unknown — falls back
239
+ // to the original "MCP" label so the pill always says something).
240
+ // Lets users see at a glance which transport is carrying their session,
241
+ // so a confused user doesn't have to guess whether they're talking to
242
+ // the local server, the cloud relay, or both. Port numbers are omitted
243
+ // here to keep the pill compact — figma_diagnose exposes the port when
244
+ // it's actually needed.
245
+ //
246
+ // NOTE: `activeConnections` is declared inside the connection-pool IIFE
247
+ // below (around line ~617), so it is NOT in scope from this top-level
248
+ // function. The IIFE exposes `window.__wsGetActiveConnections()` for
249
+ // exactly this reason — calling that getter is what makes the pill
250
+ // update once the pool reports a live connection.
251
+ function renderModeText() {
252
+ try {
253
+ var getConns = window.__wsGetActiveConnections;
254
+ var conns = typeof getConns === 'function' ? (getConns() || []) : [];
255
+ var localUp = conns.some(function(c) {
256
+ return c && c.ws && c.ws.readyState === 1 && c.port !== 'cloud';
257
+ });
258
+ var cloudUp = conns.some(function(c) {
259
+ return c && c.ws && c.ws.readyState === 1 && c.port === 'cloud';
260
+ });
261
+ if (localUp && cloudUp) return 'Local + Cloud';
262
+ if (localUp) return 'Local';
263
+ if (cloudUp) return 'Cloud';
264
+ return '';
265
+ } catch (e) {
266
+ return '';
267
+ }
268
+ }
234
269
 
235
- dot.className = 'status-indicator ' + (isError ? 'error' : (isActive ? 'active' : 'loading'));
236
- stateText.textContent = state;
270
+ function refreshStatus() {
271
+ var dot = document.getElementById('status-dot');
272
+ var stateText = document.getElementById('status-state');
273
+ var labelEl = document.querySelector('.status-text .label');
274
+ if (!dot || !stateText) return;
275
+ dot.className = 'status-indicator ' + (_currentStatusError ? 'error' : (_currentStatusActive ? 'active' : 'loading'));
276
+ var mode = renderModeText();
277
+ // Replace the static "MCP" label with the live mode label (Local / Cloud
278
+ // / Local + Cloud). Fall back to "MCP" when nothing is connected yet so
279
+ // the pill still has a visible label during initial scan.
280
+ if (labelEl) labelEl.textContent = mode || 'MCP';
281
+ stateText.textContent = _currentStatusState;
282
+ }
283
+
284
+ // UI update helper — preserves the latest state and re-renders, picking
285
+ // up any mode-text changes (local/cloud connect/disconnect).
286
+ function updateStatus(state, isActive, isError) {
287
+ _currentStatusState = state;
288
+ _currentStatusActive = isActive;
289
+ _currentStatusError = isError;
290
+ refreshStatus();
237
291
  }
238
292
 
239
293
  // ============================================================================
@@ -605,7 +659,8 @@
605
659
  };
606
660
 
607
661
  // ============================================================================
608
- // WEBSOCKET BRIDGE CLIENT - Fallback transport when CDP is unavailable
662
+ // WEBSOCKET BRIDGE CLIENT primary transport from the plugin sandbox to
663
+ // the MCP server. Scans port range 9223–9232 for multiple instances.
609
664
  // ============================================================================
610
665
  (function() {
611
666
  // Port range for multi-instance support (matches server's port-discovery.ts)
@@ -800,7 +855,9 @@
800
855
  }
801
856
 
802
857
  /**
803
- * Update backward-compat variables (ws, wsPort, wsConnected).
858
+ * Update backward-compat variables (ws, wsPort, wsConnected) and
859
+ * re-render the status pill so the Local/Cloud mode suffix reflects
860
+ * the new connection set.
804
861
  */
805
862
  function updateCompatState() {
806
863
  var live = activeConnections.filter(function(c) { return c.ws.readyState === 1; });
@@ -812,6 +869,9 @@
812
869
  ws = null;
813
870
  wsPort = null;
814
871
  }
872
+ // refreshStatus is defined in the outer scope (top-level script block).
873
+ // Guarded for the unlikely case it's invoked before that script runs.
874
+ if (typeof refreshStatus === 'function') refreshStatus();
815
875
  }
816
876
 
817
877
  /**
@@ -1109,9 +1169,10 @@
1109
1169
  section.classList.toggle('visible');
1110
1170
  toggle.classList.toggle('expanded');
1111
1171
 
1112
- // Resize plugin window to fit content
1172
+ // Resize plugin window to fit content. Default width is 180px to give
1173
+ // the status pill enough room for the "Local + Cloud" mode label.
1113
1174
  var height = isExpanding ? 130 : 50;
1114
- parent.postMessage({ pluginMessage: { type: 'RESIZE_UI', width: 140, height: height } }, '*');
1175
+ parent.postMessage({ pluginMessage: { type: 'RESIZE_UI', width: 180, height: height } }, '*');
1115
1176
  }
1116
1177
 
1117
1178
  function resetCloudUI() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mp3wizard/figma-console-mcp",
3
- "version": "1.25.1",
4
- "description": "MCP server for accessing Figma plugin console logs and screenshots via Cloudflare Workers or local mode",
3
+ "version": "1.27.2",
4
+ "description": "The most comprehensive MCP server for Figma design tokens, variables, components, write tools, version history diff, accessibility audits, FigJam, Slides, and more. Local (WebSocket Desktop Bridge plugin) and Cloudflare Workers (paired + remote) modes.",
5
5
  "type": "module",
6
6
  "main": "dist/local.js",
7
7
  "types": "dist/local.d.ts",
@@ -37,15 +37,18 @@
37
37
  "mcp",
38
38
  "figma",
39
39
  "plugin",
40
- "console",
41
- "debugging",
40
+ "design-tokens",
41
+ "design-systems",
42
+ "variables",
43
+ "figjam",
44
+ "slides",
45
+ "accessibility",
42
46
  "ai",
43
47
  "anthropic",
44
48
  "claude",
45
- "cloudflare",
46
- "workers"
49
+ "cloudflare"
47
50
  ],
48
- "author": "Your Name",
51
+ "author": "Southleft",
49
52
  "license": "MIT",
50
53
  "repository": {
51
54
  "type": "git",
@@ -60,11 +63,9 @@
60
63
  "@modelcontextprotocol/sdk": "^1.26.0",
61
64
  "agents": "^0.7.1",
62
65
  "axe-core": "^4.11.2",
63
- "chrome-remote-interface": "^0.33.2",
64
66
  "jsdom": "^29.0.1",
65
67
  "pino": "^9.5.0",
66
68
  "pino-pretty": "^13.0.0",
67
- "puppeteer-core": "^23.11.1",
68
69
  "uuid": "^11.0.3",
69
70
  "ws": "^8.19.0",
70
71
  "zod": "^3.25.76"