feat: start-at-login is a Settings switch, off by default (v2.5.0)
- Settings → About → "Start AgentHub automatically" (AutostartSettings.tsx,
GET/PUT /api/settings/autostart, server/lib/autostart.js). The switch is
the systemd --user unit's / LaunchAgent's enabled state: on writes a unit
for the running server when none exists and enables it, off disables it;
neither starts or stops the server. A foreign unit is never touched
(409 EFOREIGN)
- The plugin bootstrap no longer installs a unit on every install: it
installs or starts one only while the user has it enabled, and a rewrite
keeps the enabled state (writeUserService({ enable })). An install that
already had the unit enabled stays on. A stale-but-enabled unit beside a
live detached server is repointed, no longer started onto the bound port
- unitIsEnabled / setUnitEnabled in systemd-service.js and launchd-service.js
Also:
- fix(workspace): status bar no longer covers the chat box below md (#61)
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file autostart.js
|
||||
* @description Settings → About'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ĩ <vinnt@smartgift.vn>
|
||||
*/
|
||||
|
||||
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 };
|
||||
Reference in New Issue
Block a user