Commit Graph
3349 Commits
Author SHA1 Message Date
Ular Kimsanov 96533da560 Merge pull request #2885 from heygen-com/docs/front-door-hero
docs: rebuild the introduction as a real front door
2026-07-29 12:40:12 -07:00
ukimsanov bb2df65dd1 docs: rebuild the introduction as a real front door
Make /introduction the single "What is HyperFrames?" page a stranger can be
sent, and retire the switchboard that sat in front of it.

- introduction: lead with one sentence + a sound-on result (drop `muted`),
  simplify the loop diagram to request -> agent -> project -> video, cut the
  fake "See how it works" scroll button, and replace the equal-weight card
  walls with one clear "Start here" action.
- guides/index: remove the six-card "What do you need to do?" menu-of-menus.
  The nav already routes people and /introduction is the real entry point.
  Redirect /guides -> /introduction.
- developers: point the "create a video" link at /quickstart.

mint validate and mint broken-links both pass.
2026-07-29 12:19:10 -07:00
ukimsanov 5888e5c858 Revert "docs: make journey pages concise and visual"
This reverts commit 42ff5ceb79.
2026-07-29 00:19:01 -07:00
ukimsanov 42ff5ceb79 docs: make journey pages concise and visual 2026-07-28 23:33:36 -07:00
ukimsanov c5be64e1a7 docs: implement journey-led documentation 2026-07-28 22:44:16 -07:00
ukimsanov 4085527cb4 docs: define journey-led documentation strategy 2026-07-28 21:26:41 -07:00
ukimsanov 0f7acfe9c6 docs: prevent GitHub count navigation blink 2026-07-28 21:11:34 -07:00
ukimsanov 8bf97614fc docs: strengthen header stars and agent input 2026-07-28 20:58:57 -07:00
ukimsanov 6a19c24114 docs: preserve search on compact desktops 2026-07-28 20:48:46 -07:00
ukimsanov 5cdfb1e6a2 docs: align Aspen chrome with main 2026-07-28 20:46:20 -07:00
ukimsanov f3e5b7fc1b docs: match main sidebar navigation UX 2026-07-28 20:33:22 -07:00
ukimsanov a46ac9edb9 docs: correct navigation visual treatment 2026-07-28 20:23:26 -07:00
ukimsanov 2b1644ffd5 docs: restore default navigation behavior 2026-07-28 20:13:29 -07:00
ukimsanov 1151c8fa44 docs: flatten guides navigation 2026-07-28 20:04:55 -07:00
ukimsanov 2819249141 docs: clarify sidebar hierarchy 2026-07-28 19:53:31 -07:00
ukimsanov 4aec93401c docs: simplify navigation hierarchy 2026-07-28 19:32:48 -07:00
ukimsanov f327833374 Merge remote-tracking branch 'origin/main' into codex/docs-human-first-refactor-sync
# Conflicts:
#	docs/docs.json
#	docs/guides/feedback.mdx
#	docs/weekly-updates.mdx
2026-07-28 19:20:45 -07:00
ukimsanov f5201aa97c docs: refactor documentation around user workflows 2026-07-28 19:16:15 -07:00
Miguel Ángel b2d4fcac65 Merge pull request #2695 from heygen-com/codex/studio-timeline-c-ease-mode-switch-v2
fix(studio): switch keyframe ease modes optimistically
2026-07-29 03:59:07 +02:00
Miguel Angel Simon Sierra 5dad52370f fix(studio): keep hidden state on expanded sub-composition rows
An expanded sub-composition child row is built from a manifest clip, which
carries none of the host element's attributes, so data-hidden never reached
it. The eye on that row therefore always reported the element visible: the
first click hid it, and every click after wrote data-hidden again instead of
removing it. The element could not be shown again, not even after a reload,
because the attribute was already in the source.

The flat store element for the same child is built with its host element, so
the child row inherits hidden, timelineLocked and timelineRole from it.
2026-07-29 03:44:32 +02:00
Miguel Angel Simon Sierra adb7de5358 fix(studio): open the path node menu on arc waypoints
Right-clicking a motionPath waypoint in the preview overlay opened Chrome's
own context menu on top of the editor: the handler returned before
preventDefault for every node that was not an x/y keyframe. Both node kinds
now open Studio's menu. A waypoint has no percentage of its own, so Move to
Playhead is hidden and Delete acts on the path index, matching the hover x
badge; Delete is withheld entirely on a two-anchor arc, where the writer
refuses the removal and the entry would silently do nothing.
2026-07-29 03:44:31 +02:00
Miguel Angel Simon Sierra 659e22656e fix(studio): switch keyframe ease modes optimistically 2026-07-29 03:44:31 +02:00
Miguel Angel Simon Sierra 6b11d37433 fix(studio): publish keyframe cache refresh atomically 2026-07-29 03:44:30 +02:00
Miguel Angel Simon Sierra 23ab104aff refactor(studio): split bulk easing helpers 2026-07-29 03:39:52 +02:00
Miguel Angel Simon Sierra 10d45def05 feat(studio): bulk-edit easing for merged keyframes 2026-07-29 03:39:51 +02:00
Miguel Ángel 7482c22d82 fix(studio): target colliding keyframes exactly (#2692) 2026-07-29 03:39:17 +02:00
Miguel Ángel 9bbb6d50a0 fix: offset nested template video timing (#2859)
* fix: offset nested template video timing

* test(producer): cover nested sequential video render

* fix: share canonical nested media timing
2026-07-29 03:36:04 +02:00
Miguel Ángel 4f344c50b0 Merge pull request #2855 from heygen-com/fix/secure-runtime-dependencies
fix: remove vulnerable runtime dependency paths
2026-07-29 01:14:46 +02:00
Miguel Ángel b5be874582 Merge pull request #2858 from heygen-com/release/v0.7.79
chore: release v0.7.79
v0.7.79
2026-07-29 01:09:09 +02:00
Miguel Ángel a68729bcf1 chore: release v0.7.79 2026-07-28 23:06:45 +00:00
Xuanru LiandCursor 3a7950fd63 feat(check): add data-layout-allow-caption-zone waiver (#2853)
* feat(check): add data-layout-allow-caption-zone waiver

Opt intentional lower-third copy out of caption_zone_collision.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(check): address caption-zone waiver review nits

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(skills): document caption-zone waiver on CLI agent path

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(cli): document caption-zone waiver under check, not inspect

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-28 15:56:43 -07:00
Miguel Ángel a996e91e5d Merge pull request #2857 from heygen-com/fix/codex-imagegen-feature-flag
fix(media-use): accept renamed codex image_generation feature flag
2026-07-28 23:46:48 +02:00
Miguel Angel Simon Sierra b6da5bd6b3 chore: regenerate skills-manifest for media-use change 2026-07-28 23:31:32 +02:00
Miguel Angel Simon Sierra 02c57609ab fix(media-use): accept renamed codex image_generation feature flag
The codex image provider's fail-fast gate required an `imagegenext` row in
`codex features list`. Codex CLI 0.145 renamed that flag to `image_generation`
and dropped the old row, so the gate rejected every up-to-date CLI:

    media-use: codex image upsell unavailable: codex imagegenext unavailable
    (upgrade Codex CLI)

`resolve --type image --provider codex` returned that without ever attempting
a render, on hosts where image generation works fine. Codex itself now warns
`[features].imagegenext is deprecated. Use [features].image_generation`.

Resolve the flag name from the feature list instead of hardcoding it, and pass
whichever name the installed CLI exposes to `--enable`. The old name is
preferred when present, since CLIs that still list it reject the new one.

`codexUnavailableReason()` now returns `{ flag }` / `{ reason }` so the
resolved name reaches the exec.

Verified against codex-cli 0.145.0: `resolve --type image --provider codex`
generates and freezes an image. New unit tests pin both flag layouts so a
future rename fails loudly instead of silently disabling the provider.
2026-07-28 23:28:22 +02:00
Miguel Ángel 13ac9e3905 fix: remove vulnerable runtime dependency paths 2026-07-28 20:45:43 +00:00
Miguel Ángel 557569d18e Merge pull request #2849 from heygen-com/fix/studio-new-tween-target
fix(studio): author every new tween against one element
2026-07-28 21:57:52 +02:00
Miguel Ángel b1632f6676 Merge pull request #2848 from heygen-com/fix/studio-track-numbers-aria
fix(studio): announce real track numbers and wire lane aria-controls
2026-07-28 21:57:38 +02:00
Miguel Ángel b635e2fff2 Merge pull request #2847 from heygen-com/fix/studio-playhead-keyframe-target
fix(studio): target one element when adding a keyframe at the playhead
2026-07-28 21:57:24 +02:00
Miguel Ángel 1f2fff7f49 Merge pull request #2846 from heygen-com/fix/studio-lane-tween-attribution
fix(studio): lane every tween and attribute tweens to their real target
2026-07-28 21:57:09 +02:00
Miguel Ángel 6e6babe933 Merge pull request #2845 from heygen-com/fix/studio-subcomp-clip-timing
fix(studio): sub-composition clip timing and expanded rows
2026-07-28 21:56:56 +02:00
Miguel Ángel 7b74d99c23 Merge pull request #2844 from heygen-com/fix/studio-color-hex-shortcuts-panel
fix(studio): colour hex editing and shortcuts panel dismissal
2026-07-28 21:56:13 +02:00
Miguel Ángel 87241f8634 Merge pull request #2843 from heygen-com/fix/studio-ruler-seek-pointer-targets
fix(studio): timeline ruler seek, retime rounding, and pointer target sizes
2026-07-28 21:44:41 +02:00
Miguel Angel Simon Sierra 1f3fd2800c fix(studio): give the motion path and the fallbacks a one-element target
The narrowing this branch adds missed the motion-path overlay, and every
caller that could not narrow fell back to the exact bare class the narrowing
exists to replace.

- motionPathSelection.selectorFor now goes through writeTargetSelector. It
  feeds both the geometry read and the "set destination" write, so a class
  sibling measured its home off the FIRST sibling and then authored
  add-motion-path onto all of them. The toolbar toggle hides when no
  one-element form exists rather than arming a press that is dropped.
- The five new-tween writers that fell back to the selection's own selector
  now drop the commit instead. A gesture that does not persist reverts on the
  next reload; a tween silently aimed at five elements does not.
- tweenTargetsElement only follows the DOM to a target that matches exactly
  one element. A target the element merely shares with its siblings is a group
  tween, and these callers mutate what they find, so an individual nudge was
  rewriting the group's own tween and moving all five.
2026-07-28 21:21:37 +02:00
Miguel Angel Simon Sierra 3d92436066 fix(studio): author every new tween against one element
U3 fixed "add keyframe at playhead" widening a write to every sibling
sharing a class, but wired writeTargetSelector into only two paths. The
same bug was still reachable from the add-animation button, drag, resize,
rotate, gesture recording, and the property panel: each derived its target
from selectorFromSelection, which hands back a bare class for an id-less
element, so one edit authored a tween over all five siblings and the
timeline collapsed their rows into one.

Route every path that authors a NEW tween through the existing ladder:

- ensureElementAddressable now accepts selection.selector only when it
  addresses exactly one element, so the id-minting fallback right below it
  (previously unreachable whenever any selector was present) does the work.
- gsapDragCommit's five new-tween branches go through one newTweenTarget
  helper; instant patches reuse the written target so the runtime moves the
  element the source write names.
- useGestureCommit and useAnimatedPropertyCommit keep the existing selector
  for matching/retargeting and author new tweens with a separate write
  selector.

Retargets of an EXISTING tween are deliberately untouched: they keep
anim.targetSelector, so a tween aimed at a whole group stays aimed at it.

Narrowing the write alone regressed idempotency, verified by test: the
"is there already a write for this element" lookups matched targetSelector
by string, so the next nudge missed the write it had just made and appended
a second, conflicting one. The read half now falls back to the live DOM
(tweenTargetsElement, same contract as getAnimationsForElement), which also
still matches a deliberate group tween.

Tests reproduce each site through a real writer, re-parse with the real
parser, and resolve through resolveSelectorElementIds (what feeds the
keyframe cache and the lanes), plus pins for the new-tween vs
retarget-existing distinction so a future change cannot collapse the two.
2026-07-28 21:21:37 +02:00
Miguel Angel Simon Sierra ba0d6406d2 fix(studio): scope lane ids per timeline and stop inventing a track row
Two latent defects in the announcement path this branch adds.

- lanesId was keyed by render row alone, so a second TimelineLanes on the
  page (a mini-timeline beside the main one) would mint the same
  timeline-lanes-track-0 and every caret's aria-controls would resolve to
  whichever instance mounted first. The prefix now comes from useId, with the
  colons stripped so the id stays a legal CSS selector.
- trackDisplayNumber returned trackOrder.length + 1 for a key it could not
  find, which is indistinguishable from a real row: the label announced a row
  the user can see is wrong and nothing upstream could tell it had guessed. It
  returns null now, and trackDisplaySuffix drops the number from the label
  rather than inventing one.
2026-07-28 21:21:27 +02:00
Miguel Angel Simon Sierra f04cdb79c5 fix(studio): never re-author a target the DOM proved is not unique
writeTargetSelector returned the selection's bare selector whenever the
structural walk failed, including when a live DOM was there to check
against. An element detached between selecting and committing takes that
path, so the add re-authored the exact `.group` string the function exists
to replace. Return null instead: a failed walk against a live DOM is
evidence, not absence of it. Callers that cannot drop a user edit opt back
in with `?? selectorFromSelection` where the trade is visible.

The replace-with-keyframes paths had the mirror defect. The server deletes
and re-adds the tween, so their target string is a full rewrite, and they
derived it from the selection: promoting a set on a tween already narrowed
to `#scene > div:nth-child(3)` widened it back onto every class sibling,
undoing the narrowing an earlier add had made. They now keep the tween's
own authored target, matching what eight sibling commit modules already do.
2026-07-28 20:37:52 +02:00
Miguel Angel Simon Sierra 477916cbe2 fix(studio): label undo history with the track display row
The timeline track key is a fractional z-order sort key: an expanded
sub-composition child gets `host.track + n / (siblings + 2)`. The undo
history entry for the eye toggle interpolated that key directly, so
hiding an expanded child recorded "Hide track 0.16666666666666666".

Give the key-to-display-row conversion a single owner
(timelineTrackDisplay.ts) and route both the track header labels and the
history label through it, so the two cannot drift apart again. The raw
key still routes the callbacks and lookups that need it.

Adds a regression test that toggles a track keyed 1 / 6; a test on track
0 formats cleanly and proves nothing.
2026-07-28 20:37:52 +02:00
Miguel Angel Simon Sierra fd5555be75 fix(studio): target one element when adding a keyframe at the playhead
"Add keyframe at playhead" on an element with no id authored the bare class
buildStableSelector hands back, so one add on a `.group` wrote
`tl.to(".group", ...)`: a tween that animates all five siblings and that
resolveSelectorElementIds reads back as all five, collapsing their timeline
rows into one. It survived a reload, so the written file stayed un-editable.

writeTargetSelector is the write-side counterpart to selectorFromSelection
(which must keep returning the exact string findTweenAtTime compares against).
It resolves the element's own identity to a selector that addresses exactly
one element: `#id`, else `[data-hf-id="..."]`, else the selection's selector
when it is already unique, else a `:nth-child` path anchored on the nearest
identifiable ancestor (the selector + selectorIndex pair, resolved through the
DOM the index was counted in).

Applied to the two paths that author a NEW tween: the no-animation branch of
useEnableKeyframes and commitKeyframeAtTimeImpl. replace-with-keyframes still
writes the selection's own selector, since retargeting a tween the author
aimed at a whole group is a different decision from adding a keyframe.
2026-07-28 20:37:52 +02:00
Miguel Angel Simon Sierra 1faa0cbdad fix(studio): announce real track numbers and point aria-controls at the lanes
The timeline's track key is a fractional z-order sort value, and the header
built its visibility label straight from it, so screen readers announced
"Hide track 0.16666666666666666". A track's 1-based display row is now passed
alongside the key: the row number goes in every label, the key keeps routing
every callback (visibility toggle, lane context menu). The same fix covers the
`Track N` fallback used when a track holds no labelled element.

The layer disclosure caret's aria-controls named a div in the sticky label
column. That subtree is not empty, it holds the per-lane keyframe controls, but
its children are all absolutely positioned so the div computes to 0x0, and the
diamonds the caret visibly reveals live on the canvas instead. The caret expands
two disjoint subtrees and was naming the less useful one. TimelinePropertyLanes
now renders one static wrapper (static, not relative, so it establishes no
containing block and the absolutely-positioned lanes keep resolving against the
track-content div with identical geometry) and takes the id. TimelineLanes mints
that id, since it is the only place that sees both ends of the disclosure, and
mounts the wrapper for the track's keyframe clip in both disclosure states so
the reference still resolves while collapsed.

TimelineLaneBaseProps moves to its own module: it is the contract shared by
TimelineCanvas and TimelineLanes, and lifting it out keeps TimelineLanes.tsx
well under the 600-line cap instead of pushing past it.
2026-07-28 20:37:52 +02:00
Miguel Angel Simon Sierra be3451aae4 fix(studio): resolve a panel edit through the lane groups it can see
animIdForProp matched on the parser's whole-tween propertyGroup, which is
undefined for a legacy mixed tween such as {x, opacity}. Such a tween never
matched, so an edit to either property fell through to the selection's
default animation, a different tween than the lane the user is editing.
Resolve through animationLaneGroups, the same per-keyframe helper the
rendered lanes and the reserved row heights already count groups with.
2026-07-28 20:37:21 +02:00