import type { WorkspaceEntry } from "./useWorkspaceEntries.js";
import type { WorkspaceContentMatch, WorkspaceContentSearcher } from "./WorkspaceContentSearcher.js";
/** Options for {@link useWorkspaceContentSearch}. */
export interface UseWorkspaceContentSearchOptions {
    /** All workspace entries to search across. */
    readonly entries: readonly WorkspaceEntry[];
    /** Platform-injected content searcher. `undefined` → content search is unavailable. */
    readonly searcher: WorkspaceContentSearcher | undefined;
    /** Current search query. Trimmed; below {@link minLength} yields no search. */
    readonly query: string;
    /** Debounce delay for query changes in milliseconds. @default 300 */
    readonly debounceMs?: number;
    /** Minimum trimmed query length before a search runs. @default 2 */
    readonly minLength?: number;
}
/** Content-search hits (and per-entry status) for one workspace entry. */
export interface WorkspaceContentSearchGroup {
    /** The workspace entry these matches belong to. */
    readonly entry: WorkspaceEntry;
    /** Line-level matches within this entry, backend-ordered (path, then line). */
    readonly matches: readonly WorkspaceContentMatch[];
    /** `true` when this entry's search was capped (more matches exist than shown). */
    readonly truncated: boolean;
    /** Search error for this entry, if any (isolated — other entries still resolve). */
    readonly error: Error | null;
}
/** Return value of {@link useWorkspaceContentSearch}. */
export interface UseWorkspaceContentSearchReturn {
    /** Entries with something to show (matches, an error, or a truncation notice). */
    readonly groups: readonly WorkspaceContentSearchGroup[];
    /** Total matches across all groups (for a "showing N of M" affordance). */
    readonly totalMatches: number;
    /** `true` during the first search of a query with no prior results to show. */
    readonly isLoading: boolean;
    /** `true` while a new query loads *over* previously-shown results (no blank flash). */
    readonly isRefetching: boolean;
    /** `true` when no substrate can be searched (no searcher, or every entry unsupported). */
    readonly isUnsupported: boolean;
    /** First per-entry error, for a top-level fallback message. `null` when none. */
    readonly error: Error | null;
}
/**
 * Behavior hook powering workspace-wide content (text) search.
 *
 * The text-grep sibling of
 * {@link useWorkspaceFileSearch}: it keeps
 * that hook's per-entry aggregation, error isolation, and generation guard, and
 * adds the platform's canonical debounce idiom from `useResourceSearch`
 * (`query`/`debouncedQuery` + `setTimeout`). The key difference is that the
 * debounced query is part of the *fetch* — each keystroke hits disk via the
 * injected {@link WorkspaceContentSearcher}, uncached — so a `minLength` guard
 * and a debounce protect the filesystem.
 *
 * Prior results stay visible while a new debounced query loads (`isRefetching`
 * true, results unchanged); only the very first search with nothing to show
 * flips `isLoading`. This avoids a per-keystroke blank flash the cached filename
 * search never had.
 *
 * @example
 * ```tsx
 * const { groups, totalMatches, isRefetching } = useWorkspaceContentSearch({
 *   entries: workspace.entries,
 *   searcher: workspaceContentSearcher,
 *   query,
 * });
 * ```
 */
export declare function useWorkspaceContentSearch({ entries, searcher, query, debounceMs, minLength, }: UseWorkspaceContentSearchOptions): UseWorkspaceContentSearchReturn;
//# sourceMappingURL=useWorkspaceContentSearch.d.ts.map