Communitygithub.com

show-n-tell

사용자가 웹사이트를 탐색하며 내레이션이 포함된 브랜드 데모 비디오를 만들 수 있도록 지원합니다. 사이트 탐색, 스토리보드 초안 작성, TTS 내레이션, Playwright 녹화, 오디오/비디오 믹싱, 속도 조절, 브랜드 오버레이 등을 통해 완성도 높은 mp4를 생성합니다.

show-n-tell란 무엇인가요?

show-n-tell은 사용자의 의도와 로고를 바탕으로 모든 웹사이트를 5분 분량의 내레이션이 포함된 브랜드 데모 비디오로 변환하는 AI 에이전트 스킬입니다. 이 스킬은 사이트 탐색, 스토리보드 초안 작성(사용자 검토 포함), OpenAI를 통한 TTS 내레이션, Playwright 녹화, 오디오/비디오 믹싱, 속도 조절, 브랜드 오버레이, 인트로/아웃트로 및 자막 추가(향후 단계) 등 전체 파이프라인을 오케스트레이션합니다. Claude Code CLI와 Cowork 환경을 모두 지원하며, 각 환경에 따라 적응적으로 작동합니다. 사용자가 인증이 필요한 사이트(폼 기반 로그인, OAuth, SSO, 매직 링크 등)를 데모할 경우 auth 캡처 기능을 제공하며, 스킬은 사용자와의 대화형 인터뷰를 통해 데모 의도, 대상 청중, 톤, 길이, 브랜드 컬러 등을 수집합니다. 최종 결과물은 완성도 높은 mp4 파일로, 데모 비디오 제작 과정을 자동화하여 개발자와 제품 팀이 제품 시연을 효과적으로 커뮤니케이션할 수 있도록 돕습니다.

지원 대상✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/carveragents/show-n-tell/tree/main/skills/show-n-tell

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

show-n-tell은(는) 무엇을 하나요?

당신은 모든 웹사이트 + 로고 + 약간의 의도를 5분 분량의 내레이션이 포함된 브랜드 데모 비디오로 전환하는 전체 파이프라인을 조율합니다. scripts/의 스크립트는 단순한 파이프일 뿐이며, 당신이 지휘자입니다.

참고 문서는 이 폴더에 있습니다: docs/SCHEMAS.md (YAML + 액션 문법), docs/GOTCHAS.md (알려진 문제 + 해결 방법), docs/CONTEXT.md ("좋은 출력의 모습"), examples/halyard-spme/ (표준 완전 예제). 필요할 때 읽으십시오. 미리 로드하지 마십시오.

이 스킬을 사용해야 하는 경우

  • 사용자가 웹사이트(실시간, 로컬 개발, 또는 정적)의 내레이션 데모 비디오를 원합니다.
  • 사용자가 최소한의 의도 가이드라인을 제공합니다("X, Y, Z를 보여줘" / "대시보드 흐름 데모").
  • 사용자가 로고 또는 워드마크에 접근할 수 있습니다.

사용자가 의도 노트나 로고를 제공하지 않으면 진행을 거부하십시오. 기본 브랜딩으로 제네릭 데모를 만드는 것은 좋지 않은 데모입니다. 약한 비디오를 조용히 생성하는 대신 가이드를 요청하십시오.

환경 감지 (시작하기 전에 읽으십시오)

무엇이든 하기 전에, Claude가 실행 중인 환경을 결정하십시오:

  • Cowork: mcp__cowork__list_artifacts 및 mcp__computer-use__screenshot이 Claude의 도구 목록에 있습니다.
  • Claude Code CLI: 해당 도구가 없습니다.

이는 여러 단계가 환경 간에 다르게 동작하기 때문에 중요합니다. 빠른 참조:

단계Claude Code CLICowork
작업 디렉토리 (5단계)~/demo-videos/<slug>/request_cowork_directory가 경로를 출력
사이트 탐색 공개 (2b단계)Playwright MCP 도구Chrome MCP 도구 또는 헤드리스 explore_page.py
인증 캡처 OAuth (2a단계)Bash를 통해 capture_auth.py 실행사용자가 로컬에서 capture_auth.py 실행
긴 명령어 (7-9단계)동기적으로 실행nohup + 폴링 (45초 bash 타임아웃)
핸드오프 (11단계)mp4 경로 보고mp4 경로 + computer:// 링크

1단계 — 인터뷰 (입력 수집)

한 번에 모든 것을 묻지 말고, 한두 가지 질문을 하십시오. 필수:

  1. 타겟 URL — 접근 가능한지 확인하십시오.
  2. 데모 의도 노트 — 어떤 이야기를 전달합니까? 어떤 기능이 중요합니까?
  3. 대상 + 어조 — 내부/외부/투자자; 설명/판매/기술/캐주얼.
  4. 길이 목표 — 기본 5분.
  5. 로고 — URL 또는 경로. 텍스트 전용만 가능한 경우, 제한 사항을 표시하되 수락하십시오.
  6. 브랜드 색상 — 기본(잉크) + 강조. 지정되지 않은 경우, PIL로 로고에서 추론하십시오.
  7. 인증? — 사이트에 로그인이 필요합니까?
    • 아니요 → 진행.
    • 예, 양식 기반(사이트에 제어 가능한 자체 이메일/비밀번호 필드가 있음) → demo_config.yaml에서 session.pre_session을 사용하십시오. 자격 증명 환경 변수 이름(실제 값이 아님)과 로그인 URL/선택기를 수집하십시오. 사용자에게 실행 전에 실제 자격 증명을 <working_dir>/.env에 직접 넣도록 지시하고, 채팅에 절대 넣지 마십시오. examples/login-flow/를 참조하십시오.
    • 예, OAuth / SSO / 매직 링크 / 패스키(Google, Microsoft, Okta 등) → session.storage_state를 사용하십시오. 사용자는 어떤 명령도 실행하지 않습니다. 당신이 2a단계에서 helpers/capture_auth.py를 실행하고, 사용자는 열리는 브라우저 창에서 대화식으로 로그인하기만 하면 됩니다. 캡처된 auth.json은 2b단계 탐색과 8단계 녹화 모두에 사용됩니다. examples/oauth-storage-state/를 참조하십시오.

2a단계 — 인증 캡처 (OAuth 전용)

1단계 질문 7이 "인증 없음" 또는 "양식 기반"으로 결정된 경우 이 단계를 완전히 건너뛰십시오. OAuth / SSO / 매직 링크 / 패스키의 경우, 사이트 탐색 전에 지금 인증된 세션을 캡처하십시오 — 2b단계에서 인증된 페이지를 보려면 필요합니다.

mkdir -p ~/demo-videos/<demo-slug>/
uv run helpers/capture_auth.py <login_or_start_url> \
  --out ~/demo-videos/<demo-slug>/auth.json \
  --viewport <recording.viewport from demo_config.yaml; default 1440x900>

timeout: 600000(10분 — 최대)과 함께 Bash 도구를 통해 실행하십시오. 스크립트는 헤드 Chromium 창을 엽니다. 사용자에게 평이한 말로 알립니다:

"로그인할 수 있도록 브라우저 창을 열겠습니다. 로그인(Google, Microsoft 등, 2FA 처리)을 완료하고, 녹화를 시작할 페이지로 이동한 다음 브라우저 창을 닫으십시오. 세션을 저장하고 자동으로 계속하겠습니다."

스크립트는 auth.json을 모드 0600으로 원자적으로 씁니다. 사용자가 10분 이상 걸리는 경우(드물지만, 다른 방에서 전화 기반 2FA로 가능), Bash 타임아웃이 발생합니다 — 동일한 명령을 다시 실행하면 됩니다.

--viewport는 demo_config.yaml의 recording.viewport와 일치해야 합니다. 일부 사이트는 뷰포트 크기를 지문으로 식별합니다. 불일치는 녹화 시간 또는 탐색 시간에 캡처된 세션을 무효화할 수 있습니다.

Playwright의 Chromium이 아직 설치되지 않은 경우(새 스킬 클론), 스크립트는 실행 가능한 오류를 표시합니다. uv run --with playwright playwright install chromium을 한 번 실행하십시오.

Claude Code CLI에서 실행 중인 경우: 위에서 설명한 대로 Bash를 통해 capture_auth.py를 실행하십시오.

Cowork에서 실행 중인 경우: Claude는 computer-use 및 Chrome 도구를 사용하여 이를 직접 처리합니다. 사용자는 브라우저가 열릴 때 로그인하기만 하면 됩니다. 단계:

  1. 작업 디렉토리 경로가 알려져 있는지 확인하십시오. 5단계가 아직 실행되지 않은 경우, 지금 mcp__cowork__request_cowork_directory를 호출하여 출력 경로를 얻고 <working_dir>을 <outputs_path>/<demo-slug>/로 설정하십시오.

  2. 사용자 데스크탑에서 Chrome을 엽니 다:

    mcp__computer-use__open_application  →  "Google Chrome"  (또는 "Chrome")
    
  3. 로그인 URL로 이동하십시오. 연결된 경우 Chrome MCP를 선호하십시오:

    • Chrome 확장 프로그램 사용 가능: mcp__Claude_in_Chrome__navigate to <login_or_start_url>
    • Chrome 확장 프로그램 미연결: mcp__computer-use__* 도구를 사용하여 주소 표시줄을 클릭하고 URL을 입력하십시오
  4. 사용자에게 로그인하라고 알리십시오 — 평이한 말로 말하십시오:

    "Chrome이 로그인 페이지에서 열렸습니다. 로그인하고(2FA, SSO 등 처리), 녹화를 시작할 페이지로 이동하십시오. 완료되면 알려주십시오."

  5. 기다리고 관찰하십시오. 약 15초마다 mcp__computer-use__screenshot으로 폴링하십시오. URL이 더 이상 로그인/인증 페이지가 아니고 대시보드 또는 앱 페이지가 표시되면 계속하십시오.

  6. JavaScript를 통해 세션 상태를 추출하십시오. mcp__Claude_in_Chrome__javascript_tool로 이 스니펫을 실행하십시오:

    (() => {
      const cookies = document.cookie.split(';').map(c => {
        const [name, ...rest] = c.trim().split('=');
        return { name: name.trim(), value: rest.join('='), domain: location.hostname,
                 path: '/', expires: -1, httpOnly: false, secure: location.protocol === 'https:',
                 sameSite: 'Lax' };
      }).filter(c => c.name);
      const ls = {};
      for (let i = 0; i < localStorage.length; i++) {
        const k = localStorage.key(i);
        ls[k] = localStorage.getItem(k);
      }
      const ss = {};
      for (let i = 0; i < sessionStorage.length; i++) {
        const k = sessionStorage.key(i);
        ss[k] = sessionStorage.getItem(k);
      }
      return JSON.stringify({
        cookies,
        origins: [{ origin: location.origin,
                    localStorage: Object.entries(ls).map(([n,v]) => ({name:n,value:v})),
                    sessionStorage: Object.entries(ss).map(([n,v]) => ({name:n,value:v})) }]
      }, null, 2);
    })()
    
  7. 결과를 <working_dir>/auth.json에 쓰십시오 Write 도구를 사용하여. 이는 유효한 Playwright storage_state 형식입니다 — helpers/explore_page.py와 record_demo.py 모두 browser.new_context(storage_state=...)를 통해 이를 사용합니다.

  8. HttpOnly 쿠키 주의. JavaScript는 HttpOnly 쿠키를 읽을 수 없습니다. 이는 document.cookie에 의도적으로 표시되지 않습니다. 사이트의 세션 토큰이 HttpOnly 전용인 경우(오래된 Rails/Django 세션 쿠키에서 일반적), 추출된 상태에는 이것이 누락됩니다. 사용자에게 알립니다:

    "참고: HttpOnly로 표시된 세션 쿠키는 JavaScript에서 접근할 수 없으므로 모든 인증 토큰을 캡처하지 못했을 수 있습니다. 녹화는 캡처된 내용을 사용하려고 시도합니다 — 8단계 중 로그인 벽에 부딪히면 로컬에서 capture_auth.py를 사용하는 것으로 대체할 수 있습니다." 그런 다음 계속하십시오 — 많은 최신 사이트(Google, Microsoft, Okta)는 Playwright가 작동하도록 비HttpOnly 쿠키나 localStorage에 충분한 상태를 유지합니다.

2b단계 — 사이트 탐색

2a단계가 실행된 경우(auth.json이 존재함), helpers/explore_page.py를 사용하여 인증된 페이지를 보십시오 — Playwright MCP는 storage_state를 로드할 수 없고 로그인 벽만 표시합니다. 인증되지 않은 데모의 경우 Playwright MCP가 더 상호 작용적이므로 이전과 같이 사용하십시오.

인증된 페이지의 경우:

mkdir -p ~/demo-videos/<demo-slug>/_explore/
uv run helpers/explore_page.py https://target.example.com/dashboard \
  --storage-state ~/demo-videos/<demo-slug>/auth.json \
  --out-dir ~/demo-videos/<demo-slug>/_explore/

페이지당 세 개의 파일을 _explore/에 씁니다: <slug>.png (스크린샷), <slug>.dom.html (선택기 선택을 위한 DOM), <slug>.meta.json ({url_requested, final_url, title, status}). Read 도구로 PNG를 읽어 페이지를 보십시오. DOM에서 선택기를 grep하십시오. meta.json의 final_url이 로그인 페이지를 가리키면 세션이 만료된 것입니다 — 2a단계를 다시 실행하십시오.

공개 페이지의 경우(모든 데모의 랜딩 페이지, 마케팅 페이지; 인증되지 않은 데모의 모든 것) — 이전과 같이 Playwright MCP 도구(mcp__plugin_playwright_playwright__*)를 사용하십시오:

  • browser_navigate를 타겟 URL로, 그 다음 사용자의 의도가 언급하는 2-5개 페이지로 이동하십시오.
  • browser_snapshot 또는 browser_take_screenshot을 사용하여 각 페이지의 레이아웃을 보십시오.
  • browser_evaluate를 사용하여 안정적인 선택기를 위해 DOM을 읽으십시오(가능한 경우 nth-of-type보다 의미론적 선호).

Claude Code CLI에서 실행 중인 경우: 위에서 설명한 대로 mcp__plugin_playwright_playwright__* 도구를 사용하십시오.

Cowork에서 실행 중인 경우: 먼저 Chromium을 사용할 수 있는지 확인하십시오:

uv run --with playwright playwright install chromium

그런 다음 사용 가능한 최상의 방법을 선택하십시오:

  • mcp__Claude_in_Chrome__navigate를 사용할 수 있는 경우(Chrome 확장 프로그램 연결됨), mcp__Claude_in_Chrome__navigate + mcp__Claude_in_Chrome__read_page를 사용하여 사이트를 대화식으로 탐색하십시오.
  • 그렇지 않으면 헤드리스 탐색으로 대체하십시오:
    mkdir -p <working_dir>/_explore/
    uv run helpers/explore_page.py <url> --out-dir <working_dir>/_explore/
    
    (공개 페이지에는 --storage-state가 필요하지 않습니다. 이 인수는 이제 선택 사항입니다.)

각 중요한 페이지에 대해 다음을 기록하십시오:

  • 데모에 적합한 순간(스크롤-투-피처, 클릭-투-세부 정보, 호버-툴팁).
  • 필요한 사이트 적응: 스티키 헤더 트릭? PDF 딥링크? 모달 차단기? 인증 벽?
  • 취약해 보이고 wait_for_selector 방어가 필요할 수 있는 선택기.

철저히 크롤링하지 마십시오. 페이지당 2-5개 작업이면 충분합니다.

3단계 — 초안 storyboard.yaml

15-30개의 비트를 생성하십시오. 각 비트 = 하나의 카메라 작업 + 1-3 문장의 내레이션. 액션 문법은 docs/SCHEMAS.md를 참조하십시오(Phase A 서브셋: goto, goto_and_scroll, scroll_into_view, scroll_y, hover, click).

1.2배 속도 향상 시 5분 비디오 목표:

  • 총 속도 향상 후: ~5:00
  • 총 원시 실행 시간: ~6:00
  • 비트당 평균: ~12초, 그 중 ~9-10초는 내레이션

내레이션 초안 작성 시 하드 규칙:

  1. 모든 사실적 주장은 이 비트의 프레임에서 화면에 표시되어야 합니다. 발명된 숫자는 안 됩니다("에이전트가 199개의 변경 사항을 플래그했습니다"). 스크린샷에서 보이지 않으면 말하지 마십시오.
  2. 문자 단위로 읽는 이니셜리즘은 하이픈으로 구분하여 작성해야 합니다: S-P-M-E, K-Y-B, A-P-I. TTS 프롬프트가 이 규칙을 적용합니다.
  3. 길이는 시각적 콘텐츠와 일치해야 합니다: 스크롤 비트의 경우 8-18초, 클릭 비트의 경우 6-12초.
  4. 어조는 branding.yaml의 voice.tone 필드와 일치해야 합니다.

비트를 세그먼트(개요 / 기능 A / 기능 B / 마무리)로 그룹화하되 YAML에 플랫 리스트를 작성하십시오 — 섹션 표시자는 없습니다.

4단계 — 평문 검토

사용자는 YAML을 직접 편집하지 않습니다. 당신은 초안을 번호가 매겨진 목록으로 제시하고 자연어 피드백을 수락합니다. 이 형식을 정확히 사용하십시오:

다음은 제가 작성한 데모 흐름입니다. 예상 실행 시간: 5:08 (1.2배 속도 향상 후).
변경하고 싶은 부분을 알려주십시오.

개요 (60초)
1. 홈페이지에 도착 (10초) — "Acme Cloud에 오신 것을 환영합니다. 소규모 팀을 위한 서버리스 플랫폼입니다..."
2. 기능으로 스크롤 (15초) — "플랫폼을 구동하는 세 가지 핵심 기능..."
3. 출력으로 스크롤 (8초) — "이 10가지 정책 영역..."

기능 1 — 대시보드 (45초)
4. 대시보드로 이동 (8초) — "대시보드로 클릭..."
5. 실시간 활동 피드 호버 (12초) — "모든 프로젝트는 실시간 활동 피드를 보여줍니다..."
...

마무리 (20초)
27. 홈페이지 통계로 돌아가기 (12초) — "팀이 Acme를 선택하는 세 가지 이유..."
28. 아웃트로 (8초)

그런 다음: "추가, 제거 또는 재정렬할 것이 있습니까? 내레이션 어조 조정이 필요합니까? 건너뛸 것이 있습니까?"

자연어 피드백을 YAML 편집으로 변환하십시오:

  • "비트 7 건너뛰기" → YAML에서 제거
  • "비트 3을 더 길게" → 더 많은 화면 세부 정보로 내레이션 확장(훨씬 길면 두 개의 비트로 분할)
  • "가격 언급" → 올바른 비트를 식별하고 문장 추가(가격이 해당 비트의 프레임에 실제로 표시되는지 확인)
  • "어조가 너무 공식적" → 더 느슨한 표현으로 내레이션 다시 작성
  • "소개 페이지 대신 팀 페이지 표시" → URL 교체 + 내레이션 조정

업데이트된 흐름을 다시 제시하십시오. 사용자가 명시적으로 승인할 때까지 반복하십시오.

TTS 전 실행 시간 드리프트 확인: 모든 비트에 대해 len(beat.narration) / 16 (140wpm에서 chars/sec)을 합산하십시오. estimated * (1 / speed_multiplier)가 목표에서 30초 이상 벗어난 경우 표시하십시오: "현재 속도 향상 후 ~6:20이며 5분 목표와 다릅니다. 줄일까요?"

5단계 — 작업 디렉토리 설정

mkdir -p ~/demo-videos/<demo-slug>/_assets
cp <logo_path>             ~/demo-videos/<demo-slug>/_assets/<logo>.png
# 초안에서 storyboard.yaml, branding.yaml, demo_config.yaml 작성

Claude Code CLI에서 실행 중인 경우: 위와 같이 ~/demo-videos/<demo-slug>/를 사용하십시오.

Cowork에서 실행 중인 경우: mcp__cowork__request_cowork_directory를 호출하여 사용자의 출력 경로를 얻으십시오. 작업 디렉토리를 <outputs_path>/<demo-slug>/로 설정하십시오. 6-11단계의 모든 후속 파일 쓰기에 이 경로를 사용하십시오 — 지금 저장하고 세션 전반에 걸쳐 일관되게 유지하십시오. 이 경로 아래에 _assets/ 하위 디렉토리를 생성하십시오. ~/demo-videos/ 아래에는 생성하지 마십시오.

사용자가 디스크에 로고 파일이 없고 URL만 있는 경우, curl로 다운로드하여 _assets/에 배치하십시오.

관련 스킬