@remcp/remcp 0.2.52 → 0.2.54

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remcp/remcp",
3
- "version": "0.2.52",
3
+ "version": "0.2.54",
4
4
  "description": "ReMCP device client: pair a computer with ReMCP and run the outbound-only agent that hosts the local MCP runtime.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/agent.mjs CHANGED
@@ -9,6 +9,7 @@ import { VERSION } from './version.mjs';
9
9
  import {
10
10
  globalCliEntry,
11
11
  globalInstalledVersion,
12
+ isNewer,
12
13
  localRuntimeEntry,
13
14
  restartToApplyUpdate,
14
15
  supervisorRestart,
@@ -414,11 +414,12 @@ export function installPersistentAgent(config) {
414
414
  // (a failed install, a cleaned LaunchAgents directory, a re-imaged user), the next update recreates
415
415
  // it instead of leaving a hand-over to a process nobody supervises.
416
416
  export function ensureServiceIfRecorded(config) {
417
- if (!persistentServiceExpected(config)) return false;
417
+ if (!persistentServiceExpected(config)) return null;
418
418
  try {
419
419
  const cliPath = canonicalServiceCliPath(config);
420
420
  const nodePath = canonicalServiceNodePath(config);
421
421
  const platform = servicePlatform();
422
+ let restartScheduled = null;
422
423
  if (platform === 'linux') {
423
424
  if (!fs.existsSync(linuxServiceFile)) {
424
425
  installLinuxService(cliPath, nodePath);
@@ -445,7 +446,8 @@ export function ensureServiceIfRecorded(config) {
445
446
  // boot out a loaded agent inline: this updater may itself be a descendant of that LaunchAgent.
446
447
  // installMacService either leaves an unchanged loaded job alone, bootstraps an unloaded job, or
447
448
  // hands a changed launcher to an independent transient launchd helper.
448
- installMacService(cliPath, { restart: false, nodePath });
449
+ const state = installMacService(cliPath, { restart: false, nodePath });
450
+ if (state === 'reload-scheduled') restartScheduled = macServiceLabel;
449
451
  } else if (platform === 'win32') installWindowsService(cliPath);
450
452
  // Upgrade the legacy inferred state only after the supervisor repair succeeded. A failed repair
451
453
  // must not turn a stale artifact into a permanent "managed service" declaration.
@@ -453,10 +455,10 @@ export function ensureServiceIfRecorded(config) {
453
455
  if (config?.serviceInstalled !== true || config?.serviceCliPath !== cliScript || config?.serviceNodePath !== nodePath) {
454
456
  saveConfig({ ...config, serviceInstalled: true, serviceCliPath: cliScript, serviceNodePath: nodePath });
455
457
  }
456
- return true;
458
+ return restartScheduled;
457
459
  } catch (error) {
458
460
  console.error(`Could not ensure the background service: ${error instanceof Error ? error.message : String(error)}`);
459
- return false;
461
+ return null;
460
462
  }
461
463
  }
462
464
 
@@ -258,10 +258,13 @@ export async function updateCommand(flags) {
258
258
  saveConfig({ ...cfg, runtime:{ ...cfg.runtime, packageSpec:targets.runtimeSpec } });
259
259
  cfg = loadConfig();
260
260
  }
261
- ensureServiceIfRecorded(cfg);
261
+ const restartAlreadyScheduled = ensureServiceIfRecorded(cfg);
262
262
  cfg = loadConfig();
263
263
  const after = { cli: installedVersion(PACKAGE_NAME), runtime: installedVersion(cfg.runtime.packageName) };
264
- const restarted = restartPersistentServiceIfInstalled(cfg);
264
+ // A changed macOS plist is reloaded by an independent launchd helper. Do not schedule a second
265
+ // helper against the same job: two one-second handoffs can race bootout/bootstrap with kickstart
266
+ // and leave the device offline even though npm installed the new release successfully.
267
+ const restarted = restartAlreadyScheduled || restartPersistentServiceIfInstalled(cfg);
265
268
  if (restarted) {
266
269
  console.log(`ReMCP updated and ${restarted} restarted (client ${before.cli} → ${after.cli ?? '?'}, runtime ${before.runtime ?? '?'} → ${after.runtime ?? '?'}).`);
267
270
  return;