Commit Graph
1869 Commits
Author SHA1 Message Date
Miguel ÁngelandRyan Heinl 624c9becfd fix(studio): keep the canvas outline off the scaled preview iframe (#6452)
* fix(studio): keep the canvas outline off the scaled preview iframe

Co-authored-by: Ryan Heinl <ryan@siyglobal.com>

* fix(studio): keep NLEPreview under the file size limit

Co-authored-by: Ryan Heinl <ryan@siyglobal.com>

* fix(studio): bank the player's colour-literal baseline

Co-authored-by: Ryan Heinl <ryan@siyglobal.com>

---------

Co-authored-by: Ryan Heinl <ryan@siyglobal.com>
2026-10-27 15:49:29 +00:00
Miguel Ángel 53c9759666 chore: release v0.8.209 (#6562) 2026-10-27 14:34:53 +00:00
Miguel Ángel 6092785348 fix(studio-server): preview loads root-path media, images and CSS from the project, as render does (#6552)
* fix(studio-server): preview loads root-path media, images and CSS from the project, as render does

* fix(studio-server): preview writes root paths project-relative, the form Studio reads back
2026-10-27 12:29:17 +00:00
Miguel Ángel 58552ede4b test(studio): record each edit-accuracy shard's file writes and reloads when HF_WRITE_TRACE is set (#6532)
* test(studio): record each edit-accuracy shard's file writes and reloads when HF_WRITE_TRACE is set

* style(studio): format the write trace

* fix(core): hash the write trace with sha256

* style(studio): wrap the trace hash helper

* style(studio): format the trace hash helper

* fix(studio): turn the reload log on in the Studio page the trace watches
2026-10-27 11:50:20 +00:00
Miguel Ángel f007882ca7 chore: release v0.8.208 (#6529) 2026-10-27 11:12:48 +00:00
Miguel Ángel 619b8bc4d7 chore: release v0.8.207 (#6510) 2026-10-27 04:33:06 +00:00
Miguel Ángel 8505a4168d fix(studio): a timeline edit that lands on the clip's own values saves nothing instead of failing (#6487)
* fix(studio): a timeline edit that lands on the clip's own values saves nothing instead of failing

* chore: re-run checks against the updated PR description
2026-10-27 00:31:05 +00:00
Miguel Ángel 54d0af57eb feat(engine): render sets a keyframe interval and a peak bitrate cap (#6444)
* feat(engine): encoders cap peak bitrate and place keyframes on a set interval

* style(engine): shorten the rate-cap comment

* style(engine): drop the doc lines the comment ratchet flagged

* feat(producer): mp4 renders honour a keyframe interval and a peak bitrate cap on every encoder path

* style(producer): shorten the delivery encoder file headers

* style(producer): drop a comment line from the segment manifest

* style(producer): shorten the integration test header

* test: delivery encoder tests follow the ffprobe argv contract and run in the integration lane

* feat: the render request, server and Lambda plan carry the keyframe interval and peak bitrate cap

* fix(studio): the Studio render route passes the keyframe interval and bitrate cap to the encoder

* chore(studio-server): drop a comment the helper's name already says

* feat(cli): render and lambda render take --keyframe-interval, --max-bitrate and --buffer-size
2026-10-27 00:29:06 +00:00
Miguel Ángel 097cc094b7 fix(studio): a reload refused because the page is missing mid-edit warns instead of erroring (#6491) 2026-10-26 23:53:48 +00:00
Miguel Ángel 75bee42919 fix(core): paused preview seeks land on the composition's own frame rate (#6460)
* fix(core): preview seeks land on the composition's own frame rate

* fix(studio): frame step, frame readout and ruler use the composition's frame rate

* fix(studio): an end trim previews the clip's last frame at the composition's frame rate

* refactor(studio): ruler labels follow the ticks' frame rate and fps parsing splits by form

* style(studio): format the ruler label helper and its test

* chore(inspector): raise the package size budget to the measured size plus headroom
2026-10-26 22:54:21 +00:00
Miguel Ángel dfd2028f16 fix(studio): a clip that cannot be read gives up after two retries with one typed line (#6477)
* fix(studio): a clip that cannot be read gives up after two retries with one typed line

* fix(studio): a clip whose stream breaks mid-read also fails with the typed line
2026-10-26 21:08:46 +00:00
Miguel Ángel 85fdc9aa88 chore: release v0.8.206 (#6469) 2026-10-26 15:00:57 -04:00
Miguel Ángelandlorenzozanee 15367a9f62 fix(studio): a media preview retries after its file or project changes (#6451)
Co-authored-by: lorenzozanee <wyz0707@proton.me>
2026-10-26 18:15:56 +00:00
Miguel Ángelandlorenzozanee 25e5ab733b fix(studio): give the prompt preview editor an accessible name (#6450)
Co-authored-by: lorenzozanee <wyz0707@proton.me>
2026-10-26 18:15:46 +00:00
Miguel Ángel 121bf20e99 perf(studio): a scrub's state messages re-read the preview's compositions at most every 500 ms (#6429) 2026-10-26 17:27:26 +00:00
Miguel Ángel f1b5d89a1e perf(studio): the layer walk keeps its selector index, so scrubbing into new scenes is cheaper (#6427)
* perf(studio): the layer walk keeps its selector index, so scrubbing into new scenes is cheaper

* perf(studio): the layer walk keeps its selector index, so scrubbing into new scenes is cheaper
2026-10-26 17:27:19 +00:00
Miguel Angel Simon Sierra b4eab1a8c1 chore: release v0.8.205 2026-10-26 12:41:40 -04:00
Miguel Ángel b76b529372 feat(cli): offer the HyperFrames app download on Windows
The CLI and Studio now point Windows to the app download.

Studio names the Windows download in its install steps.
2026-10-26 12:23:42 -04:00
SophiaHuangCc 2d695a8436 feat(studio): support GIF export with loop count (#5593)
* feat(studio): support GIF export with loop count

* fix(studio): cap GIF exports at 30 fps

* fix(studio): complete GIF export review follow-ups
2026-10-26 14:57:55 +00:00
Miguel Ángel 2d1b5cfbd2 chore: release v0.8.204 (#6423) 2026-10-26 10:16:23 -04:00
Miguel Ángel dc56b3d20a perf(studio): the layer walk skips clips the runtime hid, so scrubbing a long film stays smooth (#6416)
The off-canvas indicators (always mounted) and the Layers panel rebuild their layer list every
100 ms while a scrub mutates the preview, and each rebuild read the computed style of every element
of every scene, on screen or not. The runtime already hides everything inside a clip its visibility
pass hid, so those subtrees hold no layer: the walk now skips a clip marked data-hf-clip-hidden
with an inline visibility of hidden. The marker constant moves to studio-preview-mark so the runtime
and Studio share one owner.
2026-10-26 13:22:09 +00:00
Miguel Ángel ff0a56340b chore: release v0.8.203 (#6412) 2026-10-26 07:20:07 -04:00
Miguel Ángel 84fd701daa feat(studio): preview copy progress, retry and a remembered quality (#6366)
* feat(studio-server): a copy being made says how far it has got, and can be retried

* feat(core): the preview reports its lighter copies' progress and retries failed ones

* feat(studio): the preview quality and its lighter copies' progress live in the player store

* feat(studio): every host forwards the preview quality, and the choice is kept per computer

* feat(studio): the preview quality knows if a person or the app chose it

* fix(core): the first report of the lighter copies is not held back by the throttle

* test(studio): the preview quality preference test writes under the real key

* fix(core): a quality change reports its copies at once, not after the throttle

* style: format the preview quality files

* feat(core): report how playback is going, and what the preview holds, to the host

* fix(studio): the preview quality levels come from a browser-safe core entry

* style: format the new entry's files

* style: drop two comments the file's ratchet and the citation check refuse

* feat(core): tell which lower levels would give a video a lighter copy

* fix(studio): drop the old level's playback health when the level changes

* feat(studio-server): preview facts carry the probed codec of every video

* refactor(studio): route the preview's reports through a table for the complexity gate

* fix(core): a copy's retry flag is sent on the first ask only, not on every poll

* fix(core): type the health report and restore the player hook's complexity directive

* style: cut four comments the comment ratchet refuses

* fix(studio): keep playerStore.ts within its 600-line cap

* fix(core): a scene mounting does not restart the playback health window

* fix(core): the playback health window restarts only when the display scale changes

* fix(core): a repeated display scale no longer restarts the playback health window

* fix(studio): route the preview's reports by an explicit list of message types
2026-10-26 09:20:07 +00:00
Miguel Ángel 1819276fc3 test: real-Chrome and CI smoke pages inline GSAP so they wait on no CDN (#6406)
* test(studio): real-Chrome tests inline GSAP so their page waits on no request

* test(ci): smoke projects inline GSAP so required checks wait on no CDN
2026-10-26 08:20:55 +00:00
Vance Ingalls f8d51f3146 chore: release v0.8.202 (#6404) 2026-10-26 07:55:04 +00:00
Miguel Ángel 603f4214ff fix: Remotion ports keep box sizes, the manifest hook runs after format, a drag test stops flaking (#6392)
* feat(skills): a Remotion port carries Remotion's box-sizing rule so bordered boxes keep their size

* chore(skills): regenerate the skills manifest after the format pass

* fix(hooks): the skills manifest is hashed after the formatter has run

* test(studio): a drag is measured against the box the preview shows

* test(studio): another element is read bare until it is selected
2026-10-26 07:20:03 +00:00
Miguel Ángel 3ff8cd8683 chore: release v0.8.201 (#6377) 2026-10-26 04:50:26 +00:00
James RussoandYi-111-a 9096aab8c8 fix(studio): still placeholder while a video frame thumbnail loads (#6389)
Co-authored-by: Yi-111-a <153097222+Yi-111-a@users.noreply.github.com>
2026-10-26 03:56:16 +00:00
Miguel Ángel e48c8a0614 perf(studio): a settled timeline's composition check scans only its hosts, not the whole preview (#5880) 2026-10-26 01:35:00 +00:00
Miguel Ángel 84b6319346 perf(core): keep long-media analysis responsive and sample the whole clip (#5793)
* perf(studio): music beat analysis no longer freezes the page or runs during playback

* fix(core): media-treatment --analyze finishes on long HDR clips

Grade analysis decoded the clip from the start and kept every frame until the
fps filter had emitted five samples. Past 50 s the filter rate floors at 0.1
fps, so it always decoded the first 40 s at full rate and resolution: a
3-minute 4K60 10-bit HLG clip timed out at 15 s, and every long clip was
graded from its first 40 s only.

Each sample now seeks to the middle of one fifth of the clip and decodes one
frame. The timeout applies per sample and its error names the sample time and
HYPERFRAMES_ANALYZE_TIMEOUT_MS.

* refactor(core): name the keyframe seek instead of commenting it

* fix(core): count one frame per grade sample on ffmpeg 8
2026-10-26 00:15:51 +00:00
Daniel McSheehy d787681d12 feat(studio): zoom the timeline to the selected clips (#5824)
* feat(studio): zoom the timeline to the selected clips

Toolbar action and Z fit the selected clips to the visible width, with the
range margin, and stay disabled until something is selected.

* fix(studio): gate zoom-to-selection on a resolvable clip

The scroll clamp already lives in the timeline zoom request. Drop the
unused copy, and disable the button and Z unless the selection matches
a timeline clip with duration. A collapsed timeline cancels
zoomTimelineToRange instead of laying out a percent the view cannot show.

* fix(studio): keep a zoom step when the timeline is collapsed

A collapsed timeline has no track for a range zoom, so zoom in and out
step the percent directly. Z is consumed only when that zoom actually
starts, and zoom-to-selection no longer builds the span three times.

* ci: retrigger checks after workflow approval

The approved run was cancelled during checkout, so the required checks
never executed.
2026-10-25 23:22:54 +00:00
Parman Mohammadalizadeh 6a32e26580 fix(studio): the Shift+drag edit popover stays on screen when the timeline sits low (#5422)
EditPopover positions itself with position: fixed and viewport
coordinates, but rendered inline inside the timeline's dockview panel,
whose transformed overlay becomes the containing block. The popover
landed relative to the panel and was clipped below the window. Portal it
to document.body like the other timeline menus.

Fixes #5376
2026-10-25 23:09:19 +00:00
Akshar Patel 04df17cccb fix(sdk): keep font and image declarations after object edits (#6281)
* fix(sdk): preserve font and image declarations after object edits

* fix(studio): preserve variable object defaults when editing declarations

* fix(studio): show font and image values in bind warnings
2026-10-25 23:01:32 +00:00
Miguel Ángel 2c10eb0a33 chore: release v0.8.200 (#6337) 2026-10-25 20:50:21 +00:00
Miguel Ángel 70187a13b5 perf(core): the preview mounts and draws only the scenes near the playhead (#6189)
* perf(core): skip rendering preview scenes far from the playhead

* refactor(core): split the far-scene pass into small helpers

* perf(core): a first render reveals only the clips it reaches

* fix(core): reveal the clips holding first-rendered tweens, wherever their window is

* feat(core): a scene may load a project helper and wait for fonts and still swap

* perf(core): the preview mounts only the scenes near the playhead

* perf(core): a seek waits only for the scene it lands in; neighbours mount one per turn

* feat(studio): selecting a clip in an unmounted scene mounts that scene first

* fix(core): a source a play and a seek both need is fetched and decoded once

* fix(core): a scene mounting during play joins the mix without restarting what plays

* fix(studio): selecting a clip waits on a scene mount only in a preview that unmounts scenes

* fix(core): far scenes still mount after an edit, and an edit to a parked scene keeps its styles

* perf(core): web audio schedules a clip only as the playhead comes near it

* chore(studio): trim the scene hold helper's comments to its package's share

* fix(core): a scene the preview unmounts is freed, not kept by audio, caches or old roots

* fix(studio): an unmounted scene's rows and their state come from the markup it mounts with

* perf(core): the preview mounts scenes ahead of play and keeps recent ones mounted

* refactor(core): keep the far-scene neighbour rule private to its module

* style(core): format the far-scene neighbour rule

* perf(core): the preview unmounts scenes the playhead leaves, as kept ones slowed each mount

* fix(core): scenes that measure text, call their own animate or wait on font loads can unmount

* fix(core): each preview scene carries the helpers it loads, so it mounts on its own

* fix(core): a mounted scene shows though its stand-in was hidden by display

* fix(core): a helper scenes share runs once for the film, and a remounted scene keeps showing

* fix(core): a scene that also publishes its timeline under another id stays mounted

* feat(core): scenes that draw in 2D or chain the timeline they register can unmount

* perf(core): a play frame that draws nothing new skips the hidden-clip lookup

* fix(core): a GSAP file copied into a project counts as the library for scene unmounting

* style(core): drop an unneeded escape in the registered-chain pattern

* chore: core and producer size budgets make room for the preview scene window

* fix(core): a scene that draws on a 2D canvas stays mounted

* fix(core): a scene the preview unmounts lets go of timelines it built after a font wait

* perf(core): a scene leaving the playhead keeps its last rendered size, no forced layout at the cut

* refactor(core): the far-scene skip keeps last-render boxes in their own helper

* fix(core): a mounting scene never records the runtime's root timeline as its own

* chore(producer): raise the size budget to the measured size with the preview runtime inlined

* docs(core): keep the far-scene and scene-memory comments within the comment limits

* perf(core): style each hidden clip visible once ahead of its cut, so the cut frame does not

* fix(core): a seek into a scene still mounting as a neighbour waits for that mount

* chore(core): keep comment share and size budgets to main plus the measured core growth
2026-10-25 19:39:14 +00:00
Miguel Ángel 42b84632a8 chore: release v0.8.199 (#6328) 2026-10-25 18:13:20 +00:00
Miguel Ángel 9763b68a33 fix(studio): scrubbing never auditions a track the music row did not name (#6310)
The last fallback took whatever audio came first in the preview, which is usually the voiceover, whenever the music row's own element was momentarily absent.
2026-10-25 14:52:41 +00:00
Miguel Ángel d7f323d319 chore: release v0.8.198 (#6305) 2026-10-25 12:42:50 +00:00
Miguel Ángel f51650d8a7 chore: release v0.8.197 (#6298) 2026-10-25 09:17:12 +00:00
Miguel Ángel 45167743a6 chore: release v0.8.196 (#6288) 2026-10-25 06:52:05 +00:00
Miguel Ángel 38afc0b013 fix(deps): update esbuild for the security advisory (#6277) 2026-10-25 04:52:58 +00:00
Miguel Ángel 1776b42736 chore: release v0.8.195 (#6273) 2026-10-25 03:18:09 +00:00
Miguel Ángel 3eb1aeb0de perf(core): Safari stops re-serializing inline styles on every GSAP write (#5974)
* perf(core): Safari stops re-serializing inline styles on every GSAP write in a playing film

* perf(core): declare the clip-reveal subpath in its descriptor and cut added comment lines

* fix(shader-transitions): shader transitions across a scene boundary keep the scene's contents

Every revealer now goes through one core helper that shows the clip and
lifts the runtime's hidden mark together; the page-side compositor's scene
copies were still carrying the mark. The contents rule keeps its old weight.

* fix(core): films on an older shader-transitions build keep their transition scenes

Published shader builds reveal scenes by inline style without lifting the
hidden mark. When one is on the page, the runtime keeps the inline-style
rules; builds that lift the mark declare it on load and keep the fast rules.

* test(core): pin the hidden-clip contents rule's weight on its selector

* style(core): format the reveal test and move hidden-clip rule notes into names

* test(producer): pin hidden-clip behaviours in real Chrome under the mark-keyed rules

* test(producer): read the forced restyle's result so lint accepts the restyle test
2026-10-25 03:17:39 +00:00
James RussoandClaude Opus 5.5 7f19f2335a feat(studio): load GSAP from the CLI's bundled copy by default (#6256)
* feat(studio): load GSAP from the CLI's bundled copy by default

Studio preview now loads the GSAP, CustomEase and MotionPathPlugin scripts
it adds from files the CLI ships and serves same-origin at /api/vendor/npm,
instead of jsDelivr. HYPERFRAMES_GSAP_BASE_URL still wins when set, and a
composition on another GSAP version gets its plugin from jsDelivr.

Renders now honor HYPERFRAMES_GSAP_BASE_URL when they replace a missing
local GSAP script, and the setting accepts plain http only for loopback
hosts.

Closes #6205

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* refactor(studio): keep comment share flat for the GSAP local root

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(cli): find the installed gsap with node resolution when run from source

The Windows CI lane installs with the hoisted linker, so gsap is not under
packages/core/node_modules there.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(producer): load a nested composition's missing GSAP from the mirror

A sub-composition's missing local gsap/dist script was hoisted into the
render unchanged, so HYPERFRAMES_GSAP_BASE_URL (and the jsDelivr fallback)
only reached the entry document. Run the same rewrite on every
sub-composition before it is compiled, resolving its path the way the
inliner will hoist it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 03:08:42 +00:00
Miguel Ángel 2e397dba59 chore: release v0.8.194 (#6269) 2026-10-24 22:17:19 -04:00
Vance IngallsandClaude Sonnet 5.5 19374955c7 feat(studio): the blur panel turns on events with blur (#6255)
Blur finds movers by seeking, and only runs timeline callbacks while it
scans when data-motion-blur-events is on, so motion set from a render(t)
function (k3-promo's rods and pills) showed no blur. Subtle and Strong
now write the attribute and Off removes it.

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 16:27:57 -07:00
Abdullah M. Nazif 1c14fbb542 fix(studio): allow a local GSAP dependency mirror (#6247) 2026-10-24 22:13:28 +00:00
Miguel Ángel 89081b9197 chore: release v0.8.193 (#6229) 2026-10-24 12:39:08 -04:00
Miguel Ángel 1a238171ec test: the lifecycle and thumbnail suites load cold modules in a hook, not in their first test (#6212)
* test(cli): the lifecycle suite warms the CLI module graph in a hook, not in its first test

* test(studio): the thumbnail suite warms puppeteer in a hook and cancels leftover requests
2026-10-24 11:26:33 +00:00
Miguel Ángel 291144e87d fix(studio): a scene swap no longer keeps the previous preview window in memory (#6207)
* fix(studio): a scene swap no longer keeps the previous preview window in memory

* fix(studio): drop the added comment, the handler's name carries it
2026-10-24 11:12:43 +00:00