mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-15 13:58:20 +00:00
* fix(cli): commands exit without waiting on update checks or telemetry The update and skills checks run in a detached child that refreshes the caches for the next run; the parent only reads the caches. finalizeCli no longer awaits the telemetry flush: the exit handler flushSync() delivers what is queued. The events beacon, feedback and figma error paths stop awaiting flush() too. * fix(cli): retry a failed background check at most once an hour Before starting the background worker, the CLI stamps a per-check attempt time and skips a check it attempted within the hour, so a dead network no longer starts a worker on every command. The stale-pin notice writes onto a fresh read, detached spawns set windowsHide, and a test ties the worker path to its build entry. * fix(cli): a failed-check stamp dated in the future no longer silences update checks
45 lines
1.8 KiB
TypeScript
45 lines
1.8 KiB
TypeScript
import { spawn } from "node:child_process";
|
|
import { dirname, join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { readConfig, readConfigFresh, writeConfig } from "../telemetry/config.js";
|
|
import { skillsCheckDue } from "./skillsUpdateCheck.js";
|
|
import { updateCheckDue } from "./updateCheck.js";
|
|
|
|
/** A check that did not refresh its cache (offline, DNS down) is retried at most this often. */
|
|
const FAILED_CHECK_RETRY_MS = 60 * 60 * 1000;
|
|
|
|
function attemptedRecently(stamp: string | undefined, now: number): boolean {
|
|
const age = stamp === undefined ? NaN : now - new Date(stamp).getTime();
|
|
return age >= 0 && age < FAILED_CHECK_RETRY_MS;
|
|
}
|
|
|
|
/** Refresh the due update and skills caches in a detached child, so this process never waits on it. */
|
|
export function launchBackgroundChecks(): void {
|
|
const now = Date.now();
|
|
const config = readConfig();
|
|
const due: string[] = [];
|
|
if (updateCheckDue() && !attemptedRecently(config.lastUpdateAttemptAt, now)) due.push("update");
|
|
if (skillsCheckDue() && !attemptedRecently(config.lastSkillsAttemptAt, now)) due.push("skills");
|
|
if (due.length === 0) return;
|
|
|
|
const stamped = readConfigFresh();
|
|
const at = new Date(now).toISOString();
|
|
if (due.includes("update")) stamped.lastUpdateAttemptAt = at;
|
|
if (due.includes("skills")) stamped.lastSkillsAttemptAt = at;
|
|
writeConfig(stamped);
|
|
|
|
// Next to the bundled cli.js; from source (dev mode) no check is ever due.
|
|
const worker = join(dirname(fileURLToPath(import.meta.url)), "backgroundChecksWorker.js");
|
|
try {
|
|
const child = spawn(process.execPath, [worker, ...due], {
|
|
detached: true,
|
|
stdio: "ignore",
|
|
windowsHide: true,
|
|
});
|
|
child.on("error", () => {});
|
|
child.unref();
|
|
} catch {
|
|
// Best-effort: the next run tries again.
|
|
}
|
|
}
|