@su-record/vibe 2.9.1 → 2.9.3
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/CLAUDE.md +31 -10
- package/README.ko.md +90 -25
- package/README.md +139 -25
- package/agents/teams/debug-team.md +70 -0
- package/agents/teams/dev-team.md +88 -0
- package/agents/teams/docs-team.md +80 -0
- package/agents/teams/figma/figma-analyst.md +52 -0
- package/agents/teams/figma/figma-architect.md +112 -0
- package/agents/teams/figma/figma-auditor.md +82 -0
- package/agents/teams/figma/figma-builder.md +100 -0
- package/agents/teams/figma-team.md +85 -0
- package/agents/teams/fullstack-team.md +83 -0
- package/agents/teams/lite-team.md +69 -0
- package/agents/teams/migration-team.md +78 -0
- package/agents/teams/refactor-team.md +94 -0
- package/agents/teams/research-team.md +86 -0
- package/agents/teams/review-debate-team.md +125 -0
- package/agents/teams/security-team.md +81 -0
- package/commands/vibe.analyze.md +324 -170
- package/commands/vibe.figma.md +549 -34
- package/commands/vibe.harness.md +177 -0
- package/commands/vibe.review.md +1 -63
- package/commands/vibe.run.md +52 -403
- package/commands/vibe.scaffold.md +195 -0
- package/commands/vibe.spec.md +373 -1003
- package/commands/vibe.trace.md +17 -0
- package/commands/vibe.verify.md +19 -10
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +29 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +4 -2
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/postinstall/constants.d.ts +1 -1
- package/dist/cli/postinstall/constants.d.ts.map +1 -1
- package/dist/cli/postinstall/constants.js +6 -1
- package/dist/cli/postinstall/constants.js.map +1 -1
- package/dist/cli/setup/ProjectSetup.d.ts +12 -1
- package/dist/cli/setup/ProjectSetup.d.ts.map +1 -1
- package/dist/cli/setup/ProjectSetup.js +259 -72
- package/dist/cli/setup/ProjectSetup.js.map +1 -1
- package/dist/cli/setup.d.ts +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +1 -1
- package/dist/cli/setup.js.map +1 -1
- package/hooks/scripts/figma-guard.js +220 -0
- package/hooks/scripts/figma-refine.js +315 -0
- package/hooks/scripts/figma-to-scss.js +394 -0
- package/hooks/scripts/figma-validate.js +353 -0
- package/package.json +1 -1
- package/skills/arch-guard/SKILL.md +1 -1
- package/skills/capability-loop/SKILL.md +106 -2
- package/skills/chub-usage/SKILL.md +43 -43
- package/skills/claude-md-guide/SKILL.md +175 -175
- package/skills/design-teach/SKILL.md +33 -33
- package/skills/devlog/SKILL.md +38 -38
- package/skills/event-comms/SKILL.md +23 -13
- package/skills/event-ops/SKILL.md +28 -19
- package/skills/event-planning/SKILL.md +13 -1
- package/skills/priority-todos/SKILL.md +1 -1
- package/skills/vibe.figma/SKILL.md +263 -115
- package/skills/vibe.figma/templates/component-spec.md +168 -0
- package/skills/vibe.figma.convert/SKILL.md +131 -84
- package/skills/vibe.figma.convert/rubrics/conversion-rules.md +12 -0
- package/skills/vibe.figma.extract/SKILL.md +148 -108
- package/skills/vibe.figma.extract/rubrics/image-rules.md +15 -3
- package/skills/vibe.interview/SKILL.md +358 -0
- package/skills/vibe.interview/checklists/api.md +101 -0
- package/skills/vibe.interview/checklists/feature.md +88 -0
- package/skills/vibe.interview/checklists/library.md +95 -0
- package/skills/vibe.interview/checklists/mobile.md +89 -0
- package/skills/vibe.interview/checklists/webapp.md +97 -0
- package/skills/vibe.interview/checklists/website.md +99 -0
- package/skills/vibe.plan/SKILL.md +216 -0
- package/skills/vibe.spec/SKILL.md +1155 -0
- package/{commands/vibe.spec.review.md → skills/vibe.spec.review/SKILL.md} +272 -155
- package/vibe/templates/claudemd-template.md +74 -0
- package/vibe/templates/constitution-template.md +15 -0
- package/vibe/templates/plan-template.md +194 -0
|
@@ -1,59 +1,59 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vibe.figma
|
|
3
|
-
description: Figma design to code —
|
|
3
|
+
description: Figma design to code — tree-based structural code generation
|
|
4
4
|
triggers: []
|
|
5
5
|
tier: standard
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# vibe.figma — Structural Code Generation
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Core Principles
|
|
11
11
|
|
|
12
12
|
```
|
|
13
|
-
Figma
|
|
13
|
+
The Figma tree is the source of truth for code. Screenshots are for verification only.
|
|
14
14
|
|
|
15
|
-
✅ Figma Auto Layout → CSS Flexbox 1:1
|
|
16
|
-
✅ Figma CSS
|
|
17
|
-
✅ Claude
|
|
18
|
-
✅
|
|
15
|
+
✅ Figma Auto Layout → CSS Flexbox 1:1 mechanical mapping
|
|
16
|
+
✅ Figma CSS properties → SCSS direct conversion (no guessing)
|
|
17
|
+
✅ Claude handles semantic decisions only: tag selection, component splitting, interactions
|
|
18
|
+
✅ Screenshots are used for verification only, not generation
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## Immutable Rules
|
|
22
22
|
|
|
23
23
|
```
|
|
24
|
-
1.
|
|
25
|
-
✅ BG
|
|
26
|
-
❌ TEXT
|
|
24
|
+
1. Do NOT render content as images via screenshot
|
|
25
|
+
✅ BG rendering (backgrounds with no TEXT children), vector-text GROUPs, section screenshots (verification only)
|
|
26
|
+
❌ Frames with TEXT children, INSTANCE repetitions, buttons/prices, rendering entire sections
|
|
27
27
|
|
|
28
|
-
2. BG
|
|
28
|
+
2. BG must use CSS background-image only. <img> tag is forbidden.
|
|
29
29
|
|
|
30
|
-
3.
|
|
31
|
-
Phase 2
|
|
30
|
+
3. No new screenshot calls during Phase 4 code generation.
|
|
31
|
+
Use only Phase 2 materials. No matter how complex — implement with HTML+CSS.
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
##
|
|
34
|
+
## Full Flow
|
|
35
35
|
|
|
36
36
|
```
|
|
37
|
-
|
|
38
|
-
Storyboard: figma.com/...?node-id=aaa (
|
|
37
|
+
Input: receive all URLs at once
|
|
38
|
+
Storyboard: figma.com/...?node-id=aaa (if present)
|
|
39
39
|
MO Design: figma.com/...?node-id=xxx
|
|
40
|
-
PC Design: figma.com/...?node-id=yyy (
|
|
40
|
+
PC Design: figma.com/...?node-id=yyy (if present)
|
|
41
41
|
|
|
42
42
|
→ Phase 0: Setup
|
|
43
|
-
→ Phase 1:
|
|
44
|
-
→ Phase 2:
|
|
45
|
-
→ Phase 3:
|
|
46
|
-
→ Phase 4:
|
|
47
|
-
→ Phase 5:
|
|
48
|
-
→ Phase 6:
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
→ Phase 1: Storyboard analysis → functional spec document
|
|
44
|
+
→ Phase 2: Gather materials (→ vibe.figma.extract)
|
|
45
|
+
→ Phase 3: Remapping (MO↔PC matching → remapped.json)
|
|
46
|
+
→ Phase 4: Sequential code generation (→ vibe.figma.convert)
|
|
47
|
+
→ Phase 5: Compile gate
|
|
48
|
+
→ Phase 6: Visual verification loop
|
|
49
|
+
|
|
50
|
+
Working directory:
|
|
51
51
|
/tmp/{feature}/
|
|
52
52
|
├── mo-main/tree.json, bg/, content/, sections/
|
|
53
53
|
├── pc-main/tree.json, bg/, content/, sections/
|
|
54
|
-
└── remapped.json ← Phase 4
|
|
54
|
+
└── remapped.json ← sole input for Phase 4
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Code output: placed directly in the project directory
|
|
57
57
|
components/{feature}/, styles/{feature}/
|
|
58
58
|
```
|
|
59
59
|
|
|
@@ -62,154 +62,302 @@ Figma 트리가 코드의 원천이다. 스크린샷은 검증용이다.
|
|
|
62
62
|
## Phase 0: Setup
|
|
63
63
|
|
|
64
64
|
```
|
|
65
|
-
1.
|
|
66
|
-
2.
|
|
67
|
-
3.
|
|
68
|
-
4.
|
|
69
|
-
(50
|
|
65
|
+
1. Stack detection: package.json → react/vue/svelte, next/nuxt, scss/tailwind
|
|
66
|
+
2. Feature name: Figma filename → kebab-case
|
|
67
|
+
3. Directories: components/{feature}/, public/images/{feature}/, styles/{feature}/
|
|
68
|
+
4. Component indexing → /tmp/{feature}/component-index.json
|
|
69
|
+
(scan up to 50 components, extract props/slots/classes, within 2 minutes)
|
|
70
70
|
5. Hooks/Types/Constants → /tmp/{feature}/context-index.json
|
|
71
|
-
6.
|
|
71
|
+
6. Design token scan → /tmp/{feature}/project-tokens.json
|
|
72
72
|
(SCSS > CSS Variables > Tailwind > CSS-in-JS)
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
---
|
|
76
76
|
|
|
77
|
-
## Phase 1:
|
|
77
|
+
## Phase 1: Storyboard Analysis
|
|
78
78
|
|
|
79
79
|
```
|
|
80
|
-
|
|
80
|
+
User input: enter URLs or PDF/images separated by newlines
|
|
81
81
|
|
|
82
|
-
URL
|
|
83
|
-
fileKey
|
|
84
|
-
ROOT name
|
|
82
|
+
URL classification (automatic):
|
|
83
|
+
Different fileKey → storyboard vs design
|
|
84
|
+
ROOT name contains "MO" → mobile, "PC" → desktop
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
depth=
|
|
88
|
-
SPEC(
|
|
89
|
-
PDF
|
|
86
|
+
Storyboard analysis:
|
|
87
|
+
Collect frames at depth=3 → classify by name pattern
|
|
88
|
+
SPEC (functional definition) → CONFIG (resolution) → PAGE (main sections) → SHARED (common)
|
|
89
|
+
PDF/images follow the same structural extraction
|
|
90
90
|
|
|
91
|
-
❌
|
|
91
|
+
❌ No code file creation during Phase 1
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
1.
|
|
95
|
-
2.
|
|
96
|
-
3.
|
|
97
|
-
4. TypeScript
|
|
93
|
+
Output (text only):
|
|
94
|
+
1. Section list table (name, Figma name, height, description)
|
|
95
|
+
2. Functional definition per section ([Function] + [Interaction] + [State])
|
|
96
|
+
3. Common component list
|
|
97
|
+
4. TypeScript interface draft
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
---
|
|
101
101
|
|
|
102
|
-
## Phase 2:
|
|
102
|
+
## Phase 2: Gather Materials ← Research (parallel)
|
|
103
103
|
|
|
104
|
-
**→ vibe.figma.extract
|
|
105
|
-
|
|
104
|
+
**→ Follow the rules of the vibe.figma.extract skill.**
|
|
105
|
+
**Coordinator pattern: run MO/PC extraction as parallel workers.**
|
|
106
106
|
|
|
107
107
|
```
|
|
108
|
-
# [FIGMA_SCRIPT] =
|
|
108
|
+
# [FIGMA_SCRIPT] = {{VIBE_PATH}}/hooks/scripts/figma-extract.js
|
|
109
109
|
|
|
110
|
-
MO/PC
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
→
|
|
110
|
+
Simultaneous MO/PC extraction (each as an independent worker):
|
|
111
|
+
Worker-MO: screenshot → tree → images → asset rendering → sections/
|
|
112
|
+
Worker-PC: screenshot → tree → images → asset rendering → sections/
|
|
113
|
+
→ Proceed to Phase 3 only after both workers have completed
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
Single BP: run sequentially with 1 worker
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
Multi-frame (same BP, different pages):
|
|
118
|
+
Sequential extraction (500ms interval), partial failure allowed
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
---
|
|
122
122
|
|
|
123
|
-
## Phase 3:
|
|
123
|
+
## Phase 3: Data Refinement ← Synthesis (independent per BP)
|
|
124
124
|
|
|
125
|
-
**
|
|
126
|
-
|
|
127
|
-
**리더가 두 tree를 모두 이해한 상태에서 diff를 추출해야 품질 보장.**
|
|
125
|
+
**Split and refine each BP's tree.json by section.**
|
|
126
|
+
**MO↔PC matching (responsive) is NOT done at this stage.**
|
|
128
127
|
|
|
129
|
-
###
|
|
128
|
+
### BLOCKING Command — Writing custom refine scripts is strictly forbidden
|
|
130
129
|
|
|
130
|
+
```bash
|
|
131
|
+
# MO
|
|
132
|
+
node {{VIBE_PATH}}/hooks/scripts/figma-refine.js \
|
|
133
|
+
/tmp/{feature}/mo-main/tree.json \
|
|
134
|
+
--out=/tmp/{feature}/mo-main/sections.json \
|
|
135
|
+
--design-width=720 \
|
|
136
|
+
--bp=mo
|
|
137
|
+
|
|
138
|
+
# PC
|
|
139
|
+
node {{VIBE_PATH}}/hooks/scripts/figma-refine.js \
|
|
140
|
+
/tmp/{feature}/pc-main/tree.json \
|
|
141
|
+
--out=/tmp/{feature}/pc-main/sections.json \
|
|
142
|
+
--design-width=2560 \
|
|
143
|
+
--bp=pc
|
|
131
144
|
```
|
|
132
|
-
1. 섹션 매칭: 1depth name 기준 (완전일치 → prefix → 순서)
|
|
133
|
-
2. 노드 매칭: 재귀적 name 매칭 → CSS diff 추출
|
|
134
|
-
3. diff: 같은 값 유지, 다른 값만 @media 오버라이드
|
|
135
145
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
146
|
+
⛔ **Phase 4 is blocked until these commands are executed.**
|
|
147
|
+
⛔ **Do NOT write custom refine scripts** (refine-sections.mjs, refine.js, etc. — all forbidden)
|
|
148
|
+
⛔ **Do NOT parse tree.json directly with Python/Node to produce sections.json**
|
|
149
|
+
✅ Use only the output of figma-refine.js. If the output is unsatisfactory, modify figma-refine.js.
|
|
150
|
+
|
|
151
|
+
### Core Principles
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
⛔ Refine each BP independently. Do NOT mix MO and PC.
|
|
155
|
+
⛔ The refined JSON is the sole input for Phase 4.
|
|
156
|
+
⛔ The full subtree (recursive children) for each section must be included.
|
|
142
157
|
```
|
|
143
158
|
|
|
144
|
-
###
|
|
159
|
+
### Output
|
|
145
160
|
|
|
146
161
|
```
|
|
147
|
-
|
|
148
|
-
|
|
162
|
+
/tmp/{feature}/
|
|
163
|
+
mo-main/
|
|
164
|
+
sections.json ← MO refinement result
|
|
165
|
+
pc-main/
|
|
166
|
+
sections.json ← PC refinement result
|
|
167
|
+
|
|
168
|
+
sections.json structure:
|
|
169
|
+
{
|
|
170
|
+
meta: { feature, designWidth, bp (the corresponding BP) },
|
|
171
|
+
sections: [
|
|
172
|
+
{
|
|
173
|
+
name: "Hero",
|
|
174
|
+
nodeId, name, type, size, css,
|
|
175
|
+
text, // TEXT nodes only
|
|
176
|
+
imageRef, // image fill
|
|
177
|
+
fills, // multiple fills (2 or more)
|
|
178
|
+
layoutSizingH, // HUG/FILL/FIXED
|
|
179
|
+
layoutSizingV,
|
|
180
|
+
children: [ // ⛔ full recursive subtree — down to leaf nodes
|
|
181
|
+
{ nodeId, name, type, size, css, children: [...] }
|
|
182
|
+
],
|
|
183
|
+
images: {
|
|
184
|
+
bg: "bg/hero-bg.webp",
|
|
185
|
+
content: ["content/hero-title.webp"]
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
}
|
|
149
190
|
```
|
|
150
191
|
|
|
151
|
-
|
|
192
|
+
### Node Refinement Rules
|
|
152
193
|
|
|
153
|
-
|
|
194
|
+
```
|
|
195
|
+
Refinement applied when converting tree.json → sections.json:
|
|
196
|
+
1. Nodes with size 0px → remove
|
|
197
|
+
2. VECTOR decorative lines (w/h ≤ 2px) → remove
|
|
198
|
+
3. isMask nodes → remove
|
|
199
|
+
4. BG frames → separate from children, move to images.bg
|
|
200
|
+
5. Vector-text GROUPs → separate from children, add to images.content
|
|
201
|
+
6. Design text (TEXT with multiple/gradient fills or effects) → add to images.content
|
|
202
|
+
7. Remaining nodes → keep in children (with CSS, recursive)
|
|
203
|
+
```
|
|
154
204
|
|
|
155
|
-
|
|
156
|
-
**코디네이터 패턴: 섹션 = 영역. 한 영역에 한 워커만. 충돌 방지.**
|
|
205
|
+
### Multi-frame (same BP, different pages)
|
|
157
206
|
|
|
158
207
|
```
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
208
|
+
Identify common elements → extract shared components
|
|
209
|
+
Union of common tokens → shared _tokens.scss
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Phase 4: Per-BP Static Implementation ← Implement (sequential per BP)
|
|
164
215
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
216
|
+
**→ Follow the rules of the vibe.figma.convert skill.**
|
|
217
|
+
**⛔ Implement MO fully first → pass verification → then implement PC. No responsive conversion.**
|
|
218
|
+
**⛔ CSS values must use Figma original px as-is. vw conversion, clamp, @media are forbidden.**
|
|
168
219
|
|
|
169
|
-
|
|
170
|
-
component-index.json과 대조 → 매칭되면 import, 안 되면 새 생성
|
|
220
|
+
### BLOCKING Command — SCSS must only use script output
|
|
171
221
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
222
|
+
```bash
|
|
223
|
+
# Step A: Auto-generate SCSS skeleton (run once per BP)
|
|
224
|
+
node {{VIBE_PATH}}/hooks/scripts/figma-to-scss.js \
|
|
225
|
+
/tmp/{feature}/{bp}-main/sections.json \
|
|
226
|
+
--out=/path/to/project/assets/scss/{feature}/
|
|
227
|
+
|
|
228
|
+
# Step B: Per-section validation (after writing each section's code)
|
|
229
|
+
node {{VIBE_PATH}}/hooks/scripts/figma-validate.js \
|
|
230
|
+
/path/to/project/assets/scss/{feature}/ \
|
|
231
|
+
/tmp/{feature}/{bp}-main/sections.json \
|
|
232
|
+
--section={SectionName}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
⛔ **Writing SCSS files directly without calling figma-to-scss.js invalidates Phase 4.**
|
|
236
|
+
⛔ **Do NOT write custom SCSS generation scripts** (to-scss.mjs, generate-scss.js, etc. — all forbidden)
|
|
237
|
+
⛔ **Do NOT proceed to the next section without a figma-validate.js PASS.**
|
|
238
|
+
⛔ **Do NOT write CSS values directly inside scoped style blocks** — only @import of external SCSS files is allowed.
|
|
239
|
+
✅ Use figma-to-scss.js output as-is. If unsatisfactory, modify figma-to-scss.js.
|
|
240
|
+
|
|
241
|
+
```
|
|
242
|
+
Phase 4A: MO Static Implementation
|
|
243
|
+
Input: /tmp/{feature}/mo-main/sections.json
|
|
244
|
+
⛔ No parallelism. Process one section at a time:
|
|
245
|
+
1. Read the target section from sections.json
|
|
246
|
+
2. Write an image vs HTML classification table (BLOCKING)
|
|
247
|
+
3. figma-to-scss.js → auto-generate SCSS skeleton (px as-is) — Step A once
|
|
248
|
+
4. Claude: HTML structure + semantic tags + layout + interactions (Vue/React files only)
|
|
249
|
+
⛔ No CSS written directly in <style> blocks — only @import or @use allowed
|
|
250
|
+
5. figma-validate.js → compare SCSS vs sections.json — Step B
|
|
251
|
+
├─ PASS → next section
|
|
252
|
+
└─ FAIL → fix discrepancies → re-run step 5 (repeat until P1=0, no round cap)
|
|
253
|
+
→ Phase 5 (MO compile) → Phase 6 (MO visual verification)
|
|
254
|
+
|
|
255
|
+
Phase 4B: PC Static Implementation
|
|
256
|
+
Input: /tmp/{feature}/pc-main/sections.json
|
|
257
|
+
Same process as MO
|
|
258
|
+
→ Phase 5 (PC compile) → Phase 6 (PC visual verification)
|
|
259
|
+
|
|
260
|
+
Phase 4C: Responsive Integration (after both MO+PC pass verification)
|
|
261
|
+
→ Separate flow to be established (TODO)
|
|
262
|
+
|
|
263
|
+
Claude's role (restricted):
|
|
264
|
+
✅ Image classification: BG / content / decoration / vector-text
|
|
265
|
+
✅ HTML semantics: section/h1/p/button tag selection
|
|
266
|
+
✅ Component splitting: v-for repetition, shared components
|
|
267
|
+
✅ Interactions: @click, state variables, conditional rendering
|
|
268
|
+
✅ Execute figma-to-scss.js / figma-validate.js commands
|
|
269
|
+
❌ Do NOT modify SCSS CSS values (use figma-to-scss.js output as-is)
|
|
270
|
+
❌ Do NOT write CSS directly in <style> blocks
|
|
271
|
+
❌ Do NOT use vw conversion, clamp, @media, or create custom functions/mixins
|
|
272
|
+
❌ Do NOT write custom refine/generate scripts (refine.mjs, to-scss.mjs, etc.)
|
|
273
|
+
|
|
274
|
+
SCSS Setup (before the first section):
|
|
275
|
+
index.scss, _tokens.scss, _base.scss
|
|
276
|
+
Token mapping: reference existing tokens from project-tokens.json → create new ones if no match
|
|
277
|
+
|
|
278
|
+
Component matching (before each section):
|
|
279
|
+
Compare against component-index.json → import if matched, create new if not
|
|
280
|
+
|
|
281
|
+
Multi-frame:
|
|
282
|
+
Step 1: shared components first → components/shared/
|
|
283
|
+
Step 2: unique sections per frame
|
|
175
284
|
```
|
|
176
285
|
|
|
177
286
|
---
|
|
178
287
|
|
|
179
|
-
## Phase 5:
|
|
288
|
+
## Phase 5: Compile Gate
|
|
180
289
|
|
|
181
290
|
```
|
|
182
|
-
|
|
291
|
+
No round cap. Loop until compile succeeds (or stuck → ask user).
|
|
183
292
|
|
|
184
|
-
0.
|
|
185
|
-
→ Phase 5
|
|
293
|
+
0. Capture baseline (before Phase 4): record existing tsc + build errors
|
|
294
|
+
→ Phase 5 only fixes NEW errors
|
|
186
295
|
|
|
187
296
|
1. TypeScript: vue-tsc/svelte-check/tsc --noEmit
|
|
188
|
-
2. Build: npm run build (
|
|
189
|
-
3. Dev
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
297
|
+
2. Build: npm run build (120s timeout)
|
|
298
|
+
3. Dev server: npm run dev → detect port → polling
|
|
299
|
+
|
|
300
|
+
On error: parse → auto-fix → re-check
|
|
301
|
+
Termination conditions:
|
|
302
|
+
✅ Success: all checks pass → enter Phase 6
|
|
303
|
+
⚠️ Stuck: same errors as previous round → ask user
|
|
304
|
+
1. Provide direct fix instructions → retry next round
|
|
305
|
+
2. "proceed" — record remaining errors as TODO, proceed to Phase 6
|
|
306
|
+
3. "abort" — halt workflow
|
|
307
|
+
ultrawork mode: on stuck, record TODO without prompting and proceed to Phase 6
|
|
308
|
+
|
|
309
|
+
On completion: preserve dev server PID → used in Phase 6
|
|
310
|
+
|
|
311
|
+
⛔ After Phase 5 passes (or user proceeds), must enter Phase 6. Do NOT output a "completion summary".
|
|
312
|
+
⛔ Do NOT declare work complete without Phase 6.
|
|
194
313
|
```
|
|
195
314
|
|
|
196
315
|
---
|
|
197
316
|
|
|
198
|
-
## Phase 6:
|
|
317
|
+
## Phase 6: Visual Verification Loop ← Verify (parallel) MANDATORY
|
|
199
318
|
|
|
200
|
-
|
|
319
|
+
**⛔ Phase 6 is mandatory, not optional. Enter automatically upon Phase 5 completion.**
|
|
320
|
+
**⛔ If Phase 6 is skipped, the entire task is considered "incomplete".**
|
|
321
|
+
**Coordinator pattern: independent per-section verification can be run as parallel workers.**
|
|
201
322
|
|
|
202
323
|
```
|
|
203
|
-
|
|
204
|
-
|
|
324
|
+
No round cap. Loop until P1=0 (or stuck → ask user).
|
|
325
|
+
Infrastructure: src/infra/lib/browser/ (Puppeteer + CDP)
|
|
205
326
|
|
|
206
|
-
1.
|
|
327
|
+
1. Capture rendered screenshot → pixelmatch comparison against Figma screenshot
|
|
207
328
|
diffRatio > 0.1 → P1
|
|
208
|
-
2. CSS
|
|
329
|
+
2. CSS value comparison: computed CSS vs tree.json expected values
|
|
209
330
|
delta > 4px → P1, ≤ 4px → P2
|
|
210
|
-
3.
|
|
211
|
-
4. P1
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
331
|
+
3. Check for missing images and text
|
|
332
|
+
4. Fix P1 issues first (refer to tree.json, no guessing) → revalidate compile → reload
|
|
333
|
+
|
|
334
|
+
Narrowing scope (noise reduction):
|
|
335
|
+
Round 1: P1+P2+P3 all
|
|
336
|
+
Round 2: P1+P2
|
|
337
|
+
Round 3+: P1 only (continue until P1=0)
|
|
338
|
+
|
|
339
|
+
Termination conditions:
|
|
340
|
+
✅ Success: P1 = 0 AND no new findings → complete
|
|
341
|
+
⚠️ Stuck: same findings as previous round → ask user
|
|
342
|
+
1. Provide direct resolution → retry next round
|
|
343
|
+
2. "proceed" — record remaining issues as TODO, complete
|
|
344
|
+
3. "abort" — halt workflow
|
|
345
|
+
ultrawork mode: on stuck, record TODO without prompting and complete
|
|
346
|
+
|
|
347
|
+
Responsive: after MO verification, change viewport → same loop against PC screenshots
|
|
348
|
+
Cleanup: shut down browser + dev server
|
|
349
|
+
|
|
350
|
+
⛔ "Completion summary" output is only allowed after Phase 6 is complete (or user proceeds).
|
|
215
351
|
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Error Recovery
|
|
356
|
+
|
|
357
|
+
| Failure | Recovery |
|
|
358
|
+
|---------|----------|
|
|
359
|
+
| figma-extract.js script error | Check Node.js version (>=18 required). Verify Figma API token in config. Retry once. |
|
|
360
|
+
| figma-to-scss.js parse failure | Validate input tree.json structure. If malformed, re-run extract phase. |
|
|
361
|
+
| figma-validate.js comparison failure | Skip automated validation, present screenshot side-by-side for manual review |
|
|
362
|
+
| Puppeteer/CDP not available | Skip visual verification phase, rely on manual browser check |
|
|
363
|
+
| Figma API rate limit (429) | Wait 60s and retry. If persistent, reduce node scope. |
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# component-spec.json 템플릿
|
|
2
|
+
|
|
3
|
+
architect 에이전트가 sections.json을 분석하여 생성하는 설계서.
|
|
4
|
+
builder 에이전트는 이 설계서대로만 구현한다.
|
|
5
|
+
|
|
6
|
+
## 생성 규칙
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
입력: /tmp/{feature}/{bp}-main/sections.json
|
|
10
|
+
출력: /tmp/{feature}/{bp}-main/component-spec.json
|
|
11
|
+
|
|
12
|
+
⛔ CSS 값을 결정하지 않는다 (figma-to-scss.js가 담당)
|
|
13
|
+
⛔ SCSS 파일을 생성하지 않는다
|
|
14
|
+
✅ HTML 구조, 태그 선택, 컴포넌트 분리, 이미지 분류만 결정
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 구조
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"meta": {
|
|
22
|
+
"feature": "winter-pcbang",
|
|
23
|
+
"bp": "mo",
|
|
24
|
+
"designWidth": 720,
|
|
25
|
+
"stack": "nuxt2-vue2-scss"
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
"components": [
|
|
29
|
+
{
|
|
30
|
+
"name": "KidSection",
|
|
31
|
+
"sectionName": "KID",
|
|
32
|
+
"file": "components/{feature}/KidSection.vue",
|
|
33
|
+
"scssFile": "_kid.scss",
|
|
34
|
+
"tag": "section",
|
|
35
|
+
"id": "kid",
|
|
36
|
+
|
|
37
|
+
"bg": {
|
|
38
|
+
"image": "bg/kid-bg.webp",
|
|
39
|
+
"method": "css-background"
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
"elements": [
|
|
43
|
+
{
|
|
44
|
+
"class": "btn-login",
|
|
45
|
+
"tag": "button",
|
|
46
|
+
"role": "interactive",
|
|
47
|
+
"event": { "type": "click", "action": "emit('login')" },
|
|
48
|
+
"children": [
|
|
49
|
+
{
|
|
50
|
+
"class": "btn-login-btn-login",
|
|
51
|
+
"tag": "div",
|
|
52
|
+
"role": "layout"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"class": "btn-login-btn-login-krafton-id",
|
|
56
|
+
"tag": "img",
|
|
57
|
+
"role": "content-image",
|
|
58
|
+
"src": "content/kid-krafton-id.webp",
|
|
59
|
+
"alt": "KRAFTON ID 로그인"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"class": "krafton-id",
|
|
65
|
+
"tag": "p",
|
|
66
|
+
"role": "text",
|
|
67
|
+
"text": "KRAFTON ID로 로그인하고 이벤트에 참여하세요!..."
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"class": "steam-account",
|
|
71
|
+
"tag": "div",
|
|
72
|
+
"role": "layout",
|
|
73
|
+
"children": [
|
|
74
|
+
{
|
|
75
|
+
"class": "steam-account-frame-27161",
|
|
76
|
+
"tag": "a",
|
|
77
|
+
"role": "link",
|
|
78
|
+
"href": "#",
|
|
79
|
+
"children": [
|
|
80
|
+
{
|
|
81
|
+
"class": "steam-account-frame-27161-krafton-id-steam",
|
|
82
|
+
"tag": "span",
|
|
83
|
+
"role": "text",
|
|
84
|
+
"text": "KRAFTON ID Steam 연동 안내"
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"class": "steam-account-kakao-games-krafton-id",
|
|
90
|
+
"tag": "p",
|
|
91
|
+
"role": "text",
|
|
92
|
+
"text": "Kakao games는 게임 내에서만..."
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
|
|
98
|
+
"imageClassification": [
|
|
99
|
+
{
|
|
100
|
+
"node": "BG",
|
|
101
|
+
"decision": "bg",
|
|
102
|
+
"reason": "name='BG', 합성 배경, TEXT 자식 없음"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"node": "KRAFTON ID 로그인",
|
|
106
|
+
"decision": "content-image",
|
|
107
|
+
"reason": "RENDERED_IMAGE (디자인 텍스트, outline 효과)"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"node": "볼트_2",
|
|
111
|
+
"decision": "skip",
|
|
112
|
+
"reason": "5x5 장식 볼트, 동일 imageRef 4개 → CSS로 대체 가능"
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
|
|
118
|
+
"shared": [],
|
|
119
|
+
|
|
120
|
+
"tokens": {
|
|
121
|
+
"note": "figma-to-scss.js가 _tokens.scss 자동 생성. architect는 참조만."
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 판단 기준
|
|
127
|
+
|
|
128
|
+
### tag 선택
|
|
129
|
+
| sections.json 조건 | tag |
|
|
130
|
+
|---|---|
|
|
131
|
+
| 섹션 루트 | `section` |
|
|
132
|
+
| type=TEXT + 제목 역할 (name에 title/heading) | `h2`~`h6` |
|
|
133
|
+
| type=TEXT + 설명 | `p` |
|
|
134
|
+
| type=TEXT + 라벨 | `span` / `strong` |
|
|
135
|
+
| name에 btn/button/CTA | `button` |
|
|
136
|
+
| name에 link/연동/안내 + href 가능 | `a` |
|
|
137
|
+
| type=RENDERED_IMAGE | `img` |
|
|
138
|
+
| imageRef 있음 + 콘텐츠 이미지 | `img` |
|
|
139
|
+
| INSTANCE 반복 2+ | 부모에 v-for 표시 |
|
|
140
|
+
| 나머지 FRAME/GROUP | `div` |
|
|
141
|
+
|
|
142
|
+
### role 종류
|
|
143
|
+
| role | 의미 |
|
|
144
|
+
|---|---|
|
|
145
|
+
| `bg` | 배경 (CSS background-image) |
|
|
146
|
+
| `layout` | 레이아웃 컨테이너 |
|
|
147
|
+
| `text` | 텍스트 콘텐츠 |
|
|
148
|
+
| `content-image` | 콘텐츠 이미지 (img 태그) |
|
|
149
|
+
| `interactive` | 클릭/인터랙션 가능 |
|
|
150
|
+
| `link` | 네비게이션 링크 |
|
|
151
|
+
| `decoration` | 장식 (aria-hidden) |
|
|
152
|
+
| `list` | 반복 구조 (v-for) |
|
|
153
|
+
| `skip` | 무시 (너무 작거나 불필요) |
|
|
154
|
+
|
|
155
|
+
### 이미지 분류 (imageClassification)
|
|
156
|
+
⛔ 모든 이미지 관련 노드에 대해 반드시 분류 기록.
|
|
157
|
+
| decision | 조건 |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `bg` | isBGFrame, TEXT 자식 없음 |
|
|
160
|
+
| `content-image` | RENDERED_IMAGE, 벡터 글자, 디자인 텍스트 |
|
|
161
|
+
| `asset` | imageRef 있는 아이콘/썸네일 |
|
|
162
|
+
| `skip` | 너무 작은 장식 (≤5px), CSS로 대체 가능 |
|
|
163
|
+
| `html` | TEXT 자식 포함, 인터랙티브, 동적 데이터 |
|
|
164
|
+
|
|
165
|
+
### 공유 컴포넌트 (shared)
|
|
166
|
+
- 동일 구조 INSTANCE가 2+ 섹션에서 사용 → shared
|
|
167
|
+
- 3+ 사용 시 필수 분리
|
|
168
|
+
- Props/Slots 인터페이스 정의 필수
|