import Database from 'better-sqlite3'; export type { Database }; /** * Database handle type — alias for better-sqlite3's Database instance. * All store functions take one of these as their first argument. */ export type DatabaseHandle = Database.Database; /** * Schema version written into `index_metadata` by initSchema. Bumped whenever * a structural change requires a one-shot migration on next boot (see * `bootstrap.ts` for the migration runner). * * v1: pre-1.4.0 (nodes_vec + nodes_fts only). * v2: v1.4.0 — adds chunks / chunks_vec, index_metadata, and switches * nodes_fts to `porter unicode61` tokenize. * v3: v1.5.1 — adds `embedder_prefix_strategy` metadata key for stratified * BGE/E5 prefix migration; fixes dead schema_version branch. * v4: v1.6.5 — adds `edges.target_fragment` TEXT column. Heading / block * anchor stubs (`[[X#Section]]`, `[[X^block]]`) now store the bare * target id on `target_id` and the suffix on `target_fragment`, so * `resolveForwardStubs` can migrate them like any other forward-ref. * v6: v1.7.0 — adds `embedder_capability` and `failed_chunks` tables for * adaptive capacity tracking and fault-tolerant chunk logging. * v7: v1.7.5 — extends `embedder_capability` with metadata-cache columns * (dim, query_prefix, document_prefix, prefix_source, base_model, * size_bytes, fetched_at) so HF model metadata is resolved once + cached * instead of hardcoded across `presets.ts` / `embedder.ts` / * `capacity.KNOWN_MAX_TOKENS`. 90-day TTL on `fetched_at`. * * Known `index_metadata` keys: * embedding_model, embedding_dim, schema_version, embedder_provider, * embedder_prefix_strategy */ export declare const SCHEMA_VERSION = 7; /** * Open a SQLite database at `dbPath`, enable WAL mode, load the sqlite-vec * extension, and initialize the schema. Returns the live handle. */ export declare function openDb(dbPath: string): DatabaseHandle; /** * Create all tables, indexes, and virtual tables (FTS5 + vec0) used by the * knowledge graph store. Idempotent — safe to call on an existing database. */ export declare function initSchema(db: DatabaseHandle): void; /** * Reconcile nodes_vec + chunks_vec dimensions against the embedder's actual * output dim. Called once per process after the embedder initialises. * * - Dims match: no-op. * - Dim mismatch and the vec table is empty: drop + recreate at the new dim. * Lets users switch EMBEDDING_MODEL on a fresh install without ceremony. * - Dim mismatch and the vec table has rows: refuse, with a clear instruction * to run `obsidian-brain index --drop` and rebuild from scratch. The normal * path via bootstrap.checkEmbeddingCompatibility handles model switches * automatically before we ever hit this check. */ export declare function ensureVecTables(db: DatabaseHandle, dim: number): void; /** * Back-compat shim — older call sites pass only the nodes_vec name. * @deprecated Prefer {@link ensureVecTables}. */ export declare function ensureVecTable(db: DatabaseHandle, dim: number): void; /** * Drop every embedding + sync row so the next index run rebuilds from * scratch. Called by `obsidian-brain index --drop`, typically when switching * EMBEDDING_MODEL to one with a different output dim. * * Also clears the chunk table + chunks_vec so a model switch doesn't leave * stale per-chunk rows around pointing at the old vector space. * * v1.7.2: also clears `embedder_capability` and `failed_chunks` (v6 schema * tables). Capacity is cheap to re-probe (~50 ms transformers / one HTTP call * Ollama) and failed_chunks is pure telemetry — no semantic loss from clearing * on a model/provider switch. Without this, stale capacity entries from a * prior provider can poison the next reindex with a too-small * `discovered_max_tokens` cascade. */ export declare function dropEmbeddingState(db: DatabaseHandle): void; /** * One-shot FTS5 rebuild: drop nodes_fts and recreate it with the current * tokenize clause, then re-ingest every row in nodes. * * Used by the bootstrap migration when an older database was created with * the old default-tokenizer FTS table and we want the new porter-stemmed * index without forcing a full content re-index. */ export declare function rebuildFullTextIndex(db: DatabaseHandle): void; /** Return the current stored FTS tokenize clause, or null if absent. */ export declare function currentFtsTokenize(db: DatabaseHandle): string | null; /** * Idempotent in-place migration: ensure `edges.target_fragment` exists * (schema v4 addition). Safe to call on any schema version — if the column * already exists the ALTER is skipped. Also a no-op on schema v5+ where the * column was renamed to target_subpath (the column-check below misses on * the new name, so nothing runs). */ export declare function ensureEdgesTargetFragmentColumn(db: DatabaseHandle): void; /** * Idempotent in-place migration: rename `edges.target_fragment` → * `edges.target_subpath` (schema v5). Aligns with the Obsidian API's * `LinkCache.subpath` naming used by Dataview, Juggl, and the official * plugin API. * * Runs in three cases: * - Old column exists and new doesn't → rename (normal upgrade path). * - New column already exists → no-op (fresh v5+ install, or second boot). * - Neither exists → no-op (pre-v4 DB; ensureEdgesTargetFragmentColumn * will run before us in the chain and add target_fragment, then we * rename it). */ export declare function renameTargetFragmentToSubpath(db: DatabaseHandle): void; /** * Defensive cross-check between code's expected column set and the live DB. * * Runs at the end of `openDb` after `initSchema` + bootstrap migrations. For * each v1.7.0 table (`embedder_capability`, `failed_chunks`), verifies that * `PRAGMA table_info(TABLE)` reports exactly the column set the code reads / * writes. If columns are MISSING, calls the corresponding `createXxxTable` * helper to add them (idempotent). If columns are EXTRA, warns to stderr but * continues — forward-compat for older code reading a newer DB. * * Catches stale-cache scenarios (npx cached an older version of obsidian-brain * that doesn't write/read the same columns the user's DB has) and prevents * the obscure "Too few parameter values" bind error that would otherwise fire * downstream. */ export declare function selfCheckSchema(db: DatabaseHandle): void; /** * Idempotent migration (schema v6 + v7): create `embedder_capability` table * used by the adaptive capacity module to cache per-model context-length * probes (v6) and HF metadata (v7 — dim/prefix/etc). * * Calls `ensureEmbedderCapabilityV7Columns` afterwards so a v6 install gets * the v7 columns added on the next openDb. Safe on every boot. */ export declare function createEmbedderCapabilityTable(db: DatabaseHandle): void; /** * Idempotent v6 → v7 migration helper. Adds the seven metadata-cache columns * to `embedder_capability` if they're missing. PRAGMA-guarded so re-running * is a no-op on tables that already have them. */ export declare function ensureEmbedderCapabilityV7Columns(db: DatabaseHandle): void; /** * Idempotent migration (schema v6): create `failed_chunks` table used by * the fault-tolerant indexer to record chunks that could not be embedded. */ export declare function createFailedChunksTable(db: DatabaseHandle): void;