conductor-figma 1.0.2 → 3.0.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.
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "Conductor",
3
+ "id": "conductor-figma-mcp",
4
+ "api": "1.0.0",
5
+ "main": "code.js",
6
+ "ui": "ui.html",
7
+ "capabilities": [],
8
+ "enableProposedApi": false,
9
+ "editorType": ["figma"],
10
+ "networkAccess": {
11
+ "allowedDomains": ["none"],
12
+ "reasoning": "Conductor connects to a local WebSocket server only"
13
+ }
14
+ }
@@ -0,0 +1,77 @@
1
+ <html>
2
+ <head>
3
+ <style>
4
+ body { margin:0; padding:16px; font-family:system-ui,-apple-system,sans-serif; font-size:13px; background:#1e1e1e; color:#ccc; }
5
+ .status { display:flex; align-items:center; gap:8px; margin-bottom:12px; }
6
+ .dot { width:8px; height:8px; border-radius:50%; }
7
+ .dot.on { background:#4ade80; }
8
+ .dot.off { background:#f87171; }
9
+ .log { font-family:monospace; font-size:11px; color:#888; max-height:120px; overflow-y:auto; background:#161616; border-radius:6px; padding:8px; line-height:1.6; }
10
+ h3 { font-size:14px; font-weight:600; color:#fff; margin:0 0 4px; }
11
+ p { color:#888; margin:0 0 12px; font-size:11px; }
12
+ </style>
13
+ </head>
14
+ <body>
15
+ <h3>Conductor v3</h3>
16
+ <p>150+ design-intelligent tools</p>
17
+ <div class="status">
18
+ <div class="dot" id="dot"></div>
19
+ <span id="statusText">Connecting...</span>
20
+ </div>
21
+ <div class="log" id="log"></div>
22
+
23
+ <script>
24
+ let ws = null;
25
+ let port = 3055;
26
+ let reconnectTimer = null;
27
+
28
+ function log(msg) {
29
+ const el = document.getElementById('log');
30
+ const time = new Date().toLocaleTimeString();
31
+ el.innerHTML += `<div>${time} ${msg}</div>`;
32
+ el.scrollTop = el.scrollHeight;
33
+ }
34
+
35
+ function setStatus(connected) {
36
+ document.getElementById('dot').className = 'dot ' + (connected ? 'on' : 'off');
37
+ document.getElementById('statusText').textContent = connected ? 'Connected' : 'Disconnected';
38
+ }
39
+
40
+ function connect() {
41
+ try {
42
+ ws = new WebSocket(`ws://localhost:${port}`);
43
+ ws.onopen = () => {
44
+ setStatus(true);
45
+ log('Connected to MCP server');
46
+ parent.postMessage({ pluginMessage: { type: 'connected' } }, '*');
47
+ };
48
+ ws.onmessage = (e) => {
49
+ try {
50
+ const data = JSON.parse(e.data);
51
+ log(`← ${data.command || 'response'}`);
52
+ parent.postMessage({ pluginMessage: { type: 'ws-message', data } }, '*');
53
+ } catch (err) { log('Parse error: ' + err.message); }
54
+ };
55
+ ws.onclose = () => {
56
+ setStatus(false);
57
+ log('Disconnected');
58
+ parent.postMessage({ pluginMessage: { type: 'disconnected' } }, '*');
59
+ reconnectTimer = setTimeout(connect, 3000);
60
+ };
61
+ ws.onerror = () => { setStatus(false); };
62
+ } catch (e) { log('Connection error'); setTimeout(connect, 3000); }
63
+ }
64
+
65
+ window.onmessage = (e) => {
66
+ const msg = e.data.pluginMessage;
67
+ if (!msg) return;
68
+ if (msg.type === 'connect') { port = msg.port || 3055; connect(); }
69
+ if (msg.type === 'ws-send' && ws && ws.readyState === 1) {
70
+ ws.send(msg.data);
71
+ const parsed = JSON.parse(msg.data);
72
+ log(`→ response ${parsed.id}`);
73
+ }
74
+ };
75
+ </script>
76
+ </body>
77
+ </html>
package/package.json CHANGED
@@ -1,17 +1,18 @@
1
1
  {
2
2
  "name": "conductor-figma",
3
- "version": "1.0.2",
4
- "description": "Design-intelligent MCP server for Figma. 61 tools across 10 categories. 8px grid, type scale ratios, auto-layout, component reuse, accessibility real design intelligence, not shape proxying.",
3
+ "version": "3.0.0",
4
+ "description": "Design-intelligent MCP server for Figma. 201 design-intelligent tools for Figma. Every tool knows typography, spacing, color, accessibility. Not a shape proxy a design engine.",
5
5
  "author": "0xDragoon",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
- "main": "./src/index.js",
8
+ "main": "./src/server.js",
9
9
  "bin": {
10
10
  "conductor-figma": "./bin/conductor.js"
11
11
  },
12
12
  "files": [
13
- "bin",
14
13
  "src",
14
+ "bin",
15
+ "figma-plugin",
15
16
  "README.md",
16
17
  "LICENSE"
17
18
  ],
@@ -19,22 +20,30 @@
19
20
  "start": "node bin/conductor.js",
20
21
  "test": "node test/run.js"
21
22
  },
23
+ "dependencies": {
24
+ "@anthropic-ai/sdk": "^0.39.0",
25
+ "ws": "^8.19.0"
26
+ },
22
27
  "keywords": [
23
- "mcp", "figma", "design", "ai", "cursor", "claude-code",
24
- "auto-layout", "design-system", "tokens", "components",
25
- "accessibility", "wcag", "type-scale", "spacing", "grid",
26
- "model-context-protocol", "copilot", "devtools"
28
+ "figma",
29
+ "mcp",
30
+ "model-context-protocol",
31
+ "design",
32
+ "ai-agent",
33
+ "cursor",
34
+ "claude-code",
35
+ "auto-layout",
36
+ "design-system",
37
+ "accessibility",
38
+ "design-tokens",
39
+ "code-export",
40
+ "react",
41
+ "tailwind",
42
+ "design-intelligence"
27
43
  ],
28
44
  "repository": {
29
45
  "type": "git",
30
46
  "url": "https://github.com/dragoon0x/conductor"
31
47
  },
32
- "homepage": "https://dragoon0x.github.io/conductor/",
33
- "engines": {
34
- "node": ">=18.0.0"
35
- },
36
- "dependencies": {},
37
- "optionalDependencies": {
38
- "ws": "^8.0.0"
39
- }
48
+ "homepage": "https://dragoon0x.github.io/conductor/"
40
49
  }
package/src/bridge.js ADDED
@@ -0,0 +1,60 @@
1
+ // ═══════════════════════════════════════════
2
+ // CONDUCTOR v3 — WebSocket Bridge
3
+ // ═══════════════════════════════════════════
4
+
5
+ import { WebSocketServer } from 'ws'
6
+
7
+ function log(...args) { process.stderr.write('[bridge] ' + args.join(' ') + '\n') }
8
+
9
+ export function createBridge(port) {
10
+ port = port || parseInt(process.env.CONDUCTOR_PORT) || 3055
11
+ let wss = null
12
+ let client = null
13
+ let pending = new Map()
14
+ let msgId = 0
15
+
16
+ function start() {
17
+ return new Promise((resolve) => {
18
+ wss = new WebSocketServer({ port })
19
+ wss.on('listening', () => { log(`WebSocket server on port ${port}`); resolve() })
20
+ wss.on('connection', (ws) => {
21
+ client = ws
22
+ log('Figma plugin connected')
23
+ ws.on('message', (data) => {
24
+ try {
25
+ const msg = JSON.parse(data.toString())
26
+ if (msg.id && pending.has(msg.id)) {
27
+ const { resolve, reject, timer } = pending.get(msg.id)
28
+ clearTimeout(timer)
29
+ pending.delete(msg.id)
30
+ if (msg.error) reject(new Error(msg.error))
31
+ else resolve(msg.result)
32
+ }
33
+ } catch (e) { log('Parse error:', e.message) }
34
+ })
35
+ ws.on('close', () => { client = null; log('Figma plugin disconnected') })
36
+ ws.on('error', (e) => log('WS error:', e.message))
37
+ })
38
+ wss.on('error', (e) => { log('Server error:', e.message); resolve() })
39
+ })
40
+ }
41
+
42
+ function stop() { if (wss) { wss.close(); wss = null } }
43
+
44
+ function isConnected() { return client !== null && client.readyState === 1 }
45
+
46
+ function send(command, data, timeout = 15000) {
47
+ return new Promise((resolve, reject) => {
48
+ if (!isConnected()) return reject(new Error('Figma plugin not connected. Open Figma → Plugins → Development → Conductor'))
49
+ const id = ++msgId
50
+ const timer = setTimeout(() => {
51
+ pending.delete(id)
52
+ reject(new Error(`Timeout waiting for Figma response (${timeout}ms)`))
53
+ }, timeout)
54
+ pending.set(id, { resolve, reject, timer })
55
+ client.send(JSON.stringify({ id, command, data }))
56
+ })
57
+ }
58
+
59
+ return { start, stop, isConnected, send, getPort: () => port }
60
+ }