Skip to content

Commit d8f1af1

Browse files
committed
feat(capture): write AGENTS.md alongside CLAUDE.md + skill refinements from regression tests
Capture pipeline: - agentPromptGenerator now writes AGENTS.md + CLAUDE.md (drop legacy .cursorrules), matching the dual-file convention already used by the _shared templates in hyperframes init. AGENTS.md is picked up natively by Cursor, Codex, Gemini CLI, Windsurf, Aider, and Jules; CLAUDE.md covers Claude Code. Both files share the same content — a capture data inventory that points agents to the website-to-hyperframes skill. website-to-hyperframes skill refinements (derived from 8-site regression test): - Drop slash-command phrasing throughout SKILL.md and step-6-build.md so the skill works identically across Claude Code (slash), Cursor (auto-discover by description), and other agents. - Remove stale HANDOFF.md references from SKILL.md step-7 summary and reference table — matches the intent of the prior step-7 cleanup. - step-5-vo: specify narration.txt filename convention (pronunciation- substituted spoken text; distinct from SCRIPT.md the creative doc). - step-6 self-review adds three rules derived from actual lint warnings observed across the 8 regression runs: - Every <template> root needs data-start + data-duration (catches root_composition_missing_data_start/duration, seen in 4/8 runs). - Caption exits need a hard tl.set kill after tl.to(opacity:0), or per-word karaoke tweens can leave captions stuck on screen (caption_exit_missing_hard_kill). - No duplicate media nodes with identical src + start + duration, or the compiler discovers them twice (duplicate_media_discovery_risk). Housekeeping: - .gitignore: add cursor-tests/, basecamp-video/, projects/, videos/ — local regression-test scratch dirs that should never be committed. - Remove two broken symlinks from .claude/skills/ that pointed to paths which never existed in the repo (.claude/skills/ is already gitignored). Made-with: Cursor
1 parent 92a5ef4 commit d8f1af1

8 files changed

Lines changed: 32 additions & 17 deletions

File tree

.claude/skills/hyperframes-captions

Lines changed: 0 additions & 1 deletion
This file was deleted.

.claude/skills/hyperframes-compose

Lines changed: 0 additions & 1 deletion
This file was deleted.

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,11 @@ captures/
7878
*-ad/
7979
*-tour/
8080
*-brand/
81+
82+
# Local regression-test scratch directories (website-to-hyperframes runs).
83+
# These hold per-site captures, SCRIPT/STORYBOARD/DESIGN.md, compositions,
84+
# narration audio, rendered MP4s — all reproducible, never commit.
85+
cursor-tests/
86+
basecamp-video/
87+
projects/
88+
videos/

packages/cli/src/capture/agentPromptGenerator.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
/**
2-
* Generate CLAUDE.md (and .cursorrules) for captured website projects.
2+
* Generate AGENTS.md and CLAUDE.md for captured website projects.
3+
*
4+
* Writes the same content to both filenames so any AI agent auto-discovers it:
5+
* - AGENTS.md — universal convention (Cursor, Codex, Gemini CLI, Windsurf, Aider, Jules)
6+
* - CLAUDE.md — Claude Code convention
37
*
48
* This file generates a DATA INVENTORY that tells the AI agent what files
59
* exist and what they contain. The actual workflow lives in the
6-
* /website-to-hyperframes skill — this file points agents there.
10+
* website-to-hyperframes skill — this file points agents there.
711
*/
812

913
import { writeFileSync } from "node:fs";
@@ -32,8 +36,8 @@ export function generateAgentPrompt(
3236
hasShaders,
3337
detectedLibraries,
3438
);
39+
writeFileSync(join(outputDir, "AGENTS.md"), prompt, "utf-8");
3540
writeFileSync(join(outputDir, "CLAUDE.md"), prompt, "utf-8");
36-
writeFileSync(join(outputDir, ".cursorrules"), prompt, "utf-8");
3741
}
3842

3943
function buildPrompt(
@@ -104,7 +108,7 @@ function buildPrompt(
104108
105109
Source: ${url}
106110
107-
To create a video from this capture, use the \`/website-to-hyperframes\` skill.
111+
To create a video from this capture, use the \`website-to-hyperframes\` skill.
108112
109113
## What's in This Capture
110114

packages/cli/src/capture/scaffolding.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Project scaffolding helpers for the website capture pipeline.
33
*
44
* Handles .env file loading and HyperFrames project scaffold generation
5-
* (index.html, meta.json, CLAUDE.md).
5+
* (index.html, meta.json, AGENTS.md, CLAUDE.md).
66
*/
77

88
import { existsSync, writeFileSync, readFileSync } from "node:fs";
@@ -44,10 +44,10 @@ export function loadEnvFile(startDir: string): void {
4444
}
4545

4646
/**
47-
* Generate the project scaffold files: index.html, meta.json, and CLAUDE.md.
47+
* Generate the project scaffold files: index.html, meta.json, AGENTS.md, CLAUDE.md.
4848
*
4949
* Only creates files that don't already exist (index.html, meta.json).
50-
* Always generates CLAUDE.md via agentPromptGenerator.
50+
* Always (re)generates AGENTS.md + CLAUDE.md via agentPromptGenerator.
5151
*/
5252
export async function generateProjectScaffold(
5353
outputDir: string,
@@ -78,7 +78,7 @@ export async function generateProjectScaffold(
7878
);
7979
}
8080

81-
// Generate CLAUDE.md + .cursorrules (AI agent instructions — always, regardless of API keys)
81+
// Generate AGENTS.md + CLAUDE.md (AI agent instructions — always, regardless of API keys)
8282
try {
8383
const { generateAgentPrompt } = await import("./agentPromptGenerator.js");
8484
generateAgentPrompt(
@@ -92,8 +92,8 @@ export async function generateProjectScaffold(
9292
catalogedAssets,
9393
detectedLibraries,
9494
);
95-
progress("agent", "CLAUDE.md generated");
95+
progress("agent", "AGENTS.md + CLAUDE.md generated");
9696
} catch (err) {
97-
warnings.push(`CLAUDE.md generation failed: ${err}`);
97+
warnings.push(`AGENTS.md/CLAUDE.md generation failed: ${err}`);
9898
}
9999
}

skills/website-to-hyperframes/SKILL.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ Generate TTS audio, transcribe for word-level timestamps, and map timestamps to
7070

7171
## Step 6: Build Compositions
7272

73-
**Read:** The `/hyperframes` skill (invoke it — every rule matters)
73+
**Read:** The `hyperframes` skill (load it — every rule matters)
7474
**Read:** [references/step-6-build.md](references/step-6-build.md)
7575

7676
Build each composition following the storyboard. After each one: self-review for layout, asset placement, and animation quality.
@@ -83,7 +83,7 @@ Build each composition following the storyboard. After each one: self-review for
8383

8484
**Read:** [references/step-7-validate.md](references/step-7-validate.md)
8585

86-
Lint, validate, preview. Create a HANDOFF.md for multi-session continuity.
86+
Lint, validate, preview. Deliver the final render.
8787

8888
**Gate:** `npx hyperframes lint` and `npx hyperframes validate` pass with zero errors.
8989

@@ -117,5 +117,5 @@ Lint, validate, preview. Create a HANDOFF.md for multi-session continuity.
117117
| [step-4-storyboard.md](references/step-4-storyboard.md) | Step 4 — per-beat creative direction |
118118
| [step-5-vo.md](references/step-5-vo.md) | Step 5 — TTS, transcription, timing |
119119
| [step-6-build.md](references/step-6-build.md) | Step 6 — building compositions with self-review |
120-
| [step-7-validate.md](references/step-7-validate.md) | Step 7 — lint, validate, preview, handoff |
120+
| [step-7-validate.md](references/step-7-validate.md) | Step 7 — lint, validate, snapshot, preview |
121121
| [techniques.md](references/techniques.md) | Steps 4 & 6 — 10 visual techniques with code patterns (SVG drawing, Canvas 2D, 3D, typography, Lottie, video, typing, variable fonts, MotionPath, transitions) |

skills/website-to-hyperframes/references/step-5-vo.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Pick the voice that sounds most natural and conversational. Listen for pacing
1414

1515
Generate the full script as `narration.wav` (or `.mp3`) in the project directory.
1616

17+
**Also save the exact spoken text** — with pronunciation substitutions applied (e.g., `API``A P I`, `$2T``two trillion`) — as `narration.txt` in the same directory. This is the string passed to TTS, distinct from `SCRIPT.md` which is the human-readable creative doc. Having `narration.txt` makes it trivial to regenerate the audio later with a different voice without re-deriving the substitutions. Name it exactly `narration.txt` — not `narration-input.txt` or variations.
18+
1719
## Transcribe for word-level timestamps
1820

1921
```bash

skills/website-to-hyperframes/references/step-6-build.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ FONTS — use @font-face with the captured font files, NOT Google Fonts:
3030
3131
Read DESIGN.md for exact colors and Do's/Don'ts.
3232
Read techniques.md for animation code patterns.
33-
Invoke /hyperframes for composition structure rules.
33+
Load the `hyperframes` skill for composition structure rules.
3434
```
3535

3636
After each sub-agent finishes, verify the composition references `../assets/` — if it used inline SVGs or Google Fonts instead of the captured files, fix it before moving on.
3737

38-
Invoke the `/hyperframes` skill first — it has the rules for data attributes, timeline contracts, deterministic rendering, and layout. Everything below supplements those rules, not replaces them.
38+
Load the `hyperframes` skill first — it has the rules for data attributes, timeline contracts, deterministic rendering, and layout. Everything below supplements those rules, not replaces them.
3939

4040
---
4141

@@ -113,6 +113,9 @@ After building the composition, check WITH ACTUAL CODE:
113113
- [ ] No full-screen dark linear gradients (H.264 creates visible banding — use solid + localized radial glows)
114114
- [ ] Timeline registered: `window.__timelines["comp-id"] = tl`
115115
- [ ] Colors match DESIGN.md exactly (paste the HEX value, don't approximate)
116+
- [ ] **Every `<template>` root element** — not just `index.html`, but every sub-composition's root — has `data-start="0"` **and** `data-duration="<beat_seconds>"`. The linter warns `root_composition_missing_data_start` / `root_composition_missing_data_duration` when missing; without `data-duration` the runtime may infer `Infinity` on repeating animations and stall playback.
117+
- [ ] **Caption exits have a hard kill.** If you animate captions out with `tl.to(groupEl, { opacity: 0 }, group.end)`, follow it with `tl.set(groupEl, { opacity: 0, visibility: "hidden" }, group.end)` as a deterministic kill — per-word karaoke tweens can override the exit tween and leave captions stuck on screen. Linter: `caption_exit_missing_hard_kill`.
118+
- [ ] **No duplicate media nodes.** If the same image/video source is referenced twice with identical `data-start` + `data-duration`, the compiler discovers it twice and can double-render. Dedupe by using a single `<img>` with appropriate z-layering, or stagger the `data-start` values. Linter: `duplicate_media_discovery_risk`.
116119

117120
**If `skills/hyperframes-animation-map/` is installed**, run it:
118121

0 commit comments

Comments
 (0)