@webmux/agent 0.1.1 → 0.1.3

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.
Files changed (2) hide show
  1. package/dist/cli.js +56 -9
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -254,6 +254,7 @@ async function createTerminalBridge(options) {
254
254
 
255
255
  // src/connection.ts
256
256
  var HEARTBEAT_INTERVAL_MS = 3e4;
257
+ var SESSION_SYNC_INTERVAL_MS = 15e3;
257
258
  var INITIAL_RECONNECT_DELAY_MS = 1e3;
258
259
  var MAX_RECONNECT_DELAY_MS = 3e4;
259
260
  var AgentConnection = class {
@@ -263,6 +264,7 @@ var AgentConnection = class {
263
264
  tmux;
264
265
  ws = null;
265
266
  heartbeatTimer = null;
267
+ sessionSyncTimer = null;
266
268
  reconnectTimer = null;
267
269
  reconnectDelay = INITIAL_RECONNECT_DELAY_MS;
268
270
  bridges = /* @__PURE__ */ new Map();
@@ -284,6 +286,7 @@ var AgentConnection = class {
284
286
  this.reconnectTimer = null;
285
287
  }
286
288
  this.stopHeartbeat();
289
+ this.stopSessionSync();
287
290
  this.disposeAllBridges();
288
291
  if (this.ws) {
289
292
  this.ws.close(1e3, "agent shutting down");
@@ -323,6 +326,7 @@ var AgentConnection = class {
323
326
  case "auth-ok":
324
327
  console.log("[agent] Authenticated successfully");
325
328
  this.startHeartbeat();
329
+ this.startSessionSync();
326
330
  this.syncSessions();
327
331
  break;
328
332
  case "auth-fail":
@@ -350,10 +354,10 @@ var AgentConnection = class {
350
354
  this.handleTerminalResize(msg.browserId, msg.cols, msg.rows);
351
355
  break;
352
356
  case "session-create":
353
- this.handleSessionCreate(msg.name);
357
+ this.handleSessionCreate(msg.requestId, msg.name);
354
358
  break;
355
359
  case "session-kill":
356
- this.handleSessionKill(msg.name);
360
+ this.handleSessionKill(msg.requestId, msg.name);
357
361
  break;
358
362
  default:
359
363
  console.warn("[agent] Unknown message type:", msg.type);
@@ -363,9 +367,11 @@ var AgentConnection = class {
363
367
  try {
364
368
  const sessions = await this.tmux.listSessions();
365
369
  this.sendMessage({ type: "sessions-sync", sessions });
370
+ return sessions;
366
371
  } catch (err) {
367
372
  console.error("[agent] Failed to list sessions:", err);
368
373
  this.sendMessage({ type: "error", message: "Failed to list sessions" });
374
+ return [];
369
375
  }
370
376
  }
371
377
  async handleTerminalAttach(browserId, sessionName, cols, rows) {
@@ -386,10 +392,12 @@ var AgentConnection = class {
386
392
  onExit: (exitCode) => {
387
393
  this.bridges.delete(browserId);
388
394
  this.sendMessage({ type: "terminal-exit", browserId, exitCode });
395
+ void this.syncSessions();
389
396
  }
390
397
  });
391
398
  this.bridges.set(browserId, bridge);
392
399
  this.sendMessage({ type: "terminal-ready", browserId, sessionName });
400
+ await this.syncSessions();
393
401
  } catch (err) {
394
402
  const message = err instanceof Error ? err.message : String(err);
395
403
  console.error(`[agent] Failed to attach terminal for browser ${browserId}:`, message);
@@ -401,6 +409,7 @@ var AgentConnection = class {
401
409
  if (bridge) {
402
410
  bridge.dispose();
403
411
  this.bridges.delete(browserId);
412
+ void this.syncSessions();
404
413
  }
405
414
  }
406
415
  handleTerminalInput(browserId, data) {
@@ -415,24 +424,30 @@ var AgentConnection = class {
415
424
  bridge.resize(cols, rows);
416
425
  }
417
426
  }
418
- async handleSessionCreate(name) {
427
+ async handleSessionCreate(requestId, name) {
419
428
  try {
420
429
  await this.tmux.createSession(name);
421
- await this.syncSessions();
430
+ const sessions = await this.syncSessions();
431
+ const session = sessions.find((item) => item.name === name);
432
+ if (!session) {
433
+ throw new Error("Created session was not returned by tmux");
434
+ }
435
+ this.sendMessage({ type: "command-result", requestId, ok: true, session });
422
436
  } catch (err) {
423
437
  const message = err instanceof Error ? err.message : String(err);
424
438
  console.error(`[agent] Failed to create session "${name}":`, message);
425
- this.sendMessage({ type: "error", message: `Failed to create session: ${message}` });
439
+ this.sendMessage({ type: "command-result", requestId, ok: false, error: message });
426
440
  }
427
441
  }
428
- async handleSessionKill(name) {
442
+ async handleSessionKill(requestId, name) {
429
443
  try {
430
444
  await this.tmux.killSession(name);
431
445
  await this.syncSessions();
446
+ this.sendMessage({ type: "command-result", requestId, ok: true });
432
447
  } catch (err) {
433
448
  const message = err instanceof Error ? err.message : String(err);
434
449
  console.error(`[agent] Failed to kill session "${name}":`, message);
435
- this.sendMessage({ type: "error", message: `Failed to kill session: ${message}` });
450
+ this.sendMessage({ type: "command-result", requestId, ok: false, error: message });
436
451
  }
437
452
  }
438
453
  sendMessage(msg) {
@@ -446,12 +461,24 @@ var AgentConnection = class {
446
461
  this.sendMessage({ type: "heartbeat" });
447
462
  }, HEARTBEAT_INTERVAL_MS);
448
463
  }
464
+ startSessionSync() {
465
+ this.stopSessionSync();
466
+ this.sessionSyncTimer = setInterval(() => {
467
+ void this.syncSessions();
468
+ }, SESSION_SYNC_INTERVAL_MS);
469
+ }
449
470
  stopHeartbeat() {
450
471
  if (this.heartbeatTimer) {
451
472
  clearInterval(this.heartbeatTimer);
452
473
  this.heartbeatTimer = null;
453
474
  }
454
475
  }
476
+ stopSessionSync() {
477
+ if (this.sessionSyncTimer) {
478
+ clearInterval(this.sessionSyncTimer);
479
+ this.sessionSyncTimer = null;
480
+ }
481
+ }
455
482
  disposeAllBridges() {
456
483
  for (const [browserId, bridge] of this.bridges) {
457
484
  bridge.dispose();
@@ -460,6 +487,7 @@ var AgentConnection = class {
460
487
  }
461
488
  onDisconnect() {
462
489
  this.stopHeartbeat();
490
+ this.stopSessionSync();
463
491
  this.disposeAllBridges();
464
492
  this.ws = null;
465
493
  if (this.stopped) {
@@ -591,6 +619,7 @@ service.command("install").description("Install and start the agent as a systemd
591
619
  }
592
620
  const serviceDir = path2.join(os2.homedir(), ".config", "systemd", "user");
593
621
  const servicePath = path2.join(serviceDir, `${SERVICE_NAME}.service`);
622
+ const npmPath = findBinary("npm") ?? "npm";
594
623
  const unit = `[Unit]
595
624
  Description=Webmux Agent (${creds.name})
596
625
  After=network-online.target
@@ -598,9 +627,10 @@ Wants=network-online.target
598
627
 
599
628
  [Service]
600
629
  Type=simple
601
- ExecStart=${npxPath} -y @webmux/agent start
630
+ ExecStartPre=${npmPath} install -g @webmux/agent@latest
631
+ ExecStart=${findBinary("webmux-agent") ?? `${npxPath} -y @webmux/agent`} start
602
632
  Restart=always
603
- RestartSec=5
633
+ RestartSec=10
604
634
  Environment=HOME=${os2.homedir()}
605
635
  Environment=PATH=${process.env.PATH}
606
636
  WorkingDirectory=${os2.homedir()}
@@ -656,6 +686,23 @@ service.command("status").description("Show systemd service status").action(() =
656
686
  console.log(`[agent] Service is not installed or not running.`);
657
687
  }
658
688
  });
689
+ service.command("upgrade").description("Upgrade agent to latest version and restart service").action(() => {
690
+ console.log("[agent] Upgrading @webmux/agent to latest...");
691
+ try {
692
+ execSync("npm install -g @webmux/agent@latest", { stdio: "inherit" });
693
+ } catch {
694
+ console.error("[agent] Failed to upgrade. Try manually: npm install -g @webmux/agent@latest");
695
+ process.exit(1);
696
+ }
697
+ console.log("[agent] Restarting service...");
698
+ try {
699
+ execSync(`systemctl --user restart ${SERVICE_NAME}`, { stdio: "inherit" });
700
+ console.log("[agent] Upgrade complete!");
701
+ } catch {
702
+ console.log("[agent] Package upgraded. Service not installed or restart failed.");
703
+ console.log("[agent] If running manually, restart with: npx @webmux/agent@latest start");
704
+ }
705
+ });
659
706
  function findBinary(name) {
660
707
  try {
661
708
  return execSync(`which ${name} 2>/dev/null`, { encoding: "utf-8" }).trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webmux/agent",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "webmux-agent": "./dist/cli.js"