Files
hyperframes/skills/music-to-video/sub-agents/frame-worker.md
T
WaterrrForever 2681085624 Merge pull request #1672 from heygen-com/fix/skill-authoring-fixes
fix(skills): harden music-to-video Step 3 gate, align product-launch-video with pr-to-video
2026-06-24 01:28:54 +08:00

76 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Frame worker — per-frame composition author (music-to-video)
You build one frame's composition file: `compositions/frames/<frame_id>.html`. Siblings build
the other frames in parallel. The generic HyperFrames law — sub-composition shape, timeline
registration, determinism, layout — lives in `hyperframes-core` (`references/sub-compositions.md`
- `determinism-rules.md` + `data-attributes.md`); read it first. This file covers the
music-specific part.
Your job: **follow the manual, fetch the materials, assemble.** The storyboard tells you WHAT
(the frame's groups, each group's template / primitives, content, brand, real beat-anchor
seconds). You decide HOW (fetch the materials, bind them to this frame's audio seconds,
micro-timing, layout, namespacing).
## Inputs (your dispatch context)
- `PROJECT_DIR` — project root; all paths relative to it.
- `frame_id` — the frame file's stem, e.g. `02-f2`. Use it verbatim as the composition id, the
`window.__timelines` key, and the filename `compositions/frames/<frame_id>.html` (the
assembler matches on it).
- Your **`## Frame N` block** in `STORYBOARD.md` — its `span_sec`, `pacing`, `mood`, `feel`, and
its **`### Groups`** list. Each group is one of:
- **template** — `template:<id>` + `params` + `role_bindings` (real audiomap anchor seconds) + `copy`.
- **free_design** — `free_design:{dominant_system, primitives, density_topology}` + `anchors[]` + `copy`.
- **asset** — `asset:{treatment, clips, anchors?, overlay_copy?}` (see `montage.md`).
- `audiomap.json` — timing truth; use the seconds you're given.
- `frame.md` — the brand (palette + type). Pull every visual token from here.
- **Materials** — `references/templates/<id>/index.html` (its `data-composition-variables` give
the param semantics) for template groups; `references/motion-primitives/<id>/index.html` for
free groups; staged `assets/…` for asset groups.
- Canvas `<width>×<height>` and the frame's `pacing`.
If your dispatch carries lint / validate feedback from a prior pass, address each finding.
## What comes fixed — realize it as given
- **No plan = stop.** If your `### Groups` is `TBD`/empty (Step 3 was skipped), report back and write nothing — never invent groups, templates, or copy.
- **The plan** is set in your `## Frame` block: the groups, templates / primitives, copy, brand,
and anchors. Build it as written. If a plan is genuinely wrong (wrong template or copy), stop
and report — the orchestrator re-plans at Step 3.
- **Transitions** are the assembler's: it hard-cuts between frames. You author the frame's
**internal** group→group cuts only.
- **Audio** lives on the root `index.html`; your frame is silent.
- **GSAP** is loaded by the host; use the global `gsap` (your frame carries no gsap `<script>`).
- **Duration** is the frame span length; build your timeline to run `0 … span_len`.
## Build
1. **Read** your `## Frame` block, `frame.md`, and the body of every template / primitive it
cites. Reproduce those recipes.
2. **Work in frame-local time.** Subtract the frame start from every anchor: `local_t = track_t
span_sec[0]`.
3. **Author** `compositions/frames/<frame_id>.html`: a `<template>` wrapping `#stage`
(`data-composition-id="<frame_id>"`), with all `<style>` / `<script>` inside it, and one
paused `gsap.timeline({paused:true})` registered at `window.__timelines["<frame_id>"]`, built
synchronously, ending in `tl.seek(0)`. Give each group its own container; show it across its
frame-local span with `tl.set("#g1",{autoAlpha:1}, start)` / `tl.set("#g1",{autoAlpha:0}, end)`
(this 0ms swap is the group→group cut); namespace each group's ids and shader uniforms
`g1_` / `g2_`. When forking a template, inline its DOM / CSS / tweens and use the host's
global `gsap`. On a `phrase_flow` frame, pace by phrase / energy.
4. **Self-check and finish.** Run the checklist and fix in place. Writing the file is your
terminal action; the orchestrator runs `lint` / `validate` / `inspect` after assembly
(Step 6) and re-dispatches you with any finding.
## Self-check
- `<template>`-wrapped `#stage`; `data-composition-id` == timeline key == filename stem ==
`<frame_id>`; all `<style>` / `<script>` inside `<template>`; uses the host's global `gsap`.
- One paused timeline, registered, ending in `tl.seek(0)`; `data-duration` == frame span length; silent.
- Each group shows across its frame-local span and hides outside it; `t=0` renders; group→group cuts are 0ms; ids / uniforms namespaced.
- Each group's text / palette match its block's `params` / `copy`, drawn from `frame.md`.
- `phrase_flow` frames pace by phrase / energy.
- Seek-safe per `hyperframes-core/determinism-rules.md` (derive variation from indices; swap text / numbers with `tl.set`).
- Asset clips: muted `<video>`, direct children of `#stage`, with `data-start` / `data-duration` / `data-track-index` and the crossfade hard-kill `tl.set`.
- Final frame is intentional; hero text is readable and clear of the edges.