import Database from 'better-sqlite3'; import type { SessionDelivery, SessionDeliveryIdentity } from '../shared/types.js'; export declare const CREATE_TABLE = "\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n engine TEXT NOT NULL,\n engine_session_id TEXT,\n engine_sessions TEXT,\n source TEXT NOT NULL,\n source_ref TEXT NOT NULL,\n connector TEXT,\n session_key TEXT,\n reply_context TEXT,\n message_id TEXT,\n transport_meta TEXT,\n employee TEXT,\n model TEXT,\n title TEXT,\n prompt_excerpt TEXT,\n parent_session_id TEXT,\n workflow_kind TEXT,\n workflow_id TEXT,\n workflow_name TEXT,\n workflow_run_id TEXT,\n workflow_trigger_source TEXT,\n workflow_phase_node_id TEXT,\n workflow_phase_name TEXT,\n workflow_phase_index INTEGER,\n workflow_phase_round INTEGER,\n workflow_phase_attempt INTEGER,\n user_id TEXT,\n status TEXT DEFAULT 'idle',\n attempt_outcome TEXT,\n attempt_token TEXT,\n attempt_terminal_version INTEGER NOT NULL DEFAULT 0,\n attempt_turn INTEGER NOT NULL DEFAULT 0,\n attempt_interruption_cause TEXT,\n attempt_interruption_turn INTEGER,\n archived_at TEXT,\n created_at TEXT NOT NULL,\n last_activity TEXT NOT NULL,\n last_error TEXT\n)"; export declare const CREATE_MESSAGES_TABLE = "\nCREATE TABLE IF NOT EXISTS messages (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL,\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n timestamp INTEGER NOT NULL\n)"; export declare const CREATE_MESSAGES_INDEX = "\nCREATE INDEX IF NOT EXISTS idx_messages_session ON messages (session_id, timestamp)\n"; export declare const CREATE_MESSAGES_ORDER_INDEX = "\nCREATE INDEX IF NOT EXISTS idx_messages_session_order ON messages (session_id, timestamp, seq)\n"; export declare const CREATE_SESSION_KEY_INDEX = "\nCREATE INDEX IF NOT EXISTS idx_sessions_session_key ON sessions (session_key, last_activity)\n"; /** Caller-supplied delegation idempotency keys map to one durable session. The * key stored in session_key is a scoped hash, so the unique index is both * restart-safe and safe to add to existing databases. */ export declare const CREATE_DELEGATION_IDEMPOTENCY_INDEX = "\nCREATE UNIQUE INDEX IF NOT EXISTS uq_sessions_delegation_idempotency\n ON sessions (session_key) WHERE session_key LIKE 'delegation-idempotency:%'\n"; export declare const CREATE_LAST_ACTIVITY_INDEX = "\nCREATE INDEX IF NOT EXISTS idx_sessions_last_activity ON sessions (last_activity DESC)\n"; export declare const CREATE_PARENT_INDEX = "\nCREATE INDEX IF NOT EXISTS idx_sessions_parent ON sessions (parent_session_id)\n"; export declare const CREATE_WORKFLOW_RUN_INDEX = "\nCREATE INDEX IF NOT EXISTS idx_sessions_workflow_run ON sessions (workflow_run_id)\n WHERE workflow_run_id IS NOT NULL\n"; export declare const CREATE_STATUS_INDEX = "\nCREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions (status, last_activity DESC)\n"; export declare const CREATE_MESSAGES_PARTIAL_INDEX = "\nDROP INDEX IF EXISTS idx_messages_partial;\nCREATE INDEX IF NOT EXISTS idx_messages_partial_order\n ON messages (session_id, timestamp, COALESCE(seq, 0)) WHERE partial = 1\n"; export declare const CREATE_FILES_TABLE = "\nCREATE TABLE IF NOT EXISTS files (\n id TEXT PRIMARY KEY,\n filename TEXT NOT NULL,\n size INTEGER NOT NULL,\n mimetype TEXT,\n path TEXT,\n created_at TEXT NOT NULL\n)\n"; export declare const CREATE_META_TABLE = "\nCREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT\n)\n"; export declare const CREATE_CHAT_PINS_TABLE = "\nCREATE TABLE IF NOT EXISTS chat_pins (\n pin_key TEXT PRIMARY KEY,\n pinned_at TEXT NOT NULL\n)\n"; export { CREATE_QUEUE_ITEMS_TABLE, migrateQueueItemsSchema } from './queue-items-schema.js'; export declare const CREATE_WORK_ITEM_SESSION_INDEX = "\nCREATE INDEX IF NOT EXISTS idx_sessions_work_item ON sessions (work_item_id) WHERE work_item_id IS NOT NULL\n"; /** * Additive, nullable migration: add the `media` column to an existing messages * table. Safe to run repeatedly and on legacy DBs created before media support. */ export declare function migrateMessagesSchema(database: Database.Database): void; export declare function migrateSessionsSchema(database: Database.Database): void; export declare function getMeta(database: Database.Database, key: string): string | null; export declare function setMeta(database: Database.Database, key: string, value: string): void; /** * Create the FTS5 search index + sync triggers, and record the backfill watermark. * * The triggers keep the index current for every message written from now on. Rows * that already existed before this table did are NOT seen by the triggers, so they * are seeded separately by the chunked backfill (`scheduleFtsBackfill`). To stop * the backfill from double-indexing rows the triggers also handle, we snapshot the * current MAX(rowid) here — synchronously, before any new insert can race in — and * the backfill only ever touches `rowid <= fts_backfill_max`. Anything above that * watermark is a brand-new row and belongs to the triggers. * * Idempotent: safe to run on every boot. On a DB where the backfill already * completed it is a no-op. */ export declare function migrateFtsSchema(database: Database.Database): void; export interface SessionDeliveryRow { id: string; targetSessionId: string; sourceKind: SessionDeliveryIdentity['sourceKind']; sourceId: string; sourceAttempt: string; sourceOutcome: string; sourceVersion: number; deliveryKind: string; payload: string; status: SessionDelivery['status']; messageId: string | null; queueItemId: string | null; attemptCount: number; nextAttemptAt: number | null; lastAttemptAt: number | null; lastError: string | null; deadLetteredAt: number | null; createdAt: string; acceptedAt: string | null; } /** Install the callback outbox atomically. A malformed pre-existing table is * never silently indexed: validation throws inside the transaction so any DDL * from this migration is rolled back as one unit. */ export declare function migrateCallbackDeliveriesSchema(database: Database.Database): void; export declare function canonicalCallbackIdentityText(value: unknown): string; export declare function sessionDeliveryFromRow(row: SessionDeliveryRow): SessionDelivery; export declare function canonicalSessionDeliveryIdentity(identity: SessionDeliveryIdentity): SessionDeliveryIdentity; export declare function validateSessionDeliveryIdentity(identity: SessionDeliveryIdentity): void; export declare function runImmediateMigrationWithRetry(migration: Database.Transaction<() => T>): T; export declare function runSqliteBusyRetry(operation: () => T): T; //# sourceMappingURL=migrate.d.ts.map