/**
 * Tool-lint CLI core (RFC-002 block C3 — the CI gate).
 *
 * Pattern: humble shell — `bin/agentfootprint-lint-tools.mjs` is a
 *          3-line wrapper; ALL behavior (arg parsing, catalog coercion,
 *          report, exit code) lives here so it is unit-testable without
 *          spawning a process.
 * Role:    `src/tool-lint/`. Reads ONE JSON file of tools, prints a
 *          report, returns the process exit code:
 *            0 — report.ok
 *            1 — findings failed the gate (!ok)
 *            2 — usage / input error (bad flags, unreadable file,
 *                unrecognized JSON shape)
 *
 * ## Embedder & gating honesty
 *
 * The CLI has no way to receive a consumer embedder, so it uses the
 * built-in deterministic mock (char-frequency, offline, dependency-free)
 * for the similarity RANKING — and, by default, does NOT gate on it:
 * without `--threshold`, similarity is report-only (relative ordering +
 * watch hints) and the exit code reflects structural findings alone.
 * Pass `--threshold` to make confusable pairs fail the gate — you own
 * the calibration at that point (start from
 * `MOCK_EMBEDDER_CALIBRATION.confusabilityThreshold` = 0.94). For real
 * embedder gating, use `analyzeToolCatalog` from
 * `agentfootprint/observe` in a small script instead.
 */
import type { CatalogTool } from './types.js';
export interface ToolLintCliIO {
    readonly stdout: (line: string) => void;
    readonly stderr: (line: string) => void;
}
/**
 * Normalize any of the recognized tool-list JSON shapes to the lint's
 * plain catalog. Throws (with a shape description) on unrecognized
 * input — the CLI maps that to exit code 2.
 */
export declare function coerceCatalog(json: unknown): readonly CatalogTool[];
/**
 * Run the lint CLI. Returns the exit code (never calls `process.exit` —
 * the bin wrapper assigns it to `process.exitCode`).
 */
export declare function runToolLintCli(argv: readonly string[], io?: ToolLintCliIO): Promise<number>;
