Commit Graph
529 Commits
Author SHA1 Message Date
Miguel Ángel f35b05fba0 chore: release v0.8.159 (#5621)
* chore: release v0.8.159

* chore: v0.8.159 notes list the first-frame fix

* chore: v0.8.159 notes list the sandboxed GPU check fix

* chore: v0.8.159 notes list the hidden-scene fix and the offline font test
2026-10-15 00:27:52 +00:00
Miguel Ángel fa99eec9d0 chore: release v0.8.158 (#5617) 2026-10-14 19:19:18 +00:00
Miguel Ángel b72c3fb25d chore: release v0.8.157 (#5596) 2026-10-14 09:19:15 +00:00
James RussoandClaude Opus 5.5 74e17fa9cf chore: release v0.8.156 (#5577)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-14 04:11:14 +00:00
James Russo 5a6c0575f8 chore: release v0.8.155 (#5567) 2026-10-13 23:07:51 +00:00
Xuanru Li 8147f7b940 chore: release v0.8.154 (#5545)
* chore: release v0.8.154

* ci: give the studio test job fifteen minutes

The queue run installs and builds inside the same ten minute cap.
It was still inside the studio tests when that cap cancelled the job.
2026-10-13 19:23:45 +00:00
Miguel Ángel 05786f5558 chore: release v0.8.153 (#5541) 2026-10-13 15:19:09 +00:00
Xuanru Li e8eb358fe2 chore: release v0.8.152 (#5534)
* chore: release v0.8.152

* docs(changelog): correct the v0.8.152 release notes

The summary overstated snapshot retention, history turns, and video state.
It also left out the new artifact paths and nullable keyframe times.
2026-10-13 07:37:26 +00:00
Miguel Ángel 945c61ebb6 chore: release v0.8.151 (#5529) 2026-10-13 04:13:03 +00:00
Miguel Ángel 8b27935e8c chore: release v0.8.150 (#5495) 2026-10-12 13:51:49 +00:00
James RussoandClaude Opus 5.5 bf881bf79d chore: release v0.8.149 (#5472)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 18:52:16 +00:00
Miguel Ángel 43be84d82c chore: release v0.8.148 (#5470) 2026-10-11 17:34:38 +00:00
Miguel Ángel d4dd6c097d chore: release v0.8.147 (#5456) 2026-10-11 08:55:42 +00:00
Miguel Ángel 8bca7c4417 chore: release v0.8.146 (#5448) 2026-10-11 04:25:16 +00:00
Miguel Ángel 76f8a567a5 chore: release v0.8.145 (#5412) 2026-10-10 08:04:19 +00:00
Miguel Ángel f8ee010c65 chore: release v0.8.144 (#5384) 2026-10-10 00:45:48 +00:00
James RussoandClaude Opus 5.5 3aa68869f7 chore: release v0.8.143 (#5302)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 23:28:49 +00:00
Miguel Ángel 0b21016905 chore: release v0.8.142 (#5257) 2026-10-08 16:34:18 +00:00
Xuanru LiandClaude Opus 5.5 4a335aa6a1 chore: release v0.8.141 (#5193)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 05:56:58 +00:00
Miguel Ángel 5c7f6316d3 chore: release v0.8.140 (#5175) 2026-10-07 10:04:56 +00:00
Miguel Ángel e6daed3df0 chore: release v0.8.139 (#5136)
* chore: release v0.8.139

* chore: sharpen the v0.8.139 release summary
2026-10-07 00:06:22 +00:00
Miguel Ángel 0ca28db4f8 chore: release v0.8.138 (#5121) 2026-10-06 17:53:18 +00:00
Miguel Ángel b9998dd5a8 test(studio): bundle the real-Chrome undo test with esbuild so its setup fits on Windows (#5080)
* test(studio): bundle the real-Chrome undo test with esbuild so its setup fits on Windows

* test(studio): stub only the Node built-ins the undo test bundle reaches
2026-10-06 15:32:53 +00:00
Miguel Ángel e7b69785ea chore: release v0.8.137 2026-10-06 00:39:59 -04:00
Miguel Angel Simon Sierra 3026723aa1 chore: release v0.8.136 2026-10-05 19:11:20 -07:00
Miguel Angel Simon Sierra 2f9c7dba32 chore: release v0.8.135 2026-10-05 16:49:32 -07:00
Miguel Ángel 60fc69d4f4 chore: release v0.8.134 2026-10-05 12:05:03 -04:00
Miguel Ángel f5e9c4bea4 chore: release v0.8.133 2026-10-05 08:25:49 -04:00
Miguel Ángel 46d7237f39 chore: release v0.8.132 2026-10-05 07:27:54 -04:00
Miguel Ángel 07d05cc459 chore: release v0.8.131 2026-10-05 07:02:33 -04:00
Miguel Ángel afb266d3fe chore: release v0.8.130 2026-10-05 05:40:59 -04:00
Miguel Ángel 198eb10f59 chore: release v0.8.129 2026-10-05 04:53:17 -04:00
Miguel Ángel 5765c63244 chore: release v0.8.128 2026-10-05 03:55:42 -04:00
Miguel Angel Simon Sierra da1ac75718 chore: release v0.8.127 2026-10-04 17:25:23 -07:00
Miguel Angel Simon Sierra a9787836e8 chore: release v0.8.126 2026-10-04 15:36:19 -07:00
Miguel Ángel b45818f69d fix(studio): the motion path draws on every load, not only when the layer's node is the frame's own (#4957)
* fix(studio): the motion path draws on every load, not only when the layer's node is the frame's own

useMotionPathData found the selected layer with `instanceof` against the preview
frame's HTMLElement. In the Studio preview the body's nodes often carry the editor
window's prototypes (see core's runtime/domRealm.ts), so the check failed, the path
never got its anchor and drew nothing. Core's realm-free isHtmlElement owns that
question; both motion-path call sites now use it.

* fix(studio): every preview node check asks what a node is, not which window built it

Studio checked preview nodes against their document window's own constructors in
seek reapply, studio motion, timeline z-order commits, the manual offset drag and
the z-order menu. On loads where body nodes carry the editor window's prototypes
those checks fail silently, as the motion path did. They now use core's realm-free
predicates, and a source test fails on a new window-bound check.

* fix(studio): the webmcp preview helper asks what a node is, and both realm tests stub the frame

* fix(studio): the last preview node checks ask what a node is, and the guard sees any constructor read

The selector walk read ancestor ids only from editor-realm nodes and the audio group
observer never saw a group the preview added. Both use core's predicates now. The guard
flags any DOM interface read off an object, the spellings it missed included, and the
window gates the old constructor needed are gone.

* test(studio): cover the main seek filter across windows and split member reads

* fix(studio): a press on the motion path's line inside the selected layer moves the layer

* fix(studio): a press inside the selected layer moves it, and path nodes sit where the layer is

* refactor(studio): one helper places a path point, for keyframes and the start

* fix(studio): a handle over a path node takes its press; nodes sit right on centred layers

* fix(studio): reading a layer's path anchor leaves its CSS translate alone

* chore(studio): keep the motion path home file under the comment share

* fix(studio): a new motion path ends where you click on a CSS-centred layer

* fix(studio): a path made on a transform-centred layer ends where you click

* style(studio): keep a motion path test comment within 120 columns
2026-10-04 22:08:29 +00:00
Miguel Angel Simon Sierra b6c89b5583 chore: release v0.8.125 2026-10-04 13:35:42 -07:00
Miguel Angel Simon Sierra 706118aa1a chore: release v0.8.124 2026-10-04 10:06:35 -07:00
Miguel Angel Simon Sierra 638e6b7b33 chore: release v0.8.123 2026-10-04 05:06:49 -07:00
Miguel Angel Simon Sierra b7baa5fde1 chore: release v0.8.122 2026-10-04 03:39:06 -07:00
Miguel Angel Simon Sierra a6fc2592e2 chore: release v0.8.121 2026-10-04 01:30:55 -07:00
Miguel Angel Simon Sierra ccd80ea621 chore: release v0.8.120 2026-10-03 23:34:55 -07:00
Miguel Angel Simon Sierra e5fbb01fc0 chore: release v0.8.119 2026-10-03 21:31:22 -07:00
Miguel Angel Simon Sierra ccab31b558 chore: release v0.8.118 2026-10-03 19:25:43 -07:00
Miguel Ángel f7987bb1f2 chore: release v0.8.117 (#4978) 2026-10-03 17:29:44 -07:00
Miguel Ángel 6149ec87e8 chore: release v0.8.116 (#4969) 2026-10-03 13:31:30 -07:00
Miguel Ángel 461d83cd69 chore: release v0.8.115 (#4958) 2026-10-03 09:34:27 -07:00
Miguel Ángel 70dde41b5c perf(studio): keep timeline bulk actions under a second, hand-move at most 3 clips (#4932)
* perf(studio): keep timeline bulk actions under a second, hand-move at most 3 clips

Dragging or keyboard-moving a selection of 4 or more clips is refused with a
toast pointing at the prompt box; 1 to 3 clips move as before.

Root causes of the multi-second waits on large projects:
- every selected clip fired its own source-existence probe; they now leave as
  one request per file
- a timeline delete sent one request per clip, each re-parsing the file; it is
  now one request that parses once
- each click on a clip from another file re-fetched GSAP data for every
  composition; covered files are kept and unchanged files answer 304
- any root index.html write re-captured every composition thumbnail; only a
  root head edit does now, since a scene page borrows nothing else from it

Adds timeline-bulk-actions.mjs, a browser benchmark of select-all, move 3 and
delete-all on a real project.

* chore(studio): trim the bulk benchmark header to the comment limit

* refactor(studio): tidy the bulk-action fixes after review

Root head memo is keyed by the root file's content so every subscriber of one write gets one answer, and a thumbnail request can no longer overwrite it. The GSAP read reuses the shared content version as its ETag.

* fix(studio): keep a head edit's thumbnail refresh when a later write replaces it

File changes coalesce to the newest while a drain is in flight, so the affected-composition lists are merged instead of replaced. A failed GSAP read stays unloaded and is retried, and the GSAP read's ETag is salted with the parser version.

* feat(studio): cap hand-resizing a multi-selection at 3 clips like moving

Dragging a resize edge with 4 or more clips selected is refused with the same toast as a move; the rule is one constant and one helper shared by pointer move, pointer resize and keyboard pickup.

* fix(studio): keep a head edit's thumbnail refresh through a replaced conflict

A newer blocked change replaces the held one, so it now inherits the thumbnails the held one owed.

* fix(studio): keep a held head edit's thumbnail refresh when a later write saves cleanly

The clean-save path and the failed-cleanup path now merge the held blocked change's affected compositions, and the blocked-state merge runs inside the state update so two conflicts in one tick cannot lose the first.

* chore(studio): keep useTimelineClipDrag under the 600-line cap

* feat(studio): cap by the clips an edit would change, and cut the added comments

The 3-clip rule counts the clips a move or trim would write to: a locked clip swept into a move stays put, and a trim some member cannot take edits only the grabbed clip. Comment share is back at or under the base in every changed file.

* fix(studio): clear fallow audit and comment length on the multi-select cap

* fix(studio): keep bench script comments under the block limit

* fix(studio): keep the failed file's payload when another file's snapshot delete fails
2026-10-03 08:16:01 +00:00
Miguel Ángel 01c6f6004a chore: release v0.8.114 (#4922) 2026-10-02 17:14:16 -07:00
James RussoandMiguel Ángel 5c52f72399 fix(studio): parse modern CSS colors without a new dependency (#3931)
* fix(studio): parse modern CSS colors without a new dependency

* refactor(studio): one colour parser for the text toolbar, stricter rgb numbers

The inline text toolbar kept its own canvas fallback for named colours.
parseCssColor now resolves them, so the toolbar uses it alone.
rgb() channels must be well-formed numbers; that replaces the NaN check
after parsing and rejects rgb(1. 2 3) as CSS does.

* refactor(studio): drop comment lines the comment ratchet refuses in colorValue

* fix(studio): linear-time rgb() patterns and no new colour literal in the parser

The rgb() number pattern now has one way to match each digit run, which clears
CodeQL's slow-regex alerts. The canvas reset uses transparent so the Studio
colour-literal ratchet stays at its baseline.

* fix(studio): legacy colours resolve in browsers without relative colour syntax

parseBrowserColor reads the colour itself from the canvas first and accepts a
#rrggbb or rgba() result, then tries color(from ...). Named, hsl() and percent
rgb() colours resolve again in the text toolbar on Chrome before 119 and Safari 17.

* test(studio): a colour the canvas rejects parses to null, not transparent black

* fix(studio): an inserted gradient stop takes the colour the gradient paints there

The stop colour is color-mix() in oklab, or srgb when both stops are legacy,
resolved by the browser, so it matches the painted midpoint including
premultiplied alpha; the channel blend stays as the fallback. The parser tries
color(from ...) before the legacy read, keeping alpha precise, and calls
CSS.supports inside its try. A Chrome-147-shaped fake canvas covers the modern
path in unit tests.

* test(studio): keep the fake browser canvas inside its test file

* fix(studio): mix an inserted gradient stop in the space the whole gradient uses

* fix(studio): let an unresolved var() stop keep a legacy gradient in sRGB

* fix(studio): only a bare var() stop leaves the gradient space to its neighbours

* fix(studio): pick light-dark() text colour from what the element paints

* refactor(studio): drop the neighbour clause the whole-gradient check already covers

* fix(studio): resolve the picker colour from the element that paints the selected text

* fix(studio): read the picker colour from the character the swatch colour came from

---------

Co-authored-by: Miguel Ángel <miguel.sierra@heygen.com>
2026-10-02 22:26:00 +00:00