livedesk 0.1.454 → 0.1.456
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 +31 -4
- package/bin/livedesk.js +98 -18
- package/client/bin/livedesk-client-node.js +18 -12
- package/client/bin/livedesk-client.js +2 -2
- package/client/package.json +22 -22
- package/diagnostics/livedesk-mac-physical-gate-core.mjs +365 -0
- package/diagnostics/livedesk-mac-physical-isolation.mjs +311 -0
- package/diagnostics/livedesk-mode3-capture-smoke.mjs +1393 -0
- package/hub/package.json +1 -1
- package/hub/src/remote-hub.js +33 -7
- package/hub/src/server.js +28 -17
- package/hub/src/settings/settings-schema.js +1 -0
- package/package.json +12 -11
- package/web/dist/assets/{icons-CCS0Avce.js → icons-CpeZfjFK.js} +1 -1
- package/web/dist/assets/{index-DuoWFpfo.js → index-Bv9NFUjC.js} +11 -11
- package/web/dist/assets/{react-Cg5haagh.js → react-CSxCfTKV.js} +1 -1
- package/web/dist/index.html +3 -3
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ Pass `--no-clean` to disable the startup cleanup explicitly. If a child Hub
|
|
|
51
51
|
still loses a startup race with `EADDRINUSE`, the launcher performs one cleanup
|
|
52
52
|
and startup retry, then exits without looping.
|
|
53
53
|
|
|
54
|
-
## Client compatibility
|
|
54
|
+
## Client compatibility
|
|
55
55
|
|
|
56
56
|
```powershell
|
|
57
57
|
npx -y --prefer-online livedesk@latest client 3
|
|
@@ -61,9 +61,36 @@ The `client` form remains as a legacy compatibility alias. It records the
|
|
|
61
61
|
Client role and uses the same unified runtime lock. The client signs in with
|
|
62
62
|
Google, discovers the active Hub, and connects to the wall. On Windows, enable
|
|
63
63
|
**Start with Windows** on the connection page to reconnect automatically after
|
|
64
|
-
reboot; the generated startup command uses the unified launcher.
|
|
65
|
-
|
|
66
|
-
##
|
|
64
|
+
reboot; the generated startup command uses the unified launcher.
|
|
65
|
+
|
|
66
|
+
## macOS physical diagnostic
|
|
67
|
+
|
|
68
|
+
On a Mac with two connected displays, stop every running LiveDesk runtime,
|
|
69
|
+
show visibly different content on the two displays, grant Screen Recording and
|
|
70
|
+
Accessibility permissions, then run:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npx -y --prefer-online livedesk@latest diagnose mac-physical
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This command branches before role resolution, state migration, and the normal
|
|
77
|
+
runtime lock. It refuses to overlap an existing LiveDesk runtime or capture
|
|
78
|
+
helper, and normal macOS startup reciprocally refuses an active diagnostic
|
|
79
|
+
lease. It starts only an isolated loopback Hub and temporary RemoteFast Client
|
|
80
|
+
and stops only the exact children it created. Ctrl+C and termination signals
|
|
81
|
+
join the same owned cleanup before exit. The default JSON report is written to
|
|
82
|
+
one final path after cleanup, and run/cleanup errors always produce a failed
|
|
83
|
+
result. It is written under `~/.livedesk/diagnostics`. To select a path relative
|
|
84
|
+
to the directory where the command was invoked:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx -y --prefer-online livedesk@latest diagnose mac-physical --report ./mac-result.json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Use `diagnose mac-physical --help` to inspect requirements without starting a
|
|
91
|
+
runtime or changing cached role/account state.
|
|
92
|
+
|
|
93
|
+
## Frame modes
|
|
67
94
|
|
|
68
95
|
- Mode 2: independent 320x180 RGB565+LZO tiles for large, stable walls.
|
|
69
96
|
- Mode 3: direct hardware H.264 for focused remote control up to 4K.
|
package/bin/livedesk.js
CHANGED
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
import { runLegacyClientUpdateSupervisorCli } from '../bootstrap/legacy-client-update.js';
|
|
35
35
|
import { transferSavedClientSessionToHub } from '../bootstrap/hub-auth-handoff.js';
|
|
36
36
|
import { readWindowsOwnedProcessManifest } from '../client/src/runtime/windows-owned-process-manifest.js';
|
|
37
|
+
import { inspectMacDiagnosticLease } from '../diagnostics/livedesk-mac-physical-isolation.mjs';
|
|
37
38
|
|
|
38
39
|
const require = createRequire(import.meta.url);
|
|
39
40
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -143,6 +144,22 @@ function isPidAlive(pid) {
|
|
|
143
144
|
}
|
|
144
145
|
}
|
|
145
146
|
|
|
147
|
+
async function assertNoActiveMacPhysicalDiagnosticLease() {
|
|
148
|
+
if (os.platform() !== 'darwin') return;
|
|
149
|
+
const lease = await inspectMacDiagnosticLease();
|
|
150
|
+
if (lease.status === 'missing' || lease.status === 'stale') return;
|
|
151
|
+
if (lease.status === 'active') {
|
|
152
|
+
throw new Error(
|
|
153
|
+
`Mac physical diagnostic is running (pid ${lease.pid}); normal LiveDesk startup was not started. `
|
|
154
|
+
+ 'Wait for its owned cleanup to finish or stop the diagnostic with Ctrl+C.'
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
throw new Error(
|
|
158
|
+
`Mac physical diagnostic ownership is unreadable at ${lease.path}; normal LiveDesk startup was not started `
|
|
159
|
+
+ 'to avoid overlapping a capture runtime.'
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
146
163
|
function canClaimHubUpdateResult(current, next) {
|
|
147
164
|
const currentOperationId = String(current?.operationId || '');
|
|
148
165
|
const nextOperationId = String(next?.operationId || '');
|
|
@@ -312,15 +329,18 @@ function printHelp() {
|
|
|
312
329
|
process.stdout.write(`
|
|
313
330
|
LiveDesk
|
|
314
331
|
|
|
315
|
-
Usage:
|
|
316
|
-
npx -y --prefer-online livedesk@latest
|
|
317
|
-
npx -y --prefer-online livedesk@latest --force-role hub
|
|
318
|
-
npx -y --prefer-online livedesk@latest --force-role client
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
332
|
+
Usage:
|
|
333
|
+
npx -y --prefer-online livedesk@latest
|
|
334
|
+
npx -y --prefer-online livedesk@latest --force-role hub
|
|
335
|
+
npx -y --prefer-online livedesk@latest --force-role client
|
|
336
|
+
npx -y --prefer-online livedesk@latest diagnose mac-physical
|
|
337
|
+
|
|
338
|
+
Commands:
|
|
339
|
+
No command Resolve the signed-in device role and start the matching runtime.
|
|
340
|
+
hub Legacy alias for --force-role hub.
|
|
341
|
+
client Legacy alias for --force-role client.
|
|
342
|
+
diagnose mac-physical
|
|
343
|
+
Run the isolated two-display macOS capture/control physical gate.
|
|
324
344
|
|
|
325
345
|
Hub options:
|
|
326
346
|
--no-open Do not open the browser automatically.
|
|
@@ -342,10 +362,63 @@ Common:
|
|
|
342
362
|
Do not ask for a role on first run; fail if no role is known.
|
|
343
363
|
--help Show this help.
|
|
344
364
|
--version Show version.
|
|
345
|
-
`.trimStart());
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
function
|
|
365
|
+
`.trimStart());
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function printMacPhysicalDiagnosticHelp() {
|
|
369
|
+
process.stdout.write(`
|
|
370
|
+
LiveDesk macOS physical diagnostic
|
|
371
|
+
|
|
372
|
+
Usage:
|
|
373
|
+
npx -y --prefer-online livedesk@latest diagnose mac-physical
|
|
374
|
+
npx -y --prefer-online livedesk@latest diagnose mac-physical --report ./mac-result.json
|
|
375
|
+
|
|
376
|
+
Requirements:
|
|
377
|
+
macOS with two connected displays showing visibly different content.
|
|
378
|
+
Screen Recording permission for the terminal/LiveDesk capture helper.
|
|
379
|
+
Accessibility permission for the terminal/LiveDesk input helper.
|
|
380
|
+
Stop every existing LiveDesk Hub, Client, and desktop runtime first.
|
|
381
|
+
|
|
382
|
+
Behavior:
|
|
383
|
+
Starts one isolated loopback Hub and one temporary RemoteFast Client.
|
|
384
|
+
Refuses to overlap a running LiveDesk runtime or capture helper.
|
|
385
|
+
Stops only the exact child processes created by this diagnostic.
|
|
386
|
+
Writes the default report under ~/.livedesk/diagnostics.
|
|
387
|
+
|
|
388
|
+
Options:
|
|
389
|
+
--report <path> Write the JSON report relative to the invocation directory.
|
|
390
|
+
--monitor <n> Initial zero-based display index. Default: 0.
|
|
391
|
+
--width <px> Requested capture width. Default: 1920.
|
|
392
|
+
--height <px> Requested capture height. Default: 1080.
|
|
393
|
+
--help Show this help without resolving a role or acquiring a runtime lock.
|
|
394
|
+
`.trimStart());
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
async function runDiagnosticCommand(args) {
|
|
398
|
+
const name = String(args[0] || '').trim().toLowerCase();
|
|
399
|
+
if (!name || name === '--help' || name === '-h' || name === 'help') {
|
|
400
|
+
printMacPhysicalDiagnosticHelp();
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
if (name !== 'mac-physical') {
|
|
404
|
+
throw new Error(`Unknown LiveDesk diagnostic: ${name}. Supported diagnostic: mac-physical.`);
|
|
405
|
+
}
|
|
406
|
+
if (args.slice(1).some(argument => ['--help', '-h', 'help'].includes(String(argument).toLowerCase()))) {
|
|
407
|
+
printMacPhysicalDiagnosticHelp();
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
const diagnosticEntry = resolve(
|
|
411
|
+
packageRoot,
|
|
412
|
+
'diagnostics',
|
|
413
|
+
'livedesk-mode3-capture-smoke.mjs'
|
|
414
|
+
);
|
|
415
|
+
if (!existsSync(diagnosticEntry)) {
|
|
416
|
+
throw new Error(`LiveDesk mac-physical diagnostic is missing from this package: ${diagnosticEntry}`);
|
|
417
|
+
}
|
|
418
|
+
await import(pathToFileURL(diagnosticEntry).href);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function printClientHelp() {
|
|
349
422
|
process.stdout.write(`
|
|
350
423
|
LiveDesk Client
|
|
351
424
|
|
|
@@ -2847,8 +2920,14 @@ async function runDesktopRoleBootstrap() {
|
|
|
2847
2920
|
|
|
2848
2921
|
async function main() {
|
|
2849
2922
|
const rawArgs = process.argv.slice(2);
|
|
2923
|
+
const rawCommand = String(rawArgs[0] || '').trim().toLowerCase();
|
|
2924
|
+
if (rawCommand === 'diagnose') {
|
|
2925
|
+
await runDiagnosticCommand(rawArgs.slice(1));
|
|
2926
|
+
return;
|
|
2927
|
+
}
|
|
2850
2928
|
restoreUpdateOriginalCwd();
|
|
2851
2929
|
if (rawArgs.includes('--internal-legacy-client-update')) {
|
|
2930
|
+
await assertNoActiveMacPhysicalDiagnosticLease();
|
|
2852
2931
|
await runLegacyClientUpdateSupervisorCli();
|
|
2853
2932
|
return;
|
|
2854
2933
|
}
|
|
@@ -2870,11 +2949,12 @@ async function main() {
|
|
|
2870
2949
|
printHelp();
|
|
2871
2950
|
return;
|
|
2872
2951
|
}
|
|
2873
|
-
if (command === '--version' || command === '-v' || command === 'version') {
|
|
2874
|
-
console.log(readVersion());
|
|
2875
|
-
return;
|
|
2876
|
-
}
|
|
2877
|
-
|
|
2952
|
+
if (command === '--version' || command === '-v' || command === 'version') {
|
|
2953
|
+
console.log(readVersion());
|
|
2954
|
+
return;
|
|
2955
|
+
}
|
|
2956
|
+
await assertNoActiveMacPhysicalDiagnosticLease();
|
|
2957
|
+
const explicitRoleCommand = command === 'hub' || command === 'manager' || command === 'client';
|
|
2878
2958
|
let resolvedRole;
|
|
2879
2959
|
let runtimeArgs = args;
|
|
2880
2960
|
if (explicitRoleCommand) {
|
|
@@ -1432,9 +1432,11 @@ function remotePolicyAllows(options, command) {
|
|
|
1432
1432
|
const policy = options.effectivePolicy;
|
|
1433
1433
|
if (!policy || typeof policy !== 'object') return { ok: true };
|
|
1434
1434
|
if (policy.accessMode === 'block-remote-access') return { ok: false, error: 'remote-access-blocked-by-settings' };
|
|
1435
|
-
const required = command === 'input.control'
|
|
1436
|
-
? ['allowControl']
|
|
1437
|
-
: command
|
|
1435
|
+
const required = command === 'input.control'
|
|
1436
|
+
? ['allowControl']
|
|
1437
|
+
: command === 'system.power'
|
|
1438
|
+
? ['allowPowerActions']
|
|
1439
|
+
: command.startsWith('file.transfer')
|
|
1438
1440
|
? ['allowFileTransfer']
|
|
1439
1441
|
: command === 'audio.start'
|
|
1440
1442
|
? ['allowRemoteAudio']
|
|
@@ -2044,8 +2046,8 @@ function connectOnce(options, deviceId) {
|
|
|
2044
2046
|
|
|
2045
2047
|
const message = JSON.parse(line);
|
|
2046
2048
|
if (message.type === 'welcome') {
|
|
2047
|
-
options.effectivePolicy = message.effectivePolicy && typeof message.effectivePolicy === 'object'
|
|
2048
|
-
? message.effectivePolicy
|
|
2049
|
+
options.effectivePolicy = message.effectivePolicy && typeof message.effectivePolicy === 'object'
|
|
2050
|
+
? message.effectivePolicy
|
|
2049
2051
|
: null;
|
|
2050
2052
|
console.log(`Connected to LiveDesk Hub as ${options.name} (${deviceId})`);
|
|
2051
2053
|
markClientUpdateConnected();
|
|
@@ -2058,13 +2060,17 @@ function connectOnce(options, deviceId) {
|
|
|
2058
2060
|
return;
|
|
2059
2061
|
}
|
|
2060
2062
|
|
|
2061
|
-
heartbeatTimer = setInterval(() => {
|
|
2062
|
-
writeJsonLine(socket, {
|
|
2063
|
-
type: 'status',
|
|
2064
|
-
status: getStatus(options)
|
|
2065
|
-
});
|
|
2066
|
-
}, options.heartbeatMs);
|
|
2067
|
-
} else if (message.type === '
|
|
2063
|
+
heartbeatTimer = setInterval(() => {
|
|
2064
|
+
writeJsonLine(socket, {
|
|
2065
|
+
type: 'status',
|
|
2066
|
+
status: getStatus(options)
|
|
2067
|
+
});
|
|
2068
|
+
}, options.heartbeatMs);
|
|
2069
|
+
} else if (message.type === 'policy.update') {
|
|
2070
|
+
options.effectivePolicy = message.effectivePolicy && typeof message.effectivePolicy === 'object'
|
|
2071
|
+
? message.effectivePolicy
|
|
2072
|
+
: options.effectivePolicy;
|
|
2073
|
+
} else if (message.type === 'command') {
|
|
2068
2074
|
handleRemoteCommand(socket, options, message, () => {
|
|
2069
2075
|
frameSeq += 1;
|
|
2070
2076
|
return frameSeq;
|
|
@@ -4795,8 +4795,8 @@ export async function runClientRuntime(argv = process.argv.slice(2)) {
|
|
|
4795
4795
|
const parsed = parseLauncherArgs(argv);
|
|
4796
4796
|
if (parsed.retiredModelOptionsDiscarded > 0) {
|
|
4797
4797
|
console.warn(
|
|
4798
|
-
'[LiveDesk Client] Ignored retired Client
|
|
4799
|
-
+ '
|
|
4798
|
+
'[LiveDesk Client] Ignored retired Client options. '
|
|
4799
|
+
+ 'Computer commands are handled by the Hub Codex Agent.'
|
|
4800
4800
|
);
|
|
4801
4801
|
}
|
|
4802
4802
|
if (parsed.updateWaitPid) {
|
package/client/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livedesk/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.211",
|
|
4
4
|
"description": "LiveDesk local remote client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"livedesk-client-node": "bin/livedesk-client-node.js",
|
|
10
10
|
"livedesk-client-fast": "bin/livedesk-client-fast.js"
|
|
11
11
|
},
|
|
12
|
-
"files": [
|
|
13
|
-
"bin/",
|
|
14
|
-
"src/",
|
|
15
|
-
"README.md",
|
|
16
|
-
"THIRD_PARTY_NOTICES.md"
|
|
17
|
-
],
|
|
12
|
+
"files": [
|
|
13
|
+
"bin/",
|
|
14
|
+
"src/",
|
|
15
|
+
"README.md",
|
|
16
|
+
"THIRD_PARTY_NOTICES.md"
|
|
17
|
+
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"check": "node --check bin/client-version.js && node --check bin/livedesk-client.js && node --check bin/livedesk-client-node.js && node --check bin/livedesk-client-fast.js",
|
|
20
20
|
"test:version": "node --test tests/client-version.test.mjs",
|
|
@@ -31,21 +31,21 @@
|
|
|
31
31
|
"engines": {
|
|
32
32
|
"node": ">=20"
|
|
33
33
|
},
|
|
34
|
-
"dependencies": {
|
|
35
|
-
"@ffmpeg-installer/ffmpeg": "^1.1.0",
|
|
36
|
-
"ffmpeg-static": "^5.3.0",
|
|
37
|
-
"@livedesk/runtime-core": "0.1.0",
|
|
38
|
-
"@supabase/supabase-js": "^2.110.0",
|
|
39
|
-
"node-screenshots": "^0.2.8",
|
|
40
|
-
"ws": "^8.18.3"
|
|
41
|
-
},
|
|
42
|
-
"optionalDependencies": {
|
|
43
|
-
"@livedesk/fast-linux-x64": "0.1.
|
|
44
|
-
"@livedesk/fast-osx-arm64": "0.1.
|
|
45
|
-
"@livedesk/fast-osx-x64": "0.1.
|
|
46
|
-
"@livedesk/fast-win-x64": "0.1.
|
|
47
|
-
},
|
|
48
|
-
"publishConfig": {
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@ffmpeg-installer/ffmpeg": "^1.1.0",
|
|
36
|
+
"ffmpeg-static": "^5.3.0",
|
|
37
|
+
"@livedesk/runtime-core": "0.1.0",
|
|
38
|
+
"@supabase/supabase-js": "^2.110.0",
|
|
39
|
+
"node-screenshots": "^0.2.8",
|
|
40
|
+
"ws": "^8.18.3"
|
|
41
|
+
},
|
|
42
|
+
"optionalDependencies": {
|
|
43
|
+
"@livedesk/fast-linux-x64": "0.1.415",
|
|
44
|
+
"@livedesk/fast-osx-arm64": "0.1.415",
|
|
45
|
+
"@livedesk/fast-osx-x64": "0.1.415",
|
|
46
|
+
"@livedesk/fast-win-x64": "0.1.415"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
49
|
"access": "public"
|
|
50
50
|
}
|
|
51
51
|
}
|