docs: audit and fix all documentation against actual codebase

Comprehensive audit of every documentation page against the actual source
code, fixing incorrect APIs, wrong CLI flags, nonexistent templates, and
missing public exports. Also documents the new agent-friendly CLI design.

Key fixes:
- Quickstart: `npx create-hyperframe` → `npx hyperframes init`, Node 20→22
- Templates: replaced nonexistent blank/title-card/video-edit with actual
  templates (blank, warm-grain, play-mode, swiss-grid, vignelli)
- CLI: removed nonexistent short flags (-o/-f/-q/-w), added missing
  commands (browser, docs, telemetry, skills), documented agent-friendly
  non-interactive default and --human-friendly flag
- Producer: replaced nonexistent `render()` API with actual
  `createRenderJob()`/`executeRenderJob()`, added server API docs
- Engine: replaced nonexistent `createEngine()` with actual session-based
  API, added HfProtocol, encoding, streaming, parallel rendering docs
- Core: fixed wrong type names (Composition/Clip→TimelineElement), wrong
  function names (parseHyperframeHtml→parseHtml), documented all 4 entry
  points (main, /lint, /compiler, /runtime)
- Studio: added all missing exports (NLELayout, SourceEditor,
  PropertyPanel, FileTree, StudioApp, hooks, Tailwind preset)
- All pages: --output not -o, Node 22+ not 20+

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
James
2026-03-26 18:23:32 +00:00
parent 36c91cecbb
commit db892f4e8f
11 changed files with 1098 additions and 275 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ These same rules apply to every [frame adapter](/concepts/frame-adapters). If yo
For maximum reproducibility, render in Docker:
```bash
npx hyperframes render --docker -o output.mp4
npx hyperframes render --docker --output output.mp4
```
Docker mode uses an exact Chrome version and font set, ensuring:
+13 -11
View File
@@ -18,10 +18,11 @@ Render your Hyperframes [compositions](/concepts/compositions) to MP4 with the [
Expected output:
```
✓ Node.js 20.x
✓ FFmpeg found (7.x)
Docker available
Disk space OK
✓ Node.js v22.x
✓ FFmpeg 7.x
FFprobe 7.x
Chrome (bundled)
✓ Docker available
```
</Step>
<Step title="Preview your composition">
@@ -35,7 +36,7 @@ Render your Hyperframes [compositions](/concepts/compositions) to MP4 with the [
Run the render command from your project directory:
```bash Terminal
npx hyperframes render -o output.mp4
npx hyperframes render --output output.mp4
```
Expected output:
@@ -59,7 +60,7 @@ Render your Hyperframes [compositions](/concepts/compositions) to MP4 with the [
**Requires:** FFmpeg installed on your system. See [Troubleshooting](/guides/troubleshooting) if FFmpeg is not found.
```bash Terminal
npx hyperframes render -o output.mp4
npx hyperframes render --output output.mp4
```
**Pros:**
@@ -79,7 +80,7 @@ Render your Hyperframes [compositions](/concepts/compositions) to MP4 with the [
**Requires:** Docker installed and running.
```bash Terminal
npx hyperframes render --docker -o output.mp4
npx hyperframes render --docker --output output.mp4
```
**Pros:**
@@ -112,12 +113,13 @@ Render your Hyperframes [compositions](/concepts/compositions) to MP4 with the [
| Flag | Values | Default | Description |
|------|--------|---------|-------------|
| `-f, --fps` | 24, 30, 60 | 30 | Frames per second |
| `-q, --quality` | draft, standard, high | standard | Encoding quality preset |
| `-w, --workers` | 1-8 | auto | Parallel render workers |
| `--output` | path | `renders/<name>.mp4` | Output file path |
| `--fps` | 24, 30, 60 | 30 | Frames per second |
| `--quality` | draft, standard, high | standard | Encoding quality preset |
| `--workers` | 1-8 | 4 | Parallel render workers |
| `--gpu` | — | off | GPU encoding (NVENC, VideoToolbox, VAAPI) |
| `-o, --output` | path | — | Output file path |
| `--docker` | — | off | Use Docker for [deterministic rendering](/concepts/determinism) |
| `--quiet` | — | off | Suppress verbose output |
## Tips
+104 -29
View File
@@ -11,7 +11,9 @@ Hyperframes includes starter templates to help you scaffold compositions quickly
npx hyperframes init --template <name>
```
This creates a new project directory with an `index.html` composition and any required assets.
This creates a new project directory with an `index.html` composition, sub-compositions, and any required assets.
You can also run `npx hyperframes init` without `--template` to choose interactively.
## Available Templates
@@ -19,77 +21,150 @@ This creates a new project directory with an `index.html` composition and any re
<Tab title="blank">
### blank
An empty 1920x1080 composition with a GSAP timeline wired up and nothing else. Start from scratch.
An empty composition with just the scaffolding — a video element, audio track, captions sub-composition, and an empty GSAP timeline. Start from scratch.
**What it produces:** A black (empty) canvas at 1920x1080 resolution. No visible elements, no animations. The timeline is registered and ready for you to add tweens.
**What it produces:** A minimal project with a single video clip and audio, ready for you to customize. The timeline is registered and ready for you to add tweens.
**When to use it:** You have a specific design in mind and want full control. Good for AI agent workflows that will generate the entire composition programmatically.
**When to use it:** You have a specific design in mind and want full control. Good for AI agent workflows that will generate the composition programmatically, or when starting from a source video.
```bash Terminal
npx hyperframes init --template blank
npx hyperframes init my-video --template blank
```
**What you get:**
```
my-video/
├── index.html # Empty root composition with GSAP setup
── assets/ # Empty directory for your media files
├── meta.json
── index.html
└── compositions/
└── captions.html
```
</Tab>
<Tab title="title-card">
### title-card
<Tab title="warm-grain">
### warm-grain
Animated title and subtitle with GSAP fade-in/out transitions.
A cream-toned aesthetic with grain texture overlay. Warm, organic feel suited for lifestyle and branding videos.
**What it produces:** A centered title and subtitle that fade in from the top, hold for a few seconds, then fade out. Clean, minimal typography on a solid background. Good for intro cards, chapter markers, or end screens.
**What it produces:** A composition with warm color grading, textured grain, and smooth transitions. Includes an intro sub-composition and captions support.
**When to use it:** You need a simple text-based segment — an intro, outro, or interstitial card between video clips.
**When to use it:** You want an organic, stylized look for branding, lifestyle, or editorial content.
```bash Terminal
npx hyperframes init --template title-card
npx hyperframes init my-video --template warm-grain
```
**What you get:**
```
my-video/
├── index.html # Title + subtitle with fade animations
── assets/ # Empty directory for your media files
├── meta.json
── index.html
├── compositions/
│ ├── intro.html
│ ├── graphics.html
│ └── captions.html
└── assets/
```
</Tab>
<Tab title="video-edit">
### video-edit
<Tab title="play-mode">
### play-mode
A video element with trimming, audio, and track controls.
Playful elastic animations with bold, energetic motion.
**What it produces:** A full-screen video clip with [`data-media-start`](/concepts/data-attributes#media-attributes) for trimming, a background audio track on a separate [timeline track](/concepts/data-attributes#timing-attributes), and a lower-third text overlay animated with GSAP. Demonstrates how multiple clip types work together.
**What it produces:** A composition with bouncy, elastic animation curves and dynamic layout transitions. Includes intro, stats, and captions sub-compositions.
**When to use it:** You are building a video editing workflow — cutting clips, adding overlays, mixing audio. This template shows the patterns for media-heavy compositions.
**When to use it:** You want a fun, high-energy feel — great for social media, product launches, or explainer videos.
```bash Terminal
npx hyperframes init --template video-edit
npx hyperframes init my-video --template play-mode
```
**What you get:**
```
my-video/
├── index.html # Video + audio + overlay composition
── assets/ # Place your video and audio files here
├── meta.json
── index.html
├── compositions/
│ ├── intro.html
│ ├── stats.html
│ └── captions.html
└── assets/
```
</Tab>
<Tab title="swiss-grid">
### swiss-grid
Structured grid layout inspired by Swiss/International Typographic Style.
**What it produces:** A clean, grid-based composition with precise typography and structured layouts. Includes intro, graphics, and captions sub-compositions.
**When to use it:** You want a clean, professional, information-dense layout — ideal for corporate videos, data presentations, or technical content.
```bash Terminal
npx hyperframes init my-video --template swiss-grid
```
**What you get:**
```
my-video/
├── meta.json
├── index.html
├── compositions/
│ ├── intro.html
│ ├── graphics.html
│ └── captions.html
└── assets/
```
</Tab>
<Tab title="vignelli">
### vignelli
Bold typography with red accents, inspired by Massimo Vignelli's design philosophy.
**What it produces:** A striking composition with strong typographic hierarchy, red accent colors, and confident transitions. Includes overlays and captions sub-compositions.
**When to use it:** You want a bold, authoritative visual style — great for headlines, announcements, or editorial content.
```bash Terminal
npx hyperframes init my-video --template vignelli
```
**What you get:**
```
my-video/
├── meta.json
├── index.html
├── compositions/
│ ├── overlays.html
│ └── captions.html
└── assets/
```
</Tab>
</Tabs>
## Choosing a Template
| Template | Best for | Complexity |
|----------|----------|------------|
| `blank` | Full control, agent-generated compositions | Minimal |
| `title-card` | Text intros, outros, chapter markers | Simple |
| `video-edit` | Video cutting, overlays, multi-track editing | Moderate |
| Template | Style | Best for |
|----------|-------|----------|
| `blank` | Minimal scaffolding | Full control, agent-generated, starting from video |
| `warm-grain` | Organic, textured | Lifestyle, branding, editorial |
| `play-mode` | Energetic, elastic | Social media, product launches |
| `swiss-grid` | Clean, structured | Corporate, data, technical |
| `vignelli` | Bold, typographic | Headlines, announcements |
<Tip>
If you are new to Hyperframes, start with `title-card` to see a working animation, then move to `blank` when you are comfortable with the [composition model](/concepts/compositions) and [GSAP animation](/guides/gsap-animation).
If you are new to Hyperframes, start with `warm-grain` or `play-mode` to see working animations and sub-compositions in action. Use `blank` when you want minimal scaffolding and full control. Run `npx hyperframes init` without `--template` to preview all options interactively.
</Tip>
## Passing a Source Video
You can initialize a project with your own video file using the `--video` flag:
```bash Terminal
npx hyperframes init my-video --template warm-grain --video ./my-clip.mp4
```
The CLI will probe the video for duration, resolution, and codec. If the video uses an incompatible codec (not H.264, VP8/9, AV1, or Theora), it will be automatically transcoded to H.264 MP4 if FFmpeg is available.
## Custom Templates
Any directory with an `index.html` can serve as a template. You can copy a directory manually or build your own init workflow.
+2 -2
View File
@@ -44,7 +44,7 @@ If your issue is about a specific coding mistake (animations not working, video
After installing, run `npx hyperframes doctor` to verify the CLI can find it.
<Tip>
If you cannot install FFmpeg, use [Docker mode](/guides/rendering) instead — it bundles FFmpeg inside the container: `npx hyperframes render --docker -o output.mp4`
If you cannot install FFmpeg, use [Docker mode](/guides/rendering) instead — it bundles FFmpeg inside the container: `npx hyperframes render --docker --output output.mp4`
</Tip>
</Accordion>
@@ -79,7 +79,7 @@ If your issue is about a specific coding mistake (animations not working, video
- **System-specific rendering** — GPU compositing, subpixel antialiasing, etc.
```bash Terminal
npx hyperframes render --docker -o output.mp4
npx hyperframes render --docker --output output.mp4
```
See [Rendering: When to Use Each Mode](/guides/rendering#when-to-use-each-mode) for guidance on choosing between local and Docker rendering.
+5 -5
View File
@@ -27,7 +27,7 @@ Here is a video defined entirely as HTML:
</div>
```
Run `npx hyperframes render -o demo.mp4` and this produces an MP4 with deterministic, frame-by-frame capture. Same input, identical output, every time. No timeline editor. No proprietary format. Just HTML.
Run `npx hyperframes render --output demo.mp4` and this produces an MP4 with deterministic, frame-by-frame capture. Same input, identical output, every time. No timeline editor. No proprietary format. Just HTML.
## Why Hyperframes?
@@ -36,7 +36,7 @@ Run `npx hyperframes render -o demo.mp4` and this produces an MP4 with determini
**You already know the stack.** Compositions are HTML files with data attributes. Animations use GSAP, Lottie, CSS, or any runtime that can seek to a given frame. There is no custom DSL, no proprietary component system, and no React requirement. If you can build a web page, you can build a video.
</Tab>
<Tab title="For AI agents">
**Agents already speak HTML.** Most video tools require complex APIs or drag-and-drop interfaces that agents cannot operate. Hyperframes compositions are plain HTML documents — the format LLMs are best at generating. An agent can compose, modify, and render videos using tools it already understands.
**Agents already speak HTML.** Most video tools require complex APIs or drag-and-drop interfaces that agents cannot operate. Hyperframes compositions are plain HTML documents — the format LLMs are best at generating. The CLI is non-interactive by default — all inputs via flags, plain text output, fail-fast on errors — so agents can drive every command without prompts or parsing.
</Tab>
<Tab title="For automated pipelines">
**Determinism by design.** The rendering pipeline is seek-driven with no wall-clock dependencies. `frame = floor(time * fps)` — every frame is independently captured via Chrome's `beginFrame` API and encoded with FFmpeg. Same input always produces identical output, making CI testing and batch rendering reliable.
@@ -44,7 +44,7 @@ Run `npx hyperframes render -o demo.mp4` and this produces an MP4 with determini
</Tabs>
<Tip>
Hyperframes was designed from the ground up for AI agent integration. Because compositions are plain HTML, any LLM can generate, edit, and iterate on video content without specialized tooling. Pair it with function-calling agents to build fully automated video pipelines.
Hyperframes was designed from the ground up for AI agent integration. Compositions are plain HTML that any LLM can generate. The CLI is non-interactive by default — flag-driven with plain text output — so agents can scaffold, render, and lint without interactive prompts. Add `--human-friendly` for the interactive terminal UI. See [CLI](/packages/cli) for details.
</Tip>
## How It Works
@@ -54,10 +54,10 @@ Run `npx hyperframes render -o demo.mp4` and this produces an MP4 with determini
Define your video as an HTML document. Each element gets data attributes for timing (`data-start`, `data-duration`) and layout (`data-track-index`). Add animations with GSAP, Lottie, CSS transitions, or any seekable runtime via the Frame Adapter pattern.
</Step>
<Step title="Preview in the browser">
Run `npx hyperframes dev` to open a live preview at `localhost:3000`. Edit your HTML and see changes instantly — no build step, no compilation.
Run `npx hyperframes dev` to open a live preview in your browser. Edit your HTML and see changes instantly — no build step, no compilation.
</Step>
<Step title="Render to MP4">
Run `npx hyperframes render -o output.mp4` to produce a final video. The engine seeks each frame in headless Chrome, captures it with `beginFrame`, and pipes the result through FFmpeg. Run locally or in Docker for fully reproducible output.
Run `npx hyperframes render --output output.mp4` to produce a final video. The engine seeks each frame in headless Chrome, captures it with `beginFrame`, and pipes the result through FFmpeg. Run locally or in Docker for fully reproducible output.
</Step>
</Steps>
+178 -76
View File
@@ -30,35 +30,56 @@ npx hyperframes <command>
The CLI is the recommended starting point for all Hyperframes users. It wraps the producer, engine, and studio packages so you do not need to install them separately.
</Tip>
## Agent-Friendly by Default
The CLI is **non-interactive by default** — designed so AI agents (Claude Code, Gemini CLI, Codex, Cursor) can drive every command without prompts or interactive UI.
- All inputs are passed via flags (e.g., `--template`, `--video`, `--output`)
- Missing required flags fail fast with a clear error and usage example
- Output is plain text suitable for parsing
- No interactive prompts, spinners, or selection menus
Add `--human-friendly` to any command to enable the interactive terminal UI with prompts, spinners, and selection menus.
<Tabs>
<Tab title="Agent mode (default)">
```bash
# Fully non-interactive — all inputs from flags
npx hyperframes init my-video --template blank --video video.mp4
npx hyperframes render --output output.mp4 --fps 30 --quality standard
npx hyperframes upgrade --check
```
</Tab>
<Tab title="Human mode">
```bash
# Interactive prompts, spinners, and selection menus
npx hyperframes init --human-friendly
npx hyperframes upgrade
```
</Tab>
</Tabs>
## Getting Started
<Steps>
<Step title="Create a project">
Scaffold a new composition from a template:
```bash
npx hyperframes init --template title-card
npx hyperframes init --template warm-grain
```
```
Creating composition in ./title-card...
index.html
assets/
package.json
Done! Run `cd title-card && npx hyperframes dev` to preview.
You will be prompted for a project name, or pass it as an argument:
```bash
npx hyperframes init my-video --template warm-grain
```
See [Templates](/guides/templates) for all available templates.
</Step>
<Step title="Preview in browser">
Start the development server with live hot reload:
```bash
cd title-card
cd my-video
npx hyperframes dev
```
```
Hyperframes Studio v0.1.0
Local: http://localhost:3000
Watching for changes...
```
Edit `index.html` and the preview updates instantly.
The Hyperframes Studio opens in your browser. Edit `index.html` and the preview updates instantly.
</Step>
<Step title="Lint your composition">
Check for structural issues before rendering:
@@ -73,16 +94,11 @@ npx hyperframes <command>
<Step title="Render to MP4">
Produce the final video:
```bash
npx hyperframes render -o output.mp4
```
```
Rendering index.html...
[========================================] 100% (900/900 frames)
Output: output.mp4 (30s, 1920x1080, 30fps)
npx hyperframes render --output output.mp4
```
For deterministic output, add `--docker`:
```bash
npx hyperframes render --docker -o output.mp4
npx hyperframes render --docker --output output.mp4
```
</Step>
</Steps>
@@ -96,17 +112,35 @@ npx hyperframes <command>
Create a new composition project from a template:
```bash
npx hyperframes init --template <name>
# Agent mode (default) — --template is required
npx hyperframes init my-video --template blank --video video.mp4
# Human mode — interactive prompts
npx hyperframes init --human-friendly
```
| Flag | Description |
|------|-------------|
| `--template, -t` | Template to use (required in default mode, interactive in `--human-friendly`) |
| `--video, -V` | Path to a video file (MP4, WebM, MOV) |
| `--audio, -a` | Path to an audio file (MP3, WAV, M4A) |
| `--skip-skills` | Skip AI coding skills installation |
| `--skip-transcribe` | Skip automatic whisper transcription |
| `--human-friendly` | Enable interactive terminal UI with prompts |
| Template | Description |
|----------|-------------|
| `blank` | Empty 1920x1080 composition with a GSAP timeline wired up |
| `title-card` | Animated title and subtitle with GSAP fade-in/out |
| `slideshow` | Image slideshow with crossfade transitions |
| `lower-third` | Broadcast-style lower-third overlay |
| `blank` | Empty composition — just the scaffolding |
| `warm-grain` | Cream aesthetic with grain texture |
| `play-mode` | Playful elastic animations |
| `swiss-grid` | Structured grid layout |
| `vignelli` | Bold typography with red accents |
See [Templates](/guides/templates) for full details and previews.
In default (agent) mode, `--template` is required — the CLI errors with a usage example if missing. In `--human-friendly` mode, you choose interactively. When `--video` or `--audio` is provided, the CLI automatically transcribes the audio with Whisper and patches captions into the composition (use `--skip-transcribe` to disable).
After scaffolding, the CLI installs AI coding skills for Claude Code, Gemini CLI, and Codex CLI (use `--skip-skills` to disable). See [`skills`](#skills) command.
See [Templates](/guides/templates) for full details.
### `compositions`
@@ -115,11 +149,12 @@ npx hyperframes <command>
```bash
npx hyperframes compositions
```
```
Compositions in ./my-video:
root index.html (30s, 1920x1080)
intro-anim compositions/intro.html (5s, 1920x1080)
```
| Flag | Description |
|------|-------------|
| `--json` | Output as JSON |
Shows each composition's ID, duration, resolution, and element count.
</Tab>
<Tab title="Develop">
### `dev`
@@ -127,22 +162,17 @@ npx hyperframes <command>
Start a live preview server with hot reload:
```bash
npx hyperframes dev
```
```
Hyperframes Studio v0.1.0
Local: http://localhost:3000
Watching for changes...
npx hyperframes dev [dir]
```
Opens your composition in the browser. Edits to `index.html` and any referenced sub-compositions are reflected instantly. The preview uses the same Hyperframes runtime as production rendering, so what you see is what you get.
Opens your composition in the Hyperframes Studio with live preview. Edits to `index.html` and any referenced sub-compositions are reflected instantly. The preview uses the same Hyperframes runtime as production rendering, so what you see is what you get.
### `lint`
Check a composition for common issues:
```bash
npx hyperframes lint
npx hyperframes lint [dir]
```
```
Linting index.html...
@@ -154,6 +184,10 @@ npx hyperframes <command>
1 issue found (0 errors, 1 warning)
```
| Flag | Description |
|------|-------------|
| `--json` | Output findings as JSON |
The linter detects missing attributes, deprecated names, structural problems, and more. See [Common Mistakes](/guides/common-mistakes) for details on each rule.
</Tab>
<Tab title="Build">
@@ -163,20 +197,25 @@ npx hyperframes <command>
```bash
# Local mode (fast iteration)
npx hyperframes render -o output.mp4
npx hyperframes render --output output.mp4
# Docker mode (deterministic output)
npx hyperframes render --docker -o output.mp4
npx hyperframes render --docker --output output.mp4
# With options
npx hyperframes render -o output.mp4 --fps 60 --quality high
```
```
Rendering index.html...
[========================================] 100% (900/900 frames)
Output: output.mp4 (30s, 1920x1080, 30fps)
npx hyperframes render --output output.mp4 --fps 60 --quality high
```
| Flag | Values | Default | Description |
|------|--------|---------|-------------|
| `--output` | path | `renders/<name>.mp4` | Output file path |
| `--fps` | 24, 30, 60 | 30 | Frames per second |
| `--quality` | draft, standard, high | standard | Encoding quality preset |
| `--workers` | 1-8 | 4 | Parallel render workers |
| `--gpu` | — | off | GPU encoding (NVENC, VideoToolbox, VAAPI) |
| `--docker` | — | off | Use Docker for [deterministic rendering](/concepts/determinism) |
| `--quiet` | — | off | Suppress verbose output |
See [Rendering](/guides/rendering) for all options and modes.
### `benchmark`
@@ -184,18 +223,15 @@ npx hyperframes <command>
Find optimal render settings for your system:
```bash
npx hyperframes benchmark
npx hyperframes benchmark [dir]
```
```
Running benchmark suite...
Quality: draft FPS: 30 Time: 4.2s Speed: 7.1x realtime
Quality: standard FPS: 30 Time: 8.7s Speed: 3.4x realtime
Quality: high FPS: 30 Time: 15.1s Speed: 2.0x realtime
Quality: standard FPS: 60 Time: 16.3s Speed: 1.8x realtime
| Flag | Values | Default | Description |
|------|--------|---------|-------------|
| `--runs` | 1-20 | 3 | Number of runs per configuration |
| `--json` | — | off | Output results as JSON |
Recommended: quality=standard fps=30 (best speed/quality balance)
```
Runs multiple render configurations (varying fps, quality, and worker count) and compares timing and file size for each.
</Tab>
<Tab title="Utilities">
### `doctor`
@@ -207,44 +243,110 @@ npx hyperframes <command>
```
```
Checking environment...
Node.js v20.11.0 OK
FFmpeg 6.1.1 OK
Docker 24.0.7 OK
Chrome 120.0.6099 OK (bundled)
Node.js v22.x
FFmpeg 7.x
✓ FFprobe 7.x
Chrome (bundled)
✓ Docker 24.x
✓ Docker running
All checks passed.
```
Verifies Node.js version, FFmpeg, Docker, Chrome, and other requirements.
Verifies Node.js version, FFmpeg, FFprobe, Chrome, and Docker availability.
### `info`
Display system and project information:
Display project metadata:
```bash
npx hyperframes info
```
```
Hyperframes v0.1.0
Node.js v20.11.0
Platform linux x64
FFmpeg 6.1.1
Project ./my-video (2 compositions)
npx hyperframes info [dir]
```
| Flag | Description |
|------|-------------|
| `--json` | Output as JSON |
Shows project name, resolution, duration, element counts by type, track count, and total project size.
### `upgrade`
Update Hyperframes to the latest version:
Check for updates and show upgrade instructions:
```bash
npx hyperframes upgrade
npx hyperframes upgrade --check # check and exit (no prompt)
npx hyperframes upgrade --yes # show upgrade commands without prompting
```
| Flag | Description |
|------|-------------|
| `--check` | Check for updates and exit (no prompt, agent-friendly) |
| `--yes, -y` | Show upgrade commands without prompting |
Compares your installed version against the latest on npm and provides upgrade commands.
### `browser`
Manage the Chrome browser used for rendering:
```bash
# Find or download Chrome for rendering
npx hyperframes browser ensure
# Print the browser executable path (for scripting)
npx hyperframes browser path
# Remove cached Chrome download
npx hyperframes browser clear
```
Current: 0.1.0
Latest: 0.2.0
Upgrading...
Done! Run `npx hyperframes doctor` to verify.
The `path` subcommand outputs only the path, useful in scripts: `$(npx hyperframes browser path)`.
### `docs`
View inline documentation in the terminal:
```bash
npx hyperframes docs [topic]
```
Available topics: `data-attributes`, `templates`, `rendering`, `gsap`, `troubleshooting`, `compositions`. Run without a topic to see the full list.
### `telemetry`
Manage anonymous usage telemetry:
```bash
npx hyperframes telemetry enable
npx hyperframes telemetry disable
npx hyperframes telemetry status
```
Telemetry collects command names, render performance, template choices, and system info. It does **not** collect file paths, project names, video content, or personally identifiable information. Disable with `HYPERFRAMES_NO_TELEMETRY=1` or the command above.
### `skills`
Install HyperFrames and GSAP skills for AI coding tools:
```bash
# Install to all default targets (Claude Code, Gemini CLI, Codex CLI)
npx hyperframes skills
# Install to specific tools
npx hyperframes skills --claude
npx hyperframes skills --cursor
npx hyperframes skills --claude --gemini
```
| Flag | Description |
|------|-------------|
| `--claude` | Install to Claude Code (`~/.claude/skills/`) |
| `--gemini` | Install to Gemini CLI (`~/.gemini/skills/`) |
| `--codex` | Install to Codex CLI (`~/.codex/skills/`) |
| `--cursor` | Install to Cursor (`.cursor/skills/` in current project) |
Skills are fetched from GitHub and include composition authoring, GSAP animation patterns, and other domain-specific knowledge. The `init` command also offers to install skills automatically after scaffolding a project.
</Tab>
</Tabs>
+337 -72
View File
@@ -27,35 +27,224 @@ npm install @hyperframes/core
- Render compositions to MP4 — use the [CLI](/packages/cli) (`npx hyperframes render`) or [producer](/packages/producer)
- Capture frames from a headless browser — use the [engine](/packages/engine)
## What's Inside
## Package Exports
| Module | Description |
The core package has four entry points:
| Import | Description |
|--------|-------------|
| `core.types` | TypeScript types for compositions, clips, timelines, and render config |
| `parsers/` | HTML-to-composition parsing — turns an HTML string into a typed `Composition` object |
| `generators/` | Composition-to-HTML generation — turns a `Composition` object back into HTML |
| `runtime/` | The Hyperframes runtime that manages playback, seeking, and clip lifecycle |
| `lint/` | Composition linter with rules for structural correctness |
| `adapters/` | Frame Adapter types and the built-in GSAP adapter |
| `templates/` | HTML composition templates used by `hyperframes init` |
| `@hyperframes/core` | Types, parsers, generators, templates, adapters, runtime utilities |
| `@hyperframes/core/lint` | Composition linter |
| `@hyperframes/core/compiler` | Timing compiler, HTML compiler, bundler, static guard |
| `@hyperframes/core/runtime` | Pre-built IIFE runtime for browser injection |
## Types
The core type system models compositions, timeline elements, and variables:
```typescript
import type {
TimelineElement,
TimelineMediaElement,
TimelineTextElement,
TimelineCompositionElement,
TimelineElementType, // "video" | "image" | "text" | "audio" | "composition"
CompositionSpec,
CompositionVariable,
CanvasResolution, // "landscape" | "portrait"
Orientation, // "16:9" | "9:16"
FrameAdapter,
FrameAdapterContext,
} from '@hyperframes/core';
// Type guards
import {
isTextElement,
isMediaElement,
isCompositionElement,
isStringVariable,
isNumberVariable,
isColorVariable,
isBooleanVariable,
isEnumVariable,
} from '@hyperframes/core';
// Constants
import {
CANVAS_DIMENSIONS, // { landscape: { width, height }, portrait: { width, height } }
TIMELINE_COLORS,
DEFAULT_DURATIONS,
} from '@hyperframes/core';
```
### Variable Types
Compositions can expose typed variables for dynamic content:
```typescript
import type {
CompositionVariableType, // "string" | "number" | "color" | "boolean" | "enum"
StringVariable,
NumberVariable,
ColorVariable,
BooleanVariable,
EnumVariable,
} from '@hyperframes/core';
```
### Keyframe Types
```typescript
import type {
Keyframe,
KeyframeProperties,
ElementKeyframes,
StageZoom,
StageZoomKeyframe,
} from '@hyperframes/core';
import { getDefaultStageZoom } from '@hyperframes/core';
```
## Parsing and Generating HTML
Round-trip between HTML and structured data:
```typescript
import { parseHtml, generateHyperframesHtml } from '@hyperframes/core';
import type { ParsedHtml, CompositionMetadata } from '@hyperframes/core';
// Parse HTML into structured data
const parsed: ParsedHtml = parseHtml(htmlString);
// parsed.elements, parsed.gsapScript, parsed.styles, parsed.resolution, parsed.keyframes
// Extract composition metadata
import { extractCompositionMetadata } from '@hyperframes/core';
const meta: CompositionMetadata = extractCompositionMetadata(htmlString);
// meta.id, meta.duration, meta.width, meta.height, meta.variables
// Generate HTML from structured data
const html = generateHyperframesHtml(elements, {
animations,
styles,
resolution: 'landscape',
compositionId: 'my-video',
});
```
### Modifying HTML
```typescript
import {
updateElementInHtml,
addElementToHtml,
removeElementFromHtml,
validateCompositionHtml,
} from '@hyperframes/core';
// Update an element's properties
const updatedHtml = updateElementInHtml(html, 'el-1', { start: 5 });
// Add a new element
const newHtml = addElementToHtml(html, newElement);
// Remove an element
const cleanHtml = removeElementFromHtml(html, 'el-1');
// Validate HTML structure
const result = validateCompositionHtml(html);
// result.valid, result.errors
```
### GSAP Script Parsing
```typescript
import {
parseGsapScript,
serializeGsapAnimations,
updateAnimationInScript,
addAnimationToScript,
removeAnimationFromScript,
getAnimationsForElement,
validateCompositionGsap,
keyframesToGsapAnimations,
gsapAnimationsToKeyframes,
SUPPORTED_PROPS, // animatable properties
SUPPORTED_EASES, // available easing functions
} from '@hyperframes/core';
import type { GsapAnimation, GsapMethod, ParsedGsap } from '@hyperframes/core';
// Parse GSAP script into structured animations
const parsed: ParsedGsap = parseGsapScript(scriptContent);
// parsed.animations, parsed.timelineVar, parsed.preamble, parsed.postamble
// Serialize back to script
const script = serializeGsapAnimations(parsed.animations);
```
### HTML Generation
```typescript
import {
generateHyperframesHtml,
generateGsapTimelineScript,
generateHyperframesStyles,
} from '@hyperframes/core';
// Generate a complete HTML composition
const html = generateHyperframesHtml(elements, options);
// Generate just the GSAP script
const script = generateGsapTimelineScript(animations, options);
// Generate CSS styles
const { coreCss, customCss, googleFontsLink } = generateHyperframesStyles(
elements, 'landscape', customStyles
);
```
### Template Utilities
```typescript
import {
generateBaseHtml,
getStageStyles,
GSAP_CDN,
BASE_STYLES,
ELEMENT_BASE_STYLES,
MEDIA_STYLES,
TEXT_STYLES,
ZOOM_CONTAINER_STYLES,
} from '@hyperframes/core';
// Generate base HTML structure for a resolution
const baseHtml = generateBaseHtml('landscape');
const styles = getStageStyles('portrait');
```
## Linter
The composition linter checks for structural issues that would cause rendering failures or unexpected behavior. You can run it from the CLI with `npx hyperframes lint`, or call it programmatically:
```typescript
import { lintHyperframeHtml } from '@hyperframes/core';
import { lintHyperframeHtml, lintMediaUrls } from '@hyperframes/core/lint';
import type {
HyperframeLintResult,
HyperframeLintFinding,
HyperframeLintSeverity, // "error" | "warning"
HyperframeLinterOptions,
} from '@hyperframes/core/lint';
const html = `
<div id="root" data-composition-id="root"
data-start="0" data-width="1920" data-height="1080">
<video id="clip-1" data-start="0" data-track-index="0"
src="intro.mp4"></video>
</div>
`;
const result: HyperframeLintResult = lintHyperframeHtml(html, { filePath: 'index.html' });
// result.ok, result.errorCount, result.warningCount, result.findings
const issues = lintHyperframeHtml(html);
// => [{ rule: "unmuted-video", message: "Video element 'clip-1' should have the 'muted' attribute ...", severity: "warning" }]
for (const finding of result.findings) {
console.log(finding.severity, finding.code, finding.message);
// finding.file, finding.selector, finding.elementId, finding.fixHint, finding.snippet
}
// Additional media URL validation
const mediaFindings = lintMediaUrls(result.findings);
```
Detected issues include:
@@ -71,77 +260,153 @@ Detected issues include:
For a full list of what the linter catches and how to fix each issue, see [Common Mistakes](/guides/common-mistakes) and [Troubleshooting](/guides/troubleshooting).
</Info>
## Types
## Compiler
Import the core types for use in your own tooling or integrations:
The compiler sub-package handles timing resolution, HTML compilation, and bundling:
```typescript
// Timing compiler (browser-safe — no Node.js dependencies)
import {
compileTimingAttrs,
injectDurations,
extractResolvedMedia,
clampDurations,
} from '@hyperframes/core/compiler';
import type {
Composition,
Clip,
RenderConfig,
FrameAdapterContext,
UnresolvedElement,
ResolvedDuration,
ResolvedMediaElement,
CompilationResult,
} from '@hyperframes/core/compiler';
// Compile timing attributes from HTML
const compiled: CompilationResult = compileTimingAttrs(html);
// Inject resolved durations back into HTML
const updatedHtml = injectDurations(html, compiled.durations);
// Extract resolved media elements
const media: ResolvedMediaElement[] = extractResolvedMedia(html);
```
```typescript
// HTML compiler (Node.js — requires media probing)
import { compileHtml } from '@hyperframes/core/compiler';
import type { MediaDurationProber } from '@hyperframes/core/compiler';
const prober: MediaDurationProber = async (src) => getDuration(src);
const compiledHtml = await compileHtml(html, prober);
```
```typescript
// HTML bundler (Node.js — bundles to single file)
import { bundleToSingleHtml } from '@hyperframes/core/compiler';
import type { BundleOptions } from '@hyperframes/core/compiler';
const bundled = await bundleToSingleHtml({ entryPath: './index.html', inline: true });
```
```typescript
// Static guard — validate HTML contract
import { validateHyperframeHtmlContract } from '@hyperframes/core/compiler';
import type {
HyperframeStaticGuardResult,
HyperframeStaticFailureReason,
} from '@hyperframes/core/compiler';
const guard: HyperframeStaticGuardResult = validateHyperframeHtmlContract(html);
// guard.ok, guard.failures[]
// Failure reasons: "missing_composition_id" | "missing_composition_dimensions"
// | "missing_timeline_registry" | "invalid_script_syntax"
// | "invalid_static_hyperframe_contract"
```
## Runtime
The Hyperframes runtime manages playback, seeking, and clip lifecycle in the browser. The core package provides utilities for building and loading the runtime:
```typescript
import {
loadHyperframeRuntimeSource,
buildHyperframesRuntimeScript,
HYPERFRAME_RUNTIME_ARTIFACTS,
HYPERFRAME_RUNTIME_CONTRACT,
HYPERFRAME_RUNTIME_GLOBALS,
HYPERFRAME_BRIDGE_SOURCES,
HYPERFRAME_CONTROL_ACTIONS,
} from '@hyperframes/core';
import type {
HyperframeControlAction,
HyperframesRuntimeBuildOptions,
} from '@hyperframes/core';
// Example: define a render configuration
const config: RenderConfig = {
fps: 30,
width: 1920,
height: 1080,
quality: 'standard',
};
// Load the pre-built runtime IIFE
const runtimeSource = loadHyperframeRuntimeSource();
// Example: work with a parsed composition
function getClipCount(composition: Composition): number {
return composition.clips.length;
}
// Build a custom runtime script
const script = buildHyperframesRuntimeScript(options);
```
## Parsing and Generating HTML
Round-trip between HTML and structured data:
The pre-built runtime IIFE is available as a direct import:
```typescript
import { parseHyperframeHtml, generateHyperframeHtml } from '@hyperframes/core';
// Parse HTML into a Composition object
const composition = parseHyperframeHtml(htmlString);
console.log(composition.id); // "root"
console.log(composition.width); // 1920
console.log(composition.clips); // [{ id: "clip-1", start: 0, ... }, ...]
// Generate HTML from a Composition object
const html = generateHyperframeHtml(composition);
import runtime from '@hyperframes/core/runtime';
```
This is especially useful for AI agents that generate video programmatically — they can construct a `Composition` object in code and then serialize it to HTML for rendering.
## Runtime Builds
The runtime is the JavaScript that runs inside the browser (or headless Chrome) to manage clip lifecycle, media playback, and timeline synchronization. It is built in two formats:
- **`hyperframe.runtime.iife.js`** — injected into browser iframes for preview playback
- **`hyperframe.runtime.mjs`** — for Node.js tooling and tests
Build the runtime from source:
```bash
bun run --filter @hyperframes/core build:hyperframes-runtime
```
<Warning>
You should not need to build the runtime yourself unless you are developing the Hyperframes framework itself. The CLI and producer packages bundle the runtime automatically.
</Warning>
## Frame Adapters
The core package defines the [Frame Adapter](/concepts/frame-adapters) interface — the abstraction that lets Hyperframes work with any animation runtime. The built-in GSAP adapter lives here:
The core package defines the [Frame Adapter](/concepts/frame-adapters) interface and provides the built-in GSAP adapter:
```typescript
import type { FrameAdapterContext } from '@hyperframes/core';
import { createGSAPFrameAdapter } from '@hyperframes/core';
import type {
FrameAdapter,
FrameAdapterContext,
GSAPTimelineLike,
CreateGSAPFrameAdapterOptions,
} from '@hyperframes/core';
// Every adapter must answer: "what should the screen look like at this time?"
// See the Frame Adapters concept page for the full API.
// Create a GSAP frame adapter
const adapter: FrameAdapter = createGSAPFrameAdapter({
id: 'my-composition',
fps: 30,
timeline: gsapTimeline,
});
// Adapter lifecycle
await adapter.init?.(context);
const durationFrames = adapter.getDurationFrames();
await adapter.seekFrame(42);
await adapter.destroy?.();
```
## Media Utilities
```typescript
import {
MEDIA_VISUAL_STYLE_PROPERTIES,
copyMediaVisualStyles,
quantizeTimeToFrame,
} from '@hyperframes/core';
import type { MediaVisualStyleProperty } from '@hyperframes/core';
// Quantize a time value to the nearest frame boundary
const frameTime = quantizeTimeToFrame(5.033, 30); // → 5.033... snapped to frame
// Copy visual styles between media elements
copyMediaVisualStyles(fromElement, toElement);
```
## Picker API
For element selection in editor UIs:
```typescript
import type {
HyperframePickerApi,
HyperframePickerBoundingBox,
HyperframePickerElementInfo,
} from '@hyperframes/core';
```
## Related Packages
+196 -19
View File
@@ -53,14 +53,16 @@ This approach guarantees [deterministic rendering](/concepts/determinism): the s
## Configuration
```typescript
import { resolveConfig, DEFAULT_CONFIG } from '@hyperframes/engine';
import type { EngineConfig } from '@hyperframes/engine';
const config: EngineConfig = {
fps: 30, // Frames per second: 24, 30, or 60
width: 1920, // Output width in pixels
height: 1080, // Output height in pixels
quality: 'standard', // Encoding preset: 'draft', 'standard', or 'high'
};
// Use defaults
const config = DEFAULT_CONFIG;
// Or resolve with overrides
const config = resolveConfig({
// ... custom options
});
```
### Quality Presets
@@ -81,28 +83,203 @@ const config: EngineConfig = {
## Programmatic Usage
```typescript
import { createEngine } from '@hyperframes/engine';
The engine uses a session-based API for frame capture:
const engine = createEngine({
```typescript
import {
createCaptureSession,
initializeSession,
captureFrame,
captureFrameToBuffer,
getCompositionDuration,
closeCaptureSession,
} from '@hyperframes/engine';
// 1. Create a capture session
const session = await createCaptureSession({ fps: 30, width: 1920, height: 1080 });
// 2. Initialize with a composition
await initializeSession(session, './my-video/index.html');
// 3. Get the total duration
const duration = getCompositionDuration(session);
// 4. Capture frames
const totalFrames = Math.ceil(duration * 30);
for (let i = 0; i < totalFrames; i++) {
// Capture to disk
const result = await captureFrame(session, i);
// result.path, result.captureTimeMs
// Or capture to buffer (in-memory)
const bufResult = await captureFrameToBuffer(session, i);
// bufResult.buffer, bufResult.captureTimeMs
}
// 5. Clean up
await closeCaptureSession(session);
```
### Browser Management
```typescript
import {
acquireBrowser,
releaseBrowser,
resolveHeadlessShellPath,
buildChromeArgs,
} from '@hyperframes/engine';
// Acquire a browser instance (creates or reuses from pool)
const browser = await acquireBrowser();
// Get the Chrome binary path
const chromePath = await resolveHeadlessShellPath();
// Release when done
await releaseBrowser(browser);
```
### Encoding
The engine includes FFmpeg encoding utilities:
```typescript
import {
encodeFramesFromDir,
muxVideoWithAudio,
applyFaststart,
detectGpuEncoder,
ENCODER_PRESETS,
} from '@hyperframes/engine';
// Detect GPU encoding support
const gpu = await detectGpuEncoder();
// gpu: "nvenc" | "videotoolbox" | "vaapi" | null
// Encode captured frames to video
await encodeFramesFromDir({ framesDir, outputPath, fps: 30, quality: 'standard' });
// Mix video with audio tracks
await muxVideoWithAudio({ videoPath, audioTracks, outputPath });
// Apply MP4 faststart for streaming
await applyFaststart(outputPath);
```
### Streaming Encoder
For memory-efficient encoding without writing frames to disk:
```typescript
import { spawnStreamingEncoder } from '@hyperframes/engine';
const encoder = await spawnStreamingEncoder({
outputPath: './output.mp4',
fps: 30,
width: 1920,
height: 1080,
});
// Capture all frames from a composition
const frames = await engine.capture('./my-video/index.html');
// Feed frames directly to encoder
encoder.writeFrame(frameBuffer);
// ...
const result = await encoder.finalize();
```
// Each frame is a pixel buffer (PNG/raw)
for (const frame of frames) {
// Process frames however you need:
// - pipe to FFmpeg
// - save as individual PNGs
// - generate a thumbnail
// - feed into a custom encoder
### Video Frame Extraction
Extract frames from source video files for injection into the browser:
```typescript
import {
parseVideoElements,
extractAllVideoFrames,
getFrameAtTime,
createFrameLookupTable,
FrameLookupTable,
} from '@hyperframes/engine';
// Parse video elements from HTML
const videos = parseVideoElements(html);
// Extract all frames from a video
const frames = await extractAllVideoFrames(videoPath, { fps: 30 });
// Create a lookup table for fast frame access
const lookup = createFrameLookupTable(frames);
const frame = lookup.getFrameAtTime(5.0);
```
### Audio Processing
```typescript
import { parseAudioElements, processCompositionAudio } from '@hyperframes/engine';
// Parse audio elements from HTML
const audioElements = parseAudioElements(html);
// Process and mix all audio tracks
const mixResult = await processCompositionAudio({ audioElements, duration, fps });
```
### Parallel Rendering
```typescript
import {
calculateOptimalWorkers,
distributeFrames,
executeParallelCapture,
getSystemResources,
} from '@hyperframes/engine';
// Check system resources
const resources = getSystemResources();
// Calculate optimal worker count
const workers = calculateOptimalWorkers(totalFrames);
// Distribute frames across workers
const tasks = distributeFrames(totalFrames, workers);
// Execute parallel capture
const results = await executeParallelCapture(tasks);
```
### File Server
Serve composition files over HTTP for the browser to load:
```typescript
import { createFileServer } from '@hyperframes/engine';
const server = await createFileServer({ root: './my-video', port: 0 });
// server.url, server.port
// ... use server.url as the composition URL
await server.close();
```
## The `window.__hf` Protocol
The engine communicates with the browser page via the `window.__hf` protocol. Any page that implements this protocol can be captured by the engine — you are not limited to Hyperframes compositions.
```typescript
// The page must expose this on window.__hf
interface HfProtocol {
duration: number; // Total duration in seconds
seek(time: number): void; // Seek to a specific time
media?: HfMediaElement[]; // Optional media element declarations
}
await engine.close();
interface HfMediaElement {
elementId: string; // DOM element ID
src: string; // Media source URL
startTime: number; // Start time on timeline
endTime: number; // End time on timeline
mediaOffset?: number; // Playback offset in source
volume?: number; // Volume (0-1)
hasAudio?: boolean; // Whether element has audio
}
```
## Key Concepts
+96 -20
View File
@@ -54,33 +54,92 @@ The producer orchestrates the full render pipeline:
## Programmatic Usage
```typescript
import { render } from '@hyperframes/producer';
The producer uses a two-step API: create a render job configuration, then execute it.
const result = await render({
```typescript
import { createRenderJob, executeRenderJob } from '@hyperframes/producer';
const job = createRenderJob({
input: './my-video/index.html',
output: './output.mp4',
fps: 30,
quality: 'standard',
});
console.log(result.duration); // Total render time in ms
console.log(result.frameCount); // Number of frames captured
console.log(result.outputPath); // Absolute path to the output file
const result = await executeRenderJob(job);
```
### With All Options
### Render Configuration
```typescript
await render({
input: './my-video/index.html',
output: './output.mp4',
fps: 30,
width: 1920,
height: 1080,
quality: 'high',
docker: true, // Use Docker for deterministic rendering
});
import type { RenderConfig } from '@hyperframes/producer';
const config: RenderConfig = {
fps: 30, // 24, 30, or 60
quality: 'standard', // 'draft', 'standard', or 'high'
workers: 4, // Parallel render workers (1-8)
useGpu: false, // GPU-accelerated encoding
debug: false, // Debug logging
};
```
### Progress Callbacks
```typescript
import type { ProgressCallback, RenderStatus } from '@hyperframes/producer';
const onProgress: ProgressCallback = (status: RenderStatus) => {
console.log(`Status: ${status}`);
// Statuses: "queued" | "preprocessing" | "rendering" | "encoding"
// | "assembling" | "complete" | "failed" | "cancelled"
};
```
### Cancellation
```typescript
import { RenderCancelledError } from '@hyperframes/producer';
try {
await executeRenderJob(job);
} catch (err) {
if (err instanceof RenderCancelledError) {
console.log(`Cancelled: ${err.reason}`);
// reason: "user_cancelled" | "timeout" | "aborted"
}
}
```
## HTTP Server
The producer includes a built-in HTTP server for running as a rendering service:
```typescript
import { startServer } from '@hyperframes/producer/server';
await startServer({ port: 8080 });
```
### Server Endpoints
| Method | Path | Description |
|--------|------|-------------|
| `POST` | `/render` | Blocking render — returns JSON result |
| `POST` | `/render/stream` | Streaming render with Server-Sent Events |
| `POST` | `/lint` | Lint a composition for issues |
| `GET` | `/health` | Health check |
| `GET` | `/outputs/:token` | Download a rendered MP4 |
For custom server integration, use the lower-level handlers:
```typescript
import { createRenderHandlers, createProducerApp } from '@hyperframes/producer/server';
// Get individual request handlers
const handlers = createRenderHandlers(options);
// Or get a full Hono app
const app = createProducerApp(options);
```
## Docker Rendering
@@ -89,10 +148,7 @@ For deterministic output, the producer can render inside a Docker container with
```bash
# Via the CLI (recommended)
npx hyperframes render --docker -o output.mp4
# Via the producer API
await render({ input: './index.html', output: './out.mp4', docker: true });
npx hyperframes render --docker --output output.mp4
```
<Info>
@@ -123,6 +179,26 @@ GPU encoding is automatically used when available. To check your system's capabi
npx hyperframes doctor
```
## Additional Exports
The producer also re-exports key engine functionality for convenience:
| Export | Description |
|--------|-------------|
| `createCaptureSession()` | Create a frame capture session |
| `initializeSession()` | Initialize session with a composition |
| `captureFrame()` / `captureFrameToBuffer()` | Capture individual frames |
| `closeCaptureSession()` | Clean up a capture session |
| `getCompositionDuration()` | Get total composition duration |
| `getCapturePerfSummary()` | Get capture performance metrics |
| `createFileServer()` | Create an HTTP file server for serving assets |
| `createVideoFrameInjector()` | Create a video frame injector for page |
| `resolveConfig()` / `DEFAULT_CONFIG` | Producer configuration |
| `createConsoleLogger()` / `defaultLogger` | Logging utilities |
| `quantizeTimeToFrame()` | Convert time to frame boundary |
| `resolveRenderPaths()` | Resolve render directory paths |
| `prepareHyperframeLintBody()` / `runHyperframeLint()` | Linting utilities |
## Regression Testing
The producer includes a regression harness for comparing render output against golden baselines. This is useful for catching visual regressions when changing the runtime, engine, or rendering pipeline.
+139 -18
View File
@@ -45,7 +45,137 @@ bun run dev
bun run --filter @hyperframes/studio dev
```
The studio starts at `http://localhost:3000` by default.
## Package Exports
The studio has two entry points:
| Import | Description |
|--------|-------------|
| `@hyperframes/studio` | React components, hooks, and types |
| `@hyperframes/studio/tailwind-preset` | Tailwind CSS preset for studio styling |
Peer dependencies: `react` (18 or 19), `react-dom` (18 or 19), `zustand` (4 or 5).
## Components
### Layout
```typescript
import { NLELayout, NLEPreview, CompositionBreadcrumb } from '@hyperframes/studio';
import type { CompositionLevel } from '@hyperframes/studio';
// Main NLE (Non-Linear Editor) layout container
<NLELayout>
{/* Preview, timeline, and editor panels */}
</NLELayout>
// Preview panel
<NLEPreview />
// Breadcrumb navigation for nested compositions
<CompositionBreadcrumb levels={levels} />
```
### Player & Timeline
```typescript
import {
Player,
PlayerControls,
Timeline,
PreviewPanel,
AgentActivityTrack,
} from '@hyperframes/studio';
import type { AgentActivity, TimelineElement, ActiveEdits } from '@hyperframes/studio';
// Embed the preview player
<Player />
// Playback controls (play, pause, seek, frame-step)
<PlayerControls />
// Timeline editor with scrubber
<Timeline />
// Preview display area
<PreviewPanel />
// Activity visualization track (for agent workflows)
<AgentActivityTrack activities={activities} />
```
### Editor Components
```typescript
import { SourceEditor, PropertyPanel, FileTree } from '@hyperframes/studio';
// Code editor (CodeMirror-based) for HTML, CSS, and JavaScript
<SourceEditor />
// Property inspector for selected elements
<PropertyPanel />
// Project file browser
<FileTree />
```
### Full Application
```typescript
import { StudioApp } from '@hyperframes/studio';
// The complete studio application (wraps all components)
<StudioApp />
```
## Hooks
### `useTimelinePlayer`
Manages player state and playback control:
```typescript
import { useTimelinePlayer } from '@hyperframes/studio';
const player = useTimelinePlayer();
// player.play(), player.pause(), player.seek(time), player.stepForward(), player.stepBackward()
```
### `usePlayerStore`
Zustand store for player state:
```typescript
import { usePlayerStore, liveTime, formatTime } from '@hyperframes/studio';
const store = usePlayerStore();
// Access current time, duration, playing state, etc.
// Format time for display
const display = formatTime(liveTime.current);
```
### `useCodeEditor`
Code editor state and editing functions:
```typescript
import { useCodeEditor } from '@hyperframes/studio';
const editor = useCodeEditor();
// editor.code, editor.setCode(), editor.diff, editor.onChange()
```
### `useElementPicker`
Element selection from the preview:
```typescript
import { useElementPicker } from '@hyperframes/studio';
const picker = useElementPicker();
// picker.selectedElement, picker.selectElement(id), picker.clearSelection()
```
## Features
@@ -91,29 +221,20 @@ The studio is a React application with the following structure:
4. **File watcher** — a development server (Vite-based) watches your project files and triggers hot module replacement when changes are detected.
## Embedding in Your Own Application
## Tailwind CSS Preset
If you are building a product that includes a composition editor, you can use the studio's components directly:
The studio exports a Tailwind CSS preset for consistent styling:
```typescript
import { Player, Timeline } from '@hyperframes/studio';
// tailwind.config.ts
import studioPreset from '@hyperframes/studio/tailwind-preset';
// Embed the preview player
<Player
src="./my-composition/index.html"
width={1920}
height={1080}
autoPlay={false}
/>
// Embed the timeline view
<Timeline compositionHtml={htmlString} />
export default {
presets: [studioPreset],
// ... your config
};
```
<Info>
The studio depends on `@hyperframes/core` for parsing and runtime injection. You do not need to install core separately — it is included as a dependency.
</Info>
## Related Packages
<CardGroup cols={2}>
+27 -22
View File
@@ -12,15 +12,15 @@ A 1920x1080 video with an animated title that fades in from above — rendered t
## Prerequisites
<Steps>
<Step title="Install Node.js 20+">
Hyperframes requires Node.js 20 or later. Check your version:
<Step title="Install Node.js 22+">
Hyperframes requires Node.js 22 or later. Check your version:
```bash
node --version
```
```bash Expected output
v20.11.0 # or any version >= 20
v22.0.0 # or any version >= 22
```
</Step>
@@ -58,36 +58,46 @@ A 1920x1080 video with an animated title that fades in from above — rendered t
<Steps>
<Step title="Scaffold the project">
```bash
npx create-hyperframe my-video
npx hyperframes init my-video --template blank
cd my-video
```
```bash Expected output
✔ Created my-video/
✔ index.html
✔ assets/
Done. Run `npx hyperframes dev` to preview.
The CLI is non-interactive by default — pass `--template` to select a template. For interactive mode with prompts and menus, add `--human-friendly`:
```bash
npx hyperframes init --human-friendly
```
This generates the following project structure:
See [Templates](/guides/templates) for all available templates.
This generates a project structure like:
<Tree>
<Tree.Folder name="my-video" defaultOpen>
<Tree.File name="meta.json" />
<Tree.File name="index.html" />
<Tree.Folder name="compositions" defaultOpen>
<Tree.File name=".gitkeep" />
<Tree.File name="intro.html" />
<Tree.File name="captions.html" />
</Tree.Folder>
<Tree.Folder name="assets" defaultOpen>
<Tree.File name=".gitkeep" />
<Tree.File name="video.mp4" />
</Tree.Folder>
</Tree.Folder>
</Tree>
| Path | Purpose |
|------|---------|
| `meta.json` | Project metadata (name, ID, creation date) |
| `index.html` | Root composition — your video's entry point |
| `compositions/` | Sub-compositions loaded via `data-composition-src` |
| `assets/` | Media files (video, audio, images) |
If you have a source video, pass it with `--video` for automatic transcription and captions:
```bash
npx hyperframes init my-video --template warm-grain --video ./intro.mp4
```
</Step>
<Step title="Preview in the browser">
@@ -95,12 +105,7 @@ A 1920x1080 video with an animated title that fades in from above — rendered t
npx hyperframes dev
```
```bash Expected output
✔ Hyperframes dev server running
→ http://localhost:3000
```
Open [http://localhost:3000](http://localhost:3000) to see the live preview. Edits to `index.html` reload automatically.
This starts the Hyperframes Studio and opens your composition in the browser. Edits to `index.html` reload automatically.
<Tip>
The dev server supports hot reload — save your HTML file and the preview updates instantly, no manual refresh needed.
@@ -145,7 +150,7 @@ A 1920x1080 video with an animated title that fades in from above — rendered t
<Step title="Render to MP4">
```bash
npx hyperframes render -o output.mp4
npx hyperframes render --output output.mp4
```
```bash Expected output
@@ -162,8 +167,8 @@ A 1920x1080 video with an animated title that fades in from above — rendered t
| Dependency | Required | Notes |
|-----------|----------|-------|
| **Node.js** 20+ | Yes | Runtime for CLI and dev server |
| **bun** or npm | Yes | Package manager (bun recommended) |
| **Node.js** 22+ | Yes | Runtime for CLI and dev server |
| **npm** or bun | Yes | Package manager |
| **FFmpeg** | Yes | Video encoding for local renders |
| **Docker** | No | Optional — for deterministic, reproducible renders |
@@ -177,7 +182,7 @@ A 1920x1080 video with an animated title that fades in from above — rendered t
Add fade, slide, scale, and custom animations to your videos
</Card>
<Card title="Templates" icon="grid-2" href="/guides/templates">
Start from built-in templates like title-card and video-edit
Start from built-in templates like Warm Grain and Swiss Grid
</Card>
<Card title="Rendering" icon="film" href="/guides/rendering">
Explore render options: quality presets, Docker mode, and GPU encoding