/** * Grep — regex search over the parsed session line-stream, with grep-style * line context. NOT a filesystem search: we never grep against the JSONL on * disk. Sessions are loaded via the same parsers `snap` uses, normalized into * `Conversation` objects, then rendered to the same per-line text shape snap * prints (header + `[ts] ROLE:` + content). Matching happens in-process over * those rendered lines. * * Default scope is global: all sources (Claude Code CLI, Codex, opencode), * all cwds, all time. Use --cwd / --source / --since to narrow. */ import { type Conversation, type SourceType } from './session-parser.js'; export interface GrepOptions { /** One or more patterns. Multiple patterns are OR'd (alternation). */ patterns: string[]; /** Restrict to sessions whose cwd matches (exact path). Default: all cwds. */ cwd?: string; /** Restrict to specific source types. Default: all known sources. */ sources?: SourceType[]; /** Treat patterns as literal strings, not regex. Default false. */ fixedStrings?: boolean; /** Case-insensitive matching. Default false. */ ignoreCase?: boolean; /** Lines of context before and after each match (default 5). Overridden by before/after. */ context?: number; /** Lines before the match (overrides context for the before half). */ before?: number; /** Lines after the match (overrides context for the after half). */ after?: number; /** Time window in ms from now. Sessions whose last message is older are skipped. Default: no window. */ sinceMs?: number; /** Cap on total matches across all sessions (default 50). */ maxMatches?: number; /** Cap on sessions scanned (default 500). Performance guardrail. */ maxSessions?: number; /** Skip sessions whose file mtime is within this many ms (live-session filter). Default 10_000, claude-code only. */ liveSessionWindowMs?: number; /** Include the actively-written session. Default false. */ includeCurrent?: boolean; /** Include `entrypoint: 'sdk-cli'` claude-code sessions (Claude Code's own automation). Default false. */ includeSdkCli?: boolean; } export interface GrepContextLine { /** 1-indexed line number within the rendered session text. */ lineNumber: number; text: string; /** True if this line itself matched the pattern. Context lines are false. */ isMatch: boolean; } export interface GrepMatchGroup { sessionId: string; sourceLabel: string; sourceType: SourceType; cwd: string | null; filePath: string; /** ISO timestamp of the session's last message. */ sessionLastMessageTime: string; /** Age of the session in ms (now - last message time). */ sessionAgeMs: number; /** The matching line numbers in this group (1+). */ matchLineNumbers: number[]; /** Lines in the group, with isMatch flagged for each match. Always includes context. */ lines: GrepContextLine[]; } export interface GrepResult { patterns: string[]; /** True regex used (after any -F escaping and case-insensitive flag). */ regex: string; matches: GrepMatchGroup[]; /** Pre-rendered text suitable for terminal output. Empty when matches is empty. */ text: string; /** Number of sessions actually parsed and scanned (after filters). */ sessionsScanned: number; /** Sessions that produced at least one match. */ sessionsWithMatches: number; /** Total match count across all sessions before maxMatches truncation. -1 if unknown (we capped scanning). */ totalMatchesBeforeCap: number; /** True if max-matches or max-sessions clipped the output. */ truncated: boolean; } export declare function escapeRegex(s: string): string; export declare function compileRegex(opts: GrepOptions): RegExp; /** * Render a Conversation as a flat list of lines — the same shape `snap` prints. * Header first, then per-message: a `[ts] ROLE:` marker, the message content * split on \n, and a blank line between messages. Returns lines without * trailing newlines; line N is `lines[N-1]` (1-indexed for grep semantics). */ export declare function renderSessionLines(conv: Conversation, sourceLabel: string, cwd: string | null, ageLabel: string, lastMessageTime: Date): string[]; /** * Find all matches in a rendered line array and group adjacent matches into * one block (grep merges context windows that overlap; we do the same). * * @returns { groups: array of { matchLineNumbers, lines: ContextLine[] }, totalMatches } */ export declare function findMatchGroups(lines: string[], regex: RegExp, before: number, after: number): { groups: { matchLineNumbers: number[]; lines: GrepContextLine[]; }[]; totalMatches: number; }; export declare function grep(opts: GrepOptions): GrepResult; //# sourceMappingURL=grep.d.ts.map