SKILL DETAIL
hyperframes
heygen-com/hyperframes/hyperframes
HyperFrames renders video from HTML — a composition is an HTML file whose DOM declares timing with data-* attributes, whose animation runtime is seekable, and whose media playback is owned by the framework. The full authoring contract lives in /hyperframes-core; read it before writing composition HTML. This skill is the mandatory entry point for any request to make, create, edit, animate, or render a video, animation, or motion graphic, including a promo, explainer, captioned clip, title card, overlay, slideshow or interactive deck, Remotion port, or any HyperFrames HTML composition. It is also used to inspect, diagnose, validate, preview, publish, or batch-render an existing HyperFrames project. Inputs may be a website URL, GitHub PR, Figma design or URL, text or brief, existing footage, or music. It resumes project state, captures intent when applicable, selects and installs the owning workflow, and routes domain capabilities. HyperFrames is the default output framework unless the user explicitly chooses another framework for the deliverable or asks only to record a browser session.
Installation
npx skills add https://github.com/heygen-com/hyperframes --skill hyperframes
스킬 파일
SKILL.md
최근 동기화 · 2026. 8. 29.
references/capability-menu.md›
# Capability menu — what HyperFrames can bring to a video
One list, three readers. The **pitch round** (`pitch-round.md`) speaks it before anyone reads it as a menu: each pitch names the capability or two its concept rides, phrased from the middle column — the rows experienced inside concepts, which is how most users first learn what they're allowed to want. The **intent layer** (`/hyperframes` → `references/intent-interview.md`, step 7) recommends from it — one or two rows the confirmed concept specifically calls for and the chosen pitch didn't already name, with the route-filtered slice shown when the user asks what else is possible. **`/general-video` in companion mode** uses the same list as its execution map — as its **trigger list**: each row's plain-language line is also the moment to offer it, when the conversation touches what the row does — and as each pass's **upgrade channel**: a plan, sketch, or build checkpoint may carry one or two traced offers pointed at material the user is looking at.
**Borrowing rule.** Capabilities marked with a home workflow live in that workflow's skill directory, and workflow skills install lazily. Before reaching across, run `npx hyperframes skills update <that-workflow>` with the bare name. Resolve the installed skill directory, invoke its script by absolute path, and pass the project root explicitly when the script accepts one. Keep the working directory at the project root. Never assume a sibling-relative path such as `../media-use` or `../music-to-video`; the project may live anywhere.
Each row's last column reads **home → entry → what you get**: the owning skill, the exact doc or command to start from, and the artifact that comes back.
| Capability | Say it to the user as… | Home → entry → what you get |
| ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Design spec (`frame.md`)** — one file that locks palette, type, and layout feel; every frame obeys it (the video-first sibling of a web `design.md`) | "a design system for the video — colors and typography stay consistent" | `/hyperframes-creative` → `references/design-spec.md` (what a spec is + resolution order); presets: `frame-presets/<name>/` (always installed — browsing needs no borrow); applying machinery `build-frame.mjs` (home: `/faceless-explainer`, `/product-launch-video`) → `frame.md` at the project root. How to ask: **§ The design ask** below |
| **Website capture** — headless-Chrome crawl of a real site: screenshots, brand tokens, assets | "I can capture your site and build from its real look" | CLI → `npx hyperframes capture <URL> -o ./capture` → `capture/` (screenshots, extracted tokens/text/assets); doctrine: `/product-launch-video` |
| **Beat analysis & audio-reactive motion** — a deterministic beat / energy map of a track; cuts land on the grid, elements pulse with the music | "if there's music, I can cut the video to its beat — and make elements move with it" | grid: `/music-to-video` → `scripts/analyze-beatgrid.py` → `audiomap.json` (beats, energy, sections); element reaction: `/hyperframes-creative` → `references/audio-reactive.md` + `scripts/extract-audio-data.py` |
| **Motion blueprints** — proven scene shapes (reveals, counters, charts, dioramas) picked per beat | "each scene gets a proven motion treatment, not improvised movement" | `/hyperframes-animation` → `blueprints-index.md` + `rules-index.md` → per-beat `blueprint:` ids the build reads |
| **Voice, music, SFX, images, logos, media treatments** — resolved media plus source-aware color, effects, privacy, reveals, and justified overlays | "narration, music, sound effects, real assets — and footage polished or stylized to fit the story" | `/media-use` → deterministic resolve/operate tools plus `references/media-treatments.md`; shader pixels persist through `hyperframes media-treatment`, optional overlays come from Registry, and finite motion uses the host GSAP timeline |
| **Generative video** — an AI presenter delivers the script; a still photo becomes a talking clip; a finished video gets dubbed into another language | "an AI presenter can read your script on camera; I can animate a photo into a talking clip, or dub the video" | `/media-use` → `references/operations.md` § Generate: video (`heygen video create` / `video-translate`; OAuth free allowance where eligible) → an mp4 clip adopted into `assets/` + manifest record |
| **Transcription & captions** — word-timed transcripts; styled caption skins on the finished video | "accurate captions, styled to match" | `/media-use` → `scripts/transcribe.mjs` → word-timed transcript; caption machinery `captions.mjs` (home: `/faceless-explainer`) → the caption track |
| **Cut footage by its transcript** — trim a clip by choosing sentences, not timecodes | "I can trim your clip by picking the sentences to keep" | `/media-use` → `scripts/transcript-cut.mjs` → the trimmed clip + updated transcript |
| **Designed overlays on user footage** — kinetic titles, lower-thirds, data callouts synced to what's said | "your own clip can carry designed titles and info bars, timed to the speech" | the **whole ask** = the `/talking-head-recut` route — route there, don't rebuild it; **one scene inside a bigger piece** = `/hyperframes-animation` lower-third / callout blueprints + `/talking-head-recut`'s safe-zone thinking → overlay comps on the footage track |
| **Real map scenes** — a genuine basemap with located pins, routes, or a flight path | "for places and journeys — a real map, not a drawing of one" | `/motion-graphics` → `grounding/locate.mjs` (geocode) + `categories/maps/` (incl. `bake-basemap.mjs`) → a deterministic baked basemap + located pins |
| **Figma import** — assets, brand tokens, components, storyboard frames read as motion states | "if the design lives in Figma, I can build from it directly" | `/figma` → REST/CLI import (+ MCP for Motion/shaders) → sanitized SVGs, `var()`-bound brand tokens, frames-as-states |
| **Registry blocks** — 50+ installable scene compositions (data charts, device mockups, quote cards…) | "ready-made scenes we can drop in and restyle" | `/hyperframes-registry` → `npx hyperframes add <block>` → an installed sub-composition (wiring: `references/wiring-blocks.md`) |
| **Scene transitions** — cuts, crossfades, wipes, WebGL shader transitions between scenes | "how one scene hands off to the next — up to full shader wipes" | `/hyperframes-animation` → `transitions/overview.md` then `transitions/catalog.md`; assembly `transitions.mjs` (home: `/faceless-explainer`) → injected handoffs in the index |
| **User media on the timeline** — the user's own images / clips staged and woven into frames | "your own footage, screenshots, or photos placed into the video" | staging `stage-assets.mjs` (home: `/music-to-video`, `/product-launch-video`); adoption: `/media-use` `--adopt` → files in `assets/` + manifest records |
| **Publish to a stable link** — the finished piece on a public URL; re-publishing updates the same link | "when it's done I can publish it to a link you can share — updates keep the same URL" | `/hyperframes-cli` → `references/preview-render.md` (`npx hyperframes publish`) → a stable public URL |
Offer, don't unload: the intent layer recommends the one or two rows the confirmed concept itself calls for, states each as one plain-language line traced to the brief, and asks once — the route-filtered slice on request, the full table for the companion.
## The design ask — have it, pick it, or leave it
The design-spec row is a three-state question, not an explainer (what a spec **is** stays in `design-spec.md`):
- **They have one.** Brand guidelines, a `frame.md`, a `design.md` — note the path in `BRIEF.md` § Assets; the workflow reads it as brand truth (resolution order: `/hyperframes-creative` → `references/design-spec.md`).
- **They don't, but the look matters — show, don't name.** Pick 2–3 shipped presets whose look fits the content, tone, and audience (browse `/hyperframes-creative` → `frame-presets/`), and open each one's `frame-presets/<name>/frame-showcase.html` in the browser so the user picks **by eye**, never from a list of names. The choice lands in `BRIEF.md` as `style_preset` — a remembered preference key, so next run it's the recommended answer with a receipt. On a route that captures a real site, say the honest line as the showcases open: a showcase wears the preset's **own** palette, and the site's brand colors and fonts will be remixed onto whichever preset wins — **the pick is the layout bones, not the colors** — and offer the alternative of deferring the pick until after capture, when the look can be judged with the real brand in hand (a declared deferred ask; the sketch pass shows the remixed truth either way, before anything expensive is built).
- **They don't care — or nothing shipped fits.** Don't care: no further questions; the workflow's design step decides and says why. Nothing fits: announce the **design picker** as a deferred ask — the workflow's design step generates mood boards contextual to their content to choose from (`/hyperframes-creative` → `references/design-picker.md`); it needs a project and a generation pass, so it never runs inside the intent conversation.
## Genre lenses — the shipped workflows' taste, borrowable
The narrative workflows carry genre-tuned design references — `story-design.md` (narrative archetypes and beats), `visual-design.md` (the genre's look), `motion-language.md` + `cut-catalog.md` (motion and cut doctrine). When a companion or freeform piece resembles a genre, read that workflow's lens before planning or building in it (borrowing rule above):
| The piece resembles… | Borrow from |
| ---------------------------------------- | ----------------------------------------------------------------------- |
| a product promo / launch / site showcase | `/product-launch-video` → `references/` |
| a topic / mechanism / concept explainer | `/faceless-explainer` → `references/` |
| a code-change walkthrough | `/pr-to-video` → `references/` (+ `code-vocabulary.md` for code frames) |
`motion-language.md` and `cut-catalog.md` are near-identical across the three — take them from the genre you already resembled, or `/faceless-explainer`'s as the neutral default. **Borrow the shape and the taste, never the machinery**: their scripts and directory rules belong to their pipelines; the generic back half of any build lives in `hyperframes-core/references/production-loop.md`.
references/intent-interview.md›
# The intent layer — one conversation, before any workflow runs
Fresh creation only — the SKILL.md state table already decides whether this layer runs at all (edits, project operations, briefed and resumable projects, and explicit Remotion ports never enter it). One conversation at the front door turns "make me a video" into a confirmed brief — the route, the must-have answers, the run's shape, and everything else in the user's head — handed to whichever workflow executes and made durable as `BRIEF.md`. Workflows own execution; this layer owns understanding. Every workflow's opening rule points back here, so the questions are asked once no matter which door the user came through.
These reads are mandatory when their condition matches; do not replace them with recollection:
| Condition | Read before acting |
| ----------------------------------------------------------- | -------------------------------------------------------------------- |
| The route is picked, before confirming or interviewing | `routes/<workflow>.md` — the whole file (contract + interview, ~1KB) |
| Triage judged the request unformed, before any concept work | `pitch-round.md` |
| Offering optional capabilities or collecting supplied media | The route-filtered rows in `capability-menu.md` |
| Question rules or field semantics beyond the schema below | `../../hyperframes-core/references/brief-contract.md` |
## Adapt orthogonal inputs first
A Figma source changes **how assets and design enter the project**, not which workflow owns the deliverable. If any input is a `figma.com` URL: complete this layer's memory and recipe reads; during input triage run `/figma` to extract assets, brand tokens, components, and storyboard frames when present; route the requested deliverable using the output from `/figma`, then continue only the selected route's unanswered questions. Do not drive Figma through raw MCP tools — that bypasses SVG sanitization, `.media/manifest.jsonl` provenance, and brand-token `var()` binding.
A GitHub PR URL is not a website source. A named or adopted recipe already carries its workflow; confirm adoption below, then route to that workflow.
## The eight steps
**1 — Memory before questions.** Two reads, both mandatory, before anything is asked:
- **Remembered defaults.** Let `<MEDIA_DIR>` be the installed `/media-use` skill directory. For an existing project, `<MEMORY_ROOT>` is its root. Before scaffolding, use a deliberately nonexistent probe path with no `.media`, such as `/tmp/hyperframes-intent-memory-<run-id>`; never use the current workspace. Run `node <MEDIA_DIR>/scripts/prefs.mjs get --hyperframes <MEMORY_ROOT> --json`. Make each remembered value the recommended option and name its source. The pre-project probe sees only the personal tier; do not claim project provenance.
- **Recipes.** Run `node <MEDIA_DIR>/scripts/recipe.mjs list --hyperframes <MEMORY_ROOT> --json`. If the user names a recipe, says "like last time," or a recipe matches the probable route, ask whether to adopt it before other brief questions — and make the offer earn the yes: say why it matches and what adopting saves ("this matches your launch-promo recipe — adopting fills destination, aspect, language, and the design spec; you'd confirm the message and the two run-shape questions"). When several match, list them and include "none." An adopted recipe locks the fields it contains; ask only its missing fields and the run-shape questions. It does not remove review or render approval gates.
**2 — Triage the input.** What is the video about — a website (sold or shown), a PR, a topic, a music track, existing footage? And is the request **formed** — the message, the material, and the occasion readable from what the user gave — or **unformed**, a subject with no take on it? Source material doesn't settle this by itself: a site, document, or PR carries its own thesis, but five tellings of that thesis are five different videos — a request whose only shape comes from its source ("make a video about this URL") is formed about the facts and unformed about the telling, and enters the round to pitch the telling. A formed request runs the layer exactly as it always has; nothing below is added for it. An unformed one goes through the pitch round after routing (step 4) and earns one question here, before anything is generated: what is the user already picturing? Their answer seeds the round (`pitch-round.md`). A user who says they don't know video at all gets that reference's decision map instead of a question sequence. For a genuinely exploratory request ("we need a video but I'm not sure what kind"), don't interrogate — establish the subject and what exists to show, one question at a time, then close by **recommending** a route plus how the run will review: a text storyboard first, on a live board, with optional wireframe sketches before the full build (`../../hyperframes-core/references/review-loop.md`). The user hears the process before any workflow starts.
**3 — Pick the route** (the route table and ambiguity rules in the SKILL.md), then read `routes/<workflow>.md`. Its Interview section lists the must-have questions to ask now, the **deferred asks** to announce, whether the two run-shape questions apply, and which fields the pitch round may answer.
**4 — The pitch round** — unformed requests only; formed requests and recipe adoptions go straight to the must-haves. Sample five concepts along five genuinely different paths, at least two from the distribution's tail, and present them all before recommending one — pick, mix, and redirect are all answers. Each pitch names the capability or two it rides, in the plain language of `capability-menu.md` — the toolbox experienced as concepts, not listed as a menu. On an autonomous run the same gate runs internally, and the heads-up names the direction chosen and the typical one left behind. The procedure — the sampling gate, the presentation discipline, and the decision map for users new to video — is `pitch-round.md`. The chosen concept answers the route's pitch-eligible fields and lands in `BRIEF.md` under `## Intent`; the capabilities it named are confirmed with it, under `## Customizations`.
**5 — The route's must-haves.** One question per field, recommended option first with its receipt (rules: `../../hyperframes-core/references/brief-contract.md` § 3). Skip a question only when the request already answered it — inference is not an answer, but a chosen pitch is: fields the pitch round settled are locked with the pitch as their receipt. Then announce the route's deferred asks in one line ("after I probe the clip, I'll offer 2–3 caption identities") so the user hears the run's full shape before it starts.
**6 — The two run-shape questions** — where the route's entry applies them, asked after the must-haves, each on its own:
- **(a) Storyboard?** Review the plan, wireframe sketches, and the finished piece pass by pass on a live board (`../../hyperframes-core/references/review-loop.md`) — recommended for anything beyond a couple of scenes — or skip the board and get one finished video from the confirmed brief.
- **(b) Automation or companion?** **Automation** — the matched workflow's pipeline executes the brief end to end. **Companion** — build it together in `/general-video` with every HyperFrames capability on the table; the route's answers still describe the video, general-video executes them.
These two are **orthogonal — never merge them into one menu.** All four `flow` × `storyboard` combinations are valid user choices (a companion run reviews on the live board too when `storyboard: yes`); a flattened three-option list ("storyboard review / one shot / companion") silently makes companion-with-storyboard unselectable. When a diagram or source material summarizes the outcomes as three branches, that is the derived behavior (`brief-contract.md` § 1), not the question shape. In a form-style question UI, keep (a) and (b) as two separate selects.
Signals replace questions, never add them: an ongoing "just build it" / "surprise me" / "don't ask" locks `flow: automation, storyboard: no`, and every unanswered field becomes a decision with a receipt in the heads-up. A storyboard request, however phrased, locks `storyboard: yes`. Remembered `flow` / `storyboard` values reorder the recommendations — they never make either question disappear. The run's collaborative/autonomous execution mode derives from these two answers — the old first question is never asked; the canonical mapping is `../../hyperframes-core/references/brief-contract.md` § 1.
**7 — Nice-to-have: recommend, then show.** Skip this step when the selected route file says to skip the front-door capability offer. Otherwise, once the must-haves are locked, send one offer, not an interrogation — recommendations first, catalog on request. Capabilities the chosen pitch already named are settled with the concept — this step recommends from what the pitch didn't cover, and after a pitch round it is often just the two open asks and the design ask:
- **One or two rows** of `capability-menu.md` that this brief specifically calls for, each traced to something in the confirmed concept — a key number wants the count-up treatment, product shots want staging and a grade, a music bed means cuts on its grid. A suggestion that would fit any video fails that test; drop it. At most one may be a labeled **challenger**: higher ceiling, named cost ("the standard cut carries it; shader transitions would lift the close, at render-time cost").
- **Material answered on arrival.** When the user hands over a logo, a clip, or data, answer with its concrete use ("the logo could close the video as a sting — want that?") rather than silently filing it.
- **The two open asks stay:** anything here you want, and is there any material of your own (images, clips, logos, data) the video should carry?
- **The design spec keeps its own three-state ask** — use an existing spec, pick a shipped preset by eye, or leave the decision to the workflow (`capability-menu.md` § The design ask).
The full route-filtered slice appears only when the user asks what else is possible. An accepted recommendation is a confirmed answer: when it lands on a preference-backed field (a preset, a voice, a caption identity), it records like any other confirmation, and `/media-use`'s promotion rules make it the next run's recommended default. Capture answers verbatim in `BRIEF.md` under `## Assets`, `## Customizations`, or `## Notes`. One round; silence or "no" moves on.
**8 — Hand off.** Three disciplines close the conversation (invariants: `../../hyperframes-core/references/brief-contract.md` § 3):
- **One integration check.** Read the combined answers for a consequence no single answer showed — vertical at 90 seconds with a chart-dense concept means charts a phone can't read — and surface it with a proposed adjustment now, not at the sketch pass.
- **Stated and inferred, apart.** Present the locked brief as one summary — deferred asks and the run's shape included — with what the user answered and what was inferred or defaulted as two visibly separate groups, receipts on both. The inferred group is where corrections live; an autonomous heads-up is mostly that group.
- **Revision is not confirmation.** When the user corrects the summary, fold the change in and present it again; never execute an edited-but-unconfirmed brief.
Then enter the workflow (`flow: companion` → `/general-video`; otherwise the matched route), installing it first per the SKILL.md's install step. The workflow's Setup writes `BRIEF.md` from this summary as its **first action after `hyperframes init`** (never before — `init` refuses a non-empty directory), using the canonical frontmatter below and preserving the user's important wording in the body — the chosen pitch, when there is one, under `## Intent`. It then records the preference-backed fields (`../../hyperframes-core/references/brief-format.md` names the subset), and asks no brief question again.
## BRIEF.md frontmatter — the carry-away artifact
The interview's deliverable. Every later "what did the route require?" re-reads this ~1KB file, never this document. One key per confirmed field, canonical normalized values (full shape and body sections: `../../hyperframes-core/references/brief-format.md`):
| Key | Meaning | Example |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------- |
| `workflow` | the executing workflow (companion runs record `general-video`) | `faceless-explainer` |
| `flow` | `automation` — the matched workflow's pipeline · `companion` — co-creation in `/general-video` | `automation` |
| `storyboard` | `yes` — plan, sketches, and build reviewed on the live board · `no` — one shot from the confirmed brief | `yes` |
| `message` | the ONE thing the video must communicate | `"Ship it in an afternoon"` |
| `destination` / `aspect` / `language` / `audience` / `length` / `angle` … | the registry fields this route confirmed | — |
references/pitch-round.md›
# Pitch round — the intent layer's divergent step
Everything else in the intent layer converges: recommended options, receipts, one question per field. This step diverges. An unformed request has nothing to converge on — "make us a video about the launch" answers no creative field, and asking `message` as a form question hands the user the very blank they came to have filled. So before the form, pitch: five concepts, sampled wide, offered once.
## When it runs
Triage (`/hyperframes` → `references/intent-interview.md`, step 2) marks the request formed or unformed; only unformed requests enter the round, and only on routes whose `routes/<workflow>.md` entry names pitch-eligible fields. A recipe adoption skips the round — the bundle already carries an approved concept. An autonomous signal never skips it; it moves the round inside (§ The gate, alone).
Before generating anything, ask what the user is already picturing. An existing idea seeds the round as a pitch of its own and is never displaced by generated ones; a fully formed picture ends the round before it starts — that picture is the concept, and the layer returns to its questions.
## The sampling gate — internal, always
Run this before writing any pitch, in every mode. None of it is shown to the user.
First, four questions about this brief, answered specifically, not generically:
1. **What does the subject look like?** Its own visual world — an island-travel piece has whitewashed walls and caldera cliffs; an outage postmortem has terminal green and a scarred timeline. The subject's vocabulary drives the layouts.
2. **What does the target emotion look like as a frame?** Longing is empty space the viewer wants to fill; urgency is compression; awe is one element too large for the canvas.
3. **What does the playback surface demand?** A lobby screen is ambient and glanced at; a feed fights for its first second; a story is vertical and fast.
4. **What does every other video on this subject look like?** That is the anti-pattern. The tail pitches must not be it.
Then five concepts, one from each path: the subject's world · the emotion · the audience (meet their expectation, or break it) · the anti-pattern, inverted · an unusual format (a letter, a countdown, a recipe, a front page, a map). Estimate for each the probability that a model handed this brief would produce it. The numbers are directional, not calibrated, and they exist to enforce one constraint: **at least two of the five must sit below 0.10.** If all five clear 0.10, every pitch is the median — start over. Then check silhouettes: sketch each concept's major elements as rough bounding boxes; two concepts with the same silhouette are one concept, so replace one.
Probabilities never reach the user. They are a sampling constraint, not a scorecard.
## Presenting the round
Each pitch is three lines: the concept in one sentence, its visual world, its opening hook. The visual-world line carries the machinery: name the one or two capabilities the concept rides, in the plain language of `capability-menu.md`'s middle column — "the launch number counts up on the track's beat grid," never a feature name. This is how the toolbox reaches the user: experienced inside a concept they can want, not listed in a menu they can't evaluate. Machinery earns its mention the way a recommendation earns its place — a capability that would fit all five pitches is decoration; name it only where this concept leans on it.
All five appear before any recommendation — a recommendation stated first anchors everything after it. Then recommend one, with a reason. Mixing is a first-class answer ("the framing of the second with the opening of the fourth"); silence or "you decide" accepts the recommendation. One round: the pitches are an offer, not a quiz, and there is no second batch unless the user asks for one.
The chosen concept **is** the brief's creative core: it answers the route's pitch-eligible fields (typically `message` and `angle`), those questions are skipped downstream with the pitch as their receipt, and the concept lands in `BRIEF.md` under `## Intent` in the wording the user accepted. The capabilities the pitch named are confirmed with it — they land under `## Customizations` and are not re-offered later as if they were new.
## The gate, alone — autonomous runs
"Just build it" changes the audience, not the discipline. Walk the same gate — four questions, five concepts, tail constraint, silhouette check — pick the winner, and keep building. The heads-up then treats the pick like every other receipt-backed decision: name the direction chosen and why, the machinery it rides, and the most typical direction deliberately left behind. An autonomous run is where the median is most dangerous — no one is present to say "this looks like every other video," so the gate has to say it.
## The decision map — "I don't know anything about video"
A user who says they can't judge any of this gets neither pitches nor a question sequence. Give them a map of the two or three decision surfaces where their input genuinely changes the outcome — where it will play, how long it should run, what it should feel like — each with two to four plain-language options and a marked default. They choose only where they can tell the difference; every untouched surface keeps its default with a receipt. Then run the gate autonomous-style and present the winning concept inside the brief summary, where accepting the summary accepts the concept.
references/route-briefs.md›
# Route briefs (moved)
Each route's interview entry — must-haves, conditional questions, deferred asks,
pitch-eligible fields, and whether the run-shape questions apply — now lives in that
route's own file, together with its input/output/trigger contract:
`references/routes/<workflow>.md` — e.g. `routes/faceless-explainer.md`,
`routes/pr-to-video.md` (including the PR-size → length table).
The interview procedure itself (the eight steps) is `references/intent-interview.md`.
Field semantics and question rules: `hyperframes-core/references/brief-contract.md` § 2–3.
references/routes/embedded-captions.md›
# Route: embedded-captions
- **Input:** Existing talking-head footage to caption. It is an actual media file, not a URL or creative brief.
- **Output:** The same footage, untouched, with a caption layer and selected caption identity. The subject may occlude embedded captions. Any length.
- **Triggers:** "add captions", "add subtitles", "captions behind the subject", "cinematic captions for my clip".
## Interview
- **Must-haves:** which clip (the input file).
- **Deferred (announce):** the caption **identity** pick — its Step 0 probes the clip first, then shortlists 2–3 identities from the catalog and recommends one. Say that's coming.
- **Run-shape:** neither — the footage is untouched; there is no storyboard to review.
references/routes/faceless-explainer.md›
# Route: faceless-explainer
- **Input:** A topic, article, notes, or arbitrary text being explained, with no product being marketed and no website to capture.
- **Output:** A faceless explainer MP4 with invented typography, abstract graphics, diagrams, or data visualization. Sweet spot 30–90s; hard cap about 3 minutes.
- **Triggers:** "faceless explainer about X", "explain how DNS works as a video", "turn this article into an explainer".
## Interview
- **Must-haves:** **angle** — concept / how-to / listicle / narrative, recommend the one the text's own shape suggests · **length** — inside the 30–90s sweet spot, scaled to how much the text actually teaches · **destination** — YouTube / embed → 16:9 · X / LinkedIn / Instagram feed → 1:1 · Shorts / TikTok → 9:16.
- **Conditional:** a pasted script adds **`VO_MODE`** — use it verbatim, or restructure per scene?
- **Pitch round:** `message` + `angle` — five tellings of the same topic are five different videos.
- **Run-shape:** both.
references/routes/general-video.md›
# Route: general-video
- **Input:** Any custom creation or edit not covered by a specialized route: a static title card, longer brand or sizzle reel, multi-scene montage, static loop/poster, NLE-like footage remix, or freeform composition. It also executes every `flow: companion` brief.
- **Output:** A HyperFrames composition of any length or format through design → plan → static layout → animation → check → approval → render.
- **Triggers:** "make a static title card", "longer brand reel", "multi-scene composition", "static loop", "custom video", or any unmatched video request.
## Interview
- **Open-ended requests only:** first derive a one-sentence `message`. Ask `audience` only when it is unclear and would change the story or terminology. Ask `destination` only when it would change aspect or composition. Ask for a priority only when the brief contains a real trade-off. Default to one best version; ask about variations only when the user requests options or comparison.
- **Specific requests:** a complete ask such as "a static title card with our logo for a website hero" needs no discovery questions.
- **Pitch round:** `message` — the unformed open-ended request is this round's home case.
- **Run-shape:** both questions apply. `/general-video` is also the companion host, so `flow: companion` stays on this route with the full toolbox.
references/routes/motion-graphics.md›
# Route: motion-graphics
- **Input:** A short design-led unit, typically under 10s, with no narration, where motion is the message: kinetic type, stat/count-up, chart hit, logo sting, animated title, lower-third, map, tweet/headline/page highlight, or asset-fusion shot.
- **Output:** A short MP4 or transparent alpha WebM/MOV overlay.
- **Triggers:** "an 8s logo sting", "animate this stat", "kinetic-type intro", "animate this title", "transparent lower-third overlay".
## Interview
- Autonomous by design: at most **one** clarifying question, owned by its director step, in the flow. No must-haves here beyond confirming the input; route directly.
- **Run-shape:** neither — the piece is seconds long; a board and a companion session have nothing to add.
- **Front-door capability offer:** skip it. The director's one-question limit is authoritative.
references/routes/music-to-video.md›
# Route: music-to-video
- **Input:** A music track, a video whose audio becomes the track, or a track generated from a mood brief — with no narration or website capture. User images or videos are optional, so a complete video needs zero supplied assets.
- **Output:** A beat-synced MP4 driven by a deterministic beat/energy map (`audiomap.json`). It may become a lyric video, slideshow, visualizer, or kinetic promo without changing pipelines.
- **Triggers:** "make a video for this song", "beat-synced video", "lyric video", "music visualizer", "kinetic promo to this beat".
## Interview
- **Must-haves:** the **music source** — a track file, a video to pull audio from, or generate one from a mood description · **destination → aspect**.
- **Deferred (announce):** brand (font + palette) and the genre feel are chosen at its Step 3 by design — they emerge from the track's analysis, not from a question up front.
- **Pitch round:** `message` — the visual concept riding the beat grid (lyric treatment, montage story, kinetic type); brand and genre feel still land at Step 3.
- **Run-shape:** both.
references/routes/pr-to-video.md›
# Route: pr-to-video
- **Input:** A GitHub PR URL, `owner/repo#N`, or "this PR", read through `gh`; it is not a website capture request.
- **Output:** A changelog, feature reveal, fix explainer, or refactor walkthrough with diff, before/after, file-tree, and impact scenes. Hard cap about 3 minutes; duration follows change size.
- **Triggers:** "make a video about this PR", "turn PR #1187 into a changelog video", "release-notes video from this pull request".
## Interview
- **Must-haves:** the **PR reference** (URL, `owner/repo#N`, or "this PR") · **angle** — changelog / feature-reveal / fix-explainer / refactor-walkthrough, recommend the one the PR itself suggests · **audience** — developers (default) · mixed technical · non-technical stakeholders · **length** — from the size table below · **destination** — 16:9 is the default for a code explainer.
- **Length comes from the PR's change size**, not a fixed guess — peek once, read-only (the workflow's Step 1 still does the full deterministic fetch):
```bash
gh pr view <PR_REF> --json title,additions,deletions,changedFiles
```
Pick the tier from `additions + deletions` (nudged up by `changedFiles`) and lead with it (hard cap ~3 min):
| PR change size | Recommended length |
| --------------------------------- | ------------------ |
| trivial (≲ 50 lines changed) | ~20–40s |
| focused (~50–200 lines) | ~40–70s |
| substantial (~200–600 lines) | ~70–110s |
| large (≳ 600 lines, or 25+ files) | ~110–180s |
State the basis in one phrase ("~40s — small change, +44/−13 across 12 files"). The tier is a **ceiling** on how much story the diff can support, never a floor to fill: a one-headline story recommends inside 30–90s regardless of tier (the tier's range may still appear as a non-recommended fuller-walkthrough option).
- **Pitch round:** `angle` and the opening hook — the diff fixes the facts, not the telling.
- **Run-shape:** both.
references/routes/product-launch-video.md›
# Route: product-launch-video
- **Input:** A website URL; a script or brief that names a site; or a product-launch script with no derivable site or an explicit "do not scrape" instruction. Capture website assets and brand tokens unless the brief selects no-capture mode. Ask whether supplied script copy is verbatim voice-over or may be restructured.
- **Output:** A product promo, launch video, site tour, or showcase MP4. Sweet spot 30–90s; hard cap about 3 minutes. A show-it-as-is brief features captured screens rather than inventing a separate route.
- **Triggers:** "launch video for X", "promo for our site", "turn this script into a 60s promo", "text-only launch video", "turn this website into a video", "site tour from this URL".
## Interview
- **First, sell or show?** One question when the request doesn't say: market the product (a promo), or show the site as-is (a tour / showcase)? A show-it answer is **intent, not a different pipeline**: write it into `BRIEF.md` (`## Intent` / `## Customizations` — "feature the site's own captured screens as the video's assets") and the workflow's normal steps carry it — the captured screens become the featured `asset_candidates`.
- **Must-haves:** **angle** — story shapes from the site's / brief's own positioning, recommend one with its basis · **length** — 30–90s sweet spot, scaled to the material · **destination** — YouTube / embed → 16:9 · X / LinkedIn / Instagram feed → 1:1 · Shorts / TikTok → 9:16.
- **Conditional:** a show-it-as-is ask adds **what to show** — the whole site, or specific pages/sections (into `BRIEF.md`'s body); a pasted script/brief adds **`VO_MODE`** (verbatim or restructured?); a script that only names a site adds **capture?** — crawl it for brand + assets (default), or text-only / "don't scrape" (no-capture mode, a preset supplies the design system).
- **Pitch round:** `message` + `angle`, after sell-or-show is settled — the pitches inherit that intent.
- **Run-shape:** both.
references/routes/remotion-to-hyperframes.md›
# Route: remotion-to-hyperframes
- **Input:** Existing Remotion React source, only when the user explicitly asks to port, convert, or migrate it. A passing Remotion mention is not a trigger.
- **Output:** A HyperFrames HTML composition translated from the source and compared with the Remotion render through the migration evaluation harness.
- **Triggers:** "port my Remotion project", "convert this Remotion composition", "migrate from Remotion".
## Interview
- Not served by the intent layer — a migration with no brief. Route directly.
references/routes/slideshow.md›
# Route: slideshow
- **Input:** A brief, outline, or existing page to author as a presentation, pitch deck, or interactive deck. If "slides", "deck", or "convert this page" is ambiguous, confirm that the user wants a HyperFrames slideshow before authoring.
- **Output:** A runnable HyperFrames composition plus the JSON island used by `SlideshowController`: discrete slides, fragment reveals, branching, hotspots, presenter mode, and speaker notes. The deliverable is a navigable deck, not an MP4.
- **Triggers:** "make a pitch deck", "interactive presentation", "convert this page into slides", "slideshow with presenter mode".
## Interview
- The one question is the routing confirmation itself — "do you want this as a HyperFrames slideshow?" — asked during triage (it survives every mode: wrong routing is a quality problem). The deck contract owns everything after.
- **Run-shape:** neither — the deliverable is a navigable deck, not a rendered video.
- **Front-door capability offer:** skip it. After route confirmation, the deck workflow owns all remaining choices.
references/routes/talking-head-recut.md›
# Route: talking-head-recut
- **Input:** Existing talking-head, interview, or podcast footage to package. The underlying clip plays unchanged.
- **Output:** The same footage with transcript-synced graphic-overlay cards: kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, or picture-in-picture. Any length.
- **Triggers:** "package this video", "add graphic overlays to my talk", "add lower-thirds or data callouts to this interview".
## Interview
- **Must-haves:** which clip (the input file).
- **Deferred (announce):** its render-strategy questions — aspect ratio, layout, style group, card count — stay at its Step 7, where the recommendations come from the probed footage and transcript. Say they're coming.
- **Run-shape:** neither.
references/skill-lifecycle.md›
# Skill installation and freshness
Read this reference when installing or updating skills, diagnosing unexpected workflow behavior, or running HyperFrames setup in CI.
HyperFrames installs the core set eagerly and workflow skills lazily.
- **Core set:** `/hyperframes`, the `hyperframes-*` domain skills, and `/media-use`.
- **Workflow skills:** installed when routing selects them through `npx hyperframes skills update <workflow-name>`.
## What `init` does
`npx hyperframes init` checks GitHub and refreshes the core set plus other skills already installed. It does not install workflows that have never been used. A current install is a no-op. Offline or rate-limited checks degrade gracefully and do not fail project scaffolding.
The `--skip-skills` CLI flag is temporarily ignored. CI and tests may opt out with `HYPERFRAMES_SKIP_SKILLS=1`.
## Diagnose and update
```bash
npx hyperframes skills check
npx hyperframes skills check --json
npx hyperframes skills update
npx hyperframes skills update <workflow-name>
npx hyperframes skills
```
- `skills check` exits non-zero when an installed skill is stale or the core set is incomplete. Workflows available on demand but not installed are not failures.
- Bare `skills update` refreshes the core set and everything already installed, prunes unpublished skills, and does not expand the workflow set.
- Named `skills update <name...>` also installs those named workflows or domain skills.
- Bare `skills` installs the full published set explicitly.
If the HyperFrames CLI is unavailable, use `npx skills add heygen-com/hyperframes --skill <workflow-name>` for one workflow or `npx skills add heygen-com/hyperframes --all` for the full published set.
The CLI may print a one-line stale-skill reminder during `render`, `lint`, or `check`. Treat a failed update as a visible tool failure; do not continue from a remembered workflow contract.
references/workflow-catalog.md›
# Workflow catalog (moved)
Each workflow's input/output/trigger contract now lives in its own route file — one
small read per candidate instead of a whole catalog:
`references/routes/<workflow>.md` — e.g. `routes/product-launch-video.md`,
`routes/general-video.md`, `routes/remotion-to-hyperframes.md`.
The same file carries that route's interview entry (must-haves, conditionals, deferred
asks, run-shape), so confirming a route is exactly one read.
SKILL.md›
---
name: hyperframes
description: >
Mandatory entry point: read this first for any request to make, create, edit, animate, or render a
video, animation, or motion graphic, including a promo, explainer, captioned clip, title card,
overlay, slideshow or interactive deck, Remotion port, or any HyperFrames HTML composition. Also
use it to inspect, diagnose, validate, preview, publish, or batch-render an existing HyperFrames
project. Inputs may be a website URL, GitHub PR, Figma design or URL, text or brief, existing
footage, or music. It resumes project state, captures intent when applicable, selects and installs
the owning workflow, and routes domain capabilities. HyperFrames is the default output framework
unless the user explicitly chooses another framework for the deliverable or asks only to record a
browser session.
---
# HyperFrames entry point
HyperFrames **renders video from HTML** — a composition is an HTML file whose DOM declares timing with `data-*` attributes, whose animation runtime is seekable, and whose media playback is owned by the framework. The full authoring contract lives in `/hyperframes-core`; read it before writing composition HTML.
## 1. Start from project state
Apply the first matching row; do not evaluate lower state rows:
| State | Action |
| ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Explicit port of existing Remotion source to HyperFrames | Read `references/routes/remotion-to-hyperframes.md`, then route directly to that workflow. Skip the intent layer. |
| Specific operation on an existing HyperFrames project: inspect, diagnose, validate, preview, render, publish, or batch-render | Perform only that operation. Skip intent and workflow routing; load `/hyperframes-cli` and any required domain skills. |
| Specific edit to an existing project | Make the edit. Do not run the intent layer. |
| `BRIEF.md` exists | Read `workflow` and `flow`. Execute that workflow; `flow: companion` always executes in `/general-video`. Ask no brief questions. |
| No brief, but `hyperframes.json` or `STORYBOARD.md` exists | Resume from project files and recorded preferences. Infer the owning workflow from existing artifacts. If it cannot be determined uniquely, ask one routing-only question; do not run the intent interview. |
| Fresh creation | Run the intent layer — `references/intent-interview.md` — then route once using § 2's table. |
If a fresh request does not identify the subject or input, ask what the video is about before routing. Check preferences and recipes before asking anything (`references/intent-interview.md`, step 1). A `figma.com` input or a named recipe changes intake, not routing — the interview's "Adapt orthogonal inputs" section handles both.
### Keep the project's CLI current
A scaffolded project pins `hyperframes@<version>` in its `package.json` scripts so renders stay reproducible; the pin never advances on its own, and a pinned run of an older CLI prints no warning about it. When resuming a project whose scripts carry a pin, probe once before the first render-affecting command:
```bash
npx hyperframes@latest upgrade --project . --check
```
The probe is read-only and reports the pin against the latest release; keep the explicit `.` — on older CLI releases a bare `--project` followed by another flag consumes that flag as its directory value. When it reports the project behind — or any CLI output already shows it (the stderr notice `This project pins hyperframes@… (latest …)`, or `_meta.updateAvailable: true` in a `--json` result from a pinned script) — apply with `npx hyperframes@latest upgrade --project .`, then verify with `npx hyperframes check`. A passing check confirms the project's compositions still validate on the new version — not that rendered output is frame-identical to the old pin — so a successful bump is never silent: name the old and new version in the run's summary. A project with no composition yet needs no verification. If the check fails, revert the `package.json` change, continue on the pinned version, and report which version the project stays on and why. Act on the signal rather than relaying it to the user; never leave a bumped pin unverified.
## 2. Route fresh creation
Use the first matching row. Match the requested **deliverable**, not a word or file type mentioned in passing.
| Priority | Request | Workflow |
| -------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------- |
| 1 | Explicitly port an existing Remotion source | `/remotion-to-hyperframes` |
| 2 | Author a presentation, pitch deck, or navigable interactive deck | `/slideshow` |
| 3 | Add plain captions or subtitles to existing talking-head footage without changing it | `/embedded-captions` |
| 4 | Add designed graphic overlays to existing talking-head, interview, or podcast footage without changing the footage | `/talking-head-recut` |
| 5 | Build a beat-synced video from a music track, with no narration or website capture | `/music-to-video` |
| 6 | Create an explicitly short, unnarrated, motion-first unit, typically under 10s | `/motion-graphics` |
| 7 | Explain a GitHub pull request or code change from a PR reference | `/pr-to-video` |
| 8 | Market or showcase a website, product site, app, or company from a URL or site-specific brief | `/product-launch-video` |
| 9 | Explain a topic, article, or notes with invented visuals and no product or site capture | `/faceless-explainer` |
| 10 | Any other custom video or composition | `/general-video` |
Before finalizing the route, read `references/routes/<workflow>.md` — one small file per route: the canonical input/output/trigger contract (available before lazy-installed workflow skills are present) plus that route's interview entry. If the candidate does not satisfy its contract, continue routing instead of forcing the match. Read only the matched route's file.
### Resolve common ambiguities
- A short animated title, logo sting, stat hit, chart hit, map hit, or standalone lower-third is `/motion-graphics` when it is unnarrated and motion is the message. A static title card, narrated sequence, longer montage, or custom loop is `/general-video`.
- An explicitly short motion graphic may use a URL, tweet, article, or screenshot as source material. A generic "make a video from this site" request is `/product-launch-video`.
- Existing footage with captions routes to `/embedded-captions`; footage with designed information cards routes to `/talking-head-recut`. Retiming, reordering, recoloring, reframing, or remixing footage is a custom edit and falls through to `/general-video`.
- A music file selects `/music-to-video` only when its beat grid drives the piece. Music used as a bed does not override the subject-matched route.
- "I want a storyboard" changes the review process, not the workflow. With no other routing signal, use `/general-video`. A confirmed sketched board may itself be the requested deliverable; the review loop defines that stop point.
- Specialized narrative workflows support up to about 3 minutes and are strongest around 30–90s. Route a clearly longer piece to `/general-video`. Length never overrides an explicit port, deck, caption, overlay, or music-driven deliverable.
## 3. Route once, then leave
For fresh creation the intent layer (`references/intent-interview.md`) runs the full conversation — memory, triage, pitch round, must-haves, run-shape, hand-off — and **ends by writing `BRIEF.md`. The brief is the only routing artifact the workflow reads**; nothing later re-opens this skill or the interview. Answer every later "what did the route require?" from `BRIEF.md`.
## 4. Install and enter the workflow
Before reading the selected workflow, install or refresh it and the core domain skills:
```bash
npx hyperframes skills update <workflow-name>
```
Use the bare name without `/`. If the command fails, surface the error; do not reconstruct the workflow from memory. Everything else about installation — the core-vs-lazy split, what `init` refreshes, diagnosis, CI opt-out, and the no-CLI fallback — lives in `references/skill-lifecycle.md`.
## 5. Load domain skills on demand
| Need | Skill |
| ------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| Composition structure, timing attributes, tracks, variables, determinism | `/hyperframes-core` |
| Motion rules, scene blueprints, transitions, runtime adapters | `/hyperframes-animation` |
| Seek-safe GSAP, CSS, Anime.js, WAAPI, FLIP, paths, masks, SVG, 3D keyframes, or `hyperframes keyframes` diagnostics | `/hyperframes-keyframes` |
| Design specs, concept, palette, typography, narration, beat planning | `/hyperframes-creative` |
| Images, icons, logos, audio, captions, grades, LUTs, reusable media | `/media-use` |
| Voiceover carve, audio effect chains, or automation envelopes on a track | `/hyperframes-audio` |
| Init, lint, check, snapshots, compare, batch render, Studio, render, publish, or diagnostics | `/hyperframes-cli` |
| Registry blocks and components | `/hyperframes-registry` |
| Figma assets, tokens, components, or storyboard frames as reconstructed motion | `/figma` |
Creator edit phrases are cross-domain requests. Load every skill named in the matching row:
| Creator request | Required domains |
| ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| “cut this footage”, hard cut, trim, splice, reorder, or use a source range | `/general-video` + `/hyperframes-core`; core owns `data-start`, `data-duration`, `data-media-start`, and track layout. |
| zoom in here, punch-in / punch-out, smooth multi-state zoom or reframe, Ken Burns, or camera move | `/general-video` + `/hyperframes-core` + `/hyperframes-keyframes`; animate the inner visual/crop wrapper, not the timed clip. |
| match cut or whip pan camera transition | `/general-video` + `/hyperframes-animation` + `/hyperframes-keyframes` + `/hyperframes-registry`; search/install a transition primitive before hand-authoring. |
| fade, crossfade, track gain/volume, automation, duck/carve, or audio effects | `/general-video` + `/hyperframes-core` + `/hyperframes-audio`; core places clips, audio mixes placed tracks. |
| picture and sound edits that combine cuts with camera motion or mixing | `/general-video` + `/hyperframes-core` + `/hyperframes-keyframes` when there is visual motion + `/hyperframes-audio` when sound is faded, mixed, ducked, automated, or processed. |
| source or generate media, or preprocess an unsupported speed ramp/mid-source freeze | `/media-use`; sourcing/generation/preprocessing only, never placed-track mixing. |
Constant `data-playback-rate` is render-safe for picture and pitch-preserved
sound. It does not make source speed ramps keyframeable; preprocess ramps.
For copyable edit contracts, load `/hyperframes-core` → `references/creator-editing-recipes.md`.
Broad feedback about how photographic media looks or behaves also routes to
`/media-use`, even when the user never says “color grading” or “effect”: fix
dark/flat/boring footage, stylize a clip, hide a face, or improve a media
reveal. Read `../media-use/references/media-treatments.md` before editing a
treatment; it governs how footage is treated, never whether media may be used.
Do not substitute a generic LUT, CSS filter/overlay, or opacity tween for an
existing canonical treatment primitive. Keep text/layout/motion-only edits in
their owning domain.
During a build with important photographic media, include one grounded
media-polish scan in the final quality pass; leaving suitable media unchanged is
a valid result.
Domain skills never take ownership of the end-to-end deliverable. Load only what the active workflow needs.