/** * WikiIndexService — the one-line-per-page index that makes retrieval a * two-step read: read the whole index → pick 3–5 pages → read them in * full. No embeddings, no vector store; the index IS the retrieval. * * `llm-curated/index.md` is owned by the system: every page write updates * its line, every delete removes it, and `rebuild()` regenerates it from * the pages' frontmatter (also the migration path for vaults whose index * nobody maintained). Pages are grouped by their top-level curated folder. * * @module services/wiki/wiki-index.service */ import { type WikiPageFrontmatter } from './wiki-page.js'; /** One entry of the parsed index. */ export interface WikiIndexEntry { relativePath: string; title: string; summary: string; supersededBy?: string; /** Top-level folder under llm-curated (e.g. `decisions`), or `_root`. */ group: string; } /** Parsed index + raw text. */ export interface WikiIndex { entries: WikiIndexEntry[]; raw: string; bytes: number; } /** Coverage report: pages the index does not know and vice versa. */ export interface WikiIndexCoverage { pages: number; indexed: number; missingFromIndex: string[]; indexedButMissing: string[]; } /** * Maintains `llm-curated/index.md` per vault. */ export declare class WikiIndexService { private static instance; private readonly logger; /** Per-vault write serialisation (index edits are read-modify-write). */ private readonly locks; constructor(); static getInstance(): WikiIndexService; /** Test-only reset. */ static _resetForTesting(): void; /** * Absolute path of a vault's index file. * * @param vaultPath - Vault root * @returns `/llm-curated/index.md` */ indexPath(vaultPath: string): string; /** * Read and parse the index (empty when absent). * * @param vaultPath - Vault root * @returns Parsed entries + raw text */ read(vaultPath: string): Promise; /** * Insert or replace the line for one page. * * @param vaultPath - Vault root * @param relativePath - Vault-relative page path * @param fm - The page's frontmatter (title/summary/superseded_by are used) */ upsert(vaultPath: string, relativePath: string, fm: Partial): Promise; /** * Remove a page's line (no-op when absent). * * @param vaultPath - Vault root * @param relativePath - Vault-relative page path */ remove(vaultPath: string, relativePath: string): Promise; /** * Regenerate the whole index from the pages on disk. Pages without a * `summary` still get a line (title only) so nothing is invisible, and * they show up in {@link coverage} as work for the bookkeeping agent. * * @param vaultPath - Vault root * @returns Number of entries written */ rebuild(vaultPath: string): Promise; /** * Compare the index against the pages on disk. * * @param vaultPath - Vault root * @returns Coverage report */ coverage(vaultPath: string): Promise; /** * The index text an agent should read first, cut to the folders most * relevant to a query when the full index would not fit the budget. * * @param vaultPath - Vault root * @param queryTokens - Lower-cased query terms (for folder selection when trimming) * @param maxBytes - Budget (default {@link WIKI_KB_CONSTANTS.INDEX_MAX_BYTES}) * @returns Text plus whether it was trimmed */ readForQuery(vaultPath: string, queryTokens: string[], maxBytes?: number): Promise<{ text: string; truncated: boolean; entries: number; }>; private write; private withLock; } /** * Parse index lines back into entries. * * @param raw - index.md text * @returns Entries in file order */ export declare function parseIndex(raw: string): WikiIndexEntry[]; /** Whether a vault has an index file at all. */ export declare function hasIndex(vaultPath: string): boolean; //# sourceMappingURL=wiki-index.service.d.ts.map