Repository navigation
fix(embedded-captions): support heroless themes - #3632
Merged
Merged
Conversation
miga-heygen
approved these changes
Sep 4, 2026
miga-heygen
left a comment
Contributor
There was a problem hiding this comment.
Reviewed at 4e610359a6. Looks correct and complete — approving.
What I checked:
- All 17
b.yieldblocks are gated behind!HEROLESS &&— the main source of hero-coupled GSAP emitters that were leaking the-999sentinel. frontFx()bypassed entirely in heroless mode:HEROLESS ? { css: "", html: "", js: "" } : frontFx().- Both null-access crashes guarded:
terminalandspectrumthemes'hero.start/hero.enddereferences are now behindhero &&. lastpageparadigm fields (CSS/HTML/JS) all wrapped in!HEROLESSblocks.- Setpieces already gated at L8495 via
!heroInline && !HEROLESS, so heroIn/heroOut refs inside setpiece functions are unreachable in heroless mode. lockT(computed fromheroInat L773) is harmless — only consumed in ahero && redactLinkageternary that short-circuits to0when hero is null.- Hero-present themes are unaffected — all guards are
!HEROLESS &&prefixes that pass through normally.
Test quality: Strong. The -99\d regex assertion across all 25 themes' generated pages catches any leaked sentinel. The heroless fixture is minimal and well-scoped.
One CI note: Skills: manifest in sync is failing — likely needs the new test file registered in the manifest. Not a code defect.
— Miga
heygengenesis
Bot
force-pushed
the
bugfix/1787766784.915709-heroless-hero
branch
from
September 4, 2026 13:40
4e61035 to
225a880
Compare
miga-heygen
enabled auto-merge (squash)
September 4, 2026 13:52
Co-authored-by: miguel.sierra <[email protected]>
heygengenesis
Bot
force-pushed
the
bugfix/1787766784.915709-heroless-hero
branch
from
September 4, 2026 18:17
225a880 to
32275a1
Compare
miga-heygen
approved these changes
Sep 4, 2026
miga-heygen
left a comment
Contributor
There was a problem hiding this comment.
Re-approved at 32275a1 after rebase. Manifest regenerated (142 embedded-captions files), CI green. Same fix — heroless themes skip hero-derived emitters, both null accesses guarded, 25-theme regression fixture intact. Auto-merge enabled.
— Miga
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.
What
Omitting documented-optional
theme.heronow compiles every shipped theme as a pure-body caption timeline rather than emitting-999hero timings. Hero-present timelines retain their existing behavior.Why
Reported by @miguel-heygen
Fixes #3628.
How
The generator previously used
-999only as an internal absent-hero sentinel, but body-yield and front-FX emitters still consumed it. This keeps the sentinel internal by omitting hero-coupled emitters in pure-body mode and guarding the two optional-hero accesses; ordinary body/furniture generation remains intact.Exact source map — base defect → published fix
make-theme.cjs(every changed source hunk):yield guards: base L749 → head L749; base L817 → head L817; base L2058 → head L2067; base L2215 → head L2228; base L2407 → head L2420; base L2554 → head L2571; base L2794 → head L2811; base L2802 → head L2819; base L2978 → head L2999; base L3100 → head L3125; base L3247 → head L3272; base L3747 → head L3784; base L3943 → head L3980; base L4140 → head L4177; base L4334 → head L4371; base L4470 → head L4507; base L4650 → head L4687; base L4785 → head L4822; base L4933 → head L4970.
null guards and apex-specific emitters: base L780 → head L780; base L1807-L1859 → head L1807-L1868; base L2197-L2204 → head L2206-L2217; base L2346 → head L2359; base L2430-L2449 → head L2443-L2466; base L2918-L2920 → head L2935-L2941; base L3038 → head L3059; base L3062-L3065 → head L3083-L3090; base L3327-L3370 → head L3352-L3399; base L3418-L3432 → head L3447-L3465; base L3513 → head L3546; base L3567-L3569 → head L3600-L3606; base L3629 → head L3666; base L8498 → head L8535.
New regression assets (no base counterpart): test L1-L82, theme fixture L1-L11, and transcript fixture L1-L10.
Test plan
node --test skills/embedded-captions/scripts/make-theme.test.mjs— PASS: 26 tests, 25 theme subtests, 0 failures.npx --yes [email protected] --check skills/embedded-captions/scripts/make-theme.cjs skills/embedded-captions/scripts/make-theme.test.mjs skills/embedded-captions/scripts/fixtures/heroless/theme.json skills/embedded-captions/scripts/fixtures/heroless/transcript.json— PASS.node --check skills/embedded-captions/scripts/make-theme.cjs— PASS.git diff --check— PASS.terminal,spectrum, and background-layerlastpage; generated HTML has no-99xsentinel values.node skills/embedded-captions/scripts/preview-frames.cjs <compiled-project> 2.4→timeline never registered in <page>; open embedded-captions: preview-frames.cjs is broken by a gsap SRI mismatch (hard-coded 3.14.2 vs installed 3.15.0) #3629 is a GSAP SRI mismatch—preview interception returns workspace 3.15.0 against the generated page's 3.14.2 integrity, sowindow.__timelines.maindoes not register. No runtime video/frame evidence occurred.Durable generated-output evidence: BEFORE arcade rail · AFTER arcade rail · compile matrix.
Reviewer notes (1) · Forensics
make-theme.test.mjs:76.Memory: video-rendering, text-editor
Base defect permalinks (the source map above links every published hunk at head):
hero.start, main L770-L782hero.len, main L3629-L3633Durable compiler e2e artifacts (generated pages/logs):
arcade: BEFORE rail.html → AFTER rail.htmlterminal: BEFORE null-dereference log → AFTER compile log, AFTER rail.htmlspectrum: BEFORE null-dereference log → AFTER compile log, AFTER rail.htmlThe browser-preview command could not produce screenshots in this compiler-only sandbox:
node skills/embedded-captions/scripts/preview-frames.cjs /tmp/bugfix-3628-artifacts/stage5/after/arcade 2.4exited0with[preview] need puppeteer+sharp — set HYPERFRAMES_ROOT. No screenshot is claimed. The separate #3629 SRI mismatch remains outside this PR.Regression fails on the unfixed base: after checking the committed test and fixture into a detached
19a512c05a5929a9860ef97ee47812c5e7108e57worktree,node --test skills/embedded-captions/scripts/make-theme.test.mjsexited1on the emitted-999positions; full failing output.