Community코딩 & 개발github.com

15yotsuka/claude-skills

Agent skill / project related to launch or product demo video: 15yotsuka/claude-skills

claude-skills란 무엇인가요?

claude-skills is a Claude Code agent skill that agent skill / project related to launch or product demo video: 15yotsuka/claude-skills.

지원 대상Claude Code~Codex CLI~Cursor
npx skills add 15yotsuka/claude-skills

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

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

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

문서

saas-demo-maker

Overview

This skill captures screenshots from any web or local app and renders a polished, silent SaaS demo video (MP4). It is modeled on the proven Castify pipeline at ~/SaaS/castify/generate_castify_demo.py and generalizes it for any Aperone project.

When invoked, you MUST produce an MP4 by the end of the session. Do not stop at "here is a plan" — execute it.


When to Use

以下のいずれかに該当すれば必ず起動する(部分一致・言い換えも含む)。

日本語トリガー

  • デモ動画 / デモMP4 / デモ動画を作って / デモ動画を生成して
  • プロモ動画 / 紹介動画 / サービス紹介動画
  • スクショ撮って動画にして / スクリーンショットを動画にして
  • 動画を作って(SaaSやアプリの文脈)
  • 既存のスクショから動画を作って
  • 画面録画(静止画合成で代替する旨を伝えてから対応)

英語トリガー

  • demo video / demo MP4 / product demo
  • promotional video / promo video / intro video
  • screenshot to video / capture and render
  • make a video from screenshots

/saas-demo-maker コマンド直接指定

判断が難しいケース(起動してよい)

  • 「動画」「MP4」「スクショ」を含み、アプリ・SaaS・ツールの文脈がある
  • ローカルアプリや公開URLへの言及がある
  • 「既存の画像から動画にして」という依頼

Inputs

Parse from the user's message:

InputDefaultNotes
urlFull URL or http://localhost:3000
product_nameinferred from projectUsed in pill and config
brand_color#7c3aedOverride VIOLET constant
screens5Number of screenshots to capture
output_pathoutput/saas_demo.mp4Relative to project root
modefullfull / capture / render
localeja if Japanese message, else enAffects step text
stepsfrom templates.md presetUser-supplied text wins
assets_diroutput/screenshotsSource images for render mode

Modes

full mode

Capture screenshots from a live URL or local app, then render the video.

Trigger examples:

/saas-demo-maker https://castify.aperone.com からサービスカード用デモ動画を作って。5画面、20秒以内、ブランドカラーは#7c3aed、出力はoutput/castify_demo.mp4
/saas-demo-maker http://localhost:3000 のLP、ログイン、ダッシュボード、入力、結果画面を撮って、無音ループ用のSaaSデモMP4を作って

capture mode

Screenshot capture only — no video rendering.

Trigger examples:

/saas-demo-maker スクショだけ撮って。LP、ログイン、ダッシュボード、入力、結果の5枚

render mode

Render video from existing screenshots — no capture step.

Trigger examples:

/saas-demo-maker assetsの既存スクショ5枚から動画だけ作って。プロダクト名はAperone Academy、ブランドカラーは#7c3aed
/saas-demo-maker assetsの5枚から動画だけ作って。プロダクト名はCastify、出力はoutput/castify_demo.mp4

Workflow

Step 0 — Pre-flight

  1. Read demo_config.json if it exists in the current project.
  2. Check for existing screenshots in output/screenshots/ or assets/.
  3. Detect mode from user message (default: full).
  4. Confirm output/ directory exists or create it.

Step 1 — Generate config

Write demo_config.json to project root:

  • Use values parsed from user message.
  • Choose step texts from templates.md preset matching product_name, or generic template for the screen count, or user-supplied text.
  • Write the file now, before any script generation.

Step 2 — Write scripts (full or capture mode)

Write capture_screenshots.py to project root. Write generate_saas_demo.py to project root. Write README_demo_video.md to project root (first time only; skip if exists).

For render mode, skip capture_screenshots.py.

Step 3 — Install dependencies (if missing)

Check and install as needed (see reference.md for commands):

  • ffmpegwhich ffmpeg || brew install ffmpeg
  • pillowpython3 -c "import PIL" || python3 -m pip install pillow
  • For TypeScript capture: check node_modules/playwright exists

Step 4 — Capture (full or capture mode)

Run the capture script:

python3 capture_screenshots.py

Or if the project has an existing Playwright TypeScript capture script (e.g., scripts/demo-screenshots.ts), prefer that:

npx tsx scripts/demo-screenshots.ts

Check that output/screenshots/ contains at least 2 PNG files after capture. If capture fails, read the error, fix capture_screenshots.py, and retry.

Step 5 — Render (full or render mode)

Run:

python3 generate_saas_demo.py

Watch for errors. If the script crashes, read the traceback, fix the script, and re-run. Do not ask the user — self-heal up to 3 attempts.

Step 6 — Quality check

Run ffprobe to verify:

ffprobe -v error -select_streams v:0 \
  -show_entries stream=width,height,duration,codec_name,pix_fmt \
  -of default output/saas_demo.mp4

Verify all 10 items from the quality checklist in reference.md. If any item fails, fix and re-render.

Step 7 — Report

Output the final response (see "Final response format" below).


Screenshot Capture Spec

Resolution

1280 × 720 (Chromium viewport)

Browser

Playwright Chromium, headless.

Wait strategy

await page.goto(url, wait_until="networkidle")
await page.wait_for_timeout(800)  # extra settle time

Candidate local URLs (try in order)

http://localhost:3000
http://localhost:5173
http://localhost:8000
http://localhost:8080

Output directory

output/screenshots/ relative to project root.

Standard filenames

01-landing.png
02-login.png
03-dashboard.png
04-input.png
05-result.png
06-options.png   (if 6+ screens)
07-processing.png (if 7 screens)

Local app startup

  1. Read package.json to find the dev script (dev, start, etc.).
  2. Start the dev server in the background.
  3. Wait until the candidate URL responds (max 30 s).
  4. Capture screenshots.
  5. Stop the dev server.

Auth handling

  • If .env contains test credentials and a dev-bypass flag (e.g., DEV_BYPASS_AUTH=true), set it in the environment before launching.
  • For login screens: fill a demo email (demo@<product>.io) without submitting — capture the filled state as the login screen.
  • Do not attempt real auth bypass or brute-force login.
  • If a page redirects to sign-in and bypass is unavailable, use the login screen as one of the demo screens (it looks credible).

Dev-mode artifacts

Clerk development mode banner, Next.js dev indicator, debug overlays — do NOT try to remove them in the browser. Instead, cover them in the render step with a gradient overlay or a dark panel at the bottom of the card.


Render Spec

Architecture

Generate all frames as PNG files in output/frames/, then encode with ffmpeg. Do NOT use moviepy for encoding — use ffmpeg subprocess directly.

Image sizing

card = ImageOps.fit(image.convert("RGBA"), (card_w, card_h),
                    method=Image.Resampling.LANCZOS)

This is the ONLY allowed image sizing method. The screenshot must be completely static inside each scene — no zoom, no pan, no Ken Burns.

Ken Burns — PROHIBITED

Do not apply any per-frame scale factor or position offset to the screenshot. The screenshot pixel content must not change between frame 0 and frame 98 of a scene. Only overlays (caption, pill, progress bar, glow) may animate.

Caption animation (allowed)

The caption panel may fade in and translate up 8 px over the first 20 % of a scene (scene_t < 0.2). This is the only allowed animation on the image layer.

Timing

SCENE_SECONDS     = 3.3   # fixed — do not change
TRANSITION_SECS   = 0.4   # fixed — do not change
FPS               = 30
SCENE_FRAMES      = 99
TRANSITION_FRAMES = 12

Transition

Horizontal slide: outgoing frame exits left, incoming frame enters from right. Use ease_in_out_cubic. Add a narrow seam-softening veil at the cut boundary. See reference.md for the full algorithm.

ffmpeg command

Use the exact command from reference.md. Key flags: -c:v libx264 -pix_fmt yuv420p -movflags +faststart -an -crf 18


Visual Design Rules

Background

#020617  (BG)  — fill behind card

Card layout

card_box = (34, 22, WIDTH-34, HEIGHT-22)
radius   = 30

Top chrome accent line at card_box[1] + 48. Card border: 1 px CARD_EDGE.

Overlays (all required)

  • Progress bar — segmented, top of card, violet fill for completed steps
  • Caption panel — bottom-left, glass dark panel, STEP N / name / body
  • Product pill — bottom-right, brand color dot + product name
  • Focus glow — violet glow around the key UI element (see reference.md for inference)
  • Vignette — subtle dark rounded edge on the full frame
  • Bottom gradient — covers dev-mode artifacts in the lower card area when needed

Prohibited design elements

  • White text on plain black box (no glass effect)
  • Excessive bloom / oversaturated glow
  • 3D transforms or perspective warps
  • Any distortion of the screenshot UI
  • Editing or replacing text visible in the screenshot

Configuration Rules

Write demo_config.json before running any script. When re-running in render mode, read the existing config first and merge user overrides rather than overwriting.

Schema:

{
  "product_name": "string",
  "brand_color": "#7c3aed",
  "output_path": "output/saas_demo.mp4",
  "screenshots": ["output/screenshots/01-landing.png"],
  "steps": [{ "step": 1, "name": "...", "body": "...", "focus": null }],
  "fps": 30,
  "resolution": [1280, 720],
  "mode": "full",
  "locale": "ja"
}

Implementation Requirements

capture_screenshots.py responsibilities:

  • Launch Playwright Chromium headless
  • Set viewport 1280 × 720
  • Navigate each target URL, wait for networkidle + 800 ms settle
  • Save PNGs to output/screenshots/ with standard filenames
  • Move mouse off-screen before each screenshot (page.mouse.move(1400, 800))
  • Print success/failure per screenshot
  • Exit code 0 on success, 1 on failure

generate_saas_demo.py must contain all functions listed in reference.md. Key invariants:

  • SCENE_SECONDS = 3.3 — hardcoded, no config override
  • TRANSITION_SECONDS = 0.4 — hardcoded, no config override
  • fit_cover() calls ImageOps.fit() — no zoom arithmetic
  • render_scene() does NOT modify scale per frame
  • encode_video() calls ffmpeg subprocess with -an flag

Quality Checklist

After encode_video() succeeds, verify ALL of these before reporting done:

  1. output/saas_demo.mp4 exists, size > 100 KB
  2. Duration within ±2 s of (screen_count × 3.3 s)
  3. Width=1280, Height=720 (confirmed by ffprobe)
  4. No audio stream
  5. codec_name = h264
  6. pix_fmt = yuv420p
  7. All screenshots appear in correct order
  8. No glaring dev-mode banner visible (covered by overlay if needed)
  9. Result/output screen clearly communicates product value
  10. Caption text is readable on all scenes

Run this check:

ffprobe -v error -select_streams v:0 \
  -show_entries stream=width,height,duration,codec_name,pix_fmt \
  -of default output/saas_demo.mp4

Failure Recovery

FailureRecovery
ffmpeg not foundbrew install ffmpeg, then retry
PIL not foundpython3 -m pip install pillow, then retry

관련 스킬