@atezer/figma-mcp-bridge 1.7.29 → 1.9.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/CHANGELOG.md +403 -0
- package/README.md +4 -3
- 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 +32 -0
- package/dist/core/plugin-bridge-connector.d.ts.map +1 -1
- package/dist/core/plugin-bridge-connector.js +31 -2
- package/dist/core/plugin-bridge-connector.js.map +1 -1
- package/dist/core/plugin-bridge-server.d.ts +8 -0
- package/dist/core/plugin-bridge-server.d.ts.map +1 -1
- package/dist/core/plugin-bridge-server.js +27 -2
- 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 +504 -85
- package/dist/local-plugin-only.js.map +1 -1
- package/f-mcp-plugin/code.js +514 -29
- package/f-mcp-plugin/ui.html +62 -6
- 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 -240
- package/skills/fmcp-ds-audit-orchestrator/SKILL.md +205 -0
- package/skills/fmcp-intent-router/SKILL.md +574 -0
- package/skills/fmcp-project-rules/SKILL.md +9 -5
- 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 +382 -19
- 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
|
@@ -6,6 +6,61 @@ metadata:
|
|
|
6
6
|
personas:
|
|
7
7
|
- designer
|
|
8
8
|
- uidev
|
|
9
|
+
required_inputs:
|
|
10
|
+
- name: device
|
|
11
|
+
type: enum
|
|
12
|
+
options:
|
|
13
|
+
- "iPhone 17 (402×874)"
|
|
14
|
+
- "iPhone 16 Pro Max (440×956)"
|
|
15
|
+
- "iPhone 16 (393×852)"
|
|
16
|
+
- "iPhone 13/14 (390×844)"
|
|
17
|
+
- "Android Compact (412×917)"
|
|
18
|
+
- "Android Medium (700×840)"
|
|
19
|
+
- "iPad Pro 11 (834×1194)"
|
|
20
|
+
- "iPad Pro 13 (1024×1366)"
|
|
21
|
+
- "Desktop (1440×1024)"
|
|
22
|
+
- "Custom (width×height ver)"
|
|
23
|
+
question: "Hangi device boyutunda olsun?"
|
|
24
|
+
required: true
|
|
25
|
+
default_source: ".claude/design-systems/last-intent.md#device"
|
|
26
|
+
- name: design_system
|
|
27
|
+
type: from_state
|
|
28
|
+
source: ".claude/design-systems/active-ds.md#Library Name"
|
|
29
|
+
fallback_question: "Hangi tasarım sistemi kullanılsın? (❖ SUI / Material / Apple HIG / Custom)"
|
|
30
|
+
required: true
|
|
31
|
+
- name: reference_benchmark
|
|
32
|
+
type: node_id_or_none
|
|
33
|
+
question: "Referans alınacak benchmark ekranı var mı? (Node ID veya Figma URL, yoksa 'yok')"
|
|
34
|
+
required: false
|
|
35
|
+
affects: ["screen_type", "sections"]
|
|
36
|
+
- name: screen_type
|
|
37
|
+
type: enum
|
|
38
|
+
options:
|
|
39
|
+
- "Dashboard / özet"
|
|
40
|
+
- "Liste / arama sonuçları"
|
|
41
|
+
- "Detay / profil"
|
|
42
|
+
- "Form / veri girişi"
|
|
43
|
+
- "Login / onboarding"
|
|
44
|
+
- "Confirmation / success"
|
|
45
|
+
- "Empty state"
|
|
46
|
+
- "Error / 404"
|
|
47
|
+
question: "Ne tür bir ekran?"
|
|
48
|
+
required: true
|
|
49
|
+
skip_if: "reference_benchmark != none"
|
|
50
|
+
- name: sections
|
|
51
|
+
type: string_list
|
|
52
|
+
question: "Hangi ana içerik bölümlerini istiyorsun? (örn: header, balance card, quick actions, transactions, bottom nav)"
|
|
53
|
+
required: true
|
|
54
|
+
skip_if: "reference_benchmark != none"
|
|
55
|
+
- name: variants
|
|
56
|
+
type: enum
|
|
57
|
+
options:
|
|
58
|
+
- "Tek varyant"
|
|
59
|
+
- "Light + Dark mode"
|
|
60
|
+
- "2-3 layout alternatifi"
|
|
61
|
+
question: "Kaç varyant istiyorsun?"
|
|
62
|
+
required: false
|
|
63
|
+
default: "Tek varyant"
|
|
9
64
|
---
|
|
10
65
|
|
|
11
66
|
# Generate Figma Screen — Kod/Açıklamadan Figma Ekranı
|
|
@@ -43,6 +98,33 @@ Topluluk `figma-generate-design` skill'inden uyarlanmış, F-MCP Bridge araçlar
|
|
|
43
98
|
|
|
44
99
|
**Bu adımları sırayla uygula. Adım atlama.**
|
|
45
100
|
|
|
101
|
+
### Step 0: Aktif Tasarım Sistemi Kontrolü (ZORUNLU - v1.8.0+)
|
|
102
|
+
|
|
103
|
+
**Ekran yapmaya başlamadan önce DS context'inin belirli olduğundan emin ol.**
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
1. Read .claude/design-systems/active-ds.md
|
|
107
|
+
2. Status alanı:
|
|
108
|
+
✅ Aktif → Library Name'i not al, Step 1'e geç
|
|
109
|
+
❌ Henüz seçilmedi → Kullanıcıya sor:
|
|
110
|
+
"Hangi tasarım sistemi ile ilerleyelim?
|
|
111
|
+
- ❖ SUI (varsa)
|
|
112
|
+
- Material Design
|
|
113
|
+
- Apple HIG
|
|
114
|
+
- Kendi DS'iniz (Figma library URL verin)
|
|
115
|
+
- Hiçbiri (ham Figma)"
|
|
116
|
+
3. Kullanıcı yanıtladıktan sonra active-ds.md'yi update et:
|
|
117
|
+
- Status: ✅ Aktif
|
|
118
|
+
- Library Name: <seçim>
|
|
119
|
+
- Selected At: <bugün>
|
|
120
|
+
4. Sonraki turlarda bu soruyu TEKRAR SORMA — active-ds.md zaten dolu.
|
|
121
|
+
Kullanıcı açıkça "DS değiştir" demediği sürece aynı DS'i kullan.
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Bypass:** Kullanıcı "DS'siz devam et" derse `Status: DS bypass mode` olarak işaretle. Token binding kuralı esnetilir ama yine de kullanıcıya hardcoded değer kullandığını bildir.
|
|
125
|
+
|
|
126
|
+
Detay: [figma-canvas-ops SKILL Section 0 — Design System Context](../figma-canvas-ops/SKILL.md#0-design-system-context-zorunlu--v180).
|
|
127
|
+
|
|
46
128
|
### Step 1: Plugin Bağlantısını Doğrula
|
|
47
129
|
|
|
48
130
|
```
|
|
@@ -109,13 +191,33 @@ Proje kökünde `.fmcp-brand-profile.json` varsa:
|
|
|
109
191
|
|
|
110
192
|
Üç şey gerekiyor: **bileşenler**, **variable'lar**, **stiller**.
|
|
111
193
|
|
|
112
|
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
-
|
|
116
|
-
|
|
194
|
+
**⚠️ MCP TOOL SEÇİMİ (v1.8.0+):**
|
|
195
|
+
- F-MCP plugin bağlıysa **`figma_search_assets`** veya **`figma_get_library_variables`** kullan
|
|
196
|
+
- Resmi Figma MCP'nin **`search_design_system`** tool'unu **ÇAĞIRMA** — "Resource links not supported" / "file could not be accessed" hatası verir
|
|
197
|
+
- Detay: FMCP_INSTRUCTIONS → "TOOL SELECTION" bölümü
|
|
198
|
+
|
|
199
|
+
**CACHE-FIRST KURALI (MUTLAK ZORUNLU - PRE-FLIGHT BLOCKER):**
|
|
200
|
+
|
|
201
|
+
Figma API'ye gitmeden önce `.claude/design-systems/<library-id>/` cache'ini kontrol et:
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
1. Read .claude/design-systems/<library-id>/_meta.md
|
|
205
|
+
↓
|
|
206
|
+
✅ Var, sync güncel (24h içinde) → cache'leri kullan, devam et
|
|
207
|
+
❌ Yok / sync eski / yarım kalmış → Step 3a-3d'yi ÇALIŞTIR ve cache'i doldur,
|
|
208
|
+
ANCAK O ZAMAN ekran üretimine başla
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Cache eksik veya stale ise ekran üretimi BAŞLAYAMAZ** — önce keşif/cache, sonra üretim. Bu, hardcoded fallback'leri ve tekrar tekrar API çağrılarını engeller.
|
|
212
|
+
|
|
213
|
+
- Text style key'leri → `.claude/design-systems/<library-id>/tokens.md` (text style key cache)
|
|
214
|
+
- Variable key'leri → `.claude/design-systems/<library-id>/tokens.md`
|
|
215
|
+
- Component key'leri + override notları → `.claude/design-systems/<library-id>/components.md`
|
|
216
|
+
- Font ailesi + available weights → `.claude/design-systems/<library-id>/tokens.md` (Font Weights bölümü)
|
|
217
|
+
|
|
218
|
+
Cache doldurulduktan sonra her oturumda 24 saat boyunca tekrar API'ye gitmeden okunabilir. **Bu, sonraki oturumlarda token tüketimini %60-70 düşürür.**
|
|
117
219
|
|
|
118
|
-
Cache
|
|
220
|
+
**Cache Invalidation:** Cache dosyasının başına `lastUpdated: YYYY-MM-DD HH:mm` ekle. 24 saatten eski cache'ler otomatik yenilenmelidir. Kütüphane güncellendiğinde key'ler değişebilir.
|
|
119
221
|
|
|
120
222
|
#### Kütüphane Cache Şablonu
|
|
121
223
|
|
|
@@ -201,27 +303,83 @@ Text style ve effect style'ları not al.
|
|
|
201
303
|
Ekran oluşturmadan önce kullanılacak tüm DS token'larının **variable key'lerini** topla. Bu adım atlanamaz.
|
|
202
304
|
|
|
203
305
|
1. **Kütüphane dosyasını oku:** `.claude/libraries/` dizinindeki kütüphane dosyasından font ailesi, variable collection ve text style bilgilerini al.
|
|
204
|
-
2. **
|
|
306
|
+
2. **HEDEF dosyada variable key'lerini çek** (DS dosyasına bağlanmak GEREKMEZ):
|
|
307
|
+
```
|
|
308
|
+
figma_get_library_variables({ libraryName: "❖ SUI" })
|
|
309
|
+
```
|
|
310
|
+
Veya `figma_execute` ile:
|
|
205
311
|
```js
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
312
|
+
// HEDEF dosyada çalıştır — DS dosyası değil!
|
|
313
|
+
var cols = await figma.teamLibrary.getAvailableLibraryVariableCollectionsAsync();
|
|
314
|
+
var target = cols.filter(function(c) { return c.libraryName === "❖ SUI"; });
|
|
315
|
+
var results = [];
|
|
316
|
+
for (var ci = 0; ci < target.length; ci++) {
|
|
317
|
+
var vars = await figma.teamLibrary.getVariablesInLibraryCollectionAsync(target[ci].key);
|
|
318
|
+
for (var vi = 0; vi < vars.length; vi++) {
|
|
319
|
+
results.push({ name: vars[vi].name, key: vars[vi].key, type: vars[vi].resolvedType, collection: target[ci].name });
|
|
320
|
+
}
|
|
212
321
|
}
|
|
213
|
-
return
|
|
322
|
+
return results;
|
|
214
323
|
```
|
|
215
|
-
3. **Text style
|
|
324
|
+
3. **Text style key'lerini çek:** Kütüphane cache'inde key varsa oku. Yoksa REST API ile DS dosyasından: `figma_rest_api GET /v1/files/{DS_FILE_KEY}/styles`
|
|
325
|
+
Alternatif: Hedef dosyada zaten import edilmiş style'lar:
|
|
216
326
|
```js
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
return styles.map(s => ({ id: s.id, name: s.name, key: s.key }));
|
|
327
|
+
var styles = await figma.getLocalTextStylesAsync();
|
|
328
|
+
return styles.map(function(s) { return { id: s.id, name: s.name, key: s.key }; });
|
|
220
329
|
```
|
|
221
|
-
4. **Font ailesi:** Kütüphane dosyasındaki `Font Ailesi` alanından oku. Bulunamazsa
|
|
330
|
+
4. **Font ailesi:** Kütüphane dosyasındaki `Font Ailesi` alanından oku. Bulunamazsa DS text style'larından font bilgisini çıkar. Kullanıcıya sor. Kullanıcı "sen seç" derse VE DS fontu bulunamadıysa `Inter` kullan.
|
|
222
331
|
|
|
223
332
|
Bu adımda toplanan key'ler, sonraki adımlarda `importVariableByKeyAsync` ile hedef dosyaya import edilecek.
|
|
224
333
|
|
|
334
|
+
### Step 3.5: Clone Tool'u Tuzağı — Ne Zaman Clone, Ne Zaman Sıfırdan İnşa (v1.8.2+ ZORUNLU)
|
|
335
|
+
|
|
336
|
+
`figma_clone_screen_to_device` tool'u v1.8.1'de eklendi ama **sadece dar bir use-case için** kullanılmalıdır. Yanlış kullanım, benchmark'ın mevcut yanlışlıklarını (hardcoded rectangle, eksik token binding, non-responsive layout) kopyalayarak disiplin ihlaline yol açar.
|
|
337
|
+
|
|
338
|
+
#### Karar Matrisi
|
|
339
|
+
|
|
340
|
+
| Kullanıcı isteği | Doğru yaklaşım | Tool |
|
|
341
|
+
|---|---|---|
|
|
342
|
+
| "Aynı ekranı iPhone 17'ye migrate et" (sadece boyut değişir) | Clone | `figma_clone_screen_to_device` |
|
|
343
|
+
| "Aynı DS ile benzer ekran" (tek varyant) | Clone + validate | `figma_clone_screen_to_device` + Step 6.5 |
|
|
344
|
+
| **"3 farklı alternatif tasarım"** | **Build from scratch** ⭐ | `figma_execute` + Step 4-5 |
|
|
345
|
+
| **"Hero Card varyasyonu yap"** | **Build from scratch** | `figma_execute` + Step 4-5 |
|
|
346
|
+
| **"Yeni ekran sıfırdan"** | **Build from scratch** | `figma_execute` + Step 4-5 |
|
|
347
|
+
| **"Benchmark'tan ilham al, daha iyisini yap"** | **Build from scratch** (benchmark = inspiration only) | `figma_execute` + Step 4-5 |
|
|
348
|
+
| "Mevcut ekranda DS uyumunu düzelt" | Apply-DS workflow | `apply-figma-design-system` SKILL |
|
|
349
|
+
|
|
350
|
+
#### Kullanıcının Gerçek İstediği Nedir?
|
|
351
|
+
|
|
352
|
+
Kullanıcı "3 alternatif tasarım" dediğinde **neredeyse her zaman** istediği:
|
|
353
|
+
- Farklı layout/renk/tipografi yaklaşımları
|
|
354
|
+
- Her biri gerçekten **AYRI** (sadece isim değil, içerik de)
|
|
355
|
+
- Hepsinde DS uyumu (instance + token binding)
|
|
356
|
+
- Hepsi responsive (auto-layout + FILL sizing)
|
|
357
|
+
|
|
358
|
+
Bu **clone'un kapsamında DEĞİL**. Clone sadece "kopyala, isim değiştir" yapar. Sonuçta **3 identik kopya** + farklı isimler olur. Bu kullanıcının istediği **GERÇEK varyasyon değildir**.
|
|
359
|
+
|
|
360
|
+
#### Doğru Akış: Build-from-Scratch (Step 4-5)
|
|
361
|
+
|
|
362
|
+
Benchmark varsa:
|
|
363
|
+
1. **Step 3.x'te benchmark'ı `figma_get_design_context` ile OKU** — yapısal anlayış için
|
|
364
|
+
2. Benchmark'ta kullanılan SUI instance'ları not al (NavigationTopBar, PillTabs, vb.)
|
|
365
|
+
3. Benchmark'ta **yanlış olan şeyleri kopyalama**:
|
|
366
|
+
- Hardcoded rectangle separator'lar → DS Divider component kullan
|
|
367
|
+
- Non-responsive iç frame'ler → auto-layout FILL'e çevir
|
|
368
|
+
- Missing token bindings → her yerde `setBoundVariable*` kullan
|
|
369
|
+
4. **Step 4 + Step 5 akışını takip et** — sıfırdan, SUI kurallarıyla
|
|
370
|
+
5. Her alternatif için benzersiz layout çözümü:
|
|
371
|
+
- Hero Card: bakiye kartı büyütülmüş, quick actions altta sade
|
|
372
|
+
- Liste Odaklı: hesap listesi dominant, özet sağ-altta
|
|
373
|
+
- Dark Header: root fill `Global/primary/default`, text'ler `on-primary` token
|
|
374
|
+
6. Step 6.5 validate → skor ≥ 80
|
|
375
|
+
|
|
376
|
+
#### Kısıtlama Kuralı
|
|
377
|
+
|
|
378
|
+
**Kullanıcı şu kelimelerden birini kullandıysa → `figma_clone_screen_to_device` KULLANMA:**
|
|
379
|
+
- "alternatif", "varyasyon", "farklı", "yeni", "tasarla", "iyileştir", "redesign"
|
|
380
|
+
|
|
381
|
+
Intent Router bu kelimeleri algıladığında `approach = build-from-scratch` otomatik set eder ve Claude'u Step 4-5 rotasına yönlendirir.
|
|
382
|
+
|
|
225
383
|
### Step 4: Boş Alan Bul ve Wrapper Frame Oluştur
|
|
226
384
|
|
|
227
385
|
```js
|
|
@@ -409,6 +567,44 @@ Screen: VERTICAL, counterAxis=CENTER, layoutSizingVertical=HUG
|
|
|
409
567
|
|
|
410
568
|
**Mode adı eşleşmesi DİKKAT:** `indexOf("Web")` "Mobil & Web Mobil"i de yakalar. `indexOf("Desktop")` kullan.
|
|
411
569
|
|
|
570
|
+
### Step 5.17: Quality Gate — Her Bölüm Yazıldıktan Sonra (ZORUNLU — v1.8.2+)
|
|
571
|
+
|
|
572
|
+
Her bölüm (`figma.createFrame()` sonrası) için **aşağıdaki checklist ZORUNLU**. Herhangi biri ❌ ise → bölümü **yeniden yaz**. Claude bu checklist'i kendi kendine uygulamakla yükümlüdür.
|
|
573
|
+
|
|
574
|
+
```
|
|
575
|
+
[ ] Frame'in layoutMode'u atandı mı? (ASLA "NONE" olmamalı — HORIZONTAL veya VERTICAL)
|
|
576
|
+
[ ] primaryAxisSizingMode doğru mu? (Hug: AUTO, Fixed width: FIXED)
|
|
577
|
+
[ ] counterAxisSizingMode doğru mu?
|
|
578
|
+
[ ] Tüm fills setBoundVariableForPaint ile DS token'a bağlı mı? (hardcoded SOLID YASAK)
|
|
579
|
+
[ ] Tüm padding (top/bottom/left/right) setBoundVariable ile DS spacing token'a bağlı mı?
|
|
580
|
+
[ ] itemSpacing setBoundVariable ile DS spacing token'a bağlı mı?
|
|
581
|
+
[ ] cornerRadius (varsa) setBoundVariable ile DS radius token'a bağlı mı?
|
|
582
|
+
[ ] Her text node setTextStyleIdAsync ile DS text style'a bağlı mı? (ASLA sadece fontSize hardcoded)
|
|
583
|
+
[ ] Text fills setBoundVariableForPaint ile DS text color token'a bağlı mı?
|
|
584
|
+
[ ] Bölüm içinde en az 1 DS INSTANCE var mı? (importComponentByKeyAsync ile).
|
|
585
|
+
İstisna: Sadece text + frame olan bölümler (ör. başlık row) — bu durumda yine spacing/padding/renk token'ları zorunlu.
|
|
586
|
+
[ ] Tüm child'lar appendChild sonrası layoutSizingHorizontal = "FILL" mi? (text istisna: HUG)
|
|
587
|
+
[ ] Hiçbir node'un fills'i raw hex literal ile atandı mı? (grep: `{r:`, `color:` literal)
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
**Otomatik kontrol örneği:**
|
|
591
|
+
|
|
592
|
+
```js
|
|
593
|
+
// Her createFrame sonrası Claude bu kontrolü yapar:
|
|
594
|
+
if (frame.layoutMode === "NONE") throw new Error("Quality Gate FAIL: NO_AUTO_LAYOUT");
|
|
595
|
+
if (!frame.boundVariables || !frame.boundVariables.paddingLeft) {
|
|
596
|
+
console.warn("Quality Gate WARN: padding token binding eksik");
|
|
597
|
+
}
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
**Quality Gate FAIL olursa ne yap?**
|
|
601
|
+
1. Bölümü sil: `frame.remove()`
|
|
602
|
+
2. Eksik token/instance'ı `figma_search_assets` + `figma_get_library_variables` ile ara
|
|
603
|
+
3. Bölümü **yeniden yaz** — bu sefer tüm kuralları uyarak
|
|
604
|
+
4. Tekrar kontrol et
|
|
605
|
+
|
|
606
|
+
**Skor hedef:** `figma_validate_screen` sonrası ≥ 80 (Step 6.5). Quality Gate çalışırsa validate zaten geçer.
|
|
607
|
+
|
|
412
608
|
### Step 5.2: Instance Override Rehberi (ZORUNLU)
|
|
413
609
|
|
|
414
610
|
**Component PROPERTY (TEXT/BOOLEAN/VARIANT tipi) → `setProperties`:**
|
|
@@ -469,6 +665,56 @@ Estetik yön belirlendiyse (Step 2.5), bölüm inşa sırasında şu detaylar ek
|
|
|
469
665
|
|
|
470
666
|
> **NOT:** Bu öneriler DS bileşen kütüphanesi varsa DS'nin izin verdiği ölçüde uygulanır. DS token'ları dışında hardcoded değer eklenmez.
|
|
471
667
|
|
|
668
|
+
### Step 5.6: Dark Mode / Theme Variants Workflow (ZORUNLU — v1.9.0+)
|
|
669
|
+
|
|
670
|
+
Intent router `variants` input'unda "Light + Dark mode" seçildiyse (veya kullanıcı açıkça dark+light istiyorsa), Step 6'ya geçmeden önce bu alt adımı uygula.
|
|
671
|
+
|
|
672
|
+
**Ön koşul:** DS'de theme modlar tanımlı bir variable collection var. SUI için tipik: `Colors` collection + `Light` mode + `Dark` mode.
|
|
673
|
+
|
|
674
|
+
**Akış (4 adım):**
|
|
675
|
+
|
|
676
|
+
1. **Light ekranı doğrula (Step 5 sonu):** Wrapper frame ID'sini al. Tüm fill/stroke/background'lar `setBoundVariableForPaint` ile bağlı olmalı (Step 5.17 Quality Gate zaten sağladı). Eğer hardcoded değer varsa Step 5'e dön, düzelt.
|
|
677
|
+
|
|
678
|
+
2. **Klon oluştur:**
|
|
679
|
+
```javascript
|
|
680
|
+
// figma_execute
|
|
681
|
+
const lightFrame = await figma.getNodeByIdAsync("<wrapper_id>");
|
|
682
|
+
const darkFrame = lightFrame.clone();
|
|
683
|
+
figma.currentPage.appendChild(darkFrame);
|
|
684
|
+
darkFrame.x = lightFrame.x + lightFrame.width + 80; // sağda, 80px boşluk
|
|
685
|
+
darkFrame.name = lightFrame.name + " — Dark";
|
|
686
|
+
return { darkFrameId: darkFrame.id };
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
3. **Dark mode'u klon frame'e uygula:**
|
|
690
|
+
```javascript
|
|
691
|
+
// figma_execute (ayrı çağrı)
|
|
692
|
+
const collections = await figma.variables.getLocalVariableCollectionsAsync();
|
|
693
|
+
const colorCol = collections.find(c => c.name === "Colors" || c.name.toLowerCase().includes("color"));
|
|
694
|
+
if (!colorCol) throw new Error("Theme collection bulunamadı — DS'de mode tanımlı değil");
|
|
695
|
+
const darkMode = colorCol.modes.find(m => m.name.toLowerCase().includes("dark"));
|
|
696
|
+
if (!darkMode) throw new Error("Dark mode bulunamadı — DS tek modlu");
|
|
697
|
+
|
|
698
|
+
const darkFrame = await figma.getNodeByIdAsync("<darkFrameId>");
|
|
699
|
+
darkFrame.setExplicitVariableModeForCollection(colorCol, darkMode.modeId);
|
|
700
|
+
return { status: "dark mode applied", mode: darkMode.name };
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
**Sihir burada:** `setExplicitVariableModeForCollection` ile tüm bound variable'lar otomatik olarak dark mode değerleri kullanır. Manuel swap gerekmez — tek bir API çağrısı tüm renkleri günceller. **Bu yüzden Step 5.17'de her fill/stroke mutlaka variable'a bağlı olmalı** — hardcoded kalanlar dark mode'da güncellenmez, light rengini taşır.
|
|
704
|
+
|
|
705
|
+
4. **Her iki frame'i ayrı validate et:**
|
|
706
|
+
```javascript
|
|
707
|
+
figma_validate_screen(nodeId: <lightFrameId>, minScore: 80)
|
|
708
|
+
figma_validate_screen(nodeId: <darkFrameId>, minScore: 80)
|
|
709
|
+
```
|
|
710
|
+
İkisi de ≥80 olmalı. Biri fail ederse hardcoded değerler kaldı demektir — Step 5.17 Quality Gate'e dön.
|
|
711
|
+
|
|
712
|
+
**Edge case:** DS'de dark mode yoksa (sadece light), `variants: "Light + Dark"` seçimi kullanıcıya hata raporla: "Aktif DS'de dark mode tanımlı değil, sadece light üretildi. Dark mode için DS'nin `Colors` collection'ında `Dark` modu eklenmelidir."
|
|
713
|
+
|
|
714
|
+
**Responsive + theme kombinasyonu:** `variants: ["Light + Dark", "Mobile + Web"]` seçilirse matris oluşur (Light+Mobile / Light+Web / Dark+Mobile / Dark+Web = 4 frame). Her biri için ayrı wrapper, ayrı mode/device binding, ayrı validate. Turn budget'e dikkat — 4 frame için 4 turn harca (inter-screen checkpoint gate Step 6.6).
|
|
715
|
+
|
|
716
|
+
**Known limitation:** `figma_validate_screen` skorlama algoritması **dark mode variable binding coverage'ını ayrıca ölçmez** (plugin-side: f-mcp-plugin/code.js). Dark frame'de hardcoded renk kalmış olsa bile skor ≥80 alabilir. Bu yüzden Step 5.17 Quality Gate ve Step 5.6 adım 4'teki manuel binding kontrolü zorunludur — scora tek başına güvenme.
|
|
717
|
+
|
|
472
718
|
### Step 6: Görsel Doğrulama
|
|
473
719
|
|
|
474
720
|
```
|
|
@@ -489,6 +735,123 @@ Screenshot'ı incele:
|
|
|
489
735
|
|
|
490
736
|
Sorun varsa hedefli `figma_execute` ile düzelt.
|
|
491
737
|
|
|
738
|
+
### Step 6.5: Self-Audit Mandate (ZORUNLU — v1.8.1+)
|
|
739
|
+
|
|
740
|
+
**Ekranı kullanıcıya sunmadan ÖNCE kendi kendini denetle.** Bu adım **atlanamaz** — screenshot yeterli değil çünkü Claude görsel olarak "güzel" görünen ama token/bileşen disiplininden uzak ekranları fark edemez.
|
|
741
|
+
|
|
742
|
+
#### Adım 1 — `figma_validate_screen` çağır
|
|
743
|
+
|
|
744
|
+
```
|
|
745
|
+
figma_validate_screen(nodeId="wrapper-frame-id", expectedDs="❖ SUI", minScore=80)
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
Tool şunu döner:
|
|
749
|
+
```json
|
|
750
|
+
{
|
|
751
|
+
"score": 92,
|
|
752
|
+
"passed": true,
|
|
753
|
+
"minScore": 80,
|
|
754
|
+
"breakdown": {
|
|
755
|
+
"instanceCoverage": 85,
|
|
756
|
+
"libraryInstanceCount": 7,
|
|
757
|
+
"autoLayoutCoverage": 100,
|
|
758
|
+
"tokenBindingCoverage": 90
|
|
759
|
+
},
|
|
760
|
+
"violations": [],
|
|
761
|
+
"recommendation": "Score 92/100 passed minimum 80. Screen is DS-compliant."
|
|
762
|
+
}
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
#### Adım 2 — Skor değerlendirmesi
|
|
766
|
+
|
|
767
|
+
| Skor | Karar | Davranış |
|
|
768
|
+
|---|---|---|
|
|
769
|
+
| **≥ 80** | ✅ Passed | Kullanıcıya sun, rapor et |
|
|
770
|
+
| **60-79** | ⚠️ Kısmi | Violations listesini oku, targeted fix'ler uygula, tekrar validate et |
|
|
771
|
+
| **< 60** | ❌ Failed | **Ekranı sil** (`figma_execute` → `node.remove()`), Step 3-5'e dön, DS bileşenleriyle yeniden inşa et |
|
|
772
|
+
|
|
773
|
+
#### Adım 3 — Retry Loop (max 3 deneme)
|
|
774
|
+
|
|
775
|
+
Eğer ilk denemede score < 80 ise:
|
|
776
|
+
1. Violations listesini oku (en kritik 5'i)
|
|
777
|
+
2. Her bir violation için `figma_execute` ile targeted fix uygula:
|
|
778
|
+
- `HARDCODED_FILL` → `figma_bind_variable` ile binding ekle
|
|
779
|
+
- `NO_AUTO_LAYOUT` → `layoutMode = "VERTICAL"` ekle
|
|
780
|
+
3. Tekrar `figma_validate_screen` çağır
|
|
781
|
+
4. **Max 3 deneme.** 3. denemede de fail ise:
|
|
782
|
+
- Ekranı sil
|
|
783
|
+
- Kullanıcıya rapor et: "3 denemede de minimum skoru yakalayamadım. Muhtemel sebepler: [list]. Elle düzeltmek mi, farklı yaklaşım mı denemek istersiniz?"
|
|
784
|
+
|
|
785
|
+
#### Adım 4 — Pass sonrası raporlama
|
|
786
|
+
|
|
787
|
+
Validation passed ise kullanıcıya özet çıkar:
|
|
788
|
+
```
|
|
789
|
+
✅ Ekran hazır: "Vadesiz TL - iPhone 17"
|
|
790
|
+
📊 DS Compliance Score: 92/100
|
|
791
|
+
🧩 Library Instances: 7
|
|
792
|
+
🎨 Token Bindings: 24
|
|
793
|
+
📐 Auto-Layout Coverage: 100%
|
|
794
|
+
⏱️ Süre: 18 saniye
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
#### Anti-patterns (Self-Audit atlamak)
|
|
798
|
+
|
|
799
|
+
❌ **YANLIŞ:** "Screenshot güzel görünüyor, validate'e gerek yok" → Bu bir **disiplin kaçırmasıdır**
|
|
800
|
+
✅ **DOĞRU:** Screenshot güzel olsa bile validate çalıştır. Token binding eksikliği gözle görülmez.
|
|
801
|
+
|
|
802
|
+
❌ **YANLIŞ:** Score 75 → "yeterince iyi, kullanıcıya sun"
|
|
803
|
+
✅ **DOĞRU:** Score < 80 → retry loop, ekranı düzelt
|
|
804
|
+
|
|
805
|
+
❌ **YANLIŞ:** Self-audit'i opsiyonel sayma
|
|
806
|
+
✅ **DOĞRU:** generate-figma-screen akışının **tamamlanma koşulu** bu adımdır. Validate çalıştırılmadan akış TAMAMLANMIŞ sayılmaz.
|
|
807
|
+
|
|
808
|
+
### Step 6.6: Inter-Screen Checkpoint Gate + Turn Budget (ZORUNLU — v1.8.2+)
|
|
809
|
+
|
|
810
|
+
Kullanıcı birden fazla alternatif istediğinde (N > 1), her alternatif **ayrı bir turn** olmalıdır. Tek turn'de 2+ alternatif yapmak **YASAK** — tool-use limit'e takılır, chat donar.
|
|
811
|
+
|
|
812
|
+
#### Turn Budget Kuralı
|
|
813
|
+
|
|
814
|
+
**Her turn'ün bütçesi:**
|
|
815
|
+
- Maksimum **90 saniye** toplam süre
|
|
816
|
+
- Maksimum **2 başarısız tool call** (timeout/error)
|
|
817
|
+
|
|
818
|
+
Eğer turn içinde:
|
|
819
|
+
- 2 başarısız tool call (timeout/error) olursa, **VEYA**
|
|
820
|
+
- 60+ saniye geçti ve sonuç gelmediyse
|
|
821
|
+
|
|
822
|
+
→ **Turn'ü "FAILED" olarak işaretle.** Orphan cleanup uygula (fmcp-intent-router Tool Failure Recovery Protocol). Kullanıcıya checkpoint sorusunu sor.
|
|
823
|
+
|
|
824
|
+
#### Checkpoint Gate (Her Turn Sonrası)
|
|
825
|
+
|
|
826
|
+
Alternatif N tamamlandığında (başarılı veya fail), kullanıcıya `AskUserQuestion` ile sor:
|
|
827
|
+
|
|
828
|
+
```
|
|
829
|
+
✅/⚠️ Alternatif N/M ({name}) tamamlandı
|
|
830
|
+
Node ID: 173:xxxxx
|
|
831
|
+
Skor: XX/100
|
|
832
|
+
Library instances: X
|
|
833
|
+
Token bindings: Y
|
|
834
|
+
Süre: Xs
|
|
835
|
+
|
|
836
|
+
Ne yapayım?
|
|
837
|
+
[✅ Beğendim, Alternatif N+1'e geç]
|
|
838
|
+
[✏️ Revize et (ne değişsin söyle)]
|
|
839
|
+
[🛑 Dur, bu yeter]
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
**Kullanıcı yanıtı gelmeden bir sonraki alternatife GEÇME.** Turn boundary kuralı budur.
|
|
843
|
+
|
|
844
|
+
#### Yasaklar
|
|
845
|
+
|
|
846
|
+
❌ **YANLIŞ:** Tek turn'de 3 alternatifi de yap, en sonda tek özet
|
|
847
|
+
✅ **DOĞRU:** Her alternatif ayrı turn, her biri sonunda checkpoint
|
|
848
|
+
|
|
849
|
+
❌ **YANLIŞ:** Turn içinde 3+ retry (sonsuz döngü)
|
|
850
|
+
✅ **DOĞRU:** 2 retry max, sonra Turn FAILED + kullanıcıya sor
|
|
851
|
+
|
|
852
|
+
❌ **YANLIŞ:** Alternatif N başarısız, sessizce N+1'e geç
|
|
853
|
+
✅ **DOĞRU:** N başarısız olunca orphan cleanup + rapor + checkpoint
|
|
854
|
+
|
|
492
855
|
### Step 7: Güncelleme Senaryosu
|
|
493
856
|
|
|
494
857
|
Mevcut bir ekranı güncellerken:
|
|
@@ -5,6 +5,38 @@ metadata:
|
|
|
5
5
|
mcp-server: user-figma-mcp-bridge
|
|
6
6
|
personas:
|
|
7
7
|
- uidev
|
|
8
|
+
required_inputs:
|
|
9
|
+
- name: source_node_id
|
|
10
|
+
type: string
|
|
11
|
+
question: "Hangi Figma node'unu kodlayalım? (node ID veya Figma URL)"
|
|
12
|
+
required: true
|
|
13
|
+
- name: target_platform
|
|
14
|
+
type: enum
|
|
15
|
+
options:
|
|
16
|
+
- "iOS (SwiftUI)"
|
|
17
|
+
- "iOS (UIKit)"
|
|
18
|
+
- "Android (Jetpack Compose)"
|
|
19
|
+
- "Android (XML)"
|
|
20
|
+
- "Web (React + TypeScript)"
|
|
21
|
+
- "Web (Vue)"
|
|
22
|
+
- "Web (vanilla HTML/CSS)"
|
|
23
|
+
question: "Hangi platform için kod üretelim?"
|
|
24
|
+
required: true
|
|
25
|
+
- name: output_dir
|
|
26
|
+
type: string
|
|
27
|
+
question: "Kod nereye yazılsın? (örn: ./src/components veya 'chat' - çıktıyı inline göster)"
|
|
28
|
+
required: false
|
|
29
|
+
default: "chat"
|
|
30
|
+
- name: include_tests
|
|
31
|
+
type: boolean
|
|
32
|
+
question: "Unit test dosyaları da üretilsin mi?"
|
|
33
|
+
required: false
|
|
34
|
+
default: false
|
|
35
|
+
- name: use_existing_components
|
|
36
|
+
type: boolean
|
|
37
|
+
question: "Mevcut proje component'lerini kullanıp genişleteyim mi, yoksa sıfırdan mı?"
|
|
38
|
+
required: false
|
|
39
|
+
default: true
|
|
8
40
|
---
|
|
9
41
|
|
|
10
42
|
# Implement Design (Multi-Platform)
|