@atezer/figma-mcp-bridge 1.7.30 → 1.9.1
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/CHANGELOG.md +408 -0
- package/README.md +8 -8
- package/agents/_orchestrator-protocol.md +185 -0
- package/agents/ds-auditor.md +73 -22
- package/agents/screen-builder.md +60 -22
- package/agents/token-syncer.md +63 -19
- package/dist/core/code-warnings.d.ts +38 -0
- package/dist/core/code-warnings.d.ts.map +1 -0
- package/dist/core/code-warnings.js +191 -0
- package/dist/core/code-warnings.js.map +1 -0
- package/dist/core/device-presets.d.ts +49 -0
- package/dist/core/device-presets.d.ts.map +1 -0
- package/dist/core/device-presets.js +141 -0
- package/dist/core/device-presets.js.map +1 -0
- package/dist/core/instructions.d.ts +4 -2
- package/dist/core/instructions.d.ts.map +1 -1
- package/dist/core/instructions.js +239 -29
- package/dist/core/instructions.js.map +1 -1
- package/dist/core/plugin-bridge-connector.d.ts +26 -0
- package/dist/core/plugin-bridge-connector.d.ts.map +1 -1
- package/dist/core/plugin-bridge-connector.js +18 -2
- package/dist/core/plugin-bridge-connector.js.map +1 -1
- package/dist/core/plugin-bridge-server.d.ts +16 -0
- package/dist/core/plugin-bridge-server.d.ts.map +1 -1
- package/dist/core/plugin-bridge-server.js +83 -1
- package/dist/core/plugin-bridge-server.js.map +1 -1
- package/dist/core/response-guard.d.ts +23 -0
- package/dist/core/response-guard.d.ts.map +1 -1
- package/dist/core/response-guard.js +113 -0
- package/dist/core/response-guard.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.d.ts.map +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/local-plugin-only.d.ts.map +1 -1
- package/dist/local-plugin-only.js +334 -101
- package/dist/local-plugin-only.js.map +1 -1
- package/f-mcp-plugin/code.js +514 -29
- package/f-mcp-plugin/ui.html +90 -14
- package/package.json +1 -1
- package/skills/SKILL_INDEX.md +13 -1
- package/skills/apply-figma-design-system/SKILL.md +37 -0
- package/skills/audit-figma-design-system/SKILL.md +38 -0
- package/skills/code-design-mapper/SKILL.md +37 -0
- package/skills/design-token-pipeline/SKILL.md +44 -0
- package/skills/figma-canvas-ops/SKILL.md +200 -243
- package/skills/fmcp-ds-audit-orchestrator/SKILL.md +205 -0
- package/skills/fmcp-intent-router/SKILL.md +574 -0
- package/skills/fmcp-screen-orchestrator/SKILL.md +166 -0
- package/skills/fmcp-screen-recipes/SKILL.md +528 -0
- package/skills/fmcp-token-sync-orchestrator/SKILL.md +198 -0
- package/skills/generate-figma-library/SKILL.md +38 -0
- package/skills/generate-figma-screen/SKILL.md +360 -6
- package/skills/implement-design/SKILL.md +32 -0
- package/skills/inspiration-intake/SKILL.md +220 -0
- package/skills/visual-qa-compare/SKILL.md +33 -0
package/agents/ds-auditor.md
CHANGED
|
@@ -1,35 +1,86 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ds-auditor
|
|
3
|
-
description: Figma ekranlarını
|
|
4
|
-
model:
|
|
3
|
+
description: Figma ekranlarını 5 kategori açısından denetler (DS compliance / a11y / drift / visual QA / impact). Read-only çalışır; düzeltme sadece önerir. "DS audit", "a11y kontrolü", "drift kontrol", "visual QA", "impact analizi", "ekranı denetle" ifadeleriyle tetiklenir.
|
|
4
|
+
model: opus
|
|
5
5
|
maxTurns: 30
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# DS Auditor —
|
|
8
|
+
# DS Auditor — Claude Code Thin Delegator
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Bu agent **sadece Claude Code'a özgü bir wrapper'dır**. Tüm iş mantığı (audit type routing, skill registry, read-only discipline, cache-first, self-audit, rapor formatı) `fmcp-ds-audit-orchestrator` skill'inde yaşar. Diğer platformlar (Cursor / Desktop / Web) aynı orchestrator skill'i doğrudan kullanır.
|
|
11
11
|
|
|
12
12
|
## Görev
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
2. **Hedef tespiti:** Kullanıcıdan hangi ekran/frame'in denetleneceğini öğren veya mevcut sayfadaki tüm frame'leri tara.
|
|
16
|
-
3. **Denetim:** `audit-figma-design-system` skill'indeki adımları uygula:
|
|
17
|
-
- DS bileşen kullanımı (instance vs local)
|
|
18
|
-
- Token bağlantıları (bound vs unbound)
|
|
19
|
-
- Stil tutarlılığı (text style, color style)
|
|
20
|
-
- Spacing/padding uyumu
|
|
21
|
-
4. **Raporlama:** Bulgularını yapılandırılmış markdown formatında sun.
|
|
22
|
-
5. **Öneriler:** Her bulgu için düzeltme önerisi ver (hangi skill kullanılmalı: fix-figma-design-system-finding veya apply-figma-design-system).
|
|
14
|
+
### Adım 0 — Orchestrator Skill'i Yükle
|
|
23
15
|
|
|
24
|
-
|
|
16
|
+
```
|
|
17
|
+
Read("skills/fmcp-ds-audit-orchestrator/SKILL.md")
|
|
18
|
+
```
|
|
25
19
|
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
20
|
+
Essentials bölümü common case için yeterlidir. Advanced bölümüne sadece şu koşullarda in:
|
|
21
|
+
- Çoklu audit tipi (compliance + a11y + drift aynı anda)
|
|
22
|
+
- Cache hit ama forced refresh istendi
|
|
23
|
+
- Büyük ekran SEVERE drill-down gerektiriyor
|
|
24
|
+
- Fix önerisi karmaşık (narrow vs full karar)
|
|
25
|
+
- Skill evolution ihtiyacı (yeni audit tipi)
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
### Adım 1 — Audit Type Tespit
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
Orchestrator Essentials'ındaki "Audit Type Routing" tablosuna bak. Talepten keyword ile tipi seç: `compliance | a11y | drift | visual_qa | impact | auto`.
|
|
30
|
+
|
|
31
|
+
Net değil → `AskUserQuestion` ile çoklu seçim sor.
|
|
32
|
+
|
|
33
|
+
### Adım 2 — Cache Kontrol
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
.claude/audits/<YYYY-MM-DD>-<nodeId>.md
|
|
37
|
+
```
|
|
38
|
+
24h içinde rapor var → oku, cache hit (lazy-create dizini ilk kullanımda). Yoksa fresh audit.
|
|
39
|
+
|
|
40
|
+
30 günden eski dosyaları temizle (her çalıştırma başında housekeeping).
|
|
41
|
+
|
|
42
|
+
### Adım 3 — Sub-Skill Read (Audit Type'a Göre)
|
|
43
|
+
|
|
44
|
+
| Mod | Read |
|
|
45
|
+
|---|---|
|
|
46
|
+
| compliance | `skills/audit-figma-design-system/SKILL.md` |
|
|
47
|
+
| a11y | `skills/figma-a11y-audit/SKILL.md` |
|
|
48
|
+
| drift | `skills/design-drift-detector/SKILL.md` |
|
|
49
|
+
| visual_qa | `skills/visual-qa-compare/SKILL.md` |
|
|
50
|
+
| impact | `skills/ds-impact-analysis/SKILL.md` |
|
|
51
|
+
|
|
52
|
+
Sadece seçilen modun sub-skill'ini Read et — diğerlerine DOKUNMA.
|
|
53
|
+
|
|
54
|
+
### Adım 4 — Read-Only Discipline
|
|
55
|
+
|
|
56
|
+
**Hiçbir mutation YAPMA.** Bulgular + düzeltme önerisi. Kullanıcı "fix uygula" derse:
|
|
57
|
+
- Onayı al
|
|
58
|
+
- Öneri: `screen-builder` agent'ını tetikle (bu düzeltmeyi o yapar) veya `fmcp-screen-orchestrator` skill'ini çağır
|
|
59
|
+
- Narrow (1-3 bulgu tek frame) → `fix-figma-design-system-finding`
|
|
60
|
+
- Full (4+ bulgu veya dağınık) → `apply-figma-design-system`
|
|
61
|
+
|
|
62
|
+
### Adım 5 — Self-Audit (Rapor Kalite)
|
|
63
|
+
|
|
64
|
+
Teslim öncesi:
|
|
65
|
+
- Her SEVERE kategori için ≥1 somut nodeId var mı?
|
|
66
|
+
- Her bulgu için "neden önemli" + düzeltme önerisi var mı?
|
|
67
|
+
- Metrik bloğu eksiksiz mi?
|
|
68
|
+
|
|
69
|
+
Fail → düzelt, sonra teslim.
|
|
70
|
+
|
|
71
|
+
### Adım 6 — Rapor
|
|
72
|
+
|
|
73
|
+
Orchestrator'ın "Rapor Formatı" şablonunu kullan. CI ortamında JSON mode destekle (`CI=true` env var veya kullanıcı "JSON formatında" derse).
|
|
74
|
+
|
|
75
|
+
## Kritik Kurallar (Özet — Full: orchestrator skill)
|
|
76
|
+
|
|
77
|
+
- **Read-only:** Hiçbir `figma_execute` mutation yok, sadece `figma_get_*` read tool'ları
|
|
78
|
+
- **Cheap-first:** depth=1, summary; SEVERE bulgu alt ağacında drill-down
|
|
79
|
+
- **Cache-first:** `.claude/audits/` önce kontrol, 30 günden eski temizle
|
|
80
|
+
- **Her bulgu için nodeId:** Somut olmadan raporlama yok
|
|
81
|
+
- **Türkçe rapor:** metrik bloğu sonunda
|
|
82
|
+
|
|
83
|
+
## Memory Referansları
|
|
84
|
+
|
|
85
|
+
- `feedback_figma_approval.md` — destructive action onay kuralı
|
|
86
|
+
- `feedback_turkish_chars.md` — Türkçe karakter kontrolü
|
package/agents/screen-builder.md
CHANGED
|
@@ -1,35 +1,73 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: screen-builder
|
|
3
|
-
description:
|
|
4
|
-
model:
|
|
3
|
+
description: DS-compliant Figma ekran üretim agent'ı. Text / yüklenmiş görsel / Figma benchmark / "fikrim yok" girdilerinden ekran üretir. "ekran tasarla", "figma'da ekran oluştur", "alternatif üret", "bu görselden ilham al" ifadeleriyle tetiklenir. Claude Code sub-agent isolation avantajıyla ana conversation context'ini temiz tutar.
|
|
4
|
+
model: opus
|
|
5
5
|
maxTurns: 40
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Screen Builder —
|
|
8
|
+
# Screen Builder — Claude Code Thin Delegator
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Bu agent **sadece Claude Code'a özgü bir wrapper'dır**. Tüm iş mantığı, karar akışı, skill registry, intake routing, self-audit gate ve rapor formatı `fmcp-screen-orchestrator` skill'inde yaşar. Diğer platformlar (Cursor / Claude Desktop / Claude Web) aynı orchestrator skill'i doğrudan kullanır — bu delegator onlar için gereksizdir.
|
|
11
11
|
|
|
12
12
|
## Görev
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
2. **DS hazırlık:** Kayıtlı kütüphaneyi kontrol et (`.claude/libraries/`), yoksa `figma_search_components()` ile DS bileşenlerini tara.
|
|
16
|
-
3. **Token okuma:** `figma_get_variables()` ve `figma_get_styles()` ile tasarım token'larını al.
|
|
17
|
-
4. **Ekran oluşturma:** `generate-figma-screen` skill'indeki adımları uygula:
|
|
18
|
-
- DS bileşen instance'ları kullan (hardcoded shape YASAK)
|
|
19
|
-
- Tüm değerleri DS variable'larına bağla
|
|
20
|
-
- Auto-layout ile responsive yapı kur
|
|
21
|
-
5. **Doğrulama:** `figma_capture_screenshot()` ile sonucu göster ve kullanıcı onayı al.
|
|
14
|
+
### Adım 0 — Orchestrator Skill'i Yükle
|
|
22
15
|
|
|
23
|
-
|
|
16
|
+
```
|
|
17
|
+
Read("skills/fmcp-screen-orchestrator/SKILL.md")
|
|
18
|
+
```
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
20
|
+
Essentials bölümü common case için yeterlidir. Advanced bölümüne sadece şu koşullarda in:
|
|
21
|
+
- Intake modu karmaşık (nested benchmark, hybrid image + metin)
|
|
22
|
+
- 3. self-audit denemesi başarısız
|
|
23
|
+
- Skill evolution ihtiyacı doğdu
|
|
24
|
+
- Non-obvious error (plugin bağlantı kaybı, timeout döngüsü)
|
|
28
25
|
|
|
29
|
-
|
|
26
|
+
### Adım 1 — Kullanıcı Talebini Intake Mode'a Eşle
|
|
30
27
|
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
28
|
+
Orchestrator Essentials'ındaki "Karar Akışı" bölümüne bak. Talebi şu modlardan birine ata:
|
|
29
|
+
- `text_only` — net metin açıklaması
|
|
30
|
+
- `figma_benchmark` — Figma URL pattern (`figma.com/file/...?node-id=`)
|
|
31
|
+
- `image_uploaded` — kullanıcı sohbete görsel eklemiş
|
|
32
|
+
- `image_url` — HTTP URL ama Figma değil (dribbble/behance/vs)
|
|
33
|
+
- `no_idea` — kullanıcı "bilmiyorum/bir şey öner/fikrim yok" diyor
|
|
34
|
+
|
|
35
|
+
Belirsizse önce `Read("skills/fmcp-intent-router/SKILL.md")` ile netleştir.
|
|
36
|
+
|
|
37
|
+
### Adım 2 — Orchestrator Karar Akışını Uygula
|
|
38
|
+
|
|
39
|
+
Orchestrator'ın "Karar Akışı" tablosunu takip et. Sub-skill'leri **yalnızca karar anında** Read et (lazy loading):
|
|
40
|
+
- Intake image/benchmark modunda mı? → `Read("skills/inspiration-intake/SKILL.md")`
|
|
41
|
+
- `figma_execute` çağıracak mısın? → `Read("skills/figma-canvas-ops/SKILL.md")` pre-flight
|
|
42
|
+
- Ana üretim? → `Read("skills/generate-figma-screen/SKILL.md")`
|
|
43
|
+
|
|
44
|
+
Sezgisel "belki lazım olur" Read yasak. Gereksiz sub-skill yüklemesi sub-agent context'ini şişirir.
|
|
45
|
+
|
|
46
|
+
### Adım 3 — Self-Audit Gate (Zorunlu)
|
|
47
|
+
|
|
48
|
+
Teslim öncesi:
|
|
49
|
+
```
|
|
50
|
+
figma_validate_screen(nodeId=<wrapper_id>, minScore=80)
|
|
51
|
+
```
|
|
52
|
+
`minScore=80` **her çağrıda explicit**. Başarısız → hedefli düzelt → yeniden validate. 3 deneme fail → Advanced bölümünün Error Recovery Matrix'ine in.
|
|
53
|
+
|
|
54
|
+
### Adım 4 — Rapor
|
|
55
|
+
|
|
56
|
+
Orchestrator'ın "Rapor Formatı" şablonunu kullan. Metrik bloğu (kullanılan skill'ler / API call / cache hit-miss / execute sayısı / validate score) **zorunlu**, atlanamaz.
|
|
57
|
+
|
|
58
|
+
## Kritik Kurallar (Özet — Full: orchestrator skill)
|
|
59
|
+
|
|
60
|
+
- **v1.8.2 build-from-scratch:** `"alternatif/varyasyon/farklı/yeni/tasarla/redesign"` keyword'leri → build-from-scratch KİLİTLİ, `figma_clone_screen_to_device` ASLA. Authoritative source: `skills/fmcp-intent-router/SKILL.md:68-80`
|
|
61
|
+
- **DS fallback chain:** Component → Primitive variant → Token-bound frame → ASLA raw shape
|
|
62
|
+
- **Inspiration only:** Benchmark/görselden değer alma YASAK, sadece niyet
|
|
63
|
+
- **Cache-first:** `.claude/design-systems/<lib>/` cache'i API çağırmadan ÖNCE oku
|
|
64
|
+
- **Türkçe rapor:** metrik bloğu sonunda
|
|
65
|
+
|
|
66
|
+
## Memory Referansları
|
|
67
|
+
|
|
68
|
+
- `feedback_figma_approval.md` — Figma onay kuralı
|
|
69
|
+
- `feedback_ds_component_usage.md` — ham text/shape YASAK
|
|
70
|
+
- `feedback_autolayout_fill.md` — FILL kuralı
|
|
71
|
+
- `feedback_figma_screen_standard.md` — ≤5 execute hedefi
|
|
72
|
+
- `feedback_gestalt_design.md` — eşit spacing YASAK
|
|
73
|
+
- `feedback_turkish_chars.md` — Türkçe karakter kontrolü
|
package/agents/token-syncer.md
CHANGED
|
@@ -1,32 +1,76 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: token-syncer
|
|
3
|
-
description: Figma design token'larını kod dosyalarıyla
|
|
4
|
-
model:
|
|
3
|
+
description: Figma design token'larını kod dosyalarıyla (CSS/Tailwind/Swift/Compose/Sass) senkronize eder. Diff preview + onay + write zorunlu akış. "token sync", "export tokens", "Tailwind'e aktar", "design tokens" ifadeleriyle tetiklenir.
|
|
4
|
+
model: opus
|
|
5
5
|
maxTurns: 20
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Token Syncer —
|
|
8
|
+
# Token Syncer — Claude Code Thin Delegator
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Bu agent **sadece Claude Code'a özgü bir wrapper'dır**. Tüm iş mantığı (platform routing, diff preview, binding coverage, rapor formatı) `fmcp-token-sync-orchestrator` skill'inde yaşar. Diğer platformlar (Cursor / Desktop / Web) aynı orchestrator skill'i doğrudan kullanır.
|
|
11
11
|
|
|
12
12
|
## Görev
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
2. **Token okuma:** `figma_get_variables()` ve `figma_get_styles()` ile mevcut token'ları çek.
|
|
16
|
-
3. **Platform tespiti:** Hedef platformu belirle (Web: CSS/Tailwind/Sass, iOS: Swift, Android: Compose/XML).
|
|
17
|
-
4. **Senkronizasyon:** `design-token-pipeline` skill'indeki adımları uygula:
|
|
18
|
-
- Figma → Kod (export)
|
|
19
|
-
- Kod → Figma (import — opsiyonel)
|
|
20
|
-
5. **Doğrulama:** Oluşturulan dosyaları kontrol et.
|
|
14
|
+
### Adım 0 — Orchestrator Skill'i Yükle
|
|
21
15
|
|
|
22
|
-
|
|
16
|
+
```
|
|
17
|
+
Read("skills/fmcp-token-sync-orchestrator/SKILL.md")
|
|
18
|
+
```
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
20
|
+
Essentials bölümü common case için yeterlidir. Advanced bölümüne sadece şu koşullarda in:
|
|
21
|
+
- Multi-platform sync (aynı token'lar hem CSS hem Swift)
|
|
22
|
+
- Custom component mapping (code-design-mapper gerektiren)
|
|
23
|
+
- Platform default path uygunsuz (custom path)
|
|
24
|
+
- Kod → Figma import mode
|
|
25
|
+
- Yeni platform desteği (skill evolution)
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
### Adım 1 — Platform Tespit
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
29
|
+
Orchestrator Essentials'ındaki "Platform Routing" tablosuna bak:
|
|
30
|
+
- Kullanıcı hedef dosyayı verdi mi? Uzantıdan platformu tespit et
|
|
31
|
+
- Kullanıcı sadece platform adı verdi mi? Standard path öner
|
|
32
|
+
- Hiçbiri yok → `AskUserQuestion` ile çoklu seçim sor (CSS / Tailwind / Swift / Compose)
|
|
33
|
+
|
|
34
|
+
### Adım 2 — Sub-Skill Read
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Read("skills/design-token-pipeline/SKILL.md")
|
|
38
|
+
```
|
|
39
|
+
Ana motor her zaman bu. `code-design-mapper` ve `design-system-rules` sadece spesifik ihtiyaç olursa.
|
|
40
|
+
|
|
41
|
+
### Adım 3 — Dry-Run + Diff Preview
|
|
42
|
+
|
|
43
|
+
**Dosyaya yazma!** Sadece buffer'a al, mevcut dosyayla unified diff üret, sohbete yaz.
|
|
44
|
+
|
|
45
|
+
### Adım 4 — Onay Al
|
|
46
|
+
|
|
47
|
+
`AskUserQuestion` ile: "Bu değişiklikleri uygulayayım mı? (Evet / Hayır / Sadece bazıları)". Onay olmadan `Write` / `Edit` yasak.
|
|
48
|
+
|
|
49
|
+
### Adım 5 — Write (Onay Sonrası)
|
|
50
|
+
|
|
51
|
+
- Mevcut dosya varsa → `Edit` ile hedefli
|
|
52
|
+
- Yoksa → `Write` ile yeni dosya
|
|
53
|
+
|
|
54
|
+
### Adım 6 — Self-Audit (Binding Coverage)
|
|
55
|
+
|
|
56
|
+
Write sonrası:
|
|
57
|
+
- Toplam token sayısı
|
|
58
|
+
- Binding oranı (%)
|
|
59
|
+
- Upgraded (hardcoded → variable binding)
|
|
60
|
+
- Leftover (hâlâ hardcoded kalan node sayısı) → ds-auditor'a yönlendir
|
|
61
|
+
|
|
62
|
+
### Adım 7 — Rapor
|
|
63
|
+
|
|
64
|
+
Orchestrator'ın "Rapor Formatı" şablonunu kullan. Metrik bloğu zorunlu.
|
|
65
|
+
|
|
66
|
+
## Kritik Kurallar (Özet — Full: orchestrator skill)
|
|
67
|
+
|
|
68
|
+
- **Diff olmadan write YOK:** Mutlak kural, ihlal edilemez
|
|
69
|
+
- **Platform tespit:** Belirsizse sor, tahmin etme
|
|
70
|
+
- **Cheap-first:** `figma_get_variables(verbosity="summary")` default; full sadece eksik binding keşfinde
|
|
71
|
+
- **Türkçe rapor:** metrik bloğu sonunda
|
|
72
|
+
|
|
73
|
+
## Memory Referansları
|
|
74
|
+
|
|
75
|
+
- `feedback_figma_approval.md` — destructive action onay kuralı
|
|
76
|
+
- `feedback_turkish_chars.md` — Türkçe karakter kontrolü
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static analyzer for figma_execute code — detects Plugin API gotchas AND
|
|
3
|
+
* design-system discipline violations.
|
|
4
|
+
*
|
|
5
|
+
* v1.8.1+: Emits structured CodeWarning objects with SEVERE vs ADVISORY
|
|
6
|
+
* severity. SEVERE warnings surface as _designSystemViolations in the
|
|
7
|
+
* execute response (prominent, Claude-readable); ADVISORY warnings stay
|
|
8
|
+
* in _warnings (legacy gotchas).
|
|
9
|
+
*
|
|
10
|
+
* Never blocks execution — the analyzer is advisory-only by design.
|
|
11
|
+
* Claude reads the warnings and self-corrects on the next turn.
|
|
12
|
+
*/
|
|
13
|
+
/** Warning severity — SEVERE violates DS discipline; ADVISORY is a gotcha hint. */
|
|
14
|
+
export type WarningSeverity = "SEVERE" | "ADVISORY";
|
|
15
|
+
export interface CodeWarning {
|
|
16
|
+
severity: WarningSeverity;
|
|
17
|
+
category: string;
|
|
18
|
+
message: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Analyze figma_execute code for common mistakes AND design-system discipline
|
|
22
|
+
* violations. Returns an array of structured warnings.
|
|
23
|
+
*
|
|
24
|
+
* SEVERE categories (v1.8.1+):
|
|
25
|
+
* HARDCODED_COLOR — SOLID fills without setBoundVariableForPaint
|
|
26
|
+
* NO_INSTANCE_USAGE — 3+ createFrame without component instantiation
|
|
27
|
+
* HARDCODED_FONT_SIZE — .fontSize without setTextStyleIdAsync
|
|
28
|
+
* HARDCODED_SPACING — padding/itemSpacing/cornerRadius without setBoundVariable
|
|
29
|
+
* HAND_BUILT_SEPARATORS — 2+ createRectangle without instance/binding
|
|
30
|
+
* NO_AUTO_LAYOUT — createFrame without layoutMode
|
|
31
|
+
*
|
|
32
|
+
* ADVISORY categories (pre-v1.8.1 legacy gotchas):
|
|
33
|
+
* ORDERING — FILL/ABSOLUTE set before appendChild
|
|
34
|
+
* SYNC_API — sync style APIs in dynamic-page mode
|
|
35
|
+
* FONT_LOAD — .characters= without loadFontAsync
|
|
36
|
+
*/
|
|
37
|
+
export declare function analyzeCodeForWarnings(code: string): CodeWarning[];
|
|
38
|
+
//# sourceMappingURL=code-warnings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-warnings.d.ts","sourceRoot":"","sources":["../../src/core/code-warnings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,mFAAmF;AACnF,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CA2LlE"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static analyzer for figma_execute code — detects Plugin API gotchas AND
|
|
3
|
+
* design-system discipline violations.
|
|
4
|
+
*
|
|
5
|
+
* v1.8.1+: Emits structured CodeWarning objects with SEVERE vs ADVISORY
|
|
6
|
+
* severity. SEVERE warnings surface as _designSystemViolations in the
|
|
7
|
+
* execute response (prominent, Claude-readable); ADVISORY warnings stay
|
|
8
|
+
* in _warnings (legacy gotchas).
|
|
9
|
+
*
|
|
10
|
+
* Never blocks execution — the analyzer is advisory-only by design.
|
|
11
|
+
* Claude reads the warnings and self-corrects on the next turn.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Analyze figma_execute code for common mistakes AND design-system discipline
|
|
15
|
+
* violations. Returns an array of structured warnings.
|
|
16
|
+
*
|
|
17
|
+
* SEVERE categories (v1.8.1+):
|
|
18
|
+
* HARDCODED_COLOR — SOLID fills without setBoundVariableForPaint
|
|
19
|
+
* NO_INSTANCE_USAGE — 3+ createFrame without component instantiation
|
|
20
|
+
* HARDCODED_FONT_SIZE — .fontSize without setTextStyleIdAsync
|
|
21
|
+
* HARDCODED_SPACING — padding/itemSpacing/cornerRadius without setBoundVariable
|
|
22
|
+
* HAND_BUILT_SEPARATORS — 2+ createRectangle without instance/binding
|
|
23
|
+
* NO_AUTO_LAYOUT — createFrame without layoutMode
|
|
24
|
+
*
|
|
25
|
+
* ADVISORY categories (pre-v1.8.1 legacy gotchas):
|
|
26
|
+
* ORDERING — FILL/ABSOLUTE set before appendChild
|
|
27
|
+
* SYNC_API — sync style APIs in dynamic-page mode
|
|
28
|
+
* FONT_LOAD — .characters= without loadFontAsync
|
|
29
|
+
*/
|
|
30
|
+
export function analyzeCodeForWarnings(code) {
|
|
31
|
+
const warnings = [];
|
|
32
|
+
// ────────────────────────────────────────────────────────────────────
|
|
33
|
+
// SECTION 1 — Plugin API gotchas (ADVISORY)
|
|
34
|
+
// ────────────────────────────────────────────────────────────────────
|
|
35
|
+
// 1a. FILL before appendChild — must set FILL *after* node is in auto-layout parent
|
|
36
|
+
if (/layoutSizing(?:Horizontal|Vertical)\s*=\s*['"]FILL['"]/i.test(code)) {
|
|
37
|
+
const fillIdx = code.search(/layoutSizing(?:Horizontal|Vertical)\s*=\s*['"]FILL['"]/i);
|
|
38
|
+
const appendIdx = code.indexOf("appendChild");
|
|
39
|
+
if (appendIdx === -1 || fillIdx < appendIdx) {
|
|
40
|
+
warnings.push({
|
|
41
|
+
severity: "ADVISORY",
|
|
42
|
+
category: "ORDERING",
|
|
43
|
+
message: "layoutSizingHorizontal/Vertical = 'FILL' appendChild'dan ONCE ayarlanmis. " +
|
|
44
|
+
"Oncesinde hata verir. FILL'i appendChild SONRASINA tasi.",
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// 1b. layoutPositioning = ABSOLUTE before appendChild (v1.8.1: added)
|
|
49
|
+
if (/layoutPositioning\s*=\s*['"]ABSOLUTE['"]/i.test(code)) {
|
|
50
|
+
const absIdx = code.search(/layoutPositioning\s*=\s*['"]ABSOLUTE['"]/i);
|
|
51
|
+
const appendIdx = code.indexOf("appendChild");
|
|
52
|
+
if (appendIdx === -1 || absIdx < appendIdx) {
|
|
53
|
+
warnings.push({
|
|
54
|
+
severity: "ADVISORY",
|
|
55
|
+
category: "ORDERING",
|
|
56
|
+
message: "layoutPositioning = 'ABSOLUTE' appendChild'dan ONCE ayarlanmis. " +
|
|
57
|
+
"Parent layoutMode !== NONE kontrolu basarisiz olur. appendChild SONRA ayarla.",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// 1c. Sync API usage — should use Async versions
|
|
62
|
+
// v1.8.2: expanded to include node/style/variable lookup APIs that fail
|
|
63
|
+
// in dynamic-page mode (causing "Cannot call with documentAccess: dynamic-page" errors)
|
|
64
|
+
const syncApis = [
|
|
65
|
+
{ sync: "getLocalPaintStyles(", async: "getLocalPaintStylesAsync(" },
|
|
66
|
+
{ sync: "getLocalTextStyles(", async: "getLocalTextStylesAsync(" },
|
|
67
|
+
{ sync: "getLocalEffectStyles(", async: "getLocalEffectStylesAsync(" },
|
|
68
|
+
{ sync: "getLocalGridStyles(", async: "getLocalGridStylesAsync(" },
|
|
69
|
+
// v1.8.2: dynamic-page mode fixes
|
|
70
|
+
{ sync: "figma.getNodeById(", async: "figma.getNodeByIdAsync(" },
|
|
71
|
+
{ sync: "figma.getStyleById(", async: "figma.getStyleByIdAsync(" },
|
|
72
|
+
{ sync: "figma.variables.getVariableById(", async: "figma.variables.getVariableByIdAsync(" },
|
|
73
|
+
{ sync: "figma.variables.getVariableCollectionById(", async: "figma.variables.getVariableCollectionByIdAsync(" },
|
|
74
|
+
{ sync: "figma.importComponentByKey(", async: "figma.importComponentByKeyAsync(" },
|
|
75
|
+
];
|
|
76
|
+
for (const api of syncApis) {
|
|
77
|
+
if (code.includes(api.sync) && !code.includes(api.async)) {
|
|
78
|
+
warnings.push({
|
|
79
|
+
severity: "ADVISORY",
|
|
80
|
+
category: "SYNC_API",
|
|
81
|
+
message: `Sync API '${api.sync.slice(0, -1)}' tespit edildi. 'await ${api.async.slice(0, -1)}' kullanin — dynamic-page modunda sync API'ler calismaz.`,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// 1d. Font not loaded before text modification
|
|
86
|
+
if ((/\.characters\s*=/.test(code) || code.includes(".insertCharacters") || code.includes(".deleteCharacters")) &&
|
|
87
|
+
!code.includes("loadFontAsync")) {
|
|
88
|
+
warnings.push({
|
|
89
|
+
severity: "ADVISORY",
|
|
90
|
+
category: "FONT_LOAD",
|
|
91
|
+
message: "Text icerik degisikligi (characters) tespit edildi, ancak loadFontAsync cagrisi yok. " +
|
|
92
|
+
"Metin degistirmeden once 'await figma.loadFontAsync(node.fontName)' ekleyin.",
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// 1e. Sync page assignment — does not work
|
|
96
|
+
if (/figma\.currentPage\s*=/.test(code) && !code.includes("setCurrentPageAsync")) {
|
|
97
|
+
warnings.push({
|
|
98
|
+
severity: "ADVISORY",
|
|
99
|
+
category: "SYNC_API",
|
|
100
|
+
message: "'figma.currentPage = ...' calismaz. 'await figma.setCurrentPageAsync(page)' kullanin.",
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// ────────────────────────────────────────────────────────────────────
|
|
104
|
+
// SECTION 2 — Design System Discipline (SEVERE — v1.8.1+)
|
|
105
|
+
// These warnings indicate Claude is bypassing DS tokens and instance reuse,
|
|
106
|
+
// producing hand-built UI that ignores the configured design system.
|
|
107
|
+
// ────────────────────────────────────────────────────────────────────
|
|
108
|
+
// 2a. Hardcoded solid color literal — fills = [{type:'SOLID',color:{r:...,g:...,b:...}}]
|
|
109
|
+
// Matches any code that constructs a SOLID paint with inline RGB values.
|
|
110
|
+
const hardcodedSolidRegex = /type\s*:\s*['"]SOLID['"][\s\S]{0,200}?color\s*:\s*\{\s*r\s*:\s*[\d.]+/;
|
|
111
|
+
if (hardcodedSolidRegex.test(code)) {
|
|
112
|
+
// If the code ALSO uses setBoundVariableForPaint, it's probably binding the
|
|
113
|
+
// variable and using the solid as a structure scaffold — allow it.
|
|
114
|
+
if (!code.includes("setBoundVariableForPaint")) {
|
|
115
|
+
warnings.push({
|
|
116
|
+
severity: "SEVERE",
|
|
117
|
+
category: "HARDCODED_COLOR",
|
|
118
|
+
message: "❌ TOKEN DISIPLINI IHLALI: Hardcoded SOLID color tespit edildi ama setBoundVariableForPaint cagrisi yok. " +
|
|
119
|
+
"Design system token binding ZORUNLUDUR. Once 'figma_get_library_variables' ile variable key'leri al, " +
|
|
120
|
+
"sonra 'importVariableByKeyAsync' + 'setBoundVariableForPaint' kullan. " +
|
|
121
|
+
"Ornek: const v = await figma.variables.importVariableByKeyAsync('KEY'); " +
|
|
122
|
+
"const bound = figma.variables.setBoundVariableForPaint(fills[0], 'color', v); node.fills = [bound];",
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// 2b. No-instance usage — 3+ createFrame but 0 component instantiation
|
|
127
|
+
const createFrameCount = (code.match(/figma\.createFrame\(\)/g) || []).length;
|
|
128
|
+
const hasInstanceCreation = code.includes("importComponentByKeyAsync") ||
|
|
129
|
+
code.includes("createInstance()") ||
|
|
130
|
+
code.includes(".createInstance(") ||
|
|
131
|
+
code.includes("importComponentSetByKeyAsync");
|
|
132
|
+
if (createFrameCount >= 3 && !hasInstanceCreation) {
|
|
133
|
+
warnings.push({
|
|
134
|
+
severity: "SEVERE",
|
|
135
|
+
category: "NO_INSTANCE_USAGE",
|
|
136
|
+
message: `❌ DS BILESEN KULLANIMI EKSIK: ${createFrameCount} adet createFrame() cagrisi tespit edildi ama ` +
|
|
137
|
+
"hicbir component instance olusturulmamis (importComponentByKeyAsync / createInstance yok). " +
|
|
138
|
+
"Design system bilesenleri varsa SIFIRDAN CIZME - once figma_search_assets ile mevcut DS " +
|
|
139
|
+
"bileseni ara, sonra figma_instantiate_component veya importComponentByKeyAsync kullan. " +
|
|
140
|
+
"Hesapkart, Button, NavigationTopBar, BottomNav, PillTabs gibi DS bilesenleri zaten library'de var.",
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// 2c. Hardcoded fontSize without setTextStyleIdAsync
|
|
144
|
+
if (/\.fontSize\s*=\s*\d/.test(code) && !code.includes("setTextStyleIdAsync")) {
|
|
145
|
+
warnings.push({
|
|
146
|
+
severity: "SEVERE",
|
|
147
|
+
category: "HARDCODED_FONT_SIZE",
|
|
148
|
+
message: "❌ TIPOGRAFI DISIPLINI IHLALI: Hardcoded fontSize tespit edildi ama setTextStyleIdAsync cagrisi yok. " +
|
|
149
|
+
"DS text style'lari ZORUNLUDUR. figma_import_style ile text style import et veya " +
|
|
150
|
+
"getLocalTextStylesAsync() ile bul, sonra 'await textNode.setTextStyleIdAsync(style.id)' kullan. " +
|
|
151
|
+
"Bu font family + size + weight + line-height'i TEK seferde bagllar. " +
|
|
152
|
+
"Uyari: setBoundVariable('fontSize', v) YANLIS - sadece size bagllar, style bagllmaz.",
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// 2d. Hardcoded padding/gap/radius without setBoundVariable
|
|
156
|
+
const spacingAssignRegex = /\.(?:paddingTop|paddingBottom|paddingLeft|paddingRight|itemSpacing|counterAxisSpacing|topLeftRadius|topRightRadius|bottomLeftRadius|bottomRightRadius|cornerRadius)\s*=\s*\d/;
|
|
157
|
+
if (spacingAssignRegex.test(code) && !code.includes("setBoundVariable")) {
|
|
158
|
+
warnings.push({
|
|
159
|
+
severity: "SEVERE",
|
|
160
|
+
category: "HARDCODED_SPACING",
|
|
161
|
+
message: "❌ SPACING DISIPLINI IHLALI: Hardcoded padding/itemSpacing/cornerRadius tespit edildi ama " +
|
|
162
|
+
"setBoundVariable cagrisi yok. DS spacing token'lari ZORUNLUDUR. " +
|
|
163
|
+
"figma_get_library_variables ile spacing variable key'lerini al, importVariableByKeyAsync ile import et, " +
|
|
164
|
+
"'node.setBoundVariable(\"paddingLeft\", variable)' kullan. " +
|
|
165
|
+
"Yaygin DS spacing token'lari: spacing/100, spacing/200, spacing/300, spacing/400.",
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
// 2e. Rectangle as separator without DS reference (often indicates hand-built dividers)
|
|
169
|
+
const rectCount = (code.match(/figma\.createRectangle\(\)/g) || []).length;
|
|
170
|
+
if (rectCount >= 2 && !hasInstanceCreation && !code.includes("setBoundVariableForPaint")) {
|
|
171
|
+
warnings.push({
|
|
172
|
+
severity: "SEVERE",
|
|
173
|
+
category: "HAND_BUILT_SEPARATORS",
|
|
174
|
+
message: `❌ ${rectCount} adet createRectangle() cagrisi tespit edildi (muhtemelen divider/separator icin). ` +
|
|
175
|
+
"DS'de Divider/Separator bileseni varsa onu kullan, elle rectangle cizme. " +
|
|
176
|
+
"Alternatif: frame border + setBoundVariableForPaint ile stroke token binding.",
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
// 2f. No auto-layout — createFrame without layoutMode assignment
|
|
180
|
+
if (createFrameCount >= 1 && !code.includes("layoutMode")) {
|
|
181
|
+
warnings.push({
|
|
182
|
+
severity: "SEVERE",
|
|
183
|
+
category: "NO_AUTO_LAYOUT",
|
|
184
|
+
message: `❌ RESPONSIVE EKSIK: ${createFrameCount} adet createFrame() cagrisi var ama hicbir layoutMode atamasi yok. ` +
|
|
185
|
+
"Auto-layout olmayan frame'ler responsive degildir, icerige gore boyutlanmaz. " +
|
|
186
|
+
"Her frame icin 'frame.layoutMode = \"VERTICAL\"' (veya HORIZONTAL) + primaryAxisSizingMode ekle.",
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return warnings;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=code-warnings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-warnings.js","sourceRoot":"","sources":["../../src/core/code-warnings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma device frame presets — canonical dimensions used in Figma's
|
|
3
|
+
* built-in "Frame" picker (matches the iPhone/Android/iPad preset list).
|
|
4
|
+
*
|
|
5
|
+
* v1.8.1+: Used by figma_clone_screen_to_device to adapt a source
|
|
6
|
+
* screen to a target device size while preserving auto-layout and
|
|
7
|
+
* library instance bindings.
|
|
8
|
+
*/
|
|
9
|
+
export interface DevicePreset {
|
|
10
|
+
/** Canonical name shown in Figma UI */
|
|
11
|
+
name: string;
|
|
12
|
+
/** Width in points (Figma uses px but logical points) */
|
|
13
|
+
width: number;
|
|
14
|
+
/** Height in points */
|
|
15
|
+
height: number;
|
|
16
|
+
/** Platform category for grouping */
|
|
17
|
+
category: "phone" | "tablet" | "desktop" | "watch" | "custom";
|
|
18
|
+
/** Additional aliases that resolve to this preset */
|
|
19
|
+
aliases?: string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Built-in device presets — matches Figma's Frame picker as of 2025-2026.
|
|
23
|
+
* Values verified against the user-provided screenshot of Figma's frame panel.
|
|
24
|
+
*/
|
|
25
|
+
export declare const DEVICE_PRESETS: DevicePreset[];
|
|
26
|
+
/**
|
|
27
|
+
* Look up a device preset by name or alias (case-insensitive).
|
|
28
|
+
* Returns undefined if no match found.
|
|
29
|
+
*/
|
|
30
|
+
export declare function findPreset(name: string): DevicePreset | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Parse a custom device dimension string like "1200x800" or "1200×800".
|
|
33
|
+
* Returns undefined if the string is not a valid dimension pair.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseCustomDimension(input: string): {
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
} | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a device string (name, alias, or custom "WxH") to concrete
|
|
41
|
+
* dimensions. Used by figma_clone_screen_to_device before sending the
|
|
42
|
+
* request to the plugin handler.
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveDevice(input: string): {
|
|
45
|
+
name: string;
|
|
46
|
+
width: number;
|
|
47
|
+
height: number;
|
|
48
|
+
} | undefined;
|
|
49
|
+
//# sourceMappingURL=device-presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-presets.d.ts","sourceRoot":"","sources":["../../src/core/device-presets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,YAAY;IAC5B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC9D,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,EAkExC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAwBjE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,MAAM,GACX;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAU/C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,KAAK,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAc7D"}
|