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 29m
- Merged PRs (30d)
- 649
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 2 days ago. Opentriage/ready
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. Opentriage/ready
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 7 days ago. Openbug triage/ready
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 6 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 10 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
-
[Bug]: REST API URL starting with "http" but no scheme (e.g. httpbin.org/get) is not given an http:// prefixPossibly taken @ItsDeadlyProgrammer claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
appsmithorg/appsmith#42471 · 1 comment ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
ehmpathy/rhachet-roles-bhrain#705 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
Status: Triage
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
mermaid-js/mermaid#8546 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
braintrustdata/braintrust-sdk-javascript#2659 ·
Maintainers usually reply within 1 day