livedesk 0.1.549 → 0.1.551
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/README.md +9 -9
- package/bin/livedesk.js +146 -146
- package/bootstrap/hub-self-agent.js +243 -243
- package/client/bin/livedesk-client.js +102 -102
- package/client/package.json +5 -5
- package/client/src/runtime/agent-process-lifecycle.js +7 -7
- package/electron/auth-session-owner.mjs +80 -31
- package/electron/main.mjs +143 -103
- package/electron/oauth-pkce.mjs +10 -10
- package/electron/preload.cjs +4 -3
- package/hub/package.json +1 -1
- package/hub/src/agents/agent-result-enrichment.js +66 -66
- package/hub/src/agents/codex-agent-runtime.js +4 -4
- package/hub/src/console-relay.js +424 -424
- package/hub/src/live-desk-update.js +24 -24
- package/hub/src/remote-hub.js +6 -4
- package/hub/src/server.js +92 -92
- package/hub/src/settings/settings-schema.js +12 -12
- package/package.json +6 -6
- package/scripts/sync-web-dist.js +2 -2
- package/web/dist/_headers +14 -14
- package/web/dist/app.webmanifest +35 -35
- package/web/dist/assets/icons-Bna5_o78.js +1 -0
- package/web/dist/assets/{index-Dw8qULbS.css → index-Du6fwV95.css} +1 -1
- package/web/dist/assets/index-ZUNTrWWS.js +190 -0
- package/web/dist/assets/{react-BadjGr7a.js → react-DYqrNwY4.js} +1 -1
- package/web/dist/index.html +12 -12
- package/web/dist/livedesk-build-evidence.json +27 -27
- package/web/dist/offline.html +25 -25
- package/web/dist/sw.js +36 -36
- package/web/dist/assets/icons--ICR7K55.js +0 -1
- package/web/dist/assets/index-0u9fhYbB.js +0 -188
package/README.md
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
RemoteFast package for the current operating system and CPU, so Windows, macOS,
|
|
5
5
|
and Linux native binaries are no longer downloaded together.
|
|
6
6
|
|
|
7
|
-
One-command LiveDesk application. The same launcher resolves this computer's
|
|
8
|
-
Hub or Client role. A Client starts one managed Agent. A Hub starts the Hub
|
|
9
|
-
server plus one headless Self Agent, so the Hub computer also appears on the
|
|
10
|
-
wall and can be controlled like the other computers.
|
|
7
|
+
One-command LiveDesk application. The same launcher resolves this computer's
|
|
8
|
+
Hub or Client role. A Client starts one managed Agent. A Hub starts the Hub
|
|
9
|
+
server plus one headless Self Agent, so the Hub computer also appears on the
|
|
10
|
+
wall and can be controlled like the other computers.
|
|
11
11
|
|
|
12
12
|
The `hub/`, `client/`, `runtime-core/`, and `web/` folders in this package are
|
|
13
13
|
generated copies. Edit the source packages and run
|
|
@@ -45,11 +45,11 @@ npx -y --prefer-online livedesk@latest --force-role client
|
|
|
45
45
|
npx -y --prefer-online livedesk@latest hub
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
This starts the LiveDesk Hub, opens the local screen wall, accepts clients, and
|
|
49
|
-
connects one local Self Agent through loopback TCP. The Self Agent reuses the
|
|
50
|
-
Hub computer's stable device identity and does not open another login or status
|
|
51
|
-
page. Hub shutdown, update, and role change drain that exact Agent tree before
|
|
52
|
-
the launcher exits or hands off.
|
|
48
|
+
This starts the LiveDesk Hub, opens the local screen wall, accepts clients, and
|
|
49
|
+
connects one local Self Agent through loopback TCP. The Self Agent reuses the
|
|
50
|
+
Hub computer's stable device identity and does not open another login or status
|
|
51
|
+
page. Hub shutdown, update, and role change drain that exact Agent tree before
|
|
52
|
+
the launcher exits or hands off.
|
|
53
53
|
The Hub UI/API listens on `127.0.0.1` by default while the client endpoint
|
|
54
54
|
continues to listen on the LAN.
|
|
55
55
|
|
package/bin/livedesk.js
CHANGED
|
@@ -46,11 +46,11 @@ import {
|
|
|
46
46
|
readDeadWindowsOwnedProcessManifest,
|
|
47
47
|
readWindowsOwnedProcessManifest
|
|
48
48
|
} from '../client/src/runtime/windows-owned-process-manifest.js';
|
|
49
|
-
import { inspectMacDiagnosticLease } from '../diagnostics/livedesk-mac-physical-isolation.mjs';
|
|
50
|
-
import {
|
|
51
|
-
buildHubSelfAgentLaunchSpec,
|
|
52
|
-
createHubSelfAgentSupervisor
|
|
53
|
-
} from '../bootstrap/hub-self-agent.js';
|
|
49
|
+
import { inspectMacDiagnosticLease } from '../diagnostics/livedesk-mac-physical-isolation.mjs';
|
|
50
|
+
import {
|
|
51
|
+
buildHubSelfAgentLaunchSpec,
|
|
52
|
+
createHubSelfAgentSupervisor
|
|
53
|
+
} from '../bootstrap/hub-self-agent.js';
|
|
54
54
|
|
|
55
55
|
const require = createRequire(import.meta.url);
|
|
56
56
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -2540,47 +2540,47 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
2540
2540
|
let updateStopTimer = null;
|
|
2541
2541
|
let updateHardStopTimer = null;
|
|
2542
2542
|
let launcherShutdownSignal = '';
|
|
2543
|
-
let launcherShutdownHardStopTimer = null;
|
|
2544
|
-
let runtimeShutdownWatcher = null;
|
|
2545
|
-
let selfAgentStopPromise = null;
|
|
2546
|
-
const launcherSignalHandlers = new Map();
|
|
2547
|
-
|
|
2548
|
-
let hubSelfAgent = null;
|
|
2549
|
-
try {
|
|
2550
|
-
const clientEntry = resolve(packageRoot, 'client', 'bin', 'livedesk-client.js');
|
|
2551
|
-
if (!existsSync(clientEntry)) {
|
|
2552
|
-
throw new Error('the packaged Client runtime is missing');
|
|
2553
|
-
}
|
|
2554
|
-
hubSelfAgent = createHubSelfAgentSupervisor({
|
|
2555
|
-
launch: buildHubSelfAgentLaunchSpec({
|
|
2556
|
-
nodePath: process.execPath,
|
|
2557
|
-
clientEntry,
|
|
2558
|
-
remotePort,
|
|
2559
|
-
pairToken,
|
|
2560
|
-
deviceId: env.LIVEDESK_DEVICE_ID,
|
|
2561
|
-
deviceName: env.LIVEDESK_DEVICE_NAME,
|
|
2562
|
-
stateDir: MANAGER_STATE_DIR,
|
|
2563
|
-
runtimeOwner,
|
|
2564
|
-
baseEnv: env
|
|
2565
|
-
}),
|
|
2566
|
-
report: reportLauncherUpdate
|
|
2567
|
-
});
|
|
2568
|
-
} catch (error) {
|
|
2569
|
-
reportLauncherUpdate(
|
|
2570
|
-
`[LiveDesk Hub] Self Agent is unavailable: ${error?.message || error}. Remote Clients remain available.`,
|
|
2571
|
-
true
|
|
2572
|
-
);
|
|
2573
|
-
}
|
|
2574
|
-
|
|
2575
|
-
const stopHubSelfAgent = reason => {
|
|
2576
|
-
if (!hubSelfAgent) return Promise.resolve({ ok: true, skipped: true });
|
|
2577
|
-
if (!selfAgentStopPromise) {
|
|
2578
|
-
selfAgentStopPromise = hubSelfAgent.stop(reason).finally(() => {
|
|
2579
|
-
selfAgentStopPromise = null;
|
|
2580
|
-
});
|
|
2581
|
-
}
|
|
2582
|
-
return selfAgentStopPromise;
|
|
2583
|
-
};
|
|
2543
|
+
let launcherShutdownHardStopTimer = null;
|
|
2544
|
+
let runtimeShutdownWatcher = null;
|
|
2545
|
+
let selfAgentStopPromise = null;
|
|
2546
|
+
const launcherSignalHandlers = new Map();
|
|
2547
|
+
|
|
2548
|
+
let hubSelfAgent = null;
|
|
2549
|
+
try {
|
|
2550
|
+
const clientEntry = resolve(packageRoot, 'client', 'bin', 'livedesk-client.js');
|
|
2551
|
+
if (!existsSync(clientEntry)) {
|
|
2552
|
+
throw new Error('the packaged Client runtime is missing');
|
|
2553
|
+
}
|
|
2554
|
+
hubSelfAgent = createHubSelfAgentSupervisor({
|
|
2555
|
+
launch: buildHubSelfAgentLaunchSpec({
|
|
2556
|
+
nodePath: process.execPath,
|
|
2557
|
+
clientEntry,
|
|
2558
|
+
remotePort,
|
|
2559
|
+
pairToken,
|
|
2560
|
+
deviceId: env.LIVEDESK_DEVICE_ID,
|
|
2561
|
+
deviceName: env.LIVEDESK_DEVICE_NAME,
|
|
2562
|
+
stateDir: MANAGER_STATE_DIR,
|
|
2563
|
+
runtimeOwner,
|
|
2564
|
+
baseEnv: env
|
|
2565
|
+
}),
|
|
2566
|
+
report: reportLauncherUpdate
|
|
2567
|
+
});
|
|
2568
|
+
} catch (error) {
|
|
2569
|
+
reportLauncherUpdate(
|
|
2570
|
+
`[LiveDesk Hub] Self Agent is unavailable: ${error?.message || error}. Remote Clients remain available.`,
|
|
2571
|
+
true
|
|
2572
|
+
);
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
const stopHubSelfAgent = reason => {
|
|
2576
|
+
if (!hubSelfAgent) return Promise.resolve({ ok: true, skipped: true });
|
|
2577
|
+
if (!selfAgentStopPromise) {
|
|
2578
|
+
selfAgentStopPromise = hubSelfAgent.stop(reason).finally(() => {
|
|
2579
|
+
selfAgentStopPromise = null;
|
|
2580
|
+
});
|
|
2581
|
+
}
|
|
2582
|
+
return selfAgentStopPromise;
|
|
2583
|
+
};
|
|
2584
2584
|
|
|
2585
2585
|
const removeLauncherSignalHandlers = () => {
|
|
2586
2586
|
for (const [signal, handler] of launcherSignalHandlers) {
|
|
@@ -2589,7 +2589,7 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
2589
2589
|
launcherSignalHandlers.clear();
|
|
2590
2590
|
};
|
|
2591
2591
|
|
|
2592
|
-
const requestLauncherShutdown = signal => {
|
|
2592
|
+
const requestLauncherShutdown = signal => {
|
|
2593
2593
|
if (launcherShutdownSignal) return;
|
|
2594
2594
|
launcherShutdownSignal = signal;
|
|
2595
2595
|
restartRequest = null;
|
|
@@ -2601,18 +2601,18 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
2601
2601
|
clearTimeout(updateStopTimer);
|
|
2602
2602
|
updateStopTimer = null;
|
|
2603
2603
|
}
|
|
2604
|
-
if (updateHardStopTimer) {
|
|
2604
|
+
if (updateHardStopTimer) {
|
|
2605
2605
|
clearTimeout(updateHardStopTimer);
|
|
2606
|
-
updateHardStopTimer = null;
|
|
2607
|
-
}
|
|
2608
|
-
void stopHubSelfAgent(`launcher-${signal}`);
|
|
2609
|
-
const child = activeChild;
|
|
2610
|
-
if (!child || child.exitCode !== null || child.signalCode) {
|
|
2611
|
-
void stopHubSelfAgent(`launcher-${signal}`).finally(() => {
|
|
2612
|
-
try { hubLogStream?.end(); } catch {}
|
|
2613
|
-
process.exit(0);
|
|
2614
|
-
});
|
|
2615
|
-
return;
|
|
2606
|
+
updateHardStopTimer = null;
|
|
2607
|
+
}
|
|
2608
|
+
void stopHubSelfAgent(`launcher-${signal}`);
|
|
2609
|
+
const child = activeChild;
|
|
2610
|
+
if (!child || child.exitCode !== null || child.signalCode) {
|
|
2611
|
+
void stopHubSelfAgent(`launcher-${signal}`).finally(() => {
|
|
2612
|
+
try { hubLogStream?.end(); } catch {}
|
|
2613
|
+
process.exit(0);
|
|
2614
|
+
});
|
|
2615
|
+
return;
|
|
2616
2616
|
}
|
|
2617
2617
|
reportLauncherUpdate(
|
|
2618
2618
|
`[LiveDesk Hub] Launcher received ${signal}; requesting graceful Hub shutdown for pid=${child.pid || 'unknown'}.`
|
|
@@ -2859,17 +2859,17 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
2859
2859
|
failPreflight(message);
|
|
2860
2860
|
return;
|
|
2861
2861
|
}
|
|
2862
|
-
restartRequest = {
|
|
2862
|
+
restartRequest = {
|
|
2863
2863
|
...request,
|
|
2864
2864
|
latestVersion: requestedVersion,
|
|
2865
2865
|
pid: requestPid,
|
|
2866
2866
|
operationId,
|
|
2867
2867
|
_neutralCwd: neutralCwd,
|
|
2868
2868
|
_originalCwd: UPDATE_ORIGINAL_CWD
|
|
2869
|
-
};
|
|
2870
|
-
reportLauncherUpdate(`[LiveDesk Hub] Restart requested for update ${request.operationId || 'unknown'} target=${requestedVersion}.`);
|
|
2871
|
-
void stopHubSelfAgent('hub-update');
|
|
2872
|
-
const updateChild = activeChild;
|
|
2869
|
+
};
|
|
2870
|
+
reportLauncherUpdate(`[LiveDesk Hub] Restart requested for update ${request.operationId || 'unknown'} target=${requestedVersion}.`);
|
|
2871
|
+
void stopHubSelfAgent('hub-update');
|
|
2872
|
+
const updateChild = activeChild;
|
|
2873
2873
|
let shutdownFallbackStarted = false;
|
|
2874
2874
|
const forceStop = reason => {
|
|
2875
2875
|
if (!updateChild || updateChild.exitCode !== null || updateChild.signalCode) return;
|
|
@@ -2910,7 +2910,7 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
2910
2910
|
}
|
|
2911
2911
|
};
|
|
2912
2912
|
|
|
2913
|
-
const startHubProcess = () => {
|
|
2913
|
+
const startHubProcess = () => {
|
|
2914
2914
|
const stderrChunks = [];
|
|
2915
2915
|
let stderrLength = 0;
|
|
2916
2916
|
const child = spawn(process.execPath, [hubEntry, ...options.forwarded], {
|
|
@@ -2918,22 +2918,22 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
2918
2918
|
stdio: ['inherit', 'pipe', 'pipe'],
|
|
2919
2919
|
windowsHide: !debugConsole
|
|
2920
2920
|
});
|
|
2921
|
-
activeChild = child;
|
|
2922
|
-
|
|
2923
|
-
void waitForManager(hubProbeBaseUrl).then(ok => {
|
|
2924
|
-
if (!ok
|
|
2925
|
-
|| activeChild !== child
|
|
2926
|
-
|| child.exitCode !== null
|
|
2927
|
-
|| child.signalCode
|
|
2928
|
-
|| launcherShutdownSignal
|
|
2929
|
-
|| restartRequest) return;
|
|
2930
|
-
hubSelfAgent?.start();
|
|
2931
|
-
}).catch(error => {
|
|
2932
|
-
reportLauncherUpdate(
|
|
2933
|
-
`[LiveDesk Hub] Self Agent startup wait failed: ${error?.message || error}.`,
|
|
2934
|
-
true
|
|
2935
|
-
);
|
|
2936
|
-
});
|
|
2921
|
+
activeChild = child;
|
|
2922
|
+
|
|
2923
|
+
void waitForManager(hubProbeBaseUrl).then(ok => {
|
|
2924
|
+
if (!ok
|
|
2925
|
+
|| activeChild !== child
|
|
2926
|
+
|| child.exitCode !== null
|
|
2927
|
+
|| child.signalCode
|
|
2928
|
+
|| launcherShutdownSignal
|
|
2929
|
+
|| restartRequest) return;
|
|
2930
|
+
hubSelfAgent?.start();
|
|
2931
|
+
}).catch(error => {
|
|
2932
|
+
reportLauncherUpdate(
|
|
2933
|
+
`[LiveDesk Hub] Self Agent startup wait failed: ${error?.message || error}.`,
|
|
2934
|
+
true
|
|
2935
|
+
);
|
|
2936
|
+
});
|
|
2937
2937
|
|
|
2938
2938
|
child.stdout.on('data', chunk => {
|
|
2939
2939
|
appendHubLog(chunk.toString());
|
|
@@ -2957,19 +2957,19 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
2957
2957
|
});
|
|
2958
2958
|
child.once('exit', (code, signal) => {
|
|
2959
2959
|
const startupOutput = stderrChunks.join('');
|
|
2960
|
-
if (launcherShutdownSignal) {
|
|
2960
|
+
if (launcherShutdownSignal) {
|
|
2961
2961
|
if (launcherShutdownHardStopTimer) {
|
|
2962
2962
|
clearTimeout(launcherShutdownHardStopTimer);
|
|
2963
2963
|
launcherShutdownHardStopTimer = null;
|
|
2964
2964
|
}
|
|
2965
|
-
runtimeShutdownWatcher?.stop();
|
|
2966
|
-
removeLauncherSignalHandlers();
|
|
2967
|
-
void stopHubSelfAgent(`launcher-${launcherShutdownSignal}`).finally(() => {
|
|
2968
|
-
try { hubLogStream?.end(); } catch {}
|
|
2969
|
-
process.exit(0);
|
|
2970
|
-
});
|
|
2971
|
-
return;
|
|
2972
|
-
}
|
|
2965
|
+
runtimeShutdownWatcher?.stop();
|
|
2966
|
+
removeLauncherSignalHandlers();
|
|
2967
|
+
void stopHubSelfAgent(`launcher-${launcherShutdownSignal}`).finally(() => {
|
|
2968
|
+
try { hubLogStream?.end(); } catch {}
|
|
2969
|
+
process.exit(0);
|
|
2970
|
+
});
|
|
2971
|
+
return;
|
|
2972
|
+
}
|
|
2973
2973
|
if (restartRequest) {
|
|
2974
2974
|
const request = restartRequest;
|
|
2975
2975
|
restartRequest = null;
|
|
@@ -2985,7 +2985,7 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
2985
2985
|
clearInterval(updatePollId);
|
|
2986
2986
|
updatePollId = null;
|
|
2987
2987
|
}
|
|
2988
|
-
void stopHubSelfAgent('hub-update').then(() => restartWithLatest(request)).catch(error => {
|
|
2988
|
+
void stopHubSelfAgent('hub-update').then(() => restartWithLatest(request)).catch(error => {
|
|
2989
2989
|
const message = `The Hub restart handoff failed after shutdown: ${error instanceof Error ? error.message : String(error)}`;
|
|
2990
2990
|
reportLauncherUpdate(`[LiveDesk Hub] ${message}. Restarting the unchanged Hub.`, true);
|
|
2991
2991
|
try {
|
|
@@ -3012,7 +3012,7 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
3012
3012
|
} catch {
|
|
3013
3013
|
// The unchanged Hub still restarts even if diagnostics are read-only.
|
|
3014
3014
|
}
|
|
3015
|
-
startHubProcess();
|
|
3015
|
+
startHubProcess();
|
|
3016
3016
|
if (!updatePollId) {
|
|
3017
3017
|
updatePollId = setInterval(pollUpdateRequest, HUB_UPDATE_POLL_MS);
|
|
3018
3018
|
updatePollId.unref?.();
|
|
@@ -3020,44 +3020,44 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
3020
3020
|
});
|
|
3021
3021
|
return;
|
|
3022
3022
|
}
|
|
3023
|
-
if (!signal && code === ROLE_TRANSITION_EXIT_CODE) {
|
|
3024
|
-
if (updatePollId) {
|
|
3025
|
-
clearInterval(updatePollId);
|
|
3026
|
-
updatePollId = null;
|
|
3027
|
-
}
|
|
3028
|
-
void stopHubSelfAgent('role-transition').then(() => {
|
|
3029
|
-
try {
|
|
3030
|
-
runtimeLock?.updateRole?.('client');
|
|
3031
|
-
} catch (error) {
|
|
3032
|
-
console.error(
|
|
3033
|
-
`[LiveDesk Hub] The shared runtime lock could not transition to Client: ${error?.message || error}. `
|
|
3034
|
-
+ 'The launcher will exit so a clean invocation can recover.'
|
|
3035
|
-
);
|
|
3036
|
-
runtimeShutdownWatcher?.stop();
|
|
3037
|
-
removeLauncherSignalHandlers();
|
|
3038
|
-
try { hubLogStream?.end(); } catch {}
|
|
3039
|
-
process.exit(1);
|
|
3040
|
-
return;
|
|
3041
|
-
}
|
|
3042
|
-
writeRoleCache({
|
|
3043
|
-
role: 'client',
|
|
3044
|
-
deviceId: resolvedRole?.deviceId || process.env.LIVEDESK_DEVICE_ID || '',
|
|
3045
|
-
deviceName: resolvedRole?.deviceName || os.hostname(),
|
|
3046
|
-
source: 'supabase',
|
|
3047
|
-
isOfflineFallback: false
|
|
3048
|
-
}, { stateDir: MANAGER_STATE_DIR });
|
|
3049
|
-
console.log('[LiveDesk Hub] Role transition accepted. Starting the Client runtime.');
|
|
3050
|
-
runtimeShutdownWatcher?.stop();
|
|
3051
|
-
removeLauncherSignalHandlers();
|
|
3052
|
-
void runClient([], { ...resolvedRole, role: 'client', source: 'supabase', roleTransition: true }, runtimeLock).catch(error => {
|
|
3053
|
-
console.error(`Failed to start LiveDesk Client runtime: ${error?.message || error}`);
|
|
3054
|
-
process.exitCode = 1;
|
|
3055
|
-
});
|
|
3056
|
-
}).catch(error => {
|
|
3057
|
-
console.error(`[LiveDesk Hub] Self Agent did not stop for role transition: ${error?.message || error}`);
|
|
3058
|
-
process.exit(1);
|
|
3059
|
-
});
|
|
3060
|
-
return;
|
|
3023
|
+
if (!signal && code === ROLE_TRANSITION_EXIT_CODE) {
|
|
3024
|
+
if (updatePollId) {
|
|
3025
|
+
clearInterval(updatePollId);
|
|
3026
|
+
updatePollId = null;
|
|
3027
|
+
}
|
|
3028
|
+
void stopHubSelfAgent('role-transition').then(() => {
|
|
3029
|
+
try {
|
|
3030
|
+
runtimeLock?.updateRole?.('client');
|
|
3031
|
+
} catch (error) {
|
|
3032
|
+
console.error(
|
|
3033
|
+
`[LiveDesk Hub] The shared runtime lock could not transition to Client: ${error?.message || error}. `
|
|
3034
|
+
+ 'The launcher will exit so a clean invocation can recover.'
|
|
3035
|
+
);
|
|
3036
|
+
runtimeShutdownWatcher?.stop();
|
|
3037
|
+
removeLauncherSignalHandlers();
|
|
3038
|
+
try { hubLogStream?.end(); } catch {}
|
|
3039
|
+
process.exit(1);
|
|
3040
|
+
return;
|
|
3041
|
+
}
|
|
3042
|
+
writeRoleCache({
|
|
3043
|
+
role: 'client',
|
|
3044
|
+
deviceId: resolvedRole?.deviceId || process.env.LIVEDESK_DEVICE_ID || '',
|
|
3045
|
+
deviceName: resolvedRole?.deviceName || os.hostname(),
|
|
3046
|
+
source: 'supabase',
|
|
3047
|
+
isOfflineFallback: false
|
|
3048
|
+
}, { stateDir: MANAGER_STATE_DIR });
|
|
3049
|
+
console.log('[LiveDesk Hub] Role transition accepted. Starting the Client runtime.');
|
|
3050
|
+
runtimeShutdownWatcher?.stop();
|
|
3051
|
+
removeLauncherSignalHandlers();
|
|
3052
|
+
void runClient([], { ...resolvedRole, role: 'client', source: 'supabase', roleTransition: true }, runtimeLock).catch(error => {
|
|
3053
|
+
console.error(`Failed to start LiveDesk Client runtime: ${error?.message || error}`);
|
|
3054
|
+
process.exitCode = 1;
|
|
3055
|
+
});
|
|
3056
|
+
}).catch(error => {
|
|
3057
|
+
console.error(`[LiveDesk Hub] Self Agent did not stop for role transition: ${error?.message || error}`);
|
|
3058
|
+
process.exit(1);
|
|
3059
|
+
});
|
|
3060
|
+
return;
|
|
3061
3061
|
}
|
|
3062
3062
|
if (!signal
|
|
3063
3063
|
&& code !== 0
|
|
@@ -3079,11 +3079,11 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
3079
3079
|
});
|
|
3080
3080
|
return;
|
|
3081
3081
|
}
|
|
3082
|
-
if (signal) {
|
|
3083
|
-
void stopHubSelfAgent(`hub-signal-${signal}`).finally(() => process.kill(process.pid, signal));
|
|
3084
|
-
return;
|
|
3085
|
-
}
|
|
3086
|
-
void stopHubSelfAgent('hub-exited').finally(() => process.exit(code ?? 0));
|
|
3082
|
+
if (signal) {
|
|
3083
|
+
void stopHubSelfAgent(`hub-signal-${signal}`).finally(() => process.kill(process.pid, signal));
|
|
3084
|
+
return;
|
|
3085
|
+
}
|
|
3086
|
+
void stopHubSelfAgent('hub-exited').finally(() => process.exit(code ?? 0));
|
|
3087
3087
|
});
|
|
3088
3088
|
};
|
|
3089
3089
|
|
|
@@ -3389,12 +3389,12 @@ async function main() {
|
|
|
3389
3389
|
await stopProcessesOnPorts([replacementCleanup.runtimePort, remotePort]);
|
|
3390
3390
|
}
|
|
3391
3391
|
|
|
3392
|
-
if (resolvedRole.role === 'client' || resolvedRole.role === 'hub') {
|
|
3393
|
-
// A launcher and Agent can both die while an independently spawned capture
|
|
3394
|
-
// helper survives. This applies to a normal Client and to the Hub-owned
|
|
3395
|
-
// Self Agent. Consume only the exact manifest generation returned by the
|
|
3396
|
-
// stale-lock compare-and-swap; no process-name scan participates here.
|
|
3397
|
-
const reclaimedManifestDrain = await drainReclaimedWindowsClientManifest(lock.reclaimedOwner);
|
|
3392
|
+
if (resolvedRole.role === 'client' || resolvedRole.role === 'hub') {
|
|
3393
|
+
// A launcher and Agent can both die while an independently spawned capture
|
|
3394
|
+
// helper survives. This applies to a normal Client and to the Hub-owned
|
|
3395
|
+
// Self Agent. Consume only the exact manifest generation returned by the
|
|
3396
|
+
// stale-lock compare-and-swap; no process-name scan participates here.
|
|
3397
|
+
const reclaimedManifestDrain = await drainReclaimedWindowsClientManifest(lock.reclaimedOwner);
|
|
3398
3398
|
const testHoldAfterDrainMs = Number(
|
|
3399
3399
|
process.env.LIVEDESK_TEST_HOLD_AFTER_RECLAIMED_WINDOWS_DRAIN_MS || 0
|
|
3400
3400
|
);
|
|
@@ -3402,12 +3402,12 @@ async function main() {
|
|
|
3402
3402
|
&& process.env.LIVEDESK_DEBUG === '1'
|
|
3403
3403
|
&& Number.isFinite(testHoldAfterDrainMs)
|
|
3404
3404
|
&& testHoldAfterDrainMs > 0) {
|
|
3405
|
-
console.log('[LiveDesk test] Holding after reclaimed manifest drain before Agent startup.');
|
|
3406
|
-
await waitMilliseconds(Math.min(60_000, Math.round(testHoldAfterDrainMs)));
|
|
3407
|
-
}
|
|
3408
|
-
}
|
|
3409
|
-
|
|
3410
|
-
if (resolvedRole.role === 'client') {
|
|
3405
|
+
console.log('[LiveDesk test] Holding after reclaimed manifest drain before Agent startup.');
|
|
3406
|
+
await waitMilliseconds(Math.min(60_000, Math.round(testHoldAfterDrainMs)));
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
|
|
3410
|
+
if (resolvedRole.role === 'client') {
|
|
3411
3411
|
const clientRuntimePort = normalizePort(
|
|
3412
3412
|
process.env.LIVEDESK_CLIENT_RUNTIME_PORT || process.env.LIVEDESK_LOCAL_RUNTIME_PORT,
|
|
3413
3413
|
DEFAULT_MANAGER_HTTP_PORT
|