@livedesk/client 0.1.172 → 0.1.173

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.
@@ -2888,15 +2888,18 @@ async function startConnectionChoiceServer(supabase, options = {}) {
2888
2888
 
2889
2889
  async function chooseClientConnection(supabase, options = {}) {
2890
2890
  if (isTruthy(process.env.LIVEDESK_UNIFIED_RUNTIME)) {
2891
- const connectionPage = createClientRuntimeServer({
2892
- host: process.env.LIVEDESK_CLIENT_RUNTIME_HOST || '127.0.0.1',
2893
- port: options.authPort || DEFAULT_AUTH_CALLBACK_PORT,
2894
- webDist: process.env.LIVEDESK_WEB_DIST || '',
2891
+ const connectionPage = createClientRuntimeServer({
2892
+ host: process.env.LIVEDESK_CLIENT_RUNTIME_HOST || '127.0.0.1',
2893
+ port: options.authPort || DEFAULT_AUTH_CALLBACK_PORT,
2894
+ webDist: process.env.LIVEDESK_WEB_DIST || '',
2895
2895
  appVersion: process.env.LIVEDESK_NPM_LAUNCHER_VERSION || readPackageVersion(),
2896
- deviceId: options.deviceId,
2897
- engine: options.engine,
2896
+ deviceId: options.deviceId,
2897
+ engine: options.engine,
2898
2898
  savedSession: options.savedSession,
2899
+ initialChoice: options.initialChoice,
2900
+ initialChoiceMessage: options.initialChoiceMessage,
2899
2901
  beginGoogleSignIn: async redirectTo => {
2902
+ if (!supabase?.auth) throw new Error('supabase-session-required');
2900
2903
  const { data, error } = await supabase.auth.signInWithOAuth({
2901
2904
  provider: 'google',
2902
2905
  options: {
@@ -2910,15 +2913,22 @@ async function chooseClientConnection(supabase, options = {}) {
2910
2913
  return { url: data.url };
2911
2914
  },
2912
2915
  exchangeGoogleCode: async code => {
2916
+ if (!supabase?.auth) throw new Error('supabase-session-required');
2913
2917
  const { data, error } = await supabase.auth.exchangeCodeForSession(code);
2914
2918
  if (error) throw error;
2915
2919
  if (!data?.session) throw new Error('google-session-missing');
2916
2920
  if (!writeSavedSessionToFile(data.session)) throw new Error('refresh-token-required');
2917
2921
  return data.session;
2918
2922
  },
2919
- resolvePin: pin => resolveManagerFromPin(supabase, pin),
2920
- changeRole: async (role, snapshot) => {
2921
- const session = await refreshSessionIfNeeded(supabase);
2923
+ resolvePin: pin => {
2924
+ if (!supabase) throw new Error('supabase-session-required');
2925
+ return resolveManagerFromPin(supabase, pin);
2926
+ },
2927
+ changeRole: async (role, snapshot) => {
2928
+ if (!supabase) {
2929
+ return { ok: false, error: 'supabase-session-required' };
2930
+ }
2931
+ const session = await refreshSessionIfNeeded(supabase);
2922
2932
  if (!session?.access_token) {
2923
2933
  return { ok: false, error: 'supabase-session-required' };
2924
2934
  }
@@ -3255,7 +3265,7 @@ async function prepareLoginConnection(parsed, existingConnectionPage = null) {
3255
3265
  let connectionPage = null;
3256
3266
  let discoverySource = '';
3257
3267
 
3258
- if (shouldLogin) {
3268
+ if (shouldLogin) {
3259
3269
  const supabase = await createSupabaseClient();
3260
3270
  const startupArgs = buildStartupClientArgs(parsed);
3261
3271
  let savedSession = null;
@@ -3362,10 +3372,38 @@ async function prepareLoginConnection(parsed, existingConnectionPage = null) {
3362
3372
  message: `Connected to LiveDesk Hub at ${manager}.`
3363
3373
  });
3364
3374
  }
3365
- console.log(`Found LiveDesk Hub at ${manager}.`);
3366
- }
3367
-
3368
- const slot = normalizeSlotNumber(parsed.slot);
3375
+ console.log(`Found LiveDesk Hub at ${manager}.`);
3376
+ }
3377
+ // Exact-package updates preserve the already paired Hub endpoint and pass
3378
+ // --no-login so the replacement cannot block on browser auth. The unified
3379
+ // launcher must still own its local runtime/status API; the package
3380
+ // supervisor uses that API to prove the new launcher and Agent are stable
3381
+ // before it commits the update.
3382
+ if (!shouldLogin
3383
+ && !existingConnectionPage
3384
+ && isTruthy(process.env.LIVEDESK_UNIFIED_RUNTIME)
3385
+ && manager
3386
+ && pair) {
3387
+ const preservedSession = readSavedSessionFromFile();
3388
+ const explicitConnection = await chooseClientConnection(null, {
3389
+ authPort: parsed.authPort,
3390
+ deviceId: parsed.deviceId,
3391
+ engine: parsed.engine,
3392
+ savedSession: preservedSession,
3393
+ openBrowser: false,
3394
+ initialChoice: {
3395
+ type: 'explicit',
3396
+ manager,
3397
+ pair,
3398
+ endpointCandidates: [manager],
3399
+ ...(preservedSession?.access_token ? { session: preservedSession } : {})
3400
+ },
3401
+ initialChoiceMessage: `Using the existing LiveDesk Hub pairing at ${manager}.`
3402
+ });
3403
+ connectionPage = explicitConnection.connectionPage || null;
3404
+ }
3405
+
3406
+ const slot = normalizeSlotNumber(parsed.slot);
3369
3407
  if (manager) {
3370
3408
  forwarded = upsertForwardedOption(forwarded, '--manager', manager);
3371
3409
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livedesk/client",
3
- "version": "0.1.172",
3
+ "version": "0.1.173",
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.378",
43
- "@livedesk/fast-osx-arm64": "0.1.378",
44
- "@livedesk/fast-osx-x64": "0.1.378",
45
- "@livedesk/fast-win-x64": "0.1.378"
42
+ "@livedesk/fast-linux-x64": "0.1.379",
43
+ "@livedesk/fast-osx-arm64": "0.1.379",
44
+ "@livedesk/fast-osx-x64": "0.1.379",
45
+ "@livedesk/fast-win-x64": "0.1.379"
46
46
  },
47
47
  "publishConfig": {
48
48
  "access": "public"
@@ -514,9 +514,16 @@ function sendText(res, status, body, type = 'text/plain; charset=utf-8') {
514
514
  res.end(body);
515
515
  }
516
516
 
517
- export function createClientRuntimeServer(options = {}) {
518
- const host = normalizeString(options.host, 80) || DEFAULT_HOST;
517
+ export function createClientRuntimeServer(options = {}) {
518
+ const host = normalizeString(options.host, 80) || DEFAULT_HOST;
519
519
  const port = normalizePort(options.port, DEFAULT_PORT);
520
+ const initialChoice = options.initialChoice && typeof options.initialChoice === 'object'
521
+ ? options.initialChoice
522
+ : null;
523
+ const initialChoiceMessage = normalizeString(
524
+ options.initialChoiceMessage,
525
+ 1000
526
+ ) || 'Existing LiveDesk credentials accepted. Starting the Client.';
520
527
  const trustedWebOrigins = createTrustedWebOrigins(port);
521
528
  const webDist = resolve(String(options.webDist || process.env.LIVEDESK_WEB_DIST || '').trim() || join(process.cwd(), 'apps', 'web', 'dist'));
522
529
  const deviceId = normalizeString(options.deviceId || process.env.LIVEDESK_DEVICE_ID, 160);
@@ -1030,23 +1037,29 @@ export function createClientRuntimeServer(options = {}) {
1030
1037
  else res.end();
1031
1038
  });
1032
1039
  });
1033
- server.once('error', rejectStart);
1034
- server.listen(port, host, () => {
1035
- runtime.emit('runtime.http.started', { host, port });
1036
- const saved = normalizeRuntimeAuthSession(options.savedSession, { requireRefreshToken: true });
1037
- if (saved.ok) {
1040
+ server.once('error', rejectStart);
1041
+ server.listen(port, host, () => {
1042
+ runtime.emit('runtime.http.started', { host, port });
1043
+ if (initialChoice) {
1038
1044
  setImmediate(() => {
1039
- try {
1040
- if (!writeSavedSession(saved.session)) throw new Error('refresh-token-required');
1041
- state.auth.persisted = true;
1042
- complete({ type: 'google', session: saved.session }, 'Saved sign-in found. Finding the LiveDesk Hub.');
1043
- } catch (error) {
1044
- recordAuthAttempt('rejected', `session-persistence-failed:${normalizeString(error?.message || error, 160)}`);
1045
- }
1045
+ complete(initialChoice, initialChoiceMessage);
1046
1046
  });
1047
+ } else {
1048
+ const saved = normalizeRuntimeAuthSession(options.savedSession, { requireRefreshToken: true });
1049
+ if (saved.ok) {
1050
+ setImmediate(() => {
1051
+ try {
1052
+ if (!writeSavedSession(saved.session)) throw new Error('refresh-token-required');
1053
+ state.auth.persisted = true;
1054
+ complete({ type: 'google', session: saved.session }, 'Saved sign-in found. Finding the LiveDesk Hub.');
1055
+ } catch (error) {
1056
+ recordAuthAttempt('rejected', `session-persistence-failed:${normalizeString(error?.message || error, 160)}`);
1057
+ }
1058
+ });
1059
+ }
1047
1060
  }
1048
- resolveStart();
1049
- });
1061
+ resolveStart();
1062
+ });
1050
1063
  });
1051
1064
 
1052
1065
  return {