From 3977ab85203ec336c32af85d2dbbf68a4b3cb7f5 Mon Sep 17 00:00:00 2001 From: ukimsanov Date: Tue, 20 Oct 2026 02:57:04 -0400 Subject: [PATCH 1/6] feat(cli): open scaffolded agent instructions with what hyperframes is Agents asked to make a video choose from what is on disk. The AGENTS.md and CLAUDE.md that init writes now open with a plain statement of what the project is and that `hyperframes render` replaces a hand-built headless-browser and ffmpeg pipeline, and list `snapshot` beside preview, check, render and docs. A test pins that init writes both files from the template, and the CLI docs now say init creates them. Co-Authored-By: Claude Opus 5.5 --- docs/packages/cli.mdx | 6 ++-- packages/cli/src/commands/init.test.ts | 29 ++++++++++++++++++++ packages/cli/src/templates/_shared/AGENTS.md | 6 ++++ packages/cli/src/templates/_shared/CLAUDE.md | 6 ++++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/docs/packages/cli.mdx b/docs/packages/cli.mdx index 684a0a85150..9ff14de7a0e 100644 --- a/docs/packages/cli.mdx +++ b/docs/packages/cli.mdx @@ -126,8 +126,10 @@ v4 CSS-first patterns instead of v3 `tailwind.config.js` patterns. The browser runtime is meant for scaffolded projects and quick iteration — for offline or locked-down production renders, compile Tailwind to CSS and link the stylesheet. -After scaffolding, `init` checks and installs the core AI skills from the -current GitHub source. See [`skills`](#skills). +Every new project gets an `AGENTS.md` and an identical `CLAUDE.md`: they tell a +coding agent what HyperFrames is and which commands preview, check, snapshot and +render the video. After scaffolding, `init` checks and installs the core AI +skills from the current GitHub source. See [`skills`](#skills). ### `add` diff --git a/packages/cli/src/commands/init.test.ts b/packages/cli/src/commands/init.test.ts index 259d2837bee..764d91302dd 100644 --- a/packages/cli/src/commands/init.test.ts +++ b/packages/cli/src/commands/init.test.ts @@ -88,6 +88,35 @@ describe("hyperframes init flag rename", () => { } }); + // Agents pick a video tool from what is on disk, so the scaffold must say what HyperFrames is + // and list the loop an agent runs, under both file names agents look for. + it("bare init writes AGENTS.md and CLAUDE.md with the agent loop", () => { + const dir = mkdtempSync(join(tmpdir(), "hf-init-test-")); + const target = join(dir, "proj"); + const template = readFileSync( + new URL("../templates/_shared/AGENTS.md", import.meta.url), + "utf-8", + ); + try { + const res = runInit([target, "--non-interactive"]); + expect(res.status).toBe(0); + expect(readFileSync(join(target, "AGENTS.md"), "utf-8")).toBe(template); + expect(readFileSync(join(target, "CLAUDE.md"), "utf-8")).toBe(template); + for (const command of [ + "npx hyperframes preview --background", + "npm run check", + "npx hyperframes snapshot", + "npm run render", + "npx hyperframes docs ", + "https://hyperframes.heygen.com/llms.txt", + ]) { + expect(template).toContain(command); + } + } finally { + rmSync(dir, { recursive: true, force: true }); + } + }); + it("rejects a following flag when --example has no value", () => { const dir = mkdtempSync(join(tmpdir(), "hf-init-test-")); const target = join(dir, "proj"); diff --git a/packages/cli/src/templates/_shared/AGENTS.md b/packages/cli/src/templates/_shared/AGENTS.md index dae2884ab23..f7ee43ec207 100644 --- a/packages/cli/src/templates/_shared/AGENTS.md +++ b/packages/cli/src/templates/_shared/AGENTS.md @@ -1,5 +1,10 @@ # HyperFrames Composition Project +This folder is a [HyperFrames](https://hyperframes.heygen.com) video: HTML, CSS and seekable +animations (GSAP by default) that the `hyperframes` CLI previews in the browser and renders to +MP4. Rendering, frame capture and encoding are handled by `npx hyperframes render`; there is no +need to build a headless-browser or ffmpeg pipeline here. + ## Skills — USE THESE FIRST **Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions. @@ -42,6 +47,7 @@ npx hyperframes preview --background # agent-safe persistent Studio preview npx hyperframes preview --status # verify the persistent preview is listening npx hyperframes preview --stop # stop it when review is finished npm run check # lint + runtime + layout + motion + contrast (one command) +npx hyperframes snapshot --at 1,3,5 # PNG frames at those seconds, to look at before rendering npm run render # render to MP4 npm run publish # publish and get a shareable link npx hyperframes lint --verbose # include info-level findings diff --git a/packages/cli/src/templates/_shared/CLAUDE.md b/packages/cli/src/templates/_shared/CLAUDE.md index dae2884ab23..f7ee43ec207 100644 --- a/packages/cli/src/templates/_shared/CLAUDE.md +++ b/packages/cli/src/templates/_shared/CLAUDE.md @@ -1,5 +1,10 @@ # HyperFrames Composition Project +This folder is a [HyperFrames](https://hyperframes.heygen.com) video: HTML, CSS and seekable +animations (GSAP by default) that the `hyperframes` CLI previews in the browser and renders to +MP4. Rendering, frame capture and encoding are handled by `npx hyperframes render`; there is no +need to build a headless-browser or ffmpeg pipeline here. + ## Skills — USE THESE FIRST **Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions. @@ -42,6 +47,7 @@ npx hyperframes preview --background # agent-safe persistent Studio preview npx hyperframes preview --status # verify the persistent preview is listening npx hyperframes preview --stop # stop it when review is finished npm run check # lint + runtime + layout + motion + contrast (one command) +npx hyperframes snapshot --at 1,3,5 # PNG frames at those seconds, to look at before rendering npm run render # render to MP4 npm run publish # publish and get a shareable link npx hyperframes lint --verbose # include info-level findings From bcc28c96ffde02514f50db9e9971637ff33e5b39 Mon Sep 17 00:00:00 2001 From: ukimsanov Date: Tue, 20 Oct 2026 02:57:28 -0400 Subject: [PATCH 2/6] chore: describe the npm packages in plain words npm search ranks on description and keywords. The hyperframes package now says what it does ("Make videos with code and AI agents: write HTML, render MP4. Open source.") and lists the words people and agents search for. Core and studio had empty descriptions; producer and player gain keywords too. Co-Authored-By: Claude Opus 5.5 --- packages/cli/package.json | 18 +++++++++++++++++- packages/core/package.json | 9 ++++++++- packages/player/package.json | 7 +++++++ packages/producer/package.json | 9 +++++++++ packages/studio/package.json | 9 ++++++++- 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index bfaea0a2c6b..0a08f7d57dc 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,23 @@ { "name": "@hyperframes/cli", "version": "0.8.181", - "description": "HyperFrames CLI — create, preview, and render HTML video compositions", + "description": "Make videos with code and AI agents: write HTML, render MP4. Open source.", + "keywords": [ + "ai-agents", + "animation", + "claude-code", + "codex", + "cursor", + "gsap", + "html-to-video", + "hyperframes", + "motion-graphics", + "mp4", + "remotion-alternative", + "render", + "video", + "video-editor" + ], "license": "Apache-2.0", "repository": { "type": "git", diff --git a/packages/core/package.json b/packages/core/package.json index 28acc7b34fd..de6f8e1ba75 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,14 @@ { "name": "@hyperframes/core", "version": "0.8.181", - "description": "", + "description": "Core of the HyperFrames HTML-to-video framework: types, parsers, compiler, linter and runtime", + "keywords": [ + "animation", + "gsap", + "html-to-video", + "hyperframes", + "video" + ], "repository": { "type": "git", "url": "https://github.com/heygen-com/hyperframes", diff --git a/packages/player/package.json b/packages/player/package.json index 285cec59616..d5e8e739bc3 100644 --- a/packages/player/package.json +++ b/packages/player/package.json @@ -2,6 +2,13 @@ "name": "@hyperframes/player", "version": "0.8.181", "description": "Embeddable web component for HyperFrames compositions", + "keywords": [ + "html-to-video", + "hyperframes", + "video", + "video-player", + "web-component" + ], "repository": { "type": "git", "url": "https://github.com/heygen-com/hyperframes", diff --git a/packages/producer/package.json b/packages/producer/package.json index ae6a08881b1..ff6f7002649 100644 --- a/packages/producer/package.json +++ b/packages/producer/package.json @@ -2,6 +2,15 @@ "name": "@hyperframes/producer", "version": "0.8.181", "description": "HTML-to-video rendering engine using Chrome's BeginFrame API", + "keywords": [ + "ffmpeg", + "headless-chrome", + "html-to-video", + "hyperframes", + "mp4", + "render", + "video" + ], "repository": { "type": "git", "url": "https://github.com/heygen-com/hyperframes", diff --git a/packages/studio/package.json b/packages/studio/package.json index 5bd35f3062f..4ae41709097 100644 --- a/packages/studio/package.json +++ b/packages/studio/package.json @@ -1,7 +1,14 @@ { "name": "@hyperframes/studio", "version": "0.8.181", - "description": "", + "description": "Browser-based video editor for HyperFrames compositions: timeline, code editor and live preview", + "keywords": [ + "html-to-video", + "hyperframes", + "timeline", + "video", + "video-editor" + ], "repository": { "type": "git", "url": "https://github.com/heygen-com/hyperframes", From 3f73e396481dd9a18bdf5befad1f8699b5f28248 Mon Sep 17 00:00:00 2001 From: ukimsanov Date: Tue, 20 Oct 2026 02:57:29 -0400 Subject: [PATCH 3/6] docs(readme): give coding agents a one-line start The opening paragraph said what HyperFrames is but not how an agent starts. Add one line: install the skills, then ask the agent for a video. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4529ffdda70..f02579a0ed0 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ HyperFrames is an open-source framework for turning HTML, CSS, media, and seekable animations into deterministic MP4 videos. Use it locally with the CLI, from AI coding agents with skills, or as the rendering core behind hosted authoring workflows. +Using Claude Code, Codex, Cursor, or another coding agent? Run `npx hyperframes skills update` once, then ask your agent to make a video. + ## Quick Start ### With an AI coding agent From f74a1ff0c3acd3d37d8b4b5d91a48287567e79e5 Mon Sep 17 00:00:00 2001 From: ukimsanov Date: Tue, 20 Oct 2026 03:09:03 -0400 Subject: [PATCH 4/6] fix(cli): keep the scaffolded agent intro to what the folder is Inside a scaffolded project the agent already uses the CLI, so telling it not to build its own capture pipeline there adds nothing. The intro now only says what the folder is. Co-Authored-By: Claude Opus 5.5 --- packages/cli/src/templates/_shared/AGENTS.md | 3 +-- packages/cli/src/templates/_shared/CLAUDE.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/templates/_shared/AGENTS.md b/packages/cli/src/templates/_shared/AGENTS.md index f7ee43ec207..c14c26d327e 100644 --- a/packages/cli/src/templates/_shared/AGENTS.md +++ b/packages/cli/src/templates/_shared/AGENTS.md @@ -2,8 +2,7 @@ This folder is a [HyperFrames](https://hyperframes.heygen.com) video: HTML, CSS and seekable animations (GSAP by default) that the `hyperframes` CLI previews in the browser and renders to -MP4. Rendering, frame capture and encoding are handled by `npx hyperframes render`; there is no -need to build a headless-browser or ffmpeg pipeline here. +MP4. ## Skills — USE THESE FIRST diff --git a/packages/cli/src/templates/_shared/CLAUDE.md b/packages/cli/src/templates/_shared/CLAUDE.md index f7ee43ec207..c14c26d327e 100644 --- a/packages/cli/src/templates/_shared/CLAUDE.md +++ b/packages/cli/src/templates/_shared/CLAUDE.md @@ -2,8 +2,7 @@ This folder is a [HyperFrames](https://hyperframes.heygen.com) video: HTML, CSS and seekable animations (GSAP by default) that the `hyperframes` CLI previews in the browser and renders to -MP4. Rendering, frame capture and encoding are handled by `npx hyperframes render`; there is no -need to build a headless-browser or ffmpeg pipeline here. +MP4. ## Skills — USE THESE FIRST From bcb31606ec289ed4d3df60f8fab73ad974ddf47e Mon Sep 17 00:00:00 2001 From: ukimsanov Date: Tue, 20 Oct 2026 04:10:10 -0400 Subject: [PATCH 5/6] chore: keep npm metadata to the CLI package Internal packages are not searched on npm, and the init test only re-checked the template's own text. Co-Authored-By: Claude Opus 5.5 --- packages/cli/src/commands/init.test.ts | 29 -------------------------- packages/core/package.json | 9 +------- packages/player/package.json | 7 ------- packages/producer/package.json | 9 -------- packages/studio/package.json | 9 +------- 5 files changed, 2 insertions(+), 61 deletions(-) diff --git a/packages/cli/src/commands/init.test.ts b/packages/cli/src/commands/init.test.ts index 764d91302dd..259d2837bee 100644 --- a/packages/cli/src/commands/init.test.ts +++ b/packages/cli/src/commands/init.test.ts @@ -88,35 +88,6 @@ describe("hyperframes init flag rename", () => { } }); - // Agents pick a video tool from what is on disk, so the scaffold must say what HyperFrames is - // and list the loop an agent runs, under both file names agents look for. - it("bare init writes AGENTS.md and CLAUDE.md with the agent loop", () => { - const dir = mkdtempSync(join(tmpdir(), "hf-init-test-")); - const target = join(dir, "proj"); - const template = readFileSync( - new URL("../templates/_shared/AGENTS.md", import.meta.url), - "utf-8", - ); - try { - const res = runInit([target, "--non-interactive"]); - expect(res.status).toBe(0); - expect(readFileSync(join(target, "AGENTS.md"), "utf-8")).toBe(template); - expect(readFileSync(join(target, "CLAUDE.md"), "utf-8")).toBe(template); - for (const command of [ - "npx hyperframes preview --background", - "npm run check", - "npx hyperframes snapshot", - "npm run render", - "npx hyperframes docs ", - "https://hyperframes.heygen.com/llms.txt", - ]) { - expect(template).toContain(command); - } - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); - it("rejects a following flag when --example has no value", () => { const dir = mkdtempSync(join(tmpdir(), "hf-init-test-")); const target = join(dir, "proj"); diff --git a/packages/core/package.json b/packages/core/package.json index de6f8e1ba75..28acc7b34fd 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,14 +1,7 @@ { "name": "@hyperframes/core", "version": "0.8.181", - "description": "Core of the HyperFrames HTML-to-video framework: types, parsers, compiler, linter and runtime", - "keywords": [ - "animation", - "gsap", - "html-to-video", - "hyperframes", - "video" - ], + "description": "", "repository": { "type": "git", "url": "https://github.com/heygen-com/hyperframes", diff --git a/packages/player/package.json b/packages/player/package.json index d5e8e739bc3..285cec59616 100644 --- a/packages/player/package.json +++ b/packages/player/package.json @@ -2,13 +2,6 @@ "name": "@hyperframes/player", "version": "0.8.181", "description": "Embeddable web component for HyperFrames compositions", - "keywords": [ - "html-to-video", - "hyperframes", - "video", - "video-player", - "web-component" - ], "repository": { "type": "git", "url": "https://github.com/heygen-com/hyperframes", diff --git a/packages/producer/package.json b/packages/producer/package.json index ff6f7002649..ae6a08881b1 100644 --- a/packages/producer/package.json +++ b/packages/producer/package.json @@ -2,15 +2,6 @@ "name": "@hyperframes/producer", "version": "0.8.181", "description": "HTML-to-video rendering engine using Chrome's BeginFrame API", - "keywords": [ - "ffmpeg", - "headless-chrome", - "html-to-video", - "hyperframes", - "mp4", - "render", - "video" - ], "repository": { "type": "git", "url": "https://github.com/heygen-com/hyperframes", diff --git a/packages/studio/package.json b/packages/studio/package.json index 4ae41709097..5bd35f3062f 100644 --- a/packages/studio/package.json +++ b/packages/studio/package.json @@ -1,14 +1,7 @@ { "name": "@hyperframes/studio", "version": "0.8.181", - "description": "Browser-based video editor for HyperFrames compositions: timeline, code editor and live preview", - "keywords": [ - "html-to-video", - "hyperframes", - "timeline", - "video", - "video-editor" - ], + "description": "", "repository": { "type": "git", "url": "https://github.com/heygen-com/hyperframes", From d5978b15880c623b6a5e1476ed37bcec1f2317f6 Mon Sep 17 00:00:00 2001 From: ukimsanov Date: Tue, 20 Oct 2026 04:36:51 -0400 Subject: [PATCH 6/6] chore: context7.json so agents get the docs and the composition rules Indexes docs, skills, registry and examples only (no test fixtures), and hands agents five rules from AGENTS.md. Co-Authored-By: Claude Opus 5.5 --- context7.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 context7.json diff --git a/context7.json b/context7.json new file mode 100644 index 00000000000..26574f7a6d8 --- /dev/null +++ b/context7.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://context7.com/schema/context7.json", + "folders": ["docs", "skills", "registry", "examples"], + "excludeFolders": ["docs/public", "**/tests", "**/test", "**/fixtures", "**/node_modules"], + "excludeFiles": ["weekly-updates.mdx"], + "rules": [ + "Install the HyperFrames agent skills before writing a composition: `npx skills add heygen-com/hyperframes`, or in Claude Code `claude plugin marketplace add heygen-com/hyperframes` then `claude plugin install hyperframes@hyperframes`.", + "A composition is an HTML file whose root element has data-composition-id, data-width, data-height and data-duration. Timed elements use class=\"clip\" with data-start and data-duration.", + "Register one paused GSAP root timeline per composition on window.__timelines[\"\"]. The runtime seeks it frame by frame, so never play it yourself.", + "Rendering is deterministic: no Date.now(), no unseeded Math.random(), no network fetches at render time.", + "Check before rendering: `npx hyperframes lint`, `npx hyperframes check`, and `npx hyperframes snapshot --at 1,3,5` for frames. Make the MP4 with `npx hyperframes render --output video.mp4`." + ] +}