/**
 * Overdue routine detection.
 *
 * When the daemon was not running (laptop off, reboot, daemon crash) at the
 * time a job was supposed to fire, the missed schedule is lost — croner only
 * schedules forward from "now." This module compares each enabled job's
 * most-recent expected fire time (from its cron expression) with the start
 * time of its most-recent recorded run; jobs whose latest run is older than
 * their most-recent expected fire are flagged as overdue.
 *
 * Surfaced two ways: a desktop notification on daemon startup, and a
 * `agents routines catchup` command that runs them on demand.
 */
import { type JobConfig } from './scheduling/routines.js';
export interface OverdueJob {
    name: string;
    /** Most recent expected fire time per the cron expression. */
    expectedAt: Date;
    /** Start time of the most recent recorded run, or null if never run. */
    lastRanAt: Date | null;
}
/**
 * When a routine started existing, and therefore the earliest fire it can
 * sensibly be judged against.
 *
 * `createdAt` is stamped by `writeJob`. Routines written before that field
 * existed have none, so the file's own mtime stands in — it is the closest
 * honest answer available on disk, and it only ever moves the floor later,
 * never earlier, so it cannot manufacture a false "overdue".
 *
 * Returns null when neither is available, which leaves the routine unfloored
 * (previous behaviour) rather than silently skipping it.
 */
export declare function routineEffectiveStart(job: JobConfig, now?: Date): Date | null;
/** Return every enabled, recurring job whose most recent expected fire was
 *  missed. One-shot jobs are excluded — they fire at most once. */
export declare function detectOverdueJobs(now?: Date): OverdueJob[];
/**
 * Fire a branded desktop notification listing the overdue jobs. Routed through
 * the MenubarHelper companion (notify-desktop.ts) so it carries the agents-cli
 * mark; clicking opens the runs folder (~/.agents/.history/runs). Best-effort —
 * a missing notifier or absent display is swallowed and never crashes the daemon.
 */
export declare function notifyOverdue(jobs: OverdueJob[]): void;
