@livedesk/client 0.1.170 → 0.1.171
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/bin/livedesk-client-node.js +29 -42
- package/bin/livedesk-client.js +22 -10
- package/package.json +5 -5
|
@@ -50,6 +50,9 @@ async function writeClientUpdateState(stage, details = {}) {
|
|
|
50
50
|
const statePath = getClientUpdateStatePath();
|
|
51
51
|
const operationId = String(details.operationId || process.env.LIVEDESK_CLIENT_UPDATE_OPERATION_ID || '').trim();
|
|
52
52
|
if (!operationId) return;
|
|
53
|
+
const attemptId = stage === 'scheduled'
|
|
54
|
+
? ''
|
|
55
|
+
: String(details.attemptId || process.env.LIVEDESK_CLIENT_UPDATE_ATTEMPT_ID || '').trim();
|
|
53
56
|
let previous = null;
|
|
54
57
|
try {
|
|
55
58
|
previous = JSON.parse(await fs.readFile(statePath, 'utf8'));
|
|
@@ -61,6 +64,18 @@ async function writeClientUpdateState(stage, details = {}) {
|
|
|
61
64
|
&& stage === 'scheduled'
|
|
62
65
|
&& ['connected', 'failed', 'restored'].includes(String(previous.stage || ''));
|
|
63
66
|
if (previous?.operationId && previous.operationId !== operationId && !replacesTerminalOperation) return;
|
|
67
|
+
if (!replacesTerminalOperation
|
|
68
|
+
&& previous?.attemptId
|
|
69
|
+
&& attemptId
|
|
70
|
+
&& previous.attemptId !== attemptId) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!replacesTerminalOperation
|
|
74
|
+
&& previous?.stage === 'connected'
|
|
75
|
+
&& previous?.restartVerified === true
|
|
76
|
+
&& stage !== 'connected') {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
64
79
|
const targetProductVersion = String(
|
|
65
80
|
details.targetProductVersion
|
|
66
81
|
|| process.env.LIVEDESK_CLIENT_UPDATE_TARGET_PRODUCT_VERSION
|
|
@@ -87,7 +102,7 @@ async function writeClientUpdateState(stage, details = {}) {
|
|
|
87
102
|
agentVersion: AGENT_VERSION,
|
|
88
103
|
agentPid: process.pid,
|
|
89
104
|
launcherPid: Number(process.env.LIVEDESK_CLIENT_PARENT_PID || 0) || 0,
|
|
90
|
-
attemptId
|
|
105
|
+
attemptId,
|
|
91
106
|
updatedAt: new Date().toISOString(),
|
|
92
107
|
...details
|
|
93
108
|
};
|
|
@@ -111,7 +126,7 @@ async function waitForClientUpdateShutdownSignal(operationId, timeoutMs = 150_00
|
|
|
111
126
|
await wait(200);
|
|
112
127
|
continue;
|
|
113
128
|
}
|
|
114
|
-
if (state.stage === 'waiting-for-shutdown') return true;
|
|
129
|
+
if (state.stage === 'preflight-ready' || state.stage === 'waiting-for-shutdown') return true;
|
|
115
130
|
if (state.stage === 'failed') {
|
|
116
131
|
console.error(`LiveDesk client update preparation failed: ${state.error || 'unknown error'}`);
|
|
117
132
|
return false;
|
|
@@ -1432,55 +1447,27 @@ function remotePolicyAllows(options, command) {
|
|
|
1432
1447
|
|
|
1433
1448
|
function buildClientUpdateBootstrapScript() {
|
|
1434
1449
|
return [
|
|
1435
|
-
'const { spawn
|
|
1450
|
+
'const { spawn } = require("node:child_process");',
|
|
1436
1451
|
'const fs = require("node:fs");',
|
|
1437
1452
|
'const path = require("node:path");',
|
|
1438
|
-
'const crypto = require("node:crypto");',
|
|
1439
|
-
'const waitPid = Number(process.env.LIVEDESK_UPDATE_WAIT_PID || 0);',
|
|
1440
|
-
'const agentPid = Number(process.env.LIVEDESK_UPDATE_AGENT_PID || 0);',
|
|
1441
1453
|
'const operationId = String(process.env.LIVEDESK_CLIENT_UPDATE_OPERATION_ID || "").trim();',
|
|
1442
1454
|
'const statePath = String(process.env.LIVEDESK_CLIENT_UPDATE_STATE_PATH || path.join(require("node:os").homedir(), ".livedesk", "client-update.json"));',
|
|
1443
|
-
'const logPath = statePath.replace(/\\.json$/i, "") + ".log";',
|
|
1444
1455
|
'const cleanVersion = value => String(value || "").trim().replace(/^v/i, "");',
|
|
1445
|
-
'const versionPattern = /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$/;',
|
|
1446
1456
|
'const targetProductVersion = cleanVersion(process.env.LIVEDESK_CLIENT_UPDATE_TARGET_PRODUCT_VERSION || process.env.LIVEDESK_CLIENT_UPDATE_TARGET_VERSION);',
|
|
1447
|
-
'const
|
|
1448
|
-
'const currentProductVersion = cleanVersion(process.env.LIVEDESK_CLIENT_UPDATE_CURRENT_PRODUCT_VERSION || process.env.LIVEDESK_NPM_LAUNCHER_VERSION);',
|
|
1449
|
-
'const currentAgentVersion = cleanVersion(process.env.LIVEDESK_CLIENT_UPDATE_CURRENT_AGENT_VERSION || process.env.LIVEDESK_CLIENT_PACKAGE_VERSION || currentProductVersion);',
|
|
1450
|
-
'for (const [label, version] of [["target product", targetProductVersion], ["target Agent", targetAgentVersion], ["current product", currentProductVersion], ["current Agent", currentAgentVersion]]) { if (!versionPattern.test(version)) throw new Error("Invalid LiveDesk " + label + " update version: " + version); }',
|
|
1451
|
-
'const packageSpec = "livedesk@" + targetProductVersion;',
|
|
1452
|
-
'const localLauncher = String(process.env.LIVEDESK_CLIENT_UPDATE_LOCAL_LAUNCHER || process.env.LIVEDESK_UNIFIED_LAUNCHER_ENTRY || "").trim();',
|
|
1453
|
-
'const preservedArgs = (() => { try { const decoded = JSON.parse(Buffer.from(String(process.env.LIVEDESK_CLIENT_UPDATE_ARGS_BASE64 || ""), "base64").toString("utf8")); return Array.isArray(decoded) ? decoded.map(value => String(value)) : []; } catch { return []; } })();',
|
|
1454
|
-
'const proofTimeoutMs = Math.max(500, Number(process.env.LIVEDESK_CLIENT_UPDATE_PROOF_TIMEOUT_MS || 30000));',
|
|
1455
|
-
'const proofPollMs = Math.max(25, Number(process.env.LIVEDESK_CLIENT_UPDATE_PROOF_POLL_MS || 200));',
|
|
1456
|
-
'const killGraceMs = Math.max(50, Number(process.env.LIVEDESK_CLIENT_UPDATE_KILL_GRACE_MS || 1500));',
|
|
1457
|
-
'const targetLaunchLimit = 3;',
|
|
1458
|
-
'const restoreLaunchLimit = 2;',
|
|
1457
|
+
'const versionPattern = /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$/;',
|
|
1459
1458
|
'const readState = () => { try { return JSON.parse(fs.readFileSync(statePath, "utf8")); } catch { return {}; } };',
|
|
1460
|
-
'const
|
|
1461
|
-
'const
|
|
1462
|
-
'
|
|
1463
|
-
'const
|
|
1464
|
-
'const waitForExit = async (pid, timeoutMs) => { const deadline = Date.now() + timeoutMs; while (pid > 1 && Date.now() < deadline) { if (!isAlive(pid)) return true; await sleep(250); } return pid <= 1 || !isAlive(pid); };',
|
|
1465
|
-
'const killProcessTree = async pid => { if (!Number.isInteger(pid) || pid <= 1 || pid === process.pid) return; if (process.platform === "win32") { spawnSync("taskkill.exe", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, stdio: "ignore" }); } else { try { process.kill(-pid, "SIGTERM"); } catch { try { process.kill(pid, "SIGTERM"); } catch {} } await sleep(killGraceMs); try { process.kill(-pid, "SIGKILL"); } catch { try { process.kill(pid, "SIGKILL"); } catch {} } } await waitForExit(pid, killGraceMs); };',
|
|
1466
|
-
'const ensureExit = async (pid, label) => { if (pid <= 1 || await waitForExit(pid, 20000)) return; log(label + " pid=" + pid + " did not exit gracefully; terminating its process tree."); await killProcessTree(pid); if (isAlive(pid)) throw new Error(label + " process " + pid + " did not exit before restart."); };',
|
|
1459
|
+
'const writeFailure = error => { try { fs.mkdirSync(path.dirname(statePath), { recursive: true }); const previous = readState(); if (previous.operationId && previous.operationId !== operationId) return; const now = new Date().toISOString(); const next = { ...previous, operationId, stage: "failed", targetProductVersion, restartVerified: false, error: String(error?.message || error).slice(0, 4000), failedAt: now, updatedAt: now }; const temporary = statePath + "." + process.pid + ".handoff.tmp"; fs.writeFileSync(temporary, JSON.stringify(next, null, 2), { encoding: "utf8", mode: 0o600 }); fs.renameSync(temporary, statePath); } catch {} process.stderr.write("LiveDesk update handoff failed: " + (error?.message || error) + "\\n"); process.exitCode = 1; };',
|
|
1460
|
+
'const monitorPreflight = child => { let settled = false; const finish = (error, preserveFailure = false) => { if (settled) return; settled = true; clearInterval(poll); clearTimeout(timeout); child.unref(); if (preserveFailure) process.exitCode = 1; else if (error) writeFailure(error); }; const inspect = () => { const state = readState(); if (state.operationId !== operationId) return; if (state.stage === "preflight-ready" || state.stage === "waiting-for-shutdown") finish(); else if (state.stage === "failed") finish(null, true); }; const poll = setInterval(inspect, 100); const timeout = setTimeout(() => { try { child.kill(); } catch {} finish(new Error("Timed out waiting for exact-package update preflight.")); }, Math.max(1000, Number(process.env.LIVEDESK_CLIENT_UPDATE_HANDOFF_TIMEOUT_MS || 140000))); child.once("exit", (code, signal) => { inspect(); if (!settled) finish(new Error("Exact-package update supervisor exited before preflight (code=" + (code ?? "none") + ", signal=" + (signal || "none") + ").")); }); inspect(); };',
|
|
1461
|
+
'if (!operationId || !versionPattern.test(targetProductVersion)) { writeFailure(new Error("Invalid LiveDesk exact-package update handoff.")); } else {',
|
|
1462
|
+
'const env = { ...process.env, LIVEDESK_UPDATE_STARTER_PID: String(process.pid) };',
|
|
1467
1463
|
'const nodeDir = path.dirname(process.execPath);',
|
|
1468
|
-
'const
|
|
1469
|
-
'const npx =
|
|
1470
|
-
'
|
|
1471
|
-
'const npmExecPath = String(process.env.npm_execpath || process.env.NPM_EXECPATH || "").trim();',
|
|
1472
|
-
'const npxCliCandidates = [process.env.LIVEDESK_NPX_CLI_PATH, npmExecPath ? path.join(path.dirname(npmExecPath), "npx-cli.js") : "", path.join(nodeDir, "node_modules", "npm", "bin", "npx-cli.js")].filter(Boolean);',
|
|
1473
|
-
'const npxCli = npxCliCandidates.find(candidate => fs.existsSync(candidate));',
|
|
1464
|
+
'const npxCli = [env.LIVEDESK_NPX_CLI_PATH, env.npm_execpath ? path.join(path.dirname(env.npm_execpath), "npx-cli.js") : "", env.LIVEDESK_NPX_EXECUTABLE ? path.join(path.dirname(env.LIVEDESK_NPX_EXECUTABLE), "node_modules", "npm", "bin", "npx-cli.js") : "", path.join(nodeDir, "node_modules", "npm", "bin", "npx-cli.js")].find(value => value && fs.existsSync(value));',
|
|
1465
|
+
'const npx = env.LIVEDESK_NPX_EXECUTABLE || (process.platform === "win32" ? "npx.cmd" : "npx");',
|
|
1466
|
+
'const args = ["-y", "--prefer-online", "livedesk@" + targetProductVersion, "--internal-legacy-client-update"];',
|
|
1474
1467
|
'const quoteCmd = value => "\\"" + String(value).replaceAll("%", "%%").replaceAll("\\"", "\\"\\"") + "\\"";',
|
|
1475
|
-
'const invocation =
|
|
1476
|
-
'
|
|
1477
|
-
'
|
|
1478
|
-
'const attemptIdFor = (kind, number) => operationId + "-" + kind + "-" + number + "-" + crypto.randomBytes(4).toString("hex");',
|
|
1479
|
-
'const updateAttempt = (attempt, patch) => { Object.assign(attempt, patch, { updatedAt: new Date().toISOString() }); return attempts.map(item => ({ ...item })); };',
|
|
1480
|
-
'const killAttempt = async (restartPid, attemptId) => { const state = readState(); const pids = new Set([Number(restartPid || 0)]); if (state.operationId === operationId && state.attemptId === attemptId) { pids.add(Number(state.launcherPid || 0)); pids.add(Number(state.agentPid || 0)); } for (const pid of pids) await killProcessTree(pid); };',
|
|
1481
|
-
'const launchAndVerify = async ({ kind, number, expectedProductVersion, expectedAgentVersion, call }) => { const attemptId = attemptIdFor(kind, number); const attempt = { attemptId, kind, number, status: "launching", expectedProductVersion, expectedAgentVersion, startedAt: new Date().toISOString() }; attempts.push(attempt); const attemptEnv = { ...process.env, LIVEDESK_CLIENT_UPDATE_ATTEMPT_ID: attemptId, LIVEDESK_CLIENT_UPDATE_ATTEMPT_KIND: kind, LIVEDESK_CLIENT_UPDATE_ATTEMPT_NUMBER: String(number), LIVEDESK_CLIENT_UPDATE_OPERATION_ID: operationId, LIVEDESK_CLIENT_UPDATE_TARGET_PRODUCT_VERSION: targetProductVersion, LIVEDESK_CLIENT_UPDATE_TARGET_AGENT_VERSION: targetAgentVersion, LIVEDESK_CLIENT_UPDATE_TARGET_VERSION: targetAgentVersion }; const logFd = fs.openSync(logPath, "a"); let child; try { child = spawn(call.command, call.args, { cwd: process.env.LIVEDESK_CLIENT_UPDATE_CWD || process.cwd(), env: attemptEnv, detached: true, windowsHide: true, stdio: ["ignore", logFd, logFd] }); await new Promise((resolve, reject) => { child.once("error", reject); child.once("spawn", resolve); }); } finally { fs.closeSync(logFd); } const restartPid = Number(child?.pid || 0); updateAttempt(attempt, { status: "waiting-for-connected-proof", restartPid }); writeState(kind + "-launched", { attemptId, attemptKind: kind, attemptNumber: number, restartPid, attempts: attempts.map(item => ({ ...item })), restartVerified: false, error: "" }); let exitResult = null; child.once("exit", (code, signal) => { exitResult = { code, signal }; }); const deadline = Date.now() + proofTimeoutMs; let proof = null; let failure = ""; while (Date.now() < deadline) { const state = readState(); if (state.operationId === operationId && state.attemptId === attemptId && state.stage === "connected") { const observedProduct = cleanVersion(state.productVersion); const observedAgent = cleanVersion(state.agentVersion); if (observedProduct === expectedProductVersion && observedAgent === expectedAgentVersion) { proof = state; break; } failure = "Connected version mismatch expected product " + expectedProductVersion + " / Agent " + expectedAgentVersion + ", observed product " + (observedProduct || "unknown") + " / Agent " + (observedAgent || "unknown") + "."; break; } if (exitResult) { failure = "Launcher exited before exact connected proof (code=" + (exitResult.code ?? "none") + ", signal=" + (exitResult.signal || "none") + ")."; break; } await sleep(proofPollMs); } if (proof) { updateAttempt(attempt, { status: "connected", connectedAt: proof.connectedAt || new Date().toISOString(), productVersion: cleanVersion(proof.productVersion), agentVersion: cleanVersion(proof.agentVersion) }); if (child && !exitResult) child.unref(); writeState(kind === "target" ? "connected" : "restored", { attemptId, attemptKind: kind, attemptNumber: number, restartPid, launcherPid: Number(proof.launcherPid || 0), agentPid: Number(proof.agentPid || 0), productVersion: cleanVersion(proof.productVersion), agentVersion: cleanVersion(proof.agentVersion), attempts: attempts.map(item => ({ ...item })), restartVerified: kind === "target", restored: kind === "restore", connectedAt: proof.connectedAt || new Date().toISOString(), error: kind === "restore" ? "Target update failed; previous local Client was restored." : "" }); return true; } failure = failure || "Timed out waiting for exact connected proof for " + attemptId + "."; await killAttempt(restartPid, attemptId); updateAttempt(attempt, { status: "failed", failedAt: new Date().toISOString(), killed: true, error: failure }); writeState(kind + "-attempt-failed", { attemptId, attemptKind: kind, attemptNumber: number, restartPid, attempts: attempts.map(item => ({ ...item })), restartVerified: false, error: failure }); log(attemptId + " failed: " + failure); return false; };',
|
|
1482
|
-
'process.env.LIVEDESK_SKIP_BROWSER_OPEN = "1";',
|
|
1483
|
-
'(async () => { writeState("preparing-package", { packageSpec, attempts: [], error: "" }); log("preparing " + packageSpec); const prepared = await runToExit(["-y", "--prefer-online", packageSpec, "--version"], 120000); if (prepared.code !== 0) throw new Error("LiveDesk package preparation failed (exit=" + prepared.code + "): " + (prepared.stderr || prepared.stdout).trim().slice(-2000)); const stdoutVersions = prepared.stdout.split(/\\r?\\n/).map(line => line.trim()).filter(line => versionPattern.test(line)); if (!stdoutVersions.includes(targetProductVersion)) throw new Error("Prepared LiveDesk stdout did not report requested product version " + targetProductVersion + ". stdout=" + prepared.stdout.trim().slice(-1000)); writeState("waiting-for-shutdown", { observedVersion: targetProductVersion, observedProductVersion: targetProductVersion, preparedAt: new Date().toISOString(), attempts: [], error: "" }); log("package ready product=" + targetProductVersion + "; waiting for current runtime shutdown"); await ensureExit(agentPid, "Agent"); await ensureExit(waitPid, "Launcher"); const roleArgs = ["--force-role", "client", "--no-login", "--no-open", ...preservedArgs]; const targetCall = invocation(["-y", "--prefer-online", packageSpec, ...roleArgs]); for (let number = 1; number <= targetLaunchLimit; number += 1) { if (await launchAndVerify({ kind: "target", number, expectedProductVersion: targetProductVersion, expectedAgentVersion: targetAgentVersion, call: targetCall })) { log("target connected with exact product " + targetProductVersion + " / Agent " + targetAgentVersion); return; } } writeState("restoring", { attempts: attempts.map(item => ({ ...item })), error: "All target launch attempts failed; restoring previous local Client." }); const restoreCall = localLauncher && fs.existsSync(localLauncher) ? { command: process.execPath, args: [localLauncher, ...roleArgs] } : invocation(["-y", "--prefer-offline", "livedesk@" + currentProductVersion, ...roleArgs]); for (let number = 1; number <= restoreLaunchLimit; number += 1) { if (await launchAndVerify({ kind: "restore", number, expectedProductVersion: currentProductVersion, expectedAgentVersion: currentAgentVersion, call: restoreCall })) { log("previous local Client restored at product " + currentProductVersion + " / Agent " + currentAgentVersion); process.exitCode = 1; return; } } throw new Error("Target update failed after 3 attempts and previous local Client restoration failed after 2 attempts."); })().catch(error => { const message = error?.stack || error?.message || String(error); log("failed: " + message); try { writeState("failed", { attempts: attempts.map(item => ({ ...item })), error: String(error?.message || error).slice(0, 4000), failedAt: new Date().toISOString(), restartVerified: false }); } catch {} process.exitCode = 1; });',
|
|
1468
|
+
'const invocation = npxCli ? { command: process.execPath, args: [npxCli, ...args] } : process.platform === "win32" ? { command: env.ComSpec || "cmd.exe", args: ["/d", "/s", "/c", "call " + quoteCmd(npx) + " " + args.map(quoteCmd).join(" ")] } : { command: npx, args };',
|
|
1469
|
+
'if (!npxCli && path.isAbsolute(npx) && !fs.existsSync(npx)) { writeFailure(new Error("LiveDesk npx executable was not found: " + npx)); } else { try { const child = spawn(invocation.command, invocation.args, { env, detached: true, stdio: "ignore", windowsHide: true }); child.once("error", writeFailure); child.once("spawn", () => monitorPreflight(child)); } catch (error) { writeFailure(error); } }',
|
|
1470
|
+
'}',
|
|
1484
1471
|
''
|
|
1485
1472
|
].join('\n');
|
|
1486
1473
|
}
|
package/bin/livedesk-client.js
CHANGED
|
@@ -603,8 +603,15 @@ function readClientUpdateState() {
|
|
|
603
603
|
function writeClientUpdateRuntimeStage(stage, details = {}) {
|
|
604
604
|
const operationId = String(process.env.LIVEDESK_CLIENT_UPDATE_OPERATION_ID || '').trim();
|
|
605
605
|
if (!operationId) return;
|
|
606
|
+
const attemptId = String(process.env.LIVEDESK_CLIENT_UPDATE_ATTEMPT_ID || '').trim();
|
|
606
607
|
const previous = readClientUpdateState();
|
|
607
608
|
if (previous?.operationId && previous.operationId !== operationId) return;
|
|
609
|
+
if (previous?.attemptId && attemptId && previous.attemptId !== attemptId) return;
|
|
610
|
+
if (previous?.stage === 'connected'
|
|
611
|
+
&& previous?.restartVerified === true
|
|
612
|
+
&& stage !== 'connected') {
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
608
615
|
const targetVersion = String(process.env.LIVEDESK_CLIENT_UPDATE_TARGET_VERSION || '').trim().replace(/^v/i, '');
|
|
609
616
|
const productVersion = String(process.env.LIVEDESK_NPM_LAUNCHER_VERSION || readPackageVersion()).trim();
|
|
610
617
|
const state = {
|
|
@@ -615,6 +622,7 @@ function writeClientUpdateRuntimeStage(stage, details = {}) {
|
|
|
615
622
|
productVersion,
|
|
616
623
|
agentVersion: readPackageVersion(),
|
|
617
624
|
launcherPid: process.pid,
|
|
625
|
+
attemptId,
|
|
618
626
|
updatedAt: new Date().toISOString(),
|
|
619
627
|
...details
|
|
620
628
|
};
|
|
@@ -3592,9 +3600,10 @@ function buildClientAgentEnvironment(prepared) {
|
|
|
3592
3600
|
env.LIVEDESK_NPX_CLI_PATH = npxCliPath;
|
|
3593
3601
|
}
|
|
3594
3602
|
env.LIVEDESK_CLIENT_MANAGER = String(prepared?.manager || env.LIVEDESK_CLIENT_MANAGER || '');
|
|
3595
|
-
env.LIVEDESK_CLIENT_PAIR_TOKEN = String(prepared?.pair || env.LIVEDESK_CLIENT_PAIR_TOKEN || '');
|
|
3596
|
-
env.LIVEDESK_CLIENT_NAME = String(prepared?.name || env.LIVEDESK_CLIENT_NAME || '');
|
|
3603
|
+
env.LIVEDESK_CLIENT_PAIR_TOKEN = String(prepared?.pair || env.LIVEDESK_CLIENT_PAIR_TOKEN || '');
|
|
3604
|
+
env.LIVEDESK_CLIENT_NAME = String(prepared?.name || env.LIVEDESK_CLIENT_NAME || '');
|
|
3597
3605
|
env.LIVEDESK_CLIENT_SLOT = String(prepared?.slot || env.LIVEDESK_CLIENT_SLOT || '');
|
|
3606
|
+
env.LIVEDESK_DEVICE_ID = String(prepared?.deviceId || env.LIVEDESK_DEVICE_ID || '');
|
|
3598
3607
|
env.LIVEDESK_CLIENT_ENGINE = String(prepared?.engine || env.LIVEDESK_CLIENT_ENGINE || 'auto');
|
|
3599
3608
|
env.LIVEDESK_CLIENT_UPDATE_STATE_PATH = CLIENT_UPDATE_STATE_PATH;
|
|
3600
3609
|
env.LIVEDESK_CLIENT_UPDATE_ARGS_BASE64 = Buffer
|
|
@@ -3805,16 +3814,19 @@ function resolveFastLaunch(runtime) {
|
|
|
3805
3814
|
}
|
|
3806
3815
|
|
|
3807
3816
|
function spawnAgent(command, args, env = process.env, onStart = null) {
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
activeAgentProcess = child;
|
|
3814
|
-
writeClientUpdateRuntimeStage('agent-started', {
|
|
3815
|
-
agentPid: Number(child.pid || 0),
|
|
3817
|
+
// Publish only a pre-spawn stage. A very fast child can reach Hub welcome
|
|
3818
|
+
// before spawn() returns; a post-spawn write would then erase its one-shot
|
|
3819
|
+
// connected proof.
|
|
3820
|
+
writeClientUpdateRuntimeStage('agent-launching', {
|
|
3821
|
+
agentPid: 0,
|
|
3816
3822
|
restartVerified: false
|
|
3817
3823
|
});
|
|
3824
|
+
const child = spawn(command, args, {
|
|
3825
|
+
env,
|
|
3826
|
+
stdio: 'inherit',
|
|
3827
|
+
windowsHide: true
|
|
3828
|
+
});
|
|
3829
|
+
activeAgentProcess = child;
|
|
3818
3830
|
if (typeof onStart === 'function') {
|
|
3819
3831
|
onStart(child);
|
|
3820
3832
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livedesk/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.171",
|
|
4
4
|
"description": "LiveDesk local remote client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"ws": "^8.18.3"
|
|
40
40
|
},
|
|
41
41
|
"optionalDependencies": {
|
|
42
|
-
"@livedesk/fast-linux-x64": "0.1.
|
|
43
|
-
"@livedesk/fast-osx-arm64": "0.1.
|
|
44
|
-
"@livedesk/fast-osx-x64": "0.1.
|
|
45
|
-
"@livedesk/fast-win-x64": "0.1.
|
|
42
|
+
"@livedesk/fast-linux-x64": "0.1.377",
|
|
43
|
+
"@livedesk/fast-osx-arm64": "0.1.377",
|
|
44
|
+
"@livedesk/fast-osx-x64": "0.1.377",
|
|
45
|
+
"@livedesk/fast-win-x64": "0.1.377"
|
|
46
46
|
},
|
|
47
47
|
"publishConfig": {
|
|
48
48
|
"access": "public"
|