Commit Graph
118 Commits
Author SHA1 Message Date
James 0d42d65525 chore: release v0.7.81 2026-07-29 06:11:11 +00:00
Miguel Ángel 5829515932 chore: release v0.7.80 2026-07-29 02:22:54 +00:00
Miguel Ángel a68729bcf1 chore: release v0.7.79 2026-07-28 23:06:45 +00:00
Vance Ingalls c691869e22 chore: release v0.7.78 2026-07-28 05:27:29 -07:00
Miguel Ángel 3c857d768b chore: release v0.7.77 2026-07-28 02:12:41 +00:00
Miguel Ángel 07e63b3758 Merge pull request #2791 from heygen-com/codex/studio-timeline-b-expanded-lanes-v2
feat(studio): wire expanded keyframe timeline lanes
2026-07-28 02:37:23 +02:00
Miguel Angel Simon Sierra d57039882f fix(studio): harden keyframe editing semantics 2026-07-28 00:13:46 +02:00
James 5cad2bc312 chore: release v0.7.76 2026-07-27 05:08:40 +00:00
James 45b458c007 chore: release v0.7.75 2026-07-27 03:38:16 +00:00
James Russo 0cc78c1d42 chore: release v0.7.74 (#2818) 2026-07-26 21:57:54 -04:00
James 527751c871 chore: release v0.7.73 2026-07-26 21:25:03 +00:00
James Russo 72ae39e3d0 chore: release v0.7.72 (#2800) 2026-07-26 02:01:10 -04:00
James d07d1874b6 chore: release v0.7.71 2026-07-24 19:03:16 +00:00
James Russo 7778c093b6 fix(preview): serve external symlink assets (#2764)
## What

Allow Studio Preview to serve an asset reached through a project-local symlink whose target is in a shared directory outside the project, including browser-hostile video assets that need an authoring proxy.

## Why

Preview rejected these assets with a 404 while the renderer accepted the same path. The initial static-route fix still failed for HEVC, ProRes, AV1, and VP9 assets because the proxy transcoder rejected the external target.

## How

Use lexical project-root containment for the read-only static asset route and proxy source request. The transcoder canonicalizes the target for ffmpeg and includes that identity in its cache key, while keeping the proxy cache inside the project. Composition source paths retain canonical containment because preview can persist their data-hf-id values.

## Test plan

- [x] Unit tests added/updated
- [x] `bun run --cwd packages/studio-server test` (397 tests)
- [x] Studio Server typecheck, oxlint, and oxfmt
- [x] External-symlinked hostile-video proxy route regression
- [x] Static-route traversal regression
- [ ] Documentation updated (not applicable)
2026-07-24 13:35:10 -04:00
Vance Ingalls b9c3e3a4b6 chore: release v0.7.70 2026-07-23 20:59:30 -07:00
James f0034228f5 chore: release v0.7.69 2026-07-23 12:03:36 -07:00
James 71d84ff27f chore: release v0.7.68 2026-07-22 04:41:54 +00:00
James 4b6bb8ffa9 chore: release v0.7.67 2026-07-21 23:51:05 +00:00
Miguel Angel Simon Sierra 84841b8dae chore: release v0.7.66 2026-07-21 14:36:22 +02:00
James 835fa899c7 chore: release v0.7.65 2026-07-21 04:45:59 +00:00
James 3454a80eb2 test(repo): execute packed subpaths 2026-07-18 18:27:44 -04:00
James 8d9d9c016e refactor(repo): centralize package subpaths 2026-07-18 15:58:23 -04:00
Miguel Ángel 11cd61d1e3 chore: release v0.7.64 (#2630)
Release HyperFrames v0.7.64.
2026-07-18 15:02:20 -04:00
James 562544f68d refactor(core): own edit protocol contract 2026-07-18 13:24:57 -04:00
James 8dd7e3dfc5 fix(studio): keep atomic Acorn splits Recast-free 2026-07-18 09:36:00 -04:00
James 022e260ac3 fix(studio): read writer environment explicitly 2026-07-18 06:41:26 -04:00
James 710a8f1db2 fix(studio): select writer for atomic cuts 2026-07-18 06:41:26 -04:00
James 43788c6dda refactor(studio): gate Acorn writer migration 2026-07-18 06:41:26 -04:00
Miguel Ángel feb675a89d chore: release v0.7.63 (#2628) 2026-07-18 04:44:56 -04:00
Miguel Ángel 7f76170956 chore: release v0.7.62 (#2626) 2026-07-17 22:02:49 -04:00
Miguel Ángel e64a22893a fix(studio): preserve alpha proxy playback (#2625)
* fix(studio): preserve alpha proxy playback

* test(cli): pin VP8 alpha proxy pre-resolution

* fix(studio): emit textarea field-sizing CSS

* test(studio): verify textarea CSS generation
2026-07-17 21:56:27 -04:00
Miguel Ángel 2577aaffeb fix(studio): ignore stale failed sidecars for existing renders (#2621)
* fix(studio): ignore stale failed sidecars for existing renders

* style: format stale render metadata test
2026-07-17 16:21:33 -04:00
Miguel Ángel 2b65b4efce fix(studio): harden composition timeline reliability (#2615)
* fix(studio): preserve composition playback continuity

* feat(studio): drag compositions into the timeline

* fix(studio): collapse expanded composition move aliases

* fix(studio): make timeline cuts atomic

* fix(studio): group inspector gesture history

* test(studio): cover masked text selection

* fix(studio): harden composition timeline reliability

* fix(studio): satisfy CI source gates

* fix(studio): harden composition mutation requests
2026-07-17 14:15:30 -04:00
Vance Ingalls c268f5ba85 chore: release v0.7.61 2026-07-17 01:07:09 -07:00
Vance Ingalls 1ddf9cc331 Merge pull request #2563 from heygen-com/via/thumbnail-id-escape
fix(studio,runtime): CSS.escape ids so digit-leading selectors don't crash
2026-07-17 00:43:31 -07:00
Miguel Ángel e8371a7acc feat(media): alpha-capable authoring proxies (#2598)
* feat(media): alpha-capable authoring proxies

Alpha sources were refused a proxy before the codec map ever asked whether the
browser could decode them, so a ProRes 4444 alpha file (which no browser
previews at all) rendered black forever, while an alpha WebM (which previews
fine) was already covered by the browser-safe check on the next line. The alpha
veto earned nothing and cost the one case that needed help.

Alpha is now a target-codec choice rather than a veto: alpha sources transcode
to VP9 + yuva420p in WebM, everything else keeps the existing H.264/MP4 path
byte for byte. Only files no browser can preview are proxied, which is the rule
the runtime already followed everywhere else.

WebM cannot carry AAC, so the VP9 path uses Opus and drops the MP4-only
faststart flag. PROXY_PARAMS_VERSION moves to v3 so clients stop serving the
previously cached proxies.

Safari does not decode VP9 alpha and still shows black for alpha sources, as it
does today: this is better on Chromium and Firefox and no worse anywhere.

* fix(media): infer proxy variant for rescue

* fix(media): preserve alpha proxy hardening after restack
2026-07-17 03:26:55 -04:00
Miguel Ángel 74b4f1e8c3 feat(cli): serve proxies from play and the static project server (#2593)
* feat(studio-server): serve H.264 proxies from the preview route

Wires the codec manifest and the transcoder into the preview surface: the route
negotiates a proxy via a query param and serves it through the existing range
and ETag machinery, composition HTML carries a codec map for the runtime, and
hostile assets pre-warm so a first play does not wait on a cold transcode.
Exposes the three subpath exports the CLI surfaces consume upstack.

Drops the TEMP fallow entry added with the transcoder: it has real importers now.

* fix(studio-server): publish media proxy exports

* fix(parsers): scan HTML comments linearly

* feat(cli): let projects opt out of automatic proxying

Adds media.autoProxy to hyperframes.json plus --proxy/--no-proxy flags, and
forwards the resolved value into the studio and preview servers and the vite
adapter. Lands before the runtime slice that turns auto-proxying on, so the
switch exists before there is any behavior to switch off.

* fix(cli): align media config schema

* feat(core): swap undecodable video to its proxy at runtime

Adds the browser-side half: before first load the runtime consults the injected
codec map and swaps a hostile source to its proxy, and if a video still reports
zero decodable width it rescues it reactively. An HEVC file carrying AAC fires
no error event, so zero videoWidth, not the error event, is the reliable signal.
Audio elements and alpha sources are never proxied, render mode never proxies,
and each swap evicts the element's stale sync state and reports once.

This completes the loop: auto-proxying is live for preview and studio from here.
The opt-out (media.autoProxy, --no-proxy) shipped in the previous slice.

* feat(cli): serve proxies from play, present, and the static project server

Adds proxy negotiation to the CLI-side servers and gives play byte-range
serving it never had, so a swapped video can seek. The static project server
behind check, snapshot, compare and friends injects the codec map once, so all
of its callers inherit the behavior; snapshot forwards its own proxy flag.

* fix(cli): serve proxies for camera formats
2026-07-16 23:02:01 -04:00
Miguel Ángel 67eab59f44 feat(studio-server): serve H.264 proxies from the preview route (#2590)
* feat(studio-server): serve H.264 proxies from the preview route

Wires the codec manifest and the transcoder into the preview surface: the route
negotiates a proxy via a query param and serves it through the existing range
and ETag machinery, composition HTML carries a codec map for the runtime, and
hostile assets pre-warm so a first play does not wait on a cold transcode.
Exposes the three subpath exports the CLI surfaces consume upstack.

Drops the TEMP fallow entry added with the transcoder: it has real importers now.

* fix(studio-server): publish media proxy exports

* fix(parsers): scan HTML comments linearly
2026-07-16 23:00:48 -04:00
Miguel Ángel 9d148d288a feat(studio-server): transcode bounded H.264 proxies on demand (#2589)
* feat(studio-server): bound the proxy cache with LRU accounting

Adds cache accounting and bounded cleanup for transcoded proxies, and keeps
.transcode-cache out of git. Standalone: the transcoder consumes it next.

* feat(studio-server): transcode bounded H.264 proxies on demand

Adds the proxy transcoder: a bounded work queue with per-key dedupe, a hard
kill ceiling, TTL'd failure memory so a broken asset is not retried forever,
and pixel/color normalization for browser playback. Writes through a temp name
and renames on success, so a cache entry is never partial.

Carries a TEMP fallow ignoreExports entry: this module lands below its
consumers, so a per-PR audit sees its exports as unused until the preview weld
arrives. The entry is dropped there.
2026-07-16 21:08:03 -04:00
Miguel Ángel 1d3d20450d feat(studio-server): bound the proxy cache with LRU accounting (#2588)
Adds cache accounting and bounded cleanup for transcoded proxies, and keeps
.transcode-cache out of git. Standalone: the transcoder consumes it next.
2026-07-16 21:05:08 -04:00
Miguel Ángel 9ca1e17101 feat(studio-server): probe media codec facts for proxy decisions (#2587)
* feat(studio-server): probe media codec facts for proxy decisions

Adds the codec manifest: one ffprobe-backed answer to what codec an asset
uses, whether a browser can decode it, and whether it carries alpha. Migrates
the existing prober to the shared ff-binaries resolver and to async execFile so
a scan pool runs off the event loop. No consumer yet; the preview weld wires it
up later in the stack.

* fix(studio-server): honor injected ffprobe runners
2026-07-16 20:54:50 -04:00
Miguel Angel Simon Sierra 7980479083 fix: preserve shared FFmpeg resolver behavior 2026-07-16 19:10:04 -04:00
Via 9bbdcc4ec9 fix(studio,runtime): CSS.escape ids so digit-leading selectors don't crash
The runtime picker built raw `#${id}` selectors while its sibling
attribute-selector branches (data-composition-id, data-composition-src,
data-track-index) already CSS.escape'd their values. When a user
composition has an element with a digit-leading id (e.g. `id="0"`),
the picker emits the selector `#0` which is invalid per the CSS spec —
downstream `document.querySelector` throws SyntaxError.

Same failure mode reached the Studio thumbnail: getElementScreenshotClip
called `document.querySelectorAll(selector)` unguarded, so an invalid
selector bubbling out of page.evaluate failed the whole thumbnail and
returned 500 to the browser (broken thumbnail image).

Fixes:
- packages/core/src/runtime/picker.ts — CSS.escape the id, matching the
  sibling branches on lines 100/102/104.
- packages/studio-server/src/helpers/screenshotClip.ts — catch
  SyntaxError from an invalid selector and return undefined so the
  caller falls back to a full-page screenshot, so the user still sees
  a thumbnail instead of a broken image.

Regression tests for both.

Reported via #hf-cli-feedback (Slack ts=1784218060, darwin/arm64,
CLI 0.7.60): "digit-leading worker IDs broke Studio thumbnail
querySelectorAll".

— Via
2026-07-16 18:07:58 +00:00
Vance Ingalls ff26e5f2c8 Merge pull request #2529 from heygen-com/via/resolution-portrait-fix
fix(cli): accept portrait aspects for --resolution alias flag
2026-07-16 01:54:55 -07:00
ViaandClaude 2d398ed274 fix(cli): wire aspect-agnostic resolution through cloudrun/lambda/batch + preflight recompute
Addresses R2 CHANGES_REQUESTED from Miga + Rames on PR #2529:

1. Sibling-surface gap (blocker): `hyperframes cloudrun render{,-batch}`,
   `hyperframes lambda render{,-batch}` all advertised the same tier-only
   aliases (`1080p` / `hd` / `4k` / `uhd`) but normalized them to `landscape`
   and never set `outputResolutionAspectAgnostic`. The distributed plumbing
   PR #2529 added received `undefined` from those callers, so portrait `1080p`
   still hit the original aspect-mismatch on Cloud Run / Lambda.

   Fix: introduce `resolveResolutionFlagPair` in `@hyperframes/parsers` (the
   single source of truth for the two-step normalize + aspect-agnostic
   detect) and route every distributed entrypoint through a shared
   `parseOutputResolutionFlag` CLI util so the alias signal now reaches
   `SerializableDistributedRenderConfig`. Studio Server keeps its
   canonical-only HTTP contract; that intent is now pinned in tests.

2. Preflight recompute (hardening): the earlier "downgrade aspect-mismatch"
   preflight cleared un-remapped mismatches, so IG 4:5 (non-preset aspect,
   no sibling) and portrait-4K comp + `--resolution 1080p` (remap +
   downsample) both slipped through to fail late in `resolveDeviceScaleFactor`.
   Now `checkRenderResolutionPreflight` computes the effective preset via
   `suggestMatchingPreset` (mirroring the compile stage's
   `adaptAspectAgnosticResolution`) and re-checks against that — only
   genuinely-fixable mismatches clear early. New tests pin both regressed
   input classes.

3. Docker forwarding boundary test (Miga's important #2): pinned
   `1080p` survives verbatim as `--resolution 1080p` in the Docker args
   so the in-container CLI can re-run `isAspectAgnosticResolutionAlias`.

4. Doc-nit (Miga): parsers/src/types.ts no longer references the
   nonexistent `resolveResolutionForComposition` — points at the actual
   remap helpers.

Fallow: cloudrun.ts / lambda.ts share 390 lines of pre-existing structural
symmetry (parallel AWS + GCP dispatchers), and lambda/render.ts +
render-batch.ts declare parallel RenderArgs interfaces. Both re-flagged
after threading the aspect-agnostic field through each surface; ignored
with justification in .fallowrc.jsonc. lambda.ts's `run` and
lambda/render.ts's `waitForCompletion` are pre-existing CRAP-score
hotspots untouched by this PR — added under health.ignore.

Co-Authored-By: Claude <noreply@anthropic.com>

— Via
2026-07-16 08:01:56 +00:00
James Russo 21cb722ebd refactor(core): unify composition contract (#2157)
* refactor(core): unify composition contract

* fix(parsers): parse start expressions linearly
2026-07-16 02:44:22 -04:00
Miguel Ángel 0f287ee0b6 chore: release v0.7.60 2026-07-16 05:26:57 +00:00
James Russo 2417293dab fix(studio): enforce optimistic file concurrency (#2156)
* fix(studio): enforce optimistic file concurrency

* fix(studio): harden conditional file writes

* fix(studio): honor explicit file preconditions

* test(producer): allow zero-ms encode timing
2026-07-15 18:07:04 -04:00
Vance Ingalls ff3b1541e5 chore: release v0.7.59 2026-07-15 11:57:49 -07:00
James Russo 42055296ee fix(studio): make sdk cutover transactional (#2155) 2026-07-15 10:29:22 -04:00