livedesk 0.1.503 → 0.1.504

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.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { createRequire } from 'node:module';
4
4
  import net from 'node:net';
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { dirname, join } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import net from 'net';
4
4
  import os from 'os';
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { randomBytes } from 'node:crypto';
4
4
  import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statfsSync, statSync, writeFileSync } from 'node:fs';
@@ -66,13 +66,17 @@ export function isVersionAtLeast(candidate, required) {
66
66
  return !!cleanVersion(candidate) && !!cleanVersion(required) && compareVersions(candidate, required) >= 0;
67
67
  }
68
68
 
69
+ function isDedicatedBootstrapFailure(value) {
70
+ return /^Update worker exited before terminal proof\b/i.test(String(value || '').trim());
71
+ }
72
+
69
73
  function encodePowerShell(value) {
70
74
  return Buffer.from(String(value || ''), 'utf16le').toString('base64');
71
75
  }
72
76
 
73
77
  function buildLegacyPackageSupervisorStarterSource() {
74
78
  const source = [
75
- "const{spawn}=require('node:child_process'),f=require('node:fs'),p=require('node:path'),c=JSON.parse(Buffer.from(process.env.C,'base64')),e={...process.env,LIVEDESK_UPDATE_STARTER_PID:String(process.pid),LIVEDESK_UPDATE_ORIGINAL_CWD:process.cwd()},w=p.join(require('node:os').tmpdir(),'livedesk-update-cwd','client-'+c[0]),u=e.LIVEDESK_NPX_EXECUTABLE,s=process.platform,j=process.execPath,n=u||(s==='win32'?'npx.cmd':'npx'),x=[e.LIVEDESK_NPX_CLI_PATH,e.npm_execpath&&p.join(p.dirname(e.npm_execpath),'npx-cli.js'),u&&p.join(p.dirname(u),'node_modules/npm/bin/npx-cli.js'),p.join(p.dirname(j),'node_modules/npm/bin/npx-cli.js')].find(v=>v&&f.existsSync(v)),a=['-y','--prefer-online','--prefix',w,'--workspaces=false','livedesk@'+c[6],'--internal-legacy-client-update'],z=String.fromCharCode(32),q=v=>'\"'+String(v).replaceAll('\"','\"\"')+'\"';if(!(+c[7]>0))process.exit(1);c[7]=String(Date.now()+Number(c[7]));e.C=Buffer.from(JSON.stringify(c)).toString('base64');f.mkdirSync(w,{recursive:true});if(f.readdirSync(w)[0])process.exit(1);Object.keys(e).forEach(k=>/^(INIT_CWD|npm_config_(local_prefix|workspaces?|include_workspace_root))$/i.test(k)&&Reflect.deleteProperty(e,k));Object.assign(e,{INIT_CWD:w,npm_config_local_prefix:w,npm_config_workspaces:'false',npm_config_include_workspace_root:'false',LIVEDESK_UPDATE_NEUTRAL_CWD:w});e.i=x?{c:j,a:[x,...a]}:s==='win32'?{c:e.ComSpec||'cmd.exe',a:['/d','/s','/c','call'+z+q(n)+z+a.map(q).join(z)]}:{c:n,a};e.r=spawn(e.i.c,e.i.a,{cwd:w,env:e,detached:true,stdio:'ignore',windowsHide:true});",
79
+ "const{spawn}=require('node:child_process'),f=require('node:fs'),p=require('node:path'),o=require('node:os'),c=JSON.parse(Buffer.from(process.env.C,'base64')),e={...process.env,LIVEDESK_UPDATE_STARTER_PID:String(process.pid),LIVEDESK_UPDATE_ORIGINAL_CWD:process.cwd()},w=p.join(o.tmpdir(),'livedesk-update-cwd','client-'+c[0]),k=p.join(o.tmpdir(),'livedesk-update-cache','client-'+c[0]),u=e.LIVEDESK_NPX_EXECUTABLE,s=process.platform,j=process.execPath,n=u||(s==='win32'?'npx.cmd':'npx'),x=[e.LIVEDESK_NPX_CLI_PATH,e.npm_execpath&&p.join(p.dirname(e.npm_execpath),'npx-cli.js'),u&&p.join(p.dirname(u),'node_modules/npm/bin/npx-cli.js'),p.join(p.dirname(j),'node_modules/npm/bin/npx-cli.js')].find(v=>v&&f.existsSync(v)),a=['-y','--prefer-online','--prefix',w,'--workspaces=false','livedesk@'+c[6],'--internal-legacy-client-update'],z=String.fromCharCode(32),q=v=>'\"'+String(v).replaceAll('\"','\"\"')+'\"';if(!(+c[7]>0))process.exit(1);c[7]=String(Date.now()+Number(c[7]));e.C=Buffer.from(JSON.stringify(c)).toString('base64');f.mkdirSync(w,{recursive:true});if(f.readdirSync(w)[0])process.exit(1);f.mkdirSync(k,{recursive:true});Object.keys(e).forEach(n=>/^(INIT_CWD|npm_config_(cache|local_prefix|workspaces?|include_workspace_root))$/i.test(n)&&Reflect.deleteProperty(e,n));Object.assign(e,{INIT_CWD:w,npm_config_cache:k,npm_config_local_prefix:w,npm_config_workspaces:'false',npm_config_include_workspace_root:'false',LIVEDESK_UPDATE_NEUTRAL_CWD:w});e.i=x?{c:j,a:[x,...a]}:s==='win32'?{c:e.ComSpec||'cmd.exe',a:['/d','/s','/c','call'+z+q(n)+z+a.map(q).join(z)]}:{c:n,a};e.r=spawn(e.i.c,e.i.a,{cwd:w,env:e,detached:true,stdio:'ignore',windowsHide:true});",
76
80
  "e.r.on('error',()=>process.exit(1));e.r.unref();"
77
81
  ].join('');
78
82
  if (source.includes(' ')) throw new Error('LiveDesk legacy starter source must not contain spaces.');
@@ -436,9 +440,16 @@ export function createLiveDeskUpdateManager({
436
440
  return true;
437
441
  };
438
442
 
439
- const dispatchTarget = (target, device) => {
443
+ const dispatchTarget = (target, device, options = {}) => {
440
444
  const dispatchedAtEpochMs = now();
441
- const updateDeadlineEpochMs = dispatchedAtEpochMs + effectiveTargetTimeoutMs;
445
+ const requestedTimeoutMs = Math.max(
446
+ 10_000,
447
+ Math.min(
448
+ effectiveTargetTimeoutMs,
449
+ Number(options.updateTimeoutMs) || effectiveTargetTimeoutMs
450
+ )
451
+ );
452
+ const updateDeadlineEpochMs = dispatchedAtEpochMs + requestedTimeoutMs;
442
453
  const dispatchedSessionId = String(device?.sessionId || '').trim();
443
454
  if (!dispatchedSessionId) {
444
455
  target.state = 'failed';
@@ -448,14 +459,15 @@ export function createLiveDeskUpdateManager({
448
459
  target.dispatchedSessionId = dispatchedSessionId;
449
460
  target.dispatchedPid = Math.max(0, Math.floor(Number(device?.pid) || 0));
450
461
  resetReconnectCandidate(target);
451
- const supportsDedicated = device.capabilities?.clientUpdate === true
462
+ const supportsDedicated = options.forceLegacy !== true
463
+ && device.capabilities?.clientUpdate === true
452
464
  && isVersionAtLeast(device.agentVersion, LIVE_DESK_DEDICATED_CLIENT_UPDATE_MIN_VERSION);
453
465
  const payload = {
454
466
  targetVersion: run.latestClientVersion,
455
467
  targetProductVersion: run.latestManagerVersion,
456
468
  managerVersion: run.latestManagerVersion,
457
469
  operationId: run.operationId,
458
- updateTimeoutMs: effectiveTargetTimeoutMs
470
+ updateTimeoutMs: requestedTimeoutMs
459
471
  };
460
472
  const result = supportsDedicated
461
473
  ? remoteHub.sendCommand(device.deviceId, { command: LIVE_DESK_UPDATE_COMMAND, payload })
@@ -465,7 +477,7 @@ export function createLiveDeskUpdateManager({
465
477
  run.operationId,
466
478
  run.latestClientVersion,
467
479
  run.latestManagerVersion,
468
- effectiveTargetTimeoutMs
480
+ requestedTimeoutMs
469
481
  ),
470
482
  timeoutMs: 30_000
471
483
  });
@@ -718,6 +730,9 @@ export function createLiveDeskUpdateManager({
718
730
  candidateSince: '',
719
731
  stabilityDeadlineAt: '',
720
732
  completedAt: '',
733
+ bootstrapRetryCount: 0,
734
+ bootstrapRetryAt: '',
735
+ bootstrapRetryReason: '',
721
736
  error: ''
722
737
  }))
723
738
  };
@@ -760,8 +775,41 @@ export function createLiveDeskUpdateManager({
760
775
  || !['dedicated', 'legacy-command-run'].includes(target.method)) return;
761
776
  const result = event?.result;
762
777
  if (event?.error || result?.ok === false || result?.status === 'failed' || result?.status === 'rejected') {
778
+ const failure = String(event.error || result?.error || result?.message || 'client-update-command-failed').slice(0, 500);
779
+ if (target.method === 'dedicated'
780
+ && target.bootstrapRetryCount === 0
781
+ && isDedicatedBootstrapFailure(failure)) {
782
+ const retryDevice = connectedDevices(remoteHub)
783
+ .find(device => String(device.deviceId || '') === target.deviceId);
784
+ const remainingMs = Date.parse(target.deadlineAt || '') - now();
785
+ if (retryDevice?.connected === true && remainingMs >= 10_000) {
786
+ target.bootstrapRetryCount = 1;
787
+ target.bootstrapRetryAt = new Date(now()).toISOString();
788
+ target.bootstrapRetryReason = failure;
789
+ target.error = '';
790
+ let retryResult;
791
+ try {
792
+ retryResult = dispatchTarget(target, retryDevice, {
793
+ forceLegacy: true,
794
+ updateTimeoutMs: remainingMs
795
+ });
796
+ } catch (error) {
797
+ target.error = String(error?.message || error || 'client-update-bootstrap-retry-failed').slice(0, 500);
798
+ retryResult = false;
799
+ }
800
+ if (retryResult === true) {
801
+ touch();
802
+ return;
803
+ }
804
+ target.state = 'failed';
805
+ if (!target.error) target.error = 'client-update-bootstrap-retry-failed';
806
+ touch();
807
+ failRun(`Client ${target.deviceName || target.deviceId} bootstrap retry failed: ${target.error}`);
808
+ return;
809
+ }
810
+ }
763
811
  target.state = 'failed';
764
- target.error = String(event.error || result?.error || result?.message || 'client-update-command-failed').slice(0, 500);
812
+ target.error = failure;
765
813
  touch();
766
814
  failRun(target.method === 'dedicated'
767
815
  ? `Client ${target.deviceName || target.deviceId} rejected the update request: ${target.error}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livedesk",
3
- "version": "0.1.503",
3
+ "version": "0.1.504",
4
4
  "livedeskClientVersion": "0.1.240",
5
5
  "buildFlavor": "production",
6
6
  "description": "LiveDesk Hub and client launcher",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "kind": "livedesk-production-web-source-evidence",
4
- "generatedAt": "2026-08-11T04:44:04.645Z",
5
- "sourceHash": "bff835a9eb754d88680dc90bb1950d541bf4e992f9f75876930bc9fcc842848b",
4
+ "generatedAt": "2026-08-11T05:43:09.650Z",
5
+ "sourceHash": "bb7328ac74831b8df37f553cab0a6f359cc6a08e3483cbbec6d7606ddba82193",
6
6
  "sourceFileCount": 121,
7
7
  "sourceBytes": 2068605,
8
8
  "viteEnvironmentHash": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",