/** * Bot review comment parsing and resolution filtering. * * Normalizes CodeRabbit and GCA inline review comments into * structured findings, then filters to only resolved (accepted) threads * so that `review-learn` extracts lessons only from findings the * developer actually fixed. */ /** * The review bots whose comment formats triage-pr knows how to parse, plus * `unknown` for an unrecognized author. Adding a bot is a single-place change * here + its severity parser in {@link parseSeverityForTool}. * * NOTE: `gca` is triage's local id for `gemini-code-assist` — it intentionally * diverges from the core actor-id scheme in `@mmnto/totem`'s `resolveActorId` * (which uses `gemini-code-assist` and EXACT-login matching for hit-rate * attribution). Triage's goal is broad recognition (surface every finding) with * a compact display id; it matches coderabbit/gca by substring and greptile by * its bot-login shape (see `GREPTILE_BOT_LOGIN`). The two schemes serve * different purposes and are deliberately not coupled. * * `ghcq` is GitHub's own `github-code-quality[bot]` (mmnto-ai/totem#2626; * observed corpus n=7 inline comments: mmnto-ai/totem #1897/#2224/#2434/#2457 * since 2026-05-12 + mmnto-ai/liquid-city#980) — an inline-comment-only * surface whose review submissions are empty carriers. No @-listener is known * for it (attested: no tag has ever been attempted in-org and none is * documented) — treat disposition comments as audit-trail-only. */ export type BotTool = 'coderabbit' | 'gca' | 'greptile' | 'ghcq' | 'unknown'; export interface NormalizedBotFinding { tool: BotTool; severity: string; file: string; line?: number; body: string; /** The raw suggestion text if present */ suggestion?: string; /** How we determined this was resolved */ resolutionSignal?: 'reply' | 'resolved_thread' | 'none'; /** The root comment ID of the thread this finding originated from */ rootCommentId?: number; /** * Round disposition per the canonical decline taxonomy * (doctrine bot-protocols.md §8.1; mmnto-ai/totem#2124). `declined` findings are * kept out of lesson extraction so a refuted claim is never laundered into a rule. * `undefined` means no disposition signal was available (treated as not-declined). */ disposition?: 'accepted' | 'declined'; /** For `declined` findings: the human reply that signalled the decline (audit-breadcrumb / mmnto-ai/totem#2038 backfill reference). */ dispositionRationale?: string; } export interface CommentThread { path: string; diffHunk: string; comments: Array<{ id?: number; author: string; body: string; }>; } export declare function isBotComment(author: string): boolean; export declare function detectBot(author: string): BotTool; /** Extract severity from CR comment body (red circle Critical, orange circle Major, yellow circle Minor) */ export declare function parseCRSeverity(body: string): string; /** Strip HTML wrapper tags but keep content. Unwraps
, ,
. */ export declare function stripHtmlWrappers(html: string): string; /** Extract suggestion blocks from CR/GCA comments */ export declare function extractSuggestion(body: string): string | undefined; /** Extract severity from GCA comment body (SVG priority images) */ export declare function parseGCASeverity(body: string): string; /** * Extract severity from a greptile inline comment body via its P1/P2/P3 * priority label (greptile's severity vocabulary), mapped onto the shared * high/medium/low scale that {@link mapToTriageCategory} consumes. * * Best-effort: greptile's inline format is less structured than CR's emoji or * GCA's SVG marker, so when no explicit priority token is present this returns * `info` and the body-keyword categorizer does the real bucketing. Word-bounded * so `P1`/`p1` matches but a mid-token `GP1X` does not. P0 is greptile's * critical/blocking level (greptile review on mmnto-ai/totem#2244) — without it, * a `P0` finding would silently fall through to `info`, the opposite of safe. */ export declare function parseGreptileSeverity(body: string): string; /** * Extract greptile's documented merge-readiness Confidence Score (`N/5`, integer * 0–5) from its summary comment — 5 production-ready … 0–1 critical problems * (greptile docs: code-review/first-pr-review). A status signal surfaced as * triage context (NOT a finding); returns `undefined` when no score is present. * Parsed as `N/5`, never a percentage. */ export declare function parseGreptileConfidence(body: string): number | undefined; /** * Single source of truth for "which severity parser applies to which bot". * Keeps the per-tool dispatch in one place so adding a bot does not require * touching every finding-normalizer (triage-pr, extractResolved, extractPushback). */ export declare function parseSeverityForTool(tool: BotTool, body: string): string; /** Patterns indicating human pushback (false positive signal). */ export declare const PUSHBACK_PATTERNS: RegExp[]; /** * Check if a bot comment thread was "fixed" (resolved positively). * Conservative heuristic: requires explicit agreement, not just thread resolution. */ export declare function isThreadResolved(thread: CommentThread): boolean; /** * Normalize bot review comments into structured findings. * Only returns findings from threads that were resolved positively. */ /** * Extract findings from review-bot SUMMARY bodies (CodeRabbit outside-diff + nits, * greptile "Comments Outside Diff"). Surface-agnostic: callers pass review * submission bodies (`fetchReviews`/`pr.reviews`) AND PR issue comments * (`fetchIssueComments`) — bots post these standing summaries on different * surfaces (CR in the review body, greptile in the issue-comment summary) and * edit them in place across rounds. Overlap between surfaces is collapsed * downstream by `deduplicateFindings`. Shared by triage-pr and review-learn. */ export declare function extractReviewBodyFindings(reviews: Array<{ author: string; body: string; }>): NormalizedBotFinding[]; /** * Extract findings from threads where the human explicitly pushed back (false positive signals). * Inverse of extractResolvedBotFindings — captures "intentional", "by design", "won't fix" threads. */ export declare function extractPushbackFindings(threads: CommentThread[]): NormalizedBotFinding[]; export declare function extractResolvedBotFindings(threads: CommentThread[]): NormalizedBotFinding[]; //# sourceMappingURL=bot-review-parser.d.ts.map