Commit Graph
1189 Commits
Author SHA1 Message Date
Miguel Ángel 3e17ef7447 fix: propagate data-timeline-locked in compiler inliners
The runtime path (compositionLoader.ts) already propagated
data-timeline-locked from inner root to host, but both compiler
inliners (bundler + producer) did not. Bundled output re-opened in
Studio would lose the lock. Now propagated in inlineSubCompositions
alongside the existing data-hf-authored-id propagation.
2026-05-20 02:40:49 -04:00
Miguel Ángel 9c159ad96d fix: escape href in compiler link dedup + add font-link extraction tests
Escape href values in querySelector calls for link dedup in both
htmlBundler.ts and htmlCompiler.ts to match the runtime path (which
uses CSS.escape). Prevents SyntaxError on hrefs containing quotes.

Add two tests for inlineSubCompositions font-link extraction:
- Verifies <link> elements are extracted with original rel + crossorigin
- Verifies dedup across multiple sub-compositions sharing the same font
2026-05-20 02:36:58 -04:00
Miguel Ángel 5d501a1628 fix: preserve original rel attribute on sub-composition link extraction
Store {href, rel, crossorigin} from source <link> elements instead of
re-deriving rel from a URL substring heuristic. Fixes preview-vs-render
parity: a stylesheet link whose href lacks ".css" or "css2?" was
emitted as preconnect in the compiled output, silently dropping the font.

Also documents that caption components ship with transparent backgrounds
intentionally — users add contrast layers in the host composition.
2026-05-20 02:33:40 -04:00
Miguel Ángel 576598f5ad feat(studio): disable move/resize/style editing for locked composition children
Elements inside a data-timeline-locked composition now have all
canvas interactions disabled (move, resize, manual offset/size/rotation,
style editing). Prevents "Unable to patch" errors when trying to move
JS-generated caption elements that can't be patched back to source.
2026-05-20 02:23:57 -04:00
Miguel Ángel ec66d59caa fix(registry): add pointer-events: none to caption component roots
Caption components are overlays — their root element should not
intercept pointer events, allowing clicks to pass through to the
underlying composition content in Studio.
2026-05-20 02:20:16 -04:00
Miguel Ángel 8371f42aed feat(studio): hide text panel for elements inside locked compositions
Elements inside a data-timeline-locked sub-composition now have the
TEXT property panel hidden. These elements are JS-generated — editing
them in the panel won't persist since the script rebuilds the DOM on
load. Uses findClosestByAttribute to detect the locked ancestor.
2026-05-20 02:13:25 -04:00
Miguel Ángel 335ec45bc2 style(registry): format caption component HTML files 2026-05-20 02:08:57 -04:00
Miguel Ángel 0187a82a6f fix(registry): transparent backgrounds on all caption components
Replace opaque backgrounds (#0a0a0a, #000, #000000) with transparent
on both html/body and the composition root div for all 15 caption
components. Captions are overlays — opaque backgrounds cover the
underlying video when loaded as sub-compositions.
2026-05-20 02:02:12 -04:00
Miguel Ángel 471b4efb4b feat: data-timeline-locked + fix font loss in sub-compositions
Timeline locking:
- Add data-timeline-locked attribute support — fully disables move,
  trim-start, and trim-end in Studio for clips that carry this attr
- Runtime propagates the attribute from inner composition root to host
  element so component authors control it from their HTML
- All 15 caption components in the registry now carry the attribute

Font fix:
- Extract <link rel="stylesheet"> and <link rel="preconnect"> from
  sub-composition <head> alongside existing <style>/<script> extraction
- Fixes caption components (and any sub-comp using Google Fonts via
  <link> tags) losing their font-family when loaded as sub-compositions
- Applied in both runtime (compositionLoader) and compiler
  (inlineSubCompositions) paths
2026-05-20 01:55:17 -04:00
Miguel Ángel 6d9670fd58 docs(skill): add pre-built caption component catalog to captions reference
Move catalog references from SKILL.md (reverted) into captions.md where
they're contextually relevant. Adds a table of all 15 caption components
with style descriptions and use-case guidance, plus CLI commands for
browsing and installing.
2026-05-20 01:38:04 -04:00
Miguel Ángel c9a94b5c45 Revert "docs(skill): add catalog references for blocks and components"
This reverts commit 552b9828f6.
2026-05-20 01:37:33 -04:00
Miguel Ángel 771abe8373 Revert "fix(skill): correct catalog table — fix caption-texture name, add 6 missing blocks"
This reverts commit 4e8d9f2a18.
2026-05-20 01:37:33 -04:00
Miguel Ángel 4e8d9f2a18 fix(skill): correct catalog table — fix caption-texture name, add 6 missing blocks
- caption-texture-lava → caption-texture (matches registry-item.json)
- Add transitions-destruction, transitions-other to Scene transitions
- Add vpn-youtube-spot to Social media cards
- Add blue-sweater-intro-video to Product & device showcases
- Add north-korea-locked-down, nyc-paris-flight as Narrative showcases row
- All 77 registry items now verified against registry/registry.json
2026-05-20 01:19:34 -04:00
Miguel Ángel 552b9828f6 docs(skill): add catalog references for blocks and components
Surface the full registry of pre-built blocks and components directly
in the main authoring skill so agents know what's available before
building from scratch. Adds CLI commands, use-case tables grouped by
category (transitions, social, data, maps, VFX, captions, overlays),
and quick-pick suggestions for common user requests.
2026-05-20 01:10:36 -04:00
James ce95c9aea0 docs(nav): consolidate deploy pages into one sidebar group v0.6.28 2026-05-19 21:11:08 -04:00
Miguel Ángel e5bad2b80a Merge pull request #978 from heygen-com/worktree-fix+studio-timeline-resize-and-perf
fix(studio): enable timeline resize for all elements, improve perf and UX
2026-05-20 03:07:08 +02:00
Miguel Ángel 20c82980d5 chore: address remaining review nits
Add mediabunny (MPL-2.0) to CREDITS.md third-party licenses section.

Add regression test for 4-5 clip compositions under the lowered lazy
threshold — verifies lazy mode activates and no spurious eviction churn
occurs when all clips fit within the promoted cap.
2026-05-19 21:06:22 -04:00
Miguel Ángel 366fcc2a64 fix(studio): address PR review — restore rollback, fix probe race, harden edit suppression
Restore rollback path: enqueueEdit now returns the queued promise so
Promise.resolve(handler(...)).catch(rollback) in useTimelineClipDrag
fires correctly on save failure. Handlers return the promise chain.

Fix lost-update race in probe enrichment: use zustand's functional
setState so concurrent probe completions each read the latest state
atomically instead of all reading the same stale snapshot.

Harden file-change suppression: pendingTimelineEditPathRef is now a
Set<string> with exact-match lookup instead of single-slot + endsWith.
Multiple concurrent edits on different files are all suppressed correctly.

Remove dead canOffsetTrimClipStart function and its tests — no longer
called after the capability gate simplification.

Document runtime sync mechanism: added comment explaining that the
runtime re-reads data attributes on each sync tick (init.ts:1324-1368).

Fix comment wording in patchIframeDomTiming catch block.
2026-05-19 20:59:45 -04:00
Miguel Ángel beb807493c refactor(studio): reduce complexity in timeline editing helpers
Extract resolveResizePlaybackStart, simplify patchIframeDomTiming to
accept attr tuples, inline findIframeElement. Reduces CRAP scores in
the resize handler lambda and DOM patching functions.
2026-05-19 20:54:45 -04:00
James 8080e1f920 docs(concepts): note that media data-duration can be variable-driven 2026-05-19 20:47:46 -04:00
James d28c082416 docs(concepts): clarify what can and can't be a variable 2026-05-19 20:47:46 -04:00
Miguel Ángel 0769dc4b9c refactor(studio): rename useManifestPersistence to usePreviewPersistence 2026-05-19 20:44:45 -04:00
Miguel Ángel 89f9ca196d fix(studio): enable timeline resize for all elements, improve perf and UX
Enable trim-start and trim-end for all authored timeline elements (divs,
sections, compositions) — not just video/audio/img. The deterministic-window
gate was overly restrictive since all non-implicit elements have authored
data-start/data-duration that define their timeline window.

Replace iframe reload after resize/move with direct DOM attribute patching
via patchIframeDomTiming(). This eliminates playhead-jump-to-zero, visual
blinking, and race conditions from file-watcher echoes. File persistence
runs in a serialized background queue (persistTimelineEdit + enqueueEdit)
so rapid edits don't overwrite each other.

Add mediabunny-based media probe service (mediaProbe.ts) for fast metadata
extraction from file headers. Timeline elements missing sourceDuration are
enriched asynchronously without waiting for DOM loadedmetadata events.

Tune the runtime media preloader: lower lazy threshold from 6 to 3 clips,
add 3s lookbehind window for reverse scrub, adaptive promoted-clip cap.

Deduplicate getTimelineEditCapabilities — computed once in TimelineCanvas
and passed as a prop to TimelineClip instead of recomputing per clip.

Remove dead PlaybackAdapter re-export from useTimelinePlayer — all consumers
import directly from playbackTypes.
2026-05-19 20:40:39 -04:00
James 480d0cfa5a docs(deploy): templates-on-lambda guide for personalised video at scale
User-facing guide for the automated template-rendering pipeline now
shippable end-to-end after PRs 9.1-9.4:

  - What a template is (composition + data-composition-variables)
  - Declaring variables (syntax, types, defaults, getVariables())
  - Local iteration loop (hyperframes render --variables / --variables-file
    / --strict-variables)
  - Deploying to Lambda (pointers to deploy guide + sites create)
  - Single personalised render (lambda render --variables)
  - Batch pipeline (lambda render-batch --batch users.jsonl, with a worked
    5-row example, manifest output, progress polling, --dry-run)
  - Programmatic via SDK (TypeScript example with deploySite +
    Promise.all(renderToLambda))
  - Working with large variables (the 256 KiB Step Functions ceiling,
    URL-your-assets convention, the one-line escape note for genuine
    >256 KiB cases)
  - Cost + scale considerations (Lambda concurrency, max-parallel-chunks
    vs max-concurrent, in-process vs distributed crossover)
  - Migrating from @remotion/lambda inputProps (side-by-side table; same
    256 KiB cap and same URL-your-assets convention, so migration is
    mechanical)

Includes a Mermaid architecture diagram for the site-upload-once +
N-execution fan-out flow at the top.

Adds the guide to the Deploy navigation group in docs.json (between
the existing aws-lambda and migrating-to-hyperframes-lambda pages).

Phase 9 PR 9.5 of the distributed rendering plan — the load-bearing
artifact for the user-facing pitch.
2026-05-19 19:54:30 -04:00
James f0a2740f6e feat(cli): hyperframes lambda render-batch verb
New subcommand for automated template-rendering pipelines. Given a
project dir + a JSONL batch file, fans out N personalised renders by
calling renderToLambda once per batch row with per-entry variables and
outputKey:

  hyperframes lambda render-batch ./my-template \
    --batch ./users.jsonl \
    --width 1920 --height 1080 \
    --max-concurrent 10

JSONL format (one JSON object per line):

  {"outputKey": "renders/alice.mp4", "variables": {"name": "Alice"}}
  {"outputKey": "renders/bob.mp4",   "variables": {"name": "Bob"}}

The verb deploys the site once and reuses it across renders (--site-id
skips the deploy when the project was pre-uploaded). Concurrent Step
Functions starts are capped at --max-concurrent (default 50) via a
semaphore so a 10 000-entry batch doesn't try to spawn 10 000
executions simultaneously and trip the AWS account's concurrent-
execution quota.

Per-entry results land in a manifest (one row per input line) with
executionArn + status. --json emits the manifest as machine-readable
JSON. --dry-run prints the manifest with status: "would-invoke" for
every entry without calling AWS, so callers can lint their batch file
before paying for N executions.

Variables in each batch entry pre-validate against the composition's
data-composition-variables declaration (mirroring the local
hyperframes render UX). --strict-variables aborts the run on the first
failing entry before any AWS call. The reportVariableIssues helper from
PR 9.3 is reused so the warning format matches the single-render path
exactly.

Distinction from --max-parallel-chunks: --max-concurrent caps
ORCHESTRATOR-side fan-out (how many StartExecution calls run at once);
--max-parallel-chunks caps chunks PER render. AWS account-level Lambda
concurrent-execution limits live one level up and render-batch can't
enforce those; pick --max-concurrent based on your account quota +
the reserved concurrency you provisioned via lambda deploy.

Tests cover the concurrency-cap semaphore (preserve-order,
peak-in-flight, empty-input, limit > inputs.length, propagate
rejection) and the JSONL parser (blank-line handling, malformed JSON,
missing outputKey, non-object variables).

Phase 9 PR 9.4 of the distributed rendering plan.
2026-05-19 19:54:30 -04:00
James cb948d5fcf feat(cli): hyperframes lambda render --variables / --variables-file / --strict-variables
Mirror the local hyperframes render variables UX on the Lambda CLI:

- --variables '<json>'       inline JSON object of variable values
- --variables-file <path>    path to a JSON file with variable values
- --strict-variables          fail on type/declared-mismatch (warn by default)

Resolution + validation logic is hoisted to packages/cli/src/utils/variables.ts
so both surfaces share one parser. The new reportVariableIssues helper formats
the warning block + handles --strict-variables exit, deduping the per-CLI
issue-handling block.

Variables flow into SerializableDistributedRenderConfig.variables and reach
every chunk worker via the path PR 9.1 + 9.2 wired up (plan() →
meta/encoder.json → renderChunk() → window.__hfVariables). Pre-validation
against the composition's data-composition-variables declaration runs only
when the project's index.html is on disk — --site-id pointing at a
pre-uploaded site that was packaged elsewhere skips the check, matching how
the local CLI treats unreadable index files.

The render.ts re-exports of parseVariablesArg / resolveVariablesArg /
validateVariablesAgainstProject are dropped; the matching tests move to
packages/cli/src/utils/variables.test.ts where the implementations now live.

Docs: docs/packages/cli.mdx adds a section on --variables / --variables-file /
--strict-variables for lambda render, including the 256 KiB Step Functions
execution-input cap and a pointer to the upcoming templates-on-lambda guide
(PR 9.5).

Phase 9 PR 9.3 of the distributed rendering plan.
2026-05-19 19:54:30 -04:00
James Russo 87fdd556c4 feat(aws-lambda): validate variables + 256 KiB Step Functions input cap (#976)
Add client-side validation for the new config.variables field
(introduced in PR 9.1) and a 256 KiB cap on the full Step Functions
Standard execution input. Both checks throw a typed InvalidConfigError
BEFORE the SDK calls StartExecution — catching the obvious mistakes
locally instead of as a States.DataLimitExceeded 50 ms into the
execution.

validateVariablesPayload walks the variables tree and rejects:
- functions, Symbols, BigInts, non-finite numbers
- undefined leaves (silently dropped by JSON.stringify — would
  surprise the caller when their value doesn't show up in the render)
- non-plain objects (Date, Map, class instances) — Date's toJSON does
  round-trip as a string, but the composition gets a string, not a
  Date, so explicit reject is clearer

validateStepFunctionsInputSize measures the actual UTF-8 byte length
of JSON.stringify(input) against the 256 KiB cap. We use Standard
workflows (per the plan §6.2 / §15.2) for execution-history
visibility, so the cap is 256 KiB (Express would be 32 KiB). The error
message names the actual byte count, the cap, and points at the
templates-on-lambda#working-with-large-variables section so users
know to URL-reference media assets instead of inlining them.

Both helpers are exported from @hyperframes/aws-lambda/sdk so adapters
that build custom Step Functions inputs (batch verbs, future Temporal
ports) can reuse the same gates.

Phase 9 PR 9.2 of the distributed rendering plan.
2026-05-19 19:53:31 -04:00
Miguel Ángel 0decb88946 chore: release v0.6.28 2026-05-19 19:38:08 -04:00
Miguel Ángel 8f0545738c Merge pull request #977 from func25/ceil-duration-preview
fix(core): ceil timeline payload duration to match render frames
2026-05-20 01:33:15 +02:00
func25 0fc3937809 fix(core): ceil timeline payload duration to match render frames 2026-05-20 06:04:29 +07:00
James Russo 852008bd44 feat(producer): thread variables through plan() + renderChunk() (#962)
Add `variables?: Record<string, unknown>` to DistributedRenderConfig
(§4.4) and LockedRenderConfig (§4.3). plan() snapshots the value into
meta/encoder.json so every chunk worker re-injects the same set via
captureOptions.variables, mirroring the in-process renderer's path.

The variables fold into planHash automatically because canonical
encoder.json bytes feed the hash: two plans with different variables
produce different hashes (chunked output depends on the injected
values); two plans with the same variables produce identical hashes
because canonical-JSON sorts keys.

The regression harnesses (distributed-simulated, lambda-local) also
forward the input's variables to plan() / Step Functions event so
fixtures that declare `renderConfig.variables` produce the same pixels
across modes. Previously the field was on the harness input shape but
silently dropped at the call boundary.

Phase 9 PR 9.1 of the distributed rendering plan.
2026-05-19 18:47:53 -04:00
Miguel Ángel 4237165517 chore: release v0.6.27 v0.6.27 2026-05-19 17:12:32 -04:00
Miguel Ángel 83e01e0d44 Merge pull request #965 from heygen-com/fix/sub-comp-timeline-t0
fix: activate nested child timelines on renderSeek (sub-comp at t=0)
2026-05-19 23:11:32 +02:00
Miguel Ángel d16e5d6359 test: add compiled.html golden snapshots for regression fixtures
Generated via regression-harness --update. The harness requires both
compiled.html and output.mp4 in the output/ directory.
2026-05-19 16:36:16 -04:00
Miguel Ángel a48350bf00 fix(studio): remove Ask agent popup, fix preview selection, fix manual edits in renderer (#963)
## Summary

Three interrelated studio UX and rendering fixes, plus a critical fix for manual edits not surviving video export.

### 1. Remove "Ask agent" popup on preview click
The "Ask agent" modal auto-triggered whenever clicking on a large raster element (images, backgrounds covering >40% of the viewport). This intercepted clicks meant for editable elements underneath, making it very annoying to select elements in compositions with large backgrounds or sub-composition screenshots.

**Removed:** the `isLargeRasterDomEditSelection` check + `setAgentModalOpen(true)` trigger in `usePreviewInteraction.ts`. The manual "Ask agent" button via the context menu still works — only the auto-popup is gone.

**Files:** `usePreviewInteraction.ts`, `useDomEditSession.ts`

### 2. Fix preview click selecting wrong element across visual layers
Clicking the PiP video overlay would select the Sf Chrome image behind it, because the scoring algorithm weighted DOM depth at 10,000× per level. Elements inside sub-compositions (deeper in the DOM tree) always won over visually-on-top elements at the root level, regardless of z-order.

**Fix:** replaced the weighted scoring with a visual-stacking-order-first algorithm. `resolveVisualDomEditSelectionTarget` now trusts `elementsFromPoint` order (topmost first) and only prefers a deeper candidate when it's a direct descendant of the current pick — never jumping to an unrelated element painted behind it.

**Files:** `domEditingElement.ts`

### 3. Fix manual edits not surviving video export

Two gaps in the producer's seek-reapply script (`studioPositionSeekReapplyRuntime`):

**a) Missing box-size reapplication.** The script handled translate and rotation but not width/height. Also, `data-hf-studio-box-size` was absent from the detection list in `htmlCompiler.ts`, so the script wasn't even injected for compositions with resize-only edits.

**b) GSAP transform matrix clobbering translate.** When GSAP animates an element (e.g. `scale`, `opacity`), it captures the element's translate into its internal transform matrix (`m41`/`m42`). The render script was setting the CSS `translate` property but leaving GSAP's translate baked into `transform`, causing the manual edit offset to be ignored. Ported the same `stripGsapTranslateFromTransform` logic the studio uses: parse the DOMMatrix, zero out m41/m42, and remove or rewrite the `transform` property so the CSS `translate` takes effect cleanly.

**Files:** `manualEditsRenderScript.ts`, `htmlCompiler.ts`

## Test plan

- [x] `bun test` — 50 tests pass across `domEditing.test.ts` and `manualEditsRenderScript.test.ts`
- [x] Pre-commit hooks pass (typecheck, lint, format, commitlint)
- [x] Verified in studio preview: clicking elements selects the visually-on-top one, "Ask agent" popup no longer appears
- [x] Rendered a composition with a manually-moved PiP video — position survives in the output video
2026-05-19 22:29:02 +02:00
Miguel Ángel 6652fae243 fix(#969): producer path propagates data-hf-authored-id to host element
When the producer inlines a sub-composition with compId match, it takes
innerRoot.innerHTML which strips the wrapper div and its id attribute.
CSS/GSAP selectors rewritten from #ID to [data-hf-authored-id=ID] then
match nothing.

Fix: after innerHTML injection, copy the inner root's id as
data-hf-authored-id on the host element. This makes #ID selectors work
identically in both preview (bundler) and render (producer) paths.

Closes #969
2026-05-19 16:07:24 -04:00
Miguel Ángel c44b1aaea7 chore: remove duplicate runtime fixtures, producer tests are the source of truth 2026-05-19 16:05:56 -04:00
Miguel Ángel f7d63fbebd fix(studio): address PR review — add tests, strip GSAP transform for rotation, remove dead exports
Addresses review feedback from Rames and Vai:

1. Add 7 new tests for createStudioPositionSeekReapplyScript:
   box-size reapplication, GSAP translate stripping (identity removal,
   scale+translate preservation, transform:none no-op), and rotation-
   only elements with GSAP-baked translate.

2. Add pinning test for the PiP-over-sub-composition selection bug:
   elementsFromPoint returns [pipVideo, subCompRoot, sfChromeImg] as
   siblings — assert the topmost (pipVideo) wins.

3. Apply stripGsapTranslateFromTransform to rotation-only elements
   too, not just path-offset elements. A rotation-only element with
   a GSAP-animated translate would have its position clobbered.

4. Remove dead exports: getPreviewLocalPointer,
   buildRasterClickSelectionContext, getPreviewPlayer,
   seekStudioPreview, PreviewPlayerCompat, PreviewLocalPointer from
   studioPreviewHelpers.ts. Unexport resolvePreviewLocalPointer.
2026-05-19 16:05:37 -04:00
Miguel Ángel 26450c1a27 refactor: address review — rename activateSiblingTimelines, opts arg, FIXME tracking
- Rename activateNestedChildTimelines → activateSiblingTimelines (matches player.ts)
- Use tl.play() instead of tl.paused(false) for consistency
- Convert positional activateChildren boolean to { activateChildren } opts
- Add FIXME(#969) to divergence test with tracking issue link
- Add [id="intro"] no-rewrite boundary test
- Add comment about deliberate no-restore behavior in render-seek path
2026-05-19 16:02:33 -04:00
Miguel Ángel e2f7f6a58a fix: add regression fixtures with golden baselines + address review
- Create sub-comp-t0 and sub-comp-id-selector as proper regression tests
  under packages/producer/tests/ with golden MP4 baselines
- Add both to shard-7 in regression.yml
- Add clarifying comment on activateNestedChildTimelines scope
- Confirm test fixture network safety in comment
2026-05-19 15:59:09 -04:00
Miguel Ángel 6498807e1a fix(core): strip GSAP translate from transform after reapplying manual edits
When GSAP animates an element (e.g. scale, opacity), it captures the
element's translate into its internal transform matrix (m41/m42). The
render reapply script was setting the CSS `translate` property but
leaving GSAP's translate baked into `transform`, causing the manual
edit offset to be ignored or doubled.

Port the same stripGsapTranslateFromTransform logic the studio uses:
parse the transform matrix, zero out m41/m42, and remove or rewrite
the transform property so the CSS `translate` takes effect cleanly.
2026-05-19 15:45:51 -04:00
Miguel Ángel 8fd5bf8f51 fix(studio): remove Ask agent popup, fix preview selection, fix manual edits in renderer
Three interrelated studio UX and rendering fixes:

1. Remove the "Ask agent" popup that auto-triggered when clicking large
   raster elements in the preview. The modal intercepted clicks meant
   for editable elements and blocked normal selection workflow.

2. Rewrite preview click selection to respect visual stacking order.
   The previous scoring algorithm weighted DOM depth at 10,000× per
   level, causing elements inside sub-compositions to beat visually-
   on-top elements (e.g., clicking Pip Studio selected Sf Chrome
   instead). The new algorithm trusts elementsFromPoint order and only
   prefers a deeper candidate when it is a descendant of the current
   pick — never jumping to an unrelated element painted behind it.

3. Fix manual edits (resize) not surviving video rendering. The
   producer's seek-reapply script handled translate and rotation but
   was missing box-size (width/height) reapplication after each GSAP
   seek. Also added data-hf-studio-box-size to the detection list in
   htmlCompiler so the script is injected for resize-only edits.
2026-05-19 15:45:51 -04:00
Miguel Ángel 0d12a465a3 fix: activate nested child timelines during renderSeek
The renderSeek override in init.ts called seekTimelineAndAdapters() which
only did rootTimeline.totalTime(t) without activating child timelines.
GSAP does not propagate totalTime() to internally paused children.

Also simplifies pollSubCompositionTimelines to always call rebind when
timelines are ready, removing the before/after count comparison that
could skip the rebind on fast page loads.
2026-05-19 15:42:07 -04:00
Miguel Ángel 29ad7df90c style: format fixture HTML files 2026-05-19 15:41:38 -04:00
Miguel Ángel 60cdf8c66b test: add regression fixture for sub-comp #ID selector scoping divergence
The producer inlining path strips the inner root element (taking innerHTML
when compId matches), losing the id attribute. The bundler path preserves it
via flattenInnerRoot + data-hf-authored-root-id. This causes #ID selectors
in sub-comp CSS and GSAP to fail silently during render while working in
preview.

Adds a minimal fixture with a sub-comp using #intro scope to catch this
divergence in future compiler changes.
2026-05-19 15:38:59 -04:00
James f4e96a58ed chore: release v0.6.26 v0.6.26 2026-05-19 18:16:54 +00:00
Miguel Ángel 1d51a8a975 docs: add setup guides for Google Antigravity and GitHub Copilot CLI (#960)
## Summary

Closes #744 — adds dedicated setup guides for two AI coding tools that were missing from the documentation.

- **`docs/guides/antigravity.mdx`** — Google Antigravity IDE guide covering skills installation (workspace + global), semantic skill matching, Manager view parallelism for multi-scene videos, MCP alternative, and CLAUDE.md compatibility
- **`docs/guides/copilot-cli.mdx`** — GitHub Copilot CLI guide covering skills installation, slash command invocation, `/skills` management commands, agent mode for multi-step tasks, and MCP alternative
- **`docs/quickstart.mdx`** — updated agent list to mention both new tools with links to their guides
- **`docs/guides/prompting.mdx`** — updated description to include both tools
- **`docs/docs.json`** — added both guides to the Guides navigation group

## Test plan

- [x] Verify Mintlify docs build passes (`npx mintlify dev` in `docs/`)
- [x] Check navigation: both guides appear under Documentation → Guides
- [x] Verify links from quickstart.mdx to the new guide pages resolve correctly
- [x] Review guide content for accuracy against official Antigravity and Copilot CLI documentation
2026-05-19 19:13:53 +02:00
Miguel Ángel 00cbdd1d6e docs: address PR review — fix skill paths, Copilot CLI commands, MCP flag
- Fix project skill directory to .agents/skills/ (plural) in both guides,
  matching vercel-labs/skills agent registry
- Replace invented --mcp-server flag with correct --additional-mcp-config
  flag and JSON/file syntax for Copilot CLI
- Remove non-existent /skills reload, /skills list, /skills info commands;
  document only /skills (picker) and /skills add
- Remove non-existent github-copilot binary alias
- Antigravity MCP section now defers to Antigravity's own MCP docs for
  the exact settings UI path
- Rename CLAUDE.md section to "Agent instruction files", document both
  AGENTS.md (cross-agent) and CLAUDE.md
- Use --agent long form instead of -a in examples
- Add link to Antigravity Manager view docs
- Add token budget caveat for large skill sets in Copilot CLI
2026-05-19 13:02:43 -04:00
Miguel Ángel 5939226650 fix(studio): stop injecting inline z-index on all clips during timeline edits (#959)
## Summary

- Remove the z-index injection loops from timeline move, delete, and asset-drop commit paths — only timing/track attributes are now patched on the affected clip, leaving all other clips untouched
- Fix `patchInlineStyleInTag` to handle self-closing void elements (`<img />`, `<audio />`) — the old code produced malformed `<img ... / style="z-index: 7">` output
- Delete the now-unused `buildTrackZIndexMap` helper and its tests

## Root cause

Three timeline operations (`handleTimelineElementMove`, `handleTimelineElementDelete`, `handleTimelineAssetDrop`) looped over every clip in the file on each commit and injected `style="z-index: N"` derived from an inverted `data-track-index` mapping via `buildTrackZIndexMap`. This overrode the author's CSS z-index — contradicting the documented contract that `data-track-index` does not affect visual layering — and persisted the corruption in the source HTML.

## Test plan

- [x] Reproduction test covering old bug behavior (inline z-index injection on all clips, inverted layering)
- [x] Verification tests confirming move/delete only patches the affected clip's timing attributes
- [x] Void element tests confirming `<img ... style="..." />` output (not `<img ... / style="...">`)
- [x] End-to-end browser test: opened Studio, dragged badge clip in timeline via CDP, verified only `data-start` changed on the dragged clip with zero inline z-index injections
- [x] Full test suite: 585 tests pass (54 files)
- [x] Build, lint, format, typecheck all green

Closes #958
2026-05-19 18:51:53 +02:00
Miguel Ángel 9342d3dea8 docs: add setup guides for Google Antigravity and GitHub Copilot CLI
Add dedicated guide pages for two AI coding tools that were missing
from the documentation (closes #744):

- docs/guides/antigravity.mdx — skills install, semantic matching,
  Manager view parallelism, MCP alternative, CLAUDE.md compat
- docs/guides/copilot-cli.mdx — skills install, slash commands,
  /skills management, agent mode, MCP alternative

Also updates quickstart.mdx and prompting.mdx to mention both tools
alongside the existing agent list, and adds both pages to the docs
navigation in docs.json.
2026-05-19 12:44:14 -04:00