@su-record/vibe 2.8.7 → 2.8.8
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/commands/vibe.figma.md +172 -84
- package/package.json +1 -1
package/commands/vibe.figma.md
CHANGED
|
@@ -1,57 +1,84 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Figma design to code — extract + generate in one step
|
|
3
|
-
argument-hint: "
|
|
3
|
+
argument-hint: ""
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# /vibe.figma
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Figma 디자인 + 스토리보드 → 프로덕션 코드. 인터랙티브 방식으로 URL을 입력받아 처리.
|
|
9
9
|
|
|
10
10
|
## Usage
|
|
11
11
|
|
|
12
12
|
```
|
|
13
|
-
/vibe.figma
|
|
14
|
-
/vibe.figma
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
/vibe.figma # 인터랙티브 모드 (URL 입력 프롬프트)
|
|
14
|
+
/vibe.figma --new # 새 피처 모드 (기존 디자인 시스템 무시)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
커맨드 실행 시 아래 순서로 사용자에게 질문:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
1. 📋 스토리보드 URL이 있나요? (선택)
|
|
21
|
+
→ 브레이크포인트, 인터랙션, 애니메이션 스펙 추출
|
|
22
|
+
→ 없으면 Enter (디폴트 브레이크포인트 사용)
|
|
23
|
+
|
|
24
|
+
2. 🎨 디자인 URL을 입력해주세요. (필수, 복수 가능)
|
|
25
|
+
→ 1개: 단일 디자인
|
|
26
|
+
→ 2개 이상: 반응형 (프레임 width로 mobile/desktop 자동 감지)
|
|
27
|
+
→ 각 URL은 줄바꿈 또는 공백으로 구분
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 입력 예시
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
📋 스토리보드 URL (선택, 없으면 Enter):
|
|
34
|
+
> https://www.figma.com/design/ABC/Storyboard?node-id=1-109
|
|
35
|
+
|
|
36
|
+
🎨 디자인 URL (필수, 복수 시 줄바꿈):
|
|
37
|
+
> https://www.figma.com/design/ABC/Design?node-id=10-200
|
|
38
|
+
> https://www.figma.com/design/ABC/Design?node-id=10-500
|
|
17
39
|
```
|
|
18
40
|
|
|
19
41
|
### Generation Mode
|
|
20
42
|
|
|
21
|
-
|
|
|
22
|
-
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
43
|
+
| Mode | 조건 | 동작 |
|
|
44
|
+
|------|------|------|
|
|
45
|
+
| **Project integration** | 기본값 | 기존 디자인 시스템/토큰 활용, 프로젝트 컨벤션 준수 |
|
|
46
|
+
| **--new** | 플래그 지정 시 | 자체 완결 토큰 + 컴포넌트, 기존 디자인 시스템 무관 |
|
|
47
|
+
| **Responsive** | 디자인 URL 2개 이상 | 자동 감지, fluid clamp() + @media 생성 |
|
|
26
48
|
|
|
27
|
-
###
|
|
49
|
+
### 스토리보드에서 추출하는 정보
|
|
28
50
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
51
|
+
| 항목 | 활용 Phase |
|
|
52
|
+
|------|-----------|
|
|
53
|
+
| 브레이크포인트 / 해상도 가이드 | Phase 3 (breakpoints 오버라이드) |
|
|
54
|
+
| 인터랙션 스펙 (호버, 클릭, 스크롤) | Phase 6 (이벤트 핸들러 + CSS states) |
|
|
55
|
+
| 애니메이션 스펙 (타이밍, 이징) | Phase 6 (transition/animation) |
|
|
56
|
+
| 상태별 UI (로딩, 에러, 성공, 빈 상태) | Phase 6 (조건부 렌더링) |
|
|
57
|
+
| 반응형 동작 설명 | Phase 6-3 (responsive 코드) |
|
|
58
|
+
| 컬러/타이포 가이드 | Phase 4 (토큰 생성) |
|
|
59
|
+
| 컴포넌트 명세 | Phase 5 (마크업 구조) |
|
|
34
60
|
|
|
35
|
-
|
|
61
|
+
### File Reading Policy
|
|
36
62
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
63
|
+
**스토리보드 있을 때:**
|
|
64
|
+
1. 스토리보드 `get_metadata` → 전체 프레임 목록 파악
|
|
65
|
+
2. 관련 섹션별 `get_design_context` → 스펙 정보 추출
|
|
66
|
+
3. 디자인 URL별 `get_design_context` + `get_screenshot` → 비주얼 + 코드
|
|
40
67
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
68
|
+
**스토리보드 없을 때:**
|
|
69
|
+
1. 디자인 URL별 `get_design_context` + `get_screenshot` → 비주얼 + 코드
|
|
70
|
+
2. 디폴트 브레이크포인트 적용
|
|
44
71
|
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
72
|
+
**항상:**
|
|
73
|
+
- `.claude/vibe/config.json` → 프로젝트 스택
|
|
74
|
+
- `.claude/vibe/design-context.json` → 브랜드, 토큰, 테마
|
|
75
|
+
- 기존 코드 스캔 → 컴포넌트 패턴, 디자인 시스템
|
|
49
76
|
|
|
50
77
|
## Context Reset
|
|
51
78
|
|
|
52
|
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
79
|
+
**이 커맨드 실행 시 이전 대화 무시.**
|
|
80
|
+
- Figma 데이터 + 프로젝트 스택 기반으로 판단
|
|
81
|
+
- 스토리보드 스펙이 디자인과 충돌 시 → 스토리보드 우선
|
|
55
82
|
|
|
56
83
|
---
|
|
57
84
|
|
|
@@ -94,89 +121,139 @@ Post — 코드 리뷰:
|
|
|
94
121
|
Codex 미설치 시 자동 스킵 — Claude만으로 순차 생성.
|
|
95
122
|
```
|
|
96
123
|
|
|
97
|
-
## Phase 0: Figma Data Extraction
|
|
124
|
+
## Phase 0: URL 입력 + Figma Data Extraction
|
|
98
125
|
|
|
99
|
-
|
|
126
|
+
### 0-0. 사용자 입력 수집
|
|
100
127
|
|
|
101
|
-
|
|
128
|
+
아래 순서로 사용자에게 질문 (AskUserQuestion 사용):
|
|
102
129
|
|
|
103
|
-
|
|
130
|
+
```
|
|
131
|
+
Step 1:
|
|
132
|
+
"📋 스토리보드 URL이 있나요? (없으면 Enter)"
|
|
133
|
+
→ 입력됨: storyboardUrl 저장
|
|
134
|
+
→ 빈 입력: storyboardUrl = null
|
|
104
135
|
|
|
105
|
-
|
|
136
|
+
Step 2:
|
|
137
|
+
"🎨 디자인 URL을 입력해주세요. (복수 입력 시 반응형 처리됩니다)"
|
|
138
|
+
→ 1개: designUrls = [url]
|
|
139
|
+
→ 2개+: designUrls = [url1, url2, ...] → responsive mode
|
|
106
140
|
|
|
141
|
+
Step 3 (--new 미지정 시):
|
|
142
|
+
프로젝트에 기존 디자인 시스템이 있는지 자동 감지
|
|
143
|
+
→ 있으면: default mode (기존 토큰 활용)
|
|
144
|
+
→ 없으면: 자동으로 --new mode
|
|
107
145
|
```
|
|
108
|
-
https://www.figma.com/design/:fileKey/:fileName?node-id=:nodeId
|
|
109
|
-
→ fileKey, nodeId (하이픈을 콜론으로: "110-6231" → "110:6231")
|
|
110
|
-
```
|
|
111
146
|
|
|
112
|
-
|
|
147
|
+
### 0-1. 스토리보드 추출 (storyboardUrl이 있을 때)
|
|
148
|
+
|
|
149
|
+
스토리보드에서 **구현 스펙**을 먼저 추출. 이후 Phase에서 참조.
|
|
113
150
|
|
|
114
151
|
```
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
152
|
+
URL에서 fileKey, nodeId 추출:
|
|
153
|
+
https://www.figma.com/design/:fileKey/:fileName?node-id=:nodeId
|
|
154
|
+
→ nodeId: 하이픈을 콜론으로 ("1-109" → "1:109")
|
|
155
|
+
|
|
156
|
+
1. get_metadata(fileKey, nodeId) → 전체 프레임 목록 (섹션 파악)
|
|
157
|
+
2. 관련 섹션별 get_design_context:
|
|
158
|
+
- "해상도 대응" / "Media Query" → 브레이크포인트
|
|
159
|
+
- "인터랙션" / "Interaction" → 호버/클릭/스크롤 스펙
|
|
160
|
+
- "애니메이션" / "Animation" / "Motion" → 트랜지션 스펙
|
|
161
|
+
- "상태" / "State" → 로딩/에러/성공 UI
|
|
162
|
+
- "컬러" / "Color" / "타이포" / "Typography" → 디자인 가이드
|
|
163
|
+
|
|
164
|
+
결과 → storyboardSpec 객체에 저장:
|
|
165
|
+
{
|
|
166
|
+
breakpoints: { ... }, // 브레이크포인트 오버라이드
|
|
167
|
+
interactions: [ ... ], // 인터랙션 목록
|
|
168
|
+
animations: [ ... ], // 애니메이션 스펙
|
|
169
|
+
states: [ ... ], // UI 상태 목록
|
|
170
|
+
colorGuide: { ... }, // 컬러 가이드
|
|
171
|
+
typographyGuide: { ... } // 타이포 가이드
|
|
172
|
+
}
|
|
118
173
|
```
|
|
119
174
|
|
|
120
|
-
|
|
175
|
+
### 0-2. 디자인 추출 (MCP)
|
|
176
|
+
|
|
177
|
+
각 디자인 URL에 대해 MCP로 추출:
|
|
121
178
|
|
|
122
179
|
```
|
|
123
|
-
|
|
124
|
-
|
|
180
|
+
URL에서 fileKey, nodeId 추출 (동일 방식)
|
|
181
|
+
|
|
182
|
+
각 URL에 대해:
|
|
183
|
+
1. get_design_context(fileKey, nodeId) → 코드 + 스크린샷 + 메타데이터 + 에셋 URL
|
|
184
|
+
2. get_metadata(fileKey, nodeId) → 레이어 구조 (XML)
|
|
185
|
+
3. get_screenshot(fileKey, nodeId) → 프레임 이미지
|
|
186
|
+
|
|
187
|
+
디자인 URL이 2개 이상이면:
|
|
188
|
+
→ 프레임 width로 viewport 자동 감지 (mobile/tablet/desktop)
|
|
189
|
+
→ responsive mode 진입
|
|
125
190
|
```
|
|
126
191
|
|
|
127
|
-
### 0-
|
|
192
|
+
### 0-3. Image Asset Download (BLOCKING — 코드 생성 전 반드시 완료)
|
|
193
|
+
|
|
194
|
+
> **⛔ 이 단계를 건너뛰면 안 됨.** 이미지 다운로드가 완료되지 않으면 Phase 6 코드 생성으로 진행하지 않는다.
|
|
128
195
|
|
|
129
|
-
`get_design_context` 응답에 포함된 이미지 에셋 URL
|
|
130
|
-
|
|
196
|
+
`get_design_context` 응답에 포함된 이미지 에셋 URL은 **7일 후 만료**되는 임시 URL.
|
|
197
|
+
**즉시 다운로드**하여 프로젝트에 저장해야 함.
|
|
131
198
|
|
|
132
|
-
|
|
199
|
+
**Step 1: 에셋 URL 수집**
|
|
133
200
|
|
|
134
|
-
`get_design_context`
|
|
201
|
+
`get_design_context` 응답에서 모든 이미지 URL 추출:
|
|
135
202
|
```
|
|
136
|
-
|
|
203
|
+
패턴: https://www.figma.com/api/mcp/asset/...
|
|
204
|
+
코드에 const xxxImage = 'https://...' 형태로 포함됨
|
|
137
205
|
```
|
|
138
206
|
|
|
139
|
-
|
|
207
|
+
**Step 2: 다운로드 + 저장**
|
|
140
208
|
|
|
141
209
|
```
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
5. 생성된 코드에서 임시 URL을 로컬 경로로 교체:
|
|
152
|
-
- 'https://www.figma.com/api/mcp/asset/...' → '/images/{feature}/hero-background.webp'
|
|
210
|
+
각 URL에 대해:
|
|
211
|
+
1. WebFetch로 다운로드
|
|
212
|
+
2. 프로젝트 에셋 디렉토리에 저장:
|
|
213
|
+
- Nuxt: static/images/{feature}/ 또는 public/images/{feature}/
|
|
214
|
+
- Next.js: public/images/{feature}/
|
|
215
|
+
- React: public/images/{feature}/
|
|
216
|
+
3. 파일명은 레이어 이름 기반 (kebab-case):
|
|
217
|
+
- "Hero Background" → hero-background.webp
|
|
218
|
+
- "Product Photo 1" → product-photo-1.webp
|
|
153
219
|
```
|
|
154
220
|
|
|
155
|
-
**
|
|
221
|
+
**Step 3: URL → 로컬 경로 매핑 테이블 생성**
|
|
156
222
|
|
|
157
223
|
```
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
224
|
+
다운로드 완료 후, 매핑 테이블을 메모리에 보관:
|
|
225
|
+
|
|
226
|
+
| Figma 임시 URL | 로컬 경로 | 레이어 이름 |
|
|
227
|
+
|---------------|----------|-----------|
|
|
228
|
+
| https://figma.com/api/mcp/asset/abc... | /images/winter-pcbang/hero-bg.webp | Hero Background |
|
|
229
|
+
| https://figma.com/api/mcp/asset/def... | /images/winter-pcbang/hero-title.webp | Hero Title |
|
|
230
|
+
|
|
231
|
+
→ Phase 6 코드 생성 시 이 매핑 테이블로 임시 URL을 로컬 경로로 교체
|
|
162
232
|
```
|
|
163
233
|
|
|
164
|
-
|
|
234
|
+
**Step 4: SVG 처리**
|
|
165
235
|
|
|
166
|
-
코드 생성 완료 후, MCP 임시 URL이 코드에 남아있으면 경고:
|
|
167
236
|
```
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
237
|
+
- 벡터 에셋 (아이콘, 로고) → SVG로 다운로드
|
|
238
|
+
- 작은 아이콘 (< 1KB) → 인라인 SVG 컴포넌트
|
|
239
|
+
- 큰 SVG → 파일로 저장
|
|
171
240
|
```
|
|
172
241
|
|
|
173
|
-
### 0-
|
|
242
|
+
### 0-4. Extraction Gate (코드 생성 진행 조건)
|
|
243
|
+
|
|
244
|
+
> **다음 조건을 모두 만족해야 Phase 1로 진행:**
|
|
174
245
|
|
|
175
246
|
```
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
247
|
+
✅ 디자인 URL 최소 1개의 get_design_context 성공
|
|
248
|
+
✅ 디자인 스크린샷 최소 1개 획득
|
|
249
|
+
✅ 이미지 에셋 전부 다운로드 완료 (0개 남은 미다운로드)
|
|
250
|
+
✅ URL→로컬경로 매핑 테이블 생성 완료
|
|
251
|
+
✅ (responsive) 최소 2개 뷰포트의 스크린샷 획득
|
|
252
|
+
|
|
253
|
+
❌ 하나라도 실패 시:
|
|
254
|
+
→ 실패 항목 보고 + 재시도
|
|
255
|
+
→ 이미지 다운로드 실패 시: 해당 URL 재시도 (최대 3회)
|
|
256
|
+
→ 재시도 후에도 실패: 사용자에게 수동 다운로드 요청 후 계속
|
|
180
257
|
```
|
|
181
258
|
|
|
182
259
|
---
|
|
@@ -333,9 +410,9 @@ Breakpoints are loaded from multiple sources in priority order:
|
|
|
333
410
|
|
|
334
411
|
| Priority | Source | How |
|
|
335
412
|
|----------|--------|-----|
|
|
336
|
-
| 1 |
|
|
337
|
-
| 2 |
|
|
338
|
-
| 3 |
|
|
413
|
+
| 1 | **Storyboard** | Phase 0-1에서 추출한 `storyboardSpec.breakpoints` |
|
|
414
|
+
| 2 | **`~/.vibe/config.json`** | `figma.breakpoints` — user-customized via `vibe figma breakpoints --set` |
|
|
415
|
+
| 3 | **Project CSS/Tailwind** | Grep `tailwind.config.*` → `theme.screens`, or `@media.*min-width` patterns in codebase |
|
|
339
416
|
| 4 | **Defaults** | Built-in values (breakpoint: 1024px, etc.) |
|
|
340
417
|
|
|
341
418
|
#### Default Breakpoints (built-in)
|
|
@@ -1030,9 +1107,20 @@ Max props: 5 per component
|
|
|
1030
1107
|
|
|
1031
1108
|
## Phase 6: Code Generation
|
|
1032
1109
|
|
|
1033
|
-
### 6-0. Apply
|
|
1110
|
+
### 6-0. Apply Storyboard Spec + Design Context
|
|
1111
|
+
|
|
1112
|
+
**스토리보드 스펙 (Phase 0-1)이 있으면 우선 적용:**
|
|
1113
|
+
|
|
1114
|
+
| storyboardSpec | Effect on Code Generation |
|
|
1115
|
+
|----------------|--------------------------|
|
|
1116
|
+
| `interactions` | 호버/클릭/스크롤 이벤트 → CSS `:hover`/`:active`/`:focus` + JS 핸들러 |
|
|
1117
|
+
| `animations` | 트랜지션/애니메이션 → `transition`, `@keyframes`, timing/easing 스펙대로 |
|
|
1118
|
+
| `states` | 로딩/에러/성공/빈 상태 → 조건부 렌더링 + 상태별 UI 컴포넌트 |
|
|
1119
|
+
| `breakpoints` | Phase 3-3에서 이미 적용됨 |
|
|
1120
|
+
| `colorGuide` | 스토리보드 컬러 가이드 → 토큰 검증 |
|
|
1121
|
+
| `typographyGuide` | 스토리보드 타이포 가이드 → 토큰 검증 |
|
|
1034
1122
|
|
|
1035
|
-
|
|
1123
|
+
**design-context.json이 있으면 추가 적용:**
|
|
1036
1124
|
|
|
1037
1125
|
| Context Field | Effect on Code Generation |
|
|
1038
1126
|
|---------------|--------------------------|
|