import type { Command } from "commander"; import type { EmitContext, HarneryProgramContext } from "../commander.js"; import { type SearchEngine } from "../lib/tools/ripgrep.js"; export type GrepEngine = SearchEngine; export interface GrepOpts { repo?: string; allRepos?: boolean; /** Repeatable and/or comma-separated (`--lang ts,tsx`). A bare string is accepted for direct callers. */ lang?: string | string[]; ignoreCase?: boolean; wholeWord?: boolean; literal?: boolean; filesOnly?: boolean; files?: boolean; count?: boolean; context?: string; afterContext?: string; beforeContext?: string; maxCount?: string; limit?: string; include?: string[]; exclude?: string[]; and?: string[]; without?: string[]; quiet?: boolean; noDefaultExcludes?: boolean; json?: boolean; } export interface Match { repo: string; file: string; line: number; text: string; /** "match" = primary result row (counts toward totals + --limit); "context" = free -C/-A/-B row. */ kind: "match" | "context"; } export declare function registerGrepCommand(program: Command, emit: EmitContext, context?: HarneryProgramContext): void; export interface GrepResult { pattern: string; mode: "regex" | "literal" | "files"; engine: GrepEngine; and_patterns: string[]; without_patterns: string[]; repos: { name: string; cwd: string; matches: Match[]; truncated: boolean; }[]; total_matches: number; total_files: number; truncated: boolean; elapsed_ms: number; } /** Exported for tests (not part of the package exports map). */ export declare function runGrep(pattern: string, paths: string[], opts: GrepOpts, context: HarneryProgramContext | undefined): Promise; type DecodeMode = "content" | "count" | "filesOnly" | "plainLines"; /** * Streaming decoder for NUL-framed engine output. Exported for direct * chunk-boundary tests. Record shapes (both engines, pinned by the parity * suite): * content: NUL:LF * count: NULLF (BSD grep ignores --null here: :LF) * filesOnly: NUL (NUL is the record terminator) * plainLines: LF (files mode: rg --files / find) * * Operates on Buffers so a chunk boundary can fall anywhere — including * inside a multi-byte UTF-8 sequence — without corrupting a record: bytes * are only decoded to strings once a full record is framed. */ export declare class NulDecoder { private readonly mode; private buffer; constructor(mode: DecodeMode); push(chunk: Buffer): Omit[]; /** Flush a trailing unterminated record (engine killed mid-write, or no final LF). */ flush(): Omit[]; private decodeRecord; } export {}; //# sourceMappingURL=grep.d.ts.map