import { laterReturnDate, type CadencePolicy } from './cadence.js'; import { type IsoDate } from './dates.js'; import { type Interview, type Occasion, type OccasionAcknowledgement, type OccasionConflict, type OpenItem, type Plan } from './types.js'; /** The occasions feature's effective policy, all of it operator-editable. */ export interface OccasionsPolicy extends CadencePolicy { readonly enabled: boolean; /** Default runway in days. A per-occasion `lead N` overrides it. */ readonly leadDays: number; /** The hours it may speak, `HH:MM-HH:MM`, in `daemon.timezone`. */ readonly activeHours: string; /** Whether a plan that takes the owner away moves a nudge earlier. */ readonly awayAdjust: boolean; /** Whether an occasion mirrored to a calendar is left to the calendar. */ readonly suppressMirroredNudges: boolean; /** How many questions the gift interview asks. */ readonly interviewQuestions: number; /** How long gift history is kept, in years. */ readonly giftHistoryYears: number; /** * Where nudges are delivered: a comma-separated list of channel destinations, * each `surfaceKind` or `surfaceKind:address`. Empty ⇒ pull-only. */ readonly nudgeChannel: string; /** Whether occasions are written out to the calendar as a mirror. */ readonly calendarMirror: boolean; /** How often the scheduled sweep runs, in minutes. Read live, per tick. */ readonly sweepIntervalMinutes: number; } /** One occasion that is due to be raised, with the occurrence it is about. */ export interface DueOccasion { readonly occasion: Occasion; readonly occurrence: IsoDate; /** Whole days from today. Never rendered, see nudge.ts. */ readonly daysUntil: number; } /** Everything the sweep needs, gathered by the caller. */ export interface SweepContext { readonly now: number; readonly today: IsoDate; /** Minutes past midnight where the owner is. */ readonly minutesOfDay: number; readonly occasions: readonly Occasion[]; readonly conflicts: readonly OccasionConflict[]; readonly plans: readonly Plan[]; readonly acknowledgements: readonly OccasionAcknowledgement[]; readonly openItems: readonly OpenItem[]; readonly interviews: readonly Interview[]; readonly policy: OccasionsPolicy; } /** Why a sweep raised nothing, when it raised nothing. */ export type SweepHold = 'disabled' | 'quiet-hours' | null; /** What the sweep decided. The caller delivers it and writes the items back. */ export interface SweepDecision { readonly hold: SweepHold; readonly due: readonly DueOccasion[]; readonly conflicts: readonly OccasionConflict[]; /** Interviews the owner walked away from that are due to be picked up again. */ readonly resumeInterviews: readonly Interview[]; /** Open items to create or replace, already carrying their next due date. */ readonly openItemWrites: readonly OpenItem[]; } /** * Whether the clock is inside the hours it may speak. * * The owner's words were *"8am to 10pm are generally fine, anything outside of * that probably not, so quiet outside of that range"*, so the setting names the * ACTIVE window rather than the quiet one, a setting whose value is the thing * the owner said. The parse is the check-in's, so the two cannot disagree about what * `HH:MM-HH:MM` means; the evaluation is not, because the check-in reads the * host's local clock and this has to read `daemon.timezone`. */ export declare function isWithinActiveHours(minutesOfDay: number, activeHours: string): boolean; /** The lead this occasion actually uses. */ export declare function effectiveLead(occasion: Occasion, policy: OccasionsPolicy): number; /** The whole decision. Pure: same inputs, same answer, every time. */ export declare function decideSweep(context: SweepContext): SweepDecision; /** * The date a `later` comes back on, re-exported at the sweep's boundary. * * It belongs to the answer path rather than to the sweep, but every caller that * records a `later` is a caller of this module, and a second import path for one * function is how two callers end up disagreeing about what "later" means. */ export { laterReturnDate }; //# sourceMappingURL=sweep.d.ts.map