@remcp/remcp 0.2.236 → 0.2.238
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 +2 -2
- package/src/cli/service-inventory.mjs +6 -4
- package/src/cli/service-linux.mjs +92 -0
- package/src/cli/service.mjs +48 -19
- package/src/cli/update.mjs +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remcp/remcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.238",
|
|
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",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"README.md"
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
|
-
"check": "node --check bin/remcp.mjs && node --check src/agent-deploy-reconnect.mjs && node --check src/agent-network-probe-client.mjs && node --check src/agent-relay-connection.mjs && node --check src/agent-responder.mjs && node --check src/agent-runtime-capabilities.mjs && node --check src/agent-update-monitor.mjs && node --check src/agent-update-rollout.mjs && node --check src/agent-update.mjs && node --check src/agent-utilities.mjs && node --check src/agent.mjs && node --check src/cli.mjs && node --check src/cli/config.mjs && node --check src/cli/connect.mjs && node --check src/cli/doctor.mjs && node --check src/cli/env.mjs && node --check src/cli/installation-audit.mjs && node --check src/cli/mac-native-temperature.mjs && node --check src/cli/npm-global.mjs && node --check src/cli/pairing-qr.mjs && node --check src/cli/service-inventory.mjs && node --check src/cli/service-macos.mjs && node --check src/cli/service-paths.mjs && node --check src/cli/service.mjs && node --check src/cli/shell.mjs && node --check src/cli/supervised-agent-lifecycle.mjs && node --check src/cli/update.mjs && node --check src/cli/windows-cli-shim.mjs && node --check src/cli/windows-owned-job-source.mjs && node --check src/cli/windows-owned-job.mjs && node --check src/cli/windows-supervisor.mjs && node --check src/cli/windows-update-lock.mjs && node --check src/cli/windows-user-supervisor.mjs && node --check src/fetch-update-manifest.mjs && node --check src/fs-access.mjs && node --check src/npm.mjs && node --check src/runtime.mjs && node --check src/version.mjs",
|
|
21
|
+
"check": "node --check bin/remcp.mjs && node --check src/agent-deploy-reconnect.mjs && node --check src/agent-network-probe-client.mjs && node --check src/agent-relay-connection.mjs && node --check src/agent-responder.mjs && node --check src/agent-runtime-capabilities.mjs && node --check src/agent-update-monitor.mjs && node --check src/agent-update-rollout.mjs && node --check src/agent-update.mjs && node --check src/agent-utilities.mjs && node --check src/agent.mjs && node --check src/cli.mjs && node --check src/cli/config.mjs && node --check src/cli/connect.mjs && node --check src/cli/doctor.mjs && node --check src/cli/env.mjs && node --check src/cli/installation-audit.mjs && node --check src/cli/mac-native-temperature.mjs && node --check src/cli/npm-global.mjs && node --check src/cli/pairing-qr.mjs && node --check src/cli/service-inventory.mjs && node --check src/cli/service-linux.mjs && node --check src/cli/service-macos.mjs && node --check src/cli/service-paths.mjs && node --check src/cli/service.mjs && node --check src/cli/shell.mjs && node --check src/cli/supervised-agent-lifecycle.mjs && node --check src/cli/update.mjs && node --check src/cli/windows-cli-shim.mjs && node --check src/cli/windows-owned-job-source.mjs && node --check src/cli/windows-owned-job.mjs && node --check src/cli/windows-supervisor.mjs && node --check src/cli/windows-update-lock.mjs && node --check src/cli/windows-user-supervisor.mjs && node --check src/fetch-update-manifest.mjs && node --check src/fs-access.mjs && node --check src/npm.mjs && node --check src/runtime.mjs && node --check src/version.mjs",
|
|
22
22
|
"test": "node --test test/*.test.mjs"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
@@ -5,6 +5,7 @@ import { spawnSync } from 'node:child_process';
|
|
|
5
5
|
import { PACKAGE_NAME, VERSION } from '../version.mjs';
|
|
6
6
|
import { saveConfig } from './config.mjs';
|
|
7
7
|
import { linuxServiceFile, linuxServiceLauncherFile, macServiceFile, macServiceLabel, windowsStartupScriptFile, windowsTaskName } from './env.mjs';
|
|
8
|
+
import { linuxSystemAgentOwned } from './service-linux.mjs';
|
|
8
9
|
import { servicePlatform, globalCliPath, npmGlobalUpdateForNode } from './npm-global.mjs';
|
|
9
10
|
import { windowsStartupScriptInstalled } from './windows-supervisor.mjs';
|
|
10
11
|
|
|
@@ -12,7 +13,7 @@ export function persistentServiceExpected(config) {
|
|
|
12
13
|
if (config?.serviceInstalled === false) return false;
|
|
13
14
|
if (config?.serviceInstalled === true) return true;
|
|
14
15
|
const platform = servicePlatform();
|
|
15
|
-
if (platform === 'linux') return fs.existsSync(linuxServiceFile);
|
|
16
|
+
if (platform === 'linux') return linuxSystemAgentOwned() || fs.existsSync(linuxServiceFile);
|
|
16
17
|
if (platform === 'darwin') return fs.existsSync(macServiceFile);
|
|
17
18
|
if (platform === 'win32') {
|
|
18
19
|
return windowsStartupScriptInstalled(windowsStartupScriptFile) ||
|
|
@@ -25,9 +26,10 @@ export function persistentServiceState(config) {
|
|
|
25
26
|
const platform = servicePlatform();
|
|
26
27
|
const expected = persistentServiceExpected(config);
|
|
27
28
|
if (platform === 'linux') {
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
29
|
+
const system = linuxSystemAgentOwned();
|
|
30
|
+
const installed = system || fs.existsSync(linuxServiceFile);
|
|
31
|
+
const active = installed && spawnSync('systemctl', [...(system ? [] : ['--user']), 'is-active', '--quiet', 'remcp-agent.service'], { stdio: 'ignore' }).status === 0;
|
|
32
|
+
return { expected, installed, active, manager:system ? 'systemd-system' : 'systemd-user', name:'remcp-agent.service' };
|
|
31
33
|
}
|
|
32
34
|
if (platform === 'darwin') {
|
|
33
35
|
const installed = fs.existsSync(macServiceFile);
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Linux headless agents may be supervised by PID 1. Never mistake a system unit for
|
|
2
|
+
// a session-owned user unit during status checks, repairs or auto-updates.
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import process from 'node:process';
|
|
7
|
+
import { spawnSync } from 'node:child_process';
|
|
8
|
+
import { home, linuxServiceFile, linuxServiceLauncherFile } from './env.mjs';
|
|
9
|
+
import { resolvedCliScript, shellQuote } from './service-paths.mjs';
|
|
10
|
+
|
|
11
|
+
export const linuxSystemServiceFile = '/etc/systemd/system/remcp-agent.service';
|
|
12
|
+
|
|
13
|
+
export function isManagedLinuxSystemUnit(text, launcher = linuxServiceLauncherFile) {
|
|
14
|
+
if (typeof text !== 'string') return false;
|
|
15
|
+
const expected = new Set([
|
|
16
|
+
'ExecStart="' + launcher.replaceAll('\\', '\\\\').replaceAll('"', '\\"') + '" start --service',
|
|
17
|
+
'ExecStart=' + launcher + ' start --service',
|
|
18
|
+
]);
|
|
19
|
+
return text.split(/\r?\n/).some(line => expected.has(line.trim()));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function linuxSystemAgentOwned() {
|
|
23
|
+
if (process.platform !== 'linux' || process.getuid?.() !== 0) return false;
|
|
24
|
+
try {
|
|
25
|
+
return isManagedLinuxSystemUnit(fs.readFileSync(linuxSystemServiceFile, 'utf8'));
|
|
26
|
+
} catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function linuxServiceScope() {
|
|
32
|
+
return linuxSystemAgentOwned() ? 'system' : 'user';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function linuxActiveServiceFile() {
|
|
36
|
+
return linuxServiceScope() === 'system' ? linuxSystemServiceFile : linuxServiceFile;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Without linger, logind terminates user@UID.service at the final logout,
|
|
40
|
+
// even if systemctl --user enable --now reported success.
|
|
41
|
+
export function ensureLinuxLinger() {
|
|
42
|
+
if (process.platform !== 'linux') return;
|
|
43
|
+
// Tests isolate HOME in a temporary fixture. Never mutate the real host's loginctl
|
|
44
|
+
// configuration on behalf of that synthetic service installation.
|
|
45
|
+
if (path.resolve(home) !== path.resolve(os.userInfo().homedir)) {
|
|
46
|
+
if (process.env.NODE_ENV === 'test') return;
|
|
47
|
+
throw new Error('Refusing a persistent Linux service with HOME different from the account home directory.');
|
|
48
|
+
}
|
|
49
|
+
const username = os.userInfo().username;
|
|
50
|
+
const query = () => spawnSync('loginctl', ['show-user', username, '-p', 'Linger', '--value'],
|
|
51
|
+
{ encoding:'utf8', timeout:10000 });
|
|
52
|
+
let state = query();
|
|
53
|
+
if (state.status === 0 && state.stdout.trim() === 'yes') return;
|
|
54
|
+
const enabled = spawnSync('loginctl', ['enable-linger', username],
|
|
55
|
+
{ encoding:'utf8', timeout:10000 });
|
|
56
|
+
if (enabled.status !== 0) {
|
|
57
|
+
throw new Error('ReMCP cannot guarantee background operation after logout: '
|
|
58
|
+
+ 'loginctl enable-linger failed. Ask an administrator to enable lingering for this account.');
|
|
59
|
+
}
|
|
60
|
+
state = query();
|
|
61
|
+
if (state.status !== 0 || state.stdout.trim() !== 'yes') {
|
|
62
|
+
throw new Error('ReMCP cannot verify systemd lingering; refusing to claim persistent installation.');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// The vetted bootstrap may install npm under ~/.local/share/remcp/npm and Node
|
|
67
|
+
// under ~/.local/share/remcp/bootstrap; neither bin is necessarily on login PATH.
|
|
68
|
+
export function linuxCliShimText(cliPath, nodePath) {
|
|
69
|
+
const entry = resolvedCliScript(cliPath);
|
|
70
|
+
const suffix = path.join('lib', 'node_modules', '@remcp', 'remcp', 'bin', 'remcp.mjs');
|
|
71
|
+
const prefix = entry.endsWith(path.sep + suffix)
|
|
72
|
+
? entry.slice(0, -(suffix.length + 1)) : path.dirname(path.dirname(cliPath));
|
|
73
|
+
return '#!/bin/sh\n# ReMCP managed CLI shim\nNPM_CONFIG_PREFIX=' + shellQuote(prefix)
|
|
74
|
+
+ '\nexport NPM_CONFIG_PREFIX\nPATH=' + shellQuote(path.dirname(nodePath)) + ':$PATH'
|
|
75
|
+
+ '\nexport PATH\nexec ' + shellQuote(nodePath) + ' ' + shellQuote(entry) + ' "$@"\n';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function ensureLinuxCliCommand(cliPath, nodePath) {
|
|
79
|
+
if (process.platform !== 'linux') return;
|
|
80
|
+
const destination = process.getuid?.() === 0
|
|
81
|
+
? '/usr/local/bin/remcp' : path.join(home, '.local', 'bin', 'remcp');
|
|
82
|
+
fs.mkdirSync(path.dirname(destination), { recursive:true, mode:0o755 });
|
|
83
|
+
const marker = '# ReMCP managed CLI shim';
|
|
84
|
+
if (fs.existsSync(destination)) {
|
|
85
|
+
const current = fs.readFileSync(destination, 'utf8');
|
|
86
|
+
if (!current.includes(marker)) return; // Never overwrite an unrelated executable.
|
|
87
|
+
}
|
|
88
|
+
const content = linuxCliShimText(cliPath, nodePath);
|
|
89
|
+
const temp = destination + '.' + process.pid + '.tmp';
|
|
90
|
+
fs.writeFileSync(temp, content, { mode:0o755 });
|
|
91
|
+
fs.renameSync(temp, destination);
|
|
92
|
+
}
|
package/src/cli/service.mjs
CHANGED
|
@@ -5,6 +5,7 @@ export { persistentServiceExpected, persistentServiceState, releasePairPresentAt
|
|
|
5
5
|
// Installing, repairing and removing the background agent: one supervisor per platform, plus the
|
|
6
6
|
// write-access tweaks a fresh install needs. Service maintenance follows local OS permissions.
|
|
7
7
|
import fs from 'node:fs';
|
|
8
|
+
import os from 'node:os';
|
|
8
9
|
import path from 'node:path';
|
|
9
10
|
import process from 'node:process';
|
|
10
11
|
import { spawnSync } from 'node:child_process';
|
|
@@ -17,6 +18,7 @@ import { PACKAGE_NAME, VERSION } from '../version.mjs';
|
|
|
17
18
|
import { saveConfig } from './config.mjs';
|
|
18
19
|
import { configDir, home, linuxServiceFile, linuxServiceLauncherFile, macServiceFile, macServiceLabel, windowsServiceLauncherFile, windowsStartupScriptFile, windowsTaskName } from './env.mjs';
|
|
19
20
|
import { run } from './shell.mjs';
|
|
21
|
+
import { linuxActiveServiceFile, linuxServiceScope, linuxSystemAgentOwned, linuxSystemServiceFile, ensureLinuxLinger, ensureLinuxCliCommand } from './service-linux.mjs';
|
|
20
22
|
import { windowsServiceLauncherText, windowsTaskAbsenceCommand, windowsStartupScriptText, windowsStartupScriptInstalled } from './windows-supervisor.mjs';
|
|
21
23
|
import { ensureWindowsSupervisorKey, windowsSupervisorCommand } from './windows-user-supervisor.mjs';
|
|
22
24
|
|
|
@@ -62,11 +64,30 @@ function writeLinuxServiceLauncher(cliPath = globalCliPath(), nodePath = process
|
|
|
62
64
|
|
|
63
65
|
export function installLinuxService(cliPath = globalCliPath(), nodePath = process.execPath) {
|
|
64
66
|
const launcherFile = writeLinuxServiceLauncher(cliPath, nodePath);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
// Fresh root installs are boot services owned by PID 1. Legacy per-user units are
|
|
68
|
+
// left under their existing supervisor, but must have linger enabled.
|
|
69
|
+
const privileged = process.getuid?.() === 0 && path.resolve(home) === path.resolve(os.userInfo().homedir);
|
|
70
|
+
if (privileged && fs.existsSync(linuxSystemServiceFile) && !linuxSystemAgentOwned()) {
|
|
71
|
+
throw new Error('Refusing to replace an unmanaged systemd remcp-agent.service');
|
|
72
|
+
}
|
|
73
|
+
const system = privileged && (linuxSystemAgentOwned() || !fs.existsSync(linuxServiceFile));
|
|
74
|
+
if (system) {
|
|
75
|
+
if (fs.existsSync(linuxSystemServiceFile) && !linuxSystemAgentOwned()) {
|
|
76
|
+
throw new Error('Refusing to replace an unmanaged systemd remcp-agent.service');
|
|
77
|
+
}
|
|
78
|
+
const unit = `[Unit]\nDescription=ReMCP headless device agent (system service)\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=simple\nUser=root\nWorkingDirectory=/root\nEnvironment=HOME=/root\nUMask=0077\nExecStart=${quoteSystemd(launcherFile)} start --service\nRestart=always\nRestartSec=5\n\n[Install]\nWantedBy=multi-user.target\n`;
|
|
79
|
+
fs.writeFileSync(linuxSystemServiceFile, unit, { mode:0o644 });
|
|
80
|
+
run('systemctl', ['daemon-reload']);
|
|
81
|
+
run('systemctl', ['enable', '--now', 'remcp-agent.service']);
|
|
82
|
+
} else {
|
|
83
|
+
ensureLinuxLinger();
|
|
84
|
+
const unit = `[Unit]\nDescription=ReMCP device agent\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=simple\nExecStart=${quoteSystemd(launcherFile)} start --service\nRestart=always\nRestartSec=3\n\n[Install]\nWantedBy=default.target\n`;
|
|
85
|
+
fs.mkdirSync(path.dirname(linuxServiceFile), { recursive: true });
|
|
86
|
+
fs.writeFileSync(linuxServiceFile, unit);
|
|
87
|
+
run('systemctl', ['--user', 'daemon-reload']);
|
|
88
|
+
run('systemctl', ['--user', 'enable', '--now', 'remcp-agent.service']);
|
|
89
|
+
}
|
|
90
|
+
ensureLinuxCliCommand(cliPath, nodePath);
|
|
70
91
|
}
|
|
71
92
|
|
|
72
93
|
export function writeWindowsServiceLauncher(cliPath = globalCliPath(), nodePath = process.execPath) {
|
|
@@ -241,11 +262,13 @@ export function ensureServiceIfRecorded(config) {
|
|
|
241
262
|
const platform = servicePlatform();
|
|
242
263
|
let restartScheduled = null;
|
|
243
264
|
if (platform === 'linux') {
|
|
244
|
-
|
|
245
|
-
|
|
265
|
+
const scope = linuxServiceScope();
|
|
266
|
+
if (scope === 'user') ensureLinuxLinger();
|
|
267
|
+
// Read and repair the active unit through one descriptor. Never create a
|
|
268
|
+
// second user agent when a PID-1 system service already owns this pairing.
|
|
246
269
|
let fd = null;
|
|
247
270
|
try {
|
|
248
|
-
fd = fs.openSync(
|
|
271
|
+
fd = fs.openSync(linuxActiveServiceFile(), fs.constants.O_RDWR | (fs.constants.O_NOFOLLOW || 0));
|
|
249
272
|
} catch (error) {
|
|
250
273
|
if (error?.code !== 'ENOENT') throw error;
|
|
251
274
|
}
|
|
@@ -279,7 +302,7 @@ export function ensureServiceIfRecorded(config) {
|
|
|
279
302
|
}
|
|
280
303
|
fs.ftruncateSync(fd, data.length);
|
|
281
304
|
fs.fsyncSync(fd);
|
|
282
|
-
run('systemctl', ['--user', 'daemon-reload']);
|
|
305
|
+
run('systemctl', [...(scope === 'user' ? ['--user'] : []), 'daemon-reload']);
|
|
283
306
|
}
|
|
284
307
|
} finally {
|
|
285
308
|
fs.closeSync(fd);
|
|
@@ -308,24 +331,28 @@ export function ensureServiceIfRecorded(config) {
|
|
|
308
331
|
}
|
|
309
332
|
}
|
|
310
333
|
|
|
311
|
-
export function deferredLinuxAgentRestartArgs(pid) {
|
|
334
|
+
export function deferredLinuxAgentRestartArgs(pid, scope = 'user') {
|
|
312
335
|
if (!Number.isSafeInteger(pid) || pid <= 0) throw new Error('Invalid process identifier');
|
|
313
|
-
|
|
314
|
-
|
|
336
|
+
if (scope !== 'user' && scope !== 'system') throw new Error('Invalid Linux service scope');
|
|
337
|
+
const option = scope === 'user' ? ['--user'] : [];
|
|
338
|
+
return [...option, '--on-active=3s', `--unit=remcp-agent-settings-${pid}`,
|
|
339
|
+
'systemctl', ...option, 'restart', 'remcp-agent.service'];
|
|
315
340
|
}
|
|
316
341
|
|
|
317
342
|
export function restartPersistentServiceIfInstalled(config, { deferLinux = false, deferWindows = false } = {}) {
|
|
318
343
|
if (!persistentServiceExpected(config)) return null;
|
|
319
344
|
const platform = servicePlatform();
|
|
320
|
-
if (platform === 'linux' && fs.existsSync(
|
|
345
|
+
if (platform === 'linux' && fs.existsSync(linuxActiveServiceFile())) {
|
|
346
|
+
const scope = linuxServiceScope();
|
|
347
|
+
const option = scope === 'user' ? ['--user'] : [];
|
|
321
348
|
// Only owner-confirmed remote policy changes defer their restart. Ordinary
|
|
322
349
|
// installs and updates preserve their existing synchronous supervisor contract.
|
|
323
350
|
if (deferLinux) {
|
|
324
|
-
run('systemd-run', deferredLinuxAgentRestartArgs(process.pid));
|
|
351
|
+
run('systemd-run', deferredLinuxAgentRestartArgs(process.pid, scope));
|
|
325
352
|
return 'remcp-agent.service (restart scheduled)';
|
|
326
353
|
}
|
|
327
|
-
run('systemctl', [
|
|
328
|
-
run('systemctl', [
|
|
354
|
+
run('systemctl', [...option, 'daemon-reload']);
|
|
355
|
+
run('systemctl', [...option, 'restart', 'remcp-agent.service']);
|
|
329
356
|
return 'remcp-agent.service';
|
|
330
357
|
}
|
|
331
358
|
if (platform === 'darwin' && fs.existsSync(macServiceFile)) {
|
|
@@ -357,9 +384,11 @@ export function restartPersistentServiceIfInstalled(config, { deferLinux = false
|
|
|
357
384
|
export function uninstallPersistentService() {
|
|
358
385
|
const platform = servicePlatform();
|
|
359
386
|
if (platform === 'linux') {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
spawnSync('systemctl', ['--
|
|
387
|
+
const scope = linuxServiceScope();
|
|
388
|
+
const option = scope === 'user' ? ['--user'] : [];
|
|
389
|
+
spawnSync('systemctl', [...option, 'disable', '--now', 'remcp-agent.service'], { stdio:'inherit' });
|
|
390
|
+
try { fs.unlinkSync(linuxActiveServiceFile()); } catch {}
|
|
391
|
+
spawnSync('systemctl', [...option, 'daemon-reload'], { stdio:'inherit' });
|
|
363
392
|
} else if (platform === 'darwin') {
|
|
364
393
|
const domain = macLaunchDomain();
|
|
365
394
|
spawnSync('launchctl', ['bootout', domain, macServiceFile], { stdio: 'ignore' });
|
package/src/cli/update.mjs
CHANGED
|
@@ -12,6 +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 { linuxSystemAgentOwned } from './service-linux.mjs';
|
|
15
16
|
import { assertWindowsUpdateLifecycleSafe, currentInstallationInfo, ensureMacCliCommand, ensureServiceIfRecorded, npmGlobalUpdate, persistentServiceExpected, rememberCurrentInstallation, restartPersistentServiceIfInstalled, servicePlatform, serviceInstallationInfo, syncKnownInstallations } from './service.mjs';
|
|
16
17
|
|
|
17
18
|
const UPDATE_DISCOVERY_TIMEOUT_MS = 5000;
|
|
@@ -235,7 +236,7 @@ export async function updateCommand(flags) {
|
|
|
235
236
|
updateSource: targets.source,
|
|
236
237
|
installable: targets.installable,
|
|
237
238
|
upToDate: alreadyCurrent,
|
|
238
|
-
managedService: fs.existsSync(linuxServiceFile) || fs.existsSync(macServiceFile),
|
|
239
|
+
managedService: linuxSystemAgentOwned() || fs.existsSync(linuxServiceFile) || fs.existsSync(macServiceFile),
|
|
239
240
|
supervisor: supervisorRestart() ?? 'none',
|
|
240
241
|
}, null, 2));
|
|
241
242
|
return;
|