import { FSWatcher } from 'fs'; import { ScheduleRepo, SCHEDULES_FILE, type ScheduleTask } from '../../store/schedule-repo.js'; export type { ScheduleTask } from '../../store/schedule-repo.js'; declare function parseDuration(str: string | null | undefined): number | null; declare function formatDuration(ms: number): string; declare function formatTimeUntil(ms: number): string; interface RunnerParams { message: string; projectId: string; scheduleTaskId: string; profileName: string; /** Where the fired task should land — passed through so scheduled-task.ts can pick its dispatch branch. */ target?: ScheduleTask['target']; /** What to do if the chosen target thread no longer exists at fire time. */ fallback?: ScheduleTask['fallback']; } interface TaskDispatchParams { channel: string; scheduleTaskId: string; profileName: string; } interface ProgrammaticHandlerParams { channel: string; scheduleTaskId: string; } type RunnerFn = (params: RunnerParams) => Promise; type TaskDispatchRunnerFn = (params: TaskDispatchParams) => Promise; type ProgrammaticHandler = (params: ProgrammaticHandlerParams) => Promise; interface SchedulerOptions { schedulesFile?: string; watchFile?: boolean; /** Override the default scheduleRepo (for tests with custom schedulesFile). */ repo?: ScheduleRepo; } declare class Scheduler { runner: RunnerFn; taskDispatchRunner: TaskDispatchRunnerFn | null; programmaticHandlers: Record; schedulesFile: string; watchFile: boolean; timers: Map>; _repo: ScheduleRepo; _inFlight: Set; _taskConfigs: Map; _watcher: FSWatcher | null; _reloadTimer: ReturnType | null; _selfWriting: boolean; _beforeRunGuard: ((task: ScheduleTask) => boolean) | null; /** Async callback invoked after _beforeRunGuard blocks a task. Used for async bookkeeping (e.g. persisting pause). */ _onGuardBlocked: ((task: ScheduleTask) => Promise) | null; /** Admin notification callback for hot-reload → Slack messages. Set by app.ts after adapter creation. */ _adminNotifier: ((text: string) => void) | null; /** Set _selfWriting=true before a disk write, clear after 100ms to avoid triggering fs.watch hot-reload. */ _withWriteGuard(fn: () => Promise): Promise; constructor(runner: RunnerFn, taskDispatchRunner: TaskDispatchRunnerFn | null, programmaticHandlers?: Record, options?: SchedulerOptions); /** Set a callback for admin notifications (hot-reload → Slack). Called by app.ts after adapter creation. */ setAdminNotifier(fn: (text: string) => void): void; start(): Promise; stop(): void; _startWatching(): void; _hotReload(): Promise; add(type: string, options: Record): Promise; remove(id: string): Promise; list(): Promise; get(id: string): Promise; update(id: string, patch: Record): Promise; pause(id: string, pausedBy?: 'user' | 'rate-limit'): Promise; resume(id: string): Promise; setBeforeRunGuard(fn: ((task: ScheduleTask) => boolean) | null): void; setOnGuardBlocked(fn: ((task: ScheduleTask) => Promise) | null): void; getRateLimitThrottle(): Promise<{ resetsAt: number; activatedAt: number; modes?: string[]; } | null>; setRateLimitThrottle(meta: { resetsAt: number; activatedAt: number; modes?: string[]; } | null): Promise; setInterval(id: string, intervalMs: number): Promise; _rescheduleTask(task: ScheduleTask): void; _scheduleTask(task: ScheduleTask): void; _runTask(task: ScheduleTask): Promise; } export { Scheduler, parseDuration, formatDuration, formatTimeUntil, SCHEDULES_FILE };