Files
hyperframes/packages/studio
Vance Ingalls ce90d046b2 fix(studio): repair the automation paste path and finish the key arbitration
Paste was the least safe path in this feature: it resolved its target from
the player store but committed through a different, asynchronously-lagging
channel. Six review findings against this branch, plus the Cmd+C/Cmd+V half
of the arbitration wa-15 started for Delete.

- Write channel: resolvePasteTarget bails unless the binding's
  commitTargetKey equals the element it resolved. useAutomationLanes exposes
  that key, resolved through resolveTimelineIdForSelection — the same
  resolver applyDomSelection uses — and read in the same render as the
  commit handlers, so a handler and the key cannot describe different
  moments. Before this, clicking clip B then immediately pasting serialized
  B's automation onto A and left B untouched.
- Chaining: the paste anchor comes from sel.t1, not sel.t0, so a second
  Cmd+V lands after the first instead of on top of it. The old comment
  claimed the new behaviour while the code did the opposite, and no test
  pressed Cmd+V twice.
- Empty copy: copyRange returns false rather than arming a clipboard whose
  every paste is a destructive flatten, and samples the range's edges so
  copying a smooth stretch yields a real segment instead of no points.
- Playhead: the playhead branch requires the playhead to be inside the clip
  rather than silently clamping an out-of-clip playhead to the clip's start.
- Keys: one chord helper normalizes with toLowerCase() and gates on
  !shiftKey && !altKey, matching useAppHotkeys. CapsLock no longer kills the
  shortcut and Ctrl+Alt+V no longer pastes where the app declines.
- Arbitration: useAppHotkeys consults automationOwnsKey before its c/v
  branch, so an active range keeps Cmd+C/Cmd+V from the clip clipboard the
  same way it keeps Delete. Without it Cmd+V duplicated the clip while the
  automation paste wrote the same file, and Cmd+C armed both clipboards.
  It returns without preventDefault — the downstream handler needs the key —
  and declines when the automation clipboard is empty so clip paste still
  works. dispatchModifierKey is exported to pin this, like dispatchPlainKey.
- Double-action: the hook now returns early on e.defaultPrevented.
  useAppHotkeys is on window/capture and deliberately lets a keyframe
  selection outrank a range on Delete; without this that press deleted the
  keyframes there AND emptied the range here.

- Project scoping: the clipboard scopes itself. Every entry point carries the
  project it speaks for and a mismatch empties the module, the shape
  keyframeSlice already uses to discard a request from a previous session.
  Scoping it inside the module rather than clearing it from the session seam
  is deliberate: the failure is silent and destructive — a range copied in
  project A pasted into B is remapped through A's captured sourceRange for an
  FX node B may not have, and the keystroke is consumed so clip paste never
  runs — so no future caller should be able to forget the guard. The mark
  isLastPasteSpan reads is scoped transitively, through the same check.
- Session reset: createTimelineResetState clears automationSelection. It is
  as ephemeral as selectedKeyframes, and a range surviving a project switch
  can match a same-keyed clip in the new project and redirect a paste through
  sel.elementKey === paste.elementKey to a stale t0.

Five of the six paste fixes above shipped without a test that fails without
them, which is how the branch reached review with a comment describing
chaining that the code did not do. Each now has one: a second Cmd+V landing
after the first, a commit-target mismatch declining, an out-of-clip playhead
declining, an empty-lane copy leaving an earlier clipboard intact, and Cmd+V
with CapsLock on. All five fail against this branch's parent.
2026-08-06 10:59:34 -07:00
..
2026-08-03 22:48:00 -07:00
…

@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