프로젝트 설정
목표: 빈 클론을 이 사람의 스타일로 편집하는 파이프라인으로 전환하는 것입니다. 사용자가 무엇을 좋아하는지 이해하고, 서비스를 연결하며, 향후 영상의 장면을 보여줍니다. 사용자의 언어로 짧고 인간미 있게 말하세요.
프로젝트에는 자체 스타일이 없습니다. 영상의 외관(팔레트, 글꼴, 자막, 카드, 스티커, 포스터, 템포, 펀치인, 그레이딩, 사운드 등)에 관한 모든 것은 사용자가 선택하거나 사용자의 참고 자료에서 가져옵니다. '표준' 또는 '인기' 옵션을 제안하지 않으며, 자신의 선호도를 대입하지 않고, 프로젝트에 이미 있는 것(harness.config.json의 더미 값과 데모는 스타일이 아니라 빈 공간입니다)을 사용하지 않습니다.
인터뷰 규칙
- 한 블록은 한 메시지로, 블록은 절대 합치지 않습니다.
AskUserQuestion형식 하나에 두 블록을 넣지 마세요. 사람들은 첫 번째 옵션에만 답합니다. 블록 4(서비스), 6(팔레트), 7(글꼴), 8(편집 스타일)은 여러 메시지로 구성된 대화입니다. - 취향에 '(추천)' 표시 금지. 이 표시는 순수 기술적 선택(블록 3의 전사 방식)에만 허용됩니다. 색상, 글꼴, 스타일, 서비스 및 사용자에 대한 질문에는 없습니다. 옵션은 각각이 제공하는 내용을 중립적으로 설명하세요.
- 옵션은 사용자의 답변과 참고 자료에서 가져옵니다. 답변도 참고 자료도 없으면 사용자의 주제와 어조에 맞는 눈에 띄게 다른 2~3가지 옵션을 모아 장면으로 보여주세요. 선택은 사용자의 몫입니다.
- 설명하지 말고 보여주세요: 팔레트, 글꼴 및 편집 스타일은
video/scripts/variants.py를 통해 완성된 장면으로 보여주세요. - 블록 건너뛰기('건너뛰기')는 사용자의 명시적인 말에만 응답하세요. 그러면 프로필에 중립적인 더미 값이 남게 되며, 이 사실을 직접 말하세요: '나중에 설정할 수 있습니다. "자막 설정"이라고 말씀하세요.'
- 사용자에 대해 추측하지 마세요. 브랜드, 이름, 주제, 대상 및 어조는 사용자의 답변에서만 가져오고, 계정 이메일, 시스템 이름, 폴더 이름 또는 저장소 링크에서 가져오지 마세요. 저장소 링크의 계정 이름은 템플릿 작성자이지 사용자가 아닙니다.
- 기술적인 내용은 인터뷰에 포함하지 않습니다: 안전 영역, 잘린 꼬리 없는 편집, 2패스 loudnorm, 클립 간 펀치인 메커니즘 등은 취향이 아니라 파이프라인이 작동하는 방식입니다(
CLAUDE.md, '메커니즘'). - 키는 절대 채팅을 통해 전달되지 않습니다. 사용자가 직접
video/.env에 입력합니다.doctor.sh를 통해 접근 권한을 확인하며, 아무것도 출력하지 않습니다. 키를 채팅으로 보내면 사용하지 말고, 키를 취소하고 새로 만들도록 조언하세요. brew/pip로 설치하거나 용량이 큰 모든 항목은 먼저 '무엇이고, 용량은 얼마이며', 그 다음 '예'입니다.
단계 0. 인사 (한 메시지)
2~3줄: 이것은 Claude Code + Remotion을 통한 '토킹 헤드' 수직 영상 편집입니다. 프로젝트에는 자체 스타일이 없습니다. 이제 모든 것을 사용자에 맞춰 설정하겠습니다: 자신에 대해 말씀해 주시고, 마음에 드는 릴스 약 10개를 보내주시고, 색상, 글꼴 및 편집 스타일을 선택하겠습니다(장면으로 옵션을 보여드립니다), 필요한 서비스를 연결하겠습니다. 바로 단계 1로 넘어가세요.
단계 1. 환경
cd video && ( [ -d node_modules ] || npm install ) && bash scripts/doctor.sh
결과를 짧은 표로 보여주세요. 각각의 MISSING 항목에 대해 출력에서 명령어를 제안하고, 동의를 얻으면 실행하세요:
- Remotion 스킬 (필수): 프로젝트 루트에서
npx -y skills add remotion-dev/skills --skill '*' --agent claude-code -y실행. ffmpeg,node,python3,yt-dlp(참고 자료용) —brew install …(macOS); Linux는 패키지 관리자; Windows는 WSL.- whisper / rembg — 답변에 따라 필요할 때(단계 3).
brew가 없으면 https://brew.sh 링크를 제공하고 기다리세요(설치 시 암호를 묻습니다. 사용자가 직접 수행합니다).
단계 2. 인터뷰
블록 1 — 당신은 누구인가요?
브랜드 / 채널 이름; 영상에 등장하는 사람; 영상 주제; 플랫폼 및 핸들(Reels, TikTok, Shorts, Telegram…); 대상; 어조; 영상 언어; 최종 클 투 액션.
열린 질문을 하세요. 한 메시지로 자신의 말로 답하도록 하세요. 옵션(어조나 클 투 액션에 대한)을 제시하는 경우, 중립적이며 어떤 사람에게도 동일하고, 주제나 틈새가 대입되지 않아야 합니다.
블록 2 — 참고 자료 (~10개의 릴스)
요청: '편집 스타일이 마음에 드는 릴스 링크 약 10개를 보내주세요. Instagram, TikTok 또는 Shorts. 자신이 닮고 싶은 스타일이면 좋습니다. 이를 통해 템포, 자막, 그래픽, 색상, 글꼴 등 취향을 파악하겠습니다.' 5개 미만이면 더 요청하세요: 3개 영상으로는 공통 취향을 파악하기 어렵습니다. 참고 자료가 없으면 블록 6~8에서 더 자세히 질문해야 한다고 설명하세요.
링크를 받으면 즉시 백그라운드에서 분석을 시작하고 블록 3으로 넘어가세요:
cd video && python3 scripts/refs.py "URL1" "URL2" … > ../takes/refs.log 2>&1 # run_in_background
스크립트는 takes/refs/에 다운로드하고(git에 포함되지 않음) 다음을 측정합니다: 길이, 컷 빈도, 후크 내 컷 빈도, 음량, 말하기 속도, 첫 문구, 선명한 색상(palette.png); NN-sheet.jpg (영상당 24프레임) 및 NN-hook.jpg (처음 3초)를 생성합니다. 일부 링크가 로그인 필요로 FAILED되면 SERVICES.md → 'Instagram'의 옵션: COOKIES_FROM=chrome으로 다시 시작(명시적인 '예'가 있는 경우에만) 또는 사용자가 직접 다운로드하여 mp4를 takes/refs/에 넣도록 합니다(그런 다음 링크 대신 경로를 전달).
블록 3 — 음성 전사
- whisper.cpp 로컬 (Mac에서 권장): 무료, 오프라인;
brew install whisper-cpp+ 모델 large-v3-turbo 1.6GB. - ElevenLabs Scribe: 유료(크레딧), 설치 불필요, 모든 시스템에서 작동; 키 필요(블록 4).
블록 4 — 서비스 (서비스당 하나의 메시지)
'무엇을 연결하시겠습니까?'라는 하나의 질문으로 묻지 마세요. 서비스를 하나씩 순서대로 진행하세요 — 서비스당 하나의 메시지: 편집에서 제공하는 기능(예시 포함 1~2줄), 비용, 사용자에게 필요한 것, 소요 시간. 질문: '지금 연결 / 나중에 / 필요 없음'.
| 서비스 | 편집에서 제공하는 기능 | 접근 | 시간 |
|---|---|---|---|
| ElevenLabs | Scribe 전사; 취향에 맞는 사운드 악센트; 음성 해설 | API 키 | ~3분 |
| Higgsfield | 보여줄 수 있는 내용을 말할 때 짧은 비디오 삽입(B-roll) | 브라우저 로그인 | ~2분 + 재시작 후 |
| 21st.dev | 새로운 그래픽의 기반이 되는 기성 React 컴포넌트 | API 키 | ~3분 |
| Buffer | Reels / TikTok / Shorts 게시물 초안 | 브라우저 로그인 + Buffer의 채널 | ~5분 |
순서: ElevenLabs → Higgsfield → 21st.dev → Buffer. 블록 3에서 Scribe를 선택한 경우 ElevenLabs는 필수이며, 그렇게 말하세요. '나중에' 및 '필요 없음'은 정상적인 답변입니다.
'지금'이라고 답한 각 서비스에 대해 SERVICES.md의 해당 섹션을 진행하세요: 링크와 단계를 자신의 말로 설명하고, '완료'를 기다리고, 자신의 부분을 설정하고 확인하세요:
- 키 (ElevenLabs, 21st.dev):
video/.env가 없으면cp video/.env.example video/.env; 사용자가 직접 키를 입력합니다(open -e video/.env). 확인은bash video/scripts/doctor.sh,access섹션. 거부되면 키가 완전히 복사되지 않았거나 필요한 권한이 없을 가능성이 높습니다. 새 키를 만들도록 하세요. - 21st.dev: 키 확인 후 로컬에 서버를 추가합니다(키는 셸에서 직접
.env에서 읽습니다):PATH에cd video && set -a && . ./.env && set +a && cd .. && claude mcp add --transport http 21st https://21st.dev/api/mcp --header "x-api-key: $TWENTYFIRST_API_KEY" --scope localclaude가 없으면 사용자에게 터미널에서 이 명령어를 실행하도록 안내합니다. - OAuth (Higgsfield, Buffer, 선택 사항으로 ElevenLabs MCP): 선택한 서버를 루트
.mcp.json에 추가합니다:브라우저 로그인은 Claude Code 재시작 후({ "mcpServers": { "higgsfield": { "type": "http", "url": "https://mcp.higgsfield.ai/mcp" }, "buffer": { "type": "http", "url": "https://mcp.buffer.com/mcp" }, "elevenlabs": { "type": "http", "url": "https://api.elevenlabs.io/v1/mcp" } } }/mcp→ 서버 → Authenticate): 지금 말하고 단계 5에서 상기시킵니다. Buffer의 경우 Buffer 자체에서 채널(Instagram 전문 계정)을 미리 연결하도록 요청하세요.
연결된 서비스를 integrations에 표시하세요. 서비스에 15분 이상 막혔으면 연기를 제안하세요: '나중에 연결하겠습니다. "Buffer 연결"이라고 말씀하세요.'
블록 5 — 당신이 좋아하는 것 (참고 자료 기반)
분석이 끝날 때까지 기다리세요(ps -axo command | grep "[r]efs.py"), takes/refs/refs.json을 읽고, 각각의 NN-hook.jpg, NN-sheet.jpg 및 palette.png를 확인하세요. 각 영상에 대해 숫자로는 볼 수 없는 것을 기록하세요: 자막(위치, 크기, 대소문자, 굵기, 색상, 단어 강조, 배경), 그래픽(카드 및 유형, 스티커, 스크린샷, B-roll, 이모지), 샷 크기 및 펀치인, 맨 얼굴 비율, 그래픽 팔레트, 글꼴, 후크 내용(텍스트 포스터, 질문, 액션), 엔딩.
'취향 프로필'로 요약하세요: 최소 절반의 영상에서 나타나는 57가지 패턴을 숫자(8의 제안이 됩니다. 거기서는 사용자의 장면을 다른 옵션 옆에 표시하고, 조용히 적용하지 않습니다. 설정에 맞지 않는 것(이모지 스티커, 그린 스크린 등)은 프로필에 희망 사항으로 기록하세요.refs.py의 중앙값)와 함께 표시합니다. 하나의 메시지로 보여주고 물어보세요: '이것이 당신을 설명하나요? 이 중에서 자신의 영상에 원하는 것과 원하지 않는 것은 무엇인가요?' 수락된 내용은 블록 6
블록 6 — 팔레트 (2~3 메시지)
6.1 질문 — 하나의 메시지로, 열린 텍스트:
- 브랜드 색상(로고, 웹사이트, 채널 디자인, 썸네일)이 있나요? hex, 웹사이트 링크를 보내거나 로고/스크린샷을
takes/brand/에 넣어주세요. - 영상에서 색상으로 강조해야 할 것은 무엇인가요? 숫자, 키워드, 클 투 액션?
- 어떤 느낌이 필요한가요? 엄격함, 따뜻함, 화려함, 차분함?
- 확실히 피해야 할 색상은 무엇인가요?
이미지를 보내면 주요 색상을 추출하세요:
python3 -c "
from PIL import Image; import sys
im = Image.open(sys.argv[1]).convert('RGB').resize((200, 200)).quantize(6)
pal = im.getpalette(); cnt = sorted(im.getcolors(), reverse=True)
print([('#%02X%02X%02X' % tuple(pal[i*3:i*3+3]), round(100*n/40000)) for n, i in cnt])
" takes/brand/logo.png
웹사이트 링크는 열어서 주요 색상(로고, 버튼, CSS 변수)을 찾으세요.
6.2 후보 — 2~3개의 팔레트. 각각 네 가지 역할: dark (플래카드, 스크림), light (텍스트), accent (강조), pain (경고 카드, 필요한 경우):
- 참고 자료에서 —
refs.json의recurring_colours및palette.png; 스토리보드와 교차 확인하여 색상이 그래픽 또는 텍스트인지, 벽, 장면 내 물체 또는 피부가 아닌지 확인합니다. - 브랜드 색상에서 (있는 경우);
- 6.1 답변에서 — 느낌과 강조할 내용.
가독성(기술, 취향 아님): 플래카드 및 푸티지 위의 텍스트는 읽을 수 있어야 합니다. 각 후보의 대비를 확인하세요(light on dark ≥ 7:1, accent on dark ≥ 3:1); 후보가 통과하지 못하면 말하고 통과하는 가장 가까운 것을 제안하세요:
python3 -c "
import sys
def L(h):
c=[int(h[i:i+2],16)/255 for i in (1,3,5)]
c=[x/12.92 if x<=0.03928 else ((x+0.055)/1.055)**2.4 for x in c]
return 0.2126*c[0]+0.7152*c[1]+0.0722*c[2]
a,b=sorted([L(sys.argv[1]),L(sys.argv[2])]); print(round((b+0.05)/(a+0.05),1))
" '#FFFFFF' '#141414'
6.3 장면으로 보여주세요:
cd video && python3 scripts/variants.py out/palette-options.png 70,368 \
'{"label":"A","colors":{"dark":"#…","light":"#…","accent":"#…","pain":"#…"}}' \
'{"label":"B","colors":{…}}' '{"label":"C","colors":{…}}'
시트를 보여주고(SendUserFile), 설명을 추가하세요: 'A — 참고 자료에서, B — 로고에서, C — 느낌에 따라'. 수정('A, 하지만 악센트가 더 어둡게') — 새로 실행하세요. 선택된 것은 colors에 저장합니다.
블록 7 — 글꼴 (2~3 메시지)
두 가지 글꼴: 텍스트 (자막 및 카드, 무게 500 / 600 / 700) 및 포스터 (영상 시작 부분의 제목, 있는 경우). 둘 다 영상 언어의 알파벳을 지원해야 합니다.
7.1 질문 — 하나의 메시지로: 브랜드 글꼴(이름 또는 takes/brand/의 파일)이 있나요? 어떤 성격인가요? 엄격함, 친근함, 기술적, 편집적? 자막은 가벼운가요 무거운가요?
블록 2가 있었다면 스토리보드에서 자막과 제목을 보고 무엇이 보이는지 말하세요: 유형(기하학적 그로테스크, 네오 그로테스크, 좁은, 둥근, 세리프), 굵기, 대소문자. 이미지에서 정확한 이름을 추측하지 마세요. 유사한 무료 글꼴을 선택하세요.
7.2 후보 — 2~3개의 '텍스트 + 포스터' 쌍. @fontsource에서 필요한 알파벳으로, 성격이 다르며, 사용자의 답변과 참고 자료에 맞습니다. 러시아어의 경우 키릴 문자를 확인하세요. Bebas Neue는 라틴 문자만 지원합니다. 구매한 브랜드 글꼴은 video/src/fonts/에 수동으로 넣고 @font-face를 font-display: block과 함께 추가하세요. 저장소가 공개된 경우 라이선스에 대해 상기시키세요.
7.3 장면으로 보여주세요:
cd video && npm i @fontsource/<a> @fontsource/<b> # 후보
ls node_modules/@fontsource/<a>/ | grep -c cyrillic # ru의 경우 > 0
ls node_modules/@fontsource/<a>/ | grep -E '^[0-9]+\.css$' # 사용 가능한 무게
grep -m1 font-family node_modules/@fontsource/<a>/400.css # 정확한 패밀리 이름
video/src/index.css에 후보의 무게 가져오기를 추가하세요(@import "@fontsource/<a>/600.css"; …), 그런 다음:
python3 scripts/variants.py out/font-options.png 70,368 \
'{"label":"A","fonts":{"text":"…","poster":"…","posterWeight":700}}' '{"label":"B","fonts":{…}}'
보여주고 설명을 추가하세요. 선택 후 index.css에 선택된 가져오기만 남기고 불필요한 패키지를 제거하세요(npm un …).
블록 8 — 편집 스타일 (주제당 하나의 메시지)
네 가지 주제, 각각 별도 메시지: 질문, 참고 자료에서 보이는 것('10개 중 7개에서 자막이 중앙에 크게 있음'), 그런 다음 variants.py를 통해 2~3개의 옵션을 장면으로 보여줍니다(키 style.*, 프레임 70,270,368). '추천' 없이.
8.1 자막 (style.captions):
- 위치:
cycle— 문구가 프레임 주위를 이동(왼쪽 위 → 오른쪽 위 → 아래);rail— 항상 아래;center— 중앙; - 크기
size: [일반 단어, 강조 단어]in px (≈ 48 작음, 60 중간, 76 큼); - 굵기
weight(500–800); 대소문자case:lower/asis/upper; - 강조
highlight:color(액센트 색상의 키워드) /size(크게) /both/none; - 배경
box:true— 줄 아래 플래카드,false— 그림자.
8.2 그래픽:
- 카드
style.cards:glass(반투명 유리) /solid(단색 플래카드) /none; 빈도는editing-taste.md§3에 말로 표현; - 일시 정지 시 스티커 그림 문자
style.stickers:true/false; - 시작 부분 머리 뒤 포스터 제목
style.poster:enabled, 대소문자case(upper/asis), 작은 부제kicker. 활성화된 경우 rembg 필요(~영상당 30분 백그라운드, 모델 ~1GB 한 번); - B-roll (Higgsfield가 연결된 경우): 필요한지, 얼마나 필요한지
brand-kit.md§5에 말로 표현.
8.3 움직임과 화면:
(원본에서 잘린 부분 – 번역은 여기까지 제공된 내용을 기준으로 함)
단계 3. 스타일 저장
cd video && python3 scripts/variants.py out/style-preview.png 70,270,368 \
'{"label":"선택됨","captions":{…},"cards":{…},"motion":{…},"colors":{…},"fonts":{…}}'
최종 미리보기를 보여주고 확인을 요청하세요. 확인되면 harness.config.json의 "configured": true를 설정하고, brand-kit.md, editing-taste.md, exemplars.md를 업데이트하세요.