diff --git a/scripts/proxy/install.js b/scripts/proxy/install.js index db44eb9..f740986 100644 --- a/scripts/proxy/install.js +++ b/scripts/proxy/install.js @@ -94,6 +94,7 @@ function askSecret(question) { } async function askConfirm(question, defaultYes = true) { + if (FLAGS.dryRun) { console.log(`(dry-run) would ask: ${question} -> default ${defaultYes ? 'y' : 'n'}`); return defaultYes; } if (FLAGS.nonInteractive) return defaultYes; const a = (await ask(`${question} (y/n)`, defaultYes ? 'y' : 'n')).toLowerCase(); return a === 'y'; @@ -399,7 +400,30 @@ function sectionUnit() { const S = 'systemd service'; if (FLAGS.noSystemd) { report(S, 'SKIPPED', '--no-systemd'); return true; } const unitPath = path.join(SYSTEMD_USER_DIR, 'proxy-bridge.service'); - const nodeBin = process.execPath; + // The service must not run on an agent-bundled runtime: prefer (1) the node + // already pinned in an existing unit (stable, known-good), (2) the newest + // nvm-installed node, (3) PATH lookup that does NOT resolve into the hermes + // agent dir, (4) process.execPath as a last resort. + let nodeBin = null; + try { + const existing = fs.readFileSync(unitPath, 'utf8'); + const m = existing.match(/^ExecStart=(\S+)\s+/m); + if (m && fs.existsSync(m[1])) nodeBin = m[1]; + } catch {} + if (!nodeBin) { + const nvmRoot = path.join(os.homedir(), '.nvm', 'versions', 'node'); + try { + const versions = fs.readdirSync(nvmRoot).filter(v => /^v\d+/.test(v)).sort((a, b) => + a.localeCompare(b, undefined, { numeric: true })); + if (versions.length > 0) nodeBin = path.join(nvmRoot, versions[versions.length - 1], 'bin', 'node'); + } catch {} + } + if (!nodeBin) { + const loginNode = run('bash', ['--noprofile', '--norc', '-c', 'command -v node'], { readOnly: true }); + const cand = loginNode.status === 0 ? loginNode.stdout.trim() : ''; + if (cand && !fs.realpathSync(cand).includes('/.hermes/')) nodeBin = cand; + } + if (!nodeBin) nodeBin = process.execPath; const want = `[Unit]\nDescription=Local Proxy Bridge (Keyring Auth)\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=${nodeBin} ${BRIDGE_DIR}/bridge.js\nRestart=on-failure\nRestartSec=5\n\n[Install]\nWantedBy=default.target\n`; let current = null; try { current = fs.readFileSync(unitPath, 'utf8'); } catch {}