refactor(skills): restructure product-launch-video into references + sub-agents#1597
Open
WaterrrForever wants to merge 18 commits into
Open
refactor(skills): restructure product-launch-video into references + sub-agents#1597WaterrrForever wants to merge 18 commits into
WaterrrForever wants to merge 18 commits into
Conversation
…-video Collapse the phase/style-preset-heavy product-launch-video skill into a leaner product-lunch-video layout (references + scripts + sub-agents), and extend the hyperframes core/creative/media skills with new format and preset references. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…unch-video Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| rmSync(td, { recursive: true, force: true }); | ||
| } catch {} | ||
| return r; | ||
| writeFileSync(storyboardPath, lines.join("\n")); |
| mkdirSync(dirname(outPath), { recursive: true }); | ||
| writeFileSync(outPath, html); | ||
| // ── write caption-overrides.json shim ── | ||
| if (!existsSync(overridesPath)) writeFileSync(overridesPath, "[]\n"); |
Extend the validation checklist and finalize gate to run `hyperframes inspect` and midpoint `snapshot`, and update the frame-worker self-check with template-transport and hero-visibility callouts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add biennale-yellow, blue-professional, bold-poster, broadside, cartesian, cobalt-grid, coral, creative-mode, daisy-days, and editorial-forest frame presets (FRAME.md + frame-showcase.html each), and list all 12 presets in the design-spec preset table with Look / Pick-when descriptions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reframe the skill's planning prompts around a shot model (entrance → development → settle) so frames choreograph across their full duration instead of animating in then freezing: - visual-design: "every frame is a directed shot"; require ≥3 effects sequenced into phases; add Reproduce / Adapt / Compose blueprint postures; phased composition notes by default - motion-language / story-design: shot model, phases, idle-life budget, both failure modes (slideshow / screensaver) on the negative list - SKILL.md: capture gate now requires visible-text.txt + asset-descriptions.md as the canonical asset inventory - frame-worker: align with the directed-shot brief Also fix transitions.mjs: stamp a full-span anchor so window.__timelines["main"].duration() equals the composition total — without it the Studio reads a short master duration and collapses its timeline (clips dropped, blank stage). Render engine was unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fetch-sfx passed no min_score to searchSounds, inheriting the HeyGen /v3/audio/sounds server default of 0.7. But good sound_effects matches score only ~0.52-0.67, so most named cues (click, pop, ding, sparkle, notification, impact, ...) silently returned 0 hits and were skipped — only whoosh/swoosh-family hits cleared 0.7. Floor the SFX search to 0.4 so authored cues resolve; BGM keeps the default (music scores high). Verified end-to-end: cues that previously dropped now download. Also refresh the searchSounds doc comment: data is a ranked array (not an object), query is required (>=1 char), limit caps at 50, and note the min_score gotcha. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Asset staging used to happen only inside assemble-index.mjs (Step 5), so during Step 4 the frame workers and the live preview referenced public/ files that weren't there yet. Extract the staging logic and run it earlier: - new lib/assets.mjs — shared stageAssets() (named-candidates only, first-wins, safe to call twice) - new stage-assets.mjs — runs at Step 4 close so workers + preview see real public/<basename> files - assemble-index.mjs drops its inline copy and calls the shared lib as an idempotent backstop for late-named assets Also condense SKILL.md (goal + gate per step; drop the example-phrasing and step tables) and tighten frame-worker's Reproduce / Adapt / Compose guidance. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- test-skills-fresh.sh: update the verification list to the current 10 workflows (drop removed footage-recut; add website-to-video, embedded-captions, graphic-overlays, slideshow) + refresh examples - captions.mjs: rank accent colors by chroma so the loudest hue maps to --cap-accent (e.g. biennale's solar sun over near-paper paper-deep) - biennale-yellow: add caption-skin.html (preset-local karaoke lower-third) and preview it in frame-showcase.html Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Frontmatter name was left as product-launch-video-refactor on this branch, so `skills add` registered/displayed the skill under that name — mismatching the directory, the /product-launch-video router references, and the test-skills-fresh.sh verification list. Rename back to product-launch-video. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…captions Give each hyperframes-creative frame-preset its own lower-third karaoke caption look (caption-skin.html) and preview it in each frame-showcase.html. Rework product-launch-video captions.mjs to load a project-local caption-skin.html and inject brand tokens derived from frame.md — colors mapped to a shared semantic vocab (--cap-ink/--cap-canvas/--cap-accent/ --cap-accent-2 by name + chroma), fonts to --font-display/--font-body, plus the keep-out band geometry — filling the skin's reserved holes and wrapping in a <template>. Falls back to the built-in pill when no skin is present. SKILL.md Step 2 now copies the chosen preset's caption-skin.html into the project so the look auto-applies; Step 5 documents the source. Presets: blockframe, blue-professional, bold-poster, broadside, capsule, cartesian, cobalt-grid, coral, creative-mode, daisy-days, editorial-forest (biennale-yellow landed earlier). Each skin uses the shared --cap-* vocab plus the preset's own border/shadow/corner/font/highlight identity. Also fix the ink-color resolver to match "ink" only as a whole word-segment so "pink"/"soft-pink" no longer resolve as the ink color. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…a preset onto brand tokens Add scripts/build-frame.mjs: the LLM only chooses a frame preset; the script copies its FRAME.md -> frame.md and remixes colors/typography onto the project's brand tokens (capture/extracted/tokens.json), copies the preset's caption-skin.html, and self-validates (exit 1 on a broken mapping). Colors map onto the preset's keys by role — ink/canvas by name+luminance, every other color repainted with the brand accent's hue+sat at its OWN lightness so tint families (sun/sun-soft/haze) stay families; fonts swap the preset's display + body families for the brand's. Empty brand tokens -> the preset palette is kept. Extract the shared color/font parsing + semantic role mapping into lib/tokens.mjs; captions.mjs now imports it, so frame.md and the captions derive tokens from one place and stay consistent. SKILL.md Step 2 is reduced to "pick a preset, run build-frame.mjs"; scripts list updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… general-video
Consolidate the triplicated audio pipeline into one engine in hyperframes-media
so workflows consume it instead of vendoring copies.
- engine: scripts/audio.mjs reads a neutral audio_request.json, writes id-keyed
audio_meta.json. Three capabilities degrade on ONE switch (HeyGen credential
present?): TTS HeyGen REST -> ElevenLabs -> Kokoro; BGM retrieve ->
Lyria/MusicGen generate; SFX retrieve (min_score 0.4) -> bundled 21-file
library. lib/{heygen,tts,bgm,sfx}.mjs; --only subset+merge; detached BGM via
wait-bgm.mjs; heygen-tts.mjs now wraps lib/tts.
- product-launch: scripts/audio.mjs is now a thin storyboard->request adapter
that maps the engine's meta back to the frame-keyed shape captions/assemble
consume; sync-durations kept; vendored lib/heygen.mjs moved into the engine.
- general-video: SKILL.md routes audio to the engine with a minimal request example.
- docs: media SKILL.md + references/{bgm,sfx}.md rewritten -- engine is the
single source, SFX bundled library is first-class, reference impl points here.
Not migrated yet: pr-to-video, faceless-explainer (still vendored).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rename the staging destination from public/ to assets/ consistently across the staging scripts (lib/assets.mjs, stage-assets.mjs, assemble-index.mjs) and the docs that reference the asset_candidates path form (SKILL.md, story-design, visual-design, frame-worker). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| total_duration_s: totalDuration, | ||
| }; | ||
| mkdirSync(dirname(outPath), { recursive: true }); | ||
| writeFileSync(outPath, JSON.stringify(meta, null, 2)); |
| total_duration_s: totalDuration, | ||
| }; | ||
| mkdirSync(dirname(outPath), { recursive: true }); | ||
| writeFileSync(outPath, JSON.stringify(meta, null, 2)); |
| const opts = { method, headers: { ...headers } }; | ||
| if (body !== undefined) { | ||
| opts.headers["Content-Type"] = "application/json"; | ||
| opts.body = JSON.stringify(body); |
| if (!res.ok) throw new Error(`download HTTP ${res.status}: ${String(url).slice(0, 80)}`); | ||
| const bytes = Buffer.from(await res.arrayBuffer()); | ||
| mkdirSync(dirname(destPath), { recursive: true }); | ||
| writeFileSync(destPath, bytes); |
| function transcodeToWav(bytes, destWav) { | ||
| const td = mkdtempSync(join(tmpdir(), "hf-tts-")); | ||
| const tmp = join(td, "a.mp3"); | ||
| writeFileSync(tmp, bytes); |
| if (!transcodeToWav(bytes, wavAbs)) return { ok: false, words: null }; | ||
| } else { | ||
| mkdirSync(dirname(wavAbs), { recursive: true }); | ||
| writeFileSync(wavAbs, bytes); |
Update build-frame.mjs / lib/tokens.mjs brand-token remix and captions.mjs accent handling, and align SKILL.md Step 2 with the script-driven design system. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the phases/ + agents/ tree (style-presets, prep/validate scripts, bundled sfx) with the references/ + sub-agents/ layout and the shared build-frame / assets / storyboard / tokens scripts, matching the product-launch-video architecture. Update SKILL.md and the retained scripts (ingest, fetch-pr, captions, audio, transitions) accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…itecture Replace the phases/ + agents/ tree (style-presets, prep/validate scripts, bundled sfx) with the references/ + sub-agents/ layout and the shared build-frame / assets / storyboard / tokens scripts, matching the product-launch-video architecture. Update SKILL.md and the retained scripts (captions, audio, transitions, assemble-index) accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the claude frame preset (FRAME.md, caption-skin.html, frame-showcase.html) and register it in references/design-spec.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ition preview A CSS identifier cannot start with a digit, so an authored rule like `#1-wall-pushes-back { ... }` is an invalid selector and the browser drops the whole rule — taking the root's size/background with it. A full composition masks this (the host stretches/paints the frame), but a standalone preview has no host, so the root collapses to height:0 + transparent and renders blank. extractFullDocumentParts now rewrites `#<digit-leading-id>` selectors to their escaped valid form (`#\30 1-...`, still matching the element id), scoped to ids actually present and matched only as `#id` not followed by an ident char so hex colors are never touched. Also harden the <template> inner-HTML extraction to use the DOM instead of a greedy regex. Tests added. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| // (broadside's literally says "<template>"), which the linter's tag scanner then picks | ||
| // up as the root element → false root_missing_composition_id / root_missing_dimensions. | ||
| // The comments are preview/authoring docs, not needed in the generated composition. | ||
| out = out.replace(/<!--[\s\S]*?-->/g, ""); |
| // (broadside's literally says "<template>"), which the linter's tag scanner then picks | ||
| // up as the root element → false root_missing_composition_id / root_missing_dimensions. | ||
| // The comments are preview/authoring docs, not needed in the generated composition. | ||
| out = out.replace(/<!--[\s\S]*?-->/g, ""); |
| // index.html's <head>, so tokens still resolve there too.) | ||
| html = html.replace(/[ \t]*<style data-brand-tokens>[\s\S]*?<\/style>\s*\n?/g, ""); | ||
| // ── write caption-overrides.json shim ── | ||
| if (!existsSync(overridesPath)) writeFileSync(overridesPath, "[]\n"); |
| `BGM: Lyria unavailable → installing local MusicGen fallback (${BGM_PY_DEPS.join(" ")})…`, | ||
| ); | ||
| const r = spawnSync("pip", ["install", "-q", ...BGM_PY_DEPS], { stdio: "ignore" }); | ||
| writeFileSync(storyboardPath, lines.join("\n")); |
| // (broadside's literally says "<template>"), which the linter's tag scanner then picks | ||
| // up as the root element → false root_missing_composition_id / root_missing_dimensions. | ||
| // The comments are preview/authoring docs, not needed in the generated composition. | ||
| out = out.replace(/<!--[\s\S]*?-->/g, ""); |
| // index.html's <head>, so tokens still resolve there too.) | ||
| html = html.replace(/[ \t]*<style data-brand-tokens>[\s\S]*?<\/style>\s*\n?/g, ""); | ||
| // ── write caption-overrides.json shim ── | ||
| if (!existsSync(overridesPath)) writeFileSync(overridesPath, "[]\n"); |
| const targetS = Math.max(1, totalS); | ||
| const seedS = Math.min(bgmSeedSeconds, 30); | ||
| const loops = targetS > seedS ? Math.ceil(targetS / seedS) : 1; | ||
| writeFileSync(storyboardPath, lines.join("\n")); |
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
Restructure the
product-launch-videoskill from a phase/style-preset-heavylayout into a leaner one (
references/+scripts/+sub-agents/), and extendthe shared
hyperframes-core/-creative/-mediaskills with the formats andpresets the new layout depends on.
Net: 349 files, +3,721 / −41,964 — mostly deleting the old
phases/,agents/,bundled SFX assets, and oversized scripts.
Why
The old skill carried a large, drift-prone surface: per-phase guides, design/motion
rules duplicated between the skill and the shared references, ~20 bundled SFX files,
and multi-thousand-line scripts (validate/verify/prep/hoist). Consolidating the
rules into shared references + a single frame-worker sub-agent removes the
duplication and shrinks the skill to what the orchestrator actually needs.
How
product-launch-videoskillphases/+agents/withreferences/(composition, motion-language,story-design, visual-design) and
sub-agents/frame-worker.md.helpers); drop validate/verify/prep/hoist and the bundled
assets/sfx/.Shared skills
hyperframes-core: addreferences/script-format.md+storyboard-format.md.hyperframes-creative: addreferences/design-spec.mdandframe-presets/(blockframe, capsule) with showcase HTML.
hyperframes-media: extend the bgm/sfx references.hyperframes/general-video: update routing copy.CLI
contentExtractor.ts: surface downloaded video clips first, tagged[video],sourced from
video-manifest.json— hero motion clips are the strongest productmaterial and downstream planners key off the
[video]marker.Test plan
bun run buildnpx hyperframes lint/npx hyperframes validateon a sample composition/product-launch-videoend-to-end on a sample product URL