refactor(daemon): share service arg types across backends

This commit is contained in:
Peter Steinberger
2026-02-19 10:03:09 +00:00
parent be7462af1e
commit 70900feaa7
5 changed files with 109 additions and 144 deletions

View File

@@ -7,8 +7,17 @@ import { resolveGatewayStateDir } from "./paths.js";
import { parseKeyValueOutput } from "./runtime-parse.js";
import { execSchtasks } from "./schtasks-exec.js";
import type { GatewayServiceRuntime } from "./service-runtime.js";
import type {
GatewayServiceCommandConfig,
GatewayServiceControlArgs,
GatewayServiceEnv,
GatewayServiceEnvArgs,
GatewayServiceInstallArgs,
GatewayServiceManageArgs,
GatewayServiceRenderArgs,
} from "./service-types.js";
function resolveTaskName(env: Record<string, string | undefined>): string {
function resolveTaskName(env: GatewayServiceEnv): string {
const override = env.OPENCLAW_WINDOWS_TASK_NAME?.trim();
if (override) {
return override;
@@ -16,7 +25,7 @@ function resolveTaskName(env: Record<string, string | undefined>): string {
return resolveGatewayWindowsTaskName(env.OPENCLAW_PROFILE);
}
export function resolveTaskScriptPath(env: Record<string, string | undefined>): string {
export function resolveTaskScriptPath(env: GatewayServiceEnv): string {
const override = env.OPENCLAW_TASK_SCRIPT?.trim();
if (override) {
return override;
@@ -33,7 +42,7 @@ function quoteCmdArg(value: string): string {
return `"${value.replace(/"/g, '\\"')}"`;
}
function resolveTaskUser(env: Record<string, string | undefined>): string | null {
function resolveTaskUser(env: GatewayServiceEnv): string | null {
const username = env.USERNAME || env.USER || env.LOGNAME;
if (!username) {
return null;
@@ -54,11 +63,9 @@ function parseCommandLine(value: string): string[] {
return splitArgsPreservingQuotes(value, { escapeMode: "backslash-quote-only" });
}
export async function readScheduledTaskCommand(env: Record<string, string | undefined>): Promise<{
programArguments: string[];
workingDirectory?: string;
environment?: Record<string, string>;
} | null> {
export async function readScheduledTaskCommand(
env: GatewayServiceEnv,
): Promise<GatewayServiceCommandConfig | null> {
const scriptPath = resolveTaskScriptPath(env);
try {
const content = await fs.readFile(scriptPath, "utf8");
@@ -137,12 +144,7 @@ function buildTaskScript({
programArguments,
workingDirectory,
environment,
}: {
description?: string;
programArguments: string[];
workingDirectory?: string;
environment?: Record<string, string | undefined>;
}): string {
}: GatewayServiceRenderArgs): string {
const lines: string[] = ["@echo off"];
if (description?.trim()) {
lines.push(`rem ${description.trim()}`);
@@ -179,14 +181,7 @@ export async function installScheduledTask({
workingDirectory,
environment,
description,
}: {
env: Record<string, string | undefined>;
stdout: NodeJS.WritableStream;
programArguments: string[];
workingDirectory?: string;
environment?: Record<string, string | undefined>;
description?: string;
}): Promise<{ scriptPath: string }> {
}: GatewayServiceInstallArgs): Promise<{ scriptPath: string }> {
await assertSchtasksAvailable();
const scriptPath = resolveTaskScriptPath(env);
await fs.mkdir(path.dirname(scriptPath), { recursive: true });
@@ -244,10 +239,7 @@ export async function installScheduledTask({
export async function uninstallScheduledTask({
env,
stdout,
}: {
env: Record<string, string | undefined>;
stdout: NodeJS.WritableStream;
}): Promise<void> {
}: GatewayServiceManageArgs): Promise<void> {
await assertSchtasksAvailable();
const taskName = resolveTaskName(env);
await execSchtasks(["/Delete", "/F", "/TN", taskName]);
@@ -266,15 +258,9 @@ function isTaskNotRunning(res: { stdout: string; stderr: string; code: number })
return detail.includes("not running");
}
export async function stopScheduledTask({
stdout,
env,
}: {
stdout: NodeJS.WritableStream;
env?: Record<string, string | undefined>;
}): Promise<void> {
export async function stopScheduledTask({ stdout, env }: GatewayServiceControlArgs): Promise<void> {
await assertSchtasksAvailable();
const taskName = resolveTaskName(env ?? (process.env as Record<string, string | undefined>));
const taskName = resolveTaskName(env ?? (process.env as GatewayServiceEnv));
const res = await execSchtasks(["/End", "/TN", taskName]);
if (res.code !== 0 && !isTaskNotRunning(res)) {
throw new Error(`schtasks end failed: ${res.stderr || res.stdout}`.trim());
@@ -285,12 +271,9 @@ export async function stopScheduledTask({
export async function restartScheduledTask({
stdout,
env,
}: {
stdout: NodeJS.WritableStream;
env?: Record<string, string | undefined>;
}): Promise<void> {
}: GatewayServiceControlArgs): Promise<void> {
await assertSchtasksAvailable();
const taskName = resolveTaskName(env ?? (process.env as Record<string, string | undefined>));
const taskName = resolveTaskName(env ?? (process.env as GatewayServiceEnv));
await execSchtasks(["/End", "/TN", taskName]);
const res = await execSchtasks(["/Run", "/TN", taskName]);
if (res.code !== 0) {
@@ -299,17 +282,15 @@ export async function restartScheduledTask({
stdout.write(`${formatLine("Restarted Scheduled Task", taskName)}\n`);
}
export async function isScheduledTaskInstalled(args: {
env?: Record<string, string | undefined>;
}): Promise<boolean> {
export async function isScheduledTaskInstalled(args: GatewayServiceEnvArgs): Promise<boolean> {
await assertSchtasksAvailable();
const taskName = resolveTaskName(args.env ?? (process.env as Record<string, string | undefined>));
const taskName = resolveTaskName(args.env ?? (process.env as GatewayServiceEnv));
const res = await execSchtasks(["/Query", "/TN", taskName]);
return res.code === 0;
}
export async function readScheduledTaskRuntime(
env: Record<string, string | undefined> = process.env as Record<string, string | undefined>,
env: GatewayServiceEnv = process.env as GatewayServiceEnv,
): Promise<GatewayServiceRuntime> {
try {
await assertSchtasksAvailable();