diff --git a/AGENTS.md b/AGENTS.md index 6e2159ef13..584fd61149 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -80,7 +80,7 @@ skills/ → AI agent skill definitions - **Package manager**: bun (not pnpm, not npm for workspace operations) - **Commit format**: Conventional commits (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`) - **TypeScript**: Avoid `any` and `as T` assertions. Prefer type guards and narrowing. -- **Compositions**: HTML files with `data-*` attributes. Clips need `class="clip"`. GSAP timelines must be paused and registered on `window.__timelines`. +- **Compositions**: HTML files with `data-*` attributes. Clips need `class="clip"`. Each composition registers **exactly one** paused GSAP timeline on `window.__timelines`. Don't nest your own paused sub-timelines into it: a paused child never advances when the root is seeked, so the render comes out blank. - **Frame Adapters**: Animation runtimes plug in via the seek-by-frame adapter pattern. GSAP is the primary adapter. - **Deterministic rendering**: No `Date.now()`, no unseeded `Math.random()`, no render-time network fetches. diff --git a/CLAUDE.md b/CLAUDE.md index f46ed0d658..97beeb04a0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -111,7 +111,7 @@ skills/ → AI agent skill definitions - **Package manager**: bun (not pnpm, not npm for workspace operations) - **Commit format**: Conventional commits (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`) - **TypeScript**: Avoid `any` and `as T` assertions. Prefer type guards and narrowing. -- **Compositions**: HTML files with `data-*` attributes. Clips need `class="clip"`. GSAP timelines must be paused and registered on `window.__timelines`. +- **Compositions**: HTML files with `data-*` attributes. Clips need `class="clip"`. Each composition registers **exactly one** paused GSAP timeline on `window.__timelines`. Don't nest your own paused sub-timelines into it: a paused child never advances when the root is seeked, so the render comes out blank. - **Frame Adapters**: Animation runtimes plug in via the seek-by-frame adapter pattern. GSAP is the primary adapter. - **Deterministic rendering**: No `Date.now()`, no unseeded `Math.random()`, no render-time network fetches. diff --git a/packages/cli/src/templates/_shared/AGENTS.md b/packages/cli/src/templates/_shared/AGENTS.md index 31ae625c33..d7d3a2e69a 100644 --- a/packages/cli/src/templates/_shared/AGENTS.md +++ b/packages/cli/src/templates/_shared/AGENTS.md @@ -90,11 +90,15 @@ Fix all errors before presenting the result. Warnings should be reviewed before 1. Every timed element needs `data-start`, `data-duration`, and `data-track-index` 2. Elements with timing **MUST** have `class="clip"` — the framework uses this for visibility control -3. Timelines must be paused and registered on `window.__timelines`: +3. Register **exactly one** paused timeline per composition on `window.__timelines`: ```js window.__timelines = window.__timelines || {}; window.__timelines["composition-id"] = gsap.timeline({ paused: true }); ``` + Only that registered timeline is paused. Don't build scene timelines as + `gsap.timeline({ paused: true })` and `.add()` them into it — a paused child + never advances when the root is seeked, so every frame renders the t=0 state + and the video comes out blank with no warning from lint, check or validate. 4. Videos use `muted` with a separate `