fix(cli): use multi-strategy runtime resolver for snapshot

Use loadRuntimeSource() from runtimeSource.ts instead of a single
hardcoded path. Tries: build from source (dev), inlined constant
(production), pre-built artifact (fallback). Fixes snapshot in dev
mode where __dirname is src/commands/ not dist/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
ukimsanov
2026-04-28 14:36:34 -04:00
co-authored by Claude Opus 4.7
parent 8f97edb2b9
commit ce4bcc47c0
+6 -11
View File
@@ -2,15 +2,11 @@ import { spawn } from "node:child_process";
import { defineCommand } from "citty"; import { defineCommand } from "citty";
import { existsSync, mkdtempSync, readFileSync, mkdirSync, rmSync } from "node:fs"; import { existsSync, mkdtempSync, readFileSync, mkdirSync, rmSync } from "node:fs";
import { tmpdir } from "node:os"; import { tmpdir } from "node:os";
import { resolve, join, dirname, relative, isAbsolute } from "node:path"; import { resolve, join, relative, isAbsolute } from "node:path";
import { fileURLToPath } from "node:url";
import { resolveProject } from "../utils/project.js"; import { resolveProject } from "../utils/project.js";
import { c } from "../ui/colors.js"; import { c } from "../ui/colors.js";
import type { Example } from "./_examples.js"; import type { Example } from "./_examples.js";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
/** Maximum time a single-frame FFmpeg extract is allowed to run. Mirrors the /** Maximum time a single-frame FFmpeg extract is allowed to run. Mirrors the
* default applied by `@hyperframes/engine`'s `runFfmpeg` so a pathological * default applied by `@hyperframes/engine`'s `runFfmpeg` so a pathological
* clip (corrupt media, stalled network mount, codec edge case) cannot wedge * clip (corrupt media, stalled network mount, codec edge case) cannot wedge
@@ -103,12 +99,11 @@ async function captureSnapshots(
let html = await bundleToSingleHtml(projectDir); let html = await bundleToSingleHtml(projectDir);
// Inject local runtime if available. // Inject local runtime if available.
// The runtime IIFE is copied into the CLI dist during build (build:runtime), // Uses the same multi-strategy resolver as the studio preview server
// so it lives alongside cli.js. The old ../../../core/dist/ path only worked // (runtimeSource.ts) so snapshot works in dev (tsx), built CLI, and npx.
// in the monorepo dev layout and broke for published/npx installs. const { loadRuntimeSource } = await import("../server/runtimeSource.js");
const runtimePath = resolve(__dirname, "hyperframe.runtime.iife.js"); const runtimeSource = await loadRuntimeSource();
if (existsSync(runtimePath)) { if (runtimeSource) {
const runtimeSource = readFileSync(runtimePath, "utf-8");
html = html.replace( html = html.replace(
/<script[^>]*data-hyperframes-preview-runtime[^>]*src="[^"]*"[^>]*><\/script>/, /<script[^>]*data-hyperframes-preview-runtime[^>]*src="[^"]*"[^>]*><\/script>/,
() => `<script data-hyperframes-preview-runtime="1">${runtimeSource}</script>`, () => `<script data-hyperframes-preview-runtime="1">${runtimeSource}</script>`,