@remcp/remcp 0.2.10 → 0.2.11
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 +1 -1
- package/src/agent.mjs +32 -6
package/package.json
CHANGED
package/src/agent.mjs
CHANGED
|
@@ -106,11 +106,14 @@ export function updateDecision({ advertised, cliVersion, runtimeVersion, runtime
|
|
|
106
106
|
// Applies a freshly installed version. Exiting is what a supervisor needs; without one the new CLI is
|
|
107
107
|
// started in this process' place. Either way the agent stops holding a stale runtime, which is what
|
|
108
108
|
// makes an update actually take effect on a machine that no service manager watches.
|
|
109
|
-
async function restartToApplyUpdate(cli, stopAgent, markStopping) {
|
|
109
|
+
async function restartToApplyUpdate(cli, stopAgent, markStopping, onRuntimeRepaired) {
|
|
110
110
|
try {
|
|
111
111
|
const installed = globalInstalledVersion();
|
|
112
112
|
if (installed && !isNewer(installed, VERSION)) {
|
|
113
|
-
|
|
113
|
+
// The client is current, so the update was a runtime repair: restart the runtime rather than
|
|
114
|
+
// the whole agent, or a device with no usable runtime would stay broken.
|
|
115
|
+
console.log(`ReMCP ${VERSION} is already the installed version; restarting the local runtime.`);
|
|
116
|
+
await onRuntimeRepaired?.();
|
|
114
117
|
return;
|
|
115
118
|
}
|
|
116
119
|
console.log(`ReMCP ${installed || 'a newer version'} installed; restarting to apply it.`);
|
|
@@ -200,6 +203,9 @@ export async function runAgent(options) {
|
|
|
200
203
|
let runtimeVersion = 'unknown';
|
|
201
204
|
let runtimeRestarts = 0;
|
|
202
205
|
let runtimeDown = false;
|
|
206
|
+
// The reason the runtime is not running, sent to the server so the workspace can show something
|
|
207
|
+
// actionable instead of a machine that merely looks connected.
|
|
208
|
+
let runtimeError = '';
|
|
203
209
|
const telemetryQueue = [];
|
|
204
210
|
let telemetryTimer = null;
|
|
205
211
|
// A device whose runtime is missing or unreadable must still run the agent: the agent is what
|
|
@@ -209,7 +215,8 @@ export async function runAgent(options) {
|
|
|
209
215
|
runtimeEntry = localRuntimeEntry(options.runtime);
|
|
210
216
|
} catch (error) {
|
|
211
217
|
runtimeDown = true;
|
|
212
|
-
|
|
218
|
+
runtimeError = error instanceof Error ? error.message : String(error);
|
|
219
|
+
console.error(`${runtimeError} The agent keeps running and retries; remcp update reinstalls the runtime.`);
|
|
213
220
|
}
|
|
214
221
|
|
|
215
222
|
// --- local runtime supervision ------------------------------------------------------
|
|
@@ -254,11 +261,15 @@ export async function runAgent(options) {
|
|
|
254
261
|
runtimeVersion = client.getServerVersion()?.version || runtimeVersion;
|
|
255
262
|
runtimeRestarts += 1;
|
|
256
263
|
runtimeRestartDelay = RUNTIME_RESTART_BASE_MS;
|
|
264
|
+
runtimeDown = false;
|
|
265
|
+
runtimeError = '';
|
|
257
266
|
console.log(`ReMCP local runtime ready (${runtimeVersion})`);
|
|
258
267
|
send({ type: 'metrics', metrics: deviceMetrics({ reconnects, pendingRequests, runtimeVersion, runtimeRestarts, runtimeDown: false }) });
|
|
259
268
|
if (runtimeRestarts > 1) queueEvent({ event: 'runtime_restart', at: Date.now(), count: runtimeRestarts, success: true });
|
|
260
269
|
} catch (error) {
|
|
261
|
-
|
|
270
|
+
runtimeDown = true;
|
|
271
|
+
runtimeError = error instanceof Error ? error.message : String(error);
|
|
272
|
+
console.error(`ReMCP local runtime failed to start: ${runtimeError}`);
|
|
262
273
|
handleRuntimeExit('failed');
|
|
263
274
|
}
|
|
264
275
|
}
|
|
@@ -305,6 +316,7 @@ export async function runAgent(options) {
|
|
|
305
316
|
platform: process.platform,
|
|
306
317
|
arch: process.arch,
|
|
307
318
|
installSpec: String(options.installSpec || ''),
|
|
319
|
+
runtimeState: runtimeDown ? 'down' : 'ready',
|
|
308
320
|
})) {
|
|
309
321
|
persistState({ installReported: true });
|
|
310
322
|
console.log('ReMCP reported this installation to your own workspace (disable with `remcp telemetry off`).');
|
|
@@ -361,11 +373,13 @@ export async function runAgent(options) {
|
|
|
361
373
|
arch: process.arch,
|
|
362
374
|
agentVersion: VERSION,
|
|
363
375
|
runtimeVersion,
|
|
376
|
+
runtimeState: runtimeDown ? 'down' : 'ready',
|
|
377
|
+
runtimeError,
|
|
364
378
|
telemetryEnabled,
|
|
365
379
|
reconnects,
|
|
366
380
|
}));
|
|
367
381
|
console.log(`Connected to ${serverUrl} as ${deviceName}`);
|
|
368
|
-
send({ type: 'metrics', metrics: deviceMetrics({ reconnects, pendingRequests, runtimeVersion, runtimeRestarts, runtimeDown }) });
|
|
382
|
+
send({ type: 'metrics', metrics: deviceMetrics({ reconnects, pendingRequests, runtimeVersion, runtimeRestarts, runtimeDown }), runtimeState: runtimeDown ? 'down' : 'ready', runtimeError });
|
|
369
383
|
reportInstallOnce();
|
|
370
384
|
flushTelemetry();
|
|
371
385
|
void checkForUpdate();
|
|
@@ -463,7 +477,19 @@ export async function runAgent(options) {
|
|
|
463
477
|
console.error(`remcp update exited with ${code}; keeping ${VERSION} and retrying after the cooldown.`);
|
|
464
478
|
return;
|
|
465
479
|
}
|
|
466
|
-
void restartToApplyUpdate(cli, stop, () => { stopping = true; })
|
|
480
|
+
void restartToApplyUpdate(cli, stop, () => { stopping = true; }, async () => {
|
|
481
|
+
// The packages are installed now: clear the failure, reset the backoff and start again.
|
|
482
|
+
runtimeRestartDelay = RUNTIME_RESTART_BASE_MS;
|
|
483
|
+
runtimeDown = false;
|
|
484
|
+
runtimeError = '';
|
|
485
|
+
try {
|
|
486
|
+
runtimeEntry = localRuntimeEntry(options.runtime);
|
|
487
|
+
} catch (error) {
|
|
488
|
+
runtimeDown = true;
|
|
489
|
+
runtimeError = error instanceof Error ? error.message : String(error);
|
|
490
|
+
}
|
|
491
|
+
if (!runtimeDown && !stopping) await startRuntime();
|
|
492
|
+
});
|
|
467
493
|
});
|
|
468
494
|
child.on('error', error => {
|
|
469
495
|
updateInFlight = false;
|