livedesk 0.1.253 → 0.1.254

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 CHANGED
@@ -13,15 +13,13 @@ This starts the LiveDesk Hub, opens the local screen wall, and accepts clients.
13
13
  The Hub UI/API listens on `127.0.0.1` by default while the client endpoint
14
14
  continues to listen on the LAN.
15
15
 
16
- On startup, the launcher finds stale processes whose command line identifies
17
- them as a LiveDesk Hub, even if the old Hub is still starting and has not
18
- finished binding its ports. It also checks the Hub ports (`5179` and `5197`),
19
- waits for stale LiveDesk processes to exit, and then starts the new Hub. The
20
- client endpoint remains fixed at TCP `5197` by default so firewall rules,
21
- router forwarding, and direct clients keep a stable contract. An unrelated
22
- process is preserved and reported instead of being terminated; stop it or use
23
- an explicit `--remote-port` value. Pass `--no-clean` to disable the startup
24
- cleanup explicitly.
16
+ On startup, the launcher checks the Hub ports (`5179` and `5197`), stops every
17
+ process listening on those configured ports, waits for the ports to be released,
18
+ and then starts the new Hub. The client endpoint remains fixed at TCP `5197` by
19
+ default so firewall rules, router forwarding, and direct clients keep a stable
20
+ contract. If a process cannot be stopped or the port remains occupied, startup
21
+ fails with the owning PID and command line. Pass `--no-clean` to disable the
22
+ startup cleanup explicitly.
25
23
 
26
24
  ## Client
27
25
 
package/bin/livedesk.js CHANGED
@@ -223,19 +223,6 @@ async function stopProcessesOnPorts(ports) {
223
223
  '$ErrorActionPreference = "SilentlyContinue";',
224
224
  `$ports = @(${uniquePorts.join(',')});`,
225
225
  `$currentNodePid = ${process.pid};`,
226
- ' $liveDeskProcessPattern = "(?i)(?:livedesk|@livedesk)";',
227
- ' $hubServerProcessPattern = "(?i)(?:hub[\\\\/].*server\\.js|server\\.js)";',
228
- 'function Get-ProcessCommandChain($proc) {',
229
- ' $chain = @();',
230
- ' $current = $proc;',
231
- ' for ($depth = 0; $current -and $depth -lt 8; $depth++) {',
232
- ' $chain += [string]$current.CommandLine;',
233
- ' $parentId = [int]$current.ParentProcessId;',
234
- ' if ($parentId -le 0) { break }',
235
- ' $current = Get-CimInstance Win32_Process -Filter "ProcessId = $parentId" -ErrorAction SilentlyContinue;',
236
- ' }',
237
- ' return ($chain -join " ");',
238
- '}',
239
226
  'function Get-ListenConnections($port) {',
240
227
  ' $connections = @(Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue);',
241
228
  ' if ($connections.Count -gt 0) { return $connections }',
@@ -248,44 +235,29 @@ async function stopProcessesOnPorts(ports) {
248
235
  ' }',
249
236
  '}',
250
237
  '$records = foreach ($port in $ports) {',
251
- ' $connections = @(Get-ListenConnections $port | Where-Object { $_.OwningProcess -and $_.OwningProcess -ne $currentNodePid });',
238
+ ' $connections = @(Get-ListenConnections $port | Where-Object { $_.OwningProcess -and $_.OwningProcess -ne $currentNodePid -and $_.OwningProcess -ne $PID });',
252
239
  ' foreach ($connection in $connections) {',
253
240
  ' $owner = [int]$connection.OwningProcess;',
254
241
  ' $proc = Get-CimInstance Win32_Process -Filter "ProcessId = $owner" -ErrorAction SilentlyContinue;',
255
242
  ' $processName = if ($proc) { [string]$proc.Name } else { "" };',
256
243
  ' $commandLine = if ($proc) { [string]$proc.CommandLine } else { "" };',
257
- ' $commandChain = if ($proc) { Get-ProcessCommandChain $proc } else { "" };',
258
- ' $knownLiveDesk = ($processName -match "(?i)^node(?:\\.exe)?$") -and ($commandChain -match $liveDeskProcessPattern) -and ($commandChain -match $hubServerProcessPattern);',
259
- ' [pscustomobject]@{ Port = [int]$port; Pid = $owner; ProcessName = $processName; CommandLine = $commandLine; KnownLiveDesk = [bool]$knownLiveDesk; Action = "preserved"; PortAvailable = $false; ProcessGone = $false }',
244
+ ' [pscustomobject]@{ Port = [int]$port; Pid = $owner; ProcessName = $processName; CommandLine = $commandLine; Action = "preserved"; PortAvailable = $false }',
260
245
  ' }',
261
246
  '}',
262
247
  '$records = @($records | Sort-Object Port,Pid -Unique);',
263
- '$hubProcesses = @(Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object { $_.ProcessId -and $_.ProcessId -ne $currentNodePid -and ([string]$_.Name) -ieq "node.exe" } | ForEach-Object {',
264
- ' $commandChain = Get-ProcessCommandChain $_;',
265
- ' if (($commandChain -match $liveDeskProcessPattern) -and ($commandChain -match $hubServerProcessPattern)) {',
266
- ' [pscustomobject]@{ ProcessId = [int]$_.ProcessId; ParentProcessId = [int]$_.ParentProcessId; Name = [string]$_.Name; CommandLine = [string]$_.CommandLine; CommandChain = $commandChain }',
267
- ' }',
268
- '});',
269
- 'foreach ($proc in $hubProcesses) {',
270
- ' if (-not (@($records | Where-Object { $_.Pid -eq [int]$proc.ProcessId }).Count)) {',
271
- ' $records += [pscustomobject]@{ Port = 0; Pid = [int]$proc.ProcessId; ProcessName = [string]$proc.Name; CommandLine = [string]$proc.CommandLine; KnownLiveDesk = $true; Action = "preserved"; PortAvailable = $false; ProcessGone = $false }',
272
- ' }',
273
- '}',
274
- 'foreach ($record in @($records | Where-Object { $_.KnownLiveDesk })) {',
248
+ 'foreach ($record in $records) {',
275
249
  ' Stop-Process -Id $record.Pid -Force -ErrorAction SilentlyContinue;',
276
250
  ' $record.Action = "stopped";',
277
251
  '}',
278
252
  '$deadline = (Get-Date).ToUniversalTime().AddMilliseconds(3000);',
279
253
  'do {',
280
- ' $busyPorts = @($ports | ForEach-Object { Get-ListenConnections $_ });',
281
- ' $busyHubPids = @($records | Where-Object { $_.KnownLiveDesk } | ForEach-Object { Get-Process -Id $_.Pid -ErrorAction SilentlyContinue });',
282
- ' if (($busyPorts.Count -eq 0 -and $busyHubPids.Count -eq 0) -or (Get-Date).ToUniversalTime() -ge $deadline) { break }',
254
+ ' $busyConnections = @($ports | ForEach-Object { Get-ListenConnections $_ });',
255
+ ' if ($busyConnections.Count -eq 0 -or (Get-Date).ToUniversalTime() -ge $deadline) { break }',
283
256
  ' Start-Sleep -Milliseconds 100;',
284
257
  '} while ($true);',
285
- '$busyPortNumbers = @($busyPorts | Select-Object -ExpandProperty LocalPort -Unique);',
258
+ '$busyPortNumbers = @($busyConnections | Select-Object -ExpandProperty LocalPort -Unique);',
286
259
  'foreach ($record in $records) {',
287
260
  ' $record.PortAvailable = $busyPortNumbers -notcontains $record.Port;',
288
- ' $record.ProcessGone = -not (Get-Process -Id $record.Pid -ErrorAction SilentlyContinue);',
289
261
  '}',
290
262
  '$records | ConvertTo-Json -Compress'
291
263
  ].join(' ');
@@ -305,12 +277,12 @@ async function stopProcessesOnPorts(ports) {
305
277
  const stopped = records.filter(record => record?.Action === 'stopped');
306
278
  if (stopped.length > 0) {
307
279
  const summary = stopped.map(record => `${record.Pid}:${record.ProcessName || 'node'}${record.Port ? `@${record.Port}` : ''}`).join(', ');
308
- console.log(`Restarting LiveDesk Hub. Stopped stale LiveDesk owner(s): ${summary}`);
280
+ console.log(`Restarting LiveDesk Hub. Stopped Hub port owner(s): ${summary}`);
309
281
  }
310
- const blocked = records.filter(record => record?.PortAvailable !== true || (record?.Port === 0 && record?.ProcessGone !== true));
282
+ const blocked = records.filter(record => record?.PortAvailable !== true);
311
283
  if (blocked.length > 0) {
312
- const summary = blocked.map(record => `${record.Pid}:${record.ProcessName || 'unknown'}@${record.Port}[port-free=${record.PortAvailable === true},process-gone=${record.ProcessGone === true},cmd=${String(record.CommandLine || 'unavailable').replace(/\s+/g, ' ').slice(0, 240)}]`).join(', ');
313
- throw new Error(`LiveDesk Hub startup cleanup could not release port/process owner(s): ${summary}. LiveDesk keeps the configured port fixed; stop that process or choose an explicit --port/--remote-port value.`);
284
+ const summary = blocked.map(record => `${record.Pid}:${record.ProcessName || 'unknown'}@${record.Port}[port-free=${record.PortAvailable === true},cmd=${String(record.CommandLine || 'unavailable').replace(/\s+/g, ' ').slice(0, 240)}]`).join(', ');
285
+ throw new Error(`LiveDesk Hub startup cleanup could not release port/process owner(s): ${summary}. Stop that process manually or choose an explicit --port/--remote-port value.`);
314
286
  }
315
287
  return;
316
288
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livedesk",
3
- "version": "0.1.253",
3
+ "version": "0.1.254",
4
4
  "description": "LiveDesk Hub and client launcher",
5
5
  "type": "module",
6
6
  "bin": {