mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 12:54:29 +00:00
v0.6.63
30
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3542a79b3a |
fix(skill): reconcile SFX drift tolerance to ±0.1s across script + prose
Vai (vanceingalls) caught a 10× tolerance mismatch between the script and the prose. Rames confirmed as blocking: step-5-build.md:458 (per-beat evidence rule): ±0.05s step-6-validate.md (playback verification): ±0.1s w2h-verify.mjs:29 (SFX_DRIFT_TOLERANCE_S): 0.5s So an agent writing per-beat evidence at ±0.05s reports a 0.3s drift as FAIL, while the script reports the same drift as PASS. The pasted- verbatim report contradicts the agent's evidence block — exactly the kind of internal contradiction this PR was built to eliminate. Converged on ±0.1s everywhere: - w2h-verify.mjs:29: SFX_DRIFT_TOLERANCE_S = 0.1 (3 frames at 30fps) - step-5-build.md:458: ±0.05s → ±0.1s, with cross-reference noting it matches the script + step-6 playback floor The other ±0.5s constants in step-6 are for total audio/video duration and storyboard beat-range matching — those are coarser-grained timing checks (not SFX-to-visual sync). Left as-is intentionally. Regression check: huly-v3 now flags 4 SFX drifts instead of 3 — the new one is glitch-1.mp3 at 0.20s drift (6 frames). The old 0.5s tolerance was masking this real timing issue. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
a5bc11632f |
fix(skill): address PR #1026 review — find $HOME, order-indep audioRegex, cached reads
Three issues from Miguel's + Rames's reviews:
**[Blocking] find / violates CLAUDE.md guidance (Miguel)**
CLAUDE.md says: "When running find, search from . (or a specific path),
not / — scanning the full filesystem can exhaust system resources on
large trees." I introduced 3 instances of `find /` in skill prose to
help sub-agents locate skill files from unknown CWDs. Replaced all 3
with `find "$HOME" ... -maxdepth 10`. Verified all 4 skill files
resolve correctly under $HOME on the testbed setup.
Files: step-3-storyboard.md (×2), step-5-build.md, step-6-validate.md.
**[Blocking] SFX audio regex assumed attribute ordering (Miguel + Rames)**
The v2 audioRegex required src= to appear lexically BEFORE data-start=
in the same <audio> tag. But capabilities.md:365 — in the same skill —
documents the canonical pattern with src= LAST:
<audio id="..." data-start="..." data-duration="..." data-volume="..."
data-track-index="..." src="...">
Real compositions following the docs would have audio tags that don't
match the regex → SFX reported as MISSING → false FAIL in the script
output → false alarm in the user-facing summary. Exactly what v2 was
supposed to fix.
Replaced with the same two-step shape that readBeatDurationsFromIndex
already uses correctly: match `<audio[^>]*?>` to grab the whole tag,
then extract src= and data-start= from the tag string with independent
regexes. Verified both attribute orderings (src first, src last) now
work via inline node test.
**[Minor] readBeatCompositions / readBeatDurationsFromIndex re-read on
every call (Rames)**
Added process-scoped caches to both helpers. The script is a one-shot
CLI so no invalidation needed — first call hits disk, subsequent calls
return the cached result. readBeatCompositions was called 3×,
readBeatDurationsFromIndex 2× — now 1× each.
**Regression checks**
- huly-v3: 4 PASS · 3 FAIL · 1 INFO (unchanged — same 3 real issues
flagged: 48px wordmark, missing shaders, 3 SFX drifts)
- huly-launch-v4: 6 PASS · 0 FAIL · 2 INFO (unchanged)
- Lint + format: clean
2 files changed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
f4a7961bc1 |
fix(skill): w2h-verify v2 — kill false positives from real-agent debrief
A fresh agent session ran the v1 verify script and the disclosure pasted
into their final summary showed 3 FAIL rows for things that weren't
actually defects:
Headline font-size: flagged Beat 2 (wordmark SVG), Beat 3 (UI grid),
Beat 5 (terminal). None of these legitimately have text headlines.
Timeline coverage: flagged 5/6 beats because the script's regex only
saw `tl.X(..., 2.5)` literal positions and missed forEach loops,
variable-position tweens, and long-duration scaler tweens.
Beat durations: flagged 2 beats because my "duration X.Xs near beat
label" fallback false-matched non-beat durations
(e.g., "shader runs — duration 0.7s" near a "Beat 1" mention).
The agent had to write ~5 paragraphs defensively justifying each false
FAIL. That's friction we can fix.
Tested against the agent's actual project (huly-launch-v4): went from
4 FAIL (3 false positives + 1 real bare-table parser miss) to 0 FAIL.
Also re-verified huly-v3 still correctly catches its 3 real issues
(48px wordmark, missing shaders, 3 SFX drifts) — no regression.
**Brand visuals check**
Switched from "≥30% asset usage" (gameable, rewards quantity over quality)
to "at least 1 beat references a captured hero/image/svg" — quality
signal that's cheap to satisfy when real, hard to fake. Excludes fonts,
logos, favicons, contact-sheets.
**Headline check**
Now only flags beats where the LARGEST font-size is in the 40–<80px
range — the "aspiring headline but too small" zone. Below 40px = beat
has no text headline by design (terminal, UI labels, SVG-only); skip.
≥80px = proper headline; pass. Eliminates the false positives on
SVG-dominated and UI-grid beats while still catching the real "headline
too small" failure (Beat 4 at 72px in this run; Beat 1 wordmark at 48px
in another).
**Timeline coverage check**
Three improvements:
1. Detects forEach loops + for-loops containing tl.X() calls — beats
with these have events at positions the static parser can't read;
mark as INFO-skipped rather than failed.
2. Detects long-duration tweens — if a single tween's duration covers
≥70% of the beat duration (camera dolly, breathing animation), the
beat has full coverage via persistent motion; skip the position check.
3. New paren-balanced parser for extracting tl.X() position arguments —
the v1 regex was matching `rgba(86,131,218,0.35)` and capturing 0.35
as a tween position. The new parser walks paren depth and only
captures top-level trailing numeric args. No more rgba false matches.
**Shader transitions check**
Two fixes:
1. Filter out inventory lines — lines listing 3+ shader names are
"what's available," not "what's planned for use." Real use
mentions one or two shaders per line.
2. Apply the same SFX-context exclusion to the declared side that the
present-check side already had — "glitch" inside `sfx/glitch-1.mp3`
no longer counts as a declared shader transition.
For huly-v3: was 6 declared (1 phantom from inventory + 5 + glitch
from SFX), now 2 declared (light-leak, cinematic-zoom) — matches the
storyboard's actual plan.
**Beat duration check**
1. Dropped the "duration X.Xs within 200 chars of beat label" fallback
— too loose; matched shader durations, animation durations, anything
labeled "duration". This was the source of the 0.70s misread in the
debrief.
2. Added a bare-number timing-table parser for the format
`| 1 | 0.00s | 5.20s | 5.20s | ... |` (with optional `>` blockquote
prefix). Computes duration = end - start.
3. Added a negative lookahead so `\bB3\b` doesn't false-match "B3.1"
sub-beats and grab the wrong row.
4. Filter buildBeatIds to only numbered beats — skips the root
composition (`data-composition-id="main"`) so it doesn't inflate
"parseable" count.
**Brand visuals + asset count**
Excluded fonts/ subdirectory (always-used via @font-face → would
always pass) and contact-sheet-*.jpg (pipeline outputs, not website
inputs). Both inflated the denominator and weakened the signal.
**Edge case fixes**
- Removed `basename` unused import (oxlint).
- Fixed shader-name substring overlap: longest-name-first matching so
"cross-warp-morph" doesn't double-count as "cross-warp".
- SFX timestamps now collect ALL audio tags per file (multi-timestamp
SFX like click×3); picks closest index timestamp to each storyboard
timestamp instead of just keeping the last.
**Step 6 doc**
Updated the skill's "w2h-verify — the source of truth" section to
describe the new checks accurately and what failure mode each catches.
2 files changed, +486/-109. Format + lint clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
190f1ec71a |
feat(skill): w2h-verify script + Step 6 DoD wiring — tooling-based enforcement
Three rounds of text-based enforcement plateaued. A third agent debrief showed the same failures: 9% asset usage (vs ≥30% floor), shader transitions declared in STORYBOARD.md but not in shipping index.html, SFX timestamps drifted up to 12.4s, animation-map skipped, MP4 not rendered, honest-disclosure section omitted from final summary. The pattern is clear: language-only enforcement is selectively interpretable by the agent under ship pressure. Move enforcement into tooling — facts the agent can't fudge. **New script: `skills/website-to-hyperframes/scripts/w2h-verify.mjs`** Pure file-analysis script (no shell spawns). Computes six checks and prints a PASS/FAIL/INFO table: 1. Asset usage — assets referenced in compositions ÷ assets captured; target ≥30%. Tested against videos/huly-v3: caught 6/74 = 8% FAIL. 2. Shader transitions consistency — STORYBOARD.md-declared shaders vs index.html. Longest-name matching to avoid substring false positives (cross-warp-morph not double-counted as cross-warp). Tested: caught 6 declared / 1 present / 5 missing. 3. SFX timestamp drift — parses STORYBOARD.md table rows for `sfx/X.mp3` + time-with-`s`, parses index.html <audio data-start>, flags drift >0.5s. Tested: caught 12.4s drift on click.mp3 that the agent debrief didn't even mention. 4. animation-map.json existence — explicit file check. 5. Rendered MP4 existence — scans project root, output/, renders/. 6. Required artifacts — STORYBOARD.md, DESIGN.md, SCRIPT.md, index.html all present. Exit code: 0 (all pass) or 1 (one or more fail). The script's output becomes the Step 6 deliverable — paste verbatim into the user-facing summary. **Skill update: `step-6-validate.md`** Adds `w2h-verify report` to the DoD checklist with the rule: paste the FULL output verbatim into the final summary. Cherry-picking rows, substituting adjectives for percentages, or omitting FAIL lines is explicitly forbidden. If a row says FAIL, either fix it and re-run until PASS or include the FAIL line verbatim in "What I did NOT verify" with a one-sentence reason. Test run against the project that prompted this: ``` SUMMARY: 1 PASS · 4 FAIL · 1 INFO - Asset usage: FAIL 6/74 (8%) target ≥30% - Shader transitions: FAIL 6 declared, 1 present, 5 missing - SFX timestamps: FAIL 3 drifted >0.5s (max 12.4s) - animation-map.json: FAIL missing - Rendered MP4: INFO no .mp4 found - Required artifacts: PASS ``` The agent could selectively ignore "the WCAG warnings are false positives." The agent cannot selectively ignore a line that says `6/74 (8%) — target ≥30%`. 2 files changed (+ 1 new script, ~330 lines). Format checks pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
5594a8286c |
fix(skill): w2h enforcement round 2 — close the deeper shirking patterns
A second agent debrief (different session, with the prior enforcement edits
applied) revealed the most damning failure yet: the agent used 1 of 65
captured assets. They wrote their own "Asset Audit" table saying SKIP for
64 hero illustrations, brand SVGs, and signature visuals. The entire point
of capture is to USE the brand's assets — that gate was bypassed entirely.
The debrief also revealed 5 other patterns the prior enforcement missed.
This commit closes all 6.
**Pattern A — Asset Audit gate (step-3-storyboard.md)** — BIGGEST FIX
Adds a non-skippable Asset Audit section in Step 3 that requires viewing
every page of capture/assets/contact-sheet-*.jpg + svgs/contact-sheet-*.jpg,
pasting 5 distinctive assets per page (with descriptions of what's actually
pictured), and choosing USE/SKIP per asset with one-sentence justification
for each SKIP. Brand-defaults floor: at least one beat MUST use a captured
hero illustration/photograph/signature diagram — not just the logo. The
forbidden list explicitly calls out: reading asset-descriptions.md alone
without opening the contact sheets, and rebuilding signature graphics in
CSS when the brand's own SVG of that graphic is in capture/assets/.
**Pattern B — Auto mode scope (SKILL.md + step-2-brief.md)**
Clarifies that auto mode covers user-PREFERENCE gates (TTS provider,
voice, beat count, captions yes/no — where the agent decides on the
user's behalf) but NOT quality-VERIFICATION gates (Asset Audit, per-beat
HTML read, DoD checklist, honest disclosure). Adds explicit test for
distinguishing: if the answer changes the content of the video, it's a
preference; if the answer is "did the verification happen?", it's a
quality gate. The agent that skipped the captions question by reasoning
"auto mode says bias toward action" was misusing auto mode.
**Pattern C — 3-path audio/motion verification (step-6-validate.md)**
Replaces the prior "Path 1 or explicit deferred" with three explicit
paths: (1) Play preview in Playwright, (2) render low-res MP4 and read
frames at ≥5fps, or (3) explicit deferred disclosure with QUANTIFIED
coverage gap ("18/900 frames = 2% coverage"). The percentage in Path 3 is
mandatory — vague "deferred to user" was the loophole. Forbidden: claiming
"confirmed via snapshot" as audio/motion evidence; 18 PNGs from a 900-
frame video is 2% coverage, not verification.
**Pattern D — Sub-agent diagnoses are hypotheses (beat-builder-guide.md)**
When a sub-agent reports "this is a linter false positive" / "this is a
known bug", that is a HYPOTHESIS from one symptom — not a verified
finding. Before propagating the workaround to other beats, main agent
must EITHER read the source to confirm OR explicitly disclose the
unverified claim. The debrief showed the main agent applied beat-2's
"linter false positive" diagnosis to beat-4 without ever reading
packages/core/src/lint/utils.ts to confirm.
**Pattern E — Re-snapshot after parallel sub-agents (step-5-build.md)**
When sub-agents run in parallel, each snapshots a project where sibling
beats may not exist yet. Their snapshots at beat boundaries or during
shader transitions show the WRONG content (typically previous beat).
Required after all complete: a canonical project-wide snapshot via the
CLI — that's what Step 6's DoD uses. Sub-agents' intermediate snapshots
are sanity checks, not the deliverable.
**Pattern F — STORYBOARD.md must be updated when divergence accepted
(beat-builder-guide.md)**
When a sub-agent diverges from spec ("the real brand mark is lowercase
'huly' not uppercase 'HULY'") AND the main agent accepts the divergence,
the main agent MUST patch STORYBOARD.md to reflect reality. Otherwise
the spec lies and the next session reading it as ground truth gets the
wrong information. Examples covered: brand mark casing, cell size at
scale, SFX timing alignment.
6 files changed, +131/-11 (net +120 lines of enforcement).
Format checks pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
18444decde |
fix(skill): w2h enforcement edits — close the 9 shirking patterns from agent debrief
After the audit-fix commit (
|
||
|
|
e47bc6c6db |
fix(skill): w2h audit — resolve contradictions, path issues, missing fallbacks
10 fixes from an audit of skills/website-to-hyperframes/ targeting clarity for AI agents following the pipeline. Each fix is a surgical edit; no behavior changes for human readers. **Critical contradictions resolved:** - capabilities.md: `onUpdate`/`tl.call` was simultaneously documented as required (canvas/WebGL/typing patterns) and banned (determinism). Sub-agents reading the ban would silently strip working code from Canvas 2D and Three.js beats. - step-1-design.md: Removed "Depth & Elevation" section template that the same file's Rules section forbade. Renumbered remaining sections (6→5). - beat-builder-guide.md: Narrowed "no onUpdate for counters" rule so canvas rendering loops aren't caught by the prohibition. **Path resolution fixes for sub-agents:** Sub-agents run from `<project-dir>` (e.g. videos/foo/), not repo root, so repo-relative paths like `skills/website-to-hyperframes/assets/sfx/manifest.json` fail silently. Replaced with `find / -path ...` patterns that work from any CWD. - step-3-storyboard.md: sfx/manifest.json + text-effects.md paths - step-5-build.md: beat-builder-guide.md path **Missing fallbacks added:** - step-3-storyboard.md Gate: autonomous mode now propagates from Step 2 — gate no longer blocks on explicit approval when user said "surprise me". - step-4-vo.md: timing-formula recalibration now has concrete steps for both "too short" (add pauses) and "too long" (cut highest-density beat). - step-6-validate.md: agent-authored descriptions fallback when GEMINI_API_KEY is unavailable — DoD checklist no longer has a dead end. **Quick Reference polish:** - SKILL.md: step-1-design entry now mentions 50-line fast-path exception. 8 files changed, +32/-37 (net -5 lines). Format checks pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
0253c2ccc8 |
fix(skill)!: reference pixel-point/animate-text — stop vendoring
Per James and Miguel's review feedback:
James: "you can only reference the skill or recreate things"
Miguel: "I'd just reference the skill without trying to copy
everything"
James: "we can't vendor their artifacts in our own repo"
The 48 vendored text-effects JSON files were direct copies from
pixel-point/animate-text (verified: typewriter.json matches the
upstream byte-for-byte at duration_ms: 240, stagger_ms: 46,
easing: steps(1, end)). That repo has no LICENSE file, so the
files default to "all rights reserved" — Apache 2.0 redistribution
in our repo is a compliance violation.
The earlier "rewrite from scratch" attempt produced JSON that
didn't render correctly (7 of 24 effects broke when I built a demo
HTML to validate them). Rather than keep iterating on a rewrite
that doesn't match the upstream's calibration, this commit drops
the vendored files entirely and updates skill prose to REFERENCE
the upstream skill instead.
### Changes
- Delete `skills/hyperframes/assets/text-effects/` (48 JSON files
+ the dual-directory structure, 8451 lines).
- Rewrite `skills/hyperframes/references/text-effects.md` as a
reference page that:
- Names pixel-point/animate-text as the source of truth
- Explains why we don't ship the catalog (licensing gap)
- Tells sub-agents to load `/animate-text` via Claude Code skill
invocation or `npx skills add pixel-point/animate-text`
- Lists the 24 effect IDs by category as vocabulary (so agents
can name effects in STORYBOARD.md before loading the upstream)
- Documents the fallback path: implement from name + GSAP
knowledge if the upstream skill isn't available
- Update 5 cross-references to reframe the catalog as upstream-
referenced instead of repo-bundled:
- skills/hyperframes/references/techniques.md (TOC pointer)
- skills/hyperframes/references/beat-direction.md (text-anim
guidance bullet)
- skills/website-to-hyperframes/references/capabilities.md
(registry-overview entry)
- skills/website-to-hyperframes/references/step-3-storyboard.md
(storyboard template + Text Animations section format)
- skills/website-to-hyperframes/references/beat-builder-guide.md
(references table row)
### What sub-agents see
Before: read `text-effects.md` → see 24 named effects → read each
spec from in-repo `assets/text-effects/effects/<id>.json`.
After: read `text-effects.md` → see 24 named IDs and a load
instruction → invoke `/animate-text` (or `npx skills add
pixel-point/animate-text`) → read each spec from
`.agents/skills/animate-text/assets/effects/<id>.json` (the
upstream's own files, not vendored copies).
End-user UX cost: one extra `npx skills add` for projects that
want the deterministic catalog. Or accept the fallback where
sub-agents implement from effect name + GSAP knowledge — works
fine for simple effects, less ideal for the 3 layout-aware ones
(kinetic-center-build, short-slide-right, short-slide-down).
Net diff on #991: -8488 lines.
|
||
|
|
24aef5475c |
fix(skill): eval feedback — font src paths, WCAG pairings, flash-through-white regression
Five fixes from Ular's first-pass workflow run: 1. step-1-design.md Fonts section — sub-agents pointed @font-face for "ES Build Neutral" at the Inter .woff2 files because DESIGN.md only named families, never emitted exact src: paths. Now the Fonts section example shows per-family + per-weight file paths AND a copy-verbatim @font-face block sub-agents can paste, so there's no inference step. Adds an explicit narrative of the real failure mode and how to avoid it. 2. beat-builder-guide.md FONTS rule — was "brand fonts with capture/assets/fonts/ path need @font-face in <style>." Now: "copy the @font-face block VERBATIM from DESIGN.md. Do NOT guess which .woff2 file belongs to which family — capture filenames are content-hashed and there is no visible mapping. If DESIGN.md doesn't include exact src: paths per family, STOP and ask the main agent; never pair an arbitrary .woff2 with a family name from memory." 3. step-1-design.md Colors section — Sub-agents reproduced brand colors faithfully and hit WCAG AA failures on dark surfaces (#68686A on #18191B = 3.16:1). Now the Colors section example computes per-pairing contrast ratios with ✅/⚠/❌ markers, documents the dark-surface substitute color when the brand's own palette fails, and points at the /hyperframes-contrast skill for ratio computation. Sub-agents pick text colors by surface context, not by "this is the brand's secondary text color." 4. capabilities.md flash-through-white entry — the "ideal as invisible bridge at duration: 0.01" framing caused agents to scatter white flashes through every composition as transition bridges. The fix was documented in the branch's HANDOFF but never landed. Now: "Fade through white midpoint — a visible white flash between scenes. Use only when the brand specifically calls for a white-flash beat boundary; this is NOT a neutral 'default' transition." 5. step-6-validate.md Warnings list — adds a paragraph on WCAG contrast false positives. The validator samples at fixed timestamps; elements at opacity:0 / mid-fade get measured as if fully visible, producing spurious failures. Tells the agent to verify visually before changing colors to clear a WCAG warning — bumping a color to fix a sampling artifact changes brand identity for no real benefit. |
||
|
|
e5160b6022 |
chore(skill): brand-floor → brand-defaults; captured-asset-primary is normal
Second-batch audit cleanup after Ular's "logo isn't a requirement, just a nice default" correction. Three related places still framed captured-asset-primary beats as rare exceptions and the brand-floor rules as hard MUSTs — both overstatements that contradict the rest of the dial-back. Plus a TOC-only callout on capabilities.md. - step-3:300 "for the RARE beat where a captured asset is the primary visual ... defaulted to the slideshow pattern this workflow exists to break" — rewritten. Captured-asset-primary beats are a normal valid choice. The narrow no-go is just pasting product-UI screenshots full-bleed. - step-3:351 "Each one has a composed visual that carries it" — rewritten to "Each one has a primary visual that carries it (composed UI, captured asset, kinetic typography, WebGL, etc.)". - step-3:353 "assets decorate concept-defined beats; they do not seed them" — kept "do not seed" (correct: don't write a beat because of a cool asset); dropped the "decorate" framing (overgeneralized — assets can be primary too). - step-3 brand-inflection floor section: relabeled from "REQUIRED minimums" to "Brand defaults (nice-to-haves for most brand videos)". "MUST appear" softened to "for most brand videos, the logo lands in the opener and the closer" with explicit "skippable when the storyboard's concept calls for it" language. - step-3:379 "The bar:" bullet: "brand-floor minimums ... the minimum, not the ceiling" → "brand-defaults section covers most brand videos but isn't a hard requirement." - step-5:413 "Brand-floor check" section in the per-beat read protocol: relabeled "Brand-defaults check", reframed each item as a default not a fail-condition; agent checks against the storyboard's intent rather than enforcing a hard rule. - capabilities.md top: added a "Scan the TOC; do NOT read this file linearly" callout — it's a 700+ line inventory; agents should jump to the section a beat needs, not read top-to-bottom. |
||
|
|
d31ef3f15b |
chore(skill): audit cleanup — captured assets are first-class primaries
Three follow-ups caught by a post-restructure audit pass. All three were places where the earlier "compose primary, asset is accent" framing survived after the step-3 and step-5 paragraphs already got the primitive-toolkit rewrite. Cleans up the contradiction so the skill speaks with one voice: captured assets can be primary content; the narrow no-go is just pasting product-UI screenshots. - step-2-brief.md:80 — the "flip it" example said agents should reframe "the hero illustration centers the opener" into "kinetic typography ... hero illustration as ambient depth." That reverses the dial-back: captured illustrations CAN center an opener. The flip-it rule now applies narrowly to product-UI screenshots; for captured logos/illustrations/hero art, no flip is needed. - step-2-brief.md:149 — option-template guidance said "primary content is 'the screenshot of X'" was forbidden. Narrowed to "primary content is a pasted product-UI screenshot." Other captured assets (SVG logos, illustrations, hero art) are valid primaries when the concept calls for them. - step-3-storyboard.md:314 — Common-accent-uses bullet implied accents are always layered on "composed UI." Reframed: list accent uses for when the primary is something else; when the captured asset IS the primary (logo opener, hero parallax), document it under Composition, not Accents. |
||
|
|
eed6dfb2f2 |
refactor(skill): primitive-toolkit framing across step-1, step-3, step-5
Cleans up two related overcorrections that crept across the skill
prose: (a) "compose UIs from divs/SVG/CSS" repeated 6+ times in
step-1, anchoring agents to website-shaped beats; (b) "every beat's
primary visual stays composed from divs / SVG / CSS / GSAP" and
"captured assets are accents — they decorate, they don't carry"
overstatements in step-3 and step-5 that contradicted the dial-back
done earlier in this stack.
The real framing: a beat composes from whatever primitives the scene
needs — HTML/CSS, SVG, captured assets, WebGL, Canvas, Three.js,
kinetic typography, Lottie — alone or in combination. They're inputs
to one output (the video frame). No rule maps intent → primitive.
The narrow no-go is one rule: never paste a product-UI screenshot as
load-bearing content (the slideshow pattern).
step-1-design.md (8 edits):
- L5 intro: drop "composed from divs/SVG/CSS at build time" detail.
- L7 length: drop "compose UIs from scratch (divs/SVG/CSS)" framing;
merge L290's "over-investing in prose" caveat in.
- L97: "composing UIs from divs in Step 5" → "building beats".
- L161: "compose the X UI" → "a beat featuring the X".
- L290: duplicate length bullet — deleted.
- L293: "sub-agents compose UIs at build time from divs/SVG/CSS..."
→ "No separate Components section — Quick Reference is where
components live."
step-3-storyboard.md (3 edits):
- L3 (intro): "alongside composed UIs" → "alongside composed beats".
- L276 ("Compose the load-bearing visuals yourself") paragraph
replaced with the primitive-toolkit framing — toolkit is open, the
only no-go is product-UI screenshots as load-bearing content.
- L381–383 ("The bar:") three bullets collapsed to one bullet:
primary visuals use whatever combination the scene needs; accents
are optional; brand-floor minimums are the minimum.
step-5-build.md (2 edits):
- L104 stacked-beats intro: "composed from divs, SVG, canvas, and
CSS. Never a full-bleed screenshot." → "composes from whatever
primitives the storyboard called for ... Narrow no-go: never a
full-bleed product-UI screenshot as load-bearing content."
- L147: "Build the UI element from divs and CSS" → "Build the
element from divs and CSS" — drops the UI bias since this rule
applies only when the asset IS a product-UI screenshot.
Net result: "compose from divs/SVG/CSS" mentions drop from 10+ to 0
as a generalized framing; the term survives only in concrete
examples (e.g. "cards-as-divs" when the beat is specifically a
kanban demo) where divs/CSS IS the right answer.
|
||
|
|
7f6bceb473 |
refactor(skill): step-0 owns capture, not analysis
Step 0 had bloated to 91 lines that did the work of Steps 1–3: viewing contact sheets cell-by-cell, reading 8 data files, listing promising assets, inferring product purpose / audience / value prop / brand voice. That meant the agent did all the heavy lifting upfront, produced summaries that went stale before they were used, and the actual "run the capture" instruction was buried. Step 0 now owns only what Step 0 is: run the capture command, sanity-check it succeeded, hand off. 91 → 55 lines. Moved (composed into destination files, verified each was the right home before adding): - Read tokens.json + design-styles.json → step-1-design.md replaces the passive "you read these in Step 0" line with an active "Read these now — primary data source for Sections 3–6." - Contact-sheet "every cell, name 5 assets per page" anti-glance prose → step-3-storyboard.md asset-discovery bullet (which already covered contact-sheet viewing generally, now strengthened with the anti-glance rule). - Strategic site summary (product / audience / voice / value prop) → step-2-brief.md absorbed this; the brief itself IS the summary. Replaced "After presenting the site summary (from Step 0)" with step-2 grounding itself by reading DESIGN.md + asset-descriptions + visible-text directly. Step 0's new structure: - Run the capture (CLI command + project-dir convention) — unchanged - Confirm it succeeded (1-line summary, error-out on bad capture) - Reference table mapping each capture/ file to the step that first reads it (explicit "DO NOT read these here") - Gate: capture exits 0 + counts non-zero |
||
|
|
7093ee900b |
refactor(skill): slim SKILL.md to step-pointer index, push to step files
SKILL.md grew to 192 lines from a 124-line baseline. Most of the
bloat was content duplicated in the step reference files it points
to. Removed 6 sections that duplicated step content, composed 2
small additions into the step files where they actually belonged.
Removed from SKILL.md (already covered elsewhere):
- "Take your time" / "Quality matters more than speed" paragraph
— operational philosophy already implicit in step-6-validate's
cell-by-cell review prose.
- "Creative Tension Principle" section — step-3-storyboard.md:21
already has the exact "What makes this video different from a
generic [video type] for any [industry] brand?" single-sentence
test. Duplicate removed; storyboard is the right home.
- "Step -1: What we're actually making" (30 lines: anti-patterns,
video grammar, shot framing, camera moves) — duplicates step-3-
storyboard.md:197+ (shot types), :229–232 (anti-patterns), and
beat-builder-guide.md:126+ (shot framing).
- "Sub-agent mode" + "No sub-agents" preamble — step-5-build.md:286
–292 already handles both parallel and serial runtimes.
- "Image-viewing capability" warning — operationally implicit in
step-0 ("View the contact sheets") and step-6 ("View snapshots/
contact-sheet.jpg cell-by-cell").
- "User Interaction Points" table — redundant with the inline 💬
markers on Steps 3 and 4.
Composed into step files (content that wasn't there yet):
- step-1-design.md "Target length" paragraph: added the fast-pacing
/ billboard-per-beat exception (50-line DESIGN.md is enough when
beats are single hero elements on full-bleed backgrounds, not
full UIs).
- step-2-brief.md "Surprise me" section: added the global-propagation
rule — when the user signals autonomous mode at Step 2, every 💬
gate downstream (Step 3 storyboard approval, Step 4 TTS choice) is
also skipped.
Step 5 SKILL.md gate paragraph trimmed from a 6-clause description
of the per-beat read to one line that points at step-5-build.md
for the full checklist.
Updated the techniques.md reference counts from "20" to "13" in
SKILL.md, beat-builder-guide.md, and step-3-storyboard.md to match
the techniques.md trim in the upstream branch.
Net: SKILL.md 192 → 131 lines.
|
||
|
|
051c9c9de4 |
chore(skill): drop visual-vocabulary.md + use published npx hyperframes
- Delete `references/visual-vocabulary.md` and scrub the four call sites that referenced it. The 6-axis lookup framing it introduced contradicted the rest of the skill's "design from the brand, not from a table" stance. - Replace all `npx tsx packages/cli/src/cli.ts <cmd>` invocations with `npx hyperframes <cmd>` in step-0-capture.md, step-5-build.md, step-6-validate.md, and beat-builder-guide.md. The capture- and snapshot-pipeline improvements that previously required the local CLI now ship in the published CLI via the stack's PRs #987 and #988, so once the stack lands the published CLI is the right invocation for the skill prose. - Remove the now-contradictory "ALWAYS use the local CLI — never npx hyperframes" warnings in step-0-capture.md and step-6-validate.md. |
||
|
|
a1ffb6e7bf |
feat(skill): website-to-hyperframes — concept-first authoring + per-beat read protocol
Rewrite of the website-to-hyperframes skill that came out of 11
evaluation rounds. The honest read of those evals: prose-only
guidance had hit its ceiling — sub-agents kept reporting "0 errors,
looks good" without doing the work, producing slideshow-quality
videos with mismatched brand colors, missing logos, and beats that
didn't serve the storyboard. This restructure addresses the
failure modes that real videos showed, not theoretical ones.
**Step structure (replaces 7-step layout with concept-first 6-step)**
Old: capture → design → script → storyboard → vo → build → validate
New: capture → design → brief → storyboard → vo → build → validate
The brief step (Step 2) is new: a conversation-shaped step that
aligns message + audience + arc before any beat-writing happens.
Concept-first throughout — message → arc → beats that serve the arc
→ which assets and techniques bring each beat to life.
**Step 0 (capture)**
- "View the contact sheets — carefully, every cell, not a glance"
closes the failure mode where agents reported "viewed the contact
sheet" after one scroll and later wrote beats referencing assets
that didn't exist or missed the brand logo.
- Names the right artifacts to read in order (tokens.json →
design-styles.json → asset-descriptions.md → fonts-manifest.json),
with read-on-demand guidance for the rest.
**Step 1 (design)**
- DESIGN.md authoring guide. Restored component CSS sections
(Component Stylings, Spacing & Layout, Depth & Elevation) that
earlier batches over-collapsed.
**Step 2 (brief)**
- Strategy/messaging step. Clear instruction for "Surprise me" /
minimal direction: state the minimum context (where the video
runs, who it's for) and proceed bold.
**Step 3 (storyboard + script)**
- Concept gate at the top — answer "what makes this video distinct"
before writing beat 1.
- Brand-floor MUST rules (logo in opener + closer; signature visual
somewhere in the video).
- Captured assets (SVG logos, illustrations, hero art, gradients)
are first-class beat content alongside composed UIs — many of
them carry beats outright. The constraint is only that you start
from the message, not the asset inventory.
**Step 4 (vo)**
- TTS ranking: HeyGen first (auto word timestamps), ElevenLabs
second, Kokoro free. Audio timing reconciliation gate: if actual
audio duration ≠ storyboard planned ±15%, rescale beats or trim
script before Step 5.
**Step 5 (build) + beat-builder-guide.md**
- Sub-agent template now pastes brand values inline rather than
telling the sub-agent to re-read DESIGN.md. Targeted file reads
with specific sections + line ranges.
- "Patterns that ARE shots" affirmative list (captured logo
draw-on, hero illustration push-in, captured screenshot with
parallax layers, kinetic typography over captured asset).
- Webpage-mimicry patterns (full CSS browser chrome, parked-camera
composition, ±2px breathing motion) marked ⚠ rather than ❌ —
fine when the storyboard genuinely calls for them as the subject.
- Required cinematography per beat: shot type, camera move, depth
strategy, purpose.
**Step 6 (validate) — per-beat read protocol**
This replaces the previous "spawn verify-beats CLI" gate. A grep
of composition HTML can catch structural lies (missing hex codes,
wrong asset paths) but it can't catch boring beats, off-screen
logos, GSAP timelines that only cover the first 2 seconds, or
camera moves that don't match the storyboard. Those failures only
surface when somebody opens the file and reads it.
Per-beat verdict template names the brand hex codes used, captured
asset paths referenced, headline `font-size`, GSAP timeline
coverage, and storyboard alignment. Critic sub-agent scores a
"Captured asset utilization" dimension specifically so the eval
captures whether captured SVGs/illustrations carried beats or got
recreated as divs.
**Asset bundle**
- 20 Pixabay-licensed SFX files with `CREDITS.md` documenting
provenance. SFX assignment moved to Step 3 (creative decision)
so Step 5 implements rather than improvises.
- Capabilities reference + html-in-canvas-patterns updated:
Three.js 0.181.2 + ESM jsm imports, mulberry32 seeded PRNG for
deterministic shatter, 24-effect text-animation catalog
referenced (catalog itself lands in the hyperframes-skill PR).
- Visual vocabulary rewritten: replaces user-word lookup tables
with brand-first derivation across 6 axes; user words land as
modifiers, not replacements.
|
||
|
|
22f0e6a5cd |
feat(skills): design.md integration, shared video references, Claude Design gaps (#549)
## What Major skill infrastructure update: design.md support, shared video-composition references, and creative direction patterns extracted from website-to-hyperframes into the base hyperframes skill. ## Changes ### design.md Integration (lightweight) - Step 0a reads any format design.md (YAML, prose, tables) — no format mandate - Brand colors/fonts are strict; video layout adapts per video-composition.md - Font warning gate: warns user if design.md names fonts without local .woff2 files - Design picker generates spec-compliant design.md with YAML frontmatter + prose - Picker generates contextual options from user's prompt (3-4 architectures, 5-6 palettes, 3 type pairings) ### Shared Video References (extracted from website-to-hyperframes) - `video-composition.md` — density, scale, color presence, frame composition rules. Light canvas guidance (don't override user palette). **Always read.** - `beat-direction.md` — per-beat planning (concept → mood → choreography verbs → transition), rhythm templates by video type - `techniques.md` — 11 visual techniques with code patterns (SVG drawing, Canvas 2D, kinetic type, Lottie, etc.) - `narration.md` — pacing, tone, script structure, number pronunciation, hooks - `motion-principles.md` — gained image motion treatment + load-bearing GSAP rules ### Claude Design Transfer Brief (6 gaps applied) 1. Discovery step for exploratory requests (audience, platform, priority, variations) 2. Anti-scope-creep: "build what was asked, every element earns its place" 3. Read-source discipline: "read actual files, don't guess" 4. Rhythm planning: declare scene rhythm before implementing 5. Variations as first-class output for exploratory requests 6. Two-phase verification: fast checks block, slow checks parallel ### Prompt Expansion Updated - Uses beat-direction format (concept → mood → verbs → depth layers) - Rhythm declaration before scene breakdown - References video-composition.md and beat-direction.md ### Key Design Decision **design.md = brand truth, not video layout spec.** Background color is strict from design.md (don't switch light to dark). Video-composition rules teach how to make any palette work cinematically. ## Files Changed (16) **New shared references:** - `skills/hyperframes/references/video-composition.md` - `skills/hyperframes/references/beat-direction.md` - `skills/hyperframes/references/techniques.md` - `skills/hyperframes/references/narration.md` **Updated:** - `skills/hyperframes/SKILL.md` — discovery, anti-scope-creep, rhythm, variations, two-phase verify, new references - `skills/hyperframes/references/prompt-expansion.md` — beat-direction format - `skills/hyperframes/references/motion-principles.md` — image treatment + GSAP rules - `skills/hyperframes/references/design-picker.md` — contextual generation - `skills/hyperframes/visual-styles.md` — YAML token blocks per preset - `skills/hyperframes/house-style.md` — design.md precedence - `skills/hyperframes/templates/design-picker.html` — spec-compliant output - `skills/website-to-hyperframes/references/*` — now reference shared files ## Test plan - [x] Design picker generates and serves correctly - [x] Picker output is spec-compliant design.md - [x] Composition built from picker design.md renders in Studio - [x] Before/after eval: 4 topics × 2 versions showing skill guidance impact - [x] Light canvas compositions respect user palette (don't switch to dark) 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
343bb8ea81 | docs(skills): clarify preview handoff URL | ||
|
|
9b72a87c17 |
fix(lint): remove root_composition_missing_data_duration (#490)
* fix(lint): remove root_composition_missing_data_duration Lint cannot statically observe the runtime's true Infinity-emission condition: it requires a finite GSAP timeline duration AND a finite media/sub-comp window AND timeline > floor + 1, none of which are visible to the static linter. The looping shapes that drive the condition are already covered by `gsap_infinite_repeat` and `gsap_repeat_ceil_overshoot` (both from #243), which point at the real authoring mistake — flagging the missing duration separately was a noisy proxy for the same signal. Per #490 review discussion, deprecate the static rule and let those two GSAP rules carry the pre-render coverage. If perfect precision on `durationInFrames = Infinity` is needed, that belongs on the runtime/render path where `shouldEmitNonDeterministicInf` is actually known. Add regression tests pinning the removal: a docs-compliant root without `data-duration` no longer warns, and the canonical loop-inflated shape now surfaces only via `gsap_infinite_repeat` instead of two duplicate findings. * docs(skills): update step-6 build checklist after rule removal Drops the `root_composition_missing_data_duration` reference now that the rule is gone. Keeps the authoring recommendation (and explains the runtime Infinity case) but points authors at the GSAP rules that actually carry the lint signal: `gsap_infinite_repeat` and `gsap_repeat_ceil_overshoot`. |
||
|
|
2cb933df61 | style: format | ||
|
|
924fd2f145 |
docs(step-6-build): sharpen Rule 2 — name from() seek-past-end reset as root cause
Per review feedback on PR #364: the 'hero vanishes' failure has two mechanisms. Primary: second tween's immediateRender overwrites the first at construction time. Secondary: tl.from() resets to its declared from- state when seeked past timeline end, which the capture engine triggers. Both are now named so the rule has precise rationale, not just a pattern to avoid. Ref: https://github.com/heygen-com/hyperframes/pull/364#pullrequestreview-4167523103 |
||
|
|
731baebbaa |
docs(website-to-hyperframes): add load-bearing GSAP authoring rules
Add five animation-authoring rules to step-6-build.md that the linter cannot catch but that silently ship broken output. Surfaced from two independent builds (2026-04-20) where compositions passed lint and still rendered elements invisible / unscrubbing. Rules added: - No iframes for captured content (don't scrub) - Never stack transform tweens on one element (entrance + Ken Burns on same img silently kills it) - Prefer tl.fromTo() over tl.from() inside .clip scenes (immediateRender interacts badly with scene boundaries) - Ambient pulses must attach to seekable tl, not standalone gsap.to() - Generalize the caption hard-kill rule to every scene-boundary exit |
||
|
|
a78ec5ec76 |
fix(skill): all file paths use capture/ subfolder prefix (#345)
* fix(skill): all file paths use capture/ subfolder prefix Step-1 was updated to capture into <project-dir>/capture/ but all file-read instructions across steps 1-6 still used bare paths (extracted/tokens.json, assets/hero.png). Agents following the skill looked for files in wrong locations, producing broken compositions with 404'd images and fonts. - step-1: all 12+ file-read paths prefixed with capture/ - step-2: tokens.json and asset-descriptions.md paths fixed - step-3: visible-text.txt path fixed - step-4: asset-descriptions.md, asset examples, directory tree expanded to show capture/ children (screenshots/, assets/, extracted/) - step-5: minor cleanup - step-6: asset-descriptions.md path fixed, composition examples already correct (../capture/assets/) - techniques.md: Lottie, video, font paths all prefixed Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(skill): address Copilot review — font comment path, add videos/ to tree - techniques.md: comment says ../capture/assets/fonts/ (matches composition context) - step-4 file tree: add videos/ under capture/assets/ --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
4e87f28cd9 |
fix: address PR #339 review — 7 issues
1. Catalog failure safety: warn when catalog is empty or throws, so capture doesn't silently produce zero images 2. Dead path: extract-audio-data.py → skills/gsap/scripts/ (was skills/hyperframes/scripts/) 3. --json fonts compat: emit both `fonts` (string[]) and `fontsDetailed` (FontToken[]) to avoid breaking external consumers 4. Restore .cursorrules writing alongside AGENTS.md + CLAUDE.md 5. .gitignore: remove over-broad `projects/` and `videos/` entries, keep scoped `cursor-tests/` and `launch-video*/` 6. agentPromptGenerator: mark unused params as reserved with comments, remove _animations from buildPrompt 7. Cookie filter: threshold 20 → 8 chars to preserve footer copy like "© 2026 Stripe" (16 chars) and "Privacy & Terms" (15 chars) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
517e327294 |
docs(skill): render step is on-demand, not automatic
Preview is the delivery — scrub through it, iterate on tweaks, only render
once the user explicitly asks ("render it", "make the final", "I'm happy").
Rendering takes minutes per pass and is wasted work if the user wants any
changes after seeing it.
- step-7-validate: rename Render section to "Render (on-demand only)" and
make the trigger criteria explicit
- SKILL.md: step-7 summary updated to "Deliver the preview to the user
first — only render to MP4 on explicit request"
Made-with: Cursor
|
||
|
|
1a69cde4be |
docs(skill): shader/audio/render/snapshot guidance from regression evidence
Adds decision guidance and conventions the 8-site regression test exposed as blind spots — agents had the capability but never reached for it. step-1-capture: - Clarify capture goes into <project-dir>/capture/ so capture artifacts stay isolated from later build files (SCRIPT/STORYBOARD/DESIGN/compositions/) - 7/8 regression tests already did this; codify as the convention step-4-storyboard: - Add "When to pick which" decision table for shader vs CSS vs hard cut transitions. Shader transitions were available but used in 0/8 tests — every test defaulted to CSS. The table frames shaders as "reveals, reaction shots, brand moments" vs CSS as "connective tissue" - Update technique count (10 → 11) step-6-build: - Mid-scene activity table gets a new row for audio-reactive logo/CTA animation (bass pulse, treble glow). Audio-reactive was used in 0/8 tests despite narration being present in all of them step-7-validate: - Snapshot section: explicit "use hyperframes snapshot, don't roll custom" with the default naming pattern spelled out. Stripe's run used custom ffmpeg naming (beat-6-cta-at-20.5s.png) instead of frame-XX-at-Ys.png - New render section: require --output renders/<project>.mp4 so final MP4s have predictable names. Without this, 7/8 tests produced wildly different filenames (preview.mp4, cal_2026-04-19_20-29-21.mp4, basecamp.mp4, etc.) techniques.md: - New technique #11: Audio-Reactive Animation. Covers the sampling pattern (per-frame tl.call, not single tween), when to use (music/dramatic VO videos), intensity ranges (3-5% for text/logos, 10-30% for backgrounds), and anti-patterns (equalizer bars, waveforms, strobing). Cross-references skills/hyperframes/references/audio-reactive.md for the full API Made-with: Cursor |
||
|
|
d8f1af1ef1 |
feat(capture): write AGENTS.md alongside CLAUDE.md + skill refinements from regression tests
Capture pipeline:
- agentPromptGenerator now writes AGENTS.md + CLAUDE.md (drop legacy
.cursorrules), matching the dual-file convention already used by the
_shared templates in hyperframes init. AGENTS.md is picked up natively by
Cursor, Codex, Gemini CLI, Windsurf, Aider, and Jules; CLAUDE.md covers
Claude Code. Both files share the same content — a capture data inventory
that points agents to the website-to-hyperframes skill.
website-to-hyperframes skill refinements (derived from 8-site regression test):
- Drop slash-command phrasing throughout SKILL.md and step-6-build.md so the
skill works identically across Claude Code (slash), Cursor (auto-discover
by description), and other agents.
- Remove stale HANDOFF.md references from SKILL.md step-7 summary and
reference table — matches the intent of the prior step-7 cleanup.
- step-5-vo: specify narration.txt filename convention (pronunciation-
substituted spoken text; distinct from SCRIPT.md the creative doc).
- step-6 self-review adds three rules derived from actual lint warnings
observed across the 8 regression runs:
- Every <template> root needs data-start + data-duration (catches
root_composition_missing_data_start/duration, seen in 4/8 runs).
- Caption exits need a hard tl.set kill after tl.to(opacity:0), or
per-word karaoke tweens can leave captions stuck on screen
(caption_exit_missing_hard_kill).
- No duplicate media nodes with identical src + start + duration, or
the compiler discovers them twice (duplicate_media_discovery_risk).
Housekeeping:
- .gitignore: add cursor-tests/, basecamp-video/, projects/, videos/ —
local regression-test scratch dirs that should never be committed.
- Remove two broken symlinks from .claude/skills/ that pointed to paths
which never existed in the repo (.claude/skills/ is already gitignored).
Made-with: Cursor
|
||
|
|
92a5ef419b |
feat(capture): improve capture quality + clean up CLAUDE.md
Capture improvements:
- Font weights via document.fonts API + DOM sampling (variable font detection)
- Section background-image extraction (no more false #FFFFFF on hero photos)
- Detected libraries surfaced in CLAUDE.md brand summary
- Structured visible-text.txt with [tag] prefixes, cookie/nav noise filtered
- tokens.json cleaned: removed images/paragraphs/icons (duplicated elsewhere),
filtered sections to heading-only, trimmed cssVariables to design-relevant
- Removed redundant scroll pass in htmlExtractor (2-5s faster per capture)
- Font cap at 20 families, Placeholder/Fallback fonts filtered
CLAUDE.md rewrite:
- Removed prescriptive tone ("use exact strings" → "rephrase freely")
- Removed fluff sections (How to Create, DESIGN.md warning, Example Prompts,
Source Patterns)
- asset-descriptions.md promoted to first data row
- Removed assets-catalog.json from inventory
Skill fixes:
- Dead shader refs → point to packages/shader-transitions/README.md
- Google Fonts import in techniques.md → local @font-face placeholder
- Added Stripe DESIGN.md as light-brand example
- Removed HANDOFF.md generation from step-7
- Updated step-1 for new font weight + visible-text formats
|
||
|
|
de5b53c08b |
feat(capture): switch Gemini 2.5 Flash → 3.1 Flash Lite
Gemini 3.1 Flash Lite Preview: 2.5x faster TTFT, 45% faster output, slightly cheaper ($0.25/M vs $0.30/M input), near-2.5-Flash quality. Descriptions are actually more detailed in testing. |
||
|
|
87f4c77e2f |
feat: website capture pipeline + 7-step video production skill (#284)
* feat(cli): add website capture with AI-powered DESIGN.md generation Adds `hyperframes capture <url>` command that extracts a complete design system from any website, producing AI-agent-ready output: - Full-page screenshot (lazy-load aware, nav at top) - AI-generated DESIGN.md via Claude API (colors, typography, elevation, components, do's/don'ts) with programmatic asset catalog (136+ assets with HTML context annotations like img[src], css url(), link[rel=preload]) - CSS-purged compositions (87% size reduction via PurgeCSS) - HTML-prettified compositions (one-tag-per-line for AI readability) - CLAUDE.md + .cursorrules auto-generated for AI agent instructions - Asset deduplication (srcset variants) and tracking pixel filtering * feat(cli): add gemini 3.1 pro, playwright screenshots, replica refinement - switch to gemini 3.1 pro (gemini-3.1-pro-preview) with claude fallback - playwright for full-page screenshots (fixes puppeteer gradient/fixed bugs) - replica refinement loop: generate, screenshot, compare, fix - extract inline svgs (50 max, 10kb each) to assets/svgs/ - extract visible text in dom order for content accuracy - detect js libraries (gsap, three.js, scrolltrigger) via globals - improved asset catalog grouping and naming - reverse-engineered aura system prompt documentation - comprehensive session handoff doc Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: update session handoff with slack research findings - key finding: team already wants DESIGN.md integration (James, Bin, Vance) - skills quality matters enormously - must invoke /hyperframes-compose - eval infrastructure exists (Abhay's dashboards, Teodora's 78-criteria guide) - templates at templates/ need study before finalizing skill - session handoff updated with critical next steps * refactor(cli): simplify capture pipeline, remove replica generator * feat(capture): add Lottie detection and WebGL shader extraction Captures Lottie animations via network interception and WebGL shader source via gl.shaderSource hooking during site crawl. Updates website-to-hyperframes skill with asset planning guidance, Lottie/shader reading instructions, and stronger creative direction for scene planning. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(capture): clean pipeline + shader-first creative workflow Capture pipeline: - Remove dead deps (puppeteer-extra, stealth plugin, duplicate devDeps) - Remove duplicate generateAgentPrompt() call (first lied about DESIGN.md) - Remove dead canvas-to-image code in htmlExtractor (post canvas removal) - Parallelize image downloads (batches of 5 via Promise.allSettled) - Fix pre-existing TS error (match[1] guard in font downloader) - Default capture output to captures/<hostname> Skill creative overhaul: - Add shader transition selection to creative director step (Step 4) - Add shader wiring instructions to engineer step (Step 5) - Replace 4-line energy modifiers with visual vocabulary table - Strip rigid scene-by-scene templates from video-recipes.md - Strip example fill data from scene plan tables - Add "read transition refs before planning" instruction - Add creative ambition language ("how the hell did they make this") Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add skill architecture redesign spec Comprehensive redesign of website-to-hyperframes skill and capture pipeline based on code review findings and Claude Code architecture research. Key changes: remove AI auto-generation, restructure skill into phases, embed shader boilerplate in scaffold, fix color format. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add implementation plan for skill architecture redesign 13-task plan covering: capture pipeline cleanup (remove AI generation, fix colors to HEX, add asset descriptions, shader-ready scaffold), skill restructuring (4 phases with artifact gates), and compose skill Visual Identity Gate upgrade. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor(capture): remove AI auto-generation and SDK dependencies * fix(capture): convert extracted colors to HEX format * refactor(capture): remove AI key path, add asset descriptions generator * refactor(capture): update agent prompt, remove hasDesignMd, add asset descriptions * feat(capture): pre-wire shader transitions in index.html scaffold * chore: remove duplicate visual-styles.md (canonical is in hyperframes/) * refactor(skill): rewrite website-to-hyperframes as phase-based orchestrator * feat(skill): add Phase 1 understand reference * feat(skill): add Phase 2 design reference with full DESIGN.md schema * feat(skill): add Phase 3 creative direction reference * feat(skill): add Phase 4 build reference with inline shader example * feat(skill): upgrade Visual Identity Gate to produce full DESIGN.md * docs: update CLAUDE.md skill references for phase-based workflow * fix: address code review findings - Remove orphaned `false` argument in generateAgentPrompt call (critical: was shifting hasLottie, hasShaders, catalogedAssets parameters) - Add HSL color handling in rgbToHex via temp element resolution - Remove build artifact commit section from phase-4-build.md - Fix __GSAP_TIMELINE reference to __timelines Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(capture): regex double-escape + simplify scaffold + fix asset descriptions - Double-escape regex in tokenExtractor template literal (\s→\\s, \d→\\d, \(→\\() so browser receives valid regex patterns via page.evaluate() - Simplify index.html scaffold: scene slots + audio + timeline + comment pointing to shader-setup.md reference (no broken inline shader boilerplate) - Fix asset descriptions: use CatalogedAsset.contexts/notes instead of nonexistent htmlContext field Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: code review — 16 bugs, 7-step skill rewrite, cleanup Code fixes: - snapshot.ts: path traversal guard, browser leak (try/finally), div-by-zero for --frames 1, port bind error handling, rAF-based render settle - index.ts: remove invalid thinkingConfig for gemini-2.5-flash, fix Gemini batch/rate-limit comments, fix video preview viewport y-coordinate - tokenExtractor.ts: remove dead seen[si] dedup code - gsap.ts: index ALL classes for inline-style transform conflict detection Skill architecture rewrite (4-phase → 7-step): - Replace phase-1 through phase-4 with step-1 through step-7 - Add techniques.md (10 visual techniques with code patterns) - Fix /hyperframes-compose → /hyperframes (skill doesn't exist) - Fix captures/arc-browser reference → shader-setup.md (file doesn't exist) - Fix step-7 hardcoded captures/stripe path - Document Gemini API free/paid rate limits in step-1 Cleanup: - CLAUDE.md: restore from Stripe-capture overwrite, update 4-phase → 7-step - .gitignore: add PR #267 skills (hyperframes-animation-map, hyperframes-contrast) - Delete old phase-*.md, animation-recreation.md, tts-integration.md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: remove dev artifacts, research docs, wrong lockfiles Remove files that shouldn't ship in this PR: - docs/research/ (aura analysis, prompt catalogs) - docs/session-*.md, docs/SESSION-HANDOFF.md (dev notes) - docs/superpowers/ planning and spec docs - pnpm-lock.yaml at root and cli (repo uses bun, not pnpm) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(CLAUDE.md): align with main — slim format, add website-to-hyperframes mention Main PR #283 removed the full skills table from CLAUDE.md and moved it to AGENTS.md. Align with that decision: use main's slim dev-focused format, fix pnpm→bun references, add one-line /website-to-hyperframes pointer. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(cli): add capture command to help groups The capture command was registered in cli.ts but missing from the help groups, so it wouldn't appear in `hyperframes --help`. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: format skill reference files (oxfmt) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: regenerate bun.lock after rebase The lockfile was stale after rebasing onto main — bun install --frozen-lockfile failed in CI because new dependencies (google/genai, patchright, purgecss) weren't reflected in the lockfile. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address PR review comments + improve capture quality Review fixes (16 comments from jrusso1020 + vanceingalls): - screenshotCapture: remove Playwright dep, use Puppeteer for all screenshots - screenshotCapture: dynamic screenshot count based on page height (30% overlap) - snapshot.ts: fix duration() function-vs-property bug, cross-platform path guard - htmlExtractor: fix code injection via parameterized evaluate - index.ts: video preview re-measures position after scroll, .env file loading - capture.ts: BLOCKED.md on timeout failures - gsap.ts: 5 inline-style lint tests added (all pass) - Remove Playwright, patchright deps; @google/genai to optionalDependencies - Gitignore: generic patterns instead of 20 hardcoded directories - Remove asset-sourcing.md, video-recipes.md (unused, duplicated guidance) Capture quality improvements (tested on 10+ websites): - Color extraction: canvas-based oklch/lab resolver, pixel sampling via elementFromPoint, broad sweep for accent colors, gradient/shadow extraction - Section detection: broadened selectors for div-based layouts, height cap to skip page-level wrappers, parent bg walkup for dark sites - Font downloads: cap 6 per family / 30 total (Cal.com: 306→30) - CTA detection: text pattern matching + nav context filtering - Heading text: innerText with whitespace normalization - Gemini captioning: maxOutputTokens 100→300, .env auto-loading - .env.example updated with GEMINI_API_KEY docs - TTS ranking: Kokoro first with Python 3.10+ note * fix: address PR review comments + improve capture quality Review round 2 fixes (jrusso1020 + vanceingalls): - verify/index.ts: add path traversal guard (relative + isAbsolute) - verify/index.ts: fix sections[i] undefined typecheck error (CI green) - index.ts: escape Lottie JSON with \u003c to prevent </script> breakout - step-4-storyboard: fix technique count contradiction (2-3 per beat, not across whole video) - step-6-build: perspective tilt uses gsap.set() instead of CSS transform (avoids GSAP overwrite conflict) - step-1-capture: reorder — command first, Gemini note after (zero-config is the default path, API key is optional enhancement) - step-7-validate: add tsx fallback for snapshot command - step-3-script: vary hook patterns, don't default to number every time - assetDownloader: exempt SVGs from 10KB minimum filter (company logos like Hubspot/Intel/DHL are 2-6KB; HeyGen capture: 13→75 assets) Note: adm-zip was NOT removed (reviewer #3) — it's still in packages/cli/package.json:30. The root package.json had patchright and purgecss removed, not adm-zip. Note: ANTHROPIC_API_KEY not restored in .env.example — grep confirms zero references in the entire codebase. The @anthropic-ai/sdk dependency was removed earlier in this branch. * refactor(capture): split index.ts (1175 to 566 lines) into modules Mechanical extraction, zero logic changes. New files: - mediaCapture.ts (345 lines): Lottie preview, video manifest/screenshots - contentExtractor.ts (314 lines): library detection, text, Gemini, asset descriptions - scaffolding.ts (135 lines): .env loading, project scaffold generation Also fixes false-positive BLOCKED.md with structural Cloudflare detection. Tested on 20 websites, pre/post output identical. * chore(capture): remove --split flow (splitter, verify, cssPurger, purgecss) The --split feature auto-generates compositions from captured HTML — a different approach from the /website-to-hyperframes skill workflow where agents build compositions from scratch using the storyboard. No skill file, no step reference, and no test session ever used --split. Removes 923 lines of unused code + purgecss dependency. Backed up to ~/Desktop/capture-split-backup/ for reference. * fix(security): add ssrf protection, lottie injection fix, oom guard - assetDownloader: add isPrivateUrl() guard blocking private IP ranges (127.x, 10.x, 172.16-31.x, 192.168.x, 169.254.x), cloud metadata endpoints, localhost, and non-HTTP schemes - mediaCapture: fix Lottie JSON injection by loading shell HTML first then passing animation data via parameterized page.evaluate() - index.ts: check Content-Length header before response.buffer() in Lottie network interception to avoid OOM on multi-GB responses * fix(capture): security fixes, timeout, sub-agent dispatch instructions Security (from miguel-heygen review): - assetDownloader: export isPrivateUrl() SSRF guard - htmlExtractor: add isPrivateUrl check before CSS fetch - mediaCapture: add isPrivateUrl check before Lottie fetch - mediaCapture: fix previewPage leak (try/finally) - mediaCapture: skip Lottie files > 2MB for preview (CDP limit) - contentExtractor: skip images > 4MB for Gemini captioning - index.ts: check Content-Length before response.buffer() (OOM guard) - snapshot.ts: register error handler before server.listen() Capture improvements: - Default timeout 30s to 120s (Shopify needs ~90s for Cloudflare) - step-6-build: sub-agent dispatch template with explicit rules: pass file PATHS not contents, use local fonts not Google Fonts, verify ../assets/ references after each beat * fix(capture): catalog before DOM mutation, networkidle2, faster Gemini Critical: asset cataloger now runs BEFORE extractHtml which converts img src to data URLs. Framer sites like heykuba.com went from 2 to 78 images. - networkidle2 instead of networkidle0 (unblocks SPAs with WebSockets) - Lazy-load wait: scroll to bottom, wait for img.complete - CSS background-image cataloging for Framer/Webflow - SVG naming: checks class, id, parent, inner text (not just aria-label) - Gemini batch 5->20, pause 12s->2s (paid tier: 2000 RPM, ~0.001/img) - maxOutputTokens 300->500, descriptions sorted captioned-first - Remove tsx fallback from step-1 (reviewer nit, published CLI has it) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |