@remcp/remcp 0.2.215 → 0.2.216

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.215",
3
+ "version": "0.2.216",
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",
@@ -5,7 +5,9 @@ import { VERSION } from './version.mjs';
5
5
  import { fetchUpdateManifest } from './fetch-update-manifest.mjs';
6
6
  import { globalCliEntry, globalInstalledVersion, isNewer, restartToApplyUpdate, updateDecision, updateInvocationArgs } from './agent-update.mjs';
7
7
 
8
- export const UPDATE_CHECK_INTERVAL_MS = 6 * 60 * 60 * 1000;
8
+ // Poll releases while connected too: relying on reconnect alone can leave a
9
+ // healthy long-lived agent stale for six hours after deployment.
10
+ export const UPDATE_CHECK_INTERVAL_MS = 30 * 60 * 1000;
9
11
  const UPDATE_CHECK_TIMEOUT_MS = 12000;
10
12
  // A flapping relay must not trigger update discovery on every successful reconnect.
11
13
  const UPDATE_CHECK_RECONNECT_GAP_MS = 30000;
@@ -12,7 +12,7 @@ import { loadConfig, saveConfig } from './config.mjs';
12
12
  import { assertSecureServerUrl } from './connect.mjs';
13
13
  import { installedVersion } from './doctor.mjs';
14
14
  import { linuxServiceFile, macServiceFile, officialOrigin } from './env.mjs';
15
- import { currentInstallationInfo, ensureMacCliCommand, ensureServiceIfRecorded, npmGlobalUpdate, persistentServiceExpected, rememberCurrentInstallation, restartPersistentServiceIfInstalled, serviceInstallationInfo, syncKnownInstallations } from './service.mjs';
15
+ import { currentInstallationInfo, ensureMacCliCommand, ensureServiceIfRecorded, npmGlobalUpdate, persistentServiceExpected, rememberCurrentInstallation, restartPersistentServiceIfInstalled, servicePlatform, serviceInstallationInfo, syncKnownInstallations } from './service.mjs';
16
16
 
17
17
  const UPDATE_DISCOVERY_TIMEOUT_MS = 5000;
18
18
 
@@ -201,6 +201,14 @@ export function verifyManagedServiceReleasePair(serviceInstall, clientSpec, runt
201
201
  }
202
202
  }
203
203
 
204
+ // A pinned automatic update can be a no-op on disk while an older Windows agent
205
+ // still owns the Scheduled Task. Keep manual unpinned no-ops side-effect free.
206
+ export function shouldApplyAlreadyInstalledWindowsRelease({ platform, serviceExpected, flags }) {
207
+ return platform === 'win32' && serviceExpected === true &&
208
+ typeof flags?.client === 'string' && Boolean(flags.client.trim()) &&
209
+ typeof flags?.runtime === 'string' && Boolean(flags.runtime.trim());
210
+ }
211
+
204
212
  export async function updateCommand(flags) {
205
213
  let cfg = rememberCurrentInstallation(loadConfig());
206
214
  const targets = await resolveUpdateTargets({ cfg, flags });
@@ -246,6 +254,13 @@ export async function updateCommand(flags) {
246
254
  }
247
255
  const currentRuntimeVersion = String(currentInstall.runtimeVersion || specVersion(cfg.runtime.packageName, targets.runtimeSpec) || '?');
248
256
  console.log(`ReMCP is already up to date (client ${currentInstall.cliVersion || VERSION}, runtime ${currentRuntimeVersion}).`);
257
+ if (shouldApplyAlreadyInstalledWindowsRelease({ platform: servicePlatform(), serviceExpected, flags })) {
258
+ // This CLI may be newer than its still-running parent agent. The canonical
259
+ // service files are correct, but the existing Windows task must hand over.
260
+ const restarted = restartPersistentServiceIfInstalled(cfg, { deferWindows: true });
261
+ if (!restarted) throw new Error('ReMCP Windows task could not schedule a restart for the installed release');
262
+ console.log(`ReMCP installed release will be applied: ${restarted}.`);
263
+ }
249
264
  return;
250
265
  }
251
266
 
@@ -284,7 +299,12 @@ export async function updateCommand(flags) {
284
299
  // A changed macOS plist is reloaded by an independent launchd helper. Do not schedule a second
285
300
  // helper against the same job: two one-second handoffs can race bootout/bootstrap with kickstart
286
301
  // and leave the device offline even though npm installed the new release successfully.
287
- const restarted = restartAlreadyScheduled || restartPersistentServiceIfInstalled(cfg);
302
+ // On Windows the updater may be a descendant of the task being restarted.
303
+ // An inline /End kills the updater before its /Run can execute, leaving an
304
+ // older process connected after the new release was installed on disk.
305
+ // Use the already-tested independent handoff helper for every update.
306
+ const restarted = restartAlreadyScheduled ||
307
+ restartPersistentServiceIfInstalled(cfg, { deferWindows: true });
288
308
  if (restarted) {
289
309
  console.log(`ReMCP updated and ${restarted} restarted (client ${before.cli} → ${after.cli ?? '?'}, runtime ${before.runtime ?? '?'} → ${after.runtime ?? '?'}).`);
290
310
  return;