import Anthropic from '@anthropic-ai/sdk'; import type { AcceptanceCriterion, Finding, Task } from '@manehorizons/cadence-types'; import { type SpawnFn } from './host-cli-client.js'; /** * Phase 24.3 — code-review verifier. Per-file findings against the phase * diff. Fires at `cadence settle run` when `'code-review'` is in the * effective gate set (strict×standard, strict×complex, standard×complex). * HIGH findings refuse settle unless `--force` / `--allow-code-review-failure`. * * Phase 236 (T5, D9) — `Finding` is the shared, persisted SUMMARY-schema type * from `@manehorizons/cadence-types` (severity `critical|high|medium|low`, * plus the optional `id`/`target`/`disposition`/`waiver`/`anchor` fields). * This module used to declare its own local `Finding`/`FindingSeverity` * (severity `high|medium|low` only) — that divergence is now converged; see * `contracts/index.ts`'s `CodeReviewFinding` re-export for the compat name. */ /** * Phase 235 (T3) — a task->AC ref as seen by the review verifier: what a task * touches, how it is verified, and which AC it claims to satisfy. A `Pick` * over the DRAFT's own `Task` shape (`@manehorizons/cadence-types`) rather * than a restated structural type, so it cannot drift from the schema. */ export type CodeReviewTaskRef = Pick; export interface CodeReviewInput { /** Touched files (from draft tasks). Used to scope diff parsing + Anthropic prompt. */ files: string[]; /** Unified diff (`git diff HEAD -- `). May be empty. */ diff: string; /** * Phase 235 (T3) — the DRAFT's acceptance criteria (`id`, `name`, `given`, * `when`, `then`), so the reviewer can see what the phase committed to * rather than grading against general good practice alone. Additive and * optional: existing callers and all four providers keep compiling * unchanged when it is omitted. */ acceptanceCriteria?: AcceptanceCriterion[]; /** * Phase 235 (T3) — the DRAFT's `## Boundaries` list ("Do NOT touch/add" * prose). Additive and optional, same as `acceptanceCriteria`. */ boundaries?: string[]; /** * Phase 235 (T3) — task->AC refs (`Task.id`, `files`, `verify`, `done`, * `status`) from the DRAFT's tasks. Additive and optional, same as * `acceptanceCriteria`. */ taskRefs?: CodeReviewTaskRef[]; } export interface CodeReviewResult { /** Per-file findings. File paths use forward slashes. */ findings: Record; provider: string; model?: string; } export interface CodeReviewVerifier { readonly name: string; verify(input: CodeReviewInput): Promise; } /** * Phase 235 (T5) — one opt-in extra diff marker beyond the built-in * `console.log(` HIGH rule: a regex tested against each added line's body * (the same slice(1) the console.log rule uses), and the severity/message to * emit on a match. Exists so the §6 Slice 3 adversarial corpus (findings at * severities other than HIGH, tied to specific synthetic defects) can be * exercised offline through the mock's existing deterministic line-walk, * without adding a second parsing pass or touching the console.log rule. */ export interface MockCodeReviewMarker { pattern: RegExp; severity: Finding['severity']; message: string; } export interface MockCodeReviewVerifierOptions { /** * Phase 235 (T5) — additional recognized markers, checked in the same * per-added-line loop as `console.log(`, after it, using the identical * `postLine` bookkeeping so line numbers stay accurate. Additive and * opt-in: omitted or empty (the default) means `new * MockCodeReviewVerifier()` produces byte-for-byte the same output as * before this option existed — the console.log→HIGH rule, its line-number * arithmetic, and the empty-diff early return are all untouched. */ extraMarkers?: readonly MockCodeReviewMarker[]; } /** * Deterministic mock — flags every `console.log(...)` added in the diff as * a HIGH finding. Empty diff (or no matches) returns no findings. The rule * is intentionally narrow: real reviews live in the Anthropic provider. * Phase 235 (T5): optionally takes `extraMarkers` to recognize additional * diff patterns for offline corpus testing — see `MockCodeReviewVerifierOptions`. */ export declare class MockCodeReviewVerifier implements CodeReviewVerifier { readonly name = "mock"; private readonly extraMarkers; constructor(options?: MockCodeReviewVerifierOptions); verify(input: CodeReviewInput): Promise; } export interface AnthropicCodeReviewVerifierOptions { apiKey?: string; model?: string; maxTokens?: number; /** Inject a client for tests; production callers should omit this. */ client?: Anthropic; } export declare class AnthropicCodeReviewVerifier implements CodeReviewVerifier { readonly name = "anthropic"; private readonly client; private readonly model; private readonly maxTokens; constructor(opts?: AnthropicCodeReviewVerifierOptions); verify(input: CodeReviewInput): Promise; } export interface LocalCodeReviewVerifierOptions { baseURL: string; model: string; transport?: typeof fetch; } export declare class LocalCodeReviewVerifier implements CodeReviewVerifier { private readonly o; readonly name = "local"; constructor(o: LocalCodeReviewVerifierOptions); verify(input: CodeReviewInput): Promise; } export interface HostCliCodeReviewVerifierOptions { /** Host CLI binary name or path, e.g. `"claude"` or `"codex"`. */ bin: string; model?: string; /** Inject a spawn implementation for tests; production callers should omit this. */ spawnImpl?: SpawnFn; } /** * Phase 191 — spawns the user's already-installed, already-authenticated * host CLI (`claude`/`codex`) in headless mode via `hostCliJSON` instead of * calling an HTTP endpoint. Structurally mirrors `LocalCodeReviewVerifier` — * same early-return, `SYSTEM_PROMPT`/`formatUserMessage`/ * `CodeReviewResponseSchema`, only the transport differs. */ export declare class HostCliCodeReviewVerifier implements CodeReviewVerifier { private readonly o; readonly name = "host-cli"; constructor(o: HostCliCodeReviewVerifierOptions); verify(input: CodeReviewInput): Promise; } //# sourceMappingURL=code-review.d.ts.map