/**
 * Monthly Contributor Recap Watcher Service
 *
 * Time-driven companion to the contributor pipeline (spec 097, FR-31 /
 * FR-32). Once per poll interval (default daily), checks whether the
 * previous calendar month's recap has already been generated; if not,
 * generates it via `GenerateMonthlyRecapUseCase` and fans the artifact
 * out across the configured publish targets via
 * `PublishMonthlyRecapUseCase`. Each channel publish is gated through
 * `IContributorActionGate` inside the use case; the watcher trusts the
 * gate to decide what actually goes out.
 */
import type { GenerateMonthlyRecapUseCase } from '../../../application/use-cases/contributors/generate-monthly-recap.use-case.js';
import type { PublishMonthlyRecapUseCase, PublishMonthlyRecapResult } from '../../../application/use-cases/contributors/publish-monthly-recap.use-case.js';
import type { RecapTarget } from '../../../application/ports/output/services/recap-publisher.interface.js';
export declare const DEFAULT_RECAP_POLL_INTERVAL_MS: number;
export interface MonthlyRecapWatcherDeps {
    generate: GenerateMonthlyRecapUseCase;
    publish: PublishMonthlyRecapUseCase;
    /** Optional override of "now" — useful for deterministic tests. */
    now?: () => Date;
    /** Optional overrideable storage of which months have already shipped. */
    recapAlreadyPublished?: (yearMonth: string) => Promise<boolean>;
    /** Optional override of publish targets; defaults to file-only. */
    targets?: readonly RecapTarget[];
    /** Optional poll interval (ms). */
    pollIntervalMs?: number;
}
export declare class MonthlyRecapWatcherService {
    private readonly deps;
    private readonly publishedThisProcess;
    private intervalId;
    constructor(deps: MonthlyRecapWatcherDeps);
    isRunning(): boolean;
    start(): void;
    stop(): void;
    /** Exposed for tests: returns the publish result if a recap shipped. */
    poll(): Promise<PublishMonthlyRecapResult | null>;
}
/**
 * Compute the UTC `YYYY-MM` of the calendar month immediately before
 * the given `now`. The recap is always for the *previous* month so we
 * are not running mid-month on partial data.
 */
export declare function previousYearMonth(now: Date): string;
export declare function initializeMonthlyRecapWatcher(deps: MonthlyRecapWatcherDeps): void;
export declare function getMonthlyRecapWatcher(): MonthlyRecapWatcherService;
export declare function hasMonthlyRecapWatcher(): boolean;
export declare function resetMonthlyRecapWatcher(): void;
//# sourceMappingURL=monthly-recap-watcher.service.d.ts.map