figma-console-mcp 0.1.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 +328 -0
- package/dist/browser/base.d.ts +50 -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 +66 -0
- package/dist/browser/local.d.ts.map +1 -0
- package/dist/browser/local.js +223 -0
- package/dist/browser/local.js.map +1 -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/config.js +161 -0
- package/dist/cloudflare/core/console-monitor.js +382 -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 +273 -0
- package/dist/cloudflare/core/figma-desktop-connector.js +383 -0
- package/dist/cloudflare/core/figma-style-extractor.js +311 -0
- package/dist/cloudflare/core/figma-tools.js +2299 -0
- package/dist/cloudflare/core/logger.js +53 -0
- package/dist/cloudflare/core/snippet-injector.js +96 -0
- package/dist/cloudflare/core/types/enriched.js +5 -0
- package/dist/cloudflare/core/types/index.js +4 -0
- package/dist/cloudflare/index.js +1059 -0
- package/dist/cloudflare/test-browser.js +88 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +141 -0
- package/dist/config.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 +81 -0
- package/dist/core/console-monitor.d.ts.map +1 -0
- package/dist/core/console-monitor.js +383 -0
- package/dist/core/console-monitor.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 +137 -0
- package/dist/core/figma-api.d.ts.map +1 -0
- package/dist/core/figma-api.js +274 -0
- package/dist/core/figma-api.js.map +1 -0
- package/dist/core/figma-desktop-connector.d.ts +52 -0
- package/dist/core/figma-desktop-connector.d.ts.map +1 -0
- package/dist/core/figma-desktop-connector.js +384 -0
- package/dist/core/figma-desktop-connector.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 +15 -0
- package/dist/core/figma-tools.d.ts.map +1 -0
- package/dist/core/figma-tools.js +2300 -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/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/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/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/local.d.ts +57 -0
- package/dist/local.d.ts.map +1 -0
- package/dist/local.js +668 -0
- package/dist/local.js.map +1 -0
- package/dist/logger.d.ts +22 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +45 -0
- package/dist/logger.js.map +1 -0
- package/dist/server.d.ts +40 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +99 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/index.d.ts +15 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +184 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types/index.d.ts +102 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/figma-desktop-bridge/README.md +232 -0
- package/figma-desktop-bridge/code.js +133 -0
- package/figma-desktop-bridge/manifest.json +13 -0
- package/figma-desktop-bridge/ui.html +200 -0
- package/package.json +77 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging infrastructure using pino
|
|
3
|
+
*/
|
|
4
|
+
import pino from 'pino';
|
|
5
|
+
/**
|
|
6
|
+
* Create logger instance
|
|
7
|
+
* Note: In Cloudflare Workers, console methods are automatically captured
|
|
8
|
+
*/
|
|
9
|
+
export function createLogger(level = 'info') {
|
|
10
|
+
// Check if running in Cloudflare Workers environment
|
|
11
|
+
const isWorkers = typeof globalThis.caches !== 'undefined';
|
|
12
|
+
if (isWorkers) {
|
|
13
|
+
// Cloudflare Workers: use simple console-based logging
|
|
14
|
+
return pino({
|
|
15
|
+
level: process.env.LOG_LEVEL || level,
|
|
16
|
+
browser: {
|
|
17
|
+
asObject: true,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
// Node.js environment: detect MCP stdio mode
|
|
22
|
+
// When stdout is not a TTY, we're likely in MCP stdio mode
|
|
23
|
+
const isMCPStdio = !process.stdout.isTTY;
|
|
24
|
+
// MCP stdio mode: NO pretty printing, stderr only
|
|
25
|
+
if (isMCPStdio) {
|
|
26
|
+
return pino({ level: process.env.LOG_LEVEL || level }, pino.destination({ dest: 2, sync: false }));
|
|
27
|
+
}
|
|
28
|
+
// Development/terminal mode: use pretty printing
|
|
29
|
+
return pino({
|
|
30
|
+
level: process.env.LOG_LEVEL || level,
|
|
31
|
+
transport: process.env.NODE_ENV !== 'production'
|
|
32
|
+
? {
|
|
33
|
+
target: 'pino-pretty',
|
|
34
|
+
options: {
|
|
35
|
+
colorize: true,
|
|
36
|
+
translateTime: 'HH:MM:ss',
|
|
37
|
+
ignore: 'pid,hostname',
|
|
38
|
+
destination: 2, // Explicit stderr for transport
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
: undefined,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Default logger instance
|
|
46
|
+
*/
|
|
47
|
+
export const logger = createLogger();
|
|
48
|
+
/**
|
|
49
|
+
* Create child logger with additional context
|
|
50
|
+
*/
|
|
51
|
+
export function createChildLogger(bindings) {
|
|
52
|
+
return logger.child(bindings);
|
|
53
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snippet Injector
|
|
3
|
+
* Generates and manages console-based data extraction snippets for Figma
|
|
4
|
+
*/
|
|
5
|
+
import { createChildLogger } from './logger.js';
|
|
6
|
+
const logger = createChildLogger({ component: 'snippet-injector' });
|
|
7
|
+
export class SnippetInjector {
|
|
8
|
+
/**
|
|
9
|
+
* Generate variables extraction snippet for Figma console
|
|
10
|
+
*/
|
|
11
|
+
generateVariablesSnippet() {
|
|
12
|
+
return `
|
|
13
|
+
(async () => {
|
|
14
|
+
try {
|
|
15
|
+
const vars = await figma.variables.getLocalVariablesAsync();
|
|
16
|
+
const collections = await figma.variables.getLocalVariableCollectionsAsync();
|
|
17
|
+
|
|
18
|
+
const payload = {
|
|
19
|
+
timestamp: Date.now(),
|
|
20
|
+
variables: vars.map(v => ({
|
|
21
|
+
id: v.id,
|
|
22
|
+
name: v.name,
|
|
23
|
+
key: v.key,
|
|
24
|
+
resolvedType: v.resolvedType,
|
|
25
|
+
valuesByMode: v.valuesByMode,
|
|
26
|
+
variableCollectionId: v.variableCollectionId,
|
|
27
|
+
scopes: v.scopes,
|
|
28
|
+
description: v.description,
|
|
29
|
+
hiddenFromPublishing: v.hiddenFromPublishing
|
|
30
|
+
})),
|
|
31
|
+
variableCollections: collections.map(c => ({
|
|
32
|
+
id: c.id,
|
|
33
|
+
name: c.name,
|
|
34
|
+
key: c.key,
|
|
35
|
+
modes: c.modes.map(m => ({ modeId: m.modeId, name: m.name })),
|
|
36
|
+
defaultModeId: c.defaultModeId,
|
|
37
|
+
variableIds: c.variableIds
|
|
38
|
+
}))
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
console.log('[MCP_VARIABLES]', JSON.stringify(payload), '[MCP_VARIABLES_END]');
|
|
42
|
+
console.log('✅ Variables data captured! Run figma_get_variables({ parseFromConsole: true }) in Claude to retrieve.');
|
|
43
|
+
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.error('[MCP_VARIABLES_ERROR]', error.message);
|
|
46
|
+
console.log('❌ Make sure you\\'re running this in a Figma file with variables.');
|
|
47
|
+
}
|
|
48
|
+
})();
|
|
49
|
+
`.trim();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Parse variables from console log entry
|
|
53
|
+
*/
|
|
54
|
+
parseVariablesFromLog(logEntry) {
|
|
55
|
+
try {
|
|
56
|
+
// Check for marker
|
|
57
|
+
if (!logEntry.message.includes('[MCP_VARIABLES]')) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
// Extract JSON from args
|
|
61
|
+
// The snippet logs: console.log('[MCP_VARIABLES]', JSON.stringify(payload), '[MCP_VARIABLES_END]')
|
|
62
|
+
// So args[0] is the marker, args[1] is the JSON string
|
|
63
|
+
const jsonStr = logEntry.args[1] || logEntry.args[0];
|
|
64
|
+
if (!jsonStr) {
|
|
65
|
+
throw new Error('No data found in console log');
|
|
66
|
+
}
|
|
67
|
+
const data = typeof jsonStr === 'string' ? JSON.parse(jsonStr) : jsonStr;
|
|
68
|
+
logger.info({
|
|
69
|
+
variableCount: data.variables?.length || 0,
|
|
70
|
+
collectionCount: data.variableCollections?.length || 0,
|
|
71
|
+
}, 'Successfully parsed variables from console log');
|
|
72
|
+
return {
|
|
73
|
+
variables: data.variables || [],
|
|
74
|
+
variableCollections: data.variableCollections || [],
|
|
75
|
+
timestamp: data.timestamp || Date.now(),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
logger.error({ error }, 'Failed to parse variables from console log');
|
|
80
|
+
throw new Error(`Failed to parse variables from console log: ${error instanceof Error ? error.message : String(error)}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Find the most recent variables log entry
|
|
85
|
+
*/
|
|
86
|
+
findVariablesLog(logs) {
|
|
87
|
+
// Search in reverse (most recent first)
|
|
88
|
+
for (let i = logs.length - 1; i >= 0; i--) {
|
|
89
|
+
const log = logs[i];
|
|
90
|
+
if (log.message.includes('[MCP_VARIABLES]')) {
|
|
91
|
+
return log;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|