@su-record/vibe 2.8.12 → 2.8.13

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@su-record/vibe",
3
- "version": "2.8.12",
3
+ "version": "2.8.13",
4
4
  "description": "AI Coding Framework for Claude Code — 49 agents, 41+ tools, multi-LLM orchestration",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: vibe-figma
3
+ description: Step A — 스토리보드 추출 + 프로젝트 Base 구조 설계
4
+ triggers: []
5
+ tier: standard
6
+ ---
7
+
8
+ # Skill: vibe-figma — Step A: 스토리보드 + Base 구조
9
+
10
+ ## 스토리보드에서 추출하는 정보
11
+
12
+ | 항목 | 활용 |
13
+ |------|------|
14
+ | 브레이크포인트 / 해상도 가이드 | base 레이아웃 설계 |
15
+ | 인터랙션 스펙 (호버, 클릭, 스크롤) | 이벤트 핸들러 + CSS states |
16
+ | 애니메이션 스펙 (타이밍, 이징) | transition/animation |
17
+ | 상태별 UI (로딩, 에러, 성공) | 조건부 렌더링 |
18
+ | 반응형 동작 설명 | responsive 코드 |
19
+ | 컬러/타이포 가이드 | 토큰 생성 |
20
+
21
+ ---
22
+
23
+ ## A-1. 스토리보드 URL 입력
24
+
25
+ AskUserQuestion (options 사용 금지, 자유 텍스트만):
26
+ ```
27
+ question: "📋 스토리보드 Figma URL을 입력해주세요. (없으면 '없음')"
28
+ → ⏸️ 응답 대기 (응답 받기 전 다음 진행 금지)
29
+ → figma.com URL → storyboardUrl 저장
30
+ → "없음" → storyboardUrl = null
31
+ ```
32
+
33
+ ## A-2. 스토리보드 추출 (storyboardUrl이 있을 때)
34
+
35
+ ```
36
+ URL에서 fileKey, nodeId 추출:
37
+ https://www.figma.com/design/:fileKey/:fileName?node-id=:nodeId
38
+ → nodeId: 하이픈을 콜론으로 ("1-109" → "1:109")
39
+
40
+ 1. get_metadata(fileKey, nodeId) → 전체 프레임 목록
41
+ 2. 관련 섹션별 get_design_context:
42
+ - "해상도 대응" / "Media Query" → 브레이크포인트
43
+ - "인터랙션" / "Interaction" → 호버/클릭/스크롤 스펙
44
+ - "애니메이션" / "Animation" / "Motion" → 트랜지션 스펙
45
+ - "상태" / "State" → 로딩/에러/성공 UI
46
+ - "컬러" / "Color" / "타이포" / "Typography" → 디자인 가이드
47
+ ```
48
+
49
+ 추출 결과를 `storyboardSpec`으로 저장:
50
+ ```
51
+ storyboardSpec = {
52
+ breakpoints: { ... },
53
+ interactions: [ ... ],
54
+ animations: [ ... ],
55
+ states: { ... },
56
+ colorGuide: { ... },
57
+ typographyGuide: { ... }
58
+ }
59
+ ```
60
+
61
+ ## A-3. 프로젝트 스택 감지 + Base 구조 설계
62
+
63
+ ```
64
+ 1. 프로젝트 스택 감지 (vibe-figma-rules Phase 3 참조)
65
+ 2. 디자인 시스템 감지 (--new 미지정 시)
66
+ 3. 브레이크포인트 로드 (vibe-figma-rules Phase 3-3 참조, 스토리보드 우선)
67
+ 4. 피처명 결정 (Figma 파일명에서 추출)
68
+ 5. 파일 구조 생성:
69
+ - 루트 페이지 파일 (빈 shell)
70
+ - 컴포넌트 디렉토리 (빈 폴더)
71
+ - 토큰 파일 (스토리보드 기반 초기값)
72
+ ```
73
+
74
+ ### 피처명 결정
75
+
76
+ Figma 파일명에서 피처명 자동 추출 → kebab-case 변환.
77
+
78
+ ```
79
+ 예: Figma 파일명 "PUBG 9주년 이벤트" → pubg-anniversary
80
+ ```
81
+
82
+ ### 파일 구조 감지 및 생성
83
+
84
+ **페이지 디렉토리:**
85
+ ```
86
+ Next.js → pages/ or app/
87
+ Nuxt → pages/
88
+ React → src/pages/ or src/views/
89
+ Vue → src/views/
90
+ ```
91
+
92
+ **컴포넌트 디렉토리:**
93
+ ```
94
+ Next.js → components/ or src/components/
95
+ Nuxt → components/
96
+ React → src/components/
97
+ Vue → src/components/
98
+ ```
99
+
100
+ **스타일 디렉토리:**
101
+ ```
102
+ SCSS → assets/scss/ or src/scss/ or src/styles/
103
+ CSS → src/styles/ or styles/
104
+ Tailwind → tailwind.config.* (extend)
105
+ ```
106
+
107
+ **생성 예시 (Nuxt 프로젝트):**
108
+ ```
109
+ pages/pubg-anniversary.vue ← 루트 페이지 (빈 shell)
110
+ components/pubg-anniversary/ ← 컴포넌트 디렉토리 (빈 폴더)
111
+ assets/scss/_pubg-anniversary-tokens.scss ← 스토리보드 기반 초기 토큰
112
+ ```
113
+
114
+ **생성 예시 (React + Next.js):**
115
+ ```
116
+ app/pubg-anniversary/page.tsx ← 루트 페이지 (빈 shell)
117
+ components/pubg-anniversary/ ← 컴포넌트 디렉토리 (빈 폴더)
118
+ styles/pubg-anniversary-tokens.css ← 스토리보드 기반 초기 토큰
119
+ ```
120
+
121
+ Step A 완료 후 → Step B (vibe-figma-mobile) 로 진행.
@@ -0,0 +1,325 @@
1
+ ---
2
+ name: vibe-figma-analyze
3
+ tier: standard
4
+ description: "스토리보드 세밀 분석 → 실제 레이아웃 코드 + 기능 주석 + 컴포넌트 구조 생성. Step A에서 vibe-figma 이후 실행."
5
+ triggers: []
6
+ ---
7
+
8
+ # Storyboard Deep Analysis & Layout Generation
9
+
10
+ 스토리보드 URL 하나로 **실제 동작하는 레이아웃 코드**를 생성.
11
+ 빈 shell이 아니라, 스토리보드에서 파악 가능한 모든 정보를 코드에 반영.
12
+
13
+ ## 입력
14
+
15
+ - 스토리보드 URL의 get_metadata 결과 (전체 프레임 목록)
16
+ - storyboardSpec (브레이크포인트 등, vibe-figma에서 추출)
17
+
18
+ ## Phase 1: 프레임 전수 조사
19
+
20
+ get_metadata에서 얻은 **모든 최상위 프레임**을 분류:
21
+
22
+ ```
23
+ 각 프레임을 카테고리로 분류:
24
+
25
+ SKIP — "개요", "Cover", "변경 이력" (문서 관리용)
26
+ SPEC — "기능 정의", "정책" → 기능 스펙 텍스트 추출 대상
27
+ CONFIG — "해상도", "Media Query", "브라우저" → 설정값 추출
28
+ SHARED — "공통", "GNB", "Footer", "Popup", "Dialog" → 공통 컴포넌트
29
+ FLOW — "Event Flow", "플로우" → 유저 플로우 파악
30
+ ASSET — "OG", "배너", "어셋" → 스킵 (메타 이미지)
31
+ PAGE — "메인", "화면설계" 하위 → 핵심 섹션 (코드 생성 대상)
32
+
33
+ 서브 프레임 (3.x.1, 3.x.2 등):
34
+ → 해당 PAGE 섹션의 상태 변형 / 인터랙션 결과 화면
35
+ ```
36
+
37
+ ## Phase 2: SPEC 프레임 세밀 분석 (기능 정의서)
38
+
39
+ **기능 정의서 프레임**에 대해 get_design_context 호출:
40
+
41
+ ```
42
+ 추출 대상:
43
+ - Overview: 이벤트 개요, 대상, 일정
44
+ - Spec: 각 섹션별 기능 정의 (로직, 조건, 보상 구조)
45
+ - Event 일정: 시작/종료 시간, 단계별 기간
46
+
47
+ 추출한 텍스트를 섹션별로 분리:
48
+ {
49
+ "overview": "겨울 PC방 이벤트...",
50
+ "sections": {
51
+ "hero": "키 비주얼 영역, 로그인 연동, 가맹 PC방 확인...",
52
+ "dailyCheckIn": "매일 ON 게임 진입 + 출석란 터치 → 스노우 토큰 즉시 지급...",
53
+ "playTimeMission": "일일 플레이 타임 달성 시 보상...",
54
+ "tokenExchange": "스노우 토큰으로 아이템 교환...",
55
+ "tokenRaffle": "스노우 토큰으로 상품 응모..."
56
+ }
57
+ }
58
+
59
+ → 이 정보가 Phase 5에서 각 컴포넌트의 기능 주석이 됨
60
+ ```
61
+
62
+ ## Phase 3: SHARED 프레임 분석 (공통 컴포넌트)
63
+
64
+ 공통 요소 프레임들의 get_screenshot으로 구조 파악:
65
+
66
+ ```
67
+ GNB: 네비게이션 구조, 메뉴 항목, 언어 변경, 로그인 버튼
68
+ Footer: 소셜 링크, 법적 고지, 시간 표시 (UTC/KST)
69
+ Popup: 패턴 분류 (확인/취소, 상세 모달, 알림, 입력 폼)
70
+ Error: 에러 페이지 구조
71
+
72
+ → 프로젝트에 이미 있는 컴포넌트 확인 (Glob으로 탐색)
73
+ → 있으면 import 재사용, 없으면 새로 생성
74
+ ```
75
+
76
+ ## Phase 4: PAGE 프레임 세밀 분석 (화면설계)
77
+
78
+ **각 PAGE 프레임**에 대해 get_screenshot + get_design_context:
79
+
80
+ ```
81
+ 각 프레임에서 추출:
82
+
83
+ 1. 레이아웃 구조 (get_screenshot 비주얼 분석):
84
+ - 섹션 경계 (배경 변화 지점)
85
+ - 요소 배치 방향 (vertical stack / grid / positioned)
86
+ - 이미지 배경 영역 vs 콘텐츠 영역
87
+ - 대략적인 비율 (hero 50vh, section padding 등)
88
+
89
+ 2. 인터랙션 스펙 (우측 주석):
90
+ - 번호 태그 (①②③) → 인터랙션 ID
91
+ - 동작 설명 → 이벤트 타입 + 결과
92
+ - 조건 분기 (로그인 여부, 기간 내/외 등)
93
+
94
+ 3. 상태 변형 (서브 프레임 3.x.1, 3.x.2):
95
+ - 기본 → 클릭 후 → 성공 → 에러 등
96
+ - 팝업 트리거 조건
97
+
98
+ 결과를 섹션별로 저장:
99
+ sections[sectionName] = {
100
+ layout: "vertical-stack, bg-image + overlay + content",
101
+ children: ["Title", "Description", "RewardGrid", "CTAButton"],
102
+ interactions: [
103
+ { id: "①", trigger: "클릭", action: "출석 처리", result: "보상 표시" }
104
+ ],
105
+ states: ["default", "checked", "reward-claimed"],
106
+ popups: ["ConfirmDialog"]
107
+ }
108
+ ```
109
+
110
+ ## Phase 5: 실제 코드 생성 (빈 shell 아님)
111
+
112
+ 스토리보드 분석 결과로 **실제 동작하는 레이아웃 코드** 생성.
113
+ 스타일은 Step B에서 채우지만, **구조/로직/주석은 이 단계에서 완성**.
114
+
115
+ ### 루트 페이지
116
+
117
+ ```vue
118
+ <!-- pages/{feature-name}.vue -->
119
+ <template>
120
+ <div class="eventPage">
121
+ <GnbHeader />
122
+
123
+ <HeroSection />
124
+ <DailyCheckInSection />
125
+ <PlayTimeMissionSection />
126
+ <TokenExchangeSection />
127
+ <TokenRaffleSection />
128
+ <CautionSection />
129
+
130
+ <EventFooter />
131
+
132
+ <!-- Popups -->
133
+ <ConfirmDialog v-if="showConfirm" @close="showConfirm = false" />
134
+ <TokenDetailModal v-if="showTokenDetail" @close="showTokenDetail = false" />
135
+ </div>
136
+ </template>
137
+
138
+ <script setup lang="ts">
139
+ /**
140
+ * {이벤트명} 메인 페이지
141
+ *
142
+ * [개요] Phase 2에서 추출한 overview 텍스트
143
+ * [일정] 시작일 ~ 종료일
144
+ * [대상] 대상자 설명
145
+ */
146
+
147
+ import HeroSection from '~/components/{feature-name}/HeroSection.vue'
148
+ // ... 모든 섹션 import
149
+
150
+ const showConfirm = ref(false)
151
+ const showTokenDetail = ref(false)
152
+ </script>
153
+ ```
154
+
155
+ ### 각 섹션 컴포넌트 (기능 주석 포함)
156
+
157
+ ```vue
158
+ <!-- components/{feature-name}/DailyCheckInSection.vue -->
159
+ <template>
160
+ <section class="dailyCheckInSection">
161
+ <div class="dailyCheckInSection__title">
162
+ <!-- Step B: 모바일 디자인에서 타이틀 이미지/텍스트 반영 -->
163
+ </div>
164
+
165
+ <div class="dailyCheckInSection__calendar">
166
+ <div
167
+ v-for="day in checkInDays"
168
+ :key="day.date"
169
+ class="dailyCheckInSection__day"
170
+ :class="{ 'is-checked': day.checked, 'is-today': day.isToday }"
171
+ @click="handleCheckIn(day)"
172
+ >
173
+ <!-- Step B: 일별 UI (아이콘, 날짜, 보상) -->
174
+ </div>
175
+ </div>
176
+
177
+ <div class="dailyCheckInSection__accumulated">
178
+ <div
179
+ v-for="milestone in milestones"
180
+ :key="milestone.days"
181
+ class="dailyCheckInSection__milestone"
182
+ :class="{ 'is-claimable': milestone.claimable, 'is-claimed': milestone.claimed }"
183
+ @click="handleClaimReward(milestone)"
184
+ >
185
+ <!-- Step B: 누적 보상 UI -->
186
+ </div>
187
+ </div>
188
+ </section>
189
+ </template>
190
+
191
+ <script setup lang="ts">
192
+ /**
193
+ * 일일 출석 미션 섹션
194
+ *
195
+ * [기능 정의]
196
+ * - 매일 ON 게임 진입, 대상 출석란 터치 시 출석 처리
197
+ * - 스노우 토큰이 즉시 지급됨
198
+ * - 누적 출석일 보상: 3일/5일/7일 달성 시 추가 보상
199
+ *
200
+ * [인터랙션]
201
+ * ① 출석하기 클릭 → 출석 처리 API 호출 → 토큰 지급 표시
202
+ * ② 누적 보상 달성 시 → 보상받기 버튼 활성화 → 클릭 시 수령
203
+ *
204
+ * [상태]
205
+ * - default: 오늘 미출석
206
+ * - checked: 오늘 출석 완료
207
+ * - reward-claimed: 누적 보상 수령 완료
208
+ *
209
+ * [조건]
210
+ * - 이벤트 기간 내에만 출석 가능
211
+ * - 가맹 PC방에서만 출석 가능 (비가맹 시 안내 팝업)
212
+ */
213
+
214
+ interface CheckInDay {
215
+ date: string
216
+ checked: boolean
217
+ isToday: boolean
218
+ reward: number
219
+ }
220
+
221
+ interface Milestone {
222
+ days: number
223
+ claimable: boolean
224
+ claimed: boolean
225
+ reward: string
226
+ }
227
+
228
+ const checkInDays = ref<CheckInDay[]>([])
229
+ const milestones = ref<Milestone[]>([])
230
+
231
+ function handleCheckIn(day: CheckInDay): void {
232
+ // TODO: 출석 API 호출
233
+ }
234
+
235
+ function handleClaimReward(milestone: Milestone): void {
236
+ // TODO: 누적 보상 수령 API 호출
237
+ }
238
+ </script>
239
+
240
+ <style lang="scss" scoped>
241
+ /* Step B: 모바일 디자인 URL 반영 시 스타일 구현 */
242
+ .dailyCheckInSection {
243
+ /* layout will be filled in Step B */
244
+ }
245
+ </style>
246
+ ```
247
+
248
+ ### 핵심 원칙: 스타일 없이 동작하는 코드
249
+
250
+ ```
251
+ ✅ 클릭 → 팝업 열림/닫힘이 실제로 동작
252
+ ✅ 탭 전환, 아코디언 펼침/접기가 동작
253
+ ✅ 상태 변경 (체크, 선택, 비활성화)이 반영됨
254
+ ✅ 모달/팝업 open/close가 v-if/ref로 연결됨
255
+ ✅ emit으로 부모-자식 이벤트가 실제 연결됨
256
+ ✅ 리스트 렌더링 (v-for)이 더미 데이터로 동작
257
+ ✅ 조건부 렌더링 (v-if)이 상태에 따라 전환됨
258
+
259
+ → 브라우저에서 열면 스타일은 없지만 클릭/인터랙션은 동작하는 상태
260
+
261
+ ✅ 기능 정의서 내용 → 컴포넌트 JSDoc 주석
262
+ ✅ 인터랙션 스펙 → 이벤트 핸들러 함수 (API 호출은 TODO)
263
+ ✅ 상태 목록 → TypeScript 인터페이스 + ref + 더미 데이터
264
+ ✅ 스타일은 빈 블록 → Step B에서 채움
265
+ ✅ 이미지는 placeholder → Step B에서 교체
266
+ ```
267
+
268
+ ### 팝업/모달 구현 수준
269
+
270
+ ```vue
271
+ <!-- 팝업이 실제로 열리고 닫히는 코드 -->
272
+ <template>
273
+ <!-- 트리거 버튼 -->
274
+ <button @click="showConfirm = true">교환하기</button>
275
+
276
+ <!-- 모달 — v-if로 제어, 실제 동작 -->
277
+ <Teleport to="body">
278
+ <div v-if="showConfirm" class="modalOverlay" @click.self="showConfirm = false">
279
+ <div class="modalContent">
280
+ <p>정말 교환하시겠습니까?</p>
281
+ <button @click="handleConfirm">확인</button>
282
+ <button @click="showConfirm = false">취소</button>
283
+ </div>
284
+ </div>
285
+ </Teleport>
286
+ </template>
287
+
288
+ <script setup lang="ts">
289
+ const showConfirm = ref(false)
290
+
291
+ function handleConfirm(): void {
292
+ // TODO: 교환 API 호출
293
+ showConfirm.value = false
294
+ }
295
+ </script>
296
+ ```
297
+
298
+ ## Phase 6: 인터랙션 매핑 테이블
299
+
300
+ 코드 생성 후, 전체 인터랙션을 테이블로 출력:
301
+
302
+ ```markdown
303
+ ## 인터랙션 매핑
304
+
305
+ | 섹션 | ID | 트리거 | 동작 | 컴포넌트 | 함수 |
306
+ |------|-----|--------|------|---------|------|
307
+ | Hero | ① | 공유 클릭 | 공유하기 팝업 | HeroSection | handleShare() |
308
+ | 출석 | ① | 출석하기 클릭 | API 호출 → 토큰 지급 | DailyCheckInSection | handleCheckIn() |
309
+ | 출석 | ② | 누적 보상 클릭 | 보상 수령 | DailyCheckInSection | handleClaimReward() |
310
+ | 교환소 | ① | 교환하기 클릭 | 확인 팝업 → 교환 처리 | TokenExchangeSection | handleExchange() |
311
+ | 응모 | ① | 응모하기 클릭 | 응모 처리 → 이메일 수집 | TokenRaffleSection | handleRaffle() |
312
+
313
+ → Step B/C에서 코드 생성 시 이 함수들의 body를 구현
314
+ ```
315
+
316
+ ## 출력 요약
317
+
318
+ ```
319
+ ✅ 루트 페이지 (실제 레이아웃 + 섹션 배치 + 팝업 조건부 렌더링)
320
+ ✅ 각 섹션 컴포넌트 (구조 코드 + 기능 주석 + 이벤트 핸들러 + TypeScript 인터페이스)
321
+ ✅ 공통 컴포넌트 (GNB, Footer, Popup — 기존 재사용 또는 신규)
322
+ ✅ 인터랙션 매핑 테이블
323
+ ✅ 스타일은 빈 블록 → Step B(모바일)에서 디자인 URL 받고 채움
324
+ ✅ 이미지는 placeholder → Step B에서 다운로드 후 교체
325
+ ```