chore: sync upstream + lint GSAP animating <video> dimensions#17
Merged
Conversation
heygen-com#489) `lintAudioSrcNotFound` resolves every `<audio src>` against the project root, which is correct for index.html but wrong for sub-compositions — their srcs are written relative to the sub-composition file (e.g. `../assets/foo.mp3`), and the bundler rewrites them at compile time. Carry the sub-composition path alongside each html source and run `<audio src>` strings starting with `../` through the existing `rewriteAssetPath` helper before checking existence on disk. Mirrors the runtime/bundler behaviour so the lint check sees the same path the renderer will fetch. Original (un-rewritten) src is still surfaced in the finding message so authors can grep for it in their HTML.
* fix(cli): publish projects through staged uploads * fix(cli): honor signed upload length header
) * fix(lint): remove root_composition_missing_data_duration Lint cannot statically observe the runtime's true Infinity-emission condition: it requires a finite GSAP timeline duration AND a finite media/sub-comp window AND timeline > floor + 1, none of which are visible to the static linter. The looping shapes that drive the condition are already covered by `gsap_infinite_repeat` and `gsap_repeat_ceil_overshoot` (both from heygen-com#243), which point at the real authoring mistake — flagging the missing duration separately was a noisy proxy for the same signal. Per heygen-com#490 review discussion, deprecate the static rule and let those two GSAP rules carry the pre-render coverage. If perfect precision on `durationInFrames = Infinity` is needed, that belongs on the runtime/render path where `shouldEmitNonDeterministicInf` is actually known. Add regression tests pinning the removal: a docs-compliant root without `data-duration` no longer warns, and the canonical loop-inflated shape now surfaces only via `gsap_infinite_repeat` instead of two duplicate findings. * docs(skills): update step-6 build checklist after rule removal Drops the `root_composition_missing_data_duration` reference now that the rule is gone. Keeps the authoring recommendation (and explains the runtime Infinity case) but points authors at the GSAP rules that actually carry the lint signal: `gsap_infinite_repeat` and `gsap_repeat_ceil_overshoot`.
…-and-video-dim-lint
…t/x/y Animating box dimensions on a <video> directly causes Chromium to stop pushing frames or to drop the compositor — documented as the most common cause of broken compositions in the upstream Common Mistakes guide. The fix is always the same: wrap the <video> in a non-timed <div> and animate the wrapper instead. The rule fires when: - a GSAP method (to/from/fromTo/set on a timeline or gsap.*) targets a direct id selector (#id), AND - the matching tag is a <video>, AND - the tween animates one of width/height/top/left/x/y. False-positive guard: only direct id selectors are flagged. Class or attribute selectors might wrap a video legitimately and we don't want to penalize wrapper-pattern code. Tests cover: width/height fires, x/y/top/left fires, opacity/scale/filter do not fire, wrapper-div pattern does not fire, non-video element does not fire, class selector touching a video does not fire. Refs: hyperframes Common Mistakes guide — "Animating video element dimensions" — closes the GAP-1 audit finding. Co-Authored-By: Claude Opus 4.7 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two things bundled in one PR because they're both small and the merge needs to land first so the lint rule sits on a current base:
heygen-com/hyperframesupstream — pull 7 commits we were behind on (3 fixes + v0.4.25/26/27 releases + a Claude Design refactor).gsap_animates_video_dimensions) — flag GSAP tweens that animate box dimensions on a<video>directly. This is the upstream Common Mistakes guide's feat(elevenlabs): add ElevenLabs TTS provider (CLI + Studio API) #1 footgun and previously had no enforcement.Verified: all 5 packages green —
630core (+8 vs pre-PR: 6 from upstream lint additions, 6 from new rule, minus a removed rule),178cli (+4 from upstream's publish/lint tests),221studio,491engine + 3 LFS-skipped,84player.oxlintclean.oxfmtclean.tsc --noEmitclean.Phase 5 — upstream sync (7 commits)
cli publishstaged uploadspublish. Single-shot upload was failing for large projects on big payloads.<audio>src pathroot_composition_missing_data_duration#495— Move Claude Design instructions todocs/skills/claude-design-hyperframes/SKILL.md→docs/guides/claude-design-hyperframes.md. The oldSKILL.mdbecomes a 5-line stub.Merge was clean — zero conflicts. Upstream's new tests (
composition.test.ts+59L,lintProject.test.ts+43L,publishProject.test.ts+88L) all pass against our combined tree.GAP-1 —
gsap_animates_video_dimensionsThe upstream Common Mistakes guide opens with:
…but our linter never caught it. It does now.
Rule shape: for each script with GSAP tweens, intersect the tween's target id selector with our
<video>tag inventory. If the selector matches a video AND the tween animateswidth,height,top,left,x, ory, raise anerror-severity finding with a wrapper-pattern fix-hint.False-positive guard: only direct id selectors fire. Class and attribute selectors are ignored — those might legitimately wrap a video, and we don't want to penalize the right pattern.
File: packages/core/src/lint/rules/gsap.ts (new rule appended to
gsapRules)Tests — 6 cases in gsap.test.ts:
tl.to("#video", { width, height })on a<video id="video">tl.fromTo("#video", {}, { x, y, top })on a<video>tl.to("#video", { opacity, scale, filter })tl.to("#pip-wrapper", { width, height, top, left })(wrapper)tl.to("#card", { width, height })on a non-videotl.to(".bg", { width })against a class selector matching videoTest plan
bun run --cwd packages/core test— 630 / 630bun run --cwd packages/cli test— 178 / 178bun run --cwd packages/studio test— 221 / 221bun run --cwd packages/engine test— 491 / 491 + 3 LFS-skippedbun run --cwd packages/player test— 84 / 84bunx oxlint .— cleanbunx oxfmt --check— cleantsc --noEmit— clean every package🤖 Generated with Claude Code