@remcp/remcp 0.2.192 → 0.2.193
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/cli/service.mjs +3 -0
- package/src/cli.mjs +25 -2
package/package.json
CHANGED
package/src/cli/service.mjs
CHANGED
|
@@ -245,6 +245,9 @@ export function restartPersistentServiceIfInstalled(config, { deferLinux = false
|
|
|
245
245
|
if (platform === 'win32') {
|
|
246
246
|
const result = spawnSync('schtasks.exe', ['/Query', '/TN', windowsTaskName], { stdio: 'ignore' });
|
|
247
247
|
if (result.status === 0) {
|
|
248
|
+
// /Run does not restart a task that is already running; stop the previous
|
|
249
|
+
// process first so a rotated credential is loaded by the replacement.
|
|
250
|
+
spawnSync('schtasks.exe', ['/End', '/TN', windowsTaskName], { stdio: 'ignore' });
|
|
248
251
|
run('schtasks.exe', ['/Run', '/TN', windowsTaskName]);
|
|
249
252
|
return windowsTaskName;
|
|
250
253
|
}
|
package/src/cli.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import { ensureMachineId, loadConfig, readJsonFile, saveConfig, setTelemetry, te
|
|
|
11
11
|
import { assertRuntimeTrust, assertSecureServerUrl, pairWithDeviceCode } from './cli/connect.mjs';
|
|
12
12
|
import { diagnoseLocalRuntime, installedVersion, runtimeAllowedRoots } from './cli/doctor.mjs';
|
|
13
13
|
import { configFile, npm, officialOrigin, runtimeConfigFile } from './cli/env.mjs';
|
|
14
|
-
import { currentInstallationInfo, ensureMacCliCommand, installPersistentAgent, persistentServiceState, rememberCurrentInstallation, restartPersistentServiceIfInstalled, serviceInstallationInfo, uninstallPersistentService } from './cli/service.mjs';
|
|
14
|
+
import { currentInstallationInfo, ensureMacCliCommand, installPersistentAgent, persistentServiceState, servicePlatform, rememberCurrentInstallation, restartPersistentServiceIfInstalled, serviceInstallationInfo, uninstallPersistentService } from './cli/service.mjs';
|
|
15
15
|
import { run } from './cli/shell.mjs';
|
|
16
16
|
import { updateCommand } from './cli/update.mjs';
|
|
17
17
|
function fetchConfiguredServer(url, options) {
|
|
@@ -49,6 +49,11 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
49
49
|
// Like the desktop-app flow this mirrors: with no flags the command talks to the official
|
|
50
50
|
// server, prints a code, opens the browser to approve it, and pairs. `--code` keeps working for
|
|
51
51
|
// the workspace-generated command and for CI, and `--server` for self-hosted deployments.
|
|
52
|
+
const previous = loadConfig(false);
|
|
53
|
+
const alreadyPaired = Boolean(previous?.deviceId && previous?.deviceToken);
|
|
54
|
+
if (alreadyPaired && flags['re-pair'] !== true) {
|
|
55
|
+
throw new Error('This computer is already paired. Use `remcp doctor` or `remcp install` to repair it without changing credentials. To intentionally replace the pairing (possibly moving it to another account), add --re-pair.');
|
|
56
|
+
}
|
|
52
57
|
const server = assertSecureServerUrl(flags.server || officialOrigin, { allowInsecure: flags['allow-insecure-transport'] === true });
|
|
53
58
|
const code = String(flags.code || '').replace(/\s+/g, '').toUpperCase();
|
|
54
59
|
assertRuntimeTrust(server, flags);
|
|
@@ -60,7 +65,7 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
60
65
|
method: 'POST',
|
|
61
66
|
redirect: 'error',
|
|
62
67
|
headers: { 'content-type': 'application/json' },
|
|
63
|
-
body: JSON.stringify({ code, machineId: ensureMachineId(), name: String(flags.name || os.hostname()), hostname: os.hostname(), platform: process.platform, arch: process.arch }),
|
|
68
|
+
body: JSON.stringify({ code, machineId: ensureMachineId(), name: String(flags.name || os.hostname()), hostname: os.hostname(), platform: process.platform, arch: process.arch, rePair: flags['re-pair'] === true }),
|
|
64
69
|
|
|
65
70
|
});
|
|
66
71
|
if (!response.ok) throw new Error(`Pairing failed (${response.status}): ${await response.text()}`);
|
|
@@ -75,6 +80,7 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
75
80
|
console.log('This computer was paired to another ReMCP account. That device was revoked and this machine now belongs to the account you approved.');
|
|
76
81
|
}
|
|
77
82
|
const config = {
|
|
83
|
+
...(previous || {}),
|
|
78
84
|
serverUrl: server,
|
|
79
85
|
deviceId: paired.deviceId || paired.device_id,
|
|
80
86
|
deviceToken: paired.deviceToken || paired.device_token,
|
|
@@ -90,8 +96,25 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
90
96
|
saveConfig(config);
|
|
91
97
|
const accountEmail = String(paired.account?.email || '');
|
|
92
98
|
console.log(`Paired ${os.hostname()} with ${server}${accountEmail ? ` as ${accountEmail}` : ''}`);
|
|
99
|
+
// Credential rotation must reload the managed agent; a normal install of an already
|
|
100
|
+
// running systemd service does not restart it, and Windows /Run may keep the old task.
|
|
101
|
+
const managedBefore = alreadyPaired &&
|
|
102
|
+
(previous.serviceInstalled === true ||
|
|
103
|
+
(previous.serviceInstalled === undefined && persistentServiceState(previous).active));
|
|
93
104
|
if (flags.install) {
|
|
94
105
|
installPersistentAgent(config);
|
|
106
|
+
if (alreadyPaired && servicePlatform() !== 'darwin') {
|
|
107
|
+
restartPersistentServiceIfInstalled(config, { deferLinux: true });
|
|
108
|
+
}
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (managedBefore) {
|
|
112
|
+
const restarted = restartPersistentServiceIfInstalled(config, { deferLinux: true });
|
|
113
|
+
if (!restarted) installPersistentAgent(config);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (alreadyPaired) {
|
|
117
|
+
console.log('Pairing credentials replaced. Restart any manually managed ReMCP agent to use the new token.');
|
|
95
118
|
return;
|
|
96
119
|
}
|
|
97
120
|
// Only the command that asked for its own code keeps running: someone who ran `remcp connect` on
|