export type CronSchedule = | { kind: "at"; atMs: number } | { kind: "every"; everyMs: number; anchorMs?: number } | { kind: "cron"; expr: string; tz?: string }; export type CronSessionTarget = "main" | "isolated"; export type CronWakeMode = "next-heartbeat" | "now"; export type CronPayload = | { kind: "systemEvent"; text: string } | { kind: "agentTurn"; message: string; /** Optional model override (provider/model or alias). */ model?: string; thinking?: string; timeoutSeconds?: number; deliver?: boolean; provider?: | "last" | "whatsapp" | "telegram" | "discord" | "slack" | "signal" | "imessage"; to?: string; bestEffortDeliver?: boolean; }; export type CronIsolation = { postToMainPrefix?: string; }; export type CronJobState = { nextRunAtMs?: number; runningAtMs?: number; lastRunAtMs?: number; lastStatus?: "ok" | "error" | "skipped"; lastError?: string; lastDurationMs?: number; }; export type CronJob = { id: string; name: string; description?: string; enabled: boolean; createdAtMs: number; updatedAtMs: number; schedule: CronSchedule; sessionTarget: CronSessionTarget; wakeMode: CronWakeMode; payload: CronPayload; isolation?: CronIsolation; state: CronJobState; }; export type CronStoreFile = { version: 1; jobs: CronJob[]; }; export type CronJobCreate = Omit< CronJob, "id" | "createdAtMs" | "updatedAtMs" | "state" > & { state?: Partial; }; export type CronJobPatch = Partial< Omit & { state: CronJobState } >;