hyperframes 0.7.77 → 0.7.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -50,7 +50,7 @@ var VERSION;
50
50
  var init_version = __esm({
51
51
  "src/version.ts"() {
52
52
  "use strict";
53
- VERSION = true ? "0.7.77" : "0.0.0-dev";
53
+ VERSION = true ? "0.7.78" : "0.0.0-dev";
54
54
  }
55
55
  });
56
56
 
@@ -62886,6 +62886,15 @@ function memoryAdaptiveCacheBytesMb() {
62886
62886
  if (total <= LOW_MEMORY_TOTAL_MB_THRESHOLD) return 256;
62887
62887
  return DEFAULT_CONFIG2.frameDataUriCacheBytesLimitMb;
62888
62888
  }
62889
+ function isDrawElementPlatform(platform10) {
62890
+ return platform10 === "darwin" || platform10 === "win32";
62891
+ }
62892
+ function resolveDefaultDrawElement(args) {
62893
+ if (!args.useDrawElement) return false;
62894
+ if (args.explicitOptIn) return true;
62895
+ if (!isDrawElementPlatform(args.platform) || args.browserGpuMode === "software") return false;
62896
+ return args.workerEncode;
62897
+ }
62889
62898
  function resolveConfig(overrides) {
62890
62899
  const env = (key2) => process.env[key2];
62891
62900
  const envNum = (key2, fallback) => {
@@ -63014,12 +63023,13 @@ function resolveConfig(overrides) {
63014
63023
  ...overrides
63015
63024
  };
63016
63025
  const explicitDrawElementOptIn = env("PRODUCER_EXPERIMENTAL_FAST_CAPTURE") === "true" || overrides?.useDrawElement === true;
63017
- if (merged.useDrawElement && !explicitDrawElementOptIn && !(process.platform === "darwin" && merged.browserGpuMode !== "software")) {
63018
- merged.useDrawElement = false;
63019
- }
63020
- if (merged.useDrawElement && !explicitDrawElementOptIn && !merged.enableDrawElementWorkerEncode) {
63021
- merged.useDrawElement = false;
63022
- }
63026
+ merged.useDrawElement = resolveDefaultDrawElement({
63027
+ useDrawElement: merged.useDrawElement,
63028
+ explicitOptIn: explicitDrawElementOptIn,
63029
+ platform: process.platform,
63030
+ browserGpuMode: merged.browserGpuMode,
63031
+ workerEncode: merged.enableDrawElementWorkerEncode
63032
+ });
63023
63033
  const explicitForceScreenshotOptOut = env("PRODUCER_FORCE_SCREENSHOT") === "false" || overrides?.forceScreenshot === false;
63024
63034
  if (explicitForceScreenshotOptOut) {
63025
63035
  merged.forceScreenshotExplicitlyOptedOut = true;
@@ -64510,15 +64520,22 @@ function instrumentAcceleratedCanvases() {
64510
64520
  return ctx;
64511
64521
  };
64512
64522
  }
64513
- async function detectSwiftShader(page) {
64523
+ function classifyGpuRenderer(renderer) {
64524
+ if (!renderer) return void 0;
64525
+ const r2 = renderer.toLowerCase();
64526
+ const backend = r2.includes("swiftshader") ? "swiftshader" : r2.includes("metal") ? "metal" : r2.includes("direct3d11") || r2.includes("d3d11") ? "d3d11" : r2.includes("direct3d9") || r2.includes("d3d9") ? "d3d9" : r2.includes("vulkan") ? "vulkan" : r2.includes("opengl") || r2.includes("angle") ? "opengl" : "other";
64527
+ const vendor = r2.includes("apple") ? "apple" : r2.includes("nvidia") ? "nvidia" : r2.includes("amd") || r2.includes("radeon") ? "amd" : r2.includes("intel") ? "intel" : r2.includes("microsoft") ? "microsoft" : "other";
64528
+ return `${backend}/${vendor}`;
64529
+ }
64530
+ async function detectGpuBackend(page) {
64514
64531
  return page.evaluate(() => {
64515
64532
  const canvas = document.createElement("canvas");
64516
64533
  const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
64517
- if (!gl) return false;
64534
+ if (!gl) return { isSwiftShader: false, renderer: null };
64518
64535
  const ext = gl.getExtension("WEBGL_debug_renderer_info");
64519
- if (!ext) return false;
64536
+ if (!ext) return { isSwiftShader: false, renderer: null };
64520
64537
  const renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
64521
- return renderer.toLowerCase().includes("swiftshader");
64538
+ return { isSwiftShader: renderer.toLowerCase().includes("swiftshader"), renderer };
64522
64539
  });
64523
64540
  }
64524
64541
  async function injectDrawElementCanvas(page, width, height) {
@@ -66248,7 +66265,9 @@ async function initDrawElementOrTransparentBackground(session, page, logInitPhas
66248
66265
  );
66249
66266
  }
66250
66267
  if (useDrawElement) {
66251
- session.isSwiftShader = await detectSwiftShader(page);
66268
+ const gpuBackend = await detectGpuBackend(page);
66269
+ session.isSwiftShader = gpuBackend.isSwiftShader;
66270
+ session.gpuRenderer = classifyGpuRenderer(gpuBackend.renderer);
66252
66271
  const transparent = session.options.format === "png";
66253
66272
  async function routeToFallback() {
66254
66273
  session.captureMode = session.launchCaptureMode;
@@ -67960,6 +67979,7 @@ function getCapturePerfSummary(session) {
67960
67979
  beginFrameNoDamage: session.beginFrameNoDamageCount,
67961
67980
  beginFrameHasDamage: session.beginFrameHasDamageCount,
67962
67981
  captureMode: session.captureMode,
67982
+ gpuRenderer: session.gpuRenderer,
67963
67983
  deGateReason: session.deGateReason,
67964
67984
  deFallbackTrigger: session.deFallbackTrigger,
67965
67985
  deWorkerEncode: session.workerEncodeEnabled ?? false,
@@ -88550,8 +88570,10 @@ __export(system_exports, {
88550
88570
  bytesToMb: () => bytesToMb,
88551
88571
  getAvailableMemoryMb: () => getAvailableMemoryMb,
88552
88572
  getFreeDiskMb: () => getFreeDiskMb,
88573
+ getPowerState: () => getPowerState,
88553
88574
  getShmSizeMb: () => getShmSizeMb,
88554
- getSystemMeta: () => getSystemMeta
88575
+ getSystemMeta: () => getSystemMeta,
88576
+ parsePmsetPowerSource: () => parsePmsetPowerSource
88555
88577
  });
88556
88578
  import { cpus as cpus2, freemem as freemem2, platform as platform3, release as release3 } from "os";
88557
88579
  import { existsSync as existsSync20, readFileSync as readFileSync10, statfsSync } from "fs";
@@ -88626,6 +88648,31 @@ function getFreeDiskMb(path2 = ".") {
88626
88648
  return null;
88627
88649
  }
88628
88650
  }
88651
+ function parsePmsetPowerSource(raw) {
88652
+ const m2 = raw.match(/Now drawing from '([^']+)'/);
88653
+ if (!m2) return null;
88654
+ return m2[1] === "Battery Power";
88655
+ }
88656
+ function getPowerState() {
88657
+ if (platform3() !== "darwin") {
88658
+ return { on_battery: null, low_power_mode: null };
88659
+ }
88660
+ let on_battery = null;
88661
+ let low_power_mode = null;
88662
+ try {
88663
+ on_battery = parsePmsetPowerSource(
88664
+ execSync2("pmset -g batt", { encoding: "utf-8", timeout: 2e3 })
88665
+ );
88666
+ } catch {
88667
+ }
88668
+ try {
88669
+ const raw = execSync2("pmset -g", { encoding: "utf-8", timeout: 2e3 });
88670
+ const m2 = raw.match(/lowpowermode\s+(\d)/);
88671
+ if (m2) low_power_mode = m2[1] === "1";
88672
+ } catch {
88673
+ }
88674
+ return { on_battery, low_power_mode };
88675
+ }
88629
88676
  function getAvailableMemoryMb() {
88630
88677
  const fallback = bytesToMb(freemem2());
88631
88678
  if (platform3() === "darwin") {
@@ -88855,6 +88902,14 @@ __export(events_exports, {
88855
88902
  trackSkillsInstallSkipped: () => trackSkillsInstallSkipped,
88856
88903
  trackTranscribeUnavailable: () => trackTranscribeUnavailable
88857
88904
  });
88905
+ function powerStateFields() {
88906
+ if (!shouldTrack()) return {};
88907
+ const power = getPowerState();
88908
+ return {
88909
+ on_battery: power.on_battery ?? void 0,
88910
+ low_power_mode: power.low_power_mode ?? void 0
88911
+ };
88912
+ }
88858
88913
  function runIdField(runId3) {
88859
88914
  return runId3 !== void 0 ? { run_id: runId3 } : {};
88860
88915
  }
@@ -88892,6 +88947,7 @@ function renderObservabilityEventProperties(props) {
88892
88947
  de_worker_inversion: props.captureDeWorkerInversion,
88893
88948
  de_pre_inversion_workers: props.captureDePreInversionWorkers,
88894
88949
  de_parallel_router: props.captureDeParallelRouter,
88950
+ gpu_renderer: props.captureDeGpuRenderer,
88895
88951
  de_pre_router_workers: props.captureDePreRouterWorkers,
88896
88952
  de_self_verify_fallback: props.captureDeSelfVerifyFallback,
88897
88953
  de_fallback_reason: props.captureDeFallbackReason,
@@ -88960,6 +89016,7 @@ function trackRenderComplete(props) {
88960
89016
  de_parallel_router: props.deParallelRouter,
88961
89017
  de_pre_router_workers: props.dePreRouterWorkers,
88962
89018
  de_gate_reason: props.deGateReason,
89019
+ gpu_renderer: props.gpuRenderer,
88963
89020
  de_worker_encode: props.deWorkerEncode,
88964
89021
  de_verify_armed: props.deVerifyArmed,
88965
89022
  de_verify_checked: props.deVerifyChecked,
@@ -88975,6 +89032,7 @@ function trackRenderComplete(props) {
88975
89032
  de_blank_recaptures: props.deBlankRecaptures,
88976
89033
  de_boundary_frames: props.deBoundaryFrames,
88977
89034
  de_ncpr_fallbacks: props.deNcprFallbacks,
89035
+ ...powerStateFields(),
88978
89036
  source: props.source ?? "cli",
88979
89037
  composition_duration_ms: props.compositionDurationMs,
88980
89038
  composition_width: props.compositionWidth,
@@ -89027,6 +89085,11 @@ function trackRenderError(props) {
89027
89085
  elapsed_ms: props.elapsedMs,
89028
89086
  peak_memory_mb: props.peakMemoryMb,
89029
89087
  memory_free_mb: props.memoryFreeMb,
89088
+ ...powerStateFields(),
89089
+ // gpu_renderer arrives via renderObservabilityEventProperties below:
89090
+ // on the failure path perfSummary is never built, so live capture
89091
+ // observability is the only source. Backend attribution matters MOST
89092
+ // here — a win32 D3D11 crash is what the rollout is watching for.
89030
89093
  ...renderObservabilityEventProperties(props)
89031
89094
  },
89032
89095
  props.distinctId
@@ -89193,6 +89256,7 @@ var init_events = __esm({
89193
89256
  init_feedbackRating();
89194
89257
  init_client();
89195
89258
  init_config();
89259
+ init_system();
89196
89260
  }
89197
89261
  });
89198
89262
 
@@ -93071,6 +93135,25 @@ var init_normalize = __esm({
93071
93135
  }
93072
93136
  });
93073
93137
 
93138
+ // src/telemetry/skill.ts
93139
+ var skill_exports = {};
93140
+ __export(skill_exports, {
93141
+ SKILL_SLUG: () => SKILL_SLUG,
93142
+ normalizeSkillSlug: () => normalizeSkillSlug
93143
+ });
93144
+ function normalizeSkillSlug(raw) {
93145
+ if (typeof raw !== "string") return void 0;
93146
+ const slug = raw.trim();
93147
+ return SKILL_SLUG.test(slug) ? slug : void 0;
93148
+ }
93149
+ var SKILL_SLUG;
93150
+ var init_skill = __esm({
93151
+ "src/telemetry/skill.ts"() {
93152
+ "use strict";
93153
+ SKILL_SLUG = /^[a-z0-9][a-z0-9-]{0,63}$/;
93154
+ }
93155
+ });
93156
+
93074
93157
  // src/utils/projectConfig.ts
93075
93158
  var projectConfig_exports = {};
93076
93159
  __export(projectConfig_exports, {
@@ -93081,6 +93164,7 @@ __export(projectConfig_exports, {
93081
93164
  projectConfigPath: () => projectConfigPath,
93082
93165
  readProjectConfig: () => readProjectConfig,
93083
93166
  resolveAutoProxy: () => resolveAutoProxy,
93167
+ seedProjectAuthoringSkill: () => seedProjectAuthoringSkill,
93084
93168
  writeProjectConfig: () => writeProjectConfig
93085
93169
  });
93086
93170
  import { readFileSync as readFileSync16, writeFileSync as writeFileSync10 } from "fs";
@@ -93108,7 +93192,10 @@ function normalizeConfig(partial) {
93108
93192
  },
93109
93193
  media: {
93110
93194
  autoProxy: typeof partial.media?.autoProxy === "boolean" ? partial.media.autoProxy : DEFAULT_PROJECT_CONFIG.media?.autoProxy
93111
- }
93195
+ },
93196
+ // Slug-gate on read so a hand-edited or corrupt value never reaches the
93197
+ // telemetry stream; an invalid slug simply drops the attribution.
93198
+ authoringSkill: normalizeSkillSlug(partial.authoringSkill)
93112
93199
  };
93113
93200
  }
93114
93201
  function writeProjectConfig(projectDir, config = DEFAULT_PROJECT_CONFIG) {
@@ -93124,11 +93211,44 @@ function resolveAutoProxy(projectDir, flagValue) {
93124
93211
  }
93125
93212
  return loadProjectConfig(projectDir).media?.autoProxy ?? true;
93126
93213
  }
93214
+ function isJsonObject(value) {
93215
+ return typeof value === "object" && value !== null && !Array.isArray(value);
93216
+ }
93217
+ function isFileNotFound(error) {
93218
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
93219
+ }
93220
+ function seedProjectAuthoringSkill(projectDir, rawSkill) {
93221
+ const skill = normalizeSkillSlug(rawSkill);
93222
+ if (!skill) return;
93223
+ const path2 = projectConfigPath(projectDir);
93224
+ let text2;
93225
+ try {
93226
+ text2 = readFileSync16(path2, "utf-8");
93227
+ } catch (error) {
93228
+ if (isFileNotFound(error)) {
93229
+ try {
93230
+ writeProjectConfig(projectDir, { ...DEFAULT_PROJECT_CONFIG, authoringSkill: skill });
93231
+ } catch {
93232
+ }
93233
+ }
93234
+ return;
93235
+ }
93236
+ try {
93237
+ const parsed = JSON.parse(text2);
93238
+ if (!isJsonObject(parsed)) return;
93239
+ if (normalizeSkillSlug(parsed.authoringSkill)) return;
93240
+ parsed.authoringSkill = skill;
93241
+ const indent = /\n([ \t]+)"/.exec(text2)?.[1] ?? " ";
93242
+ writeFileSync10(path2, JSON.stringify(parsed, null, indent) + "\n", "utf-8");
93243
+ } catch {
93244
+ }
93245
+ }
93127
93246
  var PROJECT_CONFIG_FILENAME, PROJECT_CONFIG_SCHEMA_URL, DEFAULT_PROJECT_CONFIG;
93128
93247
  var init_projectConfig = __esm({
93129
93248
  "src/utils/projectConfig.ts"() {
93130
93249
  "use strict";
93131
93250
  init_registry2();
93251
+ init_skill();
93132
93252
  PROJECT_CONFIG_FILENAME = "hyperframes.json";
93133
93253
  PROJECT_CONFIG_SCHEMA_URL = "https://hyperframes.heygen.com/schema/hyperframes.json";
93134
93254
  DEFAULT_PROJECT_CONFIG = {
@@ -95870,6 +95990,7 @@ function renderObservabilityTelemetryPayload(observability) {
95870
95990
  captureDeWorkerInversion: capture2.deWorkerInversion,
95871
95991
  captureDePreInversionWorkers: capture2.dePreInversionWorkers,
95872
95992
  captureDeParallelRouter: capture2.deParallelRouter,
95993
+ captureDeGpuRenderer: capture2.deGpuRenderer,
95873
95994
  captureDePreRouterWorkers: capture2.dePreRouterWorkers,
95874
95995
  captureDeSelfVerifyFallback: capture2.deSelfVerifyFallback,
95875
95996
  captureDeFallbackReason: capture2.deFallbackReason,
@@ -110227,6 +110348,9 @@ function aggregateDrawElement(perfs, de2) {
110227
110348
  const gateReasons = [
110228
110349
  ...new Set(perfs.map((p2) => p2.deGateReason).filter((r2) => !!r2))
110229
110350
  ].sort();
110351
+ const gpuRenderers = [
110352
+ ...new Set(perfs.map((p2) => p2.gpuRenderer).filter((r2) => !!r2))
110353
+ ].sort();
110230
110354
  const drain = de2.drainStats;
110231
110355
  return {
110232
110356
  mode: modes.join("|") || "unknown",
@@ -110237,6 +110361,7 @@ function aggregateDrawElement(perfs, de2) {
110237
110361
  parallelRouter: de2.parallelRouter ?? "none",
110238
110362
  preRouterWorkers: de2.preRouterWorkers,
110239
110363
  gateReason: gateReasons.length > 0 ? gateReasons.join("|") : void 0,
110364
+ gpuRenderer: gpuRenderers.length > 0 ? gpuRenderers.join("|") : void 0,
110240
110365
  workerEncode: perfs.some((p2) => p2.deWorkerEncode),
110241
110366
  verifyArmed: perfs.reduce((sum, p2) => sum + (p2.deVerifyArmed ?? 0), 0),
110242
110367
  verifyChecked: drain?.verifyChecked ?? 0,
@@ -117423,6 +117548,10 @@ function resolveVideoExtractionPolicy(env = process.env) {
117423
117548
  const maxTransientRetries = failureMode !== "off" && env.HF_VIDEO_EXTRACTION_MAX_RETRIES?.trim() === "1" ? 1 : 0;
117424
117549
  return { failureMode, maxTransientRetries };
117425
117550
  }
117551
+ function assertVideoExtractionSucceeded(result) {
117552
+ const error = buildVideoExtractionStageError(result);
117553
+ if (error) throw error;
117554
+ }
117426
117555
  function buildVideoExtractionStageError(result) {
117427
117556
  if (result.success && result.errors.length === 0) return null;
117428
117557
  const counts = /* @__PURE__ */ new Map();
@@ -121335,7 +121464,7 @@ function resolveInversionRetryPlan(args) {
121335
121464
  };
121336
121465
  }
121337
121466
  function shouldPreferParallelDrawElement(args) {
121338
- return args.routerEnabled && args.workerCount > 1 && typeof args.requestedWorkers !== "number" && args.useDrawElement && !args.deCompileGate && !args.forceScreenshot && args.outputFormat === "mp4" && args.minFrames > 0 && args.totalFrames >= args.minFrames && !args.layeredOrEffectRoute && !args.supersampling && !args.probeDeGated && !args.experimentalParallelDeOptIn && // RAM floor: routed parallel DE runs 3 concurrent hardware-GPU Chrome
121467
+ return args.routerEnabled && args.parallelStreamingAvailable && args.workerCount > 1 && typeof args.requestedWorkers !== "number" && args.useDrawElement && !args.deCompileGate && !args.forceScreenshot && args.outputFormat === "mp4" && args.minFrames > 0 && args.totalFrames >= args.minFrames && !args.layeredOrEffectRoute && !args.supersampling && !args.probeDeGated && !args.experimentalParallelDeOptIn && // RAM floor: routed parallel DE runs 3 concurrent hardware-GPU Chrome
121339
121468
  // instances. On a 16 GB machine that produced vertical black slabs in the
121340
121469
  // final MP4 (wild report, CLI 0.7.52) — compositor tiles evicted under
121341
121470
  // GPU/memory pressure, and sampled self-verify can miss partial-frame
@@ -121929,8 +122058,8 @@ async function executeRenderPipeline(input2) {
121929
122058
  });
121930
122059
  const deParallelRouterEnabled = process.env.HF_DE_PARALLEL_ROUTER === "true";
121931
122060
  const deParallelMinFramesRaw = process.env.HF_DE_PARALLEL_MIN_FRAMES;
121932
- const deParallelMinFramesNum = deParallelMinFramesRaw === void 0 || deParallelMinFramesRaw.trim() === "" ? 2e3 : Number(deParallelMinFramesRaw);
121933
- const deParallelMinFrames = Number.isFinite(deParallelMinFramesNum) ? deParallelMinFramesNum : 2e3;
122061
+ const deParallelMinFramesNum = deParallelMinFramesRaw === void 0 || deParallelMinFramesRaw.trim() === "" ? 700 : Number(deParallelMinFramesRaw);
122062
+ const deParallelMinFrames = Number.isFinite(deParallelMinFramesNum) ? deParallelMinFramesNum : 700;
121934
122063
  const deParallelMinMemRaw = process.env.HF_DE_PARALLEL_MIN_MEM_MB;
121935
122064
  const deParallelMinMemNum = deParallelMinMemRaw === void 0 || deParallelMinMemRaw.trim() === "" ? 24576 : Number(deParallelMinMemRaw);
121936
122065
  const deParallelMinMemoryMb = Number.isFinite(deParallelMinMemNum) ? deParallelMinMemNum : 24576;
@@ -121948,6 +122077,15 @@ async function executeRenderPipeline(input2) {
121948
122077
  probeDeGated: probeSession !== null && probeSession.captureMode !== "drawelement" && !probeSession.deInitDeferred,
121949
122078
  experimentalParallelDeOptIn: process.env.PRODUCER_EXPERIMENTAL_FAST_CAPTURE === "true" || process.env.HF_DE_PARALLEL_STREAM === "true",
121950
122079
  routerEnabled: deParallelRouterEnabled,
122080
+ // Router pins 3 workers for the streaming path; don't pin when the
122081
+ // duration cap (or any other streaming gate) would turn that path off.
122082
+ parallelStreamingAvailable: shouldUseStreamingEncode(
122083
+ cfg,
122084
+ outputFormat,
122085
+ 3,
122086
+ job.duration,
122087
+ true
122088
+ ),
121951
122089
  totalMemoryMb: Math.round(totalmem2() / (1024 * 1024)),
121952
122090
  minMemoryMb: deParallelMinMemoryMb
121953
122091
  });
@@ -122071,7 +122209,12 @@ async function executeRenderPipeline(input2) {
122071
122209
  // to 3 workers regardless of calibration is the leading suspect for
122072
122210
  // any resource-pressure failure unique to this cohort.
122073
122211
  dePreInversionWorkers: deWorkerInversion ? preRoutingWorkerCount : void 0,
122074
- dePreRouterWorkers: deParallelRouter ? preRoutingWorkerCount : void 0
122212
+ dePreRouterWorkers: deParallelRouter ? preRoutingWorkerCount : void 0,
122213
+ // Same rationale as the counters above: carried on live capture
122214
+ // observability, not only the success-path perfSummary, so a crash /
122215
+ // OOM / timeout still reports which GPU backend it happened on. That
122216
+ // is the cohort the win32 D3D11 rollout most needs to attribute.
122217
+ deGpuRenderer: probeSession?.gpuRenderer
122075
122218
  });
122076
122219
  observability.checkpoint("worker_resolution", "resolved", {
122077
122220
  workerCount,
@@ -124194,6 +124337,7 @@ var init_server = __esm({
124194
124337
  init_renderRequest();
124195
124338
  DEFAULT_SERVER_FPS = { num: 30, den: 1 };
124196
124339
  SAFE_RENDER_ERROR_CODES = /* @__PURE__ */ new Set([
124340
+ "INVALID_VIDEO_METADATA",
124197
124341
  "VIDEO_SOURCE_UNRENDERABLE",
124198
124342
  "VIDEO_EXTRACTION_FAILED"
124199
124343
  ]);
@@ -124578,6 +124722,154 @@ import { dirname as dirname28, join as join63 } from "path";
124578
124722
  import { existsSync as existsSync56, readFileSync as readFileSync33 } from "fs";
124579
124723
  import { fileURLToPath as fileURLToPath7 } from "url";
124580
124724
  import { promisify as promisify4 } from "util";
124725
+ function metadataError(field, expectation) {
124726
+ throw new PlanVideosMetadataError(`${field} ${expectation}`);
124727
+ }
124728
+ function readRecord(value, field) {
124729
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
124730
+ metadataError(field, "must be an object");
124731
+ }
124732
+ return value;
124733
+ }
124734
+ function readNonEmptyString(value, field) {
124735
+ if (typeof value !== "string" || value.length === 0) {
124736
+ metadataError(field, "must be a non-empty string");
124737
+ }
124738
+ return value;
124739
+ }
124740
+ function readString(value, field) {
124741
+ if (typeof value !== "string") {
124742
+ metadataError(field, "must be a string");
124743
+ }
124744
+ return value;
124745
+ }
124746
+ function readFiniteNumber(value, field) {
124747
+ if (typeof value !== "number" || !Number.isFinite(value)) {
124748
+ metadataError(field, "must be a finite number");
124749
+ }
124750
+ return value;
124751
+ }
124752
+ function readBoolean(value, field) {
124753
+ if (typeof value !== "boolean") {
124754
+ metadataError(field, "must be boolean");
124755
+ }
124756
+ return value;
124757
+ }
124758
+ function readPositiveInteger(value, field) {
124759
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
124760
+ metadataError(field, "must be a positive integer");
124761
+ }
124762
+ return value;
124763
+ }
124764
+ function readNonNegativeInteger(value, field) {
124765
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
124766
+ metadataError(field, "must be a non-negative integer");
124767
+ }
124768
+ return value;
124769
+ }
124770
+ function readVideoMetadata(value, field) {
124771
+ const record = readRecord(value, field);
124772
+ let colorSpace = null;
124773
+ if (record.colorSpace !== null) {
124774
+ const color = readRecord(record.colorSpace, `${field}.colorSpace`);
124775
+ colorSpace = {
124776
+ colorTransfer: readString(color.colorTransfer, `${field}.colorSpace.colorTransfer`),
124777
+ colorPrimaries: readString(color.colorPrimaries, `${field}.colorSpace.colorPrimaries`),
124778
+ colorSpace: readString(color.colorSpace, `${field}.colorSpace.colorSpace`)
124779
+ };
124780
+ }
124781
+ return {
124782
+ durationSeconds: readFiniteNumber(record.durationSeconds, `${field}.durationSeconds`),
124783
+ videoStreamDurationSeconds: readFiniteNumber(
124784
+ record.videoStreamDurationSeconds,
124785
+ `${field}.videoStreamDurationSeconds`
124786
+ ),
124787
+ width: readPositiveInteger(record.width, `${field}.width`),
124788
+ height: readPositiveInteger(record.height, `${field}.height`),
124789
+ fps: readFiniteNumber(record.fps, `${field}.fps`),
124790
+ videoCodec: readNonEmptyString(record.videoCodec, `${field}.videoCodec`),
124791
+ hasAudio: readBoolean(record.hasAudio, `${field}.hasAudio`),
124792
+ isVFR: readBoolean(record.isVFR, `${field}.isVFR`),
124793
+ hasAlpha: readBoolean(record.hasAlpha, `${field}.hasAlpha`),
124794
+ colorSpace
124795
+ };
124796
+ }
124797
+ function parsePlanVideosJson(value) {
124798
+ const record = readRecord(value, "meta/videos.json");
124799
+ if (!Array.isArray(record.videos) || !Array.isArray(record.extracted)) {
124800
+ metadataError("meta/videos.json", "must contain videos and extracted arrays");
124801
+ }
124802
+ const videos = record.videos.map((value2, index) => {
124803
+ const field = `meta/videos.json.videos[${index}]`;
124804
+ const video = readRecord(value2, field);
124805
+ return {
124806
+ id: readNonEmptyString(video.id, `${field}.id`),
124807
+ src: readNonEmptyString(video.src, `${field}.src`),
124808
+ start: readFiniteNumber(video.start, `${field}.start`),
124809
+ end: readFiniteNumber(video.end, `${field}.end`),
124810
+ mediaStart: readFiniteNumber(video.mediaStart, `${field}.mediaStart`),
124811
+ loop: readBoolean(video.loop, `${field}.loop`),
124812
+ hasAudio: readBoolean(video.hasAudio, `${field}.hasAudio`)
124813
+ };
124814
+ });
124815
+ const extracted = record.extracted.map((value2, index) => {
124816
+ const field = `meta/videos.json.extracted[${index}]`;
124817
+ const entry = readRecord(value2, field);
124818
+ return {
124819
+ videoId: readNonEmptyString(entry.videoId, `${field}.videoId`),
124820
+ srcPath: readNonEmptyString(entry.srcPath, `${field}.srcPath`),
124821
+ framePattern: readNonEmptyString(entry.framePattern, `${field}.framePattern`),
124822
+ fps: readFiniteNumber(entry.fps, `${field}.fps`),
124823
+ totalFrames: readNonNegativeInteger(entry.totalFrames, `${field}.totalFrames`),
124824
+ metadata: readVideoMetadata(entry.metadata, `${field}.metadata`)
124825
+ };
124826
+ });
124827
+ const videoIds = /* @__PURE__ */ new Set();
124828
+ for (const video of videos) {
124829
+ if (videoIds.has(video.id)) {
124830
+ metadataError("meta/videos.json.videos", `contains duplicate id ${JSON.stringify(video.id)}`);
124831
+ }
124832
+ videoIds.add(video.id);
124833
+ }
124834
+ const extractedIds = /* @__PURE__ */ new Set();
124835
+ for (const entry of extracted) {
124836
+ if (extractedIds.has(entry.videoId)) {
124837
+ metadataError(
124838
+ "meta/videos.json.extracted",
124839
+ `contains duplicate videoId ${JSON.stringify(entry.videoId)}`
124840
+ );
124841
+ }
124842
+ extractedIds.add(entry.videoId);
124843
+ if (!videoIds.has(entry.videoId)) {
124844
+ metadataError(
124845
+ "meta/videos.json.extracted",
124846
+ `references undeclared video ${JSON.stringify(entry.videoId)}`
124847
+ );
124848
+ }
124849
+ }
124850
+ for (const video of videos) {
124851
+ if (!extractedIds.has(video.id)) {
124852
+ metadataError(
124853
+ "meta/videos.json.extracted",
124854
+ `is missing declared video ${JSON.stringify(video.id)}`
124855
+ );
124856
+ }
124857
+ }
124858
+ return { videos, extracted };
124859
+ }
124860
+ function buildPlanVideosJson(input2) {
124861
+ const videos = input2.videos.map((video, index) => {
124862
+ if (Number.isFinite(video.end)) return { ...video };
124863
+ if (!Number.isFinite(input2.compositionEnd) || input2.compositionEnd <= 0 || input2.compositionEnd <= video.start) {
124864
+ metadataError(
124865
+ `meta/videos.json.videos[${index}].end`,
124866
+ "cannot be resolved without a finite composition end after its start"
124867
+ );
124868
+ }
124869
+ return { ...video, end: input2.compositionEnd };
124870
+ });
124871
+ return parsePlanVideosJson({ videos, extracted: input2.extracted });
124872
+ }
124581
124873
  async function readFfmpegVersion() {
124582
124874
  if (cachedFfmpegVersion !== null) return cachedFfmpegVersion;
124583
124875
  const { stdout: stdout2 } = await execFile6("ffmpeg", ["-version"], { maxBuffer: 1024 * 1024 });
@@ -124634,7 +124926,7 @@ function readProducerVersion() {
124634
124926
  cachedProducerVersion = "0.0.0-unknown";
124635
124927
  return cachedProducerVersion;
124636
124928
  }
124637
- var PLAN_VIDEOS_META_RELATIVE_PATH, PLAN_AUDIO_RELATIVE_PATH, execFile6, cachedFfmpegVersion, cachedProducerVersion;
124929
+ var PLAN_VIDEOS_META_RELATIVE_PATH, PLAN_AUDIO_RELATIVE_PATH, INVALID_VIDEO_METADATA, PlanVideosMetadataError, execFile6, cachedFfmpegVersion, cachedProducerVersion;
124638
124930
  var init_shared2 = __esm({
124639
124931
  "../producer/src/services/distributed/shared.ts"() {
124640
124932
  "use strict";
@@ -124642,6 +124934,16 @@ var init_shared2 = __esm({
124642
124934
  init_logger();
124643
124935
  PLAN_VIDEOS_META_RELATIVE_PATH = "meta/videos.json";
124644
124936
  PLAN_AUDIO_RELATIVE_PATH = "audio.aac";
124937
+ INVALID_VIDEO_METADATA = "INVALID_VIDEO_METADATA";
124938
+ PlanVideosMetadataError = class extends Error {
124939
+ // Read by cloud adapters across the package boundary to classify retries.
124940
+ // fallow-ignore-next-line unused-class-member
124941
+ code = INVALID_VIDEO_METADATA;
124942
+ constructor(message) {
124943
+ super(message);
124944
+ this.name = "PlanVideosMetadataError";
124945
+ }
124946
+ };
124645
124947
  execFile6 = promisify4(execFileCallback);
124646
124948
  cachedFfmpegVersion = null;
124647
124949
  cachedProducerVersion = null;
@@ -125117,6 +125419,9 @@ async function plan(projectDir, config, planDir) {
125117
125419
  materializeSymlinks: true
125118
125420
  });
125119
125421
  if (extractResult.failureToEnforce) throw extractResult.failureToEnforce;
125422
+ if (extractResult.extractionResult) {
125423
+ assertVideoExtractionSucceeded(extractResult.extractionResult);
125424
+ }
125120
125425
  const audioResult = await runAudioStage({
125121
125426
  projectDir,
125122
125427
  workDir,
@@ -125139,8 +125444,9 @@ async function plan(projectDir, config, planDir) {
125139
125444
  }
125140
125445
  if (existsSync57(finalCompiledDir)) rmSync18(finalCompiledDir, { recursive: true, force: true });
125141
125446
  renameSync12(compiledDir, finalCompiledDir);
125142
- const planVideosJson = {
125447
+ const planVideosJson = buildPlanVideosJson({
125143
125448
  videos: composition.videos,
125449
+ compositionEnd: job.duration ?? Number.NaN,
125144
125450
  extracted: (extractResult.extractionResult?.extracted ?? []).map((ext) => ({
125145
125451
  videoId: ext.videoId,
125146
125452
  srcPath: ext.srcPath,
@@ -125149,7 +125455,7 @@ async function plan(projectDir, config, planDir) {
125149
125455
  totalFrames: ext.totalFrames,
125150
125456
  metadata: ext.metadata
125151
125457
  }))
125152
- };
125458
+ });
125153
125459
  mkdirSync29(join65(planDir, "meta"), { recursive: true });
125154
125460
  writeFileSync20(
125155
125461
  join65(planDir, PLAN_VIDEOS_META_RELATIVE_PATH),
@@ -125635,90 +125941,20 @@ function listVideoFramePaths(planV1Dir, videos) {
125635
125941
  };
125636
125942
  });
125637
125943
  }
125638
- function readFiniteNumber(value, field) {
125639
- if (typeof value !== "number" || !Number.isFinite(value)) {
125640
- throw new PlanV2IntegrityError(`${field} must be a finite number`);
125641
- }
125642
- return value;
125643
- }
125644
- function readBoolean(value, field) {
125645
- if (typeof value !== "boolean") {
125646
- throw new PlanV2IntegrityError(`${field} must be boolean`);
125647
- }
125648
- return value;
125649
- }
125650
- function readVideoMetadata(value, field) {
125651
- if (!isRecord7(value)) {
125652
- throw new PlanV2IntegrityError(`${field} must be an object`);
125653
- }
125654
- let colorSpace = null;
125655
- if (value.colorSpace !== null) {
125656
- if (!isRecord7(value.colorSpace)) {
125657
- throw new PlanV2IntegrityError(`${field}.colorSpace must be an object or null`);
125944
+ function parsePlanVideosJson2(value) {
125945
+ try {
125946
+ return parsePlanVideosJson(value);
125947
+ } catch (err) {
125948
+ if (err instanceof PlanVideosMetadataError) {
125949
+ throw new PlanV2IntegrityError(err.message);
125658
125950
  }
125659
- colorSpace = {
125660
- colorTransfer: readColorComponent(
125661
- value.colorSpace.colorTransfer,
125662
- `${field}.colorSpace.colorTransfer`
125663
- ),
125664
- colorPrimaries: readColorComponent(
125665
- value.colorSpace.colorPrimaries,
125666
- `${field}.colorSpace.colorPrimaries`
125667
- ),
125668
- colorSpace: readColorComponent(value.colorSpace.colorSpace, `${field}.colorSpace.colorSpace`)
125669
- };
125670
- }
125671
- return {
125672
- durationSeconds: readFiniteNumber(value.durationSeconds, `${field}.durationSeconds`),
125673
- videoStreamDurationSeconds: readFiniteNumber(
125674
- value.videoStreamDurationSeconds,
125675
- `${field}.videoStreamDurationSeconds`
125676
- ),
125677
- width: readPositiveInteger(value.width, `${field}.width`),
125678
- height: readPositiveInteger(value.height, `${field}.height`),
125679
- fps: readFiniteNumber(value.fps, `${field}.fps`),
125680
- videoCodec: readString(value.videoCodec, `${field}.videoCodec`),
125681
- hasAudio: readBoolean(value.hasAudio, `${field}.hasAudio`),
125682
- isVFR: readBoolean(value.isVFR, `${field}.isVFR`),
125683
- hasAlpha: readBoolean(value.hasAlpha, `${field}.hasAlpha`),
125684
- colorSpace
125685
- };
125686
- }
125687
- function parsePlanVideosJson(value) {
125688
- if (!isRecord7(value) || !Array.isArray(value.videos) || !Array.isArray(value.extracted)) {
125689
- throw new PlanV2IntegrityError("meta/videos.json must contain videos and extracted arrays");
125951
+ throw err;
125690
125952
  }
125691
- const videos = value.videos.map((video, index) => {
125692
- const field = `meta/videos.json.videos[${index}]`;
125693
- if (!isRecord7(video)) throw new PlanV2IntegrityError(`${field} must be an object`);
125694
- return {
125695
- id: readString(video.id, `${field}.id`),
125696
- src: readString(video.src, `${field}.src`),
125697
- start: readFiniteNumber(video.start, `${field}.start`),
125698
- end: readFiniteNumber(video.end, `${field}.end`),
125699
- mediaStart: readFiniteNumber(video.mediaStart, `${field}.mediaStart`),
125700
- loop: readBoolean(video.loop, `${field}.loop`),
125701
- hasAudio: readBoolean(video.hasAudio, `${field}.hasAudio`)
125702
- };
125703
- });
125704
- const extracted = value.extracted.map((entry, index) => {
125705
- const field = `meta/videos.json.extracted[${index}]`;
125706
- if (!isRecord7(entry)) throw new PlanV2IntegrityError(`${field} must be an object`);
125707
- return {
125708
- videoId: readString(entry.videoId, `${field}.videoId`),
125709
- srcPath: readString(entry.srcPath, `${field}.srcPath`),
125710
- framePattern: readString(entry.framePattern, `${field}.framePattern`),
125711
- fps: readFiniteNumber(entry.fps, `${field}.fps`),
125712
- totalFrames: readNonNegativeInteger(entry.totalFrames, `${field}.totalFrames`),
125713
- metadata: readVideoMetadata(entry.metadata, `${field}.metadata`)
125714
- };
125715
- });
125716
- return { videos, extracted };
125717
125953
  }
125718
125954
  function materializeExtractedVideoDirectories(planDir) {
125719
125955
  const videosPath = join68(planDir, PLAN_VIDEOS_META_RELATIVE_PATH);
125720
125956
  if (!existsSync59(videosPath)) return;
125721
- const videos = parsePlanVideosJson(readJsonFile(videosPath, PLAN_VIDEOS_META_RELATIVE_PATH));
125957
+ const videos = parsePlanVideosJson2(readJsonFile(videosPath, PLAN_VIDEOS_META_RELATIVE_PATH));
125722
125958
  for (const video of videos.extracted) {
125723
125959
  mkdirSync31(resolveExtractedVideoOutputDir(planDir, video.videoId), { recursive: true });
125724
125960
  }
@@ -125731,9 +125967,9 @@ function parseChunkSlices(value) {
125731
125967
  return value.map((chunk, position) => {
125732
125968
  const field = `meta/chunks.json[${position}]`;
125733
125969
  if (!isRecord7(chunk)) throw new PlanV2IntegrityError(`${field} must be an object`);
125734
- const index = readNonNegativeInteger(chunk.index, `${field}.index`);
125735
- const startFrame = readNonNegativeInteger(chunk.startFrame, `${field}.startFrame`);
125736
- const endFrame = readPositiveInteger(chunk.endFrame, `${field}.endFrame`);
125970
+ const index = readNonNegativeInteger2(chunk.index, `${field}.index`);
125971
+ const startFrame = readNonNegativeInteger2(chunk.startFrame, `${field}.startFrame`);
125972
+ const endFrame = readPositiveInteger2(chunk.endFrame, `${field}.endFrame`);
125737
125973
  if (endFrame <= startFrame) {
125738
125974
  throw new PlanV2IntegrityError(`${field}.endFrame must be greater than startFrame`);
125739
125975
  }
@@ -125754,12 +125990,12 @@ function buildVideoChunkDependencies(planV1Dir, dimensions) {
125754
125990
  const chunksPath = join68(planV1Dir, "meta", "chunks.json");
125755
125991
  const videos = readJsonFile(videosPath, PLAN_VIDEOS_META_RELATIVE_PATH);
125756
125992
  const chunks = readJsonFile(chunksPath, "meta/chunks.json");
125757
- const parsedVideos = parsePlanVideosJson(videos);
125993
+ const parsedVideos = parsePlanVideosJson2(videos);
125758
125994
  const parsedChunks = parseChunkSlices(chunks);
125759
125995
  const extracted = listVideoFramePaths(planV1Dir, parsedVideos);
125760
125996
  const table = createFrameLookupTable(parsedVideos.videos, extracted);
125761
- const fpsNum = readPositiveInteger(dimensions.fpsNum, "dimensions.fpsNum");
125762
- const fpsDen = readPositiveInteger(dimensions.fpsDen, "dimensions.fpsDen");
125997
+ const fpsNum = readPositiveInteger2(dimensions.fpsNum, "dimensions.fpsNum");
125998
+ const fpsDen = readPositiveInteger2(dimensions.fpsDen, "dimensions.fpsDen");
125763
125999
  const mutable = /* @__PURE__ */ new Map();
125764
126000
  for (const chunk of parsedChunks) {
125765
126001
  for (let frame = chunk.startFrame; frame < chunk.endFrame; frame++) {
@@ -125848,14 +126084,14 @@ function buildPlanV2Publication(planV1Dir) {
125848
126084
  const base2 = {
125849
126085
  protocol: PLAN_PROTOCOL_V2,
125850
126086
  sourcePlanV1Hash,
125851
- chunkCount: readPositiveInteger(v1Plan.chunkCount, "chunkCount"),
125852
- totalFrames: readPositiveInteger(v1Plan.totalFrames, "totalFrames"),
126087
+ chunkCount: readPositiveInteger2(v1Plan.chunkCount, "chunkCount"),
126088
+ totalFrames: readPositiveInteger2(v1Plan.totalFrames, "totalFrames"),
125853
126089
  fps: readV1PlanFps(dimensions),
125854
- width: readPositiveInteger(dimensions.width, "dimensions.width"),
125855
- height: readPositiveInteger(dimensions.height, "dimensions.height"),
126090
+ width: readPositiveInteger2(dimensions.width, "dimensions.width"),
126091
+ height: readPositiveInteger2(dimensions.height, "dimensions.height"),
125856
126092
  format: readDistributedFormat(dimensions.format),
125857
- ffmpegVersion: readString(v1Plan.ffmpegVersion, "ffmpegVersion"),
125858
- producerVersion: readString(v1Plan.producerVersion, "producerVersion"),
126093
+ ffmpegVersion: readString2(v1Plan.ffmpegVersion, "ffmpegVersion"),
126094
+ producerVersion: readString2(v1Plan.producerVersion, "producerVersion"),
125859
126095
  limitations: { videoDependencyMode: videoDependencyPlan.mode },
125860
126096
  artifacts
125861
126097
  };
@@ -125958,25 +126194,19 @@ function resultFromManifest(planV2Dir, manifest) {
125958
126194
  limitations: manifest.limitations
125959
126195
  };
125960
126196
  }
125961
- function readString(value, field) {
126197
+ function readString2(value, field) {
125962
126198
  if (typeof value !== "string" || value.length === 0) {
125963
126199
  throw new PlanV2IntegrityError(`${field} must be a non-empty string`);
125964
126200
  }
125965
126201
  return value;
125966
126202
  }
125967
- function readColorComponent(value, field) {
125968
- if (typeof value !== "string") {
125969
- throw new PlanV2IntegrityError(`${field} must be a string`);
125970
- }
125971
- return value;
125972
- }
125973
- function readPositiveInteger(value, field) {
126203
+ function readPositiveInteger2(value, field) {
125974
126204
  if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
125975
126205
  throw new PlanV2IntegrityError(`${field} must be a positive integer`);
125976
126206
  }
125977
126207
  return value;
125978
126208
  }
125979
- function readNonNegativeInteger(value, field) {
126209
+ function readNonNegativeInteger2(value, field) {
125980
126210
  if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
125981
126211
  throw new PlanV2IntegrityError(`${field} must be a non-negative integer`);
125982
126212
  }
@@ -125989,7 +126219,7 @@ function readSupportedFps(value) {
125989
126219
  return value;
125990
126220
  }
125991
126221
  function readV1PlanFps(dimensions) {
125992
- const fpsDen = readPositiveInteger(dimensions.fpsDen, "dimensions.fpsDen");
126222
+ const fpsDen = readPositiveInteger2(dimensions.fpsDen, "dimensions.fpsDen");
125993
126223
  if (fpsDen !== 1) {
125994
126224
  throw new PlanV2IntegrityError("dimensions.fpsDen must be 1 for plan v2");
125995
126225
  }
@@ -126003,7 +126233,7 @@ function readDistributedFormat(value) {
126003
126233
  }
126004
126234
  function parseArtifact(value, index) {
126005
126235
  if (!isRecord7(value)) throw new PlanV2IntegrityError(`artifacts[${index}] must be an object`);
126006
- const path2 = readString(value.path, `artifacts[${index}].path`);
126236
+ const path2 = readString2(value.path, `artifacts[${index}].path`);
126007
126237
  assertSafeRelativePath(path2);
126008
126238
  if (!isSha256(value.sha256)) {
126009
126239
  throw new PlanV2IntegrityError(`artifacts[${index}].sha256 must be a lowercase sha256`);
@@ -126056,14 +126286,14 @@ function parsePlanV2Manifest(value) {
126056
126286
  protocol: PLAN_PROTOCOL_V2,
126057
126287
  planHash: value.planHash,
126058
126288
  sourcePlanV1Hash: value.sourcePlanV1Hash,
126059
- chunkCount: readPositiveInteger(value.chunkCount, "chunkCount"),
126060
- totalFrames: readPositiveInteger(value.totalFrames, "totalFrames"),
126289
+ chunkCount: readPositiveInteger2(value.chunkCount, "chunkCount"),
126290
+ totalFrames: readPositiveInteger2(value.totalFrames, "totalFrames"),
126061
126291
  fps: readSupportedFps(value.fps),
126062
- width: readPositiveInteger(value.width, "width"),
126063
- height: readPositiveInteger(value.height, "height"),
126292
+ width: readPositiveInteger2(value.width, "width"),
126293
+ height: readPositiveInteger2(value.height, "height"),
126064
126294
  format: readDistributedFormat(value.format),
126065
- ffmpegVersion: readString(value.ffmpegVersion, "ffmpegVersion"),
126066
- producerVersion: readString(value.producerVersion, "producerVersion"),
126295
+ ffmpegVersion: readString2(value.ffmpegVersion, "ffmpegVersion"),
126296
+ producerVersion: readString2(value.producerVersion, "producerVersion"),
126067
126297
  limitations: { videoDependencyMode: value.limitations.videoDependencyMode },
126068
126298
  artifacts
126069
126299
  };
@@ -126465,6 +126695,16 @@ var init_assemble = __esm({
126465
126695
  import { randomBytes as randomBytes2 } from "crypto";
126466
126696
  import { existsSync as existsSync61, mkdirSync as mkdirSync34, readFileSync as readFileSync36, readdirSync as readdirSync21, rmSync as rmSync23, writeFileSync as writeFileSync25 } from "fs";
126467
126697
  import { extname as extname15, join as join70 } from "path";
126698
+ function validatePlanVideosForChunk(value) {
126699
+ try {
126700
+ return parsePlanVideosJson(value);
126701
+ } catch (err) {
126702
+ throw new RenderChunkValidationError(
126703
+ INVALID_VIDEO_METADATA,
126704
+ `[renderChunk] invalid meta/videos.json: ${err instanceof Error ? err.message : String(err)}`
126705
+ );
126706
+ }
126707
+ }
126468
126708
  async function createVerifiedDistributedCaptureSession(serverUrl, framesDir, captureOptions, cfg, dependencies = distributedCaptureSessionDependencies) {
126469
126709
  const session = await dependencies.createCaptureSession(
126470
126710
  serverUrl,
@@ -126599,10 +126839,11 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
126599
126839
  let planVideos = null;
126600
126840
  if (existsSync61(videosJsonPath)) {
126601
126841
  try {
126602
- planVideos = JSON.parse(readFileSync36(videosJsonPath, "utf-8"));
126842
+ planVideos = validatePlanVideosForChunk(JSON.parse(readFileSync36(videosJsonPath, "utf-8")));
126603
126843
  } catch (err) {
126844
+ if (err instanceof RenderChunkValidationError) throw err;
126604
126845
  throw new RenderChunkValidationError(
126605
- MISSING_PLAN_ARTIFACT,
126846
+ INVALID_VIDEO_METADATA,
126606
126847
  `[renderChunk] failed to parse ${videosJsonPath}: ${err instanceof Error ? err.message : String(err)}`
126607
126848
  );
126608
126849
  }
@@ -127097,6 +127338,7 @@ var init_distributed = __esm({
127097
127338
  init_renderConfigValidation();
127098
127339
  init_projectHash();
127099
127340
  init_planProtocol();
127341
+ init_shared2();
127100
127342
  init_planValidation();
127101
127343
  }
127102
127344
  });
@@ -130123,7 +130365,7 @@ function applyResolutionPreset(destDir, resolution) {
130123
130365
  if (changed) writeFileSync27(file, html, "utf-8");
130124
130366
  }
130125
130367
  }
130126
- async function scaffoldProject(destDir, name, templateId, localVideoName, durationSeconds, tailwind = false, resolution) {
130368
+ async function scaffoldProject(destDir, name, templateId, localVideoName, durationSeconds, tailwind = false, resolution, authoringSkill) {
130127
130369
  mkdirSync38(destDir, { recursive: true });
130128
130370
  const templateDir = getStaticTemplateDir(templateId);
130129
130371
  if (existsSync67(join78(templateDir, "index.html"))) {
@@ -130149,7 +130391,12 @@ async function scaffoldProject(destDir, name, templateId, localVideoName, durati
130149
130391
  );
130150
130392
  if (!existsSync67(resolve39(destDir, "hyperframes.json"))) {
130151
130393
  const { writeProjectConfig: writeProjectConfig2, DEFAULT_PROJECT_CONFIG: DEFAULT_PROJECT_CONFIG2 } = await Promise.resolve().then(() => (init_projectConfig(), projectConfig_exports));
130152
- writeProjectConfig2(destDir, DEFAULT_PROJECT_CONFIG2);
130394
+ const { normalizeSkillSlug: normalizeSkillSlug2 } = await Promise.resolve().then(() => (init_skill(), skill_exports));
130395
+ const skill = normalizeSkillSlug2(authoringSkill);
130396
+ writeProjectConfig2(
130397
+ destDir,
130398
+ skill ? { ...DEFAULT_PROJECT_CONFIG2, authoringSkill: skill } : DEFAULT_PROJECT_CONFIG2
130399
+ );
130153
130400
  }
130154
130401
  writeDefaultPackageJson(destDir, name);
130155
130402
  const sharedDir = getSharedTemplateDir();
@@ -130298,6 +130545,10 @@ var init_init = __esm({
130298
130545
  resolution: {
130299
130546
  type: "string",
130300
130547
  description: "Canvas resolution preset: landscape (1920x1080), portrait (1080x1920), landscape-4k (3840x2160), portrait-4k (2160x3840), square (1080x1080), square-4k (2160x2160). Aliases: 1080p, 4k, uhd, 1080p-square, square-1080p, 4k-square. Default: keep template dimensions (typically 1920x1080)."
130548
+ },
130549
+ skill: {
130550
+ type: "string",
130551
+ description: "Owning authoring workflow slug (e.g. product-launch-video). Stamped into hyperframes.json so every render of this project is attributed to it on anonymous telemetry, without re-passing --skill on each render. Ignored unless it is a slug."
130301
130552
  }
130302
130553
  },
130303
130554
  async run({ args }) {
@@ -130432,7 +130683,8 @@ var init_init = __esm({
130432
130683
  localVideoName2,
130433
130684
  videoDuration2,
130434
130685
  tailwind,
130435
- resolutionPreset
130686
+ resolutionPreset,
130687
+ args.skill
130436
130688
  );
130437
130689
  } catch (err) {
130438
130690
  console.error(
@@ -130620,7 +130872,8 @@ var init_init = __esm({
130620
130872
  localVideoName,
130621
130873
  videoDuration,
130622
130874
  tailwind,
130623
- resolutionPreset
130875
+ resolutionPreset,
130876
+ args.skill
130624
130877
  );
130625
130878
  if (!isBundled) {
130626
130879
  spin.stop(c.success(`Downloaded ${templateId}`));
@@ -133822,20 +134075,6 @@ var init_renderArgs = __esm({
133822
134075
  }
133823
134076
  });
133824
134077
 
133825
- // src/telemetry/skill.ts
133826
- function normalizeSkillSlug(raw) {
133827
- if (typeof raw !== "string") return void 0;
133828
- const slug = raw.trim();
133829
- return SKILL_SLUG.test(slug) ? slug : void 0;
133830
- }
133831
- var SKILL_SLUG;
133832
- var init_skill = __esm({
133833
- "src/telemetry/skill.ts"() {
133834
- "use strict";
133835
- SKILL_SLUG = /^[a-z0-9][a-z0-9-]{0,63}$/;
133836
- }
133837
- });
133838
-
133839
134078
  // src/commands/render/plan.ts
133840
134079
  import { statSync as statSync27 } from "fs";
133841
134080
  import { dirname as dirname39, join as join85, resolve as resolve51 } from "path";
@@ -133885,8 +134124,9 @@ function createRenderPlan(args, now = /* @__PURE__ */ new Date()) {
133885
134124
  failUsage();
133886
134125
  }
133887
134126
  const quality = qualityRaw;
133888
- const authoringSkill = normalizeSkillSlug(args.skill);
133889
- const invalidAuthoringSkill = typeof args.skill === "string" && args.skill.trim() !== "" && !authoringSkill ? args.skill : void 0;
134127
+ const flagSkill = normalizeSkillSlug(args.skill);
134128
+ const authoringSkill = flagSkill ?? loadProjectConfig(project.dir).authoringSkill;
134129
+ const invalidAuthoringSkill = typeof args.skill === "string" && args.skill.trim() !== "" && !flagSkill ? args.skill : void 0;
133890
134130
  const formatRaw = args.format ?? "mp4";
133891
134131
  const format = parseRenderFormat(formatRaw);
133892
134132
  if (!format) {
@@ -134122,6 +134362,7 @@ var init_plan2 = __esm({
134122
134362
  init_project();
134123
134363
  init_renderArgs();
134124
134364
  init_skill();
134365
+ init_projectConfig();
134125
134366
  VALID_QUALITY = /* @__PURE__ */ new Set(["draft", "standard", "high"]);
134126
134367
  RENDER_FORMATS = ["mp4", "webm", "mov", "png-sequence", "gif"];
134127
134368
  VALID_FORMAT = new Set(RENDER_FORMATS);
@@ -135479,7 +135720,7 @@ __export(render_exports, {
135479
135720
  renderLocal: () => renderLocal,
135480
135721
  resolveBrowserGpuForCli: () => resolveBrowserGpuForCli
135481
135722
  });
135482
- import { mkdirSync as mkdirSync43, readdirSync as readdirSync27, readFileSync as readFileSync53, statSync as statSync28, writeFileSync as writeFileSync30, rmSync as rmSync26 } from "fs";
135723
+ import { mkdtempSync as mkdtempSync11, readdirSync as readdirSync27, readFileSync as readFileSync53, statSync as statSync28, writeFileSync as writeFileSync30, rmSync as rmSync26 } from "fs";
135483
135724
  import { freemem as freemem5, tmpdir as tmpdir12 } from "os";
135484
135725
  import { resolve as resolve54, dirname as dirname41, join as join87, basename as basename16 } from "path";
135485
135726
  import { execFileSync as execFileSync11, spawn as spawn14 } from "child_process";
@@ -135547,8 +135788,7 @@ function ensureDockerImage(version2, platform10, quiet) {
135547
135788
  }
135548
135789
  if (!quiet) console.log(c.dim(` Building Docker image: ${tag} (${platform10})...`));
135549
135790
  const dockerfilePath = resolveDockerfilePath();
135550
- const tmpDir = join87(tmpdir12(), `hyperframes-docker-${Date.now()}`);
135551
- mkdirSync43(tmpDir, { recursive: true });
135791
+ const tmpDir = mkdtempSync11(join87(tmpdir12(), "hyperframes-docker-"));
135552
135792
  writeFileSync30(join87(tmpDir, "Dockerfile"), readFileSync53(dockerfilePath));
135553
135793
  const targetArch = platform10 === "linux/arm64" ? "arm64" : "amd64";
135554
135794
  try {
@@ -136098,6 +136338,7 @@ function trackRenderMetrics(job, elapsedMs, options, docker) {
136098
136338
  deParallelRouter: perf?.drawElement?.parallelRouter,
136099
136339
  dePreRouterWorkers: perf?.drawElement?.preRouterWorkers,
136100
136340
  deGateReason: perf?.drawElement?.gateReason,
136341
+ gpuRenderer: perf?.drawElement?.gpuRenderer,
136101
136342
  deWorkerEncode: perf?.drawElement?.workerEncode,
136102
136343
  deVerifyArmed: perf?.drawElement?.verifyArmed,
136103
136344
  deVerifyChecked: perf?.drawElement?.verifyChecked,
@@ -136185,6 +136426,7 @@ var init_render = __esm({
136185
136426
  init_commandResult();
136186
136427
  init_dist();
136187
136428
  init_plan2();
136429
+ init_projectConfig();
136188
136430
  init_present2();
136189
136431
  init_execute();
136190
136432
  init_producer();
@@ -136440,6 +136682,7 @@ var init_render = __esm({
136440
136682
  // Keep the transport adapter thin: each phase has one ownership boundary.
136441
136683
  async run({ args }) {
136442
136684
  const plan2 = createRenderPlan(args);
136685
+ seedProjectAuthoringSkill(plan2.project.dir, args.skill);
136443
136686
  await presentRenderPlan(plan2);
136444
136687
  await executeRenderPlan(plan2, {
136445
136688
  renderDocker,
@@ -138123,7 +138366,7 @@ __export(validate_exports, {
138123
138366
  resolveNavigationTimeoutMs: () => resolveNavigationTimeoutMs,
138124
138367
  shouldIgnoreRequestFailure: () => shouldIgnoreRequestFailure
138125
138368
  });
138126
- import { existsSync as existsSync80, mkdtempSync as mkdtempSync11, readFileSync as readFileSync56, rmSync as rmSync27 } from "fs";
138369
+ import { existsSync as existsSync80, mkdtempSync as mkdtempSync12, readFileSync as readFileSync56, rmSync as rmSync27 } from "fs";
138127
138370
  import { tmpdir as tmpdir13 } from "os";
138128
138371
  import { join as join90, dirname as dirname43 } from "path";
138129
138372
  import { fileURLToPath as fileURLToPath12 } from "url";
@@ -138290,7 +138533,7 @@ async function localizeRemoteAssets(html) {
138290
138533
  try {
138291
138534
  const { loadProducer: loadProducer2 } = await Promise.resolve().then(() => (init_producer(), producer_exports));
138292
138535
  const { localizeRemoteMediaSources: localizeRemoteMediaSources2, localizeRemoteImageSources: localizeRemoteImageSources2, localizeRemoteFontFaces: localizeRemoteFontFaces2 } = await loadProducer2();
138293
- dir = mkdtempSync11(join90(tmpdir13(), "hf-validate-assets-"));
138536
+ dir = mkdtempSync12(join90(tmpdir13(), "hf-validate-assets-"));
138294
138537
  const assetDir = dir;
138295
138538
  const media = await localizeRemoteMediaSources2(html, assetDir);
138296
138539
  const images = await localizeRemoteImageSources2(media.html, assetDir);
@@ -138601,7 +138844,7 @@ __export(checkBrowser_exports, {
138601
138844
  preResolveHostileMediaProxies: () => preResolveHostileMediaProxies,
138602
138845
  runBrowserCheck: () => runBrowserCheck
138603
138846
  });
138604
- import { mkdirSync as mkdirSync44, writeFileSync as writeFileSync31 } from "fs";
138847
+ import { mkdirSync as mkdirSync43, writeFileSync as writeFileSync31 } from "fs";
138605
138848
  import { join as join91, resolve as resolve56 } from "path";
138606
138849
  async function preResolveHostileMediaProxies(projectDir, html, autoProxyOverride) {
138607
138850
  if (!resolveAutoProxy(projectDir, autoProxyOverride)) return;
@@ -138701,7 +138944,7 @@ async function captureFindingCrops(project, options, requests) {
138701
138944
  const page = session.page;
138702
138945
  await waitForPreferredSeekTarget(page);
138703
138946
  const snapshotDir = join91(project.dir, "snapshots");
138704
- mkdirSync44(snapshotDir, { recursive: true });
138947
+ mkdirSync43(snapshotDir, { recursive: true });
138705
138948
  for (const request of requests) {
138706
138949
  await seekCompositionTimeline(page, request.time, AUDIT_SEEK_OPTIONS);
138707
138950
  const canvas = await page.evaluate(() => ({
@@ -139493,7 +139736,7 @@ var init_checkBrowser = __esm({
139493
139736
  });
139494
139737
 
139495
139738
  // src/utils/checkPipeline.ts
139496
- import { mkdirSync as mkdirSync45, writeFileSync as writeFileSync33 } from "fs";
139739
+ import { mkdirSync as mkdirSync44, writeFileSync as writeFileSync33 } from "fs";
139497
139740
  import { join as join93, relative as relative21 } from "path";
139498
139741
  function selectContrastTimes(grid) {
139499
139742
  if (grid.length <= 5) return [...grid];
@@ -140435,7 +140678,7 @@ async function runBrowserCheck2(project, options, motion) {
140435
140678
  }
140436
140679
  async function writeSnapshot(projectDir, index, time, pngBase64) {
140437
140680
  const snapshotDir = join93(projectDir, "snapshots");
140438
- mkdirSync45(snapshotDir, { recursive: true });
140681
+ mkdirSync44(snapshotDir, { recursive: true });
140439
140682
  const filename = `frame-${String(index).padStart(2, "0")}-at-${time.toFixed(1)}s.png`;
140440
140683
  const path2 = join93(snapshotDir, filename);
140441
140684
  writeFileSync33(path2, Buffer.from(pngBase64, "base64"));
@@ -141132,7 +141375,7 @@ __export(beats_exports, {
141132
141375
  default: () => beats_default,
141133
141376
  examples: () => examples13
141134
141377
  });
141135
- import { existsSync as existsSync83, readFileSync as readFileSync58, mkdirSync as mkdirSync46, writeFileSync as writeFileSync34 } from "fs";
141378
+ import { existsSync as existsSync83, readFileSync as readFileSync58, mkdirSync as mkdirSync45, writeFileSync as writeFileSync34 } from "fs";
141136
141379
  import { resolve as resolve57, join as join95, dirname as dirname45 } from "path";
141137
141380
  function fail(message) {
141138
141381
  console.error(c.error(message));
@@ -141205,7 +141448,7 @@ var init_beats2 = __esm({
141205
141448
  fail(`No beats detected in ${rel} \u2014 nothing written. (Track may be silent/ambient.)`);
141206
141449
  }
141207
141450
  const outPath = join95(project.dir, "beats", `${rel}.json`);
141208
- mkdirSync46(dirname45(outPath), { recursive: true });
141451
+ mkdirSync45(dirname45(outPath), { recursive: true });
141209
141452
  writeFileSync34(outPath, serializeBeats(result.beatTimes, result.beatStrengths, rel));
141210
141453
  report(`beats/${rel}.json`, result, Boolean(args.json));
141211
141454
  }
@@ -143054,10 +143297,10 @@ __export(motionShot_exports, {
143054
143297
  captureMotionPathShot: () => captureMotionPathShot,
143055
143298
  ensureShotOutputDir: () => ensureShotOutputDir
143056
143299
  });
143057
- import { mkdirSync as mkdirSync47, writeFileSync as writeFileSync35 } from "fs";
143300
+ import { mkdirSync as mkdirSync46, writeFileSync as writeFileSync35 } from "fs";
143058
143301
  import { dirname as dirname46 } from "path";
143059
143302
  function ensureShotOutputDir(outPath) {
143060
- mkdirSync47(dirname46(outPath), { recursive: true });
143303
+ mkdirSync46(dirname46(outPath), { recursive: true });
143061
143304
  }
143062
143305
  function applyOrbitCamera(selectors, cam) {
143063
143306
  const first = document.querySelector(selectors[0] ?? "");
@@ -145130,7 +145373,7 @@ var init_remove_background = __esm({
145130
145373
 
145131
145374
  // src/whisper/parakeet.ts
145132
145375
  import { execFileSync as execFileSync12 } from "child_process";
145133
- import { existsSync as existsSync88, mkdtempSync as mkdtempSync12, readFileSync as readFileSync63, rmSync as rmSync28, writeFileSync as writeFileSync36 } from "fs";
145376
+ import { existsSync as existsSync88, mkdtempSync as mkdtempSync13, readFileSync as readFileSync63, rmSync as rmSync28, writeFileSync as writeFileSync36 } from "fs";
145134
145377
  import { homedir as homedir17, tmpdir as tmpdir14 } from "os";
145135
145378
  import { basename as basename19, extname as extname17, join as join99 } from "path";
145136
145379
  function isRunnable(bin) {
@@ -145200,7 +145443,7 @@ function transcribeWithParakeet(inputPath, dir, options) {
145200
145443
  options?.onProgress?.(
145201
145444
  cached2 ? "Transcribing with Parakeet..." : "Downloading Parakeet model (first run, ~600MB)..."
145202
145445
  );
145203
- const workDir = mkdtempSync12(join99(tmpdir14(), "hyperframes-parakeet-"));
145446
+ const workDir = mkdtempSync13(join99(tmpdir14(), "hyperframes-parakeet-"));
145204
145447
  try {
145205
145448
  const argv2 = [inputPath, "--model", model, "--output-format", "json", "--output-dir", workDir];
145206
145449
  if (options?.language) argv2.push("--language", options.language);
@@ -145507,7 +145750,7 @@ var init_transcribe2 = __esm({
145507
145750
  });
145508
145751
 
145509
145752
  // src/tts/manager.ts
145510
- import { existsSync as existsSync90, mkdirSync as mkdirSync48 } from "fs";
145753
+ import { existsSync as existsSync90, mkdirSync as mkdirSync47 } from "fs";
145511
145754
  import { homedir as homedir18 } from "os";
145512
145755
  import { join as join101 } from "path";
145513
145756
  function inferLangFromVoiceId(voiceId) {
@@ -145526,7 +145769,7 @@ async function ensureModel3(model = DEFAULT_MODEL4, options) {
145526
145769
  `Unknown TTS model: ${model}. Available: ${Object.keys(MODEL_URLS2).join(", ")}`
145527
145770
  );
145528
145771
  }
145529
- mkdirSync48(MODELS_DIR3, { recursive: true });
145772
+ mkdirSync47(MODELS_DIR3, { recursive: true });
145530
145773
  options?.onProgress?.(`Downloading TTS model ${model} (~311 MB)...`);
145531
145774
  await downloadFile(url, modelPath2);
145532
145775
  if (!existsSync90(modelPath2)) {
@@ -145537,7 +145780,7 @@ async function ensureModel3(model = DEFAULT_MODEL4, options) {
145537
145780
  async function ensureVoices(options) {
145538
145781
  const voicesPath = join101(VOICES_DIR, "voices-v1.0.bin");
145539
145782
  if (existsSync90(voicesPath)) return voicesPath;
145540
- mkdirSync48(VOICES_DIR, { recursive: true });
145783
+ mkdirSync47(VOICES_DIR, { recursive: true });
145541
145784
  options?.onProgress?.("Downloading voice data (~27 MB)...");
145542
145785
  await downloadFile(VOICES_URL, voicesPath);
145543
145786
  if (!existsSync90(voicesPath)) {
@@ -145681,12 +145924,12 @@ __export(synthesize_exports, {
145681
145924
  synthesize: () => synthesize
145682
145925
  });
145683
145926
  import { execFileSync as execFileSync14 } from "child_process";
145684
- import { existsSync as existsSync91, writeFileSync as writeFileSync38, mkdirSync as mkdirSync49, readdirSync as readdirSync30, unlinkSync as unlinkSync7 } from "fs";
145927
+ import { existsSync as existsSync91, writeFileSync as writeFileSync38, mkdirSync as mkdirSync48, readdirSync as readdirSync30, unlinkSync as unlinkSync7 } from "fs";
145685
145928
  import { join as join103, dirname as dirname50, basename as basename20 } from "path";
145686
145929
  import { homedir as homedir19 } from "os";
145687
145930
  function ensureSynthScript() {
145688
145931
  if (!existsSync91(SCRIPT_PATH)) {
145689
- mkdirSync49(SCRIPT_DIR, { recursive: true });
145932
+ mkdirSync48(SCRIPT_DIR, { recursive: true });
145690
145933
  writeFileSync38(SCRIPT_PATH, SYNTH_SCRIPT);
145691
145934
  const currentName = basename20(SCRIPT_PATH);
145692
145935
  try {
@@ -145727,7 +145970,7 @@ async function synthesize(text2, outputPath, options) {
145727
145970
  ensureVoices({ onProgress: options?.onProgress })
145728
145971
  ]);
145729
145972
  const scriptPath = ensureSynthScript();
145730
- mkdirSync49(dirname50(outputPath), { recursive: true });
145973
+ mkdirSync48(dirname50(outputPath), { recursive: true });
145731
145974
  options?.onProgress?.(`Generating speech with voice ${voice} (${lang})...`);
145732
145975
  try {
145733
145976
  const espeakLang = ESPEAK_LANG_OVERRIDES[lang] ?? lang;
@@ -187169,7 +187412,7 @@ __export(snapshot_exports, {
187169
187412
  resolveSnapshotVideoFrameTime: () => resolveSnapshotVideoFrameTime,
187170
187413
  tailFrameTime: () => tailFrameTime
187171
187414
  });
187172
- import { existsSync as existsSync98, mkdtempSync as mkdtempSync13, readFileSync as readFileSync68, mkdirSync as mkdirSync50, rmSync as rmSync29, writeFileSync as writeFileSync41 } from "fs";
187415
+ import { existsSync as existsSync98, mkdtempSync as mkdtempSync14, readFileSync as readFileSync68, mkdirSync as mkdirSync49, rmSync as rmSync29, writeFileSync as writeFileSync41 } from "fs";
187173
187416
  import { tmpdir as tmpdir15 } from "os";
187174
187417
  import { resolve as resolve67, join as join106, relative as relative24, isAbsolute as isAbsolute15, basename as basename25 } from "path";
187175
187418
  function orbitStageSource() {
@@ -187214,7 +187457,7 @@ function requireSnapshotFfmpeg(ffmpegPath) {
187214
187457
  );
187215
187458
  }
187216
187459
  async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDecoder = false) {
187217
- const tmp = mkdtempSync13(join106(tmpdir15(), "hf-snapshot-frame-"));
187460
+ const tmp = mkdtempSync14(join106(tmpdir15(), "hf-snapshot-frame-"));
187218
187461
  const outPath = join106(tmp, "frame.png");
187219
187462
  try {
187220
187463
  const ffmpegPath = requireSnapshotFfmpeg(findFFmpeg());
@@ -187328,7 +187571,7 @@ async function captureSnapshots(projectDir, opts) {
187328
187571
  }
187329
187572
  const cameraExpr = opts.angle && (opts.angle.yaw !== 0 || opts.angle.pitch !== 0) ? `(${orbitStageSource()})(${JSON.stringify(opts.angle)})` : null;
187330
187573
  const snapshotDir = opts.outputDir ?? join106(projectDir, "snapshots");
187331
- mkdirSync50(snapshotDir, { recursive: true });
187574
+ mkdirSync49(snapshotDir, { recursive: true });
187332
187575
  try {
187333
187576
  const { readdirSync: readdirSync38 } = await import("fs");
187334
187577
  for (const file of readdirSync38(snapshotDir)) {
@@ -188676,8 +188919,8 @@ __export(grade_compare_exports, {
188676
188919
  import {
188677
188920
  copyFileSync as copyFileSync10,
188678
188921
  existsSync as existsSync100,
188679
- mkdirSync as mkdirSync51,
188680
- mkdtempSync as mkdtempSync14,
188922
+ mkdirSync as mkdirSync50,
188923
+ mkdtempSync as mkdtempSync15,
188681
188924
  readFileSync as readFileSync70,
188682
188925
  rmSync as rmSync30,
188683
188926
  writeFileSync as writeFileSync44
@@ -188939,7 +189182,7 @@ function frameFileNameForPath(framePath) {
188939
189182
  return "frame.png";
188940
189183
  }
188941
189184
  async function prepareGradeCompareTempProject(opts) {
188942
- const tempDir = mkdtempSync14(join107(tmpdir16(), "hf-grade-compare-"));
189185
+ const tempDir = mkdtempSync15(join107(tmpdir16(), "hf-grade-compare-"));
188943
189186
  try {
188944
189187
  const frameFileName2 = opts.frameFileName ?? frameFileNameForPath(opts.framePath);
188945
189188
  writeFileSync44(join107(tempDir, frameFileName2), opts.frameBuffer);
@@ -188986,7 +189229,7 @@ function isVideoPath2(filePath) {
188986
189229
  return [".mp4", ".mov", ".m4v", ".webm", ".mkv", ".avi", ".mpeg", ".mpg", ".ogv"].includes(ext);
188987
189230
  }
188988
189231
  async function extractVideoFrameToBuffer2(videoPath) {
188989
- const tmp = mkdtempSync14(join107(tmpdir16(), "hf-grade-compare-frame-"));
189232
+ const tmp = mkdtempSync15(join107(tmpdir16(), "hf-grade-compare-frame-"));
188990
189233
  const outPath = join107(tmp, "frame.png");
188991
189234
  try {
188992
189235
  const ffmpegPath = findFFmpeg();
@@ -189183,7 +189426,7 @@ var init_grade_compare = __esm({
189183
189426
  prepared.tempDir,
189184
189427
  parsed.timeoutMs
189185
189428
  );
189186
- mkdirSync51(dirname54(parsed.outPath), { recursive: true });
189429
+ mkdirSync50(dirname54(parsed.outPath), { recursive: true });
189187
189430
  copyFileSync10(tempSheet, parsed.outPath);
189188
189431
  trackCompareSheet({
189189
189432
  command: "grade-compare",
@@ -189228,7 +189471,7 @@ __export(compare_exports, {
189228
189471
  parseCompareArgs: () => parseCompareArgs,
189229
189472
  prepareCompareVariantProjects: () => prepareCompareVariantProjects
189230
189473
  });
189231
- import { cpSync as cpSync6, existsSync as existsSync101, mkdirSync as mkdirSync53, mkdtempSync as mkdtempSync15, renameSync as renameSync16, rmSync as rmSync31, statSync as statSync35 } from "fs";
189474
+ import { cpSync as cpSync6, existsSync as existsSync101, mkdirSync as mkdirSync51, mkdtempSync as mkdtempSync16, renameSync as renameSync16, rmSync as rmSync31, statSync as statSync35 } from "fs";
189232
189475
  import { tmpdir as tmpdir17 } from "os";
189233
189476
  import { basename as basename28, dirname as dirname55, extname as extname24, join as join108 } from "path";
189234
189477
  function defaultLabelForPath(input2) {
@@ -189329,7 +189572,7 @@ function inputError(variant) {
189329
189572
  );
189330
189573
  }
189331
189574
  function stageHtmlVariant(variant) {
189332
- const stagedDir = mkdtempSync15(join108(tmpdir17(), "hf-compare-variant-"));
189575
+ const stagedDir = mkdtempSync16(join108(tmpdir17(), "hf-compare-variant-"));
189333
189576
  try {
189334
189577
  cpSync6(dirname55(variant.inputPath), stagedDir, {
189335
189578
  recursive: true,
@@ -189426,7 +189669,7 @@ async function renderCompareSheet(parsed) {
189426
189669
  const capResult = capCompareVariants(parsed.variants);
189427
189670
  const variants = capResult.variants;
189428
189671
  const prepared = prepareCompareVariantProjects(variants);
189429
- const frameDir = mkdtempSync15(join108(tmpdir17(), "hf-compare-frames-"));
189672
+ const frameDir = mkdtempSync16(join108(tmpdir17(), "hf-compare-frames-"));
189430
189673
  const framePaths = [];
189431
189674
  try {
189432
189675
  let renderReadyTimedOut = false;
@@ -189441,7 +189684,7 @@ async function renderCompareSheet(parsed) {
189441
189684
  framePaths.push(rendered.framePath);
189442
189685
  renderReadyTimedOut = renderReadyTimedOut || rendered.renderReadyTimedOut;
189443
189686
  }
189444
- mkdirSync53(dirname55(parsed.outPath), { recursive: true });
189687
+ mkdirSync51(dirname55(parsed.outPath), { recursive: true });
189445
189688
  await createContactSheet(framePaths, parsed.outPath, {
189446
189689
  cols: parsed.cols ?? defaultCompareCols(framePaths.length),
189447
189690
  maxImages: framePaths.length,
@@ -189560,7 +189803,7 @@ ${c.error("\u2717")} Compare failed: ${message}`);
189560
189803
  });
189561
189804
 
189562
189805
  // src/capture/assetDownloader.ts
189563
- import { writeFileSync as writeFileSync45, mkdirSync as mkdirSync54 } from "fs";
189806
+ import { writeFileSync as writeFileSync45, mkdirSync as mkdirSync53 } from "fs";
189564
189807
  import { join as join109, extname as extname25 } from "path";
189565
189808
  import { createHash as createHash18 } from "crypto";
189566
189809
  function svgContentHashSlug(svgSource, isLogo) {
@@ -189569,10 +189812,10 @@ function svgContentHashSlug(svgSource, isLogo) {
189569
189812
  }
189570
189813
  async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks) {
189571
189814
  const assetsDir = join109(outputDir, "assets");
189572
- mkdirSync54(assetsDir, { recursive: true });
189815
+ mkdirSync53(assetsDir, { recursive: true });
189573
189816
  const assets = [];
189574
189817
  const downloadedUrls = /* @__PURE__ */ new Set();
189575
- mkdirSync54(join109(outputDir, "assets", "svgs"), { recursive: true });
189818
+ mkdirSync53(join109(outputDir, "assets", "svgs"), { recursive: true });
189576
189819
  const usedSvgNames = /* @__PURE__ */ new Set();
189577
189820
  for (let i2 = 0; i2 < tokens.svgs.length && i2 < 30; i2++) {
189578
189821
  const svg = tokens.svgs[i2];
@@ -189703,7 +189946,7 @@ function normalizeUrl(u) {
189703
189946
  }
189704
189947
  async function downloadAndRewriteFonts(css, outputDir) {
189705
189948
  const assetsDir = join109(outputDir, "assets", "fonts");
189706
- mkdirSync54(assetsDir, { recursive: true });
189949
+ mkdirSync53(assetsDir, { recursive: true });
189707
189950
  const fontUrlRegex = /url\(['"]?(https?:\/\/[^'")\s]+\.(?:woff2?|ttf|otf)[^'")\s]*?)['"]?\)/g;
189708
189951
  const fontUrls = /* @__PURE__ */ new Set();
189709
189952
  let match;
@@ -189896,7 +190139,7 @@ __export(video_exports, {
189896
190139
  runVideoMode: () => runVideoMode,
189897
190140
  safeFilename: () => safeFilename
189898
190141
  });
189899
- import { createWriteStream as createWriteStream4, existsSync as existsSync103, mkdirSync as mkdirSync55, readFileSync as readFileSync71, unlinkSync as unlinkSync9 } from "fs";
190142
+ import { createWriteStream as createWriteStream4, existsSync as existsSync103, mkdirSync as mkdirSync54, readFileSync as readFileSync71, unlinkSync as unlinkSync9 } from "fs";
189900
190143
  import { resolve as resolve71, join as join110, basename as basename29 } from "path";
189901
190144
  async function streamToFile(url, destPath) {
189902
190145
  const r2 = await safeFetch(url, {
@@ -190072,7 +190315,7 @@ async function runVideoMode(args) {
190072
190315
  return;
190073
190316
  }
190074
190317
  const outDir = isW2hLayout ? join110(projectDir, "capture", "assets", "videos") : join110(projectDir, "assets", "videos");
190075
- mkdirSync55(outDir, { recursive: true });
190318
+ mkdirSync54(outDir, { recursive: true });
190076
190319
  const fname = safeFilename(entry.filename || basename29(entry.url));
190077
190320
  const outPath = join110(outDir, fname);
190078
190321
  const relPath = isW2hLayout ? `capture/assets/videos/${fname}` : `assets/videos/${fname}`;
@@ -191641,7 +191884,7 @@ var init_animationCataloger = __esm({
191641
191884
  });
191642
191885
 
191643
191886
  // src/capture/mediaCapture.ts
191644
- import { mkdirSync as mkdirSync56, writeFileSync as writeFileSync47, readdirSync as readdirSync34, readFileSync as readFileSync74, statSync as statSync36 } from "fs";
191887
+ import { mkdirSync as mkdirSync55, writeFileSync as writeFileSync47, readdirSync as readdirSync34, readFileSync as readFileSync74, statSync as statSync36 } from "fs";
191645
191888
  import { join as join113, extname as extname26 } from "path";
191646
191889
  async function saveLottieAnimations(discoveredLotties, lottieDir) {
191647
191890
  let savedCount = 0;
@@ -191703,7 +191946,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
191703
191946
  async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
191704
191947
  const manifest = [];
191705
191948
  const previewDir = join113(lottieDir, "previews");
191706
- mkdirSync56(previewDir, { recursive: true });
191949
+ mkdirSync55(previewDir, { recursive: true });
191707
191950
  for (const file of readdirSync34(lottieDir)) {
191708
191951
  if (!file.endsWith(".json")) continue;
191709
191952
  try {
@@ -191869,9 +192112,9 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
191869
192112
  const merged = [...byKey.values()];
191870
192113
  if (merged.length === 0) return;
191871
192114
  const videoManifestDir = join113(outputDir, "assets", "videos");
191872
- mkdirSync56(videoManifestDir, { recursive: true });
192115
+ mkdirSync55(videoManifestDir, { recursive: true });
191873
192116
  const previewDir = join113(videoManifestDir, "previews");
191874
- mkdirSync56(previewDir, { recursive: true });
192117
+ mkdirSync55(previewDir, { recursive: true });
191875
192118
  const videoManifest = [];
191876
192119
  const dlStart = Date.now();
191877
192120
  for (let vi = 0; vi < merged.length && vi < 20; vi++) {
@@ -192577,11 +192820,11 @@ var screenshotCapture_exports = {};
192577
192820
  __export(screenshotCapture_exports, {
192578
192821
  captureScrollScreenshots: () => captureScrollScreenshots
192579
192822
  });
192580
- import { writeFileSync as writeFileSync50, mkdirSync as mkdirSync57 } from "fs";
192823
+ import { writeFileSync as writeFileSync50, mkdirSync as mkdirSync56 } from "fs";
192581
192824
  import { join as join117 } from "path";
192582
192825
  async function captureScrollScreenshots(page, outputDir) {
192583
192826
  const screenshotsDir = join117(outputDir, "screenshots");
192584
- mkdirSync57(screenshotsDir, { recursive: true });
192827
+ mkdirSync56(screenshotsDir, { recursive: true });
192585
192828
  const MAX_SCREENSHOTS = 20;
192586
192829
  const filePaths = [];
192587
192830
  try {
@@ -193021,7 +193264,7 @@ var capture_exports = {};
193021
193264
  __export(capture_exports, {
193022
193265
  captureWebsite: () => captureWebsite
193023
193266
  });
193024
- import { mkdirSync as mkdirSync58, writeFileSync as writeFileSync51, existsSync as existsSync108 } from "fs";
193267
+ import { mkdirSync as mkdirSync57, writeFileSync as writeFileSync51, existsSync as existsSync108 } from "fs";
193025
193268
  import { join as join118 } from "path";
193026
193269
  async function captureWebsite(opts, onProgress) {
193027
193270
  const {
@@ -193039,9 +193282,9 @@ async function captureWebsite(opts, onProgress) {
193039
193282
  onProgress?.(stage, detail);
193040
193283
  };
193041
193284
  loadEnvFile(outputDir);
193042
- mkdirSync58(join118(outputDir, "extracted"), { recursive: true });
193043
- mkdirSync58(join118(outputDir, "screenshots"), { recursive: true });
193044
- mkdirSync58(join118(outputDir, "assets"), { recursive: true });
193285
+ mkdirSync57(join118(outputDir, "extracted"), { recursive: true });
193286
+ mkdirSync57(join118(outputDir, "screenshots"), { recursive: true });
193287
+ mkdirSync57(join118(outputDir, "assets"), { recursive: true });
193045
193288
  progress("browser", "Launching headless Chrome...");
193046
193289
  const { ensureBrowser: ensureBrowser2 } = await Promise.resolve().then(() => (init_manager2(), manager_exports2));
193047
193290
  const browser = await ensureBrowser2();
@@ -193202,7 +193445,7 @@ async function captureWebsite(opts, onProgress) {
193202
193445
  }
193203
193446
  if (discoveredLotties.length > 0) {
193204
193447
  const lottieDir = join118(outputDir, "assets", "lottie");
193205
- mkdirSync58(lottieDir, { recursive: true });
193448
+ mkdirSync57(lottieDir, { recursive: true });
193206
193449
  const savedCount = await saveLottieAnimations(discoveredLotties, lottieDir);
193207
193450
  if (savedCount > 0) {
193208
193451
  await renderLottiePreviews(chromeBrowser, lottieDir, outputDir);
@@ -193706,8 +193949,8 @@ var init_capture2 = __esm({
193706
193949
  } catch (err) {
193707
193950
  const errMsg = normalizeErrorMessage(err);
193708
193951
  try {
193709
- const { mkdirSync: mkdirSync69, writeFileSync: writeFileSync61 } = await import("fs");
193710
- mkdirSync69(outputDir, { recursive: true });
193952
+ const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync61 } = await import("fs");
193953
+ mkdirSync68(outputDir, { recursive: true });
193711
193954
  const isTimeout = /timeout|timed out/i.test(errMsg);
193712
193955
  const reason = isTimeout ? "Page navigation timed out \u2014 the site may be blocking headless browsers or requires authentication." : `Capture failed: ${errMsg}`;
193713
193956
  writeFileSync61(
@@ -193774,14 +194017,14 @@ __export(state_exports, {
193774
194017
  stateFilePath: () => stateFilePath,
193775
194018
  writeStackOutputs: () => writeStackOutputs
193776
194019
  });
193777
- import { existsSync as existsSync109, mkdirSync as mkdirSync59, readdirSync as readdirSync37, readFileSync as readFileSync77, rmSync as rmSync32, writeFileSync as writeFileSync53 } from "fs";
194020
+ import { existsSync as existsSync109, mkdirSync as mkdirSync58, readdirSync as readdirSync37, readFileSync as readFileSync77, rmSync as rmSync32, writeFileSync as writeFileSync53 } from "fs";
193778
194021
  import { dirname as dirname56, join as join119 } from "path";
193779
194022
  function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
193780
194023
  return join119(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
193781
194024
  }
193782
194025
  function writeStackOutputs(outputs, cwd = process.cwd()) {
193783
194026
  const path2 = stateFilePath(outputs.stackName, cwd);
193784
- mkdirSync59(dirname56(path2), { recursive: true });
194027
+ mkdirSync58(dirname56(path2), { recursive: true });
193785
194028
  writeFileSync53(path2, JSON.stringify(outputs, null, 2) + "\n");
193786
194029
  return path2;
193787
194030
  }
@@ -195376,7 +195619,7 @@ __export(cloudrun_exports, {
195376
195619
  missingCloudRunAdapterMessage: () => missingCloudRunAdapterMessage
195377
195620
  });
195378
195621
  import { spawnSync as spawnSync6 } from "child_process";
195379
- import { existsSync as existsSync116, mkdirSync as mkdirSync60, readFileSync as readFileSync81, writeFileSync as writeFileSync54 } from "fs";
195622
+ import { existsSync as existsSync116, mkdirSync as mkdirSync59, readFileSync as readFileSync81, writeFileSync as writeFileSync54 } from "fs";
195380
195623
  import { homedir as homedir20 } from "os";
195381
195624
  import { join as join126, resolve as resolve76 } from "path";
195382
195625
  function loadCloudRunAdapter() {
@@ -195403,7 +195646,7 @@ function statePath() {
195403
195646
  return join126(stateDir(), "cloudrun-state.json");
195404
195647
  }
195405
195648
  function writeState(state) {
195406
- mkdirSync60(stateDir(), { recursive: true });
195649
+ mkdirSync59(stateDir(), { recursive: true });
195407
195650
  writeFileSync54(statePath(), JSON.stringify(state, null, 2));
195408
195651
  }
195409
195652
  function readState(args) {
@@ -195562,7 +195805,7 @@ function findRepoRoot(tfDir) {
195562
195805
  }
195563
195806
  function writeCloudBuildConfig(image) {
195564
195807
  const cfgPath = join126(stateDir(), "cloudrun-cloudbuild.yaml");
195565
- mkdirSync60(stateDir(), { recursive: true });
195808
+ mkdirSync59(stateDir(), { recursive: true });
195566
195809
  writeFileSync54(
195567
195810
  cfgPath,
195568
195811
  [
@@ -196215,7 +196458,7 @@ var init_poll = __esm({
196215
196458
  });
196216
196459
 
196217
196460
  // src/cloud/download.ts
196218
- import { createWriteStream as createWriteStream5, mkdirSync as mkdirSync61, unlinkSync as unlinkSync10 } from "fs";
196461
+ import { createWriteStream as createWriteStream5, mkdirSync as mkdirSync60, unlinkSync as unlinkSync10 } from "fs";
196219
196462
  import { dirname as dirname58 } from "path";
196220
196463
  async function downloadToFile(url, destPath, options = {}) {
196221
196464
  const fetchImpl = options.fetchImpl ?? fetch;
@@ -196226,7 +196469,7 @@ async function downloadToFile(url, destPath, options = {}) {
196226
196469
  if (!res.body) {
196227
196470
  throw new Error(`Failed to download ${url}: empty response body`);
196228
196471
  }
196229
- mkdirSync61(dirname58(destPath), { recursive: true });
196472
+ mkdirSync60(dirname58(destPath), { recursive: true });
196230
196473
  const totalHeader = res.headers.get("content-length");
196231
196474
  const total = totalHeader ? Number.parseInt(totalHeader, 10) : void 0;
196232
196475
  const totalOpt = total !== void 0 && Number.isFinite(total) ? total : void 0;
@@ -198783,7 +199026,7 @@ var init_parseFigmaRef = __esm({
198783
199026
  });
198784
199027
 
198785
199028
  // ../core/dist/figma/freeze.js
198786
- import { copyFileSync as copyFileSync11, mkdirSync as mkdirSync63, rmSync as rmSync33, statSync as statSync38, writeFileSync as writeFileSync55 } from "fs";
199029
+ import { copyFileSync as copyFileSync11, mkdirSync as mkdirSync61, rmSync as rmSync33, statSync as statSync38, writeFileSync as writeFileSync55 } from "fs";
198787
199030
  import { dirname as dirname59 } from "path";
198788
199031
  function exceedsFreezeCap(byteLength) {
198789
199032
  return byteLength > MAX_FREEZE_BYTES;
@@ -198793,7 +199036,7 @@ function freezeBytes(bytes, destPath) {
198793
199036
  throw new Error("freeze failed: empty bytes");
198794
199037
  if (exceedsFreezeCap(bytes.length))
198795
199038
  throw new Error(`freeze failed: ${bytes.length} bytes exceeds ${MAX_FREEZE_BYTES} cap`);
198796
- mkdirSync63(dirname59(destPath), { recursive: true });
199039
+ mkdirSync61(dirname59(destPath), { recursive: true });
198797
199040
  try {
198798
199041
  writeFileSync55(destPath, bytes, { flag: "wx" });
198799
199042
  } catch (err) {
@@ -198837,7 +199080,7 @@ var init_jsonl = __esm({
198837
199080
  });
198838
199081
 
198839
199082
  // ../core/dist/figma/manifest.js
198840
- import { appendFileSync as appendFileSync2, existsSync as existsSync119, mkdirSync as mkdirSync64, readFileSync as readFileSync85, writeFileSync as writeFileSync56 } from "fs";
199083
+ import { appendFileSync as appendFileSync2, existsSync as existsSync119, mkdirSync as mkdirSync63, readFileSync as readFileSync85, writeFileSync as writeFileSync56 } from "fs";
198841
199084
  import { join as join127 } from "path";
198842
199085
  function mediaDir(projectDir) {
198843
199086
  return join127(projectDir, ".media");
@@ -198870,7 +199113,7 @@ function readManifest(projectDir) {
198870
199113
  return readJsonlValues(manifestPath(projectDir)).filter(isFigmaManifestRecord);
198871
199114
  }
198872
199115
  function appendRecord(projectDir, record) {
198873
- mkdirSync64(typeDirPath(projectDir, record.type), { recursive: true });
199116
+ mkdirSync63(typeDirPath(projectDir, record.type), { recursive: true });
198874
199117
  appendFileSync2(manifestPath(projectDir), JSON.stringify(record) + "\n");
198875
199118
  }
198876
199119
  function findAllByFigmaNode(projectDir, fileKey, nodeId) {
@@ -198932,7 +199175,7 @@ var init_manifest = __esm({
198932
199175
  });
198933
199176
 
198934
199177
  // ../core/dist/figma/mediaIndex.js
198935
- import { mkdirSync as mkdirSync65, writeFileSync as writeFileSync57 } from "fs";
199178
+ import { mkdirSync as mkdirSync64, writeFileSync as writeFileSync57 } from "fs";
198936
199179
  import { dirname as dirname60, join as join128 } from "path";
198937
199180
  function isRow(value) {
198938
199181
  return typeof value === "object" && value !== null;
@@ -198983,7 +199226,7 @@ function regenerateIndex(projectDir) {
198983
199226
  const records = readJsonlValues(manifestPath(projectDir)).filter(isRow);
198984
199227
  const content = generateIndexContent(records);
198985
199228
  const p2 = indexPath(projectDir);
198986
- mkdirSync65(dirname60(p2), { recursive: true });
199229
+ mkdirSync64(dirname60(p2), { recursive: true });
198987
199230
  writeFileSync57(p2, content);
198988
199231
  return content;
198989
199232
  }
@@ -199049,7 +199292,7 @@ var init_sanitizeSvg = __esm({
199049
199292
  });
199050
199293
 
199051
199294
  // ../core/dist/figma/bindings.js
199052
- import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync66, writeFileSync as writeFileSync58 } from "fs";
199295
+ import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync65, writeFileSync as writeFileSync58 } from "fs";
199053
199296
  import { join as join129 } from "path";
199054
199297
  function bindingsPath(projectDir) {
199055
199298
  return join129(mediaDir(projectDir), BINDINGS_FILE);
@@ -199069,7 +199312,7 @@ function readBindings(projectDir) {
199069
199312
  function upsertBindings(projectDir, records) {
199070
199313
  const incoming = new Set(records.map((r2) => r2.figmaId));
199071
199314
  const survivors = readLines(projectDir).filter((line2) => !(isBindingRecord(line2) && incoming.has(line2.figmaId)));
199072
- mkdirSync66(mediaDir(projectDir), { recursive: true });
199315
+ mkdirSync65(mediaDir(projectDir), { recursive: true });
199073
199316
  const lines = [...survivors, ...records].map((r2) => JSON.stringify(r2)).join("\n");
199074
199317
  writeFileSync58(bindingsPath(projectDir), lines.length > 0 ? lines + "\n" : "");
199075
199318
  }
@@ -199938,7 +200181,7 @@ __export(component_exports, {
199938
200181
  default: () => component_default,
199939
200182
  runComponentImport: () => runComponentImport
199940
200183
  });
199941
- import { existsSync as existsSync121, mkdirSync as mkdirSync67, writeFileSync as writeFileSync60 } from "fs";
200184
+ import { existsSync as existsSync121, mkdirSync as mkdirSync66, writeFileSync as writeFileSync60 } from "fs";
199942
200185
  import { join as join133, relative as relative29 } from "path";
199943
200186
  function escapeAttr2(value) {
199944
200187
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
@@ -199955,7 +200198,7 @@ async function runComponentImport(refInput, deps) {
199955
200198
  console.warn(
199956
200199
  `component dir compositions/components/${name} already exists \u2014 overwriting (rename the figma frame for a separate import)`
199957
200200
  );
199958
- mkdirSync67(componentDir, { recursive: true });
200201
+ mkdirSync66(componentDir, { recursive: true });
199959
200202
  const { html, frozenAssets, failedRasterize } = await rasterizeFallback(
199960
200203
  mapped,
199961
200204
  ref2.fileKey,
@@ -200156,7 +200399,7 @@ __export(autoUpdate_exports, {
200156
200399
  scheduleBackgroundInstall: () => scheduleBackgroundInstall
200157
200400
  });
200158
200401
  import { spawn as spawn16 } from "child_process";
200159
- import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync68, openSync as openSync8 } from "fs";
200402
+ import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync67, openSync as openSync8 } from "fs";
200160
200403
  import { homedir as homedir21 } from "os";
200161
200404
  import { join as join134 } from "path";
200162
200405
  import { compareVersions as compareVersions3 } from "compare-versions";
@@ -200173,14 +200416,14 @@ function majorOf(version2) {
200173
200416
  }
200174
200417
  function log(line2) {
200175
200418
  try {
200176
- mkdirSync68(CONFIG_DIR3, { recursive: true, mode: 448 });
200419
+ mkdirSync67(CONFIG_DIR3, { recursive: true, mode: 448 });
200177
200420
  appendFileSync4(LOG_FILE, `${(/* @__PURE__ */ new Date()).toISOString()} ${line2}
200178
200421
  `, { mode: 384 });
200179
200422
  } catch {
200180
200423
  }
200181
200424
  }
200182
200425
  function launchDetachedInstall(invocation, displayCommand, version2) {
200183
- mkdirSync68(CONFIG_DIR3, { recursive: true, mode: 448 });
200426
+ mkdirSync67(CONFIG_DIR3, { recursive: true, mode: 448 });
200184
200427
  const configFile = join134(CONFIG_DIR3, "config.json");
200185
200428
  const nodeScript = `
200186
200429
  const { execFile } = require("node:child_process");