From 3e96fdea9fc75937e6a61b5af8ee3cb1bdea76a6 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 12 Apr 2026 03:51:11 +0100 Subject: [PATCH] fix(cron): split gateway cron service contract --- src/cron/service-contract.ts | 53 ++++++++++++++++++++++ src/cron/service.ts | 11 ++++- src/gateway/server-methods/shared-types.ts | 4 +- 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 src/cron/service-contract.ts diff --git a/src/cron/service-contract.ts b/src/cron/service-contract.ts new file mode 100644 index 00000000000..aacceb2b0c2 --- /dev/null +++ b/src/cron/service-contract.ts @@ -0,0 +1,53 @@ +import type { + CronAddInput, + CronAddResult, + CronListResult, + CronRemoveResult, + CronRunMode, + CronRunResult, + CronStatusSummary, + CronUpdateInput, + CronUpdateResult, + CronWakeMode, +} from "./service/state.js"; +import type { CronJob } from "./types.js"; + +type CronJobsEnabledFilter = "all" | "enabled" | "disabled"; +type CronJobsSortBy = "nextRunAtMs" | "updatedAtMs" | "name"; +type CronSortDir = "asc" | "desc"; + +export type CronListPageOptions = { + includeDisabled?: boolean; + limit?: number; + offset?: number; + query?: string; + enabled?: CronJobsEnabledFilter; + sortBy?: CronJobsSortBy; + sortDir?: CronSortDir; +}; + +export type CronListPageResult = { + jobs: CronJob[]; + total: number; + offset: number; + limit: number; + hasMore: boolean; + nextOffset: number | null; +}; + +export type CronWakeResult = { ok: true } | { ok: false }; + +export interface CronServiceContract { + start(): Promise; + stop(): void; + status(): Promise; + list(opts?: { includeDisabled?: boolean }): Promise; + listPage(opts?: CronListPageOptions): Promise; + add(input: CronAddInput): Promise; + update(id: string, patch: CronUpdateInput): Promise; + remove(id: string): Promise; + run(id: string, mode?: CronRunMode): Promise; + enqueueRun(id: string, mode?: CronRunMode): Promise; + getJob(id: string): CronJob | undefined; + wake(opts: { mode: CronWakeMode; text: string }): CronWakeResult; +} diff --git a/src/cron/service.ts b/src/cron/service.ts index a221cb68b15..d972b2b0c0b 100644 --- a/src/cron/service.ts +++ b/src/cron/service.ts @@ -1,10 +1,17 @@ +import type { CronListPageOptions, CronServiceContract } from "./service-contract.js"; import * as ops from "./service/ops.js"; import { type CronServiceDeps, createCronServiceState } from "./service/state.js"; import type { CronJob, CronJobCreate, CronJobPatch } from "./types.js"; export type { CronEvent, CronServiceDeps } from "./service/state.js"; +export type { + CronListPageOptions, + CronListPageResult, + CronServiceContract, + CronWakeResult, +} from "./service-contract.js"; -export class CronService { +export class CronService implements CronServiceContract { private readonly state; constructor(deps: CronServiceDeps) { this.state = createCronServiceState(deps); @@ -26,7 +33,7 @@ export class CronService { return await ops.list(this.state, opts); } - async listPage(opts?: ops.CronListPageOptions) { + async listPage(opts?: CronListPageOptions) { return await ops.listPage(this.state, opts); } diff --git a/src/gateway/server-methods/shared-types.ts b/src/gateway/server-methods/shared-types.ts index e748071fc97..1d5e8de8298 100644 --- a/src/gateway/server-methods/shared-types.ts +++ b/src/gateway/server-methods/shared-types.ts @@ -2,7 +2,7 @@ import type { ModelCatalogEntry } from "../../agents/model-catalog.types.js"; import type { CliDeps } from "../../cli/deps.types.js"; import type { HealthSummary } from "../../commands/health.types.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import type { CronService } from "../../cron/service.js"; +import type { CronServiceContract } from "../../cron/service-contract.js"; import type { PluginApprovalRequestPayload } from "../../infra/plugin-approvals.js"; import type { createSubsystemLogger } from "../../logging/subsystem.js"; import type { WizardSession } from "../../wizard/session.js"; @@ -37,7 +37,7 @@ export type RespondFn = ( export type GatewayRequestContext = { deps: CliDeps; - cron: CronService; + cron: CronServiceContract; cronStorePath: string; execApprovalManager?: ExecApprovalManager; pluginApprovalManager?: ExecApprovalManager;