livedesk 0.1.261 → 0.1.263

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/hub/src/server.js CHANGED
@@ -3,7 +3,7 @@
3
3
  import express from 'express';
4
4
  import crypto from 'node:crypto';
5
5
  import { createServer } from 'node:http';
6
- import { existsSync, readFileSync } from 'node:fs';
6
+ import { existsSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
7
7
  import { dirname, resolve } from 'node:path';
8
8
  import { fileURLToPath } from 'node:url';
9
9
  import { WebSocketServer } from 'ws';
@@ -25,7 +25,8 @@ import { getAgentToolDefinition } from './agents/agent-tool-registry.js';
25
25
  import { LiveDeskSettingsStore, SettingsConflictError } from './settings/settings-store.js';
26
26
  import { effectiveDevicePolicy } from './settings/settings-schema.js';
27
27
  import { buildEffectiveDevicePolicy } from './settings/effective-device-policy.js';
28
- import { CaptureStore } from './captures/capture-store.js';
28
+ import { CaptureStore } from './captures/capture-store.js';
29
+ import { createLiveDeskUpdateManager } from './live-desk-update.js';
29
30
 
30
31
  const __dirname = dirname(fileURLToPath(import.meta.url));
31
32
  const webDistCandidates = [
@@ -72,15 +73,17 @@ let verifiedLicense = {
72
73
  };
73
74
  let frameClientSeq = 0;
74
75
  let inputClientSeq = 0;
75
- let audioClientSeq = 0;
76
+ let audioClientSeq = 0;
77
+ let liveDeskUpdateManager = null;
76
78
 
77
79
  function readPositiveIntegerEnv(name, fallback) {
78
80
  const value = Number(process.env[name]);
79
81
  return Number.isFinite(value) && value > 0 ? Math.round(value) : fallback;
80
82
  }
81
83
 
82
- function handleRemoteHubEvent(type, event) {
83
- if (type === 'RemoteInputApplied') {
84
+ function handleRemoteHubEvent(type, event) {
85
+ liveDeskUpdateManager?.handleRemoteEvent(type, event);
86
+ if (type === 'RemoteInputApplied') {
84
87
  for (const ws of inputClients) {
85
88
  sendJson(ws, {
86
89
  type: 'RemoteInputApplied',
@@ -247,7 +250,7 @@ void liveDeskSettingsStore.getRecord().catch(error => {
247
250
  console.warn(`[LiveDesk Hub] settings load failed: ${error instanceof Error ? error.message : String(error)}`);
248
251
  });
249
252
 
250
- const remoteHub = createRemoteHub({
253
+ const remoteHub = createRemoteHub({
251
254
  managerPackage: '@livedesk/hub',
252
255
  managerVersion: packageInfo.version,
253
256
  env: {
@@ -260,8 +263,35 @@ const remoteHub = createRemoteHub({
260
263
  emitEvent: handleRemoteHubEvent,
261
264
  emitFrame: broadcastRemoteBinaryFrame,
262
265
  emitAudio: broadcastRemoteBinaryAudio,
263
- getEffectiveDevicePolicy: ({ deviceId, capabilities }) => buildEffectiveDevicePolicy(liveDeskSettingsStore.getCached(), { deviceId, capabilities })
264
- });
266
+ getEffectiveDevicePolicy: ({ deviceId, capabilities }) => buildEffectiveDevicePolicy(liveDeskSettingsStore.getCached(), { deviceId, capabilities })
267
+ });
268
+
269
+ function requestHubRestart(request = {}) {
270
+ const requestPath = String(process.env.LIVEDESK_HUB_UPDATE_REQUEST_PATH || '').trim();
271
+ if (!requestPath) {
272
+ return { ok: false, error: 'hub-launcher-restart-unavailable' };
273
+ }
274
+ try {
275
+ const temporaryPath = `${requestPath}.${process.pid}.tmp`;
276
+ writeFileSync(temporaryPath, JSON.stringify({
277
+ ...request,
278
+ pid: process.pid,
279
+ requestedAt: new Date().toISOString()
280
+ }), 'utf8');
281
+ renameSync(temporaryPath, requestPath);
282
+ return { ok: true };
283
+ } catch (error) {
284
+ return { ok: false, error: `hub-restart-request-failed: ${error instanceof Error ? error.message : String(error)}` };
285
+ }
286
+ }
287
+
288
+ liveDeskUpdateManager = createLiveDeskUpdateManager({
289
+ remoteHub,
290
+ currentManagerVersion: process.env.LIVEDESK_MANAGER_VERSION || packageInfo.version,
291
+ currentClientVersion: process.env.LIVEDESK_CLIENT_PACKAGE_VERSION || '',
292
+ restartSupported: !!String(process.env.LIVEDESK_HUB_UPDATE_REQUEST_PATH || '').trim(),
293
+ requestHubRestart
294
+ });
265
295
  const agentMcpSessions = new Map();
266
296
  const agentMcpRunBatches = new Map();
267
297
  const agentMcpRunCleanupTimers = new Map();
@@ -2206,16 +2236,32 @@ app.post('/api/settings/agent/summary', async (req, res) => {
2206
2236
  }
2207
2237
  });
2208
2238
 
2209
- app.get('/api/remote/status', (_req, res) => {
2210
- noStore(res);
2211
- const secretStatus = remoteHub.getStatus({ includeSecrets: true });
2212
- res.json({
2213
- ...remoteHub.getStatus({ includeSecrets: false }),
2214
- pairingPin: secretStatus.pairingPin,
2215
- product: 'LiveDesk',
2216
- agentPackage: '@livedesk/client'
2217
- });
2218
- });
2239
+ app.get('/api/remote/status', (_req, res) => {
2240
+ noStore(res);
2241
+ const secretStatus = remoteHub.getStatus({ includeSecrets: true });
2242
+ res.json({
2243
+ ...remoteHub.getStatus({ includeSecrets: false }),
2244
+ pairingPin: secretStatus.pairingPin,
2245
+ product: 'LiveDesk',
2246
+ agentPackage: '@livedesk/client',
2247
+ update: liveDeskUpdateManager?.getStatus() || null
2248
+ });
2249
+ });
2250
+
2251
+ app.get('/api/update/status', (_req, res) => {
2252
+ noStore(res);
2253
+ res.json(liveDeskUpdateManager?.getStatus() || { updateAvailable: false, state: 'unavailable' });
2254
+ });
2255
+
2256
+ app.post('/api/update/apply', async (_req, res) => {
2257
+ noStore(res);
2258
+ try {
2259
+ const result = await liveDeskUpdateManager?.startUpdate();
2260
+ res.status(result?.ok === false ? 409 : 200).json(result || { ok: false, error: 'update-manager-unavailable' });
2261
+ } catch (error) {
2262
+ res.status(500).json({ ok: false, error: error instanceof Error ? error.message : String(error) });
2263
+ }
2264
+ });
2219
2265
 
2220
2266
  app.get('/api/remote/registry-credentials', (_req, res) => {
2221
2267
  noStore(res);
@@ -2934,8 +2980,9 @@ httpServer.listen(httpPort, httpHost, () => {
2934
2980
  });
2935
2981
 
2936
2982
  for (const signal of ['SIGINT', 'SIGTERM']) {
2937
- process.once(signal, async () => {
2938
- for (const session of atlasClients.values()) session.close();
2983
+ process.once(signal, async () => {
2984
+ liveDeskUpdateManager?.close();
2985
+ for (const session of atlasClients.values()) session.close();
2939
2986
  atlasClients.clear();
2940
2987
  hubSharedFolders.close();
2941
2988
  await remoteHub.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livedesk",
3
- "version": "0.1.261",
3
+ "version": "0.1.263",
4
4
  "description": "LiveDesk Hub and client launcher",
5
5
  "type": "module",
6
6
  "bin": {
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@ffmpeg-installer/ffmpeg": "^1.1.0",
34
- "@livedesk/client": "0.1.134",
34
+ "@livedesk/client": "0.1.135",
35
35
  "@openai/codex-sdk": "0.144.5",
36
36
  "cors": "^2.8.5",
37
37
  "express": "^4.21.2",