mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-04 07:19:52 +00:00
* feat(media-use): core infrastructure — manifest, cache, adopt, probe Foundation for media-use — the media resolution layer for HyperFrames. - manifest.mjs: JSONL read/write/find for .media/manifest.jsonl - index-gen.mjs: regenerate agent-readable index.md from manifest - cache.mjs: content-addressed global cache at ~/.media/ (SHA-256, sentinel) - freeze.mjs: download URL or copy local file to .media/ - probe.mjs: extract duration/dimensions via ffprobe - adopt.mjs: scan assets/ directory, register existing files with metadata - 19 passing tests (manifest round-trip, cache, promote, index generation) * fix(media-use): oxfmt formatting + cap freeze download size Format adopt/cache/probe/manifest.test (CI oxfmt --check gate). Cap freezeUrl downloads at 256MB so a hostile/runaway URL can't fill the disk (addresses CodeQL #670: network data written to file). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(media-use): resolve engine + all providers + brand from frame.md - resolve.mjs: cheapest-first cascade - BGM/SFX via heygen --headers, Image/Icon via heygen asset search - Brand tokens from frame.md / design.md (local, no API) - SKILL.md: full agent docs + hyperframes.dev/design redirect - Router skill + workflow skill references * fix(media-use): oxfmt formatting for resolve + providers Format brand/heygen-search/providers/sfx providers + resolve.mjs (CI oxfmt --check gate). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(media-use): align providers with the real heygen CLI surface (v0.1.6) Verified live against the official Go `heygen` CLI v0.1.6 with a valid key: - Caller attribution: pass `--headers 'X-HeyGen-Client-Source: media-use'` (the allowlisted flag the CLI added for media-use in v0.1.6). The old `--x-source media-use` was never a real flag and broke every call. - Command is `asset search` (the `list` leaf was dropped in v0.1.6), not `asset search list`. - `--min-score` is sent server-side: honored by `audio sounds list`, but the `asset search` backend rejects it and returns no score field, so only the audio providers pass it (image/icon don't). - Drop hardcoded `ext` so resolve.mjs derives it from the URL: catalog icons are .png (not .svg), some BGM is .wav (not .mp3). Also: surface CLI/auth failures on stderr instead of swallowing them as 'no results', carry icon width/height through, and document the heygen CLI install + >= v0.1.6 requirement. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
60 lines
1.6 KiB
JavaScript
60 lines
1.6 KiB
JavaScript
import { readFileSync, existsSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
function findDesignSpec(projectDir) {
|
|
for (const name of ["frame.md", "design.md", "DESIGN.md"]) {
|
|
const p = join(projectDir, name);
|
|
if (existsSync(p)) return { path: p, name };
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function parseFrontmatter(content) {
|
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
if (!match) return null;
|
|
const yaml = match[1];
|
|
const tokens = {};
|
|
for (const line of yaml.split("\n")) {
|
|
const m = line.match(/^\s*(\w[\w-]*):\s*(.+)/);
|
|
if (m) tokens[m[1]] = m[2].trim().replace(/^["']|["']$/g, "");
|
|
}
|
|
return tokens;
|
|
}
|
|
|
|
function extractColors(tokens) {
|
|
const colors = [];
|
|
for (const [k, v] of Object.entries(tokens)) {
|
|
if (typeof v === "string" && /^#[0-9a-fA-F]{3,8}$/.test(v)) {
|
|
colors.push({ name: k, hex: v });
|
|
}
|
|
}
|
|
return colors;
|
|
}
|
|
|
|
export const brandProvider = {
|
|
async search(intent, { projectDir } = {}) {
|
|
if (!projectDir) return null;
|
|
const spec = findDesignSpec(projectDir);
|
|
if (!spec) return null;
|
|
const content = readFileSync(spec.path, "utf8");
|
|
const tokens = parseFrontmatter(content);
|
|
if (!tokens) return null;
|
|
const colors = extractColors(tokens);
|
|
return {
|
|
localPath: spec.path,
|
|
source: "local",
|
|
ext: ".md",
|
|
metadata: {
|
|
description: "Brand tokens from " + spec.name,
|
|
provider: "design_spec",
|
|
provenance: {
|
|
file: spec.name,
|
|
colors,
|
|
font: tokens.font || tokens.typography || null,
|
|
logo: tokens.logo || null,
|
|
},
|
|
},
|
|
};
|
|
},
|
|
};
|