conductor-figma 3.0.1 → 3.0.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.
- package/README.md +0 -16
- package/package.json +1 -1
- package/src/bridge.js +52 -36
package/README.md
CHANGED
|
@@ -80,22 +80,6 @@ Every tool queries the intelligence engine:
|
|
|
80
80
|
- **Font Weights**: Auto-resolves "bold" → "Bold", "600" → "Semi Bold"
|
|
81
81
|
- **Layout Intelligence**: 13 layout presets (row, column, center, spread, grid, sidebar, form)
|
|
82
82
|
|
|
83
|
-
## vs Competition
|
|
84
|
-
|
|
85
|
-
|---------|-----------|--------|-----------|---------------|
|
|
86
|
-
| Tools | 201 | 45 | 5 | 12 |
|
|
87
|
-
| Categories | 17 | ~8 | 1 | ~4 |
|
|
88
|
-
| Design intelligence | Yes | No | No | No |
|
|
89
|
-
| Smart components | 18 types | No | No | No |
|
|
90
|
-
| Accessibility | 12 tools | No | No | No |
|
|
91
|
-
| Code export | 5 frameworks | No | No | Partial |
|
|
92
|
-
| Batch operations | 17 tools | No | No | No |
|
|
93
|
-
| Design system | 10 tools (free) | $9 add-on | No | Partial |
|
|
94
|
-
| Responsive | 5 tools | No | No | No |
|
|
95
|
-
| Typography | 10 tools | No | No | No |
|
|
96
|
-
| Prototype | 10 tools | No | No | No |
|
|
97
|
-
| Annotation | 10 tools | No | No | No |
|
|
98
|
-
|
|
99
83
|
## License
|
|
100
84
|
|
|
101
85
|
MIT. Built by [0xDragoon](https://github.com/dragoon0x).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conductor-figma",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
4
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",
|
package/src/bridge.js
CHANGED
|
@@ -4,57 +4,73 @@
|
|
|
4
4
|
|
|
5
5
|
import { WebSocketServer } from 'ws'
|
|
6
6
|
|
|
7
|
-
function log(
|
|
7
|
+
function log() { process.stderr.write('[bridge] ' + Array.prototype.join.call(arguments, ' ') + '\n') }
|
|
8
8
|
|
|
9
9
|
export function createBridge(port) {
|
|
10
10
|
port = port || parseInt(process.env.CONDUCTOR_PORT) || 3055
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
var wss = null
|
|
12
|
+
var client = null
|
|
13
|
+
var pending = new Map()
|
|
14
|
+
var msgId = 0
|
|
15
|
+
var isOwner = false
|
|
15
16
|
|
|
16
17
|
function start() {
|
|
17
|
-
return new Promise((resolve)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
18
|
+
return new Promise(function(resolve) {
|
|
19
|
+
try {
|
|
20
|
+
wss = new WebSocketServer({ port: port })
|
|
21
|
+
wss.on('listening', function() { isOwner = true; log('WebSocket server on port ' + port); resolve() })
|
|
22
|
+
wss.on('connection', function(ws) {
|
|
23
|
+
client = ws
|
|
24
|
+
log('Figma plugin connected')
|
|
25
|
+
ws.on('message', function(data) {
|
|
26
|
+
try {
|
|
27
|
+
var msg = JSON.parse(data.toString())
|
|
28
|
+
if (msg.id && pending.has(msg.id)) {
|
|
29
|
+
var p = pending.get(msg.id)
|
|
30
|
+
clearTimeout(p.timer)
|
|
31
|
+
pending.delete(msg.id)
|
|
32
|
+
if (msg.error) p.reject(new Error(msg.error))
|
|
33
|
+
else p.resolve(msg.result)
|
|
34
|
+
}
|
|
35
|
+
} catch (e) { log('Parse error:', e.message) }
|
|
36
|
+
})
|
|
37
|
+
ws.on('close', function() { client = null; log('Figma plugin disconnected') })
|
|
38
|
+
ws.on('error', function(e) { log('WS error:', e.message) })
|
|
34
39
|
})
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
wss.on('error', function(e) {
|
|
41
|
+
if (e.code === 'EADDRINUSE') {
|
|
42
|
+
log('Port ' + port + ' in use — another Conductor instance is running. This instance will handle MCP only.')
|
|
43
|
+
wss = null
|
|
44
|
+
resolve()
|
|
45
|
+
} else {
|
|
46
|
+
log('Server error:', e.message)
|
|
47
|
+
resolve()
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
} catch (e) {
|
|
51
|
+
log('Bridge start error:', e.message)
|
|
52
|
+
resolve()
|
|
53
|
+
}
|
|
39
54
|
})
|
|
40
55
|
}
|
|
41
56
|
|
|
42
|
-
function stop() { if (wss) { wss.close(); wss = null } }
|
|
57
|
+
function stop() { if (wss && isOwner) { wss.close(); wss = null } }
|
|
43
58
|
|
|
44
59
|
function isConnected() { return client !== null && client.readyState === 1 }
|
|
45
60
|
|
|
46
|
-
function send(command, data, timeout
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
61
|
+
function send(command, data, timeout) {
|
|
62
|
+
timeout = timeout || 15000
|
|
63
|
+
return new Promise(function(resolve, reject) {
|
|
64
|
+
if (!isConnected()) return reject(new Error('Figma plugin not connected. Run the Conductor plugin in Figma, and make sure the WebSocket server is running on port ' + port))
|
|
65
|
+
var id = ++msgId
|
|
66
|
+
var timer = setTimeout(function() {
|
|
51
67
|
pending.delete(id)
|
|
52
|
-
reject(new Error(
|
|
68
|
+
reject(new Error('Timeout waiting for Figma response (' + timeout + 'ms)'))
|
|
53
69
|
}, timeout)
|
|
54
|
-
pending.set(id, { resolve, reject, timer })
|
|
55
|
-
client.send(JSON.stringify({ id, command, data }))
|
|
70
|
+
pending.set(id, { resolve: resolve, reject: reject, timer: timer })
|
|
71
|
+
client.send(JSON.stringify({ id: id, command: command, data: data }))
|
|
56
72
|
})
|
|
57
73
|
}
|
|
58
74
|
|
|
59
|
-
return { start, stop, isConnected, send, getPort: ()
|
|
75
|
+
return { start: start, stop: stop, isConnected: isConnected, send: send, getPort: function() { return port } }
|
|
60
76
|
}
|