import Database from 'better-sqlite3'; export declare const SCHEMA_VERSION = 2; export declare function initDb(path?: string): Database.Database; export declare function validateRequiredPragmas(candidate: Database.Database): void; export declare function validateSchema(candidate?: any): void; export interface GatewayConfigInput { channelId: string; channelLabel: string; workingDirectory: string; piBinary: string; defaultModel: string; defaultThinking: string; archiveRetentionDays?: number; mediaRetentionHours?: number; maxAttachmentBytes?: number; maxTotalAttachmentBytes?: number; schedulerBatchLimit?: number; logLevel?: string; } /** Setup is the sole creator of the configuration singleton. */ export declare function createGatewayConfig(input: GatewayConfigInput): void; export declare function validateTrustedUserRow(row: Record): void; export declare function validateInboxRow(row: Record): void; export declare function validateSlackEventRow(row: Record): void; export type ScheduleRow = { id: number; title: string; instructions: string; kind: 'at' | 'cron'; at_time: string | null; cron_expression: string | null; timezone: string | null; enabled: number; next_run_at: string | null; created_at: string; updated_at: string; }; export declare function validateScheduleRow(row: Record): asserts row is ScheduleRow; export declare function requireConfiguredDb(): Database.Database; /** Validates schema v2 and the complete configuration singleton on an injected connection. */ export declare function validateConfiguredDatabase(candidate: Database.Database): void; declare const mutableConfigColumns: { readonly defaultModel: "default_model"; readonly defaultThinking: "default_thinking"; readonly sessionModelOverride: "session_model_override"; readonly sessionThinkingOverride: "session_thinking_override"; readonly archiveRetentionDays: "archive_retention_days"; readonly mediaRetentionHours: "media_retention_hours"; readonly maxAttachmentBytes: "max_attachment_bytes"; readonly maxTotalAttachmentBytes: "max_total_attachment_bytes"; readonly schedulerBatchLimit: "scheduler_batch_limit"; readonly logLevel: "log_level"; }; export type MutableConfigKey = keyof typeof mutableConfigColumns; export declare function readGatewayConfig(): Record; /** Updates only non-structural settings after validating the complete resulting row. */ export declare function updateGatewayConfig(key: MutableConfigKey, value: unknown): Record; /** Clears one of the optional session overrides. */ export declare function resetGatewayConfig(key: MutableConfigKey): Record; export declare function closeDb(): void; export declare function publicId(kind: 'inbox' | 'task' | 'schedule', id: number): string; export declare function parsePublicId(kind: 'inbox' | 'task' | 'schedule', value: string): number; export declare function addTrustedUser(userId: string, label?: string): boolean; export declare function removeTrustedUser(userId: string): boolean; export declare function isTrustedUser(userId: string): boolean; export type SlackMutation = { eventId: string; kind: 'new-message' | 'edit' | 'deletion'; messageId: string; senderId: string; senderLabel: string; content?: string; messageTs: string; threadTs?: string; attachments?: unknown[]; }; /** Atomically records a delivery and mutates an open source snapshot. Ignored mutations are deliberately not ledgered. */ export type AcceptanceMetadata = { acceptedAt: string; sessionId: string; runSequence: number; }; export declare function markSlackEventAccepted(eventId: string, metadata: AcceptanceMetadata): void; export declare function inboxSnapshot(id: number): Record | undefined; /** Creates a manual task before attempting its intentionally non-atomic pi delivery. */ export type TaskRow = { id: number; source: 'manual' | 'schedule'; occurrence_key: string | null; schedule_id: number | null; title: string; instructions: string; catch_up_first_at: string | null; catch_up_last_at: string | null; catch_up_count: number | null; state: 'open' | 'resolved'; resolution_reason: string | null; resolved_at: string | null; rpc_accepted_at: string | null; pi_session_id: string | null; run_sequence: number | null; created_at: string; }; export declare function validateTaskRow(row: Record): asserts row is TaskRow; export declare function validatePersistedRows(candidate: Database.Database): void; export declare function createManualTask(title: string, instructions: string): Record; export declare function createScheduleRow(input: { title: string; instructions: string; kind: 'at' | 'cron'; at?: string; cron?: string; timezone?: string; nextRunAt?: string; }): ScheduleRow; export declare function scheduleRow(id: number): ScheduleRow | undefined; export declare function listScheduleRows(limit: number, cursor?: { createdAt: string; id: number; }): ScheduleRow[]; export declare function setScheduleEnabled(id: number, enabled: boolean, nextRunAt: string | null): ScheduleRow; export declare function removeScheduleRow(id: number): boolean; /** Atomically creates one task per due definition and advances it. Recurring downtime is coalesced. */ export declare function materializeDueScheduleTasks(current: string, nextCron: (row: ScheduleRow, after: string) => string): Array>; /** Records only an RPC command that pi has explicitly accepted. */ export declare function markTaskAccepted(id: number, metadata: AcceptanceMetadata): void; /** Existing work for a single startup/reset recovery message; this never changes acceptance metadata. */ export declare function openWorkSummary(): { inboxTotal: number; inbox: Array>; taskTotal: number; tasks: Array>; }; /** Records best-effort gateway reaction reconciliation without changing inbox lifecycle. */ export declare function setInboxWorking(id: number): Record; /** Returns abandoned in-progress markers to the open-work receipt state. */ export declare function revertOpenInboxWorkingReactions(): number; /** Resolves an open inbox after a confirmed Slack reply, preserving terminal snapshots. */ export declare function recordInboxReply(id: number, replyTs: string): void; export declare function recordInboxReaction(id: number, state: { desired?: string | null; actual?: string | null; error?: string | null; nextAttemptAt?: string | null; }): void; export declare function inboxReactionsDue(limit: number): Array>; export declare function ingestSlackEvent(event: SlackMutation): { duplicate: boolean; ignored: boolean; inboxId?: number; revision?: number; outcome: string; }; export {};