Skip to content

feat(skill): webster-video — HyperFrames timelapse render pipeline#13

Merged
richsak merged 15 commits intodevfrom
feat/webster-video-skill
Apr 26, 2026
Merged

feat(skill): webster-video — HyperFrames timelapse render pipeline#13
richsak merged 15 commits intodevfrom
feat/webster-video-skill

Conversation

@richsak
Copy link
Copy Markdown
Owner

@richsak richsak commented Apr 26, 2026

Summary

Ships the webster-video skill: a HyperFrames-based render pipeline that turns the 11-week simulation council arc into a 130s timelapse with synchronized narration. Renders deterministically from committed substrate (demo-output/landing-page/wNN/).

What's in the PR

  • HyperFrames composition (video/): 7 sub-scenes (title-card, before-state, transformation, learning-beat, recovery-arc, final-state, end-card) plus master index.html sequencing them at 0/12/28/48/70/98/118s. Brand tokens + reusable component classes in video/shared.css. Council/metrics/brand JSON under video/data/.
  • Skill scripts (skills/webster-video/scripts/):
    • hydrate-demo-assets.ts — pulls demo-output/landing-page/wNN/ from sim outputs.
    • build-slot-packets.ts — generates 7 polish-slot packets for Claude Design handoff.
    • apply-polish-bundle.ts — integrates returned bundles back into the composition; hyperframes lint afterward.
    • mux-narration.ts — ffmpeg loudnorm -16 LUFS + bandpass 80–12k Hz, then stream-copy mux silent mp4 + leveled audio. No Auphonic API dependency.
  • Polish-slot bundle (skills/webster-video/polish-slots/): 7 slot directories × {baseline.html, baseline.css, baseline.png, slot.json, brand.tokens.json, acceptance.md, DO_NOT_TOUCH.md} + top-level PROMPT.md / README.md for the claude.ai/design system prompt.
  • Demo-asset substrate (demo-output/landing-page/w00..w10/): 11 weeks × {desktop/mobile/tablet PNGs, heatmap JSON+SVG, synthetic analytics, visual-review.md}. The video animates over these.
  • Tracking dir (context/webster-video/): CONTEXT.md (compaction-resistant) + STATUS.md (day-log of every render iteration).
  • README evidence section: under ## For judges, points at the simulation arc, the Managed Agents memory-store screenshot, and the reproduce command.
  • .gitignore: adds demo-output/videos/. Rendered mp4 is hosted externally rather than committed.

Reproduce locally

bun skills/webster-video/scripts/hydrate-demo-assets.ts
cd video && npx hyperframes render -q high --strict

Produces a silent 130s 1920×1080 30fps h264 mp4. ~58s wall with 6 parallel workers on the latest substrate.

Test plan

  • npx hyperframes lint — 0/0 across all 7 sub-compositions + master
  • npx hyperframes inspect — 0 layout issues across 9 timeline samples
  • npx hyperframes snapshot — 7 scene-midpoint frames render with correct content + brand styling
  • npx hyperframes render -q high --strict — clean 130s silent mp4 produced (3 iterations: draft → polish → paired-LP rebuild)
  • bash -n on mux-narration.ts flow — uses execFileSync (no shell-concat) per security hook
  • Polish round (in flight): upload polish-slots.zip (1.3 MB, gitignored) to claude.ai/design with PROMPT.md as system prompt; integrate returned bundles via apply-polish-bundle.ts
  • Narration mux (pending polish): record over silent render → audio/narration.raw.{wav,mp3,m4a}bun skills/webster-video/scripts/mux-narration.tsdemo-output/videos/webster-lp-demo.mp4
  • Host the muxed mp4 externally; add link to README + submission form

Out of scope

  • Production agents and the live council prompt are untouched — this is additive over the simulation substrate
  • No changes to agents/, prompts/second-wbs-session.md, or any production runner
  • Final video file is not committed (gitignored — see commit 9fe7163)

🤖 Generated with Claude Code

richsak and others added 12 commits April 26, 2026 06:02
CONTEXT.md is compaction-resistant (mission, locked decisions, critical
paths, current phase, don't-drift invariants, polish-slot index). Single
Read call restores alignment after autocompact or fresh session.
STATUS.md is the running tracker: phase, latest action, blockers, render
history, day log.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Day 0 of the webster-video skill plan. Copies weekly council-simulation
artifacts from local-runs/lp-council/w01-single-offer-visual-heatmap/
(simulation working copy) into demo-output/landing-page/wNN/ (committed
deliverable, the canonical handoff per T7/T9 task graph).

Per-week (w00-w10): desktop/mobile/tablet PNGs + matching heatmap SVGs +
analytics.json + heatmap.json + visual-review.md (w00 omits since it is
the pre-council baseline). Plus brand.json, agents.json, manifest.json
with hash + week list at the run root.

Also gitignores local-runs/ (now that the durable copy is in
demo-output/) and audio/*.raw.mp3 (only the Auphonic-leveled narration.mp3
is committed).

Unblocks remote planning surfaces (Ultraplan, fresh clones) which only
see committed files; the timelapse story now travels with the repo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Installed @heygen-com/hyperframes skill bundle (5 sub-skills: gsap,
hyperframes, hyperframes-cli, hyperframes-registry, website-to-hyperframes)
into .agents/skills/, symlinked into .claude/skills/ for Claude Code.

Ran hyperframes init video --example blank to scaffold the project root
with index.html (1920x1080 master composition, GSAP timeline registered on
window.__timelines["main"]), hyperframes.json config, and the bundled
AGENTS.md / CLAUDE.md guides.

Pre-flight verified: node v25.9.0, ffmpeg 8.0.1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Day 1 baseline of the webster-video skill plan. The structural draft
renders the full 130-second story end-to-end via HyperFrames sub-compositions,
with plain-but-working baselines that Claude Design will polish in Phase B.

Layout:
- video/index.html — master composition (1920x1080 at 130s) sequencing the 7
  sub-compositions via data-composition-src
- video/compositions/{title-card,before-state,transformation,learning-beat,
  recovery-arc,final-state,end-card}.html — one HyperFrames sub-composition
  per storyboard beat. Each has data-composition-id, scoped GSAP timeline
  registered on window.__timelines, and class="clip" elements with
  data-start/data-duration/data-track-index per the framework contract.
- video/shared.css — brand tokens (deep teal, warm cream, leaf green,
  charcoal, soft gold) + typography (Cormorant Garamond, Inter, IBM Plex
  Sans Condensed) + 5 reusable component classes (brand-title,
  synthetic-disclaimer, stat-counter, heatmap-overlay, council-ring) +
  scene primitives. Single source of truth for visual primitives;
  Claude Design will polish individual classes per the slot contract.
- video/data/{metrics,brand,council}.json — typed copies of the per-week CSV
  from prompts/video-composition-session.md, brand tokens from
  demo-output/landing-page/brand.json, and the 10-agent council roster.
- video/lib/{easings,trim-points}.js — shared GSAP easings and the 90s
  social-cut frame-range definitions for the trim-points polish slot.
- video/script.md — 130s narration with beat-by-beat visual cues, callouts,
  voice direction, and an honesty checklist tying every claim back to the
  synthetic-data invariant.
- video/assets — symlink to ../demo-output/landing-page so HyperFrames
  serves committed weekly artifacts via static paths.

Validation:
- npx hyperframes lint: 0 errors, 0 warnings across all 8 files
- npx hyperframes inspect: 0 layout issues across 9 timeline samples

Also gitignores the AI-platform symlinks installed by `skills add` (parallel
agent installs we don't use) and treats .agents/skills/ + .claude/skills/
like node_modules (re-installable via npx skills add heygen-com/hyperframes).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All 7 HyperFrames sub-compositions render with brand-aligned visuals:
0 lint errors, 0 layout issues, 7/7 scene snapshots passed visual check.
video/snapshots/ and video/renders/ added to .gitignore (regenerable).
Awaiting Richie's confirmation before Day 2 (audio chain, slot packets,
Claude Design polish, final render).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…choreography

shared.css: layered card shadows via --brand-shadow-card, tightened brand-title
letter-spacing, refined synthetic-disclaimer with left-edge teal accent + soft
drop shadow, stat-counter value depth via text-shadow + tabular-nums, thicker
callout-chip accent border.

7 scene timelines: mask-reveal entrances on title-card + end-card via
clipPath inset; overshoot-stagger callouts on before/transformation/learning/
recovery/final via back.out(1.4); scale-on-entry for w04 + w09; PASS chip
stamps with back.out(1.7). Counter ramp on transformation kept as the single
metric story arc.

No HTML structure changes — data-* attributes, .clip class, and
window.__timelines registration preserved per HyperFrames contract.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Silent render: demo-output/videos/webster-lp-demo.silent.mp4
130s · 1920x1080 · 30fps · h264 · ~10 MB · rendered with hyperframes
-q high --strict in ~58s wall with 6 parallel workers.

mux-narration.ts: replaces planned auphonic-process.ts with ffmpeg
loudnorm (-16 LUFS) + bandpass + AAC mux. Auto-detects audio/narration.raw.{wav,mp3,m4a}, levels to audio/narration.mp3, muxes
silent mp4 + leveled audio into demo-output/videos/webster-lp-demo.mp4.
--skip-level flag for users who pre-level externally (Auphonic).
Uses execFileSync (no shell concat) per security hook.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…come panel

Per user feedback after first silent render:
- Drop mobile screenshots; desktop only.
- Show full LP scrolling top-to-bottom over each scene's duration.
- Center the LP up top, place analytics + narrative below.
- Show week evolution by pairing last week | current week.
- Pinpoint what data said and how the council decided to react.

shared.css rev 2: drop screenshot-card, week-chip, callout-chip, heatmap-*,
council-ring*, stat-counter*. Add lp-pair-stage / lp-week-block / lp-week-label
(+ chip current/dim/final variants) / lp-card (860x600, overflow hidden) /
lp-card--dim (saturate 0.5 brightness 0.94) / lp-image (absolute, GSAP
translateY for scroll). Add narrative-panel / narrative-col (+ decision/
outcome variants) / narrative-eyebrow / narrative-body / narrative-stat
(+ --small variant for two-value displays) / narrative-stat__delta.

Pair scheme:
- before-state w00 solo (baseline narrative)
- transformation w01 | w02 (council's first transformation)
- learning-beat w03 | w04 (experiment + correction)
- recovery-arc w08 dim | w09 (failure + recovery)
- final-state w00 dim | w10 (full-arc bookend recap)

Scroll distances hardcoded per week from native 1440-wide screenshot heights:
526 / 2162 / 3362 / 3414 / 3727 / 3671 / 3599 / 3587 px. Linear ease across
scene minus 2s entry buffer. w00 short height creates intentional slow scroll
versus dense w10 fast scroll — visual story of "the page grew rich over 11
weeks". Counter ramps preserved on transformation (151→343) and final-state
(151→323).

title-card and end-card unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Single-shot polish workflow: prepare 7 self-contained slot packets,
upload as zip to claude.ai/design, receive polished bundles, integrate
back via apply-polish-bundle.ts.

build-slot-packets.ts: generates skills/webster-video/polish-slots/<slot>/
for each of the 7 scenes (title-card, before-state, transformation,
learning-beat, recovery-arc, final-state, end-card). Per slot:
  - slot.json (master frame range + fps/dimensions)
  - brand.tokens.json (palette, typography, motion, honesty constraints,
    HyperFrames contract reminder)
  - baseline.html (current scene)
  - baseline.css (full shared.css for context)
  - baseline.png (mid-scene snapshot from video/snapshots/)
  - acceptance.md (measurable "done" criteria + visual goals + "what can
    change")
  - DO_NOT_TOUCH.md (locked text, numbers, durations, scroll distances,
    honesty framing, HyperFrames contract)
Plus polish-slots/README.md (operator workflow) and PROMPT.md (system
prompt to paste into claude.ai/design).

apply-polish-bundle.ts: reads polish-slots/<slot>/handoff/*.html (full
replacement) and optional handoff-shared/shared.css. Runs hyperframes
lint after, prints next steps. Does not auto-commit — review via
git diff. Uses execFileSync (no shell concat) per security hook.

.gitignore: added skills/webster-video/polish-slots/**/handoff/ and
handoff-shared/ and polish-slots.zip. Baseline slot files are committed;
polished handoff bundles stay local until reviewed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s ceiling

User pivot: rather than locking text, durations, honesty framing, and
HyperFrames-contract per scene, give Claude Design full autonomy with one
absolute constraint — total video ≤ 2.5 min (150s).

Changes:
- PROMPT.md rewritten as a free-form brief. Layout, scene count, scene
  durations, copy, typography, motion language, color treatment — all
  up to Claude Design.
- README.md slimmed to match.
- 14 per-slot constraint files removed (acceptance.md + DO_NOT_TOUCH.md
  for each of 7 slots).
- brand.tokens.json stripped: palette + typography + motion easings +
  card shadow only. No voice / design_direction / constraints / honesty
  framing / HyperFrames-contract reminder text.
- slot.json field rename: master_*_seconds → current_master_*_seconds
  (signals these are starting context, not specs).
- build-slot-packets.ts: added cleanStaleFiles() so future regenerations
  remove acceptance.md / DO_NOT_TOUCH.md if reintroduced. Script body
  shrank from 518 lines to ~200.
- polish-slots.zip regenerated (1.3 MB).

Net: -1303 / +150 lines. Bundle is now consistently free.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
No semantic changes — prettier expanded multi-line template literals in
build-slot-packets.ts and trimmed trailing whitespace in STATUS.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…d mp4

Adds a "Demo arc artifacts" line under README "## For judges" pointing at the
11-week simulation council deliverables under demo-output/landing-page/, the
Managed Agents memory-store screenshot, and the local reproduce command.

Adds demo-output/videos/ to .gitignore. The rendered timelapse mp4 is hosted
externally for the hackathon submission rather than committed (avoids 70+ MB
binary in git history; the rendering pipeline + committed substrate already
proves reproducibility).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 26, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • main
  • review/empty-base

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0d20e502-8514-4d29-a856-fce0dbc040ed

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/webster-video-skill

Comment @coderabbitai help to get the list of available commands and usage tips.

richsak added 3 commits April 26, 2026 16:50
- video/lib/easings.js, trim-points.js: add /* global window */
  (flat-config replacement for the deprecated /* eslint-env browser */).
- skills/webster-video/scripts/hydrate-demo-assets.ts: convert two
  type-alias decls to interface form to satisfy
  @typescript-eslint/consistent-type-definitions.

Closes the 6 lint errors blocking PR #13's CI.
- .markdownlint-cli2.jsonc: add demo-output/ and video/assets/ to
  ignores. Both contain auto-generated visual-review.md files (same
  category as history/, already ignored).
- Auto-fix MD031/MD032/MD026/MD034 in video/AGENTS.md, video/CLAUDE.md,
  skills/webster-video/polish-slots/PROMPT.md.
- Add explicit language tag (`text` / `bash`) to two unfenced code
  blocks in video/CLAUDE.md and skills/webster-video/polish-slots/README.md
  to satisfy MD040.

Closes the 27 markdown lint errors blocking PR #13's CI.
The Playwright screenshot test was timing out at bun:test's default 5s.
First Chromium launch in clean CI is 5–10s. The sibling test in
run-simulation.test.ts that exercises the same code path took 4.9s
on this run. Bumping to 30s gives margin without slowing happy-path.
@richsak richsak merged commit aa9e0b0 into dev Apr 26, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant