Commit Graph
544 Commits
Author SHA1 Message Date
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 Ángel 34ff5ca1de refactor(core): one pure owner for composition length and root size (#4990)
* test(core): pin how the runtime resolves a composition's length and size

* refactor(core): move composition length and root size rules into a pure module

* test(core): pin the one-frame timeline floor against a derived length

* fix(core): build and declare the composition-length subpath, reject a non-finite declared length
2026-10-04 08:16:20 +00: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 cd1a34ceca fix(studio): one owner for gsap CDN URLs, so MotionPathPlugin matches the composition's gsap (#4976)
* fix(studio): load MotionPathPlugin at the composition's own gsap version

* fix(core): list the gsap-cdn subpath where core's exports are generated from

* fix(core): every default gsap URL comes from the one gsap-cdn owner

* fix(core): the gsap a new composition or first tween gets comes from the gsap-cdn owner
2026-10-04 00:44:50 +00: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 ada4e0d289 fix(studio): show each timeline row its own layer instead of a flat bar (#4917)
* fix(studio): show each timeline row its own layer instead of a grey bar

A row got a frame only if it spanned under 92% of the film and its id did not
look like a backdrop; every other row drew a plain grey bar. Every element row
now gets its frame, and the capture fades the row element's siblings first, so
the frame shows that layer and not the whole film. Studio's dev server and the
CLI share one capture helper; Studio's own copy is gone.

* fix(studio): read timeline rows from any realm so each keeps its selector

* refactor(studio-server): always isolate the element in a thumbnail clip

* fix(cli): undo a thumbnail's isolation before its page takes the next capture

* chore(core): generate the dom-realm export and trim thumbnail clip comments

* fix(studio-server): restore sibling opacity after a clip, hash selectors in cache keys

* fix(studio-server): keep faded siblings in a page-owned list so restore is exact

* feat(studio): draw a text layer row as its own live text instead of a captured picture

* refactor(studio): move timeline text reading into its own module

* fix(studio): keep text rows readable and current, and leave painted layers as pictures

* fix(studio): refresh a canvas-edited text row by its own identity and source file

* fix(studio): refresh a canvas-edited text row known only by its data-hf-id
2026-10-03 00:22:49 +00:00
Miguel Ángel 01c6f6004a chore: release v0.8.114 (#4922) 2026-10-02 17:14:16 -07:00
Miguel Ángel aca4bc2f49 chore: release v0.8.113 (#4913) 2026-10-02 12:14:00 -07:00
Miguel Ángel ea55218eba chore: release v0.8.112 (#4909) 2026-10-02 08:36:30 -07:00
Miguel Angel Simon Sierra 8447a55a1d chore: release v0.8.111 2026-10-02 01:32:47 -07:00
Vance Ingalls ec6363d3b6 chore: release v0.8.110 2026-10-02 00:31:59 -07:00
Miguel Angel Simon Sierra 6691e59b1a chore: release v0.8.109 2026-10-02 00:02:36 -07:00
Vance IngallsandClaude Sonnet 5.5 0559be0b13 feat(studio): link a video and its audio with data-link (6/8) (#4818)
* feat(core): add data-link media link helpers

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

* feat(lint): warn on out-of-sync and orphaned linked clips

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

* feat(studio): select, drag and trim linked clips together

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

* feat(studio): detach, merge, link and unlink source transforms

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

* feat(studio): link-aware split, delete, alt-edit unlink and link edit actions

Split and delete fan out to link partners. Alt drag/trim edits one member
and unlinks it. onLinkEdit runs unlink, link, detach and merge as one undo
step each. Single-clip timing edits of a linked clip skip the SDK path so
its linked default cannot move the partner behind the store.

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

* feat(studio-server): give split right halves of a linked pair their own link

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

* feat(studio): clip menu detach, unlink, link, merge back and delete-one items

Items live in clipMenuLinkItems.tsx with a one-line hook in ClipContextMenu;
the same resolver drives the Cmd+L, Opt+Shift+D and Opt+Delete shortcuts.

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

* feat(sdk): setTiming applies to data-link partners by default

{ linked: false } edits one member and unlinks it, matching Studio's Alt-edit.

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

* docs(skills): document data-link linked clips in hyperframes-core

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

* chore(studio): keep comment share at or below base in link plumbing

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

* test(studio): audio pill link follows data-link, not a shared file name

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

* fix(studio): alt-click selects one linked member even inside the pair selection

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

* refactor(lint): drop the rule-list comment for the linked clip rules

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

* fix(sdk,lint): keep a link group inside its own composition

Link ids are minted per file, so lk-1 is normal in the root and in a child
composition. The SDK's linked-timing query descended into nested hosts and
addressed every match with the initiating scope, so moving a root clip moved
the child's pair too; lint grouped them into one drifting group. Both now
group only members of the same composition scope.

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

* fix(studio): match linked media by full asset path, scope links, keep hidden sound silent

Merge and Link compared only a lowercased basename, so assets/one/talk.mp4
and assets/two/talk.mp4 enabled a destructive Merge. Clips now compare the
src resolved against each clip's own source file, and Merge re-checks the
two srcs in the source before it runs. Link membership in the timeline
(linked members, gesture expansion, unlink orphans) is scoped to a source
file. Detach and the keep-sound cutout carry a hidden video's data-hidden
to its audio, and Merge refuses when only one member is hidden.

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

* refactor(studio): move the timeline move-edits handler into its adapter

App.tsx sat at 600 lines on this layer and 602 once merged with main.
useTimelineMoveEditsHandler now lives beside persistTimelineMoveEditsAtomically,
same callback and dependencies, bringing App.tsx to 592.

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

* fix(sdk,studio,lint): keep link groups inside inline compositions

A link group now stays inside the nearest data-composition-id or
data-composition-file ancestor. The SDK used to recognise only file hosts,
and Studio compared only sourceFile, so an inline child composition that
reused a link id was edited together with the root group. core/media-link
linkScopeOf is the shared rule for the SDK and Studio. Lint cannot import
core, so it uses the same two attributes directly. Studio rows record their
compositionScope, and link and merge refuse pairs that cross it.

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

* fix(sdk): refuse a link edit whose partner address names another clip

A partner addressed in the caller's scope can resolve to a different element
when an inline composition reuses a root clip's data-hf-id. setTiming now
checks that each partner's address resolves back to that partner and throws
before mutating when it does not, instead of editing the root clip.

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

* fix(studio): a remote media url keeps its query when matching an asset

Two different videos at one remote path with different queries were treated as
the same file, so Merge could delete the audio and use the wrong video's
sound. Project-local srcs still drop query and hash.

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

* fix(studio): keep a remote url's query exactly as written when matching assets

Decoding the whole url folded %26 into & so two different media urls matched.
Decode only the path; the query is compared as authored.

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

* fix(studio): compare a remote url as serialized, decode only local paths

A remote pathname with an encoded reserved character (%3F) matched the same
path with a literal ?, though they can return different media. Remote urls
keep origin, path and query exactly; local srcs are still decoded and
stripped of query and hash.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 05:23:25 +00:00
Miguel Angel Simon Sierra a63c8d0577 chore: release v0.8.108 2026-10-01 22:20:30 -07:00
Vance IngallsandClaude Opus 5.5 3c299acc7f feat(core): audible videos in preview web audio, audio groups, meters and carve (2/8) (#4814)
* feat(core): add isAudibleVideoElement predicate and audible media selector

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

* feat(runtime): route processed audible videos through web audio in preview

An audible <video> joins the Web Audio schedule, hidden-toggle and
group-capture passes when it needs a gain el.volume cannot express: a
boost above unity, an fx chain, automation, or an audio group. A plain
audible video at unity stays on native output. The clock master stays
audio-only; a video whose capture fails stays on native output (never
decoded, never failed closed).

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

* feat(audio): let audible videos join audio groups in preview and render

resolveAudioGroups, audioGroupOf, group render ids, the engine mixer and
the audio_group_no_members lint rule accept an audible <video>. A hidden
group drops its video members from the mix; muted videos stay inert.

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

* feat(editing): offer the audio fx section on audible videos

EditableElementFacts gains hasAudio; studio and sdk derive it from muted and data-has-audio.

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

* feat(studio): show audio meters when a project has an audible video

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

* feat(studio): offer audible videos as carve voices

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

* feat(studio): let audible video clips join audio groups

Drops the video refusal; grouping and group audition count audible videos.

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

* fix(engine): honor hidden audio groups for auto-detected video audio

Muted videos that declare data-has-audio are no longer mixed.

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

* fix(studio): keep authored src, loop and honest status when keeping cutout sound

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

* fix(core): treat only data-has-audio=true as audible in runtime and lint

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

* refactor(core): trim the web audio route and group-key comments

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

* fix(runtime): capture ramped clips so a group's bus carries them in preview

A rate lane skipped Web Audio entirely, so a ramped video or audio clip in a
group played native output without the group's fader, mute or FX while the
export applied them. Only the decoded-buffer fallback cannot follow a rate
curve; the media-element capture can, so the skip now guards that fallback.

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

* fix(studio): show meters only for videos Web Audio carries

A plain audible video at unity stays on native output, which the meters
cannot read, so it no longer advertises them. The runtime's join rule and the
meter gate now share audibleVideoNeedsWebAudio (core/audible-video).

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 02:28:30 +00:00
Miguel Angel Simon Sierra c3a20c589d chore: release v0.8.107 2026-10-01 19:05:00 -07:00
Miguel Ángel 89704189d8 chore: release v0.8.106 (#4873) 2026-10-01 11:46:50 -07:00
Miguel Ángel bc57e282fd chore: release v0.8.105 (#4858) 2026-10-01 07:33:11 -07:00
Miguel Ángel 0db5b0a285 chore: release v0.8.104 (#4850) 2026-10-01 03:53:24 -07:00
Miguel Ángel 86a7e8cc75 chore: release v0.8.103 (#4838) 2026-10-01 00:15:00 -07:00
Miguel Ángel ed20d67b16 chore: release v0.8.102 (#4835) 2026-09-30 23:04:17 -07:00
Miguel Ángel be80a30802 chore: release v0.8.101 (#4831) 2026-09-30 21:12:22 -07:00
Miguel Ángel e29433c77e chore: release v0.8.100 (#4828) 2026-09-30 20:24:37 -07:00
Miguel Ángel 132b9909fa chore: release v0.8.99 (#4800) 2026-09-30 22:41:49 +00:00
Miguel Ángel 567525a8c2 fix: readers never see an empty or half-written project file (#4777)
* fix: readers never see an empty or half-written project file

* test: pin the create routes and block install to whole-file writes

* fix(sdk): a write through a link to a missing file creates that file

* fix: saves through a linked folder reach the real file, atomic writes handle long names

* test(sdk): check for the stray file, not the folder listing

* fix(core): creates work on Windows FAT drives, and links through folders resolve as the system does

* fix: agree the helper move in the deletion check, and match temp paths without a path regex

* test: check POSIX file modes only off Windows
2026-09-30 19:17:59 +00:00
Miguel Ángel 04b01342cf chore: release v0.8.98 (#4788) 2026-09-30 18:43:57 +00:00
Miguel Ángel 9ae1e3c842 chore: release v0.8.97 (#4775) 2026-09-30 14:08:38 +00:00
Miguel Ángel 5461e0ab03 chore: release v0.8.96 (#4752) 2026-09-30 05:17:09 +00:00
Miguel Ángel f5a348e92d chore: release v0.8.95 (#4751) 2026-09-30 03:47:02 +00:00
Miguel Ángel daa44fcd75 chore: release v0.8.94 (#4744) 2026-09-29 17:41:30 -07:00
Miguel Ángel 2eeaefb3e5 chore: release v0.8.93 (#4733) 2026-09-29 13:14:35 -07:00
Miguel Ángel 6d00d94b46 chore: release v0.8.92 (#4729) 2026-09-29 15:47:29 +00:00
Miguel Ángel dcff54749c chore: release v0.8.91 (#4726) 2026-09-29 06:33:17 +00:00
Miguel Ángel e4fbc84874 chore: release v0.8.90 (#4721) 2026-09-28 19:29:59 -07:00
Miguel Ángel ea4893602a chore: release v0.8.89 (#4720) 2026-09-28 19:10:32 -07:00
Miguel Ángel 343cf381f7 chore: release v0.8.88 (#4719) 2026-09-28 18:33:19 -07:00
Miguel Ángel 82ae73a031 chore: release v0.8.87 (#4717) 2026-09-28 18:02:10 -07:00
Miguel Ángel 1004b69829 chore: release v0.8.86 (#4695) 2026-09-28 13:37:47 -07:00
Miguel Ángel a46095f1cc chore: release v0.8.85 (#4676) 2026-09-28 10:52:18 -07:00
Miguel Ángel 52f849e2b4 chore: release v0.8.84 (#4671) 2026-09-28 10:00:31 -07:00
Miguel Ángel 8fd5fd5a32 chore: release v0.8.83 (#4668) 2026-09-28 09:27:18 -07:00
Miguel Ángel 2449ea05b1 perf(core): light entries for safe paths, asset paths and the runtime script (#4642) 2026-09-28 08:20:47 +00:00
Miguel Ángel 5969c6894b chore: release v0.8.82 (#4641) 2026-09-28 08:04:14 +00:00
Miguel Ángel e738e10267 feat(core): export findProjects to list the HyperFrames projects on a machine (#4627)
* feat(cli): hyperframes projects finds the HyperFrames projects on this machine

* refactor(core): keep the project rule's comment share under its package's

* fix(cli): projects keeps Spotlight hits under a symlinked root and refuses a missing root

* style(cli): format the projects walker and its tests

* fix(cli): projects tests pass under a symlinked temp folder and a bad root errors on stderr

* test(cli): projects tests hold on Windows and cover an unreadable root

* style(cli): format the projects command and tests

* refactor(cli): split the projects Spotlight check and regenerate the skills manifest

* refactor(core): findProjects moves to @hyperframes/core/projects so Desktop can import it

* chore(core): publish the projects subpath

* fix(core): findProjects fails on a root it cannot read instead of finding nothing

* docs(core): name the project marker writers without naming one app

* refactor(core): ship findProjects as a core export only, with no CLI command

* feat(core): findProjects stops on an abort signal and defaults to the home folder

* fix(core): findProjects checks an aborted signal first and stops when onProject throws
2026-09-28 06:09:25 +00:00