/**
 * Cron-based job scheduler for routines.
 *
 * Wraps the croner library to manage scheduled jobs in-memory. The daemon
 * process creates a single JobScheduler instance that loads enabled jobs
 * on startup and reloads them on SIGHUP.
 */
import { Cron } from 'croner';
import type { JobConfig } from './scheduling/routines.js';
/** How a fire was triggered, carrying the scheduler's intended UTC slot time. */
export interface TriggerContext {
    /** The ALIGNED cron slot this callback fires for, for the single-fire claim
     *  keyed on (routine, scheduledFor). Derived by {@link fireSlot} — NOT croner's
     *  raw `currentRun()`, which carries wall-clock jitter. */
    scheduledFor?: Date;
}
/**
 * The aligned occurrence boundary a fire callback belongs to — the value the
 * single-fire `(routine, scheduledFor)` claim keys on.
 *
 * croner's `currentRun()` inside a fire callback is the JITTERED wall-clock
 * trigger instant (it carries milliseconds — verified against croner 10.x), not
 * the aligned schedule boundary. Keying `slotRunId` on it directly minted a
 * distinct run id per delivery, so two callbacks for one occurrence each claimed
 * a different run dir and both launched, and a live fire never collided with its
 * catch-up twin (`missedRunId`, which keys on the aligned boundary). Flooring the
 * fire to its schedule boundary via {@link alignedSlotForFire} makes the claim a
 * structural claim on the occurrence identity (SING-15). Always returns a
 * concrete Date — `currentRun()` falls back to now, and an unresolvable boundary
 * falls back to the fire instant — so the forward path never dispatches without a
 * durable slot key.
 */
export declare function fireSlot(cron: Cron): Date;
/** In-memory cron scheduler that triggers a callback when jobs fire. */
export declare class JobScheduler {
    private jobs;
    private onTrigger;
    constructor(onTrigger: (config: JobConfig, ctx?: TriggerContext) => Promise<void>);
    loadAll(): void;
    schedule(config: JobConfig): void;
    unschedule(name: string): void;
    reloadAll(): void;
    stopAll(): void;
    getNextRun(name: string): Date | null;
    listScheduled(): Array<{
        name: string;
        nextRun: Date | null;
        enabled: boolean;
    }>;
}
