fix(lint): promote rules to errors with registry exemptions and false-positive fixes (#1495)

* fix(lint): promote rules to errors with registry exemptions and false-positive fixes

- Export isRegistrySourceFile/isRegistryInstalledFile from composition.ts
- Add registry exemptions to google_fonts_import and font_family_without_font_face
- Add registry exemption to requestanimationframe_in_composition
- Fix timed_element_missing_clip_class: data-track-index alone no longer triggers
- Fix caption_transcript_parse_error: balanced-bracket scanner replaces non-greedy regex
- Fix missing_timeline_registry: skips sub-compositions and template-wrapped files
- Fix scene_layer_missing_visibility_kill: strip JS comments before pattern matching
- Fix gsap_css_transform_conflict: exempt from() alongside fromTo()
- Fix gsap_from_opacity_noop: only fires when opacity value is actually 0
- Add regression test for data-track-index-only elements

* test(lint): add regression tests for false-positive fixes

Covers the 7 missing negative-case assertions flagged in PR review:
- registry marker suppresses google_fonts_import + font_family_without_font_face
- registry marker suppresses requestanimationframe_in_composition
- isSubComposition suppresses missing_timeline_registry
- scene_layer_missing_visibility_kill: fires, commented-kill fires, real kill suppresses
- gsap_css_transform_conflict: from() exempt alongside fromTo()
- gsap_from_opacity_noop: non-zero opacity (e.g. 0.5) is a valid reveal, not a noop

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

* fix(examples): fix warm-grain template to pass promoted lint rules

- index.html: remove undeclared "Lexend" from font-family stack
- intro.html: replace Google Fonts @import with bundled Inter font
- captions.html: quote TRANSCRIPT keys for valid JSON + use Inter font

Fixes CLI smoke CI failure after google_fonts_import, font_family_without_font_face,
and caption_transcript_parse_error were promoted from warning to error.

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

* fix(cli): resolve warm-grain from repo registry in dev mode + bundle at build

getStaticTemplateDir now falls back to registry/examples/<id> in dev mode
so CI smoke tests use the PR-branch copy instead of fetching from main.
build-copy.mjs copies warm-grain to dist/templates/warm-grain at build time
so packed CLIs can scaffold it offline.

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

* fix(examples): remove trailing comma from warm-grain TRANSCRIPT array

JSON.parse rejects trailing commas (valid JS, invalid JSON).
caption_transcript_parse_error was still firing because of the comma
on the last entry after quoting all keys.

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vance Ingalls
2026-06-16 21:13:00 -07:00
committed by GitHub
co-authored by Claude Sonnet 4.6
parent cc7c206e9c
commit 386df23a74
17 changed files with 341 additions and 167 deletions
+47 -47
View File
@@ -37,7 +37,7 @@
[data-composition-id="captions"] .caption-text {
color: #f5f0e0;
font-family: "Outfit", sans-serif;
font-family: "Inter", sans-serif;
font-size: 48px;
font-weight: 700;
text-align: center;
@@ -52,52 +52,52 @@
<script>
(function () {
const script = [
{ text: "We", start: 0.119, end: 0.259 },
{ text: "asked", start: 0.319, end: 0.479 },
{ text: "what", start: 0.519, end: 0.659 },
{ text: "you", start: 0.699, end: 0.819 },
{ text: "needed.", start: 0.859, end: 1.819 },
{ text: "Forty-seven", start: 1.86, end: 2.299 },
{ text: "percent", start: 2.399, end: 2.679 },
{ text: "of", start: 2.7, end: 2.799 },
{ text: "you", start: 2.839, end: 2.939 },
{ text: "said", start: 3.039, end: 3.179 },
{ text: "motion", start: 3.24, end: 3.559 },
{ text: "graphics,", start: 3.579, end: 4.599 },
{ text: "sixty-two", start: 4.679, end: 5.179 },
{ text: "percent", start: 5.299, end: 5.759 },
{ text: "said", start: 5.859, end: 5.98 },
{ text: "static", start: 6.079, end: 6.399 },
{ text: "content", start: 6.46, end: 6.879 },
{ text: "was", start: 6.92, end: 7.079 },
{ text: "costing", start: 7.099, end: 7.48 },
{ text: "you", start: 7.5, end: 7.579 },
{ text: "attention,", start: 7.679, end: 8.659 },
{ text: "and", start: 8.699, end: 8.86 },
{ text: "three", start: 8.88, end: 9.06 },
{ text: "out", start: 9.079, end: 9.18 },
{ text: "of", start: 9.199, end: 9.34 },
{ text: "four", start: 9.38, end: 9.799 },
{ text: "said", start: 9.84, end: 10.0 },
{ text: "you", start: 10.019, end: 10.159 },
{ text: "know", start: 10.179, end: 10.36 },
{ text: "the", start: 10.38, end: 10.42 },
{ text: "look", start: 10.519, end: 10.699 },
{ text: "you", start: 10.739, end: 10.859 },
{ text: "want", start: 10.98, end: 11.34 },
{ text: "but", start: 11.359, end: 11.52 },
{ text: "don't", start: 11.56, end: 11.779 },
{ text: "have", start: 11.819, end: 11.94 },
{ text: "the", start: 11.96, end: 12.06 },
{ text: "editing", start: 12.079, end: 12.4 },
{ text: "skills", start: 12.52, end: 12.86 },
{ text: "to", start: 12.88, end: 13.0 },
{ text: "get", start: 13.019, end: 13.18 },
{ text: "there.", start: 13.22, end: 14.22 },
{ text: "So", start: 14.239, end: 14.399 },
{ text: "we", start: 14.42, end: 14.52 },
{ text: "built", start: 14.619, end: 14.88 },
{ text: "Hyperframes.", start: 15.079, end: 16.02 },
{ "text": "We", "start": 0.119, "end": 0.259 },
{ "text": "asked", "start": 0.319, "end": 0.479 },
{ "text": "what", "start": 0.519, "end": 0.659 },
{ "text": "you", "start": 0.699, "end": 0.819 },
{ "text": "needed.", "start": 0.859, "end": 1.819 },
{ "text": "Forty-seven", "start": 1.86, "end": 2.299 },
{ "text": "percent", "start": 2.399, "end": 2.679 },
{ "text": "of", "start": 2.7, "end": 2.799 },
{ "text": "you", "start": 2.839, "end": 2.939 },
{ "text": "said", "start": 3.039, "end": 3.179 },
{ "text": "motion", "start": 3.24, "end": 3.559 },
{ "text": "graphics,", "start": 3.579, "end": 4.599 },
{ "text": "sixty-two", "start": 4.679, "end": 5.179 },
{ "text": "percent", "start": 5.299, "end": 5.759 },
{ "text": "said", "start": 5.859, "end": 5.98 },
{ "text": "static", "start": 6.079, "end": 6.399 },
{ "text": "content", "start": 6.46, "end": 6.879 },
{ "text": "was", "start": 6.92, "end": 7.079 },
{ "text": "costing", "start": 7.099, "end": 7.48 },
{ "text": "you", "start": 7.5, "end": 7.579 },
{ "text": "attention,", "start": 7.679, "end": 8.659 },
{ "text": "and", "start": 8.699, "end": 8.86 },
{ "text": "three", "start": 8.88, "end": 9.06 },
{ "text": "out", "start": 9.079, "end": 9.18 },
{ "text": "of", "start": 9.199, "end": 9.34 },
{ "text": "four", "start": 9.38, "end": 9.799 },
{ "text": "said", "start": 9.84, "end": 10.0 },
{ "text": "you", "start": 10.019, "end": 10.159 },
{ "text": "know", "start": 10.179, "end": 10.36 },
{ "text": "the", "start": 10.38, "end": 10.42 },
{ "text": "look", "start": 10.519, "end": 10.699 },
{ "text": "you", "start": 10.739, "end": 10.859 },
{ "text": "want", "start": 10.98, "end": 11.34 },
{ "text": "but", "start": 11.359, "end": 11.52 },
{ "text": "don't", "start": 11.56, "end": 11.779 },
{ "text": "have", "start": 11.819, "end": 11.94 },
{ "text": "the", "start": 11.96, "end": 12.06 },
{ "text": "editing", "start": 12.079, "end": 12.4 },
{ "text": "skills", "start": 12.52, "end": 12.86 },
{ "text": "to", "start": 12.88, "end": 13.0 },
{ "text": "get", "start": 13.019, "end": 13.18 },
{ "text": "there.", "start": 13.22, "end": 14.22 },
{ "text": "So", "start": 14.239, "end": 14.399 },
{ "text": "we", "start": 14.42, "end": 14.52 },
{ "text": "built", "start": 14.619, "end": 14.88 },
{ "text": "Hyperframes.", "start": 15.079, "end": 16.02 }
];
// Group words into lines (max 5 words per line)