/** * Local Backend (Multi-Repo) * * Provides tool implementations using local .gitnexus/ indexes. * Supports multiple indexed repositories via a global registry. * LadybugDB connections are opened lazily per repo on first query. */ import type { ResolvedUnityBinding } from '../../core/unity/resolver.js'; import { type UnityContextPayload, type UnityHydrationMeta } from './unity-enrichment.js'; import type { VerificationHint } from './process-confidence.js'; import { type RegistryEntry } from '../../storage/repo-manager.js'; /** * Quick test-file detection for filtering impact results. * Matches common test file patterns across all supported languages. */ export declare function isTestFilePath(filePath: string): boolean; type ResourceSeedMode = 'strict' | 'balanced'; export interface ExpandedSymbolCandidate { id: string; name: string; type: string; filePath: string; startLine?: number; endLine?: number; } export declare function parseResourceSeedMode(raw: unknown): ResourceSeedMode; export declare function extractUnityResourcePaths(text: string): string[]; export declare function computeVerifierMinimumEvidenceSatisfied(input: { evidenceMetaRows: Array<{ verifier_minimum_evidence_satisfied?: boolean; minimum_evidence_satisfied?: boolean; truncated?: boolean; filter_exhausted?: boolean; }>; truncated: boolean; filterExhausted: boolean; }): boolean; export declare function resolveSeedPath(input: { queryText?: string; resourcePathPrefix?: string; filePath?: string; }): string | undefined; interface NextHopPayload { kind: 'resource' | 'symbol' | 'process' | 'verify'; target: string; why: string; next_command: string; } export declare function pickVerificationTarget(input: { seedMode: ResourceSeedMode; seedPath?: string; mappedSeedTargets: string[]; resourceBindings: ResolvedUnityBinding[]; fallback: string; }): string; export declare function pickVerifierSymbolAnchor(input: { queryText?: string; processSymbols: any[]; definitions: any[]; }): { symbolName?: string; symbolFilePath?: string; }; export declare function buildNextHops(input: { seedPath?: string; mappedSeedTargets: string[]; resourceBindings: ResolvedUnityBinding[]; verificationHint?: VerificationHint; repoName?: string; symbolName: string; queryForSymbol: string; }): NextHopPayload[]; export declare function resolveSeedTargetsFromResourceFile(repoPath: string, seedPath: string): Promise; export declare function filterBm25ResultsByScopePreset(rows: T[], scopePreset?: string): T[]; export declare function rankExpandedSymbolsForQuery(symbols: ExpandedSymbolCandidate[], query: string, limit?: number, scopePreset?: string): ExpandedSymbolCandidate[]; export declare function mergeUnityBindings(baseBindings: ResolvedUnityBinding[], resolvedByPath: Map): ResolvedUnityBinding[]; export declare function mergeParityUnityBindings(baseNonLightweightBindings: ResolvedUnityBinding[], resolvedBindings: ResolvedUnityBinding[]): ResolvedUnityBinding[]; export declare function attachUnityHydrationMeta(payload: UnityContextPayload, input: Pick & { hasExpandableBindings: boolean; }): UnityContextPayload; /** Valid LadybugDB node labels for safe Cypher query construction */ export declare const VALID_NODE_LABELS: Set; /** Valid relation types for impact analysis filtering */ export declare const VALID_RELATION_TYPES: Set; /** Regex to detect write operations in user-supplied Cypher queries */ export declare const CYPHER_WRITE_RE: RegExp; /** Check if a Cypher query contains write operations */ export declare function isWriteQuery(query: string): boolean; export interface CodebaseContext { projectName: string; stats: { fileCount: number; functionCount: number; communityCount: number; processCount: number; }; } interface RepoHandle { id: string; name: string; repoPath: string; storagePath: string; lbugPath: string; indexedAt: string; lastCommit: string; stats?: RegistryEntry['stats']; } export declare class LocalBackend { private repos; private contextCache; private initializedRepos; /** * Initialize from the global registry. * Returns true if at least one repo is available. */ init(): Promise; /** * Re-read the global registry and update the in-memory repo map. * New repos are added, existing repos are updated, removed repos are pruned. * LadybugDB connections for removed repos are NOT closed (they idle-timeout naturally). */ private refreshRepos; /** * Generate a stable repo ID from name + path. * If names collide, append a hash of the path. */ private repoId; /** * Resolve which repo to use. * - If repoParam is given, match by name or path * - If only 1 repo, use it * - If 0 or multiple without param, throw with helpful message * * On a miss, re-reads the registry once in case a new repo was indexed * while the MCP server was running. */ resolveRepo(repoParam?: string): Promise; /** * Try to resolve a repo from the in-memory cache. Returns null on miss. */ private resolveRepoFromCache; private ensureInitialized; /** * Get context for a specific repo (or the single repo if only one). */ getContext(repoId?: string): CodebaseContext | null; /** * List all registered repos with their metadata. * Re-reads the global registry so newly indexed repos are discovered * without restarting the MCP server. */ listRepos(): Promise>; callTool(method: string, params: any): Promise; private unityUiTrace; /** * Query tool — process-grouped search. * * 1. Hybrid search (BM25 + semantic) to find matching symbols * 2. Trace each match to its process(es) via STEP_IN_PROCESS * 3. Group by process, rank by aggregate relevance + internal cluster cohesion * 4. Return: { processes, process_symbols, definitions } */ private query; /** * BM25 keyword search helper - uses LadybugDB FTS for always-fresh results */ private bm25Search; /** * Semantic vector search helper */ private semanticSearch; executeCypher(repoName: string, query: string): Promise; private cypher; /** * Format raw Cypher result rows as a markdown table for LLM readability. * Falls back to raw result if rows aren't tabular objects. */ private formatCypherAsMarkdown; /** * Aggregate same-named clusters: group by heuristicLabel, sum symbols, * weighted-average cohesion, filter out tiny clusters (<5 symbols). * Raw communities stay intact in LadybugDB for Cypher queries. */ private aggregateClusters; private overview; /** * Context tool — 360-degree symbol view with categorized refs. * Disambiguation when multiple symbols share a name. * UID-based direct lookup. No cluster in output. */ private context; /** * Legacy explore — kept for backwards compatibility with resources.ts. * Routes cluster/process types to direct graph queries. */ private explore; /** * Detect changes — git-diff based impact analysis. * Maps changed lines to indexed symbols, then finds affected processes. */ private detectChanges; /** * Rename tool — multi-file coordinated rename using graph + text search. * Graph refs are tagged "graph" (high confidence). * Additional refs found via text search are tagged "text_search" (lower confidence). */ private rename; private impact; private _impactImpl; /** * Query clusters (communities) directly from graph. * Used by getClustersResource — avoids legacy overview() dispatch. */ queryClusters(repoName?: string, limit?: number): Promise<{ clusters: any[]; }>; /** * Query processes directly from graph. * Used by getProcessesResource — avoids legacy overview() dispatch. */ queryProcesses(repoName?: string, limit?: number): Promise<{ processes: any[]; }>; /** * Query cluster detail (members) directly from graph. * Used by getClusterDetailResource. */ queryClusterDetail(name: string, repoName?: string): Promise; /** * Query process detail (steps) directly from graph. * Used by getProcessDetailResource. */ queryProcessDetail(name: string, repoName?: string): Promise; disconnect(): Promise; } export {};