@su-record/vibe 2.8.37 → 2.8.39
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/package.json +1 -1
- package/skills/vibe.figma/SKILL.md +101 -111
- package/skills/vibe.figma/templates/figma-handoff.md +4 -4
- package/skills/vibe.figma.convert/SKILL.md +298 -141
- package/skills/vibe.figma.convert/rubrics/conversion-rules.md +71 -80
- package/skills/vibe.figma.convert/templates/component.md +90 -98
- package/skills/vibe.figma.extract/SKILL.md +182 -80
- package/skills/vibe.figma.extract/rubrics/image-rules.md +1 -1
package/package.json
CHANGED
|
@@ -1,32 +1,34 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vibe.figma
|
|
3
|
-
description: Figma design to code —
|
|
3
|
+
description: Figma design to code — 트리 기반 구조적 코드 생성
|
|
4
4
|
triggers: []
|
|
5
5
|
tier: standard
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# vibe.figma —
|
|
8
|
+
# vibe.figma — Structural Code Generation
|
|
9
9
|
|
|
10
10
|
## 핵심 원칙
|
|
11
11
|
|
|
12
12
|
```
|
|
13
|
-
|
|
13
|
+
Figma 트리가 코드의 원천이다. 스크린샷은 검증용이다.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
✅
|
|
17
|
-
✅
|
|
18
|
-
✅
|
|
15
|
+
✅ Figma Auto Layout → CSS Flexbox 1:1 기계적 매핑
|
|
16
|
+
✅ Figma CSS 속성 → SCSS 직접 변환 (추정 없음)
|
|
17
|
+
✅ Claude는 시맨틱 판단만: 태그 선택, 컴포넌트 분리, 인터랙션
|
|
18
|
+
✅ 스크린샷은 생성이 아닌 검증에만 사용
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
## 금지 사항
|
|
22
22
|
|
|
23
23
|
```
|
|
24
|
-
❌
|
|
24
|
+
❌ 스크린샷을 보고 CSS 추정 (범용 LLM의 약점)
|
|
25
|
+
❌ Figma 레이어를 무분별하게 div soup로 변환
|
|
25
26
|
❌ CSS로 이미지 재현 (gradient/shape으로 그림 그리기)
|
|
26
27
|
❌ 이미지 다운로드 없이 코드 생성 진행
|
|
27
28
|
❌ placeholder / 빈 src="" 남기기
|
|
28
|
-
❌
|
|
29
|
+
❌ tree.json에 없는 CSS 값을 추정하여 작성
|
|
29
30
|
❌ 컴포넌트 파일 안에 <style> 블록 / 인라인 style=""
|
|
31
|
+
✅ tree.json의 CSS 속성을 SCSS에 직접 매핑
|
|
30
32
|
✅ 외부 SCSS 파일에만 스타일 작성
|
|
31
33
|
```
|
|
32
34
|
|
|
@@ -34,11 +36,12 @@ tier: standard
|
|
|
34
36
|
|
|
35
37
|
```
|
|
36
38
|
/vibe.figma
|
|
37
|
-
→ Phase 0: Setup (스택 감지, 디렉토리
|
|
39
|
+
→ Phase 0: Setup (스택 감지, 디렉토리 생성, 기존 자산 인덱싱)
|
|
38
40
|
→ Phase 1: Storyboard (스토리보드 → 레이아웃 + 컴포넌트 + 기능 정의)
|
|
39
|
-
→ Phase 2: 재료 확보 (디자인 URL →
|
|
40
|
-
→ Phase 3:
|
|
41
|
-
→ Phase
|
|
41
|
+
→ Phase 2: 재료 확보 (디자인 URL → 트리 + 이미지 + 스크린샷)
|
|
42
|
+
→ Phase 3: 구조적 코드 생성 (트리 → HTML+SCSS 매핑 + 시맨틱 보강)
|
|
43
|
+
→ Phase 3.5: 컴파일 게이트 (tsc → build → dev 확인)
|
|
44
|
+
→ Phase 4: 시각 검증 루프 (렌더링 vs 스크린샷 비교 → 수정)
|
|
42
45
|
```
|
|
43
46
|
|
|
44
47
|
---
|
|
@@ -199,78 +202,56 @@ URL에서 fileKey, nodeId 추출
|
|
|
199
202
|
→ 또는 depth 높여서 하위 분할 조회
|
|
200
203
|
```
|
|
201
204
|
|
|
202
|
-
### 1-2.
|
|
203
|
-
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
* ② 누적 보상 클릭 → 보상 수령
|
|
240
|
-
*
|
|
241
|
-
* [상태] default, checked, reward-claimed
|
|
242
|
-
*/
|
|
243
|
-
- TypeScript 인터페이스
|
|
244
|
-
- 목 데이터 (빈 배열 금지, 3~7개 아이템)
|
|
245
|
-
- 이벤트 핸들러 stub (body는 // TODO:)
|
|
246
|
-
|
|
247
|
-
<style> 블록 없음 — 스타일은 Phase 3에서 외부 파일로.
|
|
248
|
-
|
|
249
|
-
3. 공통 컴포넌트 (SHARED에서 파악):
|
|
250
|
-
→ 프로젝트에 이미 있으면 import 재사용
|
|
251
|
-
→ 없으면 새로 생성 (GNB, Footer, Popup)
|
|
252
|
-
|
|
253
|
-
4. 스타일 디렉토리 구조 생성 (빈 파일):
|
|
254
|
-
styles/{feature}/index.scss
|
|
255
|
-
styles/{feature}/_tokens.scss
|
|
256
|
-
styles/{feature}/_mixins.scss
|
|
257
|
-
styles/{feature}/_base.scss
|
|
258
|
-
styles/{feature}/layout/
|
|
259
|
-
styles/{feature}/components/
|
|
205
|
+
### 1-2. 기능 스펙 문서 작성 (파일 생성 없음)
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
❌ Phase 1에서 코드 파일을 생성하지 않는다.
|
|
209
|
+
→ Phase 1 HTML 구조와 Phase 3 트리 매핑이 충돌하면 이중 작업
|
|
210
|
+
→ Phase 3에서 tree.json 기반으로 코드를 생성
|
|
211
|
+
|
|
212
|
+
✅ Phase 1의 출력물은 기능 스펙 문서 (텍스트):
|
|
213
|
+
|
|
214
|
+
1. 섹션 목록:
|
|
215
|
+
| # | 섹션 이름 | Figma 프레임 name | 높이 | 설명 |
|
|
216
|
+
|---|----------|------------------|------|------|
|
|
217
|
+
| 1 | Hero | Hero | 1280px | 키비주얼 + 이벤트 정보 |
|
|
218
|
+
| 2 | DailyCheckIn | Daily | 3604px | 출석 미션 |
|
|
219
|
+
| 3 | PlayTime | Frame 633371 | 11363px | 플레이타임 미션 |
|
|
220
|
+
|
|
221
|
+
2. 각 섹션의 기능 정의:
|
|
222
|
+
/**
|
|
223
|
+
* 일일 출석 미션 섹션
|
|
224
|
+
*
|
|
225
|
+
* [기능 정의]
|
|
226
|
+
* - 매일 출석 시 스노우 토큰 즉시 지급
|
|
227
|
+
* - 누적 3/5/7일 달성 시 추가 보상
|
|
228
|
+
*
|
|
229
|
+
* [인터랙션]
|
|
230
|
+
* ① 출석하기 클릭 → API호출 → 토큰지급 표시
|
|
231
|
+
* ② 누적 보상 클릭 → 보상 수령
|
|
232
|
+
*
|
|
233
|
+
* [상태] default, checked, reward-claimed
|
|
234
|
+
*/
|
|
235
|
+
|
|
236
|
+
3. 공통 컴포넌트 목록:
|
|
237
|
+
→ 프로젝트에 이미 있는 컴포넌트 (GNB, Footer 등)
|
|
238
|
+
→ 새로 만들 공통 컴포넌트
|
|
239
|
+
|
|
240
|
+
4. TypeScript 인터페이스 초안:
|
|
241
|
+
interface RewardItem { id: string; name: string; tokenAmount: number; status: 'locked'|'available'|'claimed' }
|
|
260
242
|
```
|
|
261
243
|
|
|
262
244
|
### 1-3. 검증
|
|
263
245
|
|
|
264
246
|
```
|
|
265
247
|
Phase 1 완료 조건:
|
|
266
|
-
□
|
|
267
|
-
□
|
|
268
|
-
□
|
|
269
|
-
□
|
|
270
|
-
□
|
|
248
|
+
□ 모든 섹션이 목록에 포함되어 있다
|
|
249
|
+
□ 각 섹션에 [기능 정의] + [인터랙션] + [상태] 가 정의되어 있다
|
|
250
|
+
□ TypeScript 인터페이스 초안이 작성되어 있다
|
|
251
|
+
□ 공통 컴포넌트가 식별되어 있다
|
|
252
|
+
□ 파일을 하나도 생성하지 않았다
|
|
271
253
|
|
|
272
|
-
|
|
273
|
-
스타일/이미지는 없어도 됨 — Phase 3에서 채움.
|
|
254
|
+
Phase 3에서 이 스펙 + tree.json을 합쳐서 코드를 생성한다.
|
|
274
255
|
```
|
|
275
256
|
|
|
276
257
|
---
|
|
@@ -313,6 +294,16 @@ URL에서 fileKey, nodeId 추출
|
|
|
313
294
|
node "[FIGMA_SCRIPT]" images {fileKey} {nodeId} --out=/tmp/{feature}/images/ --depth=10
|
|
314
295
|
→ 모든 이미지 에셋 확보. 누락 0건, 0byte 0건.
|
|
315
296
|
|
|
297
|
+
3.5단계 — 아이템/아이콘 노드 렌더링 (추가 시각 재료):
|
|
298
|
+
tree.json에서 INSTANCE/COMPONENT 타입 중 아이템 후보를 식별:
|
|
299
|
+
- name에 "item", "icon", "reward", "token", "coin", "badge" 포함
|
|
300
|
+
- 크기 50~300px 범위의 독립 요소
|
|
301
|
+
- fill 이미지가 없지만 시각적으로 의미 있는 노드
|
|
302
|
+
해당 노드를 개별 렌더링:
|
|
303
|
+
node "[FIGMA_SCRIPT]" images {fileKey} {nodeId} --render --nodeIds={id1},{id2},... --out=/tmp/{feature}/images/
|
|
304
|
+
→ 이미지 fill이 아닌 벡터/인스턴스 에셋도 PNG로 확보
|
|
305
|
+
→ Phase 3에서 목 데이터의 image 경로에 연결
|
|
306
|
+
|
|
316
307
|
4단계 — 섹션별 스크린샷 (부분 정답):
|
|
317
308
|
트리의 1depth 자식 프레임 각각:
|
|
318
309
|
node "[FIGMA_SCRIPT]" screenshot {fileKey} {child.nodeId} --out=/tmp/{feature}/sections/{child.name}.png
|
|
@@ -542,40 +533,40 @@ Phase 1에서 생성한 빈 SCSS 파일에 기본 내용 Write:
|
|
|
542
533
|
❌ 90% 유사한데 새로 만들기 금지
|
|
543
534
|
```
|
|
544
535
|
|
|
545
|
-
### 3-1.
|
|
536
|
+
### 3-1. 트리 기반 구조적 코드 생성
|
|
546
537
|
|
|
547
538
|
```
|
|
548
|
-
각 섹션에
|
|
549
|
-
|
|
550
|
-
1. 정답 확인 — 섹션 스크린샷을 Read로 본다
|
|
551
|
-
/tmp/{feature}/sections/{section}.png
|
|
552
|
-
→ "이 화면처럼 만들어야 한다"
|
|
539
|
+
각 섹션에 대해 (vibe.figma.convert 참조):
|
|
553
540
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
- 텍스트: TEXT 노드의 characters
|
|
541
|
+
1. 트리 구조 읽기 — tree.json에서 해당 섹션 노드를 Read
|
|
542
|
+
→ Auto Layout 속성(flex, gap, padding)이 코드의 기반
|
|
543
|
+
→ 스크린샷은 검증용으로만 참조
|
|
558
544
|
|
|
559
|
-
|
|
545
|
+
2. 기계적 매핑 (추정 없음):
|
|
560
546
|
a. 이미지 복사: images/ → static/images/{feature}/
|
|
561
|
-
b.
|
|
562
|
-
-
|
|
563
|
-
-
|
|
564
|
-
-
|
|
565
|
-
-
|
|
566
|
-
-
|
|
567
|
-
c.
|
|
568
|
-
-
|
|
569
|
-
|
|
570
|
-
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
-
|
|
576
|
-
-
|
|
577
|
-
-
|
|
578
|
-
|
|
547
|
+
b. 노드 → HTML 매핑:
|
|
548
|
+
- Auto Layout 있음 → <div> + flex (direction/gap/padding 직접)
|
|
549
|
+
- Auto Layout 없음 → <div> + position:relative (자식 absolute)
|
|
550
|
+
- TEXT 노드 → <span> (Claude가 h2/p/button으로 승격)
|
|
551
|
+
- imageRef 있음 → <img src="다운로드된 파일">
|
|
552
|
+
- 반복 패턴 (동일 구조 3+) → v-for
|
|
553
|
+
c. CSS 직접 매핑:
|
|
554
|
+
- node.css의 모든 속성을 SCSS에 1:1 매핑
|
|
555
|
+
- scaleFactor 적용 (px 값만)
|
|
556
|
+
- tree.json에 없는 CSS 값은 작성하지 않음
|
|
557
|
+
d. Phase 1의 JSDoc, 인터페이스, 핸들러 보존
|
|
558
|
+
|
|
559
|
+
3. Claude 시맨틱 보강:
|
|
560
|
+
- div → section/h2/p/button 태그 승격
|
|
561
|
+
- 컴포넌트 분리 + props 설계
|
|
562
|
+
- 접근성 (alt, aria)
|
|
563
|
+
- 인터랙션 (클릭, 상태)
|
|
564
|
+
|
|
565
|
+
4. 자가 검증:
|
|
566
|
+
- template 클래스 ↔ SCSS 클래스 1:1 일치
|
|
567
|
+
- 모든 img src가 static/에 실제 존재
|
|
568
|
+
- Auto Layout 노드 → SCSS에 flex 속성 존재
|
|
569
|
+
- 스크린샷과 비교 (시각 확인)
|
|
579
570
|
```
|
|
580
571
|
|
|
581
572
|
### 3-2. 코드 작성 규칙
|
|
@@ -583,11 +574,10 @@ Phase 1에서 생성한 빈 SCSS 파일에 기본 내용 Write:
|
|
|
583
574
|
```
|
|
584
575
|
컴포넌트 (Vue 예시):
|
|
585
576
|
<template>
|
|
586
|
-
|
|
587
|
-
|
|
577
|
+
tree.json의 Auto Layout 구조를 HTML flex 레이아웃으로 직접 매핑.
|
|
578
|
+
Claude가 시맨틱 태그로 승격 (div → section/h2/p/button).
|
|
588
579
|
Phase 1의 기능 요소(v-for, @click, v-if) 보존.
|
|
589
|
-
|
|
590
|
-
이미지 경로: /images/{feature}/파일명.png
|
|
580
|
+
이미지 경로: /images/{feature}/파일명.png (실제 파일 존재 확인)
|
|
591
581
|
텍스트: tree.json의 TEXT 노드 characters 값 그대로.
|
|
592
582
|
|
|
593
583
|
<script setup>
|
|
@@ -40,11 +40,11 @@ Breakpoint threshold: `@media (min-width: {{BP_PC}}px)`
|
|
|
40
40
|
|
|
41
41
|
## Sections
|
|
42
42
|
|
|
43
|
-
| # | Section Name | Component File |
|
|
44
|
-
|
|
45
|
-
| 1 | {{SECTION_NAME}} | `components/{{FEATURE_KEY}}/{{ComponentName}}.vue` | {{
|
|
43
|
+
| # | Section Name | Component File | Tree Nodes | Height (design) |
|
|
44
|
+
|---|-------------|---------------|-----------|----------------|
|
|
45
|
+
| 1 | {{SECTION_NAME}} | `components/{{FEATURE_KEY}}/{{ComponentName}}.vue` | {{NODE_COUNT}} | {{HEIGHT}}px |
|
|
46
46
|
|
|
47
|
-
**
|
|
47
|
+
**Generation:** tree.json → HTML+SCSS 구조적 매핑 (external SCSS)
|
|
48
48
|
|
|
49
49
|
---
|
|
50
50
|
|