/** * Linter cross-referencing engine. * * Verifies that linter rule references (e.g., "eslint/no-console") point to * real rules that exist and are enabled in project config. Supports: * ESLint, Stylelint (Node API), Ruff, Clippy, Pylint, RuboCop, Detekt, * Ktlint, Checkstyle, golangci-lint (CLI), * Cedar (filesystem policies for AWS Bedrock AgentCore / Vectimus). * * Across 11 catalog APIs (10 linters + Cedar policy language): a rule name is * RESOLVED against the linter's own catalog rather than matched as a string, and * its enabled state is read from the project's config. * * An exclusivity claim stood here ("the core moat — no other tool ..."). Removed * 2026-09-08 for two independent reasons, noted rather than deleted silently so * it is not restored as a wording change: it rested on a competitor matrix * checked against DOCUMENTATION rather than a run (the same matrix put a false * claim on the landing page, see tools/measure-validate-overlap.mjs), and this * repository is public, where the `no-product-strategy-here` rule forbids * competitive positioning outright. Describe the mechanism; let a reader compare. */ import { editDistance } from "./edit-distance.js"; export type { ConfigEnabledStatus, DiscoveredRules, Discovery, LinterAdapter, LinterCapabilities, } from "./linter-adapter.js"; import type { ConfigEnabledStatus, LinterAdapter } from "./linter-adapter.js"; import { type EslintInventory } from "./eslint-inventory.js"; import type { BuiltinLinter } from "./spec.js"; export interface LinterCheckResult { exists: boolean; enabled: ConfigEnabledStatus; linter: string; rule: string; error?: string; } export interface DetectedLinter { name: string; ruleCount?: number; via?: string; } /** @internal */ export declare function extractLinterName(enforcedBy: string): string; /** @internal */ export declare function extractRuleName(enforcedBy: string): string | null; /** The effective state of one detekt rule, read from a project's config. */ export interface DetektRuleState { /** The enclosing ruleset key (e.g. `style`, `complexity`). */ readonly ruleset: string; /** * `enabled`/`disabled` if the rule's own `active:` is set, else `disabled` * when its ENCLOSING ruleset is `active: false` (a ruleset-level off disables * every rule under it), else `unknown` — the rule inherits detekt's default. */ readonly active: ConfigEnabledStatus; } /** * Parse a detekt YAML config into a map of PascalCase rule name → its effective * state. Parsed with js-yaml, NOT a hand-rolled indent regex (see the * `parse-structured-input-with-a-real-parser` rule) — so indentation, quoting, * comments and inline maps all work, and a nested rule OPTION (`threshold:`, * `ignoreNumbers:`) can never be mistaken for a rule. The ONE parser every * detekt site derives from: rule-key discovery, the config-names-rule existence * fallback, and the enabled-state check. Rulesets are the top-level maps; a rule * is a PascalCase child key of a ruleset (detekt's meta sections — build, * processors, console-reports — have only lowercase/kebab children, so they are * never read as rules). Malformed YAML → an empty map (fail closed). * @internal */ export declare function parseDetektConfig(yaml: string): Map; /** * The PascalCase rule names named by a detekt config — the discovery/existence * surface. A thin projection of {@link parseDetektConfig} so key extraction and * enabled-state can never disagree. * @internal */ export declare function parseDetektRuleKeys(yaml: string): Set; /** Read the first present detekt config file's contents (null if none). @internal */ export declare function readDetektConfig(basePath: string): string | null; /** * Config-enabled status for a detekt rule, read from the project's detekt * YAML (detekt.yml / detekt-config.yml / config/detekt/detekt.yml). The rule's * own `active: true|false` decides; failing that, a ruleset-level `active: false` * disables it; otherwise the rule inherits detekt's default, reported honestly * as "unknown". Derived from the shared {@link parseDetektConfig}. * @internal */ export declare function detektEnabledStatus(ruleName: string, basePath: string): ConfigEnabledStatus; /** * Config-enabled status for a ktlint rule, read from `.editorconfig`. The * per-rule property is `ktlint__ = enabled|disabled` * (e.g. `ktlint_standard_no-wildcard-imports = disabled`); a ruleset-level * `ktlint_ = enabled|disabled` is the fallback. An unqualified rule * name defaults to the `standard` ruleset, matching ktlint. * @internal */ export declare function ktlintEnabledStatus(ruleName: string, basePath: string): ConfigEnabledStatus; /** * Config-enabled status for a checkstyle module. A checkstyle config is a * whitelist — only listed modules run — so a module absent from the config is * "disabled", and a listed module is "enabled" unless its own `severity` * property is `ignore`. * @internal */ export declare function checkstyleEnabledStatus(ruleName: string, basePath: string): ConfigEnabledStatus; /** * Whether `golangci-lint help linters` / `golangci-lint linters` output lists * a linter of this name (names start a line, followed by `:`, whitespace, or * an alt-name paren like `govet (vet, vetshadow):`). * @internal */ export declare function golangciOutputListsLinter(output: string, name: string): boolean; /** * Config-enabled status from `golangci-lint linters` output, which lists an * "Enabled by your configuration linters:" section followed by a * "Disabled by your configuration linters:" section (same section-split shape * as the pylint checker). * @internal */ export declare function golangciEnabledStatusFromOutput(output: string, name: string): ConfigEnabledStatus; /** * The linter names in the ENABLED half of `golangci-lint linters` output — the * generate-types discovery surface. Reads only the "Enabled by your * configuration linters:" section (everything before the "Disabled by …" split), * taking each name that starts a line (an optional `(alt, names)` paren ignored). * Pure so discovery can be unit-tested with no `golangci-lint` binary. * @internal */ export declare function parseGolangciEnabledLinters(output: string): string[]; /** * The repo's ESLint inventory — the ONE answer `enforce()` verification, * `generate types` and the routing catalog read. One child process per * project per run, however many references ask. */ export declare function eslintInventory(basePath: string): EslintInventory; export { editDistance }; /** @internal */ export declare function clearCedarCache(): void; export declare const LINTERS: Record; /** * Check a single linter rule reference (e.g., "eslint/no-console"). * * Verifies: (1) rule exists in linter, (2) rule is enabled in project config. * Returns a result with exists/enabled status. */ export declare function checkLinterRule(enforcedBy: string, basePath: string, options?: { catalogOnly?: boolean; linters?: Record; }): LinterCheckResult; //# sourceMappingURL=linters.d.ts.map