import { type DatabaseHandle } from './store/db.js'; import type { Embedder } from './embeddings/types.js'; import { Search } from './search/unified.js'; import { VaultWriter } from './vault/writer.js'; import { IndexPipeline } from './pipeline/indexer.js'; import { type BootstrapResult } from './pipeline/bootstrap.js'; import { ObsidianClient } from './obsidian/client.js'; import { type Config } from './config.js'; /** * Shared runtime state that every tool handler needs. Constructed once at * server startup and captured by each tool's registration closure. * * `embedder` is instantiated but NOT initialized — call `ensureEmbedderReady` * before touching semantic search. First call downloads the default * embedding model (~34MB for the v1.5.2 default bge-small-en-v1.5), so * we defer it until actually needed. * * `getBootstrap` returns the result of the last startup compatibility check * (model/schema change detection). `null` until `ensureEmbedderReady` has * run at least once — the check can't happen until the embedder knows its * dimensions. */ export interface ServerContext { db: DatabaseHandle; embedder: Embedder; search: Search; writer: VaultWriter; pipeline: IndexPipeline; config: Config; obsidian: ObsidianClient; ensureEmbedderReady: () => Promise; getBootstrap: () => BootstrapResult | null; embedderReady: () => boolean; initError: unknown | undefined; /** * Tracks the tail of the fire-and-forget reindex chain from write tools. * In production nothing awaits this — the writes return immediately and * the reindex drains in the background. In tests, afterEach awaits * `ctx.pendingReindex` before tearing down the temp vault / closing the * DB so the trailing reindex doesn't ENOENT against a deleted directory. * Always a resolved promise when no work is queued. */ pendingReindex: Promise; /** * Internal hook — write tools call this to chain their fire-and-forget * reindex onto the tail of `pendingReindex`. Not part of the user API. */ enqueueBackgroundReindex: (work: () => Promise) => void; /** * True while a background reindex is actively running (e.g. triggered by a * PREFIX_STRATEGY_VERSION bump or embedder change). Distinct from the * embedder-not-yet-ready state — allows search to surface a more accurate * "re-embedding in progress" message instead of the "still downloading" * first-run message. */ reindexInProgress: boolean; /** * v1.7.20 C8: reason recorded when the user triggered a reindex via the * `reindex` tool (as opposed to a bootstrap migration trigger). Read by * `index_status.lastReindexReasons`, merged with bootstrap migration * reasons. Null until the first manual reindex; persists in-process only. */ lastManualReindexReason: string | null; } export declare function createContext(): Promise;