@livedesk/client 0.1.23 → 0.1.25
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 +4 -2
- package/bin/livedesk-client-node.js +1 -1
- package/bin/livedesk-client.js +76 -3
- package/fast/linux-x64/mindexec-remote-fast.dll +0 -0
- package/fast/linux-x64/mindexec-remote-fast.pdb +0 -0
- package/fast/osx-arm64/mindexec-remote-fast.dll +0 -0
- package/fast/osx-arm64/mindexec-remote-fast.pdb +0 -0
- package/fast/osx-x64/mindexec-remote-fast.dll +0 -0
- package/fast/osx-x64/mindexec-remote-fast.pdb +0 -0
- package/fast/win-x64/mindexec-remote-fast.dll +0 -0
- package/fast/win-x64/mindexec-remote-fast.pdb +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,8 +35,10 @@ to `Desktop/LiveDeskFiles` unless the Hub sets another destination folder.
|
|
|
35
35
|
|
|
36
36
|
By default, the launcher uses the packaged C# RemoteFast engine when supported.
|
|
37
37
|
It falls back to the Node engine for AI assist or when a compatible RemoteFast
|
|
38
|
-
runtime is unavailable.
|
|
39
|
-
|
|
38
|
+
runtime is unavailable. macOS auto mode uses the Node engine by default because
|
|
39
|
+
the current RemoteFast macOS path shells out to `screencapture`, which can show
|
|
40
|
+
repeated Screen Recording privacy prompts. Use `--engine fast` on macOS only for
|
|
41
|
+
experimental testing.
|
|
40
42
|
|
|
41
43
|
Useful flags:
|
|
42
44
|
|
|
@@ -6,7 +6,7 @@ import path from 'path';
|
|
|
6
6
|
import crypto from 'crypto';
|
|
7
7
|
import { promises as fs, statfsSync } from 'fs';
|
|
8
8
|
|
|
9
|
-
const AGENT_VERSION = '0.1.
|
|
9
|
+
const AGENT_VERSION = '0.1.24-livedesk.1';
|
|
10
10
|
const DEFAULT_MANAGER = '127.0.0.1:5197';
|
|
11
11
|
const DEFAULT_HEARTBEAT_MS = 5000;
|
|
12
12
|
const DEFAULT_RECONNECT_MS = 5000;
|
package/bin/livedesk-client.js
CHANGED
|
@@ -17,6 +17,7 @@ const DEFAULT_AUTH_CALLBACK_HOST = '127.0.0.1';
|
|
|
17
17
|
const DEFAULT_AUTH_CALLBACK_PORT = 5198;
|
|
18
18
|
const DISCOVERY_RETRY_MS = 5000;
|
|
19
19
|
const EXIT_INVALID_PAIR_TOKEN = 23;
|
|
20
|
+
const SESSION_REFRESH_SKEW_SECONDS = 60;
|
|
20
21
|
const SUPABASE_URL = process.env.LIVEDESK_SUPABASE_URL || 'https://otbyfkjxrkngvjziawki.supabase.co';
|
|
21
22
|
const SUPABASE_PUBLISHABLE_KEY = process.env.LIVEDESK_SUPABASE_PUBLISHABLE_KEY || 'sb_publishable_NpUs0RDJH2YnllsqTKO6TQ_1jTdSsNQ';
|
|
22
23
|
const CLIENT_STATE_DIR = join(os.homedir(), '.livedesk-client');
|
|
@@ -60,7 +61,8 @@ Options:
|
|
|
60
61
|
--help Show this help.
|
|
61
62
|
|
|
62
63
|
Auto uses C# RemoteFast when supported and falls back to Node for AI assist or
|
|
63
|
-
when a packaged RemoteFast runtime is unavailable.
|
|
64
|
+
when a packaged RemoteFast runtime is unavailable. On macOS, auto uses the Node
|
|
65
|
+
agent by default to avoid repeated screencapture privacy prompts.
|
|
64
66
|
`.trimStart());
|
|
65
67
|
}
|
|
66
68
|
|
|
@@ -73,6 +75,14 @@ function readPackageVersion() {
|
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
77
|
|
|
78
|
+
function isTruthy(value) {
|
|
79
|
+
return /^(1|true|yes|on)$/i.test(String(value || '').trim());
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function isMacFastAutoEnabled() {
|
|
83
|
+
return isTruthy(process.env.LIVEDESK_CLIENT_MAC_FAST || process.env.MINDEXEC_REMOTE_MAC_FAST);
|
|
84
|
+
}
|
|
85
|
+
|
|
76
86
|
function normalizeEngine(value) {
|
|
77
87
|
const engine = String(value || 'auto').trim().toLowerCase();
|
|
78
88
|
if (engine === 'c#' || engine === 'csharp' || engine === 'fast') {
|
|
@@ -278,7 +288,7 @@ async function createSupabaseClient() {
|
|
|
278
288
|
const { createClient } = await import('@supabase/supabase-js');
|
|
279
289
|
return createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, {
|
|
280
290
|
auth: {
|
|
281
|
-
autoRefreshToken:
|
|
291
|
+
autoRefreshToken: false,
|
|
282
292
|
persistSession: true,
|
|
283
293
|
detectSessionInUrl: false,
|
|
284
294
|
flowType: 'pkce',
|
|
@@ -288,6 +298,62 @@ async function createSupabaseClient() {
|
|
|
288
298
|
});
|
|
289
299
|
}
|
|
290
300
|
|
|
301
|
+
function getNestedErrorCode(error) {
|
|
302
|
+
let cursor = error;
|
|
303
|
+
for (let i = 0; i < 5 && cursor; i++) {
|
|
304
|
+
if (typeof cursor.code === 'string' && cursor.code.trim()) {
|
|
305
|
+
return cursor.code.trim();
|
|
306
|
+
}
|
|
307
|
+
cursor = cursor.cause;
|
|
308
|
+
}
|
|
309
|
+
return '';
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function getNestedErrorMessage(error) {
|
|
313
|
+
const messages = [];
|
|
314
|
+
let cursor = error;
|
|
315
|
+
for (let i = 0; i < 5 && cursor; i++) {
|
|
316
|
+
if (typeof cursor.message === 'string' && cursor.message.trim()) {
|
|
317
|
+
messages.push(cursor.message.trim());
|
|
318
|
+
}
|
|
319
|
+
cursor = cursor.cause;
|
|
320
|
+
}
|
|
321
|
+
return messages.join(' ');
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function isTransientNetworkError(error) {
|
|
325
|
+
const code = getNestedErrorCode(error).toUpperCase();
|
|
326
|
+
if (['ENOTFOUND', 'EAI_AGAIN', 'ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'ENETUNREACH', 'EHOSTUNREACH'].includes(code)) {
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
return /fetch failed|network|dns|socket|connection|timeout|getaddrinfo/i.test(getNestedErrorMessage(error));
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function formatDiscoveryError(error) {
|
|
333
|
+
if (isTransientNetworkError(error)) {
|
|
334
|
+
const code = getNestedErrorCode(error);
|
|
335
|
+
return `Network is not ready yet${code ? ` (${code})` : ''}. Waiting for DNS/Wi-Fi after sleep.`;
|
|
336
|
+
}
|
|
337
|
+
return error instanceof Error ? error.message : String(error);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
async function refreshSessionIfNeeded(supabase) {
|
|
341
|
+
const { data: existing } = await supabase.auth.getSession();
|
|
342
|
+
const session = existing?.session;
|
|
343
|
+
if (!session?.access_token) {
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
const expiresAt = Number(session.expires_at || 0);
|
|
347
|
+
if (expiresAt <= 0 || expiresAt - Math.floor(Date.now() / 1000) > SESSION_REFRESH_SKEW_SECONDS) {
|
|
348
|
+
return session;
|
|
349
|
+
}
|
|
350
|
+
const { data, error } = await supabase.auth.refreshSession(session);
|
|
351
|
+
if (error) {
|
|
352
|
+
throw error;
|
|
353
|
+
}
|
|
354
|
+
return data?.session || session;
|
|
355
|
+
}
|
|
356
|
+
|
|
291
357
|
function openBrowser(url) {
|
|
292
358
|
if (os.platform() === 'win32') {
|
|
293
359
|
spawn('rundll32.exe', ['url.dll,FileProtocolHandler', url], { detached: true, stdio: 'ignore', windowsHide: true }).unref();
|
|
@@ -533,6 +599,7 @@ function normalizeEndpointCandidates(target) {
|
|
|
533
599
|
}
|
|
534
600
|
|
|
535
601
|
async function resolveManagerFromSupabase(supabase, options = {}) {
|
|
602
|
+
await refreshSessionIfNeeded(supabase);
|
|
536
603
|
const { data, error } = await supabase
|
|
537
604
|
.from('livedesk_remote_host_targets')
|
|
538
605
|
.select('endpoint, endpoint_candidates, pair_token, active, expires_at, updated_at, manager_version')
|
|
@@ -576,7 +643,7 @@ async function waitForManagerFromSupabase(supabase, options = {}) {
|
|
|
576
643
|
try {
|
|
577
644
|
return await resolveManagerFromSupabase(supabase, { requireReachable: true });
|
|
578
645
|
} catch (err) {
|
|
579
|
-
const message =
|
|
646
|
+
const message = formatDiscoveryError(err);
|
|
580
647
|
if (message !== lastMessage || attempts === 1 || attempts % 6 === 0) {
|
|
581
648
|
const suffix = attempts === 1 ? '' : ` attempt ${attempts}`;
|
|
582
649
|
console.log(`Still waiting for LiveDesk Hub${suffix}: ${message}`);
|
|
@@ -830,6 +897,9 @@ function shouldUseFast(parsed) {
|
|
|
830
897
|
if (parsed.engine === 'fast') {
|
|
831
898
|
return true;
|
|
832
899
|
}
|
|
900
|
+
if (os.platform() === 'darwin' && !isMacFastAutoEnabled()) {
|
|
901
|
+
return false;
|
|
902
|
+
}
|
|
833
903
|
return !parsed.nodeOnlyFeature;
|
|
834
904
|
}
|
|
835
905
|
|
|
@@ -856,6 +926,9 @@ async function main() {
|
|
|
856
926
|
const fastRuntime = getFastRuntime();
|
|
857
927
|
const useFast = shouldTryFast(prepared, fastRuntime);
|
|
858
928
|
let result;
|
|
929
|
+
if (!useFast && prepared.engine === 'auto' && os.platform() === 'darwin') {
|
|
930
|
+
console.warn('LiveDesk uses the Node engine on macOS to avoid repeated Screen Recording prompts. Use --engine fast only for experimental testing.');
|
|
931
|
+
}
|
|
859
932
|
if (useFast) {
|
|
860
933
|
const fastArgs = buildFastArgs(prepared.forwarded, prepared.fakeThumbnail);
|
|
861
934
|
const fastLaunch = resolveFastLaunch(fastRuntime);
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|