feat(captions): energy-based technique selection and mandatory quality checks - #176
Merged
Conversation
This was referenced Apr 1, 2026
Merged
Collaborator
Author
This stack of pull requests is managed by Graphite. Learn more about stacking. |
4 tasks
vanceingalls
marked this pull request as ready for review
April 1, 2026 04:22
This was referenced Apr 1, 2026
vanceingalls
force-pushed
the
vance/captions-skill-updates
branch
from
April 1, 2026 05:38
1cbe901 to
fe9a3a2
Compare
vanceingalls
force-pushed
the
vance/whisper-improvements
branch
from
April 1, 2026 05:38
5360ae6 to
c47472a
Compare
8 tasks
miguel-heygen
approved these changes
Apr 1, 2026
vanceingalls
force-pushed
the
vance/captions-skill-updates
branch
from
April 1, 2026 22:05
44abb54 to
847ba6e
Compare
vanceingalls
force-pushed
the
vance/whisper-improvements
branch
from
April 1, 2026 22:05
c47472a to
28e707c
Compare
2 tasks
vanceingalls
force-pushed
the
vance/captions-skill-updates
branch
from
April 2, 2026 05:30
847ba6e to
efb09e3
Compare
vanceingalls
force-pushed
the
vance/whisper-improvements
branch
from
April 2, 2026 05:30
28e707c to
4b0ce61
Compare
4 tasks
vanceingalls
force-pushed
the
vance/whisper-improvements
branch
from
April 2, 2026 05:57
4b0ce61 to
436cd55
Compare
vanceingalls
force-pushed
the
vance/captions-skill-updates
branch
from
April 2, 2026 05:57
efb09e3 to
777a00a
Compare
vanceingalls
force-pushed
the
vance/whisper-improvements
branch
2 times, most recently
from
April 2, 2026 06:25
7085bdc to
4e51632
Compare
vanceingalls
force-pushed
the
vance/captions-skill-updates
branch
from
April 2, 2026 06:25
71bc159 to
0686408
Compare
vanceingalls
changed the base branch from
vance/whisper-improvements
to
graphite-base/176
April 2, 2026 06:38
Collaborator
Author
|
Folded into #175 (vance/whisper-improvements) |
vanceingalls
added a commit
that referenced
this pull request
Apr 2, 2026
…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)
Remove custom skill installation from the CLI in favor of vercel-labs/skills. Fixes staleness, deduplication, listing budget, and completeness issues identified by agentic harness pattern review. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 tasks: delete install-skills, strip skills from init, front-load SKILL.md descriptions, update CLAUDE.md, clean up my-video copies. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace single "color" with activeColor (spoken) and dimColor (inactive). Runtime hook modifies existing GSAP color tweens by detecting dim vs active states via opacity heuristic. Property panel shows both color pickers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove typography, color, opacity, stroke, and background controls. Keep only Position (X/Y) and Transform (Scale/Rotation) — the controls that work reliably with the wrapper-based override system. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1px per press, 10px with Shift held. Syncs to store and auto-saves. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Caption overlay and hover states always active on captions compositions - Clicking a word auto-opens the property panel - Remove Edit Captions button — edit mode activates automatically - Reset edit mode when navigating away from captions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Caption edit mode now activates automatically when .caption-group elements are found in the iframe DOM. Works from index.html (master) without requiring drill-down into the captions sub-composition. Finds the captions source file via data-composition-src attribute. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ding Replace polling with a message listener for hf-preview state/timeline events. These fire after loadExternalCompositions completes, guaranteeing .caption-group elements exist in the DOM. Eliminates the race condition on initial page load. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove store reset from useEffect cleanup — was wiping state on dep changes and breaking auto-save subscription - Move panel auto-open into useEffect instead of during render - Add fallback 500ms poll alongside postMessage listener for initial load Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Runtime hook's wrapper was missing data-caption-wrapper attribute, so the overlay created a second wrapper on top. Transforms were applied to different wrappers causing values to compound on reload. Also: - Suppress auto-save during loadOverrides to prevent immediate re-write - Only sync non-default transform values to avoid spurious overrides Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Reduce poll interval from 500ms to 200ms for faster detection - Fall back to DOM querySelector for iframe when ref isn't set yet - Runtime wrapper sets data-caption-wrapper for consistent detection Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The runtime strips data-composition-src after loading, so the DOM query couldn't find the captions file path. Now uses the compIdToSrc map (built from raw index.html) as the primary lookup. Also adds compIdToSrc to the effect dependency array so it re-runs when the map is populated. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Panel rotation/scale/position changes now go through the wrapper span using gsap.set, reading current values first to preserve other properties. Previously set el.style.transform directly on the word span, overwriting all existing transforms. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Delete dead useCaptionDrag.ts (superseded by overlay inline drag) - Self-cancel 200ms poll after caption activation - Remove stale effectiveStyle deps from applyToIframeDom useCallback Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace doc!/win!/captionSrcPath! with guards in App.tsx async callback - Move useCallback hooks above early return in CaptionAnimationPanel (React hooks must be called unconditionally in the same order) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…erty panel - Replace filter(Boolean) + ! assertions with typed filter in generator.ts - Hoist repeated seg.id.replace() to const segVar - Remove unused ToggleButton, ColorInput, container/typography derived values, applyContainerToIframeDom, handleContainerChange, buildTextDecoration - Remove CaptionContainerStyle import Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add change detection to 66ms overlay poll (skip setWordBoxes when unchanged) - Add activating guard to prevent duplicate caption source fetches - Remove applyOpacityToColor wrapper (inline hexToRgba) - Rename rawWords back to words in normalize.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The single-quote replacement regex ran after key-quoting, causing it to match apostrophes inside already-double-quoted strings like "didn't". Moving it before key-quoting fixes the issue since it only matches actual single-quoted string values at that point. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
Work folded into #175 (merged) |
vanceingalls
force-pushed
the
vance/captions-skill-updates
branch
from
April 2, 2026 07:23
0686408 to
2197f18
Compare
vanceingalls
force-pushed
the
graphite-base/176
branch
from
April 2, 2026 07:23
4e51632 to
fc99b40
Compare
vanceingalls
force-pushed
the
graphite-base/176
branch
from
April 2, 2026 07:26
fc99b40 to
37404f2
Compare
dahans-msft2
pushed a commit
to dahans-msft2/hyperframes
that referenced
this pull request
Aug 6, 2026
…multilingual defaults (heygen-com#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 heygen-com#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 heygen-com#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)
dahans-msft2
pushed a commit
to dahans-msft2/hyperframes
that referenced
this pull request
Aug 6, 2026
…y checks (heygen-com#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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
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.caption-group+<span>) for studio editor compatibilityTest plan
dynamic-techniques.mdaudio-reactive section usestl.to()/tl.set()only, notl.call()loops🤖 Generated with Claude Code