Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions .github/skills/overview-video/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
---
name: overview-video
description: Rebuild or update the course overview video (about 98 seconds) for this course in videos/overview. Use when running /overview-video, or when asked to refresh the course overview video, add a chapter or feature to it, retake its dark-mode app screenshots, change its copy or timing, add music, or render a new MP4.
---

# Course Overview Video

The project in `videos/overview` makes a 1920x1080 overview video of about 98 seconds
for the course. It is a HyperFrames project (HTML + GSAP, rendered to MP4).
`video.config.json` controls all of the copy, timing, and screenshots.
`scripts/build.mjs` generates `index.html` from it. Never edit `index.html`
by hand.

Read `videos/overview/README.md` for the file map and scene list, and
`videos/overview/frame.md` for the design system.

## Requirements

- Node.js 22+, ffmpeg and ffprobe, and ImageMagick (`magick`).
- HyperFrames runs with `npx --yes hyperframes@0.8.134`. You do not install it.
- For new screenshots: macOS, the signed-in `demo` persona, and the
[`github-copilot-app-automation`](../github-copilot-app-automation/SKILL.md)
skill.

## Workflow

Work from `videos/overview`.

1. **Decide the change.** Read the course `README.md` and the chapter READMEs
to find what changed (new chapter, renamed feature, new app UI). Keep the
total near 90–100 s: when you add time in one place, remove it from
another. Keep
durations on a 0.5 s grid. Think like a beginner: give each chapter at
least 5.5 s and each screen at least 3 s, and cut content before you
shorten them.
2. **Update `video.config.json`.**
- A chapter needs `num`, `short` (tracklist label), `studio` (the chapter's
"From the Studio" name), `headline` (two lines of about 17 characters
or fewer, the second is shown in the gradient), `sub` (one plain line),
`duration`, and either `shots` or `canvas`.
- Headlines name the app feature (for example, "Put it on repeat / with
automations."). Use the studio analogy only in `studio` labels. Do not
use jargon such as "worktree" or "MCP" without a plain `sub` line.
- A shot is `{ "src": "<name>", "focus": [left, top, right, bottom] }` in
1920x1080 screenshot pixels. The camera pushes in to the focus box.
A focus ring is drawn when the box is small. Use `"ring": false` to hide
the ring, or `"ring": [l, t, r, b]` to draw it on another box. Use
`"fallback": "<name>"` when a shot can be missing.
- Several shots in one chapter share its duration and change by crossfade.
Use no more than three shots in one chapter. A shot can set its own
`"duration"`.
- A shot can play a screen recording: add `"video": "assets/clips/<name>.mp4"`
(1920x1080, H.264, no audio). `src` is the still that shows when the clip
is missing. Optional: `"mediaStart"` (seconds to skip) and `"rate"`.
- `"moves": [{ "at": 1.5, "focus": [l, t, r, b], "dur": 1.2 }]` replaces the
default push with timed camera moves (`at` is seconds into the shot).
Use it to follow the action in a video shot.
Use `steps` with a `step` index on each shot to light a step rail.
- `float` adds mono pills near the card (for example, mode names). Use it
only when it helps a beginner read the screen.
3. **Retake screenshots when the app UI changes.** Follow the
`github-copilot-app-automation` skill with these rules:
- Run the persona on the laptop screen: export
`COPILOT_CAPTURE_DISPLAY=builtin` in every command that runs
`prepare-persona.sh` or `capture-window.sh`.
- Switch the persona to a dark theme in **Settings > Themes** before you
capture, and set the original theme again when you finish.
- Do not add `--callout`, `--box`, `--arrow`, or `--crop`. Video cards must
be clean.
- Save to `videos/overview/assets/shots/<name>.png` (the script also
writes `.webp`). Only the WebP files are committed.
- Do not set `TMPDIR` to a folder in the repository.
- Agent-at-work shots (`session-plan`, `session-working`,
`session-diff-live`, `browser-preview`) need a real session in the
persona. Get the user's approval before you send a prompt. Use a new
worktree and Plan mode. Do not push, open a PR, or merge. Archive the
session when you finish.
- Find focus boxes from a half-size preview of each shot, then double the
coordinates.
- Screen recordings are not sanitized. Hide the sidebar while you record,
check frames every 0.5 s for names, handles, and paths, and cover any
that show.
4. **Build and check.**
```bash
npm run check
```
Lint must report 0 errors, and check must pass. The structure warnings
(`nested_structure_needs_subcomposition`, `timeline_track_too_dense`) are
expected for this generated, single-file composition. If
`composition_heavy_overlay_count_high` shows, remove blur, radial-gradient,
or clip-path elements until it goes away. Otherwise, the render can show
black frames.
5. **Inspect frames.**
```bash
npm run snapshot
```
Open `snapshots/contact-sheet-*.jpg`. Check every headline at its settled
time with `--zoom "#<id> .ch-head"` (and the hook, studio, lockup, and end
titles): no letter may be cut off at the edges or below the baseline
(`?`, `g`, `s`, and `y` are the usual problems). Also take snapshots 0.1 s before and
0.2 s after each cut that you changed (`npx --yes hyperframes@0.8.134
snapshot --no-end --at ...`). Look for tight word spacing, text that
overflows, empty frames, and cluttered card crossovers.
6. **Preview, then render.** Run `npm run dev` for Studio. Render only after
the user approves:
```bash
npm run render # renders/video.mp4
npm run music -- path/to/track.mp3 --start 8 # renders/video-with-music.mp4
```
7. **Music.** When a track is longer than the video, find its tempo and
beat phase and its big hits and quiet parts (for example, with numpy
on a mono decode). Then set `music.segments` so beats land on the 0.5 s
cut grid and the big hits land on key cuts: the reveal, Chapter 07, and the
end card. Make each edit on a downbeat in a section of similar loudness.
Check the result: the level change at each edit should be within normal
beat-to-beat change, and the loudness about -14 LUFS.
8. **Export.** Run `npm run export` to replace the committed web copy at
`videos/copilot-app-for-beginners-overview.mp4`. Keep it under 50 MB
(GitHub warns above that; the repo does not use Git LFS).
9. **Report** the MP4 paths, the final duration, and any shot that used a
fallback (`build.mjs` prints a warning for each).

## Rules

- Keep every visual in the video's own dark style. Do not drop in the
course's cartoon illustrations; they look out of place.
- Keep the copy short and true to the course. Do not claim features that the
chapters do not teach.
- Keep motion professional: no `back`, `elastic`, or bounce eases, and no
infinite loops.
- Keep timing deterministic: no `Math.random`, clocks, or network data at
render time (the build uses a seeded random generator).
- Screenshots must come from the sanitized persona. Before you commit, check
each one for private names, paths, or tokens.
- `renders/` and `snapshots/` are not committed.
Binary file added videos/copilot-app-for-beginners-overview.mp4
Binary file not shown.
6 changes: 6 additions & 0 deletions videos/overview/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
renders/
snapshots/
node_modules/
.hyperframes/
# Capture source PNGs are large. The lossless WebP copies are committed.
assets/shots/*.png
41 changes: 41 additions & 0 deletions videos/overview/.media/preferences.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"version": 1,
"preferences": {
"destination": {
"value": "youtube",
"confirmed_in": [
"overview"
],
"updated_at": "2026-10-05T22:53:06.819Z"
},
"aspect": {
"value": "1920x1080",
"confirmed_in": [
"overview"
],
"updated_at": "2026-10-05T22:53:06.858Z"
},
"language": {
"value": "en",
"confirmed_in": [
"overview"
],
"updated_at": "2026-10-05T22:53:06.907Z"
},
"flow": {
"value": "automation",
"confirmed_in": [
"overview"
],
"updated_at": "2026-10-05T22:53:06.952Z"
},
"storyboard": {
"value": "no",
"confirmed_in": [
"overview"
],
"updated_at": "2026-10-05T22:53:06.993Z"
}
},
"sightings": {}
}
113 changes: 113 additions & 0 deletions videos/overview/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Course overview video

This project is generated. Edit `video.config.json`, `src/`, or `scripts/`,
then run `npm run build`. Follow the repo skill
`.github/skills/overview-video/SKILL.md` for the full workflow.

# HyperFrames Composition Project

## Skills — USE THESE FIRST

**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.

**Doing anything with HyperFrames?** Start at `/hyperframes` — it tells you what HyperFrames can do and which skill or workflow handles your intent (make a video, TTS / BGM, prep footage, author / animate, render, install blocks), confirms your brief up front (the intent layer), and routes every "make me a…" request (a video, a deck, a composition port) to the right workflow. Read it first, especially when there's no project context to orient you. The workflows it routes to:

- `/product-launch-video` — any **website** URL or brief / script → a product launch / SaaS / promo video, or a site tour / showcase featuring the site's own captured visuals.
- `/faceless-explainer` — arbitrary text (topic / article / notes), **no URL, no website capture** → 60-90s faceless explainer.
- `/embedded-captions` — an existing talking-head video (MP4) → the same footage with captions / subtitles added (rail + embed, or pure-cinematic embed); the footage itself is untouched.
- `/talking-head-recut` — an existing talking-head / interview / podcast video (MP4) → the same footage **packaged with designed graphic overlays** (kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, pip) synced to the transcript; the clip plays unchanged underneath. (Plain captions/subtitles → `/embedded-captions`.)
- `/pr-to-video` — a GitHub PR (URL / `owner/repo#N` / "this PR") → 30-90s code-change explainer (changelog / feature reveal / fix / refactor).
- `/motion-graphics` — a short (typically under 10s) design-led **motion graphic**, motion-is-the-message, no narration: kinetic type, a stat / number count-up, a chart, a logo sting, a lower-third / overlay, or an animated tweet / headline / captured-page highlight; rendered to MP4 or a transparent overlay. Longer / narrated / custom → `/general-video`.
- `/music-to-video` — a **music track** (audio file, video to pull audio from, or one generated from a mood brief) → beat-synced video (lyric / slideshow / kinetic promo). Music drives pacing; user-supplied images / videos are cut onto the same beat grid.
- `/slideshow` — a **presentation / pitch deck / interactive deck** — discrete slides, fragment reveals, branching, hotspot navigation, presenter mode. Output is a navigable deck, not a rendered video.
- `/general-video` — fallback for any other video (title card, longer brand / sizzle reel, multi-scene montage, static loop, custom composition) and the home of **companion mode** — co-create with the full HyperFrames toolbox; the original hyperframes authoring flow, any length.

**Porting an existing composition?** `/remotion-to-hyperframes` translates a Remotion (React) composition into HyperFrames HTML — a source migration, separate from the creation workflows above.

The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-keyframes`, `/hyperframes-creative`, `/hyperframes-cli`, `/media-use`, `/hyperframes-audio`, `/hyperframes-registry`, `/figma`) and the full capability map live inside `/hyperframes` — it is the single source of truth for which skill handles which intent.

**Changing how real footage or images look or reveal?** Load `/media-use` and read its `references/media-treatments.md` before editing, even when the request only says dark, flat, boring, retro, private, or “make the reveal cooler.” It governs how footage is treated, never whether media may be used. Use canonical media treatments and seek-safe motion; do not improvise equivalent CSS/SVG filters or overlays.

> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.

> **Using a HyperFrames plugin?** Load skills from that installed bundle and follow
> its `hyperframes/references/plugin-installation.md` execution rules. Update via
> the plugin manager, not the standalone commands below.
>
> **Standalone skill missing or stale?** Run `npx hyperframes skills update <name>` to install/refresh
> the specific skill you need (the `/hyperframes` router does this automatically before
> entering a workflow), or bare `npx hyperframes skills update` to refresh the core set plus
> everything already installed — neither pulls the full set. Restart the agent session so
> newly installed skills load.

## Commands

```bash
npm run dev # human-operated foreground preview (blocks until stopped)
npx hyperframes preview --background # agent-safe persistent Studio preview
npx hyperframes preview --status # verify the persistent preview is listening
npx hyperframes preview --stop # stop it when review is finished
npm run check # lint + runtime + layout + motion + contrast (one command)
npm run render # render to MP4
npm run publish # publish and get a shareable link
npx hyperframes lint --verbose # include info-level findings
npx hyperframes lint --json # machine-readable output for CI
npx hyperframes docs <topic> # reference docs in terminal
```

> **Agents must use `npx hyperframes preview --background` for Studio handoff.** Do not rely
> on a shell/tool `run_in_background` wrapper around `npm run dev`: that foreground process
> remains owned by the invoking session and can disappear while the browser stays open,
> leaving refreshes at `ERR_CONNECTION_TIMED_OUT`. Verify with `preview --status`, keep it
> alive through review, and stop it explicitly with `preview --stop` afterward.

> **Pinned CLI version.** These scripts pin an exact `hyperframes@X.Y.Z` so this project re-renders identically over time. Weeks later that pin lags fixes shipped since. To move up: `npx hyperframes@latest upgrade --project . --check` (shows the delta), then `npx hyperframes@latest upgrade --project .` to rewrite the pins. Always unpinned — the pinned script re-runs the old version against itself.

## Documentation

**For quick reference**, use the local CLI docs command (no network required):

```bash
npx hyperframes docs <topic>
```

Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `examples`, `troubleshooting`

**For full documentation**, discover pages via the machine-readable index — do NOT guess URLs:

```
https://hyperframes.heygen.com/llms.txt
```

## Project Structure

- `index.html` — main composition (root timeline)
- `compositions/` — sub-compositions referenced via `data-composition-src`
- `meta.json` — project metadata (id, name)
- `transcript.json` — whisper word-level transcript (if generated)

## Linting — ALWAYS RUN AFTER CHANGES

After creating or editing any `.html` composition, **always** run the full check before considering the task complete:

```bash
npm run check
```

Fix all errors before presenting the result. Warnings should be reviewed before rendering.

## Key Rules

1. Every timed element needs `data-start` and a duration. `data-start` is what marks it as timed; `data-track-index` is an optional Studio display lane the render never reads
2. Give timed visual elements `class="clip"`. The framework keys visibility off `data-start`, not the class, but the shared `.clip` CSS is what gives a scene its full-frame box, and `lint` warns without it
3. Register one paused root timeline per composition on `window.__timelines`:
```js
window.__timelines = window.__timelines || {};
window.__timelines["composition-id"] = gsap.timeline({ paused: true });
```
Scene timelines manually added to this root must not be paused. A paused
child does not advance when the root is seeked. The runtime activates
registered composition siblings, not arbitrary nested scene timelines.
4. A video with sound keeps it on the `<video>` (`data-has-audio="true"`, no `muted`). Use a separate `<audio>` for music, voiceover, replacement audio, J/L cuts, or audio detached in Studio. Silent footage and b-roll: `muted`.
5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
54 changes: 54 additions & 0 deletions videos/overview/BRIEF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
workflow: product-launch-video
flow: automation
storyboard: no
message: "Learn to direct AI coding agents from one desktop app. Free, hands-on, open source."
destination: youtube
aspect: 1920x1080
language: en
length: 98.5s
angle: feature-cascade
audience: Developers and students who are new to agentic development
---

## Intent

An overview video of about 98 seconds for the free course **GitHub Copilot app for Beginners**.
It shows real app screenshots, what learners do in each chapter, and the key
reasons to start. The feel is "wow" but professional: cinematic, confident, and
smooth. It is less bouncy than the reference video
(<https://x.com/JamesMontemagno/status/2106894755900834195>).

## Assets

- assets/shots/*.png — clean, dark-mode screenshots of the GitHub Copilot app,
captured from the sanitized `demo` persona with the
`github-copilot-app-automation` skill (no tutorial callouts).
- assets/fonts/ — Mona Sans and Mona Sans Mono (GitHub, SIL OFL 1.1).
- assets/icons/ — Primer Octicons (GitHub, MIT).
- Music — supplied by the user later. The video renders without music, and
`scripts/add-music.mjs` adds the track without a new video render.

## Customizations

- Data-driven: chapter cards, value chips, and the end card come from
`video.config.json`, so a new chapter or feature needs a config change and a
rebuild only.
- Hook: "What if you could direct a team of AI agents while staying focused?"
Agent tiles fly in scattered, then line up and finish their work.
- Recording-studio analogy (the course theme), explained once after the hook.
The same agents move into a glass live room, and a mixing console with
Interactive, Plan, and Autopilot channels rises below it. Built in the
video's own style (no course illustrations, which looked out of place):
the app is your studio, you are the producer, and AI agents are the band.
"8 tracks. 1 course." introduces the DAW-style tracklist. Chapter labels show
the studio name in small text; headlines use plain app terms.
- Beginner pacing: one headline and one plain line per chapter, a hold on each
screen before the camera moves, and crossfades instead of swipes.
- End on availability (free, open source) and the course URL.

## Notes

- No voice-over. Music only.
- Do not show private data. Screenshots must come from the sanitized persona.
- Reproduce with the repo skill `.github/skills/overview-video/`.
Loading
Loading