Files
clawdbot/src/gateway/server-methods/cron.ts
2026-01-06 03:25:32 +01:00

179 lines
5.1 KiB
TypeScript

import {
normalizeCronJobCreate,
normalizeCronJobPatch,
} from "../../cron/normalize.js";
import {
readCronRunLogEntries,
resolveCronRunLogPath,
} from "../../cron/run-log.js";
import type { CronJobCreate, CronJobPatch } from "../../cron/types.js";
import {
ErrorCodes,
errorShape,
formatValidationErrors,
validateCronAddParams,
validateCronListParams,
validateCronRemoveParams,
validateCronRunParams,
validateCronRunsParams,
validateCronStatusParams,
validateCronUpdateParams,
validateWakeParams,
} from "../protocol/index.js";
import type { GatewayRequestHandlers } from "./types.js";
export const cronHandlers: GatewayRequestHandlers = {
wake: ({ params, respond, context }) => {
if (!validateWakeParams(params)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid wake params: ${formatValidationErrors(validateWakeParams.errors)}`,
),
);
return;
}
const p = params as {
mode: "now" | "next-heartbeat";
text: string;
};
const result = context.cron.wake({ mode: p.mode, text: p.text });
respond(true, result, undefined);
},
"cron.list": async ({ params, respond, context }) => {
if (!validateCronListParams(params)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid cron.list params: ${formatValidationErrors(validateCronListParams.errors)}`,
),
);
return;
}
const p = params as { includeDisabled?: boolean };
const jobs = await context.cron.list({
includeDisabled: p.includeDisabled,
});
respond(true, { jobs }, undefined);
},
"cron.status": async ({ params, respond, context }) => {
if (!validateCronStatusParams(params)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid cron.status params: ${formatValidationErrors(validateCronStatusParams.errors)}`,
),
);
return;
}
const status = await context.cron.status();
respond(true, status, undefined);
},
"cron.add": async ({ params, respond, context }) => {
const normalized = normalizeCronJobCreate(params) ?? params;
if (!validateCronAddParams(normalized)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid cron.add params: ${formatValidationErrors(validateCronAddParams.errors)}`,
),
);
return;
}
const job = await context.cron.add(normalized as unknown as CronJobCreate);
respond(true, job, undefined);
},
"cron.update": async ({ params, respond, context }) => {
const normalizedPatch = normalizeCronJobPatch(
(params as { patch?: unknown } | null)?.patch,
);
const candidate =
normalizedPatch && typeof params === "object" && params !== null
? { ...(params as Record<string, unknown>), patch: normalizedPatch }
: params;
if (!validateCronUpdateParams(candidate)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid cron.update params: ${formatValidationErrors(validateCronUpdateParams.errors)}`,
),
);
return;
}
const p = candidate as {
id: string;
patch: Record<string, unknown>;
};
const job = await context.cron.update(
p.id,
p.patch as unknown as CronJobPatch,
);
respond(true, job, undefined);
},
"cron.remove": async ({ params, respond, context }) => {
if (!validateCronRemoveParams(params)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid cron.remove params: ${formatValidationErrors(validateCronRemoveParams.errors)}`,
),
);
return;
}
const p = params as { id: string };
const result = await context.cron.remove(p.id);
respond(true, result, undefined);
},
"cron.run": async ({ params, respond, context }) => {
if (!validateCronRunParams(params)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid cron.run params: ${formatValidationErrors(validateCronRunParams.errors)}`,
),
);
return;
}
const p = params as { id: string; mode?: "due" | "force" };
const result = await context.cron.run(p.id, p.mode);
respond(true, result, undefined);
},
"cron.runs": async ({ params, respond, context }) => {
if (!validateCronRunsParams(params)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid cron.runs params: ${formatValidationErrors(validateCronRunsParams.errors)}`,
),
);
return;
}
const p = params as { id: string; limit?: number };
const logPath = resolveCronRunLogPath({
storePath: context.cronStorePath,
jobId: p.id,
});
const entries = await readCronRunLogEntries(logPath, {
limit: p.limit,
jobId: p.id,
});
respond(true, { entries }, undefined);
},
};