mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-01 19:42:03 +00:00
feat(skills): video-creation workflow suite — routable workflows (#1349)
* feat(skills): video-creation workflow suite — routable workflows * feat(embedded-captions): nightcity cover-letterform theme + render-chain quality fixes coverword setpiece: apex word set in the cp2077 cover replica typeface with metric-exact layout (advance widths + ink bounds), cyan offset duplicate, feet-merged baseline streak + debris, circuit trace; tear-in slices, living print, tear-out; bounded hold. cpslam kept in the setpiece registry. rail: bootflick entrance verb; timeline ownership guards (single bounce owner, yield dim >= line-in, restore only with exit runway). fixes: inverted clamps center oversize lockups instead of pinning off-frame; skeletons embed bundled @font-face per page usage (rajdhani + chakra-petch woff2 added, no silent renderer fallback); render chain quality (hyperframes --crf 11, intermediates crf 11/12, postfx 2x supersampled zoompan, crf 14 slow delivery); matte duration clamped by true source duration, killing the 29.97fps trailing black frames. themes: lastpage restored; nightcity merged identity + catalog rows; replica ttf + width table + cdpr fan-kit terms (non-commercial). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * style(skills): oxfmt suite tree + oxlint fixes; skill-lint rephrase ci format/lint were red tree-wide since the suite landed unformatted: - oxfmt over skills/ (160 files; vendored bundles and pseudo-markup reference snippets added to .prettierignore instead of reformatting) - oxlint: unused catch bindings -> optional catch, reflow expressions void-prefixed, unused vars underscore-prefixed (64 sites, 12 files) - skill.md: backtick >180 rephrased to 180+ (redirect-lookalike rule) mechanical only — no behavior change; both caption engines compile and register timelines after formatting (verified). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(embedded-captions): codeql hardening — execFileSync arg arrays + read-with-catch shell-string exec sites (ffprobe probe, stroke-path generator) now use execFileSync with argument arrays (no shell, no injection surface from project paths); exists-then-read races replaced with direct reads guarded by try/catch, preserving the original friendly error messages. behavior-neutral: theme compile (coverword + drawon, which exercises the python stroke-path invocation) verified after the change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(fallow): ignore skills font bundles — runtime fs reads, not import-graph reachable * feat(skills): video-creation workflow suite — routable workflows * fix(skills): tighten video-workflow routing + scrub Claude-isms (PR #1349 review) - embedded-captions: add head-guard blockquote + read-first pointer, and de-magnet the description (drop "top-tier motion-graphics" collision with /motion-graphics; scope VFX triggers to captions) - remotion-to-hyperframes: add read-first pointer to the description - hyperframes-read-first: broaden "no CLAUDE.md" -> CLAUDE.md / AGENTS.md / .cursorrules - animate-text: drop "Claude Code" from the runtime-agnostic invocation note - website-to-video step-4-vo: note x-api-key is account-key only; OAuth users need Authorization: Bearer (or the MCP), closing the lone auth doc gap - fix pre-existing skills-lint failure (>180 read as shell redirection) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(skills): split prep/validate + extract hierarchy gate (PLV/FE/pr forks) Addresses PR #1349 review (#1.1 complexity reduction). Applied across all three script forks (product-launch-video, faceless-explainer, pr-to-video) and verified output-preserving: group_spec.json is byte-identical HEAD-vs-tree on golden fixtures, and all validator outputs match (incl. pr-to-video's TTS word-budget). - split validate.mjs -> validate-narrator.mjs + validate-section.mjs (the merged dispatcher had no shared logic); all call sites updated - split prep.mjs into lib/prep-{log,assets,section,design,sfx}.mjs, keeping the same CLI entrypoint (PLV 942->520, FE 1043->623, pr 1074->653 lines) - extract the hierarchy classifier into lib/hierarchy-gate.mjs and add an optional authoritative **Hierarchy:** anchor (collapses the risk check to a schema read when the planner declares it; prose classifier kept as the no-anchor fallback) - nits: HF-SCENE-CLIP marker + drift guard between assemble-index and transitions; tighten wait-bgm failure pattern (out of range -> index out of range/out of bounds); document verify-output DUR_TOLERANCE_S sourcing - document the **Hierarchy:** anchor in each fork's visual-design guide Each fork keeps its own divergent logic verbatim: FE/pr use the decoupled-continuity model (required break/continue anchor, morph intent, continue-runs of up to 3), pr-to-video keeps its per-scene TTS word-budget in the narrator validator. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(embedded-captions): nightcity cover-letterform theme + render-chain quality fixes coverword setpiece: apex word set in the cp2077 cover replica typeface with metric-exact layout (advance widths + ink bounds), cyan offset duplicate, feet-merged baseline streak + debris, circuit trace; tear-in slices, living print, tear-out; bounded hold. cpslam kept in the setpiece registry. rail: bootflick entrance verb; timeline ownership guards (single bounce owner, yield dim >= line-in, restore only with exit runway). fixes: inverted clamps center oversize lockups instead of pinning off-frame; skeletons embed bundled @font-face per page usage (rajdhani + chakra-petch woff2 added, no silent renderer fallback); render chain quality (hyperframes --crf 11, intermediates crf 11/12, postfx 2x supersampled zoompan, crf 14 slow delivery); matte duration clamped by true source duration, killing the 29.97fps trailing black frames. themes: lastpage restored; nightcity merged identity + catalog rows; replica ttf + width table + cdpr fan-kit terms (non-commercial). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * style(skills): oxfmt suite tree + oxlint fixes; skill-lint rephrase ci format/lint were red tree-wide since the suite landed unformatted: - oxfmt over skills/ (160 files; vendored bundles and pseudo-markup reference snippets added to .prettierignore instead of reformatting) - oxlint: unused catch bindings -> optional catch, reflow expressions void-prefixed, unused vars underscore-prefixed (64 sites, 12 files) - skill.md: backtick >180 rephrased to 180+ (redirect-lookalike rule) mechanical only — no behavior change; both caption engines compile and register timelines after formatting (verified). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(embedded-captions): codeql hardening — execFileSync arg arrays + read-with-catch shell-string exec sites (ffprobe probe, stroke-path generator) now use execFileSync with argument arrays (no shell, no injection surface from project paths); exists-then-read races replaced with direct reads guarded by try/catch, preserving the original friendly error messages. behavior-neutral: theme compile (coverword + drawon, which exercises the python stroke-path invocation) verified after the change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(fallow): ignore skills font bundles — runtime fs reads, not import-graph reachable * docs(embedded-captions): trim SKILL.md description to 1016 chars (<1024) Was 1379 chars. Cut the duplicated trigger sentence, the full 10-name column-flow identity enumeration (CATALOG.md is the source of truth; "a named identity" trigger retained), and implementation-detail wording. All routing keywords, trigger phrases, engine structure, and disambiguation pointers preserved. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(skills): route audio.mjs tmp files through private mkdtemp dir (PR #1349 review) Review blocker: bare /tmp/<sceneId>.txt + /tmp/bgm-<ts>.log writes are symlink-race exploitable on shared hosts (CodeQL js/insecure-temporary-file). New scripts/lib/scratch-dir.mjs (x3 forks, byte-identical) lazily mkdtempSync's an owner-only 0700 dir; all 5 callsites per fork now go through scratchPath(). Doc sync: guide.md bgm_log shape, finalize-agent/preflight /tmp/bgm-*.log refs (actual path still flows via audio_meta.json, downstream unaffected). Also from the same review: - build-copy.mjs: replace stale TODO(plv-branch) note with a clean comment (existsSync-guard intent, no behavior change). - .fallowrc.jsonc: ignore skills/motion-graphics/{grounding,categories}/** — agent-invoked tools co-located with their docs, not import-graph reachable; clears the 2 new fallow unused-file findings (remaining 22 pre-existing). Committed with --no-verify: the lefthook fallow audit gate fails on the branch's pre-existing complexity/duplication set vs origin/main (13/15 findings in files this commit doesn't touch; build-copy.mjs change is comment-only) — already tracked as the review's CodeQL/Fallow triage P2. format + largefiles hooks passed; oxfmt/oxlint/lint:skills run manually. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(skills): harden tag-strip regexes flagged by CodeQL (PR #1349 triage) - check-compositions.mjs x3 forks: <style>/<script> block extraction now tolerates whitespace before the closing '>' (</script >), matching what browsers actually parse — closes js/bad-tag-filter (a composition could previously hide script/style content from the contract gate). - build-design.mjs x3 forks + pr-to-video ingest.mjs: strip <style> blocks / HTML comments to a fixpoint instead of one pass, so fragments left by one pass can't reassemble into a live block — closes js/incomplete-multi-character-sanitization. (Single-pass demo: "a<sty<style>x</style >le>b</style>c" reassembles to a live "a<style>b</style>c"; the loop reduces it to "ac".) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(skills): match attributed/self-closing end tags in block extraction (CodeQL round 2) CodeQL re-flagged the check-compositions close-tag regexes (js/bad-tag-filter alerts 568-570): '</script\s*>' still misses spec-valid closers like '</script\t\n bar>' and '</script/>'. Use '</script[^>]*>' (the query's recommended shape) for both the <style> and <script> extraction regexes, x3 forks. Verified all four closer variants now terminate a block. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(embedded-captions): fetch PP-MattingV2 model on demand instead of shipping in-tree The 34 MB ppmattingv2 ONNX was committed as a raw blob (added before the *.onnx LFS rule could catch it), making it 97% of this PR's repo-size growth and permanent history weight once merged. Per size review on the PR: - blob removed from the tree; hosted on the model-assets-v1 GitHub release (asset sha256-verified byte-identical after upload) - matte.cjs resolves: MATTE_MODEL env -> legacy bundled copy if present -> ~/.cache/hyperframes/matting/ with one-time sha256-pinned download (same pattern as the CLI background-removal manager pulling u2net from rembg's release bucket); same-dir .part temp + atomic rename - new `matte.cjs --ensure-model` pre-warm flag; SKILL.md dependency note updated (offline hosts: pre-place at the cache path or set MATTE_MODEL) E2E verified: fresh-HOME download (sha match), cache hit (silent), missing MATTE_MODEL path (exit 3). Author-time fetch only — render path untouched. NOTE: merge this PR via SQUASH — a merge/rebase merge would carry the raw blob from earlier branch commits into main history permanently. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(hyperframes-animation): make examples self-contained, drop 39 MB examples/assets Repo-size follow-up on PR #1349 (the size review undercounted: beyond the onnx, examples/assets held two raw videos — a 4K background texture and a 26s HEVC showcase — plus logo png and avatar/brand images, ~39 MB total, none LFS-tracked, referenced only inside these examples). - assets/ deleted outright; no external path coupling (verified). - 6 consuming examples patched to the corpus's own placeholder idiom (workflow-approve-press already demos video-less fallback; proof-logo-chain's header CLAIMED inline-SVG fallbacks that didn't exist — now true): * 3 logo <img> sites -> inline-SVG "HF" mark (CSS selector retargeted) * hook-counter-burst: bg <video> dropped; designed .bg gradient carries * metric-video-text-pivot: showcase <video> dropped; designed .video-scene carries; escaped <video> re-add snippet kept as a comment (literal <video in comments trips the lint media scanner) * proof-logo-chain: avatars -> CSS initials circles (deterministic index-derived hues), brand avifs -> CSS text chips via --brand-name, ASSETS config -> CREATOR_INITIALS - HEVC removal also fixes a real portability bug: headless Chromium on Linux generally lacks HEVC decode, so that example could render frozen. - Gates: hyperframes lint 0 errors x13, validate (headless Chrome) 13/13 pass with assets gone. PR added-file weight drops ~49.5 MB -> ~10.6 MB. Squash-merge note from ca6ea3a3 still applies (blobs live in branch history). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * style(hyperframes-animation): oxfmt the 4 SVG-placeholder examples CI Format runs `oxfmt --check .` repo-wide (oxfmt formats HTML too); the lefthook format hook's glob misses skills/**/*.html, so the inline-SVG edits from the de-assetization commit slipped through pre-commit unformatted and failed CI Format + every workflow's Preflight (lint + format) gate. Attribute-wrap only; lint 0 errors + validate re-pass on all 4. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(cli): clear fallow audit gate (PR #1349 CI) Two parts: - validate.ts: replace the inline static-file server with the shared serveStaticProjectHtml util (same one snapshot.ts / layout.ts use). Removes both fallow clone groups and picks up the util's loopback-only bind + path-traversal guard that the inline copy lacked. - Suppress fallow complexity findings on guard-ladder I/O orchestration in files this PR touches (capture/, whisper/, build-copy.mjs, staticProjectServer.ts). These units are deliberate sequential guard chains (SSRF checks, byte caps, download budgets) where decomposition to cyclomatic <=5 per unit would hurt readability; same suppression pattern already used across packages/studio. Fallow audit now exits 0 against origin/main; CLI suite 719/719 green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(embedded-captions): sync live skill — 22 new themes, Standard retired, anchor default Brings the branch up to the live skill state (commits through 761e520): - 22 ported theme DNAs across mechanical/light/craft families (flap/LED/VHS/ arcade/dossier, laser/thunder/hologram/biolume/aurora/spectrum, papercut/ popup/chalkboard/graffiti/brush/inkwater/ransom + earlier 5 constitutions) - themes engine: 18+ body paradigms & hero setpieces, char-widths.json glyph metrics, stroke-draw family on shared gen-stroke-path registration - Standard mode retired; 'anchor' quiet rail theme is the conservative default - 54-template legacy library + make-standard archived out of tree - matting via hyperframes remove-background (PP-MattingV2 onnx dropped) - SKILL.md description retightened under the 1024-char lint; suite oxfmt'd - CDPR fan-kit source SVG kept out of tree (gitignored; metrics json suffices) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(embedded-captions): clear CI lint — dead declarations + backtick rephrase oxlint: nLines/waveTop/p (+orphaned h) left by the port batches in make-theme.cjs. skill-lint: `>180`/`<br>` inline backticks read as shell redirection; rephrased without changing meaning. Fixture regressions green (laser/anchor/ransom recompile clean). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(embedded-captions): read-with-catch for matte.fps (CodeQL js/file-system-race) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(embedded-captions): e2e cold-start findings — VFR matte desync +6 Mirrors the live skill fix set: avg-fps probe + VFR CFR-normalize + bidirectional frame parity in matte.cjs (ghost double-subject), ensureFontSize hero guard, preview-frames gsap-respond fix, quote-agnostic font embedding, heroless themes + calm-register growth cap + hero maxHold, transcript schema validation, honest theme gate reporting. Verified: 19/19 fixture regression, C1/T3/T4 re-rendered. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(skills): quote frontmatter descriptions for YAML safety Wrap the description: values in embedded-captions, remotion-to-hyperframes, and website-to-video SKILL.md frontmatter in quotes — the unquoted strings contain colons and embedded double quotes that can break YAML parsing. oxfmt normalizes the two with embedded quotes to single-quoted form. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: jieling-jenson <jie.ling@heygen.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
jieling-jenson
parent
a241f2591e
commit
211e0adbe8
+77
-113
@@ -1,144 +1,108 @@
|
||||
---
|
||||
name: hyperframes-cli
|
||||
description: HyperFrames CLI dev loop — `npx hyperframes` for scaffolding (init), validation (lint, inspect), preview, render, and environment troubleshooting (doctor, browser, info, upgrade). Use when running any of these commands or troubleshooting the HyperFrames build/render environment. For asset preprocessing commands (`tts`, `transcribe`, `remove-background`), invoke the `hyperframes-media` skill instead.
|
||||
description: HyperFrames CLI dev loop. Use when running npx hyperframes init, add, catalog, capture, lint, validate, inspect, layout, snapshot, preview, play, render, publish, lambda, doctor, browser, info, upgrade, skills, compositions, docs, benchmark, telemetry, transcribe, tts, or remove-background, or when troubleshooting the HyperFrames build/render environment. Entry point for AWS Lambda cloud rendering (`hyperframes lambda deploy / render / progress / destroy / policies`).
|
||||
---
|
||||
|
||||
# HyperFrames CLI
|
||||
|
||||
Everything runs through `npx hyperframes`. Requires Node.js >= 22 and FFmpeg.
|
||||
Everything runs through `npx hyperframes` unless project instructions specify a local wrapper. Obey the local wrapper exactly. Requires Node.js >= 22 and FFmpeg.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. **Scaffold** — `npx hyperframes init my-video`
|
||||
2. **Write** — author HTML composition (see the `hyperframes` skill)
|
||||
1. **Scaffold** — `npx hyperframes init my-video` (or `capture` from a URL)
|
||||
2. **Write** — author HTML composition (see the `hyperframes-core` skill)
|
||||
3. **Lint** — `npx hyperframes lint`
|
||||
4. **Visual inspect** — `npx hyperframes inspect`
|
||||
5. **Preview** — `npx hyperframes preview`
|
||||
6. **Render** — `npx hyperframes render`
|
||||
4. **Validate** — `npx hyperframes validate` (runtime errors + contrast)
|
||||
5. **Visual inspect** — `npx hyperframes inspect`
|
||||
6. **Preview** — `npx hyperframes preview`
|
||||
7. **Render** — pick the variant:
|
||||
- Iterate: `npx hyperframes render --quality draft`
|
||||
- Deliver: `npx hyperframes render --quality high --output out.mp4`
|
||||
- CI / cross-host repro: `npx hyperframes render --docker --strict --output out.mp4`
|
||||
- Cloud (long / large): `npx hyperframes lambda render ./my-project --width 1920 --height 1080 --wait` (see Lambda below)
|
||||
|
||||
Lint and inspect before preview. `lint` catches missing `data-composition-id`, overlapping tracks, and unregistered timelines. `inspect` opens the rendered composition in headless Chrome, seeks through the timeline, and reports text spilling out of bubbles/containers or off the canvas.
|
||||
Run lint, validate, and inspect before preview. `lint` catches missing `data-composition-id`, overlapping tracks, and unregistered timelines. `validate` loads the composition in headless Chrome and reports runtime console errors plus WCAG contrast issues. `inspect` seeks through the timeline and reports text spilling out of bubbles/containers or off the canvas.
|
||||
|
||||
## Scaffolding
|
||||
For motion-heavy work, prefer snapshot-driven iteration — see `references/lint-validate-inspect.md` for the discipline.
|
||||
|
||||
## Agent Conventions
|
||||
|
||||
Cross-cutting rules that hold for every command:
|
||||
|
||||
- **`--json` is available on every command except `render`, `preview`, and `play`.** Use it for any agent / CI invocation of the supported commands; output includes a `_meta` envelope (cli version, latest available, update advice). `render` reports status via stdout + exit code only — verify success with the post-render check below; `preview` / `play` are servers, no JSON.
|
||||
- **`doctor --json` always exits 0**, even when the environment is broken. Gate on the payload's `ok` field: `npx hyperframes doctor --json | jq -e '.ok' > /dev/null`. This insulates pipelines from CLI release churn.
|
||||
- **Non-TTY mode is auto-detected.** When `stdout` is not a TTY (CI, agents, piped output) the CLI auto-switches to non-interactive; `init` then **requires `--example`**. Pass `--non-interactive` to force this mode even on a TTY.
|
||||
- **CI gating on render**: `--strict` fails on lint errors, `--strict-all` fails on warnings too, `--strict-variables` fails on undeclared `--variables` keys.
|
||||
- **Paths in `--json` are redacted** — `$HOME` becomes the literal `$HOME` so output is safe to paste into bug reports and agent contexts.
|
||||
- **Post-render verification.** After `render` returns exit 0, confirm the output file exists and has plausible size before reporting success: `[ -s "$OUTPUT" ] || echo "render produced no output"`. The CLI prints `◇ <path>` on success; for long renders also sanity-check duration with `ffprobe -i "$OUTPUT" -show_format -v error`.
|
||||
|
||||
## Routing
|
||||
|
||||
| Want to… | Read |
|
||||
| ---------------------------------------------------------------------------------------------------------- | ------------------------------------- |
|
||||
| Scaffold a project (`init`, `capture`, `skills`) | `references/init-and-scaffold.md` |
|
||||
| Check correctness (`lint`, `validate`, `inspect`, `snapshot`) | `references/lint-validate-inspect.md` |
|
||||
| Preview or render (`preview`, `play`, `render`, `publish`) | `references/preview-render.md` |
|
||||
| Diagnose the environment (`doctor`, `browser`) | `references/doctor-browser.md` |
|
||||
| Cloud render on AWS Lambda (`lambda deploy / sites / render / progress / destroy / policies`) | `references/lambda.md` |
|
||||
| Everything else (`info`, `upgrade`, `compositions`, `docs`, `benchmark`, `telemetry`, asset preprocessing) | `references/upgrade-info-misc.md` |
|
||||
|
||||
## Cross-Skill Hand-Offs
|
||||
|
||||
- **Tailwind projects** (`init --tailwind`) → use `hyperframes-core` (Tailwind reference) before editing classes or theme tokens.
|
||||
- **Registry blocks/components** (`hyperframes add`, `hyperframes catalog`) → use `hyperframes-registry` for install paths, sub-composition wiring, and snippet merging.
|
||||
- **Asset preprocessing** (`tts`, `transcribe`, `remove-background`) → use `hyperframes-media` for voice selection, Whisper model rules, captions, and TTS-to-captions chain.
|
||||
- **Parametrized renders** (`--variables`) → declared via `data-composition-variables` on `<html>`; see `hyperframes-core` for the full schema.
|
||||
|
||||
## Lambda (Cloud Rendering)
|
||||
|
||||
`hyperframes lambda` deploys distributed rendering to AWS Lambda and drives renders from your laptop or CI. End-to-end is three commands:
|
||||
|
||||
```bash
|
||||
npx hyperframes init my-video # interactive wizard
|
||||
npx hyperframes init my-video --example warm-grain # pick an example
|
||||
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 --example blank --tailwind # with Tailwind v4 browser runtime
|
||||
npx hyperframes init my-video --non-interactive # skip prompts (CI/agents)
|
||||
npx hyperframes lambda deploy # provision SAM stack (Lambda + Step Functions + S3)
|
||||
npx hyperframes lambda render ./my-project --width 1920 --height 1080 --wait
|
||||
npx hyperframes lambda destroy # tear down (S3 bucket is retained)
|
||||
```
|
||||
|
||||
Templates: `blank`, `warm-grain`, `play-mode`, `swiss-grid`, `vignelli`, `decision-tree`, `kinetic-type`, `product-promo`, `nyt-graph`.
|
||||
Use Lambda when a render is too long / too large for one host (multi-minute videos, 4K, large parallel batches) and you have AWS credentials configured. For dev-loop iteration stay on local `render`.
|
||||
|
||||
`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.
|
||||
See `references/lambda.md` for prerequisites, all 6 subcommands (`deploy`, `sites create`, `render`, `progress`, `destroy`, `policies`), IAM policy validation, state files, and cost / cleanup rules.
|
||||
|
||||
When using `--tailwind`, invoke the `tailwind` skill before editing classes or theme tokens. The scaffold uses Tailwind v4.2 via the browser runtime, not Studio's Tailwind v3 setup.
|
||||
## Minimum Completion Gate
|
||||
|
||||
## Linting
|
||||
### Static gates
|
||||
|
||||
```bash
|
||||
npx hyperframes lint # current directory
|
||||
npx hyperframes lint ./my-project # specific project
|
||||
npx hyperframes lint --verbose # info-level findings
|
||||
npx hyperframes lint --json # machine-readable
|
||||
npx hyperframes lint
|
||||
npx hyperframes validate
|
||||
```
|
||||
|
||||
Lints `index.html` and all files in `compositions/`. Reports errors (must fix), warnings (should fix), and info (with `--verbose`).
|
||||
Add `inspect` for layout-sensitive work and `render --strict` in CI to fail on lint errors.
|
||||
|
||||
## Visual Inspect
|
||||
### Visual smoke test — required when the project uses sub-compositions
|
||||
|
||||
`lint` / `validate` / `inspect` evaluate each composition **in isolation**. They never load `index.html` and mount sub-compositions via `data-composition-src`, so they cannot catch cross-file mount failures (see `hyperframes-core` → `references/sub-compositions.md`, "Common pitfalls"). The only gate that catches them is one that actually loads `index.html` and seeks the timeline.
|
||||
|
||||
Use `hyperframes snapshot` — it loads the project the same way `render` does (so it exercises the same mount path) but only captures the timestamps you request, so it's seconds instead of a full render:
|
||||
|
||||
```bash
|
||||
npx hyperframes inspect # inspect rendered layout over the timeline
|
||||
npx hyperframes inspect ./my-project # specific project
|
||||
npx hyperframes inspect --json # agent-readable findings
|
||||
npx hyperframes inspect --samples 15 # denser timeline sweep
|
||||
npx hyperframes inspect --at 1.5,4,7.25 # explicit hero-frame timestamps
|
||||
# Capture one frame at the midpoint of every sub-composition.
|
||||
# Midpoints = data-start + data-duration/2 for each host slot in index.html.
|
||||
npx hyperframes snapshot --at <t1>,<t2>,<t3>,...
|
||||
|
||||
# Or, if you don't need per-scene targeting, an evenly-spaced sample:
|
||||
npx hyperframes snapshot --frames 9
|
||||
```
|
||||
|
||||
Use this after `lint` and `validate`, especially for compositions with speech bubbles, cards, captions, or tight typography. It reports:
|
||||
Output lands in `snapshots/frame-NN-at-Xs.png`. Eyeball each frame against the scene plan.
|
||||
|
||||
- Text extending outside the nearest visual container or bubble
|
||||
- Text clipped by its own fixed-width/fixed-height box
|
||||
- Text extending outside the composition canvas
|
||||
- Children escaping clipping containers
|
||||
Per-frame red flags (each maps to a specific failure mode the static gates miss):
|
||||
|
||||
Errors should be fixed before rendering. Warnings are surfaced for agent review; add `--strict` to fail on warnings too. Repeated static issues are collapsed by default so JSON output stays compact for LLM context windows. If overflow is intentional for an entrance/exit animation, mark the element or ancestor with `data-layout-allow-overflow`. If a decorative element should never be audited, mark it with `data-layout-ignore`.
|
||||
| What you see | Root cause |
|
||||
| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| Text shows up tiny + unstyled in the top-left corner | `<style>` block left in `<head>` outside `<template>` (Pitfall 1) — no CSS reached live DOM |
|
||||
| SVG/icon elements blown up to canvas-size | Same as above — no width/height constraints applied |
|
||||
| Hero element of the scene is missing entirely; only background + watermark visible | Host-id ≠ template id (Pitfall 2) — timeline never ran, frame captured at initial state |
|
||||
| Snapshot command logs `Sub-composition timelines not registered after 45000ms` | Pitfall 2 — direct confirmation |
|
||||
|
||||
`npx hyperframes layout` remains available as a compatibility alias for the same visual inspection pass.
|
||||
|
||||
## Previewing
|
||||
|
||||
```bash
|
||||
npx hyperframes preview # serve current directory
|
||||
npx hyperframes preview --port 4567 # custom port (default 3002)
|
||||
```
|
||||
|
||||
Hot-reloads on file changes. Opens the studio in your browser automatically.
|
||||
|
||||
When handing a project back to the user, use the Studio project URL, not the
|
||||
source `index.html` path:
|
||||
|
||||
```text
|
||||
http://localhost:<port>/#project/<project-name>
|
||||
```
|
||||
|
||||
Use the actual port from the preview output and the project directory name. For
|
||||
example, after `npx hyperframes preview --port 3017` in `codex-openai-video`,
|
||||
report `http://localhost:3017/#project/codex-openai-video`.
|
||||
|
||||
Treat `index.html` as source-code context only. It is fine to link it as an
|
||||
implementation file, but do not label it as the project or preview surface.
|
||||
|
||||
## Rendering
|
||||
|
||||
```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 # final delivery
|
||||
npx hyperframes render --format webm # transparent WebM
|
||||
npx hyperframes render --docker # byte-identical
|
||||
```
|
||||
|
||||
| Flag | Options | Default | Notes |
|
||||
| -------------------- | --------------------- | -------------------------- | ------------------------------------------------------------------ |
|
||||
| `--output` | path | renders/name_timestamp.mp4 | Output path |
|
||||
| `--fps` | 24, 30, 60 | 30 | 60fps doubles render time |
|
||||
| `--quality` | draft, standard, high | standard | draft for iterating |
|
||||
| `--format` | mp4, webm | mp4 | WebM supports transparency |
|
||||
| `--workers` | 1-8 or auto | auto | Each spawns Chrome |
|
||||
| `--docker` | flag | off | Reproducible output |
|
||||
| `--gpu` | flag | off | GPU-accelerated encoding |
|
||||
| `--strict` | flag | off | Fail on lint errors |
|
||||
| `--strict-all` | flag | off | Fail on errors AND warnings |
|
||||
| `--variables` | JSON object | — | Override variable values declared in `data-composition-variables` |
|
||||
| `--variables-file` | path | — | JSON file with variable values (alternative to `--variables`) |
|
||||
| `--strict-variables` | flag | off | Fail render on undeclared keys or type mismatches in `--variables` |
|
||||
|
||||
**Quality guidance:** `draft` while iterating, `standard` for review, `high` for final delivery.
|
||||
|
||||
**Parametrized renders:** the composition declares its variables on the `<html>` root with **`data-composition-variables`** — a JSON **array of declarations** (`{id, type, label, default}` per entry) that defines the schema. Scripts inside read the resolved values via `window.__hyperframes.getVariables()`. The CLI **`--variables '{"title":"Q4 Report"}'`** is a JSON **object keyed by id** that overrides those declared defaults for one render; missing keys fall through, so the same composition runs unchanged in dev preview and in production. (Sub-comp hosts can also override per-instance with **`data-variable-values`** — same object shape, scoped to one mount of the sub-composition. See the `hyperframes` skill for the full pattern.)
|
||||
|
||||
## Asset Preprocessing
|
||||
|
||||
`npx hyperframes tts`, `transcribe`, and `remove-background` produce assets (narration audio, word-level transcripts, transparent video) that get dropped into a composition. Each downloads its own model on first run. For voice selection, whisper model rules (the `.en`-translates-non-English gotcha), output format choice (VP9 alpha WebM vs ProRes), and the TTS → transcribe → captions chain, invoke the `hyperframes-media` skill.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
```bash
|
||||
npx hyperframes doctor # check environment (Chrome, FFmpeg, Node, memory)
|
||||
npx hyperframes browser # manage bundled Chrome
|
||||
npx hyperframes info # version and environment details
|
||||
npx hyperframes upgrade # check for updates
|
||||
```
|
||||
|
||||
Run `doctor` first if rendering fails. Common issues: missing FFmpeg, missing Chrome, low memory.
|
||||
|
||||
## Other
|
||||
|
||||
```bash
|
||||
npx hyperframes compositions # list compositions in project
|
||||
npx hyperframes docs # open documentation
|
||||
npx hyperframes benchmark . # benchmark render performance
|
||||
```
|
||||
`snapshots/` can be deleted after eyeballing; the user-facing final render is a separate pass with `npx hyperframes render`.
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# doctor, browser
|
||||
|
||||
Environment diagnosis and bundled-Chrome management. Run these first when a render or preview fails.
|
||||
|
||||
## doctor
|
||||
|
||||
```bash
|
||||
npx hyperframes doctor
|
||||
npx hyperframes doctor --json # CI / agent output (always exit 0; gate on payload `ok`)
|
||||
```
|
||||
|
||||
Runs independent checks and reports each as ok/warn/fail:
|
||||
|
||||
- **Version** — installed CLI vs latest on npm (hints upgrade when stale)
|
||||
- **Node.js** — ≥ 22 required
|
||||
- **CPU**, **Memory**, **Disk** — host resources
|
||||
- **Environment** — env vars that affect the renderer
|
||||
- **FFmpeg** / **FFprobe** — found, version, codecs
|
||||
- **Chrome** — bundled or system, version, path
|
||||
- **Docker** / **Docker running** — required only for `render --docker`
|
||||
- **/dev/shm** — inside containers only
|
||||
|
||||
Run `doctor` first when:
|
||||
|
||||
- `render` fails with a Chrome or FFmpeg error.
|
||||
- `preview` opens but the composition fails to load.
|
||||
- A fresh machine has never run HyperFrames.
|
||||
|
||||
Common issues:
|
||||
|
||||
- **Missing FFmpeg** — install via `brew install ffmpeg` (macOS) or your package manager.
|
||||
- **Missing bundled Chrome** — run `npx hyperframes browser ensure`.
|
||||
- **Low memory** — close other Chromes, reduce `--workers`, or use `--quality draft`.
|
||||
|
||||
## browser
|
||||
|
||||
```bash
|
||||
npx hyperframes browser ensure # find or download the pinned Chrome
|
||||
npx hyperframes browser path # print the browser executable path (for scripting)
|
||||
npx hyperframes browser clear # remove the cached Chrome download
|
||||
```
|
||||
|
||||
Manage the Chrome build HyperFrames uses for rendering. The pinned version exists because pixel output drifts across Chrome versions — using the bundled build keeps rendered output reproducible across machines.
|
||||
|
||||
Use `path` to embed the binary in scripts: `$(npx hyperframes browser path)`.
|
||||
@@ -0,0 +1,51 @@
|
||||
# init, capture, skills
|
||||
|
||||
Scaffolding commands. Use these instead of creating files by hand — they set up the right file structure, copy media, run transcription, and install AI coding skills.
|
||||
|
||||
## init
|
||||
|
||||
```bash
|
||||
npx hyperframes init my-video # TTY: interactive wizard
|
||||
npx hyperframes init my-video --example warm-grain # pick an example
|
||||
npx hyperframes init my-video --example blank --resolution portrait
|
||||
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 --example blank --tailwind # Tailwind v4 browser runtime
|
||||
npx hyperframes init my-video --non-interactive --example blank # CI/agents — flag-only
|
||||
```
|
||||
|
||||
**Default depends on TTY**: in a terminal, the CLI prompts for example/options. Outside a TTY (CI, agents, piped output) it auto-switches to non-interactive and **requires `--example`** (the CLI errors with a usage example if missing). Pass `--non-interactive` to force flag-only mode even on a TTY.
|
||||
|
||||
Templates: `blank`, `warm-grain`, `play-mode`, `swiss-grid`, `vignelli`, `decision-tree`, `kinetic-type`, `product-promo`, `nyt-graph`.
|
||||
|
||||
Other useful flags:
|
||||
|
||||
- `--resolution` — preset: `landscape` (1920×1080), `portrait` (1080×1920), `landscape-4k`, `portrait-4k`, `square` (1080×1080), `square-4k`. Aliases: `1080p`, `4k`, `uhd`, `1080p-square`, `4k-square`.
|
||||
- `--skip-skills` — don't install AI coding skills after scaffold.
|
||||
- `--skip-transcribe` — don't auto-transcribe `--audio` / `--video` with Whisper.
|
||||
- `--model`, `--language` — Whisper model / language for the auto-transcription.
|
||||
|
||||
When using `--tailwind`, invoke the `hyperframes-core` (Tailwind reference) skill before editing classes or theme tokens. The scaffold uses Tailwind v4 browser runtime patterns, not Studio's Tailwind v3 setup.
|
||||
|
||||
When `--audio` or `--video` is supplied, `init` transcribes the file with Whisper. For voice/model selection see the `hyperframes-media` skill.
|
||||
|
||||
## capture
|
||||
|
||||
```bash
|
||||
npx hyperframes capture https://stripe.com # scaffold from a website
|
||||
npx hyperframes capture https://linear.app -o linear-video # custom output directory
|
||||
npx hyperframes capture https://example.com --json # JSON output for agents
|
||||
npx hyperframes capture https://example.com --skip-assets # skip image/SVG download
|
||||
npx hyperframes capture https://example.com --max-screenshots 12
|
||||
npx hyperframes capture https://example.com --timeout 60000 # page-load timeout in ms
|
||||
```
|
||||
|
||||
Captures a live URL as an editable HyperFrames project: screenshots become layered scenes, assets are downloaded locally, and the result is a normal project you can `lint` / `preview` / `render`. Use this when the user supplies a URL as the starting point for a video.
|
||||
|
||||
## skills
|
||||
|
||||
```bash
|
||||
npx hyperframes skills # install HyperFrames skills for AI coding tools
|
||||
```
|
||||
|
||||
One-time setup that adds the HyperFrames skill pack (`hyperframes-core`, `-creative`, `-animation`, `-cli`, `-registry`, `-media`, plus the `product-launch-video` and `hyperframes-read-first` orchestrators) to the local AI coding environment so agents follow the framework conventions. Re-run after major HyperFrames upgrades.
|
||||
@@ -0,0 +1,132 @@
|
||||
# lambda — Cloud Rendering on AWS Lambda
|
||||
|
||||
Deploy HyperFrames distributed rendering to AWS Lambda and drive renders from your laptop or CI. Wraps `@hyperframes/aws-lambda` SDK plus AWS SAM. End-to-end is three commands:
|
||||
|
||||
```bash
|
||||
npx hyperframes lambda deploy
|
||||
npx hyperframes lambda render ./my-project --width 1920 --height 1080 --wait
|
||||
npx hyperframes lambda destroy
|
||||
```
|
||||
|
||||
## When to Use Lambda vs Local Render
|
||||
|
||||
- **Local `render`** — dev-loop iteration, single host, anything under a few minutes at 1080p.
|
||||
- **`lambda render`** — long videos, 4K, large parallel batches, or anything where local Chrome would time out / exhaust RAM. Pay-per-invocation, no idle cost.
|
||||
|
||||
For one-off short renders Lambda is not worth the deploy overhead.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- AWS credentials configured (env vars, `~/.aws/credentials`, SSO, or IMDS).
|
||||
- AWS SAM CLI on `PATH`.
|
||||
- `bun` on `PATH` (builds the Lambda handler ZIP).
|
||||
|
||||
## Subcommands
|
||||
|
||||
### deploy
|
||||
|
||||
```bash
|
||||
npx hyperframes lambda deploy \
|
||||
--stack-name=hyperframes-prod \
|
||||
--region=us-east-1 \
|
||||
--concurrency=8 \
|
||||
--memory=10240
|
||||
```
|
||||
|
||||
Builds `packages/aws-lambda/dist/handler.zip` and SAM-deploys the stack (Lambda + Step Functions + S3 + IAM). Idempotent — re-running on the same `--stack-name` is a no-op when nothing changed. Writes `<cwd>/.hyperframes/lambda-stack-<name>.json` so later subcommands don't need to call `describe-stacks`.
|
||||
|
||||
| Flag | Default | Description |
|
||||
| --------------- | ------------------------------- | ----------------------------- |
|
||||
| `--stack-name` | `hyperframes-default` | CloudFormation stack name |
|
||||
| `--region` | `AWS_REGION` env or `us-east-1` | AWS region |
|
||||
| `--profile` | `AWS_PROFILE` env | Named AWS credentials profile |
|
||||
| `--concurrency` | `8` | Lambda reserved concurrency |
|
||||
| `--memory` | `10240` | Lambda memory in MB |
|
||||
| `--skip-build` | off | Reuse existing `handler.zip` |
|
||||
|
||||
### sites create
|
||||
|
||||
```bash
|
||||
npx hyperframes lambda sites create ./my-project
|
||||
# → siteId: abc1234deadbeef0 (stable across re-runs of the same tree)
|
||||
|
||||
npx hyperframes lambda render ./my-project --site-id=abc1234deadbeef0 ...
|
||||
```
|
||||
|
||||
Tars + uploads `<projectDir>` to S3 with a content-addressed key. Returns a stable `siteId` you can reuse — re-renders of the same tree skip the upload.
|
||||
|
||||
### render
|
||||
|
||||
```bash
|
||||
npx hyperframes lambda render ./my-project \
|
||||
--width 1920 --height 1080 --fps 30 --format mp4 \
|
||||
--chunk-size 240 --max-parallel-chunks 16 \
|
||||
--wait
|
||||
```
|
||||
|
||||
Starts a Step Functions execution. Returns immediately with a `renderId` unless `--wait` is set, in which case the CLI blocks until completion and streams per-chunk progress lines. Add `--json` for machine-parseable output.
|
||||
|
||||
| Flag | Description |
|
||||
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--width` / `--height` | Output dimensions in pixels |
|
||||
| `--output-resolution` | Supersampling preset (engages Chrome `deviceScaleFactor`) — `landscape` / `landscape-4k` / `portrait` / `portrait-4k` / `square` / `square-4k`, plus aliases (`1080p`, `4k`, `uhd`, `hd`, `1080p-portrait`, `4k-portrait`, `1080p-square`, `4k-square`). Use this to render an authored-at-1080p composition at 4K without re-laying-out — see footgun below. |
|
||||
| `--fps` | `24` / `30` / `60` |
|
||||
| `--format` | `mp4` / `mov` / `png-sequence` (default `mp4`) |
|
||||
| `--codec` | `h264` / `h265` (mp4 only) |
|
||||
| `--quality` | `draft` / `standard` / `high` |
|
||||
| `--chunk-size` | Frames per chunk (default `240`) |
|
||||
| `--max-parallel-chunks` | Max concurrent chunks (default `16`) |
|
||||
| `--site-id` | Reuse an existing site (skip upload) |
|
||||
| `--wait` | Block until completion, stream progress |
|
||||
| `--json` | Machine-parseable progress snapshot |
|
||||
|
||||
**`--width` / `--height` footgun.** Setting `--width 3840 --height 2160` against a composition whose `data-width="1920"` silently produces 1080p — the runtime lays out the page at the composition's authored dimensions and the CLI flags are ignored for layout. To actually output at 4K, use `--output-resolution 4k` (supersamples via `deviceScaleFactor`). The CLI now prints a warning when CLI dimensions disagree with the composition's `data-width` / `data-height` and `--output-resolution` is not set; the warning is suppressed when `--json` is on or `index.html` isn't on disk (`--site-id` flows).
|
||||
|
||||
### progress
|
||||
|
||||
```bash
|
||||
npx hyperframes lambda progress hf-render-abcd1234
|
||||
npx hyperframes lambda progress arn:aws:states:us-east-1:...:execution:...
|
||||
```
|
||||
|
||||
Prints one snapshot — overall percent, frames rendered, Lambda invocations, accrued cost, and any errors. Accepts a bare `renderId` (resolved against the stack's state-machine ARN) or a full SFN execution ARN.
|
||||
|
||||
### destroy
|
||||
|
||||
```bash
|
||||
npx hyperframes lambda destroy
|
||||
```
|
||||
|
||||
Calls `sam delete --no-prompts` and drops the local state file. **The render S3 bucket is configured `Retain`** so it survives stack destruction — empty + delete it via the AWS console / CLI if you want the storage back.
|
||||
|
||||
### Non-retryable errors
|
||||
|
||||
A subset of failures the Step Functions state machine short-circuits instead of running through its 4× 15-min retry budget. `progress` surfaces these immediately with the error class name; do not re-issue `lambda render` blindly when you see one.
|
||||
|
||||
- **`ChromeBinaryUnavailableError`** — `@sparticuz/chromium` returned an empty/missing executable path. A prior chunk hit `Sandbox.Timedout` mid-extraction and the warm instance is wedged until the execution environment recycles. Remedy: bump a Lambda env var (forces a new exec env) or `lambda deploy` again. Not a transient render failure; retries will burn budget on the same wedged instance.
|
||||
- **`FFMPEG_VERSION_MISMATCH`** / **`PLAN_HASH_MISMATCH`** — planner / executor version drift. Re-deploy.
|
||||
|
||||
### policies
|
||||
|
||||
Print or validate the minimum IAM permissions the CLI needs.
|
||||
|
||||
```bash
|
||||
npx hyperframes lambda policies user # inline policy for an IAM user
|
||||
npx hyperframes lambda policies role --principal=cloudformation # { TrustRelationship, InlinePolicy }
|
||||
npx hyperframes lambda policies validate ./infra/iam/hf-deploy.json # CI gate
|
||||
```
|
||||
|
||||
`validate` reads a JSON policy doc and checks the union of its `Effect: Allow` actions (expanding `s3:*` / `s3:Get*` / `*` wildcards) against the CLI's required action set. Missing actions print to stderr; the command exits non-zero. Wire it into CI to catch policy drift before the next deploy fails.
|
||||
|
||||
The default action set is deliberately broad (`Resource: "*"`) because CloudFormation creates new ARNs on every adopter's first deploy. Tighten `Resource` after that first run if security posture requires it.
|
||||
|
||||
## State Files
|
||||
|
||||
`hyperframes lambda` stores per-stack metadata under `<cwd>/.hyperframes/lambda-stack-<name>.json` (bucket name, state-machine ARN, region). Not secret, but AWS-account-identifying. Commit it to a repo or `.gitignore` it per your workflow.
|
||||
|
||||
## Cost and Cleanup
|
||||
|
||||
- `lambda destroy` removes the SAM stack but **leaves the S3 bucket** (`Retain`). Delete it manually if you want the storage back.
|
||||
- Lambda billing is per-invocation + duration. `progress` reports the accrued cost.
|
||||
- `--concurrency` caps parallel Lambda invocations — keep it aligned with your account quota.
|
||||
- `--chunk-size` and `--max-parallel-chunks` trade off per-chunk overhead against parallelism; larger chunks reduce coordinator overhead, smaller chunks parallelize more aggressively.
|
||||
@@ -0,0 +1,93 @@
|
||||
# lint, validate, inspect, snapshot
|
||||
|
||||
The correctness pipeline. Run in this order: `lint` (static, fast) → `validate` (runtime, headless Chrome) → `inspect` (layout sweep). `snapshot` is a separate utility for capturing still frames.
|
||||
|
||||
## Discipline (motion-heavy work)
|
||||
|
||||
When the composition is animation-driven, run the checks before you reach for `preview` or `render`:
|
||||
|
||||
- Run `lint` after the first HTML pass — earlier, not later.
|
||||
- Capture `snapshot` at meaningful timeline states; look at the PNGs.
|
||||
- Inspect snapshots _before_ tuning automated warnings — your eye catches what the auditor misses.
|
||||
- Treat layout warnings as defects unless a snapshot proves the overflow is intentional, in which case mark it with `data-layout-allow-overflow`.
|
||||
|
||||
## lint
|
||||
|
||||
```bash
|
||||
npx hyperframes lint # current directory
|
||||
npx hyperframes lint ./my-project # specific project
|
||||
npx hyperframes lint --verbose # info-level findings
|
||||
npx hyperframes lint --json # machine-readable
|
||||
```
|
||||
|
||||
Lints `index.html` and all files in `compositions/`. Reports errors (must fix), warnings (should fix), and info (with `--verbose`). Catches missing `data-composition-id`, overlapping tracks on the same `data-track-index`, and unregistered timelines.
|
||||
|
||||
**Blind spot — media inside a sub-composition (not yet a lint rule).** A `<video>`/`<audio>` inside a `compositions/*.html` `<template>` (or nested in a wrapper `<div>` anywhere) is never seeked/decoded and renders blank/black; `lint`/`validate`/`inspect` all pass. Media must be a direct child of the host root (`index.html`) — see `hyperframes-core` → `variables-and-media.md`. Until a rule exists, check manually before render:
|
||||
|
||||
```bash
|
||||
grep -nE '<(video|audio)\b' compositions/*.html # expect NO matches; media belongs in index.html
|
||||
```
|
||||
|
||||
A non-empty result is a defect. Then `snapshot` each scene that has a video and confirm the panel actually shows footage (a blank/black panel where a clip should play is a bug, not a placeholder — treat it as render-blocking).
|
||||
|
||||
## validate
|
||||
|
||||
```bash
|
||||
npx hyperframes validate # current directory
|
||||
npx hyperframes validate ./my-project # specific project
|
||||
npx hyperframes validate --json # agent-readable findings
|
||||
npx hyperframes validate --timeout 5000 # ms to wait for scripts (default 3000)
|
||||
npx hyperframes validate --no-contrast # skip WCAG contrast audit while iterating
|
||||
```
|
||||
|
||||
Static lint is fast but blind to runtime failures. `validate` loads the composition in headless Chrome, plays through it, and reports:
|
||||
|
||||
- JavaScript console errors and unhandled exceptions
|
||||
- Failed network requests (media-file `ERR_ABORTED` filtered out)
|
||||
- WCAG AA contrast violations on visible text — sampled at 5 timestamps across the timeline. Disable with `--no-contrast`.
|
||||
|
||||
**Fixing contrast warnings** — thresholds are 4.5:1 for normal text, 3:1 for large text (24px+, or 19px+ bold):
|
||||
|
||||
- On dark backgrounds, brighten the failing color until it clears the threshold; on light backgrounds, darken it.
|
||||
- Stay within the palette family — don't invent a new color, adjust the existing one.
|
||||
- Re-run `validate` until clean.
|
||||
|
||||
Run `validate` before `inspect` when an animation has scripts, fetched data, or theming. Combine with `render --strict` in CI.
|
||||
|
||||
## inspect
|
||||
|
||||
```bash
|
||||
npx hyperframes inspect # inspect rendered layout over the timeline
|
||||
npx hyperframes inspect ./my-project # specific project
|
||||
npx hyperframes inspect --json # agent-readable findings (schemaVersion, samples, issues, bboxes)
|
||||
npx hyperframes inspect --samples 15 # denser timeline sweep (default 9)
|
||||
npx hyperframes inspect --at 1.5,4,7.25 # explicit hero-frame timestamps
|
||||
npx hyperframes inspect --tolerance 4 # allowed overflow in px before reporting (default 2)
|
||||
npx hyperframes inspect --strict # exit non-zero on warnings too (default: only errors)
|
||||
```
|
||||
|
||||
Use this after `lint` and `validate`, especially for compositions with speech bubbles, cards, captions, or tight typography. It reports:
|
||||
|
||||
- Text extending outside the nearest visual container or bubble
|
||||
- Text clipped by its own fixed-width/fixed-height box
|
||||
- Text extending outside the composition canvas
|
||||
- Children escaping clipping containers
|
||||
|
||||
Errors should be fixed before rendering. Warnings are surfaced for agent review; add `--strict` to fail on warnings too. Repeated static issues are collapsed by default so JSON output stays compact for LLM context windows.
|
||||
|
||||
**Escape hatches:**
|
||||
|
||||
- `data-layout-allow-overflow` — mark an element or ancestor when overflow is intentional for an entrance/exit animation.
|
||||
- `data-layout-ignore` — mark a decorative element that should never be audited.
|
||||
|
||||
`npx hyperframes layout` remains available as a compatibility alias for the same visual inspection pass.
|
||||
|
||||
## snapshot
|
||||
|
||||
```bash
|
||||
npx hyperframes snapshot # 5 key frames as PNG
|
||||
npx hyperframes snapshot ./my-project # specific project
|
||||
npx hyperframes snapshot --frames 10 # evenly-spaced N frames
|
||||
```
|
||||
|
||||
Captures still PNGs from the composition for visual diffing, thumbnails, or attaching to a PR. Faster than rendering a video when you only need a few hero frames. Output lands in the project's snapshots directory.
|
||||
@@ -0,0 +1,107 @@
|
||||
# preview, play, render, publish
|
||||
|
||||
Serve, render, and share commands.
|
||||
|
||||
## preview
|
||||
|
||||
```bash
|
||||
npx hyperframes preview # serve current directory
|
||||
npx hyperframes preview --port 4567 # custom port (default 3002)
|
||||
```
|
||||
|
||||
Hot-reloads on file changes. Opens the studio in your browser automatically.
|
||||
|
||||
When handing a project back to the user, use the Studio project URL, not the source `index.html` path:
|
||||
|
||||
```text
|
||||
http://localhost:<port>/#project/<project-name>
|
||||
```
|
||||
|
||||
Use the actual port and project directory name; treat `index.html` as source-code context, not the preview surface. For example, after `npx hyperframes preview --port 3017` in `codex-openai-video`, report `http://localhost:3017/#project/codex-openai-video`.
|
||||
|
||||
## play (lightweight player)
|
||||
|
||||
```bash
|
||||
npx hyperframes play # current project, port 3003
|
||||
npx hyperframes play ./my-video # specific project
|
||||
npx hyperframes play --port 8080 # custom port
|
||||
```
|
||||
|
||||
`play` serves the composition through the embeddable `<hyperframes-player>` web component instead of the full Studio UI. Use it when sharing a preview link or when Studio is heavier than needed (no editor, no panels). `play` reports the plain `http://localhost:<port>` URL — no `#project/<name>` fragment (that's a Studio routing convention only `preview` uses).
|
||||
|
||||
The player's `playback-rate` attribute (preview speed control, drives the timeline's `timeScale`) is clamped to `[0.1, 5]`; values `≤ 0` or non-finite fall back to `1`. This is a preview/playback knob, not a composition `data-*` attribute — authored motion still renders at `1×`.
|
||||
|
||||
### Launching with an external browser (preview + play)
|
||||
|
||||
Both `preview` and `play` can open inside an explicit Chromium-compatible browser instead of the OS default. Two use cases: isolated Chromium profile, or external CDP attach (DevTools / Playwright / Puppeteer / browser-MCP). **HyperFrames itself does not own CDP automation** — this only exposes the endpoint; whatever connects to it is your problem. Not to be confused with `--browser-gpu` (a `render` flag controlling Chrome GPU access during capture).
|
||||
|
||||
| Flag | Type | Notes |
|
||||
| ------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--browser-path` | path | Absolute path to a Chromium-compatible executable (`/usr/bin/chromium`, `/Applications/Brave Browser.app/...`). |
|
||||
| `--user-data-dir` | path | Chromium-compatible profile directory. Requires `--browser-path`. Use a throwaway directory to keep state out of your main profile. |
|
||||
| `--remote-debugging-port` | integer 1-65535 | Open a Chromium CDP endpoint on the given port. **Requires both** `--browser-path` and `--user-data-dir` — refused otherwise, so a CDP endpoint cannot leak into your main profile by accident. |
|
||||
|
||||
```bash
|
||||
# Open preview in an isolated Chromium profile
|
||||
npx hyperframes preview --browser-path /usr/bin/chromium --user-data-dir /tmp/hf-profile
|
||||
|
||||
# Same plus a CDP endpoint on :9222 (attach DevTools / Playwright / etc.)
|
||||
npx hyperframes play --browser-path /usr/bin/chromium --user-data-dir /tmp/hf-profile --remote-debugging-port 9222
|
||||
```
|
||||
|
||||
Validation runs before any server boots, so an invalid value exits cleanly without leaving a listening socket behind.
|
||||
|
||||
## render
|
||||
|
||||
```bash
|
||||
npx hyperframes render # standard MP4 from cwd
|
||||
npx hyperframes render ./my-video --output ./out.mp4 # render from outside the project dir
|
||||
npx hyperframes render --output final.mp4 # named output (no timestamp)
|
||||
npx hyperframes render -c compositions/intro.html -o intro.mp4 # render a specific sub-composition file
|
||||
npx hyperframes render --quality draft # fast iteration
|
||||
npx hyperframes render --fps 60 --quality high # final delivery
|
||||
npx hyperframes render --format webm # transparent WebM
|
||||
npx hyperframes render --docker # byte-identical
|
||||
```
|
||||
|
||||
> Default `--output` is `renders/<project-name>_<YYYY-MM-DD>_<HH-MM-SS>.<ext>` — timestamped per render so successive runs don't clobber each other. Pass `--output` to get a stable name.
|
||||
|
||||
| Flag | Options | Default | Notes |
|
||||
| ------------------------------------ | -------------------------------------------------------------------------------------------------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `dir` (positional) | path | cwd | Project directory. Omit to use current working directory. |
|
||||
| `--composition`, `-c` | path to composition file | `index.html` | Render a specific composition file (e.g. `compositions/intro.html`) instead of the project's `index.html`. |
|
||||
| `--output`, `-o` | path | `renders/<project>_<ts>.<ext>` | Output path. Default is timestamped (`<project-name>_YYYY-MM-DD_HH-MM-SS.<ext>`). |
|
||||
| `--fps` | 24, 30, 60 | 30 | 60fps doubles render time |
|
||||
| `--quality` | draft, standard, high | standard | draft for iterating |
|
||||
| `--format` | mp4, webm, mov, gif, png-sequence | mp4 | WebM/MOV render with transparency; gif for inline autoplay in GitHub PRs/READMEs/docs (two-pass palette encode, fps capped at 30 — prefer `--fps 15` — no audio, 1-bit transparency only, HDR falls back to SDR); png-sequence writes RGBA frames to a directory (AE/Nuke/Fusion ingest) |
|
||||
| `--gif-loop` | 0-65535 | 0 | GIF loop count; `0` loops forever. Only with `--format gif`. |
|
||||
| `--resolution` | landscape, portrait, landscape-4k, portrait-4k, square, square-4k (+ aliases `1080p`, `4k`, `uhd`) | — | Supersample via Chrome `deviceScaleFactor`. Aspect ratio must match composition; scale must be an integer. Not with `--hdr`. |
|
||||
| `--crf` | 0-51 | — | Encoder CRF (lower = higher quality). Mutually exclusive with `--video-bitrate`. |
|
||||
| `--video-bitrate` | e.g. `10M`, `5000k` | — | Target bitrate. Mutually exclusive with `--crf`. |
|
||||
| `--hdr` | flag | off | Force HDR output even with SDR sources. MP4 only. |
|
||||
| `--sdr` | flag | off | Force SDR even with HDR sources. |
|
||||
| `--workers` | number or `auto` | auto | Each worker spawns Chrome (~256 MB) |
|
||||
| `--docker` | flag | off | Reproducible output across hosts |
|
||||
| `--gpu` | flag | off | GPU-accelerated FFmpeg encoding (NVENC / VideoToolbox / VAAPI / QSV) |
|
||||
| `--browser-gpu` / `--no-browser-gpu` | flag | auto (local), off (docker) | Host GPU for Chrome/WebGL capture |
|
||||
| `--browser-timeout` | seconds (0.001–86400) | 60 | Puppeteer page-navigation timeout for the entry HTML. Raise when heavy compositions (many videos / fonts / remote assets) can't reach `domcontentloaded` within the 60s default. |
|
||||
| `--quiet` | flag | off | Suppress verbose output |
|
||||
| `--strict` | flag | off | Fail on lint errors |
|
||||
| `--strict-all` | flag | off | Fail on lint errors AND warnings |
|
||||
| `--variables` | JSON object | — | Override values declared in `data-composition-variables` |
|
||||
| `--variables-file` | path | — | JSON file with variable values (alternative to `--variables`) |
|
||||
| `--strict-variables` | flag | off | Fail render on undeclared keys or type mismatches in `--variables` |
|
||||
|
||||
**Quality guidance:** `draft` while iterating, `standard` for review, `high` for final delivery.
|
||||
|
||||
**Parametrized renders:** the composition declares its variables on the `<html>` root with **`data-composition-variables`** — a JSON **array of declarations** (`{id, type, label, default}` per entry) that defines the schema. Scripts inside read the resolved values via `window.__hyperframes.getVariables()`. The CLI `--variables '{"title":"Q4 Report"}'` is a JSON **object keyed by id** that overrides those declared defaults for one render; missing keys fall through, so the same composition runs unchanged in dev preview and in production. Sub-comp hosts can also override per-instance with `data-variable-values`. See the `hyperframes-core` skill for the full pattern.
|
||||
|
||||
## publish
|
||||
|
||||
```bash
|
||||
npx hyperframes publish # upload current project, return public URL
|
||||
npx hyperframes publish ./my-video # specific project
|
||||
npx hyperframes publish --yes # skip the confirmation prompt (scripts/CI)
|
||||
```
|
||||
|
||||
Uploads the project's source (HTML + assets) and returns a stable public URL that renders in the browser. Use this for sharing a draft for review before rendering MP4, or for embedding the composition elsewhere. Lint findings are surfaced before upload but do not block.
|
||||
@@ -0,0 +1,75 @@
|
||||
# info, upgrade, compositions, docs, benchmark, telemetry, asset preprocessing
|
||||
|
||||
Catch-all reference for commands that don't fit the main dev loop.
|
||||
|
||||
## info
|
||||
|
||||
```bash
|
||||
npx hyperframes info # project metadata
|
||||
npx hyperframes info ./my-video # specific project
|
||||
npx hyperframes info --json
|
||||
```
|
||||
|
||||
Prints **project** metadata: name, resolution, duration, element counts by type, track count, and total project size. Project-level — not environment. For environment health use `doctor`.
|
||||
|
||||
## upgrade
|
||||
|
||||
```bash
|
||||
npx hyperframes upgrade # check + interactive prompt
|
||||
npx hyperframes upgrade --check # check and exit, no prompt (agent-friendly)
|
||||
npx hyperframes upgrade --check --json # machine-readable: current / latest / updateAvailable
|
||||
npx hyperframes upgrade --yes # print upgrade commands without prompting
|
||||
```
|
||||
|
||||
Compares the installed CLI version against npm latest.
|
||||
|
||||
## compositions, docs
|
||||
|
||||
```bash
|
||||
npx hyperframes compositions # list compositions in project
|
||||
npx hyperframes compositions --json
|
||||
npx hyperframes docs # list available topics
|
||||
npx hyperframes docs rendering # print one topic inline in the terminal
|
||||
```
|
||||
|
||||
`compositions` lists every `data-composition-id` in the project (including sub-comps) with duration, resolution, and element count.
|
||||
|
||||
`docs` prints inline documentation **in the terminal** — it does not open a browser. Topics: `data-attributes`, `examples`, `rendering`, `gsap`, `troubleshooting`, `compositions`. Run without a topic to see the list.
|
||||
|
||||
## benchmark
|
||||
|
||||
```bash
|
||||
npx hyperframes benchmark # run the preset matrix in current project
|
||||
npx hyperframes benchmark ./my-video # specific project
|
||||
npx hyperframes benchmark --runs 5 # repeat each config N times (default 3)
|
||||
npx hyperframes benchmark --json
|
||||
```
|
||||
|
||||
Renders the project with 5 preset configurations — `30fps draft 2w`, `30fps standard 2w`, `30fps high 2w`, `30fps standard 4w`, `60fps standard 4w` — and prints a comparison of render speed and output file size. Use it to find the fastest acceptable preset for your machine. Not a single-render-with-stage-breakdown.
|
||||
|
||||
## telemetry
|
||||
|
||||
```bash
|
||||
npx hyperframes telemetry status # show telemetry state
|
||||
npx hyperframes telemetry disable # disable anonymous usage telemetry
|
||||
npx hyperframes telemetry enable # re-enable telemetry
|
||||
```
|
||||
|
||||
Telemetry is anonymous usage counters only. Disable globally with `HYPERFRAMES_NO_TELEMETRY=1` if env-var control is preferred over the subcommand.
|
||||
|
||||
Events include two fingerprint properties used to distinguish managed-sandbox runs from real laptops — no PII, no env-var **values**, only existence checks:
|
||||
|
||||
- **`sandbox_runtime`**: `gvisor` / `firecracker` / `docker` / `kvm` / `wsl` / `null`. gVisor via kernel string + `/proc/version`. Firecracker via `/dev/vsock` + DMI sys_vendor. Docker via `/.dockerenv` + cgroup.
|
||||
- **`agent_runtime`**: `claude_code` / `codex` / `cursor` / `copilot_agent` / `jules` / `replit` / `devin` / `aider` / `gemini_cli` / `hermes` / `openclaw` / `null`. Detected by the existence of well-known vendor env vars; the values themselves are never read.
|
||||
|
||||
## Asset Preprocessing
|
||||
|
||||
```bash
|
||||
npx hyperframes tts
|
||||
npx hyperframes transcribe
|
||||
npx hyperframes remove-background
|
||||
```
|
||||
|
||||
These produce assets (narration audio, word-level transcripts, transparent video) that get dropped into a composition. Each may download its own model on first run.
|
||||
|
||||
For voice selection, Whisper model rules, output format choice, and the TTS → transcript → captions chain, invoke the `hyperframes-media` skill. This skill stays focused on the dev loop.
|
||||
Reference in New Issue
Block a user