/** One pending (or fired) reminder. */ export interface ScheduledReminder { id: string; /** Channel id the reminder is bound to ("feishu", "telegram", …). */ channel: string; chatKey: string; chatType: "p2p" | "group"; /** The message delivered when the reminder fires. */ text: string; /** Epoch ms when the reminder should fire. */ dueAt: number; createdAt: number; /** Sender key of the user who created it. */ ownerKey: string; /** Set once delivered; kept so a crashed process doesn't re-fire old entries. */ fired?: boolean; } /** * Parse a `/remind` time expression into an epoch ms. * Supported forms (relative or clock time): * - `10分钟` / `10m` / `10` → minutes from now * - `2小时` / `2h` → hours from now * - `14:30` → today at 14:30 (tomorrow if already past) * Returns `undefined` when the expression is not recognized. */ export declare function parseRemindTime(arg: string, now?: number): number | undefined; /** Human-readable display of a due time, in the user-facing language. */ export declare function formatRemindAt(dueAt: number, language?: "zh" | "en", now?: number): string; /** JSON-file reminder store (best-effort persistence, live in-memory truth). */ export declare class ReminderStore { private readonly file; private reminders; constructor(stateDir?: string); /** All reminders, nearest-due first. */ list(): ScheduledReminder[]; /** Reminders bound to one chat, nearest-due first. */ listFor(channel: string, chatKey: string): ScheduledReminder[]; /** Reminders that have come due and were not yet fired. */ due(now?: number): ScheduledReminder[]; /** * Add a reminder, and report **both** halves of what happened. * * The reminder is live in this process from the moment it is pushed, so it will * fire on schedule whether or not the file write succeeded — but it only * survives a restart if it did. Returning the reminder alone let every caller * treat "added" as one outcome, which is how a reminder set for tomorrow is * confirmed and then quietly gone by morning. */ add(input: Omit): { reminder: ScheduledReminder; persisted: boolean; }; remove(id: string): boolean; markFired(id: string): void; private load; /** * Write the store out. Returns false when it could not be written. * * Persistence is still best-effort — the live list is the truth and a reminder * fires from it regardless — but the failure is *returned* rather than * swallowed, because it is the difference between "set" and "set until the next * restart" and only the caller can say that to the user. */ private save; } //# sourceMappingURL=scheduler.d.ts.map