Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
7fe8bab
refactor(skills): restructure product-launch-video into product-lunch…
WaterrrForever Jun 19, 2026
d08e942
fix(skills): correct directory name product-lunch-video -> product-la…
WaterrrForever Jun 19, 2026
d7e4a5d
docs(skill): add inspect + snapshot to product-launch-video validation
WaterrrForever Jun 20, 2026
0bb82d2
feat(skill): add 10 frame-presets and register them in design-spec
WaterrrForever Jun 20, 2026
7a01e7c
refactor(product-launch-video): make every frame a directed shot
WaterrrForever Jun 21, 2026
a789cc5
fix(product-launch-video): floor SFX search min_score to 0.4
WaterrrForever Jun 21, 2026
6532d02
refactor(product-launch-video): stage assets at Step 4; tighten prompts
WaterrrForever Jun 21, 2026
9771c58
chore(skills): refresh skill test list, add biennale caption skin
WaterrrForever Jun 21, 2026
5537d6c
fix(product-launch-video): restore skill name to match directory
WaterrrForever Jun 21, 2026
8a0cb7c
feat(skills): per-preset caption skins + auto-load in product-launch …
WaterrrForever Jun 21, 2026
abf43ae
feat(product-launch-video): one-command Step 2 — build-frame remixes …
WaterrrForever Jun 21, 2026
b416f5d
feat(media): shared audio engine (TTS/BGM/SFX); wire product-launch +…
WaterrrForever Jun 21, 2026
922524e
refactor(product-launch-video): stage assets into assets/ not public/
WaterrrForever Jun 21, 2026
e1782e6
refactor(product-launch-video): build-frame token remix + caption tweaks
WaterrrForever Jun 21, 2026
d61de27
refactor(pr-to-video): restructure onto the script-driven architecture
WaterrrForever Jun 21, 2026
8c9a176
refactor(faceless-explainer): restructure onto the script-driven arch…
WaterrrForever Jun 21, 2026
aca40cd
feat(hyperframes-creative): add claude frame preset
WaterrrForever Jun 21, 2026
e43b377
fix(core): escape digit-leading id selectors in standalone sub-compos…
WaterrrForever Jun 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
33 changes: 32 additions & 1 deletion packages/cli/src/capture/contentExtractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,5 +494,36 @@ export function generateAssetDescriptions(
/* no fonts dir */
}

return [...captionedLines, ...uncaptionedLines, ...svgLines, ...fontLines];
// Describe videos — high-value motion clips. The video-manifest.json (written
// earlier by captureVideoManifest) carries each clip's DOM heading/caption +
// dims. Surfaced FIRST and tagged `[video]`: for a product/demo these moving
// clips are usually the strongest hero material, and downstream planners key off
// the `[video]` marker. (The `videos/` dir is skipped in the image walk above —
// its entries come from the manifest, which has the captions the bare files lack.)
const videoLines: string[] = [];
try {
const manifest = JSON.parse(
readFileSync(join(outputDir, "extracted", "video-manifest.json"), "utf-8"),
) as Array<{
filename?: string;
localPath?: string;
caption?: string;
heading?: string;
width?: number;
height?: number;
}>;
for (const v of manifest) {
if (!v.localPath) continue; // only describe clips that actually downloaded
const base = v.localPath.split("/").pop() || v.filename || "";
if (!base) continue;
const desc =
(v.caption || v.heading || "").trim().replace(/\s+/g, " ").slice(0, 140) || "motion clip";
const dims = v.width && v.height ? `, ~${v.width}×${v.height}` : "";
videoLines.push(`${base} — [video] ${desc}${dims}`);
}
} catch {
/* no video manifest */
}

return [...videoLines, ...captionedLines, ...uncaptionedLines, ...svgLines, ...fontLines];
}
10 changes: 7 additions & 3 deletions scripts/test-skills-fresh.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
# 5. Installs the full skills tree from the LOCAL repo via `npx skills add
# --agent <agent>`, then prunes the internal _meta/ authoring skills so the
# installed set matches what an end user gets.
# 6. Verifies the router + 6 workflows + 6 domain skills landed.
# 6. Verifies the router + 10 workflows + 6 domain skills landed.
# 7. Prints the command to start the agent + example prompts to try.
#
# Iterate after editing:
Expand Down Expand Up @@ -234,7 +234,9 @@ fi
say "Verifying skill installation..."

ROUTER="hyperframes"
WORKFLOWS=(product-launch-video faceless-explainer footage-recut pr-to-video general-video remotion-to-hyperframes motion-graphics)
WORKFLOWS=(product-launch-video website-to-video faceless-explainer embedded-captions \
graphic-overlays pr-to-video motion-graphics general-video \
remotion-to-hyperframes slideshow)
DOMAIN=(hyperframes-core hyperframes-creative hyperframes-animation hyperframes-cli hyperframes-media hyperframes-registry)

MISSING=()
Expand Down Expand Up @@ -272,6 +274,8 @@ echo "Then type any request you want to test — the agent routes it to a workfl
echo " • \"make a product launch video for https://your-site.com/\" → product-launch-video (exercises capture)"
echo " • \"explain how transformers work as a faceless explainer video\" → faceless-explainer"
echo " • \"make a video from this PR: owner/repo#123\" → pr-to-video"
echo " • \"recut this footage ./clip.mp4 with info-card overlays\" → footage-recut"
echo " • \"add lower-thirds / overlay cards to ./clip.mp4\" → graphic-overlays"
echo " • \"add captions/subtitles to ./clip.mp4\" → embedded-captions"
echo " • \"turn https://your-site.com/ into a site tour video\" → website-to-video"
echo " • \"a logo reveal / title card / data montage\" → general-video"
echo ""
75 changes: 42 additions & 33 deletions skills/general-video/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
---
name: general-video
description: >
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); use this only as the input/length-agnostic fallback.
The fallback workflow for authoring custom HyperFrames video compositions at
any length or format — longer or multi-scene pieces, brand / sizzle reels,
montages, title cards, static loops, and freeform compositions. Input- and
length-agnostic. If a specialized workflow clearly fits the input — a
marketed product, a website, a topic explainer, a GitHub PR, existing
footage, a short motion graphic, or a Remotion port — prefer it (see
/hyperframes); use this only as the general fallback when none fit.
metadata: { "tags": "orchestrator, general-video, fallback, freeform, composition-authoring" }
---

# general-video — general composition authoring
# general-video — general video workflow

> **Confirm the route before you build.** This is the **fallback** for custom composition authoring. If the input clearly fits a specialized workflow, prefer it: marketed product → `/product-launch-video`; general site → `/website-to-video`; topic explainer → `/faceless-explainer`; GitHub PR → `/pr-to-video`; existing footage → `/embedded-captions` · `/graphic-overlays`; short unnarrated motion graphic → `/motion-graphics`; Remotion port → `/remotion-to-hyperframes`. **Out of scope**: live / at-render-time data, NLE-style editing of a finished video, or producing footage HyperFrames can't capture. Unsure? **Read `/hyperframes` first.**

Expand Down Expand Up @@ -100,18 +96,40 @@ Never use `position: absolute; top: Npx` on a content container — it overflows

This maps the skill's full surface (see the `description`) to its references — non-exhaustive; when an intent isn't listed, route through `hyperframes-creative` (look/concept), `hyperframes-animation` (motion), `hyperframes-core` (contract), `hyperframes-media` (audio/captions). **The first row is ADDITIVE — read it AND your intent row, not one or the other.**

| Building… | Read first (in order) |
| --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **ALWAYS — every non-trivial piece, on top of your intent row below** | `hyperframes-creative/references/house-style.md` + `references/video-composition.md` (also gated in Step 1 / HARD-GATE; the "produced, not generated" foreground detailing) |
| **Kinetic typography / text-forward** | `hyperframes-animation/techniques.md` (kinetic type) + `adapters/gsap-easing-and-stagger.md` + `rules/kinetic-beat-slam.md` |
| **Title card / lower-third / overlay / PiP / text-behind-subject** | `hyperframes-creative/references/composition-patterns.md` + (for the centered/sized frame) `hyperframes-core` → "Root must be sized" |
| **Logo / brand-mark reveal** | `hyperframes-animation/rules/svg-path-draw.md` (draw-on) + `rules/3d-text-depth-layers.md` + `rules/scale-swap-transition.md` |
| **Data / stats / numbers** | `hyperframes-animation/rules/counting-dynamic-scale.md` + `rules/stat-bars-and-fills.md` + `hyperframes-creative/references/data-in-motion.md` |
| **Product / app / UI demo** | `hyperframes-animation/rules/3d-page-scroll.md` + `rules/cursor-click-ripple.md` + `rules/press-release-spring.md` |
| **Audio-reactive / music-driven** | `hyperframes-creative/references/audio-reactive.md` (pre-extract bands; map to motion) |
| **Narrated / voiceover / captions / subtitles** | `hyperframes-media` (`tts`, `transcribe`, caption authoring) → place assets via `hyperframes-core` |
| **Multi-scene / transitions** | `hyperframes-animation/transitions/overview.md` **then** `transitions/catalog.md` (you are not done after the overview — the GSAP recipe is in the catalog) |
| **Modular / sub-compositions** | `hyperframes-core/references/composition-patterns.md` + `references/sub-compositions.md` |
| Building… | Read first (in order) |
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **ALWAYS — every non-trivial piece, on top of your intent row below** | `hyperframes-creative/references/house-style.md` + `references/video-composition.md` (also gated in Step 1 / HARD-GATE; the "produced, not generated" foreground detailing) |
| **Kinetic typography / text-forward** | `hyperframes-animation/techniques.md` (kinetic type) + `adapters/gsap-easing-and-stagger.md` + `rules/kinetic-beat-slam.md` |
| **Title card / lower-third / overlay / PiP / text-behind-subject** | `hyperframes-creative/references/composition-patterns.md` + (for the centered/sized frame) `hyperframes-core` → "Root must be sized" |
| **Logo / brand-mark reveal** | `hyperframes-animation/rules/svg-path-draw.md` (draw-on) + `rules/3d-text-depth-layers.md` + `rules/scale-swap-transition.md` |
| **Data / stats / numbers** | `hyperframes-animation/rules/counting-dynamic-scale.md` + `rules/stat-bars-and-fills.md` + `hyperframes-creative/references/data-in-motion.md` |
| **Product / app / UI demo** | `hyperframes-animation/rules/3d-page-scroll.md` + `rules/cursor-click-ripple.md` + `rules/press-release-spring.md` |
| **Audio-reactive / music-driven** | `hyperframes-creative/references/audio-reactive.md` (pre-extract bands; map to motion) |
| **Narrated / voiceover / music / SFX / captions** | `hyperframes-media` → the shared audio engine `scripts/audio.mjs` (one call = TTS + BGM + SFX → `audio_meta.json`); caption authoring + asset placement via `hyperframes-core`. See **Audio** below. |
| **Multi-scene / transitions** | `hyperframes-animation/transitions/overview.md` **then** `transitions/catalog.md` (you are not done after the overview — the GSAP recipe is in the catalog) |
| **Modular / sub-compositions** | `hyperframes-core/references/composition-patterns.md` + `references/sub-compositions.md` |

### Audio: one engine (TTS · BGM · SFX)

Only when the piece calls for it (per "build exactly what was asked" — no ambient music on a title card). Don't hand-roll TTS or vendor a copy: write a neutral `audio_request.json` and call the shared engine in `hyperframes-media`. It auto-degrades on one switch — HeyGen credential present → HeyGen TTS + music/SFX **retrieval**; absent → ElevenLabs/Kokoro TTS, Lyria/MusicGen BGM **generation**, and the bundled SFX library. Full flag list + request/meta schema: the header comment of `hyperframes-media/scripts/audio.mjs`.

```jsonc
// audio_request.json — one line per narrated segment; `id` is yours (joins audio_meta back)
{
"lines": [
{ "id": "s1", "text": "Your opening line.", "sfx": ["whoosh"] },
{ "id": "s2", "text": "The next beat." },
],
"bgm": { "query": "calm cinematic underscore" }, // omit "mode" → auto (retrieve if HeyGen, else generate); "none" to disable
}
```

```bash
# <MEDIA_DIR> = the installed hyperframes-media skill dir (sibling of this skill)
node <MEDIA_DIR>/scripts/audio.mjs --request ./audio_request.json --hyperframes . --out ./audio_meta.json
```

Then read `audio_meta.json`: mount each `voices[].path` + (`bgm.path`, `sfx[]`) as `<audio>` tracks and use `voices[].words` for captions, all per `hyperframes-core` (audio tracks + caption authoring). If BGM took the generate path (`bgm_pending: true`), run `hyperframes-media/scripts/wait-bgm.mjs` before final render.

## Output checklist → `hyperframes-cli`

Expand All @@ -121,12 +139,3 @@ This maps the skill's full surface (see the `description`) to its references —
- [ ] contrast warnings addressed; for multi-scene work, review the animation map (`hyperframes-animation/scripts/animation-map.mjs`)
- [ ] deliver the preview; render to MP4 only on explicit request
- [ ] surface the preview **only at handoff** (it is the stable, final preview); don't pop one mid-build — build-phase snapshots are headless

## Not this workflow

- A specific **product / company / SaaS / website** being marketed, launched, or promoted → `/product-launch-video`
- A **concept / topic / article / how-X-works** being explained, no product → `/faceless-explainer`
- A **GitHub PR / code change** → `/pr-to-video`
- An **existing talking-head video** to add captions to → `/embedded-captions`
- Porting an existing **Remotion** composition → `/remotion-to-hyperframes`
- Cutting / editing a **finished video file** like an NLE → out of scope (HyperFrames composites HTML and media into a deterministic timeline; it does not edit footage)
Loading
Loading