mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-01 19:42:03 +00:00
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>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
517e327294
commit
4e87f28cd9
+3
-5
@@ -79,10 +79,8 @@ captures/
|
||||
*-tour/
|
||||
*-brand/
|
||||
|
||||
# Local regression-test scratch directories (website-to-hyperframes runs).
|
||||
# These hold per-site captures, SCRIPT/STORYBOARD/DESIGN.md, compositions,
|
||||
# narration audio, rendered MP4s — all reproducible, never commit.
|
||||
# Local regression-test and video project scratch directories.
|
||||
# These hold per-site captures, compositions, narration audio, rendered MP4s.
|
||||
cursor-tests/
|
||||
basecamp-video/
|
||||
projects/
|
||||
videos/
|
||||
launch-video*/
|
||||
|
||||
@@ -20,30 +20,22 @@ export function generateAgentPrompt(
|
||||
outputDir: string,
|
||||
url: string,
|
||||
tokens: DesignTokens,
|
||||
animations: AnimationCatalog | undefined,
|
||||
_animations: AnimationCatalog | undefined, // reserved for future animation summary
|
||||
hasScreenshot: boolean,
|
||||
hasLottie?: boolean,
|
||||
hasShaders?: boolean,
|
||||
_catalogedAssets?: CatalogedAsset[],
|
||||
_catalogedAssets?: CatalogedAsset[], // reserved for future asset inventory
|
||||
detectedLibraries?: string[],
|
||||
): void {
|
||||
const prompt = buildPrompt(
|
||||
url,
|
||||
tokens,
|
||||
animations,
|
||||
hasScreenshot,
|
||||
hasLottie,
|
||||
hasShaders,
|
||||
detectedLibraries,
|
||||
);
|
||||
const prompt = buildPrompt(url, tokens, hasScreenshot, hasLottie, hasShaders, detectedLibraries);
|
||||
writeFileSync(join(outputDir, "AGENTS.md"), prompt, "utf-8");
|
||||
writeFileSync(join(outputDir, "CLAUDE.md"), prompt, "utf-8");
|
||||
writeFileSync(join(outputDir, ".cursorrules"), prompt, "utf-8");
|
||||
}
|
||||
|
||||
function buildPrompt(
|
||||
url: string,
|
||||
tokens: DesignTokens,
|
||||
_animations: AnimationCatalog | undefined,
|
||||
hasScreenshot: boolean,
|
||||
hasLottie?: boolean,
|
||||
hasShaders?: boolean,
|
||||
|
||||
@@ -57,6 +57,8 @@ export async function downloadAssets(
|
||||
}
|
||||
|
||||
// 3. Images — use the catalog as the single source of truth (highest resolution, deduplicated)
|
||||
// If the catalog is empty, asset download produces zero images — this is surfaced as a warning
|
||||
// so the capture doesn't silently produce a half-empty dataset.
|
||||
const imageUrls: { url: string; isPoster: boolean }[] = [];
|
||||
|
||||
if (catalogedAssets && catalogedAssets.length > 0) {
|
||||
|
||||
@@ -134,9 +134,10 @@ export async function extractVisibleText(page: Page): Promise<string> {
|
||||
if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') continue;
|
||||
var tag = el.tagName.toLowerCase();
|
||||
if (tag === 'script' || tag === 'style' || tag === 'noscript') continue;
|
||||
// Skip short text inside nav/footer (catches nav links, cookie consent)
|
||||
// Skip very short text inside nav/footer (catches single-word nav links)
|
||||
// Threshold is 8 chars to preserve footer copy like "© 2026 Stripe" (16 chars)
|
||||
var inNavOrFooter = el.closest('nav, footer, [role="navigation"]');
|
||||
if (inNavOrFooter && text.length < 20) continue;
|
||||
if (inNavOrFooter && text.length < 8) continue;
|
||||
// Skip common cookie/consent patterns
|
||||
if (cookieRe.test(text)) continue;
|
||||
texts.push('[' + tag + '] ' + text);
|
||||
|
||||
@@ -339,8 +339,13 @@ export async function captureWebsite(
|
||||
const { catalogAssets } = await import("./assetCataloger.js");
|
||||
catalogedAssets = await catalogAssets(page1);
|
||||
progress("design", `${catalogedAssets.length} assets cataloged`);
|
||||
if (catalogedAssets.length === 0) {
|
||||
warnings.push(
|
||||
"Asset catalog is empty — no images will be downloaded. The page may use non-standard image loading.",
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
warnings.push(`Asset cataloging failed: ${err}`);
|
||||
warnings.push(`Asset cataloging failed (no images will be downloaded): ${err}`);
|
||||
}
|
||||
|
||||
// ── MUTATION phase: extractHtml modifies the live DOM (converts images to data URLs) ──
|
||||
|
||||
@@ -115,7 +115,8 @@ export default defineCommand({
|
||||
screenshots: result.screenshots.length,
|
||||
assets: result.assets.length,
|
||||
detectedSections: result.tokens.sections.length,
|
||||
fonts: result.tokens.fonts,
|
||||
fonts: result.tokens.fonts.map((f) => f.family),
|
||||
fontsDetailed: result.tokens.fonts,
|
||||
animations: result.animationCatalog?.summary,
|
||||
warnings: result.warnings,
|
||||
},
|
||||
|
||||
@@ -367,7 +367,7 @@ for (var f = 0; f < AUDIO_DATA.totalFrames; f++) {
|
||||
Per-frame sampling is required — a single tween will not react. Use the extract script:
|
||||
|
||||
```bash
|
||||
python3 skills/hyperframes/scripts/extract-audio-data.py narration.wav --fps 30 --bands 16 -o audio-data.json
|
||||
python3 skills/gsap/scripts/extract-audio-data.py narration.wav --fps 30 --bands 16 -o audio-data.json
|
||||
```
|
||||
|
||||
Keep text/logo intensity subtle (≤5% scale, ≤30% glow) — audio-reactive motion on tiny elements reads as jitter. Bigger backgrounds can push to 10–30%.
|
||||
|
||||
Reference in New Issue
Block a user