openclaw-matrix-multiaccounts/src/commands/onboard-non-interactive/local/daemon-install.ts
2026-01-14 01:17:56 +00:00

87 lines
2.8 KiB
TypeScript

import path from "node:path";
import type { ClawdbotConfig } from "../../../config/config.js";
import { resolveGatewayLaunchAgentLabel } from "../../../daemon/constants.js";
import { resolveGatewayProgramArguments } from "../../../daemon/program-args.js";
import {
renderSystemNodeWarning,
resolvePreferredNodePath,
resolveSystemNodeInfo,
} from "../../../daemon/runtime-paths.js";
import { resolveGatewayService } from "../../../daemon/service.js";
import { buildServiceEnvironment } from "../../../daemon/service-env.js";
import { isSystemdUserServiceAvailable } from "../../../daemon/systemd.js";
import type { RuntimeEnv } from "../../../runtime.js";
import {
DEFAULT_GATEWAY_DAEMON_RUNTIME,
isGatewayDaemonRuntime,
} from "../../daemon-runtime.js";
import type { OnboardOptions } from "../../onboard-types.js";
import { ensureSystemdUserLingerNonInteractive } from "../../systemd-linger.js";
export async function installGatewayDaemonNonInteractive(params: {
nextConfig: ClawdbotConfig;
opts: OnboardOptions;
runtime: RuntimeEnv;
port: number;
gatewayToken?: string;
}) {
const { opts, runtime, port, gatewayToken } = params;
if (!opts.installDaemon) return;
const daemonRuntimeRaw = opts.daemonRuntime ?? DEFAULT_GATEWAY_DAEMON_RUNTIME;
const systemdAvailable =
process.platform === "linux" ? await isSystemdUserServiceAvailable() : true;
if (process.platform === "linux" && !systemdAvailable) {
runtime.log(
"Systemd user services are unavailable; skipping daemon install.",
);
return;
}
if (!isGatewayDaemonRuntime(daemonRuntimeRaw)) {
runtime.error("Invalid --daemon-runtime (use node or bun)");
runtime.exit(1);
return;
}
const service = resolveGatewayService();
const devMode =
process.argv[1]?.includes(`${path.sep}src${path.sep}`) &&
process.argv[1]?.endsWith(".ts");
const nodePath = await resolvePreferredNodePath({
env: process.env,
runtime: daemonRuntimeRaw,
});
const { programArguments, workingDirectory } =
await resolveGatewayProgramArguments({
port,
dev: devMode,
runtime: daemonRuntimeRaw,
nodePath,
});
if (daemonRuntimeRaw === "node") {
const systemNode = await resolveSystemNodeInfo({ env: process.env });
const warning = renderSystemNodeWarning(systemNode, programArguments[0]);
if (warning) runtime.log(warning);
}
const environment = buildServiceEnvironment({
env: process.env,
port,
token: gatewayToken,
launchdLabel:
process.platform === "darwin"
? resolveGatewayLaunchAgentLabel(process.env.CLAWDBOT_PROFILE)
: undefined,
});
await service.install({
env: process.env,
stdout: process.stdout,
programArguments,
workingDirectory,
environment,
});
await ensureSystemdUserLingerNonInteractive({ runtime });
}