mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
Four confirmed tail findings from the review. **The label column had no canary gate** while the group ROWS it exists for do. Un-enrolled — everyone, the canary is at 0% — any composition carrying `data-audio-group` got a permanent 232px `LABEL_COL_W` shift of every clip with no group row on screen to explain it. Now gated identically; the two must agree. **Keyboard expandability disagreed with the header.** `expandable: lanes.length > 0` against the header's `lanes.length > 0 || automationRows.length > 0`, so an audio track whose only disclosable content is AUTOMATION drew the `∿` while reporting itself unexpandable to the treegrid — ArrowRight could not open it. Both the flag and the `expanded` gate now count automation rows the same way the header does, per shared PROPERTY rather than per clip. **Sub-composition child rows could land exactly on a group anchor.** A group row anchors at `firstMemberTrack - 0.5`, and the child scheme `k / (n + 2)` hits 0.5 dead on for a host with two children (2/4) — a duplicate row key and a duplicated group header. Children are now confined to the LOWER half of the gap (`0.5 * k / (n + 1)`, maximum strictly under 0.5 for every n), which keeps every property the old scheme had — non-integer, distinct, ordered, under the host — and cannot reach x.5. Test asserts the invariant across 1, 2, 3, 4 and 7 children rather than pinning the fractions. **The timeline FX popover emitted a `preset_applied` per audition.** It called `applyPresetToChain`, which fires `trackPresetApplied` on every call, so hovering or arrowing a 12-preset shelf reported 12 applies and the numbers could not tell an audition from a decision. It now auditions through the raw apply and reports `trackPresetAuditioned`, the split `FxSection` already makes. **Also: the group panel's signal path went stale on a membership change.** Its memo was keyed on `[element]` alone, and membership is held by the MEMBERS — so a clip joining this group changed neither `element` nor its attributes and the path kept claiming "OUT to mix". Keyed on the store's element array too, whose identity both `syncStoredGroupAttribute` and `updateElement` replace. **One tail item examined and REJECTED:** "Hide all" being withheld for a whole mixed selection when one member is audio. Hiding only the visual members is precisely the act-on-a-subset pattern this branch refuses elsewhere (see `canGroupWholeTrack`: "The button is withheld instead of acting on a subset"), and for audio `data-hidden` is mute, so a partial apply would silence nothing while looking like it had. Current behaviour is consistent; left alone. studio: 207 files, 2632 tests. fallow clean.
@hyperframes/studio
Browser-based composition editor UI for Hyperframes. Provides a visual timeline, code editor, and live preview for building video compositions.
Install
npm install @hyperframes/studio
What it does
The studio is a React application with:
- Visual timeline — drag, resize, and arrange elements on tracks
- Code editor — edit HTML and GSAP scripts with CodeMirror (syntax highlighting, autocomplete)
- Live preview — see changes in real time as you edit
- Composition inspector — view and modify element properties
Development
The studio is embedded in the hyperframes preview command. To develop the studio UI itself:
cd packages/studio
bun run dev # Start Vite dev server
bun run build # Build for production
bun run typecheck # Type-check
Tech stack
- React 18/19, Zustand (state management)
- CodeMirror 6 (editor)
- Tailwind CSS (styling)
- Vite (bundler)
- Phosphor Icons
Documentation
Full documentation: hyperframes.heygen.com/packages/studio
Related packages
@hyperframes/core— types and parsers used by the editorhyperframes— CLI that serves the studio viahyperframes preview