Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d32d372
fix(skills): check local render dependencies before design
user-github-me Oct 9, 2026
b6d961c
chore(skills): prepare manifest for main integration
user-github-me Oct 10, 2026
45f6c69
chore(skills): merge current main for render prerequisites
user-github-me Oct 10, 2026
b40d58e
fix(skills): regenerate local-render dependency manifest
user-github-me Oct 10, 2026
a287ac6
chore: prepare conflict resolution against current main
user-github-me Oct 13, 2026
92ab440
chore: merge main for reviewed contribution
user-github-me Oct 13, 2026
d9fc67b
chore(skills): regenerate render prerequisite manifest
user-github-me Oct 13, 2026
a3eba07
chore: prepare conflict resolution against current main
user-github-me Oct 15, 2026
08f5234
chore: merge main for reviewed contribution
user-github-me Oct 15, 2026
85080ee
fix(skills): retain early render checks with current main
user-github-me Oct 15, 2026
5f1f5d7
chore: prepare conflict resolution against current main
user-github-me Oct 18, 2026
b3fb8f3
chore: merge main for reviewed contribution
user-github-me Oct 18, 2026
89788ca
fix(skills): condense early dependency guidance after main integration
user-github-me Oct 18, 2026
066ef3a
chore: prepare conflict resolution against current main
user-github-me Oct 24, 2026
ad53080
chore: merge main for reviewed contribution
user-github-me Oct 24, 2026
7129218
fix(skills): preserve dependency checks in consolidated workflows
user-github-me Oct 24, 2026
b7f7b1d
fix(skills): keep prerequisite guidance within entry budgets
user-github-me Oct 24, 2026
806e0fe
docs(skills): retain project wrapper precedence
user-github-me Oct 24, 2026
cb4c0b0
chore: prepare conflict resolution against current main
user-github-me Oct 24, 2026
78c3932
chore: merge main for reviewed contribution
user-github-me Oct 24, 2026
d7e00c7
fix(skills): check local render dependencies before design
user-github-me Oct 24, 2026
c93f3ce
fix(skills): retain entry contracts in dependency guidance
user-github-me Oct 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/guides/troubleshooting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ sudo apt install ffmpeg

Verify with `ffmpeg -version`, then rerun `npx hyperframes doctor`.

If you already have executable FFmpeg and FFprobe binaries, you can use them
without a package manager:

```bash
export HYPERFRAMES_FFMPEG_PATH="/absolute/path/to/ffmpeg"
export HYPERFRAMES_FFPROBE_PATH="/absolute/path/to/ffprobe"
npx hyperframes doctor --json
```

Check that both entries report `ok: true` and the expected paths. The command
always exits zero; its top-level `ok` also includes optional tools.

### Docker render will not start

Run `docker info`.
Expand Down
9 changes: 7 additions & 2 deletions packages/cli/src/browser/ffmpeg.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,17 @@ describe("getFFmpegInstallCommand / getFFmpegInstallHint", () => {
setPlatform(realPlatform);
});

it("gives macOS a pasteable command and uses it verbatim as the hint", async () => {
it("gives macOS a pasteable command and a setup route without Homebrew", async () => {
setPlatform("darwin");
const { getFFmpegInstallCommand, getFFmpegInstallHint } = await import("./ffmpeg.js");

expect(getFFmpegInstallCommand()).toBe("brew install ffmpeg");
expect(getFFmpegInstallHint()).toBe("brew install ffmpeg");
const hint = getFFmpegInstallHint();
expect(hint).toContain("brew install ffmpeg");
expect(hint).toContain("https://ffmpeg.org/download.html");
expect(hint).toContain("HYPERFRAMES_FFMPEG_PATH");
expect(hint).toContain("HYPERFRAMES_FFPROBE_PATH");
expect(hint).toContain(".hyperframes/bin/");
});

it("gives Windows a winget command and keeps the manual route in the hint", async () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/src/browser/ffmpeg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ export function getFFmpegInstallHint(): string {
if (command && process.platform === "win32") {
return `${command}, or download the 64-bit build from ${FFMPEG_DOWNLOAD_URL}#build-windows and add its bin/ directory to PATH.`;
}
if (command && process.platform === "darwin") {
return `${command}, or download FFmpeg and FFprobe from ${FFMPEG_DOWNLOAD_URL}, then set HYPERFRAMES_FFMPEG_PATH and HYPERFRAMES_FFPROBE_PATH to the executable paths or place both binaries in .hyperframes/bin/ in your project.`;
}
if (command) return command;
if (process.platform === "linux") return ffmpegInstallCommand("unknown");
return FFMPEG_DOWNLOAD_URL;
Expand Down
20 changes: 19 additions & 1 deletion packages/cli/src/browser/preflight.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ describe("runEnvironmentChecks", () => {
});

it.each([
{ platform: "darwin" as const, expectedHint: "brew install ffmpeg" },
{ platform: "sunos" as const, expectedHint: "https://ffmpeg.org/download.html" },
{
platform: "win32" as const,
Expand All @@ -194,6 +193,25 @@ describe("runEnvironmentChecks", () => {
expect(ffmpeg?.title).toBe("FFmpeg cannot start");
expect(ffmpeg?.hint).toBe(expectedHint);
});

it("offers configured binaries on macOS when FFmpeg cannot launch", async () => {
Object.defineProperty(process, "platform", { value: "darwin", configurable: true });
runProcess.mockImplementation((binaryPath: string) => {
if (binaryPath !== process.env.HYPERFRAMES_FFMPEG_PATH)
return Promise.resolve({ stdout: "ffprobe version 7.1.1\n", stderr: "" });
throw Object.assign(new Error("cannot execute binary file"), { status: 126 });
});

const result = await runEnvironmentChecks();
const ffmpeg = result.outcomes.find((outcome) => outcome.name === "FFmpeg");

expect(ffmpeg).toMatchObject({ ok: false, title: "FFmpeg cannot start" });
expect(ffmpeg?.hint).toContain("brew install ffmpeg");
expect(ffmpeg?.hint).toContain("HYPERFRAMES_FFMPEG_PATH");
expect(ffmpeg?.hint).toContain("HYPERFRAMES_FFPROBE_PATH");
expect(ffmpeg?.hint).toContain(".hyperframes/bin/");
expect(result.ffmpegPath).toBeUndefined();
});
});

it("validates an explicit browser path without needing browser discovery", async () => {
Expand Down
4 changes: 2 additions & 2 deletions skills-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
"files": 2
},
"hyperframes": {
"hash": "63994723e5533606",
"hash": "e95708f47d194df8",
"files": 77
},
"hyperframes-cli": {
"hash": "d82c156c1b2069d1",
"hash": "7d2aef84a47a17ea",
"files": 13
},
"hyperframes-registry": {
Expand Down
8 changes: 5 additions & 3 deletions skills/hyperframes-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ name: hyperframes-cli
description: The HyperFrames CLI by job - scaffold, check, look at frames, edit the timeline, preview, render locally or in the cloud, publish, project history - plus reading its JSON and recovering from build or render failures.
---

**Plugin installs:** Before setup or freshness commands, follow [plugin execution rules](../hyperframes/references/plugin-installation.md) when this skill is inside a HyperFrames plugin.
**Plugin installs:** Before setup or refresh, follow [plugin execution rules](../hyperframes/references/plugin-installation.md) inside a HyperFrames plugin.

# HyperFrames CLI

Run `npx hyperframes <command>` unless the project gives a wrapper; then use the wrapper. It needs Node.js 22+ and FFmpeg. Every command has `--help`; most take `--json`, and a failure prints `✗ …`, a `Fix:` line and exits non-zero.
Run the project's wrapper, or `npx hyperframes <command>` if none. Needs Node.js 22+ and FFmpeg. All commands have `--help`; most take `--json`. Failures print `✗ …`, a `Fix:` line and exit non-zero.

## Commands by job

Expand All @@ -28,6 +28,8 @@ Run `npx hyperframes <command>` unless the project gives a wrapper; then use the

## The loop

Before planning or designing a local video: `references/doctor-browser.md`.

1. Write, then `npx hyperframes lint` after the first pass and after structural changes.
2. `npx hyperframes check --json` and fix every error. While a lint error remains the layout and contrast audits don't run; "0 samples" means nothing was checked. Contrast failures carry a `suggestedColor`. A finding at a single sample (an entrance in flight) is info; a 3 s+ video with no visible change fails `sweep_static`.
3. `npx hyperframes snapshot` and read the PNGs (under `.hyperframes/artifacts/snapshots/`): that is how you see the video. With sub-compositions, snapshot a midpoint of every scene; tiny unstyled content or a missing hero is a mount defect (`../hyperframes/references/format.md`).
Expand Down Expand Up @@ -71,7 +73,7 @@ After a verified render, send one `feedback --rating`, plus a report for anythin

| Symptom | Fix |
| --- | --- |
| Chrome missing or won't start | `npx hyperframes browser ensure`; `doctor --json` always exits 0, gate on `.ok` |
| Chrome missing or won't start | `npx hyperframes browser ensure`; `doctor --json` exits 0; `.ok` includes optional tools |
| A heavy page isn't ready in time | Raise `--timeout` on `check` or `snapshot` |
| Unusual codec looks blank | Keep `--proxy` on (the default) |
| Render slow on Linux | The summary's second line says `screenshot` + `software gpu`: the slow path |
Expand Down
10 changes: 9 additions & 1 deletion skills/hyperframes-cli/references/doctor-browser.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Environment diagnosis and bundled-Chrome management. Run these first when a rend

```bash
npx hyperframes doctor
npx hyperframes doctor --json # CI / agent output (always exit 0; gate on payload `ok`)
npx hyperframes doctor --json # CI / agent output (always exit 0; inspect checks in payload)
```

Runs independent checks and reports each as ok/warn/fail:
Expand All @@ -26,6 +26,14 @@ Run `doctor` first when:
- `preview` opens but the composition fails to load.
- A fresh machine has never run HyperFrames.

### Check local video dependencies before design

For a workflow that will render a video locally, run `npx hyperframes doctor --json` from the project directory immediately after setup or resume, before planning, sourcing, or design. Keep this result for the current run; repeat after changing the binary configuration or environment.

Require both **FFmpeg** and **FFprobe** entries with `ok: true`, and inspect their reported paths. Use [the two-tool jq gate](#configure-ffmpeg-without-a-package-manager) when `jq` is available, or inspect the JSON directly. `doctor --json` exits 0 even when dependencies are missing, and its top-level `ok` includes optional tools.

When either binary is missing or cannot run, surface the affected check and use [the supported setup paths](#configure-ffmpeg-without-a-package-manager) before design starts. Verify the two checks again after setup. If installation is unavailable or needs authorization, report the dependency and agree on how to continue before starting design; retain the user's choice of local or cloud rendering. Check Chrome separately before browser validation and rendering. Deck-only and source-port tasks follow their own prerequisites.

Common issues:

- **Missing FFmpeg** — install via `brew install ffmpeg` (macOS) or your package manager, or [configure existing binaries](#configure-ffmpeg-without-a-package-manager).
Expand Down
7 changes: 4 additions & 3 deletions skills/hyperframes/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ name: hyperframes
description: Read first to make, edit, animate or render any video with HyperFrames (HTML rendered to video), including launch films, explainers, music videos, charts, maps, vertical clips, title cards, captions and overlays. Holds the render contract, the work loop and what each kind of video needs.
---

**Plugin installs:** Before setup or freshness commands, follow [plugin execution rules](references/plugin-installation.md) when this skill is inside a HyperFrames plugin.
**Plugin installs:** Before setup or refresh, follow [plugin execution rules](references/plugin-installation.md) inside a HyperFrames plugin.

# HyperFrames

HyperFrames renders HTML to video by seeking a paused timeline frame by frame, so every render is identical; the person edits the same files in the Studio preview. Use it unless another framework or a plain browser recording is asked for. Run the CLI as `npx hyperframes <command>` (`/hyperframes-cli`); at the start of a new video, `npx hyperframes usage --json` reports the person's remaining plan usage (say "unknown" when it is).
HyperFrames seeks a paused HTML timeline frame by frame for deterministic video; the person edits the same files in the Studio preview. Use it unless another framework or plain browser recording is requested. Run `npx hyperframes <command>` (`/hyperframes-cli`); for a new video, `npx hyperframes usage --json` reports remaining plan usage (say "unknown" when it is).

`index.html` is the root composition: it declares the video's variables and mounts one scene per sub-composition from `compositions/`. Media and fonts live in `assets/`. A new project: `npx hyperframes init <dir>`. A website as the subject: `npx hyperframes capture <url> --json`.
`index.html` is the root composition: it declares the video's variables and mounts one scene per sub-composition from `compositions/`. Media and fonts live in `assets/`. Start with `npx hyperframes init <dir>`; for a website, `npx hyperframes capture <url> --json`.

Build what was asked: no voiceover or captions and no new aspect ratio unless the request or the source calls for them; a film over ~15 s that tells something gets music and sound on its visible actions unless the person asked for silence (`references/sound.md`). A new video is 1920×1080 at 30 fps. A question, a hold or a loose idea gets an answer or a proposal, not an edit. Before hand-writing a named effect, transition, caption style, chart or card, search the registry (`/hyperframes-registry`). Any media (a presenter or avatar, footage, voice, music): `/media-use`, which says when HeyGen is needed and what is free. Show real things from their source (the product's screens, the brand's logo, a real place's imagery); draw only what has none.

Expand Down Expand Up @@ -42,6 +42,7 @@ Studio edits the tags you write.

## Work loop

- [Local video prerequisites](../hyperframes-cli/references/doctor-browser.md).
- An existing project: `npx hyperframes timeline --json` shows what plays when; before any change, `npx hyperframes history --since mine --who <you>` shows what the person changed since your last turn: build on it (`/hyperframes-cli`).
- A new film over ~15 s that tells something: its type's file (below), then `references/story.md`: three storylines that are three different films, in words only; the person picks unless they asked for the file or no stops. Then `SPEC.md` (`references/spec.md`): every adjective as a number, the defaults banned by name, the shots by frame.
- After your last edit: `npx hyperframes check --json`; fix every error, weigh every warning. A film: `npx hyperframes snapshot --review` and `references/review.md`, ending in `REVIEW.md`. A small edit: snapshot what you changed (`--at`, `--range`, `--composition`) and look before you reply.
Expand Down
Loading