mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-01 19:42:03 +00:00
feat(skills): add hyperframes-cli skill (#154)
* feat(skills): add hyperframes-cli skill for CLI workflow guidance Adds a new skill that teaches AI agents how to use the HyperFrames CLI (init, lint, dev, render, doctor). Previously, agents had no way to discover the CLI — the compose-video skill only covered HTML authoring. This led to agents searching for binaries, finding the monorepo, and running bun run studio manually instead of using npx hyperframes dev. Also registers the skill in init.ts so new projects get it bundled alongside hyperframes-compose and hyperframes-captions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor(cli): rename dev command to preview The command starts a preview server — "preview" describes what users are doing more accurately than "dev". Updates the command name, file name, all CLI references, docs, skills, and template CLAUDE.md. 22 files updated across CLI source, docs, skills, and templates. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(skills): replace stale dev reference with preview in CLI skill Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(docs): catch remaining dev references missed in rename - testing-local-changes.mdx: two inline command examples - troubleshooting.mdx: anchor link #dev → #preview, "dev server" → "preview server" - cli.mdx: "dev server" → "preview server" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
bc956bb6da
commit
9cbfec1eca
+1
-1
@@ -90,7 +90,7 @@ window.__timelines["my-video"] = tl;
|
||||
After CLI commands, show what the user should see:
|
||||
|
||||
```bash
|
||||
npx hyperframes dev
|
||||
npx hyperframes preview
|
||||
# ✓ Server running at http://localhost:3000
|
||||
# ✓ Watching for changes...
|
||||
```
|
||||
|
||||
@@ -25,7 +25,7 @@ cd my-video
|
||||
Then open the project with your AI coding agent (Claude Code, Cursor, etc.) — it has HyperFrames skills installed and knows how to create and edit compositions.
|
||||
|
||||
```bash
|
||||
npx hyperframes dev # preview in browser (live reload)
|
||||
npx hyperframes preview # preview in browser (live reload)
|
||||
npx hyperframes render # render to MP4
|
||||
```
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Testing Local CLI Changes
|
||||
description: How to test unreleased CLI changes outside the monorepo using your local build.
|
||||
---
|
||||
|
||||
When you modify the CLI or any package it bundles (core, engine, producer, studio), you need to test those changes against real projects _outside_ the monorepo — the same way an end user would run `hyperframes dev`.
|
||||
When you modify the CLI or any package it bundles (core, engine, producer, studio), you need to test those changes against real projects _outside_ the monorepo — the same way an end user would run `hyperframes preview`.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -37,7 +37,7 @@ Now use `hyperframes` normally in any directory:
|
||||
|
||||
```bash
|
||||
cd ~/my-video-project
|
||||
hyperframes dev .
|
||||
hyperframes preview .
|
||||
```
|
||||
|
||||
**After every `pnpm build`** the linked binary is already up to date — no re-linking needed.
|
||||
@@ -58,7 +58,7 @@ If you don't want to touch your global `$PATH`, add a shell alias or call `node`
|
||||
alias hyperframes="node /path/to/hyperframes-oss/packages/cli/dist/cli.js"
|
||||
|
||||
# Or invoke directly
|
||||
node /path/to/hyperframes-oss/packages/cli/dist/cli.js dev .
|
||||
node /path/to/hyperframes-oss/packages/cli/dist/cli.js preview .
|
||||
```
|
||||
|
||||
Replace `/path/to/hyperframes-oss` with your actual monorepo path.
|
||||
@@ -76,7 +76,7 @@ npm pack
|
||||
mkdir /tmp/pack-test && cd /tmp/pack-test
|
||||
npx /path/to/hyperframes-oss/packages/cli/hyperframes-<version>.tgz init my-video
|
||||
cd my-video
|
||||
npx /path/to/hyperframes-oss/packages/cli/hyperframes-<version>.tgz dev .
|
||||
npx /path/to/hyperframes-oss/packages/cli/hyperframes-<version>.tgz preview .
|
||||
```
|
||||
|
||||
## Testing the fix branches
|
||||
@@ -86,7 +86,7 @@ When validating a specific bug fix, extract one of the test project archives and
|
||||
```bash
|
||||
# Example: testing audio-after-seek fix
|
||||
unzip golden-lyric-video.zip && cd golden-lyric-video
|
||||
hyperframes dev .
|
||||
hyperframes preview .
|
||||
# 1. Press Play — confirm audio plays
|
||||
# 2. Drag the timeline scrubber to a different position
|
||||
# 3. Press Play again — audio should resume from the seeked position
|
||||
@@ -129,8 +129,8 @@ cd packages/cli && pnpm link --global
|
||||
|
||||
**Port already in use**
|
||||
|
||||
`hyperframes dev` defaults to port 3002 and auto-increments if it's taken. Pass `--port` to use a specific port:
|
||||
`hyperframes preview` defaults to port 3002 and auto-increments if it's taken. Pass `--port` to use a specific port:
|
||||
|
||||
```bash
|
||||
hyperframes dev . --port 4000
|
||||
hyperframes preview . --port 4000
|
||||
```
|
||||
|
||||
@@ -29,7 +29,7 @@ Render your Hyperframes [compositions](/concepts/compositions) to MP4 with the [
|
||||
Before rendering, preview your composition in the browser to verify it looks correct:
|
||||
|
||||
```bash Terminal
|
||||
npx hyperframes dev
|
||||
npx hyperframes preview
|
||||
```
|
||||
</Step>
|
||||
<Step title="Render to MP4">
|
||||
|
||||
@@ -61,12 +61,12 @@ If your issue is about a specific coding mistake (animations not working, video
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Preview not updating">
|
||||
Make sure you are editing the `index.html` in the project directory. The [preview server](/packages/cli#dev) watches for file changes and auto-reloads.
|
||||
Make sure you are editing the `index.html` in the project directory. The [preview server](/packages/cli#preview) watches for file changes and auto-reloads.
|
||||
|
||||
If changes still do not appear:
|
||||
|
||||
1. Check the terminal for errors from the dev server
|
||||
2. Stop and restart `npx hyperframes dev`
|
||||
1. Check the terminal for errors from the preview server
|
||||
2. Stop and restart `npx hyperframes preview`
|
||||
3. Hard-refresh the browser: **Ctrl+Shift+R** (Windows/Linux) or **Cmd+Shift+R** (macOS)
|
||||
4. Clear the browser cache if CSS changes are not reflected
|
||||
</Accordion>
|
||||
|
||||
@@ -54,7 +54,7 @@ Run `npx hyperframes render --output demo.mp4` and this produces an MP4 with det
|
||||
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 in your browser. Edit your HTML and see changes instantly — no build step, no compilation.
|
||||
Run `npx hyperframes preview` 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 --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.
|
||||
|
||||
@@ -106,7 +106,7 @@ This is suppressed in CI environments, non-TTY shells, and when `HYPERFRAMES_NO_
|
||||
Start the development server with live hot reload:
|
||||
```bash
|
||||
cd my-video
|
||||
npx hyperframes dev
|
||||
npx hyperframes preview
|
||||
```
|
||||
The Hyperframes Studio opens in your browser. Edit `index.html` and the preview updates instantly.
|
||||
</Step>
|
||||
@@ -227,23 +227,23 @@ This is suppressed in CI environments, non-TTY shells, and when `HYPERFRAMES_NO_
|
||||
For music or noisy audio, use `--model medium.en` for better accuracy. For the best results with production content, transcribe via the OpenAI or Groq Whisper API and import the JSON.
|
||||
</Tip>
|
||||
</Tab>
|
||||
<Tab title="Develop">
|
||||
### `dev`
|
||||
<Tab title="Preview">
|
||||
### `preview`
|
||||
|
||||
Start a live preview server with hot reload:
|
||||
|
||||
```bash
|
||||
npx hyperframes dev [dir]
|
||||
npx hyperframes dev --port 4567
|
||||
npx hyperframes preview [dir]
|
||||
npx hyperframes preview --port 4567
|
||||
```
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--port` | Port to run the dev server on (default: 3002) |
|
||||
| `--port` | Port to run the preview server on (default: 3002) |
|
||||
|
||||
Opens your composition in the Hyperframes Studio with live preview. Edits to `index.html` and any referenced sub-compositions are reflected automatically. The preview uses the same Hyperframes runtime as production rendering, so what you see is what you get.
|
||||
|
||||
The dev server runs in three modes, auto-detected:
|
||||
The preview server runs in three modes, auto-detected:
|
||||
|
||||
1. **Embedded mode** (default for `npx`) — runs a standalone server with the studio bundled in the CLI. Zero extra dependencies.
|
||||
2. **Local studio mode** — if `@hyperframes/studio` is installed in your project's `node_modules`, spawns Vite with full HMR for faster iteration.
|
||||
@@ -482,7 +482,7 @@ This is suppressed in CI environments, non-TTY shells, and when `HYPERFRAMES_NO_
|
||||
The rendering pipeline the CLI calls under the hood. Use directly for programmatic rendering.
|
||||
</Card>
|
||||
<Card title="Studio" icon="palette" href="/packages/studio">
|
||||
The editor UI that powers `hyperframes dev`. Use directly to embed in your own app.
|
||||
The editor UI that powers `hyperframes preview`. Use directly to embed in your own app.
|
||||
</Card>
|
||||
<Card title="Core" icon="cube" href="/packages/core">
|
||||
Types, linter, and runtime. Use directly for custom tooling and integrations.
|
||||
|
||||
@@ -23,7 +23,7 @@ npm install @hyperframes/core
|
||||
- Embed the Hyperframes runtime in a custom player
|
||||
|
||||
**Use a different package if you want to:**
|
||||
- Preview compositions in the browser — use the [CLI](/packages/cli) (`npx hyperframes dev`) or [studio](/packages/studio)
|
||||
- Preview compositions in the browser — use the [CLI](/packages/cli) (`npx hyperframes preview`) or [studio](/packages/studio)
|
||||
- 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)
|
||||
|
||||
|
||||
@@ -17,12 +17,12 @@ npm install @hyperframes/studio
|
||||
- Extend the editor with custom panels, toolbars, or integrations
|
||||
|
||||
**Use a different package if you want to:**
|
||||
- Preview compositions during development — use the [CLI](/packages/cli) (`npx hyperframes dev`), which launches the studio for you
|
||||
- Preview compositions during development — use the [CLI](/packages/cli) (`npx hyperframes preview`), which launches the studio for you
|
||||
- Render compositions to MP4 — use the [CLI](/packages/cli) or [producer](/packages/producer)
|
||||
- Capture frames programmatically — use the [engine](/packages/engine)
|
||||
|
||||
<Tip>
|
||||
**For most development workflows, you do not need to install the studio directly.** Running `npx hyperframes dev` starts the studio automatically with hot reload. Install `@hyperframes/studio` only if you are embedding the editor into your own application.
|
||||
**For most development workflows, you do not need to install the studio directly.** Running `npx hyperframes preview` starts the studio automatically with hot reload. Install `@hyperframes/studio` only if you are embedding the editor into your own application.
|
||||
</Tip>
|
||||
|
||||
## Running the Studio
|
||||
@@ -30,7 +30,7 @@ npm install @hyperframes/studio
|
||||
### Via the CLI (recommended)
|
||||
|
||||
```bash
|
||||
npx hyperframes dev
|
||||
npx hyperframes preview
|
||||
```
|
||||
|
||||
This starts the studio development server, opens your composition in the browser, and watches for file changes. This is the easiest way to get a live preview.
|
||||
@@ -239,7 +239,7 @@ export default {
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="CLI" icon="terminal" href="/packages/cli">
|
||||
Launches the studio via `npx hyperframes dev` — the easiest way to preview compositions.
|
||||
Launches the studio via `npx hyperframes preview` — the easiest way to preview compositions.
|
||||
</Card>
|
||||
<Card title="Core" icon="cube" href="/packages/core">
|
||||
Types, parsing, and runtime that the studio uses for preview and timeline rendering.
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ A 1920x1080 video with an animated title that fades in from above — rendered t
|
||||
|
||||
<Step title="Preview in the browser">
|
||||
```bash
|
||||
npx hyperframes dev
|
||||
npx hyperframes preview
|
||||
```
|
||||
|
||||
This starts the Hyperframes Studio and opens your composition in the browser. Edits to `index.html` reload automatically.
|
||||
|
||||
@@ -27,15 +27,15 @@ npx hyperframes init my-video
|
||||
cd my-video
|
||||
```
|
||||
|
||||
### `dev`
|
||||
### `preview`
|
||||
|
||||
Start the live preview studio in your browser:
|
||||
|
||||
```bash
|
||||
npx hyperframes dev
|
||||
npx hyperframes preview
|
||||
# Studio running at http://localhost:3002
|
||||
|
||||
npx hyperframes dev --port 4567
|
||||
npx hyperframes preview --port 4567
|
||||
```
|
||||
|
||||
### `render`
|
||||
|
||||
@@ -18,7 +18,7 @@ import { checkForUpdate, printUpdateNotice } from "./utils/updateCheck.js";
|
||||
|
||||
const subCommands = {
|
||||
init: () => import("./commands/init.js").then((m) => m.default),
|
||||
dev: () => import("./commands/dev.js").then((m) => m.default),
|
||||
preview: () => import("./commands/preview.js").then((m) => m.default),
|
||||
render: () => import("./commands/render.js").then((m) => m.default),
|
||||
lint: () => import("./commands/lint.js").then((m) => m.default),
|
||||
info: () => import("./commands/info.js").then((m) => m.default),
|
||||
|
||||
@@ -398,7 +398,7 @@ function scaffoldProject(
|
||||
// Copy project-level skills (.claude/skills/) for immediate availability
|
||||
const skillsSrcDir = getBundledSkillsDir();
|
||||
if (existsSync(skillsSrcDir)) {
|
||||
const projectSkills = ["hyperframes-compose", "hyperframes-captions"];
|
||||
const projectSkills = ["hyperframes-compose", "hyperframes-captions", "hyperframes-cli"];
|
||||
for (const skill of projectSkills) {
|
||||
const src = join(skillsSrcDir, skill);
|
||||
if (existsSync(src)) {
|
||||
@@ -420,7 +420,7 @@ async function nextStepLoop(destDir: string): Promise<void> {
|
||||
message: "What do you want to do?",
|
||||
options: [
|
||||
{
|
||||
value: "dev",
|
||||
value: "preview",
|
||||
label: "Open in studio",
|
||||
hint: "full editor with timeline",
|
||||
},
|
||||
@@ -437,9 +437,9 @@ async function nextStepLoop(destDir: string): Promise<void> {
|
||||
// Hand off to the selected command — use explicit imports so the
|
||||
// bundler can resolve them (dynamic import with a variable fails in bundles)
|
||||
try {
|
||||
if (next === "dev") {
|
||||
const devCmd = await import("./dev.js").then((m) => m.default);
|
||||
await runCommand(devCmd, { rawArgs: [destDir] });
|
||||
if (next === "preview") {
|
||||
const previewCmd = await import("./preview.js").then((m) => m.default);
|
||||
await runCommand(previewCmd, { rawArgs: [destDir] });
|
||||
} else if (next === "render") {
|
||||
const renderCmd = await import("./render.js").then((m) => m.default);
|
||||
await runCommand(renderCmd, { rawArgs: [destDir] });
|
||||
@@ -623,7 +623,7 @@ Examples:
|
||||
);
|
||||
console.log();
|
||||
console.log(` ${c.accent("2.")} Preview in the browser:`);
|
||||
console.log(` ${c.accent(`cd ${name}`)} && ${c.accent("npx hyperframes dev")}`);
|
||||
console.log(` ${c.accent(`cd ${name}`)} && ${c.accent("npx hyperframes preview")}`);
|
||||
console.log();
|
||||
console.log(` ${c.accent("3.")} Render to MP4 when ready:`);
|
||||
console.log(` ${c.accent(`cd ${name}`)} && ${c.accent("npx hyperframes render")}`);
|
||||
|
||||
@@ -59,22 +59,22 @@ async function serveWithPortFallback(
|
||||
}
|
||||
|
||||
export default defineCommand({
|
||||
meta: { name: "dev", description: "Start the studio for local development" },
|
||||
meta: { name: "preview", description: "Start the studio for previewing compositions" },
|
||||
args: {
|
||||
dir: { type: "positional", description: "Project directory", required: false },
|
||||
port: { type: "string", description: "Port to run the dev server on", default: "3002" },
|
||||
port: { type: "string", description: "Port to run the preview server on", default: "3002" },
|
||||
},
|
||||
async run({ args }) {
|
||||
const rawArg = args.dir;
|
||||
const dir = resolve(rawArg ?? ".");
|
||||
const startPort = parseInt(args.port ?? "3002", 10);
|
||||
|
||||
// Compute display name: preserve symlink/CWD name when user runs "hyperframes dev ."
|
||||
// Compute display name: preserve symlink/CWD name when user runs "hyperframes preview ."
|
||||
const isImplicitCwd = !rawArg || rawArg === "." || rawArg === "./";
|
||||
const projectName = isImplicitCwd ? basename(process.env.PWD ?? dir) : basename(dir);
|
||||
|
||||
// Lint before starting — surface issues for the agent to fix.
|
||||
// dev.ts doesn't use resolveProject() because it needs to proceed even without index.html.
|
||||
// preview.ts doesn't use resolveProject() because it needs to proceed even without index.html.
|
||||
const indexPath = join(dir, "index.html");
|
||||
if (existsSync(indexPath)) {
|
||||
const project = { dir, name: projectName, indexPath };
|
||||
@@ -137,7 +137,7 @@ async function runDevMode(dir: string, projectName?: string): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
clack.intro(c.bold("hyperframes dev"));
|
||||
clack.intro(c.bold("hyperframes preview"));
|
||||
|
||||
const s = clack.spinner();
|
||||
s.start("Starting studio...");
|
||||
@@ -240,7 +240,7 @@ async function runLocalStudioMode(dir: string, projectName?: string): Promise<vo
|
||||
}
|
||||
}
|
||||
|
||||
clack.intro(c.bold("hyperframes dev") + c.dim(" (local studio)"));
|
||||
clack.intro(c.bold("hyperframes preview") + c.dim(" (local studio)"));
|
||||
const s = clack.spinner();
|
||||
s.start("Starting studio...");
|
||||
|
||||
@@ -304,7 +304,7 @@ async function runEmbeddedMode(
|
||||
const pName = projectName ?? basename(dir);
|
||||
const { app } = createStudioServer({ projectDir: dir, projectName: pName });
|
||||
|
||||
clack.intro(c.bold("hyperframes dev"));
|
||||
clack.intro(c.bold("hyperframes preview"));
|
||||
const s = clack.spinner();
|
||||
s.start("Starting studio...");
|
||||
|
||||
@@ -53,7 +53,7 @@ ${c.bold("SUBCOMMANDS:")}
|
||||
${c.accent("disable")} ${c.dim("Disable anonymous telemetry")}
|
||||
|
||||
${c.bold("WHAT WE COLLECT:")}
|
||||
${c.dim("\u2022")} Command names (init, render, dev, etc.)
|
||||
${c.dim("\u2022")} Command names (init, render, preview, etc.)
|
||||
${c.dim("\u2022")} Render performance (duration, fps, quality)
|
||||
${c.dim("\u2022")} Template choices
|
||||
${c.dim("\u2022")} OS, architecture, Node.js version, CLI version
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Embedded studio server for `hyperframes dev` outside the monorepo.
|
||||
* Embedded studio server for `hyperframes preview` outside the monorepo.
|
||||
*
|
||||
* Uses the shared studio API module from @hyperframes/core/studio-api,
|
||||
* providing a CLI-specific adapter for single-project, in-process rendering.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
npx hyperframes dev # preview in browser (studio editor)
|
||||
npx hyperframes preview # preview in browser (studio editor)
|
||||
npx hyperframes render # render to MP4
|
||||
npx hyperframes lint # validate compositions (errors + warnings)
|
||||
npx hyperframes lint --verbose # include info-level findings
|
||||
|
||||
@@ -13,7 +13,7 @@ export interface LintFormatOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Format lint findings for console output. Used by lint, render, and dev commands.
|
||||
* Format lint findings for console output. Used by lint, render, and preview commands.
|
||||
*/
|
||||
export function formatLintFindings(
|
||||
{ results, totalErrors, totalWarnings, totalInfos }: ProjectLintResult,
|
||||
|
||||
@@ -803,7 +803,7 @@ export function lintHyperframeHtml(
|
||||
severity: "info",
|
||||
message: `This composition loads an external script from \`${src}\`. The HyperFrames bundler automatically hoists CDN scripts from sub-compositions into the parent document. In unbundled runtime mode, \`loadExternalCompositions\` re-injects them. If you're using a custom pipeline that bypasses both, you'll need to include this script manually.`,
|
||||
fixHint:
|
||||
"No action needed when using `hyperframes dev` or `hyperframes render`. If using a custom pipeline, add this script tag to your root composition or HTML page.",
|
||||
"No action needed when using `hyperframes preview` or `hyperframes render`. If using a custom pipeline, add this script tag to your root composition or HTML page.",
|
||||
snippet: truncateSnippet(match[0] ?? ""),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ The studio is a React application with:
|
||||
|
||||
## Development
|
||||
|
||||
The studio is embedded in the `hyperframes dev` command. To develop the studio UI itself:
|
||||
The studio is embedded in the `hyperframes preview` command. To develop the studio UI itself:
|
||||
|
||||
```bash
|
||||
cd packages/studio
|
||||
@@ -43,4 +43,4 @@ Full documentation: [hyperframes.heygen.com/packages/studio](https://hyperframes
|
||||
## Related packages
|
||||
|
||||
- [`@hyperframes/core`](../core) — types and parsers used by the editor
|
||||
- [`hyperframes`](../cli) — CLI that serves the studio via `hyperframes dev`
|
||||
- [`hyperframes`](../cli) — CLI that serves the studio via `hyperframes preview`
|
||||
|
||||
@@ -293,7 +293,7 @@ GROUPS.forEach(function (group, gi) {
|
||||
tl.seek(0); // reset after lint
|
||||
```
|
||||
|
||||
Place this **before** `window.__timelines[id] = tl` so it runs at composition init. Warnings appear in the browser console during `hyperframes dev`.
|
||||
Place this **before** `window.__timelines[id] = tl` so it runs at composition init. Warnings appear in the browser console during `hyperframes preview`.
|
||||
|
||||
## Constraints
|
||||
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
---
|
||||
name: hyperframes-cli
|
||||
description: Use when the user mentions "hyperframes", wants to preview a composition in the studio, render to MP4/WebM, scaffold a new video project, lint or validate a composition, or troubleshoot rendering. Also use after finishing a composition with compose-video — lint and preview are the natural next steps.
|
||||
---
|
||||
|
||||
# HyperFrames CLI
|
||||
|
||||
The CLI turns HTML compositions into previews and rendered video. Everything runs through `npx hyperframes`.
|
||||
|
||||
```bash
|
||||
npx hyperframes <command>
|
||||
```
|
||||
|
||||
Requires Node.js >= 22 and FFmpeg. Run `npx hyperframes doctor` if anything fails.
|
||||
|
||||
## Workflow
|
||||
|
||||
The natural sequence when building a composition:
|
||||
|
||||
1. **Scaffold** — `npx hyperframes init my-video` (new projects only)
|
||||
2. **Write** — author HTML composition (see `compose-video` skill)
|
||||
3. **Lint** — `npx hyperframes lint` to catch structural errors
|
||||
4. **Preview** — `npx hyperframes preview` to see it live in the studio
|
||||
5. **Render** — `npx hyperframes render` to export video
|
||||
|
||||
**Lint before preview.** It catches missing `data-composition-id`, overlapping tracks on the same `data-track-index`, unregistered timelines, and other structural issues that silently produce broken output. A 2-second lint saves minutes debugging a blank screen. Both `preview` and `render` auto-lint, but linting explicitly after editing gives you a chance to fix issues without waiting for the server or renderer to spin up.
|
||||
|
||||
## Scaffolding New Projects
|
||||
|
||||
```bash
|
||||
npx hyperframes init my-video # interactive wizard
|
||||
npx hyperframes init my-video --template warm-grain # pick a template
|
||||
npx hyperframes init my-video --video clip.mp4 # with video file
|
||||
npx hyperframes init my-video --audio track.mp3 # with audio file
|
||||
npx hyperframes init my-video --non-interactive # skip prompts (CI/agents)
|
||||
```
|
||||
|
||||
Templates: `blank`, `warm-grain`, `play-mode`, `swiss-grid`, `vignelli`, `decision-tree`, `kinetic-type`, `product-promo`, `nyt-graph`.
|
||||
|
||||
`init` creates the right file structure, copies media, transcribes audio with Whisper, and installs AI coding skills. Use it instead of creating files by hand — the template includes boilerplate that's easy to forget.
|
||||
|
||||
## Linting
|
||||
|
||||
```bash
|
||||
npx hyperframes lint # current directory
|
||||
npx hyperframes lint ./my-project # specific project
|
||||
npx hyperframes lint --verbose # include info-level findings
|
||||
npx hyperframes lint --json # machine-readable output for scripting
|
||||
```
|
||||
|
||||
Lints `index.html` and all files in `compositions/`. Reports errors (must fix), warnings (should fix), and info (with `--verbose`).
|
||||
|
||||
**When to lint:**
|
||||
|
||||
- After writing or editing any composition file — always
|
||||
- Before rendering — `render` blocks on errors with `--strict`, but linting first is faster
|
||||
- After timing changes — overlapping clips on the same track are a common mistake
|
||||
|
||||
## Previewing in the Studio
|
||||
|
||||
```bash
|
||||
npx hyperframes preview # serve current directory
|
||||
npx hyperframes preview ./my-project # specific project
|
||||
npx hyperframes preview --port 4567 # custom port (default 3002)
|
||||
```
|
||||
|
||||
Opens the studio in your browser automatically. Hot-reloads on file changes. Run from the project root (directory containing `index.html`).
|
||||
|
||||
## Rendering to Video
|
||||
|
||||
```bash
|
||||
npx hyperframes render # standard MP4
|
||||
npx hyperframes render --output final.mp4 # named output
|
||||
npx hyperframes render --quality draft # fast iteration
|
||||
npx hyperframes render --fps 60 --quality high -o hd.mp4 # high quality
|
||||
npx hyperframes render --format webm -o overlay.webm # transparent WebM
|
||||
npx hyperframes render --docker -o deterministic.mp4 # reproducible
|
||||
```
|
||||
|
||||
| Flag | Options | Default | Notes |
|
||||
| -------------- | --------------------- | ---------------------------- | ------------------------------------- |
|
||||
| `--output` | path | renders/name_timestamp.mp4 | Output file path |
|
||||
| `--fps` | 24, 30, 60 | 30 | 60fps doubles render time |
|
||||
| `--quality` | draft, standard, high | standard | Use draft while iterating |
|
||||
| `--format` | mp4, webm | mp4 | WebM supports transparency |
|
||||
| `--workers` | 1-8 or auto | auto (half CPU cores, max 4) | Each spawns a Chrome process |
|
||||
| `--docker` | flag | off | Byte-identical output across machines |
|
||||
| `--gpu` | flag | off | GPU-accelerated encoding |
|
||||
| `--strict` | flag | off | Fail on lint errors |
|
||||
| `--strict-all` | flag | off | Fail on errors AND warnings |
|
||||
|
||||
**Quality guidance:**
|
||||
|
||||
- `draft` while iterating on timing and layout — fast feedback
|
||||
- `standard` for review and most deliverables
|
||||
- `high` only for final delivery where render time doesn't matter
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
```bash
|
||||
npx hyperframes doctor # check environment (Chrome, FFmpeg, Node, memory, disk)
|
||||
npx hyperframes browser # manage bundled Chrome installation
|
||||
npx hyperframes info # version and environment details
|
||||
npx hyperframes upgrade # check for updates
|
||||
```
|
||||
|
||||
Run `doctor` first if rendering fails or produces unexpected results. Common issues:
|
||||
|
||||
- Missing FFmpeg → `brew install ffmpeg`
|
||||
- Missing Chrome → `npx hyperframes browser ensure`
|
||||
- Low memory → close other apps (each render worker uses ~256MB)
|
||||
|
||||
## Other Commands
|
||||
|
||||
```bash
|
||||
npx hyperframes compositions # list compositions in current project
|
||||
npx hyperframes docs # open documentation in browser
|
||||
npx hyperframes benchmark . # benchmark render performance
|
||||
```
|
||||
Reference in New Issue
Block a user