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:
2026-10-06 18:53:10 +07:00
parent 4aae61297f
commit 03ecc9e29a
25 changed files with 620 additions and 36 deletions
+22
View File
@@ -1114,6 +1114,18 @@ export const api = {
/** DELETE /api/settings/codex-hooks — AgentHub's own hooks only */
remove: () => request<CodexHooksStatus>("/settings/codex-hooks", { method: "DELETE" }),
},
/** Start the dashboard at boot/login (systemd `--user` / LaunchAgent) — off
* by default; a change never starts or stops the running server. */
autostart: {
/** GET /api/settings/autostart */
get: () => request<AutostartStatus>("/settings/autostart"),
/** PUT /api/settings/autostart */
set: (enabled: boolean) =>
request<AutostartStatus>("/settings/autostart", {
method: "PUT",
body: JSON.stringify({ enabled }),
}),
},
/** Opt-in secret redaction of stored payloads and the folders whose hooks
* are dropped (`server/lib/privacy.js`). */
privacy: {
@@ -4334,6 +4346,16 @@ export interface RemoteSourceInput {
enabled?: boolean;
}
/** GET /api/settings/autostart. `available` false: no systemd `--user` /
* launchd GUI session here; `foreign`: a unit named agenthub AgentHub did not
* write, which it never touches. */
export interface AutostartStatus {
available: boolean;
kind: "systemd" | "launchd";
enabled: boolean;
foreign: boolean;
}
/** GET /api/settings/privacy. A field the environment set is `env_owned`
* and cannot be saved from the dashboard. */
export interface PrivacySettings {
+6
View File
@@ -104,6 +104,12 @@ export const SETTINGS_INDEX: {
titleKey: "about.title",
keywords: ["version", "server", "database", "uptime"],
},
{
section: "about",
titleKey: "autostart.label",
keywords: ["autostart", "boot", "login", "systemd", "launchd", "service"],
to: "#autostart",
},
{
section: "appearance",
titleKey: "sagi.title",