product-launch-video: assemble-index.mjs is not idempotent — a second run drops every approved frame video
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 75/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- html, typescript
- Domain
- backend
Research direction
Start with skills/product-launch-video/scripts/assemble-index.mjs, especially guardFrame(), hoistApprovedVideos(), and the write near line 417. Trace how the repaired frame HTML is used when building index.html, then add a regression test that assembles the same fixture twice and compares the root video count. Done when both runs preserve the approved footage and the second run does not silently produce an empty render.
Written by the indexing model from the issue text.
Description
Summary
skills/product-launch-video/scripts/assemble-index.mjs is not idempotent. The first run hoists each approved frame <video> out of its frame file and writes the frame file back with only a placeholder comment (<!-- approved frame video hoisted by assemble-index -->). A second run finds no <video> in the frame files, so it rebuilds index.html with no footage, and it exits cleanly without any error or warning.
Repro (hyperframes 0.8.163)
- A project with a frame
compositions/frames/02-x.htmlthat holds an approved video (data-frame-video="approved", withdata-start/data-duration/data-track-index/ layout attrs). - Run
assemble-index.mjs, andindex.htmlhas the root-level<video>. ✅ - Edit any frame (e.g. a caption fix) and run
assemble-index.mjsagain. index.htmlhas no<video>, the frame file has only the hoist comment, and the render shows empty device frames.
Cause
guardFrame() → hoistApprovedVideos() returns the stripped HTML as repairedHtml, and the caller persists it (writeFileSync(compAbs, guard.repairedHtml), ~line 417). The hoist is meant to happen at assembly time, but it mutates the source of truth, so the operation destroys data on re-run.
Suggested fix
Either of these would work:
- Don't write the hoist back: keep the
<video>in the frame source and strip it only in the in-memory copy used forindex.html(the root-dimension repair can still be persisted on its own). - Or make the placeholder carry the full tag (e.g. a
data-hoisted<template>or an attribute-bearing comment) so a re-run can re-hoist from it.
A regression test: run assembly twice on the same fixture and assert that the <video> count in index.html is equal across runs.
Impact
Any edit-and-reassemble loop, which the review loop encourages, silently loses all footage. The only signal is a blank render, found after a full render cycle.
- Dominant language
- TypeScript
- Stars
- 54.1k
- Forks
- 4.9k
- Avg merge
- 10h 45m
- Merged PRs (30d)
- 654
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from heygen-com/hyperframes
-
Player: speed button's accessible name doesn't include its visible textPossibly taken @Dante-dan claimed this 1 day ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
heygen-com/hyperframes#6021 · 1 comment ·
Maintainers usually reply within 1 day
-
inspector: build.mjs resolves paths with URL#pathname, fails ENOENT (F:\\F:\\...) and aborts bun run build on WindowsPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 1/5 Under an hour Newbie friendliness 88/100
heygen-com/hyperframes#5863 · 1 comment ·
Maintainers usually reply within 1 day
-
gsap_tween_tail counts GSAP's force3D and autoRound flags as propertiesPossibly taken @rudycelekli claimed this 6 days ago. Openbug triage/needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
heygen-com/hyperframes#5683 ·
Maintainers usually reply within 1 day
-
Timeline: show a clip's full name when its label is cut offPossibly taken @DanielMcSheehy claimed this 4 days ago. Opendesktop-candidate difficulty/easy enhancement good first issue help wanted triage/ready
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
heygen-com/hyperframes#5582 · 2 comments ·
Maintainers usually reply within 1 day
-
Studio: press ? to open the keyboard shortcuts panelPossibly taken @B-Payal claimed this 8 days ago. Opendesktop-candidate difficulty/easy enhancement good first issue help wanted triage/ready
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
heygen-com/hyperframes#5580 · 1 comment ·
Maintainers usually reply within 1 day
All issues in heygen-com/hyperframes
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 76/100
logto-io/logto#9837 · 1 comment ·
Maintainers usually reply within 1 day
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 76/100
lingdojo/kana-dojo#32964 · 1 comment · 5 reactions ·
Maintainers usually reply within 1 day
-
Documentation status: needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
mastra-ai/mastra#28194 · 1 comment ·
Maintainers usually reply within 1 day
-
priority-low refactor-3
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 3 days