devlens-mcp 0.3.3 → 0.4.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 +45 -37
- package/RELEASE_NOTES.md +249 -0
- package/dist/bin/cli.js +2 -0
- package/dist/bin/cli.js.map +1 -1
- package/dist/src/figma/figma-properties.d.ts +88 -0
- package/dist/src/figma/figma-properties.d.ts.map +1 -0
- package/dist/src/figma/figma-properties.js +121 -0
- package/dist/src/figma/figma-properties.js.map +1 -0
- package/dist/src/figma/figma-structure.d.ts +43 -0
- package/dist/src/figma/figma-structure.d.ts.map +1 -0
- package/dist/src/figma/figma-structure.js +74 -0
- package/dist/src/figma/figma-structure.js.map +1 -0
- package/dist/src/figma/figma-url.d.ts +37 -0
- package/dist/src/figma/figma-url.d.ts.map +1 -0
- package/dist/src/figma/figma-url.js +68 -0
- package/dist/src/figma/figma-url.js.map +1 -0
- package/dist/src/jds-tokens/resolve-token.d.ts +2 -0
- package/dist/src/jds-tokens/resolve-token.d.ts.map +1 -0
- package/dist/src/jds-tokens/resolve-token.js +24 -0
- package/dist/src/jds-tokens/resolve-token.js.map +1 -0
- package/dist/src/jds-tokens/tokens.d.ts +2 -0
- package/dist/src/jds-tokens/tokens.d.ts.map +1 -0
- package/dist/src/jds-tokens/tokens.js +12 -0
- package/dist/src/jds-tokens/tokens.js.map +1 -0
- package/dist/src/platform/ios/ios-device.d.ts +2 -0
- package/dist/src/platform/ios/ios-device.d.ts.map +1 -1
- package/dist/src/platform/ios/ios-device.js +18 -8
- package/dist/src/platform/ios/ios-device.js.map +1 -1
- package/dist/src/platform/ios/scale-resolver.d.ts +29 -0
- package/dist/src/platform/ios/scale-resolver.d.ts.map +1 -0
- package/dist/src/platform/ios/scale-resolver.js +114 -0
- package/dist/src/platform/ios/scale-resolver.js.map +1 -0
- package/dist/src/platform/ios/simctl.d.ts +5 -0
- package/dist/src/platform/ios/simctl.d.ts.map +1 -1
- package/dist/src/platform/ios/simctl.js +4 -0
- package/dist/src/platform/ios/simctl.js.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +9 -1
- package/dist/src/server.js.map +1 -1
- package/dist/src/setup/config-patcher.d.ts +2 -0
- package/dist/src/setup/config-patcher.d.ts.map +1 -0
- package/dist/src/setup/config-patcher.js +128 -0
- package/dist/src/setup/config-patcher.js.map +1 -0
- package/dist/src/setup/shell-detector.d.ts +10 -0
- package/dist/src/setup/shell-detector.d.ts.map +1 -0
- package/dist/src/setup/shell-detector.js +72 -0
- package/dist/src/setup/shell-detector.js.map +1 -0
- package/dist/src/snapshot/device-properties.d.ts +53 -0
- package/dist/src/snapshot/device-properties.d.ts.map +1 -0
- package/dist/src/snapshot/device-properties.js +94 -0
- package/dist/src/snapshot/device-properties.js.map +1 -0
- package/dist/src/snapshot/formatter.d.ts +13 -5
- package/dist/src/snapshot/formatter.d.ts.map +1 -1
- package/dist/src/snapshot/formatter.js +28 -19
- package/dist/src/snapshot/formatter.js.map +1 -1
- package/dist/src/snapshot/layout-inference.d.ts +44 -0
- package/dist/src/snapshot/layout-inference.d.ts.map +1 -0
- package/dist/src/snapshot/layout-inference.js +138 -0
- package/dist/src/snapshot/layout-inference.js.map +1 -0
- package/dist/src/tools/analyze-tools.d.ts +60 -0
- package/dist/src/tools/analyze-tools.d.ts.map +1 -0
- package/dist/src/tools/analyze-tools.js +196 -0
- package/dist/src/tools/analyze-tools.js.map +1 -0
- package/dist/src/tools/interaction-tools.d.ts +6 -6
- package/dist/src/tools/interaction-tools.d.ts.map +1 -1
- package/dist/src/tools/interaction-tools.js +12 -2
- package/dist/src/tools/interaction-tools.js.map +1 -1
- package/dist/src/tools/metro-tools.d.ts +2 -2
- package/dist/src/tools/navigation-tools.d.ts.map +1 -1
- package/dist/src/tools/navigation-tools.js +6 -1
- package/dist/src/tools/navigation-tools.js.map +1 -1
- package/dist/src/tools/screenshot-tools.d.ts +75 -0
- package/dist/src/tools/screenshot-tools.d.ts.map +1 -1
- package/dist/src/tools/screenshot-tools.js +238 -8
- package/dist/src/tools/screenshot-tools.js.map +1 -1
- package/dist/src/tools/snapshot-tools.d.ts +15 -0
- package/dist/src/tools/snapshot-tools.d.ts.map +1 -1
- package/dist/src/tools/snapshot-tools.js +32 -1
- package/dist/src/tools/snapshot-tools.js.map +1 -1
- package/dist/src/tools/vqa-tools.d.ts +62 -0
- package/dist/src/tools/vqa-tools.d.ts.map +1 -0
- package/dist/src/tools/vqa-tools.js +204 -0
- package/dist/src/tools/vqa-tools.js.map +1 -0
- package/dist/src/utils/image-preprocess.d.ts +1 -1
- package/dist/src/utils/image-preprocess.d.ts.map +1 -1
- package/dist/src/utils/image-preprocess.js +79 -0
- package/dist/src/utils/image-preprocess.js.map +1 -1
- package/dist/src/visual/color-extractor.d.ts +37 -0
- package/dist/src/visual/color-extractor.d.ts.map +1 -0
- package/dist/src/visual/color-extractor.js +116 -0
- package/dist/src/visual/color-extractor.js.map +1 -0
- package/dist/src/visual/comparator.d.ts +21 -0
- package/dist/src/visual/comparator.d.ts.map +1 -1
- package/dist/src/visual/comparator.js +110 -13
- package/dist/src/visual/comparator.js.map +1 -1
- package/dist/src/visual/layout-analyzer.d.ts.map +1 -1
- package/dist/src/visual/layout-analyzer.js +17 -7
- package/dist/src/visual/layout-analyzer.js.map +1 -1
- package/dist/src/visual/node-matcher.d.ts +43 -0
- package/dist/src/visual/node-matcher.d.ts.map +1 -0
- package/dist/src/visual/node-matcher.js +190 -0
- package/dist/src/visual/node-matcher.js.map +1 -0
- package/dist/src/visual/property-comparator.d.ts +49 -0
- package/dist/src/visual/property-comparator.d.ts.map +1 -0
- package/dist/src/visual/property-comparator.js +246 -0
- package/dist/src/visual/property-comparator.js.map +1 -0
- package/dist/src/visual/structural-comparator.d.ts +46 -0
- package/dist/src/visual/structural-comparator.d.ts.map +1 -0
- package/dist/src/visual/structural-comparator.js +293 -0
- package/dist/src/visual/structural-comparator.js.map +1 -0
- package/dist/src/visual/vqa-analyzer.d.ts +30 -0
- package/dist/src/visual/vqa-analyzer.d.ts.map +1 -0
- package/dist/src/visual/vqa-analyzer.js +271 -0
- package/dist/src/visual/vqa-analyzer.js.map +1 -0
- package/docs/figma-workflow.md +207 -40
- package/docs/setup-guide.md +102 -38
- package/docs/tool-reference.md +71 -0
- package/package.json +1 -1
- package/tsconfig.json +1 -1
- package/INSTALLATION_GUIDE.md +0 -3
- package/QUICK_START.md +0 -3
package/README.md
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
DevLens gives AI agents the ability to **see, interact with, and verify** your mobile app running on a simulator or emulator. It bridges the gap between "AI writes code" and "AI confirms the code works" — enabling a fully automated **design-to-code-to-verification loop**.
|
|
6
6
|
|
|
7
7
|
```
|
|
8
|
-
Figma Design ──► AI Agent ──► Code Changes ──► Hot Reload ──► Screenshot ──► Compare
|
|
9
|
-
▲
|
|
10
|
-
|
|
8
|
+
Figma Design ──► AI Agent ──► Code Changes ──► Hot Reload ──► Screenshot ──► Compare ──► VQA Validate
|
|
9
|
+
▲ │
|
|
10
|
+
└──────────────────── Fix & repeat until 100% match (zero VQA) ────────────────────┘
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
---
|
|
@@ -19,31 +19,14 @@ Figma Design ──► AI Agent ──► Code Changes ──► Hot Reloa
|
|
|
19
19
|
claude mcp add devlens -- npx devlens-mcp@latest
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
### Cursor IDE
|
|
23
|
-
Add to `~/.cursor/mcp.json
|
|
22
|
+
### Cursor IDE / Claude Desktop
|
|
23
|
+
Add to `~/.cursor/mcp.json` (Cursor) or `~/Library/Application Support/Claude/claude_desktop_config.json` (Desktop):
|
|
24
24
|
```json
|
|
25
25
|
{
|
|
26
26
|
"mcpServers": {
|
|
27
27
|
"devlens": {
|
|
28
|
-
"command": "
|
|
29
|
-
"args": ["devlens-mcp@latest"],
|
|
30
|
-
"env": {
|
|
31
|
-
"METRO_PORT": "8081",
|
|
32
|
-
"FIGMA_TOKEN": "figd_xxxxx"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### Claude Desktop
|
|
40
|
-
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
41
|
-
```json
|
|
42
|
-
{
|
|
43
|
-
"mcpServers": {
|
|
44
|
-
"devlens": {
|
|
45
|
-
"command": "npx",
|
|
46
|
-
"args": ["devlens-mcp@latest"],
|
|
28
|
+
"command": "/bin/zsh",
|
|
29
|
+
"args": ["-l", "-c", "npx devlens-mcp@latest"],
|
|
47
30
|
"env": {
|
|
48
31
|
"METRO_PORT": "8081",
|
|
49
32
|
"FIGMA_TOKEN": "figd_xxxxx"
|
|
@@ -55,6 +38,8 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
|
55
38
|
|
|
56
39
|
Restart your AI client after editing the config.
|
|
57
40
|
|
|
41
|
+
> **v0.4.0+**: DevLens now auto-detects your shell and `node` path on startup. It will patch MCP config files automatically if it detects a misconfigured shell or node path. See [setup guide](./docs/setup-guide.md) for details.
|
|
42
|
+
|
|
58
43
|
---
|
|
59
44
|
|
|
60
45
|
## What Problems Does It Solve?
|
|
@@ -75,6 +60,19 @@ Without DevLens, AI agents resort to manual, error-prone workflows:
|
|
|
75
60
|
|
|
76
61
|
---
|
|
77
62
|
|
|
63
|
+
## New in v0.4.0
|
|
64
|
+
|
|
65
|
+
- **Auto-Detect Shell & Node Path** — DevLens now auto-detects your shell (bash/zsh/fish), finds the correct `node`/`npx` path, and auto-patches MCP config files if they are misconfigured. No more "node not found" errors.
|
|
66
|
+
- **VQA Validator** — new `devlens_vqa_validate` tool runs comprehensive Visual Quality Assurance against Figma designs. Checks spacing, colors, alignment, sizing, and missing/extra elements. Returns a structured VQA report with fix suggestions. Goal: zero VQA tickets from designer team.
|
|
67
|
+
- **Smart Analysis Depth** — new `devlens_analyze` tool with configurable scope: `minimal` (quick diff, no layout report), `targeted` (compare specific elements only), `full` (complete analysis). `devlens_compare_with_figma` now has a `depth` parameter (`quick`/`standard`/`thorough`).
|
|
68
|
+
- **Status Bar & Nav Bar Exclusion** — comparisons now auto-exclude volatile status bar (time, battery) and navigation bar regions. Reduces false-positive diffs by 3-5%.
|
|
69
|
+
- **Perceptual Comparison Mode** — new SSIM-inspired block-based comparison tolerates anti-aliasing and sub-pixel font rendering differences. Enable with `perceptual: true` or use `depth: "thorough"`.
|
|
70
|
+
- **Smart Figma Preprocessing** — new `"smart"` strategy combines rounded corner masking, histogram-guided artifact removal, and residual border trimming for cleaner Figma exports.
|
|
71
|
+
- **Scoped Snapshots** — `devlens_snapshot` now supports `scope: "component"` to capture only a subtree of a specific ref, reducing token usage for targeted checks.
|
|
72
|
+
- **Improved Verdict Thresholds** — layout analyzer thresholds tuned: "excellent" raised to 95%, sub-pixel alignment padding added to reduce off-by-one edge mismatches.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
78
76
|
## New in v0.3.1
|
|
79
77
|
|
|
80
78
|
- **Layout-Aware Comparison** — `devlens_compare_with_figma` now reports per-element similarity scores using the accessibility tree. Instead of a single misleading global pixel-diff number, you get `"Header: 94%, ChatInput: 61%, ToolsGrid: 44% ← investigate"`. Set `layoutReport: false` to disable.
|
|
@@ -102,7 +100,7 @@ Without DevLens, AI agents resort to manual, error-prone workflows:
|
|
|
102
100
|
|
|
103
101
|
---
|
|
104
102
|
|
|
105
|
-
## Tools (
|
|
103
|
+
## Tools (36)
|
|
106
104
|
|
|
107
105
|
### Device Management (3)
|
|
108
106
|
| Tool | Description |
|
|
@@ -170,6 +168,12 @@ Without DevLens, AI agents resort to manual, error-prone workflows:
|
|
|
170
168
|
|------|-------------|
|
|
171
169
|
| `devlens_ds_context` | Load design tokens, component interfaces, and usage patterns from your codebase |
|
|
172
170
|
|
|
171
|
+
### Analysis & VQA (2)
|
|
172
|
+
| Tool | Description |
|
|
173
|
+
|------|-------------|
|
|
174
|
+
| `devlens_analyze` | Smart analysis with configurable depth (minimal/targeted/full). Respects scope of request — minimal changes get minimal analysis. |
|
|
175
|
+
| `devlens_vqa_validate` | Run VQA validation against Figma. Checks spacing, color, alignment, sizing, missing elements. Returns issues + fix suggestions. |
|
|
176
|
+
|
|
173
177
|
---
|
|
174
178
|
|
|
175
179
|
## The Figma Verification Workflow
|
|
@@ -177,17 +181,17 @@ Without DevLens, AI agents resort to manual, error-prone workflows:
|
|
|
177
181
|
DevLens integrates with Figma to create an automated design verification loop:
|
|
178
182
|
|
|
179
183
|
```
|
|
180
|
-
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
181
|
-
│ Figma │────►│ AI │────►│ Code │────►│ Device │
|
|
182
|
-
│ Design │ │ Agent │ │ Editor │ │ Screen │
|
|
183
|
-
└──────────┘ └──────┬───┘ └──────────┘ └────┬─────┘
|
|
184
|
-
│
|
|
185
|
-
│◄───
|
|
186
|
-
│ (
|
|
184
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
185
|
+
│ Figma │────►│ AI │────►│ Code │────►│ Device │────►│ VQA │
|
|
186
|
+
│ Design │ │ Agent │ │ Editor │ │ Screen │ │ Validate │
|
|
187
|
+
└──────────┘ └──────┬───┘ └──────────┘ └──────────┘ └────┬─────┘
|
|
188
|
+
│ │
|
|
189
|
+
│◄─── devlens_vqa_validate ──────────────────────┘
|
|
190
|
+
│ (issues found?)
|
|
187
191
|
│ │
|
|
188
192
|
▼ ▼
|
|
189
|
-
Fix Code ◄───
|
|
190
|
-
(
|
|
193
|
+
Fix Code ◄─── VQA Report
|
|
194
|
+
(spacing, color, alignment issues + fix suggestions)
|
|
191
195
|
```
|
|
192
196
|
|
|
193
197
|
### Step-by-step:
|
|
@@ -199,9 +203,10 @@ DevLens integrates with Figma to create an automated design verification loop:
|
|
|
199
203
|
5. **Hot reload** — `devlens_hot_reload` triggers Metro fast refresh
|
|
200
204
|
6. **Wait for stability** — `devlens_wait_for_screen` waits until UI stops changing
|
|
201
205
|
7. **Validate elements** — `devlens_snapshot(validate: true)` catches invisible/zero-size elements
|
|
202
|
-
8. **
|
|
203
|
-
9. **
|
|
204
|
-
10. **Fix
|
|
206
|
+
8. **Quick check** — `devlens_compare_with_figma(figmaUrl: "...", depth: "quick")` for fast iteration
|
|
207
|
+
9. **VQA validation** — `devlens_vqa_validate(figmaUrl: "...")` runs full VQA: spacing, colors, alignment, sizing, missing elements
|
|
208
|
+
10. **Fix issues** — AI reads VQA report with per-issue fix suggestions and applies fixes
|
|
209
|
+
11. **Repeat** — Run VQA again until status is `PASS` (zero VQA issues for designers)
|
|
205
210
|
|
|
206
211
|
---
|
|
207
212
|
|
|
@@ -325,6 +330,9 @@ Configure via `devlens.config.json` in your app root (see [Setup Guide](./docs/s
|
|
|
325
330
|
| "File not exportable" on Figma compare | Disable "Prevent viewers from copying and exporting" in Figma share settings |
|
|
326
331
|
| `devlens_ds_context` returns empty | Set `DEVLENS_CONFIG` env var to your `devlens.config.json` path |
|
|
327
332
|
| Comparison similarity always low | Run `devlens_snapshot` first so layout report has element bounds to work with |
|
|
333
|
+
| Status bar causing false diffs | Use `excludeSystemBars: "auto"` (default in v0.4.0) or `"ios"`/`"android"` |
|
|
334
|
+
| VQA report empty | Run `devlens_snapshot` first to populate element refs before `devlens_vqa_validate` |
|
|
335
|
+
| Shell/node path wrong in MCP config | v0.4.0 auto-patches on startup; check logs for `[devlens] Patched` messages |
|
|
328
336
|
|
|
329
337
|
---
|
|
330
338
|
|
package/RELEASE_NOTES.md
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# DevLens v0.4.0 — Release Notes
|
|
2
|
+
|
|
3
|
+
**Release Date:** March 2026
|
|
4
|
+
**Previous Version:** v0.3.3
|
|
5
|
+
**npm:** `npx devlens-mcp@latest`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Headline
|
|
10
|
+
|
|
11
|
+
DevLens v0.4.0 introduces **VQA validation**, **auto-config detection**, **smart analysis depth**, and **enhanced visual matching** — enabling a workflow where designers receive builds with **zero VQA tickets**.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## What's New
|
|
16
|
+
|
|
17
|
+
### 1. Auto-Detect Shell & Node Path
|
|
18
|
+
|
|
19
|
+
**Problem:** Developers manually configured `/bin/zsh`, `/bin/bash`, and `node`/`npx` paths in MCP server JSON. Wrong path = silent failure.
|
|
20
|
+
|
|
21
|
+
**Now:** DevLens auto-detects on every startup:
|
|
22
|
+
- Reads `$SHELL` to find your shell (bash, zsh, fish)
|
|
23
|
+
- Runs `which node` / `which npx` inside your login shell profile
|
|
24
|
+
- Falls back to common paths: nvm, volta, fnm, homebrew, nodenv, asdf
|
|
25
|
+
- Scans all MCP config files (Cursor, Claude Desktop, Claude Code)
|
|
26
|
+
- If a mismatch is found, **auto-patches** the JSON (with `.bak` backup)
|
|
27
|
+
|
|
28
|
+
**Result:** "node not found" errors are gone. New developers just paste the default config and it works.
|
|
29
|
+
|
|
30
|
+
**Common misconfiguration auto-fixed:**
|
|
31
|
+
If you had a config like this (using `node` with shell flags — broken):
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"command": "/opt/homebrew/bin/node",
|
|
35
|
+
"args": ["-l", "-c", "npx devlens-mcp@latest"]
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
DevLens v0.4.0 detects that `node` doesn't understand `-l` / `-c` (those are shell flags) and auto-patches to:
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"command": "/bin/zsh",
|
|
42
|
+
"args": ["-l", "-c", "npx devlens-mcp@latest"]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
A `.bak` backup is created before any patch.
|
|
46
|
+
|
|
47
|
+
**Do developers need to change their config?** **No.** The recommended config is the same as always:
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"devlens": {
|
|
52
|
+
"command": "/bin/zsh",
|
|
53
|
+
"args": ["-l", "-c", "npx devlens-mcp@latest"],
|
|
54
|
+
"env": {
|
|
55
|
+
"METRO_PORT": "8081",
|
|
56
|
+
"FIGMA_TOKEN": "figd_xxxxx"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
If your existing config has incorrect paths, DevLens fixes it on startup. No action needed.
|
|
63
|
+
|
|
64
|
+
**New files:**
|
|
65
|
+
- `src/setup/shell-detector.ts` — shell & node path detection
|
|
66
|
+
- `src/setup/config-patcher.ts` — MCP config auto-patcher
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### 2. VQA Validator — Zero Designer Tickets
|
|
71
|
+
|
|
72
|
+
**Problem:** Traditional workflow wastes 2-3 days: Dev builds → Designer reviews → 15 VQA tickets → Dev fixes → More tickets → Repeat.
|
|
73
|
+
|
|
74
|
+
**Now:** `devlens_vqa_validate` runs comprehensive Visual QA against Figma before the designer ever sees the build.
|
|
75
|
+
|
|
76
|
+
**What it checks:**
|
|
77
|
+
| Category | What it validates |
|
|
78
|
+
|----------|-------------------|
|
|
79
|
+
| Spacing | Gaps between elements vs Figma specs |
|
|
80
|
+
| Colors | Dominant colors per region (CIE76 Delta-E) |
|
|
81
|
+
| Alignment | Element center/edge positions |
|
|
82
|
+
| Sizing | Width/height within 5% tolerance |
|
|
83
|
+
| Missing | Regions with <60% match (content probably missing) |
|
|
84
|
+
| Extra | Elements on device not in Figma |
|
|
85
|
+
| Typography | Font sizes/weights via accessibility tree |
|
|
86
|
+
|
|
87
|
+
**VQA Report format:**
|
|
88
|
+
```
|
|
89
|
+
=== VQA Report: WARNING ===
|
|
90
|
+
Overall Score: 91.3%
|
|
91
|
+
Issues: 3 (0 critical, 2 major, 1 minor)
|
|
92
|
+
|
|
93
|
+
--- Issues ---
|
|
94
|
+
1. [MAJOR] [spacing] Gap between [e3] and [e5]: expected 12px, actual 20px
|
|
95
|
+
2. [MAJOR] [color] Color mismatch on [e7]: expected #1A73E8, actual #2196F3
|
|
96
|
+
3. [minor] [alignment] Element [e2] off by (3, 2)px
|
|
97
|
+
|
|
98
|
+
--- Suggested Fixes ---
|
|
99
|
+
1. [high] Adjust margin/padding on [e3] to 12px gap.
|
|
100
|
+
2. [high] Update color for [e7] to #1A73E8. Check design token mapping.
|
|
101
|
+
3. [medium] Fix alignment of [e2] — adjust flex alignment.
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Developer workflow — just paste this prompt in Cursor:**
|
|
105
|
+
```
|
|
106
|
+
Build the HomeScreen from this Figma and make sure VQA passes with zero issues:
|
|
107
|
+
https://figma.com/design/ABC123/MyApp?node-id=10-200
|
|
108
|
+
|
|
109
|
+
Run VQA after building. Fix all issues. Re-run until PASS.
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**New files:**
|
|
113
|
+
- `src/tools/vqa-tools.ts` — `devlens_vqa_validate` tool
|
|
114
|
+
- `src/visual/vqa-analyzer.ts` — VQA analysis engine (spacing, sizing, alignment, color, missing/extra)
|
|
115
|
+
- `src/visual/color-extractor.ts` — dominant color extraction & CIE76 Delta-E comparison
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### 3. Smart Analysis Depth
|
|
120
|
+
|
|
121
|
+
**Problem:** DevLens always ran full analysis — full snapshot + full layout report + full comparison. For a small padding change, this was overkill and slow.
|
|
122
|
+
|
|
123
|
+
**Now:** Analysis respects the scope of the request:
|
|
124
|
+
|
|
125
|
+
| Tool / Param | When to use | What it does |
|
|
126
|
+
|--------------|-------------|--------------|
|
|
127
|
+
| `devlens_analyze(scope: "minimal")` | Small CSS tweak | Quick pixel diff, no layout report |
|
|
128
|
+
| `devlens_analyze(scope: "targeted", targetRefs: ["e5"])` | Check one component | Inspects only specified elements |
|
|
129
|
+
| `devlens_analyze(scope: "full")` | Full screen build | Complete snapshot + layout + comparison |
|
|
130
|
+
| `devlens_compare_with_figma(depth: "quick")` | Fast iteration | Skip layout report, loose threshold |
|
|
131
|
+
| `devlens_compare_with_figma(depth: "standard")` | Normal compare | Current v0.3 behavior |
|
|
132
|
+
| `devlens_compare_with_figma(depth: "thorough")` | Final check | Per-element + perceptual + VQA hints |
|
|
133
|
+
| `devlens_snapshot(scope: "component", componentRef: "e3")` | Reduce tokens | Capture only a subtree |
|
|
134
|
+
|
|
135
|
+
**New file:** `src/tools/analyze-tools.ts`
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
### 4. Enhanced Visual Matching (95% → 100%)
|
|
140
|
+
|
|
141
|
+
Four improvements that eliminate the 5% false-positive gap:
|
|
142
|
+
|
|
143
|
+
#### 4a. Status Bar & Nav Bar Exclusion
|
|
144
|
+
- Auto-detects iOS or Android from image dimensions
|
|
145
|
+
- Masks status bar (time, battery, signal) and nav bar (home indicator)
|
|
146
|
+
- Enabled by default: `excludeSystemBars: "auto"`
|
|
147
|
+
- Eliminates 3-5% false diffs from volatile system UI
|
|
148
|
+
|
|
149
|
+
#### 4b. Perceptual Comparison Mode
|
|
150
|
+
- SSIM-inspired 8x8 block averaging
|
|
151
|
+
- Tolerates anti-aliasing and sub-pixel font rendering differences
|
|
152
|
+
- Enable with `perceptual: true` or `depth: "thorough"`
|
|
153
|
+
- New verdict: 99%+ = "Pixel-perfect match. No VQA issues expected."
|
|
154
|
+
|
|
155
|
+
#### 4c. Smart Figma Preprocessing
|
|
156
|
+
- New `"smart"` strategy for `preprocessReference`
|
|
157
|
+
- Masks rounded corners (detects corner radius, fills with inner color)
|
|
158
|
+
- Content-based cropping + residual border trimming
|
|
159
|
+
- Handles dark bars, light borders, transparent padding
|
|
160
|
+
|
|
161
|
+
#### 4d. Sub-pixel Alignment
|
|
162
|
+
- Layout analyzer adds 1px padding to scaled bounds
|
|
163
|
+
- Prevents off-by-one edge mismatches between device and Figma
|
|
164
|
+
- Verdict thresholds tuned: "excellent" = 95%+, "good" = 82%+
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## New Tools (2)
|
|
169
|
+
|
|
170
|
+
| Tool | Description |
|
|
171
|
+
|------|-------------|
|
|
172
|
+
| `devlens_analyze` | Smart analysis with configurable scope (minimal/targeted/full) |
|
|
173
|
+
| `devlens_vqa_validate` | VQA validator — checks spacing, color, alignment, sizing, missing elements against Figma |
|
|
174
|
+
|
|
175
|
+
**Total tools: 36** (up from 34 in v0.3.3)
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Enhanced Tools
|
|
180
|
+
|
|
181
|
+
| Tool | What changed |
|
|
182
|
+
|------|-------------|
|
|
183
|
+
| `devlens_compare_with_figma` | New `depth` param (quick/standard/thorough), `excludeSystemBars` param |
|
|
184
|
+
| `devlens_snapshot` | New `scope` param (screen/component), `componentRef` for subtree capture |
|
|
185
|
+
| `devlens_compare_screenshot` | Inherits status bar exclusion and perceptual mode from comparator |
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Files Changed
|
|
190
|
+
|
|
191
|
+
### New (6 files)
|
|
192
|
+
| File | Purpose |
|
|
193
|
+
|------|---------|
|
|
194
|
+
| `src/setup/shell-detector.ts` | Shell type & node path detection |
|
|
195
|
+
| `src/setup/config-patcher.ts` | MCP config JSON auto-patcher |
|
|
196
|
+
| `src/tools/analyze-tools.ts` | `devlens_analyze` tool |
|
|
197
|
+
| `src/tools/vqa-tools.ts` | `devlens_vqa_validate` tool |
|
|
198
|
+
| `src/visual/vqa-analyzer.ts` | VQA engine: spacing, sizing, alignment, color, missing checks |
|
|
199
|
+
| `src/visual/color-extractor.ts` | Dominant color extraction & Delta-E comparison |
|
|
200
|
+
|
|
201
|
+
### Modified (11 files)
|
|
202
|
+
| File | What changed |
|
|
203
|
+
|------|-------------|
|
|
204
|
+
| `bin/cli.ts` | Calls `detectAndPatchConfig()` on startup |
|
|
205
|
+
| `src/server.ts` | Registers analyze + VQA tools, version bumped to 0.4.0 |
|
|
206
|
+
| `src/visual/comparator.ts` | Status bar exclusion, perceptual mode, updated verdicts |
|
|
207
|
+
| `src/visual/layout-analyzer.ts` | Sub-pixel alignment padding, tuned verdict thresholds |
|
|
208
|
+
| `src/utils/image-preprocess.ts` | `"smart"` strategy, `maskRoundedCorners()` |
|
|
209
|
+
| `src/tools/screenshot-tools.ts` | `depth` and `excludeSystemBars` params on compare_with_figma |
|
|
210
|
+
| `src/tools/snapshot-tools.ts` | `scope` and `componentRef` params on snapshot |
|
|
211
|
+
| `package.json` | Version 0.3.3 → 0.4.0 |
|
|
212
|
+
| `README.md` | v0.4.0 changelog, updated tool count, VQA workflow |
|
|
213
|
+
| `docs/setup-guide.md` | Auto-detect docs, VQA prompts, updated tool count |
|
|
214
|
+
| `docs/figma-workflow.md` | Full VQA workflow section with prompts |
|
|
215
|
+
| `docs/tool-reference.md` | analyze + vqa_validate reference entries |
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Breaking Changes
|
|
220
|
+
|
|
221
|
+
None. All existing tool parameters and behaviors are backward-compatible. New parameters have sensible defaults:
|
|
222
|
+
- `excludeSystemBars` defaults to `"auto"`
|
|
223
|
+
- `depth` defaults to `"standard"` (same as v0.3 behavior)
|
|
224
|
+
- `scope` defaults to `"screen"` / `"full"` (same as v0.3 behavior)
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Upgrade
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# If using npx (recommended) — automatic, just restart your AI client
|
|
232
|
+
# npx devlens-mcp@latest always fetches the latest
|
|
233
|
+
|
|
234
|
+
# If installed locally
|
|
235
|
+
npm install devlens-mcp@latest
|
|
236
|
+
|
|
237
|
+
# Clear stale npx cache if needed
|
|
238
|
+
rm -rf ~/.npm/_npx/*devlens*
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## What's Next (v0.5.0 roadmap)
|
|
244
|
+
|
|
245
|
+
- Figma node-level comparison (compare Figma component tree against accessibility tree)
|
|
246
|
+
- Auto-fix integration (VQA suggestions applied directly to source code)
|
|
247
|
+
- CI/CD integration (run VQA as a build step, fail on critical issues)
|
|
248
|
+
- Multi-screen VQA batch (validate entire flow in one call)
|
|
249
|
+
- Design token drift detection (flag tokens in code that don't match Figma)
|
package/dist/bin/cli.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const index_js_1 = require("../src/index.js");
|
|
5
|
+
const config_patcher_js_1 = require("../src/setup/config-patcher.js");
|
|
5
6
|
async function main() {
|
|
7
|
+
await (0, config_patcher_js_1.detectAndPatchConfig)();
|
|
6
8
|
const server = await (0, index_js_1.createServer)();
|
|
7
9
|
process.on("SIGINT", async () => {
|
|
8
10
|
await server.close();
|
package/dist/bin/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":";;;AAEA,8CAA+C;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":";;;AAEA,8CAA+C;AAC/C,sEAAsE;AAEtE,KAAK,UAAU,IAAI;IACjB,MAAM,IAAA,wCAAoB,GAAE,CAAC;IAE7B,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAY,GAAE,CAAC;IAEpC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAC/B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;IACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract all comparable design properties from a Figma node tree.
|
|
3
|
+
* Uses the REST API JSON response (not pixel exports).
|
|
4
|
+
*
|
|
5
|
+
* Builds on figma-structure.ts which fetches the raw node tree.
|
|
6
|
+
* This module walks that tree and normalizes every measurable property
|
|
7
|
+
* into a flat, comparable format.
|
|
8
|
+
*/
|
|
9
|
+
export interface FigmaComponentProps {
|
|
10
|
+
nodeId: string;
|
|
11
|
+
name: string;
|
|
12
|
+
type: string;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
text?: {
|
|
18
|
+
content: string;
|
|
19
|
+
fontSize: number;
|
|
20
|
+
fontFamily: string;
|
|
21
|
+
fontWeight: number;
|
|
22
|
+
lineHeight: number;
|
|
23
|
+
letterSpacing: number;
|
|
24
|
+
textAlign: string;
|
|
25
|
+
};
|
|
26
|
+
fills: Array<{
|
|
27
|
+
type: "SOLID" | "GRADIENT" | "IMAGE";
|
|
28
|
+
color?: {
|
|
29
|
+
r: number;
|
|
30
|
+
g: number;
|
|
31
|
+
b: number;
|
|
32
|
+
a: number;
|
|
33
|
+
};
|
|
34
|
+
opacity?: number;
|
|
35
|
+
}>;
|
|
36
|
+
cornerRadius?: number;
|
|
37
|
+
opacity: number;
|
|
38
|
+
visible: boolean;
|
|
39
|
+
stroke?: {
|
|
40
|
+
color: {
|
|
41
|
+
r: number;
|
|
42
|
+
g: number;
|
|
43
|
+
b: number;
|
|
44
|
+
a: number;
|
|
45
|
+
};
|
|
46
|
+
weight: number;
|
|
47
|
+
};
|
|
48
|
+
effects: Array<{
|
|
49
|
+
type: string;
|
|
50
|
+
color?: {
|
|
51
|
+
r: number;
|
|
52
|
+
g: number;
|
|
53
|
+
b: number;
|
|
54
|
+
a: number;
|
|
55
|
+
};
|
|
56
|
+
offset?: {
|
|
57
|
+
x: number;
|
|
58
|
+
y: number;
|
|
59
|
+
};
|
|
60
|
+
radius: number;
|
|
61
|
+
}>;
|
|
62
|
+
layout?: {
|
|
63
|
+
mode: "HORIZONTAL" | "VERTICAL" | "NONE";
|
|
64
|
+
itemSpacing: number;
|
|
65
|
+
padding: {
|
|
66
|
+
top: number;
|
|
67
|
+
right: number;
|
|
68
|
+
bottom: number;
|
|
69
|
+
left: number;
|
|
70
|
+
};
|
|
71
|
+
primaryAlign: string;
|
|
72
|
+
counterAlign: string;
|
|
73
|
+
sizingH: string;
|
|
74
|
+
sizingV: string;
|
|
75
|
+
};
|
|
76
|
+
children: FigmaComponentProps[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Walk a raw Figma REST API node and extract all comparable properties.
|
|
80
|
+
*/
|
|
81
|
+
export declare function extractFigmaProperties(raw: any): FigmaComponentProps;
|
|
82
|
+
/**
|
|
83
|
+
* Flatten a FigmaComponentProps tree into a list of all nodes.
|
|
84
|
+
*/
|
|
85
|
+
export declare function flattenFigmaTree(root: FigmaComponentProps, parentPath?: string): Array<FigmaComponentProps & {
|
|
86
|
+
path: string;
|
|
87
|
+
}>;
|
|
88
|
+
//# sourceMappingURL=figma-properties.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figma-properties.d.ts","sourceRoot":"","sources":["../../../src/figma/figma-properties.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,mBAAmB;IAElC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IAGb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IAGV,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAGF,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;QACrC,KAAK,CAAC,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACvD,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IAGjB,MAAM,CAAC,EAAE;QACP,KAAK,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACtD,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAGF,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACvD,MAAM,CAAC,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAClC,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;IAGH,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,YAAY,GAAG,UAAU,GAAG,MAAM,CAAC;QACzC,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;QACtE,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAmBD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,GAAG,GAAG,mBAAmB,CAqFpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,mBAAmB,EACzB,UAAU,SAAK,GACd,KAAK,CAAC,mBAAmB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAY/C"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Extract all comparable design properties from a Figma node tree.
|
|
4
|
+
* Uses the REST API JSON response (not pixel exports).
|
|
5
|
+
*
|
|
6
|
+
* Builds on figma-structure.ts which fetches the raw node tree.
|
|
7
|
+
* This module walks that tree and normalizes every measurable property
|
|
8
|
+
* into a flat, comparable format.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.extractFigmaProperties = extractFigmaProperties;
|
|
12
|
+
exports.flattenFigmaTree = flattenFigmaTree;
|
|
13
|
+
/**
|
|
14
|
+
* Convert Figma's 0-1 RGBA to 0-255.
|
|
15
|
+
*/
|
|
16
|
+
function toRgb255(c) {
|
|
17
|
+
return {
|
|
18
|
+
r: Math.round((c.r ?? 0) * 255),
|
|
19
|
+
g: Math.round((c.g ?? 0) * 255),
|
|
20
|
+
b: Math.round((c.b ?? 0) * 255),
|
|
21
|
+
a: Math.round((c.a ?? 1) * 255),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Walk a raw Figma REST API node and extract all comparable properties.
|
|
26
|
+
*/
|
|
27
|
+
function extractFigmaProperties(raw) {
|
|
28
|
+
const bbox = raw.absoluteBoundingBox ?? { x: 0, y: 0, width: 0, height: 0 };
|
|
29
|
+
// Text properties
|
|
30
|
+
let text;
|
|
31
|
+
if (raw.type === "TEXT" && raw.characters) {
|
|
32
|
+
const style = raw.style ?? {};
|
|
33
|
+
text = {
|
|
34
|
+
content: raw.characters,
|
|
35
|
+
fontSize: style.fontSize ?? 0,
|
|
36
|
+
fontFamily: style.fontFamily ?? "",
|
|
37
|
+
fontWeight: style.fontWeight ?? 400,
|
|
38
|
+
lineHeight: style.lineHeightPx ?? 0,
|
|
39
|
+
letterSpacing: style.letterSpacing ?? 0,
|
|
40
|
+
textAlign: style.textAlignHorizontal ?? "LEFT",
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
// Fills
|
|
44
|
+
const fills = (raw.fills ?? [])
|
|
45
|
+
.filter((f) => f.visible !== false)
|
|
46
|
+
.map((f) => ({
|
|
47
|
+
type: f.type ?? "SOLID",
|
|
48
|
+
color: f.color ? toRgb255(f.color) : undefined,
|
|
49
|
+
opacity: f.opacity,
|
|
50
|
+
}));
|
|
51
|
+
// Stroke
|
|
52
|
+
let stroke;
|
|
53
|
+
if (raw.strokes?.length > 0 && raw.strokes[0].color) {
|
|
54
|
+
stroke = {
|
|
55
|
+
color: toRgb255(raw.strokes[0].color),
|
|
56
|
+
weight: raw.strokeWeight ?? 0,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// Effects
|
|
60
|
+
const effects = (raw.effects ?? [])
|
|
61
|
+
.filter((e) => e.visible !== false)
|
|
62
|
+
.map((e) => ({
|
|
63
|
+
type: e.type ?? "UNKNOWN",
|
|
64
|
+
color: e.color ? toRgb255(e.color) : undefined,
|
|
65
|
+
offset: e.offset,
|
|
66
|
+
radius: e.radius ?? 0,
|
|
67
|
+
}));
|
|
68
|
+
// Layout
|
|
69
|
+
let layout;
|
|
70
|
+
if (raw.layoutMode && raw.layoutMode !== "NONE") {
|
|
71
|
+
layout = {
|
|
72
|
+
mode: raw.layoutMode,
|
|
73
|
+
itemSpacing: raw.itemSpacing ?? 0,
|
|
74
|
+
padding: {
|
|
75
|
+
top: raw.paddingTop ?? 0,
|
|
76
|
+
right: raw.paddingRight ?? 0,
|
|
77
|
+
bottom: raw.paddingBottom ?? 0,
|
|
78
|
+
left: raw.paddingLeft ?? 0,
|
|
79
|
+
},
|
|
80
|
+
primaryAlign: raw.primaryAxisAlignItems ?? "MIN",
|
|
81
|
+
counterAlign: raw.counterAxisAlignItems ?? "MIN",
|
|
82
|
+
sizingH: raw.layoutSizingHorizontal ?? "FIXED",
|
|
83
|
+
sizingV: raw.layoutSizingVertical ?? "FIXED",
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
nodeId: raw.id ?? "",
|
|
88
|
+
name: raw.name ?? "",
|
|
89
|
+
type: raw.type ?? "UNKNOWN",
|
|
90
|
+
width: bbox.width ?? 0,
|
|
91
|
+
height: bbox.height ?? 0,
|
|
92
|
+
x: bbox.x ?? 0,
|
|
93
|
+
y: bbox.y ?? 0,
|
|
94
|
+
text,
|
|
95
|
+
fills,
|
|
96
|
+
cornerRadius: raw.cornerRadius ?? undefined,
|
|
97
|
+
opacity: raw.opacity ?? 1,
|
|
98
|
+
visible: raw.visible !== false,
|
|
99
|
+
stroke,
|
|
100
|
+
effects,
|
|
101
|
+
layout,
|
|
102
|
+
children: Array.isArray(raw.children)
|
|
103
|
+
? raw.children.map(extractFigmaProperties)
|
|
104
|
+
: [],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Flatten a FigmaComponentProps tree into a list of all nodes.
|
|
109
|
+
*/
|
|
110
|
+
function flattenFigmaTree(root, parentPath = "") {
|
|
111
|
+
const path = parentPath ? `${parentPath} > ${root.name}` : root.name;
|
|
112
|
+
const result = [];
|
|
113
|
+
if (root.width > 0 && root.height > 0) {
|
|
114
|
+
result.push({ ...root, path });
|
|
115
|
+
}
|
|
116
|
+
for (const child of root.children) {
|
|
117
|
+
result.push(...flattenFigmaTree(child, path));
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=figma-properties.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figma-properties.js","sourceRoot":"","sources":["../../../src/figma/figma-properties.ts"],"names":[],"mappings":"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"}
|