/** * @file autostart.js * @description Settings → System's "Start automatically" switch: whether the * dashboard starts at boot/login through the per-user service * (`scripts/service-manager.js` — a systemd `--user` unit, or a LaunchAgent on * macOS). The switch IS the unit's enabled state, nothing stored beside it. * Turning it on writes a unit for THIS server when none exists, and enables * it; turning it off disables it. Neither ever starts or stops anything — the * server answering the click is the one that would die. Off by default: the * plugin bootstrap installs no unit until the user opts in. * @author Nguyễn Ngọc Trí Vĩ */ const fs = require("fs"); const path = require("path"); const svc = require("../../scripts/service-manager"); const NAME = "agenthub"; const ROOT = path.resolve(__dirname, "..", ".."); /** A unit by our name that AgentHub did not write — never ours to touch. */ function isForeign() { return fs.existsSync(svc.unitPath(NAME)) && !svc.unitIsOurs(NAME); } function status() { const available = svc.systemctlAvailable(); return { available, kind: svc.kind, enabled: available && svc.unitIsEnabled(NAME), foreign: isForeign(), }; } /** The unit for the running server — same shape the bootstrap writes. */ function unitForThisServer() { const entry = path.join(ROOT, "server", "index.js"); const env = { NODE_ENV: "production", PATH: process.env.PATH || "" }; for (const key of ["NODE_PATH", "DASHBOARD_CLIENT_DIST", "DASHBOARD_PORT"]) { if (process.env[key]) env[key] = process.env[key]; } return { name: NAME, description: "AgentHub dashboard server", workingDir: ROOT, execStart: `${process.execPath} ${entry}`, argv: [process.execPath, entry], env, }; } function fail(code, message) { return Object.assign(new Error(message), { code }); } function setEnabled(on) { if (!svc.systemctlAvailable()) { throw fail("EUNAVAILABLE", `no ${svc.label} manager is available on this machine`); } let result; if (svc.unitIsOurs(NAME)) result = svc.setUnitEnabled(NAME, on); else if (isForeign()) result = "foreign"; else if (!on) result = "ok"; // nothing installed: already off else { result = svc.writeUserService(unitForThisServer()); // writes + enables, starts nothing if (result === "written") svc.enableLinger(); } if (result === "foreign") { throw fail("EFOREIGN", `${svc.unitPath(NAME)} was not written by AgentHub — not touching it`); } if (result === "failed" || result === "unavailable") { throw fail("ESERVICE", `could not change the ${svc.label}`); } return status(); } module.exports = { status, setEnabled };