mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 10:06:21 +00:00
fix(skills): clear two Snyk Fails and harden the network + supply-chain surface (#1804)
* fix(skills): clear Snyk findings and harden supply-chain surface
Address the security-audit findings on the published skills with no change to
any skill's behaviour.
- media-use: resolve.test.mjs runs resolve.mjs via execFileSync with an argv
array instead of execSync(`node … "${tmp}" …`), removing the command-injection
(CWE-78) sink that drove the Snyk Fail.
- music-to-video: replace dynamic `element.innerHTML = <var>` with a setSvg()
helper (DOMParser image/svg+xml + importNode, text fallback) in the
intro-kinetic-cascade and logo-split-lockup-pulse frame templates, clearing the
DOM-XSS (CWE-79) Snyk Fail. Renders identical SVG.
- pr-to-video: fetch-people-avatars.mjs refuses any avatar URL that is not https
on a GitHub avatar host (SSRF guard) and only writes under the project dir
(path-traversal guard); best-effort, always-exit-0 behaviour is unchanged.
- embedded-captions: pin `uvx --from whisperx==3.8.6` (overridable via
$WHISPERX_VERSION) so transcription no longer resolves "latest" at runtime.
- gsap: add Subresource Integrity (integrity + crossorigin) to the 8 render-time
CDN GSAP <script> tags across embedded-captions, music-to-video,
faceless-explainer, pr-to-video and product-launch-video.
- hyperframes-animation / hyperframes-creative: document package-loader's
defense-in-depth and note that the installLine strings are display-only.
Verified: media-use resolve (12/12), probe injection (1/1) and manifest (19/19)
tests pass; avatar host-allowlist checks pass; all changed JS passes node --check
and oxfmt.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(skills): clarify product-launch-video vs website-to-video routing
Sharpen the router's product-vs-site decision in hyperframes/SKILL.md: the
split is now "is the site selling a product?" — yes (SaaS / app / product /
company site) → /product-launch-video (a promo; the default for any commercial
URL, even if the site is only named); no, or the user just wants the site shown
as-is (portfolio / blog / docs / personal / event) → /website-to-video (a tour).
Updates the workflow table, the disambiguation bullet, and both workflows'
Input/Output blurbs to match.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* style(skills): satisfy oxfmt in the two music-to-video templates
The CI Format job runs `oxfmt --check .`, which also formats embedded <script> in .html. Reflow the setSvg() blocks added for the DOM-XSS fix to oxfmt's wrapping — no logic change. Regenerate the music-to-video manifest hash to match.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(skills): sanitize SVG in music-to-video templates (real CWE-79 fix)
Addresses @Magi's review: the previous setSvg() only swapped the sink
(innerHTML → DOMParser + importNode) but did NOT sanitize, so active SVG
content still executed on insertion into the live document. Verified in
headless Chrome that the old shape fired both an svg `onload` handler and an
inline `<script>`.
setSvg() now runs a default-deny cleanSvg() over the parsed tree before it ever
enters the document: only an allow-list of inert drawing elements
(svg/g/path/line/rect/circle/… ) and presentation attributes
(d/fill/stroke/viewBox/…) survives. Every other element (`<script>`, `<image>`,
`<use>`, `<foreignObject>`, `<a>`, `<animate>`, …), every `on*` handler, and
href/xlink:href/style are stripped — on the root node too. Non-SVG or malformed
input still falls back to textContent.
Trusted content (the bundled icon library + the default spark/cloud marks)
renders byte-identically; only hostile markup in vars.icon / leftMark / rightMark
is neutralized.
Browser-verified (headless Chrome, both templates' helper):
old setSvg → fired ["script","onload"]
new setSvg → fired [] · trusted icon still renders · 0 danger nodes · 0 on* attrs
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
8694424807
commit
535297280a
+17
-17
@@ -51,24 +51,24 @@ Routing needs to know **what the video is about** — its input and subject. If
|
||||
|
||||
## Workflow cheat-sheet
|
||||
|
||||
| Workflow | Use it for |
|
||||
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/product-launch-video` | Marketing / launching / promoting a **product** — from its URL, a brief, or a script (even if the site is only named) |
|
||||
| `/website-to-video` | Turning a **general website** into a video — site tour, portfolio / landing-page showcase, social clip from the site's visuals |
|
||||
| `/faceless-explainer` | **Explaining a topic / concept** from text — no product, no URL; every visual is LLM-invented |
|
||||
| `/pr-to-video` | A **GitHub PR / code change** → changelog / feature-reveal / fix / refactor explainer |
|
||||
| `/embedded-captions` | Adding **captions / subtitles** to an existing talking-head video (footage untouched) |
|
||||
| `/talking-head-recut` | Packaging an existing talking-head video with **designed graphic overlays** — lower-thirds, data callouts, kinetic titles, pull-quotes |
|
||||
| `/motion-graphics` | A short, **unnarrated, design-led motion graphic** — kinetic type, a stat / chart hit, a logo sting, a lower-third overlay |
|
||||
| `/music-to-video` | A **music track** → a **beat-synced** video — lyric video, slideshow, or kinetic promo; the music drives pacing (optional user images / videos cut onto the beat grid) |
|
||||
| `/slideshow` | A **presentation / pitch deck / interactive deck** — discrete slides, fragments, branching, hotspots; output is a navigable **deck**, not a rendered video |
|
||||
| `/general-video` | **Anything else** — longer or multi-scene pieces, a static loop / poster, a custom composition |
|
||||
| `/remotion-to-hyperframes` | **Porting an existing Remotion (React) composition** to HyperFrames (migration, not creation) |
|
||||
| Workflow | Use it for |
|
||||
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/product-launch-video` | **Selling a product** (SaaS, app, company / product site) — from a URL, brief, or script → a **promo**. The default for any commercial URL, even if the site is only named. |
|
||||
| `/website-to-video` | **Showing a site itself** — a tour / showcase built from the site's own screenshots. For non-commercial sites (portfolio, blog, docs, personal, event), or when the user wants a tour, not a promo. |
|
||||
| `/faceless-explainer` | **Explaining a topic / concept** from text — no product, no URL; every visual is LLM-invented |
|
||||
| `/pr-to-video` | A **GitHub PR / code change** → changelog / feature-reveal / fix / refactor explainer |
|
||||
| `/embedded-captions` | Adding **captions / subtitles** to an existing talking-head video (footage untouched) |
|
||||
| `/talking-head-recut` | Packaging an existing talking-head video with **designed graphic overlays** — lower-thirds, data callouts, kinetic titles, pull-quotes |
|
||||
| `/motion-graphics` | A short, **unnarrated, design-led motion graphic** — kinetic type, a stat / chart hit, a logo sting, a lower-third overlay |
|
||||
| `/music-to-video` | A **music track** → a **beat-synced** video — lyric video, slideshow, or kinetic promo; the music drives pacing (optional user images / videos cut onto the beat grid) |
|
||||
| `/slideshow` | A **presentation / pitch deck / interactive deck** — discrete slides, fragments, branching, hotspots; output is a navigable **deck**, not a rendered video |
|
||||
| `/general-video` | **Anything else** — longer or multi-scene pieces, a static loop / poster, a custom composition |
|
||||
| `/remotion-to-hyperframes` | **Porting an existing Remotion (React) composition** to HyperFrames (migration, not creation) |
|
||||
|
||||
**Disambiguation (only where confusable):**
|
||||
|
||||
- **Motion-first & unnarrated** (under ~10s, the motion _is_ the message) → `/motion-graphics`, regardless of input.
|
||||
- **A URL or script** — markets a specific product (even just naming the site) → `/product-launch-video`; a general non-product site → `/website-to-video`; a GitHub PR link → `/pr-to-video`; explains a concept with no product / site → `/faceless-explainer`. Genuinely unclear product-vs-topic, or launch-vs-general-site → ask one question.
|
||||
- **A URL or script** — ask one thing: _is the site selling a product?_ **Yes** (SaaS / app / product / company site) → `/product-launch-video` — a promo, and the default for any commercial URL even if the site is only named. **No**, or the user just wants the site shown as-is (portfolio / blog / docs / personal / event) → `/website-to-video` — a tour. A GitHub PR link → `/pr-to-video`; a concept with no product or site → `/faceless-explainer`.
|
||||
- **Existing footage** — plain spoken-word subtitles → `/embedded-captions`; designed overlay cards → `/talking-head-recut`. Neither edits the footage itself (re-timing / recolor / reframe / reorder / audio is NLE editing — out of scope).
|
||||
- **A music track is the input** (an audio file, or a video to pull audio from) with **no narration** → `/music-to-video` — the music's beats/energy drive the pacing. (Narrated pieces stay with the input-matched workflow above; `/motion-graphics` is for short unnarrated motion that isn't music-driven.)
|
||||
- **A presentation / pitch deck / interactive deck** (discrete slides, navigation, presenter mode) → `/slideshow` — output is a navigable deck, not a rendered video. An explicit "slideshow" request proceeds directly; an adjacent trigger ("deck / slides / presentation / convert this page") makes `/slideshow` confirm it's a slideshow before authoring, and switch to the appropriate non-slideshow workflow if not.
|
||||
@@ -99,13 +99,13 @@ The CLI also surfaces a one-line reminder when a `render` / `lint` / `validate`
|
||||
### `/product-launch-video`
|
||||
|
||||
- **Input:** A product being marketed — **(a)** a product URL (crawled with headless Chrome for assets + brand tokens), **(b)** a script / brief that names the product's site even without a link (PLV resolves + crawls it, unless the user opts out), or **(c)** a script with no derivable site / "don't scrape" (no-capture mode — pick a style preset that supplies palette + design system). A supplied script can be the **verbatim** voice-over or **restructured** per scene — PLV asks.
|
||||
- **Output:** product launch / SaaS promo as a HyperFrames composition → MP4. (sweet spot 30–90s).
|
||||
- **Output:** a product launch / SaaS **promo** as a HyperFrames composition → MP4 (sweet spot 30–90s) — the product's value is the subject, not a walkthrough of the site. For a plain tour of the site, use `/website-to-video`.
|
||||
- **Triggers:** "launch video for X", "promo for our site", "explain my SaaS in a minute", "turn my script into a 60s promo", "text-only launch video, don't scrape".
|
||||
|
||||
### `/website-to-video`
|
||||
|
||||
- **Input:** A **general website / URL** to turn into a video — when the goal is a video _of_ the site, not a product launch. Captured with headless Chrome for real screenshots + brand assets.
|
||||
- **Output:** a site tour / portfolio / landing-page showcase / social clip built from the site's own visuals → MP4.
|
||||
- **Input:** A website / URL whose goal is to show **the site itself**, not to sell a product. Best for non-commercial sites (portfolio, blog, docs, personal, event), or when the user explicitly wants a tour of a site as-is. Captured with headless Chrome for real screenshots + brand assets. If the site is selling something and the user wants a promo, use `/product-launch-video`.
|
||||
- **Output:** a site tour / showcase / social clip built from the site's own visuals → MP4.
|
||||
- **Triggers:** "turn this website into a video", "site tour from ", "social clip from our homepage", "I just have a URL — make something".
|
||||
|
||||
### `/faceless-explainer`
|
||||
|
||||
Reference in New Issue
Block a user