@su-record/vibe 2.8.44 → 2.8.46

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.44",
3
+ "version": "2.8.46",
4
4
  "description": "AI Coding Framework for Claude Code — 56 agents, 45 skills, multi-LLM orchestration",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",
@@ -42,7 +42,7 @@ Figma 트리가 코드의 원천이다. 스크린샷은 검증용이다.
42
42
  PC Design: https://figma.com/...?node-id=yyy (있으면)
43
43
 
44
44
  → Phase 0: Setup (스택 감지, 디렉토리 생성, 기존 자산 인덱싱)
45
- → Phase 1: Storyboard (스토리보드 → 기능 스펙 문서 작성, 파일 생성 없음)
45
+ → Phase 1: 디자인 리소스 (URL 입력 → 스토리보드 분석 → 기능 스펙 문서)
46
46
  → Phase 2: 재료 확보 (모든 BP의 트리 + 노드 렌더링 이미지 + 스크린샷)
47
47
  → Phase 3: 리매핑 (tree.json → remapped.json, BP 간 노드 매칭 + CSS diff)
48
48
  → Phase 4: 순차 코드 생성 (remapped.json → 섹션별 HTML+SCSS)
@@ -196,18 +196,44 @@ Figma 트리가 코드의 원천이다. 스크린샷은 검증용이다.
196
196
 
197
197
  ---
198
198
 
199
- ## Phase 1: Storyboard
199
+ ## Phase 1: 디자인 리소스
200
200
 
201
201
  사용자에게 질문한다:
202
- - question: "스토리보드 Figma URL을 입력해주세요. (없으면 '없음')"
202
+ - question: "스토리보드, 디자인 리소스를 줄바꿈으로 입력해주세요. (순서 무관)"
203
+ - 예시:
204
+ https://figma.com/design/xxx/...?node-id=20-4964
205
+ https://figma.com/design/yyy/...?node-id=641-78147
206
+ https://figma.com/design/yyy/...?node-id=641-78200
207
+ 또는:
208
+ docs/storyboard.pdf
209
+ https://figma.com/design/yyy/...?node-id=641-78147
203
210
  - options 제공 금지 — 자유 텍스트 입력만 허용
211
+ - 디자인 URL 최소 1개 필수
204
212
 
205
- "없음" 응답 → 스토리보드 분석 스킵
213
+ ### 입력 분류 (자동)
214
+
215
+ ```
216
+ 각 줄을 파싱하여 분류:
217
+
218
+ 1. figma.com URL → Figma 리소스
219
+ → ROOT name으로 스토리보드/MO/PC 판별
220
+ → fileKey가 다르면 스토리보드 vs 디자인 구분
221
+ → ROOT name에 "MO" → 모바일, "PC" → 데스크탑
222
+
223
+ 2. .pdf 파일 경로 → PDF 스토리보드
224
+ → Read 도구로 페이지별 분석
225
+
226
+ 3. .png/.jpg/.webp 파일 경로 → 이미지 스토리보드
227
+ → Read 도구로 시각 분석
228
+ ```
206
229
 
207
230
  ### 1-1. 스토리보드 분석
208
231
 
209
232
  ```
210
- URL에서 fileKey, nodeId 추출
233
+ 입력 타입에 따라 분기:
234
+
235
+ ■ Figma URL인 경우:
236
+ URL에서 fileKey, nodeId 추출
211
237
 
212
238
  1단계 (BLOCKING): 루트 depth=2로 전체 프레임 + nodeId 수집
213
239
  # [FIGMA_SCRIPT] = ~/.vibe/hooks/scripts/figma-extract.js
@@ -229,9 +255,22 @@ URL에서 fileKey, nodeId 추출
229
255
  하위 케이스(3.1.1, 3.2.1 등)는 건너뜀
230
256
  4순위: SHARED (공통 요소, Popup) — 필요 시
231
257
 
232
- 높이 1500px 이상 프레임:
233
- node "[FIGMA_SCRIPT]" screenshot으로 시각 파악
234
- 또는 depth 높여서 하위 분할 조회
258
+ PDF 파일인 경우:
259
+ Read 도구로 페이지별 분석 (pages: "1-5" "6-10" → ...)
260
+ 페이지에서 추출:
261
+ - 섹션 목록 + 기능 정의
262
+ - 해상도/브레이크포인트 정보 (CONFIG)
263
+ - 인터랙션 흐름
264
+ - 상태 정의
265
+ → Figma 스토리보드와 동일한 기능 스펙 문서 생성
266
+
267
+ ■ 이미지 파일인 경우:
268
+ Read 도구로 시각 분석
269
+ → 와이어프레임/목업에서 섹션 구조 + 기능 추출
270
+
271
+ ■ 스토리보드 없음:
272
+ 디자인 URL의 tree.json에서 섹션 목록만 추출
273
+ → 기능 정의는 디자인 name/구조에서 추정 (정확도 낮음)
235
274
  ```
236
275
 
237
276
  ### 1-2. 기능 스펙 문서 작성 (파일 생성 없음)
@@ -353,8 +392,8 @@ URL에서 fileKey, nodeId 추출
353
392
  부분 실패 처리:
354
393
  - 개별 URL 추출 실패 시 해당 frame만 건너뛰고 나머지 진행
355
394
  - 실패한 frame은 사용자에게 즉시 보고: "frame-{N} 추출 실패: {에러 사유}" (API 에러, 권한 부족, 잘못된 nodeId 등)
356
- - 성공한 frame ≥ 2: Phase 2.5 계속 진행
357
- - 정확히 1개만 성공: 단일 프레임 모드로 폴백 (Phase 2.5 스킵)
395
+ - 성공한 frame ≥ 2: Phase 3 계속 진행
396
+ - 정확히 1개만 성공: 단일 프레임 모드로 폴백 (Phase 3 스킵)
358
397
  - 0개 성공: 전체 실패 보고
359
398
 
360
399
  결과:
@@ -368,10 +407,10 @@ URL에서 fileKey, nodeId 추출
368
407
  │ └── ...
369
408
  ├── frame-3/ ← 서브 페이지 2
370
409
  │ └── ...
371
- └── shared/ 공통 분석 결과 (Phase 2.5에서 생성)
410
+ └── sections/ Phase 6 검증용 스크린샷
372
411
  ```
373
412
 
374
- ### 2-2. 재료함 정리
413
+ ### 2-2. 추출 데이터 정리
375
414
 
376
415
  ```
377
416
  Phase 2 완료 시 /tmp/{feature}/ 에 다음이 준비되어야 함:
@@ -468,9 +507,8 @@ UI 요소 → vw 비례:
468
507
 
469
508
  ## Phase 4: 순차 코드 생성
470
509
 
471
- **Phase 1에서 만든 컴포넌트에 Phase 2의 재료로 디자인을 입힌다.**
472
- **스크린샷을 보면서 퍼즐을 맞추듯 조립한다.**
473
- **첫 섹션(Hero) 단독 완료 후 나머지 섹션 병렬 진행.**
510
+ **remapped.json 기반으로 섹션별 순차 코드 생성.**
511
+ **한 섹션 완료 브라우저 확인 → 다음 섹션. 병렬 금지.**
474
512
 
475
513
  **멀티 프레임 모드 시 조립 순서 변경:**
476
514
  ```
@@ -505,13 +543,13 @@ UI 요소 → vw 비례:
505
543
  ```
506
544
  Phase 1에서 생성한 빈 SCSS 파일에 기본 내용 Write:
507
545
  styles/{feature}/index.scss ← @import 진입점
508
- styles/{feature}/_tokens.scss ← 재료함에서 추출한 디자인 토큰
546
+ styles/{feature}/_tokens.scss ← tree.json에서 추출한 디자인 토큰
509
547
  styles/{feature}/_mixins.scss ← breakpoint mixin
510
548
  styles/{feature}/_base.scss ← 루트 클래스
511
549
 
512
550
  토큰 매핑 (기존 토큰 우선 사용):
513
551
  1. /tmp/{feature}/project-tokens.json 을 Read로 로드
514
- 2. Figma 재료함의 각 값에 대해 project-tokens에서 동일 값 검색:
552
+ 2. Figma tree.json의 각 값에 대해 project-tokens에서 동일 값 검색:
515
553
  - 색상: hex 정규화 후 완전 일치 (Figma RGBA 0-1 → hex, 3자리→6자리, 대소문자 무시)
516
554
  ※ alpha < 1: 8자리 hex (#RRGGBBAA) 또는 rgba() 함수로 변환
517
555
  - 간격: px 값 완전 일치 (rem→px: 1rem=16px)
@@ -690,7 +728,7 @@ URL 있으면:
690
728
 
691
729
  ## Phase 5: 컴파일 게이트
692
730
 
693
- **Phase 3 퍼즐 조립 완료 후, 브라우저 검증 전에 컴파일 성공을 보장한다.**
731
+ **Phase 3 코드 생성 완료 후, 브라우저 검증 전에 컴파일 성공을 보장한다.**
694
732
  **컴파일 에러는 스킵 불가 — 반드시 수정 또는 사용자 보고.**
695
733
  **Phase 5 실패 시 Phase 4 진행 불가 (hard gate).**
696
734
 
@@ -860,7 +898,7 @@ import { getComputedStyles, compareStyles, diffsToIssues } from 'src/infra/lib/b
860
898
  'background-color', 'border-radius', 'gap',
861
899
  ])
862
900
 
863
- 2. Figma 재료함의 기대값과 비교:
901
+ 2. Figma tree.json의 기대값과 비교:
864
902
  // tree.json에서 해당 노드의 CSS 수치 (vw/clamp 변환 후)
865
903
  const expected = { 'font-size': '16px', 'color': '#ffffff', 'width': '465px' }
866
904
  const diffs = compareStyles(expected, actual)
@@ -884,7 +922,7 @@ import { extractImages, extractTextContent } from 'src/infra/lib/browser'
884
922
 
885
923
  2. 텍스트 콘텐츠 확인:
886
924
  const texts = await extractTextContent(page)
887
- 재료함의 TEXT 노드 characters와 대조
925
+ tree.json의 TEXT 노드 characters와 대조
888
926
  → 누락된 텍스트 = P1
889
927
  ```
890
928
 
@@ -896,9 +934,9 @@ import { extractImages, extractTextContent } from 'src/infra/lib/browser'
896
934
  2. P1 이슈 우선 수정:
897
935
  - 이미지 누락 → 이미지 경로 확인, static/ 에 파일 존재 확인
898
936
  - 레이아웃 다름 → 스크린샷 diff 이미지 + computed CSS로 원인 파악
899
- - 텍스트 누락 → 재료함의 정확한 텍스트 삽입
900
- - CSS 수치 틀림 → 재료함(tree.json)의 정확한 값으로 교체
901
- ⚠️ 추정으로 수정하지 않는다. 반드시 재료함 참조.
937
+ - 텍스트 누락 → tree.json의 정확한 텍스트 삽입
938
+ - CSS 수치 틀림 → tree.json(tree.json)의 정확한 값으로 교체
939
+ ⚠️ 추정으로 수정하지 않는다. 반드시 tree.json 참조.
902
940
  3. 수정 후 컴파일 재검증:
903
941
  Bash: npx tsc --noEmit 2>&1 (또는 3.5-1에서 선택한 타입 체커)
904
942
  → 시각 수정이 타입 에러를 유발하면 즉시 타입 에러 수정 후 진행
@@ -68,9 +68,14 @@ component-index (/tmp/{feature}/component-index.json) 에서 매칭되는 컴포
68
68
  children 없음 → 빈 div 또는 스킵
69
69
 
70
70
  2. 배경 레이어 판별:
71
- 부모와 동일 크기(±5%) + imageRef 있음 + z-index 낮음
72
- position:absolute + inset:0 + object-fit:cover
73
- 부모에 position:relative + overflow:hidden 추가
71
+ BG 프레임 (name에 "BG"/"bg" 또는 부모와 동일 크기)
72
+ <img> 태그로 배경 처리 금지
73
+ position:absolute + inset:0 으로 이미지 배치 금지
74
+ ✅ 부모 요소에 CSS background-image로 처리:
75
+ background-image: url('/images/{feature}/{section}-bg.png');
76
+ background-size: cover;
77
+ background-position: center top;
78
+ ✅ BG 프레임은 HTML에 아무것도 렌더링하지 않음 (CSS만)
74
79
 
75
80
  3. 반복 패턴 감지:
76
81
  같은 부모 아래 동일 타입 + 유사 구조(children 수 동일) 노드 3개 이상
@@ -192,6 +197,27 @@ tree.json의 css 객체를 SCSS로 직접 변환한다. 추정하지 않는다.
192
197
 
193
198
  ## 2. 외부 SCSS 파일 구조
194
199
 
200
+ ### _base.scss (필수 — 래퍼 컨테이너)
201
+
202
+ ```scss
203
+ // 모바일 퍼스트: vw 단위가 PC에서 거대해지는 것을 방지
204
+ // designWidth(720px)를 max-width로 제한
205
+
206
+ .{feature} {
207
+ width: 100%;
208
+ max-width: 720px; // designWidth — PC에서 모바일 레이아웃 유지
209
+ margin: 0 auto; // 중앙 정렬
210
+ overflow-x: hidden;
211
+
212
+ // PC 브레이크포인트에서 max-width 확장 (PC 디자인이 있을 때)
213
+ @media (min-width: 1025px) {
214
+ max-width: 100%; // PC 디자인이 있으면 전체 너비
215
+ }
216
+ }
217
+ ```
218
+
219
+ 이 파일이 없으면 vw 단위가 PC 뷰포트에서 비례 확대되어 레이아웃이 깨진다.
220
+
195
221
  ### layout vs components 구분
196
222
 
197
223
  ```
@@ -319,10 +345,8 @@ $bp-desktop: 1024px;
319
345
  -->
320
346
  <template>
321
347
  <section class="heroSection">
322
- <!-- BG: 부모와 동일 크기 + imageRef 배경 레이어 -->
323
- <div class="heroBg">
324
- <img src="/images/{feature}/hero-bg.png" alt="" aria-hidden="true" />
325
- </div>
348
+ <!-- BG: CSS background-image로 처리 (img 태그 아님!) -->
349
+ <!-- .heroSection { background-image: url('/images/{feature}/hero-bg.png'); background-size: cover; } -->
326
350
 
327
351
  <!-- Title: flex-column, gap:24px → 직접 매핑 -->
328
352
  <div class="heroTitle">
@@ -407,9 +431,10 @@ function handleShare(): void {
407
431
  트리 노드의 속성으로 이미지 유형을 판별한다:
408
432
 
409
433
  배경 이미지:
410
- 조건: imageRef 있음 + 부모와 크기 동일(±5%) + 형제 중 가장 먼저 위치
411
- 매핑: position:absolute + inset:0 + z-index:0 + object-fit:cover
412
- 태그: <img alt="" aria-hidden="true" />
434
+ 조건: BG 프레임 (name에 BG/bg 또는 부모와 크기 동일)
435
+ <img> 태그 금지
436
+ CSS background-image로만 처리:
437
+ 부모 { background-image: url('...'); background-size: cover; }
413
438
 
414
439
  콘텐츠 이미지:
415
440
  조건: imageRef 있음 + 독립적 크기 + TEXT 형제 없음
@@ -20,10 +20,8 @@ tree.json 노드를 기반으로 컴포넌트를 생성할 때 이 템플릿을
20
20
  -->
21
21
  <template>
22
22
  <section class="{{sectionName}}">
23
- <!-- BG: 부모와 동일 크기 + imageRef 배경 레이어 -->
24
- <div class="{{sectionName}}__bg">
25
- <img src="/images/{{FEATURE_KEY}}/{{bg-file}}.png" alt="" aria-hidden="true" />
26
- </div>
23
+ <!-- BG: CSS background-image로 처리. img 태그 사용 금지! -->
24
+ <!-- SCSS: .{{sectionName}} { background-image: url('/images/{{FEATURE_KEY}}/{{bg-file}}.png'); background-size: cover; } -->
27
25
 
28
26
  <!-- {{CHILD_1}}: tree flex-column, gap:{{GAP}}px → 직접 매핑 -->
29
27
  <div class="{{sectionName}}__{{child1Name}}">
@@ -99,6 +99,11 @@ Bash:
99
99
  ```
100
100
  각 섹션의 BG 프레임을 식별 → 합성된 배경 1장으로 렌더링:
101
101
 
102
+ ⚠️ 주의: BG 프레임만 렌더링한다 (텍스트 포함된 상위 프레임 렌더링 금지)
103
+ ❌ 섹션 전체를 렌더링 → 텍스트가 이미지에 포함 → HTML 텍스트와 중복
104
+ ✅ BG 하위 프레임만 렌더링 → 텍스트 없는 배경만 → CSS background-image
105
+ ✅ 텍스트는 tree.json에서 추출하여 HTML로 작성
106
+
102
107
  BG 프레임 판별 기준:
103
108
  - name에 "BG", "bg" 포함
104
109
  - 또는 부모와 크기 동일(±10%) + 자식 이미지 3개 이상