import type { LlmMutatorConfig } from '../config'; import type { ProposeTarget } from './propose'; import type { SourceRange } from '../seam/types'; /** Risk-formula weights (functional-architecture §4 Gate 1). Exported for tests. */ export declare const RISK_WEIGHTS: { /** w1 — per branch test node in the function subtree. */ readonly branch: 1; /** w2 — per unit of max nesting depth reached. */ readonly nesting: 0.5; /** w3 — per off-by-one-affinity construct (indexing/slice/boundary/comparison). */ readonly offByOne: 1.5; /** w4 — per `// Stryker disable`-covered node (author-vetted; deprioritize). */ readonly ignored: 2; }; /** * The semanticRichness BOOST added (to a base of 1) when a function shows ≥2 * distinct operator kinds, object/array construction, or a multi-arg call — the * places single-token formulaic swaps under-cover. */ export declare const RICHNESS_BOOST = 1; /** * Gate-2 threshold: a function is LLM-worthy when `semanticRichness >= * RICHNESS_THRESHOLD` (i.e. the boost is present). Formulaic-only functions fall * below it and are left to the heuristic mutators. */ export declare const RICHNESS_THRESHOLD: number; /** One source file the pre-pass reads (absolute path + content). */ export interface SourceFileInput { /** Absolute path Stryker keys by (`path.hub.file.opts.filename`). */ fileName: string; /** The file's full source text. */ content: string; } /** A coverage lookup: how many tests cover the span, or `undefined` if unknown. */ export type CoverageLookup = (fileName: string, range: SourceRange) => number | undefined; /** A logger sink for targeting notes (coverage, Gate-2 skips). Defaults to no-op. */ export type TargetLogger = (line: string) => void; /** * A cache probe: true when the pre-pass call for this target would be a cache * HIT. Must use the SAME key computation as the pre-pass (`proposeCacheIdentity`) * — the driver builds it from one `ResponseCache.keys()` listing. */ export type CachedTargetProbe = (target: ProposeTarget) => boolean; /** Options for {@link buildProposeTargets}. */ export interface BuildProposeTargetsOptions { /** Injected coverage probe; absent ⇒ no coverage signal (treat as eligible). */ coverageLookup?: CoverageLookup; /** Note sink for coverage + Gate-2 aggregates. */ log?: TargetLogger; /** * Injected cache probe; absent ⇒ every candidate is treated as UNCACHED (the * legacy per-file cut + top-K apply to all of them). */ isCached?: CachedTargetProbe; /** * Frozen (cache-only) mode: uncached candidates are skipped, since the * budgeted provider would answer them with no candidates anyway. Default false. */ frozen?: boolean; } /** Per-function scoring detail carried for logging + the diminishing-returns proxy. */ export interface TargetMeta { /** Absolute file the function lives in. */ fileName: string; /** The function's 0-based Stryker range. */ range: SourceRange; /** Computed risk (pre-semanticRichness). */ risk: number; /** semanticRichness multiplier (≥1). */ semanticRichness: number; /** EV = risk · semanticRichness. */ ev: number; /** Number of eligible sub-spans found in the function. */ eligibleSpanCount: number; /** True when the `isCached` probe reported a hit (a free target, never capped). */ cached: boolean; } /** The result of {@link buildProposeTargets}: the targets plus their meta. */ export interface BuildProposeTargetsResult { /** EV-ranked ProposeTargets (one per chosen enclosing function). */ targets: ProposeTarget[]; /** Per-target scoring meta, index-aligned with {@link targets}. */ meta: TargetMeta[]; } /** The per-function accumulators built during the subtree walk. */ interface FunctionScore { branchCount: number; maxDepth: number; offByOneAffinity: number; ignoredCount: number; distinctOperators: Set; hasLiteralConstruction: boolean; hasMultiArgCall: boolean; statementCount: number; hasBranch: boolean; eligibleSpanCount: number; } /** * Gate-2 complementarity predicate: a function is LLM-worthy when it is * semantically rich (≥2 distinct operators, object/array construction, or a * multi-arg call), OR it is recognizable business logic (a multi-statement body * with a branch). Formulaic-only functions are left to the heuristic mutators. */ export declare function isLlmWorthy(semanticRichness: number, score: FunctionScore): boolean; /** * Build the EV-ranked {@link ProposeTarget}s from the source files Stryker will * mutate. One target per chosen enclosing function (Gate 3 batches by function). * * @param files The absolute-path source files (the mutate glob set), already read. * @param config The parsed config (reads `dynamicLLM.targeting` + `budget`). * @param options Optional coverage probe + note logger. * @returns EV-ranked targets and their index-aligned scoring meta. */ export declare function buildProposeTargets(files: readonly SourceFileInput[], config: LlmMutatorConfig, options?: BuildProposeTargetsOptions): BuildProposeTargetsResult; export {};