Commit Graph
90 Commits
Author SHA1 Message Date
Miguel Ángel 55ee559e40 fix(lint): catch cold-seek opacity reveals (#2503)
* fix(lint): catch cold-seek opacity reveals

* fix(lint): resolve hidden selector aliases

* style(lint): format gsap rule
2026-07-16 12:03:25 -04:00
Miguel Ángel b8a44e49c9 fix(lint): ignore !important in font families (#2538) 2026-07-16 10:43:17 -04:00
James Russo 21cb722ebd refactor(core): unify composition contract (#2157)
* refactor(core): unify composition contract

* fix(parsers): parse start expressions linearly
2026-07-16 02:44:22 -04:00
Miguel Ángel 0f287ee0b6 chore: release v0.7.60 2026-07-16 05:26:57 +00:00
ViaandClaude Opus 4.7 75de927fb5 feat(lint): flag high overlay-element counts (heavy-capture risk)
Field signal ts=1784040753 (#hyperframes-cli-feedback): a composition
with ~40 heavy overlay DOM elements — `filter:blur`, oversized
`radial-gradient`, and `clip-path` animations — captures solid-black for
the first ~half of the render, recovering near the end. Reproduces
identically via drawElement AND forced --no-browser-gpu screenshot
capture AND `snapshot`, so the capture layer itself is the offender, not
encoder/mux. Independent of duration (padding the timeline grows the bad
zone proportionally, doesn't shift it). Presence alone matters — even
opacity:0 / visibility:hidden / unused overlays contribute. Reporter's
workaround was splitting into per-transition mini-compositions +
FFmpeg concat.

Add compositionCheck rule `composition_heavy_overlay_count_high`
(warning). Counts DOM elements that carry any of: inline
`style` filter:blur / clip-path (non-none) / radial-gradient, or a
class/id whose top-level CSS rule body sets one of those. `display:none`
elements are counted-out (removed from render tree); opacity:0 /
visibility:hidden overlays are counted-in per the field-signal repro
shape. Warns at 25 to give lead time before the observed 40-element bad
zone. Skips registry source and installed-block files, mirroring
`composition_file_too_large`. Includes a `ts=1784040753` reference in
fixHint so authors can trace the risk shape.

Stack: PR #5 of 9 (base via/parity-telemetry-gate).

Signed-off-by: Via

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-15 22:59:52 +00:00
Vance Ingalls ff3b1541e5 chore: release v0.7.59 2026-07-15 11:57:49 -07:00
Miguel Ángel f3800f3579 fix(lint): exempt caption cues from track density (#2461)
* fix(lint): exempt caption cues from track density

* style(media-use): satisfy resolver formatting gate
2026-07-15 02:05:39 -04:00
Miguel Ángel ada878fdcd fix(lint): consolidate lint and audit correctness (#2413)
* fix(lint): stop CSS comments in <style> from manufacturing phantom root tags

extractOpenTags scans raw source text with a flat regex that has no
concept of <style>/<script> block boundaries, so a CSS comment like
`/* <g> wrapper */` inside a <style> block reads as a real open tag.
findRootTag consumes that flat tag list and only skips tags literally
named script/style/meta/link/title, so the phantom <g> tag (not in
that skip list) wins the "first non-ignored body tag" search and gets
returned as the composition root instead of the real one that follows.

This manufactured root_missing_composition_id and root_missing_dimensions
(the phantom tag has neither) plus head_leaked_text (the leaked-text
scan slices up to the phantom tag's position, landing inside the
<style> block before its real closing tag, so the raw CSS text reads
as leaked markup) on an otherwise valid sub-composition — reported
with an exact bisected repro: a <template>-wrapped SVG sub-composition
whose <style> block comments reference an inner <g> element.

Fix: compute <style>/<script> content spans up front (reusing the
existing extractBlocks + STYLE_BLOCK_PATTERN/SCRIPT_BLOCK_PATTERN) and
skip any TAG_PATTERN match that falls inside one, before it ever
reaches findRootTag or any other extractOpenTags consumer. Same shape
as the prior fix for a leading <svg> defs block being mistaken for the
root (8ee4b7df) — this closes a sibling gap in the same function.

Test: new regression case with a <style> block containing a `/* <g> */`
comment ahead of an <svg data-composition-id> root, asserting none of
the three findings fire. Full lint package suite (318 tests) passes.

* feat(lint): flag duplicate data-composition-id values

Declaring data-composition-id on more than one element (commonly the <meta>
tag from the quickstart template AND the root <div> added to satisfy
root_missing_composition_id) is a silent collision: `compositions --json`
returns two entries for the same id (one duration:0) and inspect/snapshot
crash with "Cannot read properties of undefined (reading totalDuration)".
Lint passed clean through all of it.

New rule `duplicate_composition_id`: group elements by data-composition-id
value and error on any value shared by 2+ elements, naming the id and calling
out the meta-vs-root collision in the fixHint. 3 tests: dup fires, single id
passes, two distinct ids don't collide. (Implemented via Codex; verified
independently: 111 lint tests pass, oxfmt/oxlint clean.)

* fix(audits): avoid caption false positives

* fix(lint): ignore proxy-label tween overlaps

* fix(cli): preserve the five-percent text audit floor

* fix(lint): preserve proxy identity across lexical scopes

* fix(cli): audit only directly painted text

* fix(lint): compare live composition ids canonically

* fix(lint): preserve expanded proxy identities

* fix(cli): measure directly painted text geometry

* fix(lint): preserve first duplicate attribute value

* fix(lint): keep shared proxy identity across helpers

* fix(parsers): preserve expanded proxy identity

* fix(lint): decode composition IDs consistently
2026-07-14 20:13:01 -04:00
Miguel Ángel 14df58f017 fix(check): ignore registry component templates (#2450) 2026-07-14 18:21:25 -04:00
Miguel Ángel 4b0b89e8b1 chore: release v0.7.58 (#2446) 2026-07-14 16:15:59 -04:00
Miguel Ángel 90be05019b chore: release v0.7.57 (#2393) 2026-07-14 00:29:29 -04:00
Miguel Ángel 6f4c6308f0 fix(lint): isolate IIFE timing constants (#2378) 2026-07-13 20:53:24 -04:00
Miguel Ángel 94c2e0f6eb chore: release v0.7.56 2026-07-13 07:04:42 +00:00
Miguel Ángel 38badff820 fix(render): scope strict lint to composition (#2261)
* fix(render): scope strict lint to composition

* fix(lint): validate explicit composition scope
2026-07-12 22:18:11 -04:00
Vance Ingalls c830aa83c5 chore: release v0.7.55 2026-07-12 11:52:53 -07:00
Vance Ingalls ae4946e624 chore: release v0.7.54 2026-07-11 17:15:24 -07:00
Miguel Ángel c18391b98c fix(lint): honor data-no-timeline on root compositions (#2228) 2026-07-11 18:32:15 -04:00
Miguel Angel Simon Sierra 3b081a44ae chore: release v0.7.53 2026-07-11 15:59:07 -04:00
Miguel Ángel 03c47dbb37 Merge pull request #2230 from heygen-com/fix/studio-graded-element-editing
fix(studio): graded elements survive manual editing (disappear/resize/rotate/crop/panel)
2026-07-11 15:57:42 -04:00
Miguel Angel Simon Sierra fe52966728 fix(lint): anchor the opacity-zero probe so 0.98 stops matching
gsap_from_opacity_noop matched 'opacity: 0' as a prefix — an authored
'opacity: 0.98' triggered the rule. One boundary-anchored predicate now
owns the exactly-zero test for both block and inline declarations,
including a block's last declaration without a trailing semicolon.

domEditingDom now imports the grading contract attribute from core
instead of re-declaring the literal.
2026-07-11 04:08:07 -04:00
Miguel Ángel 05c3b5503f fix(lint): parse HTML structure without regex (#2223)
* fix(lint): ignore scripts inside quoted attributes

* Address PR review feedback (#2223)

- replace repeated attribute scanner with quoted tag ranges
- remove the Fallow complexity finding

* refactor(lint): parse HTML structure with htmlparser2

* fix(lint): traverse template style sources

* test(lint): cover nested template style sources
2026-07-11 00:03:07 -04:00
Miguel Ángel d51fa7eba2 fix(lint): flag digit-leading element ids (#2222) 2026-07-10 23:03:17 -04:00
Vance Ingalls 7498eb4a3a chore: release v0.7.52 2026-07-10 19:47:59 -07:00
Miguel Ángel 0e7f40dfc0 fix(lint): ignore macOS AppleDouble HTML files (#2191) 2026-07-10 20:27:24 -04:00
Miguel Ángel 598dd8b350 chore: release v0.7.51 (#2188) 2026-07-10 20:16:15 -04:00
Miguel Angel Simon Sierra 1d97ddaf8c chore: release v0.7.50 2026-07-10 18:48:40 -04:00
Vance Ingalls 6152437d2a chore: release v0.7.49 2026-07-10 09:57:48 -07:00
Miguel Ángel 3fd340f6ba chore: release v0.7.48 (#2118) 2026-07-09 21:49:58 -04:00
Miguel Angel Simon Sierra 3aa1cf0d83 chore: release v0.7.47 2026-07-09 20:34:59 -04:00
James 8de80bf369 feat(sdk,studio): editable template sub-compositions + promote sub-comp element properties 2026-07-09 13:31:04 -07:00
James f7ee0768ae feat(core): declarative variable bindings — data-var-src, data-var-text, css custom props 2026-07-09 13:31:03 -07:00
Vance Ingalls 030fded71d chore: release v0.7.46 2026-07-09 12:01:33 -07:00
Vance Ingalls 31f0810be8 chore: release v0.7.45 2026-07-08 22:15:49 -07:00
Vance Ingalls 1e8dd29815 chore: release v0.7.44 2026-07-08 16:21:05 -07:00
Vance Ingalls f8f945d42e chore: release v0.7.43 2026-07-08 15:51:39 -07:00
Vance Ingalls e52bfc246a Merge pull request #2053 from heygen-com/vi/figma-loop-fixes
fix(core,cli,lint): close the figma brand-token loop — runtime CSS variables, --name, snippet lint
2026-07-08 09:27:19 -07:00
Vance Ingalls 4fc619e4f1 Merge remote-tracking branch 'origin/main' into feat/lint-gsap-non-transform-motion
# Conflicts:
#	skills-manifest.json
2026-07-08 01:36:50 -07:00
Vance IngallsandClaude Fable 5 def276524b fix(core,cli,lint): close the figma brand-token loop — runtime CSS variables, --name, snippet lint
Brand-loop live test (SDS duplicate, plans/figma/brand-loop-test-plan.md)
proved the recolor chain end-to-end and surfaced three gaps:

- runtime now defines every declared composition variable as a CSS
  custom property (document root at init + scoped sub-comp hosts in the
  loader), so imported var(--slug, literal) fills resolve live — without
  this the frozen literal always won and variable-driven rebranding
  could not propagate. Slug kept byte-compatible with the figma
  importer (parity test). render --variables overrides win.
- figma component --name: variant frames are often all named
  'Platform=Desktop' and slug-collided across imports.
- imported fragments carry data-hf-snippet and the project linter skips
  composition-root rules for them.
- /figma skill documents the field-tested non-Enterprise tokens path
  (MCP get_variable_defs joined with REST boundVariables ids).

Shared-helper extractions (injectScopedStyles, flattenedRoot module,
parseHostVariableValues, rasterizeFallback, shapeCss) satisfy the
dedup/complexity audit the runtime changes tripped.

Validated live: brand-loop renders purple from the attribute alone (no
manual :root); 118 figma + 662 runtime/compiler + 331 lint tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 00:47:13 -07:00
Vance IngallsandClaude Fable 5 f6cd711bf0 chore: release v0.7.42
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 16:04:26 -07:00
Miguel Ángel 60463d0bd5 chore: release v0.7.41 2026-07-07 20:30:24 +00:00
Miguel Ángel 2bd9bb6f69 chore: release v0.7.40 (#2024) 2026-07-07 12:30:13 -04:00
Vance Ingalls 229e88eac5 chore: release v0.7.39 2026-07-06 22:48:42 -07:00
Vance Ingalls d8d3a93b0d chore: release v0.7.38 2026-07-06 17:47:34 -07:00
Vance IngallsandClaude Fable 5 992a9b6607 feat(lint,player): fast-capture lint rule + player media sync (#1921)
* feat(engine): drawElementImage capture service

* feat(engine): 3D projection + compositor-effect risk gate

* fix(engine): gate filter drop-shadow wherever blur gates (review)

detectCssEffectRisk documented drop-shadow as a ~29dB damage case but only
detected blur( in its three scan paths — a drop-shadow comp stayed on the
fast path despite the gate's own correctness contract. Detect drop-shadow(
in computed styles, stylesheet rules, and GSAP tween vars, pinned by a
focused test that runs the real page-side closure against a DOM shim
(computed / stylesheet / tween coverage + blur regression + effect-free
null).

Addresses miguel-heygen's blocker on #1918.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(engine): frame-capture core — fast-capture routing, worker-encode, dedup extension

# Conflicts:
#	packages/engine/src/services/screenshotService.ts

* fix(engine): document HF_FORCE_DRAWELEMENT as diagnostic-only; make armStaticDedup idempotent (review)

Addresses miguel-heygen's blockers on #1919:

- HF_FORCE_DRAWELEMENT promoted from a stale "SCRATCH/Uncommitted" comment to
  a documented diagnostic flag: it exists for upstream-Chromium repro work
  (gate-vs-API isolation, crbug 521861819 149-vs-151) and R&D on gated effect
  classes; renders under it may be damaged BY DESIGN since it bypasses gates
  whose thresholds encode measured damage. Never production; the safety-net
  blank guard also stands down under it so diagnostic frames arrive unmodified.
- armStaticDedup is now idempotent: the drawElement init path arms dedup
  before canvas injection, then initializeSession called it again — the
  second run overwrote the armed state with skipReason="capture_mode"
  (captureMode is "drawelement" by then), producing contradictory telemetry
  (armed frames + a skip reason), and re-ran the verification seeks on the
  fallback path. It now no-ops once staticFrames or a skip decision exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(producer): fast-capture render stages + remote bg-image localizer

* feat(lint,player): fast-capture lint rule + player media sync

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:22:35 -07:00
Miguel Ángel afa7f292fb feat(lint): warn when <html dir> can blank render output (#1893)
* feat(lint): flag dir="rtl" on <html> as a confirmed silent render failure

Two independent reports diagnosed the same exact bug: dir="rtl" (or any
non-ltr value) on <html> renders correctly in preview/snapshot but
produces a fully blank/black video from render, with no other
lint/validate/inspect check catching it - output file size (far smaller
than expected) was the only tell for both reporters. Both independently
confirmed the same fix: drop dir from <html>, keep lang, and scope
direction: rtl to individual text-containing elements via CSS instead.

Could not empirically verify the render pipeline's own root cause in this
session (headless Chrome screenshot capture is unreliable in this
sandboxed environment - even a baseline, non-RTL capture timed out), so
this ships the safe, already-confirmed advisory rather than guessing at a
runtime fix. Both reporters explicitly asked for exactly this: "deserves
a lint rule or render-time warning."

* fix(lint): only flag valid non-ltr html dir values
2026-07-06 18:16:40 -04:00
James 9de41ce316 chore: release v0.7.37 2026-07-06 05:59:36 +01:00
Miguel Ángel e8d19b1b43 chore: release v0.7.36 2026-07-05 19:25:42 +00:00
Miguel Ángel 2f55ea678a chore: release v0.7.35 2026-07-05 18:48:24 +00:00
Miguel Ángel 114d31919e chore: release v0.7.34 (#1954) 2026-07-05 10:55:11 -07:00
Miguel Ángel 78cca797f1 chore: release v0.7.33 2026-07-04 22:33:27 +00:00