/**
 * No-reply reminder service.
 *
 * Persists reminders keyed to an already-sent email and fires them when a
 * user-chosen deadline elapses. A follow-up PR will add automatic
 * reply-detection via IMAP header search; for v1 the agent composes that
 * check itself by calling search_emails with the stored Message-ID.
 *
 * Storage is a single JSON file written atomically via tmp → rename, with
 * mode 0600 to match the rest of the project's credential-hygiene story.
 */
export type ReminderStatus = "pending" | "fired" | "cancelled";
export interface Reminder {
    /** Short random ID, not persistent across manual edits. */
    id: string;
    /** RFC 2822 Message-ID of the message the user sent and wants a reply to. */
    messageId: string;
    /** IMAP UID of the original message (for quick re-lookup). */
    imapUid?: string;
    /** Recipient that ought to reply. */
    recipient: string;
    /** Original subject (stored so the reminder payload is human-readable). */
    subject: string;
    /** ISO-8601 timestamp the original message was sent. */
    sentAt: string;
    /** ISO-8601 timestamp when this reminder should fire. */
    fireAt: string;
    status: ReminderStatus;
    /** Optional free-text reminder-why, shown with the notification. */
    note?: string;
}
export declare class ReminderService {
    private readonly path;
    private reminders;
    constructor(path: string);
    private load;
    private persist;
    /**
     * SMTP-006: persist the current in-memory state, rolling it back to the
     * supplied snapshot if the write fails. Without this, a failed persist()
     * (EXDEV, ENOSPC, EACCES) leaves `this.reminders` advanced past disk; a
     * later successful persist() would then silently flush the half-baked
     * mutation — e.g. a "fired" reminder the caller never received getting
     * written as "fired", breaking check_reminders' at-least-once guarantee.
     *
     * SMTP-007: scanDue() routes its fire-transition through here, so the
     * "fired" flip is committed to disk before the method returns or rolled
     * back atomically with the in-memory state. The at-least-once limitation
     * (a dropped MCP response after a successful persist) remains by design
     * pending a dedicated acknowledge tool — see the SMTP-007 audit note.
     *
     * @param snapshot Deep copy of `this.reminders` taken BEFORE the mutation.
     * @throws Re-throws the underlying persist error after rolling back so the
     *         caller (and the MCP tool layer) sees the failure.
     */
    private persistOrRollback;
    /** Deep-clone the current reminders for use as a rollback snapshot. */
    private snapshot;
    /**
     * Create a reminder. Returns the persisted record.
     * @param args.afterDays  Days from sentAt to the deadline. Minimum 1, maximum 365.
     */
    add(args: {
        messageId: string;
        imapUid?: string;
        recipient: string;
        subject: string;
        sentAt: Date;
        afterDays: number;
        note?: string;
    }): Reminder;
    /** Return pending reminders sorted by earliest fireAt. */
    listPending(): Reminder[];
    /** Return every reminder, regardless of status. */
    listAll(): Reminder[];
    cancel(id: string): boolean;
    /**
     * Auto-cancel reminders whose tracked Message-ID appears in the
     * In-Reply-To / References headers of any of the given inbox messages.
     * Returns the IDs of the reminders that were cancelled.
     *
     * Case-insensitive match on the angle-bracket form of the Message-ID.
     * The caller typically passes a recent inbox slice (the autosync loop
     * already fetches one), so this is cheap and doesn't hit IMAP itself.
     */
    detectRepliesAndCancel(inbox: Array<{
        headers?: Record<string, string | string[]>;
    }>): string[];
    /**
     * Advance each due pending reminder to "fired" and return them. Caller is
     * responsible for surfacing the list to the user (MCP log, tool response,
     * etc.) — this method does not push anywhere.
     */
    scanDue(now?: Date): Reminder[];
    /** Remove fired/cancelled reminders older than the retention window. */
    prune(retainDays?: number): number;
}
//# sourceMappingURL=reminder-service.d.ts.map