fix: restart via systemd on linux

This commit is contained in:
Peter Steinberger
2026-01-01 17:48:17 +01:00
parent f0f5acfa42
commit dc8f2bda2a
3 changed files with 25 additions and 13 deletions

View File

@@ -23,6 +23,7 @@
- macOS packaging: move rpath config into swift build for reliability (#69) — thanks @petter-b
- macOS: prioritize main bundle for device resources to prevent crash (#73) — thanks @petter-b
- Chat UI: clear composer input immediately and allow clear while editing to prevent duplicate sends (#72) — thanks @hrdwdmrbl
- Restart: use systemd on Linux (and report actual restart method) instead of always launchctl.
- Docs: add manual OAuth setup for remote/headless deployments (#67) — thanks @wstock
- Docs/agent tools: clarify that browser `wait` should be avoided by default and used only in exceptional cases.
- Browser tools: `upload` supports auto-click refs, direct `inputRef`/`element` file inputs, and emits input/change after `setFiles` so JS-heavy sites pick up attachments.

View File

@@ -886,10 +886,10 @@ export async function getReplyFromConfig(
cleanupTyping();
return undefined;
}
triggerClawdisRestart();
const restartMethod = triggerClawdisRestart();
cleanupTyping();
return {
text: "⚙️ Restarting clawdis via launchctl; give me a few seconds to come back online.",
text: `⚙️ Restarting clawdis via ${restartMethod}; give me a few seconds to come back online.`,
};
}

View File

@@ -1,22 +1,33 @@
import { spawn } from "node:child_process";
import { spawnSync } from "node:child_process";
const DEFAULT_LAUNCHD_LABEL = "com.steipete.clawdis";
const DEFAULT_SYSTEMD_UNIT = "clawdis-gateway.service";
export function triggerClawdisRestart(): void {
export function triggerClawdisRestart(): "launchctl" | "systemd" | "supervisor" {
if (process.platform !== "darwin") {
return;
if (process.platform === "linux") {
const unit = process.env.CLAWDIS_SYSTEMD_UNIT || DEFAULT_SYSTEMD_UNIT;
const userRestart = spawnSync("systemctl", ["--user", "restart", unit], {
stdio: "ignore",
});
if (!userRestart.error && userRestart.status === 0) {
return "systemd";
}
const systemRestart = spawnSync("systemctl", ["restart", unit], {
stdio: "ignore",
});
if (!systemRestart.error && systemRestart.status === 0) {
return "systemd";
}
return "systemd";
}
return "supervisor";
}
const label = process.env.CLAWDIS_LAUNCHD_LABEL || DEFAULT_LAUNCHD_LABEL;
const uid =
typeof process.getuid === "function" ? process.getuid() : undefined;
const target = uid !== undefined ? `gui/${uid}/${label}` : label;
const child = spawn("launchctl", ["kickstart", "-k", target], {
detached: true,
stdio: "ignore",
});
child.on("error", () => {
// Best-effort restart; ignore failures (e.g. missing launchctl, invalid label).
});
child.unref();
spawnSync("launchctl", ["kickstart", "-k", target], { stdio: "ignore" });
return "launchctl";
}