@su-record/vibe 2.8.7 → 2.8.9
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 +186 -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,153 @@ 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으로 하나씩 순서대로 질문.
|
|
129
|
+
**각 질문 후 반드시 사용자 응답을 받은 다음에만 다음 Step으로 진행한다. 응답을 기다리지 않고 넘어가면 안 된다.**
|
|
102
130
|
|
|
103
|
-
|
|
131
|
+
```
|
|
132
|
+
Step 1: 스토리보드 URL (선택)
|
|
133
|
+
→ AskUserQuestion 호출:
|
|
134
|
+
question: "📋 스토리보드 Figma URL을 입력해주세요. (없으면 '없음'이라고 입력)"
|
|
135
|
+
→ ⏸️ 사용자 응답 대기 (반드시 응답을 받은 후 진행)
|
|
136
|
+
→ URL 입력됨: storyboardUrl 저장
|
|
137
|
+
→ "없음" 또는 빈 응답: storyboardUrl = null
|
|
104
138
|
|
|
105
|
-
|
|
139
|
+
Step 2: 디자인 URL (필수)
|
|
140
|
+
→ AskUserQuestion 호출:
|
|
141
|
+
question: "🎨 디자인 Figma URL을 입력해주세요."
|
|
142
|
+
→ ⏸️ 사용자 응답 대기 (반드시 응답을 받은 후 진행)
|
|
143
|
+
→ URL 저장: designUrls = [url]
|
|
106
144
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
145
|
+
Step 3: 추가 디자인 URL (반응형)
|
|
146
|
+
→ AskUserQuestion 호출:
|
|
147
|
+
question: "🎨 반응형용 추가 디자인 URL이 있나요? (없으면 '없음'이라고 입력)"
|
|
148
|
+
→ ⏸️ 사용자 응답 대기 (반드시 응답을 받은 후 진행)
|
|
149
|
+
→ URL 입력됨: designUrls에 추가 → responsive mode
|
|
150
|
+
→ "없음" 또는 빈 응답: single mode
|
|
151
|
+
|
|
152
|
+
Step 4 (--new 미지정 시):
|
|
153
|
+
프로젝트에 기존 디자인 시스템이 있는지 자동 감지
|
|
154
|
+
→ 있으면: default mode (기존 토큰 활용)
|
|
155
|
+
→ 없으면: 자동으로 --new mode
|
|
156
|
+
|
|
157
|
+
⚠️ 절대 Step 1~3을 한 번에 호출하지 않는다.
|
|
158
|
+
Step 1 응답 → Step 2 호출 → Step 2 응답 → Step 3 호출 순서 엄수.
|
|
110
159
|
```
|
|
111
160
|
|
|
112
|
-
|
|
161
|
+
### 0-1. 스토리보드 추출 (storyboardUrl이 있을 때)
|
|
162
|
+
|
|
163
|
+
스토리보드에서 **구현 스펙**을 먼저 추출. 이후 Phase에서 참조.
|
|
113
164
|
|
|
114
165
|
```
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
166
|
+
URL에서 fileKey, nodeId 추출:
|
|
167
|
+
https://www.figma.com/design/:fileKey/:fileName?node-id=:nodeId
|
|
168
|
+
→ nodeId: 하이픈을 콜론으로 ("1-109" → "1:109")
|
|
169
|
+
|
|
170
|
+
1. get_metadata(fileKey, nodeId) → 전체 프레임 목록 (섹션 파악)
|
|
171
|
+
2. 관련 섹션별 get_design_context:
|
|
172
|
+
- "해상도 대응" / "Media Query" → 브레이크포인트
|
|
173
|
+
- "인터랙션" / "Interaction" → 호버/클릭/스크롤 스펙
|
|
174
|
+
- "애니메이션" / "Animation" / "Motion" → 트랜지션 스펙
|
|
175
|
+
- "상태" / "State" → 로딩/에러/성공 UI
|
|
176
|
+
- "컬러" / "Color" / "타이포" / "Typography" → 디자인 가이드
|
|
177
|
+
|
|
178
|
+
결과 → storyboardSpec 객체에 저장:
|
|
179
|
+
{
|
|
180
|
+
breakpoints: { ... }, // 브레이크포인트 오버라이드
|
|
181
|
+
interactions: [ ... ], // 인터랙션 목록
|
|
182
|
+
animations: [ ... ], // 애니메이션 스펙
|
|
183
|
+
states: [ ... ], // UI 상태 목록
|
|
184
|
+
colorGuide: { ... }, // 컬러 가이드
|
|
185
|
+
typographyGuide: { ... } // 타이포 가이드
|
|
186
|
+
}
|
|
118
187
|
```
|
|
119
188
|
|
|
120
|
-
|
|
189
|
+
### 0-2. 디자인 추출 (MCP)
|
|
190
|
+
|
|
191
|
+
각 디자인 URL에 대해 MCP로 추출:
|
|
121
192
|
|
|
122
193
|
```
|
|
123
|
-
|
|
124
|
-
|
|
194
|
+
URL에서 fileKey, nodeId 추출 (동일 방식)
|
|
195
|
+
|
|
196
|
+
각 URL에 대해:
|
|
197
|
+
1. get_design_context(fileKey, nodeId) → 코드 + 스크린샷 + 메타데이터 + 에셋 URL
|
|
198
|
+
2. get_metadata(fileKey, nodeId) → 레이어 구조 (XML)
|
|
199
|
+
3. get_screenshot(fileKey, nodeId) → 프레임 이미지
|
|
200
|
+
|
|
201
|
+
디자인 URL이 2개 이상이면:
|
|
202
|
+
→ 프레임 width로 viewport 자동 감지 (mobile/tablet/desktop)
|
|
203
|
+
→ responsive mode 진입
|
|
125
204
|
```
|
|
126
205
|
|
|
127
|
-
### 0-
|
|
206
|
+
### 0-3. Image Asset Download (BLOCKING — 코드 생성 전 반드시 완료)
|
|
128
207
|
|
|
129
|
-
|
|
130
|
-
MCP가 반환하는 URL은 **7일 후 만료**되므로 임시 URL을 코드에 직접 넣으면 안 됨.
|
|
208
|
+
> **⛔ 이 단계를 건너뛰면 안 됨.** 이미지 다운로드가 완료되지 않으면 Phase 6 코드 생성으로 진행하지 않는다.
|
|
131
209
|
|
|
132
|
-
|
|
210
|
+
`get_design_context` 응답에 포함된 이미지 에셋 URL은 **7일 후 만료**되는 임시 URL.
|
|
211
|
+
**즉시 다운로드**하여 프로젝트에 저장해야 함.
|
|
133
212
|
|
|
134
|
-
|
|
213
|
+
**Step 1: 에셋 URL 수집**
|
|
214
|
+
|
|
215
|
+
`get_design_context` 응답에서 모든 이미지 URL 추출:
|
|
135
216
|
```
|
|
136
|
-
|
|
217
|
+
패턴: https://www.figma.com/api/mcp/asset/...
|
|
218
|
+
코드에 const xxxImage = 'https://...' 형태로 포함됨
|
|
137
219
|
```
|
|
138
220
|
|
|
139
|
-
|
|
221
|
+
**Step 2: 다운로드 + 저장**
|
|
140
222
|
|
|
141
223
|
```
|
|
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'
|
|
224
|
+
각 URL에 대해:
|
|
225
|
+
1. WebFetch로 다운로드
|
|
226
|
+
2. 프로젝트 에셋 디렉토리에 저장:
|
|
227
|
+
- Nuxt: static/images/{feature}/ 또는 public/images/{feature}/
|
|
228
|
+
- Next.js: public/images/{feature}/
|
|
229
|
+
- React: public/images/{feature}/
|
|
230
|
+
3. 파일명은 레이어 이름 기반 (kebab-case):
|
|
231
|
+
- "Hero Background" → hero-background.webp
|
|
232
|
+
- "Product Photo 1" → product-photo-1.webp
|
|
153
233
|
```
|
|
154
234
|
|
|
155
|
-
**
|
|
235
|
+
**Step 3: URL → 로컬 경로 매핑 테이블 생성**
|
|
156
236
|
|
|
157
237
|
```
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
238
|
+
다운로드 완료 후, 매핑 테이블을 메모리에 보관:
|
|
239
|
+
|
|
240
|
+
| Figma 임시 URL | 로컬 경로 | 레이어 이름 |
|
|
241
|
+
|---------------|----------|-----------|
|
|
242
|
+
| https://figma.com/api/mcp/asset/abc... | /images/winter-pcbang/hero-bg.webp | Hero Background |
|
|
243
|
+
| https://figma.com/api/mcp/asset/def... | /images/winter-pcbang/hero-title.webp | Hero Title |
|
|
244
|
+
|
|
245
|
+
→ Phase 6 코드 생성 시 이 매핑 테이블로 임시 URL을 로컬 경로로 교체
|
|
162
246
|
```
|
|
163
247
|
|
|
164
|
-
|
|
248
|
+
**Step 4: SVG 처리**
|
|
165
249
|
|
|
166
|
-
코드 생성 완료 후, MCP 임시 URL이 코드에 남아있으면 경고:
|
|
167
250
|
```
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
251
|
+
- 벡터 에셋 (아이콘, 로고) → SVG로 다운로드
|
|
252
|
+
- 작은 아이콘 (< 1KB) → 인라인 SVG 컴포넌트
|
|
253
|
+
- 큰 SVG → 파일로 저장
|
|
171
254
|
```
|
|
172
255
|
|
|
173
|
-
### 0-
|
|
256
|
+
### 0-4. Extraction Gate (코드 생성 진행 조건)
|
|
257
|
+
|
|
258
|
+
> **다음 조건을 모두 만족해야 Phase 1로 진행:**
|
|
174
259
|
|
|
175
260
|
```
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
261
|
+
✅ 디자인 URL 최소 1개의 get_design_context 성공
|
|
262
|
+
✅ 디자인 스크린샷 최소 1개 획득
|
|
263
|
+
✅ 이미지 에셋 전부 다운로드 완료 (0개 남은 미다운로드)
|
|
264
|
+
✅ URL→로컬경로 매핑 테이블 생성 완료
|
|
265
|
+
✅ (responsive) 최소 2개 뷰포트의 스크린샷 획득
|
|
266
|
+
|
|
267
|
+
❌ 하나라도 실패 시:
|
|
268
|
+
→ 실패 항목 보고 + 재시도
|
|
269
|
+
→ 이미지 다운로드 실패 시: 해당 URL 재시도 (최대 3회)
|
|
270
|
+
→ 재시도 후에도 실패: 사용자에게 수동 다운로드 요청 후 계속
|
|
180
271
|
```
|
|
181
272
|
|
|
182
273
|
---
|
|
@@ -333,9 +424,9 @@ Breakpoints are loaded from multiple sources in priority order:
|
|
|
333
424
|
|
|
334
425
|
| Priority | Source | How |
|
|
335
426
|
|----------|--------|-----|
|
|
336
|
-
| 1 |
|
|
337
|
-
| 2 |
|
|
338
|
-
| 3 |
|
|
427
|
+
| 1 | **Storyboard** | Phase 0-1에서 추출한 `storyboardSpec.breakpoints` |
|
|
428
|
+
| 2 | **`~/.vibe/config.json`** | `figma.breakpoints` — user-customized via `vibe figma breakpoints --set` |
|
|
429
|
+
| 3 | **Project CSS/Tailwind** | Grep `tailwind.config.*` → `theme.screens`, or `@media.*min-width` patterns in codebase |
|
|
339
430
|
| 4 | **Defaults** | Built-in values (breakpoint: 1024px, etc.) |
|
|
340
431
|
|
|
341
432
|
#### Default Breakpoints (built-in)
|
|
@@ -1030,9 +1121,20 @@ Max props: 5 per component
|
|
|
1030
1121
|
|
|
1031
1122
|
## Phase 6: Code Generation
|
|
1032
1123
|
|
|
1033
|
-
### 6-0. Apply
|
|
1124
|
+
### 6-0. Apply Storyboard Spec + Design Context
|
|
1125
|
+
|
|
1126
|
+
**스토리보드 스펙 (Phase 0-1)이 있으면 우선 적용:**
|
|
1127
|
+
|
|
1128
|
+
| storyboardSpec | Effect on Code Generation |
|
|
1129
|
+
|----------------|--------------------------|
|
|
1130
|
+
| `interactions` | 호버/클릭/스크롤 이벤트 → CSS `:hover`/`:active`/`:focus` + JS 핸들러 |
|
|
1131
|
+
| `animations` | 트랜지션/애니메이션 → `transition`, `@keyframes`, timing/easing 스펙대로 |
|
|
1132
|
+
| `states` | 로딩/에러/성공/빈 상태 → 조건부 렌더링 + 상태별 UI 컴포넌트 |
|
|
1133
|
+
| `breakpoints` | Phase 3-3에서 이미 적용됨 |
|
|
1134
|
+
| `colorGuide` | 스토리보드 컬러 가이드 → 토큰 검증 |
|
|
1135
|
+
| `typographyGuide` | 스토리보드 타이포 가이드 → 토큰 검증 |
|
|
1034
1136
|
|
|
1035
|
-
|
|
1137
|
+
**design-context.json이 있으면 추가 적용:**
|
|
1036
1138
|
|
|
1037
1139
|
| Context Field | Effect on Code Generation |
|
|
1038
1140
|
|---------------|--------------------------|
|