MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / launchDetachedInstall

Function launchDetachedInstall

packages/cli/src/utils/autoUpdate.ts:77–118  ·  view source on GitHub ↗

* Spawn a detached child to run the install command. Stdout/stderr land in * the log file; the child is `unref()`d so the parent exits immediately * regardless of install duration. * * The child is responsible for writing `completedUpdate` to the config when * it finishes — we express that by r

(installCommand: string, version: string)

Source from the content-addressed store, hash-verified

75 * one spawned process with no extra binary to distribute.
76 */
77function launchDetachedInstall(installCommand: string, version: string): void {
78 mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
79 const configFile = join(CONFIG_DIR, "config.json");
80
81 // The child script:
82 // 1. Runs the install command, capturing exit code + stderr tail.
83 // 2. Rewrites the config file with completedUpdate, clears pendingUpdate.
84 // We shell out to `node -e` so we don't need to ship a separate file.
85 const nodeScript = `
86 const { exec } = require("node:child_process");
87 const { readFileSync, renameSync, writeFileSync } = require("node:fs");
88 const CFG = ${JSON.stringify(configFile)};
89 const TMP = \`\${CFG}.tmp\`;
90 const VERSION = ${JSON.stringify(version)};
91 const CMD = ${JSON.stringify(installCommand)};
92 exec(CMD, { windowsHide: true, maxBuffer: 4 * 1024 * 1024 }, (err, _stdout, stderr) => {
93 let cfg = {};
94 try { cfg = JSON.parse(readFileSync(CFG, "utf-8")); } catch (e) {}
95 cfg.completedUpdate = {
96 version: VERSION,
97 ok: !err,
98 finishedAt: new Date().toISOString(),
99 ...(err ? { error: String(stderr || err.message || "install failed").slice(-400) } : {}),
100 };
101 delete cfg.pendingUpdate;
102 try {
103 writeFileSync(TMP, JSON.stringify(cfg, null, 2) + "\\n", { mode: 0o600 });
104 renameSync(TMP, CFG);
105 } catch (e) {}
106 });
107 `;
108
109 const out = openSync(LOG_FILE, "a", 0o600);
110 const child = spawn(process.execPath, ["-e", nodeScript], {
111 detached: true,
112 stdio: ["ignore", out, out],
113 windowsHide: true,
114 env: { ...process.env, HYPERFRAMES_NO_UPDATE_CHECK: "1", HYPERFRAMES_NO_AUTO_INSTALL: "1" },
115 });
116 child.unref();
117 log(`[launch] pid=${child.pid ?? "?"} cmd=${installCommand} version=${version}`);
118}
119
120/**
121 * If a new version is available and policy allows, kick off a detached

Callers 1

Calls 2

logFunction · 0.85
spawnFunction · 0.50

Tested by

no test coverage detected