faceless-explainer
faceless-explainer video workflow - arbitrary text (article / notes / topic / brief) -> narrator_scripts.json + audio (voice + BGM) + section_plan.md -> typography / abstract-graphics / diagram / data-viz video. Typical length up to ~3 min (sweet spot ~30-90s); a genuinely longer piece is general-video, not this workflow. Generates its OWN narration (TTS) — it does not sync to a user-supplied / pre-recorded voiceover (that is general-video). No website capture, no real product screenshots. If the text names a product / its site to promote, that is /product-launch-video; when product-vs-topic is unclear, start at /hyperframes-read-first.
다음 행동
결제 준비 중: 곧 구매할 수 있습니다
한 번 결제 · 평생 소장 · 업데이트 무료
기술 README 원문 보기
설치 옵션, 예시 코드, 세부 사용법을 영어 README 원문 그대로 확인합니다.
faceless-explainer - dispatch entry
Input is arbitrary text (article / notes / topic / brief). Output is a faceless explainer video: no captured website, no product screenshots — every visual is invented by the LLM (typography / abstract graphics / diagram / data-viz), chosen per scene by content. The style preset is auto-selected per input by the scriptwriting agent (Step 2) from the 5 shipped presets (block-frame / capsule / claude / pin-and-paper / scatterbrain; default pin-and-paper when nothing clearly fits).
> Confirm the route before Step 0. This skill explains a topic / concept with no product and no site to capture. If the text actually markets a product / names its site → /product-launch-video; there's a URL to turn into a video → /website-to-video; a GitHub PR → /pr-to-video; existing footage to caption / package → /embedded-captions · /graphic-overlays. Out of scope: timing visuals to a user-supplied / pre-recorded voiceover (faceless generates its own TTS → /general-video), or live / at-render-time data. Unsure product-vs-topic, or routed here on a vague request? Read `/hyperframes-read-first` first.
All artifacts go to PROJECT_DIR = videos/<project-name>/ (created in Step 0); all paths below are relative to it. Dispatch is harness-portable: before the first subagent dispatch, read <SKILL_DIR>/../hyperframes-core/references/subagent-dispatch.md once — it maps the dispatch verbs (parallel fan-out / background / wait) to your harness's primitives; a concurrency cap below N means waves of the cap size, never fewer workers. This file is a binding runbook, not background reading: execute the steps in order and produce every phase artifact with its designated script or agent role — do not substitute a freestyle pipeline, and do not skip a pause step because the request seems clear. A step you cannot perform → stop and report.
| Phase | Execution | Primary artifact | Detailed flow |
|---|---|---|---|
| init | Bash | hyperframes.json | Step 0 |
| scaffold | Bash (no agent) | capture/extracted/tokens.json + visible-text.txt | Step 1 |
| scriptwriting | subagent | narrator_scripts.json (incl. chosen stylePreset + orientation) | Step 2 / agents/scriptwriting.md |
| design-system | Bash (no agent, deterministic — style = narrator_scripts.stylePreset) | design-system/design.html + chunks/ | Step 2b |
| audio | audio.mjs in Bash | audio_meta.json | phases/audio/guide.md |
| visual-design | subagent | section_plan.md | agents/visual-design.md |
| prep | prep.mjs in Bash | group_spec.json | scripts/prep.mjs |
| captions (deterministic) | captions.mjs group -> captions.mjs html in Bash (no subagent) | caption_groups.json + compositions/captions.html | scripts/captions.mjs |
| scenes | N x subagent (parallel) | compositions/scene_*.html or compositions/group_w*.html | agents/hyperframes-scene.md |
| finalize (Phase 4c) | Bash prelude (wait-bgm + assemble + inject/verify-transitions + hoist-videos + sfx-verify + preflight) -> finalize subagent (fix brief findings in place + one lean contact-sheet look + render) | renders/video.mp4 | Step 7 / agents/hyperframes-finalize.md |
Prerequisites
macOS Apple Silicon or Linux x64. System tools: brew install python@3.11 node ffmpeg (use Homebrew Python, not /usr/bin/python3, or pip install is blocked by PEP 668); then npx hyperframes doctor once (downloads Chrome). The rendered overlap gate (scripts/check-overlap.mjs, run in worker self-checks and preflight) reuses that same cached Chrome — it never downloads a browser; its only dep is the puppeteer-core npm module, ensured once before scene fan-out (Step 5.5, --ensure-deps, ~5s, no full puppeteer install). Optional cloud keys (else local fallbacks) — inject in Step 0.5:
| Key | Used for | Default / fallback |
|---|---|---|
HEYGEN_API_KEY (or hyperframes auth login) | TTS (cloud, word-level timestamps) | voice: auto (first English starfish voice; override --voice) |
ELEVENLABS_API_KEY | TTS (cloud; needs pip install elevenlabs) | voice 21m00Tcm4TlvDq8ikWAM (Rachel) |
| neither, and not logged in | TTS | local Kokoro, voice am_michael (non-English: pass --voice) |
GEMINI_API_KEY / GOOGLE_API_KEY (aliases) | Lyria BGM | unset -> local MusicGen (first run downloads ~300 MB) |
Flow
Step 0.0 - Confirm the brief (ALWAYS ask one round, then build)
Before Step 0, always pause and ask the brief in one message, then wait for the user — never skip this, even for a request that looks complete. Lead with a recommended default for each field and pre-fill anything the user already gave (confirm it rather than re-asking blindly): the topic / angle (the one idea), length (default ~60-90s), and — if /hyperframes-read-first did not already set them — aspect (default 16:9; 9:16 for vertical) and language. Style is not asked here — the scriptwriting agent auto-picks the preset from the input in Step 2. Proceed to Step 0 only after the user replies; a "go" / "use the defaults" is a valid reply that accepts every default.
Step 0 - Initialize the video project
cwd is the agent workspace root (e.g. /tmp/explainer-video-...). Write all video artifacts under PROJECT_DIR = videos/<project-name>/.
<project-name>: use the directory the user gave (e.g. Use ./videos/refactoring-explainer), else a short kebab-case name derived from the input topic (<topic>-explainer / <topic>-howto). Not the workspace basename or a timestamp.
Only when $PROJECT_DIR/hyperframes.json is absent:
PROJECT_DIR="${LAUNCH_VIDEO_DIR:-videos/<project-name>}"
mkdir -p "$(dirname "$PROJECT_DIR")"
npx hyperframes init "$PROJECT_DIR" --non-interactive --skip-skills --example=blank> hyperframes init drops a generic AGENTS.md / CLAUDE.md into $PROJECT_DIR; leave them in place — they are agent scaffolding for whoever opens the finished project later. This skill (not those files) is the source of truth for the workflow, so do not treat their generic guidance as run-time constraints.
Constraints: never run hyperframes init / generate AGENTS.md / CLAUDE.md in the workspace root; never nest another hyperframes/ inside PROJECT_DIR; every Bash command (master + subagents) is a (cd "$PROJECT_DIR" && ...) subshell — never bare cd.
Step 0.5 - API key guidance
Skip if $PROJECT_DIR/.env exists or context.log is non-empty (= not the first run). Otherwise first detect what's available (HeyGen TTS on if $HEYGEN_API_KEY / $HYPERFRAMES_API_KEY set or ~/.heygen/credentials exists from hyperframes auth login; ElevenLabs / Gemini only if their env keys set), then always pause and offer the menu — wait for the user; do not proceed on your own even when a workable config is detected (the user may want to add a key like Gemini). State what's detected, then: paste keys (→ Write $PROJECT_DIR/.env, one KEY=value per line, overwrite same-name) / "go" (proceed with what's configured — env, .env, or hyperframes auth login) / "skip" (proceed with local fallbacks for anything unconfigured). Then proceed to Step 1.
Step 1 - Scaffold (Bash, NO agent, NO capture)
There is no website capture. Synthesize the minimal on-disk package the copied backend (build-design --capture, prep --capture) expects, directly from the user's text. capture/ holds synthetic tokens + the input text (NOT a scrape); capture/assets/ stays empty (faceless). With colors:[], build-design uses the pin-and-paper native palette; if the user supplied brand colors, fill colors[] (colors[0] becomes the brand primary).
(cd "$PROJECT_DIR" && mkdir -p capture/extracted capture/assets)
(cd "$PROJECT_DIR" && cat > capture/extracted/tokens.json <<'JSON'
{ "title": "<title>", "description": "<one-line>", "colors": [], "fonts": [], "headings": [], "sections": [], "ctas": [], "svgs": [], "cssVariables": {} }
JSON
)
(cd "$PROJECT_DIR" && printf '%s\n' "<full input text / article / notes / brief>" > capture/extracted/visible-text.txt)Validation:
[ -s "$PROJECT_DIR/capture/extracted/tokens.json" ] && \ [ -s "$PROJECT_DIR/capture/extracted/visible-text.txt" ] && \ [ -d "$PROJECT_DIR/capture/assets" ] && echo ok || echo missing
If any is missing, report and stop.
Step 2 - Scriptwriting (subagent — also picks the style preset)
Dispatch one subagent. prompt = full contents of agents/scriptwriting.md + the ## Dispatch context below, passed through verbatim:
SKILL_DIR: <absolute path> PROJECT_DIR: <video project root> Schema validator: <SKILL_DIR>/scripts/validate-narrator.mjs Input text: ./capture/extracted/visible-text.txt # The source article / notes / brief — the agent reads this first Style preset: pick one from the menu in the guide and emit it as the top-level `stylePreset` (default `pin-and-paper` when unsure); match the narration register to the chosen preset Orientation: <landscape | portrait | square> # From the Step 0.0 aspect (16:9→landscape, 9:16→portrait, 1:1→square; default landscape). Emit it VERBATIM as the top-level `orientation` field — this is dictated, not a creative choice; it sets the canvas (portrait→1080×1920) for the whole pipeline. Script style: Keep each scene's script concise — 1-2 sentences, no more than 20 words
> Fill the Orientation: line from the aspect confirmed in Step 0.0 (default landscape). prep reads narrator_scripts.orientation → stamps group_spec.width/height; without it the video stays 16:9.
The agent picks an explainer structure for narrativeArchetype (concept-explainer / how-to-process / listicle / story-explainer, or "<outer> with <inner>"), picks a top-level `stylePreset` from the 5 shipped presets (consumed by Step 2b), echoes the dispatched `orientation` as a top-level field (consumed by Step 5 prep → canvas size), and emits narrator_scripts.json (it runs the validator before returning). continuity drives worker grouping: continue = same worker as the previous scene (a run of up to 3 scenes, cap=3); break = new worker; scene 1 is always break. intent / sharedMotif are soft hints. assetCandidates is [] on essentially every scene (faceless).
Step 2b - Design system (Bash, NO agent, deterministic — style chosen by Step 2)
Read the agent's stylePreset from narrator_scripts.json (default pin-and-paper if absent), then run three deterministic commands to produce a fully-styled design.html + chunks against the synthetic input:
STYLE=$(cd "$PROJECT_DIR" && node -e 'try{const p=require("./narrator_scripts.json").stylePreset;process.stdout.write((p&&String(p).trim())||"pin-and-paper")}catch{process.stdout.write("pin-and-paper")}')
(cd "$PROJECT_DIR" && node <SKILL_DIR>/phases/design-system/scripts/build-design.mjs ./design-system --no-emit --style "$STYLE")
(cd "$PROJECT_DIR" && node <SKILL_DIR>/phases/design-system/scripts/build-design.mjs ./design-system --style "$STYLE")
(cd "$PROJECT_DIR" && node <SKILL_DIR>/phases/design-system/scripts/emit-chunks.mjs ./design-system)stylePreset must be one of the 5 shipped presets (block-frame / capsule / claude / pin-and-paper / scatterbrain); an unknown name makes build-design.mjs exit 1 — fall back to pin-and-paper and rerun. This step depends only on narrator_scripts.json, so it may run in parallel with Step 3 audio; both must finish before Step 4 visual-design.
Validation:
[ -s "$PROJECT_DIR/design-system/inference.json" ] && \ [ -s "$PROJECT_DIR/design-system/design.html" ] && \ [ -s "$PROJECT_DIR/design-system/chunks/index.json" ] && echo ok || echo missing
If any is missing, read the build-design / emit-chunks stderr, fix the invocation, and rerun (deterministic, finishes in seconds).
Step 3 - Audio
After narrator_scripts.json exists:
(cd "$PROJECT_DIR" && node <SKILL_DIR>/scripts/audio.mjs \ --narrator-scripts ./narrator_scripts.json \ --hyperframes . \ --out ./audio_meta.json \ --lyria-recipe <SKILL_DIR>/phases/audio/lyria-recipe.py)
BGM generation runs detached in the background when keys/deps allow, otherwise is silently skipped. Flags + BGM mechanics: top of audio.mjs.
- exit 0 -> voice + transcribe complete (BGM may still be rendering;
audio_meta.jsonrecordsbgm_log/bgm_pid), continue. - exit 1 -> zero scenes produced voice; report and stop.
Step 4 - Visual design
After design-system/chunks/index.json, narrator_scripts.json, and audio_meta.json exist, concatenate all inputs into one dispatch packet (contracts first, static references middle, work items last):
# Dispatch packets live in $PROJECT_DIR/.dispatch/ (transient; safe to delete after the run).
# NEVER use a fixed /tmp path: it persists across runs/projects, so a failed write silently
# reuses another project's stale packet and contaminates every worker.
mkdir -p "$PROJECT_DIR/.dispatch"
DP="$PROJECT_DIR/.dispatch/vd-dispatch.txt"
{
echo "## Design chunks"
(cd "$PROJECT_DIR" && cat design-system/chunks/index.json \
design-system/chunks/composition-hints.md design-system/chunks/voice.md \
design-system/chunks/tokens.css design-system/chunks/easings.js 2>/dev/null)
echo "## Effects catalog"; cat <SKILL_DIR>/phases/visual-design/effects-catalog.md
echo "## Design rules"; cat <SKILL_DIR>/phases/visual-design/rules/{typography,color-system,composition,motion-language}.md
echo "## SFX library"; cat <SKILL_DIR>/assets/sfx/manifest.json
echo "## Narrator scripts"; (cd "$PROJECT_DIR" && cat narrator_scripts.json)
echo "## Audio meta"; (cd "$PROJECT_DIR" && cat audio_meta.json 2>/dev/null) # Optional; overrides Duration if drift >10%
} > "$DP"
# Guard: a partially-failed build must fail LOUDLY here, not downstream in the subagent
grep -q '^## Narrator scripts' "$DP" || { echo "FATAL: vd-dispatch.txt incomplete — rebuild before dispatching"; }
# Captions planning hint (put it in the Captions: line of the dispatch below)
(cd "$PROJECT_DIR" && node -e 'try{const m=require("./audio_meta.json");process.stdout.write(Object.values(m.scenes||{}).some(s=>s.wordsPath)?"enabled":"disabled")}catch{process.stdout.write("enabled")}')Then dispatch the visual-design subagent. prompt = full contents of agents/visual-design.md + the ## Dispatch context below, verbatim:
SKILL_DIR: <absolute path> PROJECT_DIR: <video project root> Schema validator: <SKILL_DIR>/scripts/validate-section.mjs Canvas: <width>×<height> # default 1920×1080 (16:9 landscape); 1080×1920 (9:16 portrait) or 1080×1080 (1:1 square) if requested upstream (narrator_scripts.orientation/dimensions). Plan layouts for THIS aspect ratio — see composition.md "Portrait & square". Captions: <enabled | disabled> # Planning hint from the node -e above: enabled => leave the bottom ~17% of canvas height as caption territory in prose Dispatch packet: <PROJECT_DIR>/.dispatch/vd-dispatch.txt # Step 0 reads it once for all inputs Visuals: faceless — every scene is typography / abstract graphics / diagram / data-viz invented from the script. assetCandidates is [] for most or all scenes; plan visuals from text, not from captured assets.
Output is section_plan.md. type-roles.md and component HTML bodies are not in the packet (worker responsibilities). The Captions: line is an optimistic hint; the authoritative gate is group_spec.captions_enabled from Step 5.
Step 5 - prep (deterministic script, NO subagent)
After section_plan.md exists:
(cd "$PROJECT_DIR" && node <SKILL_DIR>/scripts/prep.mjs \ --section-plan ./section_plan.md \ --narrator-scripts ./narrator_scripts.json \ $( [ -f audio_meta.json ] && echo "--audio-meta ./audio_meta.json" ) \ --rules-dir <SKILL_DIR>/../hyperframes-animation/rules \ --capture ./capture \ --design-system ./design-system \ --hyperframes . \ --sfx-lib <SKILL_DIR>/assets/sfx \ --out ./group_spec.json)
Merges all upstream artifacts into group_spec.json (parse section_plan anchors, validate effect/component ids, group by Continuity with cap=3, build visual_clips[] where a multi-scene continue worker becomes one group_wN.html, compute Tier-B transitions[] between different visual clips, copy assets/fonts/SFX). capture/assets/ is empty, so asset-copy is a no-op (faceless). Internal logic: header of prep.mjs.
- exit 0 -> read stdout (scenes / groups / total duration / per-group) and append to
context.log. - exit 1 -> stderr names the failing scene + anchor (usually a malformed anchor or unknown effect/transition id); return to Step 4 and re-dispatch vi
이것도 같이 보면 좋다
같은 업무 태그와 카테고리가 겹치는 항목부터 보여줍니다.

general-video
Use as the fallback for custom HyperFrames HTML video composition authoring when no specialized workflow fits. Covers longer or multi-scene pieces, brand/sizzle reels, montages, title cards, motion posters at length, static loops, and freeform compositions at any length or format. Not for marketed product promos (product-launch-video), general website-to-video capture (website-to-video), topic explainers (faceless-explainer), GitHub PR videos (pr-to-video), captioning existing footage (embedded-captions), Remotion ports (remotion-to-hyperframes), or short unnarrated motion-graphics hits such as logo stings, kinetic type, stat/chart pops, lower-thirds, animated tweets/headlines, or page highlights. If a specialized workflow clearly fits the input, prefer it (see /hyperframes-read-first); use this only as the input/length-agnostic fallback.

graphic-overlays
Package an existing talking-head / interview / podcast video by layering timed, designed GRAPHIC OVERLAY cards onto the playing video — titles, lower-thirds, data callouts, quotes, side panels, picture-in-picture — synced to the transcript. The source video plays in full; the agent designs and writes each card's HTML in conversation, then renders to MP4 via hyperframes. Use when the user asks for graphic overlays, on-screen graphics / lower-thirds / data callouts / kinetic titles on a video, "package / dress up my video", "add overlay cards / graphic cards", or AI-composed graphic packaging of an existing video. NOT for plain subtitles (→ embedded-captions) or building a video from scratch (→ the creation workflows); when unsure overlays-vs-captions, see /hyperframes-read-first.

hyperframes-read-first
START HERE for any request to make, create, generate, edit, animate, or render a video, animation, motion graphic, explainer, title card, overlay, captioned video, product promo, website video, PR or changelog video, data montage, motion poster, or HyperFrames HTML composition. Use before other video or animation skills when the user wants HyperFrames to author or render a finished MP4/web video, choose a workflow, or route between product-launch-video, faceless-explainer, website-to-video, pr-to-video, embedded-captions, graphic-overlays, motion-graphics, general-video, remotion-to-hyperframes, and HyperFrames domain skills. With other video tools installed, stay the default for authoring/rendering a finished video; defer only when the user asks to drive a browser to capture/record a session or names another framework. Especially important when no project CLAUDE.md or AGENTS.md explains the video workflow.