mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 12:54:29 +00:00
fix(core): render standalone sub-composition previews + surface captured video assets (cli) (#1631)
* fix(core): escape digit-leading id selectors in standalone sub-composition preview
A CSS identifier cannot start with a digit, so an authored rule like
`#01-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>
(cherry picked from commit e43b377fc0)
* feat(cli): surface captured video clips in asset descriptions
generateAssetDescriptions now reads extracted/video-manifest.json and emits
each downloaded clip first, tagged [video], with its DOM heading/caption and
dimensions — motion clips are usually the strongest hero material and
downstream planners key off the [video] marker.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(studio): import commitGsapPositionFromDrag from its actual module
The function was split out into gsapDragPositionCommit.ts in #1605, but
the test kept importing it from ./gsapDragCommit, which no longer exports
it — yielding `is not a function` at runtime. Import from the correct
module to match the production import in gsapRuntimeBridge.ts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(core): address review nits on standalone sub-composition preview
Review follow-ups (#1631), all non-blocking polish:
- contentExtractor: use path.basename() instead of localPath.split('/').pop()
so video filenames resolve correctly on Windows-style paths too.
- subComposition: document that only the leading digit needs CSS escaping
(CSS Syntax L3 §4.3.11) on escapeLeadingDigitIdent.
- tests: pin three previously-uncovered paths — multiple digit-leading ids in
one composition, a digit-leading id inside compound/combinator selectors, and
the promoteTemplateCompositionId no-op when the <template> has no id.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1967901b57
commit
0e75eb2510
@@ -10,7 +10,7 @@
|
||||
|
||||
import type { Page } from "puppeteer-core";
|
||||
import { existsSync, readdirSync, statSync, readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { basename, join } from "node:path";
|
||||
import type sharpType from "sharp";
|
||||
import type { CatalogedAsset } from "./assetCataloger.js";
|
||||
import type { DesignTokens } from "./types.js";
|
||||
@@ -494,5 +494,36 @@ export function generateAssetDescriptions(
|
||||
/* no fonts dir */
|
||||
}
|
||||
|
||||
return [...captionedLines, ...uncaptionedLines, ...svgLines, ...fontLines];
|
||||
// Describe videos — high-value motion clips. The video-manifest.json (written
|
||||
// earlier by captureVideoManifest) carries each clip's DOM heading/caption +
|
||||
// dims. Surfaced FIRST and tagged `[video]`: for a product/demo these moving
|
||||
// clips are usually the strongest hero material, and downstream planners key off
|
||||
// the `[video]` marker. (The `videos/` dir is skipped in the image walk above —
|
||||
// its entries come from the manifest, which has the captions the bare files lack.)
|
||||
const videoLines: string[] = [];
|
||||
try {
|
||||
const manifest = JSON.parse(
|
||||
readFileSync(join(outputDir, "extracted", "video-manifest.json"), "utf-8"),
|
||||
) as Array<{
|
||||
filename?: string;
|
||||
localPath?: string;
|
||||
caption?: string;
|
||||
heading?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
}>;
|
||||
for (const v of manifest) {
|
||||
if (!v.localPath) continue; // only describe clips that actually downloaded
|
||||
const base = basename(v.localPath) || v.filename || "";
|
||||
if (!base) continue;
|
||||
const desc =
|
||||
(v.caption || v.heading || "").trim().replace(/\s+/g, " ").slice(0, 140) || "motion clip";
|
||||
const dims = v.width && v.height ? `, ~${v.width}×${v.height}` : "";
|
||||
videoLines.push(`${base} — [video] ${desc}${dims}`);
|
||||
}
|
||||
} catch {
|
||||
/* no video manifest */
|
||||
}
|
||||
|
||||
return [...videoLines, ...captionedLines, ...uncaptionedLines, ...svgLines, ...fontLines];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user