remotelink 0.4.1 → 0.4.3
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/dist/index.js +100 -61
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __remoteArcCreateRequire } from "node:module"; const require = __remoteArcCreateRequire(import.meta.url);
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -5275,8 +5276,10 @@ var CONFIG_DIR = path5.join(os3.homedir(), ".remotearc");
|
|
|
5275
5276
|
var AGENT_DIR = path5.join(CONFIG_DIR, "agent");
|
|
5276
5277
|
var LOG_DIR = path5.join(CONFIG_DIR, "logs");
|
|
5277
5278
|
var AGENT_BUNDLE = path5.join(AGENT_DIR, "remotelink.mjs");
|
|
5279
|
+
var AGENT_VERSION_FILE = path5.join(AGENT_DIR, "version");
|
|
5278
5280
|
var MAC_LABEL = "app.remotearc.agent";
|
|
5279
|
-
var
|
|
5281
|
+
var WINDOWS_RUN_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
|
|
5282
|
+
var WINDOWS_RUN_VALUE = "Remote Arc Agent";
|
|
5280
5283
|
var LINUX_UNIT = "remotearc-agent.service";
|
|
5281
5284
|
async function run2(command, args, options = {}) {
|
|
5282
5285
|
return new Promise((resolve, reject) => {
|
|
@@ -5319,7 +5322,7 @@ function xmlEscape(value) {
|
|
|
5319
5322
|
function psQuote(value) {
|
|
5320
5323
|
return "'" + value.replaceAll("'", "''") + "'";
|
|
5321
5324
|
}
|
|
5322
|
-
async function ensureBundle(sourcePath) {
|
|
5325
|
+
async function ensureBundle(sourcePath, version) {
|
|
5323
5326
|
await fs5.mkdir(AGENT_DIR, { recursive: true });
|
|
5324
5327
|
await fs5.mkdir(LOG_DIR, { recursive: true });
|
|
5325
5328
|
if (path5.resolve(sourcePath) !== path5.resolve(AGENT_BUNDLE)) {
|
|
@@ -5328,6 +5331,12 @@ async function ensureBundle(sourcePath) {
|
|
|
5328
5331
|
await fs5.chmod(AGENT_BUNDLE, 448).catch(() => void 0);
|
|
5329
5332
|
}
|
|
5330
5333
|
}
|
|
5334
|
+
if (version) {
|
|
5335
|
+
await fs5.writeFile(AGENT_VERSION_FILE, version + "\n", { mode: 384 });
|
|
5336
|
+
}
|
|
5337
|
+
}
|
|
5338
|
+
async function backgroundBundleVersion() {
|
|
5339
|
+
return fs5.readFile(AGENT_VERSION_FILE, "utf8").then((value) => value.trim() || null).catch(() => null);
|
|
5331
5340
|
}
|
|
5332
5341
|
function macPlistPath() {
|
|
5333
5342
|
return path5.join(os3.homedir(), "Library", "LaunchAgents", MAC_LABEL + ".plist");
|
|
@@ -5335,8 +5344,8 @@ function macPlistPath() {
|
|
|
5335
5344
|
function linuxUnitPath() {
|
|
5336
5345
|
return path5.join(os3.homedir(), ".config", "systemd", "user", LINUX_UNIT);
|
|
5337
5346
|
}
|
|
5338
|
-
async function enableMac(sourcePath, preserveCurrent) {
|
|
5339
|
-
await ensureBundle(sourcePath);
|
|
5347
|
+
async function enableMac(sourcePath, preserveCurrent, version) {
|
|
5348
|
+
await ensureBundle(sourcePath, version);
|
|
5340
5349
|
const plistPath = macPlistPath();
|
|
5341
5350
|
await fs5.mkdir(path5.dirname(plistPath), { recursive: true });
|
|
5342
5351
|
const stdoutPath = path5.join(LOG_DIR, "agent.log");
|
|
@@ -5358,6 +5367,11 @@ async function enableMac(sourcePath, preserveCurrent) {
|
|
|
5358
5367
|
<key>SuccessfulExit</key><false/>
|
|
5359
5368
|
</dict>
|
|
5360
5369
|
<key>ProcessType</key><string>Background</string>
|
|
5370
|
+
<key>EnvironmentVariables</key>
|
|
5371
|
+
<dict>
|
|
5372
|
+
<key>PATH</key><string>${xmlEscape(process.env.PATH || "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin")}</string>
|
|
5373
|
+
<key>HOME</key><string>${xmlEscape(os3.homedir())}</string>
|
|
5374
|
+
</dict>
|
|
5361
5375
|
<key>ThrottleInterval</key><integer>5</integer>
|
|
5362
5376
|
<key>StandardOutPath</key><string>${xmlEscape(stdoutPath)}</string>
|
|
5363
5377
|
<key>StandardErrorPath</key><string>${xmlEscape(stderrPath)}</string>
|
|
@@ -5402,21 +5416,23 @@ async function disableMac(stopCurrent) {
|
|
|
5402
5416
|
async function statusMac() {
|
|
5403
5417
|
const plistPath = macPlistPath();
|
|
5404
5418
|
const enabled = await fs5.access(plistPath).then(() => true).catch(() => false);
|
|
5405
|
-
const domain =
|
|
5406
|
-
const result = await run2(
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
);
|
|
5419
|
+
const domain = "gui/" + (process.getuid?.() ?? os3.userInfo().uid);
|
|
5420
|
+
const result = await run2("launchctl", ["print", domain + "/" + MAC_LABEL], { ignoreFailure: true });
|
|
5421
|
+
const pidMatch = result.stdout.match(/\\bpid = (\\d+)/);
|
|
5422
|
+
const pid = pidMatch ? Number(pidMatch[1]) : null;
|
|
5423
|
+
const active = result.code === 0 && pid !== null && /\\bstate = running\\b/i.test(result.stdout);
|
|
5411
5424
|
return {
|
|
5412
5425
|
supported: true,
|
|
5413
5426
|
enabled,
|
|
5414
|
-
active
|
|
5415
|
-
service: "launchd"
|
|
5427
|
+
active,
|
|
5428
|
+
service: "launchd",
|
|
5429
|
+
pid,
|
|
5430
|
+
version: await backgroundBundleVersion(),
|
|
5431
|
+
detail: enabled && !active ? "Background connection is configured but the launchd agent is not currently running." : void 0
|
|
5416
5432
|
};
|
|
5417
5433
|
}
|
|
5418
|
-
async function enableLinux(sourcePath, preserveCurrent) {
|
|
5419
|
-
await ensureBundle(sourcePath);
|
|
5434
|
+
async function enableLinux(sourcePath, preserveCurrent, version) {
|
|
5435
|
+
await ensureBundle(sourcePath, version);
|
|
5420
5436
|
const unitPath = linuxUnitPath();
|
|
5421
5437
|
await fs5.mkdir(path5.dirname(unitPath), { recursive: true });
|
|
5422
5438
|
const unit = `[Unit]
|
|
@@ -5457,66 +5473,81 @@ async function disableLinux(stopCurrent) {
|
|
|
5457
5473
|
return backgroundAgentStatus();
|
|
5458
5474
|
}
|
|
5459
5475
|
async function statusLinux() {
|
|
5460
|
-
const enabledResult = await run2(
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
);
|
|
5465
|
-
const activeResult = await run2(
|
|
5466
|
-
"systemctl",
|
|
5467
|
-
["--user", "is-active", LINUX_UNIT],
|
|
5468
|
-
{ ignoreFailure: true }
|
|
5469
|
-
);
|
|
5470
|
-
const supported = enabledResult.stderr.toLowerCase().includes("failed to connect to bus") ? false : true;
|
|
5476
|
+
const enabledResult = await run2("systemctl", ["--user", "is-enabled", LINUX_UNIT], { ignoreFailure: true });
|
|
5477
|
+
const activeResult = await run2("systemctl", ["--user", "is-active", LINUX_UNIT], { ignoreFailure: true });
|
|
5478
|
+
const pidResult = await run2("systemctl", ["--user", "show", LINUX_UNIT, "--property", "MainPID", "--value"], { ignoreFailure: true });
|
|
5479
|
+
const supported = !enabledResult.stderr.toLowerCase().includes("failed to connect to bus");
|
|
5480
|
+
const pidValue = Number(pidResult.stdout.trim());
|
|
5471
5481
|
return {
|
|
5472
5482
|
supported,
|
|
5473
5483
|
enabled: enabledResult.code === 0,
|
|
5474
|
-
active: activeResult.code === 0,
|
|
5484
|
+
active: activeResult.code === 0 && Number.isFinite(pidValue) && pidValue > 0,
|
|
5475
5485
|
service: supported ? "systemd-user" : "unsupported",
|
|
5486
|
+
pid: Number.isFinite(pidValue) && pidValue > 0 ? pidValue : null,
|
|
5487
|
+
version: await backgroundBundleVersion(),
|
|
5476
5488
|
detail: supported ? void 0 : "systemd user services are unavailable"
|
|
5477
5489
|
};
|
|
5478
5490
|
}
|
|
5479
5491
|
async function powershell(script, ignoreFailure = false) {
|
|
5492
|
+
const utf8Script = "$OutputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new(); " + script;
|
|
5480
5493
|
return run2(
|
|
5481
5494
|
"powershell.exe",
|
|
5482
|
-
["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command",
|
|
5495
|
+
["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", utf8Script],
|
|
5483
5496
|
{ ignoreFailure }
|
|
5484
5497
|
);
|
|
5485
5498
|
}
|
|
5486
|
-
async function
|
|
5487
|
-
|
|
5488
|
-
const
|
|
5489
|
-
const
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
await
|
|
5499
|
+
async function windowsAgentPid() {
|
|
5500
|
+
const escapedBundle = AGENT_BUNDLE.replaceAll("'", "''");
|
|
5501
|
+
const script = "$p = Get-CimInstance Win32_Process | Where-Object { $_.Name -ieq 'node.exe' -and $_.CommandLine -like '*" + escapedBundle + "*' -and $_.CommandLine -like '*--agent*' } | Select-Object -First 1 -ExpandProperty ProcessId; if ($null -ne $p) { Write-Output $p }";
|
|
5502
|
+
const result = await powershell(script, true);
|
|
5503
|
+
const pid = Number(result.stdout.trim());
|
|
5504
|
+
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
5505
|
+
}
|
|
5506
|
+
async function enableWindows(sourcePath, preserveCurrent, version) {
|
|
5507
|
+
await ensureBundle(sourcePath, version);
|
|
5508
|
+
const command = '"' + process.execPath + '" "' + AGENT_BUNDLE + '" --agent';
|
|
5509
|
+
await run2("reg.exe", [
|
|
5510
|
+
"add",
|
|
5511
|
+
WINDOWS_RUN_KEY,
|
|
5512
|
+
"/v",
|
|
5513
|
+
WINDOWS_RUN_VALUE,
|
|
5514
|
+
"/t",
|
|
5515
|
+
"REG_SZ",
|
|
5516
|
+
"/d",
|
|
5517
|
+
command,
|
|
5518
|
+
"/f"
|
|
5519
|
+
]);
|
|
5520
|
+
if (!preserveCurrent && !await windowsAgentPid()) {
|
|
5521
|
+
const stdoutPath = path5.join(LOG_DIR, "agent.log");
|
|
5522
|
+
const stderrPath = path5.join(LOG_DIR, "agent-error.log");
|
|
5523
|
+
await powershell(
|
|
5524
|
+
"Start-Process -FilePath " + psQuote(process.execPath) + " -ArgumentList @(" + psQuote(AGENT_BUNDLE) + ", '--agent') -WindowStyle Hidden -RedirectStandardOutput " + psQuote(stdoutPath) + " -RedirectStandardError " + psQuote(stderrPath) + " | Out-Null"
|
|
5525
|
+
);
|
|
5526
|
+
await new Promise((resolve) => setTimeout(resolve, 350));
|
|
5527
|
+
}
|
|
5497
5528
|
return backgroundAgentStatus();
|
|
5498
5529
|
}
|
|
5499
5530
|
async function disableWindows(stopCurrent) {
|
|
5500
|
-
|
|
5531
|
+
await run2("reg.exe", ["delete", WINDOWS_RUN_KEY, "/v", WINDOWS_RUN_VALUE, "/f"], { ignoreFailure: true });
|
|
5501
5532
|
if (stopCurrent) {
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5533
|
+
const pid = await windowsAgentPid();
|
|
5534
|
+
if (pid) {
|
|
5535
|
+
await powershell("Stop-Process -Id " + pid + " -Force -ErrorAction SilentlyContinue", true);
|
|
5536
|
+
}
|
|
5505
5537
|
}
|
|
5506
|
-
commands.push(
|
|
5507
|
-
`Unregister-ScheduledTask -TaskName ${psQuote(WINDOWS_TASK)} -Confirm:$false -ErrorAction SilentlyContinue`
|
|
5508
|
-
);
|
|
5509
|
-
await powershell(commands.join("; "), true);
|
|
5510
5538
|
return backgroundAgentStatus();
|
|
5511
5539
|
}
|
|
5512
5540
|
async function statusWindows() {
|
|
5513
|
-
const
|
|
5514
|
-
const
|
|
5541
|
+
const enabledResult = await run2("reg.exe", ["query", WINDOWS_RUN_KEY, "/v", WINDOWS_RUN_VALUE], { ignoreFailure: true });
|
|
5542
|
+
const pid = await windowsAgentPid();
|
|
5515
5543
|
return {
|
|
5516
5544
|
supported: true,
|
|
5517
|
-
enabled:
|
|
5518
|
-
active:
|
|
5519
|
-
service: "
|
|
5545
|
+
enabled: enabledResult.code === 0,
|
|
5546
|
+
active: pid !== null,
|
|
5547
|
+
service: "registry-run",
|
|
5548
|
+
pid,
|
|
5549
|
+
version: await backgroundBundleVersion(),
|
|
5550
|
+
detail: enabledResult.code === 0 && pid === null ? "Background connection is configured but the user-level agent is not currently running." : void 0
|
|
5520
5551
|
};
|
|
5521
5552
|
}
|
|
5522
5553
|
async function backgroundAgentStatus() {
|
|
@@ -5533,9 +5564,9 @@ async function backgroundAgentStatus() {
|
|
|
5533
5564
|
}
|
|
5534
5565
|
async function enableBackgroundAgent(sourcePath, options = {}) {
|
|
5535
5566
|
const preserveCurrent = options.preserveCurrent ?? false;
|
|
5536
|
-
if (process.platform === "darwin") return enableMac(sourcePath, preserveCurrent);
|
|
5537
|
-
if (process.platform === "win32") return enableWindows(sourcePath, preserveCurrent);
|
|
5538
|
-
if (process.platform === "linux") return enableLinux(sourcePath, preserveCurrent);
|
|
5567
|
+
if (process.platform === "darwin") return enableMac(sourcePath, preserveCurrent, options.version);
|
|
5568
|
+
if (process.platform === "win32") return enableWindows(sourcePath, preserveCurrent, options.version);
|
|
5569
|
+
if (process.platform === "linux") return enableLinux(sourcePath, preserveCurrent, options.version);
|
|
5539
5570
|
return backgroundAgentStatus();
|
|
5540
5571
|
}
|
|
5541
5572
|
async function disableBackgroundAgent(options = {}) {
|
|
@@ -5547,7 +5578,7 @@ async function disableBackgroundAgent(options = {}) {
|
|
|
5547
5578
|
}
|
|
5548
5579
|
|
|
5549
5580
|
// src/index.ts
|
|
5550
|
-
var VERSION = "0.4.
|
|
5581
|
+
var VERSION = "0.4.3";
|
|
5551
5582
|
var DEFAULT_ORIGIN = "https://mcp.remotearc.app";
|
|
5552
5583
|
var CONFIG_DIR2 = path6.join(os4.homedir(), ".remotearc");
|
|
5553
5584
|
var CONFIG_PATH = path6.join(CONFIG_DIR2, "config.json");
|
|
@@ -5883,7 +5914,10 @@ async function connectAgent(config) {
|
|
|
5883
5914
|
platform: process3.platform,
|
|
5884
5915
|
arch: process3.arch,
|
|
5885
5916
|
hostname: os4.hostname(),
|
|
5886
|
-
agentVersion: VERSION
|
|
5917
|
+
agentVersion: VERSION,
|
|
5918
|
+
pid: process3.pid,
|
|
5919
|
+
backgroundProcess: argFlag("--agent"),
|
|
5920
|
+
connectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5887
5921
|
},
|
|
5888
5922
|
tools: [...tools.map((tool) => tool.name), ...internalTools],
|
|
5889
5923
|
capabilities: [
|
|
@@ -5981,19 +6015,24 @@ async function connectAgent(config) {
|
|
|
5981
6015
|
await writeConfig(config);
|
|
5982
6016
|
if (enabled) {
|
|
5983
6017
|
const current = await backgroundAgentStatus();
|
|
5984
|
-
result = current.enabled ? { ...current, desired_enabled: true } : {
|
|
6018
|
+
result = current.enabled && current.active ? { ...current, desired_enabled: true } : {
|
|
5985
6019
|
...await enableBackgroundAgent(SELF_PATH, {
|
|
5986
|
-
preserveCurrent: argFlag("--agent")
|
|
6020
|
+
preserveCurrent: argFlag("--agent"),
|
|
6021
|
+
version: VERSION
|
|
5987
6022
|
}),
|
|
5988
6023
|
desired_enabled: true
|
|
5989
6024
|
};
|
|
5990
6025
|
exitAfterResponse = !argFlag("--agent");
|
|
5991
6026
|
} else {
|
|
6027
|
+
const stopCurrent = message.arguments?.stop_current === true;
|
|
6028
|
+
const runningAsBackgroundAgent = argFlag("--agent");
|
|
5992
6029
|
result = {
|
|
5993
|
-
...await disableBackgroundAgent({
|
|
6030
|
+
...await disableBackgroundAgent({
|
|
6031
|
+
stopCurrent: stopCurrent && !runningAsBackgroundAgent
|
|
6032
|
+
}),
|
|
5994
6033
|
desired_enabled: false
|
|
5995
6034
|
};
|
|
5996
|
-
exitAfterResponse =
|
|
6035
|
+
exitAfterResponse = stopCurrent && runningAsBackgroundAgent;
|
|
5997
6036
|
}
|
|
5998
6037
|
} else {
|
|
5999
6038
|
result = await core.call(
|
|
@@ -6140,7 +6179,7 @@ async function main() {
|
|
|
6140
6179
|
}
|
|
6141
6180
|
if (!foregroundMode && config.backgroundEnabled === true) {
|
|
6142
6181
|
try {
|
|
6143
|
-
const status = await enableBackgroundAgent(SELF_PATH);
|
|
6182
|
+
const status = await enableBackgroundAgent(SELF_PATH, { version: VERSION });
|
|
6144
6183
|
if (status.supported && status.enabled) {
|
|
6145
6184
|
banner();
|
|
6146
6185
|
logLine("success", "Background connection enabled.");
|