import type { SearchRouter, SearchToolKind } from "./search-router.ts"; export type FffResult = { ok: true; value: T; } | { ok: false; error: string; }; export type FffGrepMode = "plain" | "regex" | "fuzzy"; export interface FffFileItem { relativePath: string; fileName: string; size: number; modified: number; gitStatus: string; accessFrecencyScore?: number; modificationFrecencyScore?: number; totalFrecencyScore?: number; } export interface FffScore { total: number; baseScore: number; matchType: string; } export interface FffSearchResult { items: FffFileItem[]; scores: FffScore[]; totalMatched: number; totalFiles: number; } export interface FffSearchOptions { pageIndex?: number; pageSize?: number; } export interface FffGlobOptions { pageIndex?: number; pageSize?: number; } export interface FffGrepOptions { maxMatchesPerFile?: number; smartCase?: boolean; mode?: FffGrepMode; beforeContext?: number; afterContext?: number; pageSize?: number; } export interface FffGrepMatch { relativePath: string; fileName: string; gitStatus: string; size: number; modified: number; isBinary: boolean; totalFrecencyScore: number; accessFrecencyScore: number; modificationFrecencyScore: number; lineNumber: number; col: number; byteOffset: number; lineContent: string; matchRanges: [number, number][]; contextBefore?: string[]; contextAfter?: string[]; } export interface FffGrepResult { items: FffGrepMatch[]; totalMatched: number; totalFilesSearched: number; totalFiles: number; filteredFileCount: number; nextCursor: unknown | null; regexFallbackError?: string; } export interface FffFileFinder { readonly isDestroyed: boolean; destroy(): void; fileSearch(query: string, options?: FffSearchOptions): FffResult; glob(pattern: string, options?: FffGlobOptions): FffResult; grep(query: string, options?: FffGrepOptions): FffResult; waitForScan(timeoutMs?: number): Promise>; } interface FffInitOptions { basePath: string; aiMode?: boolean; enableHomeDirScanning?: boolean; enableFsRootScanning?: boolean; } interface FffFileFinderConstructor { create(options: FffInitOptions): FffResult; isAvailable?: () => boolean; } export interface FffModule { FileFinder: FffFileFinderConstructor; } export interface FffSearchBackend { getFinder(basePath: string): Promise; } /** * Calls backend.getFinder(cwd) and guarantees the returned promise can never * reject -- not even if a non-conforming backend's getFinder throws * synchronously instead of returning a rejected promise (the FffSearchBackend * contract is also implemented by extension-supplied backends, e.g. an SSH * remote search, which aren't guaranteed to be `async`-declared). find.ts and * grep.ts call this unconditionally, before routing decides whether this call * even wants FFF, specifically so a broken/throwing backend degrades to * "unavailable for this call" (graceful fd/rg fallback) instead of failing * the whole tool call or risking an unhandled rejection. */ export declare function safeGetFinder(backend: FffSearchBackend, cwd: string): Promise; /** * Acquire an FFF finder only when all three routing stages accept it. Finder startup begins before * routing so a lazy managed install can progress even when the current request falls back to fd/rg. */ export declare function resolveRoutedFffFinder(options: { backend: FffSearchBackend; router: SearchRouter; tool: SearchToolKind; cwd: string; searchPath: string; glob: boolean; ignoreCase: boolean; limit: number; readGitignoreInTree: () => Promise | boolean; }): Promise<{ finder: FffFileFinder; searchPathRelativeToCwd: string; } | undefined>; type ModuleRequire = (id: string) => unknown; export declare function loadFffModule(requires?: readonly ModuleRequire[]): FffModule | null; export declare function relativePathInside(basePath: string, targetPath: string): string | undefined; export declare function hasGitignoreInTree(rootPath: string): Promise; /** * The two calls DefaultFffSearchBackend.createFinder makes to lazily load and, * if needed, install `@ff-labs/fff-node`. Pulled out as an injectable seam * (mirroring loadFffModule's optional `requires` param) so tests can simulate * a fresh machine -- and a faked install succeeding or failing -- without * touching the real module-global caches or spawning a real npm install. */ export interface FffFinderDeps { ensureFffModule: () => Promise; ensureFffNodePackage: (silent: boolean, forceManagedInstall?: boolean) => Promise; /** Whether the last install outcome was a genuine failure worth retrying. */ isInstallRetryable: () => boolean; } export declare class DefaultFffSearchBackend implements FffSearchBackend { private readonly finders; private readonly deps; constructor(deps?: FffFinderDeps); getFinder(basePath: string): Promise; private evictIfNeeded; private createFinder; } export declare const defaultFffSearchBackend: FffSearchBackend; export {}; //# sourceMappingURL=fff-search-backend.d.ts.map