import type { HeartbeatRunResult } from "../../infra/heartbeat-wake.js";
import type { CronJob, CronStoreFile } from "../types.js";
export type CronEvent = {
    jobId: string;
    action: "added" | "updated" | "removed" | "started" | "finished";
    runAtMs?: number;
    durationMs?: number;
    status?: "ok" | "error" | "skipped";
    error?: string;
    summary?: string;
    sessionId?: string;
    sessionKey?: string;
    nextRunAtMs?: number;
};
export type Logger = {
    debug: (obj: unknown, msg?: string) => void;
    info: (obj: unknown, msg?: string) => void;
    warn: (obj: unknown, msg?: string) => void;
    error: (obj: unknown, msg?: string) => void;
};
export type CronServiceDeps = {
    nowMs?: () => number;
    log: Logger;
    storePath: string;
    cronEnabled: boolean;
    enqueueSystemEvent: (text: string, opts?: {
        koiId?: string;
    }) => void;
    requestHeartbeatNow: (opts?: {
        reason?: string;
    }) => void;
    runHeartbeatOnce?: (opts?: {
        reason?: string;
    }) => Promise<HeartbeatRunResult>;
    runIsolatedKoiJob: (params: {
        job: CronJob;
        message: string;
    }) => Promise<{
        status: "ok" | "error" | "skipped";
        summary?: string;
        /** Last non-empty koi text output (not truncated). */
        outputText?: string;
        error?: string;
        sessionId?: string;
        sessionKey?: string;
    }>;
    onEvent?: (evt: CronEvent) => void;
};
export type CronServiceDepsInternal = Omit<CronServiceDeps, "nowMs"> & {
    nowMs: () => number;
};
export type CronServiceState = {
    deps: CronServiceDepsInternal;
    store: CronStoreFile | null;
    timer: NodeJS.Timeout | null;
    running: boolean;
    op: Promise<unknown>;
    warnedDisabled: boolean;
    storeLoadedAtMs: number | null;
    storeFileMtimeMs: number | null;
};
export declare function createCronServiceState(deps: CronServiceDeps): CronServiceState;
