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,58 @@
|
||||
/**
|
||||
* @file AutostartSettings — Settings → About's "Start automatically" switch:
|
||||
* whether the dashboard starts at boot/login through the per-user service
|
||||
* (systemd `--user` unit, or a LaunchAgent on macOS), over
|
||||
* `GET/PUT /api/settings/autostart`. Off by default; a change never starts or
|
||||
* stops the running server.
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { api, type AutostartStatus } from "../../lib/api";
|
||||
import { toast } from "../../lib/toast";
|
||||
import { SettingsSection, SettingsSwitchRow } from "./SettingsRow";
|
||||
|
||||
export function AutostartSettings() {
|
||||
const { t } = useTranslation("settings");
|
||||
const [status, setStatus] = useState<AutostartStatus | null>(null);
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
api.settings.autostart
|
||||
.get()
|
||||
.then(setStatus)
|
||||
.catch(() => {});
|
||||
}, []);
|
||||
|
||||
const change = async (enabled: boolean) => {
|
||||
setSaving(true);
|
||||
try {
|
||||
setStatus(await api.settings.autostart.set(enabled));
|
||||
} catch (err) {
|
||||
toast.error(err instanceof Error ? err.message : String(err));
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
const note = !status
|
||||
? undefined
|
||||
: !status.available
|
||||
? t("autostart.unavailable")
|
||||
: status.foreign
|
||||
? t("autostart.foreign")
|
||||
: t(`autostart.desc_${status.kind}`);
|
||||
|
||||
return (
|
||||
<SettingsSection id="autostart" title={t("autostart.title")}>
|
||||
<SettingsSwitchRow
|
||||
label={t("autostart.label")}
|
||||
description={note}
|
||||
checked={!!status?.enabled}
|
||||
disabled={!status?.available || status.foreign || saving}
|
||||
onChange={(v) => void change(v)}
|
||||
/>
|
||||
</SettingsSection>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user