mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-12 23:29:50 +00:00
cb3d94c2a50b921bcca71445d3e3bc9dbfc35beb
50
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cb3d94c2a5 |
feat: add @hyperframes/shader-transitions package (#251)
## Summary
New `@hyperframes/shader-transitions` package that encapsulates WebGL shader transitions into a single `HyperShader.init()` call. Replaces ~200 lines of per-composition boilerplate that LLMs failed to wire correctly 60% of the time.
### API
```js
var tl = HyperShader.init({
bgColor: "#0a0a1a",
accentColor: "#6366f1",
scenes: ["scene1", "scene2", "scene3", "scene4", "scene5"],
transitions: [
{ time: 7.2, shader: "cross-warp-morph", duration: 0.7 },
{ time: 15.2, shader: "domain-warp", duration: 0.7 },
]
});
tl.from("#s1-title", { y: 50, opacity: 0, duration: 0.7 }, 0.3);
```
### What the library handles
- **13 shader programs**: domain-warp, ridged-burn, whip-pan, sdf-iris, ripple-waves, gravitational-lens, cinematic-zoom, chromatic-split, glitch, swirl-vortex, thermal-distortion, cross-warp-morph, light-leak
- **html2canvas** bundled as dependency (not CDN) — single script tag for CLI users
- **DOM-during-holds**: canvas hidden between transitions, GSAP animations play on live DOM
- **Async capture with pause/resume**: timeline pauses during capture, resumes after textures uploaded — prevents progress tween from running ahead
- **Accent color theming**: `accentColor` derives dark/mid/bright uniforms. Burns, glows, leaks match the composition palette
- **Graceful degradation**: falls back silently when WebGL unavailable
### Code quality (from 3 review agents)
- No `!` non-null assertions — all WebGL creation calls throw on failure
- Vertex shader compiled once, cached across all programs
- Uniform/attribute locations cached per program via WeakMap (not looked up every frame)
- Captured canvases freed after texture upload (8MB each)
- Single timeline creation (was creating two, discarding one)
- Shared `tickShader()` render callback (was copy-pasted)
- `.finally()` for DOM restore in capture (was duplicated in `.then`/`.catch`)
- `parseHex` validates input (was silently producing NaN on invalid hex)
- Dead `ND`/`CP` shader library exports removed
### Shader-compatible CSS rules (transitions.md)
6 rules for compositions using shader transitions:
1. No `transparent` in gradients (canvas interpolates through black)
2. No gradient backgrounds on elements < 4px
3. No CSS variables on captured elements
4. `data-no-capture` for uncapturable decoratives
5. No gradient opacity < 0.15
6. Every `.scene` must have explicit `background-color` matching `bgColor`
### Build output
- IIFE (~214KB with html2canvas bundled, ~65KB gzipped) — `window.HyperShader`
- ESM + CJS + TypeScript declarations
- tsup build following `@hyperframes/player` conventions
## Test plan
- [ ] `bun run build` succeeds (includes shader-transitions)
- [ ] `bunx oxlint packages/shader-transitions/src/` — 0 errors
- [ ] Create a composition using `HyperShader.init()` — verify transitions fire, DOM animations play, accent colors match
- [ ] Test graceful degradation: composition works without WebGL (no transitions, no crash)
- [ ] Verify pause/resume: scrub to transition boundary — no jump in progress
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||
|
|
5de2af5bde |
feat(skills): improve hyperframes composition quality rules (#250)
## Summary
Overhaul the hyperframes composition skill based on 26 eval rounds (~100 generated compositions). The goal: prevent known AI design tells and composition bugs while giving the LLM maximum creative freedom.
### Typography (`fonts.md` → `typography.md`)
- Two-tier banned font list (32 fonts): tier 1 bans training-data defaults, tier 2 bans the reflex replacements
- Font discovery script: queries Google Fonts API, 5 dynamic categories, top 5 randomized per run
- Selection philosophy: register-first thinking, cross-check assumptions
### Google Fonts on-demand (`deterministicFonts.ts`)
- Any Google Font works without pre-bundling — compiler fetches woff2 at compile time
- Cached to `~/.cache/hyperframes/fonts/<slug>/<weight>-<style>.woff2`
- Parallel woff2 fetches via `Promise.allSettled` (was sequential)
- Single `mkdirSync({ recursive: true })` per family (was `existsSync` x11)
- Skip redundant `readFileSync` when buffer is already in memory from fetch
### Layout rules (`SKILL.md`)
- Flexbox with gap for content text — prevents overlap from absolute positioning
- `position: absolute` reserved for decoratives only
- Cards/containers explicitly banned
### Background layer (`house-style.md`)
- 3-5 persistent decorative elements per scene (glows, ghost text, accent lines)
- All decoratives MUST have ambient GSAP animation — static decoratives banned
- WRONG/RIGHT code examples
### Transition rules (`SKILL.md`)
- Always use transitions, always entrance animations, exit animations banned except final scene
- WRONG/RIGHT code examples showing banned exit patterns
### Other
- Flash cut transition removed
- CLAUDE.md: `bun install` / `bun run build` / `bun run test` (was pnpm)
- house-style.md trimmed from 184 to ~80 lines
- SKILL.md trimmed from 364 to ~230 lines
## Test plan
- [ ] `bun install` succeeds, workspace links resolve
- [ ] `bun run build` succeeds
- [ ] `npx hyperframes lint` passes on existing compositions
- [ ] Generate a composition with `/hyperframes` skill — verify flexbox, background decoratives with animation, entrance-only animations, no banned fonts
- [ ] Verify Google Fonts on-demand: use a non-bundled font, run `npx hyperframes preview`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||
|
|
d86e4cb3c3 |
feat(skills): add layout-before-animation approach to hyperframes skill (#233)
Adds structured approach (what, structure, timing, layout, animate) and layout-before-animation guidance — build end-state CSS first, then add gsap.from() entrances and gsap.to() exits. Prevents unintentional overlap by making layout problems visible before adding motion. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
4c5b8e38a1 |
feat(skills): add typography and motion principles, fix validate $& bug (#228)
Add two new skill reference files that address measured LLM composition failures: - fonts.md: Typography principles — banned fonts, guardrails for violations (pairing two sans-serifs, defaulting to 400/700 weight), and guidance the LLM genuinely doesn't apply without being told (register switching, tension as meaning, easing direction as emotion). Includes Google Fonts API discovery script with 7-category multi-strategy query. - motion-principles.md: Motion design principles — guardrails for same-ease and same-speed defaults, y-axis entrance monotony, and guidance for build/breathe/ resolve scene structure, hard cuts as intentional transitions, visual composition rules for video-not-web density. Both files validated against baseline evals: 3 compositions created without guidance confirmed the LLM reaches for banned fonts (Inter, Cormorant Garamond, Playfair Display, Roboto Condensed), uses power2.out on 45-72% of tweens, enters 80%+ of elements from y-axis, and pairs multiple sans-serifs. Also: - Fix validate.ts $& replacement bug (runtime source containing $& caused String.prototype.replace to re-insert the matched <script src=""> tag) - Clean up font loading guidance across skills (compiler embeds automatically) - Update house-style.md to reference fonts.md Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
fc973ee2e8 |
feat(lint): add rules for missing data-start, template wrapper, and DOCTYPE
Three new lint rules that catch structural issues causing compositions to fail silently in preview: - root_composition_missing_data_start: Root composition needs data-start="0" for the runtime to begin playback - standalone_composition_wrapped_in_template: index.html should not be wrapped in <template> (only sub-compositions use that) - root_composition_missing_html_wrapper: index.html needs <!DOCTYPE html> and <html> wrapper for the bundler Also adds rawSource to LintContext so rules can inspect pre-template-stripped HTML, and isSubComposition to linter options so rules can distinguish root from sub-composition files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
85a76c0043 |
feat(cli): implement Docker rendering for deterministic output (#215)
## Summary - **The `--docker` flag was a no-op stub** — `renderDocker` called the same local `executeRenderJob` as `renderLocal`, no container was ever launched - Now `renderDocker` generates a Dockerfile, builds a versioned `hyperframes-renderer:<version>` image with Chrome/FFmpeg/fonts/chrome-headless-shell, and runs the render inside a container - Image is cached per CLI version — first render builds (~2 min), subsequent renders reuse it - Forces `linux/amd64` platform since chrome-headless-shell has no ARM Linux binary - Uses `execFileSync` (array form) throughout to prevent shell injection - Forwards `--quiet`, `--gpu`, and render config flags into the container - `Dockerfile.render` added as a reference for manual builds ## Test plan - [x] `hyperframes render --docker` builds image and produces valid MP4 - [x] Second run reuses cached image (no rebuild) - [x] `--quiet` suppresses container output while keeping stderr for errors - [x] Typecheck, lint, format all pass - [ ] Verify `--gpu` with `--docker` on a machine with GPU access 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
569513145b |
feat(skills): add WebGL shader transitions and restructure catalog (#213)
* feat(skills): add WebGL shader transitions and restructure catalog Add 14 WebGL fragment shader transitions to the transitions skill: domain warp dissolve, ridged burn, whip pan, SDF iris, ripple waves, gravitational lens, cinematic zoom, chromatic radial split, glitch, swirl vortex, thermal distortion, flash through white, cross-warp morph, and light leak (shader). Restructure catalog.md from a 1045-line monolith into a 105-line routing layer with 15 reference files. SKILL.md loads at 101 lines, catalog.md loads at 105 lines — reference files loaded on demand only for the transition type being implemented. Key additions: - Full WebGL setup boilerplate with media capture (images, video, object-fit: cover, live video re-upload during transitions) - Hard rules for shader transitions capturing all bugs found during development (Y-flip, preserveDrawingBuffer, fwidth, boomerang, tween proxy reuse, tl.call vs onComplete) - CSS vs Shader decision guide in SKILL.md - Visual pattern warning against repeating geometric patterns - Shader transitions slotted into mood/energy mapping tables - Noise libraries: quintic C2, ridged, erosion FBM, cosine palette Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor(skills): fold transitions into hyperframes skill Move transitions from a standalone skill (4th top-level) into hyperframes/references/transitions/, aligning with the consolidation in #211 that reduced 15 skills to 3. Fewer standalone skills means higher trigger reliability for multi-skill tasks. Also removes stale text-burn-dom.html reference from css-destruction.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
c47e710ffc |
feat(skills): add scene transitions skill with 35-type catalog (#212)
## What A scene transition selection framework and implementation catalog covering 35 transition types across 8 categories. ### transitions skill **SKILL.md** — Selection framework: - Energy → transition mapping (calm/medium/high) - Mood → transition mapping (warm, cold, editorial, tech, edgy, playful, dramatic, premium, retro) - Narrative position guidance (opening, between sections, climax, outro) - Blur intensity scaling by energy level - Configuration presets (snappy, smooth, gentle, dramatic, instant, luxe) **catalog.md** — Implementation reference: - GSAP code for all 35 transitions - Hard rules from real bugs (scene visibility, iframe compatibility, VHS clone pattern, z-index, overlay sizing) - Scene template ### Categories | Category | Transitions | |----------|------------| | Content-transforming | Push slide, vertical push, elastic push, squeeze, zoom through, zoom out, gravity drop, 3D flip | | Reveal/mask | Circle iris, diamond iris, diagonal split, clock wipe, shutter | | Dissolve | Crossfade, blur crossfade, focus pull, color dip | | Cover | Staggered blocks, horizontal blinds, vertical blinds | | Light | Light leak, overexposure burn, film burn | | Distortion | Glitch, chromatic aberration, ripple, VHS tape | | Pattern | Grid dissolve | | Instant | Flash cut, morph circle | ## Why Agents building multi-scene compositions were using the same opacity crossfade for every scene change regardless of video mood/energy. The transitions skill provides context-aware selection so a wellness video gets blur crossfades while a sports promo gets flash cuts and a cyberpunk event gets VHS distortion. ## How - SKILL.md follows writing-skills guide: description uses "Use when..." triggers, no workflow summary, under 500 words - catalog.md is heavy reference with table of contents - Hard rules consolidated from real rendering bugs discovered during 16 A/B eval comparisons - Mood mappings designed from a motion design perspective ## Test plan - [x] 16 A/B eval compositions comparing with/without skill across moods - [x] 39-scene transition catalog composition demoing every type - [x] Skill audit against writing-skills guide - [x] All transition types mapped to at least one mood - [x] Lint passes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
d8bffd41f9 |
feat(lint,skills): add caption/audio-reactive lint rules and skill guidance (#207)
## What Bumped all package versions to `0.2.2-alpha.4` and added five new lint rules for caption and GSAP animation quality checks. ## Why The new lint rules address common issues in HyperFrames compositions: - Caption overflow clipping when emphasis words are scaled above 1.0x - Text shadow artifacts on caption group containers with semi-transparent children - Mismatch between fitText maxWidth and scaled word dimensions - Imperceptible audio reactivity from single tweens instead of time-sampled animations - Scene layer visibility conflicts when relying only on opacity tweens ## How Added three new caption-specific lint rules in `captions.ts`: - `caption_overflow_clips_scaled_words` - detects `overflow: hidden` on caption containers when scripts scale words above 1.0x - `caption_textshadow_on_group_container` - flags textShadow tweens applied to group containers instead of individual words - `caption_fittext_scale_mismatch` - calculates effective width from fitText maxWidth × max scale factor and warns when it exceeds safe bounds Added two new GSAP lint rules in `gsap.ts`: - `audio_reactive_single_tween_per_group` - identifies audio-reactive captions using peak values instead of time-sampled loops - `scene_layer_missing_visibility_kill` - detects multi-scene compositions missing hard visibility kills after opacity exit tweens Enhanced documentation with new mask reveals guide and updated existing skills with overflow handling, scene management, and audio reactivity best practices. ## Test plan - [x] Lint rules tested against existing composition patterns - [x] Documentation updated with new techniques and constraints - [x] Version bumps applied consistently across all packages |
||
|
|
e9c2e6f772 |
fix(cli): resolve SyntaxError in bundled ESM output (#203)
Two issues prevented `npx hyperframes` from running: 1. The tsup banner declared `const __filename` which collided with esbuild's CJS-to-ESM `var __filename` shim. ESM strict mode rejects const+var redeclaration. Changed to `var` so both declarations coexist. 2. postcss (producer dependency) was not resolvable during bundling due to bun's isolated module layout. Added postcss as an external dependency of the CLI package. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
cb0b17062a |
feat(skills): add marker-highlight skill for animated text highlighting (#190)
## Summary - **New skill:** **`marker-highlight`** — integrates [MarkerHighlight.js](https://github.com/Robincodes-Sandbox/marker-highlight) into HyperFrames compositions. Canvas-based animated text highlighting with 5 drawing modes: marker pen, circle, burst, scribble, and sketchout. - **Studio fix:** added missing `captionSync` to useEffect dependency array (oxlint exhaustive-deps) - **Studio fix:** `loadOverrides` now checks `res.ok` before parsing, preventing 404 console noise on projects without captions ## Skill details The skill documents the non-obvious GSAP integration pattern discovered during development: 1. **One highlighter per container** — the library clears ALL `.highlight` divs from the shared parent on init, so multiple instances on sibling marks conflict 2. **`data-color`** **\+** **`data-original-bgcolor`** — prevents the CSS background-color flash that occurs when the library reads and clears the mark's background 3. **Canvas pre-draw + clear + reanimate** — `animate: false` pre-draws statically, canvases are hidden, then cleared and shown with `reanimateMark()` at trigger time for clean animated reveals 4. **`onReverseComplete`** **for rewind** — hides highlight divs when the timeline seeks backward past the trigger point ## Test plan - [ ] `npx hyperframes lint` passes on test-composition - [ ] Studio preview shows marker highlight on "something" at 1s, circle on "love" at 2.2s - [ ] Rewind past trigger points hides highlights - [ ] No 404 console errors for caption-overrides.json on non-caption projects [Screen Recording 2026-04-02 at 1.56.30 AM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.com/user-attachments/thumbnails/53b03f4e-538e-477a-b738-7a033b99a84e.mov" />](https://app.graphite.com/user-attachments/video/53b03f4e-538e-477a-b738-7a033b99a84e.mov) 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
5e2781b459 |
fix(studio): address caption designer PR feedback (#200)
* fix(studio): address caption designer PR feedback Fixes from review comments on feature/caption-designer (#180): - fix(generator): guard named colors in hexToRgba — "red", "transparent" no longer produce NaN rgba values - fix(sync): log auto-save failures instead of silently swallowing them - fix(sync): check res.ok before parsing caption-overrides response - refactor(components): extract Section, Row, inputCls into shared.tsx to eliminate duplication between CaptionPropertyPanel and CaptionAnimationPanel - fix(store): replace non-deterministic Date.now()+Math.random() ID with counter-based group IDs - fix(store): read selectedGroupId from state param instead of get() to avoid stale reads in batched set() calls - fix(overlay): remove cssScale multiplier from getBoundingClientRect coords — the browser already accounts for CSS transforms - docs(parser): add comment explaining the lazy ]; regex assumption Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): address remaining caption designer feedback Overlay: handle both per-word spans (generator output) and grouped text nodes (existing templates). Wraps text nodes into individual spans on demand so the overlay can target words in any caption format. Property panel: add Typography (font, size, weight, spacing) and Color (color, active, dim, opacity) sections alongside existing Position and Transform controls. Timeline: move caption timeline into a dedicated flex-shrink-0 section below the main timeline tracks instead of inside the scrollable area. Gives it fixed 60px height that's always visible. Caption overrides: classify color tweens by comparing target color to the dim baseline instead of relying on timeline position order. This handles compositions with custom color tweens correctly. App.tsx: remove polling interval, rely on runtime postMessage events for caption detection. Add clarifying comment on why useEffect is appropriate (external event subscription). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): restore cssScale in overlay coordinate conversion getBoundingClientRect() on iframe-internal elements returns coordinates in the iframe's native resolution (1920x1080), not the CSS-scaled display size. The cssScale multiplier is needed to convert to parent window coordinates. The earlier removal was incorrect — it only worked at 1:1 scale. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): fix reversed scaling on left-side corner handles Scale interaction used horizontal dx from start position, which goes negative when dragging left handles outward. Now uses distance from box center — dragging away from center increases scale regardless of which corner handle is used. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): make rotation respond to horizontal drag only Rotation handle sits directly above the word, so atan2-based rotation barely responds to left/right movement. Replace with linear horizontal mapping: drag right = clockwise, drag left = counter-clockwise, 200px = 90 degrees. Vertical movement is ignored. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): remove animation tab and typography/color from property panel Keep only Position (X, Y) and Transform (Scale, Rotation) controls. Remove tab switcher UI since there's only one view now. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: fix oxfmt formatting in CLAUDE.md and captions skill docs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
d36c1785b9 |
feat(captions): energy-based technique selection and mandatory quality checks (#176)
## Summary - Rewrite script-to-style mapping as an energy detection table (high → low) with mandatory animation requirements: karaoke baseline, 2+ highlight techniques, kinetic exits - Replace `tl.call()` per-frame audio-reactive pattern with group-level GSAP tweens — read peak bass/treble for each group's time range and modulate entrance intensity at build time, no per-frame callbacks needed - Add transcript quality check with automatic retry rules (>20% music tokens = retry with larger model) - Add caption word structure lint rule (`.caption-group` + `<span>`) for studio editor compatibility - Add multilingual model guidance and decision tree for model selection ## Test plan - [ ] Skill files render correctly as markdown - [ ] Cross-references between SKILL.md, dynamic-techniques.md, and transcript-guide.md resolve correctly - [ ] `dynamic-techniques.md` audio-reactive section uses `tl.to()`/`tl.set()` only, no `tl.call()` loops 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
ad2d63db32 |
feat(cli): skill install targets + remove custom install in favor of vercel-labs/skills (#177)
## Summary **Skill install targets (original):** - Add project-level skill install targets: Windsurf, Cline, Roo Code, Trae (opt-in via flag) - Split install logic into global vs project-level - Fix lint false positive: timed tags with `data-composition-id` no longer flagged by media rule **Skill system cleanup (folded from #189):** - Delete `install-skills.ts` (~485 lines) — remove custom installation wrapper entirely - Strip skill logic from `init` — no more project-level `.claude/skills/` copies, no `--skip-skills` flag; replaced with post-scaffold message: `npx skills add heygen-com/hyperframes` - Front-load SKILL.md trigger words — all 5 skill descriptions rewritten so activation language comes first (~150 chars) - Update CLAUDE.md — install instructions now point to [vercel-labs/skills](https://github.com/vercel-labs/skills) - Fix `.claude/settings.json` — pre-commit hook changed from `pnpm` to `bun` ## Test plan - [ ] `npx hyperframes skills` → "Unknown command skills" - [ ] `npx hyperframes init test --template blank --non-interactive --skip-transcribe` → prints `npx skills add heygen-com/hyperframes` - [ ] `grep -r "install-skills" packages/cli/src/` → no results - [ ] All 5 `skills/*/SKILL.md` have front-loaded descriptions 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
37404f23da |
feat(whisper+captions): language detection, audio-reactive captions, multilingual defaults (#175)
## Summary **Whisper improvements:** - Auto-detect language and switch from `.en` to multilingual model when needed - Detect speech onset in WAV to strip hallucinated words before speech begins - Merge whisper-cpp token fragments: contractions (`didn` + `'t` → `didn't`), split capitals (`C` + `aught` → `Caught`), dropped-g (`shin` + `in'` → `shinin'`) - Interpolate zero-duration word clusters for reliable karaoke timing **Captions skill updates (folded from #176):** - Rewrite script-to-style mapping as an energy detection table (high → low) with mandatory animation requirements: karaoke baseline, 2+ highlight techniques, kinetic exits - Replace `tl.call()` per-frame audio-reactive pattern with group-level GSAP tweens — read peak bass/treble for each group's time range and modulate entrance intensity at build time - Add transcript quality check with automatic retry rules (>20% music tokens = retry with larger model) - Add caption word structure lint rule (`.caption-group` + `<span>`) for studio editor compatibility **Multilingual defaults (folded from #186):** - Default whisper model changed from `small.en` to `small` to prevent silent translation of non-English audio - Added non-negotiable language rule to captions skill ## Test plan - [ ] `pnpm test` passes (contraction merging, fragment merging, zero-duration interpolation, speech onset) - [ ] Transcribe non-English audio — verify it transcribes in original language, not translates - [ ] Skill files render correctly, cross-references resolve - [ ] `dynamic-techniques.md` audio-reactive section uses `tl.to()`/`tl.set()` only, no `tl.call()` loops 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
159a2e7113 |
feat(skills): add dynamic caption techniques and split captions skill into references (#173)
## Summary - Split the captions skill from a single 611-line file into focused references: `SKILL.md` (core rules), `transcript-guide.md` (whisper/transcription), `dynamic-techniques.md` (animation patterns) - Add `audio-reactive` skill with "Content, Not Medium" constraint — steers away from generic visualizations (equalizer bars, spectrum analyzers, waveforms) toward content-grounded animation where audio drives *when* and *how much*, not *what to show* - Add initial dynamic caption technique selection by energy level ## Test plan - [ ] All skill files render correctly as markdown - [ ] Cross-references between files use correct relative paths - [ ] `audio-reactive/SKILL.md` contains the anti-pattern list and content-grounded examples 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
1e4c101fb4 | feat: lint for audio tag existingon found project audio (#169) | ||
|
|
0dcf73d62a |
feat: async skills install (#172)
## What
Added progress reporting to the skills installation process by converting synchronous operations to asynchronous ones and implementing progress callbacks.
## Why
The skills installation process can take a significant amount of time, especially when cloning repositories or running npm operations. Users need feedback about what's happening during the installation to understand progress and know the system hasn't frozen.
## How
- Converted `execFileSync` calls to a new `execFileAsync` function using promises
- Made all installation functions (`runSkillsAdd`, `gitClone`, `fetchRepo`, `fallbackInstall`) asynchronous
- Added an optional `onProgress` callback parameter to `installAllSkills` that accepts progress messages
- Integrated progress reporting in the `init` command by passing spinner message updates to the progress callback
- Added progress messages for key installation steps like "Installing {source} skills..." and "Cloning skill repositories..."
- Added "giget" to the external dependencies list in the build configuration
## Test plan
- [ ] Unit tests added/updated
- [ ] Manual testing performed
- [ ] Documentation updated (if applicable)
|
||
|
|
9d54192e83 | chore: remove pnpm lock (#171) | ||
|
|
116e6aa8e0 |
feat(skills): add audio visualizer effect with extraction script (#168)
* feat(skills): add audio visualizer effect with extraction script Adds reactive audio visualization patterns for HyperFrames: Script: extract-audio-data.py pre-extracts per-frame RMS amplitude and frequency band data via ffmpeg. Uses a 4096-sample FFT window for clean frequency resolution and per-band normalization across the full track so treble activity is visible alongside louder bass. Patterns: spectrum bars, mirrored waveform, pulsing circle, circular visualizer, background glow — all Canvas 2D driven from the GSAP timeline via tl.call() at each frame. Includes smoothing helper, band count guide, band ordering rules (horizontal: low-left high-right), and combining patterns section. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor(skills): replace prescriptive examples with data model + motion principles Removes five hardcoded draw functions that would get copy-pasted verbatim. Replaces with: - Clear data model docs (what rms and bands mean, how to index) - Rendering approach setup for Canvas 2D, WebGL/Three.js, and DOM - Motion principles (smoothing, value mapping, what makes it feel good) - Spatial mapping conventions (low-left/high-right, etc) The LLM invents the visualization; the skill teaches the data contract and motion constraints. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(skills): off-by-one in band slicing, add data loading, fix trigger - Fix exclusive slice end: high_bin clamped to n_bins (not n_bins-1) so the last FFT bin in each band is included - Add data loading section to skill doc (inline and fetch patterns) - Fix example JSON to show frame 0 at time 0.0 - Update description to trigger when audio is analyzed and music detected Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor(skills): require numpy, fix bugs, clean up skill doc Script rewrite: - numpy is now required (pure-Python DFT was unusable for real files) - Use np.frombuffer instead of struct.unpack (~10x less memory) - Precompute Hann window and band edges (were recalculated every frame) - Extract SAMPLE_RATE as module-level constant - Clamp band bins to prevent max() on empty slice - Validate --fps and --bands inputs Skill doc fixes: - Fix fetch loading example (was null ref on sync for-loop) - Remove redundant Canvas 2D section (was duplicate of Step 3) - Fix opening line (said "Canvas 2D" but doc covers 3 approaches) - Fix undefined W/H in example Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
e7283e5ce3 |
feat(skills): add gsap-effects skill with typewriter pattern (#158)
* feat(skills): add gsap-effects skill with typewriter pattern Distills typewriter text animation into a reusable reference: basic typewriter, blinking cursor, word rotation, appending words, and a characters-per-second timing guide. Uses GSAP TextPlugin. Also references the new skill from compose-video. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(skills): emphasize cursor must always blink when idle and sit flush Two key rules added to the typewriter skill: 1. Cursor must blink in every idle state (after typing, after clearing, during hold pauses) — a solid idle cursor looks broken. 2. No whitespace between text and cursor elements in HTML — any gap between the last character and the caret looks wrong. Also adds cursor-hide state for multi-line handoffs and updates word rotation example to include cursor state management. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(skills): backspace must delete from end, not front TextPlugin's text:{value:""} removes characters from the front, which looks wrong. Added a backspace helper that steps through substrings from right to left using tl.call(). Updated word rotation example to use it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(skills): handoffs must blink before typing, use margin for spacing Two lessons from testing: 1. Cursor handoffs need a blink pause — going hide→solid directly skips the idle state. Pattern: hide→blink→pause→solid→type→blink. 2. Use margin-left on a wrapper span for spacing between static and dynamic text. Flex gap spaces the cursor away, trailing spaces collapse. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(skills): enforce single visible cursor as a hard rule Only one cursor may be visible at a time. Multiple cursors on screen looks broken. Every other cursor must be cursor-hide. Promoted to rule #1 in the cursor section. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
256c7a74fe |
feat(cli): add gradient ASCII banner to init command (#156)
Displays a white → #74E1B9 → #6ADCFF gradient HYPERFRAMES banner using ANSI Shadow figlet font when running hyperframes init. Gracefully skips in non-TTY or no-color environments. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
9cbfec1eca |
feat(skills): add hyperframes-cli skill (#154)
* feat(skills): add hyperframes-cli skill for CLI workflow guidance Adds a new skill that teaches AI agents how to use the HyperFrames CLI (init, lint, dev, render, doctor). Previously, agents had no way to discover the CLI — the compose-video skill only covered HTML authoring. This led to agents searching for binaries, finding the monorepo, and running bun run studio manually instead of using npx hyperframes dev. Also registers the skill in init.ts so new projects get it bundled alongside hyperframes-compose and hyperframes-captions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor(cli): rename dev command to preview The command starts a preview server — "preview" describes what users are doing more accurately than "dev". Updates the command name, file name, all CLI references, docs, skills, and template CLAUDE.md. 22 files updated across CLI source, docs, skills, and templates. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(skills): replace stale dev reference with preview in CLI skill Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(docs): catch remaining dev references missed in rename - testing-local-changes.mdx: two inline command examples - troubleshooting.mdx: anchor link #dev → #preview, "dev server" → "preview server" - cli.mdx: "dev server" → "preview server" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
ef6225da1d |
feat(core): add fitTextFontSize utility for pixel-accurate text measurement (#152)
Add @chenglou/pretext dependency and fitTextFontSize() utility that uses canvas measureText to compute the largest font size that fits text within a given width. Replaces character-count heuristics with actual font-aware measurement. - New fitTextFontSize() in @hyperframes/core/text, exposed on window.__hyperframes - Generalized for all text elements (captions, titles, etc.), not just captions - Unit tests (mocked pretext) + browser integration test (real Chromium canvas) - Updated captions skill docs with usage, exit guarantee, and self-lint patterns Co-authored-by: James <james.russo@heygen.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
a97dc75702 |
fix(lint): detect GSAP animations targeting clip elements (tab crash) (#114)
* fix(lint): detect GSAP animations targeting clip elements (tab crash) The runtime manages clip visibility via inline styles. When GSAP also writes inline styles on the same element, both systems trigger style recalculations every frame, creating a runaway loop that crashes the browser tab. New rule gsap_animates_clip_element (error severity): - Builds map of all elements with class="clip" (by id and class) - Checks if any GSAP selector resolves to a clip element - Nested selectors like "#overlay .title" are correctly ignored - Merged into existing GSAP script loop (no redundant parsing) * fix: remove non-null assertions and add missing test coverage - Replace `!` assertions with optional chaining in lint.ts and tests - Add shouldBlockRender tests for --strict-all without --strict - Add clip element test for class-only detection (no id) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use optional chaining for array access in lintProject tests TypeScript's strict mode flags array indexing as possibly undefined. Use optional chaining and fallbacks instead of non-null assertions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
229538c622 |
fix: add media rendering guardrails to prevent silent failures (#112)
## Summary - **Lint rules** catch media elements missing `id` (renderer silently skips them), missing `src`, `preload="none"` (blocks renderer), and video nested in timed divs (freezes playback). Upgraded `video_nested_in_timed_element` from warning to error. - **Compiler** strips `preload="none"` from media during compilation. Runs parallel, cached keyframe interval analysis via ffprobe — warns on sparse keyframes (>2s) that cause seek failures and audio/video desync. Suggested ffmpeg command preserves audio (`-c:a copy`). - **Pre-render lint** lints `index.html` + all `compositions/*.html` sub-compositions before render via shared `lintProject()` helper. Warns by default; `--strict` blocks on errors, `--strict-all` blocks on errors + warnings. - **Render orchestrator** logs a hint to retry with `--workers 1` when parallel capture times out on video-heavy compositions. - **Refactor**: extracted `runFfprobe()` + `parseProbeJson()` helpers to deduplicate ~80 lines of spawn boilerplate across 3 ffprobe functions. Extracted `shouldBlockRender()` so strict flag tests exercise production code. Shared `lintProject()` used by both `lint` and `render` commands. ## Context Discovered during a real composition build session where: 1. `<audio>` without `id` rendered silently (preview worked fine because runtime queries `[data-start]`, but renderer queries `[id][src]`) 2. `<video>` inside timed `<div>` froze on first frame 3. `preload="none"` caused 45s renderer timeout 4. YouTube clips with sparse keyframes from `yt-dlp --download-sections` caused audio/video desync 5. Parallel workers timed out on video-heavy compositions ## Test plan - [x] Core: 365/365 tests passing (5 new lint tests) - [x] Engine: 24/24 tests passing - [x] CLI: 14/14 tests passing (7 lintProject + 7 shouldBlockRender) - [x] Lint + format hooks pass - [ ] Manual: create a composition with `<audio data-start="0" src="test.wav">` (no id) — verify `npx hyperframes lint` catches it - [ ] Manual: run `npx hyperframes render --strict` with lint errors — verify it blocks - [ ] Manual: run `npx hyperframes render --strict-all` with lint warnings — verify it blocks |
||
|
|
f0a8644208 |
feat(lint): add template_literal_selector rule (#107)
Detects querySelector/querySelectorAll calls that use template literal
variables (e.g. `${compId}`) inside script tags. The HTML bundler's
cheerio/css-what parser crashes on these during compilation, causing
silent fallback to raw HTML without runtime injection.
Severity: error (breaks bundling)
Fix: replace template literal with hardcoded composition ID string
|
||
|
|
476c20747d |
feat: add templates (#102)
## What
Adds 4 new composition templates and fixes structural issues across all templates.
### New templates
- **decision-tree** — animated flowchart with branching paths
- **kinetic-type** — bold kinetic typography promo
- **product-promo** — multi-scene product showcase with SVG assets (3 scenes)
- **nyt-graph** — animated data chart in NYT print editorial style
### Fixes across all templates
- GSAP updated from 3.12.2 → 3.14.2 (all templates, including warm-grain, swiss-grid, vignelli, play-mode)
- New templates restructured with proper root wrapper div, `data-duration`, sub-composition refs with `data-composition-id` / `data-width` / `data-height`
- nyt-chart: replaced `${compId}` template literal variables with hardcoded `"nyt-chart"` string — cheerio's css-what parser crashes on template literals during bundling, causing silent fallback to raw HTML without runtime injection
- nyt-chart: added DOM readiness retry for dynamically created SVG elements
- kinetic-type: removed external S3 audio URL
- All templates: GSAP script loaded in `<head>` before any scripts reference it
## Why
The new templates expand the range of content types available via `hyperframes init`. The fixes ensure all templates work correctly in the studio preview (bundler inlines sub-compositions and injects the runtime).
## Test plan
- [x] All 4 new templates render in studio preview
- [x] nyt-graph chart animates bars, line, and labels on playback
- [x] Existing templates unaffected (GSAP version bump is backwards compatible)
- [x] `hyperframes lint` passes on all templates
- [x] `generators.ts` updated with new template IDs
|
||
|
|
e3fad3029c |
feat(skill): add data-in-motion guide and house style refinements (#91)
data-in-motion.md — minimal guide for data/stats in video: - Visual continuity: related data stays in same visual space - Numbers need visual weight: pair metrics with fills/shapes - Avoid web patterns: no pie charts, dashboards, axes, legends house-style.md refinements from eval iterations: - Layout approach variety (step 4 in Before Writing HTML) - Explicit weight contrast requirement - SVG illustration anti-default - Overlap anti-default - Ambient motion variety (not always zoom) SKILL.md — added reference to data-in-motion.md Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
238962adff |
fix(skill): house style anti-defaults for SVG, overlap, and zoom (#68)
## Summary - Anti-default: don't draw real-world objects with SVG paths — they look crude. Geometric shapes and abstract forms only. - Anti-default: every element needs clear space — overlapping text is always ugly. - Replaced zoom-in monoculture in choreography — now offers 6 ambient motion options instead of always zooming. - Added scene pacing: build/breathe/resolve phases. Follow-up to the house style PR (#59, merged). These fixes came from visual review of 20+ eval compositions. ## Test plan - [ ] Generate a composition with a sparse prompt and verify no SVG illustrations of real objects - [ ] Verify elements don't overlap in generated compositions - [ ] Verify ambient motion varies (not always zoom-in) 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
f8fad54261 |
feat(skill): house style guide for compose-video (#59)
* feat(cli): non-interactive by default, --human-friendly for UI Following ElevenLabs CLI pattern: default mode is agent-friendly (flag-driven, plain text output, fail fast on missing args). Interactive clack UI is opt-in via --human-friendly. Init command: - --template required in default mode (errors with example if missing) - --video / --audio flags for media input - --skip-skills / --skip-transcribe to control optional steps - --human-friendly enables the existing interactive prompts - --help shows examples for every flag combination - Transcription runs automatically in default mode (unless --skip-transcribe) - Plain console.log output, process.exit(1) on errors Skills command: - Added --human-friendly flag - Added examples to --help output Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): improve --help documentation and add --yes/--check to upgrade - upgrade: add --yes and --check flags to skip interactive prompt - benchmark: clarify description — preset fps/quality/worker configs - browser: describe each subcommand (ensure/path/clear) in help - docs: list available topics inline in --help output Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(skill): add house style guide with motion defaults, palettes, and anti-defaults When no visual-style.md is provided, compose-video now follows house-style.md for professional output quality. Includes: - Motion: easing variety, timing, entrance patterns, choreography - Sizing: text scale contrast, element fill, travel distance - Visual depth: gradient/shadow/texture guidance - Typography: weight contrast, tracking, case - Anti-defaults: table of generic AI patterns to avoid - 72 curated color palettes across 9 categories - Content interpretation: generate real content, not prompt text Eval-validated across 5 iterations with 50+ test compositions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(skill): add container anti-default and typography guidance - Anti-default: discourage card/container patterns in favor of content placed directly on canvas (professional video style vs web UI style) - Typography section: weight contrast, deliberate case, tracking, one typeface at two weights - Visual depth: softened to avoid templating (content-appropriate, not every-composition-the-same) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(skill): add scene pacing guidance to house style Three-phase composition structure: build (staggered entrances), breathe (subtle motion to keep holds alive), resolve (fast exits with intention). Prevents front-loading all animation into the first second and dead static holds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(skill): replace zoom-in monoculture with ambient motion variety The viewport scale and end emphasis code examples were being copied verbatim to every composition. Now offers 6 ambient motion options (pan, rotation, scale in/out, parallax, color shift, stillness) and 4 ending options instead of always zooming. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
25f4af428e |
feat(cli): agent-friendly CLI — non-interactive by default (#57)
* feat(cli): non-interactive by default, --human-friendly for UI Following ElevenLabs CLI pattern: default mode is agent-friendly (flag-driven, plain text output, fail fast on missing args). Interactive clack UI is opt-in via --human-friendly. Init command: - --template required in default mode (errors with example if missing) - --video / --audio flags for media input - --skip-skills / --skip-transcribe to control optional steps - --human-friendly enables the existing interactive prompts - --help shows examples for every flag combination - Transcription runs automatically in default mode (unless --skip-transcribe) - Plain console.log output, process.exit(1) on errors Skills command: - Added --human-friendly flag - Added examples to --help output Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): improve --help documentation and add --yes/--check to upgrade - upgrade: add --yes and --check flags to skip interactive prompt - benchmark: clarify description — preset fps/quality/worker configs - browser: describe each subcommand (ensure/path/clear) in help - docs: list available topics inline in --help output Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
f4367d5726 |
feat(cli): add whisper transcription and template improvements (#53)
* feat(cli): add whisper transcription to init flow New modules: - whisper/manager.ts: download/cache whisper.cpp binary + model (~/.cache/hyperframes/whisper/) - whisper/transcribe.ts: extract audio, run whisper, save transcript.json Init flow changes: - "Got a video or audio file?" now accepts audio-only files (mp3, wav, m4a) - "Generate captions from audio?" prompt after file selection - Transcription produces transcript.json in project root - Graceful fallback if whisper/ffmpeg unavailable Supports: macOS ARM64/x86, Linux x86_64. Downloads whisper.cpp v1.7.3 from GitHub releases and ggml-base.en model from Hugging Face. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): use brew/system whisper instead of downloading binaries whisper.cpp doesn't ship pre-built macOS/Linux CLI binaries. Use brew install whisper-cpp on macOS (auto-installs if brew available), system PATH lookup otherwise. Model still downloaded from Hugging Face. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): simplify whisper install — detect or instruct, don't build Remove build-from-source complexity. If whisper-cpp is found on PATH, use it. If not, show install instructions instead of blocking: "To generate captions, install whisper-cpp: brew install whisper-cpp" The transcription prompt only appears when whisper is available. When it's not, the user sees the install command and can re-run init. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cli): auto-install whisper via brew or build from source ensureWhisper() now tries 4 strategies in order: 1. System PATH (whisper-cli or whisper already installed) 2. Homebrew (macOS: brew install whisper-cpp) 3. Build from source (git clone + cmake, ~30-60s) 4. Show install instructions as last resort Init flow always asks "Generate captions?" — whisper is installed automatically in the background if needed. No user intervention required on macOS with Xcode CLI tools or any system with git+cmake. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): add window.__timelines guard to all templates The studio bundler doesn't always initialize window.__timelines before template scripts run, causing "Cannot set properties of undefined" errors. Add defensive guard to every template. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cli): patch template captions with actual transcript data After scaffolding, if transcript.json exists, replace the hardcoded word array in the template's captions composition with the real transcript data. The template's caption animation and styling are preserved — only the word data changes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): show install notice when whisper needs to be installed When whisper-cpp isn't found, show an info message before the spinner: "whisper-cpp not found — installing automatically..." Then the spinner shows "Installing whisper-cpp (this may take a moment)..." Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): add muted and playsinline to all template video elements The framework requires video elements to have muted and playsinline attributes. All four templates were missing these, causing video to not play in the studio preview. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): flat asset structure + separate audio tracks in templates Assets: video, images, fonts all go at project root (not assets/ or fonts/ subdirectories). The studio preview can't resolve relative paths from subdirectories due to the /preview URL suffix. Audio: added <audio> elements alongside muted <video> in all 4 templates so the video's audio plays back. The framework requires muted video + separate audio element. Removed assets/ and fonts/ directory creation from scaffoldProject. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): inject base tag for asset resolution in preview The preview iframe serves bundled HTML from /api/projects/:id/preview but relative asset paths (video.mp4, font.woff2) resolve to the wrong URL without a <base> tag. Now injects <base href="/api/projects/:id/preview/"> so relative paths route through the static asset handler. Also adds proper MIME types for video, audio, image, and font files served from the preview asset route. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): serve HyperFrames runtime in dev mode The preview runtime script had an empty src — the framework never loaded, so video playback and clip lifecycle didn't work. Now auto-detects packages/cli/dist/hyperframe-runtime.js and serves it at /api/runtime.js. No env var needed in dev mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): filter whisper special tokens from transcript Use --output-json instead of --output-json-full to avoid special tokens like [_TT_485] and [BLANK_AUDIO]. Also filter remaining bracket tokens when building the word array for captions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): use --output-json-full for word-level timestamps --output-json only produces segment-level timing (no tokens). --output-json-full is required for word-level timestamps that the captions template needs. Special tokens are filtered out by the patchTranscript function. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cli): patch template durations to match uploaded video Templates now use __VIDEO_DURATION__ placeholder that gets replaced with the actual probed video duration. All data-duration values on the root composition, video, audio, and caption clips are updated. Without a video, defaults to 10 seconds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): merge punctuation tokens with preceding word Whisper outputs punctuation (. , ! ?) as separate tokens. These appeared as standalone words in captions, sometimes in the wrong group. Now merged with the preceding word during transcript normalization. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): match both TRANSCRIPT and script variable names in templates Three templates use `const TRANSCRIPT = [...]` while warm-grain uses `const script = [...]`. The patchTranscript function now matches both. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): security and template fixes - Replace shell injection risk (execSync rm) with unlinkSync in transcribe.ts - Add GIT_TERMINAL_PROMPT=0 to whisper buildFromSource git clone - Fix hardcoded data-duration="18" in warm-grain captions template - Add data-start="0" to root compositions in swiss-grid, vignelli, warm-grain - Add data-start="0" to warm-grain grain-overlay composition - Deduplicate hasFFmpeg: remove from init.ts, import from whisper/manager.ts - Add my-video/ and packages/studio/data/ to .gitignore Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): format warm-grain captions and fix TS nullability errors - Format warm-grain/compositions/captions.html - Add optional chaining on token.offsets (may be undefined) - Use intermediate variable for lastWord to satisfy TS strict checks Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cli): add blank template option, smart defaults for video vs audio - Blank template: minimal scaffolding (root composition, video, audio, GSAP timeline) with __VIDEO_SRC__ and __VIDEO_DURATION__ placeholders - Template defaults: video uploads default to "blank" (user brings their own content), audio-only defaults to "warm-grain" (motion graphics template since there's no video to show) - Audio-only projects now tracked with isAudioOnly flag Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): address whisper review feedback - Clean stale builds: if BUILD_DIR exists but no binary, nuke and retry - Build failures clean up BUILD_DIR so next attempt starts fresh - patchTranscript regex scoped within <script> blocks to prevent matching across block boundaries - Removed hardcoded model size hint (~148MB) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): add missing rmSync import to whisper manager Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: remove test project and lock file Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): address review items 7-12 — execFileSync, build diagnostics, WAV verification - manager.ts: replace all execSync with execFileSync to prevent command injection - manager.ts: capture cmake stderr and include in build failure error message - transcribe.ts: verify WAV is 16kHz mono via ffprobe before passing to whisper - init.ts: replace fragile JSON formatting with JSON.stringify(words, null, 2) - init.ts: fix default duration from "10" to "5" matching DEFAULT_META - init.ts: add probeAudioDuration() and --audio/--skip-transcribe flags - init.ts: extract finalizeProject() to reduce code path duplication - init.ts: wire transcription into non-interactive path Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
5fceab9279 |
feat(cli): add skills install command and init integration (#48)
* fix(ci): publish CLI from temp copy to avoid workspace mutation Copy packages/cli to a temp directory before renaming to "hyperframes" for publish. Avoids corrupting the workspace if the job fails mid-way. Addresses review feedback on #47. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): resolve leftover conflict markers in publish.yml Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cli): add skills install command Adds `hyperframes skills install` to download and install HyperFrames and GSAP skills globally to ~/.claude/skills/. Also adds `hyperframes skills list` to show installed skills. - HyperFrames skills: bundled in CLI dist, copied from dist/skills/ - GSAP skills: cloned from github.com/greensock/gsap-skills - Cache: ~/.cache/hyperframes/gsap-skills/ (shallow clone, updated on install) - Handles overwriting existing skills (removes before copy) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor(cli): simplify skills to flat command `hyperframes skills` directly installs + shows summary. No subcommands needed — list was redundant since install already prints all installed skills. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): scope skills summary to only HyperFrames and GSAP skills The summary now only lists skills installed by this command, grouped by source (HyperFrames vs GSAP), instead of listing everything in ~/.claude/skills/. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): correct dev path for bundled skills directory Path needed 4 levels up from cli/src/commands/ to reach repo root, not 3. Was resolving to packages/.claude/skills/ instead of .claude/skills/. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cli): support multiple AI coding tools for skills install Install to Claude Code, Gemini CLI, and Codex CLI by default. Use flags to target specific tools: hyperframes skills # claude + gemini + codex hyperframes skills --cursor # cursor only (project-level) hyperframes skills --claude # claude only Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cli): move skills to repo root, support multi-CLI install - Move skills from .claude/skills/ to skills/ (tool-agnostic location) - Install to Claude Code, Gemini CLI, Codex CLI by default - Add --claude, --gemini, --codex, --cursor flags for targeting specific tools - Update build script to copy from skills/ instead of .claude/skills/ Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add infographics skill for data visualization compositions Professional infographic design and animation patterns: - Typography hierarchy (hero stat, label, context) - Layout rules (grid-aligned, generous whitespace, 2-color max) - 5 infographic types: single stat, comparison, bar chart, progress, steps - Animation patterns: count-up, bar growth, entrance choreography, exits - Narration sync (stat appears when narrator says the number) - Design constraints (no gradients, no shadows, no clip art) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add evals for infographics skill Three eval scenarios testing design quality and animation correctness: 1. Single stat — count-up animation synced to narration 2. Comparison — before/after reveal with visual hierarchy 3. Process steps — sequential reveal with dimming Each eval has PASS/FAIL criteria covering: composition structure, design rules (typography, layout, color), animation patterns (timing, easing, choreography), and anti-patterns. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: remove infographics and transitions skills, add asset-management Removed skills that don't add value beyond model knowledge: - infographics: model already produces equivalent output without it - transitions: patterns are derivable from compose-video constraints Added: - asset-management: organize user-uploaded files into assets/ and fonts/ - Typography section in compose-video: min font sizes, font loading (Google Fonts + local @font-face), weight pairing, font-display:block - Assets section in compose-video: project structure with assets/ and fonts/ directories, path rules, CORS, "check before creating" rule Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: consolidate skills to 3, split compose-video under 500 lines Removed skills that don't add value beyond model knowledge: - media: duplicates compose-video - social-media: platform safe areas are the only unique content - infographics: model produces equivalent output without it - transitions: patterns derivable from compose-video Remaining skills (3): - compose-video: core framework contract (452 lines, under 500 limit) - patterns.md: PiP, title card, slideshow examples (loaded on demand) - typography-and-assets.md: font loading, sizes, asset paths (on demand) - captions: tone-adaptive caption styling from script analysis - asset-management: organize uploaded files into project directories Rewrote captions skill to focus on style detection from transcript content (per-word styling, tone mapping) rather than mechanical rules. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cli): create assets/ and fonts/ directories on init - scaffoldProject now creates assets/ and fonts/ directories - Video files are placed in assets/ instead of project root - Template __VIDEO_SRC__ placeholders resolve to assets/filename Aligns with the compose-video skill's project structure convention where user-provided media goes in assets/ and fonts in fonts/. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor(cli): fetch skills from GitHub repos instead of bundling Skills are now fetched directly from their source repos at runtime: - HyperFrames skills: github.com/heygen-com/hyperframes (skills/ dir) - GSAP skills: github.com/greensock/gsap-skills (skills/ dir) Both cached in ~/.cache/hyperframes/ and updated on each run. Removed skills bundling from build:copy step. Requires the hyperframes repo to be public for HyperFrames skills to install. GSAP skills work immediately (public repo). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cli): install skills automatically during init After scaffolding a new project, `hyperframes init` now runs `hyperframes skills` to install HyperFrames and GSAP skills. Best-effort — if skill installation fails (no git, no network), project creation still succeeds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cli): show skills install feedback during init Added installAllSkills() export for programmatic use by init. Init now shows a spinner and result message: "11 AI skills installed (Claude Code, Gemini CLI, Codex CLI)" Falls back gracefully if git or network unavailable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cli): let users select which AI tools to install skills for Interactive init now shows a multi-select prompt: "Install AI coding skills for: Claude Code, Gemini CLI, Codex CLI, Cursor" Users can deselect tools they don't use or add Cursor (off by default). Non-interactive mode still installs to all default targets. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): prevent git credential prompt from hanging skills install Set GIT_TERMINAL_PROMPT=0 so git clone/pull fails immediately on private repos instead of hanging for username/password input. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): show skipped skill sources and accurate counts Skills install now reports which sources failed (e.g., private repo) and only counts skills that actually installed. Prompt text simplified to "Install skills for:". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): clean up skills command output - Skipped sources shown as dim text, not error with full command - Summary shows "Skipped: HyperFrames (repo not accessible)" - Outro says "ready" not "installed" - Shows "No skills installed" if everything failed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): clarify partial skill install in outro message When some sources fail, the outro now says which skills are ready and which are unavailable, instead of a misleading total count. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: remove planning docs and test scaffolding Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: remove eval projects and test examples Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: remove remaining test project data Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): use generic source names in skills install outro message Replace hardcoded "GSAP skills ready. HyperFrames skills unavailable." with a dynamic message listing which sources succeeded and which were skipped, so the message stays correct as sources change. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): address review feedback on skills install - Lazy process.cwd() for Cursor target (getter, not module-load) - Track overwritten skills (logged in install output) - Add --skip-skills flag to init for agent-friendly non-interactive use - Guard both interactive and non-interactive paths with skipSkills Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): remove assets/ and fonts/ directories from init Video files go to project root, not assets/. Removes assetsDir, fonts/ directory creation, and assets/ prefix from video path. Flat project root convention consistent with compose-video skill. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): address review items 5, 6, 13 — execFileSync, resilient cache, clear counting - Replace all execSync with execFileSync for git commands (prevent injection) - On git pull failure, reuse stale cache if skills dir exists instead of nuking - Extract gitClone() helper for consistent clone calls - Use explicit counted flag instead of confusing target === targets[0] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
71e00b4533 |
fix(cli): resolve npx hyperframes from inside monorepo (#47)
* fix(cli): rename workspace package so npx resolves from registry Rename packages/cli from "hyperframes" to "@hyperframes/cli" so that npm/npx stops resolving it as a local workspace package when run from inside the monorepo. The publish workflow sets the name back to "hyperframes" before publishing so the npm package name is unchanged. Root cause: npm sees workspaces in root package.json, finds packages/cli named "hyperframes", assumes it's local, but bun manages node_modules so there's no bin symlink — npx fails with "command not found" instead of falling back to the registry. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): update lockfile for workspace package rename Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): publish CLI from temp copy to avoid workspace mutation Copy packages/cli to a temp directory before renaming to "hyperframes" for publish. Avoids corrupting the workspace if the job fails mid-way. Addresses review feedback on #47. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): resolve leftover conflict markers in publish.yml Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
0ce9dd8496 |
feat: add HyperFrames skills for AI coding tools (#46)
## Summary
- 2 skills in `skills/` directory (tool-agnostic, installed via `hyperframes skills`)
- **compose-video** (112 lines): Core HyperFrames composition authoring contract — data attributes, timeline, video/audio rules, GSAP constraints, editing consistency
- `patterns.md`: PiP, title card, slideshow examples (loaded on demand)
- **captions** (138 lines): Tone-adaptive caption styling from transcript analysis — per-word styling, script-to-style mapping, whisper.cpp format reference
## Test plan
- [ ] Skills load in Claude Code
- [ ] compose-video under 500 lines, no `assets/` or `fonts/` references
- [ ] Captions skill triggers on tone detection keywords
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||
|
|
61c5257402 |
fix(ci): update publish workflow to use bun install (#36)
* fix(ci): update publish workflow to use bun install pnpm-lock.yaml was removed in the bun migration but publish.yml still referenced it. Use bun for install/build, keep pnpm for publish (publishConfig overrides + --provenance). * docs: update stale pnpm references to bun across docs and scripts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
94e25443ae |
build: migrate from pnpm to bun as package manager (#28)
## Summary - Replace pnpm with bun for dependency installation, script running, and ad-hoc execution - Keep pnpm for publish workflow only (`publishConfig` overrides + `--provenance`) - `bun install` replaces `pnpm install` (~4-5x faster cold installs) - `bun run` replaces `pnpm run` (~28x less startup overhead) - `bunx` replaces `npx` in lefthook hooks - CI workflows updated (`oven-sh/setup-bun@v2` + `actions/setup-node@v4`) - `pnpm-lock.yaml` removed, `bun.lock` generated - `pnpm-workspace.yaml` kept for publish compatibility - CLI source code (`packages/cli/src/`) unchanged — shipped to end users who may not have bun Part 5/5 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits) ## Test plan - [x] `bun run lint` — 0 errors - [x] `bun run format:check` — all files pass - [x] `bun run build` — all 5 packages build - [x] 330 core tests pass - [x] 18 engine tests pass - [x] `publish.yml` unchanged (pnpm stays for npm publishing) - [x] No `bunx`/`bun run` references in shipped source code (`packages/*/src/`) |
||
|
|
a6c5e08abb |
ci: add lint and format check job, update CONTRIBUTING.md (#26)
## Summary - Add `lint-and-format` job to CI workflow (`pnpm lint` + `pnpm format:check`) - Fix lefthook commands to use `npx` prefix (bare binaries not on PATH) - Update CONTRIBUTING.md: document new tooling, commit conventions, and lefthook hooks Part 4/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits) ## Test plan - [x] CI job matches existing pattern (pnpm 10, node 22, frozen lockfile) - [x] Git hooks work end-to-end (bad messages rejected, valid commits pass) - [x] CONTRIBUTING.md accurately reflects new tooling |
||
|
|
20be2ea1c2 |
style: apply oxfmt baseline formatting across all source files (#25)
## Summary - Run `oxfmt .` across the entire codebase to establish formatted baseline - 299 files changed — mechanical formatting only, no logic changes - Double quotes, semicolons, 2-space indent, trailing commas, 100 print width Part 3/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits) ## Test plan - [x] `pnpm format:check` — all 426 files pass - [x] `pnpm -r typecheck` — all packages pass - [x] `pnpm build` — all packages build - [x] All 348 tests pass |
||
|
|
323ff8f860 |
fix: resolve oxlint errors across codebase (#24)
## Summary - Remove 5 unused `beforeEach` imports from test files - Remove unused imports (`existsSync`, `TimelineCompositionElement`) - Remove unused destructured variables (`options`, `width`, `height`, `goldenEl`) - Remove dead `formatDuration` function - Fix unused catch parameters (`catch (err)` → `catch`) - Prefix unused `renderError` state with `_` - Add `eslint-disable-next-line` for 2 React exhaustive-deps false positives (stable ref + zustand setter) Part 2/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits) ## Test plan - [x] `pnpm lint` — 0 errors on 193 files - [x] All 348 tests pass (core + engine) |
||
|
|
17e90f0671 |
build: add oxlint, oxfmt, commitlint, lefthook, knip, and editorconfig configs (#23)
## Summary - Install oxlint, oxfmt, commitlint, lefthook, knip as dev dependencies - Add `.oxlintrc.json` (correctness rules + React plugin) - Add `.oxfmtrc.json` (double quotes, semicolons, 2-space indent, trailing commas) - Add `commitlint.config.js` (conventional commits) - Add `lefthook.yml` (pre-commit lint+format, commit-msg commitlint) - Add `.editorconfig` and `knip.config.ts` - Add scripts: `pnpm lint`, `pnpm format`, `pnpm format:check`, `pnpm knip` Part 1/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits) ## Test plan - [x] `pnpm lint` runs (reports pre-existing errors, expected) - [x] `pnpm format:check` runs (reports pre-existing diffs, expected) - [x] `commitlint` validates and rejects messages correctly - [x] lefthook hooks install via `pnpm run prepare` - [x] `pnpm knip` runs |
||
|
|
0276255b76 |
fix: rename root package to avoid shadowing published CLI (#17)
`npx hyperframes init` failed with "could not determine executable to run" because the monorepo root package.json shared the same name as the published npm package. npx resolved the local root (which has no bin field) instead of the published package. Renaming to "hyperframes-monorepo" follows the same convention as remotion-monorepo. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
1a713b37b9 |
fix: change workspace:* to workspace:^ for npm publish compatibility (#12)
pnpm converts workspace:^ to ^X.Y.Z during publish, but workspace:* was left unconverted in the registry. This caused install failures for external consumers. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
00909c8258 |
fix: revert parity harness to puppeteer-core with channel: chrome
The puppeteer import caused protocol timeout issues. Revert to puppeteer-core but add channel: "chrome" to auto-discover the Chrome binary installed by 'puppeteer browsers install'. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
b4023ae249 |
fix: update parity fixture to use local runtime path
The fixture HTML had an empty src after the static.heygen.ai URL was scrubbed. Point to the local hyperframe.runtime.iife.js which will be copied into the fixtures dir by CI before the test runs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
8866fc5791 |
fix: use puppeteer instead of puppeteer-core in parity harness
puppeteer-core requires an explicit executablePath or channel. puppeteer auto-discovers Chrome installed by 'puppeteer browsers install'. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
6ad12df1b6 |
fix: commit regression test golden baselines
- Update .gitignore to allow packages/producer/tests/*/output/ - Commit compiled.html snapshots and output.mp4 golden baselines (MP4s tracked via Git LFS) These were excluded by the blanket output/ gitignore rule but are needed for regression tests to pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
fbfb6c6156 |
fix: resolve TypeScript strict null errors in producer
- server.ts: default token param to empty string to satisfy string type - renderOrchestrator.ts: capture fileServer in local const before closure to preserve TypeScript null narrowing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
9f8e5ba5a1 |
initial code (#2)
* feat: initial code port from hyperframes-internal Port all OSS-ready packages from the internal monorepo: - @hyperframes/core — shared types, HTML generation, GSAP utilities, runtime - @hyperframes/cli — CLI for creating, previewing, and rendering compositions - @hyperframes/engine — framework-agnostic rendering engine (BeginFrame + FFmpeg) - @hyperframes/producer — video rendering pipeline (Puppeteer + FFmpeg) - @hyperframes/ui-player — browser-based video player component - @hyperframes/studio — composition editor (React frontend + Hono backend) Includes regression test suite with Docker-based test harness. All HeyGen-internal references, deployment infrastructure, and proprietary assets have been removed. Package names migrated from @app/* to @hyperframes/*. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: scrub internal codenames and stale references from OSS port - Replace static.heygen.ai runtime URLs in test fixtures - Remove internal CDN publish script (publish-hyperframe-runtime.ts) - Replace sandbox-studio, sandbox-interceptor, __magicEditRuntime with neutral names (studio, hyperframe-runtime, __hyperframeRuntime) - Fix stale Vault API / localhost references in docs - Remove broken deprecated_studio link Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove remaining internal codenames and stale references - Delete stale producer README.md and PIPELINE.md (referenced nonexistent files) - Replace "Cerberus" codename with "HyperFrames" in test design reviews - Replace magic-edit postMessage identifiers with hf-preview/hf-parent - Rename debug-magic-edit-timeline.ts to debug-timeline.ts - Replace "Motion Cut" with "HyperFrames" in Timeline comments - Fix studio/CLI references to nonexistent archive package (use local data/projects/ dir, stub render proxy) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |