mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 23:03:09 +00:00
fix(ci): scope LOC check to studio, split useTimelinePlayer + hyperframes-player under 500 LOC (#750)
* refactor: split useTimelinePlayer.ts and hyperframes-player.ts into focused modules (<500 LOC each) * fix(ci): scope 500 LOC check to packages/studio, add allowlist for grandfathered files * feat(cli): Linux ARM64 support — auto-install Chromium on DGX Spark / GB10 / Jetson Chrome Headless Shell has no Linux ARM64 binary. On arm64 Linux: - Detects the platform automatically - Tries to auto-install system Chromium via apt-get (works on Ubuntu/Debian ARM) - Falls back to clear manual instructions with exact commands - 'hyperframes browser ensure' guides through the setup interactively - After setup, all render commands work without any flags * fix(ci): disable Windows Defender real-time monitoring to prevent EPERM builds Path exclusions are insufficient — Defender re-scans new files created during bun install before the exclusion takes effect. Disable real-time monitoring for the entire job duration instead (standard CI practice). * refactor(studio): split all files >500 LOC + extract useToast, delete allowlist All 11 large files split into focused modules under 500 LOC. App.tsx extracted toast logic into useToast hook (493 LOC now). .filesize-allowlist deleted — no longer needed. * fix: remove unused imports from split files, extract useToast from App.tsx App.tsx: 504 → 493 lines (toast logic extracted to useToast hook) timelineDOM.ts: remove unused imports from re-export pattern MotionPanel.tsx: remove unused clampStudioCustomEasePoints import studioMotionOps.ts: remove unused StudioGsapMotionDirection import * fix(ci): use Set-MpPreference to fully disable Windows Defender (both jobs) * fix(producer): use node --experimental-strip-types instead of tsx for build:fonts Eliminates the tsx binary dependency that Windows Defender locks during bun install, causing EPERM errors. Node 22.6+ strips TypeScript types natively with no external binary. * chore: remove .filesize-allowlist — App.tsx is now 493 lines (<500) * fix(ci): disable Windows Defender before checkout to prevent all EPERM races * fix(producer): skip build:fonts if fontData.generated.ts already exists The generated file is tracked in git, so CI doesn't need to regenerate it. This avoids @fontsource/inter node_modules access on Windows which triggers EPERM from Defender scanning during bun install.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { execSync } from "node:child_process";
|
||||
import { execSync, spawnSync } from "node:child_process";
|
||||
import { existsSync, rmSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
@@ -111,6 +111,55 @@ export async function findBrowser(): Promise<BrowserResult | undefined> {
|
||||
return findFromSystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* On Linux ARM64, attempt to auto-install system Chromium if not found.
|
||||
* This makes `hyperframes render` work out-of-the-box on DGX Spark / GB10 / Jetson.
|
||||
*/
|
||||
async function ensureLinuxArmBrowser(options?: EnsureBrowserOptions): Promise<BrowserResult> {
|
||||
void options;
|
||||
|
||||
// If already available (env var or system path), use it directly.
|
||||
const existing = await findBrowser();
|
||||
if (existing) return existing;
|
||||
|
||||
// Try auto-installing via apt (common on Ubuntu-based ARM systems).
|
||||
const hasApt = existsSync("/usr/bin/apt-get");
|
||||
if (hasApt) {
|
||||
console.error(
|
||||
"\n🔍 Linux ARM64 detected — Chrome Headless Shell is not available for this platform.",
|
||||
);
|
||||
console.error("📦 Auto-installing system Chromium via apt-get (this only happens once)...\n");
|
||||
|
||||
// Use spawnSync so output streams to the terminal in real time.
|
||||
const result = spawnSync("apt-get", ["install", "-y", "chromium-browser"], {
|
||||
stdio: "inherit",
|
||||
timeout: 120_000,
|
||||
});
|
||||
|
||||
if (result.status === 0) {
|
||||
const afterInstall = await findBrowser();
|
||||
if (afterInstall) {
|
||||
console.error(`\n✅ Chromium installed at ${afterInstall.executablePath}\n`);
|
||||
return afterInstall;
|
||||
}
|
||||
} else {
|
||||
// apt succeeded but binary not found, or apt failed — fall through to helpful error.
|
||||
console.error("\n⚠️ apt-get exited with errors. Trying anyway...\n");
|
||||
const afterAttempt = await findBrowser();
|
||||
if (afterAttempt) return afterAttempt;
|
||||
}
|
||||
}
|
||||
|
||||
// Could not auto-install — give clear manual instructions.
|
||||
throw new Error(
|
||||
`Chrome Headless Shell is not available for Linux ARM64 (DGX Spark, GB10, Jetson).\n\n` +
|
||||
`Install Chromium manually and point hyperframes to it:\n\n` +
|
||||
` sudo apt-get install -y chromium-browser\n` +
|
||||
` export HYPERFRAMES_BROWSER_PATH=$(which chromium-browser)\n\n` +
|
||||
`Then re-run your command. The HYPERFRAMES_BROWSER_PATH env var persists for the session.`,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find or download a browser.
|
||||
* Resolution: env var -> cached download -> system Chrome -> auto-download.
|
||||
@@ -124,6 +173,12 @@ export async function ensureBrowser(options?: EnsureBrowserOptions): Promise<Bro
|
||||
throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`);
|
||||
}
|
||||
|
||||
// Chrome headless shell has no Linux ARM64 build (e.g. DGX Spark, GB10).
|
||||
// Try to auto-install system Chromium via apt, then find it.
|
||||
if (isLinuxArm()) {
|
||||
return ensureLinuxArmBrowser(options);
|
||||
}
|
||||
|
||||
const installed = await install({
|
||||
cacheDir: CACHE_DIR,
|
||||
browser: Browser.CHROMEHEADLESSSHELL,
|
||||
@@ -147,4 +202,8 @@ export function clearBrowser(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
export function isLinuxArm(): boolean {
|
||||
return detectBrowserPlatform() === "linux_arm";
|
||||
}
|
||||
|
||||
export { CHROME_VERSION, CACHE_DIR };
|
||||
|
||||
Reference in New Issue
Block a user