import { type EntityTypeName } from './entity.js'; export interface IndexNode { id: string; type: EntityTypeName; name: string; /** @deprecated use name */ title: string; filepath: string; tags: string[]; description: string; /** @deprecated use description */ summary: string; bodySnippet: string; meta: Record; } export interface IndexSearchResult { node: IndexNode; score: number; } export interface IndexEdge { source: string; target: string; edgeType: 'mention' | 'reference' | 'link'; label?: string; } export interface IndexStats { nodeCount: number; edgeCount: number; byType: Record; builtAt: string; } export declare class EntityIndex { private nodes; private edges; private _builtAt; private static key; /** * Scan all entity directories, build node map and edge list. */ build(): Promise; /** * Clear and rebuild the index. */ rebuild(): Promise; get isBuilt(): boolean; /** * Add or update a single node and re-scan its content for edges. * Avoids a full rebuild when a single entity is created or modified. */ addOrUpdate(type: EntityTypeName, id: string, name: string, filepath: string, tags?: string[], description?: string): Promise; /** * Remove a node and all its inbound/outbound edges. */ remove(type: EntityTypeName, id: string): void; /** * Search nodes by query against title, tags, and summary. * Tokenizes query; scoring: title=3, tag=2, summary=1 per token. * All tokens must match at least one field. */ search(query: string, entityType?: EntityTypeName): IndexSearchResult[]; /** * Find a single node by exact or partial title match. * Exact match on id or title (case-insensitive), fallback to partial. */ findByTitle(entityType: EntityTypeName, titleOrId: string): IndexNode | null; getNode(key: string): IndexNode | undefined; getNodes(type?: EntityTypeName): IndexNode[]; getEdgesFrom(key: string): IndexEdge[]; getEdgesTo(key: string): IndexEdge[]; getNeighbors(key: string): { node: IndexNode; direction: 'out' | 'in'; edgeType: string; label?: string; }[]; getAllEdges(): IndexEdge[]; /** * Score and rank candidate nodes by composite relevance using CxMS RelevanceConfig. * Requires the EmbeddingIndex to be loaded for the semantic signal; falls back to * graph + recency only if embeddings are unavailable. * * @param query The user's query text (used for semantic similarity) * @param entityType Optional type filter * @param anchorKeys Keys of already-fetched nodes (seeds for graph proximity) * @param config RelevanceConfig from the entity type definition */ searchByRelevance(query: string, entityType: EntityTypeName | undefined, anchorKeys: Set, config: import('../entities/entity-type-config.js').RelevanceConfig, currentLocation?: import('../cxms/relevance-scorer.js').Coordinates): Promise; getStats(): IndexStats; } export declare function getEntityIndex(): EntityIndex; /** Reset the singleton (for testing/eval harness). */ export declare function resetEntityIndex(): void; //# sourceMappingURL=entity-index.d.ts.map