oh-my-design-cli 1.2.0 → 1.3.8
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/README.ko.md +18 -7
- package/README.md +9 -3
- package/data/issues/2026-05-13-multi-surface-schema-rfc.md +67 -0
- package/package.json +4 -1
- package/skills/omd-apply/SKILL.md +14 -2
- package/skills/omd-asset-fetch/SKILL.md +213 -0
- package/skills/omd-experiment-gallery/SKILL.md +164 -0
- package/skills/omd-harness/SKILL.md +307 -1
- package/skills/omd-init/SKILL.md +171 -70
- package/skills/omd-reference-capture/SKILL.md +711 -0
|
@@ -0,0 +1,711 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: omd:reference-capture
|
|
3
|
+
description: "선택된 reference brand의 라이브 사이트에서 디자인 컨텍스트(토큰·구조·visual reference)를 캡쳐. brand homepage 패칭, 컴퓨티드 스타일 inspect, 로고/스크린샷을 assets/_reference/<id>/ 로 가져와 attribution.md + LICENSE-NOTE.md와 함께 저장. '뱅크샐러드 에셋 가져와줘', 'X 사이트 패칭', 'X reference 캡쳐', 'X 라이브 스타일 추출', '브랜드 자료 받아와' 류 요청에 트리거. omd:init 직후 또는 omd:harness 중간에 호출 가능. DESIGN.md는 이 스킬이 만들지 않음 (omd:init 책임)."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# omd:reference-capture — Live Reference Capture
|
|
7
|
+
|
|
8
|
+
선택된 reference brand의 **라이브 사이트에서 디자인 컨텍스트를 가져온다**. 산출물은 `assets/_reference/<id>/` 디렉토리에 모이고, 사용자의 디자인 작업(omd:apply / omd:harness)에서 컨텍스트로 활용된다.
|
|
9
|
+
|
|
10
|
+
## 핵심 원칙 (위반 = regression)
|
|
11
|
+
|
|
12
|
+
이 스킬은 **dev/디자인 reference 캡쳐**용이다. brand IP를 사용자 product에 그대로 ship하는 도구가 **아니다**.
|
|
13
|
+
|
|
14
|
+
1. **Facts vs. Content 구분**
|
|
15
|
+
- **Facts (캡쳐 OK)**: 컴퓨티드 색상 hex, 폰트 family/weight, spacing, radius, 컴포넌트 구조 — 디자인 시스템 분석은 fair use.
|
|
16
|
+
- **Brand content (저장만, 사용자 product에 verbatim ship 금지)**: 로고, 히어로 사진, 마케팅 카피, 슬로건. 다운로드는 reference 확인용으로만.
|
|
17
|
+
|
|
18
|
+
2. **저작권 표시 의무**
|
|
19
|
+
- 캡쳐 시작 전 `assets/_reference/<id>/LICENSE-NOTE.md`를 **가장 먼저** 작성.
|
|
20
|
+
- 모든 다운로드 파일은 `attribution.md`에 source URL + 캡쳐 일자 + 추정 권리자 기록.
|
|
21
|
+
|
|
22
|
+
3. **사용자 product 생성 시 분리**
|
|
23
|
+
- omd:apply/omd:harness가 UI를 만들 때, brand의 **voice/tone(facts)**은 참고하되 **literal copy**는 새로 작성.
|
|
24
|
+
- brand 히어로 사진 / 마케팅 영상은 사용자 product에 직접 embed하지 말고 placeholder + "사용자 자체 자산으로 교체 필요" 주석.
|
|
25
|
+
|
|
26
|
+
4. **robots.txt / TOS 우선**
|
|
27
|
+
- 다운로드 전 `curl -sI <site>/robots.txt`로 기본 정책 확인.
|
|
28
|
+
- 사이트가 명시적으로 차단하는 경로면 skip하고 사용자에게 알림.
|
|
29
|
+
|
|
30
|
+
5. **scope 한정**
|
|
31
|
+
- 기본 캡쳐 대상: homepage 1개 + favicon/logo + 컴퓨티드 토큰.
|
|
32
|
+
- PDP / checkout / 인증 뒤 페이지는 **기본 skip** — 사용자가 명시적 요청해야만.
|
|
33
|
+
- 비디오 / 대용량 미디어는 기본 skip (URL만 attribution.md에 기록).
|
|
34
|
+
|
|
35
|
+
## 트리거
|
|
36
|
+
|
|
37
|
+
- 명시: "X 에셋 가져와줘", "X 사이트 패칭해줘", "X 라이브 스타일 추출", "X reference 캡쳐"
|
|
38
|
+
- 묵시: omd:harness 안에서 reference 선정 후, 또는 사용자가 "X처럼 만들어줘" 요청 시 omd:init 후속 작업으로 자동 제안
|
|
39
|
+
|
|
40
|
+
## Phase 0 — (v1.3.3 폐기) Mode 선택
|
|
41
|
+
|
|
42
|
+
이전 버전(v1.3.2)은 `clone` vs `inspired` 두 mode를 제공했으나 v1.3.3에서 폐기. 시각적 동일성은 brand creative work을 사용자 product에 reproduce해야 가능하고 그건 IP 영역. 단일 mode 흐름으로 통일 — brand 토큰·구조·voice는 가져오되, brand 자체 자산(mascot·로고·마케팅 사진)은 reference로만 보존하고 사용자 product에는 자체 자산 자리(`[YOUR LOGO]` placeholder 등)를 둠. 결과물의 시각 polish는 무료 라이선스 자산 라이브러리(Open Peeps / Lucide / Heroicons 등 CC0/MIT/SIL OFL)로 채움 — 자세한 카탈로그는 `skills/omd-harness/SKILL.md` Step 4 master prompt rule 6 참조.
|
|
43
|
+
|
|
44
|
+
다음 모든 Phase는 단일 흐름. (구버전 Phase 0 - clone/inspired ask 제거됨.)
|
|
45
|
+
|
|
46
|
+
## (legacy reference) — 이전 mode 선택 텍스트 (참고용, 동작 안 함)
|
|
47
|
+
|
|
48
|
+
reference-capture가 어디까지 가져올지는 사용자 의도에 따라 두 갈래. 호출 진입 시점에 mode가 결정되지 않았다면 사용자에게 한 번에 묻기:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
<id>를 어떻게 활용할까요?
|
|
52
|
+
|
|
53
|
+
1. clone — 거의 똑같이 시작. 실제 로고·일러스트·폰트 받아와서 dev scaffold 구성.
|
|
54
|
+
landing이 라이브 사이트와 시각적으로 매우 비슷하게 시작됩니다.
|
|
55
|
+
⚠ 자동으로 CLONE-MODE.md 배너 + replace-checklist.md가 생성되고,
|
|
56
|
+
"사용자 product에 ship 전에 brand 자산을 자체 자산으로 교체 필요"라고 표시됩니다.
|
|
57
|
+
|
|
58
|
+
2. inspired — 톤·체계만 가져옴. [YOUR LOGO] placeholder, 일러스트는 generic placeholder.
|
|
59
|
+
브랜드의 voice·원칙·팔레트 철학만 적용. 바로 ship 가능한 상태로 산출.
|
|
60
|
+
|
|
61
|
+
답: clone / inspired (기본값: inspired)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
이 선택은 `.omd/init-context.json`의 `mode` 필드에 저장되어 후속 omd:init / omd:harness / omd:apply가 일관되게 사용한다.
|
|
65
|
+
|
|
66
|
+
이미 omd:harness Step 3.7에서 mode를 묻고 진입했으면 Phase 0 skip.
|
|
67
|
+
|
|
68
|
+
### Mode별 동작 요약
|
|
69
|
+
|
|
70
|
+
| 단계 | clone | inspired |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| LICENSE-NOTE.md | 작성 ✓ | 작성 ✓ |
|
|
73
|
+
| tokens.json (atomic facts) | 캡쳐 ✓ | 캡쳐 ✓ |
|
|
74
|
+
| structure.json (composition facts) | 캡쳐 ✓ | 캡쳐 ✓ |
|
|
75
|
+
| logo.<ext> | 캡쳐 + product `<img>`로 사용 가능 (banner 의무) | 캡쳐만 (product에 미사용, placeholder 강제) |
|
|
76
|
+
| screenshots/ | 캡쳐 ✓ | 캡쳐 ✓ |
|
|
77
|
+
| fonts.json (CDN URLs) | 캡쳐 + 자동 `<link>` 로드 강제 | 캡쳐만 (수동 로드) |
|
|
78
|
+
| hero illustration assets | (있고 publicly accessible면) URL 기록 + 사용 가능 | URL만 기록 |
|
|
79
|
+
| attribution.md | 작성 + 사용 표시 | 작성 |
|
|
80
|
+
| **CLONE-MODE.md (project root)** | **mandatory 작성** | 미작성 |
|
|
81
|
+
| **replace-checklist.md (project root)** | **mandatory 작성** | 미작성 |
|
|
82
|
+
|
|
83
|
+
## 전체 플로우
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
Phase 1: 입력 검증 — brand id 확정
|
|
87
|
+
Phase 2: 라이브 URL 수집 (homepage, logo, docs)
|
|
88
|
+
Phase 3: 디렉토리 + LICENSE-NOTE 사전 작성 (CRITICAL — 다운로드보다 먼저)
|
|
89
|
+
Phase 4: 토큰 캡쳐 (facts) — playwright computed styles
|
|
90
|
+
Phase 5: 시각 reference 캡쳐 (screenshot + 로고)
|
|
91
|
+
Phase 6: attribution.md 작성
|
|
92
|
+
Phase 7: 사용자 요약 + 다음 단계 안내
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Phase 1 — 입력 검증
|
|
96
|
+
|
|
97
|
+
사용자 요청에서 brand id 추출:
|
|
98
|
+
- 명시 brand 이름 (한글/영문) → `.claude/data/reference-fingerprints.json` `items[].id` 매칭
|
|
99
|
+
- 없으면 사용자에게 묻기: "어느 reference brand 자료를 가져올까요? (예: banksalad, toss, socar)"
|
|
100
|
+
|
|
101
|
+
id가 카탈로그에 없으면 종료 + "X는 reference 카탈로그에 없어요. omd:init으로 추가 가능합니다."
|
|
102
|
+
|
|
103
|
+
## Phase 2 — 라이브 URL 수집
|
|
104
|
+
|
|
105
|
+
다음을 순서대로 시도:
|
|
106
|
+
|
|
107
|
+
1. **homepage URL**:
|
|
108
|
+
- `node_modules/oh-my-design-cli/web/references/<id>/_promo.json`의 `logo_url`이 brand site면 거기서 도메인 추출
|
|
109
|
+
- 없으면 `node_modules/oh-my-design-cli/web/references/<id>/_research.md`에서 Tier 1 source URL grep
|
|
110
|
+
- 둘 다 없으면 `.claude/data/reference-fingerprints.json`의 `items[].category_raw` 기반으로 추론 — 마지막 수단
|
|
111
|
+
|
|
112
|
+
2. **logo URL** (`_promo.json` 우선):
|
|
113
|
+
- `_promo.json.logo_url` → 그대로 사용
|
|
114
|
+
- 없으면 homepage HTML에서 `apple-touch-icon` / `og:image` / favicon-256 추출
|
|
115
|
+
|
|
116
|
+
3. **공식 DS docs URL** (있으면):
|
|
117
|
+
- `node_modules/oh-my-design-cli/web/references/<id>/DESIGN.md`의 footer 또는 §4 verified 섹션에서 grep
|
|
118
|
+
|
|
119
|
+
수집한 URL 후보를 사용자에게 보여주고 확인:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
다음 자료를 가져오려고 합니다:
|
|
123
|
+
- homepage: https://www.banksalad.com
|
|
124
|
+
- logo: https://blog.banksalad.com/static/img/logo-banksalad.svg
|
|
125
|
+
- 공식 DS: (없음)
|
|
126
|
+
|
|
127
|
+
저작권 안내: 이 자료는 디자인 reference 용도로만 사용됩니다. 사용자 product에 그대로 ship하지 마세요.
|
|
128
|
+
|
|
129
|
+
진행하시겠어요? (yes/no/edit-urls)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Phase 3 — 디렉토리 + LICENSE-NOTE 사전 작성 (CRITICAL)
|
|
133
|
+
|
|
134
|
+
다운로드 시작 **전에** 다음을 먼저 작성:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
mkdir -p "assets/_reference/<id>/screenshots"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`assets/_reference/<id>/LICENSE-NOTE.md`:
|
|
141
|
+
|
|
142
|
+
```markdown
|
|
143
|
+
# License Note — <id> Reference Capture
|
|
144
|
+
|
|
145
|
+
This directory contains design-reference materials captured from
|
|
146
|
+
**<id>**'s public website on **<ISO-date>** for the purpose of
|
|
147
|
+
informing UI design work in this project.
|
|
148
|
+
|
|
149
|
+
## What's here is for REFERENCE, not REDISTRIBUTION
|
|
150
|
+
|
|
151
|
+
- **Design tokens** (colors, fonts, spacing) — `tokens.json`. These
|
|
152
|
+
are facts about the brand's design system and may be used to inform
|
|
153
|
+
your own design.
|
|
154
|
+
- **Logo file** — captured for visual recognition during development.
|
|
155
|
+
This is <brand>'s trademark. Do not use in your own product, your
|
|
156
|
+
own marketing, or any redistribution. Replace with your own brand
|
|
157
|
+
mark before shipping.
|
|
158
|
+
- **Screenshots** — captured for visual reference during development.
|
|
159
|
+
Do not embed in your product, your blog, or social posts beyond
|
|
160
|
+
fair-use commentary.
|
|
161
|
+
|
|
162
|
+
## What you should NOT do
|
|
163
|
+
|
|
164
|
+
- Embed `logo.*` or `screenshots/*.png` in your own product UI as if
|
|
165
|
+
they belong to you.
|
|
166
|
+
- Copy `tokens.json`'s exact hex values into your own brand without
|
|
167
|
+
shifting them via `delta_set` (see omd:init).
|
|
168
|
+
- Copy any marketing text from screenshots into your own product
|
|
169
|
+
verbatim — voice/tone is fact, but specific phrasing is creative work.
|
|
170
|
+
|
|
171
|
+
## What you SHOULD do
|
|
172
|
+
|
|
173
|
+
- Use the **design language** (token relationships, component
|
|
174
|
+
patterns, voice register) to inform your project's DESIGN.md.
|
|
175
|
+
- Reference the screenshots during design reviews to align with the
|
|
176
|
+
visual target.
|
|
177
|
+
- Replace all brand-identifying assets with your own before any
|
|
178
|
+
external sharing.
|
|
179
|
+
|
|
180
|
+
## Attribution
|
|
181
|
+
|
|
182
|
+
See `attribution.md` in this directory for source URLs and capture
|
|
183
|
+
timestamps.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
This note is generated by `omd:reference-capture`. Do not edit by hand
|
|
188
|
+
— rerun the skill to refresh.
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Phase 3.5 — Font 캡쳐 (fonts.json, 라이브 폰트가 실제 로드되도록)
|
|
192
|
+
|
|
193
|
+
캡쳐된 brand가 web font(Pretendard / BM JUA / Inter / Noto Sans KR 등 시스템 기본이 아닌 폰트)를 쓰면, 토큰만 잡아도 생성기가 폰트를 **로드 안 하면** 결과가 시스템 fallback으로 바뀐다 (가장 흔한 증상: macOS 시스템 폰트가 둥글둥글하게 렌더되는 mismatch).
|
|
194
|
+
|
|
195
|
+
`assets/_reference/<id>/fonts.json`:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"captured_at": "<ISO-8601>",
|
|
200
|
+
"fonts": [
|
|
201
|
+
{
|
|
202
|
+
"family": "Pretendard",
|
|
203
|
+
"license": "SIL OFL 1.1 (open-source, free for commercial use)",
|
|
204
|
+
"cdn_url": "https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css",
|
|
205
|
+
"html_link": "<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css\" />",
|
|
206
|
+
"live_observed": true,
|
|
207
|
+
"role": "body + heading"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"family": "Apple SD Gothic Neo",
|
|
211
|
+
"license": "system (macOS/iOS)",
|
|
212
|
+
"cdn_url": null,
|
|
213
|
+
"html_link": null,
|
|
214
|
+
"live_observed": false,
|
|
215
|
+
"role": "system fallback"
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### 3.5.1 추출 절차
|
|
222
|
+
|
|
223
|
+
1. live homepage의 computed style에서 `body` / `h1-h3` / 주요 buttons의 `font-family` 첫 항목 추출 (fallback chain 무시, 첫 토큰만)
|
|
224
|
+
2. 추출된 family를 known-font registry에 매칭:
|
|
225
|
+
|
|
226
|
+
| 추출된 family | license | CDN URL |
|
|
227
|
+
|---|---|---|
|
|
228
|
+
| `Pretendard` | SIL OFL 1.1 | `https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css` |
|
|
229
|
+
| `Pretendard Variable` | SIL OFL 1.1 | `https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/variable/pretendardvariable.css` |
|
|
230
|
+
| `Noto Sans KR` | SIL OFL 1.1 | `https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700;900&display=swap` |
|
|
231
|
+
| `Inter` | SIL OFL 1.1 | `https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap` |
|
|
232
|
+
| `Wanted Sans` | SIL OFL 1.1 | `https://cdn.jsdelivr.net/gh/wanteddev/wanted-sans@latest/packages/wanted-sans/fonts/webfonts/static/complete/WantedSans.css` |
|
|
233
|
+
| `BM JUA` (배민 주아체) | 배달의민족 폰트 라이선스 (개인·기업 무료, **재배포·판매 금지**) | (CDN 미공식 — `html_link: null` 처리, 사용자에게 "BM JUA는 라이브에서 관측 안 됨; 로컬 fallback" 알림) |
|
|
234
|
+
| `Apple SD Gothic Neo`, `Malgun Gothic`, `system-ui`, `-apple-system` | system | `html_link: null` |
|
|
235
|
+
|
|
236
|
+
registry에 없는 family는 `html_link: null` + `notes`에 "CDN 미확인, 수동 로드 필요" 기록.
|
|
237
|
+
|
|
238
|
+
### 3.5.2 BM JUA 같은 misapplication 가드
|
|
239
|
+
|
|
240
|
+
canonical DESIGN.md가 "BM JUA를 landing/promo accent로"라고 적어뒀더라도, **라이브 inspect에서 실제 BM JUA 사용이 관측 안 되면** `live_observed: false`로 기록하고 후속 generator가 적용 안 하도록 신호. omd:init Phase 5B의 priority rule이 `live_overrides` 우선 처리.
|
|
241
|
+
|
|
242
|
+
### 3.5.3 Clone mode 강제 로드
|
|
243
|
+
|
|
244
|
+
mode=clone이면 omd:init/omd:harness가 생성 HTML `<head>`에 fonts.json의 `live_observed: true` 항목 `html_link`를 **반드시** 박는다. mode=inspired면 폰트 로드는 사용자 선택.
|
|
245
|
+
|
|
246
|
+
## Phase 3.9 — Browser harness 자동 선택 (v1.3.6 신설)
|
|
247
|
+
|
|
248
|
+
라이브 캡쳐 도구는 두 가지 옵션. 환경 detect 후 빠른 쪽 사용:
|
|
249
|
+
|
|
250
|
+
### Fast-path: browser-harness (있으면 우선)
|
|
251
|
+
|
|
252
|
+
`shutil.which("browser-harness")` 또는 `command -v browser-harness`로 detect. 있고 `browser-harness --doctor` 가 `[ok ] chrome running` 띄우면 fast-path:
|
|
253
|
+
|
|
254
|
+
- **장점**: heredoc 단일 호출 + Chrome remote-debugging CDP 직접 → playwright MCP 대비 3-5x 빠름 (실측 3.5s/페이지). sub-agent의 "did live inspect" 거짓 보고 불가능 (heredoc 실행 자체가 evidence).
|
|
255
|
+
- **prerequisite**: Python 3.11+, uv 또는 pip, Chrome with `--remote-debugging-port=9222` 또는 `chrome://inspect#remote-debugging` 활성.
|
|
256
|
+
- **호출 패턴**:
|
|
257
|
+
```bash
|
|
258
|
+
BU_CDP_URL="http://localhost:9222" browser-harness <<'PY'
|
|
259
|
+
new_tab("https://<brand-domain>")
|
|
260
|
+
wait_for_load()
|
|
261
|
+
import time; time.sleep(1.5) # SPA hydration
|
|
262
|
+
result = js("""
|
|
263
|
+
(() => {
|
|
264
|
+
const body = getComputedStyle(document.body);
|
|
265
|
+
const ctas = [...document.querySelectorAll('button, a[role="button"], [class*="button"]')]
|
|
266
|
+
.filter(el => {
|
|
267
|
+
const r = el.getBoundingClientRect();
|
|
268
|
+
return r.height >= 32 && r.height <= 80 && r.top < 1200;
|
|
269
|
+
})
|
|
270
|
+
.slice(0, 8).map(el => {
|
|
271
|
+
const cs = getComputedStyle(el);
|
|
272
|
+
return { bg: cs.backgroundColor, color: cs.color, radius: cs.borderRadius,
|
|
273
|
+
padding: cs.padding, fontWeight: cs.fontWeight, h: Math.round(el.getBoundingClientRect().height) };
|
|
274
|
+
});
|
|
275
|
+
return JSON.stringify({
|
|
276
|
+
bodyFont: body.fontFamily.split(',')[0].replace(/['"]/g,'').trim(),
|
|
277
|
+
ctas, scrollH: document.documentElement.scrollHeight
|
|
278
|
+
});
|
|
279
|
+
})()
|
|
280
|
+
""")
|
|
281
|
+
print(result)
|
|
282
|
+
capture_screenshot(path="<assets_dir>/screenshots/hero-desktop.png", full=False)
|
|
283
|
+
PY
|
|
284
|
+
```
|
|
285
|
+
- 결과를 `tokens.json#live_overrides` + `.live-inspect-proof.json` raw_samples에 그대로 박음.
|
|
286
|
+
|
|
287
|
+
### Fallback: playwright MCP (default)
|
|
288
|
+
|
|
289
|
+
browser-harness 미설치면 `mcp__playwright__browser_navigate` + `browser_evaluate` + `browser_take_screenshot` 사용 (이전 버전 동작 그대로).
|
|
290
|
+
|
|
291
|
+
### 자동 선택 logic
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
if command -v browser-harness >/dev/null && browser-harness --doctor 2>&1 | grep -q "ok.*chrome running"; then
|
|
295
|
+
echo "MODE=harness"
|
|
296
|
+
else
|
|
297
|
+
echo "MODE=playwright"
|
|
298
|
+
fi
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### 사용자 안내 (선택)
|
|
302
|
+
|
|
303
|
+
skill 진입 시 사용자에게 한 줄로 알림:
|
|
304
|
+
> "browser-harness 감지됨 — fast-path 사용 (3.5s/page)" 또는 "playwright MCP 사용 — browser-harness 설치하면 3x 빠름: github.com/browser-use/browser-harness"
|
|
305
|
+
|
|
306
|
+
이 안내는 informational only, 사용자 action 요구 X.
|
|
307
|
+
|
|
308
|
+
## Phase 4 — 토큰 캡쳐 (facts)
|
|
309
|
+
|
|
310
|
+
**Proof gate (위반 = regression)**: 이 Phase는 실제 playwright navigate + computed style 추출이 일어났음을 후속 generator에게 증명하는 artifact를 남겨야 함. 이전 버전(v1.3.3)에서 sub-agent가 "라이브 inspect 했다"고 보고하지만 실제로는 canonical 값만 복사하는 결함이 관측됨. proof gate가 이를 차단:
|
|
311
|
+
|
|
312
|
+
### 4.0 — `.live-inspect-proof.json` 작성 (REQUIRED, 이 파일 없으면 후속 generator는 live_overrides 무시)
|
|
313
|
+
|
|
314
|
+
playwright `browser_navigate` 직후 `browser_evaluate`로 raw computed style 5개 이상 추출하고 결과를 `assets/_reference/<id>/.live-inspect-proof.json`에 저장:
|
|
315
|
+
|
|
316
|
+
```json
|
|
317
|
+
{
|
|
318
|
+
"navigated_at": "<ISO-8601 with seconds>",
|
|
319
|
+
"source_url": "https://www.banksalad.com",
|
|
320
|
+
"viewport": "1280x800",
|
|
321
|
+
"tool_used": "playwright_mcp_browser_evaluate",
|
|
322
|
+
"raw_samples": [
|
|
323
|
+
{ "element_selector": "body", "font-family": "Pretendard, ...", "color": "rgb(0, 0, 0)", "background": "rgba(0, 0, 0, 0)" },
|
|
324
|
+
{ "element_selector": "header nav a:first-child", "font-size": "14px", "font-weight": "500" },
|
|
325
|
+
{ "element_selector": "button:contains('앱 다운로드')", "background-color": "rgb(19, 189, 126)", "border-radius": "41px" },
|
|
326
|
+
{ "element_selector": ".hero-section section", "background-color": "rgba(0, 0, 0, 0)" },
|
|
327
|
+
{ "element_selector": "footer", "background-color": "rgb(255, 255, 255)" }
|
|
328
|
+
],
|
|
329
|
+
"playwright_response_hash": "<5+ char of returned evaluate result>"
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
후속 generator (omd:init / omd:harness)는 이 파일이 **존재하고 raw_samples 길이 ≥5** 이어야만 `tokens.json#live_overrides`를 신뢰. 파일 없거나 비어있으면 canonical만 사용.
|
|
334
|
+
|
|
335
|
+
### 4.1 — drift detection (proof와 tokens.json#live_overrides 일관성)
|
|
336
|
+
|
|
337
|
+
tokens.json의 `live_overrides` 값이 캡쳐된 canonical 값과 **byte-for-byte 동일**하면 live inspect가 실제로는 안 돈 것 → live_overrides 블록을 통째로 삭제하고 사용자에게 "live inspect 결과가 canonical과 동일 — 차이 없거나 inspect 실패. tokens.json#live_overrides 미사용."이라고 알림. metadata note만 적고 실제 hex override 없는 거짓 live_overrides 금지.
|
|
338
|
+
|
|
339
|
+
### 4.2 — token 캡쳐 본문
|
|
340
|
+
|
|
341
|
+
playwright MCP를 사용해 homepage에 navigate한 뒤 computed styles를 추출. 결과는 `assets/_reference/<id>/tokens.json`:
|
|
342
|
+
|
|
343
|
+
```json
|
|
344
|
+
{
|
|
345
|
+
"captured_at": "<ISO-8601>",
|
|
346
|
+
"source_url": "https://www.banksalad.com",
|
|
347
|
+
"tokens": {
|
|
348
|
+
"colors": {
|
|
349
|
+
"background": "#ffffff",
|
|
350
|
+
"text_primary": "#2b2b2b",
|
|
351
|
+
"text_body": "#434444",
|
|
352
|
+
"interaction_primary": "#04c584",
|
|
353
|
+
"interaction_hover": "#10df99"
|
|
354
|
+
},
|
|
355
|
+
"typography": {
|
|
356
|
+
"body_font_family": "Pretendard, ...",
|
|
357
|
+
"body_font_weight": "400",
|
|
358
|
+
"heading_font_weight": "700",
|
|
359
|
+
"base_size_px": 16
|
|
360
|
+
},
|
|
361
|
+
"shape": {
|
|
362
|
+
"default_radius_px": 2,
|
|
363
|
+
"card_radius_px": 2,
|
|
364
|
+
"pill_radius_px": 16
|
|
365
|
+
},
|
|
366
|
+
"shadow": {
|
|
367
|
+
"default": "0 2px 5px rgba(0,0,0,0.12)"
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
"samples": [
|
|
371
|
+
{ "element": "primary button (hero CTA)", "raw_computed_style": { /* getComputedStyle slice */ } },
|
|
372
|
+
{ "element": "card", "raw_computed_style": { /* ... */ } }
|
|
373
|
+
]
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
inspect 패턴은 `.claude/skills/omd-add-reference/SKILL.md`의 "apple.com 류 라이브 inspect 패턴"과 동일. 5-10 elements 샘플링.
|
|
378
|
+
|
|
379
|
+
## Phase 4.5 — 구조 cue 캡쳐 (structure.json)
|
|
380
|
+
|
|
381
|
+
Tokens는 색·radius·font 같은 원자 값이고, **structure**는 페이지가 어떻게 짜였는지의 관측 가능한 facts다. 토큰만 보면 같은 brand도 surface마다 다른 결과물이 나오는 mismatch가 생긴다 (예: app surface의 2px-radius advisor 톤 vs marketing landing의 41px-pill 일러스트 톤). structure.json은 후속 생성기가 **실제 라이브 사이트의 composition idiom**을 따라가도록 한다.
|
|
382
|
+
|
|
383
|
+
### 4.5.1 추출 항목 (facts only — 저작권 영역 0)
|
|
384
|
+
|
|
385
|
+
`assets/_reference/<id>/structure.json`:
|
|
386
|
+
|
|
387
|
+
```json
|
|
388
|
+
{
|
|
389
|
+
"captured_at": "<ISO-8601>",
|
|
390
|
+
"source_url": "https://www.banksalad.com",
|
|
391
|
+
"viewport": "1280x800",
|
|
392
|
+
"hero": {
|
|
393
|
+
"type": "illustration | photo | video | data-card | text-only | mixed",
|
|
394
|
+
"has_carousel": false,
|
|
395
|
+
"carousel_dot_count": 0,
|
|
396
|
+
"primary_visual_position": "right | left | center | full-width | background",
|
|
397
|
+
"background_ornament": "none | gradient-blob | geometric | radial-tint | photo-bleed",
|
|
398
|
+
"approx_height_vh": 75
|
|
399
|
+
},
|
|
400
|
+
"cta": {
|
|
401
|
+
"dominant_shape": "pill | rectangular | ghost-only | text-link",
|
|
402
|
+
"primary_radius_px_observed": 41,
|
|
403
|
+
"secondary_style": "ghost-outline | underline | none",
|
|
404
|
+
"vertical_stack": true
|
|
405
|
+
},
|
|
406
|
+
"nav": {
|
|
407
|
+
"structure": "horizontal-categories | mega-menu | hamburger-mobile | single-row-utility | top-tabs",
|
|
408
|
+
"approx_item_count": 11,
|
|
409
|
+
"has_search": false,
|
|
410
|
+
"has_locale_switch": false
|
|
411
|
+
},
|
|
412
|
+
"page": {
|
|
413
|
+
"viewport_heights": 3.9,
|
|
414
|
+
"section_count_observed": 8,
|
|
415
|
+
"predominant_alignment": "center | left | grid-asymmetric",
|
|
416
|
+
"image_density": "high | medium | low | none"
|
|
417
|
+
},
|
|
418
|
+
"section_rhythm": [
|
|
419
|
+
"hero",
|
|
420
|
+
"social-proof",
|
|
421
|
+
"feature-grid",
|
|
422
|
+
"testimonial",
|
|
423
|
+
"footer"
|
|
424
|
+
],
|
|
425
|
+
"notes": [
|
|
426
|
+
"라이브 hero는 carousel — 3-5 슬라이드로 product 카테고리 순환",
|
|
427
|
+
"section_rhythm은 위에서 아래로 관측 순서"
|
|
428
|
+
]
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### 4.5.2 추출 방법
|
|
433
|
+
|
|
434
|
+
playwright로 homepage navigate 후 다음 JS 실행 (facts derivation only):
|
|
435
|
+
|
|
436
|
+
```js
|
|
437
|
+
() => {
|
|
438
|
+
// hero 탐색 — 보통 첫 800px 이내 viewport에서 가장 큰 visual element
|
|
439
|
+
const heroCandidates = [...document.querySelectorAll('section, header + div, [class*="hero" i], [class*="Hero"]')]
|
|
440
|
+
.filter(el => {
|
|
441
|
+
const r = el.getBoundingClientRect();
|
|
442
|
+
return r.top < 200 && r.height > 300 && r.width > 800;
|
|
443
|
+
});
|
|
444
|
+
const heroEl = heroCandidates[0];
|
|
445
|
+
|
|
446
|
+
// type 판정
|
|
447
|
+
const heroImgCount = heroEl ? heroEl.querySelectorAll('img, svg, picture').length : 0;
|
|
448
|
+
const heroVideoCount = heroEl ? heroEl.querySelectorAll('video').length : 0;
|
|
449
|
+
const heroHasCarouselDots = heroEl ? !!heroEl.querySelector('[class*="dot" i], [class*="pagination" i], [class*="indicator" i]') : false;
|
|
450
|
+
|
|
451
|
+
// CTA 탐색 — viewport 위 절반의 button/cta
|
|
452
|
+
const ctas = [...document.querySelectorAll('button, a[role="button"], [class*="button" i] a')]
|
|
453
|
+
.filter(el => el.getBoundingClientRect().top < 800)
|
|
454
|
+
.map(el => {
|
|
455
|
+
const cs = getComputedStyle(el);
|
|
456
|
+
return { radius: cs.borderRadius, bg: cs.backgroundColor };
|
|
457
|
+
});
|
|
458
|
+
const dominantRadii = ctas.map(c => parseInt(c.radius)).filter(n => !isNaN(n));
|
|
459
|
+
const maxRadius = Math.max(...dominantRadii, 0);
|
|
460
|
+
|
|
461
|
+
// nav
|
|
462
|
+
const navEl = document.querySelector('header nav, [role="navigation"]');
|
|
463
|
+
const navItemCount = navEl ? navEl.querySelectorAll('a, button').length : 0;
|
|
464
|
+
|
|
465
|
+
return {
|
|
466
|
+
hero_img_count: heroImgCount,
|
|
467
|
+
hero_video_count: heroVideoCount,
|
|
468
|
+
hero_has_carousel_dots: heroHasCarouselDots,
|
|
469
|
+
cta_max_radius_observed: maxRadius,
|
|
470
|
+
cta_sample_count: ctas.length,
|
|
471
|
+
nav_item_count: navItemCount,
|
|
472
|
+
total_scroll_height_px: document.documentElement.scrollHeight,
|
|
473
|
+
viewport_height_px: window.innerHeight,
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
위 raw 측정값을 structure.json schema의 enum 값으로 매핑 (예: `hero_img_count >= 1 && hero_video_count === 0` → `hero.type: "illustration"`, `cta_max_radius_observed >= 40` → `cta.dominant_shape: "pill"`).
|
|
479
|
+
|
|
480
|
+
### 4.5.3 IP 가드레일 재확인
|
|
481
|
+
|
|
482
|
+
structure.json에는 텍스트·이미지·copy·brand statement 일체 X. 오로지 **structural facts** (개수, radius, viewport-relative position). 저작권 영역 아님.
|
|
483
|
+
|
|
484
|
+
`notes` 필드의 자유 텍스트는 **본인 관찰**만 — 사이트의 마케팅 카피 인용 금지.
|
|
485
|
+
|
|
486
|
+
## Phase 5 — 시각 reference 캡쳐
|
|
487
|
+
|
|
488
|
+
### 5.1 로고 다운로드
|
|
489
|
+
|
|
490
|
+
`curl -sSL -o "assets/_reference/<id>/logo.<ext>" "<logo_url>"`
|
|
491
|
+
|
|
492
|
+
- 실패 시 sourceURL 명시하고 사용자에게 수동 다운로드 안내
|
|
493
|
+
- 확장자는 Content-Type 기준 (svg/png/ico) — 잘못된 확장자로 저장하지 말 것
|
|
494
|
+
|
|
495
|
+
### 5.2 Hero screenshot
|
|
496
|
+
|
|
497
|
+
playwright `mcp__playwright__browser_take_screenshot`로 homepage 위 fold만 캡쳐:
|
|
498
|
+
|
|
499
|
+
- viewport: 1280×800 (데스크탑 기본)
|
|
500
|
+
- fullPage: **false** — 위 fold만
|
|
501
|
+
- 저장 경로: `assets/_reference/<id>/screenshots/hero-desktop.png`
|
|
502
|
+
|
|
503
|
+
모바일 viewport (375×812)도 1장: `screenshots/hero-mobile.png`.
|
|
504
|
+
|
|
505
|
+
대용량 페이지 전체 screenshot은 default skip. 사용자가 명시적으로 요청 시만.
|
|
506
|
+
|
|
507
|
+
### 5.3 다운로드 금지 대상
|
|
508
|
+
|
|
509
|
+
- 비디오 (`.mp4`, `.webm`)
|
|
510
|
+
- 마케팅 PDF
|
|
511
|
+
- 인증 뒤 페이지의 자산
|
|
512
|
+
- robots.txt가 차단하는 경로
|
|
513
|
+
|
|
514
|
+
이런 자원은 attribution.md에 URL만 기록.
|
|
515
|
+
|
|
516
|
+
## Phase 6 — attribution.md
|
|
517
|
+
|
|
518
|
+
`assets/_reference/<id>/attribution.md`:
|
|
519
|
+
|
|
520
|
+
```markdown
|
|
521
|
+
# Attribution — <id> Reference Capture
|
|
522
|
+
|
|
523
|
+
Captured: **<ISO-8601>** via `omd:reference-capture`
|
|
524
|
+
|
|
525
|
+
## Sources
|
|
526
|
+
|
|
527
|
+
| File | Source URL | Captured | Notes |
|
|
528
|
+
|---|---|---|---|
|
|
529
|
+
| `tokens.json` | `<homepage_url>` | <date> | Computed styles via playwright, factual analysis |
|
|
530
|
+
| `structure.json` | `<homepage_url>` | <date> | Observable composition facts (hero type, CTA shape, nav structure, page rhythm) |
|
|
531
|
+
| `logo.<ext>` | `<logo_url>` | <date> | Brand trademark — do not redistribute |
|
|
532
|
+
| `screenshots/hero-desktop.png` | `<homepage_url>` (1280×800) | <date> | Reference for design alignment |
|
|
533
|
+
| `screenshots/hero-mobile.png` | `<homepage_url>` (375×812) | <date> | Reference for design alignment |
|
|
534
|
+
|
|
535
|
+
## Skipped (URL recorded for manual review)
|
|
536
|
+
|
|
537
|
+
- (none) OR <list of URLs skipped due to robots.txt / size / type>
|
|
538
|
+
|
|
539
|
+
## Rights
|
|
540
|
+
|
|
541
|
+
These materials are owned by <id> and its respective rights holders.
|
|
542
|
+
Captured under fair-use principles for the purpose of design analysis
|
|
543
|
+
and development reference. See `LICENSE-NOTE.md` for usage boundaries.
|
|
544
|
+
|
|
545
|
+
## Refresh
|
|
546
|
+
|
|
547
|
+
Rerun `omd:reference-capture <id>` to recapture (overwrites this
|
|
548
|
+
directory). Captured tokens reflect the live site at capture time and
|
|
549
|
+
may drift as the brand evolves.
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
## Phase 6.5 — Clone mode 전용 산출 (mode=clone일 때만)
|
|
553
|
+
|
|
554
|
+
### 6.5.1 `CLONE-MODE.md` (project root, mandatory)
|
|
555
|
+
|
|
556
|
+
clone mode 진입 시점에 프로젝트 루트(`./CLONE-MODE.md`)에 **다른 산출보다 먼저** 작성:
|
|
557
|
+
|
|
558
|
+
```markdown
|
|
559
|
+
# ⚠ CLONE MODE — Reference Scaffold
|
|
560
|
+
|
|
561
|
+
This project was scaffolded in **clone mode** from the **<id>** reference
|
|
562
|
+
on **<ISO-date>**. The scaffold deliberately resembles <id>'s live
|
|
563
|
+
public surface to help you start fast.
|
|
564
|
+
|
|
565
|
+
## What this means
|
|
566
|
+
|
|
567
|
+
- **Brand assets in this project are NOT yours.** The header logo, web
|
|
568
|
+
fonts, illustration patterns, and visual rhythm currently match
|
|
569
|
+
<id>'s public brand. They are placeholders/references, not part of
|
|
570
|
+
your product's identity.
|
|
571
|
+
- **You MUST replace them before shipping.** See `replace-checklist.md`
|
|
572
|
+
for the exact list of files and lines to swap.
|
|
573
|
+
- **Marketing copy** in this scaffold was generated fresh in the brand's
|
|
574
|
+
voice register — it is not copied verbatim from the live site. Edit
|
|
575
|
+
freely for your product's narrative.
|
|
576
|
+
|
|
577
|
+
## Why clone mode exists
|
|
578
|
+
|
|
579
|
+
Designers and engineers commonly evaluate "what would an X-styled UI
|
|
580
|
+
look like for my product" by starting from a close visual reference.
|
|
581
|
+
clone mode automates that scaffold step. It is **not** a license to
|
|
582
|
+
ship the reference brand's identity as your own.
|
|
583
|
+
|
|
584
|
+
## To switch back to inspired mode
|
|
585
|
+
|
|
586
|
+
Re-run with `mode=inspired` — all brand-identifying assets revert to
|
|
587
|
+
`[YOUR LOGO]` placeholders and generic illustration silhouettes, ready
|
|
588
|
+
to ship with your own brand.
|
|
589
|
+
|
|
590
|
+
---
|
|
591
|
+
|
|
592
|
+
Generated by `omd:reference-capture`. Do not delete this banner until
|
|
593
|
+
`replace-checklist.md` is fully resolved.
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### 6.5.2 `replace-checklist.md` (project root, mandatory)
|
|
597
|
+
|
|
598
|
+
clone mode가 만든 모든 brand-identifying 자산의 정확한 swap 지점 enumeration:
|
|
599
|
+
|
|
600
|
+
```markdown
|
|
601
|
+
# Replace Checklist — pre-ship swap list
|
|
602
|
+
|
|
603
|
+
Before shipping, resolve every item below. Each item points to a
|
|
604
|
+
brand-cloned asset that must be replaced with your own product's
|
|
605
|
+
equivalent.
|
|
606
|
+
|
|
607
|
+
## Logo
|
|
608
|
+
|
|
609
|
+
- [ ] `assets/_reference/<id>/logo.<ext>` — replace `<img src="assets/_reference/<id>/logo.<ext>">` references
|
|
610
|
+
in `landing.html` (line <N>), `app/layout.tsx` (line <N>), etc.
|
|
611
|
+
Suggested replacement: `assets/brand/logo.<ext>` (your own).
|
|
612
|
+
|
|
613
|
+
## Web fonts
|
|
614
|
+
|
|
615
|
+
- [ ] `<link rel="stylesheet" href="<CDN URL>">` in `landing.html` head
|
|
616
|
+
— keep if you use the same font (Pretendard is open-source);
|
|
617
|
+
remove if you switch to a different typeface.
|
|
618
|
+
|
|
619
|
+
## Hero illustration / imagery
|
|
620
|
+
|
|
621
|
+
- [ ] `landing.html` lines <N-M> — placeholder illustration matching
|
|
622
|
+
<id>'s visual idiom. Replace with your own illustration / photo.
|
|
623
|
+
|
|
624
|
+
## Marketing copy
|
|
625
|
+
|
|
626
|
+
- (none — all copy was written fresh in the brand voice register;
|
|
627
|
+
edit for your product's specific narrative as needed)
|
|
628
|
+
|
|
629
|
+
## Color tokens
|
|
630
|
+
|
|
631
|
+
- [ ] Live brand colors (e.g. `#13bd7e` for banksalad) are used as
|
|
632
|
+
`--brand-primary`. Adjust if your brand uses a different hue.
|
|
633
|
+
|
|
634
|
+
## Final pre-ship check
|
|
635
|
+
|
|
636
|
+
```bash
|
|
637
|
+
# Should return no matches before shipping:
|
|
638
|
+
grep -rn "_reference/<id>" .
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
## When this checklist is complete
|
|
642
|
+
|
|
643
|
+
Delete this file and `CLONE-MODE.md` from the project root. The
|
|
644
|
+
scaffold is now your product.
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
이 두 파일은 generator가 clone mode를 인지하는 마커이기도 함. 사용자가 의도적으로 삭제해야 inspired mode로 전환.
|
|
648
|
+
|
|
649
|
+
## Phase 7 — 사용자 요약
|
|
650
|
+
|
|
651
|
+
prose로:
|
|
652
|
+
|
|
653
|
+
```
|
|
654
|
+
✓ <id> reference captured into assets/_reference/<id>/
|
|
655
|
+
- tokens.json — <N> design tokens extracted
|
|
656
|
+
- logo.<ext> — <size>
|
|
657
|
+
- screenshots/ — <N> images
|
|
658
|
+
|
|
659
|
+
⚠ 저작권 안내: 이 자료는 디자인 reference 용도. 사용자 product에 brand 로고/스크린샷을 직접 embed하지 마세요. 자세한 사용 경계는 LICENSE-NOTE.md 참고.
|
|
660
|
+
|
|
661
|
+
다음 단계:
|
|
662
|
+
- omd:apply로 컴포넌트 작업 시작 (tokens.json 자동 활용)
|
|
663
|
+
- omd:harness로 전체 surface 디자인 (이 자료를 reference로)
|
|
664
|
+
- 토큰 시각 확인: open assets/_reference/<id>/screenshots/hero-desktop.png
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
## omd:harness / omd:apply 와의 인터페이스
|
|
668
|
+
|
|
669
|
+
이 스킬이 만든 `assets/_reference/<id>/tokens.json`은 후속 skill이 자동 활용:
|
|
670
|
+
|
|
671
|
+
- **omd:apply**가 컴포넌트 작업 시 `tokens.json`이 있으면 hex 값 동기화 우선
|
|
672
|
+
- **omd:harness**의 Component phase에서 시각 reference로 screenshots 활용
|
|
673
|
+
|
|
674
|
+
UI 생성 시 logo 사용 규칙 (omd:apply / omd:harness 둘 다 적용):
|
|
675
|
+
- 사용자 product의 **헤더/footer logo는 reference logo를 placeholder로 쓰지 말 것** — `[YOUR LOGO]` 자리만 잡고 사용자에게 자체 로고 요청
|
|
676
|
+
- favicon / og:image 등도 동일 — placeholder 위치만 표시
|
|
677
|
+
|
|
678
|
+
## 안티패턴 (절대 금지)
|
|
679
|
+
|
|
680
|
+
- ❌ 다운로드 시작 전에 LICENSE-NOTE.md 작성 skip
|
|
681
|
+
- ❌ Phase 4의 token 캡쳐 결과를 그대로 사용자 DESIGN.md에 hex값 verbatim 복사 (omd:init의 delta_set 시스템을 우회)
|
|
682
|
+
- ❌ 브랜드 마케팅 카피를 사용자 product에 그대로 인용
|
|
683
|
+
- ❌ 사용자 product의 로고 자리에 reference brand 로고 임시로라도 박기 (사용자가 잊고 ship 가능성)
|
|
684
|
+
- ❌ robots.txt 차단 경로 강행
|
|
685
|
+
- ❌ 인증 뒤 페이지 자동 탐색
|
|
686
|
+
- ❌ 비디오 / 대용량 자산 default 다운로드
|
|
687
|
+
|
|
688
|
+
## 산출 위치 (요약)
|
|
689
|
+
|
|
690
|
+
```
|
|
691
|
+
assets/_reference/<id>/
|
|
692
|
+
├── LICENSE-NOTE.md (사전 작성)
|
|
693
|
+
├── attribution.md (마지막 작성)
|
|
694
|
+
├── tokens.json (facts — atomic values)
|
|
695
|
+
├── structure.json (facts — composition cues for surface idiom)
|
|
696
|
+
├── logo.<svg|png|ico> (brand mark — reference only)
|
|
697
|
+
└── screenshots/
|
|
698
|
+
├── hero-desktop.png (1280×800, above fold)
|
|
699
|
+
└── hero-mobile.png (375×812, above fold)
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
## .gitignore 권장
|
|
703
|
+
|
|
704
|
+
`assets/_reference/` 디렉토리는 사용자 자체 자산이 아닌 reference 자료이므로, 사용자 git repo의 정책에 따라 .gitignore 권장:
|
|
705
|
+
|
|
706
|
+
```
|
|
707
|
+
# Reference capture (regeneratable via omd:reference-capture)
|
|
708
|
+
assets/_reference/
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
이 스킬은 .gitignore를 자동 수정하지 않음 — 사용자에게 알림만.
|