/**
 * Inline allowlist annotations.
 *
 * Grammar:
 *
 *   <lineComment> dxkit-allow:<category> reason="<text>"
 *
 * Examples:
 *
 *   # dxkit-allow:test-fixture reason="placeholder in unit test"
 *   // dxkit-allow:false-positive reason="regex matches our intentional placeholder"
 *
 * Two positions:
 *
 *   - **Same-line** — annotation appears on the same source line as
 *     the finding, separated by at least one space:
 *
 *       api_key = "sk_test_xxxx"  # dxkit-allow:test-fixture reason="..."
 *
 *   - **Above-line** — annotation occupies its own line, immediately
 *     preceding the finding (matching its indentation):
 *
 *       # dxkit-allow:test-fixture reason="..."
 *       api_key = "sk_test_xxxx"
 *
 * The position is chosen at insert time by `insertAnnotation`: short
 * source lines (under the configurable threshold) get same-line
 * annotation; longer lines get above-line so the result stays
 * readable.
 *
 * The grammar applies uniformly across every language; only the
 * `<lineComment>` token varies (`#` for python/ruby, `//` for
 * typescript/go/rust/csharp/kotlin/java). Each language pack
 * declares its token via `LanguageSupport.commentSyntax`.
 *
 * # Quoting + escaping
 *
 * The reason is a JSON-style string. To embed a literal `"`, escape
 * as `\"`; to embed a literal `\`, escape as `\\`. The parser
 * un-escapes both on read; the writer escapes both on insert. No
 * other escape sequences are supported (no `\n`, `\t`, etc.) — keep
 * the reason single-line for human review.
 */
import type { LanguageSupport } from '../languages/types';
import { type AllowlistCategory } from './categories';
export type AnnotationPosition = 'same-line' | 'above';
export interface InlineAnnotation {
    readonly category: AllowlistCategory;
    /** Free-form rationale. `undefined` when the annotation is
     *  syntactically valid but the `reason="..."` clause was omitted —
     *  callers typically treat this as a "malformed annotation"
     *  warning. */
    readonly reason?: string;
}
export interface AnnotationMatch {
    readonly annotation: InlineAnnotation;
    readonly position: AnnotationPosition;
    /** 1-indexed line where the annotation comment LIVES (not the
     *  finding's line — though they're the same for `same-line`). */
    readonly annotationLine: number;
}
export interface InsertOptions {
    /**
     * Maximum source-line length that still gets a same-line annotation.
     * Longer lines get above-line annotation to keep the result
     * readable. The annotation itself is typically 50-80 characters,
     * so totaling source + annotation around 120-140 characters at
     * this threshold.
     */
    readonly sameLineThreshold?: number;
}
/**
 * Render a complete annotation comment for a given language.
 * Exposed so callers (the CLI, the block-time hint formatter) can
 * surface the exact string a developer would paste, without going
 * through the file-mutation path.
 */
export declare function renderAnnotation(annotation: InlineAnnotation, lang: LanguageSupport): string;
/**
 * Parse a single line for an allowlist annotation. Returns `null`
 * when no annotation marker is found OR when the category isn't
 * one of the canonical values.
 *
 * Tolerates the `reason="..."` clause being absent — callers decide
 * whether a missing reason invalidates the suppression.
 *
 * False-positive surface: a string literal containing the literal
 * substring `<lineComment> dxkit-allow:<category>` would match.
 * Discriminating "is this inside a string" requires real language
 * parsing and isn't worth the complexity — the worst case is a
 * legitimate finding gets suppressed when a developer wrote the
 * grammar literally inside a string. Vanishingly rare in practice.
 */
export declare function parseAnnotation(line: string, lang: LanguageSupport): InlineAnnotation | null;
/**
 * Look for an annotation matching a finding at `filePath:lineNumber`
 * (1-indexed). Checks two positions:
 *
 *   1. Same-line: the finding's line itself carries the annotation.
 *   2. Above-line: the immediately-preceding line is a standalone
 *      annotation comment.
 *
 * Returns `null` when neither position has a parseable annotation.
 * Throws when the file doesn't exist or `lineNumber` is out of
 * range — callers are typically operating on findings whose line
 * numbers came from a fresh scan, so an out-of-range value
 * indicates a bug worth surfacing.
 */
export declare function findAnnotationAt(filePath: string, lineNumber: number, lang: LanguageSupport): AnnotationMatch | null;
/**
 * Insert an allowlist annotation at `filePath:lineNumber`. Chooses
 * same-line vs above-line based on the target line's length:
 *
 *   - Target shorter than `sameLineThreshold` → append to target.
 *   - Target longer than threshold → prepend a new comment line
 *     above target, copying its indentation.
 *
 * Returns the chosen position + the 1-indexed line where the
 * annotation comment ended up (useful for the CLI to print "added
 * at file:line").
 *
 * Refuses to insert when the category is not inline-compatible —
 * the caller should route accepted-risk + deferred suppressions
 * through the file-level allowlist instead.
 *
 * Preserves CRLF vs LF line endings: the file is read, split, and
 * re-joined using the detected style. Files without a trailing
 * newline keep that property.
 */
export declare function insertAnnotation(filePath: string, lineNumber: number, annotation: InlineAnnotation, lang: LanguageSupport, options?: InsertOptions): {
    position: AnnotationPosition;
    annotationLine: number;
};
/**
 * Whether a line is a "standalone annotation comment" — meaning it
 * contains nothing but leading whitespace + the comment marker +
 * the annotation body. Used to distinguish an above-line annotation
 * from a same-line annotation on a different finding's line.
 *
 * Exported because the gather pass (`src/allowlist/gather.ts`) needs
 * the same predicate to label per-occurrence `position`. Single
 * source of truth for the "what counts as standalone" rule.
 *
 * Example (python):
 *   `    # dxkit-allow:test-fixture reason="..."`   ← standalone
 *   `x = 1  # dxkit-allow:test-fixture reason="..."`  ← NOT standalone
 */
export declare function isStandaloneAnnotationLine(line: string, lang: LanguageSupport): boolean;
//# sourceMappingURL=inline.d.ts.map