Commit Graph
997 Commits
Author SHA1 Message Date
Abdullah M. Nazif 8efd9ca523 fix(sdk): drain pending saves and adapter storage on flush (#5285) 2026-10-08 19:51:25 +00:00
Abdullah M. Nazif e529fbb015 docs: explain negative z-index stacking contexts (#5201) 2026-10-08 19:31:12 +00:00
James RussoandClaude Opus 5.5 de1ef5a05a fix(engine): extract long video ranges in segments and keep plan uploads flowing (#5280)
* fix(engine): extract long video ranges in segments and keep plan uploads flowing

A distributed render's plan step extracted a whole video in one ffmpeg process,
so a long clip hit ffmpegProcessTimeout (300 s) however much of Lambda's
15-minute limit was left, and every frame then uploaded in batches of 16 that
each waited for their slowest blob.

Ranges longer than two minutes now extract as two-minute segments that run side
by side, each numbered after the last. They sample the same absolute times as a
single pass, so the frames are byte-identical (checked on a 26-minute, 37,440
frame clip). Plan v2 publishing keeps 32 uploads in flight instead of batching.
On a 10 GB Lambda the 26-minute clip's plan step fell from 395 s to 200 s.

The Lambda docs now state the plan-step length bound.

Fixes #5260

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

* fix(engine): split extraction on an integer frame count

The split compared and subtracted float seconds, so 200.3 - 80.3 became
120.00000000000001 s: a second segment got `-t 1.42e-14`, which ffmpeg
rejects, failing an ordinary two-minute range. The frame count now comes from
extractionFrameCountForDuration, the rule a single pass follows, and every
segment takes an exact frame count.

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-08 19:07:46 +00:00
Miguel Ángel 0b21016905 chore: release v0.8.142 (#5257) 2026-10-08 16:34:18 +00:00
Miguel Ángel c7d41dee5a fix(cli): enforce capture screenshot limits and report interruptions (#5171)
* fix(cli): enforce capture screenshot limits and report interruptions

* refactor(cli): split screenshot step out of capture animation phase

Keeps the screenshot limit outside the mirrored core-extraction argument
list and moves scroll screenshots into their own step, so both stay under
the audit's duplication and complexity gates with no behaviour change.
2026-10-08 15:41:50 +00:00
Miguel Ángel 8dae5ef89b fix(core): make grading writes previewable and honor computed properties (#5157)
* fix(core): write only authored hue curves, so a single hue curve passes lint

* fix(cli): apply over a grading saved with empty hue curves instead of refusing it

* fix(core): read grading properties from computed style, and stop advising an inline start

* fix(cli): preserve validation during legacy hue repair

* fix(cli): preview grading writes without apply
2026-10-08 15:21:47 +00:00
Miguel Ángel cf1b04bb71 feat(cli): accept host-managed HeyGen access tokens (#5177)
* fix(auth): accept host-managed HeyGen access tokens

* fix(auth): share environment header validation

* docs(auth): condense credential resolver guidance

* fix(auth): report the account a browser login just signed in

Identify the account from the tokens the login issued, not a fresh credential
lookup that an environment token or API key outranks.

* docs(auth): list the host access token in the CLI credential order

* fix(cli): name a rejected host access token on publish

Publish told a host-token user to log in again, which cannot help while the token outranks the login.

* docs(auth): show the media credential order main resolves

* fix(cli): warn at logout that a host access token still signs commands

One map of environment credential variables, owned by the resolver, now feeds the logout warning and both publish messages.

* docs(auth): scope the media credential order to the audio scripts

* refactor(cli): read every env credential name from the resolver's map
2026-10-08 10:33:57 +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 d2a3c076d0 fix(player): load compositions from document duration (#5176)
* docs(player): map composition probe readiness contract

* fix(player): resolve preview readiness from document duration

* fix(player): preserve timeline grace and terminal probe failure

* fix(player): scope probe rejection to the failed document

* test(player): share terminal readiness fixtures
2026-10-07 18:08:20 +00:00
Miguel Ángel 5c7f6316d3 chore: release v0.8.140 (#5175) 2026-10-07 10:04:56 +00:00
Miguel Ángel da6259896b fix(core): settle slow documents against their own frame cadence (#5168)
* docs(core): map document-relative readiness contract

* fix(core): measure idle against document frame gaps

* fix(core): preserve fast-page readiness while calibrating slow frames

* docs(core): clarify readiness coverage and measurement provenance
2026-10-07 08:40:57 +00:00
Miguel Ángel 4fcad1ed74 fix(media-use): use a host app's music tools; fail loudly without the heygen CLI (#5154)
* fix(media-use): use a host app's music tools; fail loudly without the heygen CLI

* fix(media-use): name the heygen CLI only for music and sound effects; keep the sfx test offline

* fix(skills): workflow skills use a host app's own music tools first

* fix(skills): say how a host app's music track reaches the narrated workflows

* fix(skills): set a host app's music track after the last audio pass

* fix(skills): a host-music film with no narration still fetches its sound effects

* fix(media-use): keep the stub-failure test off the machine's heygen CLI; sync the skills manifest

* fix(skills): audio passes keep a host app's music and sounds; silent needs no sound cues

* fix(skills): host audio keeps string frames, stops on a broken audio_meta.json, survives a re-run

* fix(skills): report a host audio entry with no path and a broken sidecar instead of crashing

* fix(skills): keep host audio written while an audio pass runs

* test(cli): serve the telemetry capture while the resolve child waits on it

* test(cli): fail the telemetry capture when the resolve child exits non-zero

* style(skills): wrap the host audio comment to the 120-column limit
2026-10-07 07:16:51 +00:00
Miguel Ángel 80c2547eac feat(cli): send missing features and host-app friction as ratingless feedback (#5140)
* docs(skills): ask agents inside a host app to report its friction as feedback

* feat(cli): send missing features and host-app friction as ratingless feedback

* fix(cli): keep the rating error, refuse blank reports and document ratingless feedback

* docs(skills): leave names and figures out of missing-feature reports

* docs(skills): keep anything private out of missing-feature reports
2026-10-07 06:40:37 +00:00
Miguel Ángel 2d98d5c15f fix(check): stop false sweep_static and text-overlap alarms on compositions that are fine (#5147)
* fix(check): see color, filter and media time under seek, and name data-no-timeline for stills

* fix(check): warn instead of fail when only audio advances, and judge text overlap on glyphs

* fix(check): judge glyph overlap by the glyph box, and see capitalized words and one-side borders

* fix(check): capitalize past leading punctuation, test outline color, trim a comment

* fix(check): capitalize words the way Chromium does, so digit-led words stay lowercase
2026-10-07 05:38:45 +00:00
James RussoandClaude Opus 5.5 f74f260286 feat(core): bound imported scene timing to source intervals (#5132)
* feat(core): support deterministic async frame sources

* feat(core): bridge preserved film HTML to native capture

* feat(core): bound imported scene timing to source intervals

* test(producer): verify film bridge pixels in real browser

* fix(runtime): retain queued draws and disable unsafe dedup

* fix(runtime): fail promptly on runner reloads and send errors

* fix(runtime): align film draws with export windows

* docs(core): mark frame-source hosts with data-no-timeline

A composition that follows the frame-source contract registers no GSAP
timeline, so lint reported missing_timeline_registry and every render
waited 45 s for timeline registration (17.6 s -> 1 min 47.9 s for the
14 s imported film sample). Document the existing data-no-timeline
opt-out for the host and a timeline-less root.

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

* docs(core): require data-no-timeline on imported film hosts

Imported film wrappers have no GSAP timeline. Without data-no-timeline
on the scene hosts and root, lint fails with missing_timeline_registry
and each render waits 45 s for timeline registration.

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

* fix(runtime): avoid transport redraws after render seeks

* test: set explicit film fixture canvas background

* test: diagnose film capture timeout phase

* test: foreground film pages before screenshot capture

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 05:25:09 +00:00
James RussoandClaude Opus 5.5 891a18af76 feat(core): bridge preserved film HTML to native capture (#5131)
* feat(core): support deterministic async frame sources

* feat(core): bridge preserved film HTML to native capture

* fix(runtime): retain queued draws and disable unsafe dedup

* fix(runtime): fail promptly on runner reloads and send errors

* docs(core): mark frame-source hosts with data-no-timeline

A composition that follows the frame-source contract registers no GSAP
timeline, so lint reported missing_timeline_registry and every render
waited 45 s for timeline registration (17.6 s -> 1 min 47.9 s for the
14 s imported film sample). Document the existing data-no-timeline
opt-out for the host and a timeline-less root.

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

* docs(core): require data-no-timeline on imported film hosts

Imported film wrappers have no GSAP timeline. Without data-no-timeline
on the scene hosts and root, lint fails with missing_timeline_registry
and each render waits 45 s for timeline registration.

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

* fix(runtime): avoid transport redraws after render seeks

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 03:55:42 +00:00
Miguel Ángel f6b3821626 fix(catalog): run block scripts inline in the docs player, and pages for six shader blocks (#5139) 2026-10-07 03:11:49 +00:00
James RussoandClaude Opus 5.5 a17d0bfc00 feat(core): support deterministic async frame sources (#5130)
* feat(core): support deterministic async frame sources

* fix(runtime): retain queued draws and disable unsafe dedup

* docs(core): mark frame-source hosts with data-no-timeline

A composition that follows the frame-source contract registers no GSAP
timeline, so lint reported missing_timeline_registry and every render
waited 45 s for timeline registration (17.6 s -> 1 min 47.9 s for the
14 s imported film sample). Document the existing data-no-timeline
opt-out for the host and a timeline-less root.

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

* fix(runtime): avoid transport redraws after render seeks

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 01:59:55 +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 34552a21d2 fix(cli): let parakeet-mlx detect the language and name the Parakeet install under auto (#5124)
* fix(cli): let parakeet-mlx detect the language and name the Parakeet install under auto

* docs(cli): say what --language does under each engine

* docs(cli): whisper transcribes as the --language, it does not filter

* chore(cli): drop a comment the install-hint condition already says
2026-10-06 19:04:28 +00:00
Miguel Ángel 0ca28db4f8 chore: release v0.8.138 (#5121) 2026-10-06 17:53:18 +00:00
Miguel Ángel 6308727b85 chore: remove committed design notes and ignore docs/contracts (#5107)
* chore: remove committed design notes and ignore docs/contracts

* chore: allow the design note deletions in the main deletion guard
2026-10-06 06:12:45 +00:00
Miguel Ángel e7b69785ea chore: release v0.8.137 2026-10-06 00:39:59 -04:00
Miguel Ángel 1db44c6595 fix(cli): report transcription language and progress (#5103)
* docs(cli): record transcription output contract

* fix(cli): report transcription language and progress
2026-10-06 03:42:43 +00: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 f835f83164 fix(catalog): 3D previews load their scripts under the docs host's script policy (#5090)
* fix(catalog): 3D previews load their scripts under the docs host's script policy

* fix(catalog): preserve script text through HTML parsing

* docs(catalog): describe the shared script bundle
2026-10-05 15:52:51 -07:00
Miguel Ángel 60fc69d4f4 chore: release v0.8.134 2026-10-05 12:05:03 -04:00
Miguel Ángel 061a5c0265 docs: add Studio app pages for Mac and Linux (#5063)
* docs: add Studio app pages for getting started with the Mac app

Six short pages in a new Studio app tab: get the app, connect Claude Code or Codex, make your first video, change it with the agent, export, and updates and troubleshooting. Screenshots come from a neutral fixture project.

* docs: cover Linux in the Studio app pages

The app ships a Linux AppImage beside the Mac app. Install steps get Mac and Linux tabs, platform labels name both, and troubleshooting lists where projects, settings and exports live.

* docs: correct Studio app sign-in, install and edit details

First launch asks for HeyGen sign-in on the first click; the Mac download is a disk image with an installer inside; Select shows Prompt to edit; the Connect screen sends the waiting request itself; billing, export quality and update wording match the app. Open Terminal is described for both systems.

* docs: keep Studio app tables readable on phones

Three-column tables scrolled sideways at 390 px and the data-folder table broke paths mid-word; they become two-column tables and a short list.

* docs: quote Studio app messages without their periods

Quoted UI text no longer carries its own period into a sentence or table cell, and the Mac install step says the HeyGen check can take a minute or two.

* docs: match Studio app installer and update messages

Quote the installer's HeyGen check, damaged-download and slow-check messages, and the stalled-update messages with Download it instead and Settings' Download the latest version.

* docs: fix Studio app sign-in timeout and Codex setup wording

* docs: name Framey's stuck-update line in Studio app troubleshooting

* docs: use one Studio app message per update state

A stalled update says 'The update is taking longer than it should' and a failed one 'The update didn't finish', in Framey's line and on the card alike; Try again starts the update over.

* docs: say Try again starts a new update, not one from zero
2026-10-05 15:19:14 +00: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 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 Ángel 0ca69472d9 feat(cli): feedback says whether a person or an agent wrote it, with the email an app attaches (#4984)
* feat(cli): feedback says whether a person or an agent wrote it, with the email an app attaches

* refactor(cli): split the .env loader so each part stays simple

* fix(cli): a broken .env loader fails loudly; only a missing .env is ignored
2026-10-04 05:07:49 +00: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 7dea1e581f fix(studio): playhead keyframe edits keep their ease, undo names its edit and never waits on videos (#4889)
* fix(studio): an edit on a GSAP-animated layer writes its value at the playhead into the file's tween

* fix(studio): undo pressed while an edit saves undoes that edit, not one started after the key

* fix(studio): an edit stays saved when the history reply after it cannot be read

* feat(studio): export ColorField and GradientField; a session style commit takes a map

* refactor(studio): name the map form instead of commenting it

* feat(studio): a host can move layers by exact film px, one undo per call

handleDomGroupMoveBy(moves) on useDomEditSession and DomEditValue moves each
selection by its delta in composition px, for Desktop's align and distribute.

It reuses the group drag's own path: a drag member per element (press-time
route, measured offset map), the delta carried to screen px through the
preview frames, then handleGsapAwareGroupPathOffsetCommit, so one shared
coalesce key gives one undo entry and GSAP members take the GSAP write.
A member that can't move refuses the call before anything is written; the
refusal rejects with its reason and shows no Studio toast (the group commit
takes refusalToast: false; telemetry stays). Zero deltas are skipped.

Tests: a pre-offset element and one under a half-scale parent move by exactly
{10,0} and {0,-5} under one group key; a half-scale parent with a 30 deg
rotated ancestor lands within the 0.001 px a translate is written with; a
GSAP member goes through the GSAP write; three refusal kinds write nothing,
leave the boxes where they were, show no toast and leave no gesture mark,
while a canvas group drag still toasts; the session hands the call to the
group commit with refusalToast: false. Each mutation (no frame mapping, no
zero skip, no restore, no teardown, no capability check, toast on refusal)
fails at least one of them.

* fix(studio): an outside change during a drag waits for the drop to show

While a gesture mark is live in the preview, refreshPlayer takes the shadow load instead of
swapping scenes in place. A swap replaced the node under the pointer mid-drag; the shadow load
is then held by the existing gesture hold and, if the drop saved, reloaded fresh by the stale
rule, so this adds no second "released" signal.

Test: an outside change during a live drag on a preview that can swap scenes leaves the dragged
node in place, shows nothing under the pointer, and after the drop loads fresh with the dropped
position. It fails on the parent without the condition ("swapped under the pointer").

Cost case, measured in a real headless preview on the edit-accuracy bench's per-frame teleport
check. Every GSAP instant patch was forced to miss and fall back to reloadPreview during its own
commit; move and rotate of a held element (gsap.set and tl.set holds), px and xPercent
placement, r0 and r30, root and nested, at 100%:
- The gesture mark was live when the fallback asked for the reload, but had always ended by the
  time refreshPlayer ran (refreshKey is consumed in an effect after the commit settles). So the
  new condition never fired there: root previews offer no scene swap and load shadow on both
  builds, and nested previews swap on both builds.
- Worst post-release frame offset, 32 cases on this build and 32 on the parent: 0.00 px over
  76-106 frames each (release to settle). No frame was off by more than 0.5 px.
- Sensitivity: a 3 px nudge injected 50 ms after the fallback reads back as 3.00 px.

* fix(studio): an edit no longer reopens the live-updates stream, and thumbnails ask one at a time

* fix(studio): an undo no longer waits behind paused preview videos for a connection

* feat(studio): a host whose API needs same-origin cookies can have Studio send them

* docs(studio-server): a host on same-origin cookies sets the Studio credentials opt-out

* test(studio): an undo is not held up by the preview's paused videos

* fix(studio): a resize inside one gesture writes a mixed tween once, in place, never beside it

* chore(studio): keep the carried fixes inside the comment ratchet; telemetry posts through studioApiFetch

* test(studio): a drag on a mixed tween is one write under the gesture key

* fix(studio): freeze-frame, loudness and peak-map requests go through studioApiFetch too

* fix(studio): an undo with no project open reloads in full instead of skipping nested files

* refactor(studio): drop the soft reload's reparse seeding, the held-element sweep covers it

* test(studio): keep the undo-restore browser test off the network and inside its timeout

* test(studio): nested composition reads expect the cookie-free request studioApiFetch sends

* fix(studio): an edit at the playhead rewrites its tween in place, so later tweens keep their times

* fix(studio): a rotate on a tween that turns another axis holds its angle and never turns early

* fix(studio): plan every group member before the first write so one refusal moves none

A group drag or nudge preflighted each member against the move refusal rule only. The value-at-playhead planner ran later, in the commit loop, after earlier members were already flushed to disk, so a tween with extras, eased keyframes or an unknown ease left the group half moved.

The group preflight now runs the commit's own route and keyframe plan for every member with its real offset, so any refusal refuses the whole group with nothing written and one toast attributed to the refusing member. The plan is not reused in the commit: earlier members' writes change the file under it, so each member re-plans against the fresh tween, from the same planValueEdit.

* chore(studio): the fetch lint rule also catches window.fetch, globalThis.fetch and self.fetch

* docs(studio-server): set the credentials flag before Studio loads; a mounting host injects it

* test(studio): the undo socket test needs six pinned videos under Vite and checks each undo restores

* fix(studio): Studio leaves cookies out of its requests only when served from loopback

* fix(studio): undo takes back the first edit, and the first save never waits on media

* fix(studio): undo of a move whose save failed stays undone and steps back no older edit

* fix(studio): a style set by its JavaScript name saves under its CSS name

* test(studio): the undo socket test holds round 0 to a full restore too

* fix(studio): the host revert keeps returning what shows the edit again

* fix(studio): an entrance rewritten at the playhead still shows its start state before it starts

* fix(studio): undo takes back the edit pending at the key even after a later edit claims

* chore(studio): lift the late-write quarantine now that undo never waits on videos; format

* test(studio): pin an entrance's start render on the written tween, not a happy-dom GSAP run

* revert(studio): leave entrances as on main, immediateRender does not render a keyframed start

This reverts commit ee9d130d3c and its written-vars test.

* revert(studio): undo goes back to the newest claim after the key, as on main

This reverts commit 5b9009a823.

* revert(studio): first-undo history opening moves to the next PR

This reverts commit 4e1e75d7f4.

* revert(studio): the undo socket test exempts round 0 again until first-undo lands

This reverts commit 1f8f97047c.

* test(studio): bank the edit accuracy cases this PR makes pass

* refactor(studio): share one project file fetch between the plain and optional reads

* test(studio): share the WebMCP host shim between the browser gates

* test(studio-server): share one stub adapter across the route tests

* refactor(studio): type the preview slot props from the NLE context

* test(studio): share the setup the new editing tests copied between files

* refactor(studio): split playhead tween picking and undo path merging into small tested helpers

* test(studio): pin when a resize at the playhead also writes the anchor move

* test(parsers): pin rewriting a tween in place as keyframes

* chore(studio): cut comments the new helper names already say

* fix(studio): composition thumbnails keep two fetches in flight, as the document lifetime fix expects

* fix(studio): a playhead edit parses a tween not yet played and matches only its own tween

* fix(parsers): a new position argument goes after the last argument, so trailing commas stay valid

* fix(studio): a second undo pressed during one save steps back to the edit before it

* test(studio): pin the slot an aborted thumbnail frees and the shared tween refusal

* refactor(studio): split the unplayed-tween parse into small helpers and name the claim release

* fix(studio): a playhead edit keeps the tween's default ease, delay timing and loop settings

* fix(studio): a group move refuses layers animated in two files and plans at the real drop

* style(studio): format two test files

* refactor(studio): check a group's files inside the preflight helper

* refactor(studio): move the group preflight checks out of the editing hook, under 600 lines

* fix(studio): read an unreached tween without redrawing other layers, and compare write files

* test(studio): use the shared selection helper in main's keyframe-at-time telemetry test

* chore(studio): fix a comment that read as a repo path and cut one added comment

* fix(studio): read a later tween's start as playback does, and count every keyframe add

* fix(studio): two undo presses during one save step back two edits, not one twice

* fix(studio): an undo that succeeds by any route retires the claim on the edit it undid

* fix(studio): a claim is never handed back to an edit another undo has already undone

* fix(studio): an undo picks its claimed edit at the press and skips it once undone

* fix(studio): a press refuses, as main did, once its edit is undone and a newer edit exists

* fix(studio): an unplayed keyframe tween clears every keyframe's channels before it is read

* fix(studio): reading an unplayed tween puts back every transform value its clear removed

* fix(studio): reading an unplayed tween restores each layer's whole style and GSAP state

* fix(studio): reading an unplayed tween skips plain-object targets and restores attributes

* fix(studio): shared tween-target filter uses GSAP's own styled-element test

* fix(studio): match a parsed tween on any target, and check a later keyframe channel's start

* docs(studio): say the unplayed-tween read restores styled elements only

* test(studio): a drag on a fromTo start shows the dropped x through the runtime seek
2026-10-03 13:10:54 -07:00
Miguel Ángel 461d83cd69 chore: release v0.8.115 (#4958) 2026-10-03 09:34:27 -07:00